cursor-guard 2.0.3 → 2.1.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 +2 -2
- package/README.zh-CN.md +2 -2
- package/SKILL.md +6 -6
- package/package.json +1 -1
- package/references/config-reference.md +2 -2
- package/references/config-reference.zh-CN.md +2 -2
- package/references/cursor-guard.schema.json +1 -1
- package/references/lib/auto-backup.js +16 -5
- package/references/lib/guard-doctor.js +11 -6
- package/references/recovery.md +7 -7
package/README.md
CHANGED
|
@@ -179,7 +179,7 @@ npx cursor-guard-backup --path /my/project --interval 30
|
|
|
179
179
|
./references/auto-backup.sh /my/project
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
-
The script uses Git plumbing commands to snapshot to `
|
|
182
|
+
The script uses Git plumbing commands to snapshot to `refs/guard/auto-backup` — it never switches branches or touches your working index. The ref lives outside `refs/heads/` so `git push --all` won't push it. Supports `shadow` mode for non-Git directories.
|
|
183
183
|
|
|
184
184
|
### Health Check
|
|
185
185
|
|
|
@@ -229,7 +229,7 @@ If the pre-restore backup fails, the agent will **not** proceed — it will wait
|
|
|
229
229
|
### Recovery priority
|
|
230
230
|
|
|
231
231
|
1. **Git** — `git restore`, `git reset`, `git reflog`
|
|
232
|
-
2. **Auto-backup
|
|
232
|
+
2. **Auto-backup ref** — `refs/guard/auto-backup`
|
|
233
233
|
3. **Shadow copies** — `.cursor-guard-backup/<timestamp>/`
|
|
234
234
|
4. **Conversation context** — Original file content captured by agent Read calls
|
|
235
235
|
5. **Editor history** — VS Code/Cursor Timeline (auxiliary)
|
package/README.zh-CN.md
CHANGED
|
@@ -179,7 +179,7 @@ npx cursor-guard-backup --path /my/project --interval 30
|
|
|
179
179
|
./references/auto-backup.sh /my/project
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
-
脚本使用 Git 底层命令快照到 `
|
|
182
|
+
脚本使用 Git 底层命令快照到 `refs/guard/auto-backup`——不会切换分支,也不会影响你的工作索引。该引用位于 `refs/heads/` 之外,`git push --all` 不会推送它。支持 `shadow` 模式用于非 Git 目录。
|
|
183
183
|
|
|
184
184
|
### 健康检查
|
|
185
185
|
|
|
@@ -229,7 +229,7 @@ npx cursor-guard-doctor --path /my/project
|
|
|
229
229
|
### 恢复优先级
|
|
230
230
|
|
|
231
231
|
1. **Git** — `git restore`, `git reset`, `git reflog`
|
|
232
|
-
2.
|
|
232
|
+
2. **自动备份引用** — `refs/guard/auto-backup`
|
|
233
233
|
3. **影子拷贝** — `.cursor-guard-backup/<时间戳>/`
|
|
234
234
|
4. **对话上下文** — 代理 Read 调用捕获的原始文件内容
|
|
235
235
|
5. **编辑器历史** — VS Code/Cursor Timeline(辅助)
|
package/SKILL.md
CHANGED
|
@@ -204,16 +204,16 @@ There are two distinct backup mechanisms. Do not confuse them:
|
|
|
204
204
|
|
|
205
205
|
| | **Git branch snapshot** | **Shadow copy** |
|
|
206
206
|
|---|---|---|
|
|
207
|
-
| **What** | Commits to `
|
|
207
|
+
| **What** | Commits to `refs/guard/auto-backup` via plumbing | File copies to `.cursor-guard-backup/<timestamp>/` |
|
|
208
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
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=
|
|
210
|
+
| **Restore** | `git restore --source=guard/auto-backup -- <file>` | Copy file from `.cursor-guard-backup/<ts>/<file>` to original path |
|
|
211
211
|
| **Requires Git** | Yes | No (fallback for non-git repos) |
|
|
212
212
|
|
|
213
213
|
**Priority order for the agent:**
|
|
214
214
|
|
|
215
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
|
|
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
217
|
3. **Shadow copy** (`.cursor-guard-backup/`) — fallback for non-git repos, or as extra insurance when `backup_strategy = "both"`.
|
|
218
218
|
4. **Editor habits** — Ctrl+S frequently; optional extensions are user-configured, mention only if asked.
|
|
219
219
|
|
|
@@ -267,7 +267,7 @@ If unclear, ask: "你想恢复哪个文件?还是整个项目?" / "Which fil
|
|
|
267
267
|
git log --oneline --before="5 minutes ago" -5 -- <file>
|
|
268
268
|
|
|
269
269
|
# Auto-backup branch (if exists)
|
|
270
|
-
git log
|
|
270
|
+
git log guard/auto-backup --oneline --before="5 minutes ago" -5 -- <file>
|
|
271
271
|
|
|
272
272
|
# Reflog as fallback (shows all HEAD movements)
|
|
273
273
|
git reflog --before="5 minutes ago" -5
|
|
@@ -291,7 +291,7 @@ git log --oneline -<N+5> -- <file>
|
|
|
291
291
|
git show HEAD~<N>:<file>
|
|
292
292
|
|
|
293
293
|
# Auto-backup branch
|
|
294
|
-
git log
|
|
294
|
+
git log guard/auto-backup --oneline -<N+5> -- <file>
|
|
295
295
|
```
|
|
296
296
|
|
|
297
297
|
### Step 3: Present Candidates to User
|
|
@@ -314,7 +314,7 @@ Recommended: #1 (closest to target time). Restore this one? / 推荐 #1(最接
|
|
|
314
314
|
- If only ONE candidate is found, confirm with the user before restoring.
|
|
315
315
|
- If MULTIPLE candidates, pre-select #1 (closest before target) but let the user pick another.
|
|
316
316
|
- If NO candidates before the target time:
|
|
317
|
-
- Check auto-backup
|
|
317
|
+
- Check auto-backup ref: `git rev-parse --verify refs/guard/auto-backup`
|
|
318
318
|
- Check shadow copies: `Get-ChildItem .cursor-guard-backup/ -Directory | Sort-Object Name -Descending`
|
|
319
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
320
|
- **Never silently pick a version.** Always show and confirm.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-guard",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Protects code from accidental AI overwrite or deletion in Cursor IDE — mandatory pre-write snapshots, review-before-apply, local Git safety net, and deterministic recovery. | 保护代码免受 Cursor AI 代理意外覆写或删除——强制写前快照、预览再执行、本地 Git 安全网、确定性恢复。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cursor",
|
|
@@ -51,7 +51,7 @@ Blacklist glob patterns. Matching files are excluded from protection even if the
|
|
|
51
51
|
|
|
52
52
|
| Value | Description |
|
|
53
53
|
|-------|-------------|
|
|
54
|
-
| `"git"` | Local commits to dedicated
|
|
54
|
+
| `"git"` | Local commits to dedicated ref `refs/guard/auto-backup` |
|
|
55
55
|
| `"shadow"` | File copies to `.cursor-guard-backup/<timestamp>/` |
|
|
56
56
|
| `"both"` | Git branch snapshot + shadow copies |
|
|
57
57
|
|
|
@@ -155,7 +155,7 @@ Retention policy for **shadow copies** only. Git branch snapshots are not auto-c
|
|
|
155
155
|
- **Type**: `object`
|
|
156
156
|
- **Default**: `{ "enabled": false, "mode": "count", "max_count": 200 }`
|
|
157
157
|
|
|
158
|
-
Retention policy for the **`
|
|
158
|
+
Retention policy for the **`refs/guard/auto-backup` Git ref**. By default, auto-backup commits accumulate indefinitely. Enable this to automatically prune old commits.
|
|
159
159
|
|
|
160
160
|
### Sub-fields
|
|
161
161
|
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
| 值 | 说明 |
|
|
53
53
|
|----|------|
|
|
54
|
-
| `"git"` |
|
|
54
|
+
| `"git"` | 提交到专用引用 `refs/guard/auto-backup` |
|
|
55
55
|
| `"shadow"` | 文件拷贝到 `.cursor-guard-backup/<timestamp>/` |
|
|
56
56
|
| `"both"` | Git 分支快照 + 影子拷贝同时进行 |
|
|
57
57
|
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
- **类型**:`object`
|
|
156
156
|
- **默认值**:`{ "enabled": false, "mode": "count", "max_count": 200 }`
|
|
157
157
|
|
|
158
|
-
**`
|
|
158
|
+
**`refs/guard/auto-backup` Git 引用**的保留策略。默认情况下自动备份提交会无限累积。启用此项可自动裁剪旧提交。
|
|
159
159
|
|
|
160
160
|
### 子字段
|
|
161
161
|
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
"git_retention": {
|
|
77
77
|
"type": "object",
|
|
78
|
-
"description": "Controls automatic cleanup of old commits on
|
|
78
|
+
"description": "Controls automatic cleanup of old commits on refs/guard/auto-backup.",
|
|
79
79
|
"properties": {
|
|
80
80
|
"enabled": {
|
|
81
81
|
"type": "boolean",
|
|
@@ -400,13 +400,24 @@ async function runBackup(projectDir, intervalOverride) {
|
|
|
400
400
|
process.on('exit', cleanup);
|
|
401
401
|
|
|
402
402
|
// Git-specific setup
|
|
403
|
-
const
|
|
404
|
-
const
|
|
403
|
+
const branchRef = 'refs/guard/auto-backup';
|
|
404
|
+
const legacyRef = 'refs/heads/cursor-guard/auto-backup';
|
|
405
405
|
if (repo) {
|
|
406
406
|
const exists = git(['rev-parse', '--verify', branchRef], { cwd: projectDir, allowFail: true });
|
|
407
407
|
if (!exists) {
|
|
408
|
-
|
|
409
|
-
|
|
408
|
+
// Migrate from legacy refs/heads/ location if it exists
|
|
409
|
+
const legacyHash = git(['rev-parse', '--verify', legacyRef], { cwd: projectDir, allowFail: true });
|
|
410
|
+
if (legacyHash) {
|
|
411
|
+
git(['update-ref', branchRef, legacyHash], { cwd: projectDir, allowFail: true });
|
|
412
|
+
git(['update-ref', '-d', legacyRef], { cwd: projectDir, allowFail: true });
|
|
413
|
+
console.log(color.green(`[guard] Migrated ${legacyRef} → ${branchRef}`));
|
|
414
|
+
} else {
|
|
415
|
+
const head = git(['rev-parse', 'HEAD'], { cwd: projectDir, allowFail: true });
|
|
416
|
+
if (head) {
|
|
417
|
+
git(['update-ref', branchRef, head], { cwd: projectDir, allowFail: true });
|
|
418
|
+
console.log(color.green(`[guard] Created ref: ${branchRef}`));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
410
421
|
}
|
|
411
422
|
|
|
412
423
|
const excludeFile = path.join(gDir, 'info', 'exclude');
|
|
@@ -434,7 +445,7 @@ async function runBackup(projectDir, intervalOverride) {
|
|
|
434
445
|
// Banner
|
|
435
446
|
console.log('');
|
|
436
447
|
console.log(color.cyan(`[guard] Watching '${projectDir}' every ${interval}s (Ctrl+C to stop)`));
|
|
437
|
-
console.log(color.cyan(`[guard] Strategy: ${cfg.backup_strategy} |
|
|
448
|
+
console.log(color.cyan(`[guard] Strategy: ${cfg.backup_strategy} | Ref: ${branchRef} | Retention: ${cfg.retention.mode}`));
|
|
438
449
|
console.log(color.cyan(`[guard] Log: ${logFilePath}`));
|
|
439
450
|
console.log('');
|
|
440
451
|
|
|
@@ -81,15 +81,20 @@ function runDoctor(projectDir) {
|
|
|
81
81
|
check('Strategy compatibility', 'FAIL', `unknown backup_strategy='${strategy}' (must be git/shadow/both)`);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
// 5. Backup
|
|
84
|
+
// 5. Backup ref
|
|
85
85
|
if (repo) {
|
|
86
|
-
const
|
|
87
|
-
const
|
|
86
|
+
const guardRef = 'refs/guard/auto-backup';
|
|
87
|
+
const legacyRef = 'refs/heads/cursor-guard/auto-backup';
|
|
88
|
+
const exists = git(['rev-parse', '--verify', guardRef], { cwd: projectDir, allowFail: true });
|
|
89
|
+
const legacyExists = git(['rev-parse', '--verify', legacyRef], { cwd: projectDir, allowFail: true });
|
|
88
90
|
if (exists) {
|
|
89
|
-
const count = git(['rev-list', '--count',
|
|
90
|
-
check('Backup
|
|
91
|
+
const count = git(['rev-list', '--count', guardRef], { cwd: projectDir, allowFail: true }) || '?';
|
|
92
|
+
check('Backup ref', 'PASS', `refs/guard/auto-backup exists (${count} commits)`);
|
|
93
|
+
} else if (legacyExists) {
|
|
94
|
+
const count = git(['rev-list', '--count', legacyRef], { cwd: projectDir, allowFail: true }) || '?';
|
|
95
|
+
check('Backup ref', 'WARN', `legacy refs/heads/cursor-guard/auto-backup found (${count} commits) — run auto-backup once to migrate`);
|
|
91
96
|
} else {
|
|
92
|
-
check('Backup
|
|
97
|
+
check('Backup ref', 'WARN', 'refs/guard/auto-backup not created yet (will be created on first backup)');
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
100
|
|
package/references/recovery.md
CHANGED
|
@@ -268,24 +268,24 @@ The `auto-backup.ps1` script stores periodic snapshots on a dedicated branch via
|
|
|
268
268
|
|
|
269
269
|
```bash
|
|
270
270
|
# List recent auto-backup snapshots
|
|
271
|
-
git log
|
|
271
|
+
git log guard/auto-backup --oneline -20
|
|
272
272
|
|
|
273
273
|
# Restore a file from the latest auto-backup
|
|
274
|
-
git restore --source=
|
|
274
|
+
git restore --source=guard/auto-backup -- <path/to/file>
|
|
275
275
|
|
|
276
276
|
# Restore from a specific auto-backup snapshot
|
|
277
277
|
git restore --source=<commit-hash> -- <path/to/file>
|
|
278
278
|
|
|
279
279
|
# Diff your working copy against the auto-backup version
|
|
280
|
-
git diff
|
|
280
|
+
git diff guard/auto-backup -- <path/to/file>
|
|
281
281
|
|
|
282
282
|
# Time-based: find auto-backup snapshot from before N minutes ago
|
|
283
283
|
# 按时间查找:N 分钟前之前最近的自动备份快照
|
|
284
|
-
git log
|
|
284
|
+
git log guard/auto-backup --oneline --before="5 minutes ago" -5 -- <path/to/file>
|
|
285
285
|
|
|
286
286
|
# Version-based: list recent N auto-backup snapshots
|
|
287
287
|
# 按版本查找:最近 N 个自动备份快照
|
|
288
|
-
git log
|
|
288
|
+
git log guard/auto-backup --oneline -10 -- <path/to/file>
|
|
289
289
|
```
|
|
290
290
|
|
|
291
291
|
## If not a Git repo yet
|
|
@@ -374,10 +374,10 @@ Get-ChildItem .cursor-guard-backup/ -Directory | Where-Object {
|
|
|
374
374
|
|
|
375
375
|
```bash
|
|
376
376
|
# View auto-backup history
|
|
377
|
-
git log
|
|
377
|
+
git log guard/auto-backup --oneline -30
|
|
378
378
|
|
|
379
379
|
# Delete the branch entirely (script will recreate it on next run)
|
|
380
|
-
git
|
|
380
|
+
git update-ref -d refs/guard/auto-backup
|
|
381
381
|
|
|
382
382
|
# Reclaim disk space after removing old branches
|
|
383
383
|
git gc --prune=now
|