@opengsd/gsd-core 1.10.0 → 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 (328) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/agents/gsd-debug-session-manager.md +11 -0
  4. package/agents/gsd-doc-synthesizer.md +2 -4
  5. package/agents/gsd-executor.md +5 -5
  6. package/agents/gsd-mempalace-curator.md +5 -2
  7. package/agents/gsd-phase-researcher.md +20 -1
  8. package/agents/gsd-plan-checker.md +37 -0
  9. package/agents/gsd-planner.md +44 -46
  10. package/agents/gsd-user-profiler.md +3 -0
  11. package/agents/gsd-verifier.md +12 -3
  12. package/bin/install.js +841 -971
  13. package/bin/lib/ui-safety-gate.cjs +2 -0
  14. package/commands/gsd/code-review.md +1 -1
  15. package/commands/gsd/execute-phase.md +1 -1
  16. package/commands/gsd/map-codebase.md +1 -1
  17. package/commands/gsd/mempalace-capture.md +1 -1
  18. package/commands/gsd/mempalace-recall.md +1 -1
  19. package/commands/gsd/new-milestone.md +1 -1
  20. package/commands/gsd/quick.md +1 -1
  21. package/commands/gsd/review-backlog.md +2 -1
  22. package/commands/gsd/verify-work.md +1 -1
  23. package/gsd-core/bin/gsd-tools.cjs +469 -88
  24. package/gsd-core/bin/lib/active-workstream-store.cjs +138 -22
  25. package/gsd-core/bin/lib/agent-install-check.cjs +230 -32
  26. package/gsd-core/bin/lib/api-coverage.cjs +3 -5
  27. package/gsd-core/bin/lib/artifacts.cjs +3 -0
  28. package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
  29. package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
  30. package/gsd-core/bin/lib/audit.cjs +876 -240
  31. package/gsd-core/bin/lib/broken-windows.cjs +1 -1
  32. package/gsd-core/bin/lib/capability-consent.cjs +149 -15
  33. package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
  34. package/gsd-core/bin/lib/capability-registry.cjs +575 -101
  35. package/gsd-core/bin/lib/capability-source.cjs +92 -0
  36. package/gsd-core/bin/lib/capability-trust.cjs +444 -25
  37. package/gsd-core/bin/lib/capability-validator.cjs +495 -22
  38. package/gsd-core/bin/lib/capability-writer.cjs +3 -2
  39. package/gsd-core/bin/lib/check-command-router.cjs +71 -37
  40. package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
  41. package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
  42. package/gsd-core/bin/lib/command-aliases.cjs +22 -0
  43. package/gsd-core/bin/lib/command-roster.cjs +44 -1
  44. package/gsd-core/bin/lib/commands.cjs +651 -86
  45. package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
  46. package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
  47. package/gsd-core/bin/lib/config-loader.cjs +75 -0
  48. package/gsd-core/bin/lib/config.cjs +10 -1
  49. package/gsd-core/bin/lib/core-utils.cjs +127 -29
  50. package/gsd-core/bin/lib/decisions.cjs +23 -0
  51. package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
  52. package/gsd-core/bin/lib/frontmatter.cjs +155 -20
  53. package/gsd-core/bin/lib/gap-checker.cjs +68 -7
  54. package/gsd-core/bin/lib/git-base-branch.cjs +102 -0
  55. package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
  56. package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
  57. package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
  58. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
  59. package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
  60. package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
  61. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
  62. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
  63. package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
  64. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
  65. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
  66. package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
  67. package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
  68. package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
  69. package/gsd-core/bin/lib/init.cjs +321 -129
  70. package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
  71. package/gsd-core/bin/lib/install-engine.cjs +745 -258
  72. package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
  73. package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
  74. package/gsd-core/bin/lib/install-profiles.cjs +134 -57
  75. package/gsd-core/bin/lib/install-scope.cjs +270 -0
  76. package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
  77. package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
  78. package/gsd-core/bin/lib/installer-migrations.cjs +138 -31
  79. package/gsd-core/bin/lib/io.cjs +10 -0
  80. package/gsd-core/bin/lib/markdown-sectionizer.cjs +2 -1
  81. package/gsd-core/bin/lib/markdown-table.cjs +133 -20
  82. package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
  83. package/gsd-core/bin/lib/milestone.cjs +754 -70
  84. package/gsd-core/bin/lib/model-catalog.cjs +59 -1
  85. package/gsd-core/bin/lib/model-resolver.cjs +183 -40
  86. package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
  87. package/gsd-core/bin/lib/pattern.cjs +122 -0
  88. package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
  89. package/gsd-core/bin/lib/phase-id.cjs +444 -36
  90. package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
  91. package/gsd-core/bin/lib/phase-locator.cjs +125 -18
  92. package/gsd-core/bin/lib/phase.cjs +646 -143
  93. package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
  94. package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
  95. package/gsd-core/bin/lib/plan-scan.cjs +86 -2
  96. package/gsd-core/bin/lib/planning-scope.cjs +31 -0
  97. package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
  98. package/gsd-core/bin/lib/planning-workspace.cjs +56 -6
  99. package/gsd-core/bin/lib/probe-core.cjs +1 -1
  100. package/gsd-core/bin/lib/profile-output.cjs +1 -1
  101. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
  102. package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
  103. package/gsd-core/bin/lib/review-lane-descriptor.cjs +13 -4
  104. package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
  105. package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
  106. package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
  107. package/gsd-core/bin/lib/roadmap-command-router.cjs +34 -0
  108. package/gsd-core/bin/lib/roadmap-parser.cjs +943 -184
  109. package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
  110. package/gsd-core/bin/lib/roadmap.cjs +385 -94
  111. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +608 -46
  112. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
  113. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +426 -55
  114. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
  115. package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
  116. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +115 -3
  117. package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
  118. package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
  119. package/gsd-core/bin/lib/security.cjs +104 -5
  120. package/gsd-core/bin/lib/shell-command-projection.cjs +275 -3
  121. package/gsd-core/bin/lib/smart-entry.cjs +142 -22
  122. package/gsd-core/bin/lib/state-command-router.cjs +5 -1
  123. package/gsd-core/bin/lib/state-document.cjs +152 -8
  124. package/gsd-core/bin/lib/state-transition.cjs +371 -117
  125. package/gsd-core/bin/lib/state.cjs +1794 -357
  126. package/gsd-core/bin/lib/surface.cjs +23 -9
  127. package/gsd-core/bin/lib/text-lines.cjs +80 -0
  128. package/gsd-core/bin/lib/token-scanner.cjs +76 -0
  129. package/gsd-core/bin/lib/uat-predicate.cjs +9 -3
  130. package/gsd-core/bin/lib/uat.cjs +399 -56
  131. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
  132. package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
  133. package/gsd-core/bin/lib/unusable-input.cjs +24 -0
  134. package/gsd-core/bin/lib/update-context.cjs +8 -2
  135. package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
  136. package/gsd-core/bin/lib/validate.cjs +20 -6
  137. package/gsd-core/bin/lib/vendor/README.md +37 -0
  138. package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
  139. package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
  140. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  141. package/gsd-core/bin/lib/verification.cjs +258 -8
  142. package/gsd-core/bin/lib/verify.cjs +368 -888
  143. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
  144. package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
  145. package/gsd-core/bin/lib/workstream.cjs +2 -2
  146. package/gsd-core/bin/lib/worktree-safety.cjs +176 -9
  147. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  148. package/gsd-core/bin/shared/config-schema.manifest.json +7 -1
  149. package/gsd-core/references/agent-contracts.md +43 -26
  150. package/gsd-core/references/checkpoints.md +2 -2
  151. package/gsd-core/references/context-budget.md +1 -1
  152. package/gsd-core/references/dispatch-isolation-gate.md +138 -0
  153. package/gsd-core/references/doc-conflict-engine.md +1 -1
  154. package/gsd-core/references/execute-mvp-tdd.md +3 -3
  155. package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
  156. package/gsd-core/references/execute-phase-context-guard.md +1 -1
  157. package/gsd-core/references/execute-phase-response-language.md +1 -1
  158. package/gsd-core/references/execute-phase-wave-guard.md +6 -2
  159. package/gsd-core/references/gate-prompts.md +1 -1
  160. package/gsd-core/references/git-planning-commit.md +2 -1
  161. package/gsd-core/references/loop-hook-dispatch.md +39 -2
  162. package/gsd-core/references/model-profiles.md +12 -4
  163. package/gsd-core/references/mvp-concepts.md +9 -9
  164. package/gsd-core/references/planner-guidance.md +3 -9
  165. package/gsd-core/references/planner-preconditions.md +1 -1
  166. package/gsd-core/references/planner-reviews.md +1 -1
  167. package/gsd-core/references/planning-config.md +8 -6
  168. package/gsd-core/references/revision-loop.md +1 -1
  169. package/gsd-core/references/specless-probe-fallback.md +1 -1
  170. package/gsd-core/references/universal-anti-patterns.md +3 -3
  171. package/gsd-core/references/verifier-phase-gates.md +192 -0
  172. package/gsd-core/references/verify-mvp-mode.md +1 -1
  173. package/gsd-core/references/workstream-flag.md +22 -6
  174. package/gsd-core/templates/discussion-log.md +1 -1
  175. package/gsd-core/templates/phase-prompt.md +2 -4
  176. package/gsd-core/templates/state.md +4 -4
  177. package/gsd-core/templates/verification-report.md +9 -1
  178. package/gsd-core/workflows/ai-integration-phase.md +9 -11
  179. package/gsd-core/workflows/autonomous.md +1 -1
  180. package/gsd-core/workflows/cleanup.md +62 -3
  181. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +13 -3
  182. package/gsd-core/workflows/code-review-fix.md +37 -10
  183. package/gsd-core/workflows/code-review.md +38 -12
  184. package/gsd-core/workflows/complete-milestone.md +141 -18
  185. package/gsd-core/workflows/debug.md +7 -5
  186. package/gsd-core/workflows/diagnose-issues.md +35 -9
  187. package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
  188. package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
  189. package/gsd-core/workflows/discuss-phase-assumptions.md +2 -1
  190. package/gsd-core/workflows/edit-phase.md +26 -1
  191. package/gsd-core/workflows/eval-review.md +3 -5
  192. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +31 -6
  193. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
  194. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +2 -0
  195. package/gsd-core/workflows/execute-phase.md +38 -50
  196. package/gsd-core/workflows/execute-plan.md +36 -4
  197. package/gsd-core/workflows/explore.md +131 -4
  198. package/gsd-core/workflows/fast.md +10 -2
  199. package/gsd-core/workflows/health.md +73 -4
  200. package/gsd-core/workflows/import.md +4 -4
  201. package/gsd-core/workflows/ingest-docs.md +5 -5
  202. package/gsd-core/workflows/mvp-phase.md +6 -3
  203. package/gsd-core/workflows/new-milestone.md +14 -9
  204. package/gsd-core/workflows/new-project.md +14 -14
  205. package/gsd-core/workflows/next.md +12 -0
  206. package/gsd-core/workflows/plan-phase.md +41 -17
  207. package/gsd-core/workflows/plan-review-convergence.md +50 -2
  208. package/gsd-core/workflows/progress.md +34 -6
  209. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -4
  210. package/gsd-core/workflows/quick/steps/quick-verification.md +27 -6
  211. package/gsd-core/workflows/quick/steps/research-phase.md +2 -2
  212. package/gsd-core/workflows/quick.md +35 -15
  213. package/gsd-core/workflows/review.md +26 -5
  214. package/gsd-core/workflows/secure-phase.md +1 -1
  215. package/gsd-core/workflows/session-report.md +2 -1
  216. package/gsd-core/workflows/settings.md +66 -2
  217. package/gsd-core/workflows/ship.md +104 -44
  218. package/gsd-core/workflows/spec-phase.md +30 -12
  219. package/gsd-core/workflows/sync-skills.md +63 -8
  220. package/gsd-core/workflows/transition.md +46 -11
  221. package/gsd-core/workflows/ui-phase.md +5 -5
  222. package/gsd-core/workflows/ui-review.md +2 -2
  223. package/gsd-core/workflows/update.md +1 -1
  224. package/gsd-core/workflows/validate-phase.md +1 -1
  225. package/gsd-core/workflows/verify-work.md +9 -7
  226. package/hooks/dist/gsd-agent-isolation-guard.js +103 -14
  227. package/hooks/dist/gsd-check-update-worker.js +56 -13
  228. package/hooks/dist/gsd-check-update.js +19 -1
  229. package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
  230. package/hooks/dist/gsd-cursor-subagent-start.js +77 -2
  231. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
  232. package/hooks/dist/gsd-prompt-guard.js +21 -20
  233. package/hooks/dist/gsd-read-injection-scanner.js +38 -24
  234. package/hooks/dist/gsd-statusline.js +18 -0
  235. package/hooks/dist/gsd-update-banner.js +22 -1
  236. package/hooks/dist/gsd-workflow-guard.js +134 -36
  237. package/hooks/dist/lib/git-cmd.js +92 -59
  238. package/hooks/dist/lib/injection-patterns.js +45 -0
  239. package/hooks/dist/lib/isolation-deny-reason.js +39 -0
  240. package/hooks/dist/lib/isolation-sentinel.js +9 -0
  241. package/hooks/gsd-agent-isolation-guard.js +103 -14
  242. package/hooks/gsd-check-update-worker.js +56 -13
  243. package/hooks/gsd-check-update.js +19 -1
  244. package/hooks/gsd-cursor-pre-tool.js +0 -3
  245. package/hooks/gsd-cursor-subagent-start.js +77 -2
  246. package/hooks/gsd-cursor-subagent-stop.js +3 -2
  247. package/hooks/gsd-prompt-guard.js +21 -20
  248. package/hooks/gsd-read-injection-scanner.js +38 -24
  249. package/hooks/gsd-statusline.js +18 -0
  250. package/hooks/gsd-update-banner.js +22 -1
  251. package/hooks/gsd-workflow-guard.js +134 -36
  252. package/hooks/lib/git-cmd.js +92 -59
  253. package/hooks/lib/injection-patterns.js +45 -0
  254. package/hooks/lib/isolation-deny-reason.js +39 -0
  255. package/hooks/lib/isolation-sentinel.js +9 -0
  256. package/package.json +21 -9
  257. package/pi/gsd.cjs +19 -5
  258. package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
  259. package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
  260. package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
  261. package/scripts/changeset/lint.cjs +60 -5
  262. package/scripts/check-alias-drift.cjs +7 -43
  263. package/scripts/check-contract-drift.cjs +297 -0
  264. package/scripts/ci-test-scope.cjs +19 -2
  265. package/scripts/command-contract-helpers.cjs +903 -1
  266. package/scripts/gen-adr-index.cjs +728 -38
  267. package/scripts/gen-capability-registry.cjs +3 -15
  268. package/scripts/gen-context-index.cjs +2 -11
  269. package/scripts/gen-health-docs.cjs +390 -0
  270. package/scripts/gen-inventory-manifest.cjs +50 -4
  271. package/scripts/gen-loop-host-contract.cjs +4 -24
  272. package/scripts/gen-registry.cjs +3 -14
  273. package/scripts/lib/alias-drift-families.cjs +46 -0
  274. package/scripts/lib/drift-scan.cjs +278 -0
  275. package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
  276. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
  277. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
  278. package/scripts/lint-canary-version-leak.cjs +73 -0
  279. package/scripts/lint-command-contract.cjs +96 -13
  280. package/scripts/lint-completion-predicate-drift.cjs +933 -0
  281. package/scripts/lint-completion-ratio-drift.cjs +214 -0
  282. package/scripts/lint-default-flip-documentation.cjs +193 -0
  283. package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
  284. package/scripts/lint-eslint-glob-coverage.cjs +340 -0
  285. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
  286. package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
  287. package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
  288. package/scripts/lint-milestone-window-drift.cjs +468 -0
  289. package/scripts/lint-phase-enumeration-drift.cjs +479 -0
  290. package/scripts/lint-plan-count-drift.cjs +318 -0
  291. package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
  292. package/scripts/lint-planning-prompt-drift.cjs +434 -0
  293. package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
  294. package/scripts/lint-regression-test-names.cjs +15 -13
  295. package/scripts/lint-removed-but-needed.cjs +320 -0
  296. package/scripts/lint-state-field-drift.cjs +805 -0
  297. package/scripts/lint-state-write-path-drift.cjs +1045 -0
  298. package/scripts/lint-test-file-count.allowlist.json +21 -10
  299. package/scripts/lint-unreachable-guard-drift.cjs +843 -0
  300. package/scripts/lint-vendored-deps.cjs +124 -0
  301. package/scripts/pr-changed-files.cjs +63 -0
  302. package/scripts/pr-template-policy.cjs +14 -4
  303. package/scripts/prompt-injection-scan.sh +25 -0
  304. package/scripts/require-issue-link-policy.cjs +192 -0
  305. package/scripts/state-write-path-drift-baseline.json +19 -0
  306. package/scripts/sync-runtime-launcher.cjs +2 -4
  307. package/skills/gsd-autonomous/SKILL.md +0 -1
  308. package/skills/gsd-code-review/SKILL.md +1 -1
  309. package/skills/gsd-execute-phase/SKILL.md +1 -2
  310. package/skills/gsd-map-codebase/SKILL.md +1 -1
  311. package/skills/gsd-mempalace-capture/SKILL.md +1 -1
  312. package/skills/gsd-mempalace-recall/SKILL.md +1 -1
  313. package/skills/gsd-new-milestone/SKILL.md +1 -1
  314. package/skills/gsd-next/SKILL.md +0 -1
  315. package/skills/gsd-plan-phase/SKILL.md +0 -1
  316. package/skills/gsd-progress/SKILL.md +0 -1
  317. package/skills/gsd-quick/SKILL.md +1 -1
  318. package/skills/gsd-review-backlog/SKILL.md +2 -1
  319. package/skills/gsd-stats/SKILL.md +0 -1
  320. package/skills/gsd-verify-work/SKILL.md +1 -1
  321. package/vscode/package.json +1 -1
  322. package/gsd-core/workflows/discovery-phase.md +0 -298
  323. package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
  324. package/gsd-core/workflows/verify-phase.md +0 -574
  325. package/scripts/affected-tests-lib.cjs +0 -554
  326. package/scripts/lint-allow-test-rule-refs.cjs +0 -162
  327. package/scripts/run-affected-tests.cjs +0 -7
  328. package/scripts/run-tests.cjs +0 -1051
@@ -43,6 +43,11 @@ const { readActiveProfile, resolveProfile, loadSkillsManifest,
43
43
  // below can never drift from what the stage-time writer actually wrote.
44
44
  CAPABILITY_SKILL_MARKER, } = installProfiles;
45
45
  const clusters_cjs_1 = require("./clusters.cjs");
46
+ // #2870: `isGlobalScope` centralizes the `scope === 'global'` boolean
47
+ // projection `applySurface` needs at `_computePathPrefix`'s `isGlobal:
48
+ // boolean` boundary (see its doc comment in install-scope.cts for why the
49
+ // projection is centralized rather than eliminated).
50
+ const install_scope_cjs_1 = require("./install-scope.cjs");
46
51
  // eslint-disable-next-line @typescript-eslint/no-require-imports
47
52
  const runtimeArtifactLayout = require("./runtime-artifact-layout.cjs");
48
53
  const { findInstallSourceRoot } = runtimeArtifactLayout;
@@ -316,12 +321,23 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap, registry,
316
321
  const _homedirFn = opts?.homedir ?? (() => node_os_1.default.homedir());
317
322
  const _resolvedTarget = (0, shell_command_projection_cjs_1.posixNormalize)(node_path_1.default.resolve(layout.configDir));
318
323
  const _homeDir = (0, shell_command_projection_cjs_1.posixNormalize)(_homedirFn());
319
- const _isGlobal = (layout.scope ?? 'global') === 'global';
324
+ // #2870: same judgment as createRuntimeArtifactInstallPlan's identical
325
+ // line — `layout.scope` is already the resolved scope value on the
326
+ // `Layout` this function received. `layout.scope` is optional, so the
327
+ // pre-existing `?? 'global'` default is kept ahead of the call: it must
328
+ // run BEFORE `isGlobalScope`, because `isGlobalScope(undefined)` throws
329
+ // (unlike the old inline `undefined === 'global'`, which silently
330
+ // evaluated to `false`) — the default is what makes an undefined scope
331
+ // resolve to `'global'` here, exactly as it did before. `isGlobalScope`
332
+ // then projects the defaulted value to the boolean `_computePathPrefix`'s
333
+ // existing `isGlobal: boolean` API requires.
334
+ const _isGlobal = (0, install_scope_cjs_1.isGlobalScope)(layout.scope ?? 'global');
320
335
  const _isOpencode = layout.runtime === 'opencode';
321
336
  const _isWindowsHost = (opts?.platform ?? process.platform) === 'win32';
322
337
  const _pathPrefix = runtimeArtifactConversion._computePathPrefix({ isGlobal: _isGlobal, isOpencode: _isOpencode, isWindowsHost: _isWindowsHost, resolvedTarget: _resolvedTarget, homeDir: _homeDir });
323
338
  const _attribution = opts?.resolveAttribution ? opts.resolveAttribution(layout.runtime) : undefined;
324
- const agentCtx = { runtime: layout.runtime, pathPrefix: _pathPrefix, attribution: _attribution };
339
+ // #2875 Part 2 (row I1): layout.configDir is this call's install root.
340
+ const agentCtx = { runtime: layout.runtime, pathPrefix: _pathPrefix, attribution: _attribution, targetDir: layout.configDir };
325
341
  const tempDirsToClean = [];
326
342
  // #1575: When the surface has no state modifications AND the base profile is
327
343
  // 'full', pass the '*' sentinel for agents staging so ALL agents are staged —
@@ -557,13 +573,11 @@ function _syncGsdDir(stagedDir, destDir, kind, manifest, runtime) {
557
573
  // from install and orphaned the installed gsd-*.md files, and the unscoped
558
574
  // prune deleted user-owned command files.
559
575
  //
560
- // NOTE: the destName rule below intentionally mirrors bin/install.js
561
- // `_copyStaged` (the `namespacedByDir` decision). Keep them in sync.
562
- const destLast = (typeof kind === 'object' && kind !== null && kind.destSubpath)
563
- ? node_path_1.default.basename(kind.destSubpath)
564
- : '';
565
- const prefixStem = kindPrefix ? kindPrefix.replace(/-$/, '') : '';
566
- const namespacedByDir = kindName === 'commands' && destLast === prefixStem;
576
+ // Single source of truth: runtimeArtifactLayout.isNamespacedByDir (#2871
577
+ // Phase 2 review finding — this rule previously drifted independently
578
+ // across install-engine.cts / surface.cts / runtime-artifact-layout.cts).
579
+ const kindDestSubpath = (typeof kind === 'object' && kind !== null && kind.destSubpath) ? kind.destSubpath : '';
580
+ const namespacedByDir = runtimeArtifactLayout.isNamespacedByDir(kindName, kindDestSubpath, kindPrefix);
567
581
  const stagedFiles = node_fs_1.default.readdirSync(stagedDir).filter(f => f.endsWith('.md'));
568
582
  const stagedDestNames = new Set();
569
583
  for (const file of stagedFiles) {
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * text-lines.cts — the line-terminator seam (ADR-3212 §3, epic #3212 Phase 2,
4
+ * #3413).
5
+ *
6
+ * Source in src/text-lines.cts, compiled to gsd-core/bin/lib/text-lines.cjs
7
+ * (gitignored), per the repo's ADR-457 build-at-publish convention.
8
+ *
9
+ * Sole owner of `\r?\n` splitting and CRLF normalization. Closes #3360: a
10
+ * regex anchored on `^`/`$` under `/m` against a whole multi-line string is
11
+ * exposed to `\r` being its own LineTerminator (ECMA-262), so a greedy `\s*`
12
+ * can cross a CRLF boundary and inflate a captured indent by one character.
13
+ * Split-then-match — call `splitLines` first, then match per already-split
14
+ * line — is immune by construction, because a single split line can never
15
+ * contain the delimiter that produced it. This module exists so that shape
16
+ * is the easy, obvious way to write indentation-sensitive parsing, per the
17
+ * design doc (.gsd/phase/chore-3413-text-lines-seam/40-design.md).
18
+ *
19
+ * A "genuine leaf" module (CONTEXT.md's term, shared with Phase 1's sibling
20
+ * seam `src/pattern.cts`): zero I/O, zero imports from other `src/*.cts`
21
+ * modules, pure string functions only.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.splitLines = splitLines;
25
+ exports.normalizeEol = normalizeEol;
26
+ exports.detectEol = detectEol;
27
+ exports.joinLines = joinLines;
28
+ /**
29
+ * Split document content into lines on `\r\n` or `\n`. A lone `\r` (bare CR,
30
+ * no following `\n`) is NOT a delimiter — this matches every existing
31
+ * `\r?\n` call site in the repo and is intentionally narrower than "treat
32
+ * any LineTerminator as a break." Matches `String.prototype.split`'s own
33
+ * contract for a trailing terminator (a trailing empty element) and for the
34
+ * empty string (`[""]`).
35
+ */
36
+ function splitLines(content) {
37
+ if (typeof content !== 'string') {
38
+ throw new TypeError(`splitLines: expected a string, got ${typeof content}`);
39
+ }
40
+ return content.split(/\r?\n/);
41
+ }
42
+ /**
43
+ * Normalize all line endings to LF by stripping every `\r` character — not
44
+ * only `\r\n` pairs. This is byte-for-byte the same operation as the 4
45
+ * `scripts/gen-*.cjs` copies of `normalizeLineEndings` this module
46
+ * consolidates (`content.replace(/\r/g, '')`), so a lone/unpaired `\r` (old
47
+ * Mac-style content) is stripped too. Deliberately a different contract from
48
+ * `splitLines`, which does NOT treat a bare `\r` as a delimiter (row 6) —
49
+ * these are two different operations kept as two separate functions rather
50
+ * than one "handle all CR-ish things" primitive.
51
+ */
52
+ function normalizeEol(content) {
53
+ return content.replace(/\r/g, '');
54
+ }
55
+ /**
56
+ * Detect the dominant line-terminator in `content`: `'\r\n'` when CRLF pairs
57
+ * outnumber bare LFs, `'\n'` when bare LFs outnumber CRLF pairs, and `'\r\n'`
58
+ * as the default when there is no bare LF at all (all-CRLF content, or no
59
+ * terminator present whatsoever — an empty or single-line input). See the
60
+ * design doc's Rejected section for why the tie/empty default is `'\r\n'`
61
+ * rather than `'\n'`: this function exists to PRESERVE whatever a file
62
+ * already uses, not to bias toward LF the way a write-time normalizer would.
63
+ */
64
+ function detectEol(content) {
65
+ const crlfCount = (content.match(/\r\n/g) || []).length;
66
+ const totalLfCount = (content.match(/\n/g) || []).length;
67
+ const bareLfCount = totalLfCount - crlfCount;
68
+ if (bareLfCount === 0 || crlfCount >= bareLfCount)
69
+ return '\r\n';
70
+ return '\n';
71
+ }
72
+ /**
73
+ * Join lines back into a single string with `eol` (default `'\n'`) between
74
+ * each pair — the inverse of `splitLines`. `joinLines(splitLines(x),
75
+ * detectEol(x))` reproduces `x` byte-for-byte for any `x` already in
76
+ * canonical (single-terminator) form (ADR-3212 §3's round-trip property).
77
+ */
78
+ function joinLines(lines, eol) {
79
+ return lines.join(eol ?? '\n');
80
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * token-scanner.cts — the tokenizer-first seam for stateful grammars (ADR-3212
4
+ * §4, epic #3212 Phase 3, #3414).
5
+ *
6
+ * Source in src/token-scanner.cts, compiled to gsd-core/bin/lib/token-scanner.cjs
7
+ * (gitignored), per the repo's ADR-457 build-at-publish convention.
8
+ *
9
+ * Generalizes the proven `hooks/lib/git-cmd.js` token-walk (#3129 — "has not
10
+ * re-opened") into a primitive other stateful-grammar consumers can share.
11
+ * `git-cmd.js` migrates onto `tokenizeShellLike` with zero behavior change
12
+ * (ADR §6); its own env-prefix/flag/subcommand walk logic stays put — only
13
+ * the character-level tokenizer moves here.
14
+ *
15
+ * `indentWidth` is the primitive `src/decisions.cts`'s #3169 fix needs: a
16
+ * decision-bullet list can NEST (a bullet elaborating on an already-open
17
+ * decision, indented deeper than it), and a per-line regex cannot see that
18
+ * nesting — only tracking indentation relative to the currently-open
19
+ * decision can (ADR §4 criterion 1). See
20
+ * .gsd/phase/chore-3414-tokenizer-first-seam/40-design.md §1.3 for the
21
+ * disproven bold-run-content-classification alternative and why nesting
22
+ * depth, not bullet content, is the actual distinguishing signal.
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.tokenizeShellLike = tokenizeShellLike;
26
+ exports.indentWidth = indentWidth;
27
+ /**
28
+ * Tokenize a shell-like command string: whitespace-split, with single- and
29
+ * double-quoted spans taken as one token each. No escape handling, no
30
+ * brace/variable expansion — matches `hooks/lib/git-cmd.js`'s original
31
+ * `tokenize()` exactly (parity-asserted in tests/token-scanner.test.cjs).
32
+ */
33
+ function tokenizeShellLike(cmd) {
34
+ const tokens = [];
35
+ let i = 0;
36
+ const len = cmd.length;
37
+ while (i < len) {
38
+ while (i < len && /\s/.test(cmd[i]))
39
+ i++;
40
+ if (i >= len)
41
+ break;
42
+ let token = '';
43
+ while (i < len && !/\s/.test(cmd[i])) {
44
+ if (cmd[i] === "'") {
45
+ i++;
46
+ while (i < len && cmd[i] !== "'")
47
+ token += cmd[i++];
48
+ if (i < len)
49
+ i++;
50
+ }
51
+ else if (cmd[i] === '"') {
52
+ i++;
53
+ while (i < len && cmd[i] !== '"')
54
+ token += cmd[i++];
55
+ if (i < len)
56
+ i++;
57
+ }
58
+ else {
59
+ token += cmd[i++];
60
+ }
61
+ }
62
+ if (token)
63
+ tokens.push(token);
64
+ }
65
+ return tokens;
66
+ }
67
+ /**
68
+ * Count a line's leading whitespace width. Tabs count as one column each
69
+ * (not expanded) — matches `src/decisions.cts`'s existing continuation-line
70
+ * check (`/^[ \t]/`), which never expanded tabs either; this function does
71
+ * not introduce a new tab-width policy.
72
+ */
73
+ function indentWidth(line) {
74
+ const match = line.match(/^[ \t]*/);
75
+ return match ? match[0].length : 0;
76
+ }
@@ -25,6 +25,9 @@ const { stripFencedCode } = markdownSectionizer;
25
25
  // eslint-disable-next-line @typescript-eslint/no-require-imports
26
26
  const verification = require("./verification.cjs");
27
27
  const { readVerificationStatus } = verification;
28
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
29
+ const phaseIdMod = require("./phase-id.cjs");
30
+ const { scopeToPhase } = phaseIdMod;
28
31
  // ─── Blocking state sets (documented for maintainability) ─────────────────────
29
32
  // UAT file frontmatter `status` values that indicate the file is not fully done
30
33
  const BLOCKING_UAT_FM_STATUSES = new Set([
@@ -190,9 +193,12 @@ function evaluateUatPassed(phaseFullDir, opts) {
190
193
  verification_stale_check_indeterminate: false,
191
194
  };
192
195
  }
193
- // Filter UAT and VERIFICATION files using the same filter as cmdPhaseComplete
194
- const uatFileNames = dirEntries.filter(f => f.includes('-UAT') && f.endsWith('.md'));
195
- const verFileNames = dirEntries.filter(f => f.includes('-VERIFICATION') && f.endsWith('.md'));
196
+ // Filter UAT and VERIFICATION files using the same filter as cmdPhaseComplete,
197
+ // scoped to THIS phase's own token (#3511) — a stray, cross-phase, or ad-hoc
198
+ // file can no longer contribute a blocker to a phase it does not belong to.
199
+ const phaseDirBaseName = node_path_1.default.basename(phaseFullDir);
200
+ const uatFileNames = scopeToPhase(dirEntries.filter(f => f.includes('-UAT') && f.endsWith('.md')), phaseDirBaseName);
201
+ const verFileNames = scopeToPhase(dirEntries.filter(f => f.includes('-VERIFICATION') && f.endsWith('.md')), phaseDirBaseName);
196
202
  // ── Process UAT files ──────────────────────────────────────────────────────
197
203
  for (const file of uatFileNames) {
198
204
  uatFiles.push(file);