@opengsd/gsd-core 1.7.0-rc.2 → 1.7.0-rc.4

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 (184) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/GEMINI.md +25 -23
  4. package/README.ja-JP.md +4 -3
  5. package/README.ko-KR.md +4 -3
  6. package/README.md +7 -6
  7. package/README.pt-BR.md +4 -3
  8. package/README.zh-CN.md +4 -3
  9. package/agents/gsd-advisor-researcher.md +1 -1
  10. package/agents/gsd-ai-researcher.md +1 -1
  11. package/agents/gsd-code-fixer.md +1 -1
  12. package/agents/gsd-debug-session-manager.md +1 -1
  13. package/agents/gsd-debugger.md +1 -1
  14. package/agents/gsd-domain-researcher.md +1 -1
  15. package/agents/gsd-eval-auditor.md +1 -1
  16. package/agents/gsd-executor.md +4 -4
  17. package/agents/gsd-intel-updater.md +1 -1
  18. package/agents/gsd-mempalace-curator.md +1 -1
  19. package/agents/gsd-phase-researcher.md +2 -2
  20. package/agents/gsd-plan-checker.md +1 -1
  21. package/agents/gsd-planner.md +2 -2
  22. package/agents/gsd-project-researcher.md +2 -2
  23. package/agents/gsd-research-synthesizer.md +1 -1
  24. package/agents/gsd-ui-researcher.md +2 -2
  25. package/agents/gsd-verifier.md +2 -2
  26. package/bin/install.js +132 -464
  27. package/commands/gsd/map-codebase.md +4 -4
  28. package/commands/gsd/mempalace-capture.md +1 -1
  29. package/commands/gsd/mempalace-recall.md +9 -5
  30. package/commands/gsd/next.md +29 -0
  31. package/commands/gsd/ns-project.md +2 -1
  32. package/commands/gsd/ns-workflow.md +5 -2
  33. package/commands/gsd/onboard.md +46 -0
  34. package/gsd-core/bin/ensure-runtime-build.cjs +246 -0
  35. package/gsd-core/bin/gsd-tools.cjs +72 -3
  36. package/gsd-core/bin/lib/capability-registry.cjs +684 -264
  37. package/gsd-core/bin/lib/capability-state.cjs +117 -18
  38. package/gsd-core/bin/lib/capability-writer.cjs +11 -1
  39. package/gsd-core/bin/lib/check-command-router.cjs +111 -1
  40. package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +136 -0
  41. package/gsd-core/bin/lib/claude-orchestration.cjs +404 -0
  42. package/gsd-core/bin/lib/clusters.cjs +2 -0
  43. package/gsd-core/bin/lib/command-aliases.cjs +8 -0
  44. package/gsd-core/bin/lib/config.cjs +19 -1
  45. package/gsd-core/bin/lib/core-utils.cjs +41 -0
  46. package/gsd-core/bin/lib/external-job.cjs +287 -0
  47. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +151 -0
  48. package/gsd-core/bin/lib/graphify.cjs +41 -9
  49. package/gsd-core/bin/lib/init-command-router.cjs +4 -0
  50. package/gsd-core/bin/lib/init.cjs +25 -69
  51. package/gsd-core/bin/lib/install-engine.cjs +8 -5
  52. package/gsd-core/bin/lib/install-profiles.cjs +2 -0
  53. package/gsd-core/bin/lib/loop-resolver.cjs +7 -1
  54. package/gsd-core/bin/lib/milestone.cjs +7 -1
  55. package/gsd-core/bin/lib/model-resolver.cjs +69 -4
  56. package/gsd-core/bin/lib/onboard-projection.cjs +309 -0
  57. package/gsd-core/bin/lib/phase.cjs +14 -2
  58. package/gsd-core/bin/lib/plan-scan.cjs +9 -1
  59. package/gsd-core/bin/lib/profile-output.cjs +1 -1
  60. package/gsd-core/bin/lib/prohibition-enforcement.cjs +21 -19
  61. package/gsd-core/bin/lib/roadmap.cjs +17 -2
  62. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +18 -13
  63. package/gsd-core/bin/lib/runtime-name-policy.cjs +11 -11
  64. package/gsd-core/bin/lib/shell-command-projection.cjs +12 -8
  65. package/gsd-core/bin/lib/smart-entry.cjs +521 -0
  66. package/gsd-core/bin/lib/surface.cjs +63 -33
  67. package/gsd-core/bin/lib/update-context.cjs +0 -5
  68. package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
  69. package/gsd-core/bin/shared/model-catalog.json +5 -5
  70. package/gsd-core/bin/shared/runtime-aliases.manifest.json +0 -5
  71. package/gsd-core/references/gates.md +1 -1
  72. package/gsd-core/references/gsd-run-resolver.md +8 -0
  73. package/gsd-core/references/planning-config.md +1 -1
  74. package/gsd-core/templates/project.md +1 -1
  75. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  76. package/gsd-core/workflows/add-backlog.md +1 -1
  77. package/gsd-core/workflows/add-phase.md +1 -1
  78. package/gsd-core/workflows/add-tests.md +1 -1
  79. package/gsd-core/workflows/add-todo.md +1 -1
  80. package/gsd-core/workflows/ai-integration-phase.md +1 -1
  81. package/gsd-core/workflows/audit-fix.md +1 -1
  82. package/gsd-core/workflows/audit-milestone.md +1 -1
  83. package/gsd-core/workflows/audit-uat.md +1 -1
  84. package/gsd-core/workflows/autonomous.md +1 -1
  85. package/gsd-core/workflows/check-todos.md +1 -1
  86. package/gsd-core/workflows/cleanup.md +1 -1
  87. package/gsd-core/workflows/code-review-fix.md +1 -1
  88. package/gsd-core/workflows/code-review.md +1 -1
  89. package/gsd-core/workflows/complete-milestone.md +1 -1
  90. package/gsd-core/workflows/debug.md +1 -1
  91. package/gsd-core/workflows/diagnose-issues.md +1 -1
  92. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  93. package/gsd-core/workflows/discuss-phase/modes/auto.md +1 -1
  94. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  95. package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
  96. package/gsd-core/workflows/discuss-phase.md +2 -2
  97. package/gsd-core/workflows/do.md +5 -4
  98. package/gsd-core/workflows/docs-update.md +1 -1
  99. package/gsd-core/workflows/edit-phase.md +1 -1
  100. package/gsd-core/workflows/eval-review.md +1 -1
  101. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
  102. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
  103. package/gsd-core/workflows/execute-phase.md +4 -5
  104. package/gsd-core/workflows/execute-plan.md +1 -1
  105. package/gsd-core/workflows/explore.md +1 -1
  106. package/gsd-core/workflows/extract-learnings.md +1 -1
  107. package/gsd-core/workflows/forensics.md +1 -1
  108. package/gsd-core/workflows/graduation.md +1 -1
  109. package/gsd-core/workflows/health.md +1 -1
  110. package/gsd-core/workflows/help/modes/brief.md +2 -1
  111. package/gsd-core/workflows/help/modes/default.md +2 -1
  112. package/gsd-core/workflows/help/modes/full.md +25 -1
  113. package/gsd-core/workflows/help/modes/topic.md +2 -1
  114. package/gsd-core/workflows/import.md +1 -1
  115. package/gsd-core/workflows/ingest-docs.md +1 -1
  116. package/gsd-core/workflows/insert-phase.md +1 -1
  117. package/gsd-core/workflows/list-seeds.md +1 -1
  118. package/gsd-core/workflows/list-workspaces.md +1 -1
  119. package/gsd-core/workflows/manager.md +1 -1
  120. package/gsd-core/workflows/map-codebase.md +1 -1
  121. package/gsd-core/workflows/milestone-summary.md +1 -1
  122. package/gsd-core/workflows/mvp-phase.md +1 -1
  123. package/gsd-core/workflows/new-milestone.md +1 -1
  124. package/gsd-core/workflows/new-project.md +1 -1
  125. package/gsd-core/workflows/new-workspace.md +1 -1
  126. package/gsd-core/workflows/next.md +1 -1
  127. package/gsd-core/workflows/onboard.md +277 -0
  128. package/gsd-core/workflows/pause-work.md +1 -1
  129. package/gsd-core/workflows/plan-milestone-gaps.md +1 -1
  130. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  131. package/gsd-core/workflows/plan-phase.md +9 -2
  132. package/gsd-core/workflows/plan-review-convergence.md +1 -1
  133. package/gsd-core/workflows/plant-seed.md +1 -1
  134. package/gsd-core/workflows/pr-branch.md +1 -1
  135. package/gsd-core/workflows/profile-user.md +1 -1
  136. package/gsd-core/workflows/progress.md +1 -1
  137. package/gsd-core/workflows/quick.md +21 -1
  138. package/gsd-core/workflows/reapply-patches.md +1 -1
  139. package/gsd-core/workflows/remove-phase.md +1 -1
  140. package/gsd-core/workflows/remove-workspace.md +1 -1
  141. package/gsd-core/workflows/resume-project.md +1 -1
  142. package/gsd-core/workflows/review.md +43 -7
  143. package/gsd-core/workflows/scan.md +1 -1
  144. package/gsd-core/workflows/secure-phase.md +1 -1
  145. package/gsd-core/workflows/settings-advanced.md +3 -1
  146. package/gsd-core/workflows/settings-integrations.md +1 -1
  147. package/gsd-core/workflows/settings.md +1 -1
  148. package/gsd-core/workflows/ship.md +1 -1
  149. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  150. package/gsd-core/workflows/sketch.md +1 -1
  151. package/gsd-core/workflows/smart-entry.md +120 -0
  152. package/gsd-core/workflows/spec-phase.md +8 -6
  153. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  154. package/gsd-core/workflows/spike.md +1 -1
  155. package/gsd-core/workflows/stats.md +1 -1
  156. package/gsd-core/workflows/thread.md +1 -1
  157. package/gsd-core/workflows/transition.md +1 -1
  158. package/gsd-core/workflows/ui-phase.md +1 -1
  159. package/gsd-core/workflows/ui-review.md +1 -1
  160. package/gsd-core/workflows/ultraplan-phase.md +1 -1
  161. package/gsd-core/workflows/update.md +3 -6
  162. package/gsd-core/workflows/validate-phase.md +1 -1
  163. package/gsd-core/workflows/verify-phase.md +1 -1
  164. package/gsd-core/workflows/verify-work.md +62 -4
  165. package/package.json +3 -5
  166. package/scripts/ci-test-scope.cjs +19 -1
  167. package/scripts/gen-golden-install-parity-zcode.cjs +77 -0
  168. package/scripts/generate-package-identity.cjs +27 -2
  169. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -148
  170. package/scripts/lint-regression-test-names.allowlist.json +1 -273
  171. package/scripts/lint-test-file-count.allowlist.json +7 -91
  172. package/scripts/research-profiles.cjs +6 -6
  173. package/scripts/run-tests.cjs +18 -3
  174. package/scripts/slurm-adapter.cjs +269 -0
  175. package/scripts/sync-manifest-versions.cjs +3 -2
  176. package/scripts/sync-runtime-launcher.cjs +20 -2
  177. package/skills/gsd-map-codebase/SKILL.md +3 -3
  178. package/skills/gsd-mempalace-capture/SKILL.md +1 -1
  179. package/skills/gsd-mempalace-recall/SKILL.md +9 -5
  180. package/skills/gsd-next/SKILL.md +30 -0
  181. package/skills/gsd-ns-project/SKILL.md +1 -0
  182. package/skills/gsd-ns-workflow/SKILL.md +4 -1
  183. package/skills/gsd-onboard/SKILL.md +46 -0
  184. package/gemini-extension.json +0 -6
@@ -1135,7 +1135,10 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
1135
1135
  const checkboxPattern = new RegExp(`(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}${OPTIONAL_PHASE_TAG_SOURCE}[:\\s][^\\n]*)`, 'i');
1136
1136
  roadmapContent = roadmapContent.replace(checkboxPattern, `$1x$2 (completed ${today})`);
1137
1137
  const tableRowPattern = new RegExp(`^(\\|\\s*${phaseEscaped}\\.?\\s[^|]*(?:\\|[^\\n]*))$`, 'im');
1138
- roadmapContent = roadmapContent.replace(tableRowPattern, (fullRow) => {
1138
+ // Scope the Progress-row search to the ## Progress section so the regex
1139
+ // doesn't bind to an earlier table (e.g. | Phase | Requirements | Count |)
1140
+ // whose rows also start with the phase number. (#2012)
1141
+ const updateProgressRow = (fullRow) => {
1139
1142
  const cells = fullRow.split('|').slice(1, -1);
1140
1143
  const dateShape = /^\d{4}-\d{2}-\d{2}$/;
1141
1144
  if (cells.length === 5) {
@@ -1153,7 +1156,16 @@ function cmdPhaseComplete(cwd, phaseNum, raw) {
1153
1156
  cells[3] = dateShape.test(existingDate4) ? cells[3] : ` ${today} `;
1154
1157
  }
1155
1158
  return '|' + cells.join('|') + '|';
1156
- });
1159
+ };
1160
+ const progressIdx = roadmapContent.indexOf('## Progress');
1161
+ if (progressIdx >= 0) {
1162
+ const beforeProgress = roadmapContent.slice(0, progressIdx);
1163
+ const progressSection = roadmapContent.slice(progressIdx);
1164
+ roadmapContent = beforeProgress + progressSection.replace(tableRowPattern, updateProgressRow);
1165
+ }
1166
+ else {
1167
+ roadmapContent = roadmapContent.replace(tableRowPattern, updateProgressRow);
1168
+ }
1157
1169
  const planCountPattern = new RegExp(`(#{2,4}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`, 'i');
1158
1170
  roadmapContent = roadmapContent.replace(planCountPattern, `$1${summaryCount}/${planCount} plans complete`);
1159
1171
  const phaseInfoSummaries = phaseInfo['summaries'];
@@ -9,6 +9,9 @@
9
9
  */
10
10
  const node_fs_1 = require("node:fs");
11
11
  const node_path_1 = require("node:path");
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
13
+ const coreUtils = require("./core-utils.cjs");
14
+ const { countMatchedSummaries } = coreUtils;
12
15
  // Excluded derivative files
13
16
  const PLAN_OUTLINE_RE = /-OUTLINE\.md$/i;
14
17
  const PLAN_PRE_BOUNCE_RE = /\.pre-bounce\.md$/i;
@@ -72,7 +75,12 @@ function scanPhasePlans(phaseDir) {
72
75
  const planFiles = rootPlanFiles.concat(nestedPlanFiles);
73
76
  const summaryFiles = rootSummaryFiles.concat(nestedSummaryFiles);
74
77
  const planCount = planFiles.length;
75
- const summaryCount = summaryFiles.length;
78
+ // Count only summaries that are the PLAN→SUMMARY partner of an existing plan
79
+ // (#1988): stray non-plan summaries (e.g. 30-FIX-CR02-SUMMARY.md,
80
+ // 30-GAPCLOSURE-SUMMARY.md) must not inflate summary_count or flip a phase to
81
+ // Complete when plans are still missing summaries. summaryFiles (the array)
82
+ // still holds every summary on disk for callers that read/list them.
83
+ const summaryCount = countMatchedSummaries(planFiles, summaryFiles);
76
84
  return {
77
85
  planCount,
78
86
  summaryCount,
@@ -1024,7 +1024,7 @@ function cmdGenerateClaudeMd(cwd, options, raw) {
1024
1024
  // project-instruction-file`). Previously this was a codex-only override
1025
1025
  // (#3163) that left AGENTS-native runtimes (opencode/kilo/kimi) emitting
1026
1026
  // CLAUDE.md; copilot now resolves to .github/copilot-instructions.md, and
1027
- // antigravity/gemini to GEMINI.md. GSD_RUNTIME env var takes precedence
1027
+ // antigravity to GEMINI.md. GSD_RUNTIME env var takes precedence
1028
1028
  // over config.runtime, mirroring detectRuntime().
1029
1029
  //
1030
1030
  // Non-claude runtimes always win over a stale `claude_md_path` (the #3163
@@ -515,12 +515,12 @@ function defaultProveFailFirst(check, cwd, timeoutMs) {
515
515
  // a setup crash, not from the prohibition firing. Requiring the fixture to exist before spawning
516
516
  // closes the realistic typo/stale-path case (#1279 review, Major 1).
517
517
  //
518
- // CAUSATION (#1346): existence + a non-vacuous red is necessary but not sufficient — a deceptive
519
- // negative test that reds merely BECAUSE `GSD_PROHIB_SUBJECT` is set (rather than because the
520
- // subject's CONTENT violates the must-NOT) would otherwise be accepted. The OPTIONAL `cleanFixture`
521
- // control below proves content-dependence when supplied (red on bad AND green on clean). When NO
522
- // clean fixture is authored the control cannot run, so the residual remains a documented constraint
523
- // for that case (an author opts into the stronger proof by supplying a known-clean control subject).
518
+ // CAUSATION (#1346; MANDATORY as of #1906): existence + a non-vacuous red is necessary but not
519
+ // sufficient — a deceptive negative test that reds merely BECAUSE `GSD_PROHIB_SUBJECT` is set
520
+ // (rather than because the subject's CONTENT violates the must-NOT) would otherwise be accepted.
521
+ // The `cleanFixture` control below proves content-dependence (red on bad AND green on clean) and is
522
+ // now REQUIRED for the node-test kind: absent it, the check is un-provable (fail-closed), not
523
+ // accepted under the weaker violation-only proof (#1906 supersedes #1346's opt-in; ADR-1606 D4).
524
524
  // Resolve the fixture against `cwd` (NOT the verify process's cwd): the spawned test reads
525
525
  // `GSD_PROHIB_SUBJECT` and resolves a relative subject against `cwd`, so the existence check must
526
526
  // use the SAME base or it could pass here yet ENOENT in the child (re-opening the fail-open hole).
@@ -530,20 +530,22 @@ function defaultProveFailFirst(check, cwd, timeoutMs) {
530
530
  const redOut = runNodeTestWithSubject(check, cwd, fixture, timeoutMs);
531
531
  if (!isNonVacuousNodeTestRed(redOut, check.target))
532
532
  return { provenFailFirst: false, method: 'violation-fixture' };
533
- // #1346 CAUSATION CONTROL (optional): if a clean control subject is supplied, run the SAME test
534
- // against it and require it to stay GREEN. This proves the red above was caused by the subject's
535
- // CONTENT — a deceptive test that reds merely because GSD_PROHIB_SUBJECT is SET reds here too →
536
- // not content-dependent → not proven. Absent → no control (documented residual; backward-compat).
533
+ // #1906 CAUSATION CONTROL (MANDATORY for node-test — supersedes #1346's opt-in, ADR-1606 D4): the
534
+ // clean control subject is REQUIRED. Run the SAME test against it and require it to stay GREEN,
535
+ // proving the red above was caused by the subject's CONTENT — a deceptive test that reds merely
536
+ // because GSD_PROHIB_SUBJECT is SET reds here too → not content-dependent → not proven. ABSENT →
537
+ // the control cannot run → un-provable → fail-closed (NOT accepted under the weaker violation-only
538
+ // proof). This is the one behavior change vs #1346: absent `cleanFixture` was previously proven.
537
539
  const clean = check.cleanFixture;
538
- if (clean) {
539
- // A supplied-but-missing/typo'd control path can't run the control → fail-closed, symmetric
540
- // with the violation-fixture existence guard (resolve against the SAME `cwd` as the child).
541
- if (!node_fs_1.default.existsSync(node_path_1.default.resolve(cwd, clean)))
542
- return { provenFailFirst: false, method: 'violation-fixture' };
543
- const cleanOut = runNodeTestWithSubject(check, cwd, clean, timeoutMs);
544
- if (!isNonVacuousNodeTestPass(cleanOut, check.target))
545
- return { provenFailFirst: false, method: 'violation-fixture' };
546
- }
540
+ if (!clean)
541
+ return { provenFailFirst: false, method: 'violation-fixture' };
542
+ // A supplied-but-missing/typo'd control path can't run the control → fail-closed, symmetric
543
+ // with the violation-fixture existence guard (resolve against the SAME `cwd` as the child).
544
+ if (!node_fs_1.default.existsSync(node_path_1.default.resolve(cwd, clean)))
545
+ return { provenFailFirst: false, method: 'violation-fixture' };
546
+ const cleanOut = runNodeTestWithSubject(check, cwd, clean, timeoutMs);
547
+ if (!isNonVacuousNodeTestPass(cleanOut, check.target))
548
+ return { provenFailFirst: false, method: 'violation-fixture' };
547
549
  return { provenFailFirst: true, method: 'violation-fixture' };
548
550
  }
549
551
  // Unknown kind — defensive; the LOCATE guard already rejects it.
@@ -32,8 +32,14 @@ const { planningPaths, withPlanningLock, findContextMdIn } = planningWorkspace;
32
32
  // eslint-disable-next-line @typescript-eslint/no-require-imports
33
33
  const scanPhasePlans = require("./plan-scan.cjs");
34
34
  // eslint-disable-next-line @typescript-eslint/no-require-imports
35
+ const coreUtils = require("./core-utils.cjs");
36
+ const { countMatchedSummaries } = coreUtils;
37
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
35
38
  const frontmatter = require("./frontmatter.cjs");
36
39
  const { extractFrontmatter, parseMustHavesBlock } = frontmatter;
40
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
41
+ const verificationMod = require("./verification.cjs");
42
+ const { readVerificationStatus } = verificationMod;
37
43
  // ─── coerceTruthToString ──────────────────────────────────────────────────────
38
44
  /**
39
45
  * Coerce an arbitrary YAML scalar/object into a string for cross-cutting
@@ -410,12 +416,21 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
410
416
  error(`Phase ${phaseNum} not found`);
411
417
  }
412
418
  const planCount = phaseInfo.plans.length;
413
- const summaryCount = phaseInfo.summaries.length;
419
+ // Count only summaries that pair with a real plan (#1988): stray non-plan
420
+ // summaries (30-FIX-CR02-SUMMARY.md, 30-GAPCLOSURE-SUMMARY.md, …) must not
421
+ // inflate summary_count and silently flip the phase to Complete.
422
+ const summaryCount = countMatchedSummaries(phaseInfo.plans, phaseInfo.summaries);
414
423
  if (planCount === 0) {
415
424
  output({ updated: false, reason: 'No plans found', plan_count: 0, summary_count: 0 }, raw, 'no plans');
416
425
  return;
417
426
  }
418
- const isComplete = summaryCount >= planCount;
427
+ // Verification gate (#2022): do NOT check the phase checkbox or stamp a
428
+ // completion date until the phase's verification status is 'passed', matching
429
+ // cmdPhaseComplete's gate (phase.cts:1436). Previously the checkbox fired the
430
+ // moment the last plan summary landed — before gsd-verifier had verified.
431
+ const phaseDir = node_path_1.default.join(cwd, phaseInfo.directory);
432
+ const verificationPassed = readVerificationStatus(phaseDir).status === 'passed';
433
+ const isComplete = summaryCount >= planCount && verificationPassed;
419
434
  const status = isComplete ? 'Complete' : summaryCount > 0 ? 'In Progress' : 'Planned';
420
435
  const today = clock_cjs_1.realClock.today();
421
436
  if (!node_fs_1.default.existsSync(roadmapPath)) {
@@ -1039,7 +1039,7 @@ function applySettingsJsonHooks(settings, opts) {
1039
1039
  // Configure PreToolUse hook for prompt injection detection
1040
1040
  // ADR-857 phase 5f-2: drive dialect from opts.hookEvents (registry descriptor).
1041
1041
  // hookEvents='gemini' → BeforeTool; all others → PreToolUse.
1042
- // Equivalence: hookEvents='gemini' iff runtime∈{gemini,antigravity} (same as old check).
1042
+ // Equivalence: hookEvents='gemini' iff runtime===antigravity (same as old check).
1043
1043
  const preToolEvent = hookEvents === 'gemini' ? 'BeforeTool' : 'PreToolUse';
1044
1044
  if (!settings.hooks[preToolEvent]) {
1045
1045
  settings.hooks[preToolEvent] = [];
@@ -1312,9 +1312,14 @@ function applySettingsJsonHooks(settings, opts) {
1312
1312
  }
1313
1313
  }
1314
1314
  // ── end SubagentStop / Stop / PreCompact events ────────────────────────────
1315
- // ── Gemini-only extended hook events (#776) ───────────────────────────────
1316
- // Gemini CLI exposes several hook events beyond BeforeTool/AfterTool that
1317
- // gsd previously did not register. Three high-value events are added here:
1315
+ // ── Extended hook events (#776; Gemini runtime removed #1928) ──────────────
1316
+ // The Gemini-3-backend dialect exposes several hook events beyond
1317
+ // BeforeTool/AfterTool. These were added for the now-removed Gemini CLI
1318
+ // runtime (#776). No currently supported runtime declares them —
1319
+ // Antigravity's descriptor carries `extendedHookEvents: []` — so this loop
1320
+ // is an inert, descriptor-driven seam: it no-ops for every present runtime
1321
+ // and re-activates automatically if a future runtime declares any of them.
1322
+ // Three high-value events would be wired here:
1318
1323
  //
1319
1324
  // BeforeAgent — fires after user submits a prompt, before the agent
1320
1325
  // plans. Wire gsd-context-monitor for context headroom
@@ -1335,15 +1340,15 @@ function applySettingsJsonHooks(settings, opts) {
1335
1340
  // gsd hook use case at this time; deferred to a follow-on issue.
1336
1341
  //
1337
1342
  // Guard is now descriptor-driven: only events present in extendedEvents are wired.
1338
- for (const geminiEvent of ['BeforeAgent', 'AfterAgent', 'BeforeModel']) {
1339
- if (!extendedEvents.includes(geminiEvent))
1343
+ for (const extendedEvent of ['BeforeAgent', 'AfterAgent', 'BeforeModel']) {
1344
+ if (!extendedEvents.includes(extendedEvent))
1340
1345
  continue;
1341
- if (!Array.isArray(settings.hooks[geminiEvent])) {
1342
- settings.hooks[geminiEvent] = [];
1346
+ if (!Array.isArray(settings.hooks[extendedEvent])) {
1347
+ settings.hooks[extendedEvent] = [];
1343
1348
  }
1344
- const alreadyHasContextMonitor = settings.hooks[geminiEvent].some((entry) => entry.hooks && entry.hooks.some((h) => referencesHook(h, 'gsd-context-monitor')));
1349
+ const alreadyHasContextMonitor = settings.hooks[extendedEvent].some((entry) => entry.hooks && entry.hooks.some((h) => referencesHook(h, 'gsd-context-monitor')));
1345
1350
  if (!alreadyHasContextMonitor && node_fs_1.default.existsSync(contextMonitorFile) && contextMonitorCommand) {
1346
- settings.hooks[geminiEvent].push({
1351
+ settings.hooks[extendedEvent].push({
1347
1352
  hooks: [
1348
1353
  {
1349
1354
  type: 'command',
@@ -1352,13 +1357,13 @@ function applySettingsJsonHooks(settings, opts) {
1352
1357
  }
1353
1358
  ]
1354
1359
  });
1355
- console.log(` ${green}✓${reset} Configured ${geminiEvent} context monitor hook (Gemini)`);
1360
+ console.log(` ${green}✓${reset} Configured ${extendedEvent} context monitor hook`);
1356
1361
  }
1357
1362
  else if (!alreadyHasContextMonitor && !node_fs_1.default.existsSync(contextMonitorFile)) {
1358
- console.warn(` ${yellow}⚠${reset} Skipped ${geminiEvent} hook — gsd-context-monitor.js not found at target`);
1363
+ console.warn(` ${yellow}⚠${reset} Skipped ${extendedEvent} hook — gsd-context-monitor.js not found at target`);
1359
1364
  }
1360
1365
  }
1361
- // ── end Gemini-only extended hook events ──────────────────────────────────
1366
+ // ── end Antigravity-only extended hook events ──────────────────────────────
1362
1367
  // ── FileChanged hook: hot-reload gsd config on .planning/config.json edits ─
1363
1368
  // Claude Code fires FileChanged when a watched file changes on disk. Wire
1364
1369
  // gsd-config-reload.js to reload the gsd config context whenever the user
@@ -29,7 +29,6 @@ const FALLBACK_ALIASES = {
29
29
  claude: ['claude', 'claude-code', 'claude-cli'],
30
30
  opencode: ['opencode', 'open-code', 'opencode-cli'],
31
31
  kilo: ['kilo', 'kilo-cli'],
32
- gemini: ['gemini', 'gemini-cli', 'gemini-code'],
33
32
  codex: ['codex', 'codex-app', 'codex-cli', 'codex_desktop', 'codex-desktop'],
34
33
  copilot: ['copilot', 'copilot-cli', 'github-copilot'],
35
34
  antigravity: ['antigravity', 'antigravity-cli', 'antigravity-agent'],
@@ -114,7 +113,7 @@ function resolveRuntimeNameFromCandidates(...candidates) {
114
113
  * claude → .claude/CLAUDE.md
115
114
  * codex, opencode, kilo, kimi → AGENTS.md
116
115
  * copilot → .github/copilot-instructions.md
117
- * antigravity, gemini → GEMINI.md
116
+ * antigravity → GEMINI.md
118
117
  * unknown / future runtimes → AGENTS.md (safe cross-agent default)
119
118
  *
120
119
  * Source-of-truth references for each runtime's read path:
@@ -126,7 +125,9 @@ function resolveRuntimeNameFromCandidates(...candidates) {
126
125
  * 'copilot-instructions' writes the same `.github/copilot-instructions.md`.)
127
126
  * - codex/opencode/kilo/kimi: AGENTS.md is the documented cross-agent
128
127
  * instruction file (agentsmd/agents.md convention).
129
- * - antigravity/gemini: GEMINI.md is Gemini CLI's contextFileName.
128
+ * - antigravity: GEMINI.md is Antigravity CLI's contextFileName (the Gemini
129
+ * CLI runtime that historically shared this file was removed — #1928;
130
+ * Google sunset Gemini CLI 2026-06-18 and Antigravity CLI is its successor).
130
131
  *
131
132
  * Aliases are normalized via `canonicalizeRuntimeName` first, so inputs like
132
133
  * `codex-cli` resolve to `codex` → `AGENTS.md`. Replaces the prior codex-only
@@ -139,7 +140,7 @@ function getProjectInstructionFile(runtime) {
139
140
  return '.claude/CLAUDE.md';
140
141
  if (canonical === 'copilot')
141
142
  return '.github/copilot-instructions.md';
142
- if (canonical === 'antigravity' || canonical === 'gemini')
143
+ if (canonical === 'antigravity')
143
144
  return 'GEMINI.md';
144
145
  // codex, opencode, kilo, kimi, AND unknown/future runtimes all default to
145
146
  // root AGENTS.md (the safe cross-agent instruction file).
@@ -180,7 +181,7 @@ function getDirName(runtime) {
180
181
  *
181
182
  * Voice: these are the SHORT UI labels, intentionally distinct from the
182
183
  * descriptor `title` (the long product name — e.g. "OpenAI Codex CLI",
183
- * "GitHub Copilot", "Gemini CLI") which serves documentation/registry display,
184
+ * "GitHub Copilot") which serves documentation/registry display,
184
185
  * not the install console. A future slice may relocate this to a
185
186
  * `runtime.label` descriptor field; until then this table is the source.
186
187
  *
@@ -195,7 +196,6 @@ function getDirName(runtime) {
195
196
  const RUNTIME_LABELS = {
196
197
  claude: 'Claude Code',
197
198
  opencode: 'OpenCode',
198
- gemini: 'Gemini',
199
199
  kilo: 'Kilo',
200
200
  codex: 'Codex',
201
201
  copilot: 'Copilot',
@@ -209,6 +209,7 @@ const RUNTIME_LABELS = {
209
209
  kimi: 'Kimi CLI',
210
210
  codebuddy: 'CodeBuddy',
211
211
  cline: 'Cline',
212
+ zcode: 'ZCode',
212
213
  };
213
214
  /**
214
215
  * Map a canonical runtime id to its short display label for the
@@ -231,7 +232,7 @@ function getRuntimeLabel(runtime) {
231
232
  * bin/install.js (ADR-1239 Phase B / #1679, AC2 slice 2) — the add-a-host tax:
232
233
  * a new runtime meant remembering to add a branch here. Values are preserved
233
234
  * BYTE-FOR-BYTE from the prior chain; golden install parity asserts generated
234
- * hook output is unchanged across all 16 runtimes.
235
+ * hook output is unchanged across all 15 runtimes.
235
236
  *
236
237
  * Two runtimes are intentionally absent (handled by the caller, NOT this table):
237
238
  * - `claude` → the default; falls through to `DEFAULT_FRAGMENT`.
@@ -244,7 +245,6 @@ const DEFAULT_CONFIG_HOME_FRAGMENT = "'.claude'";
244
245
  const GLOBAL_CONFIG_HOME_FRAGMENTS = {
245
246
  copilot: "'.copilot'",
246
247
  opencode: "'.config', 'opencode'",
247
- gemini: "'.gemini'",
248
248
  kilo: "'.config', 'kilo'",
249
249
  codex: "'.codex'",
250
250
  cursor: "'.cursor'",
@@ -256,6 +256,7 @@ const GLOBAL_CONFIG_HOME_FRAGMENTS = {
256
256
  codebuddy: "'.codebuddy'",
257
257
  cline: "'.cline'",
258
258
  kimi: "'.config', 'agents'",
259
+ zcode: "'.zcode'",
259
260
  };
260
261
  /**
261
262
  * Return the global config-home path-fragment source snippet for a runtime
@@ -277,8 +278,8 @@ function getGlobalConfigHomeFragment(runtime) {
277
278
  * removes).
278
279
  */
279
280
  const RUNTIME_FLAG_IDS = Object.freeze([
280
- 'opencode', 'kilo', 'gemini', 'codex', 'copilot', 'antigravity', 'cursor',
281
- 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'kimi',
281
+ 'opencode', 'kilo', 'codex', 'copilot', 'antigravity', 'cursor',
282
+ 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'kimi', 'zcode',
282
283
  ]);
283
284
  /**
284
285
  * Return a frozen map of `is<Runtime>` boolean predicates for the given runtime
@@ -303,7 +304,6 @@ function runtimeFlags(runtime) {
303
304
  */
304
305
  const DEFAULT_NEW_PROJECT_COMMAND = '/gsd-new-project';
305
306
  const RUNTIME_NEW_PROJECT_COMMANDS = {
306
- gemini: '/gsd:new-project',
307
307
  codex: '$gsd-new-project',
308
308
  cursor: 'gsd-new-project (mention the skill name)',
309
309
  kimi: '/skill:gsd-new-project',
@@ -56,16 +56,20 @@ const node_child_process_1 = __importDefault(require("node:child_process"));
56
56
  * runtime/shell combination.
57
57
  *
58
58
  * Current evidence-backed policy:
59
- * - Gemini on Windows requires `& ` for quoted node/bash runners.
60
- * - Claude Code on Windows does NOT: its hook commands execute under bash/Git
61
- * Bash and `& ` breaks there (#3413).
59
+ * - Claude Code on Windows does NOT need it: its hook commands execute under
60
+ * bash/Git Bash and `& ` breaks there (#3413).
61
+ * - #1928: Gemini CLI — the ONLY runtime with a verified need for the `& `
62
+ * prefix on Windows — was removed (Google sunset it 2026-06-18). No currently
63
+ * supported runtime has a verified need, so this seam is now inert. It is
64
+ * retained (not deleted) so a future runtime with a verified need is a
65
+ * one-line re-enable, per the conservative policy below. Note: Antigravity —
66
+ * the Gemini-backend successor — never matched the old `runtime === 'gemini'`
67
+ * check, so its behavior (no prefix) is unchanged.
62
68
  *
63
69
  * Keep the policy conservative until another runtime has a verified need.
64
70
  */
65
- function hookCommandNeedsPowerShellCallOperator(opts = {}) {
66
- const platform = opts.platform || process.platform;
67
- const runtime = opts.runtime || 'generic';
68
- return platform === 'win32' && runtime === 'gemini';
71
+ function hookCommandNeedsPowerShellCallOperator(_opts = {}) {
72
+ return false;
69
73
  }
70
74
  /**
71
75
  * Project a fully-assembled hook command string for the target runtime.
@@ -121,7 +125,7 @@ function formatManagedHookScriptToken(scriptPath, opts = {}) {
121
125
  function projectLocalHookPrefix({ runtime = 'claude', dirName }) {
122
126
  if (!dirName)
123
127
  return dirName;
124
- return (runtime === 'gemini' || runtime === 'antigravity')
128
+ return (runtime === 'antigravity')
125
129
  ? dirName
126
130
  : `"$CLAUDE_PROJECT_DIR"/${dirName}`;
127
131
  }