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/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". Run `guard-doctor.ps1` and report results.
24
-
25
- If none of the above, do not expand scope; answer normally.
26
-
27
- ---
28
-
29
- ## 0. Load Project Config (If Exists)
30
-
31
- On first trigger in a session, check if the workspace root contains `.cursor-guard.json`. If found, **read it** and apply throughout:
32
-
33
- ```jsonc
34
- {
35
- "protect": ["src/**", "lib/**", "package.json"],
36
- "ignore": ["node_modules/**", "dist/**", "*.log"],
37
-
38
- // "git": auto-backup to a dedicated branch (default)
39
- // "shadow": file copies to .cursor-guard-backup/<timestamp>/
40
- // "both": git branch snapshot + shadow copies
41
- "backup_strategy": "git",
42
- "auto_backup_interval_seconds": 60,
43
-
44
- // Sensitive file patterns auto-excluded from backup even if in protect scope.
45
- // Built-in defaults: .env, .env.*, *.key, *.pem, *.p12, *.pfx, credentials*
46
- "secrets_patterns": [".env", ".env.*", "*.key", "*.pem"],
47
-
48
- // Controls behavior before restore operations.
49
- // "always" (default): automatically preserve current version before every restore.
50
- // "ask": prompt the user each time to decide.
51
- // "never": skip preservation entirely (not recommended).
52
- "pre_restore_backup": "always",
53
-
54
- // Retention for shadow copies. mode: "days" | "count" | "size"
55
- "retention": { "mode": "days", "days": 30, "max_count": 100, "max_size_mb": 500 },
56
-
57
- // Retention for Git auto-backup branch. Disabled by default.
58
- // "count": keep N newest commits. "days": keep commits from last N days.
59
- "git_retention": { "enabled": false, "mode": "count", "max_count": 200 }
60
- }
61
- ```
62
-
63
- **Resolution rules:**
64
- - `protect` set + `ignore` set → file must match a `protect` pattern AND not match any `ignore` pattern.
65
- - Only `protect` set only matching files are protected.
66
- - Only `ignore` set everything is protected except matching files.
67
- - Neither set protect everything (same as before).
68
-
69
- **`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.
70
-
71
- **`retention`**: Controls automatic cleanup of old shadow-copy snapshots in `.cursor-guard-backup/`:
72
- - `"days"` (default): keep snapshots from the last N days (default **30**).
73
- - `"count"`: keep the N most recent snapshots (default 100).
74
- - `"size"`: keep total shadow-copy folder under N MB (default 500).
75
-
76
- **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).
77
-
78
- When the target file of an edit **falls outside the protected scope**, the agent:
79
- - Still applies "Read before Write" (Hard Rule §2).
80
- - Skips the mandatory git snapshot / shadow copy step.
81
- - Notes `outside protection scope` in the status block.
82
-
83
- ---
84
-
85
- ## 1. Assess Risk (First)
86
-
87
- | Signal | Risk |
88
- |--------|------|
89
- | Multi-file edits, `delete_file`, terminal `rm`, or **Write** to existing file | **High** |
90
- | Single small edit (`StrReplace` with narrow scope), user explicitly asked | **Medium** |
91
- | Read-only explanation, no writes | **Low** |
92
-
93
- ---
94
-
95
- ## 2. Mandatory Pre-Write Backup Protocol (ENFORCED)
96
-
97
- > **This is not optional.** The agent MUST execute these steps before making
98
- > destructive or high-risk changes. Skipping is only allowed when the user
99
- > explicitly says "不用备份" / "skip backup".
100
-
101
- ### 2a. If workspace IS a Git repo
102
-
103
- **Before any High-risk operation on a protected file:**
104
-
105
- Use a **temporary index and dedicated ref** so the user's staged/unstaged state is never touched:
106
-
107
- ```bash
108
- GIT_DIR=$(git rev-parse --git-dir)
109
- GUARD_IDX="$GIT_DIR/guard-snapshot-index"
110
-
111
- # 1. Create temp index from HEAD
112
- GIT_INDEX_FILE="$GUARD_IDX" git read-tree HEAD
113
-
114
- # 2. Stage working-tree files into temp index
115
- GIT_INDEX_FILE="$GUARD_IDX" git add -A
116
-
117
- # 3. Write tree and create commit on a guard ref (not on the user's branch)
118
- TREE=$(GIT_INDEX_FILE="$GUARD_IDX" git write-tree)
119
- COMMIT=$(git commit-tree "$TREE" -p HEAD -m "guard: snapshot before ai edit")
120
- git update-ref refs/guard/snapshot "$COMMIT"
121
-
122
- # 4. Cleanup
123
- rm -f "$GUARD_IDX"
124
- ```
125
-
126
- **PowerShell equivalent** (for agent Shell calls):
127
-
128
- ```powershell
129
- $guardIdx = Join-Path (git rev-parse --git-dir) "guard-snapshot-index"
130
- $env:GIT_INDEX_FILE = $guardIdx
131
- git read-tree HEAD
132
- git add -A
133
- $tree = git write-tree
134
- $env:GIT_INDEX_FILE = $null
135
- Remove-Item $guardIdx -Force -ErrorAction SilentlyContinue
136
- $commit = git commit-tree $tree -p HEAD -m "guard: snapshot before ai edit"
137
- git update-ref refs/guard/snapshot $commit
138
- ```
139
-
140
- - Run this via Shell tool BEFORE the first Write / StrReplace / Delete call.
141
- - The user's index (staged files) and current branch are **never modified**.
142
- - If `.cursor-guard.json` exists with `protect` patterns, scope `git add` to those paths instead of `-A`.
143
- - Record the commit hash (short) and report it to the user.
144
- - To restore: `git restore --source=refs/guard/snapshot -- <file>`.
145
- - Before writing the tree, check staged files against `secrets_patterns` (§0). Exclude any matches and warn the user.
146
-
147
- **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.
148
-
149
- **Before any Medium-risk operation:**
150
-
151
- - At minimum, run `git diff -- <target_file>` and `git status` so the user sees current state.
152
- - Recommend a snapshot commit; proceed without it only if the user confirms.
153
-
154
- ### 2b. If workspace is NOT a Git repo
155
-
156
- **Before any High-risk operation, offer TWO options (pick one):**
157
-
158
- 1. **Quick git init** (preferred):
159
- ```
160
- git init && git add -A && git commit -m "guard: initial snapshot" --no-verify
161
- ```
162
- 2. **Shadow copy** (fallback if user declines git):
163
- - Copy the target file(s) to `.cursor-guard-backup/<timestamp>/` via Shell.
164
- - Example:
165
- ```powershell
166
- $ts = Get-Date -Format 'yyyyMMdd_HHmmss'
167
- New-Item -ItemType Directory -Force ".cursor-guard-backup/$ts"
168
- Copy-Item "src/app.py" ".cursor-guard-backup/$ts/app.py"
169
- ```
170
- - Add `.cursor-guard-backup/` to `.gitignore` if git is later initialized.
171
-
172
- **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.
173
-
174
- ### 2c. Multi-file batch operations
175
-
176
- When editing 3+ files in one task:
177
-
178
- 1. Create the snapshot commit covering ALL files first.
179
- 2. Apply changes file-by-file; if any step fails, offer to `git restore` all files back to the snapshot.
180
- 3. After all edits succeed, offer a clean commit with a real message.
181
-
182
- ---
183
-
184
- ## 3. Protection Strategy During Edits
185
-
186
- **Before applying AI changes:**
187
-
188
- 1. **Preview**: Show a clear **diff-style summary** (paths + intent). For substantial edits, prefer patch-sized chunks.
189
- 2. **Destructive ops**: For deletes or large rewrites, **confirm explicitly** (one short question). Do not assume "cleanup" permission.
190
- 3. **Workspace root**: State which directory is treated as project root; avoid touching paths outside it unless the user asked.
191
- 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.
192
- 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.
193
-
194
- **After tool writes (agent wrote to disk directly):**
195
-
196
- - Tell the user: editor buffer may be stale **`Revert File`** (Ctrl+Shift+P "Revert File") or close & reopen tab.
197
- - Do **not** claim Timeline/Checkpoints will capture tool writes.
198
-
199
- ---
200
-
201
- ## 4. Backup Strategy (Priority)
202
-
203
- There are two distinct backup mechanisms. Do not confuse them:
204
-
205
- | | **Git branch snapshot** | **Shadow copy** |
206
- |---|---|---|
207
- | **What** | Commits to `refs/guard/auto-backup` via plumbing | File copies to `.cursor-guard-backup/<timestamp>/` |
208
- | **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) |
209
- | **Who cleans up** | `git_retention` config (auto, opt-in); or manual `git branch -D` | `retention` config (auto); or manual |
210
- | **Restore** | `git restore --source=guard/auto-backup -- <file>` | Copy file from `.cursor-guard-backup/<ts>/<file>` to original path |
211
- | **Requires Git** | Yes | No (fallback for non-git repos) |
212
-
213
- **Priority order for the agent:**
214
-
215
- 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.
216
- 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.
217
- 3. **Shadow copy** (`.cursor-guard-backup/`) fallback for non-git repos, or as extra insurance when `backup_strategy = "both"`.
218
- 4. **Editor habits** — Ctrl+S frequently; optional extensions are user-configured, mention only if asked.
219
-
220
- **Hard default:** Do NOT `git push` unless the user explicitly asks. Scope = **local only**.
221
-
222
- **Retention:**
223
- - **Shadow copies**: controlled by `retention` in `.cursor-guard.json` (mode: days/count/size).
224
- - **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.
225
- - See [references/config-reference.md](references/config-reference.md) for full field docs.
226
-
227
- ---
228
-
229
- ## 5. Recovery Strategy (Priority Order)
230
-
231
- 1. **Git**: `git status` → `git diff` → `git restore` → `git reset` → `git reflog` — see [references/recovery.md](references/recovery.md).
232
- 2. **Shadow copies**: Check `.cursor-guard-backup/` for timestamped copies.
233
- 3. **Conversation context**: If the agent Read the file before overwriting, the original content is in this chat — offer to re-write it back.
234
- 4. **Editor Local History / Timeline**: auxiliary, per-file; unreliable for tool-only disk writes.
235
- 5. **Cursor Checkpoints**: auxiliary; tied to Agent UI; not a long-term backup.
236
-
237
- ---
238
-
239
- ## 5a. Time-Based & Version-Based Recovery
240
-
241
- When the user requests recovery using time or version references, follow this workflow:
242
-
243
- ### Trigger Phrases (Chinese & English)
244
-
245
- | Pattern | Type | Example |
246
- |---------|------|---------|
247
- | "恢复到 N 分钟/小时前", "N minutes/hours ago" | Time-based | "恢复到5分钟前", "restore to 10 minutes ago" |
248
- | "恢复到前 N 个版本", "go back N versions" | Version-based | "恢复到前3个版本", "go back 2 versions" |
249
- | "恢复到上一个版本", "previous version" | Version-based (N=1) | "回到上一个版本", "undo last change" |
250
- | "恢复到今天下午3点", "restore to 3pm" | Time-based (absolute) | "恢复到下午3点的状态" |
251
- | "恢复到昨天的版本", "yesterday's version" | Time-based | "恢复到昨天" |
252
-
253
- ### Step 1: Parse the Request
254
-
255
- Extract two things from the user's request:
256
- - **Target scope**: specific file(s) or entire project?
257
- - **Reference point**: a time expression or a version count?
258
-
259
- If unclear, ask: "你想恢复哪个文件?还是整个项目?" / "Which file(s) do you want to restore?"
260
-
261
- ### Step 2: Find Matching Commits
262
-
263
- **For time-based requests**, the goal is to find the **latest commit AT or BEFORE the target time** not commits after it.
264
-
265
- ```bash
266
- # "恢复到5分钟前" → find the most recent commit BEFORE that point
267
- git log --oneline --before="5 minutes ago" -5 -- <file>
268
-
269
- # Auto-backup branch (if exists)
270
- git log guard/auto-backup --oneline --before="5 minutes ago" -5 -- <file>
271
-
272
- # Reflog as fallback (shows all HEAD movements)
273
- git reflog --before="5 minutes ago" -5
274
- ```
275
-
276
- Time expression mapping (always use `--before` to find the state AT that point):
277
- - "5分钟前" / "5 minutes ago" `--before="5 minutes ago"`
278
- - "1小时前" / "1 hour ago" `--before="1 hour ago"`
279
- - "今天下午3点" `--before="today 15:00"`
280
- - "昨天" / "yesterday" `--before="yesterday 23:59"`
281
-
282
- **Key rule**: the first result from `--before` is the closest commit at or before the target time — that is the correct restore point.
283
-
284
- **For version-based requests**, use commit offset:
285
-
286
- ```bash
287
- # N versions ago on current branch
288
- git log --oneline -<N+5> -- <file>
289
-
290
- # Or use HEAD~N directly
291
- git show HEAD~<N>:<file>
292
-
293
- # Auto-backup branch
294
- git log guard/auto-backup --oneline -<N+5> -- <file>
295
- ```
296
-
297
- ### Step 3: Present Candidates to User
298
-
299
- **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.
300
-
301
- Show a numbered list of matching commits with timestamps:
302
-
303
- ```
304
- Found these snapshots / 找到以下快照:
305
-
306
- 1. [abc1234] 2026-03-21 16:05:32 guard: snapshot before ai edit ← closest before target
307
- 2. [def5678] 2026-03-21 16:02:15 — guard: auto-backup 2026-03-21 16:02:15
308
- 3. [ghi9012] 2026-03-21 15:58:40 feat: add login page
309
-
310
- Recommended: #1 (closest to target time). Restore this one? / 推荐 #1(最接近目标时间)。恢复这个?
311
- ```
312
-
313
- **Rules**:
314
- - If only ONE candidate is found, confirm with the user before restoring.
315
- - If MULTIPLE candidates, pre-select #1 (closest before target) but let the user pick another.
316
- - If NO candidates before the target time:
317
- - Check auto-backup ref: `git rev-parse --verify refs/guard/auto-backup`
318
- - Check shadow copies: `Get-ChildItem .cursor-guard-backup/ -Directory | Sort-Object Name -Descending`
319
- - If still nothing, report clearly: "No snapshot found before that time. The earliest available is [hash] at [time]. Do you want to use it?"
320
- - **Never silently pick a version.** Always show and confirm.
321
-
322
- ### Step 4: Preserve Current Version Before Restore
323
-
324
- > **Rule: `restore_requires_preserve_current_by_default`**
325
- >
326
- > The behavior is controlled by `pre_restore_backup` in `.cursor-guard.json` (default: `"always"`).
327
-
328
- **4a. Determine preservation mode**
329
-
330
- Read `pre_restore_backup` from config (§0). Three modes:
331
-
332
- | Config value | Behavior |
333
- |-------------|----------|
334
- | `"always"` (default) | Automatically preserve current version. No prompt. Jump to 4b. |
335
- | `"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. |
336
- | `"never"` | Skip preservation entirely. Inform: "配置已设为不保留当前版本 (pre_restore_backup=never),直接恢复。" and jump to Step 5. |
337
-
338
- **Override rules** (apply regardless of config):
339
- - If the user **explicitly** says "不保留当前版本" / "skip backup before restore" in the current message → skip, even if config is `"always"`.
340
- - If the user **explicitly** says "先保留当前版本" / "preserve current first" → preserve, even if config is `"never"`.
341
- - User's explicit instruction in the current message always takes priority over config.
342
-
343
- **4b. Determine preservation scope**
344
-
345
- | Restore scope | What to preserve |
346
- |---------------|-----------------|
347
- | Single file | Only that file's current state |
348
- | Multiple files | All files that will be overwritten |
349
- | Entire project | Full project snapshot |
350
-
351
- **4c. Check if there are changes to preserve**
352
-
353
- ```bash
354
- # For single file: check if file differs from the restore target
355
- git diff <target-commit> -- <file>
356
-
357
- # For project: check overall status
358
- git status --porcelain
359
- ```
360
-
361
- If the file/project is **identical** to the restore target (no diff), inform:
362
- "当前版本与目标版本相同,无需保留,跳过备份。" / "Current version is identical to target, no backup needed."
363
- Then jump to Step 5.
364
-
365
- If the working tree is clean AND HEAD matches the restore target, inform:
366
- "当前无可保留变更,直接恢复。" / "No changes to preserve, proceeding with restore."
367
- Then jump to Step 5.
368
-
369
- **4d. Create preservation snapshot**
370
-
371
- Use the same temp-index plumbing as §2a to avoid polluting the user's staging area:
372
-
373
- **Git repo (preferred) timestamped ref stack:**
374
-
375
- Each pre-restore snapshot writes to a unique ref `refs/guard/pre-restore/<yyyyMMdd_HHmmss>` so consecutive restores never overwrite each other:
376
-
377
- ```powershell
378
- $ts = Get-Date -Format 'yyyyMMdd_HHmmss'
379
- $guardIdx = Join-Path (git rev-parse --git-dir) "guard-pre-restore-index"
380
- $env:GIT_INDEX_FILE = $guardIdx
381
-
382
- # For single file: read HEAD tree then update just the target file
383
- git read-tree HEAD
384
- git add -- <file>
385
-
386
- # For project: snapshot everything
387
- git read-tree HEAD
388
- git add -A
389
-
390
- $tree = git write-tree
391
- $env:GIT_INDEX_FILE = $null
392
- Remove-Item $guardIdx -Force -ErrorAction SilentlyContinue
393
-
394
- $commit = git commit-tree $tree -p HEAD -m "guard: preserve current before restore to <target>"
395
- git update-ref "refs/guard/pre-restore/$ts" $commit
396
- ```
397
-
398
- Record the short hash and the ref path. Also update `refs/guard/pre-restore` as an alias pointing to the latest:
399
-
400
- ```powershell
401
- git update-ref refs/guard/pre-restore $commit
402
- ```
403
-
404
- To list all pre-restore snapshots: `git for-each-ref refs/guard/pre-restore/ --sort=-creatordate --format="%(refname:short) %(creatordate:short) %(objectname:short)"`
405
-
406
- **Non-Git fallback (shadow copy):**
407
-
408
- ```powershell
409
- $ts = Get-Date -Format 'yyyyMMdd_HHmmss'
410
- $dir = ".cursor-guard-backup/pre-restore-$ts"
411
- New-Item -ItemType Directory -Force $dir | Out-Null
412
- Copy-Item "<file>" "$dir/<file>"
413
- ```
414
-
415
- **4e. Handle preservation failure**
416
-
417
- If the snapshot fails (e.g. disk full, permission error):
418
- 1. **Do NOT proceed with restore.** Default is to abort.
419
- 2. Inform the user: "当前版本保留失败。默认不继续恢复;如果你确认不保留当前状态也要继续,请明确说明。" / "Failed to preserve current version. Restore aborted by default. If you want to continue without backup, please confirm explicitly."
420
- 3. Only proceed if the user explicitly confirms: "即使不保留也继续" / "continue without backup".
421
-
422
- **4f. Inform user of preservation result**
423
-
424
- Before executing restore, tell the user:
425
- ```
426
- 在恢复前,我已保留当前版本:
427
- - 备份引用: refs/guard/pre-restore/20260321_163005 (abc1234)
428
- - 恢复方式: git restore --source=refs/guard/pre-restore/20260321_163005 -- <file>
429
- - 历史栈: git for-each-ref refs/guard/pre-restore/ --sort=-creatordate
430
-
431
- Current version preserved before restore:
432
- - Backup ref: refs/guard/pre-restore/20260321_163005 (abc1234)
433
- - To undo: git restore --source=refs/guard/pre-restore/20260321_163005 -- <file>
434
- - History: git for-each-ref refs/guard/pre-restore/ --sort=-creatordate
435
- ```
436
-
437
- ### Step 5: Execute Recovery
438
-
439
- **Single file recovery:**
440
-
441
- ```bash
442
- git restore --source=<commit-hash> -- <path/to/file>
443
- ```
444
-
445
- **Entire project recovery** (destructive require explicit confirmation):
446
-
447
- ```bash
448
- # Show what will change first
449
- git diff <commit-hash> -- .
450
-
451
- # After user confirms:
452
- git restore --source=<commit-hash> -- .
453
- ```
454
-
455
- **From shadow copy:**
456
-
457
- ```powershell
458
- # Find the closest timestamp directory
459
- Get-ChildItem .cursor-guard-backup/ -Directory | Sort-Object Name -Descending
460
-
461
- # Restore
462
- Copy-Item ".cursor-guard-backup/<timestamp>/<file>" "<original-path>"
463
- ```
464
-
465
- ### Step 6: Verify & Report
466
-
467
- After restoring, always:
468
- 1. Show the restored file content (or diff) so the user can verify
469
- 2. Report the recovery in the status block (§6a), including **both** the pre-restore backup ref and the restore target
470
- 3. Tell the user how to undo the restore if needed
471
-
472
- **Status block for restore operations:**
473
-
474
- ```markdown
475
- **Cursor Guard restore status**
476
- - **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)`
477
- - **Restored to**: `<target-hash>` / `<target description>`
478
- - **Scope**: single file `<path>` / N files / entire project
479
- - **Result**: success / failed
480
- - **To undo restore**: `git restore --source=refs/guard/pre-restore/<ts> -- <file>`
481
- - **All pre-restore snapshots**: `git for-each-ref refs/guard/pre-restore/ --sort=-creatordate`
482
- ```
483
-
484
- ---
485
-
486
- ## 6. Output to User (When This Skill Was Used)
487
-
488
- When you followed this skill's workflow, end with a short **status block**:
489
-
490
- ```markdown
491
- **Cursor Guard — status**
492
- - **Risk**: low / medium / high
493
- - **Snapshot**: `<short-hash>` or `shadow copy at .cursor-guard-backup/<ts>/` or `none (user declined)`
494
- - **Done**: (e.g. snapshot committed / diff previewed / recovery completed)
495
- - **Next step**: (one concrete command or one UI action)
496
- - **Recovery ref**: `references/recovery.md` in this skill folder
497
- ```
498
-
499
- Skip the block for unrelated turns.
500
-
501
- ---
502
-
503
- ## Hard Rules (Non-Negotiable)
504
-
505
- 1. **MUST snapshot before high-risk ops** — git commit or shadow copy. No exceptions unless user explicitly declines.
506
- 2. **MUST Read before Write** — never overwrite a file the agent hasn't read in the current turn.
507
- 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.
508
- 4. **Do not** treat Timeline/Checkpoints as the only or primary recovery path.
509
- 5. **Do not** recommend Checkpoints as long-term or sole backup.
510
- 6. **No automatic push** to remotes; local commits only unless user requests push.
511
- 7. **Be honest** about limits: terminal side effects, binary files, and non-tracked paths are not fully reversible without prior commits.
512
- 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.
513
- 9. **Do not** delete files via the Delete tool without explicit per-file confirmation from the user.
514
- 10. **Do not** modify or delete `.cursor-guard.json` unless the user explicitly asks — accidental config changes silently alter protection scope.
515
- 11. **Use `--no-verify`** on all guard snapshot commits to bypass pre-commit hooks that could fail or modify files.
516
- 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.
517
- 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.
518
-
519
- ---
520
-
521
- ## Optional: Project Conventions
522
-
523
- - If the workspace has `.cursor-guard.json`, the agent MUST read and follow it (see §0).
524
- - If `.cursor-guard-backup/` folder exists, align shadow copy paths with it.
525
- - 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).
526
-
527
- ---
528
-
529
- ## Further Reading
530
-
531
- - Recovery commands: [references/recovery.md](references/recovery.md)
532
- - Auto-backup (Node.js core): [references/lib/auto-backup.js](references/lib/auto-backup.js)
533
- - Guard doctor (Node.js core): [references/lib/guard-doctor.js](references/lib/guard-doctor.js)
534
- - Shared utilities: [references/lib/utils.js](references/lib/utils.js)
535
- - Config JSON Schema: [references/cursor-guard.schema.json](references/cursor-guard.schema.json)
536
- - Example config: [references/cursor-guard.example.json](references/cursor-guard.example.json)
537
- - Config field reference (EN): [references/config-reference.md](references/config-reference.md)
538
- - 配置参数说明(中文): [references/config-reference.zh-CN.md](references/config-reference.zh-CN.md)
539
-
540
- ### Running scripts
541
-
542
- Cross-platform (requires Node.js >= 18):
543
-
544
- ```bash
545
- # Via npx (if installed from npm)
546
- npx cursor-guard-backup --path /my/project --interval 60
547
- npx cursor-guard-doctor --path /my/project
548
-
549
- # Via thin wrapper (from skill directory)
550
- # Windows PowerShell:
551
- .\references\auto-backup.ps1 -Path "D:\MyProject"
552
- .\references\guard-doctor.ps1 -Path "D:\MyProject"
553
-
554
- # macOS / Linux:
555
- ./references/auto-backup.sh /my/project
556
- ./references/guard-doctor.sh /my/project
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.