gsd-pi 2.82.0-dev.2841a1e44 → 2.82.0-dev.3709f22a5

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 (305) 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 +28 -2
  9. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  10. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  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 +70 -9
  14. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  15. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  16. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  17. package/dist/resources/extensions/gsd/auto.js +37 -4
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +25 -6
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  20. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +4 -2
  21. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +5 -2
  22. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +13 -1
  23. package/dist/resources/extensions/gsd/commands/handlers/core.js +17 -1
  24. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  25. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  26. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  27. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  28. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  29. package/dist/resources/extensions/gsd/doctor.js +2 -28
  30. package/dist/resources/extensions/gsd/export-html.js +27 -425
  31. package/dist/resources/extensions/gsd/git-service.js +39 -1
  32. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  33. package/dist/resources/extensions/gsd/guided-flow.js +93 -111
  34. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  35. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  36. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  37. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  38. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  39. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  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/complete-milestone.md +1 -1
  44. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  45. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  46. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  47. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  48. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  49. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  50. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  51. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  52. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  53. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  54. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  55. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  56. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  57. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  58. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  59. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  60. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  61. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  62. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  63. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  64. package/dist/resources/extensions/gsd/unit-context-manifest.js +7 -8
  65. package/dist/resources/extensions/gsd/validation.js +23 -1
  66. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  67. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  68. package/dist/resources/extensions/gsd/worktree-lifecycle.js +33 -8
  69. package/dist/resources/extensions/shared/html-shell.js +388 -0
  70. package/dist/resources/extensions/visual-brief/page-contract.js +2 -0
  71. package/dist/resources/extensions/visual-brief/prompts.js +29 -0
  72. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  73. package/dist/web/standalone/.next/BUILD_ID +1 -1
  74. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  75. package/dist/web/standalone/.next/build-manifest.json +3 -3
  76. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  77. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  87. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  97. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/index.html +1 -1
  99. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  100. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  102. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  104. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  105. package/dist/web/standalone/.next/server/app/page.js +2 -2
  106. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  107. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  109. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  110. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  113. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  114. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  115. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  116. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  117. package/dist/web/standalone/.next/static/chunks/{webpack-6a95bc41e0f7ec89.js → webpack-9a4db269f9ed63ad.js} +1 -1
  118. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  119. package/package.json +2 -2
  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/dist/modes/interactive/components/footer.d.ts.map +1 -1
  150. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  151. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  152. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  153. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  154. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  155. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  156. package/src/resources/GSD-WORKFLOW.md +7 -0
  157. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  158. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  159. package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
  160. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  161. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  162. package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
  163. package/src/resources/extensions/gsd/auto/phases.ts +30 -2
  164. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  165. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  166. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  167. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  168. package/src/resources/extensions/gsd/auto-post-unit.ts +77 -7
  169. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  170. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  171. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  172. package/src/resources/extensions/gsd/auto.ts +40 -4
  173. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +33 -6
  174. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  175. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +4 -2
  176. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +3 -1
  177. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +16 -1
  178. package/src/resources/extensions/gsd/commands/handlers/core.ts +17 -1
  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-git-checks.ts +45 -1
  183. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  184. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  185. package/src/resources/extensions/gsd/doctor.ts +2 -27
  186. package/src/resources/extensions/gsd/export-html.ts +27 -427
  187. package/src/resources/extensions/gsd/git-service.ts +45 -1
  188. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  189. package/src/resources/extensions/gsd/guided-flow.ts +126 -128
  190. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  191. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  192. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  193. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  194. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  195. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  196. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  197. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  198. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  199. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  200. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  201. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  202. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  203. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  204. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  205. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  206. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  207. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  208. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  209. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  210. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  211. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  212. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  213. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  214. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  215. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  216. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  217. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  218. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +54 -0
  219. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
  220. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -6
  221. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  222. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  223. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  224. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  225. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  226. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  227. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  228. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  229. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  230. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  231. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  232. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  233. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  234. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  235. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  236. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  237. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  238. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  239. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  240. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  241. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  242. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  243. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  244. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  245. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  246. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  247. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  248. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  249. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  250. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  251. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  252. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  253. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  254. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  255. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  256. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  257. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  258. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  259. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  260. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  261. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  262. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  263. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  264. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +20 -1
  265. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
  266. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  267. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  268. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  269. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  270. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  271. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  272. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +65 -7
  273. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  274. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
  275. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  276. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  277. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  278. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  279. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +38 -0
  280. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  281. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  282. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  283. package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
  284. package/src/resources/extensions/gsd/types.ts +1 -1
  285. package/src/resources/extensions/gsd/unit-context-manifest.ts +12 -9
  286. package/src/resources/extensions/gsd/validation.ts +23 -1
  287. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  288. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  289. package/src/resources/extensions/gsd/worktree-lifecycle.ts +41 -8
  290. package/src/resources/extensions/shared/html-shell.ts +412 -0
  291. package/src/resources/extensions/visual-brief/page-contract.ts +2 -0
  292. package/src/resources/extensions/visual-brief/prompts.ts +37 -1
  293. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +40 -0
  294. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  295. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  296. package/dist/web/standalone/.next/static/css/0262768ec1b89d34.css +0 -1
  297. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  298. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  299. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  300. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  301. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  302. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  303. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  304. /package/dist/web/standalone/.next/static/{Qgr2B_MRhPxC0z8fwv4vT → kkGf3_VaPFkiDNV_D7Dtl}/_buildManifest.js +0 -0
  305. /package/dist/web/standalone/.next/static/{Qgr2B_MRhPxC0z8fwv4vT → kkGf3_VaPFkiDNV_D7Dtl}/_ssgManifest.js +0 -0
@@ -65,6 +65,7 @@ const QUEUE_SAFE_TOOLS = new Set([
65
65
  * true / false — shell no-ops / test exit codes
66
66
  */
67
67
  const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s|npm\s+run\s+(test|test:\w+|lint|lint:\w+|typecheck|type-check|type-check:\w+|check|verify|audit|outdated|format:check|ci|validate)\b|npm\s+(ls|list|info|view|show|outdated|audit|explain|doctor|ping|--version|-v)\b|npx\s|tsx\s|node\s+(--print|--version|-v\b)|python[23]?\s+(-c\s+'[^']*'|--version|-V\b|-m\s+(pip\s+show|pip\s+list|site))|pip[23]?\s+(show|list|freeze|check|index\s+versions)\b|jq\s|yq\s|curl\s+(-s\b|--silent\b)(?!\s+[^|>]*\s-[oO]\b)(?!\s+[^|>]*\s--output\b)[^|>]*$|openssl\s+(version|x509|s_client)|env\b|printenv\b|true\b|false\b)/;
68
+ const BASH_VERIFICATION_RE = /^\s*(npm\s+(run\s+(build|test|test:\w+|lint|lint:\w+|typecheck|type-check|verify|ci|validate)\b|test\b)|pnpm\s+(build|test|lint|typecheck|verify)\b|yarn\s+(build|test|lint|typecheck|verify)\b|vitest\b|jest\b|go\s+test\b)/;
68
69
 
69
70
  interface InMemoryWriteGateState {
70
71
  verifiedDepthMilestones: Set<string>;
@@ -767,6 +768,9 @@ function blockReason(unitType: string, mode: string, what: string): string {
767
768
  * and listed in the policy's allowedSubagents.
768
769
  * - "docs" → like "planning" but also allows writes to paths
769
770
  * matching `allowedPathGlobs` relative to basePath.
771
+ * - "verification"
772
+ * → allows Bash for project verification commands, but keeps
773
+ * writes restricted to .gsd/ and blocks subagent dispatch.
770
774
  *
771
775
  * `pathOrCommand` is the file path for write/edit-shaped tools and the
772
776
  * shell command for bash. Other tools ignore this argument.
@@ -804,7 +808,7 @@ export function shouldBlockPlanningUnit(
804
808
  return { block: true, reason: blockReason(unitType, policy.mode, `tool "${tool}" is not on the read-only allowlist`) };
805
809
  }
806
810
 
807
- // planning / planning-dispatch / docs modes share the same surface for safe tools, bash, and subagent.
811
+ // planning / planning-dispatch / docs / verification modes share the same surface for safe tools, bash, and subagent.
808
812
  if (PLANNING_SAFE_TOOLS.has(tool)) return { block: false };
809
813
  if (tool.startsWith("gsd_")) return { block: false };
810
814
 
@@ -862,6 +866,17 @@ export function shouldBlockPlanningUnit(
862
866
  }
863
867
 
864
868
  if (tool === "bash") {
869
+ if (policy.mode === "verification") {
870
+ if (BASH_VERIFICATION_RE.test(pathOrCommand) || BASH_READ_ONLY_RE.test(pathOrCommand)) return { block: false };
871
+ return {
872
+ block: true,
873
+ reason: blockReason(
874
+ unitType,
875
+ policy.mode,
876
+ `bash is restricted to build/test verification commands (npm run build, npm test, etc.); cannot run "${pathOrCommand.slice(0, 80)}${pathOrCommand.length > 80 ? "…" : ""}"`,
877
+ ),
878
+ };
879
+ }
865
880
  if (BASH_READ_ONLY_RE.test(pathOrCommand)) return { block: false };
866
881
  return {
867
882
  block: true,
@@ -1,6 +1,7 @@
1
1
  import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "@gsd/pi-coding-agent";
2
2
  import type { Model } from "@gsd/pi-ai";
3
3
  import type { GSDState } from "../../types.js";
4
+ import { createRequire } from "node:module";
4
5
 
5
6
  import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
6
7
  import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath } from "../../preferences.js";
@@ -220,7 +221,22 @@ export async function handleBrief(args: string, ctx: ExtensionCommandContext, pi
220
221
  }
221
222
 
222
223
  const outputDir = getVisualBriefOutputDir();
223
- pi.sendUserMessage(buildVisualBriefPrompt(request, { outputDir }));
224
+ const version = resolveGsdVersion();
225
+ pi.sendUserMessage(buildVisualBriefPrompt(request, { outputDir, version }));
226
+ }
227
+
228
+ const briefRequire = createRequire(import.meta.url);
229
+
230
+ function resolveGsdVersion(): string | undefined {
231
+ const envVersion = process.env.GSD_VERSION?.trim();
232
+ if (envVersion) return envVersion;
233
+ try {
234
+ const pkg = briefRequire("../../../../../../package.json") as { version?: unknown };
235
+ const fromPkg = typeof pkg.version === "string" ? pkg.version.trim() : "";
236
+ return fromPkg || undefined;
237
+ } catch {
238
+ return undefined;
239
+ }
224
240
  }
225
241
 
226
242
  export async function handleSetup(args: string, ctx: ExtensionCommandContext, pi?: ExtensionAPI): Promise<void> {
@@ -30,9 +30,10 @@ import { join } from "node:path";
30
30
  import {
31
31
  findStaleWorkerForProject,
32
32
  getAllAutoWorkers,
33
+ markWorkerCrashed,
33
34
  type AutoWorkerRow,
34
35
  } from "./db/auto-workers.js";
35
- import { getLatestForUnit, type DispatchStatus } from "./db/unit-dispatches.js";
36
+ import { markLatestActiveForWorkerCanceled, type DispatchStatus } from "./db/unit-dispatches.js";
36
37
  import { getRuntimeKv, setRuntimeKv, deleteRuntimeKv } from "./db/runtime-kv.js";
37
38
  import { _getAdapter, isDbAvailable } from "./gsd-db.js";
38
39
  import { gsdRoot, normalizeRealPath } from "./paths.js";
@@ -56,6 +57,15 @@ function lockPath(basePath: string): string {
56
57
  return join(gsdRoot(basePath), effectiveLockFile());
57
58
  }
58
59
 
60
+ function clearLegacyLockFile(basePath: string): void {
61
+ try {
62
+ const p = lockPath(basePath);
63
+ if (existsSync(p)) unlinkSync(p);
64
+ } catch {
65
+ // Best-effort.
66
+ }
67
+ }
68
+
59
69
  function readLegacyLock(basePath: string): LockData | null {
60
70
  try {
61
71
  const p = lockPath(basePath);
@@ -204,18 +214,34 @@ export function writeLock(
204
214
  * stale session-file pointer.
205
215
  */
206
216
  export function clearLock(basePath: string): void {
217
+ clearLegacyLockFile(basePath);
218
+
219
+ if (!isDbAvailable()) return;
207
220
  try {
208
- const p = lockPath(basePath);
209
- if (existsSync(p)) unlinkSync(p);
221
+ const projectRoot = normalizeRealPath(basePath);
222
+ const worker = findActiveWorkerForCurrentProcess(projectRoot);
223
+ if (!worker) return;
224
+ deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
210
225
  } catch {
211
226
  // Best-effort.
212
227
  }
228
+ }
229
+
230
+ /**
231
+ * Clear a stale DB-backed worker lock after readCrashLock/findStaleWorkerForProject
232
+ * has identified a dead worker. Unlike clearLock(), this targets the stale
233
+ * worker row instead of the current process's active worker.
234
+ */
235
+ export function clearStaleWorkerLock(basePath: string): void {
236
+ clearLegacyLockFile(basePath);
213
237
 
214
238
  if (!isDbAvailable()) return;
215
239
  try {
216
240
  const projectRoot = normalizeRealPath(basePath);
217
- const worker = findActiveWorkerForCurrentProcess(projectRoot);
241
+ const worker = findStaleWorkerForProject(projectRoot);
218
242
  if (!worker) return;
243
+ markLatestActiveForWorkerCanceled(worker.worker_id, "crash-recovered");
244
+ markWorkerCrashed(worker.worker_id);
219
245
  deleteRuntimeKv("worker", worker.worker_id, SESSION_FILE_KV_KEY);
220
246
  } catch {
221
247
  // Best-effort.
@@ -524,17 +524,18 @@ export function getRecentUnitKeysForProjectRoot(
524
524
  if (!isDbAvailable()) return [];
525
525
  const db = _getAdapter()!;
526
526
  const rows = db.prepare(
527
- `SELECT ud.unit_id
527
+ `SELECT ud.unit_type, ud.unit_id
528
528
  FROM unit_dispatches ud
529
529
  INNER JOIN workers w ON w.worker_id = ud.worker_id
530
530
  WHERE w.project_root_realpath = :project_root_realpath
531
+ AND w.status != 'crashed'
531
532
  ORDER BY ud.started_at DESC, ud.id DESC
532
533
  LIMIT :limit`,
533
534
  ).all({
534
535
  ":project_root_realpath": projectRootRealpath,
535
536
  ":limit": limit,
536
- }) as Array<{ unit_id: string }>;
537
- return rows.reverse().map((r) => ({ key: r.unit_id }));
537
+ }) as Array<{ unit_type: string; unit_id: string }>;
538
+ return rows.reverse().map((r) => ({ key: `${r.unit_type}/${r.unit_id}` }));
538
539
  }
539
540
 
540
541
  /**
@@ -5,7 +5,7 @@ import { findMilestoneIds } from "./guided-flow.js";
5
5
  import { parseUnitId } from "./unit-id.js";
6
6
  import { isDbAvailable, getMilestoneSlices, getMilestone } from "./gsd-db.js";
7
7
  import { parseRoadmap } from "./parsers-legacy.js";
8
- import { isClosedStatus } from "./status-guards.js";
8
+ import { isClosedStatus, isSkippedForDispatch } from "./status-guards.js";
9
9
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
10
10
  import { readFileSync } from "node:fs";
11
11
 
@@ -58,7 +58,7 @@ export function getPriorSliceCompletionBlocker(
58
58
  // DB-backed projects must not treat SUMMARY.md as authoritative.
59
59
  if (isDbAvailable()) {
60
60
  const milestoneRow = getMilestone(mid);
61
- if (milestoneRow && isClosedStatus(milestoneRow.status)) continue;
61
+ if (milestoneRow && isSkippedForDispatch(milestoneRow.status)) continue;
62
62
  } else {
63
63
  const summaryPath = resolveMilestoneFile(base, mid, "SUMMARY");
64
64
  let summaryContent: string | null = null;
@@ -9,7 +9,7 @@ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
9
9
  import { isDbAvailable, getMilestone } from "./gsd-db.js";
10
10
  import { resolveMilestoneFile } from "./paths.js";
11
11
  import { deriveState, isMilestoneComplete } from "./state.js";
12
- import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
12
+ import { createWorktree, listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
13
13
  import { abortAndReset } from "./git-self-heal.js";
14
14
  import { RUNTIME_EXCLUSION_PATHS, resolveMilestoneIntegrationBranch, writeIntegrationBranch } from "./git-service.js";
15
15
  import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached, nativeHasChanges, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeAddTracked, nativeCommit } from "./native-git-bridge.js";
@@ -54,6 +54,19 @@ function isSameOrNestedPath(candidate: string, container: string): boolean {
54
54
  normalizedCandidate.startsWith(`${normalizedContainer}/`);
55
55
  }
56
56
 
57
+ function hasProjectContentOnDisk(dirPath: string): boolean {
58
+ try {
59
+ for (const entry of readdirSync(dirPath, { withFileTypes: true })) {
60
+ if (entry.name === ".git" || entry.name === ".gsd") continue;
61
+ if (entry.name === ".DS_Store") continue;
62
+ return true;
63
+ }
64
+ } catch {
65
+ return false;
66
+ }
67
+ return false;
68
+ }
69
+
57
70
  function getSnapshotDiffCheckFailure(basePath: string): string | null {
58
71
  const failures: string[] = [];
59
72
 
@@ -123,6 +136,37 @@ export async function checkGitHealth(
123
136
  ? await isCompletedMilestoneTerminal(basePath, milestoneId)
124
137
  : false;
125
138
 
139
+ if (!isComplete && !hasProjectContentOnDisk(wt.path) && hasProjectContentOnDisk(basePath)) {
140
+ issues.push({
141
+ severity: "error",
142
+ code: "worktree_empty_with_project_content",
143
+ scope: "milestone",
144
+ unitId: milestoneId,
145
+ message: `Worktree ${wt.path} has no project content, but project root ${basePath} does. Run doctor --fix to recreate the worktree.`,
146
+ fixable: true,
147
+ });
148
+
149
+ if (shouldFix("worktree_empty_with_project_content")) {
150
+ try {
151
+ nativeWorktreeRemove(basePath, wt.path, true);
152
+ const recreated = createWorktree(basePath, milestoneId, {
153
+ branch: wt.branch,
154
+ reuseExistingBranch: true,
155
+ });
156
+ const reset = spawnSync("git", ["reset", "--hard"], {
157
+ cwd: recreated.path,
158
+ encoding: "utf-8",
159
+ });
160
+ if (reset.status !== 0) {
161
+ throw new Error(reset.stderr || reset.error?.message || "git reset --hard failed");
162
+ }
163
+ fixesApplied.push(`recreated empty worktree ${wt.path}`);
164
+ } catch {
165
+ fixesApplied.push(`failed to recreate empty worktree ${wt.path}`);
166
+ }
167
+ }
168
+ }
169
+
126
170
  if (isComplete) {
127
171
  issues.push({
128
172
  severity: "warning",
@@ -7,7 +7,7 @@ import { milestonesDir, gsdRoot, resolveGsdRootFile } from "./paths.js";
7
7
  import { deriveState, isGhostMilestone, isReusableGhostMilestone } from "./state.js";
8
8
  import { saveFile } from "./files.js";
9
9
  import { nativeIsRepo, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
10
- import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
10
+ import { readCrashLock, isLockProcessAlive, clearStaleWorkerLock } from "./crash-recovery.js";
11
11
  import { getActiveAutoWorkers } from "./db/auto-workers.js";
12
12
  import { normalizeRealPath } from "./paths.js";
13
13
  import { ensureGitignore, isGsdGitignored } from "./gitignore.js";
@@ -56,7 +56,7 @@ export async function checkRuntimeHealth(
56
56
  });
57
57
 
58
58
  if (shouldFix("stale_crash_lock")) {
59
- clearLock(basePath);
59
+ clearStaleWorkerLock(basePath);
60
60
  fixesApplied.push("cleared stale auto-mode worker state");
61
61
  }
62
62
  }
@@ -80,17 +80,29 @@ export async function checkRuntimeHealth(
80
80
  // heartbeat for this project?" — readCrashLock returns null for
81
81
  // healthy live workers (it surfaces stale ones only), so we must
82
82
  // consult getActiveAutoWorkers directly.
83
- const projectRoot = normalizeRealPath(basePath);
84
- const activeWorkers = getActiveAutoWorkers().filter(
85
- (w) => w.project_root_realpath === projectRoot && isLockProcessAlive({
86
- pid: w.pid,
87
- startedAt: w.started_at,
88
- unitType: "starting",
89
- unitId: "bootstrap",
90
- unitStartedAt: w.started_at,
91
- }),
92
- );
93
- const lockHolderAlive = activeWorkers.length > 0;
83
+ let lockHolderAlive = false;
84
+ try {
85
+ const projectRoot = normalizeRealPath(basePath);
86
+ for (const worker of getActiveAutoWorkers()) {
87
+ if (worker.project_root_realpath !== projectRoot) continue;
88
+ try {
89
+ if (isLockProcessAlive({
90
+ pid: worker.pid,
91
+ startedAt: worker.started_at,
92
+ unitType: "starting",
93
+ unitId: "bootstrap",
94
+ unitStartedAt: worker.started_at,
95
+ })) {
96
+ lockHolderAlive = true;
97
+ break;
98
+ }
99
+ } catch {
100
+ // Ignore malformed worker rows or transient PID probe failures.
101
+ }
102
+ }
103
+ } catch {
104
+ // If worker lookup fails, continue with the stranded lock diagnosis.
105
+ }
94
106
  if (!lockHolderAlive) {
95
107
  issues.push({
96
108
  severity: "error",
@@ -51,6 +51,7 @@ export type DoctorIssueCode =
51
51
  // Git / worktree integrity checks
52
52
  | "integration_branch_missing"
53
53
  | "worktree_directory_orphaned"
54
+ | "worktree_empty_with_project_content"
54
55
  // GSD state structural checks
55
56
  | "circular_slice_dependency"
56
57
  | "orphaned_slice_directory"
@@ -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[] = [];