gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b

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 (580) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +0 -19
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +2 -2
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  6. package/dist/resources/extensions/github-sync/templates.js +39 -8
  7. package/dist/resources/extensions/gsd/auto/loop.js +119 -18
  8. package/dist/resources/extensions/gsd/auto/phases.js +212 -135
  9. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  10. package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
  11. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  12. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  15. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
  18. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  19. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  20. package/dist/resources/extensions/gsd/auto-start.js +199 -9
  21. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  24. package/dist/resources/extensions/gsd/auto.js +95 -27
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  27. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  29. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  30. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
  33. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  36. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  38. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  39. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  40. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  41. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  42. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  43. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  44. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  45. package/dist/resources/extensions/gsd/detection.js +106 -0
  46. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  47. package/dist/resources/extensions/gsd/git-service.js +36 -4
  48. package/dist/resources/extensions/gsd/graph.js +9 -3
  49. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  50. package/dist/resources/extensions/gsd/guided-flow.js +129 -44
  51. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  52. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  53. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  54. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  55. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  56. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  57. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  58. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  59. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  60. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  61. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  62. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  64. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  66. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  68. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  70. package/dist/resources/extensions/gsd/quick.js +34 -2
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  72. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  73. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  74. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  75. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  76. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  77. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  78. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  79. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  80. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  81. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  82. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  83. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  84. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  85. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  86. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  87. package/dist/web/standalone/.next/BUILD_ID +1 -1
  88. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  89. package/dist/web/standalone/.next/build-manifest.json +3 -3
  90. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  91. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  117. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  124. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  125. package/dist/welcome-screen.d.ts +2 -0
  126. package/dist/welcome-screen.js +9 -7
  127. package/package.json +12 -8
  128. package/packages/contracts/package.json +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  133. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  134. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  135. package/packages/native/tsconfig.tsbuildinfo +1 -1
  136. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  140. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  141. package/packages/pi-agent-core/dist/agent.js +2 -0
  142. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  143. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  144. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  145. package/packages/pi-agent-core/dist/index.js +2 -0
  146. package/packages/pi-agent-core/dist/index.js.map +1 -1
  147. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  148. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  149. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  150. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  151. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  152. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  153. package/packages/pi-agent-core/dist/types.js.map +1 -1
  154. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  155. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  156. package/packages/pi-agent-core/src/agent.ts +8 -0
  157. package/packages/pi-agent-core/src/index.ts +2 -0
  158. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  159. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  160. package/packages/pi-agent-core/src/types.ts +14 -0
  161. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  162. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  163. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  164. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  165. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  166. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  167. package/packages/pi-ai/dist/models/index.js +8 -0
  168. package/packages/pi-ai/dist/models/index.js.map +1 -1
  169. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  170. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/providers/fake.js +319 -0
  172. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  173. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  174. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  175. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  176. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  177. package/packages/pi-ai/src/models/index.ts +9 -0
  178. package/packages/pi-ai/src/providers/fake.ts +376 -0
  179. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  180. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  181. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  182. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  184. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  186. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  188. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
  190. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  192. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  194. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  196. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  197. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  198. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  200. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  202. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  203. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  204. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  205. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  206. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  207. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  209. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  211. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  213. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  215. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  217. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  220. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  223. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  225. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  226. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  227. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  228. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  229. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  231. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  233. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  235. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  237. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  240. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  242. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  244. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +109 -17
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +69 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +26 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  312. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  313. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  315. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  318. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  319. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  320. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  321. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  322. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
  323. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  324. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  325. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  326. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  327. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  328. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  329. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  330. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  331. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  332. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  333. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  334. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  335. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  336. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  337. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  338. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  339. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  340. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  341. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  342. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  343. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  344. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  345. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  346. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  347. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
  348. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
  349. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
  350. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  351. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  352. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
  353. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  355. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  356. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  357. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  358. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  360. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  361. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  362. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  363. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  364. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  365. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  366. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  367. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  368. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  369. package/packages/pi-tui/dist/index.d.ts +1 -0
  370. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/index.js +2 -0
  372. package/packages/pi-tui/dist/index.js.map +1 -1
  373. package/packages/pi-tui/dist/style.d.ts +41 -0
  374. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/style.js +158 -0
  376. package/packages/pi-tui/dist/style.js.map +1 -0
  377. package/packages/pi-tui/dist/tui.d.ts +0 -1
  378. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  379. package/packages/pi-tui/dist/tui.js +21 -16
  380. package/packages/pi-tui/dist/tui.js.map +1 -1
  381. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  382. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  383. package/packages/pi-tui/src/index.ts +9 -0
  384. package/packages/pi-tui/src/style.ts +225 -0
  385. package/packages/pi-tui/src/tui.ts +23 -16
  386. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  387. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  388. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  389. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  390. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  391. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  392. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  393. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  394. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  395. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  396. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  397. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  398. package/src/resources/GSD-WORKFLOW.md +2 -2
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  401. package/src/resources/extensions/github-sync/templates.ts +38 -8
  402. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  403. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  404. package/src/resources/extensions/gsd/auto/loop.ts +151 -26
  405. package/src/resources/extensions/gsd/auto/phases.ts +289 -196
  406. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  407. package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
  408. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  409. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  410. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  411. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  412. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  413. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  414. package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
  415. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  416. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  417. package/src/resources/extensions/gsd/auto-start.ts +237 -15
  418. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  419. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  420. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  421. package/src/resources/extensions/gsd/auto.ts +110 -22
  422. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
  423. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  424. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  425. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  426. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  427. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  428. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  429. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
  430. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  431. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  432. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  433. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  434. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  435. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  436. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  437. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  438. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  439. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  440. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  441. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  442. package/src/resources/extensions/gsd/detection.ts +128 -0
  443. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  444. package/src/resources/extensions/gsd/git-service.ts +46 -8
  445. package/src/resources/extensions/gsd/graph.ts +12 -5
  446. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  447. package/src/resources/extensions/gsd/guided-flow.ts +150 -51
  448. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  449. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  450. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  451. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  452. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  453. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  454. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  455. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  456. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  457. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  458. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  459. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  460. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  462. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  464. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  466. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  468. package/src/resources/extensions/gsd/quick.ts +37 -2
  469. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  470. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  471. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  472. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  473. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  476. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  477. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  478. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  479. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  480. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  481. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  482. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  483. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  484. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  485. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  486. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
  487. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  489. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  490. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  491. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  492. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  494. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  495. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  496. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  497. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  498. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  499. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  500. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  501. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  502. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  503. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  504. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  505. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  506. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  507. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  508. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  509. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  510. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  511. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  512. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  513. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  514. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  515. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  516. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  517. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  518. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  519. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  520. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  521. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  522. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  523. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  524. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  525. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  526. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  527. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  528. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  529. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  530. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  531. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  533. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  534. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  535. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  536. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  537. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
  538. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  539. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  540. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  541. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  542. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  543. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  544. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  546. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  547. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  548. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  549. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  551. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  552. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  554. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  555. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  556. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  557. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  558. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  559. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  560. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  561. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  562. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  563. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  564. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  565. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  566. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  567. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  568. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  569. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  570. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  571. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  572. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  573. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  574. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  575. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  576. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  577. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  578. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  579. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
@@ -10,10 +10,16 @@ import {
10
10
  _resetPendingResolve,
11
11
  _hasPendingResolveForTest,
12
12
  _setActiveSession,
13
+ _setSessionSwitchInFlight,
14
+ _markSessionSwitchAbortGraceWindow,
15
+ _clearSessionSwitchAbortGraceWindow,
16
+ _consumePendingSwitchCancellation,
13
17
  isSessionSwitchInFlight,
18
+ isSessionSwitchAbortGraceActive,
14
19
  } from "../auto/resolve.js";
15
20
  import { runUnit } from "../auto/run-unit.js";
16
21
  import { autoLoop } from "../auto/loop.js";
22
+ import { runDispatch } from "../auto/phases.js";
17
23
  import { detectStuck } from "../auto/detect-stuck.js";
18
24
  import type { UnitResult, AgentEndEvent } from "../auto/types.js";
19
25
  import type { LoopDeps } from "../auto/loop-deps.js";
@@ -64,7 +70,7 @@ function makeMockSession(opts?: {
64
70
  verbose: false,
65
71
  basePath: process.cwd(),
66
72
  cmdCtx: {
67
- newSession: (options?: { abortSignal?: AbortSignal }) => {
73
+ newSession: (options?: { abortSignal?: AbortSignal; workspaceRoot?: string }) => {
68
74
  opts?.onNewSessionStart?.(session);
69
75
  if (opts?.newSessionThrows) {
70
76
  return Promise.reject(new Error(opts.newSessionThrows));
@@ -76,7 +82,7 @@ function makeMockSession(opts?: {
76
82
  setTimeout(() => {
77
83
  // Simulate AgentSession.newSession() checking abortSignal after
78
84
  // its internal async work (abort()) completes — this is where the
79
- // real code captures process.cwd() and rebuilds the tool runtime.
85
+ // real code selects a workspace root and rebuilds the tool runtime.
80
86
  // If the signal is aborted, the real code discards the session.
81
87
  opts?.onSignalCheck?.(options?.abortSignal?.aborted ?? false);
82
88
  opts?.onNewSessionSettle?.(session);
@@ -206,6 +212,28 @@ test("runUnit returns cancelled when session creation fails", async () => {
206
212
  assert.equal(pi.calls.length, 0);
207
213
  });
208
214
 
215
+ test("runUnit clears queued switch cancellation when session creation fails", async () => {
216
+ _resetPendingResolve();
217
+
218
+ const ctx = makeMockCtx();
219
+ const pi = makeMockPi();
220
+ const s = makeMockSession({
221
+ newSessionThrows: "connection refused",
222
+ onNewSessionStart: () => {
223
+ resolveAgentEndCancelled({
224
+ message: "Claude Code process aborted by user",
225
+ category: "aborted",
226
+ isTransient: false,
227
+ });
228
+ },
229
+ });
230
+
231
+ const result = await runUnit(ctx, pi, s, "task", "T01", "prompt");
232
+
233
+ assert.equal(result.status, "cancelled");
234
+ assert.equal(_consumePendingSwitchCancellation(), null);
235
+ });
236
+
209
237
  test("runUnit returns cancelled when session creation times out", async () => {
210
238
  _resetPendingResolve();
211
239
 
@@ -221,6 +249,34 @@ test("runUnit returns cancelled when session creation times out", async () => {
221
249
  assert.equal(pi.calls.length, 0);
222
250
  });
223
251
 
252
+ test("runUnit consumes a cancellation queued during session switch before dispatch", async () => {
253
+ _resetPendingResolve();
254
+
255
+ const ctx = makeMockCtx();
256
+ const pi = makeMockPi();
257
+ let cancellationQueued = false;
258
+ const s = makeMockSession({
259
+ newSessionDelayMs: 10,
260
+ onNewSessionStart: () => {
261
+ setTimeout(() => {
262
+ cancellationQueued = !resolveAgentEndCancelled({
263
+ message: "Claude Code process aborted by user",
264
+ category: "aborted",
265
+ isTransient: false,
266
+ });
267
+ }, 0);
268
+ },
269
+ });
270
+
271
+ const result = await runUnit(ctx, pi, s, "plan-slice", "M009/S01", "prompt");
272
+
273
+ assert.equal(cancellationQueued, true);
274
+ assert.equal(result.status, "cancelled");
275
+ assert.equal(result.errorContext?.category, "aborted");
276
+ assert.equal(result.errorContext?.message, "Claude Code process aborted by user");
277
+ assert.equal(pi.calls.length, 0, "queued switch cancellation must prevent prompt dispatch");
278
+ });
279
+
224
280
  test("runUnit keeps the session-switch guard across a late newSession settlement", async () => {
225
281
  _resetPendingResolve();
226
282
  mock.timers.enable();
@@ -496,10 +552,9 @@ test("runUnit proceeds when isProviderRequestReady throws (defensive) (#4555)",
496
552
  assert.equal(pi.calls.length, 0);
497
553
  });
498
554
 
499
- test("late-resolving newSession() after timeout receives aborted signal so tool runtime is not configured with root cwd (#3731)", async () => {
500
- // When newSession() times out in runUnit(), auto-mode restores cwd to project
501
- // root. If newSession() later resolves, it must NOT use process.cwd() to
502
- // configure the tool runtime (which would give it root cwd, not worktree cwd).
555
+ test("late-resolving newSession() after timeout receives aborted signal so tool runtime is not configured with stale workspace root (#3731)", async () => {
556
+ // When newSession() times out in runUnit(), a late resolution must not
557
+ // configure the tool runtime against a stale workspace root.
503
558
  //
504
559
  // The fix: runUnit creates an AbortController, aborts it on timeout, and passes
505
560
  // the signal to newSession(). AgentSession.newSession() checks the signal after
@@ -514,8 +569,8 @@ test("late-resolving newSession() after timeout receives aborted signal so tool
514
569
 
515
570
  // newSession mock simulates AgentSession.newSession() behavior:
516
571
  // after an internal delay (representing await this.abort()), it checks the
517
- // abortSignal that's where the real code would capture process.cwd() and
518
- // call _buildRuntime. If aborted, the real code must discard the session.
572
+ // abortSignal before selecting the workspace root and calling _buildRuntime.
573
+ // If aborted, the real code must discard the session.
519
574
  const s = makeMockSession({
520
575
  newSessionDelayMs: 200_000, // longer than NEW_SESSION_TIMEOUT_MS (120s)
521
576
  onSignalCheck: (aborted) => {
@@ -548,7 +603,7 @@ test("late-resolving newSession() after timeout receives aborted signal so tool
548
603
  abortedWhenLateSessionSettled,
549
604
  true,
550
605
  "runUnit must pass an aborted AbortSignal to newSession() when it resolves after the session-creation timeout (#3731). " +
551
- "Without this, AgentSession.newSession() captures root process.cwd() and rebuilds the tool runtime with wrong cwd.",
606
+ "Without this, AgentSession.newSession() can rebuild the tool runtime with a stale workspace root.",
552
607
  );
553
608
  } finally {
554
609
  mock.timers.reset();
@@ -637,7 +692,11 @@ function makeMockDeps(
637
692
  resolveMilestoneFile: () => null,
638
693
  reconcileMergeState: () => "clean",
639
694
  preflightCleanRoot: () => ({ stashPushed: false, summary: "" }),
640
- postflightPopStash: () => {},
695
+ postflightPopStash: () => ({
696
+ restored: true,
697
+ needsManualRecovery: false,
698
+ message: "restored",
699
+ }),
641
700
  getLedger: () => null,
642
701
  getProjectTotals: () => ({ cost: 0 }),
643
702
  formatCost: (c: number) => `$${c.toFixed(2)}`,
@@ -805,6 +864,145 @@ test("autoLoop exits on terminal complete state", async (t) => {
805
864
  );
806
865
  });
807
866
 
867
+ test("autoLoop stops before success notification when postflight stash restore needs recovery", async () => {
868
+ _resetPendingResolve();
869
+
870
+ const notifications: Array<{ msg: string; level: string }> = [];
871
+ const ctx = makeMockCtx();
872
+ ctx.ui.setStatus = () => {};
873
+ ctx.ui.notify = (msg: string, level: string) => {
874
+ notifications.push({ msg, level });
875
+ };
876
+ const pi = makeMockPi();
877
+ const s = makeLoopSession();
878
+ let stopReason = "";
879
+
880
+ const deps = makeMockDeps({
881
+ deriveState: async () => {
882
+ deps.callLog.push("deriveState");
883
+ return {
884
+ phase: "complete",
885
+ activeMilestone: { id: "M001", title: "Test", status: "complete" },
886
+ activeSlice: null,
887
+ activeTask: null,
888
+ registry: [{ id: "M001", status: "complete" }],
889
+ blockers: [],
890
+ } as any;
891
+ },
892
+ preflightCleanRoot: () => ({
893
+ stashPushed: true,
894
+ stashMarker: "gsd-preflight-stash:M001:test",
895
+ summary: "stashed",
896
+ }),
897
+ postflightPopStash: () => ({
898
+ restored: false,
899
+ needsManualRecovery: true,
900
+ message: "git stash pop stash@{0} failed after merge of milestone M001",
901
+ stashRef: "stash@{0}",
902
+ }),
903
+ sendDesktopNotification: () => {
904
+ deps.callLog.push("sendDesktopNotification");
905
+ },
906
+ logCmuxEvent: () => {
907
+ deps.callLog.push("logCmuxEvent");
908
+ },
909
+ stopAuto: async (_ctx, _pi, reason) => {
910
+ deps.callLog.push("stopAuto");
911
+ stopReason = reason ?? "";
912
+ },
913
+ });
914
+
915
+ await autoLoop(ctx, pi, s, deps);
916
+
917
+ assert.equal(stopReason, "Post-merge stash restore failed for milestone M001");
918
+ assert.ok(
919
+ notifications.some(
920
+ (n) => n.level === "error" && n.msg.includes("Post-merge stash restore failed for milestone M001"),
921
+ ),
922
+ "failed postflight restore must be surfaced as an error",
923
+ );
924
+ assert.ok(
925
+ !deps.callLog.includes("sendDesktopNotification"),
926
+ "must not emit milestone success desktop notification after stash restore failure",
927
+ );
928
+ assert.ok(
929
+ !deps.callLog.includes("logCmuxEvent"),
930
+ "must not emit milestone success cmux event after stash restore failure",
931
+ );
932
+ });
933
+
934
+ test("autoLoop marks transition merge complete before postflight recovery stop", async () => {
935
+ _resetPendingResolve();
936
+
937
+ const ctx = makeMockCtx();
938
+ ctx.ui.setStatus = () => {};
939
+ ctx.ui.notify = () => {};
940
+ const pi = makeMockPi();
941
+ const s = makeLoopSession();
942
+ let mergeCalls = 0;
943
+ let stopReason = "";
944
+
945
+ const deps = makeMockDeps({
946
+ deriveState: async () => {
947
+ deps.callLog.push("deriveState");
948
+ return {
949
+ phase: "executing",
950
+ activeMilestone: { id: "M002", title: "Next", status: "active" },
951
+ activeSlice: null,
952
+ activeTask: null,
953
+ registry: [
954
+ { id: "M001", title: "Done", status: "complete" },
955
+ { id: "M002", title: "Next", status: "active" },
956
+ ],
957
+ blockers: [],
958
+ } as any;
959
+ },
960
+ preflightCleanRoot: () => ({
961
+ stashPushed: true,
962
+ stashMarker: "gsd-preflight-stash:M001:test",
963
+ summary: "stashed",
964
+ }),
965
+ postflightPopStash: () => ({
966
+ restored: false,
967
+ needsManualRecovery: true,
968
+ message: "git stash pop stash@{0} failed after merge of milestone M001",
969
+ stashRef: "stash@{0}",
970
+ }),
971
+ resolver: {
972
+ get workPath() {
973
+ return "/tmp/project";
974
+ },
975
+ get projectRoot() {
976
+ return "/tmp/project";
977
+ },
978
+ get lockPath() {
979
+ return "/tmp/project";
980
+ },
981
+ enterMilestone: () => {
982
+ assert.fail("must not enter the next milestone after postflight recovery fails");
983
+ },
984
+ exitMilestone: () => {},
985
+ mergeAndExit: () => {
986
+ mergeCalls += 1;
987
+ },
988
+ mergeAndEnterNext: () => {},
989
+ } as any,
990
+ stopAuto: async (_ctx, _pi, reason) => {
991
+ deps.callLog.push("stopAuto");
992
+ stopReason = reason ?? "";
993
+ if (!s.milestoneMergedInPhases) {
994
+ deps.resolver.mergeAndExit("M001", ctx.ui);
995
+ }
996
+ },
997
+ });
998
+
999
+ await autoLoop(ctx, pi, s, deps);
1000
+
1001
+ assert.equal(stopReason, "Post-merge stash restore failed for milestone M001");
1002
+ assert.equal(s.milestoneMergedInPhases, true);
1003
+ assert.equal(mergeCalls, 1, "postflight recovery stop must not re-run an already completed transition merge");
1004
+ });
1005
+
808
1006
  test("autoLoop pauses when provider readiness cancels before dispatch", async () => {
809
1007
  _resetPendingResolve();
810
1008
 
@@ -879,7 +1077,11 @@ test("autoLoop passes structured session-lock failure details to the handler", a
879
1077
  );
880
1078
  });
881
1079
 
882
- test("autoLoop keeps queued sidecar work when the session lock is lost", async () => {
1080
+ // Regression for #5308: the iteration prelude must dequeue sidecar items
1081
+ // (popping the queue and emitting the `sidecar-dequeue` journal event) BEFORE
1082
+ // validateSessionLock + break-on-invalid. Inverting that order silently drops
1083
+ // queued sidecar work on lock-loss. Covers first-iteration and mid-session.
1084
+ test("autoLoop dequeues sidecar item before session-lock break (first iteration, #5308)", async () => {
883
1085
  _resetPendingResolve();
884
1086
 
885
1087
  const ctx = makeMockCtx();
@@ -911,12 +1113,87 @@ test("autoLoop keeps queued sidecar work when the session lock is lost", async (
911
1113
 
912
1114
  await autoLoop(ctx, pi, s, deps);
913
1115
 
914
- assert.equal(s.sidecarQueue.length, 1, "lost session lock must not consume queued sidecar work");
915
- assert.equal(s.sidecarQueue[0]?.unitId, "M001/S01/T01/review");
916
- assert.ok(!journalEvents.includes("sidecar-dequeue"), "sidecar dequeue must happen only after lock validation");
1116
+ assert.equal(
1117
+ s.sidecarQueue.length,
1118
+ 0,
1119
+ "sidecar item must be popped on lock-loss iteration (pre-#5308 ordering)",
1120
+ );
1121
+ assert.ok(
1122
+ journalEvents.includes("sidecar-dequeue"),
1123
+ "sidecar-dequeue journal event must be emitted before session-lock break",
1124
+ );
1125
+ assert.ok(
1126
+ deps.callLog.includes("handleLostSessionLock"),
1127
+ "session lock handler must still fire after sidecar dequeue",
1128
+ );
917
1129
  assert.ok(!deps.callLog.includes("deriveState"), "lock loss should stop before deriving state");
918
1130
  });
919
1131
 
1132
+ test("autoLoop dequeues sidecar item before session-lock break (mid-session, #5308)", async () => {
1133
+ _resetPendingResolve();
1134
+
1135
+ const ctx = makeMockCtx();
1136
+ ctx.ui.setStatus = () => {};
1137
+ const pi = makeMockPi();
1138
+ const s = makeLoopSession();
1139
+
1140
+ const journalEvents: string[] = [];
1141
+ let lockCheckCount = 0;
1142
+ const deps = makeMockDeps({
1143
+ // First iteration: lock valid; second iteration: lock invalidates.
1144
+ validateSessionLock: () => {
1145
+ lockCheckCount += 1;
1146
+ if (lockCheckCount === 1) {
1147
+ return { valid: true } as SessionLockStatus;
1148
+ }
1149
+ return {
1150
+ valid: false,
1151
+ failureReason: "compromised",
1152
+ expectedPid: process.pid,
1153
+ } as SessionLockStatus;
1154
+ },
1155
+ handleLostSessionLock: () => {
1156
+ deps.callLog.push("handleLostSessionLock");
1157
+ },
1158
+ emitJournalEvent: (entry) => {
1159
+ journalEvents.push(entry.eventType);
1160
+ },
1161
+ // Enqueue a sidecar item at the end of iteration 1, so iteration 2 begins
1162
+ // with a non-empty queue and an invalid lock.
1163
+ postUnitPostVerification: async () => {
1164
+ deps.callLog.push("postUnitPostVerification");
1165
+ s.sidecarQueue.push({
1166
+ kind: "hook" as const,
1167
+ unitType: "hook/review",
1168
+ unitId: "M001/S01/T01/review",
1169
+ prompt: "review the code",
1170
+ });
1171
+ return "continue" as const;
1172
+ },
1173
+ });
1174
+
1175
+ const loopPromise = autoLoop(ctx, pi, s, deps);
1176
+ // Allow the loop to reach runUnit's await on iteration 1.
1177
+ await new Promise((r) => setTimeout(r, 50));
1178
+ resolveAgentEnd(makeEvent());
1179
+ await loopPromise;
1180
+
1181
+ assert.ok(lockCheckCount >= 2, "lock validator must run on iteration 2");
1182
+ assert.equal(
1183
+ s.sidecarQueue.length,
1184
+ 0,
1185
+ "queued sidecar item must be popped on the lock-loss iteration",
1186
+ );
1187
+ assert.ok(
1188
+ journalEvents.includes("sidecar-dequeue"),
1189
+ "sidecar-dequeue journal event must be emitted before session-lock break",
1190
+ );
1191
+ assert.ok(
1192
+ deps.callLog.includes("handleLostSessionLock"),
1193
+ "lock-loss handler must still fire on iteration 2",
1194
+ );
1195
+ });
1196
+
920
1197
  test("autoLoop exits on terminal blocked state", async (t) => {
921
1198
  _resetPendingResolve();
922
1199
 
@@ -2010,6 +2287,37 @@ test("resolveAgentEndCancelled without args produces no errorContext field", asy
2010
2287
  assert.equal(resolved.errorContext, undefined, "errorContext must not be present when no args passed");
2011
2288
  });
2012
2289
 
2290
+ test("resolveAgentEndCancelled queues cancellation that arrives during session switch", () => {
2291
+ _resetPendingResolve();
2292
+
2293
+ _setSessionSwitchInFlight(true);
2294
+ const resolved = resolveAgentEndCancelled({
2295
+ message: "Claude Code process aborted by user",
2296
+ category: "aborted",
2297
+ isTransient: false,
2298
+ });
2299
+
2300
+ assert.equal(resolved, false);
2301
+ const pending = _consumePendingSwitchCancellation();
2302
+ assert.ok(pending?.errorContext, "queued cancellation should preserve errorContext");
2303
+ assert.equal(pending.errorContext.category, "aborted");
2304
+ assert.equal(pending.errorContext.message, "Claude Code process aborted by user");
2305
+ assert.equal(_consumePendingSwitchCancellation(), null);
2306
+ _resetPendingResolve();
2307
+ });
2308
+
2309
+ test("session-switch abort grace window is short-lived and resettable", () => {
2310
+ _resetPendingResolve();
2311
+
2312
+ _markSessionSwitchAbortGraceWindow(1_000);
2313
+
2314
+ assert.equal(isSessionSwitchAbortGraceActive(Date.now()), true);
2315
+ assert.equal(isSessionSwitchAbortGraceActive(Date.now() + 10_000), false);
2316
+
2317
+ _clearSessionSwitchAbortGraceWindow();
2318
+ assert.equal(isSessionSwitchAbortGraceActive(), false);
2319
+ });
2320
+
2013
2321
  // ─── #1571: artifact verification retry ──────────────────────────────────────
2014
2322
 
2015
2323
  test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)", async () => {
@@ -2430,6 +2738,199 @@ test("autoLoop stops when worktree has no .git for execute-task (#1833)", async
2430
2738
  );
2431
2739
  });
2432
2740
 
2741
+ test("dispatch health check wins before stuck detection for execute-task without .git", async () => {
2742
+ _resetPendingResolve();
2743
+
2744
+ const ctx = makeMockCtx();
2745
+ const pi = makeMockPi();
2746
+ const notifications: string[] = [];
2747
+ ctx.ui.notify = (msg: string) => { notifications.push(msg); };
2748
+
2749
+ const s = makeLoopSession({ basePath: "/tmp/broken-worktree" });
2750
+ const deps = makeMockDeps({
2751
+ existsSync: (p: string) => !p.endsWith(".git"),
2752
+ });
2753
+ const result = await runDispatch(
2754
+ {
2755
+ ctx,
2756
+ pi,
2757
+ s,
2758
+ deps,
2759
+ prefs: undefined,
2760
+ iteration: 1,
2761
+ flowId: "test-flow",
2762
+ nextSeq: () => 1,
2763
+ },
2764
+ {
2765
+ state: {
2766
+ phase: "executing",
2767
+ activeMilestone: { id: "M001", title: "Test", status: "active" },
2768
+ activeSlice: { id: "S01", title: "Slice 1" },
2769
+ activeTask: { id: "T01" },
2770
+ registry: [{ id: "M001", status: "active" }],
2771
+ blockers: [],
2772
+ } as any,
2773
+ mid: "M001",
2774
+ midTitle: "Test",
2775
+ },
2776
+ {
2777
+ recentUnits: [
2778
+ { key: "execute-task/M001/S01/T01" },
2779
+ { key: "execute-task/M001/S01/T01" },
2780
+ ],
2781
+ stuckRecoveryAttempts: 1,
2782
+ consecutiveFinalizeTimeouts: 0,
2783
+ },
2784
+ );
2785
+
2786
+ assert.equal(result.action, "break");
2787
+ assert.equal(result.reason, "worktree-invalid");
2788
+ assert.ok(deps.callLog.includes("stopAuto"), "should stop through worktree health check");
2789
+ assert.ok(
2790
+ notifications.some((n) => n.includes("Worktree health check failed") && n.includes("no .git")),
2791
+ "should notify about missing .git",
2792
+ );
2793
+ assert.ok(
2794
+ !notifications.some((n) => n.includes("Stuck on execute-task")),
2795
+ "stuck-loop message must not mask the worktree health failure",
2796
+ );
2797
+ });
2798
+
2799
+ test("pre-dispatch skip resolves before dispatch health and stuck accounting", async () => {
2800
+ _resetPendingResolve();
2801
+
2802
+ const ctx = makeMockCtx();
2803
+ const pi = makeMockPi();
2804
+ const notifications: string[] = [];
2805
+ ctx.ui.notify = (msg: string) => { notifications.push(msg); };
2806
+
2807
+ const s = makeLoopSession({ basePath: "/tmp/broken-worktree" });
2808
+ const deps = makeMockDeps({
2809
+ existsSync: (p: string) => !p.endsWith(".git"),
2810
+ runPreDispatchHooks: () => ({ firedHooks: ["skip-execute"], action: "skip" }),
2811
+ });
2812
+ const loopState = {
2813
+ recentUnits: [
2814
+ { key: "execute-task/M001/S01/T01" },
2815
+ { key: "execute-task/M001/S01/T01" },
2816
+ ],
2817
+ stuckRecoveryAttempts: 1,
2818
+ consecutiveFinalizeTimeouts: 0,
2819
+ };
2820
+
2821
+ const result = await runDispatch(
2822
+ {
2823
+ ctx,
2824
+ pi,
2825
+ s,
2826
+ deps,
2827
+ prefs: undefined,
2828
+ iteration: 1,
2829
+ flowId: "test-flow",
2830
+ nextSeq: () => 1,
2831
+ },
2832
+ {
2833
+ state: {
2834
+ phase: "executing",
2835
+ activeMilestone: { id: "M001", title: "Test", status: "active" },
2836
+ activeSlice: { id: "S01", title: "Slice 1" },
2837
+ activeTask: { id: "T01" },
2838
+ registry: [{ id: "M001", status: "active" }],
2839
+ blockers: [],
2840
+ } as any,
2841
+ mid: "M001",
2842
+ midTitle: "Test",
2843
+ },
2844
+ loopState,
2845
+ );
2846
+
2847
+ assert.equal(result.action, "continue");
2848
+ assert.ok(!deps.callLog.includes("stopAuto"), "skip hook should not stop on worktree health");
2849
+ assert.equal(loopState.recentUnits.length, 2, "skip hook should not update stuck accounting");
2850
+ assert.ok(
2851
+ notifications.some((n) => n.includes("Skipping execute-task M001/S01/T01")),
2852
+ "should notify about the skip hook",
2853
+ );
2854
+ assert.ok(
2855
+ !notifications.some((n) => n.includes("Worktree health check failed") || n.includes("Stuck on execute-task")),
2856
+ "health and stuck notifications must not run before skip hook resolution",
2857
+ );
2858
+ });
2859
+
2860
+ test("pre-dispatch replace resolves final unit before dispatch health and stuck accounting", async () => {
2861
+ _resetPendingResolve();
2862
+
2863
+ const ctx = makeMockCtx();
2864
+ const pi = makeMockPi();
2865
+ const notifications: string[] = [];
2866
+ ctx.ui.notify = (msg: string) => { notifications.push(msg); };
2867
+
2868
+ const s = makeLoopSession({ basePath: "/tmp/broken-worktree" });
2869
+ const deps = makeMockDeps({
2870
+ existsSync: (p: string) => !p.endsWith(".git"),
2871
+ runPreDispatchHooks: () => ({
2872
+ firedHooks: ["review"],
2873
+ action: "replace",
2874
+ unitType: "hook/review",
2875
+ prompt: "review before executing",
2876
+ model: "review-model",
2877
+ }),
2878
+ });
2879
+ const loopState = {
2880
+ recentUnits: [
2881
+ { key: "execute-task/M001/S01/T01" },
2882
+ { key: "execute-task/M001/S01/T01" },
2883
+ ],
2884
+ stuckRecoveryAttempts: 1,
2885
+ consecutiveFinalizeTimeouts: 0,
2886
+ };
2887
+
2888
+ const result = await runDispatch(
2889
+ {
2890
+ ctx,
2891
+ pi,
2892
+ s,
2893
+ deps,
2894
+ prefs: undefined,
2895
+ iteration: 1,
2896
+ flowId: "test-flow",
2897
+ nextSeq: () => 1,
2898
+ },
2899
+ {
2900
+ state: {
2901
+ phase: "executing",
2902
+ activeMilestone: { id: "M001", title: "Test", status: "active" },
2903
+ activeSlice: { id: "S01", title: "Slice 1" },
2904
+ activeTask: { id: "T01" },
2905
+ registry: [{ id: "M001", status: "active" }],
2906
+ blockers: [],
2907
+ } as any,
2908
+ mid: "M001",
2909
+ midTitle: "Test",
2910
+ },
2911
+ loopState,
2912
+ );
2913
+
2914
+ assert.equal(result.action, "next");
2915
+ assert.equal(result.data?.unitType, "hook/review");
2916
+ assert.equal(result.data?.finalPrompt, "review before executing");
2917
+ assert.equal(result.data?.hookModelOverride, "review-model");
2918
+ assert.ok(!deps.callLog.includes("stopAuto"), "replace hook should not stop on execute-task health");
2919
+ assert.deepEqual(
2920
+ loopState.recentUnits.map((u) => u.key),
2921
+ [
2922
+ "execute-task/M001/S01/T01",
2923
+ "execute-task/M001/S01/T01",
2924
+ "hook/review/M001/S01/T01",
2925
+ ],
2926
+ "stuck accounting should record the final replaced unit",
2927
+ );
2928
+ assert.ok(
2929
+ !notifications.some((n) => n.includes("Worktree health check failed") || n.includes("Stuck on execute-task")),
2930
+ "health and stuck notifications must use the final replaced unit",
2931
+ );
2932
+ });
2933
+
2433
2934
  test("autoLoop warns but proceeds for greenfield project (no project files) (#1833)", async () => {
2434
2935
  _resetPendingResolve();
2435
2936
 
@@ -2477,7 +2978,7 @@ test("autoLoop warns but proceeds for greenfield project (no project files) (#18
2477
2978
  "should not stop with health check failure for greenfield project",
2478
2979
  );
2479
2980
  const greenfieldWarning = notifications.find(
2480
- (n) => n.includes("no recognized project files") && n.includes("greenfield"),
2981
+ (n) => n.includes("no project content yet") && n.includes("greenfield"),
2481
2982
  );
2482
2983
  assert.ok(
2483
2984
  greenfieldWarning,