@opengsd/gsd-core 1.18.0 → 1.20.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 (308) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -1
  3. package/.opencode/plugins/gsd-core.js +2 -3
  4. package/agents/gsd-code-fixer.compact.md +7 -7
  5. package/agents/gsd-code-fixer.md +13 -7
  6. package/agents/gsd-code-reviewer.compact.md +49 -8
  7. package/agents/gsd-code-reviewer.md +53 -14
  8. package/agents/gsd-executor.md +8 -4
  9. package/agents/gsd-verifier.md +1 -1
  10. package/bin/install.js +422 -103
  11. package/commands/gsd/update.md +5 -2
  12. package/gsd-core/bin/gsd-tools.cjs +179 -30
  13. package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
  14. package/gsd-core/bin/lib/args-terminator.cjs +114 -0
  15. package/gsd-core/bin/lib/broken-windows.cjs +59 -1
  16. package/gsd-core/bin/lib/capability-lifecycle.cjs +1 -12
  17. package/gsd-core/bin/lib/capability-lock.cjs +13 -2
  18. package/gsd-core/bin/lib/capability-registry.cjs +376 -103
  19. package/gsd-core/bin/lib/capability-state.cjs +14 -8
  20. package/gsd-core/bin/lib/capability-validator.cjs +32 -0
  21. package/gsd-core/bin/lib/commands.cjs +27 -17
  22. package/gsd-core/bin/lib/config-loader.cjs +13 -3
  23. package/gsd-core/bin/lib/config.cjs +256 -58
  24. package/gsd-core/bin/lib/core-utils.cjs +45 -0
  25. package/gsd-core/bin/lib/decision-coverage-support.cjs +74 -0
  26. package/gsd-core/bin/lib/frontmatter.cjs +21 -3
  27. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +2 -2
  28. package/gsd-core/bin/lib/gate-context-drift.cjs +9 -4
  29. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +6 -1
  30. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +6 -1
  31. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
  32. package/gsd-core/bin/lib/gate-phase-context.cjs +7 -8
  33. package/gsd-core/bin/lib/gate-schema-drift.cjs +1 -1
  34. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +63 -22
  35. package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
  36. package/gsd-core/bin/lib/git-info-exclude.cjs +52 -0
  37. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +31 -12
  38. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +9 -7
  39. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +3 -3
  40. package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
  41. package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
  42. package/gsd-core/bin/lib/host-integration.cjs +13 -6
  43. package/gsd-core/bin/lib/init.cjs +245 -68
  44. package/gsd-core/bin/lib/install-engine.cjs +246 -32
  45. package/gsd-core/bin/lib/install-profiles.cjs +9 -4
  46. package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
  47. package/gsd-core/bin/lib/io.cjs +6 -0
  48. package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
  49. package/gsd-core/bin/lib/markdown-sectionizer.cjs +147 -1
  50. package/gsd-core/bin/lib/markdown-table.cjs +23 -0
  51. package/gsd-core/bin/lib/mcp-server.cjs +8 -5
  52. package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
  53. package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
  54. package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
  55. package/gsd-core/bin/lib/milestone.cjs +61 -51
  56. package/gsd-core/bin/lib/model-catalog.cjs +8 -0
  57. package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
  58. package/gsd-core/bin/lib/phase-entry-grammar.cjs +119 -0
  59. package/gsd-core/bin/lib/phase-id-display.cjs +2 -0
  60. package/gsd-core/bin/lib/phase-id.cjs +629 -38
  61. package/gsd-core/bin/lib/phase-lifecycle.cjs +12 -44
  62. package/gsd-core/bin/lib/phase-locator.cjs +328 -19
  63. package/gsd-core/bin/lib/phase.cjs +3066 -653
  64. package/gsd-core/bin/lib/planning-document.cjs +26 -5
  65. package/gsd-core/bin/lib/planning-inspect.cjs +27 -35
  66. package/gsd-core/bin/lib/planning-snapshot.cjs +15 -8
  67. package/gsd-core/bin/lib/planning-workspace.cjs +21 -3
  68. package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
  69. package/gsd-core/bin/lib/read-only-git-env.cjs +79 -0
  70. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +2 -2
  71. package/gsd-core/bin/lib/review-lane-descriptor.cjs +57 -2
  72. package/gsd-core/bin/lib/review-lane-invocation.cjs +125 -18
  73. package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
  74. package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +11 -9
  75. package/gsd-core/bin/lib/roadmap-parser.cjs +735 -137
  76. package/gsd-core/bin/lib/roadmap-progress.cjs +136 -0
  77. package/gsd-core/bin/lib/roadmap-upgrade.cjs +47 -7
  78. package/gsd-core/bin/lib/roadmap.cjs +383 -123
  79. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +381 -14
  80. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
  81. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
  82. package/gsd-core/bin/lib/shell-command-projection.cjs +151 -19
  83. package/gsd-core/bin/lib/smart-entry.cjs +35 -11
  84. package/gsd-core/bin/lib/state-contract.cjs +39 -15
  85. package/gsd-core/bin/lib/state-document.cjs +344 -27
  86. package/gsd-core/bin/lib/state-transition.cjs +156 -32
  87. package/gsd-core/bin/lib/state.cjs +527 -186
  88. package/gsd-core/bin/lib/surface.cjs +9 -0
  89. package/gsd-core/bin/lib/task-command-router.cjs +5 -25
  90. package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
  91. package/gsd-core/bin/lib/template.cjs +2 -2
  92. package/gsd-core/bin/lib/validate.cjs +3 -2
  93. package/gsd-core/bin/lib/vendor/re2js.cjs +863 -577
  94. package/gsd-core/bin/lib/vendor/re2js.d.cts +284 -219
  95. package/gsd-core/bin/lib/verification.cjs +96 -9
  96. package/gsd-core/bin/lib/verify.cjs +4 -2
  97. package/gsd-core/bin/lib/workstream-inventory.cjs +26 -20
  98. package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
  99. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  100. package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
  101. package/gsd-core/bin/verify-reapply-patches.cjs +411 -10
  102. package/gsd-core/references/cicd-review-patterns.md +45 -0
  103. package/gsd-core/references/git-integration.md +11 -0
  104. package/gsd-core/references/loop-hook-dispatch.md +13 -6
  105. package/gsd-core/references/necessity-review.md +48 -0
  106. package/gsd-core/references/planning-config.md +2 -0
  107. package/gsd-core/references/tdd.md +2 -2
  108. package/gsd-core/templates/DEBUG.md +16 -0
  109. package/gsd-core/templates/config.json +2 -1
  110. package/gsd-core/templates/verification-report.md +1 -1
  111. package/gsd-core/workflows/audit-fix.md +2 -1
  112. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
  113. package/gsd-core/workflows/code-review-fix.md +46 -5
  114. package/gsd-core/workflows/code-review.md +64 -7
  115. package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
  116. package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
  117. package/gsd-core/workflows/complete-milestone.md +37 -150
  118. package/gsd-core/workflows/diagnose-issues.md +29 -5
  119. package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
  120. package/gsd-core/workflows/discuss-phase-assumptions.md +33 -2
  121. package/gsd-core/workflows/discuss-phase-power.md +19 -2
  122. package/gsd-core/workflows/discuss-phase.md +6 -10
  123. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
  124. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +7 -2
  125. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -1
  126. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +2 -2
  127. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
  128. package/gsd-core/workflows/execute-phase.md +10 -6
  129. package/gsd-core/workflows/execute-plan.md +1 -1
  130. package/gsd-core/workflows/health.md +2 -1
  131. package/gsd-core/workflows/import.md +1 -1
  132. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +2 -2
  133. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +13 -9
  134. package/gsd-core/workflows/plan-phase.md +14 -14
  135. package/gsd-core/workflows/pr-branch.md +2 -0
  136. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
  137. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
  138. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
  139. package/gsd-core/workflows/quick.md +1 -1
  140. package/gsd-core/workflows/reapply-patches.md +104 -0
  141. package/gsd-core/workflows/review.md +70 -154
  142. package/gsd-core/workflows/section-manifest.json +5 -0
  143. package/gsd-core/workflows/secure-phase.md +1 -1
  144. package/gsd-core/workflows/settings-advanced.md +57 -9
  145. package/gsd-core/workflows/settings.md +1 -0
  146. package/gsd-core/workflows/ship.md +15 -4
  147. package/gsd-core/workflows/spec-phase.md +3 -6
  148. package/gsd-core/workflows/verify-work.md +4 -3
  149. package/hooks/dist/gsd-agent-isolation-guard.js +11 -1
  150. package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
  151. package/hooks/dist/gsd-graphify-update.sh +6 -0
  152. package/hooks/dist/gsd-path-export.js +95 -0
  153. package/hooks/dist/gsd-secret-read-guard.js +172 -39
  154. package/hooks/dist/gsd-statusline.js +37 -3
  155. package/hooks/dist/gsd-windsurf-pre-write.js +29 -2
  156. package/hooks/dist/gsd-workflow-guard.js +3 -2
  157. package/hooks/dist/gsd-worktree-path-guard.js +29 -2
  158. package/hooks/dist/lib/git-probe.js +16 -0
  159. package/hooks/dist/lib/isolation-sentinel.js +44 -0
  160. package/hooks/dist/managed-hooks-registry.cjs +1 -0
  161. package/hooks/gsd-agent-isolation-guard.js +11 -1
  162. package/hooks/gsd-cursor-subagent-start.js +6 -2
  163. package/hooks/gsd-graphify-update.sh +6 -0
  164. package/hooks/gsd-path-export.js +95 -0
  165. package/hooks/gsd-secret-read-guard.js +172 -39
  166. package/hooks/gsd-statusline.js +37 -3
  167. package/hooks/gsd-windsurf-pre-write.js +29 -2
  168. package/hooks/gsd-workflow-guard.js +3 -2
  169. package/hooks/gsd-worktree-path-guard.js +29 -2
  170. package/hooks/hooks.json +1 -0
  171. package/hooks/lib/git-probe.js +16 -0
  172. package/hooks/lib/isolation-sentinel.js +44 -0
  173. package/hooks/managed-hooks-registry.cjs +1 -0
  174. package/package.json +15 -8
  175. package/pi/gsd.cjs +1047 -10
  176. package/pi/package-agents/gsd-advisor-researcher.md +113 -0
  177. package/pi/package-agents/gsd-ai-researcher.md +111 -0
  178. package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
  179. package/pi/package-agents/gsd-code-fixer.md +774 -0
  180. package/pi/package-agents/gsd-code-reviewer.md +441 -0
  181. package/pi/package-agents/gsd-codebase-mapper.md +850 -0
  182. package/pi/package-agents/gsd-debug-session-manager.md +416 -0
  183. package/pi/package-agents/gsd-debugger.md +1274 -0
  184. package/pi/package-agents/gsd-doc-classifier.md +269 -0
  185. package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
  186. package/pi/package-agents/gsd-doc-verifier.md +212 -0
  187. package/pi/package-agents/gsd-doc-writer.md +626 -0
  188. package/pi/package-agents/gsd-dom-verifier.md +164 -0
  189. package/pi/package-agents/gsd-domain-researcher.md +144 -0
  190. package/pi/package-agents/gsd-eval-auditor.md +185 -0
  191. package/pi/package-agents/gsd-eval-planner.md +149 -0
  192. package/pi/package-agents/gsd-executor.md +898 -0
  193. package/pi/package-agents/gsd-framework-selector.md +159 -0
  194. package/pi/package-agents/gsd-integration-checker.md +476 -0
  195. package/pi/package-agents/gsd-intel-updater.md +338 -0
  196. package/pi/package-agents/gsd-mempalace-curator.md +49 -0
  197. package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
  198. package/pi/package-agents/gsd-pattern-mapper.md +340 -0
  199. package/pi/package-agents/gsd-phase-researcher.md +897 -0
  200. package/pi/package-agents/gsd-plan-checker.md +1077 -0
  201. package/pi/package-agents/gsd-planner.md +1003 -0
  202. package/pi/package-agents/gsd-project-researcher.md +611 -0
  203. package/pi/package-agents/gsd-research-synthesizer.md +259 -0
  204. package/pi/package-agents/gsd-roadmapper.md +779 -0
  205. package/pi/package-agents/gsd-security-auditor.md +171 -0
  206. package/pi/package-agents/gsd-ui-auditor.md +581 -0
  207. package/pi/package-agents/gsd-ui-checker.md +417 -0
  208. package/pi/package-agents/gsd-ui-researcher.md +469 -0
  209. package/pi/package-agents/gsd-user-profiler.md +174 -0
  210. package/pi/package-agents/gsd-verifier.md +963 -0
  211. package/pi/package-agents/manifest.json +39 -0
  212. package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
  213. package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
  214. package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
  215. package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
  216. package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
  217. package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
  218. package/pi/package-skills/gsd-capture/SKILL.md +68 -0
  219. package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
  220. package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
  221. package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
  222. package/pi/package-skills/gsd-config/SKILL.md +60 -0
  223. package/pi/package-skills/gsd-debug/SKILL.md +64 -0
  224. package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
  225. package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
  226. package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
  227. package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
  228. package/pi/package-skills/gsd-explore/SKILL.md +26 -0
  229. package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
  230. package/pi/package-skills/gsd-fast/SKILL.md +33 -0
  231. package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
  232. package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
  233. package/pi/package-skills/gsd-health/SKILL.md +36 -0
  234. package/pi/package-skills/gsd-help/SKILL.md +37 -0
  235. package/pi/package-skills/gsd-import/SKILL.md +46 -0
  236. package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
  237. package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
  238. package/pi/package-skills/gsd-manager/SKILL.md +46 -0
  239. package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
  240. package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
  241. package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
  242. package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
  243. package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
  244. package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
  245. package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
  246. package/pi/package-skills/gsd-next/SKILL.md +34 -0
  247. package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
  248. package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
  249. package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
  250. package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
  251. package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
  252. package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
  253. package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
  254. package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
  255. package/pi/package-skills/gsd-phase/SKILL.md +61 -0
  256. package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
  257. package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
  258. package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
  259. package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
  260. package/pi/package-skills/gsd-progress/SKILL.md +51 -0
  261. package/pi/package-skills/gsd-quick/SKILL.md +179 -0
  262. package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
  263. package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
  264. package/pi/package-skills/gsd-review/SKILL.md +50 -0
  265. package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
  266. package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
  267. package/pi/package-skills/gsd-settings/SKILL.md +30 -0
  268. package/pi/package-skills/gsd-ship/SKILL.md +27 -0
  269. package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
  270. package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
  271. package/pi/package-skills/gsd-spike/SKILL.md +53 -0
  272. package/pi/package-skills/gsd-stats/SKILL.md +22 -0
  273. package/pi/package-skills/gsd-surface/SKILL.md +177 -0
  274. package/pi/package-skills/gsd-thread/SKILL.md +29 -0
  275. package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
  276. package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
  277. package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
  278. package/pi/package-skills/gsd-undo/SKILL.md +38 -0
  279. package/pi/package-skills/gsd-update/SKILL.md +54 -0
  280. package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
  281. package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
  282. package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
  283. package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
  284. package/scripts/build-hooks.js +4 -0
  285. package/scripts/ci-next-health.cjs +246 -23
  286. package/scripts/command-contract-helpers.cjs +1 -1
  287. package/scripts/docs-guard-registry.cjs +22 -7
  288. package/scripts/gen-features.cjs +14 -2
  289. package/scripts/gen-health-docs.cjs +13 -1
  290. package/scripts/gen-pi-package-skills.cjs +217 -0
  291. package/scripts/lib/drift-scan.cjs +27 -0
  292. package/scripts/lib/macos-conformance-tier.generated.cjs +17 -1
  293. package/scripts/lib/platform-conformance-tier.generated.cjs +37 -1
  294. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
  295. package/scripts/lint-phase-enumeration-drift.cjs +8 -4
  296. package/scripts/lint-retired-runtime-name.cjs +5 -0
  297. package/scripts/lint-roadmap-progress-drift.cjs +421 -0
  298. package/scripts/mutation-matrix.cjs +23 -1
  299. package/scripts/npm-audit-baseline.cjs +41 -7
  300. package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
  301. package/scripts/select-docs-guards.cjs +1 -1
  302. package/scripts/self-test-report-policy.cjs +350 -0
  303. package/scripts/sync-next-version.cjs +38 -6
  304. package/skills/gsd-update/SKILL.md +5 -2
  305. package/vscode/package.json +1 -1
  306. package/scripts/diagnose-validate-commit-in-tier.cjs +0 -270
  307. package/scripts/diagnose-validate-commit-phases.cjs +0 -348
  308. package/scripts/xtrace-phase-timing.cjs +0 -205
@@ -245,6 +245,14 @@ exports.EFFORT_ARGV = {
245
245
  supported: new Set(['low', 'medium', 'high', 'xhigh', 'max']),
246
246
  clamp: (level) => (level === 'minimal' ? 'low' : level),
247
247
  },
248
+ // Verified against `pi --help` (pi 1.3.0, #5557): `--thinking <level>` — "Set
249
+ // thinking level: off, minimal, low, medium, high, xhigh, max". `off` is a
250
+ // pi-only level with no universal counterpart, so it is not in `supported`.
251
+ pi: {
252
+ render: (level) => ['--thinking', level],
253
+ supported: new Set(['minimal', 'low', 'medium', 'high', 'xhigh', 'max']),
254
+ clamp: (level) => level,
255
+ },
248
256
  };
249
257
  /**
250
258
  * Clamp a universal effort level to what a host actually accepts, or null.
@@ -180,8 +180,75 @@ function normalizeTestCommand(rawCmd, cwd) {
180
180
  function cmdNormalizeTestCommand(cwd, rawCmd) {
181
181
  process.stdout.write(normalizeTestCommand(rawCmd ?? '', cwd));
182
182
  }
183
+ const PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun'];
184
+ // Lockfile order only matters when a project somehow carries several; the
185
+ // `packageManager` field outranks all of them.
186
+ const LOCKFILE_MANAGERS = [
187
+ ['pnpm-lock.yaml', 'pnpm'],
188
+ ['yarn.lock', 'yarn'],
189
+ ['bun.lock', 'bun'],
190
+ ['bun.lockb', 'bun'],
191
+ ];
192
+ // The script name is spliced into a shell command by the caller, so it is
193
+ // restricted to a plain identifier. Anything else is refused (empty output).
194
+ const SCRIPT_NAME = /^[A-Za-z0-9_][A-Za-z0-9:_-]{0,63}$/;
195
+ // Same bounded-read stance as the rest of this module: a package.json larger
196
+ // than this is not a real manifest, so it is not parsed.
197
+ const MAX_PACKAGE_JSON_BYTES = 1024 * 1024;
198
+ function packageManagerFromField(cwd) {
199
+ try {
200
+ const pkgPath = node_path_1.default.join(cwd, 'package.json');
201
+ const stat = node_fs_1.default.statSync(pkgPath);
202
+ if (!stat.isFile() || stat.size > MAX_PACKAGE_JSON_BYTES)
203
+ return null;
204
+ const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgPath, 'utf-8'));
205
+ if (typeof pkg !== 'object' || pkg === null)
206
+ return null;
207
+ const field = pkg.packageManager;
208
+ if (typeof field !== 'string')
209
+ return null;
210
+ const name = field.split('@')[0];
211
+ return PACKAGE_MANAGERS.includes(name) ? name : null;
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }
217
+ function detectPackageManager(cwd) {
218
+ const declared = packageManagerFromField(cwd);
219
+ if (declared)
220
+ return declared;
221
+ for (const [lockfile, manager] of LOCKFILE_MANAGERS) {
222
+ try {
223
+ if (node_fs_1.default.statSync(node_path_1.default.join(cwd, lockfile)).isFile())
224
+ return manager;
225
+ }
226
+ catch { /* absent: try the next lockfile */ }
227
+ }
228
+ return 'npm';
229
+ }
230
+ /**
231
+ * Command that runs package script `script` with the project's package manager.
232
+ * `test` uses the manager's short form where it has one; `bun test` is bun's
233
+ * own runner, not the package script, so bun always goes through `bun run`.
234
+ * Returns '' for a script name that is not a plain identifier.
235
+ */
236
+ function resolvePackageManagerCommand(script, cwd) {
237
+ if (typeof script !== 'string' || !SCRIPT_NAME.test(script))
238
+ return '';
239
+ const manager = detectPackageManager(cwd);
240
+ if (script === 'test' && manager !== 'bun')
241
+ return `${manager} test`;
242
+ return `${manager} run ${script}`;
243
+ }
244
+ /** CLI handler for `gsd-tools query resolve-package-manager <script>`. */
245
+ function cmdResolvePackageManager(cwd, script) {
246
+ process.stdout.write(resolvePackageManagerCommand(script ?? '', cwd));
247
+ }
183
248
  module.exports = {
184
249
  normalizeTestCommand,
185
250
  cmdNormalizeTestCommand,
186
251
  isAlreadyOneShot,
252
+ resolvePackageManagerCommand,
253
+ cmdResolvePackageManager,
187
254
  };
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /**
3
+ * Phase-entry grammar — the one definition of a ROADMAP phase-list entry
4
+ * (`- [ ] **Phase 1: Name**`): bullet marker, checkbox, bold token and line
5
+ * anchoring (#5763, Phase 3 of epic #5692; census in #5703).
6
+ *
7
+ * Before this module every reader owned a private pattern, and the patterns
8
+ * disagreed on each axis (`-` only vs `[-*]`; required, optional or `\*{0,2}`
9
+ * bold; `[ x]` vs `[ xX]` vs `(x| )`; `^`-anchored vs the unanchored forms
10
+ * behind #4965 and #5545). Readers now compose their pattern from the prefix
11
+ * built here and keep only their own tail (label, id token, separator).
12
+ *
13
+ * The accepted grammar:
14
+ * entry := indent marker mgap box gap bold? gap <caller tail>
15
+ * indent := [ \t]* — an entry starts its line
16
+ * marker := '-' | '*'
17
+ * mgap := [ \t]{1,4} — a list item: `-[ ]` is not one (#5764)
18
+ * box := '[' (' ' | 'x' | 'X') ']'
19
+ * bold := '**' | '__' — a reader may require it
20
+ * gap := [ \t]* — horizontal whitespace only
21
+ * A reader that needs plain `- **Phase N**` bullets may make the box optional.
22
+ *
23
+ * Writers (flip, delete, renumber, id rewrite) compose their patterns here too
24
+ * (#5764, Phase 4): `phaseEntryRegExp` for a whole-line match and
25
+ * `phaseEntrySplitRegExp` when the writer rewrites the box and needs the text on
26
+ * either side of it.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.PHASE_ENTRY_BOLD_CLOSE_SRC = exports.PHASE_ENTRY_BOLD_TOKEN_SRC = void 0;
30
+ exports.phaseEntryPrefixSrc = phaseEntryPrefixSrc;
31
+ exports.phaseEntryRegExp = phaseEntryRegExp;
32
+ exports.phaseEntrySplitRegExp = phaseEntrySplitRegExp;
33
+ exports.isPhaseEntryChecked = isPhaseEntryChecked;
34
+ exports.isBoxCharChecked = isBoxCharChecked;
35
+ const MARKER_SRC = '[-*]';
36
+ // A list item has 1 to 4 spaces or tabs after its marker (CommonMark: none is not a list item,
37
+ // five or more makes the rest an indented code block), so `-[ ] **Phase 1**` is not an entry.
38
+ const MARKER_GAP_SRC = '[ \\t]{1,4}';
39
+ const BOLD_TOKEN_SRC = '(?:\\*\\*|__)';
40
+ /** Regex source of one bold token, for a reader that must also consume the closing wrapper. */
41
+ exports.PHASE_ENTRY_BOLD_TOKEN_SRC = BOLD_TOKEN_SRC;
42
+ /**
43
+ * Regex source of a closing bold wrapper for a reader that captures the entry's
44
+ * name up to it. `**` closes anywhere; `__` closes only at the end of the line,
45
+ * so a name that contains `__init__` or `__tests__` is not cut short.
46
+ */
47
+ exports.PHASE_ENTRY_BOLD_CLOSE_SRC = '(?:\\*\\*|__(?=[ \\t]*\\r?$))';
48
+ /**
49
+ * Line start, indent, marker and the marker's gap, up to where the box opens.
50
+ * A leading BOM can only precede the first line; it is not part of the grammar's indent.
51
+ */
52
+ const LINE_OPEN_SRC = `^\\uFEFF?[ \\t]*${MARKER_SRC}${MARKER_GAP_SRC}`;
53
+ /**
54
+ * Source for the bold token and its trailing gap. `(?:token[ \t]*)?` rather than
55
+ * `[ \t]*` + token + `[ \t]*`, which backtracks quadratically on a long blank run.
56
+ */
57
+ function boldSrcFor(bold) {
58
+ return bold === 'required' ? `${BOLD_TOKEN_SRC}[ \\t]*` : `(?:${BOLD_TOKEN_SRC}[ \\t]*)?`;
59
+ }
60
+ /** Source for the box interior, honouring the requested state filter. */
61
+ function stateSrc(state) {
62
+ if (state === 'unchecked')
63
+ return ' ';
64
+ if (state === 'checked')
65
+ return '[xX]';
66
+ if (state === 'captured')
67
+ return '([ xX])';
68
+ return '[ xX]';
69
+ }
70
+ /**
71
+ * Regex source of everything before the caller's `Phase`/label tail: line start, indent,
72
+ * marker, box, bold token and the horizontal gaps between them. A `captured`
73
+ * state adds exactly one capture group (the box character) at the front.
74
+ */
75
+ function phaseEntryPrefixSrc(options = {}) {
76
+ const { bold = 'optional', box = 'required', state = 'any', decorated = false } = options;
77
+ // The decoration may not contain the word `Phase`, so the entry's own label is the first one
78
+ // on the line and `- [ ] **Phase 5**: needs Phase 2` is not an entry of phase 2. No gap
79
+ // before the run: `[ \t]*` then a lazy run overlap and backtrack quadratically.
80
+ if (decorated)
81
+ return `${LINE_OPEN_SRC}\\[${stateSrc(state)}\\](?:(?!Phase)[^\\r\\n])*?`;
82
+ const boxSrc = `\\[${stateSrc(state)}\\][ \\t]*`;
83
+ const body = box === 'optional' ? `(?:${boxSrc})?` : boxSrc;
84
+ return `${LINE_OPEN_SRC}${body}${boldSrcFor(bold)}`;
85
+ }
86
+ /**
87
+ * A RegExp for a phase entry: the grammar prefix followed by the caller's
88
+ * `tailSrc`. The `m` flag is always set, so `^` is a line start.
89
+ */
90
+ function phaseEntryRegExp(tailSrc, flags = '', options = {}) {
91
+ const withM = flags.includes('m') ? flags : `${flags}m`;
92
+ return new RegExp(`${phaseEntryPrefixSrc(options)}${tailSrc}`, withM);
93
+ }
94
+ /**
95
+ * A RegExp for a phase entry a writer rewrites at the box: capture group 1 is
96
+ * everything through the opening `[` (indent, marker, gap) and capture group 2
97
+ * is everything from the closing `]` through the end of `tailSrc` (gap, bold
98
+ * token, label). A flip is `line.replace(re, '$1x$2')`; the box state itself is
99
+ * matched, not captured, so the writer chooses the new state. The `m` flag is
100
+ * always set.
101
+ */
102
+ function phaseEntrySplitRegExp(tailSrc, flags = '', options = {}) {
103
+ const { bold = 'optional', state = 'any' } = options;
104
+ const withM = flags.includes('m') ? flags : `${flags}m`;
105
+ return new RegExp(`(${LINE_OPEN_SRC}\\[)${stateSrc(state)}(\\][ \\t]*${boldSrcFor(bold)}${tailSrc})`, withM);
106
+ }
107
+ const ENTRY_BOX_RE = new RegExp(`^\\uFEFF?[ \\t]*${MARKER_SRC}${MARKER_GAP_SRC}\\[([ xX])\\]`);
108
+ /**
109
+ * Whether a phase entry line (or a regex match of one, which starts at the
110
+ * line) is ticked. The single place the box character is interpreted.
111
+ */
112
+ function isPhaseEntryChecked(entryText) {
113
+ const m = ENTRY_BOX_RE.exec(entryText);
114
+ return m !== null && m[1].toLowerCase() === 'x';
115
+ }
116
+ /** Whether a captured box character (`captured` state option) is a tick. */
117
+ function isBoxCharChecked(boxChar) {
118
+ return boxChar.toLowerCase() === 'x';
119
+ }
@@ -75,4 +75,6 @@ function renderBracketMilestoneDisplay(milestone, projectCode) {
75
75
  module.exports = {
76
76
  renderBracketPhaseDisplay,
77
77
  renderBracketMilestoneDisplay,
78
+ milestoneToken,
79
+ phaseToken,
78
80
  };