cursor-guard 2.1.1 → 4.0.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/README.md +69 -11
- package/README.zh-CN.md +351 -293
- package/ROADMAP.md +1040 -0
- package/SKILL.md +631 -557
- package/package.json +14 -5
- package/references/config-reference.md +215 -175
- package/references/config-reference.zh-CN.md +215 -175
- package/references/cursor-guard.example.json +6 -6
- package/references/cursor-guard.schema.json +30 -0
- package/references/lib/auto-backup.js +315 -530
- package/references/lib/core/anomaly.js +217 -0
- package/references/lib/core/backups.js +357 -0
- package/references/lib/core/core.test.js +1459 -0
- package/references/lib/core/dashboard.js +208 -0
- package/references/lib/core/doctor-fix.js +237 -0
- package/references/lib/core/doctor.js +248 -0
- package/references/lib/core/restore.js +360 -0
- package/references/lib/core/snapshot.js +198 -0
- package/references/lib/core/status.js +163 -0
- package/references/lib/guard-doctor.js +46 -238
- package/references/lib/utils.js +438 -371
- package/references/mcp/mcp.test.js +374 -0
- package/references/mcp/server.js +252 -0
- package/references/quickstart.zh-CN.md +364 -0
package/SKILL.md
CHANGED
|
@@ -1,557 +1,631 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: cursor-guard
|
|
3
|
-
description: >-
|
|
4
|
-
Protects code from accidental AI overwrite or deletion in Cursor: mandatory
|
|
5
|
-
pre-write snapshots, review-before-apply, local Git safety net, and
|
|
6
|
-
deterministic recovery. Trigger on code loss, rollback, checkpoints,
|
|
7
|
-
Timeline/local history, tool vs editor saves, multi-root workspaces, or safe
|
|
8
|
-
AI editing workflows (including Chinese phrases like 回滚, 误删, 丢版本).
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Cursor Guard — Strong Protection Mode
|
|
12
|
-
|
|
13
|
-
## When This Skill Applies (Triggers)
|
|
14
|
-
|
|
15
|
-
Use this skill when any of the following appear:
|
|
16
|
-
|
|
17
|
-
- **Auto disk writes**: Agent/tools edit files without the user reviewing a diff first.
|
|
18
|
-
- **Deletes or renames**: Bulk delete, `rm`, refactor that removes paths.
|
|
19
|
-
- **History confusion**: Checkpoints missing, Timeline/local history not rolling back, "save failed" after external writes.
|
|
20
|
-
- **Parallel context**: Multiple repos or branches; unclear which folder is the workspace root.
|
|
21
|
-
- **Recovery asks**: e.g. "改不回来", "丢版本", "回滚", "reflog", "误删", or English equivalents.
|
|
22
|
-
- **Time/version recovery**: e.g. "恢复到5分钟前", "恢复到前3个版本", "回到上一个版本", "restore to 10 minutes ago", "go back 2 versions", "恢复到下午3点的状态".
|
|
23
|
-
- **Health check**: e.g. "guard doctor", "检查备份配置", "自检", "诊断guard", "check guard setup".
|
|
24
|
-
|
|
25
|
-
If
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
**
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
##
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
**
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
#
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
If
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
git
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
-
|
|
480
|
-
-
|
|
481
|
-
-
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
-
|
|
532
|
-
-
|
|
533
|
-
-
|
|
534
|
-
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
1
|
+
---
|
|
2
|
+
name: cursor-guard
|
|
3
|
+
description: >-
|
|
4
|
+
Protects code from accidental AI overwrite or deletion in Cursor: mandatory
|
|
5
|
+
pre-write snapshots, review-before-apply, local Git safety net, and
|
|
6
|
+
deterministic recovery. Trigger on code loss, rollback, checkpoints,
|
|
7
|
+
Timeline/local history, tool vs editor saves, multi-root workspaces, or safe
|
|
8
|
+
AI editing workflows (including Chinese phrases like 回滚, 误删, 丢版本).
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Cursor Guard — Strong Protection Mode
|
|
12
|
+
|
|
13
|
+
## When This Skill Applies (Triggers)
|
|
14
|
+
|
|
15
|
+
Use this skill when any of the following appear:
|
|
16
|
+
|
|
17
|
+
- **Auto disk writes**: Agent/tools edit files without the user reviewing a diff first.
|
|
18
|
+
- **Deletes or renames**: Bulk delete, `rm`, refactor that removes paths.
|
|
19
|
+
- **History confusion**: Checkpoints missing, Timeline/local history not rolling back, "save failed" after external writes.
|
|
20
|
+
- **Parallel context**: Multiple repos or branches; unclear which folder is the workspace root.
|
|
21
|
+
- **Recovery asks**: e.g. "改不回来", "丢版本", "回滚", "reflog", "误删", or English equivalents.
|
|
22
|
+
- **Time/version recovery**: e.g. "恢复到5分钟前", "恢复到前3个版本", "回到上一个版本", "restore to 10 minutes ago", "go back 2 versions", "恢复到下午3点的状态".
|
|
23
|
+
- **Health check**: e.g. "guard doctor", "检查备份配置", "自检", "诊断guard", "check guard setup", "MCP 能用吗". If MCP `doctor` tool is available, call `doctor { "path": "<project>" }` and format the result; otherwise run `guard-doctor.ps1` and report results. Doctor output includes an "MCP server" check (SDK installed + server.js present). If doctor reports FAIL items, suggest running `doctor_fix` (MCP) or guide the user through manual fixes.
|
|
24
|
+
- **Auto-fix**: e.g. "guard fix", "修复配置", "自动修复". If MCP `doctor_fix` tool is available, call `doctor_fix { "path": "<project>", "dry_run": true }` first to preview, then `doctor_fix { "path": "<project>" }` to apply. Without MCP, guide the user through manual steps based on doctor output.
|
|
25
|
+
- **Backup status**: e.g. "备份状态", "guard status", "watcher 在跑吗", "最近一次备份". If MCP `backup_status` tool is available, call `backup_status { "path": "<project>" }` and format the structured result for the user (watcher running/stale, last backup time, strategy, ref counts, disk). Without MCP, check lock file existence and `git log` manually.
|
|
26
|
+
- **Health dashboard**: e.g. "看板", "dashboard", "健康状态", "备份总览", "guard 概况". If MCP `dashboard` tool is available, call `dashboard { "path": "<project>" }` and present the structured dashboard (strategy, last backup, counts, disk usage, protection scope, health status, alerts). Format as a clear summary for the user.
|
|
27
|
+
- **Alert check**: e.g. "有告警吗", "alert status", "变更异常", "风险提示". If MCP `alert_status` tool is available, call `alert_status { "path": "<project>" }` to check for active change-velocity alerts. Report whether an alert is active and its details.
|
|
28
|
+
|
|
29
|
+
If none of the above, do not expand scope; answer normally.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 0. Load Project Config (If Exists)
|
|
34
|
+
|
|
35
|
+
On first trigger in a session, check if the workspace root contains `.cursor-guard.json`. If found, **read it** and apply throughout:
|
|
36
|
+
|
|
37
|
+
```jsonc
|
|
38
|
+
{
|
|
39
|
+
"protect": ["src/**", "lib/**", "package.json"],
|
|
40
|
+
"ignore": ["node_modules/**", "dist/**", "*.log"],
|
|
41
|
+
|
|
42
|
+
// "git": auto-backup to a dedicated branch (default)
|
|
43
|
+
// "shadow": file copies to .cursor-guard-backup/<timestamp>/
|
|
44
|
+
// "both": git branch snapshot + shadow copies
|
|
45
|
+
"backup_strategy": "git",
|
|
46
|
+
"auto_backup_interval_seconds": 60,
|
|
47
|
+
|
|
48
|
+
// Sensitive file patterns — auto-excluded from backup even if in protect scope.
|
|
49
|
+
// Built-in defaults: .env, .env.*, *.key, *.pem, *.p12, *.pfx, credentials*
|
|
50
|
+
"secrets_patterns": [".env", ".env.*", "*.key", "*.pem"],
|
|
51
|
+
|
|
52
|
+
// Controls behavior before restore operations.
|
|
53
|
+
// "always" (default): automatically preserve current version before every restore.
|
|
54
|
+
// "ask": prompt the user each time to decide.
|
|
55
|
+
// "never": skip preservation entirely (not recommended).
|
|
56
|
+
"pre_restore_backup": "always",
|
|
57
|
+
|
|
58
|
+
// Retention for shadow copies. mode: "days" | "count" | "size"
|
|
59
|
+
"retention": { "mode": "days", "days": 30, "max_count": 100, "max_size_mb": 500 },
|
|
60
|
+
|
|
61
|
+
// Retention for Git auto-backup branch. Disabled by default.
|
|
62
|
+
// "count": keep N newest commits. "days": keep commits from last N days.
|
|
63
|
+
"git_retention": { "enabled": false, "mode": "count", "max_count": 200 },
|
|
64
|
+
|
|
65
|
+
// V4: Proactive change-velocity detection (default: on).
|
|
66
|
+
// When enabled, the watcher monitors file change frequency and raises
|
|
67
|
+
// alerts when abnormal patterns are detected (e.g. 20+ files in 10s).
|
|
68
|
+
"proactive_alert": true,
|
|
69
|
+
"alert_thresholds": {
|
|
70
|
+
"files_per_window": 20, // trigger threshold
|
|
71
|
+
"window_seconds": 10, // sliding window
|
|
72
|
+
"cooldown_seconds": 60 // min gap between alerts
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Resolution rules:**
|
|
78
|
+
- `protect` set + `ignore` set → file must match a `protect` pattern AND not match any `ignore` pattern.
|
|
79
|
+
- Only `protect` set → only matching files are protected.
|
|
80
|
+
- Only `ignore` set → everything is protected except matching files.
|
|
81
|
+
- Neither set → protect everything (same as before).
|
|
82
|
+
|
|
83
|
+
**`secrets_patterns`**: Glob patterns for sensitive files (`.env`, keys, certificates). Matching files are **auto-excluded** from backup commits, even within `protect` scope. Built-in defaults: `.env`, `.env.*`, `*.key`, `*.pem`, `*.p12`, `*.pfx`, `credentials*`. Set this field to override.
|
|
84
|
+
|
|
85
|
+
**`retention`**: Controls automatic cleanup of old shadow-copy snapshots in `.cursor-guard-backup/`:
|
|
86
|
+
- `"days"` (default): keep snapshots from the last N days (default **30**).
|
|
87
|
+
- `"count"`: keep the N most recent snapshots (default 100).
|
|
88
|
+
- `"size"`: keep total shadow-copy folder under N MB (default 500).
|
|
89
|
+
|
|
90
|
+
**If no config file exists**, the agent operates in "protect everything" mode (backward compatible). Mention to the user that they can create `.cursor-guard.json` to narrow scope — see [references/cursor-guard.example.json](references/cursor-guard.example.json).
|
|
91
|
+
|
|
92
|
+
### 0a. Execution Path: MCP vs Shell
|
|
93
|
+
|
|
94
|
+
cursor-guard provides an **MCP server** (`cursor-guard-mcp`) as an optional enhancement. When available, prefer MCP tool calls over shell commands — they are faster, return structured JSON, and consume fewer tokens.
|
|
95
|
+
|
|
96
|
+
**Detection**: at the start of a session, check if the following MCP tools are available in your tool list: `doctor`, `list_backups`, `snapshot_now`, `restore_file`, `restore_project`, `dashboard`, `alert_status`. If **any** of them exists, use MCP for that operation; otherwise, fall back to shell commands as described in the sections below.
|
|
97
|
+
|
|
98
|
+
**Routing table** (MCP tool → replaces which shell workflow):
|
|
99
|
+
|
|
100
|
+
| Operation | MCP tool | Shell fallback section |
|
|
101
|
+
|-----------|----------|----------------------|
|
|
102
|
+
| Health check / diagnostics | `doctor` | guard-doctor.ps1 / .sh |
|
|
103
|
+
| Auto-fix common issues | `doctor_fix` | manual steps per doctor output |
|
|
104
|
+
| Backup system status | `backup_status` | manual: check lock file + git log + shadow dir |
|
|
105
|
+
| Pre-write snapshot | `snapshot_now` | §2a plumbing commands |
|
|
106
|
+
| List restore points | `list_backups` | §5a Step 2 git log |
|
|
107
|
+
| Restore single file | `restore_file` | §5a Step 5 git restore |
|
|
108
|
+
| Preview project restore | `restore_project` (preview=true) | §5a Step 5 git diff |
|
|
109
|
+
| Execute project restore | `restore_project` (preview=false) | §5a Step 5 git restore -- . |
|
|
110
|
+
| Backup health dashboard | `dashboard` | manual: combine backup_status + git/shadow stats |
|
|
111
|
+
| Change-velocity alerts | `alert_status` | manual: check alert file in .git/ or .cursor-guard-backup/ |
|
|
112
|
+
|
|
113
|
+
**Rules**:
|
|
114
|
+
- MCP results are JSON — parse `status`, `error`, and data fields; do not re-run shell to verify.
|
|
115
|
+
- If an MCP call returns an `error` field, report it to the user and fall back to the shell path for that operation.
|
|
116
|
+
- All Hard Rules (§Hard Rules) still apply regardless of execution path. MCP tools enforce them internally (e.g. `restore_file` creates a pre-restore snapshot by default).
|
|
117
|
+
- If MCP is not configured, the skill works exactly as before — **no degradation**.
|
|
118
|
+
- `doctor_fix` is safe to call — each fix is idempotent. Use `dry_run: true` to preview changes before applying. Typical fixes: create missing config, init git repo, gitignore backup dir, remove stale lock file.
|
|
119
|
+
- `restore_project` with `preview: false` executes a full restore including pre-restore snapshot. Always call with `preview: true` first, show the result to the user, and only execute after explicit confirmation.
|
|
120
|
+
|
|
121
|
+
When the target file of an edit **falls outside the protected scope**, the agent:
|
|
122
|
+
- Still applies "Read before Write" (Hard Rule §2).
|
|
123
|
+
- Skips the mandatory git snapshot / shadow copy step.
|
|
124
|
+
- Notes `outside protection scope` in the status block.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 1. Assess Risk (First)
|
|
129
|
+
|
|
130
|
+
| Signal | Risk |
|
|
131
|
+
|--------|------|
|
|
132
|
+
| Multi-file edits, `delete_file`, terminal `rm`, or **Write** to existing file | **High** |
|
|
133
|
+
| Single small edit (`StrReplace` with narrow scope), user explicitly asked | **Medium** |
|
|
134
|
+
| Read-only explanation, no writes | **Low** |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 2. Mandatory Pre-Write Backup Protocol (ENFORCED)
|
|
139
|
+
|
|
140
|
+
> **This is not optional.** The agent MUST execute these steps before making
|
|
141
|
+
> destructive or high-risk changes. Skipping is only allowed when the user
|
|
142
|
+
> explicitly says "不用备份" / "skip backup".
|
|
143
|
+
|
|
144
|
+
### 2a. If workspace IS a Git repo
|
|
145
|
+
|
|
146
|
+
**Before any High-risk operation on a protected file:**
|
|
147
|
+
|
|
148
|
+
> **MCP shortcut**: if `snapshot_now` tool is available, call it with `{ "path": "<project>", "strategy": "git" }` instead of the shell commands below. The tool handles temp index, secrets exclusion, and ref creation internally, and returns `{ "git": { "status": "created", "commitHash": "...", "shortHash": "..." } }`. Report the `shortHash` to the user and proceed.
|
|
149
|
+
|
|
150
|
+
Use a **temporary index and dedicated ref** so the user's staged/unstaged state is never touched:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
GIT_DIR=$(git rev-parse --git-dir)
|
|
154
|
+
GUARD_IDX="$GIT_DIR/guard-snapshot-index"
|
|
155
|
+
|
|
156
|
+
# 1. Create temp index from HEAD
|
|
157
|
+
GIT_INDEX_FILE="$GUARD_IDX" git read-tree HEAD
|
|
158
|
+
|
|
159
|
+
# 2. Stage working-tree files into temp index
|
|
160
|
+
GIT_INDEX_FILE="$GUARD_IDX" git add -A
|
|
161
|
+
|
|
162
|
+
# 3. Write tree and create commit on a guard ref (not on the user's branch)
|
|
163
|
+
TREE=$(GIT_INDEX_FILE="$GUARD_IDX" git write-tree)
|
|
164
|
+
COMMIT=$(git commit-tree "$TREE" -p HEAD -m "guard: snapshot before ai edit")
|
|
165
|
+
git update-ref refs/guard/snapshot "$COMMIT"
|
|
166
|
+
|
|
167
|
+
# 4. Cleanup
|
|
168
|
+
rm -f "$GUARD_IDX"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**PowerShell equivalent** (for agent Shell calls):
|
|
172
|
+
|
|
173
|
+
```powershell
|
|
174
|
+
$guardIdx = Join-Path (git rev-parse --git-dir) "guard-snapshot-index"
|
|
175
|
+
$env:GIT_INDEX_FILE = $guardIdx
|
|
176
|
+
git read-tree HEAD
|
|
177
|
+
git add -A
|
|
178
|
+
$tree = git write-tree
|
|
179
|
+
$env:GIT_INDEX_FILE = $null
|
|
180
|
+
Remove-Item $guardIdx -Force -ErrorAction SilentlyContinue
|
|
181
|
+
$commit = git commit-tree $tree -p HEAD -m "guard: snapshot before ai edit"
|
|
182
|
+
git update-ref refs/guard/snapshot $commit
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- Run this via Shell tool BEFORE the first Write / StrReplace / Delete call.
|
|
186
|
+
- The user's index (staged files) and current branch are **never modified**.
|
|
187
|
+
- If `.cursor-guard.json` exists with `protect` patterns, scope `git add` to those paths instead of `-A`.
|
|
188
|
+
- Record the commit hash (short) and report it to the user.
|
|
189
|
+
- To restore: `git restore --source=refs/guard/snapshot -- <file>`.
|
|
190
|
+
- Before writing the tree, check staged files against `secrets_patterns` (§0). Exclude any matches and warn the user.
|
|
191
|
+
|
|
192
|
+
**Simplified fallback**: If the plumbing approach fails (e.g. `commit-tree` not available), the agent MAY fall back to `git stash push -m "guard: snapshot" --keep-index` + `git stash pop` to shelter and restore the user's state. Report which method was used in the status block.
|
|
193
|
+
|
|
194
|
+
**Before any Medium-risk operation:**
|
|
195
|
+
|
|
196
|
+
- At minimum, run `git diff -- <target_file>` and `git status` so the user sees current state.
|
|
197
|
+
- Recommend a snapshot commit; proceed without it only if the user confirms.
|
|
198
|
+
|
|
199
|
+
### 2b. If workspace is NOT a Git repo
|
|
200
|
+
|
|
201
|
+
**Before any High-risk operation, offer TWO options (pick one):**
|
|
202
|
+
|
|
203
|
+
1. **Quick git init** (preferred):
|
|
204
|
+
```
|
|
205
|
+
git init && git add -A && git commit -m "guard: initial snapshot" --no-verify
|
|
206
|
+
```
|
|
207
|
+
2. **Shadow copy** (fallback if user declines git):
|
|
208
|
+
- Copy the target file(s) to `.cursor-guard-backup/<timestamp>/` via Shell.
|
|
209
|
+
- Example:
|
|
210
|
+
```powershell
|
|
211
|
+
$ts = Get-Date -Format 'yyyyMMdd_HHmmss'
|
|
212
|
+
New-Item -ItemType Directory -Force ".cursor-guard-backup/$ts"
|
|
213
|
+
Copy-Item "src/app.py" ".cursor-guard-backup/$ts/app.py"
|
|
214
|
+
```
|
|
215
|
+
- Add `.cursor-guard-backup/` to `.gitignore` if git is later initialized.
|
|
216
|
+
|
|
217
|
+
**If user declines BOTH:** document refusal in the status block (§6), state the file cannot be recovered if lost, and proceed only with explicit "我了解风险,继续" confirmation.
|
|
218
|
+
|
|
219
|
+
### 2c. Multi-file batch operations
|
|
220
|
+
|
|
221
|
+
When editing 3+ files in one task:
|
|
222
|
+
|
|
223
|
+
1. Create the snapshot commit covering ALL files first.
|
|
224
|
+
2. Apply changes file-by-file; if any step fails, offer to `git restore` all files back to the snapshot.
|
|
225
|
+
3. After all edits succeed, offer a clean commit with a real message.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 3. Protection Strategy During Edits
|
|
230
|
+
|
|
231
|
+
**Before applying AI changes:**
|
|
232
|
+
|
|
233
|
+
1. **Preview**: Show a clear **diff-style summary** (paths + intent). For substantial edits, prefer patch-sized chunks.
|
|
234
|
+
2. **Destructive ops**: For deletes or large rewrites, **confirm explicitly** (one short question). Do not assume "cleanup" permission.
|
|
235
|
+
3. **Workspace root**: State which directory is treated as project root; avoid touching paths outside it unless the user asked.
|
|
236
|
+
4. **Read before Write**: The agent MUST Read a file's current content before using Write to overwrite it. This ensures the full original content is captured in conversation context as a last-resort recovery source.
|
|
237
|
+
5. **Rename / Move**: Treat renames and moves as a delete + create. Snapshot the original path before proceeding; note both old and new paths in the status block so history can be traced.
|
|
238
|
+
|
|
239
|
+
**After tool writes (agent wrote to disk directly):**
|
|
240
|
+
|
|
241
|
+
- Tell the user: editor buffer may be stale → **`Revert File`** (Ctrl+Shift+P → "Revert File") or close & reopen tab.
|
|
242
|
+
- Do **not** claim Timeline/Checkpoints will capture tool writes.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 4. Backup Strategy (Priority)
|
|
247
|
+
|
|
248
|
+
There are two distinct backup mechanisms. Do not confuse them:
|
|
249
|
+
|
|
250
|
+
| | **Git branch snapshot** | **Shadow copy** |
|
|
251
|
+
|---|---|---|
|
|
252
|
+
| **What** | Commits to `refs/guard/auto-backup` via plumbing | File copies to `.cursor-guard-backup/<timestamp>/` |
|
|
253
|
+
| **Who creates** | Auto-backup script (when `backup_strategy` = `git` or `both`) | Auto-backup script (when `backup_strategy` = `shadow` or `both`); or the agent manually (§2b) |
|
|
254
|
+
| **Who cleans up** | `git_retention` config (auto, opt-in); or manual `git branch -D` | `retention` config (auto); or manual |
|
|
255
|
+
| **Restore** | `git restore --source=guard/auto-backup -- <file>` | Copy file from `.cursor-guard-backup/<ts>/<file>` to original path |
|
|
256
|
+
| **Requires Git** | Yes | No (fallback for non-git repos) |
|
|
257
|
+
|
|
258
|
+
**Priority order for the agent:**
|
|
259
|
+
|
|
260
|
+
1. **Guard ref snapshot** (`refs/guard/snapshot`) — agent creates before each high-risk edit using temp index (§2a). Does not pollute user's branch or staging area.
|
|
261
|
+
2. **Git auto-backup ref** (`refs/guard/auto-backup`) — periodic snapshots by auto-backup script. Lives outside `refs/heads/` so `git push --all` won't push it.
|
|
262
|
+
3. **Shadow copy** (`.cursor-guard-backup/`) — fallback for non-git repos, or as extra insurance when `backup_strategy = "both"`.
|
|
263
|
+
4. **Editor habits** — Ctrl+S frequently; optional extensions are user-configured, mention only if asked.
|
|
264
|
+
|
|
265
|
+
**Hard default:** Do NOT `git push` unless the user explicitly asks. Scope = **local only**.
|
|
266
|
+
|
|
267
|
+
**Retention:**
|
|
268
|
+
- **Shadow copies**: controlled by `retention` in `.cursor-guard.json` (mode: days/count/size).
|
|
269
|
+
- **Git branch**: controlled by `git_retention` in `.cursor-guard.json` (disabled by default; enable with `"enabled": true`, mode: count/days). Safely rebuilds the backup branch as an orphan chain containing only kept snapshots — never touches user history. Run `git gc` to reclaim disk space.
|
|
270
|
+
- See [references/config-reference.md](references/config-reference.md) for full field docs.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 5. Recovery Strategy (Priority Order)
|
|
275
|
+
|
|
276
|
+
1. **Git**: `git status` → `git diff` → `git restore` → `git reset` → `git reflog` — see [references/recovery.md](references/recovery.md).
|
|
277
|
+
2. **Shadow copies**: Check `.cursor-guard-backup/` for timestamped copies.
|
|
278
|
+
3. **Conversation context**: If the agent Read the file before overwriting, the original content is in this chat — offer to re-write it back.
|
|
279
|
+
4. **Editor Local History / Timeline**: auxiliary, per-file; unreliable for tool-only disk writes.
|
|
280
|
+
5. **Cursor Checkpoints**: auxiliary; tied to Agent UI; not a long-term backup.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## 5a. Time-Based & Version-Based Recovery
|
|
285
|
+
|
|
286
|
+
When the user requests recovery using time or version references, follow this workflow:
|
|
287
|
+
|
|
288
|
+
### Trigger Phrases (Chinese & English)
|
|
289
|
+
|
|
290
|
+
| Pattern | Type | Example |
|
|
291
|
+
|---------|------|---------|
|
|
292
|
+
| "恢复到 N 分钟/小时前", "N minutes/hours ago" | Time-based | "恢复到5分钟前", "restore to 10 minutes ago" |
|
|
293
|
+
| "恢复到前 N 个版本", "go back N versions" | Version-based | "恢复到前3个版本", "go back 2 versions" |
|
|
294
|
+
| "恢复到上一个版本", "previous version" | Version-based (N=1) | "回到上一个版本", "undo last change" |
|
|
295
|
+
| "恢复到今天下午3点", "restore to 3pm" | Time-based (absolute) | "恢复到下午3点的状态" |
|
|
296
|
+
| "恢复到昨天的版本", "yesterday's version" | Time-based | "恢复到昨天" |
|
|
297
|
+
|
|
298
|
+
### Step 1: Parse the Request
|
|
299
|
+
|
|
300
|
+
Extract two things from the user's request:
|
|
301
|
+
- **Target scope**: specific file(s) or entire project?
|
|
302
|
+
- **Reference point**: a time expression or a version count?
|
|
303
|
+
|
|
304
|
+
If unclear, ask: "你想恢复哪个文件?还是整个项目?" / "Which file(s) do you want to restore?"
|
|
305
|
+
|
|
306
|
+
### Step 2: Find Matching Commits
|
|
307
|
+
|
|
308
|
+
> **MCP shortcut**: if `list_backups` tool is available, call it with `{ "path": "<project>", "file": "<file>", "before": "<time expr>", "limit": 10 }`. The tool searches all sources (git refs + shadow copies) in one call and returns a unified list sorted by time. Skip to Step 3 with the results.
|
|
309
|
+
|
|
310
|
+
**For time-based requests**, the goal is to find the **latest commit AT or BEFORE the target time** — not commits after it.
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# "恢复到5分钟前" → find the most recent commit BEFORE that point
|
|
314
|
+
git log --oneline --before="5 minutes ago" -5 -- <file>
|
|
315
|
+
|
|
316
|
+
# Auto-backup branch (if exists)
|
|
317
|
+
git log guard/auto-backup --oneline --before="5 minutes ago" -5 -- <file>
|
|
318
|
+
|
|
319
|
+
# Reflog as fallback (shows all HEAD movements)
|
|
320
|
+
git reflog --before="5 minutes ago" -5
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Time expression mapping (always use `--before` to find the state AT that point):
|
|
324
|
+
- "5分钟前" / "5 minutes ago" → `--before="5 minutes ago"`
|
|
325
|
+
- "1小时前" / "1 hour ago" → `--before="1 hour ago"`
|
|
326
|
+
- "今天下午3点" → `--before="today 15:00"`
|
|
327
|
+
- "昨天" / "yesterday" → `--before="yesterday 23:59"`
|
|
328
|
+
|
|
329
|
+
**Key rule**: the first result from `--before` is the closest commit at or before the target time — that is the correct restore point.
|
|
330
|
+
|
|
331
|
+
**For version-based requests**, use commit offset:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
# N versions ago on current branch
|
|
335
|
+
git log --oneline -<N+5> -- <file>
|
|
336
|
+
|
|
337
|
+
# Or use HEAD~N directly
|
|
338
|
+
git show HEAD~<N>:<file>
|
|
339
|
+
|
|
340
|
+
# Auto-backup branch
|
|
341
|
+
git log guard/auto-backup --oneline -<N+5> -- <file>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Step 3: Present Candidates to User
|
|
345
|
+
|
|
346
|
+
**Selection rule**: prefer the **latest commit AT or BEFORE the target time**. This is always candidate #1 in the `--before` results. Only if no commit exists before the target time, inform the user and offer the closest commit after it as an approximation.
|
|
347
|
+
|
|
348
|
+
Show a numbered list of matching commits with timestamps:
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
Found these snapshots / 找到以下快照:
|
|
352
|
+
|
|
353
|
+
→ 1. [abc1234] 2026-03-21 16:05:32 — guard: snapshot before ai edit ← closest before target
|
|
354
|
+
2. [def5678] 2026-03-21 16:02:15 — guard: auto-backup 2026-03-21 16:02:15
|
|
355
|
+
3. [ghi9012] 2026-03-21 15:58:40 — feat: add login page
|
|
356
|
+
|
|
357
|
+
Recommended: #1 (closest to target time). Restore this one? / 推荐 #1(最接近目标时间)。恢复这个?
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Rules**:
|
|
361
|
+
- If only ONE candidate is found, confirm with the user before restoring.
|
|
362
|
+
- If MULTIPLE candidates, pre-select #1 (closest before target) but let the user pick another.
|
|
363
|
+
- If NO candidates before the target time:
|
|
364
|
+
- Check auto-backup ref: `git rev-parse --verify refs/guard/auto-backup`
|
|
365
|
+
- Check shadow copies: `Get-ChildItem .cursor-guard-backup/ -Directory | Sort-Object Name -Descending`
|
|
366
|
+
- If still nothing, report clearly: "No snapshot found before that time. The earliest available is [hash] at [time]. Do you want to use it?"
|
|
367
|
+
- **Never silently pick a version.** Always show and confirm.
|
|
368
|
+
|
|
369
|
+
### Step 4: Preserve Current Version Before Restore
|
|
370
|
+
|
|
371
|
+
> **Rule: `restore_requires_preserve_current_by_default`**
|
|
372
|
+
>
|
|
373
|
+
> The behavior is controlled by `pre_restore_backup` in `.cursor-guard.json` (default: `"always"`).
|
|
374
|
+
|
|
375
|
+
**4a. Determine preservation mode**
|
|
376
|
+
|
|
377
|
+
Read `pre_restore_backup` from config (§0). Three modes:
|
|
378
|
+
|
|
379
|
+
| Config value | Behavior |
|
|
380
|
+
|-------------|----------|
|
|
381
|
+
| `"always"` (default) | Automatically preserve current version. No prompt. Jump to 4b. |
|
|
382
|
+
| `"ask"` | Prompt the user: "恢复前是否保留当前版本?(Y/n)" / "Preserve current version before restore? (Y/n)". If user answers yes/default → jump to 4b. If user answers no → inform and jump to Step 5. |
|
|
383
|
+
| `"never"` | Skip preservation entirely. Inform: "配置已设为不保留当前版本 (pre_restore_backup=never),直接恢复。" and jump to Step 5. |
|
|
384
|
+
|
|
385
|
+
**Override rules** (apply regardless of config):
|
|
386
|
+
- If the user **explicitly** says "不保留当前版本" / "skip backup before restore" in the current message → skip, even if config is `"always"`.
|
|
387
|
+
- If the user **explicitly** says "先保留当前版本" / "preserve current first" → preserve, even if config is `"never"`.
|
|
388
|
+
- User's explicit instruction in the current message always takes priority over config.
|
|
389
|
+
|
|
390
|
+
**4b. Determine preservation scope**
|
|
391
|
+
|
|
392
|
+
| Restore scope | What to preserve |
|
|
393
|
+
|---------------|-----------------|
|
|
394
|
+
| Single file | Only that file's current state |
|
|
395
|
+
| Multiple files | All files that will be overwritten |
|
|
396
|
+
| Entire project | Full project snapshot |
|
|
397
|
+
|
|
398
|
+
**4c. Check if there are changes to preserve**
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
# For single file: check if file differs from the restore target
|
|
402
|
+
git diff <target-commit> -- <file>
|
|
403
|
+
|
|
404
|
+
# For project: check overall status
|
|
405
|
+
git status --porcelain
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
If the file/project is **identical** to the restore target (no diff), inform:
|
|
409
|
+
"当前版本与目标版本相同,无需保留,跳过备份。" / "Current version is identical to target, no backup needed."
|
|
410
|
+
Then jump to Step 5.
|
|
411
|
+
|
|
412
|
+
If the working tree is clean AND HEAD matches the restore target, inform:
|
|
413
|
+
"当前无可保留变更,直接恢复。" / "No changes to preserve, proceeding with restore."
|
|
414
|
+
Then jump to Step 5.
|
|
415
|
+
|
|
416
|
+
**4d. Create preservation snapshot**
|
|
417
|
+
|
|
418
|
+
Use the same temp-index plumbing as §2a to avoid polluting the user's staging area:
|
|
419
|
+
|
|
420
|
+
**Git repo (preferred) — timestamped ref stack:**
|
|
421
|
+
|
|
422
|
+
Each pre-restore snapshot writes to a unique ref `refs/guard/pre-restore/<yyyyMMdd_HHmmss>` so consecutive restores never overwrite each other:
|
|
423
|
+
|
|
424
|
+
```powershell
|
|
425
|
+
$ts = Get-Date -Format 'yyyyMMdd_HHmmss'
|
|
426
|
+
$guardIdx = Join-Path (git rev-parse --git-dir) "guard-pre-restore-index"
|
|
427
|
+
$env:GIT_INDEX_FILE = $guardIdx
|
|
428
|
+
|
|
429
|
+
# For single file: read HEAD tree then update just the target file
|
|
430
|
+
git read-tree HEAD
|
|
431
|
+
git add -- <file>
|
|
432
|
+
|
|
433
|
+
# For project: snapshot everything
|
|
434
|
+
git read-tree HEAD
|
|
435
|
+
git add -A
|
|
436
|
+
|
|
437
|
+
$tree = git write-tree
|
|
438
|
+
$env:GIT_INDEX_FILE = $null
|
|
439
|
+
Remove-Item $guardIdx -Force -ErrorAction SilentlyContinue
|
|
440
|
+
|
|
441
|
+
$commit = git commit-tree $tree -p HEAD -m "guard: preserve current before restore to <target>"
|
|
442
|
+
git update-ref "refs/guard/pre-restore/$ts" $commit
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Record the short hash and the ref path. Also update `refs/guard/pre-restore` as an alias pointing to the latest:
|
|
446
|
+
|
|
447
|
+
```powershell
|
|
448
|
+
git update-ref refs/guard/pre-restore $commit
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
To list all pre-restore snapshots: `git for-each-ref refs/guard/pre-restore/ --sort=-creatordate --format="%(refname:short) %(creatordate:short) %(objectname:short)"`
|
|
452
|
+
|
|
453
|
+
**Non-Git fallback (shadow copy):**
|
|
454
|
+
|
|
455
|
+
```powershell
|
|
456
|
+
$ts = Get-Date -Format 'yyyyMMdd_HHmmss'
|
|
457
|
+
$dir = ".cursor-guard-backup/pre-restore-$ts"
|
|
458
|
+
New-Item -ItemType Directory -Force $dir | Out-Null
|
|
459
|
+
Copy-Item "<file>" "$dir/<file>"
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**4e. Handle preservation failure**
|
|
463
|
+
|
|
464
|
+
If the snapshot fails (e.g. disk full, permission error):
|
|
465
|
+
1. **Do NOT proceed with restore.** Default is to abort.
|
|
466
|
+
2. Inform the user: "当前版本保留失败。默认不继续恢复;如果你确认不保留当前状态也要继续,请明确说明。" / "Failed to preserve current version. Restore aborted by default. If you want to continue without backup, please confirm explicitly."
|
|
467
|
+
3. Only proceed if the user explicitly confirms: "即使不保留也继续" / "continue without backup".
|
|
468
|
+
|
|
469
|
+
**4f. Inform user of preservation result**
|
|
470
|
+
|
|
471
|
+
Before executing restore, tell the user:
|
|
472
|
+
```
|
|
473
|
+
在恢复前,我已保留当前版本:
|
|
474
|
+
- 备份引用: refs/guard/pre-restore/20260321_163005 (abc1234)
|
|
475
|
+
- 恢复方式: git restore --source=refs/guard/pre-restore/20260321_163005 -- <file>
|
|
476
|
+
- 历史栈: git for-each-ref refs/guard/pre-restore/ --sort=-creatordate
|
|
477
|
+
|
|
478
|
+
Current version preserved before restore:
|
|
479
|
+
- Backup ref: refs/guard/pre-restore/20260321_163005 (abc1234)
|
|
480
|
+
- To undo: git restore --source=refs/guard/pre-restore/20260321_163005 -- <file>
|
|
481
|
+
- History: git for-each-ref refs/guard/pre-restore/ --sort=-creatordate
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Step 5: Execute Recovery
|
|
485
|
+
|
|
486
|
+
> **MCP shortcut**: if `restore_file` / `restore_project` tools are available:
|
|
487
|
+
> - Single file: `restore_file { "path": "<project>", "file": "<file>", "source": "<hash-or-timestamp>", "preserve_current": true }` — handles pre-restore snapshot + restore + verification in one call.
|
|
488
|
+
> - Project preview: `restore_project { "path": "<project>", "source": "<hash>", "preview": true }` — returns the list of files that would change.
|
|
489
|
+
> - Project execute: after user confirms, `restore_project { "path": "<project>", "source": "<hash>", "preview": false, "preserve_current": true }` — creates pre-restore snapshot, then restores all files in one call. Returns `{ filesRestored, preRestoreRef, files }`.
|
|
490
|
+
> - MCP `restore_file` and `restore_project` respect `pre_restore_backup` config (§Step 4) automatically. The response includes `preRestoreRef` if a snapshot was created.
|
|
491
|
+
|
|
492
|
+
**Single file recovery:**
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
git restore --source=<commit-hash> -- <path/to/file>
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Entire project recovery** (destructive — require explicit confirmation):
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
# Show what will change first
|
|
502
|
+
git diff <commit-hash> -- .
|
|
503
|
+
|
|
504
|
+
# After user confirms:
|
|
505
|
+
git restore --source=<commit-hash> -- .
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
**From shadow copy:**
|
|
509
|
+
|
|
510
|
+
```powershell
|
|
511
|
+
# Find the closest timestamp directory
|
|
512
|
+
Get-ChildItem .cursor-guard-backup/ -Directory | Sort-Object Name -Descending
|
|
513
|
+
|
|
514
|
+
# Restore
|
|
515
|
+
Copy-Item ".cursor-guard-backup/<timestamp>/<file>" "<original-path>"
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Step 6: Verify & Report
|
|
519
|
+
|
|
520
|
+
After restoring, always:
|
|
521
|
+
1. Show the restored file content (or diff) so the user can verify
|
|
522
|
+
2. Report the recovery in the status block (§6a), including **both** the pre-restore backup ref and the restore target
|
|
523
|
+
3. Tell the user how to undo the restore if needed
|
|
524
|
+
|
|
525
|
+
**Status block for restore operations:**
|
|
526
|
+
|
|
527
|
+
```markdown
|
|
528
|
+
**Cursor Guard — restore status**
|
|
529
|
+
- **Pre-restore backup**: `refs/guard/pre-restore/<ts>` (`<short-hash>`) or `shadow copy at .cursor-guard-backup/pre-restore-<ts>/` or `skipped (user opted out)` or `skipped (no changes)`
|
|
530
|
+
- **Restored to**: `<target-hash>` / `<target description>`
|
|
531
|
+
- **Scope**: single file `<path>` / N files / entire project
|
|
532
|
+
- **Result**: success / failed
|
|
533
|
+
- **To undo restore**: `git restore --source=refs/guard/pre-restore/<ts> -- <file>`
|
|
534
|
+
- **All pre-restore snapshots**: `git for-each-ref refs/guard/pre-restore/ --sort=-creatordate`
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## 6. Output to User (When This Skill Was Used)
|
|
540
|
+
|
|
541
|
+
When you followed this skill's workflow, end with a short **status block**:
|
|
542
|
+
|
|
543
|
+
```markdown
|
|
544
|
+
**Cursor Guard — status**
|
|
545
|
+
- **Risk**: low / medium / high
|
|
546
|
+
- **Snapshot**: `<short-hash>` or `shadow copy at .cursor-guard-backup/<ts>/` or `none (user declined)`
|
|
547
|
+
- **Done**: (e.g. snapshot committed / diff previewed / recovery completed)
|
|
548
|
+
- **Next step**: (one concrete command or one UI action)
|
|
549
|
+
- **Recovery ref**: `references/recovery.md` in this skill folder
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Skip the block for unrelated turns.
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## Hard Rules (Non-Negotiable)
|
|
557
|
+
|
|
558
|
+
1. **MUST snapshot before high-risk ops** — git commit or shadow copy. No exceptions unless user explicitly declines.
|
|
559
|
+
2. **MUST Read before Write** — never overwrite a file the agent hasn't read in the current turn.
|
|
560
|
+
3. **MUST preserve current version before restore** — every restore operation must first snapshot the current state (§5a Step 4). Skip ONLY when: (a) user explicitly opts out, (b) current state is identical to target, or (c) no changes exist. If preservation fails, abort restore by default.
|
|
561
|
+
4. **Do not** treat Timeline/Checkpoints as the only or primary recovery path.
|
|
562
|
+
5. **Do not** recommend Checkpoints as long-term or sole backup.
|
|
563
|
+
6. **No automatic push** to remotes; local commits only unless user requests push.
|
|
564
|
+
7. **Be honest** about limits: terminal side effects, binary files, and non-tracked paths are not fully reversible without prior commits.
|
|
565
|
+
8. **Do not** run `git clean`, `reset --hard`, or other destructive Git commands unless the user clearly asked; always show what would be affected first.
|
|
566
|
+
9. **Do not** delete files via the Delete tool without explicit per-file confirmation from the user.
|
|
567
|
+
10. **Do not** modify or delete `.cursor-guard.json` unless the user explicitly asks — accidental config changes silently alter protection scope.
|
|
568
|
+
11. **Use `--no-verify`** on all guard snapshot commits to bypass pre-commit hooks that could fail or modify files.
|
|
569
|
+
12. **Concurrent agents**: if multiple Agent threads are active, warn the user to avoid simultaneous writes to the same file. Snapshots cannot prevent race conditions between parallel agents.
|
|
570
|
+
13. **Preservation must not pollute** — all pre-restore backups use temp index + dedicated ref (`refs/guard/pre-restore`). The user's staging area, working tree, and commit history on their branch are never modified by the preservation process.
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
## Optional: Project Conventions
|
|
575
|
+
|
|
576
|
+
- If the workspace has `.cursor-guard.json`, the agent MUST read and follow it (see §0).
|
|
577
|
+
- If `.cursor-guard-backup/` folder exists, align shadow copy paths with it.
|
|
578
|
+
- Template config: [references/cursor-guard.example.json](references/cursor-guard.example.json) — copy to workspace root and customize. Field docs: [references/config-reference.md](references/config-reference.md).
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## Further Reading
|
|
583
|
+
|
|
584
|
+
- Recovery commands: [references/recovery.md](references/recovery.md)
|
|
585
|
+
- Auto-backup (Node.js core): [references/lib/auto-backup.js](references/lib/auto-backup.js)
|
|
586
|
+
- Guard doctor (Node.js core): [references/lib/guard-doctor.js](references/lib/guard-doctor.js)
|
|
587
|
+
- Core modules: [references/lib/core/](references/lib/core/) (doctor, doctor-fix, snapshot, backups, restore, status, anomaly, dashboard)
|
|
588
|
+
- MCP server: [references/mcp/server.js](references/mcp/server.js) (9 tools: doctor, doctor_fix, backup_status, list_backups, snapshot_now, restore_file, restore_project, dashboard, alert_status)
|
|
589
|
+
- Shared utilities: [references/lib/utils.js](references/lib/utils.js)
|
|
590
|
+
- Config JSON Schema: [references/cursor-guard.schema.json](references/cursor-guard.schema.json)
|
|
591
|
+
- Example config: [references/cursor-guard.example.json](references/cursor-guard.example.json)
|
|
592
|
+
- Config field reference (EN): [references/config-reference.md](references/config-reference.md)
|
|
593
|
+
- 配置参数说明(中文): [references/config-reference.zh-CN.md](references/config-reference.zh-CN.md)
|
|
594
|
+
- Version roadmap: [ROADMAP.md](ROADMAP.md)
|
|
595
|
+
|
|
596
|
+
### Running scripts
|
|
597
|
+
|
|
598
|
+
Cross-platform (requires Node.js >= 18):
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
# Via npx (if installed from npm)
|
|
602
|
+
npx cursor-guard-backup --path /my/project --interval 60
|
|
603
|
+
npx cursor-guard-doctor --path /my/project
|
|
604
|
+
|
|
605
|
+
# Via thin wrapper (from skill directory)
|
|
606
|
+
# Windows PowerShell:
|
|
607
|
+
.\references\auto-backup.ps1 -Path "D:\MyProject"
|
|
608
|
+
.\references\guard-doctor.ps1 -Path "D:\MyProject"
|
|
609
|
+
|
|
610
|
+
# macOS / Linux:
|
|
611
|
+
./references/auto-backup.sh /my/project
|
|
612
|
+
./references/guard-doctor.sh /my/project
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### MCP Server (optional enhancement)
|
|
616
|
+
|
|
617
|
+
If your Cursor config supports MCP, add `cursor-guard` as an MCP server for lower token cost and structured tool calls:
|
|
618
|
+
|
|
619
|
+
```jsonc
|
|
620
|
+
// .cursor/mcp.json (or global Cursor MCP settings)
|
|
621
|
+
{
|
|
622
|
+
"mcpServers": {
|
|
623
|
+
"cursor-guard": {
|
|
624
|
+
"command": "node",
|
|
625
|
+
"args": ["<path-to-skill>/references/mcp/server.js"]
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
Once configured, the 9 tools (`doctor`, `doctor_fix`, `backup_status`, `list_backups`, `snapshot_now`, `restore_file`, `restore_project`, `dashboard`, `alert_status`) are available as MCP tool calls. See §0a for routing logic.
|