gsd-pi 2.76.0 → 2.77.0-dev.c9c8932c6

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 (757) hide show
  1. package/README.md +32 -30
  2. package/dist/claude-cli-check.js +32 -3
  3. package/dist/cli.js +14 -0
  4. package/dist/extension-discovery.d.ts +6 -0
  5. package/dist/extension-discovery.js +37 -0
  6. package/dist/extension-registry.d.ts +3 -0
  7. package/dist/extension-sort.d.ts +18 -0
  8. package/dist/extension-sort.js +114 -0
  9. package/dist/extension-validator.d.ts +47 -0
  10. package/dist/extension-validator.js +127 -0
  11. package/dist/loader.js +35 -7
  12. package/dist/mcp-server.d.ts +7 -0
  13. package/dist/mcp-server.js +35 -1
  14. package/dist/onboarding.js +45 -0
  15. package/dist/resource-loader.d.ts +1 -1
  16. package/dist/resource-loader.js +2 -8
  17. package/dist/resources/agents/researcher.md +1 -1
  18. package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +134 -57
  20. package/dist/resources/extensions/cmux/index.js +20 -0
  21. package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
  22. package/dist/resources/extensions/google-search/index.js +2 -375
  23. package/dist/resources/extensions/gsd/auto/loop.js +9 -0
  24. package/dist/resources/extensions/gsd/auto/phases.js +104 -11
  25. package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
  26. package/dist/resources/extensions/gsd/auto/session.js +22 -1
  27. package/dist/resources/extensions/gsd/auto-dispatch.js +56 -17
  28. package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +59 -2
  30. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  31. package/dist/resources/extensions/gsd/auto-recovery.js +69 -1
  32. package/dist/resources/extensions/gsd/auto-start.js +74 -59
  33. package/dist/resources/extensions/gsd/auto-verification.js +33 -0
  34. package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
  35. package/dist/resources/extensions/gsd/auto.js +92 -37
  36. package/dist/resources/extensions/gsd/blocked-models.js +68 -0
  37. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
  38. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
  39. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
  40. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
  41. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +23 -0
  42. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +95 -29
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  45. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  46. package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
  47. package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
  48. package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
  49. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  50. package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
  51. package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
  52. package/dist/resources/extensions/gsd/db-writer.js +88 -16
  53. package/dist/resources/extensions/gsd/dispatch-guard.js +44 -3
  54. package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
  55. package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
  56. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
  57. package/dist/resources/extensions/gsd/error-classifier.js +31 -3
  58. package/dist/resources/extensions/gsd/exec-history.js +120 -0
  59. package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
  60. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  61. package/dist/resources/extensions/gsd/gsd-db.js +168 -23
  62. package/dist/resources/extensions/gsd/guided-flow.js +190 -1
  63. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  64. package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
  65. package/dist/resources/extensions/gsd/init-wizard.js +15 -1
  66. package/dist/resources/extensions/gsd/key-manager.js +28 -0
  67. package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
  68. package/dist/resources/extensions/gsd/memory-store.js +19 -0
  69. package/dist/resources/extensions/gsd/model-router.js +36 -3
  70. package/dist/resources/extensions/gsd/notifications.js +30 -16
  71. package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
  72. package/dist/resources/extensions/gsd/preferences-types.js +9 -0
  73. package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
  74. package/dist/resources/extensions/gsd/preferences.js +17 -17
  75. package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
  76. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  78. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  80. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  81. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  82. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  84. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
  85. package/dist/resources/extensions/gsd/prompts/system.md +1 -0
  86. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  87. package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
  88. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  89. package/dist/resources/extensions/gsd/state.js +43 -4
  90. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  91. package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
  92. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
  93. package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
  94. package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
  95. package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
  96. package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
  97. package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
  98. package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  99. package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
  100. package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
  101. package/dist/resources/extensions/search-the-web/native-search.js +45 -13
  102. package/dist/resources/extensions/shared/cmux-events.js +12 -0
  103. package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
  104. package/dist/resources/skills/api-design/SKILL.md +190 -0
  105. package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
  106. package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
  107. package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
  108. package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
  109. package/dist/resources/skills/forensics/SKILL.md +153 -0
  110. package/dist/resources/skills/grill-me/SKILL.md +93 -0
  111. package/dist/resources/skills/handoff/SKILL.md +121 -0
  112. package/dist/resources/skills/observability/SKILL.md +174 -0
  113. package/dist/resources/skills/security-review/SKILL.md +181 -0
  114. package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
  115. package/dist/resources/skills/tdd/SKILL.md +112 -0
  116. package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
  117. package/dist/resources/skills/write-docs/SKILL.md +82 -0
  118. package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/web/standalone/.next/BUILD_ID +1 -1
  121. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  122. package/dist/web/standalone/.next/build-manifest.json +4 -4
  123. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  124. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  125. package/dist/web/standalone/.next/required-server-files.json +4 -4
  126. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  201. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  215. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  217. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  219. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  221. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/index.html +1 -1
  231. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  232. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  233. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  234. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  236. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  237. package/dist/web/standalone/.next/server/app/page.js +2 -2
  238. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  240. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  241. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  242. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  244. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/middleware.js +2 -2
  246. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  248. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  249. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  250. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  251. package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +9 -0
  252. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  253. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  254. package/dist/web/standalone/.next/static/chunks/app/page-5b113fd32bc2a1c3.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-1832629448831fdc.js} +1 -1
  258. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  259. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  260. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  261. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  264. package/dist/web/standalone/server.js +1 -1
  265. package/dist/welcome-screen.js +6 -1
  266. package/dist/wizard.js +2 -0
  267. package/package.json +14 -12
  268. package/packages/daemon/package.json +2 -2
  269. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  270. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  271. package/packages/mcp-server/dist/remote-questions.js +732 -0
  272. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  273. package/packages/mcp-server/dist/server.d.ts +7 -0
  274. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  275. package/packages/mcp-server/dist/server.js +70 -8
  276. package/packages/mcp-server/dist/server.js.map +1 -1
  277. package/packages/mcp-server/dist/session-manager.d.ts +14 -0
  278. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  279. package/packages/mcp-server/dist/session-manager.js +49 -1
  280. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
  282. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  283. package/packages/mcp-server/dist/workflow-tools.js +163 -25
  284. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  285. package/packages/mcp-server/package.json +9 -3
  286. package/packages/mcp-server/src/mcp-server.test.ts +67 -0
  287. package/packages/mcp-server/src/readers/readers.test.ts +5 -1
  288. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  289. package/packages/mcp-server/src/remote-questions.ts +916 -0
  290. package/packages/mcp-server/src/server.ts +89 -14
  291. package/packages/mcp-server/src/session-manager.ts +43 -1
  292. package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
  293. package/packages/mcp-server/src/workflow-tools.ts +215 -43
  294. package/packages/mcp-server/tsconfig.test.json +19 -0
  295. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  296. package/packages/native/package.json +6 -1
  297. package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
  298. package/packages/native/tsconfig.tsbuildinfo +1 -1
  299. package/packages/pi-agent-core/dist/agent-loop.js +12 -0
  300. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  301. package/packages/pi-agent-core/dist/types.d.ts +30 -0
  302. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  303. package/packages/pi-agent-core/dist/types.js.map +1 -1
  304. package/packages/pi-agent-core/package.json +6 -1
  305. package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
  306. package/packages/pi-agent-core/src/agent-loop.ts +14 -0
  307. package/packages/pi-agent-core/src/types.ts +34 -0
  308. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  309. package/packages/pi-ai/dist/models/custom.d.ts +38 -0
  310. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/models/custom.js +41 -0
  312. package/packages/pi-ai/dist/models/custom.js.map +1 -1
  313. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  314. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  315. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
  316. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
  317. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
  318. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
  319. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  320. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  321. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  322. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  323. package/packages/pi-ai/dist/providers/anthropic.js +13 -4
  324. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  325. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  326. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  327. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  328. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  329. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  330. package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
  331. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  332. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  333. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  334. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  335. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  336. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
  337. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
  338. package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
  339. package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
  340. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
  341. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
  342. package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
  343. package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
  344. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  345. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
  346. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  347. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
  348. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  349. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
  351. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  352. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
  353. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
  354. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
  355. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
  356. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  357. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
  358. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  359. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
  360. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
  361. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
  362. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
  363. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
  364. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
  365. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
  366. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
  367. package/packages/pi-ai/package.json +6 -1
  368. package/packages/pi-ai/src/models/custom.ts +42 -0
  369. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  370. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
  371. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  372. package/packages/pi-ai/src/providers/anthropic.ts +15 -4
  373. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  374. package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
  375. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  376. package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
  377. package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
  378. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
  379. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
  380. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
  381. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
  382. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
  383. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
  384. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
  385. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  386. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
  387. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
  389. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/agent-session.js +32 -2
  391. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
  393. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
  395. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  396. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
  397. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
  399. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  400. package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
  401. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  403. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +8 -2
  404. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  405. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
  406. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
  407. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
  408. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  409. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
  410. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
  411. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
  412. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
  413. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
  414. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
  415. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
  416. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
  417. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  418. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  419. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  420. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
  421. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  422. package/packages/pi-coding-agent/dist/core/extensions/loader.js +28 -8
  423. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  424. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
  425. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  426. package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
  427. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  428. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +212 -2
  429. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  430. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  431. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
  432. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
  433. package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
  434. package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
  435. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
  436. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
  437. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
  438. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
  439. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  440. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  441. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  442. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  443. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
  444. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
  446. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
  447. package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
  448. package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
  449. package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
  450. package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
  451. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
  452. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
  453. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
  454. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
  455. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
  456. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  457. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  458. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  459. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  460. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  461. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
  462. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
  463. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
  464. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  465. package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
  466. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  467. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
  468. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
  469. package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
  470. package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
  471. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
  472. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
  473. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
  474. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
  475. package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
  476. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  477. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  478. package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
  479. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  480. package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
  481. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  482. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
  483. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  484. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  485. package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
  486. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  487. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
  488. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
  489. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  490. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  491. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  492. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
  493. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  494. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
  495. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  496. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  497. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
  498. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  499. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
  500. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  501. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
  502. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  503. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
  504. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  505. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  506. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  507. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  508. package/packages/pi-coding-agent/package.json +6 -1
  509. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
  510. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
  511. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
  512. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
  513. package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
  514. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +8 -1
  515. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
  516. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
  517. package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
  518. package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
  519. package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
  520. package/packages/pi-coding-agent/src/core/extensions/loader.ts +29 -11
  521. package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
  522. package/packages/pi-coding-agent/src/core/extensions/types.ts +266 -0
  523. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
  524. package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
  525. package/packages/pi-coding-agent/src/core/index.ts +10 -0
  526. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
  527. package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
  528. package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
  529. package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
  530. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
  531. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  532. package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
  533. package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
  534. package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
  535. package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
  536. package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
  537. package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
  538. package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
  539. package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
  540. package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
  541. package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
  542. package/packages/pi-coding-agent/src/index.ts +16 -0
  543. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
  544. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
  545. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
  546. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
  547. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  548. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  549. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
  550. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  551. package/packages/pi-tui/package.json +6 -1
  552. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
  553. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  554. package/packages/rpc-client/package.json +6 -1
  555. package/pkg/package.json +1 -1
  556. package/scripts/install.js +512 -0
  557. package/scripts/lib/workspace-manifest.cjs +86 -0
  558. package/scripts/link-workspace-packages.cjs +5 -16
  559. package/scripts/postinstall.js +9 -178
  560. package/src/resources/agents/researcher.md +1 -1
  561. package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
  562. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +148 -61
  563. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +236 -5
  564. package/src/resources/extensions/cmux/index.ts +35 -10
  565. package/src/resources/extensions/google-search/extension-manifest.json +5 -4
  566. package/src/resources/extensions/google-search/index.ts +8 -470
  567. package/src/resources/extensions/gsd/auto/loop-deps.ts +15 -1
  568. package/src/resources/extensions/gsd/auto/loop.ts +9 -0
  569. package/src/resources/extensions/gsd/auto/phases.ts +131 -10
  570. package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
  571. package/src/resources/extensions/gsd/auto/session.ts +35 -2
  572. package/src/resources/extensions/gsd/auto/types.ts +1 -1
  573. package/src/resources/extensions/gsd/auto-dispatch.ts +59 -16
  574. package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
  575. package/src/resources/extensions/gsd/auto-post-unit.ts +62 -3
  576. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  577. package/src/resources/extensions/gsd/auto-recovery.ts +62 -1
  578. package/src/resources/extensions/gsd/auto-start.ts +80 -74
  579. package/src/resources/extensions/gsd/auto-verification.ts +33 -0
  580. package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
  581. package/src/resources/extensions/gsd/auto.ts +100 -41
  582. package/src/resources/extensions/gsd/blocked-models.ts +98 -0
  583. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
  584. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
  585. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
  586. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
  587. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +26 -0
  588. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
  589. package/src/resources/extensions/gsd/bootstrap/system-context.ts +102 -35
  590. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  591. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  592. package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
  593. package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
  594. package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
  595. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  596. package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
  597. package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
  598. package/src/resources/extensions/gsd/db-writer.ts +88 -17
  599. package/src/resources/extensions/gsd/dispatch-guard.ts +44 -2
  600. package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
  601. package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
  602. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
  603. package/src/resources/extensions/gsd/error-classifier.ts +36 -3
  604. package/src/resources/extensions/gsd/exec-history.ts +153 -0
  605. package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
  606. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  607. package/src/resources/extensions/gsd/gsd-db.ts +186 -23
  608. package/src/resources/extensions/gsd/guided-flow.ts +222 -1
  609. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  610. package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
  611. package/src/resources/extensions/gsd/init-wizard.ts +15 -1
  612. package/src/resources/extensions/gsd/journal.ts +2 -1
  613. package/src/resources/extensions/gsd/key-manager.ts +28 -0
  614. package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
  615. package/src/resources/extensions/gsd/memory-store.ts +26 -0
  616. package/src/resources/extensions/gsd/model-router.ts +42 -1
  617. package/src/resources/extensions/gsd/notifications.ts +27 -15
  618. package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
  619. package/src/resources/extensions/gsd/preferences-types.ts +46 -0
  620. package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
  621. package/src/resources/extensions/gsd/preferences.ts +17 -17
  622. package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
  623. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  624. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  625. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  626. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  627. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  628. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  629. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  630. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  631. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
  632. package/src/resources/extensions/gsd/prompts/system.md +1 -0
  633. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  634. package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
  635. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  636. package/src/resources/extensions/gsd/state.ts +45 -4
  637. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
  638. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
  639. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  640. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
  641. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
  642. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
  643. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
  644. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
  645. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
  646. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
  647. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
  648. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  649. package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
  650. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
  651. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
  652. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
  653. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
  654. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  655. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  656. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
  657. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  658. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
  659. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
  660. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +9 -9
  661. package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
  662. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
  663. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  664. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
  665. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  666. package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
  667. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
  668. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
  669. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
  670. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
  671. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +121 -0
  672. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
  673. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
  674. package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
  675. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
  676. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
  677. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
  678. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
  679. package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
  680. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
  681. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
  682. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  683. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
  684. package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
  685. package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
  686. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  687. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
  688. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  689. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
  690. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
  691. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
  692. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  693. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
  694. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
  695. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
  696. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  697. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
  698. package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
  699. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  700. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
  701. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
  702. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  703. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  704. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
  705. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  706. package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
  707. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
  708. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  709. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  710. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  711. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  712. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
  713. package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
  714. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +136 -8
  715. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
  716. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  717. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
  718. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
  719. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
  720. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  721. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
  722. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  723. package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
  724. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
  725. package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
  726. package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
  727. package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
  728. package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
  729. package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
  730. package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
  731. package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  732. package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
  733. package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
  734. package/src/resources/extensions/search-the-web/native-search.ts +48 -12
  735. package/src/resources/extensions/shared/cmux-events.ts +59 -0
  736. package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
  737. package/src/resources/skills/api-design/SKILL.md +190 -0
  738. package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
  739. package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
  740. package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
  741. package/src/resources/skills/design-an-interface/SKILL.md +102 -0
  742. package/src/resources/skills/forensics/SKILL.md +153 -0
  743. package/src/resources/skills/grill-me/SKILL.md +93 -0
  744. package/src/resources/skills/handoff/SKILL.md +121 -0
  745. package/src/resources/skills/observability/SKILL.md +174 -0
  746. package/src/resources/skills/security-review/SKILL.md +181 -0
  747. package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
  748. package/src/resources/skills/tdd/SKILL.md +112 -0
  749. package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
  750. package/src/resources/skills/write-docs/SKILL.md +82 -0
  751. package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
  752. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
  753. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  754. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  755. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  756. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → H51SzzS_EEgdBsDVhrLBv}/_buildManifest.js +0 -0
  757. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → H51SzzS_EEgdBsDVhrLBv}/_ssgManifest.js +0 -0
@@ -26,15 +26,24 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
26
26
  let sessionResult;
27
27
  let sessionTimeoutHandle;
28
28
  const mySessionSwitchGeneration = ++sessionSwitchGeneration;
29
+ // #3731: Cancellation controller for newSession(). When the session-creation
30
+ // timeout fires, we abort this controller so that the still-in-flight
31
+ // newSession() discards itself after await this.abort() completes, preventing
32
+ // it from capturing the (now-root) process.cwd() and rebuilding the tool
33
+ // runtime with the wrong cwd.
34
+ const sessionAbortController = new AbortController();
29
35
  _setSessionSwitchInFlight(true);
30
36
  try {
31
- const sessionPromise = s.cmdCtx.newSession().finally(() => {
37
+ const sessionPromise = s.cmdCtx.newSession({ abortSignal: sessionAbortController.signal }).finally(() => {
32
38
  if (sessionSwitchGeneration === mySessionSwitchGeneration) {
33
39
  _setSessionSwitchInFlight(false);
34
40
  }
35
41
  });
36
42
  const timeoutPromise = new Promise((resolve) => {
37
- sessionTimeoutHandle = setTimeout(() => resolve({ cancelled: true }), NEW_SESSION_TIMEOUT_MS);
43
+ sessionTimeoutHandle = setTimeout(() => {
44
+ sessionAbortController.abort();
45
+ resolve({ cancelled: true });
46
+ }, NEW_SESSION_TIMEOUT_MS);
38
47
  });
39
48
  sessionResult = await Promise.race([sessionPromise, timeoutPromise]);
40
49
  }
@@ -92,6 +101,33 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
92
101
  catch (e) {
93
102
  logWarning("engine", "Failed to chdir to basePath before dispatch", { basePath: s.basePath, error: String(e) });
94
103
  }
104
+ // ── Provider request-readiness pre-check (#4555) ──
105
+ // Verify the provider can accept requests before dispatching. If the token
106
+ // has expired since bootstrap, return cancelled immediately so the unit is
107
+ // not wasted on a guaranteed 401.
108
+ {
109
+ const provider = s.currentUnitModel?.provider ?? ctx.model?.provider;
110
+ const registry = ctx.modelRegistry;
111
+ if (provider && registry != null && typeof registry.isProviderRequestReady === "function") {
112
+ let ready = false;
113
+ try {
114
+ ready = registry.isProviderRequestReady(provider);
115
+ }
116
+ catch {
117
+ ready = false;
118
+ }
119
+ if (!ready) {
120
+ return {
121
+ status: "cancelled",
122
+ errorContext: {
123
+ message: `Provider ${provider} is not request-ready (login/token expired)`,
124
+ category: "provider",
125
+ isTransient: false,
126
+ },
127
+ };
128
+ }
129
+ }
130
+ }
95
131
  // ── Send the prompt ──
96
132
  debugLog("runUnit", { phase: "send-message", unitType, unitId });
97
133
  pi.sendMessage({ customType: "gsd-auto", content: prompt, display: s.verbose }, { triggerTurn: true });
@@ -65,6 +65,8 @@ export class AutoSession {
65
65
  currentDispatchedModelId = null;
66
66
  originalModelId = null;
67
67
  originalModelProvider = null;
68
+ autoModeStartThinkingLevel = null;
69
+ originalThinkingLevel = null;
68
70
  lastBudgetAlertLevel = 0;
69
71
  // ── Recovery ─────────────────────────────────────────────────────────────
70
72
  pendingCrashRecovery = null;
@@ -77,6 +79,17 @@ export class AutoSession {
77
79
  lastStateRebuildAt = 0;
78
80
  // ── Sidecar queue ─────────────────────────────────────────────────────
79
81
  sidecarQueue = [];
82
+ // ── Pre-exec gate failure context (#4551) ───────────────────────────
83
+ /**
84
+ * Persisted when a pre-execution gate fails on a plan-slice or refine-slice
85
+ * unit. The planning → plan-slice dispatch rule reads this field and injects
86
+ * the failure details into the next re-dispatch prompt so the LLM can fix the
87
+ * specific issues instead of producing an identical plan.
88
+ *
89
+ * Cleared after it has been consumed (injected into the prompt) to avoid
90
+ * stale context bleeding into unrelated slices.
91
+ */
92
+ lastPreExecFailure = null;
80
93
  // ── Tool invocation errors (#2883) ──────────────────────────────────
81
94
  /** Set when a GSD tool execution ends with isError due to malformed/truncated
82
95
  * JSON arguments. Checked by postUnitPreVerification to break retry loops. */
@@ -137,7 +150,12 @@ export class AutoSession {
137
150
  this.unitLifetimeDispatches.clear();
138
151
  }
139
152
  get lockBasePath() {
140
- return this.originalBasePath || this.basePath;
153
+ // Prefer originalBasePath (project root); fall back to basePath.
154
+ // Strip /.gsd/worktrees/ suffix if basePath is itself a worktree path
155
+ // to avoid reading/writing the lock inside the worktree (#3729).
156
+ const resolved = this.originalBasePath || this.basePath;
157
+ const markerIdx = resolved.indexOf("/.gsd/worktrees/");
158
+ return markerIdx !== -1 ? resolved.slice(0, markerIdx) : resolved;
141
159
  }
142
160
  reset() {
143
161
  this.clearTimers();
@@ -177,6 +195,8 @@ export class AutoSession {
177
195
  this.currentDispatchedModelId = null;
178
196
  this.originalModelId = null;
179
197
  this.originalModelProvider = null;
198
+ this.autoModeStartThinkingLevel = null;
199
+ this.originalThinkingLevel = null;
180
200
  this.lastBudgetAlertLevel = 0;
181
201
  // Recovery
182
202
  this.pendingCrashRecovery = null;
@@ -195,6 +215,7 @@ export class AutoSession {
195
215
  this.sidecarQueue = [];
196
216
  this.rewriteAttemptCount = 0;
197
217
  this.consecutiveCompleteBootstraps = 0;
218
+ this.lastPreExecFailure = null;
198
219
  this.lastToolInvocationError = null;
199
220
  this.lastGitActionFailure = null;
200
221
  this.lastGitActionStatus = null;
@@ -17,7 +17,7 @@ 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 } from "./auto-recovery.js";
20
+ import { hasImplementationArtifacts, classifyMilestoneSummaryContent } from "./auto-recovery.js";
21
21
  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
22
  import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
23
23
  import { resolveUokFlags } from "./uok/flags.js";
@@ -451,18 +451,31 @@ export const DISPATCH_RULES = [
451
451
  },
452
452
  {
453
453
  name: "planning → plan-slice",
454
- match: async ({ state, mid, midTitle, basePath, sessionContextWindow, modelRegistry }) => {
454
+ match: async ({ state, mid, midTitle, basePath, sessionContextWindow, modelRegistry, session }) => {
455
455
  if (state.phase !== "planning")
456
456
  return null;
457
457
  if (!state.activeSlice)
458
458
  return missingSliceStop(mid, state.phase);
459
459
  const sid = state.activeSlice.id;
460
460
  const sTitle = state.activeSlice.title;
461
+ // #4551: Consume any persisted pre-exec failure for this slice so the
462
+ // re-dispatched prompt includes the exact blocked references. Clear the
463
+ // field immediately after reading to prevent stale context leaking into
464
+ // a later, unrelated plan-slice run.
465
+ const unitId = `${mid}/${sid}`;
466
+ let priorPreExecFailure;
467
+ if (session?.lastPreExecFailure?.unitId === unitId) {
468
+ priorPreExecFailure = {
469
+ blockingFindings: session.lastPreExecFailure.blockingFindings,
470
+ verdictExcerpt: session.lastPreExecFailure.verdictExcerpt,
471
+ };
472
+ session.lastPreExecFailure = null;
473
+ }
461
474
  return {
462
475
  action: "dispatch",
463
476
  unitType: "plan-slice",
464
- unitId: `${mid}/${sid}`,
465
- prompt: await buildPlanSlicePrompt(mid, midTitle, sid, sTitle, basePath, undefined, { sessionContextWindow, modelRegistry }),
477
+ unitId,
478
+ prompt: await buildPlanSlicePrompt(mid, midTitle, sid, sTitle, basePath, undefined, { sessionContextWindow, modelRegistry, priorPreExecFailure }),
466
479
  };
467
480
  },
468
481
  },
@@ -689,22 +702,13 @@ export const DISPATCH_RULES = [
689
702
  return { action: "skip" };
690
703
  }
691
704
  }
692
- // Reconciliation guard (#4324): when the SUMMARY file already exists
693
- // on disk but the DB says the milestone is not complete, the DB is
694
- // out of sync (e.g. journal reset, partial merge, crash recovery).
695
- // Reconcile the DB status directly instead of re-dispatching the
696
- // tool, which would overwrite the richer on-disk SUMMARY with a
697
- // thinner regenerated version — causing silent data loss.
698
705
  const existingSummary = resolveMilestoneFile(basePath, mid, "SUMMARY");
706
+ let summaryOutcome = "unknown";
699
707
  if (existingSummary && isDbAvailable()) {
700
- try {
701
- updateMilestoneStatus(mid, "complete", new Date().toISOString());
702
- logWarning("dispatch", `Milestone ${mid} has SUMMARY on disk but DB status was not complete — reconciled DB to complete (#4324)`);
703
- }
704
- catch (err) {
705
- logWarning("dispatch", `Failed to reconcile milestone ${mid} status: ${err instanceof Error ? err.message : String(err)}`);
708
+ const summaryContent = await loadFile(existingSummary);
709
+ if (summaryContent) {
710
+ summaryOutcome = classifyMilestoneSummaryContent(summaryContent);
706
711
  }
707
- return { action: "skip" };
708
712
  }
709
713
  // Safety guard (#2675): block completion when VALIDATION verdict is
710
714
  // needs-remediation. The state machine treats needs-remediation as
@@ -782,6 +786,41 @@ export const DISPATCH_RULES = [
782
786
  catch (err) { /* fall through — don't block on DB errors */
783
787
  logWarning("dispatch", `verification class check failed: ${err instanceof Error ? err.message : String(err)}`);
784
788
  }
789
+ // Disk/DB mismatch handling (#4658): SUMMARY presence alone is not enough.
790
+ // Apply post-gate policy:
791
+ // - success summary: reconcile DB and skip re-dispatch
792
+ // - failure summary: pause/fail-closed
793
+ // - unknown summary: pause/fail-closed
794
+ if (existingSummary && isDbAvailable()) {
795
+ const milestone = getMilestone(mid);
796
+ const status = milestone?.status ?? "missing";
797
+ if (summaryOutcome === "success") {
798
+ try {
799
+ updateMilestoneStatus(mid, "complete", new Date().toISOString());
800
+ logWarning("dispatch", `Milestone ${mid} SUMMARY indicates completion while DB status was "${status}" — reconciled DB to complete (#4658)`);
801
+ return { action: "skip" };
802
+ }
803
+ catch (err) {
804
+ return {
805
+ action: "stop",
806
+ level: "warning",
807
+ reason: `Milestone ${mid} SUMMARY indicates completion but DB reconciliation failed (${err instanceof Error ? err.message : String(err)}). Auto-mode paused for manual review.`,
808
+ };
809
+ }
810
+ }
811
+ if (summaryOutcome === "failure") {
812
+ return {
813
+ action: "stop",
814
+ level: "warning",
815
+ reason: `Milestone ${mid} has a failure-path SUMMARY while DB status is "${status}". Auto-mode will not promote completion from failure artifacts. Re-run complete-milestone only after blockers are resolved and verification passes.`,
816
+ };
817
+ }
818
+ return {
819
+ action: "stop",
820
+ level: "warning",
821
+ reason: `Milestone ${mid} has an ambiguous SUMMARY while DB status is "${status}". Auto-mode paused instead of promoting completion from file presence alone.`,
822
+ };
823
+ }
785
824
  return {
786
825
  action: "dispatch",
787
826
  unitType: "complete-milestone",
@@ -12,10 +12,20 @@ import { getSessionModelOverride } from "./session-model-override.js";
12
12
  import { logWarning } from "./workflow-logger.js";
13
13
  import { resolveUokFlags } from "./uok/flags.js";
14
14
  import { applyModelPolicyFilter } from "./uok/model-policy.js";
15
+ import { isModelBlocked } from "./blocked-models.js";
16
+ function reapplyThinkingLevel(pi, level) {
17
+ if (!level)
18
+ return;
19
+ pi.setThinkingLevel(level);
20
+ }
15
21
  export function resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode = true) {
16
22
  const explicitConfig = resolveModelWithFallbacksForUnit(unitType);
17
- if (explicitConfig)
18
- return explicitConfig;
23
+ if (explicitConfig) {
24
+ return {
25
+ ...explicitConfig,
26
+ source: "explicit",
27
+ };
28
+ }
19
29
  // In interactive mode, don't synthesize a routing-based model config.
20
30
  // The user's session model (/model) should be used as-is (#3962).
21
31
  if (!isAutoMode)
@@ -38,6 +48,7 @@ export function resolvePreferredModelConfig(unitType, autoModeStartModel, isAuto
38
48
  return {
39
49
  primary: ceilingModel,
40
50
  fallbacks: [],
51
+ source: "synthesized",
41
52
  };
42
53
  }
43
54
  /**
@@ -52,7 +63,9 @@ export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, p
52
63
  * Dynamic routing only applies in auto-mode where cost optimization is expected. (#3962) */
53
64
  isAutoMode = true,
54
65
  /** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
55
- sessionModelOverride) {
66
+ sessionModelOverride,
67
+ /** Thinking level captured at auto-mode start and re-applied after model swaps. */
68
+ autoModeStartThinkingLevel) {
56
69
  const uokFlags = resolveUokFlags(prefs);
57
70
  const effectiveSessionModelOverride = sessionModelOverride === undefined
58
71
  ? getSessionModelOverride(ctx.sessionManager.getSessionId())
@@ -90,6 +103,11 @@ sessionModelOverride) {
90
103
  if (prefs?.token_profile === "burn-max") {
91
104
  routingConfig.enabled = false;
92
105
  }
106
+ if (modelConfig.source === "explicit") {
107
+ // Explicit per-phase model preferences express hard user intent.
108
+ // Dynamic routing may only treat synthesized tier ceilings as downgradeable.
109
+ routingConfig.enabled = false;
110
+ }
93
111
  let effectiveModelConfig = modelConfig;
94
112
  let routingTierLabel = "";
95
113
  let routingEligibleModels = availableModels;
@@ -210,6 +228,7 @@ sessionModelOverride) {
210
228
  effectiveModelConfig = {
211
229
  primary: routingResult.modelId,
212
230
  fallbacks: routingResult.fallbacks,
231
+ source: modelConfig.source,
213
232
  };
214
233
  // Always notify on model downgrade — users should see when their
215
234
  // model selection is overridden, not just in verbose mode (#3962).
@@ -249,6 +268,14 @@ sessionModelOverride) {
249
268
  }
250
269
  attemptedPolicyEligible = true;
251
270
  }
271
+ // Skip models the provider has previously rejected for this account
272
+ // (issue #4513). The block is persisted in .gsd/runtime/blocked-models.json
273
+ // so it survives /gsd auto restarts — without this, the same dead model
274
+ // gets reselected after every restart.
275
+ if (isModelBlocked(basePath, model.provider, model.id)) {
276
+ ctx.ui.notify(`Skipping blocked model ${model.provider}/${model.id} (provider rejected it for this account).`, "warning");
277
+ continue;
278
+ }
252
279
  // Warn if the ID is ambiguous across providers
253
280
  if (!modelId.includes("/")) {
254
281
  const providers = availableModels.filter(m => m.id === modelId).map(m => m.provider);
@@ -260,10 +287,11 @@ sessionModelOverride) {
260
287
  const ok = await pi.setModel(model, { persist: false });
261
288
  if (ok) {
262
289
  appliedModel = model;
290
+ reapplyThinkingLevel(pi, autoModeStartThinkingLevel);
263
291
  // ADR-005: Adjust active tool set for the selected model's provider capabilities.
264
292
  // Hard-filter incompatible tools, then let extensions override via adjust_tool_set hook.
265
293
  const activeToolNames = pi.getActiveTools();
266
- const { toolNames: compatibleTools, removedTools } = adjustToolSet(activeToolNames, model.api);
294
+ const { toolNames: compatibleTools, removedTools } = adjustToolSet(activeToolNames, model.api, model.provider);
267
295
  let finalToolNames = compatibleTools;
268
296
  // Fire adjust_tool_set hook — extensions can override the filtered tool set
269
297
  if (routingConfig.hooks !== false) {
@@ -314,19 +342,28 @@ sessionModelOverride) {
314
342
  // No model preference for this unit type — re-apply the model captured
315
343
  // at auto-mode start to prevent bleed from shared global settings.json (#650).
316
344
  const availableModels = ctx.modelRegistry.getAvailable();
317
- const startModel = availableModels.find(m => m.provider === autoModeStartModel.provider && m.id === autoModeStartModel.id);
318
- if (startModel) {
319
- const ok = await pi.setModel(startModel, { persist: false });
320
- if (!ok) {
321
- const byId = availableModels.find(m => m.id === autoModeStartModel.id);
322
- if (byId) {
323
- const fallbackOk = await pi.setModel(byId, { persist: false });
324
- if (fallbackOk)
325
- appliedModel = byId;
345
+ const startBlocked = isModelBlocked(basePath, autoModeStartModel.provider, autoModeStartModel.id);
346
+ if (startBlocked) {
347
+ ctx.ui.notify(`Auto-mode start model ${autoModeStartModel.provider}/${autoModeStartModel.id} is blocked for this account. Using current session model instead.`, "warning");
348
+ }
349
+ else {
350
+ const startModel = availableModels.find(m => m.provider === autoModeStartModel.provider && m.id === autoModeStartModel.id);
351
+ if (startModel) {
352
+ const ok = await pi.setModel(startModel, { persist: false });
353
+ if (!ok) {
354
+ const byId = availableModels.find(m => m.id === autoModeStartModel.id && !isModelBlocked(basePath, m.provider, m.id));
355
+ if (byId) {
356
+ const fallbackOk = await pi.setModel(byId, { persist: false });
357
+ if (fallbackOk) {
358
+ appliedModel = byId;
359
+ reapplyThinkingLevel(pi, autoModeStartThinkingLevel);
360
+ }
361
+ }
362
+ }
363
+ else {
364
+ appliedModel = startModel;
365
+ reapplyThinkingLevel(pi, autoModeStartThinkingLevel);
326
366
  }
327
- }
328
- else {
329
- appliedModel = startModel;
330
367
  }
331
368
  }
332
369
  }
@@ -30,7 +30,7 @@ import { checkPostUnitHooks, isRetryPending, consumeRetryTrigger, persistHookSta
30
30
  import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures } from "./captures.js";
31
31
  import { debugLog } from "./debug-logger.js";
32
32
  import { runSafely } from "./auto-utils.js";
33
- import { getEvidence } from "./safety/evidence-collector.js";
33
+ import { getEvidence, clearEvidenceFromDisk } from "./safety/evidence-collector.js";
34
34
  import { validateFileChanges } from "./safety/file-change-validator.js";
35
35
  // crossReferenceEvidence available for future use when verification_evidence is stored in DB
36
36
  // import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
@@ -45,8 +45,23 @@ import { ensureCodebaseMapFresh } from "./codebase-generator.js";
45
45
  import { resolveUokFlags } from "./uok/flags.js";
46
46
  import { UokGateRunner } from "./uok/gate-runner.js";
47
47
  import { writeTurnGitTransaction } from "./uok/gitops.js";
48
+ import { isClosedStatus } from "./status-guards.js";
48
49
  /** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
49
50
  const MAX_VERIFICATION_RETRIES = 3;
51
+ const COMPLETE_MILESTONE_DB_SETTLE_MS = 1500;
52
+ const COMPLETE_MILESTONE_DB_SETTLE_POLL_MS = 100;
53
+ async function waitForMilestoneDbClose(mid) {
54
+ const deadline = Date.now() + COMPLETE_MILESTONE_DB_SETTLE_MS;
55
+ while (Date.now() < deadline) {
56
+ if (!isDbAvailable())
57
+ return false;
58
+ const milestone = getMilestone(mid);
59
+ if (milestone && isClosedStatus(milestone.status))
60
+ return true;
61
+ await new Promise((resolve) => setTimeout(resolve, COMPLETE_MILESTONE_DB_SETTLE_POLL_MS));
62
+ }
63
+ return false;
64
+ }
50
65
  /** Enqueue a sidecar item (hook, triage, or quick-task) for the main loop to
51
66
  * drain via runUnit. Logs the enqueue event and notifies the UI. */
52
67
  function enqueueSidecar(s, ctx, entry, debugExtra, notification) {
@@ -535,7 +550,7 @@ export async function postUnitPreVerification(pctx, opts) {
535
550
  if (taskRow) {
536
551
  const expectedOutput = taskRow.expected_output ?? [];
537
552
  const plannedFiles = taskRow.files ?? [];
538
- const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles);
553
+ const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
539
554
  if (audit && audit.violations.length > 0) {
540
555
  const warnings = audit.violations.filter(v => v.severity === "warning");
541
556
  for (const v of warnings) {
@@ -588,6 +603,16 @@ export async function postUnitPreVerification(pctx, opts) {
588
603
  debugLog("postUnit", { phase: "safety-content-validation", error: String(e) });
589
604
  }
590
605
  }
606
+ // Clear persisted evidence file now that post-unit processing is complete
607
+ // (Bug #4385 — prevents stale evidence from affecting retries of same unit ID).
608
+ if (safetyConfig.evidence_collection && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
609
+ try {
610
+ clearEvidenceFromDisk(s.basePath, sMid, sSid, sTid);
611
+ }
612
+ catch (e) {
613
+ debugLog("postUnit", { phase: "safety-evidence-clear", error: String(e) });
614
+ }
615
+ }
591
616
  }
592
617
  }
593
618
  catch (e) {
@@ -607,6 +632,25 @@ export async function postUnitPreVerification(pctx, opts) {
607
632
  }
608
633
  // If verification failed, attempt to regenerate missing projection files
609
634
  // from DB data before giving up (e.g. research-slice produces PLAN from engine).
635
+ if (!triggerArtifactVerified) {
636
+ if (s.currentUnit.type === "complete-milestone") {
637
+ try {
638
+ const { milestone: mid } = parseUnitId(s.currentUnit.id);
639
+ if (mid) {
640
+ const settled = await waitForMilestoneDbClose(mid);
641
+ if (settled) {
642
+ triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.basePath);
643
+ if (triggerArtifactVerified) {
644
+ invalidateAllCaches();
645
+ }
646
+ }
647
+ }
648
+ }
649
+ catch (e) {
650
+ debugLog("postUnit", { phase: "artifact-verify-settle-db", error: String(e) });
651
+ }
652
+ }
653
+ }
610
654
  if (!triggerArtifactVerified) {
611
655
  try {
612
656
  const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
@@ -950,12 +994,25 @@ export async function postUnitPostVerification(pctx) {
950
994
  const suffix = blockingChecks.length > 3 ? `\n \u2022 ...and ${blockingChecks.length - 3} more` : "";
951
995
  const evidenceNote = `\nSee ${sid}-PRE-EXEC-VERIFY.json for full details.`;
952
996
  ctx.ui.notify(`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found\n${details}${suffix}${evidenceNote}`, "error");
997
+ // Persist failure context so the next plan-slice re-dispatch can inject
998
+ // it into the prompt and break the infinite loop (#4551).
999
+ s.lastPreExecFailure = {
1000
+ unitId: currentUnit.id,
1001
+ blockingFindings: blockingChecks.map(c => `[${c.category}] ${c.target}: ${c.message}`),
1002
+ verdictExcerpt: `status=${result.status}; ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} detected`,
1003
+ };
953
1004
  preExecPauseNeeded = true;
954
1005
  }
955
1006
  else if (result.status === "warn") {
956
1007
  ctx.ui.notify(`Pre-execution checks passed with warnings`, "warning");
957
1008
  // Strict mode: treat warnings as blocking
958
1009
  if (prefs?.enhanced_verification_strict === true) {
1010
+ const warnChecks = result.checks.filter(c => !c.passed);
1011
+ s.lastPreExecFailure = {
1012
+ unitId: currentUnit.id,
1013
+ blockingFindings: warnChecks.map(c => `[${c.category}] ${c.target}: ${c.message}`),
1014
+ verdictExcerpt: `status=${result.status} (strict mode); ${warnChecks.length} warning${warnChecks.length === 1 ? "" : "s"} treated as blocking`,
1015
+ };
959
1016
  preExecPauseNeeded = true;
960
1017
  }
961
1018
  }
@@ -1223,6 +1223,20 @@ export async function buildPlanSlicePrompt(mid, _midTitle, sid, sTitle, base, le
1223
1223
  prependBlocks.push(`## Prior Sketch Scope (soft hint — non-binding)\n\n${options.softScopeHint.trim()}\n\n` +
1224
1224
  `This scope was captured during an earlier progressive-planning pass that was later disabled. Treat it as context only — you may plan beyond it if the work genuinely requires more scope. Do NOT treat this as a hard boundary.`);
1225
1225
  }
1226
+ // #4551: inject pre-exec failure context so the re-dispatched plan-slice
1227
+ // addresses the exact blocked references rather than reproducing the same plan.
1228
+ if (options?.priorPreExecFailure) {
1229
+ const { blockingFindings, verdictExcerpt } = options.priorPreExecFailure;
1230
+ const findingsList = blockingFindings.length > 0
1231
+ ? blockingFindings.map(f => `- ${f}`).join("\n")
1232
+ : "- (no specific findings recorded)";
1233
+ prependBlocks.push(`## Fix these specific issues from the prior pre-exec check\n\n` +
1234
+ `The previous plan-slice attempt was blocked by pre-execution validation.\n` +
1235
+ `Gate verdict: ${verdictExcerpt}\n\n` +
1236
+ `Blocked references that must be resolved in this plan:\n${findingsList}\n\n` +
1237
+ `Revise the plan so that every reference listed above is satisfied before execution begins. ` +
1238
+ `Do not reproduce the same file paths, package names, or task ordering that caused these failures.`);
1239
+ }
1226
1240
  return renderSlicePrompt({
1227
1241
  mid, sid, sTitle, base,
1228
1242
  level: level ?? resolveInlineLevel(),
@@ -11,10 +11,12 @@ import { appendEvent } from "./workflow-events.js";
11
11
  import { atomicWriteSync } from "./atomic-write.js";
12
12
  import { clearParseCache } from "./files.js";
13
13
  import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
14
- import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus } from "./gsd-db.js";
14
+ import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone } from "./gsd-db.js";
15
15
  import { isValidationTerminal } from "./state.js";
16
16
  import { getErrorMessage } from "./error-utils.js";
17
17
  import { logWarning, logError } from "./workflow-logger.js";
18
+ import { splitFrontmatter, parseFrontmatterMap } from "./files.js";
19
+ import { isClosedStatus } from "./status-guards.js";
18
20
  import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
19
21
  import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
20
22
  import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
@@ -23,6 +25,30 @@ import { dirname, join } from "node:path";
23
25
  import { resolveExpectedArtifactPath, diagnoseExpectedArtifact, } from "./auto-artifact-paths.js";
24
26
  // Re-export so existing consumers of auto-recovery.ts keep working.
25
27
  export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
28
+ /**
29
+ * Classify milestone summary content for recovery/dispatch decisions.
30
+ * - success: canonical completion summary (frontmatter status is closed)
31
+ * - failure: explicit blocker/failure markers
32
+ * - unknown: ambiguous content
33
+ */
34
+ export function classifyMilestoneSummaryContent(content) {
35
+ const [fmLines] = splitFrontmatter(content);
36
+ const fm = fmLines ? parseFrontmatterMap(fmLines) : null;
37
+ const rawStatus = typeof fm?.status === "string" ? fm.status.trim().toLowerCase() : "";
38
+ if (rawStatus) {
39
+ if (isClosedStatus(rawStatus))
40
+ return "success";
41
+ if (["active", "pending", "blocked", "failed", "incomplete"].includes(rawStatus))
42
+ return "failure";
43
+ }
44
+ const failureSignal = /(?:^|\n)\s*#\s*BLOCKER\b/i.test(content)
45
+ || /auto-mode recovery failed/i.test(content)
46
+ || /verification\s+failed/i.test(content)
47
+ || /\bnot complete\b/i.test(content);
48
+ if (failureSignal)
49
+ return "failure";
50
+ return "unknown";
51
+ }
26
52
  // ─── Artifact Resolution & Verification ───────────────────────────────────────
27
53
  /**
28
54
  * Check whether a milestone produced implementation artifacts (non-`.gsd/` files)
@@ -220,12 +246,25 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
220
246
  // RESEARCH file. Without this, resolveExpectedArtifactPath returns null and
221
247
  // the retry/escalation machinery silently re-dispatches forever.
222
248
  //
249
+ // #4068: Also treat a PARALLEL-BLOCKER placeholder as a terminal completion
250
+ // so that timeout-recovery can write the blocker, have verifyExpectedArtifact
251
+ // return true, and let the dispatch loop advance past this unit. Without
252
+ // this, the blocker is written but verification still returns false, the unit
253
+ // is never cleared from unitDispatchCount, and on the next iteration the
254
+ // dispatch rule (which correctly skips parallel-research when PARALLEL-BLOCKER
255
+ // exists) returns null — leaving the loop stuck re-deriving indefinitely.
256
+ //
223
257
  // NOTE: this predicate mirrors the dispatch rule at
224
258
  // auto-dispatch.ts parallel-research-slices — keep the two in sync.
225
259
  if (unitType === "research-slice" && unitId.endsWith("/parallel-research")) {
226
260
  const { milestone: mid } = parseUnitId(unitId);
227
261
  if (!mid)
228
262
  return false;
263
+ // #4068: PARALLEL-BLOCKER written by timeout-recovery is a terminal state.
264
+ const blockerPath = resolveExpectedArtifactPath(unitType, unitId, base);
265
+ if (blockerPath && existsSync(blockerPath)) {
266
+ return true;
267
+ }
229
268
  const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
230
269
  if (!roadmapFile || !existsSync(roadmapFile)) {
231
270
  logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
@@ -420,6 +459,17 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
420
459
  // A milestone with only .gsd/ plan files and zero implementation code is
421
460
  // not genuinely complete — the LLM wrote plan files but skipped actual work.
422
461
  if (unitType === "complete-milestone") {
462
+ const summaryOutcome = classifyMilestoneSummaryContent(readFileSync(absPath, "utf-8"));
463
+ if (summaryOutcome === "failure")
464
+ return false;
465
+ const { milestone: mid } = parseUnitId(unitId);
466
+ if (mid && isDbAvailable()) {
467
+ const dbMilestone = getMilestone(mid);
468
+ if (!dbMilestone)
469
+ return false;
470
+ if (!isClosedStatus(dbMilestone.status) && summaryOutcome !== "success")
471
+ return false;
472
+ }
423
473
  if (hasImplementationArtifacts(base) === "absent")
424
474
  return false;
425
475
  }
@@ -497,6 +547,24 @@ export function writeBlockerPlaceholder(unitType, unitId, base, reason) {
497
547
  logWarning("recovery", `appendEvent failed for slice recovery: ${e instanceof Error ? e.message : String(e)}`);
498
548
  }
499
549
  }
550
+ // Insert a placeholder complete slice so deriveState sees activeMilestoneSlices.length > 0
551
+ // and exits the pre-planning phase. Without this, activeMilestoneSlices stays empty
552
+ // after the blocker ROADMAP.md is written, causing deriveState to return phase:'pre-planning'
553
+ // indefinitely and re-dispatching plan-milestone in an infinite loop (#4378).
554
+ if (unitType === "plan-milestone" && mid) {
555
+ try {
556
+ insertSlice({ id: "S00-blocker", milestoneId: mid, title: "Blocker placeholder — planning failed", status: "complete", sequence: 0 });
557
+ }
558
+ catch (e) {
559
+ logWarning("recovery", `insertSlice placeholder failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`);
560
+ }
561
+ try {
562
+ appendEvent(base, { cmd: "plan-milestone", params: { milestoneId: mid }, ts, actor: "system", trigger_reason: "blocker-placeholder-recovery" });
563
+ }
564
+ catch (e) {
565
+ logWarning("recovery", `appendEvent failed for plan-milestone recovery: ${e instanceof Error ? e.message : String(e)}`);
566
+ }
567
+ }
500
568
  }
501
569
  return diagnoseExpectedArtifact(unitType, unitId, base);
502
570
  }