gsd-pi 2.82.0-dev.2841a1e44 → 2.82.0-dev.98ea09b1e

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 (277) hide show
  1. package/README.md +2 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +7 -0
  4. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  5. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  6. package/dist/resources/extensions/gsd/auto/loop.js +5 -5
  7. package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
  8. package/dist/resources/extensions/gsd/auto/phases.js +8 -1
  9. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
  11. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  12. package/dist/resources/extensions/gsd/auto-post-unit.js +70 -9
  13. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  14. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  15. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  16. package/dist/resources/extensions/gsd/auto.js +30 -3
  17. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -1
  18. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  19. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +5 -2
  20. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +13 -1
  21. package/dist/resources/extensions/gsd/commands/handlers/core.js +17 -1
  22. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  23. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  24. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  25. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  26. package/dist/resources/extensions/gsd/doctor.js +2 -28
  27. package/dist/resources/extensions/gsd/export-html.js +27 -425
  28. package/dist/resources/extensions/gsd/git-service.js +39 -1
  29. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  30. package/dist/resources/extensions/gsd/guided-flow.js +13 -6
  31. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  32. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  33. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  34. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  35. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  36. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  37. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  38. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  39. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  40. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  41. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  42. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  43. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  44. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  45. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  46. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  47. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  48. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  49. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  50. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  51. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  52. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  53. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  54. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  55. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  56. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  57. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  58. package/dist/resources/extensions/gsd/unit-context-manifest.js +7 -8
  59. package/dist/resources/extensions/gsd/validation.js +23 -1
  60. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  61. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  62. package/dist/resources/extensions/gsd/worktree-lifecycle.js +33 -8
  63. package/dist/resources/extensions/shared/html-shell.js +388 -0
  64. package/dist/resources/extensions/visual-brief/page-contract.js +2 -0
  65. package/dist/resources/extensions/visual-brief/prompts.js +29 -0
  66. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  67. package/dist/web/standalone/.next/BUILD_ID +1 -1
  68. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  69. package/dist/web/standalone/.next/build-manifest.json +3 -3
  70. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  71. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  81. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  91. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/index.html +1 -1
  93. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  94. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  96. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  98. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  99. package/dist/web/standalone/.next/server/app/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  101. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  103. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  104. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  107. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  108. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  109. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  110. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  111. package/dist/web/standalone/.next/static/chunks/{webpack-6a95bc41e0f7ec89.js → webpack-9a4db269f9ed63ad.js} +1 -1
  112. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  113. package/package.json +2 -2
  114. package/packages/mcp-server/src/workflow-tools.test.ts +1 -1
  115. package/packages/native/tsconfig.json +2 -1
  116. package/packages/native/tsconfig.tsbuildinfo +1 -1
  117. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  118. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  119. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  120. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  121. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  122. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  123. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  124. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  125. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  126. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  127. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  128. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  129. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  130. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  131. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  132. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  133. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  134. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  135. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  136. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  137. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  138. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  139. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  140. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  141. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  142. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  143. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  144. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  145. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  146. package/src/resources/GSD-WORKFLOW.md +7 -0
  147. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  148. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  149. package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
  150. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  151. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  152. package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
  153. package/src/resources/extensions/gsd/auto/phases.ts +7 -1
  154. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  155. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  156. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  157. package/src/resources/extensions/gsd/auto-post-unit.ts +77 -7
  158. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  159. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  160. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  161. package/src/resources/extensions/gsd/auto.ts +32 -3
  162. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +6 -1
  163. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  164. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +3 -1
  165. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +16 -1
  166. package/src/resources/extensions/gsd/commands/handlers/core.ts +17 -1
  167. package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
  168. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  169. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  170. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  171. package/src/resources/extensions/gsd/doctor.ts +2 -27
  172. package/src/resources/extensions/gsd/export-html.ts +27 -427
  173. package/src/resources/extensions/gsd/git-service.ts +45 -1
  174. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  175. package/src/resources/extensions/gsd/guided-flow.ts +14 -7
  176. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  177. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  178. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  179. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  180. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  181. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  182. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  183. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  184. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  185. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  186. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  187. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  188. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  189. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  190. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  191. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  192. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  193. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  194. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  195. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  196. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  197. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  198. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  199. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  200. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +54 -0
  201. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
  202. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -6
  203. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  204. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  205. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  206. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  207. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  208. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  209. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  210. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  211. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  212. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  213. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  214. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  215. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  216. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  217. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  218. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +6 -6
  219. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  220. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  221. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  222. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  223. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  224. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  225. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  226. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  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-prompt.test.ts +2 -0
  232. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  233. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  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/state-reconciliation-drift.test.ts +119 -23
  242. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  243. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  244. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +65 -7
  245. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  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 +38 -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 +12 -9
  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/workflow-projections.ts +6 -8
  261. package/src/resources/extensions/gsd/worktree-lifecycle.ts +41 -8
  262. package/src/resources/extensions/shared/html-shell.ts +412 -0
  263. package/src/resources/extensions/visual-brief/page-contract.ts +2 -0
  264. package/src/resources/extensions/visual-brief/prompts.ts +37 -1
  265. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +40 -0
  266. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  267. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  268. package/dist/web/standalone/.next/static/css/0262768ec1b89d34.css +0 -1
  269. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  270. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  271. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  272. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  273. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  274. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  275. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  276. /package/dist/web/standalone/.next/static/{Qgr2B_MRhPxC0z8fwv4vT → euQ0CLP_v8V4e76Tu3odJ}/_buildManifest.js +0 -0
  277. /package/dist/web/standalone/.next/static/{Qgr2B_MRhPxC0z8fwv4vT → euQ0CLP_v8V4e76Tu3odJ}/_ssgManifest.js +0 -0
@@ -20,6 +20,7 @@
20
20
  * Design: Linear-inspired — restrained palette, geometric status, no emoji.
21
21
  */
22
22
  import { formatDateShort, formatDuration } from '../shared/format-utils.js';
23
+ import { esc, renderHtmlShell } from '../shared/html-shell.js';
23
24
  import { formatCost, formatTokenCount } from './metrics.js';
24
25
  export function generateHtmlReport(data, opts) {
25
26
  const generated = new Date().toISOString();
@@ -37,69 +38,35 @@ export function generateHtmlReport(data, opts) {
37
38
  buildStatsSection(data),
38
39
  buildDiscussionSection(data),
39
40
  ];
40
- const milestoneTag = opts.milestoneId
41
- ? ` <span class="sep">/</span> <span class="mono accent">${esc(opts.milestoneId)}</span>`
42
- : '';
41
+ const title = opts.milestoneId ? `${opts.projectName} / ${opts.milestoneId}` : opts.projectName;
43
42
  const backLink = opts.indexRelPath
44
43
  ? `<a class="back-link" href="${esc(opts.indexRelPath)}">All Reports</a>`
45
44
  : '';
46
- return `<!DOCTYPE html>
47
- <html lang="en">
48
- <head>
49
- <meta charset="UTF-8">
50
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
51
- <title>GSD Report — ${esc(opts.projectName)}${opts.milestoneId ? ` — ${esc(opts.milestoneId)}` : ''}</title>
52
- <style>${CSS}</style>
53
- </head>
54
- <body>
55
- <header>
56
- <div class="header-inner">
57
- <div class="branding">
58
- <span class="logo">GSD</span>
59
- <span class="version">v${esc(opts.gsdVersion)}</span>
60
- </div>
61
- <div class="header-meta">
62
- <h1>${esc(opts.projectName)}${milestoneTag}</h1>
63
- <span class="header-path">${esc(opts.projectPath)}</span>
64
- </div>
65
- <div class="header-right">
66
- ${backLink}
67
- <div class="generated">${formatDateLong(generated)}</div>
68
- </div>
69
- </div>
70
- </header>
71
- <nav class="toc" aria-label="Report sections">
72
- <ul>
73
- <li><a href="#summary">Summary</a></li>
74
- <li><a href="#blockers">Blockers</a></li>
75
- <li><a href="#progress">Progress</a></li>
76
- <li><a href="#timeline">Timeline</a></li>
77
- <li><a href="#depgraph">Dependencies</a></li>
78
- <li><a href="#metrics">Metrics</a></li>
79
- <li><a href="#health">Health</a></li>
80
- <li><a href="#changelog">Changelog</a></li>
81
- <li><a href="#knowledge">Knowledge</a></li>
82
- <li><a href="#captures">Captures</a></li>
83
- <li><a href="#stats">Artifacts</a></li>
84
- <li><a href="#discussion">Planning</a></li>
85
- </ul>
86
- </nav>
87
- <main>
88
- ${sections.join('\n')}
89
- </main>
90
- <footer>
91
- <div class="footer-inner">
92
- <span>GSD v${esc(opts.gsdVersion)}</span>
93
- <span class="sep">/</span>
94
- <span>${esc(opts.projectName)}</span>
95
- ${opts.milestoneId ? `<span class="sep">/</span><span class="mono">${esc(opts.milestoneId)}</span>` : ''}
96
- <span class="sep">/</span>
97
- <span>${formatDateLong(generated)}</span>
98
- </div>
99
- </footer>
100
- <script>${JS}</script>
101
- </body>
102
- </html>`;
45
+ return renderHtmlShell({
46
+ title,
47
+ documentTitle: `GSD Report — ${opts.projectName}${opts.milestoneId ? ` — ${opts.milestoneId}` : ''}`,
48
+ subtitle: opts.projectPath,
49
+ kind: 'Report',
50
+ version: opts.gsdVersion,
51
+ generatedAt: generated,
52
+ headerActionsHtml: backLink,
53
+ footerNote: opts.milestoneId ? `${opts.projectName} / ${opts.milestoneId}` : opts.projectName,
54
+ toc: [
55
+ { href: '#summary', label: 'Summary' },
56
+ { href: '#blockers', label: 'Blockers' },
57
+ { href: '#progress', label: 'Progress' },
58
+ { href: '#timeline', label: 'Timeline' },
59
+ { href: '#depgraph', label: 'Dependencies' },
60
+ { href: '#metrics', label: 'Metrics' },
61
+ { href: '#health', label: 'Health' },
62
+ { href: '#changelog', label: 'Changelog' },
63
+ { href: '#knowledge', label: 'Knowledge' },
64
+ { href: '#captures', label: 'Captures' },
65
+ { href: '#stats', label: 'Artifacts' },
66
+ { href: '#discussion', label: 'Planning' },
67
+ ],
68
+ mainHtml: sections.join('\n'),
69
+ });
103
70
  }
104
71
  // ─── Section: Summary ─────────────────────────────────────────────────────────
105
72
  function buildSummarySection(data, opts, _generated) {
@@ -904,368 +871,3 @@ function hRow(label, value, status) {
904
871
  }
905
872
  function shortModel(m) { return m.replace(/^claude-/, '').replace(/^anthropic\//, ''); }
906
873
  function truncStr(s, n) { return s.length > n ? s.slice(0, n - 1) + '\u2026' : s; }
907
- function formatDateLong(iso) {
908
- try {
909
- const d = new Date(iso);
910
- return d.toLocaleString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', timeZoneName: 'short' });
911
- }
912
- catch {
913
- return iso;
914
- }
915
- }
916
- function esc(s) {
917
- if (s == null)
918
- return '';
919
- return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
920
- }
921
- // ─── CSS ───────────────────────────────────────────────────────────────────────
922
- // Linear-inspired: restrained palette, one accent, no emoji, no gradients.
923
- const CSS = `
924
- *,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
925
- :root{
926
- --bg-0:#0f1115;--bg-1:#16181d;--bg-2:#1e2028;--bg-3:#272a33;
927
- --border-1:#2b2e38;--border-2:#3b3f4c;
928
- --text-0:#ededef;--text-1:#a1a1aa;--text-2:#71717a;
929
- --accent:#5e6ad2;--accent-subtle:rgba(94,106,210,.12);
930
- --ok:#22c55e;--ok-subtle:rgba(34,197,94,.12);--warn:#ef4444;--caution:#eab308;
931
- /* Chart palette — 6 hues for bar charts */
932
- --c0:#5e6ad2;--c1:#e5796d;--c2:#14b8a6;--c3:#a78bfa;--c4:#f59e0b;--c5:#10b981;
933
- /* Token breakdown — 4 distinct hues */
934
- --tk-input:#5e6ad2;--tk-output:#e5796d;--tk-cache-r:#2dd4bf;--tk-cache-w:#64748b;
935
- --font:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
936
- --mono:'JetBrains Mono','Fira Code',ui-monospace,SFMono-Regular,monospace;
937
- }
938
- html{scroll-behavior:smooth;font-size:13px}
939
- body{background:var(--bg-0);color:var(--text-0);font-family:var(--font);line-height:1.6;-webkit-font-smoothing:antialiased}
940
- a{color:var(--accent);text-decoration:none}
941
- a:hover{text-decoration:underline}
942
- code{font-family:var(--mono);font-size:12px;background:var(--bg-3);padding:1px 5px;border-radius:3px}
943
- .mono{font-family:var(--mono);font-size:12px}
944
- .muted{color:var(--text-2)}
945
- .accent{color:var(--accent)}
946
- .sep{color:var(--border-2);margin:0 4px}
947
- .empty{color:var(--text-2);padding:8px 0;font-size:13px}
948
- .indent{padding-left:12px}
949
- .num{font-variant-numeric:tabular-nums;text-align:right}
950
-
951
- /* Status dots — geometric, no emoji */
952
- .dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0;vertical-align:middle}
953
- .dot-sm{width:6px;height:6px}
954
- .dot-complete{background:var(--ok);opacity:.6}
955
- .dot-active{background:var(--accent)}
956
- .dot-pending{background:transparent;border:1.5px solid var(--border-2)}
957
- .dot-parked{background:var(--warn);opacity:.5}
958
-
959
- /* Header */
960
- header{background:var(--bg-1);border-bottom:1px solid var(--border-1);padding:12px 32px;position:sticky;top:0;z-index:200}
961
- .header-inner{display:flex;align-items:center;gap:16px;max-width:1280px;margin:0 auto}
962
- .branding{display:flex;align-items:baseline;gap:6px;flex-shrink:0}
963
- .logo{font-size:18px;font-weight:800;letter-spacing:-.5px;color:var(--text-0)}
964
- .version{font-size:10px;color:var(--text-2);font-family:var(--mono)}
965
- .header-meta{flex:1;min-width:0}
966
- .header-meta h1{font-size:15px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
967
- .header-path{font-size:11px;color:var(--text-2);font-family:var(--mono);display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
968
- .header-right{text-align:right;flex-shrink:0;display:flex;flex-direction:column;align-items:flex-end;gap:4px}
969
- .generated{font-size:11px;color:var(--text-2)}
970
- .back-link{font-size:12px;color:var(--text-1)}
971
- .back-link:hover{color:var(--accent)}
972
-
973
- /* TOC nav */
974
- .toc{background:var(--bg-1);border-bottom:1px solid var(--border-1);overflow-x:auto}
975
- .toc ul{display:flex;list-style:none;max-width:1280px;margin:0 auto;padding:0 32px}
976
- .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}
977
- .toc a:hover{color:var(--text-0);border-bottom-color:var(--border-2)}
978
- .toc a.active{color:var(--text-0);border-bottom-color:var(--accent)}
979
-
980
- /* Layout */
981
- main{max-width:1280px;margin:0 auto;padding:32px;display:flex;flex-direction:column;gap:48px}
982
- section{scroll-margin-top:82px}
983
- 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}
984
- h3{font-size:13px;font-weight:600;color:var(--text-1);margin:20px 0 8px}
985
- .count{font-size:11px;font-weight:500;color:var(--text-2);background:var(--bg-3);border-radius:3px;padding:1px 6px}
986
- .count-warn{color:var(--caution)}
987
-
988
- /* KV grid (stats/metrics) */
989
- .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}
990
- .kv{background:var(--bg-1);padding:10px 16px;display:flex;flex-direction:column;gap:2px;min-width:110px;flex:1}
991
- .kv-val{font-size:18px;font-weight:600;color:var(--text-0);font-variant-numeric:tabular-nums}
992
- .kv-lbl{font-size:10px;color:var(--text-2);text-transform:uppercase;letter-spacing:.4px}
993
-
994
- /* Progress bar */
995
- .progress-wrap{display:flex;align-items:center;gap:10px;margin-bottom:12px}
996
- .progress-track{flex:1;height:4px;background:var(--bg-3);border-radius:2px;overflow:hidden}
997
- .progress-fill{height:100%;background:var(--accent);border-radius:2px}
998
- .progress-label{font-size:12px;font-weight:600;color:var(--text-1);min-width:40px;text-align:right}
999
- .active-info{font-size:12px;color:var(--text-1);margin-bottom:4px}
1000
- .activity-line{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-1);padding:6px 0}
1001
-
1002
- /* Tables */
1003
- .tbl{width:100%;border-collapse:collapse;font-size:12px}
1004
- .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}
1005
- .tbl td{padding:6px 12px;border-bottom:1px solid var(--border-1);vertical-align:top}
1006
- .tbl tr:last-child td{border-bottom:none}
1007
- .tbl tbody tr:hover td{background:var(--accent-subtle)}
1008
- .tbl-kv td:first-child{color:var(--text-2);width:180px}
1009
- .table-scroll{overflow-x:auto;border:1px solid var(--border-1);border-radius:4px}
1010
- .table-scroll .tbl{border:none}
1011
-
1012
- /* Health */
1013
- .h-ok td:first-child{color:var(--text-1)}
1014
- .h-caution td{color:var(--caution)}
1015
- .h-warn td{color:var(--warn)}
1016
-
1017
- /* Labels */
1018
- .label{font-size:10px;font-weight:500;color:var(--accent);text-transform:uppercase;letter-spacing:.4px}
1019
- .risk{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;flex-shrink:0}
1020
- .risk-low{color:var(--text-2)}
1021
- .risk-medium{color:var(--caution)}
1022
- .risk-high{color:var(--warn)}
1023
- .risk-unknown{color:var(--text-2)}
1024
-
1025
- /* Tags */
1026
- .tag-row{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px}
1027
- .tag{font-size:11px;font-family:var(--mono);color:var(--text-2);background:var(--bg-3);border-radius:3px;padding:1px 6px}
1028
-
1029
- /* Verification */
1030
- .verif{font-size:12px;color:var(--text-1);padding:4px 0;margin-bottom:6px}
1031
- .verif-blocker{color:var(--warn)}
1032
-
1033
- /* Detail blocks */
1034
- .detail-block{font-size:12px;color:var(--text-2);margin-bottom:6px}
1035
- .detail-label{font-weight:600;color:var(--text-1);display:block;margin-bottom:2px}
1036
- .detail-block ul{padding-left:16px;margin-top:2px}
1037
- .detail-block li{margin-bottom:1px}
1038
-
1039
- /* Progress tree */
1040
- .ms-block{border:1px solid var(--border-1);border-radius:4px;overflow:hidden;margin-bottom:8px}
1041
- .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}
1042
- .ms-summary:hover{background:var(--bg-2)}
1043
- .ms-summary::-webkit-details-marker{display:none}
1044
- .ms-id{font-weight:600}
1045
- .ms-title{flex:1;font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1046
- .ms-body{padding:6px 12px 8px 24px;display:flex;flex-direction:column;gap:4px}
1047
-
1048
- .sl-block{border:1px solid var(--border-1);border-radius:3px;overflow:hidden}
1049
- .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}
1050
- .sl-summary:hover{background:var(--bg-3)}
1051
- .sl-summary::-webkit-details-marker{display:none}
1052
- .sl-crit{border-left:2px solid var(--accent)}
1053
- .sl-deps::before{content:'\\2190 ';color:var(--border-2)}
1054
- .sl-detail{padding:8px 12px;background:var(--bg-0);border-top:1px solid var(--border-1)}
1055
-
1056
- .task-list{list-style:none;padding:4px 0 0;display:flex;flex-direction:column;gap:2px}
1057
- .task-row{display:flex;align-items:center;gap:6px;font-size:12px;padding:3px 6px;border-radius:2px}
1058
-
1059
- /* Dep graph */
1060
- .dep-block{margin-bottom:28px}
1061
- .dep-legend{display:flex;gap:14px;font-size:12px;color:var(--text-2);margin-bottom:8px;align-items:center}
1062
- .dep-legend span{display:flex;align-items:center;gap:4px}
1063
- .dep-wrap{overflow-x:auto;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:16px}
1064
- .dep-svg{display:block}
1065
- .edge{fill:none;stroke:var(--border-2);stroke-width:1.5}
1066
- .edge-crit{stroke:var(--accent);stroke-width:2}
1067
- .node rect{fill:var(--bg-2);stroke:var(--border-2);stroke-width:1}
1068
- .n-done rect{fill:var(--ok-subtle);stroke:rgba(34,197,94,.4)}
1069
- .n-active rect{fill:var(--accent-subtle);stroke:var(--accent)}
1070
- .n-crit rect{stroke:var(--accent)!important;stroke-width:1.5!important}
1071
- .n-id{font-family:var(--mono);font-size:10px;fill:var(--text-1);font-weight:600;text-anchor:middle}
1072
- .n-title{font-size:9px;fill:var(--text-2);text-anchor:middle}
1073
- .n-active .n-id{fill:var(--accent)}
1074
-
1075
- /* Metrics */
1076
- .token-block{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px;margin-bottom:16px}
1077
- .token-bar{display:flex;height:16px;border-radius:2px;overflow:hidden;gap:1px;margin-bottom:8px}
1078
- .tseg{height:100%;min-width:2px}
1079
- .seg-1{background:var(--tk-input)}
1080
- .seg-2{background:var(--tk-output)}
1081
- .seg-3{background:var(--tk-cache-r)}
1082
- .seg-4{background:var(--tk-cache-w)}
1083
- .token-legend{display:flex;flex-wrap:wrap;gap:12px}
1084
- .leg-item{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text-2)}
1085
- .leg-dot{width:8px;height:8px;border-radius:2px;flex-shrink:0}
1086
- .chart-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;margin-bottom:16px}
1087
- .chart-block{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px}
1088
- .bar-row{display:grid;grid-template-columns:120px 1fr 68px;align-items:center;gap:6px;margin-bottom:2px}
1089
- .bar-lbl{font-size:12px;color:var(--text-2);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
1090
- .bar-track{height:14px;background:var(--bg-3);border-radius:2px;overflow:hidden}
1091
- .bar-fill{height:100%;border-radius:2px;background:var(--c0)}
1092
- .bar-c0{background:var(--c0)}.bar-c1{background:var(--c1)}.bar-c2{background:var(--c2)}
1093
- .bar-c3{background:var(--c3)}.bar-c4{background:var(--c4)}.bar-c5{background:var(--c5)}
1094
- .bar-val{font-size:11px;font-variant-numeric:tabular-nums;color:var(--text-1)}
1095
- .bar-sub{font-size:10px;color:var(--text-2);padding-left:128px;margin-bottom:6px}
1096
-
1097
- /* Changelog */
1098
- .cl-entry{border-bottom:1px solid var(--border-1);padding:12px 0}
1099
- .cl-entry:last-child{border-bottom:none}
1100
- .cl-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}
1101
- .cl-title{flex:1;font-weight:500}
1102
- .cl-date{margin-left:auto;white-space:nowrap}
1103
- .cl-liner{font-size:13px;color:var(--text-1);margin-bottom:6px}
1104
- .files-detail summary{font-size:12px;cursor:pointer}
1105
- .file-list{list-style:none;padding-left:10px;margin-top:4px;display:flex;flex-direction:column;gap:2px}
1106
- .file-list li{font-size:12px;color:var(--text-1)}
1107
-
1108
- /* Footer */
1109
- footer{border-top:1px solid var(--border-1);padding:20px 32px;margin-top:40px}
1110
- .footer-inner{display:flex;align-items:center;gap:6px;justify-content:center;font-size:11px;color:var(--text-2)}
1111
-
1112
- /* Executive summary & ETA */
1113
- .exec-summary{font-size:13px;color:var(--text-1);margin-bottom:12px;line-height:1.7}
1114
- .eta-line{font-size:12px;color:var(--accent);margin-top:4px}
1115
-
1116
- /* Cost over time chart */
1117
- .cost-svg{display:block;margin:8px 0;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px}
1118
- .cost-line{fill:none;stroke:var(--accent);stroke-width:2}
1119
- .cost-area{fill:var(--accent-subtle);stroke:none}
1120
- .cost-axis{fill:var(--text-2);font-family:var(--mono);font-size:10px}
1121
- .cost-grid{stroke:var(--border-1);stroke-width:1;stroke-dasharray:4,4}
1122
-
1123
- /* Budget burndown */
1124
- .burndown-wrap{background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:14px;margin-bottom:16px}
1125
- .burndown-bar{display:flex;height:20px;border-radius:3px;overflow:hidden;gap:1px;margin-bottom:8px}
1126
- .burndown-spent{background:var(--accent);height:100%}
1127
- .burndown-projected{background:var(--caution);height:100%;opacity:.6}
1128
- .burndown-overshoot{background:var(--warn);height:100%;opacity:.7}
1129
- .burndown-legend{display:flex;flex-wrap:wrap;gap:12px;font-size:11px;color:var(--text-2)}
1130
- .burndown-legend span{display:flex;align-items:center;gap:4px}
1131
- .burndown-dot{display:inline-block;width:8px;height:8px;border-radius:2px}
1132
-
1133
- /* Blockers */
1134
- .blocker-card{border-left:3px solid var(--warn);background:var(--bg-1);border-radius:0 4px 4px 0;padding:10px 14px;margin-bottom:8px}
1135
- .blocker-id{font-family:var(--mono);font-size:12px;color:var(--warn);margin-bottom:2px}
1136
- .blocker-text{font-size:12px;color:var(--text-1)}
1137
- .blocker-risk{font-size:11px;color:var(--caution);margin-top:2px}
1138
-
1139
- /* Gantt */
1140
- .gantt-wrap{overflow-x:auto;background:var(--bg-1);border:1px solid var(--border-1);border-radius:4px;padding:16px;margin-top:16px}
1141
- .gantt-svg{display:block}
1142
- .gantt-bar-done{fill:var(--ok);opacity:.7}
1143
- .gantt-bar-active{fill:var(--accent)}
1144
- .gantt-bar-pending{fill:var(--border-2)}
1145
- .gantt-label{fill:var(--text-2);font-family:var(--mono);font-size:10px}
1146
- .gantt-axis{fill:var(--text-2);font-family:var(--mono);font-size:9px}
1147
-
1148
- /* Interactive */
1149
- .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}
1150
- .tl-filter:focus{border-color:var(--accent)}
1151
- .tl-filter::placeholder{color:var(--text-2)}
1152
- .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}
1153
- .sec-toggle:hover{border-color:var(--text-1);color:var(--text-1)}
1154
- .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)}
1155
- .theme-toggle:hover{border-color:var(--accent);color:var(--accent)}
1156
-
1157
- /* Light theme */
1158
- .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}
1159
-
1160
- /* Responsive */
1161
- @media(max-width:768px){
1162
- header{padding:10px 16px}
1163
- .header-inner{flex-wrap:wrap;gap:8px}
1164
- .header-meta h1{font-size:13px}
1165
- main{padding:16px}
1166
- .kv-grid{gap:1px}
1167
- .kv{min-width:80px;padding:8px 10px}
1168
- .kv-val{font-size:14px}
1169
- .chart-row{grid-template-columns:1fr}
1170
- .toc ul{padding:0 16px}
1171
- .toc a{padding:6px 8px;font-size:11px}
1172
- .bar-row{grid-template-columns:80px 1fr 56px}
1173
- .ms-body{padding-left:12px}
1174
- }
1175
- @media(max-width:480px){
1176
- .kv{min-width:60px;padding:6px 8px}
1177
- .kv-val{font-size:12px}
1178
- .kv-lbl{font-size:9px}
1179
- .bar-row{grid-template-columns:60px 1fr 48px}
1180
- .bar-lbl{font-size:10px}
1181
- .toc ul{flex-wrap:wrap}
1182
- .header-right{display:none}
1183
- .gantt-wrap{overflow-x:auto}
1184
- }
1185
-
1186
- /* Print */
1187
- @media print{
1188
- header,nav.toc{position:static}
1189
- body{background:#fff;color:#1a1a1a}
1190
- :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}
1191
- section{page-break-inside:avoid}
1192
- .table-scroll{overflow:visible}
1193
- }
1194
- `;
1195
- // ─── JS ────────────────────────────────────────────────────────────────────────
1196
- const JS = `
1197
- (function(){
1198
- const sections=document.querySelectorAll('section[id]');
1199
- const links=document.querySelectorAll('.toc a');
1200
- if(!sections.length||!links.length)return;
1201
- const obs=new IntersectionObserver(entries=>{
1202
- for(const e of entries){
1203
- if(!e.isIntersecting)continue;
1204
- for(const l of links)l.classList.remove('active');
1205
- const a=document.querySelector('.toc a[href="#'+e.target.id+'"]');
1206
- if(a)a.classList.add('active');
1207
- }
1208
- },{rootMargin:'-10% 0px -80% 0px',threshold:0});
1209
- for(const s of sections)obs.observe(s);
1210
- })();
1211
- (function(){
1212
- var tl=document.getElementById('timeline');
1213
- if(!tl)return;
1214
- var table=tl.querySelector('.tbl');
1215
- if(!table)return;
1216
- var input=document.createElement('input');
1217
- input.className='tl-filter';
1218
- input.placeholder='Filter timeline\\u2026';
1219
- input.type='text';
1220
- table.parentNode.insertBefore(input,table);
1221
- var rows=table.querySelectorAll('tbody tr');
1222
- input.addEventListener('input',function(){
1223
- var q=this.value.toLowerCase();
1224
- for(var i=0;i<rows.length;i++){
1225
- rows[i].style.display=rows[i].textContent.toLowerCase().indexOf(q)>-1?'':'none';
1226
- }
1227
- });
1228
- })();
1229
- (function(){
1230
- var saved=JSON.parse(localStorage.getItem('gsd-collapsed')||'{}');
1231
- document.querySelectorAll('section[id]').forEach(function(sec){
1232
- var h2=sec.querySelector('h2');
1233
- if(!h2)return;
1234
- var btn=document.createElement('button');
1235
- btn.className='sec-toggle';
1236
- btn.textContent=saved[sec.id]?'+':'-';
1237
- btn.setAttribute('aria-label','Toggle section');
1238
- h2.prepend(btn);
1239
- if(saved[sec.id])toggleSection(sec,true);
1240
- btn.addEventListener('click',function(e){
1241
- e.preventDefault();
1242
- var collapsed=btn.textContent==='-';
1243
- toggleSection(sec,collapsed);
1244
- btn.textContent=collapsed?'+':'-';
1245
- saved[sec.id]=collapsed;
1246
- localStorage.setItem('gsd-collapsed',JSON.stringify(saved));
1247
- });
1248
- });
1249
- function toggleSection(sec,hide){
1250
- var children=sec.children;
1251
- for(var i=0;i<children.length;i++){
1252
- if(children[i].tagName!=='H2')children[i].style.display=hide?'none':'';
1253
- }
1254
- }
1255
- })();
1256
- (function(){
1257
- var hr=document.querySelector('.header-right');
1258
- if(!hr)return;
1259
- var btn=document.createElement('button');
1260
- btn.className='theme-toggle';
1261
- btn.textContent=localStorage.getItem('gsd-theme')==='light'?'Dark':'Light';
1262
- if(localStorage.getItem('gsd-theme')==='light')document.documentElement.classList.add('light-theme');
1263
- btn.addEventListener('click',function(){
1264
- document.documentElement.classList.toggle('light-theme');
1265
- var isLight=document.documentElement.classList.contains('light-theme');
1266
- btn.textContent=isLight?'Dark':'Light';
1267
- localStorage.setItem('gsd-theme',isLight?'light':'dark');
1268
- });
1269
- hr.prepend(btn);
1270
- })();
1271
- `;
@@ -139,6 +139,30 @@ function isExcludedScopedPath(path, exclusions) {
139
139
  }
140
140
  return false;
141
141
  }
142
+ function submodulePathsFromLsFiles(output) {
143
+ const submodulePaths = new Set();
144
+ if (!output)
145
+ return submodulePaths;
146
+ for (const line of output.split("\n")) {
147
+ const match = line.match(/^160000\s+\S+\s+\d+\t(.+)$/);
148
+ if (!match)
149
+ continue;
150
+ submodulePaths.add(match[1].replace(/\\/g, "/").replace(/\/+$/, ""));
151
+ }
152
+ return submodulePaths;
153
+ }
154
+ function isInsideSubmodule(path, submodulePaths) {
155
+ const normalizedPath = path.replace(/\\/g, "/");
156
+ if (submodulePaths.has(normalizedPath))
157
+ return true;
158
+ let slashIndex = normalizedPath.lastIndexOf("/");
159
+ while (slashIndex > 0) {
160
+ if (submodulePaths.has(normalizedPath.slice(0, slashIndex)))
161
+ return true;
162
+ slashIndex = normalizedPath.lastIndexOf("/", slashIndex - 1);
163
+ }
164
+ return false;
165
+ }
142
166
  /**
143
167
  * Thrown when a slice merge hits code conflicts in non-.gsd files.
144
168
  * The working tree is left in a conflicted state (no reset) so the
@@ -572,6 +596,20 @@ export class GitServiceImpl {
572
596
  .filter((file) => file !== null)
573
597
  .filter(file => !nativeIsIgnored(this.basePath, file))
574
598
  .filter(file => !isExcludedScopedPath(file, allExclusions));
599
+ const scopedPaths = [];
600
+ const submodulePaths = [];
601
+ const repoSubmodules = submodulePathsFromLsFiles(runGit(this.basePath, ["ls-files", "--stage"], { allowFailure: true }));
602
+ for (const path of normalized) {
603
+ if (isInsideSubmodule(path, repoSubmodules)) {
604
+ submodulePaths.push(path);
605
+ }
606
+ else {
607
+ scopedPaths.push(path);
608
+ }
609
+ }
610
+ if (submodulePaths.length > 0) {
611
+ logWarning("engine", `scoped stage: dropping ${submodulePaths.length} keyFile(s) inside git submodule(s): ${submodulePaths.join(", ")}`, { file: "git-service.ts" });
612
+ }
575
613
  // Drop entries that don't exist on disk. The LLM occasionally lists files
576
614
  // it intended to write but didn't (or names them with wrong casing/path).
577
615
  // Pre-`b304f738b` `git add -A` swallowed these silently; the scoped
@@ -579,7 +617,7 @@ export class GitServiceImpl {
579
617
  // the whole commit fail (see #5500). Filter so valid paths still commit.
580
618
  const missing = [];
581
619
  const existing = [];
582
- for (const path of normalized) {
620
+ for (const path of scopedPaths) {
583
621
  if (existsSync(join(this.basePath, path))) {
584
622
  existing.push(path);
585
623
  }
@@ -1769,6 +1769,7 @@ export function deleteTask(milestoneId, sliceId, taskId) {
1769
1769
  transaction(() => {
1770
1770
  // Must delete verification_evidence first (FK constraint)
1771
1771
  currentDb.prepare(`DELETE FROM verification_evidence WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1772
+ currentDb.prepare(`DELETE FROM quality_gates WHERE milestone_id = :mid AND slice_id = :sid AND task_id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1772
1773
  currentDb.prepare(`DELETE FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND id = :tid`).run({ ":mid": milestoneId, ":sid": sliceId, ":tid": taskId });
1773
1774
  });
1774
1775
  }
@@ -1238,6 +1238,7 @@ export async function showDiscuss(ctx, pi, basePath) {
1238
1238
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1239
1239
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1240
1240
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1241
+ workingDirectory: basePath,
1241
1242
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1242
1243
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1243
1244
  fastPathInstruction: "",
@@ -1253,6 +1254,7 @@ export async function showDiscuss(ctx, pi, basePath) {
1253
1254
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1254
1255
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: mid, step: false });
1255
1256
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
1257
+ workingDirectory: basePath,
1256
1258
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1257
1259
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1258
1260
  fastPathInstruction: "",
@@ -1488,6 +1490,7 @@ async function dispatchDiscussForMilestone(ctx, pi, basePath, mid, milestoneTitl
1488
1490
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1489
1491
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1490
1492
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1493
+ workingDirectory: basePath,
1491
1494
  milestoneId: mid,
1492
1495
  milestoneTitle,
1493
1496
  inlinedTemplates: discussMilestoneTemplates,
@@ -1755,16 +1758,17 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1755
1758
  }
1756
1759
  if (interrupted.classification !== "recoverable") {
1757
1760
  try {
1758
- const { autoImportMarkdownHierarchyIfDbMismatch } = await import("./migration-auto-check.js");
1759
- const result = await autoImportMarkdownHierarchyIfDbMismatch(basePath);
1760
- if (result.action === "imported") {
1761
- ctx.ui.notify(`Recovered migrated planning state into gsd.db (${result.reason}): ${result.afterDb.milestones} milestone(s), ${result.afterDb.slices} slice(s), ${result.afterDb.tasks} task(s).`, "info");
1761
+ const { checkMarkdownHierarchyAgainstDb } = await import("./migration-auto-check.js");
1762
+ const result = await checkMarkdownHierarchyAgainstDb(basePath);
1763
+ if (result.action === "recovery-required") {
1764
+ ctx.ui.notify(result.message ??
1765
+ `Markdown planning artifacts do not match the authoritative DB. Run \`${result.recoveryCommand ?? "gsd recover"}\` to import markdown explicitly.`, "warning");
1762
1766
  }
1763
1767
  }
1764
1768
  catch (err) {
1765
1769
  const message = err instanceof Error ? err.message : String(err);
1766
- ctx.ui.notify(`GSD could not auto-import existing planning state into gsd.db: ${message}`, "warning");
1767
- logWarning("guided", `planning state auto-import failed: ${message}`, { file: "guided-flow.ts" });
1770
+ ctx.ui.notify(`GSD could not compare markdown planning artifacts with gsd.db: ${message}`, "warning");
1771
+ logWarning("guided", `planning state DB/markdown comparison failed: ${message}`, { file: "guided-flow.ts" });
1768
1772
  }
1769
1773
  }
1770
1774
  // Always derive from the project root — the assessment may have derived
@@ -1957,6 +1961,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1957
1961
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1958
1962
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1959
1963
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1964
+ workingDirectory: basePath,
1960
1965
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1961
1966
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
1962
1967
  fastPathInstruction: "",
@@ -1972,6 +1977,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1972
1977
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1973
1978
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId, step: stepMode });
1974
1979
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
1980
+ workingDirectory: basePath,
1975
1981
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1976
1982
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
1977
1983
  fastPathInstruction: "",
@@ -2052,6 +2058,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
2052
2058
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2053
2059
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2054
2060
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
2061
+ workingDirectory: basePath,
2055
2062
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2056
2063
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2057
2064
  fastPathInstruction: "",
@@ -71,6 +71,16 @@ function parsePhaseEntry(line) {
71
71
  raw: line,
72
72
  };
73
73
  }
74
+ // Format 3: - ✅ v1.0 MVP — Phases 1-6
75
+ const fmtVersionPhases = stripped.match(/^-\s+([✅🚧])\s+v\d+(?:\.\d+)*\s+(.+?)\s*[—–]\s*Phases?\s+(\d+(?:\.\d+)?)(?:\s*-\s*\d+(?:\.\d+)?)?(?:\s+\(.*\))?\s*$/iu);
76
+ if (fmtVersionPhases) {
77
+ return {
78
+ number: parseFloat(fmtVersionPhases[3]),
79
+ title: fmtVersionPhases[2].trim(),
80
+ done: fmtVersionPhases[1] === '✅',
81
+ raw: line,
82
+ };
83
+ }
74
84
  return null;
75
85
  }
76
86
  /**