@opengsd/gsd-core 1.8.0 → 1.9.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.
Files changed (174) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +31 -1
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-codebase-mapper.md +1 -1
  6. package/agents/gsd-debug-session-manager.md +36 -0
  7. package/agents/gsd-executor.md +20 -7
  8. package/agents/gsd-intel-updater.md +3 -3
  9. package/agents/gsd-phase-researcher.md +4 -2
  10. package/agents/gsd-plan-checker.md +20 -0
  11. package/agents/gsd-planner.md +15 -23
  12. package/agents/gsd-project-researcher.md +2 -2
  13. package/agents/gsd-ui-auditor.md +0 -40
  14. package/bin/install.js +186 -55
  15. package/commands/gsd/plan-review-convergence.md +5 -1
  16. package/gsd-core/bin/gsd-tools.cjs +849 -2
  17. package/gsd-core/bin/lib/api-coverage.cjs +22 -8
  18. package/gsd-core/bin/lib/audit.cjs +8 -8
  19. package/gsd-core/bin/lib/capability-consent.cjs +40 -1
  20. package/gsd-core/bin/lib/capability-lifecycle.cjs +58 -0
  21. package/gsd-core/bin/lib/capability-loader.cjs +23 -1
  22. package/gsd-core/bin/lib/capability-registry.cjs +1353 -132
  23. package/gsd-core/bin/lib/capability-trust.cjs +468 -33
  24. package/gsd-core/bin/lib/capability-validator.cjs +882 -6
  25. package/gsd-core/bin/lib/check-command-router.cjs +12 -2
  26. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +15 -0
  27. package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +102 -12
  28. package/gsd-core/bin/lib/claude-orchestration.cjs +125 -22
  29. package/gsd-core/bin/lib/commands.cjs +246 -18
  30. package/gsd-core/bin/lib/config-loader.cjs +200 -28
  31. package/gsd-core/bin/lib/config.cjs +90 -5
  32. package/gsd-core/bin/lib/estimate-cli.cjs +336 -0
  33. package/gsd-core/bin/lib/frontmatter.cjs +125 -15
  34. package/gsd-core/bin/lib/host-integration.cjs +215 -8
  35. package/gsd-core/bin/lib/init.cjs +44 -19
  36. package/gsd-core/bin/lib/install-engine.cjs +1 -0
  37. package/gsd-core/bin/lib/milestone.cjs +5 -5
  38. package/gsd-core/bin/lib/model-catalog.cjs +51 -1
  39. package/gsd-core/bin/lib/observability/logger.cjs +7 -2
  40. package/gsd-core/bin/lib/phase-command-router.cjs +10 -1
  41. package/gsd-core/bin/lib/phase-estimation.cjs +398 -0
  42. package/gsd-core/bin/lib/phase-id.cjs +278 -5
  43. package/gsd-core/bin/lib/phase.cjs +57 -5
  44. package/gsd-core/bin/lib/plan-drift-guard.cjs +1 -1
  45. package/gsd-core/bin/lib/plan-scan.cjs +1 -1
  46. package/gsd-core/bin/lib/planning-workspace.cjs +9 -2
  47. package/gsd-core/bin/lib/profile-output.cjs +34 -8
  48. package/gsd-core/bin/lib/review-lane-descriptor.cjs +927 -0
  49. package/gsd-core/bin/lib/review-lane-invocation.cjs +348 -0
  50. package/gsd-core/bin/lib/review-lane-runner.cjs +594 -0
  51. package/gsd-core/bin/lib/review-reviewer-selection.cjs +114 -32
  52. package/gsd-core/bin/lib/roadmap-parser.cjs +54 -6
  53. package/gsd-core/bin/lib/roadmap.cjs +10 -4
  54. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +31 -4
  55. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +1 -1
  56. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +140 -0
  57. package/gsd-core/bin/lib/runtime-name-policy.cjs +15 -2
  58. package/gsd-core/bin/lib/smart-entry.cjs +1 -1
  59. package/gsd-core/bin/lib/state-document.cjs +164 -20
  60. package/gsd-core/bin/lib/state-transition.cjs +28 -10
  61. package/gsd-core/bin/lib/state.cjs +141 -21
  62. package/gsd-core/bin/lib/uat-predicate.cjs +6 -4
  63. package/gsd-core/bin/lib/uat.cjs +9 -7
  64. package/gsd-core/bin/lib/ui-consideration-probe.cjs +2 -2
  65. package/gsd-core/bin/lib/unusable-input.cjs +216 -0
  66. package/gsd-core/bin/lib/validate.cjs +32 -0
  67. package/gsd-core/bin/lib/verification.cjs +51 -14
  68. package/gsd-core/bin/lib/verify.cjs +128 -20
  69. package/gsd-core/bin/lib/worktree-safety.cjs +360 -15
  70. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  71. package/gsd-core/bin/shared/config-schema.manifest.json +1 -13
  72. package/gsd-core/bin/shared/model-catalog.json +5 -0
  73. package/gsd-core/bin/shared/runtime-aliases.manifest.json +5 -0
  74. package/gsd-core/references/context-budget.md +40 -0
  75. package/gsd-core/references/gate-prompts.md +6 -3
  76. package/gsd-core/references/model-profile-resolution.md +64 -13
  77. package/gsd-core/references/offer-next.md +88 -0
  78. package/gsd-core/references/planning-config.md +2 -1
  79. package/gsd-core/references/reviewer-instances.md +28 -21
  80. package/gsd-core/references/runtime-aware-dispatch.md +42 -0
  81. package/gsd-core/references/ui-consideration-probe.md +2 -2
  82. package/gsd-core/references/worktree-branch-check.md +4 -4
  83. package/gsd-core/templates/summary-minimal.md +4 -0
  84. package/gsd-core/templates/summary-standard.md +4 -0
  85. package/gsd-core/templates/summary.md +7 -0
  86. package/gsd-core/workflows/ai-integration-phase.md +4 -4
  87. package/gsd-core/workflows/audit-fix.md +4 -0
  88. package/gsd-core/workflows/audit-milestone.md +8 -0
  89. package/gsd-core/workflows/autonomous.md +19 -15
  90. package/gsd-core/workflows/check-todos.md +2 -2
  91. package/gsd-core/workflows/code-review-fix.md +14 -6
  92. package/gsd-core/workflows/code-review.md +76 -19
  93. package/gsd-core/workflows/debug.md +10 -2
  94. package/gsd-core/workflows/diagnose-issues.md +4 -0
  95. package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -4
  96. package/gsd-core/workflows/discuss-phase/modes/auto.md +0 -6
  97. package/gsd-core/workflows/discuss-phase-assumptions.md +15 -9
  98. package/gsd-core/workflows/discuss-phase.md +2 -2
  99. package/gsd-core/workflows/docs-update.md +8 -0
  100. package/gsd-core/workflows/eval-review.md +1 -1
  101. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +4 -0
  102. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +160 -0
  103. package/gsd-core/workflows/execute-phase.md +85 -115
  104. package/gsd-core/workflows/execute-plan.md +5 -4
  105. package/gsd-core/workflows/explore.md +4 -0
  106. package/gsd-core/workflows/extract-learnings.md +21 -0
  107. package/gsd-core/workflows/help/modes/full.md +3 -3
  108. package/gsd-core/workflows/import.md +4 -1
  109. package/gsd-core/workflows/ingest-docs.md +4 -0
  110. package/gsd-core/workflows/map-codebase.md +13 -6
  111. package/gsd-core/workflows/new-milestone.md +10 -2
  112. package/gsd-core/workflows/new-project.md +11 -4
  113. package/gsd-core/workflows/next.md +5 -2
  114. package/gsd-core/workflows/plan-phase.md +42 -46
  115. package/gsd-core/workflows/plan-review-convergence.md +18 -14
  116. package/gsd-core/workflows/progress.md +1 -1
  117. package/gsd-core/workflows/quick.md +14 -3
  118. package/gsd-core/workflows/review.md +146 -575
  119. package/gsd-core/workflows/scan.md +9 -1
  120. package/gsd-core/workflows/secure-phase.md +10 -2
  121. package/gsd-core/workflows/ship.md +41 -11
  122. package/gsd-core/workflows/smart-entry.md +1 -1
  123. package/gsd-core/workflows/ui-phase.md +8 -1
  124. package/gsd-core/workflows/ui-review.md +8 -1
  125. package/gsd-core/workflows/update.md +104 -5
  126. package/gsd-core/workflows/validate-phase.md +10 -2
  127. package/gsd-core/workflows/verify-work.md +8 -1
  128. package/hooks/dist/gsd-cursor-session-start.js +6 -2
  129. package/hooks/dist/gsd-cursor-stop.js +6 -2
  130. package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
  131. package/hooks/dist/gsd-graphify-update.sh +9 -0
  132. package/hooks/dist/gsd-phase-boundary.sh +14 -2
  133. package/hooks/dist/gsd-prompt-guard.js +101 -2
  134. package/hooks/dist/gsd-read-guard.js +100 -2
  135. package/hooks/dist/gsd-read-injection-scanner.js +109 -2
  136. package/hooks/dist/gsd-statusline.js +9 -6
  137. package/hooks/dist/gsd-workflow-guard.js +110 -6
  138. package/hooks/dist/gsd-worktree-path-guard.js +132 -8
  139. package/hooks/dist/lib/cursor-workspace.js +74 -0
  140. package/hooks/gsd-cursor-session-start.js +6 -2
  141. package/hooks/gsd-cursor-stop.js +6 -2
  142. package/hooks/gsd-cursor-subagent-start.js +6 -2
  143. package/hooks/gsd-graphify-update.sh +9 -0
  144. package/hooks/gsd-phase-boundary.sh +14 -2
  145. package/hooks/gsd-prompt-guard.js +101 -2
  146. package/hooks/gsd-read-guard.js +100 -2
  147. package/hooks/gsd-read-injection-scanner.js +109 -2
  148. package/hooks/gsd-statusline.js +9 -6
  149. package/hooks/gsd-workflow-guard.js +110 -6
  150. package/hooks/gsd-worktree-path-guard.js +132 -8
  151. package/hooks/lib/cursor-workspace.js +74 -0
  152. package/package.json +7 -7
  153. package/pi/gsd.cjs +26 -1
  154. package/scripts/check-coverage-gate.cjs +51 -0
  155. package/scripts/check-glossary-refs.cjs +24 -0
  156. package/scripts/ci-test-scope.cjs +67 -17
  157. package/scripts/gen-adr-index.cjs +6 -4
  158. package/scripts/gen-capability-matrix.cjs +26 -2
  159. package/scripts/gen-capability-registry.cjs +132 -34
  160. package/scripts/gen-emitted-baseline.cjs +145 -0
  161. package/scripts/lint-compiled-artifact-sync.cjs +146 -0
  162. package/scripts/lint-emitted-drift-ack.cjs +149 -0
  163. package/scripts/lint-fix-has-regression-test.cjs +131 -0
  164. package/scripts/lint-resolution-provenance.cjs +9 -0
  165. package/scripts/mutation-matrix.cjs +4 -0
  166. package/scripts/prompt-injection-scan.sh +6 -0
  167. package/scripts/registry-schema.cjs +57 -8
  168. package/scripts/release-notes/conventional-title.cjs +19 -1
  169. package/scripts/release-notes/format-github-release-notes.cjs +7 -3
  170. package/scripts/workflow-size.cjs +16 -8
  171. package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
  172. package/vscode/package.json +1 -1
  173. package/scripts/gen-golden-install-parity-zcode.cjs +0 -77
  174. package/scripts/update-size-baseline.cjs +0 -68
package/bin/install.js CHANGED
@@ -325,7 +325,13 @@ const GSD_WINDSURF_HOOK_SCRIPTS = [
325
325
 
326
326
  // GSD-managed files under hooks/lib/ (helpers required by gsd-*.sh hooks).
327
327
  // git-cmd.js does not start with "gsd-" (shared classifier for #3129), gsd-graphify-rebuild.sh does.
328
- const GSD_HOOK_LIB_FILES = ['git-cmd.js', 'gsd-graphify-rebuild.sh'];
328
+ // cursor-workspace.js (#2587) is required by the Cursor lifecycle hooks. Those
329
+ // are staged individually by writeCursorHooksJson (Cursor sets
330
+ // hostBehaviors.skipSharedHooksInstall, so it never reaches the bulk hooks/lib
331
+ // copy below) — that function stages this helper alongside them. Listing it
332
+ // here keeps uninstall and the manifest managing it for every OTHER runtime
333
+ // that does receive hooks/lib.
334
+ const GSD_HOOK_LIB_FILES = ['git-cmd.js', 'gsd-graphify-rebuild.sh', 'cursor-workspace.js'];
329
335
 
330
336
  const CODEX_AGENT_SANDBOX = {
331
337
  'gsd-executor': 'workspace-write',
@@ -627,7 +633,7 @@ if (hasMinimal && _profileArgRaw) {
627
633
 
628
634
  function selectRuntimesFromArgs(runtimeArgs) {
629
635
  if (runtimeArgs.includes('--all')) {
630
- return ['claude', 'kimi', 'kilo', 'opencode', 'pi', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'zcode'];
636
+ return ['claude', 'kimi', 'kimi-code', 'kilo', 'opencode', 'pi', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'zcode'];
631
637
  }
632
638
  if (runtimeArgs.includes('--both')) {
633
639
  return ['claude', 'opencode'];
@@ -648,6 +654,7 @@ function selectRuntimesFromArgs(runtimeArgs) {
648
654
  if (runtimeArgs.includes('--qwen')) selected.push('qwen');
649
655
  if (runtimeArgs.includes('--hermes')) selected.push('hermes');
650
656
  if (runtimeArgs.includes('--kimi')) selected.push('kimi');
657
+ if (runtimeArgs.includes('--kimi-code')) selected.push('kimi-code');
651
658
  if (runtimeArgs.includes('--codebuddy')) selected.push('codebuddy');
652
659
  if (runtimeArgs.includes('--cline')) selected.push('cline');
653
660
  if (runtimeArgs.includes('--zcode')) selected.push('zcode');
@@ -657,6 +664,62 @@ function selectRuntimesFromArgs(runtimeArgs) {
657
664
  // Runtime selection - can be set by flags or interactive prompt
658
665
  let selectedRuntimes = selectRuntimesFromArgs(args);
659
666
 
667
+ // #2505 Phase 5: Kimi variant disambiguation (#2513). Kimi CLI (Python, ~/.kimi/)
668
+ // and Kimi Code (Node, ~/.kimi-code/) are two distinct Moonshot products that
669
+ // share the "kimi" brand. Probe for each product's config.toml and warn when
670
+ // the selected runtime doesn't match the detected install — catches the common
671
+ // "ran --kimi --global but actually on Kimi Code" mistake that produced inert
672
+ // YAMLs and empty agent-skills before the Phase 1 descriptor split.
673
+ function disambiguateKimiVariant(runtimes) {
674
+ const home = os.homedir();
675
+ const hasKimiCli = fs.existsSync(path.join(home, '.kimi', 'config.toml'));
676
+ const hasKimiCode = fs.existsSync(path.join(home, '.kimi-code', 'config.toml'));
677
+ const notices = [];
678
+ if (runtimes.includes('kimi') && hasKimiCode && !hasKimiCli) {
679
+ notices.push({
680
+ kind: 'wrong-variant',
681
+ selected: 'kimi',
682
+ detected: 'kimi-code',
683
+ message: `Detected ~/.kimi-code/config.toml (Kimi Code, Node CLI) but not ~/.kimi/config.toml (Kimi CLI, Python). You selected --kimi but appear to be on Kimi Code. Re-run with --kimi-code for a working install. (Kimi CLI = Python kimi-cli with named subagents; Kimi Code = Node CLI with coder/explore/plan built-ins only.)`,
684
+ });
685
+ }
686
+ if (runtimes.includes('kimi-code') && hasKimiCli && !hasKimiCode) {
687
+ notices.push({
688
+ kind: 'wrong-variant',
689
+ selected: 'kimi-code',
690
+ detected: 'kimi',
691
+ message: `Detected ~/.kimi/config.toml (Kimi CLI, Python) but not ~/.kimi-code/config.toml (Kimi Code, Node CLI). You selected --kimi-code but appear to be on Kimi CLI. Re-run with --kimi for a working install.`,
692
+ });
693
+ }
694
+ // Distinct-entry descriptions when either Kimi variant is selected.
695
+ if (runtimes.includes('kimi')) {
696
+ notices.push({
697
+ kind: 'description',
698
+ runtime: 'kimi',
699
+ message: 'Kimi CLI (Python kimi-cli): named subagents via YAML, config at ~/.kimi/, hooks via ~/.kimi/config.toml [[hooks]].',
700
+ });
701
+ }
702
+ if (runtimes.includes('kimi-code')) {
703
+ notices.push({
704
+ kind: 'description',
705
+ runtime: 'kimi-code',
706
+ message: 'Kimi Code (Node CLI): three built-in subagents (coder/explore/plan), Agent Skills at ~/.kimi-code/skills/, config at ~/.kimi-code/.',
707
+ });
708
+ }
709
+ return notices;
710
+ }
711
+
712
+ if (selectedRuntimes.includes('kimi') || selectedRuntimes.includes('kimi-code')) {
713
+ const kimiNotices = disambiguateKimiVariant(selectedRuntimes);
714
+ for (const notice of kimiNotices) {
715
+ if (notice.kind === 'wrong-variant') {
716
+ console.error(`${yellow}⚠ Kimi variant mismatch (${notice.selected} → ${notice.detected}).${reset} ${notice.message}`);
717
+ } else if (notice.kind === 'description') {
718
+ console.log(`${dim} ${notice.runtime}: ${notice.message}${reset}`);
719
+ }
720
+ }
721
+ }
722
+
660
723
  // #1928: Google sunset Gemini CLI on 2026-06-18; Antigravity CLI is its
661
724
  // official successor. `--gemini` is no longer a valid runtime selector —
662
725
  // selectRuntimesFromArgs above no longer recognizes it, so it never lands in
@@ -3956,10 +4019,14 @@ Typed mapping (agent_type-capable schema only):
3956
4019
  inherited, or unsupported values; do not invent one-off effort literals in
3957
4020
  workflow prose.
3958
4021
  - \`fork_context: false\` by default — GSD agents load their own context via \`<files_to_read>\` blocks
3959
- - \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct Codex mapping.
3960
- Codex \`spawn_agent\` does not create or bind a git worktree automatically.
3961
- Workflows that require this isolation must fail closed or use an explicit
3962
- manual worktree protocol before spawning (#3360).
4022
+ - \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct \`spawn_agent\` mapping,
4023
+ but Codex declares \`dispatch.isolation: orchestrator-worktree\` (#2584). Codex
4024
+ \`spawn_agent\` still does not create or bind a git worktree; instead GSD itself
4025
+ creates the worktree and process-spawns the executor into it with
4026
+ \`codex exec --cd <dir>\`, performing every git operation on the executor's behalf
4027
+ (its \`workspace-write\` sandbox makes \`.git\` read-only). Workflows must therefore
4028
+ never fabricate a manual worktree protocol — route through the negotiated
4029
+ isolation adapter, which still fails closed for hosts declaring \`none\` (#3360).
3963
4030
 
3964
4031
  Generic-agent workaround (multi_agent_v1 schema — NO agent_type field):
3965
4032
  When only the generic \`multi_agent_v1\` schema is available, typed GSD agent dispatch
@@ -8434,6 +8501,17 @@ function uninstall(isGlobal, runtime = DEFAULT_RUNTIME) {
8434
8501
  console.log(` ${green}✓${reset} Removed ${removedLibFiles} hooks/lib/ helper(s)`);
8435
8502
  }
8436
8503
  }
8504
+
8505
+ // #2717: remove the CommonJS marker GSD wrote into hooks/ for runtimes that
8506
+ // stage .js hooks via dedicated paths (cursor/windsurf/codex) — but ONLY if
8507
+ // it still carries GSD's exact content (a user-authored package.json is
8508
+ // never deleted). Safe no-op for runtimes whose marker lives at the config
8509
+ // root (the shared-bundle path) or that never received one.
8510
+ try {
8511
+ if (hooksSurface.removeCommonJsMarkerIfGsdOwned(hooksDir)) {
8512
+ console.log(` ${green}✓${reset} Removed GSD hooks/package.json (CommonJS marker)`);
8513
+ }
8514
+ } catch { /* best-effort */ }
8437
8515
  }
8438
8516
 
8439
8517
  // 4z. Remove the native plugin adapter (#1914, extended to Kilo by #2093).
@@ -10339,6 +10417,45 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
10339
10417
  return Array.isArray(scopeLayout) && scopeLayout.length > 0;
10340
10418
  })();
10341
10419
 
10420
+ // #2624: write the .gsd-source marker. Extracted from its former late position so it can be
10421
+ // called BEFORE staging reads the marker (see the call site below). Scoped to the Claude-global
10422
+ // layout (issue #1477) — the only install path that ships the skills layout without a
10423
+ // commands/gsd source tree, so findInstallSourceRoot's walk-up has nothing to find and
10424
+ // /gsd-surface (list/status) throws without it. Points at the package's own commands/gsd
10425
+ // source. Guarded on source presence so a half-published package never writes a dangling
10426
+ // marker. Write failure is non-fatal (install proceeds; warn so /gsd-surface breakage is
10427
+ // diagnosable) — the same contract the late write had.
10428
+ function _writeGsdSourceMarker(runtime, targetDir, src, isGlobal) {
10429
+ if (_hostBehaviors(runtime).sourceMarkerFile && isGlobal) {
10430
+ const gsdSourceCommands = path.join(src, 'commands', 'gsd');
10431
+ if (fs.existsSync(gsdSourceCommands)) {
10432
+ try {
10433
+ // ADR-1239 Phase B write-confinement: the descriptor-sourced marker filename
10434
+ // must resolve under targetDir (parity with the other descriptor-driven writes).
10435
+ const _markerPath = assertDestWithinConfigHome(targetDir, _hostBehaviors(runtime).sourceMarkerFile);
10436
+ fs.writeFileSync(_markerPath, gsdSourceCommands + '\n', 'utf8');
10437
+ } catch (err) {
10438
+ // Non-fatal: install proceeds. But on the Claude-global layout walk-up
10439
+ // also fails (no commands/gsd source tree), so a silent write failure
10440
+ // still leaves /gsd-surface broken at runtime — warn so it's diagnosable.
10441
+ console.warn(` ${yellow}!${reset} Could not write .gsd-source marker (${err.message}); /gsd-surface list/status may fail`);
10442
+ }
10443
+ }
10444
+ }
10445
+ }
10446
+
10447
+ // #2624: write the .gsd-source marker BEFORE any staging reads it. The marker write
10448
+ // formerly lived AFTER staging; on an upgrade the marker still held the PREVIOUS
10449
+ // install's source path (e.g. an npx per-version cache dir that still exists on disk),
10450
+ // so findInstallSourceRoot(configDir) — called inside installRuntimeArtifacts below —
10451
+ // returned the stale path and every converted skill was generated from the OLD version's
10452
+ // commands/gsd, silently installing prior-version content with a self-consistent manifest
10453
+ // hash. Writing first closes the read-before-write hole for every findInstallSourceRoot
10454
+ // consumer (skills, commands, /gsd-surface, capability-state). Placed here (before the
10455
+ // _isSkillsRuntime branch) so it runs for every Claude-global install, matching the
10456
+ // original write's sourceMarkerFile && isGlobal guard exactly.
10457
+ _writeGsdSourceMarker(runtime, targetDir, src, isGlobal);
10458
+
10342
10459
  if (_isSkillsRuntime) {
10343
10460
  // Layout-driven install for skills-based runtimes (full and minimal modes)
10344
10461
  const scope = isGlobal ? 'global' : 'local';
@@ -10627,35 +10744,11 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
10627
10744
  failures.push('gsd-core');
10628
10745
  }
10629
10746
 
10630
- // Write the .gsd-source marker so runtime source resolution succeeds at
10631
- // runtime (#1477). The Claude-global skills layout ships gsd-core/{bin,
10632
- // contexts,references,templates,workflows} but NOT the commands/gsd source
10633
- // tree, and _runLegacyUninstallCleanup actively removes any commands/gsd/
10634
- // for that scope — so findInstallSourceRoot's walk-up has nothing to find
10635
- // and /gsd-surface (list/status) throws. This is the writer half of the
10636
- // marker that runtime-artifact-layout.cjs's finders already read (the reader
10637
- // landed in #1476). It points at the package's own commands/gsd source.
10638
- // Scoped to the Claude-global layout (issue #1477) — the only install path
10639
- // that ships the skills layout without a commands/gsd source tree; every
10640
- // other runtime/scope deploys commands/gsd, so its walk-up already resolves
10641
- // and needs no marker. Guarded on source presence so a half-published
10642
- // package never writes a dangling marker.
10643
- if (_hostBehaviors(runtime).sourceMarkerFile && isGlobal) {
10644
- const gsdSourceCommands = path.join(src, 'commands', 'gsd');
10645
- if (fs.existsSync(gsdSourceCommands)) {
10646
- try {
10647
- // ADR-1239 Phase B write-confinement: the descriptor-sourced marker filename
10648
- // must resolve under targetDir (parity with the other descriptor-driven writes).
10649
- const _markerPath = assertDestWithinConfigHome(targetDir, _hostBehaviors(runtime).sourceMarkerFile);
10650
- fs.writeFileSync(_markerPath, gsdSourceCommands + '\n', 'utf8');
10651
- } catch (err) {
10652
- // Non-fatal: install proceeds. But on the Claude-global layout walk-up
10653
- // also fails (no commands/gsd source tree), so a silent write failure
10654
- // still leaves /gsd-surface broken at runtime — warn so it's diagnosable.
10655
- console.warn(` ${yellow}!${reset} Could not write .gsd-source marker (${err.message}); /gsd-surface list/status may fail`);
10656
- }
10657
- }
10658
- }
10747
+ // #2624: the .gsd-source marker is now written by _writeGsdSourceMarker()
10748
+ // BEFORE staging reads it (see the early call above the _isSkillsRuntime
10749
+ // block). The former write lived here — AFTER staging — which on an upgrade
10750
+ // let staging read a stale prior-version marker and silently install
10751
+ // old-version skill content. Moved up; this site intentionally left empty.
10659
10752
 
10660
10753
  // #1629 critical fix: Windsurf workflow wrappers (convertClaudeCommandToWindsurfWorkflow)
10661
10754
  // delegate to command bodies at <targetDir>/gsd-core/commands/gsd/${stem}.md via a
@@ -11321,7 +11414,15 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
11321
11414
  throw _earlyInstallErr;
11322
11415
  }
11323
11416
 
11324
- if (plan.installSurface === 'codex-toml' && !isMinimalMode(_effectiveInstallMode)) {
11417
+ // #2695: this branch runs for BOTH `core` (minimal) and `full` profiles.
11418
+ // Hooks are lightweight infrastructure (update-check + context monitor), not the
11419
+ // "full agent surface" that `core` deliberately omits. The config.toml / agent
11420
+ // generation below is still gated by its own inner `!isMinimalMode` guard, so
11421
+ // `core` enters the branch to receive the hook-file copy + hooks.json wiring but
11422
+ // does NOT get agent roles generated. Before #2695 the outer `!isMinimalMode`
11423
+ // here skipped the whole branch for `core`, so the registered parent hook pointed
11424
+ // at a worker/registry the same installer never delivered.
11425
+ if (plan.installSurface === 'codex-toml') {
11325
11426
  // Capture pre-install snapshots before ANY GSD mutation
11326
11427
  // (#2760 fix 3). On post-write schema-validation failure OR any throw
11327
11428
  // during the mutation sequence (write failure, merge throw, etc.) we
@@ -11504,9 +11605,18 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
11504
11605
 
11505
11606
  // Copy only the hook files that Codex actually registers via its hook configuration (#2153).
11506
11607
  // #772: added gsd-context-monitor.js for the new SubagentStart/Stop/PostToolUse events.
11608
+ // #2695: the parent gsd-check-update.js spawn()s gsd-check-update-worker.js, which
11609
+ // require()s managed-hooks-registry.cjs for MANAGED_HOOKS — so all four must be
11610
+ // installed/refreshed together for every profile, or Codex is wired to a dependency
11611
+ // chain the same installer never delivers.
11507
11612
  // We deliberately do *not* copy gsd-graphify-update.sh or hooks/lib/ for Codex
11508
11613
  // in this change (graphify auto-update support for Codex is out of scope for #3579).
11509
- const CODEX_HOOKS_TO_COPY = ['gsd-check-update.js', 'gsd-context-monitor.js'];
11614
+ const CODEX_HOOKS_TO_COPY = [
11615
+ 'gsd-check-update.js',
11616
+ 'gsd-check-update-worker.js',
11617
+ 'managed-hooks-registry.cjs',
11618
+ 'gsd-context-monitor.js',
11619
+ ];
11510
11620
  const codexHooksSrc = path.join(src, 'hooks', 'dist');
11511
11621
  if (fs.existsSync(codexHooksSrc)) {
11512
11622
  const codexHooksDest = path.join(targetDir, 'hooks');
@@ -11536,9 +11646,28 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
11536
11646
  content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
11537
11647
  fs.writeFileSync(destFile, content);
11538
11648
  try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
11649
+ } else {
11650
+ // #2695: raw byte-for-byte copy for allowlisted artifacts that carry
11651
+ // no {{GSD_VERSION}} placeholder and no runtime path token (e.g.
11652
+ // managed-hooks-registry.cjs, whose only `.claude` mention is inside a
11653
+ // doc comment). Version/path transforms would be a no-op at best and a
11654
+ // surprise at worst; the issue requires the registry copied verbatim.
11655
+ fs.copyFileSync(srcFile, destFile);
11656
+ try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
11539
11657
  }
11540
11658
  }
11541
11659
  console.log(` ${green}✓${reset} Installed hooks (Codex)`);
11660
+ // #2717: write the CommonJS marker into hooks/ alongside the staged .js
11661
+ // scripts. Codex is excluded from installSharedHooksBundle by the
11662
+ // !isCodex gate, so it never received the marker the shared-bundle path
11663
+ // writes for the other runtimes. Without it, a ~/.codex/package.json
11664
+ // declaring {"type":"module"} makes Node load gsd-check-update.js /
11665
+ // gsd-context-monitor.js as ESM and their require() calls fail silently.
11666
+ // Reuses the same helper the Cursor/Windsurf writers call so the marker
11667
+ // content + user-file-preservation contract is identical everywhere.
11668
+ if (hooksSurface.ensureCommonJsMarker(codexHooksDest)) {
11669
+ console.log(` ${green}✓${reset} Wrote hooks/package.json (CommonJS mode)`);
11670
+ }
11542
11671
  }
11543
11672
 
11544
11673
  // Add Codex hooks (SessionStart for update checking) — requires codex_hooks feature flag
@@ -12390,16 +12519,17 @@ const runtimeMap = {
12390
12519
  '8': 'cursor',
12391
12520
  '9': 'hermes',
12392
12521
  '10': 'kimi',
12393
- '11': 'kilo',
12394
- '12': 'opencode',
12395
- '13': 'pi',
12396
- '14': 'qwen',
12397
- '15': 'trae',
12398
- '16': 'windsurf',
12399
- '17': 'zcode'
12522
+ '11': 'kimi-code',
12523
+ '12': 'kilo',
12524
+ '13': 'opencode',
12525
+ '14': 'pi',
12526
+ '15': 'qwen',
12527
+ '16': 'trae',
12528
+ '17': 'windsurf',
12529
+ '18': 'zcode'
12400
12530
  };
12401
- const allRuntimes = ['claude', 'antigravity', 'augment', 'cline', 'codebuddy', 'codex', 'copilot', 'cursor', 'hermes', 'kimi', 'kilo', 'opencode', 'pi', 'qwen', 'trae', 'windsurf', 'zcode'];
12402
- const ALL_RUNTIMES_OPTION = '18';
12531
+ const allRuntimes = ['claude', 'antigravity', 'augment', 'cline', 'codebuddy', 'codex', 'copilot', 'cursor', 'hermes', 'kimi', 'kimi-code', 'kilo', 'opencode', 'pi', 'qwen', 'trae', 'windsurf', 'zcode'];
12532
+ const ALL_RUNTIMES_OPTION = '19';
12403
12533
 
12404
12534
  /**
12405
12535
  * Build the runtime-selection prompt text shown by the interactive installer.
@@ -12417,14 +12547,15 @@ function buildRuntimePromptText() {
12417
12547
  ${cyan}8${reset}) Cursor ${dim}(~/.cursor)${reset}
12418
12548
  ${cyan}9${reset}) Hermes Agent ${dim}(~/.hermes)${reset}
12419
12549
  ${cyan}10${reset}) Kimi ${dim}(~/.config/agents, then ~/.agents if existing)${reset}
12420
- ${cyan}11${reset}) Kilo ${dim}(~/.config/kilo)${reset}
12421
- ${cyan}12${reset}) OpenCode ${dim}(~/.config/opencode)${reset}
12422
- ${cyan}13${reset}) pi ${dim}(~/.pi/agent)${reset}
12423
- ${cyan}14${reset}) Qwen Code ${dim}(~/.qwen)${reset}
12424
- ${cyan}15${reset}) Trae ${dim}(~/.trae)${reset}
12425
- ${cyan}16${reset}) Windsurf ${dim}(~/.codeium/windsurf)${reset}
12426
- ${cyan}17${reset}) ZCode ${dim}(~/.zcode)${reset}
12427
- ${cyan}18${reset}) All
12550
+ ${cyan}11${reset}) Kimi Code ${dim}(~/.kimi-code)${reset}
12551
+ ${cyan}12${reset}) Kilo ${dim}(~/.config/kilo)${reset}
12552
+ ${cyan}13${reset}) OpenCode ${dim}(~/.config/opencode)${reset}
12553
+ ${cyan}14${reset}) pi ${dim}(~/.pi/agent)${reset}
12554
+ ${cyan}15${reset}) Qwen Code ${dim}(~/.qwen)${reset}
12555
+ ${cyan}16${reset}) Trae ${dim}(~/.trae)${reset}
12556
+ ${cyan}17${reset}) Windsurf ${dim}(~/.codeium/windsurf)${reset}
12557
+ ${cyan}18${reset}) ZCode ${dim}(~/.zcode)${reset}
12558
+ ${cyan}19${reset}) All
12428
12559
 
12429
12560
  ${dim}Select multiple: 1,2,6 or 1 2 6${reset}
12430
12561
  `;
@@ -12435,7 +12566,7 @@ function buildRuntimePromptText() {
12435
12566
  * Pure function — exported so tests can verify split/dedupe/fallback behavior.
12436
12567
  * - Accepts comma- and/or whitespace-separated choices
12437
12568
  * - Deduplicates while preserving order
12438
- * - Maps option 16 ("All") to every runtime
12569
+ * - Maps option 19 ("All") to every runtime
12439
12570
  * - Falls back to ['claude'] when nothing valid is selected
12440
12571
  */
12441
12572
  function parseRuntimeInput(answer) {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: gsd:plan-review-convergence
3
3
  description: "Cross-AI plan convergence - replan until review concerns are resolved."
4
- argument-hint: "<phase> [--codex] [--gemini] [--claude] [--opencode] [--ollama] [--lm-studio] [--llama-cpp] [--agy] [--text] [--ws <name>] [--all] [--max-cycles N]"
4
+ argument-hint: "<phase> [--gemini] [--claude] [--codex] [--coderabbit] [--opencode] [--qwen] [--cursor] [--antigravity] [--agy] [--ollama] [--lm-studio] [--llama-cpp] [--kimi-code] [--text] [--ws <name>] [--all] [--max-cycles N]"
5
5
  allowed-tools:
6
6
  - Read
7
7
  - Write
@@ -44,10 +44,14 @@ Phase number: extracted from $ARGUMENTS (required)
44
44
  - `--gemini` — Use Gemini CLI as reviewer
45
45
  - `--agy` / `--antigravity` — Use Antigravity CLI as reviewer (successor to the discontinued Gemini CLI)
46
46
  - `--claude` — Use Claude CLI as reviewer (separate session)
47
+ - `--coderabbit` — Use CodeRabbit as reviewer (reviews the working-tree diff, not the source tree)
47
48
  - `--opencode` — Use OpenCode as reviewer
49
+ - `--qwen` — Use Qwen Code CLI as reviewer (Alibaba Qwen models)
50
+ - `--cursor` — Use Cursor agent as reviewer
48
51
  - `--ollama` — Use local Ollama server as reviewer (OpenAI-compatible, default host `http://localhost:11434`; configure model via `review.models.ollama`)
49
52
  - `--lm-studio` — Use local LM Studio server as reviewer (OpenAI-compatible, default host `http://localhost:1234`; configure model via `review.models.lm_studio`)
50
53
  - `--llama-cpp` — Use local llama.cpp server as reviewer (OpenAI-compatible, default host `http://localhost:8080`; configure model via `review.models.llama_cpp`)
54
+ - `--kimi-code` — Use Kimi Code CLI as reviewer (Moonshot AI)
51
55
  - `--all` — Use all available CLIs and running local model servers
52
56
  - `--max-cycles N` — Maximum replan→review cycles (default: 3)
53
57