gsd-pi 2.82.0-dev.c22380fc3 → 2.82.0-dev.dfbc5f58f

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 (287) hide show
  1. package/README.md +4 -3
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  5. package/dist/resources/extensions/cmux/index.js +5 -0
  6. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  7. package/dist/resources/extensions/gsd/auto/loop.js +5 -5
  8. package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
  9. package/dist/resources/extensions/gsd/auto/phases.js +8 -1
  10. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
  12. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +233 -127
  14. package/dist/resources/extensions/gsd/auto-prompts.js +2 -2
  15. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  16. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  17. package/dist/resources/extensions/gsd/auto-verification.js +28 -22
  18. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  19. package/dist/resources/extensions/gsd/auto.js +30 -3
  20. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -1
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  22. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  23. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -2
  24. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  25. package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
  26. package/dist/resources/extensions/gsd/commands/handlers/core.js +37 -0
  27. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  28. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  29. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  30. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  31. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  32. package/dist/resources/extensions/gsd/doctor.js +2 -28
  33. package/dist/resources/extensions/gsd/export-html.js +27 -425
  34. package/dist/resources/extensions/gsd/git-service.js +39 -1
  35. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  36. package/dist/resources/extensions/gsd/guided-flow.js +6 -0
  37. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  38. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  39. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  40. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  41. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  42. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  43. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  44. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  45. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  46. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  47. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  48. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  49. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  50. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  51. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  52. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  53. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  54. package/dist/resources/extensions/gsd/validation.js +23 -1
  55. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  56. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  57. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  58. package/dist/resources/extensions/gsd/worktree-lifecycle.js +33 -8
  59. package/dist/resources/extensions/shared/html-shell.js +388 -0
  60. package/dist/resources/extensions/subagent/index.js +448 -78
  61. package/dist/resources/extensions/subagent/launch.js +77 -0
  62. package/dist/resources/extensions/subagent/run-store.js +148 -0
  63. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  64. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  65. package/dist/resources/extensions/visual-brief/index.js +5 -0
  66. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  67. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  68. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  69. package/dist/web/standalone/.next/BUILD_ID +1 -1
  70. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  71. package/dist/web/standalone/.next/build-manifest.json +3 -3
  72. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  73. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  74. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  84. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  94. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/index.html +1 -1
  96. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  97. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  99. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  101. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  102. package/dist/web/standalone/.next/server/app/page.js +2 -2
  103. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  104. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  106. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  107. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  111. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  112. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  113. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  114. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  115. package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
  116. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  117. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-9a4db269f9ed63ad.js} +1 -1
  118. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  119. package/package.json +4 -4
  120. package/packages/mcp-server/src/workflow-tools.test.ts +1 -1
  121. package/packages/native/tsconfig.json +2 -1
  122. package/packages/native/tsconfig.tsbuildinfo +1 -1
  123. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  124. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  125. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  126. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  127. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  128. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  129. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  130. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  131. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  133. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  134. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  135. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  136. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  137. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  138. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  139. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  140. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  141. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  142. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  143. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  144. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  145. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  146. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  147. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  148. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  149. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  150. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  151. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  152. package/src/resources/GSD-WORKFLOW.md +10 -1
  153. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  154. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  155. package/src/resources/extensions/cmux/index.ts +6 -0
  156. package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
  157. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  158. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  159. package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
  160. package/src/resources/extensions/gsd/auto/phases.ts +7 -1
  161. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  162. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  163. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  164. package/src/resources/extensions/gsd/auto-post-unit.ts +266 -139
  165. package/src/resources/extensions/gsd/auto-prompts.ts +2 -2
  166. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  167. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  168. package/src/resources/extensions/gsd/auto-verification.ts +36 -34
  169. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  170. package/src/resources/extensions/gsd/auto.ts +32 -3
  171. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +6 -1
  172. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  173. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  174. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -3
  175. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  176. package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
  177. package/src/resources/extensions/gsd/commands/handlers/core.ts +40 -0
  178. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  179. package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
  180. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  181. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  182. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  183. package/src/resources/extensions/gsd/doctor.ts +2 -27
  184. package/src/resources/extensions/gsd/export-html.ts +27 -427
  185. package/src/resources/extensions/gsd/git-service.ts +45 -1
  186. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  187. package/src/resources/extensions/gsd/guided-flow.ts +6 -0
  188. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  189. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  190. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  191. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  192. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  193. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  194. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  195. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  196. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  197. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  198. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  199. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  200. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  201. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +54 -0
  202. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
  203. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -6
  204. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  205. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  206. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  207. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  208. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  209. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  210. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  211. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  212. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  213. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  214. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  215. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  216. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  217. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  218. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  219. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  220. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  221. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  222. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  223. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  224. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  225. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  226. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  227. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  228. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  229. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  230. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  231. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  232. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  233. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  234. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  235. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  236. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  237. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  238. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
  239. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  240. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +31 -1
  241. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  242. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  243. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +86 -7
  244. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  245. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  246. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
  247. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  248. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  249. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  250. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  251. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  252. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  253. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  254. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  255. package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
  256. package/src/resources/extensions/gsd/types.ts +1 -1
  257. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  258. package/src/resources/extensions/gsd/validation.ts +23 -1
  259. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  260. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  261. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  262. package/src/resources/extensions/gsd/worktree-lifecycle.ts +41 -8
  263. package/src/resources/extensions/shared/html-shell.ts +412 -0
  264. package/src/resources/extensions/subagent/index.ts +567 -103
  265. package/src/resources/extensions/subagent/launch.ts +131 -0
  266. package/src/resources/extensions/subagent/run-store.ts +218 -0
  267. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  268. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  269. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  270. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  271. package/src/resources/extensions/visual-brief/index.ts +8 -0
  272. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  273. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  274. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  275. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  276. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  277. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  278. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  279. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  280. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  281. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  282. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  283. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  284. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  285. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  286. /package/dist/web/standalone/.next/static/{Wop3A7KRGyR06H3rla_1- → q0WYuDVbHeFFYbdd-fei2}/_buildManifest.js +0 -0
  287. /package/dist/web/standalone/.next/static/{Wop3A7KRGyR06H3rla_1- → q0WYuDVbHeFFYbdd-fei2}/_ssgManifest.js +0 -0
@@ -16,6 +16,7 @@ import type { RoadmapSliceEntry } from "./types.js";
16
16
  import { checkGitHealth, checkRuntimeHealth, checkGlobalHealth, checkEngineHealth } from "./doctor-checks.js";
17
17
  import { checkEnvironmentHealth } from "./doctor-environment.js";
18
18
  import { runProviderChecks } from "./doctor-providers.js";
19
+ import { validateTitle } from "./validation.js";
19
20
 
20
21
  // ── Re-exports ─────────────────────────────────────────────────────────────
21
22
  // All public types and functions from extracted modules are re-exported here
@@ -25,33 +26,7 @@ export { summarizeDoctorIssues, filterDoctorIssues, formatDoctorReport, formatDo
25
26
  export { runEnvironmentChecks, runFullEnvironmentChecks, formatEnvironmentReport, type EnvironmentCheckResult } from "./doctor-environment.js";
26
27
  export { computeProgressScore, computeProgressScoreWithContext, formatProgressLine, formatProgressReport, type ProgressScore, type ProgressLevel } from "./progress-score.js";
27
28
 
28
- /**
29
- * Characters that are used as delimiters in GSD state management documents
30
- * and should not appear in milestone or slice titles.
31
- *
32
- * - "\u2014" (em dash, U+2014): used as a display separator in STATE.md and other docs.
33
- * A title containing "\u2014" makes the separator ambiguous, corrupting state display
34
- * and confusing the LLM agent that reads and writes these files.
35
- * - "\u2013" (en dash, U+2013): visually similar to em dash; same ambiguity risk.
36
- * - "/" (forward slash, U+002F): used as the path separator in unit IDs (M001/S01)
37
- * and git branch names (gsd/M001/S01). A slash in a title can break path resolution.
38
- */
39
- const TITLE_DELIMITER_RE = /[\u2014\u2013\/]/; // em dash, en dash, forward slash
40
-
41
- /**
42
- * Check whether a milestone or slice title contains characters that conflict
43
- * with GSD's state document delimiter conventions.
44
- * Returns a human-readable description of the problem, or null if the title is safe.
45
- */
46
- export function validateTitle(title: string): string | null {
47
- if (TITLE_DELIMITER_RE.test(title)) {
48
- const found: string[] = [];
49
- if (/[\u2014\u2013]/.test(title)) found.push("em/en dash (\u2014 or \u2013)");
50
- if (/\//.test(title)) found.push("forward slash (/)");
51
- return `title contains ${found.join(" and ")}, which conflict with GSD state document delimiters`;
52
- }
53
- return null;
54
- }
29
+ export { validateTitle } from "./validation.js";
55
30
 
56
31
  function validatePreferenceShape(preferences: GSDPreferences): string[] {
57
32
  const issues: string[] = [];
@@ -26,6 +26,7 @@ import type {
26
26
  VisualizerSlice,
27
27
  } from './visualizer-data.js';
28
28
  import { formatDateShort, formatDuration } from '../shared/format-utils.js';
29
+ import { esc, renderHtmlShell } from '../shared/html-shell.js';
29
30
  import { formatCost, formatTokenCount } from './metrics.js';
30
31
  import type { UnitMetrics } from './metrics.js';
31
32
 
@@ -60,71 +61,37 @@ export function generateHtmlReport(
60
61
  buildDiscussionSection(data),
61
62
  ];
62
63
 
63
- const milestoneTag = opts.milestoneId
64
- ? ` <span class="sep">/</span> <span class="mono accent">${esc(opts.milestoneId)}</span>`
65
- : '';
64
+ const title = opts.milestoneId ? `${opts.projectName} / ${opts.milestoneId}` : opts.projectName;
66
65
 
67
66
  const backLink = opts.indexRelPath
68
67
  ? `<a class="back-link" href="${esc(opts.indexRelPath)}">All Reports</a>`
69
68
  : '';
70
69
 
71
- return `<!DOCTYPE html>
72
- <html lang="en">
73
- <head>
74
- <meta charset="UTF-8">
75
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
76
- <title>GSD Report — ${esc(opts.projectName)}${opts.milestoneId ? ` — ${esc(opts.milestoneId)}` : ''}</title>
77
- <style>${CSS}</style>
78
- </head>
79
- <body>
80
- <header>
81
- <div class="header-inner">
82
- <div class="branding">
83
- <span class="logo">GSD</span>
84
- <span class="version">v${esc(opts.gsdVersion)}</span>
85
- </div>
86
- <div class="header-meta">
87
- <h1>${esc(opts.projectName)}${milestoneTag}</h1>
88
- <span class="header-path">${esc(opts.projectPath)}</span>
89
- </div>
90
- <div class="header-right">
91
- ${backLink}
92
- <div class="generated">${formatDateLong(generated)}</div>
93
- </div>
94
- </div>
95
- </header>
96
- <nav class="toc" aria-label="Report sections">
97
- <ul>
98
- <li><a href="#summary">Summary</a></li>
99
- <li><a href="#blockers">Blockers</a></li>
100
- <li><a href="#progress">Progress</a></li>
101
- <li><a href="#timeline">Timeline</a></li>
102
- <li><a href="#depgraph">Dependencies</a></li>
103
- <li><a href="#metrics">Metrics</a></li>
104
- <li><a href="#health">Health</a></li>
105
- <li><a href="#changelog">Changelog</a></li>
106
- <li><a href="#knowledge">Knowledge</a></li>
107
- <li><a href="#captures">Captures</a></li>
108
- <li><a href="#stats">Artifacts</a></li>
109
- <li><a href="#discussion">Planning</a></li>
110
- </ul>
111
- </nav>
112
- <main>
113
- ${sections.join('\n')}
114
- </main>
115
- <footer>
116
- <div class="footer-inner">
117
- <span>GSD v${esc(opts.gsdVersion)}</span>
118
- <span class="sep">/</span>
119
- <span>${esc(opts.projectName)}</span>
120
- ${opts.milestoneId ? `<span class="sep">/</span><span class="mono">${esc(opts.milestoneId)}</span>` : ''}
121
- <span class="sep">/</span>
122
- <span>${formatDateLong(generated)}</span>
123
- </div>
124
- </footer>
125
- <script>${JS}</script>
126
- </body>
127
- </html>`;
70
+ return renderHtmlShell({
71
+ title,
72
+ documentTitle: `GSD Report — ${opts.projectName}${opts.milestoneId ? ` — ${opts.milestoneId}` : ''}`,
73
+ subtitle: opts.projectPath,
74
+ kind: 'Report',
75
+ version: opts.gsdVersion,
76
+ generatedAt: generated,
77
+ headerActionsHtml: backLink,
78
+ footerNote: opts.milestoneId ? `${opts.projectName} / ${opts.milestoneId}` : opts.projectName,
79
+ toc: [
80
+ { href: '#summary', label: 'Summary' },
81
+ { href: '#blockers', label: 'Blockers' },
82
+ { href: '#progress', label: 'Progress' },
83
+ { href: '#timeline', label: 'Timeline' },
84
+ { href: '#depgraph', label: 'Dependencies' },
85
+ { href: '#metrics', label: 'Metrics' },
86
+ { href: '#health', label: 'Health' },
87
+ { href: '#changelog', label: 'Changelog' },
88
+ { href: '#knowledge', label: 'Knowledge' },
89
+ { href: '#captures', label: 'Captures' },
90
+ { href: '#stats', label: 'Artifacts' },
91
+ { href: '#discussion', label: 'Planning' },
92
+ ],
93
+ mainHtml: sections.join('\n'),
94
+ });
128
95
  }
129
96
 
130
97
  // ─── Section: Summary ─────────────────────────────────────────────────────────
@@ -1039,370 +1006,3 @@ function hRow(label: string, value: string, status?: 'ok' | 'caution' | 'warn'):
1039
1006
  function shortModel(m: string) { return m.replace(/^claude-/, '').replace(/^anthropic\//, ''); }
1040
1007
  function truncStr(s: string, n: number) { return s.length > n ? s.slice(0, n - 1) + '\u2026' : s; }
1041
1008
 
1042
- function formatDateLong(iso: string): string {
1043
- try {
1044
- const d = new Date(iso);
1045
- return d.toLocaleString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', timeZoneName: 'short' });
1046
- } catch { return iso; }
1047
- }
1048
-
1049
-
1050
- function esc(s: string | undefined | null): string {
1051
- if (s == null) return '';
1052
- return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
1053
- }
1054
-
1055
- // ─── CSS ───────────────────────────────────────────────────────────────────────
1056
- // Linear-inspired: restrained palette, one accent, no emoji, no gradients.
1057
-
1058
- const CSS = `
1059
- *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
1060
- :root{
1061
- --bg-0:#0f1115;--bg-1:#16181d;--bg-2:#1e2028;--bg-3:#272a33;
1062
- --border-1:#2b2e38;--border-2:#3b3f4c;
1063
- --text-0:#ededef;--text-1:#a1a1aa;--text-2:#71717a;
1064
- --accent:#5e6ad2;--accent-subtle:rgba(94,106,210,.12);
1065
- --ok:#22c55e;--ok-subtle:rgba(34,197,94,.12);--warn:#ef4444;--caution:#eab308;
1066
- /* Chart palette — 6 hues for bar charts */
1067
- --c0:#5e6ad2;--c1:#e5796d;--c2:#14b8a6;--c3:#a78bfa;--c4:#f59e0b;--c5:#10b981;
1068
- /* Token breakdown — 4 distinct hues */
1069
- --tk-input:#5e6ad2;--tk-output:#e5796d;--tk-cache-r:#2dd4bf;--tk-cache-w:#64748b;
1070
- --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
1071
- --mono:'JetBrains Mono','Fira Code',ui-monospace,SFMono-Regular,monospace;
1072
- }
1073
- html{scroll-behavior:smooth;font-size:13px}
1074
- body{background:var(--bg-0);color:var(--text-0);font-family:var(--font);line-height:1.6;-webkit-font-smoothing:antialiased}
1075
- a{color:var(--accent);text-decoration:none}
1076
- a:hover{text-decoration:underline}
1077
- code{font-family:var(--mono);font-size:12px;background:var(--bg-3);padding:1px 5px;border-radius:3px}
1078
- .mono{font-family:var(--mono);font-size:12px}
1079
- .muted{color:var(--text-2)}
1080
- .accent{color:var(--accent)}
1081
- .sep{color:var(--border-2);margin:0 4px}
1082
- .empty{color:var(--text-2);padding:8px 0;font-size:13px}
1083
- .indent{padding-left:12px}
1084
- .num{font-variant-numeric:tabular-nums;text-align:right}
1085
-
1086
- /* Status dots — geometric, no emoji */
1087
- .dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0;vertical-align:middle}
1088
- .dot-sm{width:6px;height:6px}
1089
- .dot-complete{background:var(--ok);opacity:.6}
1090
- .dot-active{background:var(--accent)}
1091
- .dot-pending{background:transparent;border:1.5px solid var(--border-2)}
1092
- .dot-parked{background:var(--warn);opacity:.5}
1093
-
1094
- /* Header */
1095
- header{background:var(--bg-1);border-bottom:1px solid var(--border-1);padding:12px 32px;position:sticky;top:0;z-index:200}
1096
- .header-inner{display:flex;align-items:center;gap:16px;max-width:1280px;margin:0 auto}
1097
- .branding{display:flex;align-items:baseline;gap:6px;flex-shrink:0}
1098
- .logo{font-size:18px;font-weight:800;letter-spacing:-.5px;color:var(--text-0)}
1099
- .version{font-size:10px;color:var(--text-2);font-family:var(--mono)}
1100
- .header-meta{flex:1;min-width:0}
1101
- .header-meta h1{font-size:15px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
1102
- .header-path{font-size:11px;color:var(--text-2);font-family:var(--mono);display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1103
- .header-right{text-align:right;flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:4px}
1104
- .generated{font-size:11px;color:var(--text-2)}
1105
- .back-link{font-size:12px;color:var(--text-1)}
1106
- .back-link:hover{color:var(--accent)}
1107
-
1108
- /* TOC nav */
1109
- .toc{background:var(--bg-1);border-bottom:1px solid var(--border-1);overflow-x:auto}
1110
- .toc ul{display:flex;list-style:none;max-width:1280px;margin:0 auto;padding:0 32px}
1111
- .toc a{display:inline-block;padding:8px 12px;color:var(--text-2);font-size:12px;font-weight:500;border-bottom:2px solid transparent;transition:color .12s,border-color .12s;white-space:nowrap;text-decoration:none}
1112
- .toc a:hover{color:var(--text-0);border-bottom-color:var(--border-2)}
1113
- .toc a.active{color:var(--text-0);border-bottom-color:var(--accent)}
1114
-
1115
- /* Layout */
1116
- main{max-width:1280px;margin:0 auto;padding:32px;display:flex;flex-direction:column;gap:48px}
1117
- section{scroll-margin-top:82px}
1118
- section>h2{font-size:14px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-1);margin-bottom:16px;padding-bottom:8px;border-bottom:1px solid var(--border-1);display:flex;align-items:center;gap:8px}
1119
- h3{font-size:13px;font-weight:600;color:var(--text-1);margin:20px 0 8px}
1120
- .count{font-size:11px;font-weight:500;color:var(--text-2);background:var(--bg-3);border-radius:3px;padding:1px 6px}
1121
- .count-warn{color:var(--caution)}
1122
-
1123
- /* KV grid (stats/metrics) */
1124
- .kv-grid{display:flex;flex-wrap:wrap;gap:1px;background:var(--border-1);border:1px solid var(--border-1);border-radius:4px;overflow:hidden;margin-bottom:16px}
1125
- .kv{background:var(--bg-1);padding:10px 16px;display:flex;flex-direction:column;gap:2px;min-width:110px;flex:1}
1126
- .kv-val{font-size:18px;font-weight:600;color:var(--text-0);font-variant-numeric:tabular-nums}
1127
- .kv-lbl{font-size:10px;color:var(--text-2);text-transform:uppercase;letter-spacing:.4px}
1128
-
1129
- /* Progress bar */
1130
- .progress-wrap{display:flex;align-items:center;gap:10px;margin-bottom:12px}
1131
- .progress-track{flex:1;height:4px;background:var(--bg-3);border-radius:2px;overflow:hidden}
1132
- .progress-fill{height:100%;background:var(--accent);border-radius:2px}
1133
- .progress-label{font-size:12px;font-weight:600;color:var(--text-1);min-width:40px;text-align:right}
1134
- .active-info{font-size:12px;color:var(--text-1);margin-bottom:4px}
1135
- .activity-line{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-1);padding:6px 0}
1136
-
1137
- /* Tables */
1138
- .tbl{width:100%;border-collapse:collapse;font-size:12px}
1139
- .tbl th{color:var(--text-2);font-weight:500;padding:6px 12px;text-align:left;border-bottom:1px solid var(--border-1);font-size:11px;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap}
1140
- .tbl td{padding:6px 12px;border-bottom:1px solid var(--border-1);vertical-align:top}
1141
- .tbl tr:last-child td{border-bottom:none}
1142
- .tbl tbody tr:hover td{background:var(--accent-subtle)}
1143
- .tbl-kv td:first-child{color:var(--text-2);width:180px}
1144
- .table-scroll{overflow-x:auto;border:1px solid var(--border-1);border-radius:4px}
1145
- .table-scroll .tbl{border:none}
1146
-
1147
- /* Health */
1148
- .h-ok td:first-child{color:var(--text-1)}
1149
- .h-caution td{color:var(--caution)}
1150
- .h-warn td{color:var(--warn)}
1151
-
1152
- /* Labels */
1153
- .label{font-size:10px;font-weight:500;color:var(--accent);text-transform:uppercase;letter-spacing:.4px}
1154
- .risk{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0}
1155
- .risk-low{color:var(--text-2)}
1156
- .risk-medium{color:var(--caution)}
1157
- .risk-high{color:var(--warn)}
1158
- .risk-unknown{color:var(--text-2)}
1159
-
1160
- /* Tags */
1161
- .tag-row{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px}
1162
- .tag{font-size:11px;font-family:var(--mono);color:var(--text-2);background:var(--bg-3);border-radius:3px;padding:1px 6px}
1163
-
1164
- /* Verification */
1165
- .verif{font-size:12px;color:var(--text-1);padding:4px 0;margin-bottom:6px}
1166
- .verif-blocker{color:var(--warn)}
1167
-
1168
- /* Detail blocks */
1169
- .detail-block{font-size:12px;color:var(--text-2);margin-bottom:6px}
1170
- .detail-label{font-weight:600;color:var(--text-1);display:block;margin-bottom:2px}
1171
- .detail-block ul{padding-left:16px;margin-top:2px}
1172
- .detail-block li{margin-bottom:1px}
1173
-
1174
- /* Progress tree */
1175
- .ms-block{border:1px solid var(--border-1);border-radius:4px;overflow:hidden;margin-bottom:8px}
1176
- .ms-summary{display:flex;align-items:center;gap:8px;padding:10px 14px;cursor:pointer;list-style:none;background:var(--bg-1);user-select:none;font-size:13px}
1177
- .ms-summary:hover{background:var(--bg-2)}
1178
- .ms-summary::-webkit-details-marker{display:none}
1179
- .ms-id{font-weight:600}
1180
- .ms-title{flex:1;font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1181
- .ms-body{padding:6px 12px 8px 24px;display:flex;flex-direction:column;gap:4px}
1182
-
1183
- .sl-block{border:1px solid var(--border-1);border-radius:3px;overflow:hidden}
1184
- .sl-summary{display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;list-style:none;background:var(--bg-2);font-size:12px;user-select:none}
1185
- .sl-summary:hover{background:var(--bg-3)}
1186
- .sl-summary::-webkit-details-marker{display:none}
1187
- .sl-crit{border-left:2px solid var(--accent)}
1188
- .sl-deps::before{content:'\\2190 ';color:var(--border-2)}
1189
- .sl-detail{padding:8px 12px;background:var(--bg-0);border-top:1px solid var(--border-1)}
1190
-
1191
- .task-list{list-style:none;padding:4px 0 0;display:flex;flex-direction:column;gap:2px}
1192
- .task-row{display:flex;align-items:center;gap:6px;font-size:12px;padding:3px 6px;border-radius:2px}
1193
-
1194
- /* Dep graph */
1195
- .dep-block{margin-bottom:28px}
1196
- .dep-legend{display:flex;gap:14px;font-size:12px;color:var(--text-2);margin-bottom:8px;align-items:center}
1197
- .dep-legend span{display:flex;align-items:center;gap:4px}
1198
- .dep-wrap{overflow-x:auto;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:16px}
1199
- .dep-svg{display:block}
1200
- .edge{fill:none;stroke:var(--border-2);stroke-width:1.5}
1201
- .edge-crit{stroke:var(--accent);stroke-width:2}
1202
- .node rect{fill:var(--bg-2);stroke:var(--border-2);stroke-width:1}
1203
- .n-done rect{fill:var(--ok-subtle);stroke:rgba(34,197,94,.4)}
1204
- .n-active rect{fill:var(--accent-subtle);stroke:var(--accent)}
1205
- .n-crit rect{stroke:var(--accent)!important;stroke-width:1.5!important}
1206
- .n-id{font-family:var(--mono);font-size:10px;fill:var(--text-1);font-weight:600;text-anchor:middle}
1207
- .n-title{font-size:9px;fill:var(--text-2);text-anchor:middle}
1208
- .n-active .n-id{fill:var(--accent)}
1209
-
1210
- /* Metrics */
1211
- .token-block{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px;margin-bottom:16px}
1212
- .token-bar{display:flex;height:16px;border-radius:2px;overflow:hidden;gap:1px;margin-bottom:8px}
1213
- .tseg{height:100%;min-width:2px}
1214
- .seg-1{background:var(--tk-input)}
1215
- .seg-2{background:var(--tk-output)}
1216
- .seg-3{background:var(--tk-cache-r)}
1217
- .seg-4{background:var(--tk-cache-w)}
1218
- .token-legend{display:flex;flex-wrap:wrap;gap:12px}
1219
- .leg-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-2)}
1220
- .leg-dot{width:8px;height:8px;border-radius:2px;flex-shrink:0}
1221
- .chart-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;margin-bottom:16px}
1222
- .chart-block{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px}
1223
- .bar-row{display:grid;grid-template-columns:120px 1fr 68px;align-items:center;gap:6px;margin-bottom:2px}
1224
- .bar-lbl{font-size:12px;color:var(--text-2);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1225
- .bar-track{height:14px;background:var(--bg-3);border-radius:2px;overflow:hidden}
1226
- .bar-fill{height:100%;border-radius:2px;background:var(--c0)}
1227
- .bar-c0{background:var(--c0)}.bar-c1{background:var(--c1)}.bar-c2{background:var(--c2)}
1228
- .bar-c3{background:var(--c3)}.bar-c4{background:var(--c4)}.bar-c5{background:var(--c5)}
1229
- .bar-val{font-size:11px;font-variant-numeric:tabular-nums;color:var(--text-1)}
1230
- .bar-sub{font-size:10px;color:var(--text-2);padding-left:128px;margin-bottom:6px}
1231
-
1232
- /* Changelog */
1233
- .cl-entry{border-bottom:1px solid var(--border-1);padding:12px 0}
1234
- .cl-entry:last-child{border-bottom:none}
1235
- .cl-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}
1236
- .cl-title{flex:1;font-weight:500}
1237
- .cl-date{margin-left:auto;white-space:nowrap}
1238
- .cl-liner{font-size:13px;color:var(--text-1);margin-bottom:6px}
1239
- .files-detail summary{font-size:12px;cursor:pointer}
1240
- .file-list{list-style:none;padding-left:10px;margin-top:4px;display:flex;flex-direction:column;gap:2px}
1241
- .file-list li{font-size:12px;color:var(--text-1)}
1242
-
1243
- /* Footer */
1244
- footer{border-top:1px solid var(--border-1);padding:20px 32px;margin-top:40px}
1245
- .footer-inner{display:flex;align-items:center;gap:6px;justify-content:center;font-size:11px;color:var(--text-2)}
1246
-
1247
- /* Executive summary & ETA */
1248
- .exec-summary{font-size:13px;color:var(--text-1);margin-bottom:12px;line-height:1.7}
1249
- .eta-line{font-size:12px;color:var(--accent);margin-top:4px}
1250
-
1251
- /* Cost over time chart */
1252
- .cost-svg{display:block;margin:8px 0;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px}
1253
- .cost-line{fill:none;stroke:var(--accent);stroke-width:2}
1254
- .cost-area{fill:var(--accent-subtle);stroke:none}
1255
- .cost-axis{fill:var(--text-2);font-family:var(--mono);font-size:10px}
1256
- .cost-grid{stroke:var(--border-1);stroke-width:1;stroke-dasharray:4,4}
1257
-
1258
- /* Budget burndown */
1259
- .burndown-wrap{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px;margin-bottom:16px}
1260
- .burndown-bar{display:flex;height:20px;border-radius:3px;overflow:hidden;gap:1px;margin-bottom:8px}
1261
- .burndown-spent{background:var(--accent);height:100%}
1262
- .burndown-projected{background:var(--caution);height:100%;opacity:.6}
1263
- .burndown-overshoot{background:var(--warn);height:100%;opacity:.7}
1264
- .burndown-legend{display:flex;flex-wrap:wrap;gap:12px;font-size:11px;color:var(--text-2)}
1265
- .burndown-legend span{display:flex;align-items:center;gap:4px}
1266
- .burndown-dot{display:inline-block;width:8px;height:8px;border-radius:2px}
1267
-
1268
- /* Blockers */
1269
- .blocker-card{border-left:3px solid var(--warn);background:var(--bg-1);border-radius:0 4px 4px 0;padding:10px 14px;margin-bottom:8px}
1270
- .blocker-id{font-family:var(--mono);font-size:12px;color:var(--warn);margin-bottom:2px}
1271
- .blocker-text{font-size:12px;color:var(--text-1)}
1272
- .blocker-risk{font-size:11px;color:var(--caution);margin-top:2px}
1273
-
1274
- /* Gantt */
1275
- .gantt-wrap{overflow-x:auto;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:16px;margin-top:16px}
1276
- .gantt-svg{display:block}
1277
- .gantt-bar-done{fill:var(--ok);opacity:.7}
1278
- .gantt-bar-active{fill:var(--accent)}
1279
- .gantt-bar-pending{fill:var(--border-2)}
1280
- .gantt-label{fill:var(--text-2);font-family:var(--mono);font-size:10px}
1281
- .gantt-axis{fill:var(--text-2);font-family:var(--mono);font-size:9px}
1282
-
1283
- /* Interactive */
1284
- .tl-filter{display:block;width:100%;padding:6px 10px;margin-bottom:8px;background:var(--bg-2);border:1px solid var(--border-1);border-radius:4px;color:var(--text-0);font-size:12px;font-family:var(--font);outline:none}
1285
- .tl-filter:focus{border-color:var(--accent)}
1286
- .tl-filter::placeholder{color:var(--text-2)}
1287
- .sec-toggle{background:none;border:1px solid var(--border-2);color:var(--text-2);width:20px;height:20px;border-radius:3px;cursor:pointer;font-size:14px;line-height:1;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}
1288
- .sec-toggle:hover{border-color:var(--text-1);color:var(--text-1)}
1289
- .theme-toggle{background:var(--bg-3);border:1px solid var(--border-2);color:var(--text-1);padding:4px 10px;border-radius:4px;cursor:pointer;font-size:11px;font-family:var(--font)}
1290
- .theme-toggle:hover{border-color:var(--accent);color:var(--accent)}
1291
-
1292
- /* Light theme */
1293
- .light-theme{--bg-0:#fff;--bg-1:#fafafa;--bg-2:#f5f5f5;--bg-3:#ebebeb;--border-1:#e5e5e5;--border-2:#d4d4d4;--text-0:#1a1a1a;--text-1:#525252;--text-2:#a3a3a3;--accent:#4f46e5;--accent-subtle:rgba(79,70,229,.08);--ok:#16a34a;--ok-subtle:rgba(22,163,74,.08);--warn:#dc2626;--caution:#ca8a04;--c0:#4f46e5;--c1:#dc2626;--c2:#0d9488;--c3:#7c3aed;--c4:#d97706;--c5:#059669;--tk-input:#4f46e5;--tk-output:#dc2626;--tk-cache-r:#0d9488;--tk-cache-w:#64748b}
1294
-
1295
- /* Responsive */
1296
- @media(max-width:768px){
1297
- header{padding:10px 16px}
1298
- .header-inner{flex-wrap:wrap;gap:8px}
1299
- .header-meta h1{font-size:13px}
1300
- main{padding:16px}
1301
- .kv-grid{gap:1px}
1302
- .kv{min-width:80px;padding:8px 10px}
1303
- .kv-val{font-size:14px}
1304
- .chart-row{grid-template-columns:1fr}
1305
- .toc ul{padding:0 16px}
1306
- .toc a{padding:6px 8px;font-size:11px}
1307
- .bar-row{grid-template-columns:80px 1fr 56px}
1308
- .ms-body{padding-left:12px}
1309
- }
1310
- @media(max-width:480px){
1311
- .kv{min-width:60px;padding:6px 8px}
1312
- .kv-val{font-size:12px}
1313
- .kv-lbl{font-size:9px}
1314
- .bar-row{grid-template-columns:60px 1fr 48px}
1315
- .bar-lbl{font-size:10px}
1316
- .toc ul{flex-wrap:wrap}
1317
- .header-right{display:none}
1318
- .gantt-wrap{overflow-x:auto}
1319
- }
1320
-
1321
- /* Print */
1322
- @media print{
1323
- header,nav.toc{position:static}
1324
- body{background:#fff;color:#1a1a1a}
1325
- :root{--bg-0:#fff;--bg-1:#fafafa;--bg-2:#f5f5f5;--bg-3:#ebebeb;--border-1:#e5e5e5;--border-2:#d4d4d4;--text-0:#1a1a1a;--text-1:#525252;--text-2:#a3a3a3;--accent:#4f46e5;--ok:#16a34a;--ok-subtle:rgba(22,163,74,.08);--c0:#4f46e5;--c1:#dc2626;--c2:#0d9488;--c3:#7c3aed;--c4:#d97706;--c5:#059669;--tk-input:#4f46e5;--tk-output:#dc2626;--tk-cache-r:#0d9488;--tk-cache-w:#64748b}
1326
- section{page-break-inside:avoid}
1327
- .table-scroll{overflow:visible}
1328
- }
1329
- `;
1330
-
1331
- // ─── JS ────────────────────────────────────────────────────────────────────────
1332
-
1333
- const JS = `
1334
- (function(){
1335
- const sections=document.querySelectorAll('section[id]');
1336
- const links=document.querySelectorAll('.toc a');
1337
- if(!sections.length||!links.length)return;
1338
- const obs=new IntersectionObserver(entries=>{
1339
- for(const e of entries){
1340
- if(!e.isIntersecting)continue;
1341
- for(const l of links)l.classList.remove('active');
1342
- const a=document.querySelector('.toc a[href="#'+e.target.id+'"]');
1343
- if(a)a.classList.add('active');
1344
- }
1345
- },{rootMargin:'-10% 0px -80% 0px',threshold:0});
1346
- for(const s of sections)obs.observe(s);
1347
- })();
1348
- (function(){
1349
- var tl=document.getElementById('timeline');
1350
- if(!tl)return;
1351
- var table=tl.querySelector('.tbl');
1352
- if(!table)return;
1353
- var input=document.createElement('input');
1354
- input.className='tl-filter';
1355
- input.placeholder='Filter timeline\\u2026';
1356
- input.type='text';
1357
- table.parentNode.insertBefore(input,table);
1358
- var rows=table.querySelectorAll('tbody tr');
1359
- input.addEventListener('input',function(){
1360
- var q=this.value.toLowerCase();
1361
- for(var i=0;i<rows.length;i++){
1362
- rows[i].style.display=rows[i].textContent.toLowerCase().indexOf(q)>-1?'':'none';
1363
- }
1364
- });
1365
- })();
1366
- (function(){
1367
- var saved=JSON.parse(localStorage.getItem('gsd-collapsed')||'{}');
1368
- document.querySelectorAll('section[id]').forEach(function(sec){
1369
- var h2=sec.querySelector('h2');
1370
- if(!h2)return;
1371
- var btn=document.createElement('button');
1372
- btn.className='sec-toggle';
1373
- btn.textContent=saved[sec.id]?'+':'-';
1374
- btn.setAttribute('aria-label','Toggle section');
1375
- h2.prepend(btn);
1376
- if(saved[sec.id])toggleSection(sec,true);
1377
- btn.addEventListener('click',function(e){
1378
- e.preventDefault();
1379
- var collapsed=btn.textContent==='-';
1380
- toggleSection(sec,collapsed);
1381
- btn.textContent=collapsed?'+':'-';
1382
- saved[sec.id]=collapsed;
1383
- localStorage.setItem('gsd-collapsed',JSON.stringify(saved));
1384
- });
1385
- });
1386
- function toggleSection(sec,hide){
1387
- var children=sec.children;
1388
- for(var i=0;i<children.length;i++){
1389
- if(children[i].tagName!=='H2')children[i].style.display=hide?'none':'';
1390
- }
1391
- }
1392
- })();
1393
- (function(){
1394
- var hr=document.querySelector('.header-right');
1395
- if(!hr)return;
1396
- var btn=document.createElement('button');
1397
- btn.className='theme-toggle';
1398
- btn.textContent=localStorage.getItem('gsd-theme')==='light'?'Dark':'Light';
1399
- if(localStorage.getItem('gsd-theme')==='light')document.documentElement.classList.add('light-theme');
1400
- btn.addEventListener('click',function(){
1401
- document.documentElement.classList.toggle('light-theme');
1402
- var isLight=document.documentElement.classList.contains('light-theme');
1403
- btn.textContent=isLight?'Dark':'Light';
1404
- localStorage.setItem('gsd-theme',isLight?'light':'dark');
1405
- });
1406
- hr.prepend(btn);
1407
- })();
1408
- `;
@@ -270,6 +270,30 @@ function isExcludedScopedPath(path: string, exclusions: readonly string[]): bool
270
270
  return false;
271
271
  }
272
272
 
273
+ function submodulePathsFromLsFiles(output: string): Set<string> {
274
+ const submodulePaths = new Set<string>();
275
+ if (!output) return submodulePaths;
276
+
277
+ for (const line of output.split("\n")) {
278
+ const match = line.match(/^160000\s+\S+\s+\d+\t(.+)$/);
279
+ if (!match) continue;
280
+ submodulePaths.add(match[1].replace(/\\/g, "/").replace(/\/+$/, ""));
281
+ }
282
+ return submodulePaths;
283
+ }
284
+
285
+ function isInsideSubmodule(path: string, submodulePaths: ReadonlySet<string>): boolean {
286
+ const normalizedPath = path.replace(/\\/g, "/");
287
+ if (submodulePaths.has(normalizedPath)) return true;
288
+
289
+ let slashIndex = normalizedPath.lastIndexOf("/");
290
+ while (slashIndex > 0) {
291
+ if (submodulePaths.has(normalizedPath.slice(0, slashIndex))) return true;
292
+ slashIndex = normalizedPath.lastIndexOf("/", slashIndex - 1);
293
+ }
294
+ return false;
295
+ }
296
+
273
297
  /**
274
298
  * Thrown when a slice merge hits code conflicts in non-.gsd files.
275
299
  * The working tree is left in a conflicted state (no reset) so the
@@ -764,6 +788,26 @@ export class GitServiceImpl {
764
788
  .filter(file => !nativeIsIgnored(this.basePath, file))
765
789
  .filter(file => !isExcludedScopedPath(file, allExclusions));
766
790
 
791
+ const scopedPaths: string[] = [];
792
+ const submodulePaths: string[] = [];
793
+ const repoSubmodules = submodulePathsFromLsFiles(
794
+ runGit(this.basePath, ["ls-files", "--stage"], { allowFailure: true }),
795
+ );
796
+ for (const path of normalized) {
797
+ if (isInsideSubmodule(path, repoSubmodules)) {
798
+ submodulePaths.push(path);
799
+ } else {
800
+ scopedPaths.push(path);
801
+ }
802
+ }
803
+ if (submodulePaths.length > 0) {
804
+ logWarning(
805
+ "engine",
806
+ `scoped stage: dropping ${submodulePaths.length} keyFile(s) inside git submodule(s): ${submodulePaths.join(", ")}`,
807
+ { file: "git-service.ts" },
808
+ );
809
+ }
810
+
767
811
  // Drop entries that don't exist on disk. The LLM occasionally lists files
768
812
  // it intended to write but didn't (or names them with wrong casing/path).
769
813
  // Pre-`b304f738b` `git add -A` swallowed these silently; the scoped
@@ -771,7 +815,7 @@ export class GitServiceImpl {
771
815
  // the whole commit fail (see #5500). Filter so valid paths still commit.
772
816
  const missing: string[] = [];
773
817
  const existing: string[] = [];
774
- for (const path of normalized) {
818
+ for (const path of scopedPaths) {
775
819
  if (existsSync(join(this.basePath, path))) {
776
820
  existing.push(path);
777
821
  } else {
@@ -2081,6 +2081,9 @@ export function deleteTask(milestoneId: string, sliceId: string, taskId: string)
2081
2081
  currentDb!.prepare(
2082
2082
  `DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`,
2083
2083
  ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2084
+ currentDb!.prepare(
2085
+ `DELETE FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`,
2086
+ ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
2084
2087
  currentDb!.prepare(
2085
2088
  `DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`,
2086
2089
  ).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
@@ -1539,6 +1539,7 @@ export async function showDiscuss(
1539
1539
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1540
1540
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1541
1541
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1542
+ workingDirectory: basePath,
1542
1543
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1543
1544
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1544
1545
  fastPathInstruction: "",
@@ -1553,6 +1554,7 @@ export async function showDiscuss(
1553
1554
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1554
1555
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: mid, step: false });
1555
1556
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
1557
+ workingDirectory: basePath,
1556
1558
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1557
1559
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1558
1560
  fastPathInstruction: "",
@@ -1822,6 +1824,7 @@ async function dispatchDiscussForMilestone(
1822
1824
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1823
1825
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1824
1826
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1827
+ workingDirectory: basePath,
1825
1828
  milestoneId: mid,
1826
1829
  milestoneTitle,
1827
1830
  inlinedTemplates: discussMilestoneTemplates,
@@ -2356,6 +2359,7 @@ export async function showSmartEntry(
2356
2359
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2357
2360
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2358
2361
  const basePrompt = loadPrompt("guided-discuss-milestone", {
2362
+ workingDirectory: basePath,
2359
2363
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2360
2364
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2361
2365
  fastPathInstruction: "",
@@ -2370,6 +2374,7 @@ export async function showSmartEntry(
2370
2374
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2371
2375
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId, step: stepMode });
2372
2376
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
2377
+ workingDirectory: basePath,
2373
2378
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2374
2379
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2375
2380
  fastPathInstruction: "",
@@ -2462,6 +2467,7 @@ export async function showSmartEntry(
2462
2467
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2463
2468
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2464
2469
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
2470
+ workingDirectory: basePath,
2465
2471
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2466
2472
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2467
2473
  fastPathInstruction: "",
@@ -95,6 +95,17 @@ function parsePhaseEntry(line: string): PlanningRoadmapEntry | null {
95
95
  };
96
96
  }
97
97
 
98
+ // Format 3: - ✅ v1.0 MVP — Phases 1-6
99
+ const fmtVersionPhases = stripped.match(/^-\s+([✅🚧])\s+v\d+(?:\.\d+)*\s+(.+?)\s*[—–]\s*Phases?\s+(\d+(?:\.\d+)?)(?:\s*-\s*\d+(?:\.\d+)?)?(?:\s+\(.*\))?\s*$/iu);
100
+ if (fmtVersionPhases) {
101
+ return {
102
+ number: parseFloat(fmtVersionPhases[3]),
103
+ title: fmtVersionPhases[2].trim(),
104
+ done: fmtVersionPhases[1] === '✅',
105
+ raw: line,
106
+ };
107
+ }
108
+
98
109
  return null;
99
110
  }
100
111