gsd-pi 2.77.0-dev.eaa4973bc → 2.78.0

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 (655) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/headless.js +49 -4
  4. package/dist/loader.js +0 -0
  5. package/dist/resource-loader.d.ts +40 -0
  6. package/dist/resource-loader.js +32 -13
  7. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  8. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  9. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  10. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  11. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  12. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  13. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
  15. package/dist/resources/extensions/github-sync/templates.js +103 -0
  16. package/dist/resources/extensions/google-search/index.js +3 -2
  17. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  18. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  19. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  20. package/dist/resources/extensions/gsd/auto-dispatch.js +142 -29
  21. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +150 -64
  23. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  24. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  25. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  27. package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
  28. package/dist/resources/extensions/gsd/auto.js +76 -21
  29. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  30. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  31. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  34. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  35. package/dist/resources/extensions/gsd/component-types.js +69 -0
  36. package/dist/resources/extensions/gsd/context-store.js +23 -7
  37. package/dist/resources/extensions/gsd/detection.js +49 -1
  38. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  40. package/dist/resources/extensions/gsd/forensics.js +106 -0
  41. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  42. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  43. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  44. package/dist/resources/extensions/gsd/git-service.js +126 -2
  45. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  46. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  47. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  48. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  49. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  50. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  51. package/dist/resources/extensions/gsd/model-router.js +6 -0
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  53. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  54. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  55. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  56. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  57. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  58. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  59. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  60. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  61. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  62. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  63. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  64. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  65. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  66. package/dist/resources/extensions/gsd/state.js +69 -58
  67. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  68. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  69. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  70. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  71. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  72. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  73. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  74. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  75. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  76. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  77. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  78. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  79. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  80. package/dist/resources/extensions/gsd/worktree-manager.js +85 -8
  81. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  82. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  83. package/dist/resources/extensions/mcp-client/index.js +3 -1
  84. package/dist/resources/extensions/ollama/index.js +5 -1
  85. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  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 +12 -12
  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/required-server-files.json +3 -3
  92. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  93. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  103. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  131. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  151. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  167. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  181. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  187. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/index.html +1 -1
  197. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  198. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  199. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  200. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  202. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/page.js +2 -2
  204. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  206. package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
  207. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  208. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  211. package/dist/web/standalone/.next/server/middleware.js +2 -2
  212. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  214. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  215. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  216. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  217. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  222. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  223. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  224. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  225. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  226. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  228. package/dist/web/standalone/server.js +1 -1
  229. package/package.json +2 -3
  230. package/packages/daemon/package.json +2 -2
  231. package/packages/daemon/src/logger.ts +4 -3
  232. package/packages/mcp-server/dist/server.d.ts +24 -0
  233. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  234. package/packages/mcp-server/dist/server.js +88 -87
  235. package/packages/mcp-server/dist/server.js.map +1 -1
  236. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  237. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  238. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  239. package/packages/mcp-server/package.json +2 -2
  240. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  241. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  242. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  243. package/packages/mcp-server/src/server.ts +131 -105
  244. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  245. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  246. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  247. package/packages/native/package.json +2 -2
  248. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  249. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  250. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  251. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  252. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  253. package/packages/pi-agent-core/package.json +1 -1
  254. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  255. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  256. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  257. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  258. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  259. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  260. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  261. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  262. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  263. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  264. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  265. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  266. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  267. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  268. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  269. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  270. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  271. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  272. package/packages/pi-ai/dist/models.test.js +36 -11
  273. package/packages/pi-ai/dist/models.test.js.map +1 -1
  274. package/packages/pi-ai/package.json +1 -1
  275. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  276. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  277. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  278. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  279. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  280. package/packages/pi-ai/src/models.test.ts +48 -11
  281. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  282. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  283. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  285. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  287. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  289. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  291. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  293. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  295. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  297. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  300. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  302. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  304. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  305. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  306. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  308. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  310. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  312. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/index.js +1 -0
  314. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  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 +30 -12
  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/input-controller.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  324. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  328. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  333. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  335. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  336. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  337. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  338. package/packages/pi-coding-agent/package.json +1 -1
  339. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  340. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  341. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  342. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  343. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  344. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  345. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  346. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  347. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  348. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  349. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  350. package/packages/pi-coding-agent/src/index.ts +1 -0
  351. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  352. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  353. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  354. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  355. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  356. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  357. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  358. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  359. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  360. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  361. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  362. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  363. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  364. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +37 -11
  365. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  366. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  367. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  368. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  369. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  370. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  371. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  372. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  373. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  374. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  375. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  376. package/packages/pi-tui/dist/components/editor.js +19 -0
  377. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  378. package/packages/pi-tui/dist/components/image.test.js +6 -5
  379. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  380. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  381. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  382. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  383. package/packages/pi-tui/package.json +1 -1
  384. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  385. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  386. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +42 -11
  387. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  388. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  389. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  390. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  391. package/packages/pi-tui/src/components/editor.ts +22 -0
  392. package/packages/pi-tui/src/components/image.test.ts +10 -5
  393. package/packages/pi-tui/src/editor-component.ts +3 -0
  394. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  395. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  396. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  397. package/packages/rpc-client/package.json +1 -1
  398. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  399. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  400. package/pkg/package.json +1 -1
  401. package/scripts/install.js +15 -1
  402. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  403. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  404. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  405. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  406. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  407. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  408. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  409. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
  410. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
  411. package/src/resources/extensions/github-sync/templates.ts +151 -0
  412. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  413. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  414. package/src/resources/extensions/google-search/index.ts +3 -2
  415. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  416. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  417. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  418. package/src/resources/extensions/gsd/auto-dispatch.ts +156 -29
  419. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  420. package/src/resources/extensions/gsd/auto-post-unit.ts +163 -73
  421. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  422. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  423. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  424. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  425. package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
  426. package/src/resources/extensions/gsd/auto.ts +90 -23
  427. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  428. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  429. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
  430. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  431. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  432. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  433. package/src/resources/extensions/gsd/component-types.ts +362 -0
  434. package/src/resources/extensions/gsd/context-store.ts +25 -8
  435. package/src/resources/extensions/gsd/detection.ts +58 -1
  436. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  437. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  438. package/src/resources/extensions/gsd/forensics.ts +118 -1
  439. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  440. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  441. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  442. package/src/resources/extensions/gsd/git-service.ts +149 -2
  443. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  444. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  445. package/src/resources/extensions/gsd/journal.ts +11 -1
  446. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  447. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  448. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  449. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  450. package/src/resources/extensions/gsd/model-router.ts +6 -0
  451. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  452. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  453. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  454. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  455. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  456. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  457. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  458. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  459. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  460. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  461. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  462. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  463. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  464. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  465. package/src/resources/extensions/gsd/state.ts +76 -66
  466. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  467. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  468. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  469. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  470. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  471. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +133 -292
  472. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  473. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  476. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  477. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  478. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  479. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  480. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  481. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  482. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  483. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  484. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  485. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  486. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  487. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  488. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  489. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  490. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  491. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  492. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  493. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  494. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  495. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  496. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  497. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  498. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  499. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  500. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  501. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  502. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  503. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  505. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  506. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  507. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  508. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  509. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  510. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  511. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  512. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  513. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  514. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  515. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  516. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  517. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  518. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  519. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  520. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  521. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  522. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  523. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  524. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  525. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  526. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  527. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  528. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  529. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  530. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
  531. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  532. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  533. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  534. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  535. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  536. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  537. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  538. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  539. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  540. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  541. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  542. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  543. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  544. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  545. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  546. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
  547. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
  548. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  549. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  550. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  551. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  552. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  553. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  554. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  555. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  556. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  557. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  558. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  559. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  560. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  561. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  562. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  563. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  564. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  565. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  566. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  567. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  568. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  569. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  570. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  571. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  572. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  573. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  574. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  575. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  576. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  577. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  578. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  579. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  580. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  581. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  582. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  583. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  584. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  585. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  586. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  587. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  588. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  589. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  590. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  591. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  592. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  593. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  594. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  595. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  596. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  597. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  598. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  599. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  600. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  601. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  602. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  603. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  604. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  605. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  606. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  607. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  608. package/src/resources/extensions/gsd/types.ts +3 -3
  609. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  610. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  611. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  612. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  613. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  614. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  615. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  616. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  617. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  618. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  619. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  620. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  621. package/src/resources/extensions/gsd/worktree-manager.ts +108 -7
  622. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  623. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  624. package/src/resources/extensions/mcp-client/index.ts +3 -1
  625. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  626. package/src/resources/extensions/ollama/index.ts +5 -1
  627. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  628. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  629. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  630. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  631. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  632. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  633. package/dist/web/standalone/.next/static/chunks/app/page-5b113fd32bc2a1c3.js +0 -1
  634. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  635. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  636. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  637. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  638. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  639. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  640. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  641. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  642. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  643. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  644. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  645. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  646. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  647. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  648. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  649. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  650. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  651. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  652. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  653. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  654. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → C1zT2kEfoLhDdbWPWKrXd}/_buildManifest.js +0 -0
  655. /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → C1zT2kEfoLhDdbWPWKrXd}/_ssgManifest.js +0 -0
@@ -12,13 +12,15 @@ import { _clearCurrentResolve } from "./resolve.js";
12
12
  import { runPreDispatch, runDispatch, runGuards, runUnitPhase, runFinalize, } from "./phases.js";
13
13
  import { debugLog } from "../debug-logger.js";
14
14
  import { isInfrastructureError, isTransientCooldownError, getCooldownRetryAfterMs, COOLDOWN_FALLBACK_WAIT_MS, MAX_COOLDOWN_RETRIES } from "./infra-errors.js";
15
+ import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
15
16
  import { resolveEngine } from "../engine-resolver.js";
16
17
  import { logWarning } from "../workflow-logger.js";
17
18
  import { gsdRoot } from "../paths.js";
19
+ import { atomicWriteSync } from "../atomic-write.js";
18
20
  import { resolveUokFlags } from "../uok/flags.js";
19
21
  import { scheduleSidecarQueue } from "../uok/execution-graph.js";
20
22
  import { ExecutionGraphScheduler } from "../uok/execution-graph.js";
21
- import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
23
+ import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs";
22
24
  import { join } from "node:path";
23
25
  // ── Stuck detection persistence (#3704) ──────────────────────────────────
24
26
  // Persist stuck detection state to disk so it survives session restarts.
@@ -62,12 +64,64 @@ function saveStuckState(basePath, state) {
62
64
  debugLog("autoLoop", { phase: "save-stuck-state-failed", error: err instanceof Error ? err.message : String(err) });
63
65
  }
64
66
  }
67
+ // ── Custom workflow verification retry persistence ───────────────────────
68
+ // Custom workflows can request verification retries after a step runs. The
69
+ // retry budget must survive an auto-mode restart or a failing verifier can
70
+ // consume a fresh retry budget every session.
71
+ function customVerifyRetryStateDir(s) {
72
+ return s.activeRunDir ? join(s.activeRunDir, "runtime") : join(gsdRoot(s.basePath), "runtime");
73
+ }
74
+ function customVerifyRetryStatePath(s) {
75
+ return join(customVerifyRetryStateDir(s), "custom-verify-retries.json");
76
+ }
77
+ function hydrateCustomVerifyRetryCounts(s) {
78
+ if (s.verificationRetryCount.size > 0) {
79
+ return s.verificationRetryCount;
80
+ }
81
+ try {
82
+ const raw = JSON.parse(readFileSync(customVerifyRetryStatePath(s), "utf-8"));
83
+ const counts = raw && typeof raw === "object" && raw.counts && typeof raw.counts === "object"
84
+ ? raw.counts
85
+ : {};
86
+ for (const [key, value] of Object.entries(counts)) {
87
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
88
+ s.verificationRetryCount.set(key, Math.floor(value));
89
+ }
90
+ }
91
+ }
92
+ catch (err) {
93
+ debugLog("autoLoop", { phase: "load-custom-verify-retries-failed", error: err instanceof Error ? err.message : String(err) });
94
+ }
95
+ return s.verificationRetryCount;
96
+ }
97
+ function saveCustomVerifyRetryCounts(s) {
98
+ const retryCounts = s.verificationRetryCount;
99
+ const filePath = customVerifyRetryStatePath(s);
100
+ try {
101
+ if (!retryCounts || retryCounts.size === 0) {
102
+ unlinkSync(filePath);
103
+ return;
104
+ }
105
+ mkdirSync(customVerifyRetryStateDir(s), { recursive: true });
106
+ atomicWriteSync(filePath, JSON.stringify({
107
+ counts: Object.fromEntries(retryCounts),
108
+ updatedAt: new Date().toISOString(),
109
+ }) + "\n");
110
+ }
111
+ catch (err) {
112
+ const code = err && typeof err === "object" && "code" in err ? err.code : undefined;
113
+ if (code !== "ENOENT") {
114
+ debugLog("autoLoop", { phase: "save-custom-verify-retries-failed", error: err instanceof Error ? err.message : String(err) });
115
+ }
116
+ }
117
+ }
65
118
  // ── Memory pressure monitoring (#3331) ──────────────────────────────────
66
119
  // Check heap usage every N iterations and trigger graceful shutdown before
67
120
  // the OS OOM killer sends SIGKILL. The threshold is 90% of the V8 heap
68
121
  // limit (--max-old-space-size or default ~1.5-4GB depending on platform).
69
122
  const MEMORY_CHECK_INTERVAL = 5; // check every 5 iterations
70
123
  const MEMORY_PRESSURE_THRESHOLD = 0.85; // 85% of heap limit
124
+ const MAX_CUSTOM_ENGINE_VERIFY_RETRIES = 3;
71
125
  function checkMemoryPressure() {
72
126
  const mem = process.memoryUsage();
73
127
  // v8.getHeapStatistics() gives heap_size_limit but requires import
@@ -360,15 +414,41 @@ export async function autoLoop(ctx, pi, s, deps, options) {
360
414
  break;
361
415
  }
362
416
  if (verifyResult === "retry") {
363
- debugLog("autoLoop", { phase: "custom-engine-verify-retry", iteration, unitId: iterData.unitId });
417
+ const recoveryKey = `${iterData.unitType}/${iterData.unitId}`;
418
+ const retryCounts = hydrateCustomVerifyRetryCounts(s);
419
+ const attempts = (retryCounts.get(recoveryKey) ?? 0) + 1;
420
+ retryCounts.set(recoveryKey, attempts);
421
+ saveCustomVerifyRetryCounts(s);
422
+ debugLog("autoLoop", { phase: "custom-engine-verify-retry", iteration, unitId: iterData.unitId, attempts });
364
423
  deps.uokObserver?.onPhaseResult("custom-engine", "retry", {
365
424
  unitType: iterData.unitType,
366
425
  unitId: iterData.unitId,
426
+ attempts,
367
427
  });
428
+ if (attempts > MAX_CUSTOM_ENGINE_VERIFY_RETRIES) {
429
+ const recovery = await policy.recover(iterData.unitType, iterData.unitId, { basePath: s.basePath });
430
+ if (recovery.outcome === "pause") {
431
+ await deps.pauseAuto(ctx, pi);
432
+ finishTurn("paused", "manual-attention", recovery.reason ?? "custom-engine-verify-retry-exhausted");
433
+ break;
434
+ }
435
+ if (recovery.outcome === "skip") {
436
+ await deps.stopAuto(ctx, pi, recovery.reason ??
437
+ `Custom workflow verification for ${iterData.unitId} requested skip after retry exhaustion, but the custom engine cannot reconcile skipped steps.`);
438
+ finishTurn("stopped", "manual-attention", "custom-engine-verify-retry-exhausted");
439
+ break;
440
+ }
441
+ const exhaustedReason = `Custom workflow verification for ${iterData.unitId} requested retry ${attempts} times without passing.`;
442
+ await deps.stopAuto(ctx, pi, recovery.outcome === "stop" && recovery.reason ? recovery.reason : exhaustedReason);
443
+ finishTurn("stopped", "manual-attention", "custom-engine-verify-retry-exhausted");
444
+ break;
445
+ }
368
446
  finishTurn("retry");
369
447
  continue;
370
448
  }
371
449
  // Verification passed — mark step complete
450
+ s.verificationRetryCount?.delete(`${iterData.unitType}/${iterData.unitId}`);
451
+ saveCustomVerifyRetryCounts(s);
372
452
  debugLog("autoLoop", { phase: "custom-engine-reconcile", iteration, unitId: iterData.unitId });
373
453
  const reconcileResult = await engine.reconcile(engineState, {
374
454
  unitType: iterData.unitType,
@@ -516,6 +596,48 @@ export async function autoLoop(ctx, pi, s, deps, options) {
516
596
  // completion even on failure (#2344). Without this, errors in
517
597
  // runFinalize leave the journal incomplete, making diagnosis harder.
518
598
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration, error: msg } });
599
+ // ── Pre-send model-policy block: not a retryable error (#4959 / #4850) ──
600
+ // The model-policy gate runs before the prompt is sent. When every
601
+ // candidate model is denied (cross-provider disabled + flat-rate
602
+ // baseline + tool-policy denial), retrying the same unit produces the
603
+ // same denial — burning the consecutive-error budget toward a 3-strike
604
+ // hard stop and corrupting auto-mode state. Pause for user attention
605
+ // instead, with the per-model deny reasons surfaced from the typed
606
+ // error.
607
+ if (loopErr instanceof ModelPolicyDispatchBlockedError) {
608
+ debugLog("autoLoop", {
609
+ phase: "model-policy-blocked",
610
+ iteration,
611
+ unitType: loopErr.unitType,
612
+ unitId: loopErr.unitId,
613
+ reasons: loopErr.reasons,
614
+ });
615
+ ctx.ui.notify(`Auto-mode paused: model-policy denied dispatch for ${loopErr.unitType}/${loopErr.unitId}. ${msg}`, "error");
616
+ deps.emitJournalEvent({
617
+ ts: new Date().toISOString(),
618
+ flowId,
619
+ seq: nextSeq(),
620
+ eventType: "unit-end",
621
+ data: {
622
+ unitType: loopErr.unitType,
623
+ unitId: loopErr.unitId,
624
+ status: "blocked",
625
+ reason: "model-policy-dispatch-blocked",
626
+ reasons: loopErr.reasons,
627
+ },
628
+ });
629
+ // Carry the blocked unit identity into the turn-result observer:
630
+ // the throw originated inside dispatch, so observedUnitType/Id were
631
+ // not assigned by the success path at lines 453/631/647 — but the
632
+ // typed error already names the unit (#4959 / CodeRabbit).
633
+ observedUnitType = loopErr.unitType;
634
+ observedUnitId = loopErr.unitId;
635
+ await deps.pauseAuto(ctx, pi);
636
+ finishTurn("paused", "manual-attention", msg);
637
+ // Do NOT increment consecutiveErrors — the failure is configuration,
638
+ // not a transient runtime fault.
639
+ break;
640
+ }
519
641
  // ── Infrastructure errors: immediate stop, no retry ──
520
642
  // These are unrecoverable (disk full, OOM, etc.). Retrying just burns
521
643
  // LLM budget on guaranteed failures.
@@ -11,12 +11,12 @@ import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from ".
11
11
  import { detectStuck } from "./detect-stuck.js";
12
12
  import { runUnit } from "./run-unit.js";
13
13
  import { debugLog } from "../debug-logger.js";
14
- import { PROJECT_FILES } from "../detection.js";
14
+ import { PROJECT_FILES, hasProjectFileInAncestor } from "../detection.js";
15
15
  import { MergeConflictError } from "../git-service.js";
16
16
  import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
17
17
  import { pauseAutoForProviderError } from "../provider-error-pause.js";
18
18
  import { resumeAutoAfterProviderDelay } from "../bootstrap/provider-error-resume.js";
19
- import { join, basename, dirname, parse as parsePath } from "node:path";
19
+ import { join, basename } from "node:path";
20
20
  import { existsSync, cpSync, readdirSync } from "node:fs";
21
21
  import { logWarning, logError, _resetLogs, drainLogs, drainAndSummarize, formatForNotification, hasAnyIssues, } from "../workflow-logger.js";
22
22
  import { gsdRoot } from "../paths.js";
@@ -27,7 +27,7 @@ import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "
27
27
  import { getEligibleSlices } from "../slice-parallel-eligibility.js";
28
28
  import { startSliceParallel } from "../slice-parallel-orchestrator.js";
29
29
  import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
30
- import { ensurePlanV2Graph } from "../uok/plan-v2.js";
30
+ import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "../uok/plan-v2.js";
31
31
  import { resolveUokFlags } from "../uok/flags.js";
32
32
  import { UokGateRunner } from "../uok/gate-runner.js";
33
33
  import { resetEvidence, loadEvidenceFromDisk } from "../safety/evidence-collector.js";
@@ -127,6 +127,7 @@ async function generateMilestoneReport(s, ctx, milestoneId) {
127
127
  async function closeoutAndStop(ctx, pi, s, deps, reason) {
128
128
  if (s.currentUnit) {
129
129
  await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
130
+ s.currentUnit = null;
130
131
  }
131
132
  await deps.stopAuto(ctx, pi, reason);
132
133
  }
@@ -296,27 +297,42 @@ export async function runPreDispatch(ic, loopState) {
296
297
  const compiled = ensurePlanV2Graph(s.basePath, state);
297
298
  if (!compiled.ok) {
298
299
  const reason = compiled.reason ?? "Plan v2 compilation failed";
300
+ if (isMissingFinalizedContextResult(compiled)) {
301
+ await runPreDispatchGate({
302
+ gateId: "plan-v2-gate",
303
+ gateType: "policy",
304
+ outcome: "pass",
305
+ failureClass: "none",
306
+ rationale: "plan v2 missing context recovery deferred to dispatch",
307
+ findings: reason,
308
+ milestoneId: state.activeMilestone?.id ?? undefined,
309
+ });
310
+ }
311
+ else {
312
+ await runPreDispatchGate({
313
+ gateId: "plan-v2-gate",
314
+ gateType: "policy",
315
+ outcome: "manual-attention",
316
+ failureClass: "manual-attention",
317
+ rationale: "plan v2 compile gate failed",
318
+ findings: reason,
319
+ milestoneId: state.activeMilestone?.id ?? undefined,
320
+ });
321
+ ctx.ui.notify(`Plan gate failed-closed: ${reason}\n\nIf this keeps happening, try: /gsd doctor heal`, "error");
322
+ await deps.pauseAuto(ctx, pi);
323
+ return { action: "break", reason: "plan-v2-gate-failed" };
324
+ }
325
+ }
326
+ if (compiled.ok) {
299
327
  await runPreDispatchGate({
300
328
  gateId: "plan-v2-gate",
301
329
  gateType: "policy",
302
- outcome: "manual-attention",
303
- failureClass: "manual-attention",
304
- rationale: "plan v2 compile gate failed",
305
- findings: reason,
330
+ outcome: "pass",
331
+ failureClass: "none",
332
+ rationale: "plan v2 compile gate passed",
306
333
  milestoneId: state.activeMilestone?.id ?? undefined,
307
334
  });
308
- ctx.ui.notify(`Plan gate failed-closed: ${reason}\n\nIf this keeps happening, try: /gsd doctor heal`, "error");
309
- await deps.pauseAuto(ctx, pi);
310
- return { action: "break", reason: "plan-v2-gate-failed" };
311
335
  }
312
- await runPreDispatchGate({
313
- gateId: "plan-v2-gate",
314
- gateType: "policy",
315
- outcome: "pass",
316
- failureClass: "none",
317
- rationale: "plan v2 compile gate passed",
318
- milestoneId: state.activeMilestone?.id ?? undefined,
319
- });
320
336
  }
321
337
  deps.syncCmuxSidebar(prefs, state);
322
338
  let mid = state.activeMilestone?.id;
@@ -667,10 +683,14 @@ export async function runDispatch(ic, preData, loopState) {
667
683
  const pauseAfterUatDispatch = dispatchResult.pauseAfterDispatch ?? false;
668
684
  // ── Sliding-window stuck detection with graduated recovery ──
669
685
  const derivedKey = `${unitType}/${unitId}`;
686
+ // Always record this dispatch in the sliding window so detectStuck() has
687
+ // accurate history. Skipping the push when pendingVerificationRetry is set
688
+ // caused infinite artifact-retry loops to be invisible to stuck detection
689
+ // (#2007). Only the *response* to a stuck signal is suppressed during retries.
690
+ loopState.recentUnits.push({ key: derivedKey });
691
+ if (loopState.recentUnits.length > STUCK_WINDOW_SIZE)
692
+ loopState.recentUnits.shift();
670
693
  if (!s.pendingVerificationRetry) {
671
- loopState.recentUnits.push({ key: derivedKey });
672
- if (loopState.recentUnits.length > STUCK_WINDOW_SIZE)
673
- loopState.recentUnits.shift();
674
694
  const stuckSignal = detectStuck(loopState.recentUnits);
675
695
  if (stuckSignal) {
676
696
  debugLog("autoLoop", {
@@ -996,22 +1016,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
996
1016
  // Monorepo support (#2347): if no project files in the worktree directory,
997
1017
  // walk parent directories up to the filesystem root. In monorepos,
998
1018
  // package.json / Cargo.toml etc. live in a parent directory.
999
- let hasProjectFileInParent = false;
1000
- if (!hasProjectFile && !hasSrcDir && !hasXcodeBundle) {
1001
- let checkDir = dirname(s.basePath);
1002
- const { root } = parsePath(checkDir);
1003
- while (checkDir !== root) {
1004
- // Stop at git repository boundary — ancestors above the repo root
1005
- // (e.g. ~ or /usr/local) may contain unrelated project files.
1006
- if (deps.existsSync(join(checkDir, ".git")))
1007
- break;
1008
- if (PROJECT_FILES.some((f) => deps.existsSync(join(checkDir, f)))) {
1009
- hasProjectFileInParent = true;
1010
- break;
1011
- }
1012
- checkDir = dirname(checkDir);
1013
- }
1014
- }
1019
+ const hasProjectFileInParent = !hasProjectFile && !hasSrcDir && !hasXcodeBundle
1020
+ ? hasProjectFileInAncestor(s.basePath, deps.existsSync)
1021
+ : false;
1015
1022
  if (!hasProjectFile && !hasSrcDir && !hasXcodeBundle && !hasProjectFileInParent) {
1016
1023
  // Greenfield projects won't have project files yet — the first task creates them.
1017
1024
  // Log a warning but allow execution to proceed. The .git check above is sufficient
@@ -1241,9 +1248,18 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
1241
1248
  }
1242
1249
  if (unitResult.status === "cancelled") {
1243
1250
  const errorCategory = unitResult.errorContext?.category;
1244
- // Provider-error pause: pauseAuto already handled cleanup and scheduled
1245
- // recovery. Don't hard-stop just break out of the loop (#2762).
1251
+ // Provider-error pause: agent_end recovery normally pauses before this
1252
+ // branch. Provider readiness failures happen before dispatch, so pause here
1253
+ // if nothing upstream already did.
1246
1254
  if (errorCategory === "provider") {
1255
+ if (!s.paused) {
1256
+ const detail = unitResult.errorContext?.message ?? `Provider unavailable for ${unitType} ${unitId}`;
1257
+ await pauseAutoForProviderError(ctx.ui, detail, () => deps.pauseAuto(ctx, pi), {
1258
+ isRateLimit: false,
1259
+ isTransient: Boolean(unitResult.errorContext?.isTransient),
1260
+ retryAfterMs: unitResult.errorContext?.retryAfterMs,
1261
+ });
1262
+ }
1247
1263
  await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
1248
1264
  debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext?.isTransient });
1249
1265
  return { action: "break", reason: "provider-pause" };
@@ -1537,6 +1553,8 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
1537
1553
  }
1538
1554
  // Both pre and post verification completed without timeout — reset counter
1539
1555
  loopState.consecutiveFinalizeTimeouts = 0;
1556
+ s.currentUnit = null;
1557
+ clearCurrentPhase();
1540
1558
  // Surface accumulated workflow-logger issues for this unit to the user.
1541
1559
  // Warnings/errors logged during the unit are buffered in the logger and
1542
1560
  // drained here so the user sees a single consolidated post-unit alert.
@@ -16,9 +16,7 @@
16
16
  * `let` or `var` declarations.
17
17
  */
18
18
  // ─── Constants ───────────────────────────────────────────────────────────────
19
- export const MAX_UNIT_DISPATCHES = 3;
20
19
  export const STUB_RECOVERY_THRESHOLD = 2;
21
- export const MAX_LIFETIME_DISPATCHES = 6;
22
20
  export const NEW_SESSION_TIMEOUT_MS = 120_000;
23
21
  // ─── AutoSession ─────────────────────────────────────────────────────────────
24
22
  export class AutoSession {
@@ -105,6 +103,11 @@ export class AutoSession {
105
103
  /** Set to true after phases.ts successfully calls mergeAndExit, so that
106
104
  * stopAuto does not attempt the same merge a second time (#2645). */
107
105
  milestoneMergedInPhases = false;
106
+ // #4765 — slice-cadence collapse: main-branch SHAs at the moment each
107
+ // milestone's first slice merge began. Used by resquashMilestoneOnMain at
108
+ // milestone completion to collapse N slice commits into one. Cleared when
109
+ // the milestone finishes (or resquash runs).
110
+ milestoneStartShas = new Map();
108
111
  // ── Dispatch circuit breakers ──────────────────────────────────────
109
112
  rewriteAttemptCount = 0;
110
113
  /** Tracks consecutive bootstrap attempts that found phase === "complete".
@@ -221,6 +224,7 @@ export class AutoSession {
221
224
  this.lastGitActionStatus = null;
222
225
  this.isolationDegraded = false;
223
226
  this.milestoneMergedInPhases = false;
227
+ this.milestoneStartShas = new Map();
224
228
  this.checkpointSha = null;
225
229
  // Signal handler
226
230
  this.sigtermHandler = null;
@@ -17,11 +17,47 @@ import { parseRoadmap } from "./parsers-legacy.js";
17
17
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
18
18
  import { logWarning, logError } from "./workflow-logger.js";
19
19
  import { join } from "node:path";
20
- import { hasImplementationArtifacts, classifyMilestoneSummaryContent } from "./auto-recovery.js";
20
+ import { hasImplementationArtifacts } from "./auto-recovery.js";
21
+ import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
21
22
  import { buildDiscussMilestonePrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildRefineSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, buildParallelResearchSlicesPrompt, checkNeedsReassessment, checkNeedsRunUat, } from "./auto-prompts.js";
22
23
  import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
23
24
  import { resolveUokFlags } from "./uok/flags.js";
24
25
  import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
26
+ import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
27
+ import { EXECUTION_ENTRY_PHASES, hasFinalizedMilestoneContext } from "./uok/plan-v2.js";
28
+ import { isAutoActive } from "./auto.js";
29
+ import { markDepthVerified } from "./bootstrap/write-gate.js";
30
+ let reassessmentChecker = checkNeedsReassessment;
31
+ export function setReassessmentCheckerForTest(checker) {
32
+ const previous = reassessmentChecker;
33
+ reassessmentChecker = checker;
34
+ return () => {
35
+ reassessmentChecker = previous;
36
+ };
37
+ }
38
+ async function readUatGateVerdict(basePath, mid, sliceId) {
39
+ const uatFile = resolveSliceFile(basePath, mid, sliceId, "UAT");
40
+ const assessmentFile = resolveSliceFile(basePath, mid, sliceId, "ASSESSMENT");
41
+ const uatContent = uatFile ? await loadFile(uatFile) : null;
42
+ const uatType = uatContent ? extractUatType(uatContent) : undefined;
43
+ const assessmentContent = assessmentFile ? await loadFile(assessmentFile) : null;
44
+ if (assessmentContent) {
45
+ const assessmentVerdict = extractVerdict(assessmentContent);
46
+ if (assessmentVerdict) {
47
+ return {
48
+ verdict: assessmentVerdict,
49
+ uatType: uatType ?? extractUatType(assessmentContent),
50
+ };
51
+ }
52
+ }
53
+ if (uatContent) {
54
+ const legacyUatVerdict = extractVerdict(uatContent);
55
+ if (legacyUatVerdict) {
56
+ return { verdict: legacyUatVerdict, uatType };
57
+ }
58
+ }
59
+ return null;
60
+ }
25
61
  function missingSliceStop(mid, phase) {
26
62
  return {
27
63
  action: "stop",
@@ -155,6 +191,45 @@ export const DISPATCH_RULES = [
155
191
  };
156
192
  },
157
193
  },
194
+ {
195
+ // #4671 — Recovery path for execution-entry phases with missing CONTEXT.md.
196
+ //
197
+ // Once `deriveStateFromDb` returns an execution-entry phase (executing /
198
+ // summarizing / validating-milestone / completing-milestone), the
199
+ // pre-planning guard at `pre-planning (no context) → discuss-milestone`
200
+ // no longer fires. The plan-v2 gate correctly detects the missing context
201
+ // but can only block — it cannot redispatch. Without this rule the
202
+ // milestone is stuck until `/gsd doctor heal` repairs it (and heal
203
+ // historically missed this check too).
204
+ //
205
+ // Fire BEFORE the execution-entry phase rules so we redispatch to
206
+ // `discuss-milestone` instead of hitting the plan-v2 gate.
207
+ name: "execution-entry phase (no context) → discuss-milestone",
208
+ match: async ({ state, mid, midTitle, basePath, structuredQuestionsAvailable }) => {
209
+ if (!EXECUTION_ENTRY_PHASES.has(state.phase))
210
+ return null;
211
+ // Align with the plan-v2 gate's lookup semantics: whitespace-only counts
212
+ // as missing, and an auto worktree may fall back to GSD_PROJECT_ROOT.
213
+ if (hasFinalizedMilestoneContext(basePath, mid))
214
+ return null;
215
+ // H6 fix (#4973): In auto-mode there is no human to answer the
216
+ // depth-verification ask_user_questions, so the write-gate deadlocks.
217
+ // Pre-mark the milestone as depth-verified so gsd_summary_save({artifact_type:"CONTEXT"})
218
+ // is not blocked. Safe ordering: session_switch fires clearDiscussionFlowState()
219
+ // (register-hooks.ts:106) before before_agent_start, which fires before resolveDispatch
220
+ // reaches this match fn — so this call always happens after any session-switch reset.
221
+ // Interactive sessions (isAutoActive()===false) are unaffected.
222
+ if (isAutoActive()) {
223
+ markDepthVerified(mid, basePath);
224
+ }
225
+ return {
226
+ action: "dispatch",
227
+ unitType: "discuss-milestone",
228
+ unitId: mid,
229
+ prompt: await buildDiscussMilestonePrompt(mid, midTitle, basePath, structuredQuestionsAvailable),
230
+ };
231
+ },
232
+ },
158
233
  {
159
234
  name: "summarizing → complete-slice",
160
235
  match: async ({ state, mid, midTitle, basePath }) => {
@@ -205,27 +280,29 @@ export const DISPATCH_RULES = [
205
280
  // Only applies when UAT dispatch is enabled
206
281
  if (!prefs?.uat_dispatch)
207
282
  return null;
208
- const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
209
- // DB-first: get completed slices from DB
210
- let completedSliceIds;
283
+ // DB-first: prefer closed slices from DB; fall back to ROADMAP on disk.
284
+ let closedSliceIds;
211
285
  if (isDbAvailable()) {
212
- completedSliceIds = getMilestoneSlices(mid)
213
- .filter(s => s.status === "complete")
286
+ closedSliceIds = getMilestoneSlices(mid)
287
+ .filter(s => isClosedStatus(s.status))
214
288
  .map(s => s.id);
215
289
  }
216
290
  else {
217
- return null;
291
+ // Filesystem fallback for degraded / unmigrated projects.
292
+ // `slice.done` in the parsed ROADMAP is the disk-level closed signal.
293
+ const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
294
+ const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
295
+ if (!roadmapContent)
296
+ return null;
297
+ const roadmap = parseRoadmap(roadmapContent);
298
+ closedSliceIds = roadmap.slices.filter(s => s.done).map(s => s.id);
218
299
  }
219
- for (const sliceId of completedSliceIds) {
220
- const resultFile = resolveSliceFile(basePath, mid, sliceId, "UAT");
221
- if (!resultFile)
300
+ for (const sliceId of closedSliceIds) {
301
+ const result = await readUatGateVerdict(basePath, mid, sliceId);
302
+ if (!result)
222
303
  continue;
223
- const content = await loadFile(resultFile);
224
- if (!content)
225
- continue;
226
- const verdict = extractVerdict(content);
227
- const uatType = extractUatType(content);
228
- if (verdict && !isAcceptableUatVerdict(verdict, uatType)) {
304
+ const { verdict, uatType } = result;
305
+ if (!isAcceptableUatVerdict(verdict, uatType)) {
229
306
  return {
230
307
  action: "stop",
231
308
  reason: `UAT verdict for ${sliceId} is "${verdict}" — blocking progression until resolved.\nReview the UAT result and update the verdict to PASS, or re-run /gsd auto after fixing.`,
@@ -241,12 +318,16 @@ export const DISPATCH_RULES = [
241
318
  match: async ({ state, mid, midTitle, basePath, prefs }) => {
242
319
  if (prefs?.phases?.skip_reassess)
243
320
  return null;
244
- // Default reassess_after_slice to true reassessment after slice completion
245
- // is essential for roadmap integrity. Opt-out via explicit `false`.
246
- const reassessEnabled = prefs?.phases?.reassess_after_slice ?? true;
321
+ // Default reassess_after_slice to false per ADR-003 §4 most reassess
322
+ // units conclude "roadmap is fine" and burn a session for no change.
323
+ // The plan-slice prompt now carries a reassessment preamble so the
324
+ // next slice's planner does JIT roadmap verification at zero extra
325
+ // cost. Opt-in via explicit `reassess_after_slice: true` (e.g.
326
+ // burn-max profile) when you want the dedicated reassess session.
327
+ const reassessEnabled = prefs?.phases?.reassess_after_slice ?? false;
247
328
  if (!reassessEnabled)
248
329
  return null;
249
- const needsReassess = await checkNeedsReassessment(basePath, mid, state);
330
+ const needsReassess = await reassessmentChecker(basePath, mid, state);
250
331
  if (!needsReassess)
251
332
  return null;
252
333
  return {
@@ -262,6 +343,12 @@ export const DISPATCH_RULES = [
262
343
  match: async ({ state, mid, midTitle, basePath, structuredQuestionsAvailable }) => {
263
344
  if (state.phase !== "needs-discussion")
264
345
  return null;
346
+ // H6 fix (#4973): auto-mark depth-verified so the write-gate does not
347
+ // deadlock in non-interactive (auto-mode) runs. See ordering note at
348
+ // "execution-entry phase (no context) → discuss-milestone" above.
349
+ if (isAutoActive()) {
350
+ markDepthVerified(mid, basePath);
351
+ }
265
352
  return {
266
353
  action: "dispatch",
267
354
  unitType: "discuss-milestone",
@@ -279,6 +366,12 @@ export const DISPATCH_RULES = [
279
366
  const hasContext = !!(contextFile && (await loadFile(contextFile)));
280
367
  if (hasContext)
281
368
  return null; // fall through to next rule
369
+ // H6 fix (#4973): auto-mark depth-verified so the write-gate does not
370
+ // deadlock in non-interactive (auto-mode) runs. See ordering note at
371
+ // "execution-entry phase (no context) → discuss-milestone" above.
372
+ if (isAutoActive()) {
373
+ markDepthVerified(mid, basePath);
374
+ }
282
375
  return {
283
376
  action: "dispatch",
284
377
  unitType: "discuss-milestone",
@@ -352,6 +445,12 @@ export const DISPATCH_RULES = [
352
445
  return null;
353
446
  if (prefs?.phases?.skip_research || prefs?.phases?.skip_slice_research)
354
447
  return null;
448
+ // #4781 phase 2: trivial-scope milestones skip dedicated slice research.
449
+ // plan-slice absorbs the lightweight discovery a trivial deliverable
450
+ // needs. Null result (DB unavailable / unknown) falls through to today's
451
+ // behavior.
452
+ if (await getMilestonePipelineVariant(mid) === "trivial")
453
+ return null;
355
454
  // Load roadmap to find all slices
356
455
  const roadmapFile = resolveMilestoneFile(basePath, mid, "ROADMAP");
357
456
  const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
@@ -401,6 +500,9 @@ export const DISPATCH_RULES = [
401
500
  // Phase skip: skip research when preference or profile says so
402
501
  if (prefs?.phases?.skip_research || prefs?.phases?.skip_slice_research)
403
502
  return null;
503
+ // #4781 phase 2: trivial-scope milestones skip dedicated slice research.
504
+ if (await getMilestonePipelineVariant(mid) === "trivial")
505
+ return null;
404
506
  if (!state.activeSlice)
405
507
  return missingSliceStop(mid, state.phase);
406
508
  const sid = state.activeSlice.id;
@@ -682,22 +784,29 @@ export const DISPATCH_RULES = [
682
784
  level: "error",
683
785
  };
684
786
  }
685
- // Skip preference: write a minimal pass-through VALIDATION file
686
- if (prefs?.phases?.skip_milestone_validation) {
787
+ // #4781 phase 2: trivial-scope milestones skip the dedicated validate
788
+ // unit — complete-milestone's own verification steps (3/4/5 in the
789
+ // closer prompt) are sufficient proof for contained deliverables.
790
+ const trivialVariant = await getMilestonePipelineVariant(mid) === "trivial";
791
+ // Skip preference OR trivial scope: write a minimal pass-through VALIDATION file.
792
+ if (prefs?.phases?.skip_milestone_validation || trivialVariant) {
687
793
  const mDir = resolveMilestonePath(basePath, mid);
688
794
  if (mDir) {
689
795
  if (!existsSync(mDir))
690
796
  mkdirSync(mDir, { recursive: true });
691
797
  const validationPath = join(mDir, buildMilestoneFileName(mid, "VALIDATION"));
798
+ const skipSource = trivialVariant
799
+ ? "trivial-scope pipeline variant (#4781)"
800
+ : "`skip_milestone_validation` preference";
692
801
  const content = [
693
802
  "---",
694
803
  "verdict: pass",
695
804
  "remediation_round: 0",
696
805
  "---",
697
806
  "",
698
- "# Milestone Validation (skipped by preference)",
807
+ "# Milestone Validation (skipped)",
699
808
  "",
700
- "Milestone validation was skipped via `skip_milestone_validation` preference.",
809
+ `Milestone validation was skipped via ${skipSource}.`,
701
810
  ].join("\n");
702
811
  writeFileSync(validationPath, content, "utf-8");
703
812
  }
@@ -728,7 +837,7 @@ export const DISPATCH_RULES = [
728
837
  }
729
838
  const existingSummary = resolveMilestoneFile(basePath, mid, "SUMMARY");
730
839
  let summaryOutcome = "unknown";
731
- if (existingSummary && isDbAvailable()) {
840
+ if (existingSummary) {
732
841
  const summaryContent = await loadFile(existingSummary);
733
842
  if (summaryContent) {
734
843
  summaryOutcome = classifyMilestoneSummaryContent(summaryContent);
@@ -764,7 +873,7 @@ export const DISPATCH_RULES = [
764
873
  // Safety guard (#1703): verify the milestone produced implementation
765
874
  // artifacts (non-.gsd/ files). A milestone with only plan files and
766
875
  // zero implementation code should not be marked complete.
767
- const artifactCheck = hasImplementationArtifacts(basePath);
876
+ const artifactCheck = hasImplementationArtifacts(basePath, mid);
768
877
  if (artifactCheck === "absent") {
769
878
  return {
770
879
  action: "stop",
@@ -815,10 +924,14 @@ export const DISPATCH_RULES = [
815
924
  // - success summary: reconcile DB and skip re-dispatch
816
925
  // - failure summary: pause/fail-closed
817
926
  // - unknown summary: pause/fail-closed
818
- if (existingSummary && isDbAvailable()) {
819
- const milestone = getMilestone(mid);
820
- const status = milestone?.status ?? "missing";
927
+ if (existingSummary) {
928
+ const milestone = isDbAvailable() ? getMilestone(mid) : null;
929
+ const status = milestone?.status ?? (isDbAvailable() ? "missing" : "unavailable");
821
930
  if (summaryOutcome === "success") {
931
+ if (!isDbAvailable()) {
932
+ logWarning("dispatch", `Milestone ${mid} SUMMARY indicates completion while DB is unavailable — skipping duplicate complete-milestone dispatch`);
933
+ return { action: "skip" };
934
+ }
822
935
  try {
823
936
  updateMilestoneStatus(mid, "complete", new Date().toISOString());
824
937
  logWarning("dispatch", `Milestone ${mid} SUMMARY indicates completion while DB status was "${status}" — reconciled DB to complete (#4658)`);