fix(#2695): deliver the complete four-file codex hook set for every profile (#2822)

* test(#2695): failing-first regression for codex hook worker/registry omission

* fix(#2695): deliver the complete four-file codex hook set for every profile

* test(#2695): regenerate codex install-tree + acknowledge emitted hook ripple

* test(#2695): pin core config.toml/hooks.json wiring + fix agent-extension guard (review)

* docs(changeset): backfill #2695 PR number to 2822

* fix(#2695): SessionStart wiring assertion is extension-portable (Windows .cmd shim)
This commit is contained in:
Tom Boucher
2026-07-29 09:30:26 -04:00
committed by GitHub
parent 8b44a0da43
commit cfdfdf0b4c
5 changed files with 372 additions and 2 deletions

View File

@@ -11403,7 +11403,15 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
throw _earlyInstallErr;
}
if (plan.installSurface === 'codex-toml' && !isMinimalMode(_effectiveInstallMode)) {
// #2695: this branch runs for BOTH `core` (minimal) and `full` profiles.
// Hooks are lightweight infrastructure (update-check + context monitor), not the
// "full agent surface" that `core` deliberately omits. The config.toml / agent
// generation below is still gated by its own inner `!isMinimalMode` guard, so
// `core` enters the branch to receive the hook-file copy + hooks.json wiring but
// does NOT get agent roles generated. Before #2695 the outer `!isMinimalMode`
// here skipped the whole branch for `core`, so the registered parent hook pointed
// at a worker/registry the same installer never delivered.
if (plan.installSurface === 'codex-toml') {
// Capture pre-install snapshots before ANY GSD mutation
// (#2760 fix 3). On post-write schema-validation failure OR any throw
// during the mutation sequence (write failure, merge throw, etc.) we
@@ -11586,9 +11594,18 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
// Copy only the hook files that Codex actually registers via its hook configuration (#2153).
// #772: added gsd-context-monitor.js for the new SubagentStart/Stop/PostToolUse events.
// #2695: the parent gsd-check-update.js spawn()s gsd-check-update-worker.js, which
// require()s managed-hooks-registry.cjs for MANAGED_HOOKS — so all four must be
// installed/refreshed together for every profile, or Codex is wired to a dependency
// chain the same installer never delivers.
// We deliberately do *not* copy gsd-graphify-update.sh or hooks/lib/ for Codex
// in this change (graphify auto-update support for Codex is out of scope for #3579).
const CODEX_HOOKS_TO_COPY = ['gsd-check-update.js', 'gsd-context-monitor.js'];
const CODEX_HOOKS_TO_COPY = [
'gsd-check-update.js',
'gsd-check-update-worker.js',
'managed-hooks-registry.cjs',
'gsd-context-monitor.js',
];
const codexHooksSrc = path.join(src, 'hooks', 'dist');
if (fs.existsSync(codexHooksSrc)) {
const codexHooksDest = path.join(targetDir, 'hooks');
@@ -11618,6 +11635,14 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
fs.writeFileSync(destFile, content);
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
} else {
// #2695: raw byte-for-byte copy for allowlisted artifacts that carry
// no {{GSD_VERSION}} placeholder and no runtime path token (e.g.
// managed-hooks-registry.cjs, whose only `.claude` mention is inside a
// doc comment). Version/path transforms would be a no-op at best and a
// surprise at worst; the issue requires the registry copied verbatim.
fs.copyFileSync(srcFile, destFile);
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
}
}
console.log(` ${green}✓${reset} Installed hooks (Codex)`);