vigiles 19.0.0 → 19.0.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/dist/hook-install.js +35 -3
- package/package.json +1 -1
package/dist/hook-install.js
CHANGED
|
@@ -83,9 +83,41 @@ function normalizeHookRef(hookPath, cwd = process.cwd()) {
|
|
|
83
83
|
*/
|
|
84
84
|
function managesHook(entry, hookPath) {
|
|
85
85
|
const ref = normalizeHookRef(hookPath);
|
|
86
|
-
return entry.hooks.some((h) => h.command
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
return entry.hooks.some((h) => h.command.split(/\s+/).some((token) => {
|
|
87
|
+
const bare = bareToken(token);
|
|
88
|
+
return bare !== "" && normalizeHookRef(bare) === ref;
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A command token reduced to the PATH it names, so two spellings of the same
|
|
93
|
+
* hook file compare equal.
|
|
94
|
+
*
|
|
95
|
+
* 🔴 BOTH STRIPS ARE REGRESSIONS, MEASURED IN A CONSUMER REPO 2026-08-21, and
|
|
96
|
+
* they compound: a settings.json wired the Claude-Code-recommended way carries
|
|
97
|
+
* BOTH a quote and the project-dir variable, so `managesHook` saw
|
|
98
|
+
* `"$CLAUDE_PROJECT_DIR/.claude/hooks/x.hook.ts"`, canonicalized it to
|
|
99
|
+
* something under the cwd that resembles nothing, and reported "not managed by
|
|
100
|
+
* this hook". Recompiling then APPENDED its own block beside the existing one.
|
|
101
|
+
* Twelve hooks, twelve duplicates, and the duplicate is the WORSE of the two:
|
|
102
|
+
* it spells the path relative to the cwd, so it dies with exit 2 the moment the
|
|
103
|
+
* agent runs from a subdirectory — while the healthy copy beside it keeps
|
|
104
|
+
* working, which is why this survived a full day unnoticed.
|
|
105
|
+
*
|
|
106
|
+
* - QUOTES. A path with a space MUST be quoted, so the quoted form is not an
|
|
107
|
+
* exotic spelling — it is the correct one. Comparing it raw could never match.
|
|
108
|
+
* - `$CLAUDE_PROJECT_DIR`. It is defined as the project root, which is exactly
|
|
109
|
+
* what `normalizeHookRef` resolves relative paths against, so stripping the
|
|
110
|
+
* prefix makes the two spellings the same path by definition rather than by
|
|
111
|
+
* guess. `${CLAUDE_PROJECT_DIR}` is the same variable in brace syntax.
|
|
112
|
+
*
|
|
113
|
+
* Nothing else is stripped. A token this function does not recognise is left
|
|
114
|
+
* alone and simply fails to match, which is the pre-existing behaviour: the
|
|
115
|
+
* cost of a miss here is a duplicate block, and the cost of an over-match is
|
|
116
|
+
* deleting a hook the user wrote themselves.
|
|
117
|
+
*/
|
|
118
|
+
function bareToken(token) {
|
|
119
|
+
const unquoted = token.replace(/^["']/, "").replace(/["']$/, "");
|
|
120
|
+
return unquoted.replace(/^\$\{?CLAUDE_PROJECT_DIR\}?[/\\]/, "");
|
|
89
121
|
}
|
|
90
122
|
/**
|
|
91
123
|
* Idempotently merge a compiled hook's block into an existing `settings.json`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigiles",
|
|
3
|
-
"version": "19.0.
|
|
3
|
+
"version": "19.0.1",
|
|
4
4
|
"description": "Audit, test and measure the harness your AI agent runs on — grade your CLAUDE.md / AGENTS.md, skills, subagents and hooks, run them against a scripted model, and measure whether they actually fire.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|