@opengsd/gsd-core 1.9.1 → 1.11.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 (426) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -3
  3. package/.opencode/plugins/gsd-core.js +8 -1
  4. package/agents/gsd-code-fixer.md +27 -3
  5. package/agents/gsd-debug-session-manager.md +11 -0
  6. package/agents/gsd-debugger.md +12 -246
  7. package/agents/gsd-doc-synthesizer.md +2 -4
  8. package/agents/gsd-executor.md +12 -10
  9. package/agents/gsd-integration-checker.md +3 -0
  10. package/agents/gsd-mempalace-curator.md +5 -2
  11. package/agents/gsd-phase-researcher.md +20 -1
  12. package/agents/gsd-plan-checker.md +46 -0
  13. package/agents/gsd-planner.md +49 -54
  14. package/agents/gsd-roadmapper.md +21 -3
  15. package/agents/gsd-user-profiler.md +3 -0
  16. package/agents/gsd-verifier.md +26 -73
  17. package/bin/install.js +1272 -1238
  18. package/bin/lib/ui-safety-gate.cjs +2 -0
  19. package/commands/gsd/code-review.md +1 -1
  20. package/commands/gsd/execute-phase.md +1 -1
  21. package/commands/gsd/map-codebase.md +1 -1
  22. package/commands/gsd/mempalace-capture.md +2 -2
  23. package/commands/gsd/mempalace-recall.md +1 -1
  24. package/commands/gsd/new-milestone.md +2 -2
  25. package/commands/gsd/plan-phase.md +1 -1
  26. package/commands/gsd/quick.md +1 -1
  27. package/commands/gsd/review-backlog.md +2 -1
  28. package/commands/gsd/verify-work.md +1 -1
  29. package/gsd-core/bin/gsd-tools.cjs +1009 -115
  30. package/gsd-core/bin/lib/active-workstream-store.cjs +153 -12
  31. package/gsd-core/bin/lib/agent-install-check.cjs +268 -38
  32. package/gsd-core/bin/lib/api-coverage.cjs +123 -5
  33. package/gsd-core/bin/lib/artifacts.cjs +3 -0
  34. package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
  35. package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
  36. package/gsd-core/bin/lib/audit.cjs +926 -202
  37. package/gsd-core/bin/lib/broken-windows.cjs +36 -6
  38. package/gsd-core/bin/lib/capability-consent.cjs +149 -15
  39. package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
  40. package/gsd-core/bin/lib/capability-registry.cjs +608 -148
  41. package/gsd-core/bin/lib/capability-source.cjs +92 -0
  42. package/gsd-core/bin/lib/capability-trust.cjs +444 -25
  43. package/gsd-core/bin/lib/capability-validator.cjs +507 -24
  44. package/gsd-core/bin/lib/capability-writer.cjs +3 -2
  45. package/gsd-core/bin/lib/check-command-router.cjs +114 -38
  46. package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
  47. package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
  48. package/gsd-core/bin/lib/command-aliases.cjs +94 -0
  49. package/gsd-core/bin/lib/command-roster.cjs +44 -1
  50. package/gsd-core/bin/lib/commands.cjs +665 -99
  51. package/gsd-core/bin/lib/commonjs-marker.cjs +142 -0
  52. package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
  53. package/gsd-core/bin/lib/config-loader.cjs +76 -0
  54. package/gsd-core/bin/lib/config.cjs +22 -2
  55. package/gsd-core/bin/lib/context-composer.cjs +278 -0
  56. package/gsd-core/bin/lib/context-predicates.cjs +506 -0
  57. package/gsd-core/bin/lib/core-utils.cjs +217 -40
  58. package/gsd-core/bin/lib/decisions.cjs +23 -0
  59. package/gsd-core/bin/lib/docs.cjs +3 -2
  60. package/gsd-core/bin/lib/external-job.cjs +19 -4
  61. package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
  62. package/gsd-core/bin/lib/frontmatter.cjs +239 -32
  63. package/gsd-core/bin/lib/gap-checker.cjs +68 -7
  64. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +57 -6
  65. package/gsd-core/bin/lib/git-base-branch.cjs +160 -15
  66. package/gsd-core/bin/lib/graphify.cjs +142 -27
  67. package/gsd-core/bin/lib/gsd2-import.cjs +37 -5
  68. package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
  69. package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
  71. package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
  72. package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
  73. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
  74. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
  75. package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
  76. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
  77. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
  78. package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
  79. package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
  80. package/gsd-core/bin/lib/host-integration.cjs +13 -1
  81. package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
  82. package/gsd-core/bin/lib/init-command-router.cjs +83 -8
  83. package/gsd-core/bin/lib/init.cjs +1325 -169
  84. package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
  85. package/gsd-core/bin/lib/install-engine.cjs +805 -264
  86. package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
  87. package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
  88. package/gsd-core/bin/lib/install-profiles.cjs +160 -57
  89. package/gsd-core/bin/lib/install-scope.cjs +270 -0
  90. package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
  91. package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
  92. package/gsd-core/bin/lib/installer-migration-authoring.cjs +3 -1
  93. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  94. package/gsd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs +149 -0
  95. package/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs +55 -0
  96. package/gsd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs +199 -0
  97. package/gsd-core/bin/lib/installer-migrations.cjs +206 -13
  98. package/gsd-core/bin/lib/io.cjs +38 -3
  99. package/gsd-core/bin/lib/markdown-sectionizer.cjs +8 -1
  100. package/gsd-core/bin/lib/markdown-table.cjs +133 -20
  101. package/gsd-core/bin/lib/mcp-catalog.cjs +518 -0
  102. package/gsd-core/bin/lib/mcp-server.cjs +135 -3
  103. package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
  104. package/gsd-core/bin/lib/milestone.cjs +821 -109
  105. package/gsd-core/bin/lib/model-catalog.cjs +59 -1
  106. package/gsd-core/bin/lib/model-resolver.cjs +183 -40
  107. package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
  108. package/gsd-core/bin/lib/pattern.cjs +122 -0
  109. package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
  110. package/gsd-core/bin/lib/phase-id.cjs +507 -36
  111. package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
  112. package/gsd-core/bin/lib/phase-locator.cjs +258 -58
  113. package/gsd-core/bin/lib/phase.cjs +891 -156
  114. package/gsd-core/bin/lib/plan-dependency-graph.cjs +303 -0
  115. package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
  116. package/gsd-core/bin/lib/plan-scan.cjs +86 -2
  117. package/gsd-core/bin/lib/planning-scope.cjs +31 -0
  118. package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
  119. package/gsd-core/bin/lib/planning-workspace.cjs +60 -6
  120. package/gsd-core/bin/lib/probe-core.cjs +1 -1
  121. package/gsd-core/bin/lib/profile-output.cjs +1 -1
  122. package/gsd-core/bin/lib/prompt-budget.cjs +128 -165
  123. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
  124. package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +85 -0
  125. package/gsd-core/bin/lib/review-lane-descriptor.cjs +108 -0
  126. package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
  127. package/gsd-core/bin/lib/review-lane-runner.cjs +447 -68
  128. package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
  129. package/gsd-core/bin/lib/roadmap-command-router.cjs +76 -9
  130. package/gsd-core/bin/lib/roadmap-parser.cjs +1035 -194
  131. package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
  132. package/gsd-core/bin/lib/roadmap.cjs +405 -84
  133. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +795 -100
  134. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
  135. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +440 -57
  136. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
  137. package/gsd-core/bin/lib/runtime-homes.cjs +220 -41
  138. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +220 -44
  139. package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
  140. package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
  141. package/gsd-core/bin/lib/section-manifest.cjs +209 -0
  142. package/gsd-core/bin/lib/security.cjs +104 -5
  143. package/gsd-core/bin/lib/shell-command-projection.cjs +388 -30
  144. package/gsd-core/bin/lib/smart-entry.cjs +154 -22
  145. package/gsd-core/bin/lib/state-command-router.cjs +5 -1
  146. package/gsd-core/bin/lib/state-document.cjs +152 -8
  147. package/gsd-core/bin/lib/state-transition.cjs +424 -105
  148. package/gsd-core/bin/lib/state.cjs +1927 -401
  149. package/gsd-core/bin/lib/surface.cjs +35 -10
  150. package/gsd-core/bin/lib/text-lines.cjs +80 -0
  151. package/gsd-core/bin/lib/token-scanner.cjs +76 -0
  152. package/gsd-core/bin/lib/uat-predicate.cjs +20 -4
  153. package/gsd-core/bin/lib/uat.cjs +706 -64
  154. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
  155. package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
  156. package/gsd-core/bin/lib/unusable-input.cjs +33 -0
  157. package/gsd-core/bin/lib/update-context.cjs +8 -2
  158. package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
  159. package/gsd-core/bin/lib/validate.cjs +20 -6
  160. package/gsd-core/bin/lib/vendor/README.md +37 -0
  161. package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
  162. package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
  163. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  164. package/gsd-core/bin/lib/verification.cjs +287 -20
  165. package/gsd-core/bin/lib/verify.cjs +368 -880
  166. package/gsd-core/bin/lib/workflow-fragments.cjs +557 -0
  167. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +203 -19
  168. package/gsd-core/bin/lib/workstream-inventory.cjs +576 -31
  169. package/gsd-core/bin/lib/workstream.cjs +8 -2
  170. package/gsd-core/bin/lib/worktree-base-ref.cjs +50 -6
  171. package/gsd-core/bin/lib/worktree-safety.cjs +450 -125
  172. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  173. package/gsd-core/bin/shared/config-schema.manifest.json +9 -1
  174. package/gsd-core/references/agent-contracts.md +43 -26
  175. package/gsd-core/references/artifact-types.md +10 -3
  176. package/gsd-core/references/autonomous-ui-design-contract.md +42 -0
  177. package/gsd-core/references/checkpoints.md +2 -2
  178. package/gsd-core/references/context-budget.md +1 -1
  179. package/gsd-core/references/debugger-techniques.md +255 -0
  180. package/gsd-core/references/dispatch-isolation-gate.md +138 -0
  181. package/gsd-core/references/doc-conflict-engine.md +1 -1
  182. package/gsd-core/references/execute-mvp-tdd.md +3 -3
  183. package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
  184. package/gsd-core/references/execute-phase-context-guard.md +1 -1
  185. package/gsd-core/references/execute-phase-response-language.md +1 -1
  186. package/gsd-core/references/execute-phase-wave-guard.md +6 -2
  187. package/gsd-core/references/gate-prompts.md +1 -1
  188. package/gsd-core/references/git-planning-commit.md +2 -1
  189. package/gsd-core/references/loop-hook-dispatch.md +39 -2
  190. package/gsd-core/references/model-profiles.md +12 -4
  191. package/gsd-core/references/mvp-concepts.md +9 -9
  192. package/gsd-core/references/planner-guidance.md +3 -9
  193. package/gsd-core/references/planner-preconditions.md +1 -1
  194. package/gsd-core/references/planner-reviews.md +1 -1
  195. package/gsd-core/references/planning-config.md +8 -6
  196. package/gsd-core/references/research-documentation-lookup.md +5 -3
  197. package/gsd-core/references/revision-loop.md +1 -1
  198. package/gsd-core/references/specless-probe-fallback.md +8 -7
  199. package/gsd-core/references/universal-anti-patterns.md +3 -3
  200. package/gsd-core/references/verifier-phase-gates.md +192 -0
  201. package/gsd-core/references/verifier-wiring-patterns.md +100 -0
  202. package/gsd-core/references/verify-mvp-mode.md +1 -1
  203. package/gsd-core/references/workstream-flag.md +22 -6
  204. package/gsd-core/references/worktree-branch-check.md +2 -2
  205. package/gsd-core/templates/discussion-log.md +1 -1
  206. package/gsd-core/templates/phase-prompt.md +2 -4
  207. package/gsd-core/templates/state.md +4 -4
  208. package/gsd-core/templates/summary-complex.md +2 -0
  209. package/gsd-core/templates/summary-minimal.md +2 -0
  210. package/gsd-core/templates/summary-standard.md +2 -0
  211. package/gsd-core/templates/summary.md +2 -0
  212. package/gsd-core/templates/verification-report.md +9 -1
  213. package/gsd-core/workflows/ai-integration-phase.md +9 -11
  214. package/gsd-core/workflows/audit-milestone.md +3 -0
  215. package/gsd-core/workflows/autonomous/steps/converge-banner.md +1 -0
  216. package/gsd-core/workflows/autonomous/steps/converge-dispatch-bg.md +11 -0
  217. package/gsd-core/workflows/autonomous/steps/converge-dispatch-inline.md +7 -0
  218. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +21 -0
  219. package/gsd-core/workflows/autonomous/steps/converge-loop.md +7 -0
  220. package/gsd-core/workflows/autonomous.md +33 -70
  221. package/gsd-core/workflows/cleanup.md +62 -3
  222. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +39 -0
  223. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +93 -0
  224. package/gsd-core/workflows/code-review-fix.md +37 -10
  225. package/gsd-core/workflows/code-review.md +74 -166
  226. package/gsd-core/workflows/complete-milestone/steps/git-tag.md +29 -0
  227. package/gsd-core/workflows/complete-milestone.md +160 -95
  228. package/gsd-core/workflows/debug.md +16 -17
  229. package/gsd-core/workflows/diagnose-issues.md +56 -8
  230. package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
  231. package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
  232. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +15 -0
  233. package/gsd-core/workflows/discuss-phase-assumptions.md +7 -17
  234. package/gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md +51 -0
  235. package/gsd-core/workflows/docs-update.md +8 -51
  236. package/gsd-core/workflows/edit-phase.md +26 -1
  237. package/gsd-core/workflows/eval-review.md +3 -5
  238. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +64 -7
  239. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +50 -0
  240. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +31 -0
  241. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
  242. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +21 -0
  243. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +42 -0
  244. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +43 -37
  245. package/gsd-core/workflows/execute-phase.md +103 -187
  246. package/gsd-core/workflows/execute-plan.md +36 -4
  247. package/gsd-core/workflows/explore.md +131 -4
  248. package/gsd-core/workflows/fast.md +10 -2
  249. package/gsd-core/workflows/health.md +73 -4
  250. package/gsd-core/workflows/help/modes/full.md +6 -1
  251. package/gsd-core/workflows/import.md +4 -4
  252. package/gsd-core/workflows/ingest-docs.md +7 -6
  253. package/gsd-core/workflows/mvp-phase.md +6 -3
  254. package/gsd-core/workflows/new-milestone/steps/project-md-milestone-write.md +16 -0
  255. package/gsd-core/workflows/new-milestone/steps/reset-phase-safety.md +19 -0
  256. package/gsd-core/workflows/new-milestone.md +35 -47
  257. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +176 -0
  258. package/gsd-core/workflows/new-project/steps/auto-mode-detection.md +32 -0
  259. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +18 -0
  260. package/gsd-core/workflows/new-project.md +27 -240
  261. package/gsd-core/workflows/next.md +12 -0
  262. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +15 -0
  263. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +110 -0
  264. package/gsd-core/workflows/plan-phase/steps/prd-express-gate.md +8 -0
  265. package/gsd-core/workflows/plan-phase/steps/research-only-early-exit.md +17 -0
  266. package/gsd-core/workflows/plan-phase/steps/research-only-modifiers.md +16 -0
  267. package/gsd-core/workflows/plan-phase/steps/reviews-prerequisite.md +17 -0
  268. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +149 -0
  269. package/gsd-core/workflows/plan-phase.md +89 -209
  270. package/gsd-core/workflows/plan-review-convergence.md +50 -2
  271. package/gsd-core/workflows/progress/steps/forensic-audit.md +125 -0
  272. package/gsd-core/workflows/progress/steps/mvp-display.md +18 -0
  273. package/gsd-core/workflows/progress.md +45 -159
  274. package/gsd-core/workflows/quick/steps/discussion-phase.md +124 -0
  275. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +111 -0
  276. package/gsd-core/workflows/quick/steps/quick-verification.md +67 -0
  277. package/gsd-core/workflows/quick/steps/research-phase.md +72 -0
  278. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +37 -0
  279. package/gsd-core/workflows/quick.md +55 -405
  280. package/gsd-core/workflows/resume-project.md +3 -0
  281. package/gsd-core/workflows/review/steps/reviewer-instances-note-1.md +4 -0
  282. package/gsd-core/workflows/review/steps/reviewer-instances-note-2.md +3 -0
  283. package/gsd-core/workflows/review.md +41 -13
  284. package/gsd-core/workflows/section-manifest.json +219 -0
  285. package/gsd-core/workflows/secure-phase.md +1 -1
  286. package/gsd-core/workflows/session-report.md +2 -1
  287. package/gsd-core/workflows/settings.md +66 -2
  288. package/gsd-core/workflows/ship.md +104 -44
  289. package/gsd-core/workflows/sketch.md +1 -1
  290. package/gsd-core/workflows/spec-phase.md +41 -20
  291. package/gsd-core/workflows/spike-wrap-up.md +20 -5
  292. package/gsd-core/workflows/spike.md +50 -16
  293. package/gsd-core/workflows/sync-skills.md +106 -13
  294. package/gsd-core/workflows/transition/steps/workstream-collision-check.md +17 -0
  295. package/gsd-core/workflows/transition.md +53 -31
  296. package/gsd-core/workflows/ui-phase.md +13 -12
  297. package/gsd-core/workflows/ui-review.md +2 -2
  298. package/gsd-core/workflows/update/steps/channel-banner.md +7 -0
  299. package/gsd-core/workflows/update.md +19 -8
  300. package/gsd-core/workflows/validate-phase.md +1 -1
  301. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +36 -0
  302. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +21 -0
  303. package/gsd-core/workflows/verify-work.md +17 -65
  304. package/hooks/dist/gsd-agent-isolation-guard.js +517 -0
  305. package/hooks/dist/gsd-check-update-worker.js +64 -12
  306. package/hooks/dist/gsd-check-update.js +19 -1
  307. package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
  308. package/hooks/dist/gsd-cursor-subagent-start.js +607 -26
  309. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
  310. package/hooks/dist/gsd-prompt-guard.js +21 -20
  311. package/hooks/dist/gsd-read-injection-scanner.js +45 -24
  312. package/hooks/dist/gsd-statusline.js +90 -6
  313. package/hooks/dist/gsd-update-banner.js +22 -1
  314. package/hooks/dist/gsd-workflow-guard.js +134 -36
  315. package/hooks/dist/gsd-worktree-path-guard.js +2 -1
  316. package/hooks/dist/gsd-write-guard.js +359 -0
  317. package/hooks/dist/lib/git-cmd.js +92 -59
  318. package/hooks/dist/lib/injection-patterns.js +45 -0
  319. package/hooks/dist/lib/isolation-deny-reason.js +39 -0
  320. package/hooks/dist/lib/isolation-sentinel.js +277 -0
  321. package/hooks/dist/managed-hooks-registry.cjs +2 -0
  322. package/hooks/gsd-agent-isolation-guard.js +517 -0
  323. package/hooks/gsd-check-update-worker.js +64 -12
  324. package/hooks/gsd-check-update.js +19 -1
  325. package/hooks/gsd-cursor-pre-tool.js +0 -3
  326. package/hooks/gsd-cursor-subagent-start.js +607 -26
  327. package/hooks/gsd-cursor-subagent-stop.js +3 -2
  328. package/hooks/gsd-prompt-guard.js +21 -20
  329. package/hooks/gsd-read-injection-scanner.js +45 -24
  330. package/hooks/gsd-statusline.js +90 -6
  331. package/hooks/gsd-update-banner.js +22 -1
  332. package/hooks/gsd-workflow-guard.js +134 -36
  333. package/hooks/gsd-worktree-path-guard.js +2 -1
  334. package/hooks/gsd-write-guard.js +359 -0
  335. package/hooks/hooks.json +12 -0
  336. package/hooks/lib/git-cmd.js +92 -59
  337. package/hooks/lib/injection-patterns.js +45 -0
  338. package/hooks/lib/isolation-deny-reason.js +39 -0
  339. package/hooks/lib/isolation-sentinel.js +277 -0
  340. package/hooks/managed-hooks-registry.cjs +2 -0
  341. package/package.json +31 -10
  342. package/pi/gsd.cjs +71 -12
  343. package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
  344. package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
  345. package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
  346. package/scripts/build-hooks.js +9 -0
  347. package/scripts/changeset/lint.cjs +68 -6
  348. package/scripts/changeset/serialize.cjs +5 -1
  349. package/scripts/check-alias-drift.cjs +7 -43
  350. package/scripts/check-contract-drift.cjs +297 -0
  351. package/scripts/ci-test-scope.cjs +19 -2
  352. package/scripts/command-contract-helpers.cjs +903 -1
  353. package/scripts/gen-adr-index.cjs +728 -38
  354. package/scripts/gen-capability-matrix.cjs +1 -1
  355. package/scripts/gen-capability-registry.cjs +3 -15
  356. package/scripts/gen-context-index.cjs +439 -0
  357. package/scripts/gen-health-docs.cjs +390 -0
  358. package/scripts/gen-inventory-manifest.cjs +150 -4
  359. package/scripts/gen-loop-host-contract.cjs +4 -24
  360. package/scripts/gen-prompt-budget-parity-corpus.cjs +645 -0
  361. package/scripts/gen-registry.cjs +3 -14
  362. package/scripts/gen-section-manifest.cjs +638 -0
  363. package/scripts/generate-package-identity.cjs +4 -2
  364. package/scripts/lib/alias-drift-families.cjs +46 -0
  365. package/scripts/lib/drift-scan.cjs +278 -0
  366. package/scripts/lint-allow-test-rule-refs.allowlist.json +15 -54
  367. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
  368. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
  369. package/scripts/lint-canary-version-leak.cjs +73 -0
  370. package/scripts/lint-command-contract.cjs +96 -13
  371. package/scripts/lint-compiled-artifact-sync.cjs +6 -1
  372. package/scripts/lint-completion-predicate-drift.cjs +933 -0
  373. package/scripts/lint-completion-ratio-drift.cjs +214 -0
  374. package/scripts/lint-default-flip-documentation.cjs +193 -0
  375. package/scripts/lint-docs-command-form.cjs +195 -0
  376. package/scripts/lint-docs-required.cjs +9 -1
  377. package/scripts/lint-emitted-drift-ack.cjs +215 -20
  378. package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
  379. package/scripts/lint-eslint-glob-coverage.cjs +340 -0
  380. package/scripts/lint-example-parser-parity.cjs +395 -0
  381. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
  382. package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
  383. package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
  384. package/scripts/lint-milestone-window-drift.cjs +468 -0
  385. package/scripts/lint-phase-enumeration-drift.cjs +479 -0
  386. package/scripts/lint-plan-count-drift.cjs +318 -0
  387. package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
  388. package/scripts/lint-planning-prompt-drift.cjs +434 -0
  389. package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
  390. package/scripts/lint-regression-test-names.cjs +15 -13
  391. package/scripts/lint-removed-but-needed.cjs +320 -0
  392. package/scripts/lint-state-field-drift.cjs +805 -0
  393. package/scripts/lint-state-write-path-drift.cjs +1045 -0
  394. package/scripts/lint-test-file-count.allowlist.json +40 -3
  395. package/scripts/lint-unreachable-guard-drift.cjs +843 -0
  396. package/scripts/lint-vendored-deps.cjs +124 -0
  397. package/scripts/mutation-matrix.cjs +13 -0
  398. package/scripts/pr-changed-files.cjs +63 -0
  399. package/scripts/pr-template-policy.cjs +14 -4
  400. package/scripts/prompt-injection-scan.sh +52 -6
  401. package/scripts/require-issue-link-policy.cjs +192 -0
  402. package/scripts/state-write-path-drift-baseline.json +19 -0
  403. package/scripts/sync-runtime-launcher.cjs +2 -4
  404. package/skills/gsd-autonomous/SKILL.md +0 -1
  405. package/skills/gsd-code-review/SKILL.md +1 -1
  406. package/skills/gsd-execute-phase/SKILL.md +1 -2
  407. package/skills/gsd-map-codebase/SKILL.md +1 -1
  408. package/skills/gsd-mempalace-capture/SKILL.md +2 -2
  409. package/skills/gsd-mempalace-recall/SKILL.md +1 -1
  410. package/skills/gsd-new-milestone/SKILL.md +2 -2
  411. package/skills/gsd-next/SKILL.md +0 -1
  412. package/skills/gsd-plan-phase/SKILL.md +1 -2
  413. package/skills/gsd-progress/SKILL.md +0 -1
  414. package/skills/gsd-quick/SKILL.md +1 -1
  415. package/skills/gsd-review-backlog/SKILL.md +2 -1
  416. package/skills/gsd-stats/SKILL.md +0 -1
  417. package/skills/gsd-verify-work/SKILL.md +1 -1
  418. package/vscode/package.json +1 -1
  419. package/gsd-core/workflows/discovery-phase.md +0 -298
  420. package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
  421. package/gsd-core/workflows/verify-phase.md +0 -577
  422. package/scripts/affected-tests-lib.cjs +0 -554
  423. package/scripts/gen-emitted-baseline.cjs +0 -145
  424. package/scripts/lint-allow-test-rule-refs.cjs +0 -162
  425. package/scripts/run-affected-tests.cjs +0 -7
  426. package/scripts/run-tests.cjs +0 -1050
@@ -34,6 +34,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
34
34
  return (mod && mod.__esModule) ? mod : { "default": mod };
35
35
  };
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.GSD_LOCATION_ENV_KEYS = exports.NON_REGISTRY_CONFIG_HOME_DESCRIPTORS = exports.KIMI_CODE_HOOKS_TOML_DESCRIPTOR = exports.KIMI_HOOKS_TOML_DESCRIPTOR = exports.LEGACY_NON_REGISTRY_RUNTIME_IDS = void 0;
38
+ exports.isRegisteredRuntimeId = isRegisteredRuntimeId;
37
39
  exports.resolveConfigHomeFromDescriptor = resolveConfigHomeFromDescriptor;
38
40
  exports.resolveAntigravityGlobalDir = resolveAntigravityGlobalDir;
39
41
  exports.detectAntigravityDirAmbiguity = detectAntigravityDirAmbiguity;
@@ -48,15 +50,36 @@ const node_os_1 = __importDefault(require("node:os"));
48
50
  const node_path_1 = __importDefault(require("node:path"));
49
51
  const node_fs_1 = __importDefault(require("node:fs"));
50
52
  /**
51
- * Expand a leading ~ to os.homedir().
53
+ * Expand a leading ~ to the given home directory (defaults to os.homedir()).
54
+ * Every call site inside resolveConfigHomeFromDescriptor threads its
55
+ * resolved `home` local through here so an injected opts.home (used by
56
+ * hermetic tests) is honored instead of silently falling back to the real
57
+ * home directory.
52
58
  */
53
- function expandTilde(p) {
59
+ function expandTilde(p, home = node_os_1.default.homedir()) {
54
60
  if (!p)
55
61
  return p;
56
62
  if (p.startsWith('~/') || p === '~')
57
- return node_path_1.default.join(node_os_1.default.homedir(), p.slice(1));
63
+ return node_path_1.default.join(home, p.slice(1));
58
64
  return p;
59
65
  }
66
+ /**
67
+ * True when `val` is a usable env-var override: a real string that contains
68
+ * at least one non-whitespace character. Every env-override consumption site
69
+ * in resolveConfigHomeFromDescriptor gates on this instead of a bare truthy
70
+ * check, so `FOO_DIR=''` (empty), `FOO_DIR` unset (`undefined`), and
71
+ * `FOO_DIR=' '` (whitespace-only — e.g. from a shell templating bug that
72
+ * leaves a variable substitution blank but quoted) all fall back to the
73
+ * descriptor default identically. Deliberately does NOT trim: a value that
74
+ * merely has leading/trailing whitespace around otherwise-real content (or
75
+ * interior whitespace, e.g. `~/My Agent Dir`) is passed through byte-for-byte
76
+ * unchanged, exactly as this module already treats every other env-var
77
+ * override (no site here or elsewhere in this file trims a path value) — so
78
+ * default behavior for every non-whitespace value is unaffected by this guard.
79
+ */
80
+ function hasNonBlankOverride(val) {
81
+ return typeof val === 'string' && val.trim() !== '';
82
+ }
60
83
  function resolveDescriptorWithOptions(configHome) {
61
84
  return resolveConfigHomeFromDescriptor(configHome, {
62
85
  env: process.env,
@@ -68,6 +91,64 @@ function getRegistry() {
68
91
  // eslint-disable-next-line @typescript-eslint/no-require-imports
69
92
  return require('./capability-registry.cjs');
70
93
  }
94
+ /**
95
+ * Legacy runtime ids that have a genuine, dedicated resolution branch
96
+ * elsewhere in this module but no capability-registry descriptor (#3024
97
+ * review BLOCKER, finding 1).
98
+ *
99
+ * `isRegisteredRuntimeId`'s real contract is "does this id resolve to a
100
+ * real, runtime-specific path?", not "is it a key in the registry map" —
101
+ * registry membership is only a proxy for that, and the proxy is wrong for
102
+ * `grok`: `getGlobalConfigDir` has a live hardcoded branch for it (`~/.agents`,
103
+ * overridable via `GROK_AGENTS_HOME`), predating the capability-registry
104
+ * descriptor system, and it is documented end-user-facing surface
105
+ * (pre-fix `gsd-core/workflows/sync-skills.md` listed it explicitly, and
106
+ * `docs/discussions/grok-build-support-2026-05.md` records the support
107
+ * decision). Rejecting it here would silently remove working, documented
108
+ * `--skills-root`/`sync-skills` support for a runtime that never regressed.
109
+ *
110
+ * This set is enumerated by hand, not derived, and MUST stay in lockstep
111
+ * with `getGlobalConfigDir`'s hardcoded branches: as of #3024, `grok` is
112
+ * the ONLY id in this position (verified by reading the full function body
113
+ * — every other unregistered id there falls through to the claude
114
+ * fallback, which is the behavior this validator exists to reject). Do
115
+ * NOT add an id here just because it "should" work — add it only after
116
+ * confirming `getGlobalConfigDir` has a real dedicated branch for it, the
117
+ * way `grok`'s is confirmed above. Do not "clean this up" by removing it;
118
+ * that is exactly the regression this constant guards against.
119
+ */
120
+ exports.LEGACY_NON_REGISTRY_RUNTIME_IDS = new Set(['grok']);
121
+ /**
122
+ * True when `runtime` is a real runtime id with a genuine, runtime-specific
123
+ * resolution path — either a registered id in the capability registry
124
+ * (`capability-registry.cjs`'s `runtimes` object) or one of the small,
125
+ * explicitly named `LEGACY_NON_REGISTRY_RUNTIME_IDS` set (currently just
126
+ * `grok`) that resolves via a dedicated hardcoded branch instead of a
127
+ * registry descriptor.
128
+ *
129
+ * Guarded with an own-property lookup — never a bare index — so a
130
+ * prototype-chain id (`__proto__`, `constructor`, `prototype`, `toString`,
131
+ * …) can never resolve to an inherited value and be mistaken for a real
132
+ * entry. Without this, `getGlobalSkillsBase`/`getGlobalConfigDir`'s bare
133
+ * `runtimes[runtime]` lookups fall through the prototype chain for those
134
+ * ids, find no usable descriptor, and silently resolve to claude's
135
+ * fallback path instead of failing loudly (#3024).
136
+ *
137
+ * Single shared validator for every `--skills-root` entry point
138
+ * (`gsd-tools query skills-root`'s `routeSkillsRoot`, `install.js
139
+ * --skills-root`) so the two surfaces can never diverge on which runtime
140
+ * ids they accept.
141
+ */
142
+ function isRegisteredRuntimeId(runtime) {
143
+ if (typeof runtime !== 'string')
144
+ return false;
145
+ const trimmed = runtime.trim();
146
+ if (!trimmed)
147
+ return false;
148
+ if (Object.prototype.hasOwnProperty.call(getRegistry().runtimes, trimmed))
149
+ return true;
150
+ return exports.LEGACY_NON_REGISTRY_RUNTIME_IDS.has(trimmed);
151
+ }
71
152
  /**
72
153
  * Resolve a configHome descriptor to an absolute directory path.
73
154
  *
@@ -86,16 +167,16 @@ function resolveConfigHomeFromDescriptor(configHome, opts = {}) {
86
167
  // First env var that is set wins
87
168
  for (const varName of configHome.env) {
88
169
  const val = env[varName];
89
- if (val)
90
- return expandTilde(val);
170
+ if (hasNonBlankOverride(val))
171
+ return expandTilde(val, home);
91
172
  }
92
173
  return node_path_1.default.join(home, configHome.name);
93
174
  }
94
175
  case 'dot-home-nested': {
95
176
  // env override
96
177
  const nestedEnv0Val = env[configHome.env[0]];
97
- if (configHome.env[0] && nestedEnv0Val) {
98
- return expandTilde(nestedEnv0Val);
178
+ if (configHome.env[0] && hasNonBlankOverride(nestedEnv0Val)) {
179
+ return expandTilde(nestedEnv0Val, home);
99
180
  }
100
181
  const base = node_path_1.default.join(home, configHome.parent);
101
182
  if (configHome.probe && configHome.probe.length > 0) {
@@ -127,49 +208,50 @@ function resolveConfigHomeFromDescriptor(configHome, opts = {}) {
127
208
  case 'xdg': {
128
209
  // env[0]: direct override dir
129
210
  const xdgEnv0Val = env[configHome.env[0]];
130
- if (configHome.env[0] && xdgEnv0Val) {
131
- return expandTilde(xdgEnv0Val);
211
+ if (configHome.env[0] && hasNonBlankOverride(xdgEnv0Val)) {
212
+ return expandTilde(xdgEnv0Val, home);
132
213
  }
133
214
  // env[1]: FILE path → dirname
134
215
  const xdgEnv1Val = env[configHome.env[1]];
135
- if (configHome.env[1] && xdgEnv1Val) {
136
- return node_path_1.default.dirname(expandTilde(xdgEnv1Val));
216
+ if (configHome.env[1] && hasNonBlankOverride(xdgEnv1Val)) {
217
+ return node_path_1.default.dirname(expandTilde(xdgEnv1Val, home));
137
218
  }
138
219
  // env[2]: XDG_CONFIG_HOME → subdir
139
220
  const xdgEnv2Val = env[configHome.env[2]];
140
- if (configHome.env[2] && xdgEnv2Val) {
141
- return node_path_1.default.join(expandTilde(xdgEnv2Val), configHome.name);
221
+ if (configHome.env[2] && hasNonBlankOverride(xdgEnv2Val)) {
222
+ return node_path_1.default.join(expandTilde(xdgEnv2Val, home), configHome.name);
142
223
  }
143
224
  return node_path_1.default.join(home, '.config', configHome.name);
144
225
  }
145
226
  case 'generic-agents-root': {
146
227
  // env override
147
228
  const garEnv0Val = env[configHome.env[0]];
148
- if (configHome.env[0] && garEnv0Val) {
149
- return expandTilde(garEnv0Val);
229
+ if (configHome.env[0] && hasNonBlankOverride(garEnv0Val)) {
230
+ return expandTilde(garEnv0Val, home);
150
231
  }
151
232
  // probe each candidate; return first where probeExists subpath exists
152
233
  for (const candidate of configHome.probe) {
153
- const resolved = expandTildeWithHome(candidate, home);
234
+ const resolved = expandTilde(candidate, home);
154
235
  if (existsSyncFn(node_path_1.default.join(resolved, configHome.probeExists))) {
155
236
  return resolved;
156
237
  }
157
238
  }
158
239
  // fallback: first probe candidate
159
- return expandTildeWithHome(configHome.probe[0], home);
240
+ return expandTilde(configHome.probe[0], home);
241
+ }
242
+ case 'none': {
243
+ // #2103: no file-projected config directory exists for this runtime
244
+ // (e.g. vscode). Previously this kind had no matching case, so the
245
+ // switch fell through and implicitly returned `undefined` — which
246
+ // then crashed a downstream `path.join(undefined, ...)` with a
247
+ // cryptic `TypeError [ERR_INVALID_ARG_TYPE]` far from the real cause.
248
+ // Throwing here makes the failure mode explicit; callers that need a
249
+ // nullable result (getGlobalSkillsBase) check `configHome.kind` and
250
+ // short-circuit BEFORE ever reaching this function.
251
+ throw new Error(`Runtime "${configHome.name}" has no config-home directory (configHome.kind === "none")`);
160
252
  }
161
253
  }
162
254
  }
163
- /**
164
- * Expand ~ using an explicit home directory (for hermetic testing).
165
- */
166
- function expandTildeWithHome(p, home) {
167
- if (!p)
168
- return p;
169
- if (p.startsWith('~/') || p === '~')
170
- return node_path_1.default.join(home, p.slice(1));
171
- return p;
172
- }
173
255
  /**
174
256
  * Resolve Antigravity global config dir across 1.x and 2.x layouts.
175
257
  *
@@ -257,25 +339,111 @@ function resolveKimiGlobalDir(opts = {}) {
257
339
  }, { env, home, existsSync: existsSyncFn });
258
340
  }
259
341
  /**
260
- * Resolve the directory holding Kimi CLI's OWN native config.toml (the file
261
- * Kimi itself reads for providers/models/hooks/etc — see
262
- * moonshotai.github.io/kimi-cli/en/configuration/data-locations.html and
263
- * .../reference/kimi-command.html). Default `~/.kimi`, overridden by
264
- * `KIMI_SHARE_DIR` per Kimi's own upstream env-var (NOT `KIMI_CONFIG_DIR`,
265
- * which is a GSD-installer write-location override for the unrelated generic
266
- * Agent-Skills root resolved by resolveKimiGlobalDir above).
342
+ * Kimi CLI's own native config.toml home. Hoisted out of resolveKimiHooksTomlDir
343
+ * so it is ENUMERABLE, not merely resolvable.
267
344
  *
268
- * This is deliberately a SEPARATE directory from GSD's kimi configHome
269
- * (~/.config/agents): Kimi's own docs confirm the Agent-Skills search path is
270
- * independent of KIMI_SHARE_DIR ("This variable does not affect Agent Skills
271
- * search paths, which are handled separately"). #2095 Upgrade 1 writes GSD's
272
- * native [[hooks]] entries into `<this dir>/config.toml`, never into the
273
- * skills configDir.
345
+ * #2665 round 3: a config-location var that lives only inside a function body is
346
+ * invisible to every consumer that needs the SET rather than the path — the test
347
+ * scrub list and the hermeticity guard both derive from descriptors, and this one
348
+ * reached neither. `kimi` is the sharp case precisely because it owns TWO config
349
+ * homes: KIMI_CONFIG_DIR (registry-visible, already covered) and KIMI_SHARE_DIR
350
+ * (this one), so a derivation keyed only on the registry looks complete and is not.
351
+ */
352
+ exports.KIMI_HOOKS_TOML_DESCRIPTOR = {
353
+ kind: 'dot-home',
354
+ name: '.kimi',
355
+ env: ['KIMI_SHARE_DIR'],
356
+ };
357
+ /**
358
+ * Kimi Code's native config.toml home — the `kimi-code` counterpart of the
359
+ * descriptor above, hoisted for exactly the same reason.
360
+ *
361
+ * #2755 landed kimi-code hooks support on `next` while this PR was open, and
362
+ * declared this descriptor as an inline object literal inside
363
+ * resolveKimiHooksTomlDir's body — the same resolvable-but-not-enumerable shape
364
+ * round 3 hoisted KIMI_SHARE_DIR out of. Hoisting it puts `KIMI_CODE_HOME` into
365
+ * the derived scrub set and the hermeticity guard's watch roots in the SAME
366
+ * commit, which is the property NON_REGISTRY_CONFIG_HOME_DESCRIPTORS exists to
367
+ * guarantee. Each product's env var stays scoped to that product (#2755).
368
+ */
369
+ exports.KIMI_CODE_HOOKS_TOML_DESCRIPTOR = {
370
+ kind: 'dot-home',
371
+ name: '.kimi-code',
372
+ env: ['KIMI_CODE_HOME'],
373
+ };
374
+ /**
375
+ * Config-home descriptors resolved OUTSIDE the capability registry.
376
+ *
377
+ * Anything added here is picked up by every derived consumer in the same commit —
378
+ * which is the property that makes the derivation structurally incapable of being
379
+ * narrower than the surface it guards. Adding a hardcoded resolver WITHOUT adding
380
+ * its descriptor here is the defect this array exists to make hard.
381
+ */
382
+ exports.NON_REGISTRY_CONFIG_HOME_DESCRIPTORS = [
383
+ exports.KIMI_HOOKS_TOML_DESCRIPTOR,
384
+ exports.KIMI_CODE_HOOKS_TOML_DESCRIPTOR,
385
+ ];
386
+ /**
387
+ * GSD's OWN location vars — a second family, not runtime configHomes.
388
+ *
389
+ * #2665 round 3: the registry describes where each *third-party runtime* keeps its
390
+ * config. It says nothing about where GSD keeps its own user-owned state, and that
391
+ * is a separate env-first surface:
392
+ *
393
+ * GSD_HOME — `process.env['GSD_HOME'] || os.homedir()`, the root of
394
+ * `$GSD_HOME/.gsd/` (consent.json, defaults.json, capability
395
+ * overlays). Read env-first by capability-loader, capability-consent,
396
+ * capability-state, capability-writer, config-loader, install-profiles
397
+ * and bin/install.js. A WRITE surface.
398
+ * GSD_AGENTS_DIR — `if (process.env['GSD_AGENTS_DIR']) return it`, priority 1 in
399
+ * getAgentsDir. Misdirects a READ rather than a write, hence lower
400
+ * severity — but it is env-first and unconditional, so it belongs
401
+ * to the same class.
402
+ *
403
+ * Deliberately NOT folded into the descriptor array above: these do not resolve
404
+ * through resolveConfigHomeFromDescriptor and have no `kind`/`name` shape.
405
+ */
406
+ exports.GSD_LOCATION_ENV_KEYS = ['GSD_HOME', 'GSD_AGENTS_DIR'];
407
+ /**
408
+ * Resolve the directory holding the Kimi product's OWN native config.toml —
409
+ * the file that product itself reads for providers/models/hooks/etc, and the
410
+ * one GSD writes its `[[hooks]]` block, hooks bundle and CommonJS marker into.
411
+ *
412
+ * The two Kimi runtimes share `hooksSurface: "kimi-hooks-toml"` but are
413
+ * different products with different roots, and this must be selected by
414
+ * `runtime` (#2755). Before that fix this function was unparameterized and a
415
+ * `--kimi-code` install wrote its hooks into Kimi CLI's `~/.kimi`, leaving Kimi
416
+ * Code with none:
417
+ *
418
+ * kimi → `~/.kimi`, overridden by `KIMI_SHARE_DIR`
419
+ * (moonshotai.github.io/kimi-cli/en/configuration/data-locations.html)
420
+ * kimi-code → `~/.kimi-code`, overridden by `KIMI_CODE_HOME`
421
+ * (moonshotai/kimi-code docs/en/configuration/data-locations.md;
422
+ * its hooks doc places `[[hooks]]` in `~/.kimi-code/config.toml`)
423
+ *
424
+ * Each product's env var is scoped to that product: `KIMI_SHARE_DIR` is Kimi
425
+ * CLI's own upstream variable and must NOT redirect kimi-code, nor vice versa.
426
+ *
427
+ * An unrecognised `runtime` (and an omitted one) falls back to `~/.kimi`, which
428
+ * preserves the pre-#2755 behaviour for every existing caller that passes no
429
+ * runtime — this function is exported, so that default is a contract.
430
+ *
431
+ * For BOTH runtimes this is deliberately a SEPARATE directory from the generic
432
+ * Agent-Skills root resolved by `resolveKimiGlobalDir` (`~/.config/agents`):
433
+ * both vendors' docs confirm the Agent-Skills search path is independent of the
434
+ * data-root env var. GSD's native `[[hooks]]` entries go in
435
+ * `<this dir>/config.toml`, never into the skills configDir.
274
436
  */
275
437
  function resolveKimiHooksTomlDir(opts = {}) {
276
438
  const env = opts.env ?? process.env;
277
439
  const home = opts.home ?? node_os_1.default.homedir();
278
- return resolveConfigHomeFromDescriptor({ kind: 'dot-home', name: '.kimi', env: ['KIMI_SHARE_DIR'] }, { env, home });
440
+ // Explicit comparison rather than an object lookup keyed on `runtime`: the
441
+ // value originates from argv, and an index would resolve inherited keys
442
+ // (`constructor`, `__proto__`) to something that is not a descriptor.
443
+ const descriptor = opts.runtime === 'kimi-code'
444
+ ? exports.KIMI_CODE_HOOKS_TOML_DESCRIPTOR
445
+ : exports.KIMI_HOOKS_TOML_DESCRIPTOR;
446
+ return resolveConfigHomeFromDescriptor(descriptor, { env, home });
279
447
  }
280
448
  /**
281
449
  * Return the global config base directory for the given runtime.
@@ -317,6 +485,17 @@ function resolveSkillsBaseFromDescriptor(configHome, opts = {}, skillsDestSubpat
317
485
  function getGlobalSkillsBase(runtime) {
318
486
  const runtimeEntry = getRegistry().runtimes[runtime];
319
487
  const descriptor = runtimeEntry?.runtime;
488
+ // #2103: a runtime with `configHome.kind === 'none'` (e.g. vscode —
489
+ // Marketplace/VSIX extension, installSurface:'none') has no file-projected
490
+ // config directory at all, and therefore no skills root. Short-circuit to
491
+ // null BEFORE falling through to getGlobalConfigDir below, which would
492
+ // otherwise throw resolving a 'none' configHome (see
493
+ // resolveConfigHomeFromDescriptor's 'none' case). null is the correct
494
+ // answer here, not a crash — the `=== null` guard at every call site
495
+ // (bin/install.js --skills-root, gsd-tools routeSkillsRoot) already
496
+ // handles it as "this runtime does not use a skills directory".
497
+ if (descriptor?.configHome?.kind === 'none')
498
+ return null;
320
499
  const globalSkillsKind = descriptor?.artifactLayout?.global?.find((entry) => entry.kind === 'skills');
321
500
  // ADR-1239 upgrade 3 (#2088): honor a skills-kind `home` override (e.g. Codex
322
501
  // → $HOME/.agents/skills, independent of $CODEX_HOME) so the reported skills