@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.
- package/CHANGELOG.md +814 -0
- package/dist/types/generation.d.ts +7 -1
- package/dist/types/generation.d.ts.map +1 -1
- package/dist/utils/image-optimizer.d.ts +91 -0
- package/dist/utils/image-optimizer.d.ts.map +1 -0
- package/dist/utils/image-optimizer.js +241 -0
- package/dist/utils/image-optimizer.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/workflow/workflow-orchestrator.d.ts.map +1 -1
- package/dist/workflow/workflow-orchestrator.js +34 -1
- package/dist/workflow/workflow-orchestrator.js.map +1 -1
- package/dist/workflow/workflow-tools.d.ts.map +1 -1
- package/dist/workflow/workflow-tools.js +8 -22
- package/dist/workflow/workflow-tools.js.map +1 -1
- package/docs/guides/README.md +24 -0
- package/docs/guides/backup-system-flow.md +511 -0
- package/docs/guides/backup-system.md +688 -0
- package/docs/guides/development-testing.md +338 -0
- package/docs/guides/html-support.md +548 -0
- package/docs/guides/image-optimization.md +370 -0
- package/docs/guides/testing.md +279 -0
- package/docs/guides/usage-examples.md +101 -0
- package/docs/guides/vf-workflow.md +112 -0
- package/docs/guides/workflow-with-backups.md +471 -0
- package/package.json +15 -3
- package/dist/.gitkeep +0 -0
|
@@ -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
|