gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.1b44e695b

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 (619) hide show
  1. package/README.md +93 -18
  2. package/dist/cli.js +20 -9
  3. package/dist/headless-ui.js +13 -6
  4. package/dist/headless.js +9 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +10 -1
  7. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
  9. package/dist/resources/extensions/cmux/index.js +5 -0
  10. package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
  11. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  12. package/dist/resources/extensions/gsd/auto/loop.js +122 -40
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
  14. package/dist/resources/extensions/gsd/auto/phases.js +134 -49
  15. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  16. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  17. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  18. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  19. package/dist/resources/extensions/gsd/auto-budget.js +9 -0
  20. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  21. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +144 -30
  23. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  24. package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
  25. package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
  26. package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
  27. package/dist/resources/extensions/gsd/auto-start.js +99 -16
  28. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +146 -34
  30. package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
  31. package/dist/resources/extensions/gsd/auto.js +135 -74
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
  35. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  37. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  38. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  40. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  41. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  42. package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
  43. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -2
  45. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  46. package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
  47. package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
  48. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  49. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  50. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  51. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  52. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  53. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  54. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  55. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  57. package/dist/resources/extensions/gsd/doctor.js +2 -28
  58. package/dist/resources/extensions/gsd/export-html.js +27 -425
  59. package/dist/resources/extensions/gsd/forensics.js +10 -3
  60. package/dist/resources/extensions/gsd/git-service.js +152 -15
  61. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  62. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  63. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  64. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  65. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  66. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
  67. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  68. package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
  69. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  70. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  71. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  72. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  73. package/dist/resources/extensions/gsd/paths.js +4 -0
  74. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  75. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  76. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  77. package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
  78. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  79. package/dist/resources/extensions/gsd/preferences-types.js +3 -0
  80. package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
  81. package/dist/resources/extensions/gsd/preferences.js +6 -0
  82. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  83. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  86. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  87. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  88. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  89. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  90. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  91. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  92. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  93. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  94. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  95. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  96. package/dist/resources/extensions/gsd/repo-identity.js +39 -22
  97. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  98. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  99. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  100. package/dist/resources/extensions/gsd/session-lock.js +15 -2
  101. package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
  102. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
  103. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  104. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  105. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  106. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  107. package/dist/resources/extensions/gsd/state.js +28 -7
  108. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  109. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  110. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  111. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  112. package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
  113. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
  114. package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
  115. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  116. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  117. package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
  118. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
  119. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  120. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  121. package/dist/resources/extensions/gsd/validation.js +23 -1
  122. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  123. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  124. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  125. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  126. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  127. package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
  128. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  129. package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
  130. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  131. package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
  132. package/dist/resources/extensions/shared/html-shell.js +388 -0
  133. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  134. package/dist/resources/extensions/shared/next-action-ui.js +13 -5
  135. package/dist/resources/extensions/subagent/index.js +448 -78
  136. package/dist/resources/extensions/subagent/launch.js +77 -0
  137. package/dist/resources/extensions/subagent/run-store.js +148 -0
  138. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  139. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  140. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  141. package/dist/resources/extensions/visual-brief/index.js +5 -0
  142. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  143. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  144. package/dist/resources/skills/forensics/SKILL.md +1 -1
  145. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  146. package/dist/web/standalone/.next/BUILD_ID +1 -1
  147. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  148. package/dist/web/standalone/.next/build-manifest.json +3 -3
  149. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  150. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  151. package/dist/web/standalone/.next/required-server-files.json +1 -1
  152. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  154. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  162. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  165. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  166. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  167. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  169. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  172. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/index.html +1 -1
  175. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  176. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  178. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  180. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  181. package/dist/web/standalone/.next/server/app/page.js +2 -2
  182. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  185. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  186. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  190. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  191. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  192. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  193. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  194. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  195. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  196. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  197. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  198. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  199. package/dist/web/standalone/server.js +1 -1
  200. package/package.json +4 -4
  201. package/packages/contracts/dist/rpc.test.js +7 -0
  202. package/packages/contracts/dist/rpc.test.js.map +1 -1
  203. package/packages/contracts/dist/workflow.d.ts +21 -0
  204. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  205. package/packages/contracts/dist/workflow.js +24 -0
  206. package/packages/contracts/dist/workflow.js.map +1 -1
  207. package/packages/contracts/src/rpc.test.ts +8 -0
  208. package/packages/contracts/src/workflow.ts +24 -0
  209. package/packages/daemon/package.json +2 -2
  210. package/packages/mcp-server/README.md +13 -4
  211. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  212. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  213. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  214. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  215. package/packages/mcp-server/package.json +2 -2
  216. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  217. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  218. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  219. package/packages/native/package.json +1 -1
  220. package/packages/native/tsconfig.json +2 -1
  221. package/packages/native/tsconfig.tsbuildinfo +1 -1
  222. package/packages/pi-agent-core/package.json +1 -1
  223. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  224. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  225. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  226. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  227. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  228. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  229. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  230. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  231. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  232. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  233. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  234. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  235. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  236. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  237. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  238. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  239. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  240. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  241. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  242. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  243. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  244. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  245. package/packages/pi-ai/package.json +1 -1
  246. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  247. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  248. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  249. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  250. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  251. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  252. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  253. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  256. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  258. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  260. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
  262. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  264. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  266. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  268. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  280. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  288. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  289. package/packages/pi-coding-agent/package.json +1 -1
  290. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  291. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  292. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  293. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  294. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  295. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  296. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  297. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  298. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  299. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
  300. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  301. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  302. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  303. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  304. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  305. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  306. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  307. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  308. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  309. package/packages/pi-tui/dist/__tests__/tui.test.js +45 -2
  310. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  311. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  312. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  313. package/packages/pi-tui/dist/terminal.js +12 -0
  314. package/packages/pi-tui/dist/terminal.js.map +1 -1
  315. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  316. package/packages/pi-tui/dist/tui.js +106 -27
  317. package/packages/pi-tui/dist/tui.js.map +1 -1
  318. package/packages/pi-tui/package.json +1 -1
  319. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  320. package/packages/pi-tui/src/__tests__/tui.test.ts +59 -2
  321. package/packages/pi-tui/src/terminal.ts +11 -0
  322. package/packages/pi-tui/src/tui.ts +108 -27
  323. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  324. package/packages/rpc-client/package.json +1 -1
  325. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  326. package/pkg/package.json +1 -1
  327. package/src/resources/GSD-WORKFLOW.md +10 -1
  328. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  329. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  330. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  331. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  332. package/src/resources/extensions/cmux/index.ts +6 -0
  333. package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
  334. package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
  335. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  336. package/src/resources/extensions/gsd/auto/loop.ts +123 -40
  337. package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
  338. package/src/resources/extensions/gsd/auto/phases.ts +160 -60
  339. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  340. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  341. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  342. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  343. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  344. package/src/resources/extensions/gsd/auto-budget.ts +11 -0
  345. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  346. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  347. package/src/resources/extensions/gsd/auto-dispatch.ts +164 -29
  348. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  349. package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
  350. package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
  351. package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
  352. package/src/resources/extensions/gsd/auto-start.ts +109 -14
  353. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  354. package/src/resources/extensions/gsd/auto-verification.ts +174 -42
  355. package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
  356. package/src/resources/extensions/gsd/auto.ts +172 -81
  357. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
  358. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
  359. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
  360. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  361. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  362. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  363. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  364. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  365. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  366. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  367. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  368. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  369. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +11 -3
  370. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  371. package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
  372. package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
  373. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  374. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  375. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  376. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  377. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  378. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  379. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  380. package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
  381. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  382. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  383. package/src/resources/extensions/gsd/doctor.ts +2 -27
  384. package/src/resources/extensions/gsd/export-html.ts +27 -427
  385. package/src/resources/extensions/gsd/forensics.ts +9 -3
  386. package/src/resources/extensions/gsd/git-service.ts +182 -16
  387. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  388. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  389. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  390. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  391. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  392. package/src/resources/extensions/gsd/journal.ts +8 -1
  393. package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
  394. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  395. package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
  396. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  397. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  398. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  399. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  400. package/src/resources/extensions/gsd/paths.ts +5 -0
  401. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  402. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  403. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  404. package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
  405. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  406. package/src/resources/extensions/gsd/preferences-types.ts +35 -0
  407. package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
  408. package/src/resources/extensions/gsd/preferences.ts +9 -0
  409. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  410. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  411. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  412. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  413. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  414. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  415. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  416. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  417. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  418. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  419. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  421. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  422. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  423. package/src/resources/extensions/gsd/repo-identity.ts +45 -25
  424. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  425. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  426. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  427. package/src/resources/extensions/gsd/session-lock.ts +15 -2
  428. package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
  429. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
  430. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  431. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  432. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  433. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  434. package/src/resources/extensions/gsd/state.ts +33 -7
  435. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  436. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  437. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  438. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  439. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  440. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  441. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  442. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  443. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
  444. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
  445. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  446. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  447. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  448. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
  449. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
  450. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  451. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  452. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  453. package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
  454. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  455. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  456. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  457. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  458. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  459. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  460. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  461. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  462. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
  463. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
  464. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  465. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  466. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  467. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  468. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  469. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  470. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +111 -1
  471. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  472. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
  473. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  474. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  475. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  476. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
  477. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
  478. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  479. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  480. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  481. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  482. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  483. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  484. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  485. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  486. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  487. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  488. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  489. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  490. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  491. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  492. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
  493. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
  494. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
  495. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  496. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
  497. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  498. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  499. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  500. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  501. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  502. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
  503. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
  504. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  505. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  506. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  507. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  508. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  509. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  510. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  511. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  512. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  513. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  514. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  515. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  516. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  517. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
  518. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  519. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
  520. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  521. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  522. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  523. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
  524. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
  525. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  526. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  527. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  528. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  529. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  530. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
  531. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  532. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  533. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
  534. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
  535. package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
  536. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
  537. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  538. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
  539. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  540. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  541. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  542. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  543. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  544. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  546. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  547. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  548. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  549. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
  550. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  551. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
  552. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  553. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  554. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  555. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  556. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
  557. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  558. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  559. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
  560. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  561. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
  562. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  563. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
  564. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  565. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  566. package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
  567. package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
  568. package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
  569. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  570. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  571. package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
  572. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
  573. package/src/resources/extensions/gsd/types.ts +1 -1
  574. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  575. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  576. package/src/resources/extensions/gsd/validation.ts +23 -1
  577. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  578. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  579. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  580. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  581. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  582. package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
  583. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  584. package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
  585. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  586. package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
  587. package/src/resources/extensions/shared/html-shell.ts +412 -0
  588. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  589. package/src/resources/extensions/shared/next-action-ui.ts +11 -5
  590. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  591. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
  592. package/src/resources/extensions/subagent/index.ts +567 -103
  593. package/src/resources/extensions/subagent/launch.ts +131 -0
  594. package/src/resources/extensions/subagent/run-store.ts +218 -0
  595. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  596. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  597. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  598. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  599. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  600. package/src/resources/extensions/visual-brief/index.ts +8 -0
  601. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  602. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  603. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  604. package/src/resources/skills/forensics/SKILL.md +1 -1
  605. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  606. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  607. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  608. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  610. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  611. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  612. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  613. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  614. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  615. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  616. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  617. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  618. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_buildManifest.js +0 -0
  619. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → Z8H5evS-hDo0qdP22XJPA}/_ssgManifest.js +0 -0
@@ -19,14 +19,15 @@ import {
19
19
  insertMilestone,
20
20
  _getAdapter,
21
21
  } from "../gsd-db.ts";
22
- import { registerAutoWorker } from "../db/auto-workers.ts";
22
+ import { getAutoWorker, registerAutoWorker } from "../db/auto-workers.ts";
23
23
  import { claimMilestoneLease } from "../db/milestone-leases.ts";
24
- import { recordDispatchClaim } from "../db/unit-dispatches.ts";
24
+ import { getLatestForUnit, markRunning, recordDispatchClaim } from "../db/unit-dispatches.ts";
25
25
  import { setRuntimeKv, getRuntimeKv } from "../db/runtime-kv.ts";
26
26
  import {
27
27
  writeLock,
28
28
  readCrashLock,
29
29
  clearLock,
30
+ clearStaleWorkerLock,
30
31
  isLockProcessAlive,
31
32
  } from "../crash-recovery.ts";
32
33
  import { normalizeRealPath } from "../paths.ts";
@@ -206,6 +207,24 @@ test("writeLock stores the session_file in runtime_kv (worker scope)", (t) => {
206
207
  assert.equal(lock!.sessionFile, "/tmp/session-xyz.jsonl");
207
208
  });
208
209
 
210
+ test("writeLock without session file clears stale worker session_file pointer", (t) => {
211
+ const base = makeBase();
212
+ t.after(() => cleanup(base));
213
+ openDatabase(join(base, ".gsd", "gsd.db"));
214
+ const projectRoot = normalizeRealPath(base);
215
+ const workerId = registerAutoWorker({ projectRootRealpath: projectRoot });
216
+
217
+ writeLock(base, "plan-slice", "M001/S01", "/tmp/session-stale.jsonl");
218
+ assert.equal(getRuntimeKv("worker", workerId, "session_file"), "/tmp/session-stale.jsonl");
219
+
220
+ writeLock(base, "execute-task", "M001/S01/T01");
221
+ assert.equal(
222
+ getRuntimeKv("worker", workerId, "session_file"),
223
+ null,
224
+ "preliminary lock write must clear stale session_file pointer",
225
+ );
226
+ });
227
+
209
228
  test("clearLock removes the session_file row for the active worker", (t) => {
210
229
  const base = makeBase();
211
230
  t.after(() => cleanup(base));
@@ -223,3 +242,86 @@ test("clearLock removes the session_file row for the active worker", (t) => {
223
242
  assert.equal(getRuntimeKv("worker", workerId, "session_file"), null,
224
243
  "session_file row deleted by clearLock");
225
244
  });
245
+
246
+ test("clearLock marks stale worker crashed when no current-process worker matches", (t) => {
247
+ const base = makeBase();
248
+ t.after(() => cleanup(base));
249
+ openDatabase(join(base, ".gsd", "gsd.db"));
250
+ const projectRoot = normalizeRealPath(base);
251
+ const workerId = registerAutoWorker({ projectRootRealpath: projectRoot });
252
+
253
+ setRuntimeKv("worker", workerId, "session_file", "/tmp/stale-session.jsonl");
254
+ setWorkerPid(workerId, 99999);
255
+ expireWorker(workerId);
256
+ assert.ok(readCrashLock(base), "stale worker is detected before clearLock");
257
+
258
+ clearLock(base);
259
+
260
+ assert.equal(getAutoWorker(workerId)?.status, "crashed");
261
+ assert.equal(getRuntimeKv("worker", workerId, "session_file"), null);
262
+ assert.equal(readCrashLock(base), null);
263
+ });
264
+
265
+ test("clearStaleWorkerLock crashes stale worker and cancels latest active dispatch", (t) => {
266
+ const base = makeBase();
267
+ t.after(() => cleanup(base));
268
+ openDatabase(join(base, ".gsd", "gsd.db"));
269
+ insertMilestone({ id: "M001", title: "T", status: "active" });
270
+ const projectRoot = normalizeRealPath(base);
271
+ const workerId = registerAutoWorker({ projectRootRealpath: projectRoot });
272
+ const lease = claimMilestoneLease(workerId, "M001");
273
+ assert.equal(lease.ok, true);
274
+ if (!lease.ok) return;
275
+ const claim = recordDispatchClaim({
276
+ traceId: "t1",
277
+ workerId,
278
+ milestoneLeaseToken: lease.token,
279
+ milestoneId: "M001",
280
+ sliceId: "S01",
281
+ taskId: "T02",
282
+ unitType: "hook/codex-review",
283
+ unitId: "M001/S01/T02",
284
+ });
285
+ assert.equal(claim.ok, true);
286
+ if (!claim.ok) return;
287
+ markRunning(claim.dispatchId);
288
+ setRuntimeKv("worker", workerId, "session_file", "/tmp/pi-session-hook.jsonl");
289
+ setWorkerPid(workerId, 99999);
290
+ expireWorker(workerId);
291
+
292
+ assert.ok(readCrashLock(base), "stale worker is detected before cleanup");
293
+
294
+ clearStaleWorkerLock(base);
295
+
296
+ assert.equal(getAutoWorker(workerId)?.status, "crashed");
297
+ const dispatch = getLatestForUnit("M001/S01/T02");
298
+ assert.ok(dispatch);
299
+ assert.equal(dispatch!.status, "canceled");
300
+ assert.equal(dispatch!.exit_reason, "crash-recovered");
301
+ assert.equal(getRuntimeKv("worker", workerId, "session_file"), null);
302
+ assert.equal(readCrashLock(base), null);
303
+ });
304
+
305
+ test("clearLock marks stale worker crashed and releases held milestone lease", (t) => {
306
+ const base = makeBase();
307
+ t.after(() => cleanup(base));
308
+ openDatabase(join(base, ".gsd", "gsd.db"));
309
+ insertMilestone({ id: "M001", title: "T", status: "active" });
310
+ const projectRoot = normalizeRealPath(base);
311
+ const workerId = registerAutoWorker({ projectRootRealpath: projectRoot });
312
+ const lease = claimMilestoneLease(workerId, "M001");
313
+ assert.equal(lease.ok, true);
314
+ if (!lease.ok) return;
315
+
316
+ setWorkerPid(workerId, 99999);
317
+ expireWorker(workerId);
318
+ assert.ok(readCrashLock(base), "stale worker is detected before clearLock");
319
+
320
+ clearLock(base);
321
+
322
+ assert.equal(getAutoWorker(workerId)?.status, "crashed");
323
+ const leaseRow = _getAdapter()!.prepare(
324
+ `SELECT status FROM milestone_leases WHERE milestone_id = :m`,
325
+ ).get({ ":m": "M001" }) as { status: string } | undefined;
326
+ assert.equal(leaseRow?.status, "released");
327
+ });
@@ -98,6 +98,8 @@ function makeMockPi() {
98
98
  sendMessage: (...args: unknown[]) => {
99
99
  calls.push(args);
100
100
  },
101
+ getThinkingLevel: () => "off",
102
+ setThinkingLevel: () => {},
101
103
  calls,
102
104
  } as any;
103
105
  }
@@ -0,0 +1,208 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Regression tests for DB authority over markdown projections.
3
+
4
+ import test from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { tmpdir } from "node:os";
9
+
10
+ import {
11
+ closeDatabase,
12
+ getAllMilestones,
13
+ getSliceTasks,
14
+ insertMilestone,
15
+ insertRequirement,
16
+ insertSlice,
17
+ openDatabase,
18
+ } from "../gsd-db.ts";
19
+ import { migrateHierarchyToDb } from "../md-importer.ts";
20
+ import { checkMarkdownHierarchyAgainstDb } from "../migration-auto-check.ts";
21
+ import { queryDecisions } from "../context-store.ts";
22
+ import { deriveStateFromDb, invalidateStateCache } from "../state.ts";
23
+ import type { Requirement } from "../types.ts";
24
+
25
+ function makeBase(prefix = "gsd-db-authority-"): string {
26
+ const base = mkdtempSync(join(tmpdir(), prefix));
27
+ mkdirSync(join(base, ".gsd"), { recursive: true });
28
+ return base;
29
+ }
30
+
31
+ function cleanup(base: string): void {
32
+ try {
33
+ closeDatabase();
34
+ } catch {
35
+ /* noop */
36
+ }
37
+ rmSync(base, { recursive: true, force: true });
38
+ }
39
+
40
+ function openProjectDb(base: string): void {
41
+ openDatabase(join(base, ".gsd", "gsd.db"));
42
+ }
43
+
44
+ function activeRequirement(id: string): Requirement {
45
+ return {
46
+ id,
47
+ class: "functional",
48
+ status: "active",
49
+ description: `${id} from DB`,
50
+ why: "DB authority regression fixture",
51
+ source: "test",
52
+ primary_owner: "M999/S01",
53
+ supporting_slices: "",
54
+ validation: "derive state",
55
+ notes: "",
56
+ full_content: `${id} from DB`,
57
+ superseded_by: null,
58
+ };
59
+ }
60
+
61
+ test("DB authority: PROJECT.md and QUEUE-ORDER projections do not choose runtime milestone", async (t) => {
62
+ const base = makeBase();
63
+ t.after(() => cleanup(base));
64
+
65
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
66
+ writeFileSync(
67
+ join(base, ".gsd", "PROJECT.md"),
68
+ [
69
+ "# Projection Project",
70
+ "",
71
+ "## Milestone Sequence",
72
+ "- [ ] M001: Projection Only -- should not become active",
73
+ "",
74
+ ].join("\n"),
75
+ );
76
+ writeFileSync(
77
+ join(base, ".gsd", "QUEUE-ORDER.json"),
78
+ JSON.stringify({ order: ["M001", "M999"], updatedAt: new Date().toISOString() }),
79
+ );
80
+
81
+ openProjectDb(base);
82
+ insertMilestone({ id: "M999", title: "DB Milestone", status: "active" });
83
+ insertSlice({ id: "S01", milestoneId: "M999", title: "DB Slice", status: "pending", risk: "low", depends: [], demo: "DB demo", sequence: 1 });
84
+
85
+ invalidateStateCache();
86
+ const state = await deriveStateFromDb(base);
87
+
88
+ assert.equal(state.activeMilestone?.id, "M999");
89
+ assert.equal(state.registry.some((entry) => entry.id === "M001"), false);
90
+ });
91
+
92
+ test("DB authority: REQUIREMENTS.md and DECISIONS.md projections do not populate DB reads", async (t) => {
93
+ const base = makeBase();
94
+ t.after(() => cleanup(base));
95
+
96
+ writeFileSync(
97
+ join(base, ".gsd", "REQUIREMENTS.md"),
98
+ [
99
+ "# Requirements",
100
+ "",
101
+ "## Active",
102
+ "### R001 - Projection-only requirement",
103
+ "- Class: functional",
104
+ "- Status: active",
105
+ "",
106
+ ].join("\n"),
107
+ );
108
+ writeFileSync(
109
+ join(base, ".gsd", "DECISIONS.md"),
110
+ [
111
+ "# Decisions",
112
+ "",
113
+ "| # | When / Context | Scope | Decision | Choice | Rationale | Revisable | Made By |",
114
+ "|---|----------------|-------|----------|--------|-----------|----------|---------|",
115
+ "| D001 | Now | global | Projection-only decision | Ignore | DB is authority | Yes | human |",
116
+ "",
117
+ ].join("\n"),
118
+ );
119
+
120
+ openProjectDb(base);
121
+ insertMilestone({ id: "M999", title: "DB Milestone", status: "active" });
122
+
123
+ invalidateStateCache();
124
+ const state = await deriveStateFromDb(base);
125
+
126
+ assert.deepEqual(state.requirements, {
127
+ active: 0,
128
+ validated: 0,
129
+ deferred: 0,
130
+ outOfScope: 0,
131
+ blocked: 0,
132
+ total: 0,
133
+ });
134
+ assert.deepEqual(queryDecisions(), []);
135
+ });
136
+
137
+ test("DB authority: DB requirements remain canonical when REQUIREMENTS.md disagrees", async (t) => {
138
+ const base = makeBase();
139
+ t.after(() => cleanup(base));
140
+
141
+ writeFileSync(
142
+ join(base, ".gsd", "REQUIREMENTS.md"),
143
+ [
144
+ "# Requirements",
145
+ "",
146
+ "## Active",
147
+ "### R999 - Projection-only requirement",
148
+ "- Class: functional",
149
+ "- Status: active",
150
+ "",
151
+ ].join("\n"),
152
+ );
153
+
154
+ openProjectDb(base);
155
+ insertMilestone({ id: "M999", title: "DB Milestone", status: "active" });
156
+ insertRequirement(activeRequirement("R001"));
157
+
158
+ invalidateStateCache();
159
+ const state = await deriveStateFromDb(base);
160
+
161
+ assert.ok(state.requirements);
162
+ assert.equal(state.requirements.active, 1);
163
+ assert.equal(state.requirements.total, 1);
164
+ });
165
+
166
+ test("explicit markdown import remains opt-in and is not run by startup mismatch check", async (t) => {
167
+ const base = makeBase();
168
+ t.after(() => cleanup(base));
169
+
170
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
171
+ const sliceDir = join(milestoneDir, "slices", "S01");
172
+ const tasksDir = join(sliceDir, "tasks");
173
+ mkdirSync(tasksDir, { recursive: true });
174
+ writeFileSync(
175
+ join(milestoneDir, "M001-ROADMAP.md"),
176
+ [
177
+ "# M001: Imported Explicitly",
178
+ "",
179
+ "**Vision:** Explicit recovery import only",
180
+ "",
181
+ "## Slices",
182
+ "- [ ] **S01: Slice** `risk:low` `depends:[]`",
183
+ "",
184
+ ].join("\n"),
185
+ );
186
+ writeFileSync(
187
+ join(sliceDir, "S01-PLAN.md"),
188
+ [
189
+ "# S01: Slice",
190
+ "",
191
+ "**Goal:** prove explicit import",
192
+ "",
193
+ "## Tasks",
194
+ "- [ ] **T01: Task** `est:5m`",
195
+ "",
196
+ ].join("\n"),
197
+ );
198
+
199
+ openProjectDb(base);
200
+ const check = await checkMarkdownHierarchyAgainstDb(base);
201
+ assert.equal(check.action, "recovery-required");
202
+ assert.equal(getAllMilestones().length, 0, "startup mismatch check must not import markdown");
203
+
204
+ const imported = migrateHierarchyToDb(base);
205
+ assert.deepEqual(imported, { milestones: 1, slices: 1, tasks: 1 });
206
+ assert.equal(getAllMilestones().length, 1);
207
+ assert.equal(getSliceTasks("M001", "S01").length, 1);
208
+ });
@@ -47,6 +47,7 @@ describe("db-task-slice-rows", () => {
47
47
  replan_triggered_at: null,
48
48
  is_sketch: 0,
49
49
  sketch_scope: "",
50
+ target_repositories: [],
50
51
  });
51
52
  });
52
53
 
@@ -1,6 +1,6 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
3
+ import { chmodSync, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { execFileSync } from "node:child_process";
5
5
  import { tmpdir } from "node:os";
6
6
  import { join } from "node:path";
@@ -10,7 +10,7 @@ import { runDispatch, runPreDispatch } from "../auto/phases.ts";
10
10
  import { AutoSession } from "../auto/session.ts";
11
11
  import { resolveUnitSupervisionTimeouts } from "../auto-timers.ts";
12
12
  import { bootstrapAutoSession } from "../auto-start.ts";
13
- import { postUnitPreVerification } from "../auto-post-unit.ts";
13
+ import { postUnitPostVerification, postUnitPreVerification } from "../auto-post-unit.ts";
14
14
  import { resolveDispatch, setResearchProjectPromptBuilderForTest } from "../auto-dispatch.ts";
15
15
  import { resolveExpectedArtifactPath, verifyExpectedArtifact, writeBlockerPlaceholder } from "../auto-recovery.ts";
16
16
  import { finalizeProjectResearchTimeout } from "../project-research-policy.ts";
@@ -272,6 +272,7 @@ test("deep project setup: bootstrap can start auto-mode without an active milest
272
272
  {
273
273
  shouldUseWorktreeIsolation: () => false,
274
274
  registerSigtermHandler: () => {},
275
+ registerAutoWorkerForSession: () => {},
275
276
  lockBase: () => base,
276
277
  buildLifecycle: () => ({
277
278
  adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
@@ -386,6 +387,7 @@ test("deep project setup: bootstrap continues queued M002 without milestone cont
386
387
  {
387
388
  shouldUseWorktreeIsolation: () => false,
388
389
  registerSigtermHandler: () => {},
390
+ registerAutoWorkerForSession: () => {},
389
391
  lockBase: () => base,
390
392
  buildLifecycle: () => ({
391
393
  adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
@@ -1587,6 +1589,63 @@ test("deep project setup: discuss-milestone question failure pauses instead of a
1587
1589
  }
1588
1590
  });
1589
1591
 
1592
+ test("verified task git closeout failure retries and continues auto-mode", async () => {
1593
+ const base = makeBase();
1594
+ try {
1595
+ execFileSync("git", ["init"], { cwd: base, stdio: "ignore" });
1596
+ execFileSync("git", ["config", "user.email", "test@example.com"], { cwd: base, stdio: "ignore" });
1597
+ execFileSync("git", ["config", "user.name", "Test User"], { cwd: base, stdio: "ignore" });
1598
+ const hookPath = join(base, ".git", "hooks", "pre-commit");
1599
+ writeFileSync(
1600
+ hookPath,
1601
+ [
1602
+ "#!/bin/sh",
1603
+ "count_file=.git/pre-commit-count",
1604
+ "count=0",
1605
+ "if [ -f \"$count_file\" ]; then count=$(cat \"$count_file\"); fi",
1606
+ "count=$((count + 1))",
1607
+ "printf \"%s\" \"$count\" > \"$count_file\"",
1608
+ "echo blocked by test hook >&2",
1609
+ "exit 1",
1610
+ ].join("\n"),
1611
+ );
1612
+ chmodSync(hookPath, 0o755);
1613
+ writeFileSync(join(base, "work.txt"), "changed\n");
1614
+
1615
+ const s = new AutoSession();
1616
+ s.active = true;
1617
+ s.basePath = base;
1618
+ s.originalBasePath = base;
1619
+ s.currentUnit = { type: "execute-task", id: "M001/S01/T01", startedAt: Date.now() };
1620
+
1621
+ let pauseCalled = false;
1622
+ const notifications: Array<{ message: string; severity?: string }> = [];
1623
+ const result = await postUnitPostVerification({
1624
+ s,
1625
+ ctx: { ui: { notify: (message: string, severity?: string) => notifications.push({ message, severity }) } } as any,
1626
+ pi: {} as any,
1627
+ buildSnapshotOpts: () => ({}) as any,
1628
+ lockBase: () => base,
1629
+ stopAuto: async () => {},
1630
+ pauseAuto: async () => { pauseCalled = true; },
1631
+ updateProgressWidget: () => {},
1632
+ });
1633
+
1634
+ assert.equal(result, "continue");
1635
+ assert.equal(pauseCalled, false);
1636
+ assert.equal(s.lastGitActionStatus, "failed");
1637
+ const preCommitCount = Number(readFileSync(join(base, ".git", "pre-commit-count"), "utf-8"));
1638
+ assert.equal(Number.isFinite(preCommitCount), true);
1639
+ assert.ok(preCommitCount >= 3, "git closeout should retry the failing commit path");
1640
+ assert.ok(
1641
+ notifications.some((entry) => entry.severity === "warning" && entry.message.includes("Git commit failed")),
1642
+ "verified task git closeout failure should warn instead of stopping auto-mode",
1643
+ );
1644
+ } finally {
1645
+ rmSync(base, { recursive: true, force: true });
1646
+ }
1647
+ });
1648
+
1590
1649
  test("deep project setup: approval wait wins over deterministic write-gate placeholder", async () => {
1591
1650
  const base = makeBase();
1592
1651
  try {
@@ -10,9 +10,10 @@ import assert from "node:assert/strict";
10
10
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
+ import { execFileSync } from "node:child_process";
13
14
 
14
15
  import { DISPATCH_RULES, type DispatchContext } from "../auto-dispatch.ts";
15
- import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
16
+ import { closeDatabase, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
16
17
 
17
18
  function makeBase(): string {
18
19
  const base = mkdtempSync(join(tmpdir(), "gsd-complete-dispatch-"));
@@ -23,6 +24,14 @@ function makeBase(): string {
23
24
  return base;
24
25
  }
25
26
 
27
+ function initGitRepo(base: string): void {
28
+ execFileSync("git", ["init"], { cwd: base, stdio: "ignore" });
29
+ execFileSync("git", ["config", "user.email", "test@test.com"], { cwd: base, stdio: "ignore" });
30
+ execFileSync("git", ["config", "user.name", "Test"], { cwd: base, stdio: "ignore" });
31
+ execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
32
+ execFileSync("git", ["commit", "-m", "initial"], { cwd: base, stdio: "ignore" });
33
+ }
34
+
26
35
  function buildDispatchCtx(basePath: string): DispatchContext {
27
36
  return {
28
37
  basePath,
@@ -76,6 +85,68 @@ describe("completing-milestone dispatch guard (#4324)", () => {
76
85
  assert.equal(result?.unitType, "complete-milestone");
77
86
  assert.equal(result?.unitId, "M001");
78
87
  });
88
+
89
+ test("dispatches complete-milestone when only .gsd/ files exist in git history (#5097)", async () => {
90
+ base = makeBase();
91
+ rmSync(join(base, "implementation.txt"), { force: true });
92
+ initGitRepo(base);
93
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"), "# Milestone Summary\n");
94
+ execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
95
+ execFileSync("git", ["commit", "-m", "chore: planning artifacts only"], { cwd: base, stdio: "ignore" });
96
+
97
+ const result = await rule.match(buildDispatchCtx(base));
98
+
99
+ assert.equal(result?.action, "dispatch");
100
+ assert.equal(result?.unitType, "complete-milestone");
101
+ assert.equal(result?.unitId, "M001");
102
+ });
103
+
104
+ test("blocks complete-milestone dispatch when the working tree is dirty (#6132)", async () => {
105
+ base = makeBase();
106
+ initGitRepo(base);
107
+ writeFileSync(join(base, "implementation.txt"), "dirty\n");
108
+
109
+ const result = await rule.match(buildDispatchCtx(base));
110
+
111
+ assert.equal(result?.action, "stop");
112
+ assert.match(result?.reason ?? "", /uncommitted changes detected/i);
113
+ });
114
+
115
+ test("blocks complete-milestone dispatch when UAT verdict is non-PASS and uat_dispatch is enabled (#6132)", async () => {
116
+ base = makeBase();
117
+ openDatabase(join(base, ".gsd", "gsd.db"));
118
+ insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
119
+ insertSlice({ milestoneId: "M001", id: "S01", title: "Done", status: "complete" });
120
+ writeFileSync(
121
+ join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-ASSESSMENT.md"),
122
+ "---\nverdict: fail\n---\n\nUAT failed.\n",
123
+ );
124
+
125
+ const ctx = buildDispatchCtx(base);
126
+ ctx.prefs = { uat_dispatch: true } as DispatchContext["prefs"];
127
+ const result = await rule.match(ctx);
128
+
129
+ assert.equal(result?.action, "stop");
130
+ assert.match(result?.reason ?? "", /manual UAT sign-off \(PASS\) is required/i);
131
+ });
132
+
133
+ test("blocks complete-milestone dispatch when UAT verdict is missing and uat_dispatch is enabled (#6132)", async () => {
134
+ base = makeBase();
135
+ openDatabase(join(base, ".gsd", "gsd.db"));
136
+ insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
137
+ insertSlice({ milestoneId: "M001", id: "S01", title: "Done", status: "complete" });
138
+ writeFileSync(
139
+ join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-ASSESSMENT.md"),
140
+ "# UAT\n\nNo verdict yet.\n",
141
+ );
142
+
143
+ const ctx = buildDispatchCtx(base);
144
+ ctx.prefs = { uat_dispatch: true } as DispatchContext["prefs"];
145
+ const result = await rule.match(ctx);
146
+
147
+ assert.equal(result?.action, "stop");
148
+ assert.match(result?.reason ?? "", /manual UAT sign-off \(PASS\) is required/i);
149
+ });
79
150
  });
80
151
 
81
152
  describe("complete phase dispatch guard (#5683)", () => {
@@ -118,3 +189,42 @@ describe("complete phase dispatch guard (#5683)", () => {
118
189
  assert.equal(result?.reason, "All milestones complete.");
119
190
  });
120
191
  });
192
+
193
+ describe("complete milestone context recovery guard (#5831)", () => {
194
+ let base = "";
195
+ const executionEntryRule = DISPATCH_RULES.find(
196
+ (candidate) => candidate.name === "execution-entry phase (no context) → discuss-milestone",
197
+ );
198
+ const prePlanningRule = DISPATCH_RULES.find(
199
+ (candidate) => candidate.name === "pre-planning (no context) → discuss-milestone",
200
+ );
201
+ assert.ok(executionEntryRule, "execution-entry missing-context rule should exist");
202
+ assert.ok(prePlanningRule, "pre-planning missing-context rule should exist");
203
+
204
+ afterEach(() => {
205
+ if (base) rmSync(base, { recursive: true, force: true });
206
+ base = "";
207
+ });
208
+
209
+ test("does not discuss a complete execution-entry milestone with no CONTEXT file", async () => {
210
+ base = makeBase();
211
+ const ctx = buildDispatchCtx(base);
212
+ ctx.state.registry = [{ id: "M001", title: "Milestone One", status: "complete" }];
213
+ ctx.state.phase = "completing-milestone";
214
+
215
+ const result = await executionEntryRule.match(ctx);
216
+
217
+ assert.equal(result, null);
218
+ });
219
+
220
+ test("does not discuss a complete pre-planning milestone with no CONTEXT file", async () => {
221
+ base = makeBase();
222
+ const ctx = buildDispatchCtx(base);
223
+ ctx.state.registry = [{ id: "M001", title: "Milestone One", status: "complete" }];
224
+ ctx.state.phase = "pre-planning";
225
+
226
+ const result = await prePlanningRule.match(ctx);
227
+
228
+ assert.equal(result, null);
229
+ });
230
+ });
@@ -3,7 +3,7 @@ import assert from "node:assert/strict";
3
3
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
- import { getPriorSliceCompletionBlocker } from "../dispatch-guard.ts";
6
+ import { getConsecutiveDispatchBlocker, getPriorSliceCompletionBlocker } from "../dispatch-guard.ts";
7
7
  import { openDatabase, closeDatabase, insertMilestone, insertSlice } from "../gsd-db.ts";
8
8
 
9
9
  /** Helper: create temp dir and open an in-dir DB for dispatch-guard tests */
@@ -47,6 +47,33 @@ test("dispatch guard blocks when prior milestone has incomplete slices", (t) =>
47
47
  );
48
48
  });
49
49
 
50
+ test("dispatch guard skips prior DB parked or deferred milestones without marker files", (t) => {
51
+ const repo = setupRepo();
52
+ t.after(() => teardownRepo(repo));
53
+
54
+ mkdirSync(join(repo, ".gsd", "milestones", "M001"), { recursive: true });
55
+ mkdirSync(join(repo, ".gsd", "milestones", "M002"), { recursive: true });
56
+ mkdirSync(join(repo, ".gsd", "milestones", "M003"), { recursive: true });
57
+
58
+ insertMilestone({ id: "M001", title: "Parked", status: "parked" });
59
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Incomplete", status: "pending", depends: [], sequence: 1 });
60
+
61
+ insertMilestone({ id: "M002", title: "Deferred", status: "deferred" });
62
+ insertSlice({ id: "S01", milestoneId: "M002", title: "Incomplete", status: "pending", depends: [], sequence: 1 });
63
+
64
+ insertMilestone({ id: "M003", title: "Current", status: "active" });
65
+ insertSlice({ id: "S01", milestoneId: "M003", title: "First", status: "pending", depends: [], sequence: 1 });
66
+
67
+ writeFileSync(join(repo, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# M001\n");
68
+ writeFileSync(join(repo, ".gsd", "milestones", "M002", "M002-ROADMAP.md"), "# M002\n");
69
+ writeFileSync(join(repo, ".gsd", "milestones", "M003", "M003-ROADMAP.md"), "# M003\n");
70
+
71
+ assert.equal(
72
+ getPriorSliceCompletionBlocker(repo, "main", "plan-slice", "M003/S01"),
73
+ null,
74
+ );
75
+ });
76
+
50
77
  test("dispatch guard blocks later slice in same milestone when earlier incomplete", (t) => {
51
78
  const repo = setupRepo();
52
79
  t.after(() => teardownRepo(repo));
@@ -254,6 +281,46 @@ test("dispatch guard does not skip prior milestone from SUMMARY projection when
254
281
  );
255
282
  });
256
283
 
284
+ test("consecutive dispatch guard blocks complete-milestone after repeat cap", () => {
285
+ // REPEAT_CAP = 2: two same-unit dispatches are allowed; the third is blocked.
286
+ const state = {
287
+ consecutiveDispatchCount: new Map<string, number>(),
288
+ lastDispatchedKey: null as string | null,
289
+ lastDispatchPhase: null as string | null,
290
+ };
291
+
292
+ assert.equal(getConsecutiveDispatchBlocker(state, "completing-milestone", "complete-milestone", "M009"), null);
293
+ assert.equal(getConsecutiveDispatchBlocker(state, "completing-milestone", "complete-milestone", "M009"), null);
294
+ assert.match(
295
+ getConsecutiveDispatchBlocker(state, "completing-milestone", "complete-milestone", "M009") ?? "",
296
+ /same-unit repeat cap reached/,
297
+ );
298
+ });
299
+
300
+ test("consecutive dispatch guard resets when unit changes", () => {
301
+ const state = {
302
+ consecutiveDispatchCount: new Map<string, number>(),
303
+ lastDispatchedKey: null as string | null,
304
+ lastDispatchPhase: null as string | null,
305
+ };
306
+
307
+ assert.equal(getConsecutiveDispatchBlocker(state, "validating-milestone", "validate-milestone", "M001"), null);
308
+ assert.equal(getConsecutiveDispatchBlocker(state, "validating-milestone", "research-slice", "M001/parallel-research"), null);
309
+ assert.equal(getConsecutiveDispatchBlocker(state, "validating-milestone", "validate-milestone", "M001"), null);
310
+ });
311
+
312
+ test("consecutive dispatch guard resets when phase changes", () => {
313
+ const state = {
314
+ consecutiveDispatchCount: new Map<string, number>(),
315
+ lastDispatchedKey: null as string | null,
316
+ lastDispatchPhase: null as string | null,
317
+ };
318
+
319
+ assert.equal(getConsecutiveDispatchBlocker(state, "validating-milestone", "validate-milestone", "M001"), null);
320
+ assert.equal(getConsecutiveDispatchBlocker(state, "validating-milestone", "validate-milestone", "M001"), null);
321
+ assert.equal(getConsecutiveDispatchBlocker(state, "completing-milestone", "validate-milestone", "M001"), null);
322
+ });
323
+
257
324
  test("dispatch guard does not skip failed milestone SUMMARY without blocker prose", (t) => {
258
325
  const repo = setupRepo();
259
326
  t.after(() => teardownRepo(repo));