@michelabboud/visual-forge-mcp 0.5.5 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,688 @@
1
+ # Visual Forge MCP - Backup System
2
+
3
+ ## Overview
4
+
5
+ The backup system provides automatic, transparent file backup and restoration capabilities for Visual Forge MCP. It ensures users can safely revert changes if needed while maintaining a clean, intuitive workflow.
6
+
7
+ ## Features
8
+
9
+ ✅ **Automatic backups** before modifying markdown files
10
+ ✅ **Backup generated images** alongside markdown files
11
+ ✅ **Integrity verification** with MD5 hashing
12
+ ✅ **24-hour reminders** for pending backups
13
+ ✅ **Atomic operations** for backup/restore
14
+ ✅ **State persistence** across sessions
15
+ ✅ **Enable/disable switch** (VF_BACKUP_ENABLED)
16
+ ✅ **MCP tool integration** (approve, restore, list)
17
+
18
+ ## Configuration
19
+
20
+ ### Environment Variable
21
+
22
+ ```bash
23
+ # Enable/disable backups (default: true)
24
+ VF_BACKUP_ENABLED=true
25
+
26
+ # Disable backups
27
+ VF_BACKUP_ENABLED=false
28
+ ```
29
+
30
+ ### Configuration Object
31
+
32
+ ```typescript
33
+ {
34
+ enabled: true, // Enable backups
35
+ extension: '.vf-bak', // Backup file extension
36
+ reminderIntervalHours: 24, // Reminder frequency
37
+ }
38
+ ```
39
+
40
+ ## How It Works
41
+
42
+ ### 1. Backup Creation
43
+
44
+ When Visual Forge modifies files, it automatically creates backups:
45
+
46
+ ```
47
+ Original Files:
48
+ docs/README.md
49
+ generated-images/diagram-001.png
50
+
51
+ Backup Files Created:
52
+ docs/README.md.vf-bak
53
+ generated-images/diagram-001.png.vf-bak
54
+ ```
55
+
56
+ Each backup includes:
57
+ - Original file path
58
+ - Backup file path
59
+ - Timestamp
60
+ - File size
61
+ - MD5 hash (for integrity verification)
62
+ - File type (markdown or image)
63
+
64
+ ### 2. State Tracking
65
+
66
+ Backups are tracked in the StateManager:
67
+
68
+ ```typescript
69
+ {
70
+ backups: {
71
+ current: BackupSet | null, // Active backup set
72
+ history: [ // Past backups
73
+ {
74
+ id: "backup-uuid",
75
+ createdAt: "2026-01-13T...",
76
+ action: "approved",
77
+ actionAt: "2026-01-13T...",
78
+ filesCount: 8
79
+ }
80
+ ]
81
+ }
82
+ }
83
+ ```
84
+
85
+ ### 3. User Workflow
86
+
87
+ ```
88
+ 1. User generates images
89
+
90
+ 2. Visual Forge creates backups (transparent)
91
+
92
+ 3. Visual Forge modifies markdown files
93
+
94
+ 4. User reviews changes
95
+
96
+ 5a. Approve → Delete backups 5b. Restore → Undo changes
97
+ ```
98
+
99
+ ## MCP Tools
100
+
101
+ ### 1. `approve_changes`
102
+
103
+ **Description**: Approve changes and delete backup files (keeps modifications)
104
+
105
+ **Input**: None
106
+
107
+ **Output**:
108
+ ```json
109
+ {
110
+ "success": true,
111
+ "message": "Changes approved successfully",
112
+ "filesDeleted": 8,
113
+ "backupId": "abc-123-def"
114
+ }
115
+ ```
116
+
117
+ **Use Case**: User is happy with generated images and wants to keep changes
118
+
119
+ **Example**:
120
+ ```
121
+ User: "The images look great! I'll keep these changes."
122
+ AI: Calling approve_changes...
123
+ Response: "✓ Changes approved! Deleted 8 backup files."
124
+ ```
125
+
126
+ ---
127
+
128
+ ### 2. `restore_from_backups`
129
+
130
+ **Description**: Restore files from backups (undoes all changes)
131
+
132
+ **Input**: None
133
+
134
+ **Output**:
135
+ ```json
136
+ {
137
+ "success": true,
138
+ "message": "All files restored successfully",
139
+ "filesRestored": 8,
140
+ "errors": [],
141
+ "backupId": "abc-123-def"
142
+ }
143
+ ```
144
+
145
+ **Use Case**: User wants to undo changes and go back to original state
146
+
147
+ **Example**:
148
+ ```
149
+ User: "Actually, I don't like these images. Can we start over?"
150
+ AI: Calling restore_from_backups...
151
+ Response: "✓ Restored 8 files from backup. All changes undone."
152
+ ```
153
+
154
+ ---
155
+
156
+ ### 3. `list_backups`
157
+
158
+ **Description**: Show current backup status and details
159
+
160
+ **Input**: None
161
+
162
+ **Output (with pending backups)**:
163
+ ```json
164
+ {
165
+ "hasPendingBackups": true,
166
+ "current": {
167
+ "id": "abc-123-def",
168
+ "createdAt": "2026-01-13T08:00:00Z",
169
+ "markdownFiles": 3,
170
+ "imageFiles": 5,
171
+ "totalFiles": 8,
172
+ "totalSize": 524288,
173
+ "lastRemindedAt": null,
174
+ "needsReminder": false
175
+ },
176
+ "summary": "📸 Backup: abc-123-def\n Created: 2 hours ago\n Files: 3 markdown, 5 images\n Size: 512.00 KB",
177
+ "actions": {
178
+ "approve": "Call approve_changes to keep modifications",
179
+ "restore": "Call restore_from_backups to undo all changes"
180
+ },
181
+ "history": [],
182
+ "backupEnabled": true
183
+ }
184
+ ```
185
+
186
+ **Output (no pending backups)**:
187
+ ```json
188
+ {
189
+ "hasPendingBackups": false,
190
+ "message": "No pending backups",
191
+ "history": [
192
+ {
193
+ "id": "xyz-456-abc",
194
+ "createdAt": "2026-01-12T10:00:00Z",
195
+ "action": "approved",
196
+ "actionAt": "2026-01-12T11:00:00Z",
197
+ "filesCount": 5
198
+ }
199
+ ],
200
+ "backupEnabled": true
201
+ }
202
+ ```
203
+
204
+ **Use Case**: Check if there are pending backups and their details
205
+
206
+ **Example**:
207
+ ```
208
+ User: "Do I have any pending changes to review?"
209
+ AI: Calling list_backups...
210
+ Response: "You have 8 files backed up (3 markdown, 5 images) from 2 hours ago.
211
+ To keep: call approve_changes
212
+ To undo: call restore_from_backups"
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Architecture
218
+
219
+ ### Component Structure
220
+
221
+ ```
222
+ src/
223
+ ├── backup/
224
+ │ └── backup-manager.ts # Core backup logic
225
+ ├── types/
226
+ │ └── backup.ts # Type definitions
227
+ ├── state/
228
+ │ └── state-manager.ts # State persistence (extended)
229
+ └── server/
230
+ └── mcp-server.ts # MCP tools (extended)
231
+ ```
232
+
233
+ ### Class: BackupManager
234
+
235
+ **Location**: `src/backup/backup-manager.ts`
236
+
237
+ **Key Methods**:
238
+
239
+ ```typescript
240
+ class BackupManager {
241
+ // Create backups for specified files
242
+ async createBackup(
243
+ markdownFiles: string[],
244
+ imageFiles: string[]
245
+ ): Promise<BackupResult>
246
+
247
+ // Restore files from backup set
248
+ async restoreFromBackup(
249
+ backupSet: BackupSet
250
+ ): Promise<RestoreResult>
251
+
252
+ // Approve changes (delete backups)
253
+ async approveChanges(
254
+ backupSet: BackupSet
255
+ ): Promise<ApprovalResult>
256
+
257
+ // Check if reminder needed
258
+ shouldRemind(backupSet: BackupSet): boolean
259
+
260
+ // Get human-readable summary
261
+ getBackupSummary(backupSet: BackupSet): string
262
+
263
+ // Verify backup integrity
264
+ async verifyBackup(backupFile: BackupFile): Promise<boolean>
265
+
266
+ // Get/set configuration
267
+ getConfig(): BackupConfig
268
+ setConfig(config: Partial<BackupConfig>): void
269
+ }
270
+ ```
271
+
272
+ ### StateManager Extensions
273
+
274
+ **Added Methods**:
275
+
276
+ ```typescript
277
+ class StateManager {
278
+ // Set current backup set
279
+ setCurrentBackup(backupSet: BackupSet): void
280
+
281
+ // Get current backup set
282
+ getCurrentBackup(): BackupSet | null
283
+
284
+ // Clear backup after approval/restore
285
+ clearCurrentBackup(action: 'approved' | 'restored'): void
286
+
287
+ // Update reminder timestamp
288
+ updateBackupReminder(): void
289
+
290
+ // Check for pending backups
291
+ hasPendingBackups(): boolean
292
+
293
+ // Get backup history
294
+ getBackupHistory(): Array<...>
295
+ }
296
+ ```
297
+
298
+ ### Type Definitions
299
+
300
+ **Location**: `src/types/backup.ts`
301
+
302
+ **Key Types**:
303
+
304
+ ```typescript
305
+ interface BackupFile {
306
+ originalPath: string;
307
+ backupPath: string;
308
+ timestamp: string;
309
+ size: number;
310
+ type: 'markdown' | 'image';
311
+ hash: string;
312
+ }
313
+
314
+ interface BackupSet {
315
+ id: string;
316
+ createdAt: string;
317
+ lastRemindedAt?: string;
318
+ markdownFiles: BackupFile[];
319
+ imageFiles: BackupFile[];
320
+ totalFiles: number;
321
+ totalSize: number;
322
+ approved: boolean;
323
+ sessionId?: string;
324
+ }
325
+
326
+ interface BackupState {
327
+ current: BackupSet | null;
328
+ history: Array<{
329
+ id: string;
330
+ createdAt: string;
331
+ action: 'approved' | 'restored';
332
+ actionAt: string;
333
+ filesCount: number;
334
+ }>;
335
+ }
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Workflow Integration
341
+
342
+ ### When Backups Are Created
343
+
344
+ Backups are created automatically when:
345
+
346
+ 1. **Before markdown modification**: When updating markdown files with image references
347
+ 2. **After image generation**: When new images are created
348
+
349
+ ### Example Workflow
350
+
351
+ ```typescript
352
+ // 1. User starts workflow
353
+ await workflowOrchestrator.start();
354
+
355
+ // 2. Generate images
356
+ const images = await generateImages(specs);
357
+
358
+ // 3. CREATE BACKUP (automatic)
359
+ const backupResult = await backupManager.createBackup(
360
+ ['docs/README.md'],
361
+ images.map(img => img.path)
362
+ );
363
+
364
+ // 4. Store backup in state
365
+ stateManager.setCurrentBackup(backupResult.backupSet);
366
+ await stateManager.save();
367
+
368
+ // 5. Modify markdown files
369
+ await updateMarkdownFiles(images);
370
+
371
+ // 6. User reviews changes
372
+ // ... user can approve or restore ...
373
+ ```
374
+
375
+ ---
376
+
377
+ ## Backup File Format
378
+
379
+ ### Backup Extension
380
+
381
+ All backups use the `.vf-bak` extension:
382
+
383
+ ```
384
+ original-file.md → original-file.md.vf-bak
385
+ diagram-001.png → diagram-001.png.vf-bak
386
+ ```
387
+
388
+ ### Backup Location
389
+
390
+ Backups are stored **alongside original files**:
391
+
392
+ ```
393
+ project/
394
+ ├── docs/
395
+ │ ├── README.md
396
+ │ └── README.md.vf-bak ← Backup
397
+ ├── generated-images/
398
+ │ ├── diagram-001.png
399
+ │ └── diagram-001.png.vf-bak ← Backup
400
+ ```
401
+
402
+ This ensures:
403
+ - ✅ Backups stay with their files
404
+ - ✅ Easy to find and manage
405
+ - ✅ Works with any directory structure
406
+
407
+ ---
408
+
409
+ ## Integrity Verification
410
+
411
+ ### MD5 Hash Verification
412
+
413
+ Every backup includes an MD5 hash of the original file:
414
+
415
+ ```typescript
416
+ {
417
+ originalPath: "docs/README.md",
418
+ backupPath: "docs/README.md.vf-bak",
419
+ hash: "5d41402abc4b2a76b9719d911017c592"
420
+ }
421
+ ```
422
+
423
+ **When restoring:**
424
+ 1. Read backup file
425
+ 2. Calculate MD5 hash
426
+ 3. Compare with stored hash
427
+ 4. Warn if mismatch (file modified after backup)
428
+
429
+ ### Atomic Operations
430
+
431
+ **Backup Creation**:
432
+ 1. Read original file
433
+ 2. Calculate hash
434
+ 3. Copy to `.vf-bak`
435
+ 4. Verify copy successful
436
+ 5. Store in state
437
+
438
+ **Restoration**:
439
+ 1. Verify backup exists
440
+ 2. Verify backup integrity (hash)
441
+ 3. Copy backup → original
442
+ 4. Delete backup file
443
+ 5. Update state
444
+
445
+ ---
446
+
447
+ ## 24-Hour Reminder System
448
+
449
+ ### How Reminders Work
450
+
451
+ 1. Backup created at `T0`
452
+ 2. User calls `list_backups` at `T0 + 25 hours`
453
+ 3. System detects 24 hours passed
454
+ 4. Sets `needsReminder: true` in response
455
+ 5. Updates `lastRemindedAt` timestamp
456
+ 6. Next reminder at `T0 + 49 hours`
457
+
458
+ ### Reminder Logic
459
+
460
+ ```typescript
461
+ shouldRemind(backupSet: BackupSet): boolean {
462
+ const now = Date.now();
463
+ const createdAt = new Date(backupSet.createdAt).getTime();
464
+ const lastRemindedAt = backupSet.lastRemindedAt
465
+ ? new Date(backupSet.lastRemindedAt).getTime()
466
+ : createdAt;
467
+
468
+ const hoursSinceLastReminder =
469
+ (now - lastRemindedAt) / (1000 * 60 * 60);
470
+
471
+ return hoursSinceLastReminder >= 24;
472
+ }
473
+ ```
474
+
475
+ ### Reminder Message Example
476
+
477
+ ```
478
+ ⏰ Reminder: You have unapproved changes (created 24 hours ago)
479
+ - 3 markdown files backed up
480
+ - 5 images backed up
481
+
482
+ Actions:
483
+ - approve_changes → Keep changes, delete backups
484
+ - restore_from_backups → Undo all changes
485
+ ```
486
+
487
+ ---
488
+
489
+ ## Error Handling
490
+
491
+ ### Backup Creation Failures
492
+
493
+ ```typescript
494
+ {
495
+ success: false,
496
+ filesBackedUp: 0,
497
+ error: "Failed to read file: docs/README.md"
498
+ }
499
+ ```
500
+
501
+ **Cause**: File permissions, missing file, disk full
502
+
503
+ **Resolution**: Check file exists, fix permissions, free disk space
504
+
505
+ ### Restore Failures
506
+
507
+ ```typescript
508
+ {
509
+ success: false,
510
+ filesRestored: 2,
511
+ errors: [
512
+ {
513
+ file: "docs/GUIDE.md",
514
+ error: "Backup file not found"
515
+ }
516
+ ]
517
+ }
518
+ ```
519
+
520
+ **Cause**: Backup file deleted manually, corrupted
521
+
522
+ **Resolution**: Partial restore succeeded, review errors
523
+
524
+ ### Approval Failures
525
+
526
+ ```typescript
527
+ {
528
+ success: false,
529
+ filesDeleted: 3,
530
+ errors: [
531
+ {
532
+ file: "docs/README.md.vf-bak",
533
+ error: "Permission denied"
534
+ }
535
+ ]
536
+ }
537
+ ```
538
+
539
+ **Cause**: File permissions, file in use
540
+
541
+ **Resolution**: Fix permissions, close files
542
+
543
+ ---
544
+
545
+ ## Best Practices
546
+
547
+ ### For Users
548
+
549
+ 1. **Review regularly**: Check `list_backups` to see pending changes
550
+ 2. **Approve or restore**: Don't leave backups pending indefinitely
551
+ 3. **Keep enabled**: Leave `VF_BACKUP_ENABLED=true` for safety
552
+ 4. **Check reminders**: Respond to 24-hour reminder notifications
553
+
554
+ ### For Developers
555
+
556
+ 1. **Always create backups**: Before any file modification
557
+ 2. **Store in state**: Use StateManager to track backups
558
+ 3. **Handle errors**: Catch backup/restore errors gracefully
559
+ 4. **Verify integrity**: Check MD5 hashes on restore
560
+ 5. **Clean up**: Delete backups after approval/restore
561
+
562
+ ---
563
+
564
+ ## Testing
565
+
566
+ ### Manual Testing
567
+
568
+ ```bash
569
+ # 1. Generate images (creates backups)
570
+ # User: "Generate diagrams for docs/README.md"
571
+
572
+ # 2. List backups
573
+ # User: "Show me the backup status"
574
+ # AI calls: list_backups
575
+
576
+ # 3. Restore changes
577
+ # User: "I don't like these, restore original"
578
+ # AI calls: restore_from_backups
579
+
580
+ # 4. Generate again and approve
581
+ # User: "These look great, keep them"
582
+ # AI calls: approve_changes
583
+ ```
584
+
585
+ ### Automated Testing
586
+
587
+ ```bash
588
+ # Run backup tests
589
+ npm test test/backup/
590
+
591
+ # Test scenarios:
592
+ # - Backup creation
593
+ # - Backup restoration
594
+ # - Approval workflow
595
+ # - Integrity verification
596
+ # - Reminder system
597
+ ```
598
+
599
+ ---
600
+
601
+ ## Troubleshooting
602
+
603
+ ### Issue: Backups not created
604
+
605
+ **Check**:
606
+ ```bash
607
+ # Verify enabled
608
+ echo $VF_BACKUP_ENABLED # Should be "true" or empty (default true)
609
+
610
+ # Check logs
611
+ tail -f ~/.visual-forge-mcp/logs/visual-forge.log
612
+ ```
613
+
614
+ ### Issue: Cannot restore backups
615
+
616
+ **Check**:
617
+ ```bash
618
+ # Verify backup files exist
619
+ ls -la docs/*.vf-bak
620
+
621
+ # Check file permissions
622
+ chmod 644 docs/*.vf-bak
623
+ ```
624
+
625
+ ### Issue: Backup files remain after approval
626
+
627
+ **Manually clean**:
628
+ ```bash
629
+ # Remove all backup files
630
+ find . -name "*.vf-bak" -delete
631
+
632
+ # Clear state
633
+ rm ~/.visual-forge-mcp/state.json
634
+ ```
635
+
636
+ ---
637
+
638
+ ## Future Enhancements
639
+
640
+ ### Planned Features
641
+
642
+ 1. **Compression**: Compress backup files to save space
643
+ 2. **Retention policy**: Auto-delete old backups after N days
644
+ 3. **Selective restore**: Restore individual files instead of all
645
+ 4. **Backup directory**: Store backups in centralized location
646
+ 5. **Backup metadata**: Include generation parameters in backup
647
+ 6. **Version history**: Track multiple versions with rollback
648
+
649
+ ### Integration Points
650
+
651
+ 1. **WorkflowOrchestrator**: Auto-create backups before markdown modification
652
+ 2. **MarkdownParser**: Include backup info in parsed output
653
+ 3. **Image generators**: Auto-backup generated images
654
+ 4. **CLI tool**: Add `vf backup` commands for manual management
655
+
656
+ ---
657
+
658
+ ## Summary
659
+
660
+ The backup system provides:
661
+
662
+ ✅ **Safety**: Never lose work, always reversible
663
+ ✅ **Transparency**: Automatic, no user action needed
664
+ ✅ **Control**: User decides when to approve/restore
665
+ ✅ **Persistence**: Survives session restarts
666
+ ✅ **Integrity**: MD5 verification ensures correctness
667
+ ✅ **Flexibility**: Enable/disable via environment variable
668
+
669
+ **Configuration**: `VF_BACKUP_ENABLED=true` (default)
670
+ **MCP Tools**: `approve_changes`, `restore_from_backups`, `list_backups`
671
+ **Storage**: `.vf-bak` files alongside originals
672
+ **State**: Tracked in `~/.visual-forge-mcp/state.json`
673
+
674
+ ---
675
+
676
+ ## References
677
+
678
+ - **Implementation**: `src/backup/backup-manager.ts`
679
+ - **Types**: `src/types/backup.ts`
680
+ - **State**: `src/state/state-manager.ts`
681
+ - **MCP Tools**: `src/server/mcp-server.ts`
682
+ - **Tests**: `test/backup/` (coming soon)
683
+
684
+ ---
685
+
686
+ **Last Updated**: 2026-01-13
687
+ **Version**: 1.0.0
688
+ **Status**: ✅ Implemented