gsd-pi 2.80.0-dev.8b3a59f5c → 2.80.0-dev.b0acf17e9

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 (659) hide show
  1. package/README.md +4 -2
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  18. package/dist/resources/extensions/gsd/auto/phases.js +240 -139
  19. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  21. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  23. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  24. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +103 -86
  27. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  28. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  29. package/dist/resources/extensions/gsd/auto-start.js +240 -15
  30. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  31. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +165 -28
  33. package/dist/resources/extensions/gsd/auto.js +165 -45
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -10
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +50 -37
  36. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +35 -10
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +36 -20
  38. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +10 -1
  39. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +12 -4
  40. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +11 -3
  41. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  42. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +319 -54
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  44. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  45. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  46. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  47. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  48. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  49. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  50. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  51. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  52. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  53. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  54. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  55. package/dist/resources/extensions/gsd/detection.js +106 -0
  56. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  57. package/dist/resources/extensions/gsd/git-service.js +73 -5
  58. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  59. package/dist/resources/extensions/gsd/guided-flow.js +143 -48
  60. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  61. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  62. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  63. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  64. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  65. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  66. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  67. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  68. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  69. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  70. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  71. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  73. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  75. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  77. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  78. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  79. package/dist/resources/extensions/gsd/quick.js +34 -2
  80. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  81. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  83. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  84. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  85. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  86. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  87. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  88. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  89. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  90. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  91. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  92. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  93. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  94. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  95. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  96. package/dist/resources/extensions/gsd/worktree-resolver.js +90 -22
  97. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  98. package/dist/web/standalone/.next/BUILD_ID +1 -1
  99. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  100. package/dist/web/standalone/.next/build-manifest.json +3 -3
  101. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  102. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  103. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/index.html +1 -1
  122. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  123. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  124. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  130. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/middleware.js +3 -3
  133. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  134. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  135. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  136. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  137. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  138. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  139. package/dist/welcome-screen.d.ts +2 -0
  140. package/dist/welcome-screen.js +9 -7
  141. package/package.json +6 -4
  142. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  143. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  144. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  145. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  146. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  147. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  148. package/packages/native/tsconfig.tsbuildinfo +1 -1
  149. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  150. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  151. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  152. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  153. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  154. package/packages/pi-agent-core/dist/agent.js +2 -0
  155. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  156. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  157. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  158. package/packages/pi-agent-core/dist/index.js +2 -0
  159. package/packages/pi-agent-core/dist/index.js.map +1 -1
  160. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  161. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  162. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  163. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  164. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  165. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  166. package/packages/pi-agent-core/dist/types.js.map +1 -1
  167. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  168. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  169. package/packages/pi-agent-core/src/agent.ts +8 -0
  170. package/packages/pi-agent-core/src/index.ts +2 -0
  171. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  172. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  173. package/packages/pi-agent-core/src/types.ts +14 -0
  174. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  175. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  176. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  177. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  178. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  179. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  180. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  181. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  182. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  183. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  184. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  185. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  186. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  187. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  188. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  189. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  190. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  191. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  192. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  193. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  194. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  195. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  196. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  197. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  198. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  199. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  200. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  202. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  204. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  206. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +35 -1
  208. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  210. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  212. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  214. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  215. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  216. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  218. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  220. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  222. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  224. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  225. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  227. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  229. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  231. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  233. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +41 -3
  235. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  238. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  240. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  241. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  242. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  243. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  244. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  246. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  248. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  249. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  250. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  252. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  254. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  256. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  258. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  260. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  262. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  264. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  266. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  268. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  270. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  272. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  274. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  276. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  278. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  280. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  282. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  286. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  288. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  290. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  292. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  294. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  295. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  296. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  297. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  298. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  299. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  300. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  301. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  302. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  304. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +114 -22
  308. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +2 -2
  310. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +2 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +177 -19
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +33 -6
  324. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  329. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  332. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +21 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  336. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  337. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  338. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  339. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  340. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  341. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  342. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  343. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  344. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  345. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +41 -1
  346. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  347. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  348. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  349. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  350. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  351. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  352. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  353. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -2
  354. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  355. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  356. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  357. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  358. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  359. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  360. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  361. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  362. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  363. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  364. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  365. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  366. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  367. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  368. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  369. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  370. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  371. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  372. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  373. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  374. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +144 -22
  375. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +2 -2
  376. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  377. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +2 -1
  378. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  379. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +208 -19
  380. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  381. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +41 -8
  382. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  384. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +25 -0
  385. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  386. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  387. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  388. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  389. package/packages/pi-tui/dist/tui.js +18 -8
  390. package/packages/pi-tui/dist/tui.js.map +1 -1
  391. package/packages/pi-tui/src/tui.ts +20 -8
  392. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  393. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  394. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  395. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  396. package/src/resources/GSD-WORKFLOW.md +2 -2
  397. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  398. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  399. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  400. package/src/resources/extensions/github-sync/sync.ts +8 -1
  401. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  402. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  403. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  404. package/src/resources/extensions/gsd/auto/phases.ts +328 -200
  405. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  406. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  407. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  408. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  409. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  410. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  411. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  412. package/src/resources/extensions/gsd/auto-post-unit.ts +116 -88
  413. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  414. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  415. package/src/resources/extensions/gsd/auto-start.ts +293 -21
  416. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  417. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  418. package/src/resources/extensions/gsd/auto-worktree.ts +199 -30
  419. package/src/resources/extensions/gsd/auto.ts +216 -40
  420. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -8
  421. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +51 -37
  422. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +35 -10
  423. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +38 -19
  424. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +11 -1
  425. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +13 -4
  426. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +12 -3
  427. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  428. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +369 -54
  429. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  430. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  431. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  432. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  433. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  434. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  435. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  436. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  437. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  438. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  439. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  440. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  441. package/src/resources/extensions/gsd/detection.ts +128 -0
  442. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  443. package/src/resources/extensions/gsd/git-service.ts +87 -10
  444. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  445. package/src/resources/extensions/gsd/guided-flow.ts +169 -55
  446. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  447. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  448. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  449. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  450. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  451. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  452. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  453. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  454. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  455. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  456. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  457. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  458. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  459. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  460. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  462. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  464. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  465. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  466. package/src/resources/extensions/gsd/quick.ts +37 -2
  467. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  468. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  469. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  470. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  471. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  472. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  473. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  474. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +433 -11
  475. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  476. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  477. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  478. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +160 -11
  479. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  480. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  481. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  482. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  483. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  484. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  485. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  486. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  487. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  488. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  489. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  490. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  491. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  492. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  493. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  494. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  495. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  496. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  497. package/src/resources/extensions/gsd/tests/cmux.test.ts +42 -53
  498. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  499. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  500. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  501. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  502. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  503. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  504. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  505. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  506. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  507. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  508. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  509. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  510. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  511. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  512. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  513. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  514. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  515. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  516. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  517. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  518. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  519. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  520. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  521. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  522. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  523. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  524. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  525. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  526. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  527. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  528. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  529. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  530. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  531. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +35 -0
  532. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  533. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  534. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  535. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  536. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  537. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  538. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  539. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  540. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  541. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  542. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  543. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  544. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  545. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  546. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  547. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  548. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  549. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  550. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  551. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  552. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  554. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  555. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  556. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  557. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  558. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
  559. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  560. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  561. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  562. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  563. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  564. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  565. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  566. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  567. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  568. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  569. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  570. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  571. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  572. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  573. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  574. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  575. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  576. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  577. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  578. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  579. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  580. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  581. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  582. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  583. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  584. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  585. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  586. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  587. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  588. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  589. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  590. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  591. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  592. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  593. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  594. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  595. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  596. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  597. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  598. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  599. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  600. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  601. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  602. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  603. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  604. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  605. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  606. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  607. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  608. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  609. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +36 -45
  610. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  611. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  612. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  613. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  614. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  615. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  616. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  617. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  618. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  619. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  620. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  621. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  622. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  623. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  624. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  625. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  626. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  627. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  628. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  629. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  630. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  631. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  632. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  633. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  634. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  635. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  636. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  637. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  638. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  639. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  640. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +203 -4
  641. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  642. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  643. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  644. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  645. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  646. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  647. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  648. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  649. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  650. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  651. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  652. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  653. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  654. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  655. package/src/resources/extensions/gsd/worktree-resolver.ts +119 -20
  656. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  657. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  658. /package/dist/web/standalone/.next/static/{k-MDjzPMF62Rg1-FR437h → naNyn5ToUBzCQtuLbEYXC}/_buildManifest.js +0 -0
  659. /package/dist/web/standalone/.next/static/{k-MDjzPMF62Rg1-FR437h → naNyn5ToUBzCQtuLbEYXC}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -259,6 +259,7 @@ Full documentation is in the [`docs/`](./docs/) directory:
259
259
 
260
260
  - **[Architecture](./docs/dev/architecture.md)** — system design and dispatch pipeline
261
261
  - **[CI/CD Pipeline](./docs/dev/ci-cd-pipeline.md)** — three-stage promotion pipeline (Dev → Test → Prod)
262
+ - **[E2E Testing](./tests/e2e/README.md)** — real-process CLI/runtime coverage and CI runner expectations
262
263
  - **[Pipeline Simplification (ADR-003)](./docs/dev/ADR-003-pipeline-simplification.md)** — merged research into planning, mechanical completion
263
264
  - **[VS Code Extension](./vscode-extension/README.md)** — chat participant, sidebar dashboard, RPC integration
264
265
 
@@ -361,7 +362,7 @@ The database is authoritative for milestones, slices, tasks, requirements, decis
361
362
 
362
363
  2. **Context pre-loading** — The dispatch prompt includes inlined task plans, slice plans, prior task summaries, dependency summaries, roadmap excerpts, and decisions register. The LLM starts with everything it needs instead of spending tool calls reading files.
363
364
 
364
- 3. **Context Mode** — Context Mode is enabled by default and gives every auto-mode unit guidance for preserving context. Agents are steered toward `gsd_exec` for noisy scans, builds, tests, and diagnostics; full stdout/stderr is saved under `.gsd/exec/` while only a short digest enters the conversation. `gsd_exec_search` lets agents reuse prior runs instead of repeating expensive checks, and `gsd_resume` reads `.gsd/last-snapshot.md` after compaction or resume. Opt out with `context_mode.enabled: false`; tune sandbox timeout/output caps with `context_mode.exec_timeout_ms`, `context_mode.exec_stdout_cap_bytes`, and `context_mode.exec_digest_chars`.
365
+ 3. **Context Mode** — Context Mode is enabled by default and gives eligible auto-mode units guidance for preserving context. Agents are steered toward `gsd_exec` for noisy scans, builds, tests, and diagnostics; capped stdout/stderr and metadata are saved under `.gsd/exec/` while only a short digest enters the conversation. `gsd_exec_search` lets agents reuse prior runs instead of repeating expensive checks, and `gsd_resume` reads a prior compaction snapshot from `.gsd/last-snapshot.md` when one exists. Opt out with `context_mode.enabled: false` to disable Context Mode guidance, snapshot injection, `gsd_exec`, `gsd_exec_search`, and `gsd_resume`; tune sandbox timeout/output caps and environment forwarding with `context_mode.exec_timeout_ms`, `context_mode.exec_stdout_cap_bytes`, `context_mode.exec_digest_chars`, and `context_mode.exec_env_allowlist`.
365
366
 
366
367
  4. **Git isolation** — When `git.isolation` is set to `worktree` or `branch`, each milestone runs on its own `milestone/<MID>` branch (in a worktree or in-place). All slice work commits sequentially — no branch switching, no merge conflicts. When the milestone completes, it's squash-merged to main as one clean commit. The default is `none` (work on the current branch), configurable via preferences. If `worktree` is configured in a repo with no committed `HEAD`, GSD temporarily behaves as `none` until the first commit exists because git worktrees need a committed start point.
367
368
 
@@ -659,10 +660,11 @@ auto_report: true
659
660
  | `unique_milestone_ids` | Uses unique milestone names to avoid clashes when working in teams of people |
660
661
  | `git.isolation` | `none` (default), `worktree`, or `branch` — enable worktree or branch isolation for milestone work. `worktree` requires a committed `HEAD`; zero-commit repos temporarily run as `none` |
661
662
  | `git.manage_gitignore` | Set `false` to prevent GSD from modifying `.gitignore` |
662
- | `context_mode.enabled` | Context Mode is default-on; set `false` to disable `gsd_exec`, exec history guidance, and resume snapshots |
663
+ | `context_mode.enabled` | Context Mode is default-on; set `false` to disable prompt guidance, snapshot injection, `gsd_exec`, `gsd_exec_search`, and `gsd_resume` |
663
664
  | `context_mode.exec_timeout_ms` | Timeout for sandboxed `gsd_exec` runs (default: 30000) |
664
665
  | `context_mode.exec_stdout_cap_bytes` | Persisted stdout cap for `gsd_exec` output (default: 1048576) |
665
666
  | `context_mode.exec_digest_chars` | Trailing stdout characters returned to the agent context (default: 300) |
667
+ | `context_mode.exec_env_allowlist` | Environment variables forwarded to sandboxed `gsd_exec` runs in addition to `PATH` and `HOME` |
666
668
  | `verification_commands` | Array of shell commands to run after task execution (e.g., `["npm run lint", "npm run test"]`) |
667
669
  | `verification_auto_fix` | Auto-retry on verification failures (default: true) |
668
670
  | `verification_max_retries` | Max retries for verification failures (default: 2) |
@@ -1,3 +1,16 @@
1
+ /**
2
+ * Spawn the Claude CLI without triggering Node's DEP0190.
3
+ *
4
+ * Passing `args` together with `shell: true` is deprecated in Node 22+
5
+ * because the args are concatenated into the command string without
6
+ * escaping. On Windows we still need a shell to resolve `.cmd` shims, so
7
+ * we invoke `cmd /c <command> <args...>` explicitly. On POSIX we don't
8
+ * need a shell at all.
9
+ */
10
+ export declare function buildClaudeSpawnInvocation(command: string, args: string[], platform?: NodeJS.Platform): {
11
+ command: string;
12
+ args: string[];
13
+ };
1
14
  /**
2
15
  * Platform-correct binary name for the Claude Code CLI.
3
16
  *
@@ -7,7 +20,24 @@
7
20
  * authenticated. Mirrors the `NPM_COMMAND` pattern in
8
21
  * `src/resources/extensions/gsd/pre-execution-checks.ts`.
9
22
  */
23
+ export declare function getClaudeCommand(platform?: NodeJS.Platform): string;
10
24
  export declare const CLAUDE_COMMAND: string;
25
+ /**
26
+ * Ordered list of binary names to probe for the Claude Code CLI.
27
+ *
28
+ * Windows installs vary: npm-global installs produce a `claude.cmd` shim,
29
+ * direct binary installs produce `claude.exe`, and Git Bash wrappers may
30
+ * expose a bare `claude` shim. Try all three so no valid install is missed.
31
+ */
32
+ export declare function getClaudeCommandCandidates(platform?: NodeJS.Platform): string[];
33
+ /**
34
+ * Decide auth state from `claude auth status` output.
35
+ *
36
+ * Newer Claude CLI builds emit JSON with a `loggedIn` boolean. Older builds
37
+ * emit free-form text. Prefer the structured signal; fall back to a text
38
+ * heuristic. The text heuristic only covers English phrasing.
39
+ */
40
+ export declare function parseAuthStatus(output: string): boolean | null;
11
41
  /**
12
42
  * Check if the `claude` binary is installed (regardless of auth state).
13
43
  */
@@ -14,11 +14,15 @@ import { execFileSync } from 'node:child_process';
14
14
  * we invoke `cmd /c <command> <args...>` explicitly. On POSIX we don't
15
15
  * need a shell at all.
16
16
  */
17
- function spawnClaude(command, args, opts) {
18
- if (process.platform === 'win32') {
19
- return execFileSync('cmd', ['/c', command, ...args], opts);
17
+ export function buildClaudeSpawnInvocation(command, args, platform = process.platform) {
18
+ if (platform === 'win32') {
19
+ return { command: 'cmd', args: ['/c', command, ...args] };
20
20
  }
21
- return execFileSync(command, args, opts);
21
+ return { command, args };
22
+ }
23
+ function spawnClaude(command, args, opts) {
24
+ const invocation = buildClaudeSpawnInvocation(command, args);
25
+ return execFileSync(invocation.command, invocation.args, opts);
22
26
  }
23
27
  /**
24
28
  * Platform-correct binary name for the Claude Code CLI.
@@ -29,7 +33,10 @@ function spawnClaude(command, args, opts) {
29
33
  * authenticated. Mirrors the `NPM_COMMAND` pattern in
30
34
  * `src/resources/extensions/gsd/pre-execution-checks.ts`.
31
35
  */
32
- export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'claude';
36
+ export function getClaudeCommand(platform = process.platform) {
37
+ return platform === 'win32' ? 'claude.cmd' : 'claude';
38
+ }
39
+ export const CLAUDE_COMMAND = getClaudeCommand();
33
40
  /**
34
41
  * Ordered list of binary names to probe for the Claude Code CLI.
35
42
  *
@@ -37,7 +44,11 @@ export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'cla
37
44
  * direct binary installs produce `claude.exe`, and Git Bash wrappers may
38
45
  * expose a bare `claude` shim. Try all three so no valid install is missed.
39
46
  */
40
- const CLAUDE_COMMAND_CANDIDATES = process.platform === 'win32' ? [CLAUDE_COMMAND, 'claude.exe', 'claude'] : [CLAUDE_COMMAND];
47
+ export function getClaudeCommandCandidates(platform = process.platform) {
48
+ const command = getClaudeCommand(platform);
49
+ return platform === 'win32' ? [command, 'claude.exe', 'claude'] : [command];
50
+ }
51
+ const CLAUDE_COMMAND_CANDIDATES = getClaudeCommandCandidates();
41
52
  const VERSION_TIMEOUT_MS = 5_000;
42
53
  // Auth probe needs more headroom on Windows because the spawn goes through
43
54
  // cmd.exe → claude.cmd → node → Claude CLI.
@@ -80,7 +91,7 @@ function findWorkingCommand() {
80
91
  * emit free-form text. Prefer the structured signal; fall back to a text
81
92
  * heuristic. The text heuristic only covers English phrasing.
82
93
  */
83
- function parseAuthStatus(output) {
94
+ export function parseAuthStatus(output) {
84
95
  const trimmed = output.trim();
85
96
  if (!trimmed)
86
97
  return null;
package/dist/cli.js CHANGED
@@ -760,25 +760,6 @@ if (!process.stdin.isTTY || !process.stdout.isTTY) {
760
760
  : 'stdout is';
761
761
  printNonTtyErrorAndExit(missing, true);
762
762
  }
763
- // Welcome screen — shown on every fresh interactive session before TUI takes over.
764
- // Skip when the first-run banner was already printed in loader.ts (prevents double banner).
765
- if (!process.env.GSD_FIRST_RUN_BANNER) {
766
- const { printWelcomeScreen } = await import('./welcome-screen.js');
767
- let remoteChannel;
768
- try {
769
- const { resolveRemoteConfig } = await import('./resources/extensions/remote-questions/config.js');
770
- const rc = resolveRemoteConfig();
771
- if (rc)
772
- remoteChannel = rc.channel;
773
- }
774
- catch { /* non-fatal */ }
775
- printWelcomeScreen({
776
- version: process.env.GSD_VERSION || '0.0.0',
777
- modelName: settingsManager.getDefaultModel() || undefined,
778
- provider: settingsManager.getDefaultProvider() || undefined,
779
- remoteChannel,
780
- });
781
- }
782
763
  const interactiveMode = new InteractiveMode(session);
783
764
  markStartup('InteractiveMode');
784
765
  printStartupTimings();
@@ -36,6 +36,13 @@ export declare function shouldUseAgentExtensionsDir(opts: {
36
36
  agentDir: string;
37
37
  useAgentDir: boolean;
38
38
  };
39
+ declare function loadExtensionModules(): Promise<{
40
+ openProjectDbIfPresent: (basePath: string) => Promise<void>;
41
+ deriveState: (basePath: string) => Promise<GSDState>;
42
+ resolveDispatch: (opts: any) => Promise<any>;
43
+ readAllSessionStatuses: (basePath: string) => any[];
44
+ loadEffectiveGSDPreferences: () => any;
45
+ }>;
39
46
  export interface QuerySnapshot {
40
47
  state: GSDState;
41
48
  next: {
@@ -59,4 +66,7 @@ export interface QueryResult {
59
66
  exitCode: number;
60
67
  data?: QuerySnapshot;
61
68
  }
69
+ type HeadlessQueryModules = Awaited<ReturnType<typeof loadExtensionModules>>;
70
+ export declare function runHeadlessQuery(basePath: string, modules: HeadlessQueryModules, writeOutput?: (text: string) => void): Promise<QueryResult>;
62
71
  export declare function handleQuery(basePath: string): Promise<QueryResult>;
72
+ export {};
@@ -77,9 +77,8 @@ async function loadExtensionModules() {
77
77
  loadEffectiveGSDPreferences: prefsModule.loadEffectiveGSDPreferences,
78
78
  };
79
79
  }
80
- // ─── Implementation ─────────────────────────────────────────────────────────
81
- export async function handleQuery(basePath) {
82
- const { openProjectDbIfPresent, deriveState, resolveDispatch, readAllSessionStatuses, loadEffectiveGSDPreferences, } = await loadExtensionModules();
80
+ export async function runHeadlessQuery(basePath, modules, writeOutput = (text) => process.stdout.write(text)) {
81
+ const { openProjectDbIfPresent, deriveState, resolveDispatch, readAllSessionStatuses, loadEffectiveGSDPreferences, } = modules;
83
82
  await openProjectDbIfPresent(basePath);
84
83
  const state = await deriveState(basePath);
85
84
  // Derive next dispatch action
@@ -120,6 +119,9 @@ export async function handleQuery(basePath) {
120
119
  next,
121
120
  cost: { workers, total: workers.reduce((sum, w) => sum + w.cost, 0) },
122
121
  };
123
- process.stdout.write(JSON.stringify(snapshot) + '\n');
122
+ writeOutput(JSON.stringify(snapshot) + '\n');
124
123
  return { exitCode: 0, data: snapshot };
125
124
  }
125
+ export async function handleQuery(basePath) {
126
+ return runHeadlessQuery(basePath, await loadExtensionModules());
127
+ }
@@ -0,0 +1,8 @@
1
+ export interface LoaderEntrypointOptions {
2
+ gsdRoot: string;
3
+ invokedBinPath: string | undefined;
4
+ env?: NodeJS.ProcessEnv;
5
+ existsSync?: (path: string) => boolean;
6
+ }
7
+ export declare function resolveLoaderCliEntrypoint({ gsdRoot, invokedBinPath, env, existsSync, }: LoaderEntrypointOptions): string | undefined;
8
+ export declare function applyLoaderCliEntrypointEnv(env: NodeJS.ProcessEnv, options: LoaderEntrypointOptions): string | undefined;
@@ -0,0 +1,27 @@
1
+ // GSD-2 - Loader child-process entrypoint resolution helpers.
2
+ import { existsSync as defaultExistsSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ export function resolveLoaderCliEntrypoint({ gsdRoot, invokedBinPath, env = process.env, existsSync = defaultExistsSync, }) {
5
+ const sourceLoaderPath = join(gsdRoot, "src", "loader.ts");
6
+ const devCliPath = env.GSD_DEV_CLI_PATH?.trim() || join(gsdRoot, "scripts", "dev-cli.js");
7
+ const explicitCliPath = env.GSD_CLI_PATH?.trim() || env.GSD_BIN_PATH?.trim();
8
+ const isSourceLoader = Boolean(invokedBinPath && resolve(invokedBinPath) === sourceLoaderPath);
9
+ const rawGsdBinPath = explicitCliPath || (isSourceLoader && existsSync(devCliPath) ? devCliPath : invokedBinPath);
10
+ return rawGsdBinPath ? resolve(rawGsdBinPath) : undefined;
11
+ }
12
+ export function applyLoaderCliEntrypointEnv(env, options) {
13
+ const resolvedGsdBinPath = resolveLoaderCliEntrypoint({ ...options, env });
14
+ if (resolvedGsdBinPath) {
15
+ env.GSD_BIN_PATH = resolvedGsdBinPath;
16
+ if (!env.GSD_CLI_PATH) {
17
+ env.GSD_CLI_PATH = resolvedGsdBinPath;
18
+ }
19
+ }
20
+ else {
21
+ delete env.GSD_BIN_PATH;
22
+ if (!env.GSD_CLI_PATH) {
23
+ delete env.GSD_CLI_PATH;
24
+ }
25
+ }
26
+ return resolvedGsdBinPath;
27
+ }
package/dist/loader.js CHANGED
@@ -63,6 +63,7 @@ import { serializeBundledExtensionPaths } from './bundled-extension-paths.js';
63
63
  import { resolveBundledResourcesDirFromPackageRoot } from './bundled-resource-path.js';
64
64
  import { discoverExtensionEntryPaths } from './extension-discovery.js';
65
65
  import { loadRegistry, readManifestFromEntryPath, isExtensionEnabled } from './extension-registry.js';
66
+ import { applyLoaderCliEntrypointEnv } from './loader-entrypoint.js';
66
67
  import { renderLogo } from './logo.js';
67
68
  // pkg/ is a shim directory: contains gsd's piConfig (package.json) and pi's
68
69
  // theme assets (dist/modes/interactive/theme/) without a src/ directory.
@@ -117,17 +118,7 @@ process.env.GSD_VERSION = gsdVersion;
117
118
  // subagent/parallel workers to spawn gsd instead of pi when dispatching
118
119
  // workflow tasks. In source-dev mode this must remain scripts/dev-cli.js, not
119
120
  // src/loader.ts, because child processes need the --import resolve-ts wrapper.
120
- const invokedBinPath = process.argv[1];
121
- const sourceLoaderPath = join(gsdRoot, 'src', 'loader.ts');
122
- const devCliPath = process.env.GSD_DEV_CLI_PATH?.trim() || join(gsdRoot, 'scripts', 'dev-cli.js');
123
- const explicitCliPath = process.env.GSD_CLI_PATH?.trim() || process.env.GSD_BIN_PATH?.trim();
124
- const isSourceLoader = invokedBinPath && resolve(invokedBinPath) === sourceLoaderPath;
125
- const rawGsdBinPath = explicitCliPath || (isSourceLoader && existsSync(devCliPath) ? devCliPath : invokedBinPath);
126
- const resolvedGsdBinPath = rawGsdBinPath ? resolve(rawGsdBinPath) : undefined;
127
- process.env.GSD_BIN_PATH = resolvedGsdBinPath;
128
- if (!process.env.GSD_CLI_PATH) {
129
- process.env.GSD_CLI_PATH = resolvedGsdBinPath;
130
- }
121
+ applyLoaderCliEntrypointEnv(process.env, { gsdRoot, invokedBinPath: process.argv[1] });
131
122
  // GSD_WORKFLOW_PATH — absolute path to bundled GSD-WORKFLOW.md, used by patched gsd extension
132
123
  // when dispatching workflow prompts. Prefers dist/resources/ (stable, set at build time)
133
124
  // over src/resources/ (live working tree) — see resource-loader.ts for rationale.
@@ -22,6 +22,7 @@ export interface McpToolDef {
22
22
  isError?: boolean;
23
23
  }>;
24
24
  }
25
+ export declare function mcpSdkSpecifier(subpath: 'server/index' | 'server/stdio' | 'types'): string;
25
26
  /**
26
27
  * Starts a native MCP (Model Context Protocol) server over stdin/stdout.
27
28
  *
@@ -29,6 +29,9 @@ function isPlainObject(value) {
29
29
  // built via a template string so TypeScript's NodeNext resolver treats them as
30
30
  // `any` and skips static checking.
31
31
  const MCP_PKG = '@modelcontextprotocol/sdk';
32
+ export function mcpSdkSpecifier(subpath) {
33
+ return `${MCP_PKG}/${subpath}.js`;
34
+ }
32
35
  /**
33
36
  * Starts a native MCP (Model Context Protocol) server over stdin/stdout.
34
37
  *
@@ -45,9 +48,9 @@ const MCP_PKG = '@modelcontextprotocol/sdk';
45
48
  */
46
49
  export async function startMcpServer(options) {
47
50
  const { tools, version = '0.0.0' } = options;
48
- const serverMod = await import(`${MCP_PKG}/server/index.js`);
49
- const stdioMod = await import(`${MCP_PKG}/server/stdio.js`);
50
- const typesMod = await import(`${MCP_PKG}/types.js`);
51
+ const serverMod = await import(mcpSdkSpecifier('server/index'));
52
+ const stdioMod = await import(mcpSdkSpecifier('server/stdio'));
53
+ const typesMod = await import(mcpSdkSpecifier('types'));
51
54
  const Server = serverMod.Server;
52
55
  const StdioServerTransport = stdioMod.StdioServerTransport;
53
56
  const { ListToolsRequestSchema, CallToolRequestSchema } = typesMod;
@@ -1 +1 @@
1
- 2b428bb01a7f0322
1
+ 8dffbaaacac1f342
@@ -28,7 +28,7 @@ Then do the thing `STATE.md` says to do next.
28
28
  ## The Hierarchy
29
29
 
30
30
  ```
31
- Milestone → a shippable version (4-10 slices)
31
+ Milestone → a shippable version (1-10 slices, sized to the work)
32
32
  Slice → one demoable vertical capability (1-7 tasks)
33
33
  Task → one context-window-sized unit of work (fits in one session)
34
34
  ```
@@ -331,7 +331,7 @@ The **Don't Hand-Roll** and **Common Pitfalls** sections prevent the most expens
331
331
 
332
332
  **For a milestone (roadmap):**
333
333
  1. Read `M###-CONTEXT.md`, `M###-RESEARCH.md`, and `.gsd/DECISIONS.md` if they exist.
334
- 2. Decompose the vision into 4-10 demoable vertical slices.
334
+ 2. Decompose the vision into 1-10 demoable vertical slices. Prefer one slice for tiny, single-file, or static work unless the request clearly spans independent capabilities.
335
335
  3. Order by risk (high-risk first to validate feasibility early).
336
336
  4. Write `M###-ROADMAP.md` with checkboxes, risk levels, dependencies, demo sentences.
337
337
  5. **Write the boundary map** — for each slice, specify what it produces (functions, types, interfaces, endpoints) and what it consumes from upstream slices. This forces interface thinking before implementation and enables deterministic verification that slices actually connect.
@@ -23,11 +23,15 @@ import { execFileSync } from "node:child_process";
23
23
  * we invoke `cmd /c <command> <args...>` explicitly. On POSIX we don't
24
24
  * need a shell at all.
25
25
  */
26
- function spawnClaude(command, args, opts) {
27
- if (process.platform === "win32") {
28
- return execFileSync("cmd", ["/c", command, ...args], opts);
26
+ export function buildClaudeSpawnInvocation(command, args, platform = process.platform) {
27
+ if (platform === "win32") {
28
+ return { command: "cmd", args: ["/c", command, ...args] };
29
29
  }
30
- return execFileSync(command, args, opts);
30
+ return { command, args };
31
+ }
32
+ function spawnClaude(command, args, opts) {
33
+ const invocation = buildClaudeSpawnInvocation(command, args);
34
+ return execFileSync(invocation.command, invocation.args, opts);
31
35
  }
32
36
  /**
33
37
  * Candidate executable names for the Claude Code CLI.
@@ -35,14 +39,21 @@ function spawnClaude(command, args, opts) {
35
39
  * Keep the explicit win32 ternary selector for regression coverage (Issue #4424):
36
40
  * Node's execFileSync must target `claude.cmd` directly on Windows.
37
41
  */
38
- const CLAUDE_COMMAND = process.platform === "win32" ? "claude.cmd" : "claude";
42
+ export function getClaudeCommand(platform = process.platform) {
43
+ return platform === "win32" ? "claude.cmd" : "claude";
44
+ }
45
+ const CLAUDE_COMMAND = getClaudeCommand();
39
46
  /**
40
47
  * Windows installs vary: some environments expose `claude.cmd` (npm shim),
41
48
  * `claude.exe` (direct binary install), or a bare `claude` shim on PATH
42
49
  * (for example Git Bash wrappers). Try all three to avoid false "not
43
50
  * installed" results in readiness checks.
44
51
  */
45
- const CLAUDE_COMMAND_CANDIDATES = process.platform === "win32" ? [CLAUDE_COMMAND, "claude.exe", "claude"] : [CLAUDE_COMMAND];
52
+ export function getClaudeCommandCandidates(platform = process.platform) {
53
+ const command = getClaudeCommand(platform);
54
+ return platform === "win32" ? [command, "claude.exe", "claude"] : [command];
55
+ }
56
+ const CLAUDE_COMMAND_CANDIDATES = getClaudeCommandCandidates();
46
57
  // Keep the version probe snappy — `claude --version` is a quick path.
47
58
  const VERSION_TIMEOUT_MS = 5_000;
48
59
  // Auth status can be much slower on Windows because the spawn goes through
@@ -90,7 +101,7 @@ function findWorkingCommand() {
90
101
  * back to a text heuristic. Note: the text heuristic only covers English
91
102
  * phrasing — the JSON path is the durable signal.
92
103
  */
93
- function parseAuthStatus(output) {
104
+ export function parseAuthStatus(output) {
94
105
  const trimmed = output.trim();
95
106
  if (!trimmed)
96
107
  return null;
@@ -261,6 +261,26 @@ function makeErrorMessage(model, errorMsg) {
261
261
  timestamp: Date.now(),
262
262
  };
263
263
  }
264
+ export function isClaudeCodeAbortErrorMessage(message) {
265
+ if (!message)
266
+ return false;
267
+ return /\b(?:claude code process aborted by user|request aborted by user|process aborted by user)\b/i.test(message);
268
+ }
269
+ function isBareClaudeCodeAbortErrorMessage(message) {
270
+ if (!message)
271
+ return false;
272
+ const normalized = message.trim().replace(/\s+/g, " ").toLowerCase();
273
+ return normalized === "claude code process aborted by user"
274
+ || normalized === "request aborted by user"
275
+ || normalized === "process aborted by user";
276
+ }
277
+ export function resolveClaudeCodeAbortedMessageText(errorMsg, lastTextContent) {
278
+ const trimmedError = errorMsg.trim();
279
+ if (trimmedError && !isBareClaudeCodeAbortErrorMessage(trimmedError)) {
280
+ return trimmedError;
281
+ }
282
+ return lastTextContent;
283
+ }
264
284
  /**
265
285
  * Generator exhaustion without a terminal result means the SDK stream was
266
286
  * interrupted mid-turn. Surface it as an error so downstream recovery logic
@@ -1512,6 +1532,15 @@ async function pumpSdkMessages(model, context, options, stream) {
1512
1532
  }
1513
1533
  catch (err) {
1514
1534
  const errorMsg = err instanceof Error ? err.message : String(err);
1535
+ if (options?.signal?.aborted || isClaudeCodeAbortErrorMessage(errorMsg)) {
1536
+ const abortedText = resolveClaudeCodeAbortedMessageText(errorMsg, lastTextContent);
1537
+ stream.push({
1538
+ type: "error",
1539
+ reason: "aborted",
1540
+ error: makeAbortedMessage(modelId, abortedText),
1541
+ });
1542
+ return;
1543
+ }
1515
1544
  stream.push({
1516
1545
  type: "error",
1517
1546
  reason: "error",
@@ -79,6 +79,9 @@ export async function runGitHubSync(basePath, unitType, unitId) {
79
79
  debugLog("github-sync", { error: String(err) });
80
80
  }
81
81
  }
82
+ export function shouldCreateSlicePrForSyncEvent(unitType, config) {
83
+ return unitType === "complete-slice" && config.slice_prs !== false;
84
+ }
82
85
  // ─── Per-Event Sync Functions ───────────────────────────────────────────────
83
86
  async function syncMilestonePlan(basePath, mapping, config, mid) {
84
87
  // Skip if already synced
@@ -307,7 +310,7 @@ async function syncSliceComplete(basePath, mapping, config, mid, sid) {
307
310
  }
308
311
  if (!sliceRecord || sliceRecord.state === "closed")
309
312
  return;
310
- if (!sliceRecord.prNumber && config.slice_prs !== false) {
313
+ if (!sliceRecord.prNumber && shouldCreateSlicePrForSyncEvent("complete-slice", config)) {
311
314
  await ensureSlicePullRequest(basePath, mapping, mid, sid);
312
315
  sliceRecord = getSliceRecord(mapping, mid, sid);
313
316
  if (!sliceRecord || !sliceRecord.prNumber)
@@ -16,7 +16,7 @@ import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
16
16
  import { resolveEngine } from "../engine-resolver.js";
17
17
  import { logWarning } from "../workflow-logger.js";
18
18
  import { recordDispatchClaim, markRunning as markDispatchRunning, markCompleted as markDispatchCompleted, markFailed as markDispatchFailed, getRecentForUnit as getRecentDispatchesForUnit, getRecentUnitKeysForProjectRoot, } from "../db/unit-dispatches.js";
19
- import { refreshMilestoneLease } from "../db/milestone-leases.js";
19
+ import { claimMilestoneLease, refreshMilestoneLease } from "../db/milestone-leases.js";
20
20
  import { heartbeatAutoWorker } from "../db/auto-workers.js";
21
21
  import { getRuntimeKv, setRuntimeKv } from "../db/runtime-kv.js";
22
22
  import { resolveUokFlags } from "../uok/flags.js";
@@ -25,7 +25,9 @@ import { normalizeRealPath } from "../paths.js";
25
25
  import { decideCooldownRecovery, decideDispatchClaim, decideEngineDispatch, decideFinalizeResult, decideInfrastructureError, decideIterationErrorRecovery, decideMemoryPressure, decideModelPolicyBlocked, decideMinRequestInterval, decideWorkflowLoop, formatDispatchExceptionSummary, formatUnhandledDispatchErrorSummary, resolveUnitRequestTimestamp, shouldUseCustomEnginePath, } from "./workflow-kernel.js";
26
26
  import { hydrateCustomVerifyRetryCounts, saveCustomVerifyRetryCounts, } from "./custom-verify-retry-store.js";
27
27
  import { settleDispatchCompleted, settleDispatchFailed, } from "./workflow-dispatch-ledger.js";
28
- import { openDispatchClaim } from "./workflow-dispatch-claim.js";
28
+ import { emitOpenUnitEndForUnit } from "../crash-recovery.js";
29
+ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
30
+ import { ensureDispatchLease, openDispatchClaim } from "./workflow-dispatch-claim.js";
29
31
  import { completeWorkflowIteration } from "./workflow-iteration-completion.js";
30
32
  import { createWorkflowJournalReporter } from "./workflow-journal-reporter.js";
31
33
  import { createWorkflowPhaseReporter } from "./workflow-phase-reporter.js";
@@ -103,6 +105,18 @@ function logDispatchClaimFailed(err) {
103
105
  error: err instanceof Error ? err.message : String(err),
104
106
  });
105
107
  }
108
+ function logDispatchLeaseRecovered(details) {
109
+ debugLog("autoLoop", {
110
+ phase: details.recovered ? "dispatch-lease-recovered" : "dispatch-lease-acquired",
111
+ ...details,
112
+ });
113
+ }
114
+ function logDispatchLeaseRecoveryFailed(details) {
115
+ debugLog("autoLoop", {
116
+ phase: "dispatch-lease-recovery-failed",
117
+ ...details,
118
+ });
119
+ }
106
120
  function logCustomVerifyRetryLoadFailure(err) {
107
121
  debugLog("autoLoop", {
108
122
  phase: "load-custom-verify-retries-failed",
@@ -133,6 +147,24 @@ async function enforceMinRequestInterval(s, prefs) {
133
147
  await new Promise(r => setTimeout(r, decision.waitMs));
134
148
  }
135
149
  }
150
+ function closeOutCrashedUnit(s, iterData, err) {
151
+ const summary = formatDispatchExceptionSummary({ error: err });
152
+ try {
153
+ emitOpenUnitEndForUnit(s.basePath, iterData.unitType, iterData.unitId, "cancelled", {
154
+ message: summary,
155
+ category: "unit-exception",
156
+ isTransient: false,
157
+ });
158
+ writeUnitRuntimeRecord(s.basePath, iterData.unitType, iterData.unitId, s.currentUnit?.startedAt ?? Date.now(), {
159
+ phase: "crashed",
160
+ lastProgressAt: Date.now(),
161
+ lastProgressKind: "unit-exception",
162
+ });
163
+ }
164
+ catch (closeoutErr) {
165
+ logWarning("dispatch", `unit crash closeout failed: ${closeoutErr instanceof Error ? closeoutErr.message : String(closeoutErr)}`);
166
+ }
167
+ }
136
168
  /**
137
169
  * Main auto-mode execution loop. Iterates: derive → dispatch → guards →
138
170
  * runUnit → finalize → repeat. Exits when s.active becomes false or a
@@ -166,6 +198,10 @@ export async function autoLoop(ctx, pi, s, deps, options) {
166
198
  phase: "heartbeat-failed",
167
199
  error: err instanceof Error ? err.message : String(err),
168
200
  }),
201
+ logLeaseRefreshMiss: details => debugLog("autoLoop", {
202
+ phase: "lease-refresh-missed",
203
+ ...details,
204
+ }),
169
205
  });
170
206
  // ── Journal: per-iteration flow grouping ──
171
207
  const flowId = randomUUID();
@@ -392,7 +428,17 @@ export async function autoLoop(ctx, pi, s, deps, options) {
392
428
  }
393
429
  // ── Unit execution (shared with dev path) ──
394
430
  await enforceMinRequestInterval(s, prefs);
395
- const unitPhaseResult = await runUnitPhaseViaContract(dispatchContract, ic, iterData, loopState, undefined, unitDispatchDeps);
431
+ let unitPhaseResult;
432
+ try {
433
+ unitPhaseResult = await runUnitPhaseViaContract(dispatchContract, ic, iterData, loopState, undefined, unitDispatchDeps);
434
+ }
435
+ catch (err) {
436
+ if (err instanceof ModelPolicyDispatchBlockedError) {
437
+ throw err;
438
+ }
439
+ closeOutCrashedUnit(s, iterData, err);
440
+ throw err;
441
+ }
396
442
  if (unitPhaseResult.action === "next") {
397
443
  const requestTimestamp = resolveUnitRequestTimestamp(unitPhaseResult.data);
398
444
  if (requestTimestamp !== undefined)
@@ -551,23 +597,70 @@ export async function autoLoop(ctx, pi, s, deps, options) {
551
597
  await enforceMinRequestInterval(s, prefs);
552
598
  // Phase B: claim a unit_dispatches row before invoking the unit. The
553
599
  // partial unique index idx_unit_dispatches_active_per_unit prevents
554
- // a second worker from claiming the same unit concurrently. Returns
555
- // null when DB unavailable, no worker registered, or no active lease
556
- // those degraded paths fall through to the existing single-worker
557
- // semantics with no ledger entry, preserving back-compat.
558
- const dispatchClaim = openDispatchClaim(s, flowId, turnId, iterData, {
600
+ // a second worker from claiming the same unit concurrently. When this
601
+ // process has a worker identity, make the milestone lease explicit before
602
+ // claiming so a step-mode handoff cannot leave us running with a stale
603
+ // in-memory token and no backing lease row.
604
+ const leaseBeforeClaim = ensureDispatchLease(s, iterData.mid, {
605
+ claimMilestoneLease,
606
+ logLeaseRecovered: logDispatchLeaseRecovered,
607
+ logLeaseRecoveryFailed: logDispatchLeaseRecoveryFailed,
608
+ });
609
+ if (leaseBeforeClaim.kind === "blocked" || leaseBeforeClaim.kind === "failed") {
610
+ const msg = `Lost milestone lease for ${iterData.mid ?? "unknown"} before dispatching ${iterData.unitType} ${iterData.unitId}: ${leaseBeforeClaim.reason}`;
611
+ ctx.ui.notify(msg, "error");
612
+ finishTurn("stopped", "execution", msg);
613
+ await deps.stopAuto(ctx, pi, msg);
614
+ break;
615
+ }
616
+ let dispatchClaim = openDispatchClaim(s, flowId, turnId, iterData, {
559
617
  getRecentDispatchesForUnit,
560
618
  recordDispatchClaim,
561
619
  markDispatchRunning,
562
620
  logClaimRejected: logDispatchClaimRejected,
563
621
  logClaimFailed: logDispatchClaimFailed,
564
622
  });
565
- const dispatchDecision = decideDispatchClaim(dispatchClaim.kind === "opened"
623
+ let dispatchDecision = decideDispatchClaim(dispatchClaim.kind === "opened"
566
624
  ? { kind: "opened", dispatchId: dispatchClaim.dispatchId }
567
625
  : dispatchClaim.kind === "skip"
568
626
  ? { kind: "skip", reason: dispatchClaim.reason }
569
627
  : { kind: "degraded" });
628
+ if (dispatchDecision.action === "skip" && dispatchDecision.reason === "stale-lease") {
629
+ const leaseRecovery = ensureDispatchLease(s, iterData.mid, {
630
+ claimMilestoneLease,
631
+ logLeaseRecovered: logDispatchLeaseRecovered,
632
+ logLeaseRecoveryFailed: logDispatchLeaseRecoveryFailed,
633
+ }, { forceReclaim: true });
634
+ if (leaseRecovery.kind === "ready") {
635
+ dispatchClaim = openDispatchClaim(s, flowId, turnId, iterData, {
636
+ getRecentDispatchesForUnit,
637
+ recordDispatchClaim,
638
+ markDispatchRunning,
639
+ logClaimRejected: logDispatchClaimRejected,
640
+ logClaimFailed: logDispatchClaimFailed,
641
+ });
642
+ dispatchDecision = decideDispatchClaim(dispatchClaim.kind === "opened"
643
+ ? { kind: "opened", dispatchId: dispatchClaim.dispatchId }
644
+ : dispatchClaim.kind === "skip"
645
+ ? { kind: "skip", reason: dispatchClaim.reason }
646
+ : { kind: "degraded" });
647
+ }
648
+ else {
649
+ const msg = `Lost milestone lease for ${iterData.mid ?? "unknown"} while claiming ${iterData.unitType} ${iterData.unitId}: ${leaseRecovery.reason}`;
650
+ ctx.ui.notify(msg, "error");
651
+ finishTurn("stopped", "execution", msg);
652
+ await deps.stopAuto(ctx, pi, msg);
653
+ break;
654
+ }
655
+ }
570
656
  if (dispatchDecision.action === "skip") {
657
+ if (dispatchDecision.reason === "stale-lease") {
658
+ const msg = `Lost milestone lease for ${iterData.mid ?? "unknown"} while claiming ${iterData.unitType} ${iterData.unitId}; dispatch claim still failed after recovery.`;
659
+ ctx.ui.notify(msg, "error");
660
+ finishTurn("stopped", "execution", msg);
661
+ await deps.stopAuto(ctx, pi, msg);
662
+ break;
663
+ }
571
664
  finishTurn("skipped", "execution", dispatchDecision.reason);
572
665
  continue;
573
666
  }
@@ -580,6 +673,7 @@ export async function autoLoop(ctx, pi, s, deps, options) {
580
673
  if (err instanceof ModelPolicyDispatchBlockedError) {
581
674
  throw err;
582
675
  }
676
+ closeOutCrashedUnit(s, iterData, err);
583
677
  dispatchSettled = settleDispatchFailed(dispatchId, formatDispatchExceptionSummary({ error: err }), {
584
678
  markFailed: markDispatchFailed,
585
679
  logWriteFailure: logDispatchLedgerWriteFailure,