cursor-guard 4.0.0 → 4.2.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 +64 -17
- package/README.zh-CN.md +64 -17
- package/SKILL.md +4 -1
- package/package.json +5 -2
- package/references/bin/cursor-guard-init.js +122 -0
- package/references/dashboard/public/app.js +1068 -0
- package/references/dashboard/public/index.html +106 -0
- package/references/dashboard/public/style.css +666 -0
- package/references/dashboard/server.js +207 -0
- package/references/lib/core/doctor.js +48 -7
- package/references/lib/core/restore.js +25 -1
- package/references/lib/core/snapshot.js +6 -5
- package/references/lib/utils.js +7 -2
- package/references/mcp/server.js +9 -1
package/README.md
CHANGED
|
@@ -24,45 +24,53 @@ When Cursor's AI agent edits your files, there's a risk of accidental overwrites
|
|
|
24
24
|
- **Auto-fix diagnostics** — `doctor_fix` automatically patches missing configs, uninitialized Git repos, gitignore gaps, and stale locks
|
|
25
25
|
- **Proactive change-velocity alerts (V4)** — Auto-detects abnormal file change patterns and raises risk warnings
|
|
26
26
|
- **Backup health dashboard (V4)** — One-call comprehensive view: strategy, counts, disk usage, protection scope, health status
|
|
27
|
+
- **Web dashboard (V4.2)** — Local read-only web UI at `http://127.0.0.1:3120` — see health, backups, restore points, diagnostics, protection scope at a glance. Dual-language (zh-CN / en-US), auto-refresh every 15s, multi-project support
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
30
31
|
## Installation
|
|
31
32
|
|
|
32
|
-
### Method 1: npm
|
|
33
|
+
### Method 1: npm (Recommended)
|
|
33
34
|
|
|
34
35
|
```bash
|
|
35
36
|
npm install cursor-guard
|
|
37
|
+
npx cursor-guard-init
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
The `init` command copies skill files to `.cursor/skills/cursor-guard/`, installs MCP dependencies, and adds `.gitignore` entries — all in one step.
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
Options:
|
|
41
43
|
|
|
42
|
-
```
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# Per-project (current project only)
|
|
47
|
-
Copy-Item -Recurse node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
44
|
+
```bash
|
|
45
|
+
npx cursor-guard-init # project-local (default)
|
|
46
|
+
npx cursor-guard-init --global # global (~/.cursor/skills/)
|
|
47
|
+
npx cursor-guard-init --path /my/project # specify project root
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
After init, the npm package in `node_modules` is no longer needed:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
|
|
54
|
-
cp -r node_modules/cursor-guard ~/.cursor/skills/cursor-guard
|
|
55
|
-
|
|
56
|
-
# Per-project
|
|
57
|
-
cp -r node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
53
|
+
npm uninstall cursor-guard
|
|
58
54
|
```
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
<details>
|
|
57
|
+
<summary>Manual installation (without init command)</summary>
|
|
58
|
+
|
|
59
|
+
If you prefer manual setup, copy files then install dependencies:
|
|
61
60
|
|
|
62
61
|
```bash
|
|
63
|
-
|
|
62
|
+
# Copy
|
|
63
|
+
cp -r node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
64
|
+
|
|
65
|
+
# Install MCP dependencies in the skill directory
|
|
66
|
+
cd .cursor/skills/cursor-guard && npm install --omit=dev && cd -
|
|
67
|
+
|
|
68
|
+
# Add to .gitignore so node_modules aren't captured by git snapshots
|
|
69
|
+
echo ".cursor/skills/**/node_modules/" >> .gitignore
|
|
64
70
|
```
|
|
65
71
|
|
|
72
|
+
</details>
|
|
73
|
+
|
|
66
74
|
### Method 2: Git clone
|
|
67
75
|
|
|
68
76
|
```bash
|
|
@@ -108,6 +116,12 @@ After installation, your directory structure should look like this:
|
|
|
108
116
|
│ ├── status.js # Backup system status
|
|
109
117
|
│ ├── anomaly.js # V4: Change-velocity detection
|
|
110
118
|
│ └── dashboard.js # V4: Health dashboard aggregation
|
|
119
|
+
├── dashboard/
|
|
120
|
+
│ ├── server.js # Dashboard HTTP server + API
|
|
121
|
+
│ └── public/ # Web UI (HTML/CSS/JS)
|
|
122
|
+
│ ├── index.html
|
|
123
|
+
│ ├── style.css
|
|
124
|
+
│ └── app.js
|
|
111
125
|
├── mcp/
|
|
112
126
|
│ └── server.js # MCP Server (9 tools)
|
|
113
127
|
├── bin/
|
|
@@ -242,6 +256,37 @@ npx cursor-guard-doctor --path /my/project
|
|
|
242
256
|
|
|
243
257
|
> **Note**: Run backup/doctor scripts in a separate terminal, NOT inside Cursor's integrated terminal.
|
|
244
258
|
|
|
259
|
+
### Web Dashboard
|
|
260
|
+
|
|
261
|
+
A local read-only web page for monitoring backup health, restore points, protection scope, and diagnostics — all in one view.
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Monitor a single project
|
|
265
|
+
npx cursor-guard-dashboard --path /my/project
|
|
266
|
+
|
|
267
|
+
# Monitor multiple projects
|
|
268
|
+
npx cursor-guard-dashboard --path /project-a --path /project-b
|
|
269
|
+
|
|
270
|
+
# Custom port (default: 3120)
|
|
271
|
+
npx cursor-guard-dashboard --path /my/project --port 8080
|
|
272
|
+
|
|
273
|
+
# Windows PowerShell (from skill directory)
|
|
274
|
+
node references\dashboard\server.js --path "D:\MyProject"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Then open `http://127.0.0.1:3120` in your browser.
|
|
278
|
+
|
|
279
|
+
Features:
|
|
280
|
+
|
|
281
|
+
- **Read-only** — no write operations, safe to run anytime
|
|
282
|
+
- **Dual-language** — zh-CN / en-US, auto-detects system language, manual toggle in top-right
|
|
283
|
+
- **Auto-refresh** — pulls data every 15 seconds, plus manual refresh button
|
|
284
|
+
- **Multi-project** — pass multiple `--path` args to monitor several projects from one page
|
|
285
|
+
- **4 sections**: Overview (health + watcher + alerts + latest backups), Backups & Recovery (restore point table with type filters), Protection Scope (protect/ignore patterns), Diagnostics (doctor checks)
|
|
286
|
+
- **2 detail drawers**: Restore Point drawer (preview JSON, copy ref/hash), Doctor drawer (full check list, WARN/FAIL expanded by default)
|
|
287
|
+
- **Security** — binds to `127.0.0.1` only (not exposed to LAN), API uses project IDs instead of raw file paths, static file serving restricted to `public/` directory
|
|
288
|
+
- **Zero extra dependencies** — uses Node.js built-in `http` module + existing cursor-guard core modules
|
|
289
|
+
|
|
245
290
|
---
|
|
246
291
|
|
|
247
292
|
## Recovery
|
|
@@ -318,6 +363,8 @@ The skill activates on these signals:
|
|
|
318
363
|
| `references/lib/utils.js` | Shared utilities (config, glob, git, manifest) |
|
|
319
364
|
| `references/bin/cursor-guard-backup.js` | CLI entry: `npx cursor-guard-backup` |
|
|
320
365
|
| `references/bin/cursor-guard-doctor.js` | CLI entry: `npx cursor-guard-doctor` |
|
|
366
|
+
| `references/dashboard/server.js` | Dashboard HTTP server + REST API |
|
|
367
|
+
| `references/dashboard/public/` | Dashboard web UI (index.html, style.css, app.js) |
|
|
321
368
|
| `references/auto-backup.ps1` / `.sh` | Thin wrappers (Windows / macOS+Linux) |
|
|
322
369
|
| `references/guard-doctor.ps1` / `.sh` | Thin wrappers (Windows / macOS+Linux) |
|
|
323
370
|
| `references/recovery.md` | Recovery command templates |
|
package/README.zh-CN.md
CHANGED
|
@@ -24,45 +24,53 @@
|
|
|
24
24
|
- **自动诊断修复** — `doctor_fix` 一键修补缺失配置、未初始化 Git、gitignore 遗漏等常见问题
|
|
25
25
|
- **主动变更频率告警(V4)** — 自动检测异常文件变更模式并发出风险预警
|
|
26
26
|
- **备份健康看板(V4)** — 一次调用全面查看:策略、数量、磁盘占用、保护范围、健康状态
|
|
27
|
+
- **Web 仪表盘(V4.2)** — 本地只读 Web 页面 `http://127.0.0.1:3120`——健康状态、备份、恢复点、诊断、保护范围一目了然。中英双语、每 15 秒自动刷新、支持多项目监控
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
30
31
|
## 安装
|
|
31
32
|
|
|
32
|
-
### 方式一:npm
|
|
33
|
+
### 方式一:npm 安装(推荐)
|
|
33
34
|
|
|
34
35
|
```bash
|
|
35
36
|
npm install cursor-guard
|
|
37
|
+
npx cursor-guard-init
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
`init` 命令一键完成:复制技能文件到 `.cursor/skills/cursor-guard/`、安装 MCP 依赖、添加 `.gitignore` 条目。
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
可选参数:
|
|
41
43
|
|
|
42
|
-
```
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# 项目级安装(仅当前项目生效)
|
|
47
|
-
Copy-Item -Recurse node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
44
|
+
```bash
|
|
45
|
+
npx cursor-guard-init # 项目级安装(默认)
|
|
46
|
+
npx cursor-guard-init --global # 全局安装(~/.cursor/skills/)
|
|
47
|
+
npx cursor-guard-init --path /my/project # 指定项目根目录
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
初始化完成后,`node_modules` 中的 npm 包已不再需要:
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
|
-
|
|
54
|
-
cp -r node_modules/cursor-guard ~/.cursor/skills/cursor-guard
|
|
55
|
-
|
|
56
|
-
# 项目级安装
|
|
57
|
-
cp -r node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
53
|
+
npm uninstall cursor-guard
|
|
58
54
|
```
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
<details>
|
|
57
|
+
<summary>手动安装(不使用 init 命令)</summary>
|
|
58
|
+
|
|
59
|
+
如果你更喜欢手动操作,复制文件后需要手动安装依赖:
|
|
61
60
|
|
|
62
61
|
```bash
|
|
63
|
-
|
|
62
|
+
# 复制
|
|
63
|
+
cp -r node_modules/cursor-guard .cursor/skills/cursor-guard
|
|
64
|
+
|
|
65
|
+
# 在 skill 目录中安装 MCP 依赖
|
|
66
|
+
cd .cursor/skills/cursor-guard && npm install --omit=dev && cd -
|
|
67
|
+
|
|
68
|
+
# 添加到 .gitignore,防止 node_modules 被 git 快照捕获
|
|
69
|
+
echo ".cursor/skills/**/node_modules/" >> .gitignore
|
|
64
70
|
```
|
|
65
71
|
|
|
72
|
+
</details>
|
|
73
|
+
|
|
66
74
|
### 方式二:Git 克隆
|
|
67
75
|
|
|
68
76
|
```bash
|
|
@@ -108,6 +116,12 @@ git clone https://github.com/zhangqiang8vipp/cursor-guard.git .cursor/skills/cur
|
|
|
108
116
|
│ ├── status.js # 备份系统状态
|
|
109
117
|
│ ├── anomaly.js # V4:变更频率检测
|
|
110
118
|
│ └── dashboard.js # V4:健康看板聚合
|
|
119
|
+
├── dashboard/
|
|
120
|
+
│ ├── server.js # 仪表盘 HTTP 服务 + API
|
|
121
|
+
│ └── public/ # Web UI(HTML/CSS/JS)
|
|
122
|
+
│ ├── index.html
|
|
123
|
+
│ ├── style.css
|
|
124
|
+
│ └── app.js
|
|
111
125
|
├── mcp/
|
|
112
126
|
│ └── server.js # MCP Server(9 个工具)
|
|
113
127
|
├── bin/
|
|
@@ -242,6 +256,37 @@ npx cursor-guard-doctor --path /my/project
|
|
|
242
256
|
|
|
243
257
|
> **注意**:请在独立终端窗口中运行备份/检查脚本,不要在 Cursor 集成终端中运行。
|
|
244
258
|
|
|
259
|
+
### Web 仪表盘
|
|
260
|
+
|
|
261
|
+
本地只读 Web 页面,一页查看备份健康状态、恢复点、保护范围和诊断结果。
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# 监控单个项目
|
|
265
|
+
npx cursor-guard-dashboard --path /my/project
|
|
266
|
+
|
|
267
|
+
# 监控多个项目
|
|
268
|
+
npx cursor-guard-dashboard --path /project-a --path /project-b
|
|
269
|
+
|
|
270
|
+
# 自定义端口(默认 3120)
|
|
271
|
+
npx cursor-guard-dashboard --path /my/project --port 8080
|
|
272
|
+
|
|
273
|
+
# Windows PowerShell(从 skill 目录运行)
|
|
274
|
+
node references\dashboard\server.js --path "D:\MyProject"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
然后在浏览器打开 `http://127.0.0.1:3120`。
|
|
278
|
+
|
|
279
|
+
特性:
|
|
280
|
+
|
|
281
|
+
- **只读** — 不执行任何写操作,随时可以安全运行
|
|
282
|
+
- **中英双语** — zh-CN / en-US,自动检测系统语言,右上角手动切换
|
|
283
|
+
- **自动刷新** — 每 15 秒拉取数据,支持手动刷新按钮
|
|
284
|
+
- **多项目** — 传多个 `--path` 参数可从一个页面监控多个项目
|
|
285
|
+
- **4 个区块**:总览(健康状态 + 守护进程 + 告警 + 最近备份)、备份与恢复(恢复点表格,按类型过滤)、保护范围(protect/ignore 规则)、诊断(doctor 检查项)
|
|
286
|
+
- **2 个详情抽屉**:恢复点抽屉(预览 JSON、复制引用/hash)、诊断抽屉(完整检查列表,WARN/FAIL 默认展开)
|
|
287
|
+
- **安全性** — 仅绑定 `127.0.0.1`(不暴露到局域网)、API 使用项目 ID 而非原始路径、静态文件服务严格限制在 `public/` 目录
|
|
288
|
+
- **零额外依赖** — 使用 Node.js 内置 `http` 模块 + cursor-guard 已有核心模块
|
|
289
|
+
|
|
245
290
|
---
|
|
246
291
|
|
|
247
292
|
## 恢复
|
|
@@ -318,6 +363,8 @@ npx cursor-guard-doctor --path /my/project
|
|
|
318
363
|
| `references/lib/utils.js` | 共享工具库(配置、glob、git、manifest) |
|
|
319
364
|
| `references/bin/cursor-guard-backup.js` | CLI 入口:`npx cursor-guard-backup` |
|
|
320
365
|
| `references/bin/cursor-guard-doctor.js` | CLI 入口:`npx cursor-guard-doctor` |
|
|
366
|
+
| `references/dashboard/server.js` | 仪表盘 HTTP 服务 + REST API |
|
|
367
|
+
| `references/dashboard/public/` | 仪表盘 Web UI(index.html、style.css、app.js) |
|
|
321
368
|
| `references/auto-backup.ps1` / `.sh` | 薄封装(Windows / macOS+Linux) |
|
|
322
369
|
| `references/guard-doctor.ps1` / `.sh` | 薄封装(Windows / macOS+Linux) |
|
|
323
370
|
| `references/recovery.md` | 恢复命令模板 |
|
package/SKILL.md
CHANGED
|
@@ -202,7 +202,7 @@ git update-ref refs/guard/snapshot $commit
|
|
|
202
202
|
|
|
203
203
|
1. **Quick git init** (preferred):
|
|
204
204
|
```
|
|
205
|
-
git init
|
|
205
|
+
git init; git add -A; git commit -m "guard: initial snapshot" --no-verify
|
|
206
206
|
```
|
|
207
207
|
2. **Shadow copy** (fallback if user declines git):
|
|
208
208
|
- Copy the target file(s) to `.cursor-guard-backup/<timestamp>/` via Shell.
|
|
@@ -488,6 +488,7 @@ Current version preserved before restore:
|
|
|
488
488
|
> - Project preview: `restore_project { "path": "<project>", "source": "<hash>", "preview": true }` — returns the list of files that would change.
|
|
489
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
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
|
+
> - **`.cursor/` protection**: `restore_project` automatically preserves the `.cursor/` directory (including skills, MCP configs, rules) from HEAD after restoring. Preview results mark `.cursor/` files with a `warning` field. If a user explicitly wants to restore `.cursor/` contents, they must do so file-by-file via `restore_file`.
|
|
491
492
|
|
|
492
493
|
**Single file recovery:**
|
|
493
494
|
|
|
@@ -568,6 +569,7 @@ Skip the block for unrelated turns.
|
|
|
568
569
|
11. **Use `--no-verify`** on all guard snapshot commits to bypass pre-commit hooks that could fail or modify files.
|
|
569
570
|
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
571
|
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.
|
|
572
|
+
14. **Do not restore `.cursor/` directory** — `.cursor/skills/`, `.cursor/rules/`, and `.cursor/mcp.json` are tool infrastructure, not project code. `restore_project` automatically protects this directory. Never include `.cursor/` in manual restore commands unless the user explicitly requests it. Restoring `.cursor/skills/cursor-guard/` would downgrade the protection tool itself.
|
|
571
573
|
|
|
572
574
|
---
|
|
573
575
|
|
|
@@ -586,6 +588,7 @@ Skip the block for unrelated turns.
|
|
|
586
588
|
- Guard doctor (Node.js core): [references/lib/guard-doctor.js](references/lib/guard-doctor.js)
|
|
587
589
|
- Core modules: [references/lib/core/](references/lib/core/) (doctor, doctor-fix, snapshot, backups, restore, status, anomaly, dashboard)
|
|
588
590
|
- 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)
|
|
591
|
+
- Web dashboard: [references/dashboard/](references/dashboard/) (local read-only web UI — `node references/dashboard/server.js --path <project>`)
|
|
589
592
|
- Shared utilities: [references/lib/utils.js](references/lib/utils.js)
|
|
590
593
|
- Config JSON Schema: [references/cursor-guard.schema.json](references/cursor-guard.schema.json)
|
|
591
594
|
- Example config: [references/cursor-guard.example.json](references/cursor-guard.example.json)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-guard",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.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",
|
|
@@ -27,9 +27,11 @@
|
|
|
27
27
|
"test": "node references/lib/utils.test.js && node references/lib/core/core.test.js && node references/mcp/mcp.test.js"
|
|
28
28
|
},
|
|
29
29
|
"bin": {
|
|
30
|
+
"cursor-guard-init": "references/bin/cursor-guard-init.js",
|
|
30
31
|
"cursor-guard-backup": "references/bin/cursor-guard-backup.js",
|
|
31
32
|
"cursor-guard-doctor": "references/bin/cursor-guard-doctor.js",
|
|
32
|
-
"cursor-guard-mcp": "references/mcp/server.js"
|
|
33
|
+
"cursor-guard-mcp": "references/mcp/server.js",
|
|
34
|
+
"cursor-guard-dashboard": "references/dashboard/server.js"
|
|
33
35
|
},
|
|
34
36
|
"files": [
|
|
35
37
|
"SKILL.md",
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
"references/lib/utils.js",
|
|
48
50
|
"references/lib/core/",
|
|
49
51
|
"references/mcp/",
|
|
52
|
+
"references/dashboard/",
|
|
50
53
|
"references/config-reference.md",
|
|
51
54
|
"references/config-reference.zh-CN.md",
|
|
52
55
|
"references/cursor-guard.example.json",
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const { execFileSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
const args = process.argv.slice(2);
|
|
10
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
11
|
+
console.log(`Usage: cursor-guard-init [options]
|
|
12
|
+
|
|
13
|
+
Installs cursor-guard skill into your Cursor skills directory, including
|
|
14
|
+
MCP dependencies and .gitignore entries.
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--global Install to ~/.cursor/skills/ (default: project-local)
|
|
18
|
+
--path <dir> Project directory (default: current dir)
|
|
19
|
+
--help, -h Show this help message
|
|
20
|
+
--version, -v Show version number`);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
25
|
+
const pkg = require('../../package.json');
|
|
26
|
+
console.log(pkg.version);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const isGlobal = args.includes('--global');
|
|
31
|
+
const pathIdx = args.indexOf('--path');
|
|
32
|
+
const projectDir = path.resolve(pathIdx >= 0 && args[pathIdx + 1] ? args[pathIdx + 1] : '.');
|
|
33
|
+
|
|
34
|
+
const skillSource = path.resolve(__dirname, '../..');
|
|
35
|
+
const skillTarget = isGlobal
|
|
36
|
+
? path.join(process.env.USERPROFILE || process.env.HOME || os.homedir(), '.cursor', 'skills', 'cursor-guard')
|
|
37
|
+
: path.join(projectDir, '.cursor', 'skills', 'cursor-guard');
|
|
38
|
+
|
|
39
|
+
function copyRecursive(src, dest) {
|
|
40
|
+
const stat = fs.statSync(src);
|
|
41
|
+
if (stat.isDirectory()) {
|
|
42
|
+
if (path.basename(src) === 'node_modules') return;
|
|
43
|
+
if (path.basename(src) === '.git') return;
|
|
44
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
45
|
+
for (const entry of fs.readdirSync(src)) {
|
|
46
|
+
copyRecursive(path.join(src, entry), path.join(dest, entry));
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
50
|
+
fs.copyFileSync(src, dest);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log(`\n cursor-guard init\n`);
|
|
55
|
+
console.log(` Source: ${skillSource}`);
|
|
56
|
+
console.log(` Target: ${skillTarget}`);
|
|
57
|
+
console.log(` Mode: ${isGlobal ? 'global (~/.cursor/skills/)' : 'project-local (.cursor/skills/)'}\n`);
|
|
58
|
+
|
|
59
|
+
// Step 1: Copy skill files (excluding node_modules and .git)
|
|
60
|
+
console.log(' [1/4] Copying skill files...');
|
|
61
|
+
if (fs.existsSync(skillTarget)) {
|
|
62
|
+
fs.rmSync(skillTarget, { recursive: true, force: true });
|
|
63
|
+
}
|
|
64
|
+
copyRecursive(skillSource, skillTarget);
|
|
65
|
+
console.log(' Done.');
|
|
66
|
+
|
|
67
|
+
// Step 2: Install MCP dependencies in skill directory
|
|
68
|
+
console.log(' [2/4] Installing MCP dependencies...');
|
|
69
|
+
try {
|
|
70
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
71
|
+
execFileSync(npmCmd, ['install', '--omit=dev', '--ignore-scripts'], {
|
|
72
|
+
cwd: skillTarget,
|
|
73
|
+
stdio: 'pipe',
|
|
74
|
+
});
|
|
75
|
+
console.log(' Done.');
|
|
76
|
+
} catch (e) {
|
|
77
|
+
console.log(` Warning: npm install failed (${e.message}). MCP tools may not work.`);
|
|
78
|
+
console.log(' You can fix this later: cd "' + skillTarget + '" ; npm install');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Step 3: Add .gitignore entries for skill node_modules
|
|
82
|
+
console.log(' [3/4] Updating .gitignore...');
|
|
83
|
+
const gitignorePath = path.join(projectDir, '.gitignore');
|
|
84
|
+
const entries = ['.cursor/skills/**/node_modules/'];
|
|
85
|
+
let gitignoreUpdated = false;
|
|
86
|
+
if (!isGlobal) {
|
|
87
|
+
let existing = '';
|
|
88
|
+
try { existing = fs.readFileSync(gitignorePath, 'utf-8'); } catch { /* doesn't exist */ }
|
|
89
|
+
const missing = entries.filter(e => !existing.includes(e));
|
|
90
|
+
if (missing.length > 0) {
|
|
91
|
+
const newline = existing.endsWith('\n') || !existing ? '' : '\n';
|
|
92
|
+
fs.appendFileSync(gitignorePath, `${newline}# cursor-guard skill dependencies\n${missing.join('\n')}\n`);
|
|
93
|
+
gitignoreUpdated = true;
|
|
94
|
+
console.log(' Added: ' + missing.join(', '));
|
|
95
|
+
} else {
|
|
96
|
+
console.log(' Already configured.');
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
console.log(' Skipped (global install, not inside a project).');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Step 4: Summary
|
|
103
|
+
console.log(' [4/4] Verifying...');
|
|
104
|
+
const serverExists = fs.existsSync(path.join(skillTarget, 'references', 'mcp', 'server.js'));
|
|
105
|
+
const sdkExists = fs.existsSync(path.join(skillTarget, 'node_modules', '@modelcontextprotocol', 'sdk'));
|
|
106
|
+
const skillMdExists = fs.existsSync(path.join(skillTarget, 'SKILL.md'));
|
|
107
|
+
|
|
108
|
+
console.log(` SKILL.md: ${skillMdExists ? 'OK' : 'MISSING'}`);
|
|
109
|
+
console.log(` MCP server: ${serverExists ? 'OK' : 'MISSING'}`);
|
|
110
|
+
console.log(` MCP SDK: ${sdkExists ? 'OK' : 'MISSING — run npm install in skill dir'}`);
|
|
111
|
+
|
|
112
|
+
console.log(`\n Installation complete!\n`);
|
|
113
|
+
console.log(' ⚠ If MCP was already configured, restart Cursor (or Ctrl+Shift+P →');
|
|
114
|
+
console.log(' "Developer: Reload Window") to load the updated MCP server.\n');
|
|
115
|
+
console.log(' Next steps:');
|
|
116
|
+
console.log(' 1. The skill activates automatically in Cursor Agent conversations.');
|
|
117
|
+
console.log(' 2. (Optional) Copy example config to project root:');
|
|
118
|
+
console.log(` cp "${path.join(skillTarget, 'references', 'cursor-guard.example.json')}" .cursor-guard.json`);
|
|
119
|
+
console.log(' 3. (Optional) Enable MCP — add to .cursor/mcp.json:');
|
|
120
|
+
console.log(` { "mcpServers": { "cursor-guard": { "command": "node", "args": ["${path.join(skillTarget, 'references', 'mcp', 'server.js').replace(/\\/g, '/')}"] } } }`);
|
|
121
|
+
console.log(' 4. (Optional) Start auto-backup:');
|
|
122
|
+
console.log(` npx cursor-guard-backup --path "${projectDir}"\n`);
|