cursordoctrine 0.5.2 → 0.5.3
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/bin/cli.mjs +38 -7
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -62,6 +62,29 @@ function keyOf(command, keys) {
|
|
|
62
62
|
return keys.find((k) => command.includes(k));
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// Detect a STALE entry from a prior install: its command names a hook script
|
|
66
|
+
// (ps1/sh, not an .md prompt) under .agents/hooks OR names inject-doctrine,
|
|
67
|
+
// but that filename is NOT in the current payload. These are NOT foreign
|
|
68
|
+
// entries the user added — they are leftovers from an older version of THIS
|
|
69
|
+
// pack (e.g. anchor-set-nudge / minimal-edit-audit, deleted in 0.5.0). The
|
|
70
|
+
// old merge preserved them as "foreign", so deleted hooks kept running on
|
|
71
|
+
// every edit silently. Returning true here makes install reap them.
|
|
72
|
+
const HOOK_FILENAME_RE = /([\w.\-]+)\.(ps1|sh)\b/;
|
|
73
|
+
const INJECT_RE = /\binject-doctrine\.(ps1|sh)\b/;
|
|
74
|
+
function isStaleOurs(command) {
|
|
75
|
+
if (typeof command !== 'string') return false;
|
|
76
|
+
const hookMatch = command.match(HOOK_FILENAME_RE);
|
|
77
|
+
if (hookMatch) {
|
|
78
|
+
const fname = `${hookMatch[1]}.${hookMatch[2]}`;
|
|
79
|
+
// If the script still ships, it's current ours (handled elsewhere).
|
|
80
|
+
return !payloadHookFiles().includes(fname);
|
|
81
|
+
}
|
|
82
|
+
if (INJECT_RE.test(command)) {
|
|
83
|
+
return !doctrineFiles.includes(injectName) ? true : false;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
65
88
|
function mergeHooks(existing, incoming, keys) {
|
|
66
89
|
const out = structuredClone(existing);
|
|
67
90
|
if (out.version === undefined) out.version = incoming.version;
|
|
@@ -75,22 +98,25 @@ function mergeHooks(existing, incoming, keys) {
|
|
|
75
98
|
if (i >= 0) cur[i] = entry;
|
|
76
99
|
else cur.push(entry);
|
|
77
100
|
}
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
101
|
+
// Reap stale ours entries from prior installs BEFORE treating anything as
|
|
102
|
+
// foreign. isStaleOurs catches commands referencing scripts this pack no
|
|
103
|
+
// longer ships (e.g. anchor-set-nudge / minimal-edit-audit, deleted in
|
|
104
|
+
// 0.5.0). Without this, deleted hooks kept running silently on every edit
|
|
105
|
+
// because the merge mistook them for user-added foreign entries.
|
|
106
|
+
const live = cur.filter((x) => x && !isStaleOurs(x.command));
|
|
107
|
+
const foreign = live.filter((x) => x && !isOurs(x.command, keys));
|
|
82
108
|
const reordered = [];
|
|
83
109
|
const used = new Set();
|
|
84
110
|
for (const entry of entries) {
|
|
85
111
|
const k = keyOf(entry.command, keys);
|
|
86
112
|
if (!k || !isOurs(entry.command, keys)) continue;
|
|
87
|
-
const found =
|
|
113
|
+
const found = live.find((x) => x && keyOf(x.command, keys) === k);
|
|
88
114
|
if (found) {
|
|
89
115
|
reordered.push(found);
|
|
90
116
|
used.add(k);
|
|
91
117
|
}
|
|
92
118
|
}
|
|
93
|
-
for (const x of
|
|
119
|
+
for (const x of live) {
|
|
94
120
|
const k = keyOf(x?.command, keys);
|
|
95
121
|
if (isOurs(x?.command, keys) && k && !used.has(k)) reordered.push(x);
|
|
96
122
|
}
|
|
@@ -429,7 +455,12 @@ function uninstall() {
|
|
|
429
455
|
let foreign = 0;
|
|
430
456
|
for (const [event, entries] of Object.entries(existing.hooks || {})) {
|
|
431
457
|
if (!Array.isArray(entries)) continue;
|
|
432
|
-
|
|
458
|
+
// Remove both current ours AND stale ours (commands referencing scripts
|
|
459
|
+
// this pack no longer ships - leftovers from prior versions). Pure
|
|
460
|
+
// foreign entries are kept, same as before.
|
|
461
|
+
existing.hooks[event] = entries.filter(
|
|
462
|
+
(x) => !x || (!isOurs(x.command, keys) && !isStaleOurs(x.command))
|
|
463
|
+
);
|
|
433
464
|
foreign += existing.hooks[event].length;
|
|
434
465
|
if (existing.hooks[event].length === 0) delete existing.hooks[event];
|
|
435
466
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursordoctrine",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Thin self-review hooks for Cursor — the model is the auditor. Pruned + deduplicated: intent-anchor (auto-scaffolded .scope.json per prompt + per-turn re-injection against Salience Dilution), intent-trace final review, unified anti-slop checklist as single source of truth.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cursordoctrine": "bin/cli.mjs"
|