@marcomigozzi/trailhead 0.13.0 → 0.15.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.it.md +142 -29
- package/README.md +141 -28
- package/bin/base-preflight-docs.test.js +65 -0
- package/bin/execute-split-docs.test.js +146 -0
- package/bin/isolation-answer-docs.test.js +41 -0
- package/bin/isolation-copy-docs.test.js +28 -0
- package/bin/lib/codex-projection.js +17 -10
- package/bin/lib/codex-projection.test.js +80 -11
- package/bin/lib/install-verify.js +10 -5
- package/bin/lib/install-verify.test.js +51 -0
- package/bin/report-status-docs.test.js +195 -0
- package/bin/resolve-helpers-docs.test.js +36 -0
- package/bin/scope-confirm-skip-docs.test.js +70 -0
- package/bin/trailhead.js +40 -28
- package/bin/trailhead.test.js +503 -6
- package/bin/uat-setup-docs.test.js +65 -0
- package/package.json +4 -1
- package/plugins/trailhead/.claude-plugin/plugin.json +3 -2
- package/plugins/trailhead/agents/trailhead-code-review.md +15 -2
- package/plugins/trailhead/agents/trailhead-codebase-map.md +20 -1
- package/plugins/trailhead/agents/trailhead-debug.md +20 -1
- package/plugins/trailhead/agents/trailhead-executor.md +29 -2
- package/plugins/trailhead/agents/trailhead-fix.md +29 -2
- package/plugins/trailhead/agents/trailhead-plan.md +20 -1
- package/plugins/trailhead/agents/trailhead-research.md +22 -3
- package/plugins/trailhead/agents/trailhead-verify.md +15 -2
- package/plugins/trailhead/commands/panel.md +10 -0
- package/plugins/trailhead/hooks/hooks.json +3 -18
- package/plugins/trailhead/hooks/lib/base-preflight.test.js +513 -0
- package/plugins/trailhead/hooks/lib/body-sources.js +795 -0
- package/plugins/trailhead/hooks/lib/commit-message-check.js +1 -1
- package/plugins/trailhead/hooks/lib/commit-message-check.test.js +3 -2
- package/plugins/trailhead/hooks/lib/commit-msg-module-repo.test.js +116 -0
- package/plugins/trailhead/hooks/lib/commit-msg-sync.test.js +100 -9
- package/plugins/trailhead/hooks/lib/dashboard.test.js +409 -0
- package/plugins/trailhead/hooks/lib/fixtures/commit-msg-legacy-js +104 -0
- package/plugins/trailhead/hooks/lib/gh-subcommand.js +92 -10
- package/plugins/trailhead/hooks/lib/gh-subcommand.test.js +55 -0
- package/plugins/trailhead/hooks/lib/isolation-answer.test.js +258 -0
- package/plugins/trailhead/hooks/lib/isolation-copy.test.js +298 -0
- package/plugins/trailhead/hooks/lib/issue-body.test.js +470 -0
- package/plugins/trailhead/hooks/lib/mockup-link.js +21 -5
- package/plugins/trailhead/hooks/lib/report-status.test.js +366 -0
- package/plugins/trailhead/hooks/lib/shell-scan.js +532 -65
- package/plugins/trailhead/hooks/lib/shell-scan.test.js +434 -0
- package/plugins/trailhead/hooks/lib/uat-backfill.test.js +150 -0
- package/plugins/trailhead/hooks/lib/uat-setup.test.js +340 -0
- package/plugins/trailhead/hooks/lib/unmodelled.js +345 -0
- package/plugins/trailhead/hooks/lib/unmodelled.test.js +173 -0
- package/plugins/trailhead/hooks/lib/work-state.test.js +297 -0
- package/plugins/trailhead/hooks/mod/README.md +219 -0
- package/plugins/trailhead/hooks/mod/map-pane-view.ts +606 -0
- package/plugins/trailhead/hooks/mod/map-pane.tsx +832 -0
- package/plugins/trailhead/hooks/mod/register.tsx +293 -0
- package/plugins/trailhead/hooks/mod/work-state-prompt.ts +69 -0
- package/plugins/trailhead/hooks/mod/work-state-view.ts +110 -0
- package/plugins/trailhead/hooks/trailhead-bash-guards.js +140 -0
- package/plugins/trailhead/hooks/trailhead-bash-guards.test.js +233 -0
- package/plugins/trailhead/hooks/trailhead-body-guard.js +145 -61
- package/plugins/trailhead/hooks/trailhead-body-guard.test.js +224 -3
- package/plugins/trailhead/hooks/trailhead-commit-guard.js +41 -14
- package/plugins/trailhead/hooks/trailhead-commit-guard.test.js +2 -1
- package/plugins/trailhead/hooks/trailhead-install-guard.js +187 -42
- package/plugins/trailhead/hooks/trailhead-install-guard.test.js +182 -2
- package/plugins/trailhead/hooks/trailhead-mockup-link-guard.js +48 -11
- package/plugins/trailhead/hooks/trailhead-mockup-link-guard.test.js +75 -3
- package/plugins/trailhead/hooks/trailhead-search-guard.js +59 -13
- package/plugins/trailhead/hooks/trailhead-search-guard.test.js +68 -3
- package/plugins/trailhead/hooks/trailhead-secret-guard.js +541 -57
- package/plugins/trailhead/hooks/trailhead-secret-guard.test.js +1000 -4
- package/plugins/trailhead/hooks/trailhead-secret-read-guard.js +171 -6
- package/plugins/trailhead/hooks/trailhead-secret-read-guard.test.js +170 -0
- package/plugins/trailhead/skills/_shared/choices.md +7 -3
- package/plugins/trailhead/skills/_shared/configuration-reference.md +15 -3
- package/plugins/trailhead/skills/_shared/load-first.md +3 -3
- package/plugins/trailhead/skills/_shared/multi-map.md +3 -3
- package/plugins/trailhead/skills/_shared/session-handoff.md +1 -1
- package/plugins/trailhead/skills/_shared/substrate-commands.md +22 -11
- package/plugins/trailhead/skills/_shared/substrate.md +6 -4
- package/plugins/trailhead/skills/_shared/teamwork.md +17 -6
- package/plugins/trailhead/skills/_shared/techniques/acceptance-testing.md +17 -9
- package/plugins/trailhead/skills/_shared/techniques/code-review.md +1 -1
- package/plugins/trailhead/skills/_shared/techniques/codebase-map.md +1 -1
- package/plugins/trailhead/skills/_shared/techniques/debug.md +2 -0
- package/plugins/trailhead/skills/_shared/techniques/prototype.md +1 -1
- package/plugins/trailhead/skills/_shared/techniques/research.md +4 -2
- package/plugins/trailhead/skills/_shared/techniques/verify.md +1 -1
- package/plugins/trailhead/skills/_shared/techniques.md +12 -2
- package/plugins/trailhead/skills/trailhead/SKILL.md +3 -3
- package/plugins/trailhead/skills/trailhead-capture/SKILL.md +1 -1
- package/plugins/trailhead/skills/trailhead-capture/references/capture.md +2 -2
- package/plugins/trailhead/skills/trailhead-chart/SKILL.md +1 -1
- package/plugins/trailhead/skills/trailhead-chart/references/charting.md +1 -1
- package/plugins/trailhead/skills/trailhead-manage/SKILL.md +1 -1
- package/plugins/trailhead/skills/trailhead-manage/references/auditing.md +1 -1
- package/plugins/trailhead/skills/trailhead-view/SKILL.md +8 -6
- package/plugins/trailhead/skills/trailhead-work/SKILL.md +16 -13
- package/plugins/trailhead/skills/trailhead-work/references/auto.md +6 -4
- package/plugins/trailhead/skills/trailhead-work/references/executor-brief.md +29 -0
- package/plugins/trailhead/skills/trailhead-work/references/ticket-engines.md +28 -10
- package/plugins/trailhead/templates/trailhead-base-preflight.js +305 -0
- package/plugins/trailhead/templates/trailhead-commit-msg +38 -102
- package/plugins/trailhead/templates/trailhead-commit-msg-sync.js +58 -27
- package/plugins/trailhead/templates/trailhead-commit-msg.cjs +114 -0
- package/plugins/trailhead/templates/trailhead-dashboard.js +340 -0
- package/plugins/trailhead/templates/trailhead-isolation-answer.js +227 -0
- package/plugins/trailhead/templates/trailhead-isolation-copy.js +239 -0
- package/plugins/trailhead/templates/trailhead-issue-body.js +459 -0
- package/plugins/trailhead/templates/trailhead-report-status.js +274 -0
- package/plugins/trailhead/templates/trailhead-uat-backfill.js +114 -0
- package/plugins/trailhead/templates/trailhead-uat-setup.js +385 -0
- package/plugins/trailhead/templates/trailhead-work-state.js +217 -0
- package/plugins/trailhead/tests/map-pane-ui.test.ts +1921 -0
- package/plugins/trailhead/tests/map-pane-view.test.ts +853 -0
- package/plugins/trailhead/tests/mod.test.ts +14 -0
- package/plugins/trailhead/tests/work-state-prompt-hook.test.ts +207 -0
- package/plugins/trailhead/tests/work-state-prompt.test.ts +109 -0
- package/plugins/trailhead/tests/work-state-ui.test.ts +365 -0
- package/plugins/trailhead/tests/work-state-view.test.ts +110 -0
- package/plugins/trailhead/types/index.d.ts +103 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Docs test for #253: the skill prose names the Resolve bookkeeping helpers as the
|
|
3
|
+
// default path (trailhead-issue-body.js, trailhead-dashboard.js, and the one `clear`
|
|
4
|
+
// that also removes the session-ticket marker), while keeping the by-hand fallback.
|
|
5
|
+
// Run: node resolve-helpers-docs.test.js
|
|
6
|
+
const assert = require('assert');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const skills = path.join(__dirname, '..', 'plugins', 'trailhead', 'skills');
|
|
11
|
+
const read = (rel) => fs.readFileSync(path.join(skills, rel), 'utf8');
|
|
12
|
+
|
|
13
|
+
let passed = 0;
|
|
14
|
+
const ok = (name, cond) => { assert.ok(cond, name); passed++; };
|
|
15
|
+
|
|
16
|
+
// file -> strings it must carry
|
|
17
|
+
const EXPECT = {
|
|
18
|
+
'_shared/substrate.md': ['trailhead-issue-body.js', 'trailhead-dashboard.js', 'when a helper is missing'],
|
|
19
|
+
'_shared/substrate-commands.md': ['trailhead-issue-body.js append --issue <map> --section "Decisions so far"', 'trailhead-dashboard.js', '--set-last-audit', 'fully generated'],
|
|
20
|
+
'trailhead-work/references/ticket-engines.md': ['trailhead-issue-body.js append --issue <map> --section "Decisions so far"', 'trailhead-dashboard.js', 'trailhead-work-state.js clear --repo <working-root>'],
|
|
21
|
+
'trailhead-work/SKILL.md': ['trailhead-issue-body.js append --issue <map> --section "Decisions so far"', 'trailhead-dashboard.js', 'trailhead-work-state.js clear --repo <working-root>',
|
|
22
|
+
'trailhead-issue-body.js remove --issue <map> --section "Not yet specified" --match "<unique text of the entry>"'],
|
|
23
|
+
'_shared/session-handoff.md': ['trailhead-work-state.js clear --repo <working-root>', 'removes both'],
|
|
24
|
+
'_shared/teamwork.md': ['trailhead-issue-body.js append --issue <map> --section "Decisions so far"', 'sessionTicket', 'when the helper is missing'],
|
|
25
|
+
'trailhead-view/SKILL.md': ['trailhead-dashboard.js', '--dry-run'],
|
|
26
|
+
'trailhead-manage/references/auditing.md': ['trailhead-dashboard.js --set-last-audit'],
|
|
27
|
+
'_shared/configuration-reference.md': ['trailhead-issue-body.js replace --issue <conventions> --section :preamble'],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
for (const [rel, needles] of Object.entries(EXPECT)) {
|
|
31
|
+
const text = read(rel);
|
|
32
|
+
for (const needle of needles) ok(`${rel} names: ${needle}`, text.includes(needle));
|
|
33
|
+
ok(`${rel} has no em-dash`, !text.includes('—'));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(`resolve-helpers-docs.test.js: ${passed} checks passed`);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Docs test for #244: the ticket-start scope confirm is skipped on a ticket this session
|
|
3
|
+
// already shaped. The rule is stated once (Work the map step 3); the quick bullet and the
|
|
4
|
+
// choices table only point at it.
|
|
5
|
+
// Run: node scope-confirm-skip-docs.test.js
|
|
6
|
+
const assert = require('assert');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const skills = path.join(__dirname, '..', 'plugins', 'trailhead', 'skills');
|
|
11
|
+
const read = (rel) => fs.readFileSync(path.join(skills, rel), 'utf8');
|
|
12
|
+
|
|
13
|
+
let passed = 0;
|
|
14
|
+
const ok = (name, cond) => { assert.ok(cond, name); passed++; };
|
|
15
|
+
|
|
16
|
+
const ANCHOR = 'Skip the confirm on a ticket this session already shaped';
|
|
17
|
+
const DEFINITION = `**${ANCHOR}.**`;
|
|
18
|
+
|
|
19
|
+
const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
|
|
20
|
+
e.isDirectory() ? walk(path.join(dir, e.name)) : [path.join(dir, e.name)]);
|
|
21
|
+
|
|
22
|
+
// 1. the bold definition exists exactly once, in trailhead-work/SKILL.md
|
|
23
|
+
const defs = walk(skills).filter((f) => fs.readFileSync(f, 'utf8').includes(DEFINITION));
|
|
24
|
+
ok('definition appears in exactly one file', defs.length === 1);
|
|
25
|
+
ok('definition lives in trailhead-work/SKILL.md', defs[0] === path.join(skills, 'trailhead-work', 'SKILL.md'));
|
|
26
|
+
const work = read('trailhead-work/SKILL.md');
|
|
27
|
+
ok('definition appears once in SKILL.md', work.split(DEFINITION).length === 2);
|
|
28
|
+
|
|
29
|
+
// 2. step 3 carries the normative fragments
|
|
30
|
+
const lines = work.split('\n');
|
|
31
|
+
const s = lines.findIndex((l) => l.startsWith('3. **Brief the ticket and confirm scope'));
|
|
32
|
+
const e = lines.findIndex((l, i) => i > s && l.startsWith('4. '));
|
|
33
|
+
ok('step 3 found', s >= 0 && e > s);
|
|
34
|
+
const step3 = lines.slice(s, e).join('\n');
|
|
35
|
+
ok('step 3 carries the definition', step3.includes(DEFINITION));
|
|
36
|
+
// match the fragments in the rule sub-bullet only, not the whole of step 3
|
|
37
|
+
const rule = lines.slice(s, e).find((l) => l.includes(DEFINITION));
|
|
38
|
+
for (const frag of [
|
|
39
|
+
"from the user's own request for it",
|
|
40
|
+
'a Grilling round on this ticket concluded',
|
|
41
|
+
'created in bulk',
|
|
42
|
+
'earlier session',
|
|
43
|
+
'/clear',
|
|
44
|
+
'resume',
|
|
45
|
+
'one-line',
|
|
46
|
+
'never inferred from tracker metadata',
|
|
47
|
+
'`auto` is unchanged',
|
|
48
|
+
]) ok(`rule carries: ${frag}`, rule.includes(frag));
|
|
49
|
+
|
|
50
|
+
// 3. the quick bullet only points at the rule
|
|
51
|
+
const quick = lines.find((l) => l.startsWith('- **Briefs and confirms scope first'));
|
|
52
|
+
ok('quick bullet found', !!quick);
|
|
53
|
+
ok('quick bullet references the anchor', quick.includes(ANCHOR));
|
|
54
|
+
ok('quick bullet gates the menu on the rule', quick.includes('Whether the menu is posed at all follows'));
|
|
55
|
+
ok('quick "<text>" gets the note, no menu', quick.includes('one-line note, no menu'));
|
|
56
|
+
ok('quick bullet does not restate bulk exclusion', !quick.includes('created in bulk'));
|
|
57
|
+
ok('quick bullet does not restate grill trigger', !quick.includes('a Grilling round on this ticket concluded'));
|
|
58
|
+
|
|
59
|
+
// 4. the choices row only points at the rule
|
|
60
|
+
const row = read('_shared/choices.md').split('\n').find((l) => l.startsWith('| Ticket-start scope confirm'));
|
|
61
|
+
ok('choices row found', !!row);
|
|
62
|
+
ok('choices row references the anchor', row.includes(ANCHOR));
|
|
63
|
+
ok('choices row does not restate bulk exclusion', !row.includes('created in bulk'));
|
|
64
|
+
|
|
65
|
+
// 5. no em-dash in the touched files
|
|
66
|
+
for (const rel of ['trailhead-work/SKILL.md', '_shared/choices.md'])
|
|
67
|
+
ok(`${rel} has no em-dash`, !read(rel).includes('\u2014'));
|
|
68
|
+
ok('this test has no em-dash', !fs.readFileSync(__filename, 'utf8').includes('\u2014'));
|
|
69
|
+
|
|
70
|
+
console.log(`scope-confirm-skip-docs.test.js: ${passed} checks passed`);
|
package/bin/trailhead.js
CHANGED
|
@@ -243,18 +243,27 @@ function claudePaths(configDir) {
|
|
|
243
243
|
settings: path.join(configDir, 'settings.json'),
|
|
244
244
|
};
|
|
245
245
|
}
|
|
246
|
-
|
|
246
|
+
// The five Bash guard modules. They are shipped, but only require()d by the
|
|
247
|
+
// merged trailhead-bash-guards.js (one process per Bash call), never registered
|
|
248
|
+
// on their own. Legacy installs registered each one; the installers strip those.
|
|
249
|
+
const BASH_GUARD_MODULES = ['trailhead-commit-guard.js', 'trailhead-secret-guard.js', 'trailhead-install-guard.js', 'trailhead-search-guard.js', 'trailhead-body-guard.js'];
|
|
250
|
+
// Every hook script copied into the hooks dir (shipped runtime files).
|
|
251
|
+
const HOOK_FILES = [...BASH_GUARD_MODULES, 'trailhead-bash-guards.js', 'trailhead-issue-injection-scanner.js', 'trailhead-secret-read-guard.js', 'trailhead-mockup-link-guard.js', 'trailhead-mockup-link-stop.js', 'trailhead-check-update.js'];
|
|
252
|
+
// The registered entrypoints: the shipped files that must appear in
|
|
253
|
+
// settings.json / hooks.json (everything but the require()d guard modules).
|
|
254
|
+
const ENTRYPOINT_FILES = HOOK_FILES.filter((f) => !BASH_GUARD_MODULES.includes(f));
|
|
247
255
|
// Runtime libs the hook scripts require (trailhead-commit-guard.js does
|
|
248
|
-
// require('./lib/commit-message-check.js');
|
|
249
|
-
//
|
|
250
|
-
// follow-up; trailhead-body-guard.js and trailhead-secret-guard.js both do
|
|
251
|
-
// require('./lib/gh-subcommand.js'), #153 follow-up; trailhead-
|
|
256
|
+
// require('./lib/commit-message-check.js'); several guards (grep `lib/shell-scan`:
|
|
257
|
+
// search, secret-read, secret, install, lib/unmodelled.js) do
|
|
258
|
+
// require('./lib/shell-scan.js'), #135 follow-up; trailhead-body-guard.js and trailhead-secret-guard.js both do
|
|
259
|
+
// require('./lib/gh-subcommand.js'), #153 follow-up; trailhead-secret-guard.js
|
|
260
|
+
// also does require('./lib/body-sources.js'), #210; trailhead-check-update.js
|
|
252
261
|
// does require('./lib/model-defaults-review.js'), which in turn reads the
|
|
253
262
|
// sibling model-defaults.json, #186; both mockup-link hooks do
|
|
254
263
|
// require('./lib/mockup-link.js')). Copied by name, never a recursive
|
|
255
264
|
// sweep: the Claude hooks/lib dir is shared with other plugins, so we must
|
|
256
265
|
// not clobber a co-tenant's lib nor ship our own *.test.js files.
|
|
257
|
-
const HOOK_LIB_FILES = ['commit-message-check.js', 'shell-scan.js', 'gh-subcommand.js', 'model-defaults-review.js', 'model-defaults.json', 'mockup-link.js'];
|
|
266
|
+
const HOOK_LIB_FILES = ['commit-message-check.js', 'shell-scan.js', 'gh-subcommand.js', 'body-sources.js', 'unmodelled.js', 'model-defaults-review.js', 'model-defaults.json', 'mockup-link.js'];
|
|
258
267
|
// search-guard is Claude-Code-specific (#169), and so is mockup-link-guard
|
|
259
268
|
// (it gates the AskUserQuestion tool, which Codex lacks): excluded from both
|
|
260
269
|
// the Codex hook copy and the Codex verify spec's expected hookFiles, so a
|
|
@@ -264,6 +273,10 @@ const CODEX_HOOK_EXCLUDE = ['trailhead-search-guard.js', 'trailhead-mockup-link-
|
|
|
264
273
|
// Claude Code gates the AskUserQuestion call instead, so it is neither copied
|
|
265
274
|
// nor expected on a Claude install.
|
|
266
275
|
const CLAUDE_HOOK_EXCLUDE = ['trailhead-mockup-link-stop.js'];
|
|
276
|
+
const claudeShippedHooks = () => HOOK_FILES.filter((f) => !CLAUDE_HOOK_EXCLUDE.includes(f));
|
|
277
|
+
const claudeEntrypoints = () => ENTRYPOINT_FILES.filter((f) => !CLAUDE_HOOK_EXCLUDE.includes(f));
|
|
278
|
+
const codexShippedHooks = () => HOOK_FILES.filter((f) => !CODEX_HOOK_EXCLUDE.includes(f));
|
|
279
|
+
const codexEntrypoints = () => ENTRYPOINT_FILES.filter((f) => !CODEX_HOOK_EXCLUDE.includes(f));
|
|
267
280
|
|
|
268
281
|
// Copy the hook scripts and their runtime libs into a destination hooks dir
|
|
269
282
|
// (Claude's ~/.claude/hooks or Codex's skills/trailhead/hooks). Shared by both
|
|
@@ -357,6 +370,12 @@ function stripHook(s, event, substr) {
|
|
|
357
370
|
s.hooks[event] = s.hooks[event].filter((g) => (g.hooks || []).length);
|
|
358
371
|
}
|
|
359
372
|
|
|
373
|
+
// Drop the per-guard PreToolUse registrations an earlier install made (and the
|
|
374
|
+
// pre-#169 Codex search-guard one): the merged entrypoint replaces all of them.
|
|
375
|
+
function stripLegacyBashGuards(s) {
|
|
376
|
+
for (const f of BASH_GUARD_MODULES) stripHook(s, 'PreToolUse', f);
|
|
377
|
+
}
|
|
378
|
+
|
|
360
379
|
function uninstallClaude(configDir) {
|
|
361
380
|
const P = claudePaths(configDir);
|
|
362
381
|
// Sweep every trailhead-owned skill dir (current set + any stale dir a prior
|
|
@@ -371,12 +390,9 @@ function uninstallClaude(configDir) {
|
|
|
371
390
|
// with other plugins, so never rmrf the whole dir.
|
|
372
391
|
HOOK_LIB_FILES.forEach((f) => rmrf(path.join(P.hooksDir, 'lib', f)));
|
|
373
392
|
const s = readJSON(P.settings);
|
|
374
|
-
|
|
375
|
-
stripHook(s, 'PreToolUse', 'trailhead-
|
|
376
|
-
stripHook(s, 'PreToolUse', 'trailhead-install-guard.js');
|
|
377
|
-
stripHook(s, 'PreToolUse', 'trailhead-search-guard.js');
|
|
393
|
+
stripLegacyBashGuards(s);
|
|
394
|
+
stripHook(s, 'PreToolUse', 'trailhead-bash-guards.js');
|
|
378
395
|
stripHook(s, 'PreToolUse', 'trailhead-secret-read-guard.js');
|
|
379
|
-
stripHook(s, 'PreToolUse', 'trailhead-body-guard.js');
|
|
380
396
|
stripHook(s, 'PreToolUse', 'trailhead-mockup-link-guard.js');
|
|
381
397
|
stripHook(s, 'PostToolUse', 'trailhead-issue-injection-scanner.js');
|
|
382
398
|
stripHook(s, 'SessionStart', 'trailhead-check-update.js');
|
|
@@ -419,12 +435,11 @@ function installClaude(configDir, { useSymlink }) {
|
|
|
419
435
|
}
|
|
420
436
|
|
|
421
437
|
const s = readJSON(P.settings);
|
|
438
|
+
// Migration: an earlier install registered each Bash guard on its own; the
|
|
439
|
+
// merged entrypoint below replaces all five.
|
|
440
|
+
stripLegacyBashGuards(s);
|
|
422
441
|
const added = [
|
|
423
|
-
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-
|
|
424
|
-
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-secret-guard.js')),
|
|
425
|
-
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-install-guard.js')),
|
|
426
|
-
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-search-guard.js')),
|
|
427
|
-
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-body-guard.js')),
|
|
442
|
+
addHook(s, 'PreToolUse', 'Bash', hookCmd('trailhead-bash-guards.js')),
|
|
428
443
|
addHook(s, 'PreToolUse', 'Read|Bash', hookCmd('trailhead-secret-read-guard.js')),
|
|
429
444
|
addHook(s, 'PreToolUse', 'AskUserQuestion', hookCmd('trailhead-mockup-link-guard.js')),
|
|
430
445
|
addHook(s, 'PostToolUse', 'Bash', hookCmd('trailhead-issue-injection-scanner.js')),
|
|
@@ -438,7 +453,8 @@ function installClaude(configDir, { useSymlink }) {
|
|
|
438
453
|
const spec = claudeVerifySpec(configDir, {
|
|
439
454
|
skillDirs: shippedSkillDirs(),
|
|
440
455
|
sharedFiles: readSharedCoreFiles(),
|
|
441
|
-
hookFiles:
|
|
456
|
+
hookFiles: claudeShippedHooks(),
|
|
457
|
+
entrypointFiles: claudeEntrypoints(),
|
|
442
458
|
hookLibFiles: HOOK_LIB_FILES,
|
|
443
459
|
env: process.env,
|
|
444
460
|
home: os.homedir(),
|
|
@@ -653,7 +669,7 @@ function installCodex(configDir, { useSymlink }) {
|
|
|
653
669
|
// Migration: strip a pre-#169 search-guard registration. Its target is
|
|
654
670
|
// always gone now (search-guard is never copied to Codex), so a prior
|
|
655
671
|
// install's stale entry would otherwise fail the post-install check below.
|
|
656
|
-
|
|
672
|
+
stripLegacyBashGuards(h);
|
|
657
673
|
for (const e of codexHookEntries(L.hooksScriptsDir)) addHook(h, e.event, e.matcher, e.command);
|
|
658
674
|
writeJSON(L.hooksJson, h);
|
|
659
675
|
|
|
@@ -709,7 +725,8 @@ function installCodex(configDir, { useSymlink }) {
|
|
|
709
725
|
const spec = codexVerifySpec(configDir, {
|
|
710
726
|
skillDirs: shippedSkillDirs(),
|
|
711
727
|
sharedFiles: readSharedCoreFiles(),
|
|
712
|
-
hookFiles:
|
|
728
|
+
hookFiles: codexShippedHooks(),
|
|
729
|
+
entrypointFiles: codexEntrypoints(),
|
|
713
730
|
hookLibFiles: HOOK_LIB_FILES,
|
|
714
731
|
env: process.env,
|
|
715
732
|
home: os.homedir(),
|
|
@@ -772,16 +789,11 @@ function uninstallCodex(configDir) {
|
|
|
772
789
|
// settings.json flags alone.
|
|
773
790
|
if (fs.existsSync(L.hooksJson)) {
|
|
774
791
|
const h = readJSON(L.hooksJson);
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
stripHook(h, 'PreToolUse', 'trailhead-
|
|
778
|
-
|
|
779
|
-
// Claude-Code-specific), so it is never registered by a current install;
|
|
780
|
-
// this strip is retained only to clean up a stale entry left by a
|
|
781
|
-
// pre-#169 install that did register it.
|
|
782
|
-
stripHook(h, 'PreToolUse', 'trailhead-search-guard.js');
|
|
792
|
+
// The merged Bash guard entry, plus every legacy per-guard registration
|
|
793
|
+
// (commit, secret, install, body, and the pre-#169 search-guard one).
|
|
794
|
+
stripHook(h, 'PreToolUse', 'trailhead-bash-guards.js');
|
|
795
|
+
stripLegacyBashGuards(h);
|
|
783
796
|
stripHook(h, 'PreToolUse', 'trailhead-secret-read-guard.js');
|
|
784
|
-
stripHook(h, 'PreToolUse', 'trailhead-body-guard.js');
|
|
785
797
|
stripHook(h, 'PostToolUse', 'trailhead-issue-injection-scanner.js');
|
|
786
798
|
stripHook(h, 'Stop', 'trailhead-mockup-link-stop.js');
|
|
787
799
|
stripHook(h, 'SessionStart', 'trailhead-check-update.js');
|