cursor-guard 4.9.0 → 4.9.1
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/ROADMAP.md +8 -2
- package/package.json +1 -1
- package/references/vscode-extension/dist/{cursor-guard-ide-4.9.0.vsix → cursor-guard-ide-4.9.1.vsix} +0 -0
- package/references/vscode-extension/dist/guard-version.json +1 -1
- package/references/vscode-extension/dist/lib/sidebar-webview.js +24 -10
- package/references/vscode-extension/dist/mcp/server.js +1 -1
- package/references/vscode-extension/dist/package.json +1 -1
- package/references/vscode-extension/dist/skill/ROADMAP.md +8 -2
- package/references/vscode-extension/lib/sidebar-webview.js +24 -10
- package/references/vscode-extension/package.json +1 -1
package/ROADMAP.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> 本文档描述 cursor-guard 从 V2 到 V7 的长期演进方向。
|
|
4
4
|
> 每一代向下兼容,低版本功能永远不废弃。
|
|
5
5
|
>
|
|
6
|
-
> **当前版本**:`V4.9.
|
|
7
|
-
> **文档状态**:`V2` ~ `V4.9.
|
|
6
|
+
> **当前版本**:`V4.9.1`
|
|
7
|
+
> **文档状态**:`V2` ~ `V4.9.1` 已完成交付(含 V5 intent/audit 基础),`V5` 主体规划中
|
|
8
8
|
|
|
9
9
|
## 阅读导航
|
|
10
10
|
|
|
@@ -734,6 +734,12 @@ V4 经过 4 轮系统性代码审查,修复了以下关键问题:
|
|
|
734
734
|
}
|
|
735
735
|
```
|
|
736
736
|
|
|
737
|
+
### V4.9.1:侧边栏"Last backup"实时计时 ✅
|
|
738
|
+
|
|
739
|
+
| 优化 | 说明 |
|
|
740
|
+
|------|------|
|
|
741
|
+
| **备份时间实时跳动** | 侧边栏 Quick Stats 的 "Last backup Xs ago" 现在每秒自动更新,不再依赖 Poller 刷新周期。通过 `data-backup-ts` 属性传递时间戳,复用已有的 1s `setInterval` 计算相对时间 |
|
|
742
|
+
|
|
737
743
|
### V4.9.0:事件驱动架构 — 从轮询到实时响应 ✅
|
|
738
744
|
|
|
739
745
|
| 改造 | 说明 |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-guard",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.1",
|
|
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",
|
package/references/vscode-extension/dist/{cursor-guard-ide-4.9.0.vsix → cursor-guard-ide-4.9.1.vsix}
RENAMED
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"4.9.
|
|
1
|
+
{"version":"4.9.1"}
|
|
@@ -257,16 +257,25 @@ window.addEventListener('message', e => {
|
|
|
257
257
|
vscode.postMessage({ cmd: 'ready' });
|
|
258
258
|
|
|
259
259
|
setInterval(() => {
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
if (_alertExpiresAt) {
|
|
261
|
+
const el = document.querySelector('.alert-countdown');
|
|
262
|
+
if (el) {
|
|
263
|
+
const remain = Math.max(0, Math.ceil((_alertExpiresAt - Date.now()) / 1000));
|
|
264
|
+
if (remain <= 0) { el.textContent = '0s'; _alertExpiresAt = 0; }
|
|
265
|
+
else { el.textContent = remain > 60 ? Math.floor(remain / 60) + 'm ' + (remain % 60) + 's' : remain + 's'; }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const ageEl = document.querySelector('.backup-age[data-backup-ts]');
|
|
269
|
+
if (ageEl) {
|
|
270
|
+
const ts = parseInt(ageEl.dataset.backupTs, 10);
|
|
271
|
+
if (ts) {
|
|
272
|
+
const sec = Math.floor((Date.now() - ts) / 1000);
|
|
273
|
+
if (sec < 60) ageEl.textContent = sec + 's ago';
|
|
274
|
+
else if (sec < 3600) ageEl.textContent = Math.floor(sec / 60) + 'm ' + (sec % 60) + 's ago';
|
|
275
|
+
else if (sec < 86400) ageEl.textContent = Math.floor(sec / 3600) + 'h ' + Math.floor((sec % 3600) / 60) + 'm ago';
|
|
276
|
+
else ageEl.textContent = Math.floor(sec / 86400) + 'd ago';
|
|
277
|
+
}
|
|
268
278
|
}
|
|
269
|
-
el.textContent = remain > 60 ? Math.floor(remain / 60) + 'm ' + (remain % 60) + 's' : remain + 's';
|
|
270
279
|
}, 1000);
|
|
271
280
|
|
|
272
281
|
function render(projects) {
|
|
@@ -346,6 +355,7 @@ function renderProject(d) {
|
|
|
346
355
|
// ── Quick stats ──
|
|
347
356
|
const gitC = d.counts?.git?.commits || 0;
|
|
348
357
|
const shadowC = d.counts?.shadow?.snapshots || 0;
|
|
358
|
+
const lastGitTs = d.lastBackup?.git?.timestamp || '';
|
|
349
359
|
const lastGit = d.lastBackup?.git?.relativeTime || 'never';
|
|
350
360
|
const freeGB = d.disk?.freeGB;
|
|
351
361
|
const freeDisplay = typeof freeGB === 'number' ? freeGB.toFixed(1) + ' GB' : 'N/A';
|
|
@@ -353,7 +363,11 @@ function renderProject(d) {
|
|
|
353
363
|
|
|
354
364
|
h += '<div class="stats-card">';
|
|
355
365
|
h += '<div class="label-sm">Quick Stats</div>';
|
|
356
|
-
|
|
366
|
+
if (lastGitTs) {
|
|
367
|
+
h += '<div class="stat-row"><span class="name">Last backup</span><span class="val green backup-age" data-backup-ts="' + new Date(lastGitTs).getTime() + '">' + esc(lastGit) + '</span></div>';
|
|
368
|
+
} else {
|
|
369
|
+
h += statRow('Last backup', lastGit, 'green');
|
|
370
|
+
}
|
|
357
371
|
h += statRow('Git backups', gitC, 'blue');
|
|
358
372
|
if (shadowC > 0) h += statRow('Shadow copies', shadowC, 'blue');
|
|
359
373
|
h += statRow('Disk free', freeDisplay, diskWarn ? 'yellow' : 'green');
|
|
@@ -35568,7 +35568,7 @@ var require_package = __commonJS({
|
|
|
35568
35568
|
"package.json"(exports2, module2) {
|
|
35569
35569
|
module2.exports = {
|
|
35570
35570
|
name: "cursor-guard",
|
|
35571
|
-
version: "4.9.
|
|
35571
|
+
version: "4.9.1",
|
|
35572
35572
|
description: "Protects code from accidental AI overwrite or deletion in Cursor IDE \u2014 mandatory pre-write snapshots, review-before-apply, local Git safety net, and deterministic recovery. | \u4FDD\u62A4\u4EE3\u7801\u514D\u53D7 Cursor AI \u4EE3\u7406\u610F\u5916\u8986\u5199\u6216\u5220\u9664\u2014\u2014\u5F3A\u5236\u5199\u524D\u5FEB\u7167\u3001\u9884\u89C8\u518D\u6267\u884C\u3001\u672C\u5730 Git \u5B89\u5168\u7F51\u3001\u786E\u5B9A\u6027\u6062\u590D\u3002",
|
|
35573
35573
|
keywords: [
|
|
35574
35574
|
"cursor",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "cursor-guard-ide",
|
|
3
3
|
"displayName": "Cursor Guard",
|
|
4
4
|
"description": "AI code protection dashboard embedded in your IDE — real-time alerts, backup history, one-click snapshots",
|
|
5
|
-
"version": "4.9.
|
|
5
|
+
"version": "4.9.1",
|
|
6
6
|
"publisher": "zhangqiang8vipp",
|
|
7
7
|
"license": "BUSL-1.1",
|
|
8
8
|
"engines": {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> 本文档描述 cursor-guard 从 V2 到 V7 的长期演进方向。
|
|
4
4
|
> 每一代向下兼容,低版本功能永远不废弃。
|
|
5
5
|
>
|
|
6
|
-
> **当前版本**:`V4.9.
|
|
7
|
-
> **文档状态**:`V2` ~ `V4.9.
|
|
6
|
+
> **当前版本**:`V4.9.1`
|
|
7
|
+
> **文档状态**:`V2` ~ `V4.9.1` 已完成交付(含 V5 intent/audit 基础),`V5` 主体规划中
|
|
8
8
|
|
|
9
9
|
## 阅读导航
|
|
10
10
|
|
|
@@ -734,6 +734,12 @@ V4 经过 4 轮系统性代码审查,修复了以下关键问题:
|
|
|
734
734
|
}
|
|
735
735
|
```
|
|
736
736
|
|
|
737
|
+
### V4.9.1:侧边栏"Last backup"实时计时 ✅
|
|
738
|
+
|
|
739
|
+
| 优化 | 说明 |
|
|
740
|
+
|------|------|
|
|
741
|
+
| **备份时间实时跳动** | 侧边栏 Quick Stats 的 "Last backup Xs ago" 现在每秒自动更新,不再依赖 Poller 刷新周期。通过 `data-backup-ts` 属性传递时间戳,复用已有的 1s `setInterval` 计算相对时间 |
|
|
742
|
+
|
|
737
743
|
### V4.9.0:事件驱动架构 — 从轮询到实时响应 ✅
|
|
738
744
|
|
|
739
745
|
| 改造 | 说明 |
|
|
@@ -257,16 +257,25 @@ window.addEventListener('message', e => {
|
|
|
257
257
|
vscode.postMessage({ cmd: 'ready' });
|
|
258
258
|
|
|
259
259
|
setInterval(() => {
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
260
|
+
if (_alertExpiresAt) {
|
|
261
|
+
const el = document.querySelector('.alert-countdown');
|
|
262
|
+
if (el) {
|
|
263
|
+
const remain = Math.max(0, Math.ceil((_alertExpiresAt - Date.now()) / 1000));
|
|
264
|
+
if (remain <= 0) { el.textContent = '0s'; _alertExpiresAt = 0; }
|
|
265
|
+
else { el.textContent = remain > 60 ? Math.floor(remain / 60) + 'm ' + (remain % 60) + 's' : remain + 's'; }
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const ageEl = document.querySelector('.backup-age[data-backup-ts]');
|
|
269
|
+
if (ageEl) {
|
|
270
|
+
const ts = parseInt(ageEl.dataset.backupTs, 10);
|
|
271
|
+
if (ts) {
|
|
272
|
+
const sec = Math.floor((Date.now() - ts) / 1000);
|
|
273
|
+
if (sec < 60) ageEl.textContent = sec + 's ago';
|
|
274
|
+
else if (sec < 3600) ageEl.textContent = Math.floor(sec / 60) + 'm ' + (sec % 60) + 's ago';
|
|
275
|
+
else if (sec < 86400) ageEl.textContent = Math.floor(sec / 3600) + 'h ' + Math.floor((sec % 3600) / 60) + 'm ago';
|
|
276
|
+
else ageEl.textContent = Math.floor(sec / 86400) + 'd ago';
|
|
277
|
+
}
|
|
268
278
|
}
|
|
269
|
-
el.textContent = remain > 60 ? Math.floor(remain / 60) + 'm ' + (remain % 60) + 's' : remain + 's';
|
|
270
279
|
}, 1000);
|
|
271
280
|
|
|
272
281
|
function render(projects) {
|
|
@@ -346,6 +355,7 @@ function renderProject(d) {
|
|
|
346
355
|
// ── Quick stats ──
|
|
347
356
|
const gitC = d.counts?.git?.commits || 0;
|
|
348
357
|
const shadowC = d.counts?.shadow?.snapshots || 0;
|
|
358
|
+
const lastGitTs = d.lastBackup?.git?.timestamp || '';
|
|
349
359
|
const lastGit = d.lastBackup?.git?.relativeTime || 'never';
|
|
350
360
|
const freeGB = d.disk?.freeGB;
|
|
351
361
|
const freeDisplay = typeof freeGB === 'number' ? freeGB.toFixed(1) + ' GB' : 'N/A';
|
|
@@ -353,7 +363,11 @@ function renderProject(d) {
|
|
|
353
363
|
|
|
354
364
|
h += '<div class="stats-card">';
|
|
355
365
|
h += '<div class="label-sm">Quick Stats</div>';
|
|
356
|
-
|
|
366
|
+
if (lastGitTs) {
|
|
367
|
+
h += '<div class="stat-row"><span class="name">Last backup</span><span class="val green backup-age" data-backup-ts="' + new Date(lastGitTs).getTime() + '">' + esc(lastGit) + '</span></div>';
|
|
368
|
+
} else {
|
|
369
|
+
h += statRow('Last backup', lastGit, 'green');
|
|
370
|
+
}
|
|
357
371
|
h += statRow('Git backups', gitC, 'blue');
|
|
358
372
|
if (shadowC > 0) h += statRow('Shadow copies', shadowC, 'blue');
|
|
359
373
|
h += statRow('Disk free', freeDisplay, diskWarn ? 'yellow' : 'green');
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "cursor-guard-ide",
|
|
3
3
|
"displayName": "Cursor Guard",
|
|
4
4
|
"description": "AI code protection dashboard embedded in your IDE — real-time alerts, backup history, one-click snapshots",
|
|
5
|
-
"version": "4.9.
|
|
5
|
+
"version": "4.9.1",
|
|
6
6
|
"publisher": "zhangqiang8vipp",
|
|
7
7
|
"license": "BUSL-1.1",
|
|
8
8
|
"engines": {
|