gsd-pi 2.57.0 → 2.58.0-dev.778d6ac

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 (707) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +49 -35
  3. package/dist/headless-ui.d.ts +17 -0
  4. package/dist/headless-ui.js +97 -3
  5. package/dist/headless.js +67 -6
  6. package/dist/help-text.js +1 -0
  7. package/dist/onboarding.js +44 -0
  8. package/dist/resource-loader.js +16 -1
  9. package/dist/resources/agents/researcher.md +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +16 -3
  11. package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
  12. package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
  13. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  14. package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
  16. package/dist/resources/extensions/context7/extension-manifest.json +1 -1
  17. package/dist/resources/extensions/get-secrets-from-user.js +8 -5
  18. package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
  19. package/dist/resources/extensions/google-search/index.js +2 -1
  20. package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
  21. package/dist/resources/extensions/gsd/auto/phases.js +25 -21
  22. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  24. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
  25. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  27. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  28. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  30. package/dist/resources/extensions/gsd/auto-worktree.js +203 -14
  31. package/dist/resources/extensions/gsd/auto.js +4 -0
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
  34. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  36. package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  38. package/dist/resources/extensions/gsd/captures.js +56 -4
  39. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  40. package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
  41. package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
  42. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  43. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  44. package/dist/resources/extensions/gsd/doctor.js +3 -1
  45. package/dist/resources/extensions/gsd/error-classifier.js +13 -10
  46. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  47. package/dist/resources/extensions/gsd/forensics.js +123 -20
  48. package/dist/resources/extensions/gsd/git-service.js +23 -1
  49. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  50. package/dist/resources/extensions/gsd/gsd-db.js +44 -10
  51. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  52. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  53. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  54. package/dist/resources/extensions/gsd/index.js +1 -1
  55. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  56. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  57. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  58. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  59. package/dist/resources/extensions/gsd/model-router.js +35 -1
  60. package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
  61. package/dist/resources/extensions/gsd/notifications.js +16 -1
  62. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  63. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  64. package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
  65. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  66. package/dist/resources/extensions/gsd/paths.js +43 -0
  67. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  68. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  69. package/dist/resources/extensions/gsd/preferences.js +42 -31
  70. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  71. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  73. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  76. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  80. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  82. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  83. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  84. package/dist/resources/extensions/gsd/rethink.js +5 -0
  85. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  86. package/dist/resources/extensions/gsd/state.js +85 -27
  87. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  89. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  90. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  91. package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
  92. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  93. package/dist/resources/extensions/gsd/undo.js +2 -2
  94. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  95. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  96. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  97. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  98. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  99. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  100. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  101. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  102. package/dist/resources/extensions/mcp-client/index.js +11 -7
  103. package/dist/resources/extensions/ollama/index.js +112 -0
  104. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  105. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  106. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  107. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  108. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  109. package/dist/resources/extensions/ollama/types.js +2 -0
  110. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  111. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  112. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  113. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  114. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  115. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  116. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  117. package/dist/startup-model-validation.d.ts +39 -0
  118. package/dist/startup-model-validation.js +50 -0
  119. package/dist/web/standalone/.next/BUILD_ID +1 -1
  120. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  121. package/dist/web/standalone/.next/build-manifest.json +4 -4
  122. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  123. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  124. package/dist/web/standalone/.next/required-server-files.json +3 -3
  125. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  128. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  136. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  145. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  164. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  198. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  214. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  216. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  218. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/index.html +1 -1
  228. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  229. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  230. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  231. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  232. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  233. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  234. package/dist/web/standalone/.next/server/app/page.js +2 -2
  235. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  237. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  238. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  239. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/middleware.js +2 -2
  242. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  244. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  245. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  246. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  247. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  248. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  249. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  250. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  252. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
  254. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  255. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  256. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  257. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  258. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  259. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  260. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  261. package/dist/web/standalone/server.js +1 -1
  262. package/dist/web-mode.js +2 -1
  263. package/package.json +2 -2
  264. package/packages/daemon/src/cli.ts +49 -0
  265. package/packages/daemon/src/daemon.test.ts +104 -1
  266. package/packages/daemon/src/daemon.ts +24 -1
  267. package/packages/daemon/src/discord-bot.ts +73 -3
  268. package/packages/daemon/src/event-bridge.ts +15 -9
  269. package/packages/daemon/src/event-formatter.ts +30 -2
  270. package/packages/daemon/src/index.ts +9 -0
  271. package/packages/daemon/src/launchd.test.ts +356 -0
  272. package/packages/daemon/src/launchd.ts +242 -0
  273. package/packages/daemon/src/message-batcher.test.ts +2 -2
  274. package/packages/daemon/src/message-batcher.ts +9 -3
  275. package/packages/daemon/src/orchestrator.test.ts +1 -0
  276. package/packages/daemon/src/orchestrator.ts +106 -2
  277. package/packages/native/dist/ast/index.js +9 -5
  278. package/packages/native/dist/ast/types.js +2 -1
  279. package/packages/native/dist/clipboard/index.js +12 -7
  280. package/packages/native/dist/clipboard/types.js +2 -1
  281. package/packages/native/dist/diff/index.js +12 -7
  282. package/packages/native/dist/diff/types.js +2 -1
  283. package/packages/native/dist/fd/index.js +6 -3
  284. package/packages/native/dist/fd/types.js +2 -1
  285. package/packages/native/dist/glob/index.js +9 -5
  286. package/packages/native/dist/glob/types.js +2 -1
  287. package/packages/native/dist/grep/index.js +9 -5
  288. package/packages/native/dist/grep/types.js +2 -1
  289. package/packages/native/dist/gsd-parser/index.js +18 -11
  290. package/packages/native/dist/gsd-parser/types.js +2 -1
  291. package/packages/native/dist/highlight/index.js +12 -7
  292. package/packages/native/dist/highlight/types.js +2 -1
  293. package/packages/native/dist/html/index.js +6 -3
  294. package/packages/native/dist/html/types.js +2 -1
  295. package/packages/native/dist/image/index.js +10 -5
  296. package/packages/native/dist/image/types.js +7 -4
  297. package/packages/native/dist/index.js +70 -17
  298. package/packages/native/dist/json-parse/index.js +13 -8
  299. package/packages/native/dist/native.js +47 -10
  300. package/packages/native/dist/ps/index.js +15 -9
  301. package/packages/native/dist/ps/types.js +2 -1
  302. package/packages/native/dist/stream-process/index.js +12 -7
  303. package/packages/native/dist/text/index.js +24 -14
  304. package/packages/native/dist/text/types.js +5 -2
  305. package/packages/native/dist/truncate/index.js +12 -7
  306. package/packages/native/dist/ttsr/index.js +12 -7
  307. package/packages/native/dist/ttsr/types.js +2 -1
  308. package/packages/native/dist/xxhash/index.js +9 -5
  309. package/packages/native/package.json +19 -19
  310. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  311. package/packages/native/src/native.ts +9 -8
  312. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  313. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  314. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  315. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  316. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  317. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  318. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  319. package/packages/pi-agent-core/src/proxy.ts +1 -1
  320. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  321. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  322. package/packages/pi-ai/dist/index.d.ts +1 -0
  323. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  324. package/packages/pi-ai/dist/index.js +1 -0
  325. package/packages/pi-ai/dist/index.js.map +1 -1
  326. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  327. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  328. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  329. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  330. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  331. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  332. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  333. package/packages/pi-ai/dist/types.d.ts +3 -3
  334. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/types.js.map +1 -1
  336. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  337. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  338. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  339. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  340. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  341. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  342. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  343. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  344. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  345. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  346. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  347. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  348. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  349. package/packages/pi-ai/src/index.ts +1 -0
  350. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  351. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  352. package/packages/pi-ai/src/types.ts +3 -2
  353. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  354. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  355. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  356. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  357. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  359. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  361. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  363. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  365. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  366. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  367. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  368. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  370. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  372. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  373. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  374. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  375. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  376. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  378. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  379. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  380. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  382. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  384. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  385. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  386. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  387. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  388. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  390. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  392. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  393. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  394. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  396. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  397. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  398. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  400. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  402. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  403. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  404. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  405. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  406. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  407. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  409. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  411. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  412. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  413. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  415. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  417. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  418. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  419. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  420. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  422. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  424. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  426. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  428. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  429. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  430. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  431. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  432. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  433. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  434. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  435. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  436. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  437. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  439. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  440. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  441. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  442. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  443. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  444. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  445. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  446. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  447. package/packages/pi-coding-agent/dist/index.js +1 -1
  448. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  449. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  450. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
  451. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  452. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  453. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  454. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  455. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  456. package/packages/pi-coding-agent/package.json +1 -1
  457. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  458. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  459. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  460. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  461. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  462. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  463. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  464. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  465. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  466. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  467. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  468. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  469. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  470. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  471. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  472. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  473. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  474. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  475. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  476. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  477. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  478. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  479. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  480. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  481. package/packages/pi-coding-agent/src/index.ts +6 -0
  482. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
  483. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  484. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  485. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  486. package/packages/pi-tui/dist/terminal.js +9 -0
  487. package/packages/pi-tui/dist/terminal.js.map +1 -1
  488. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  489. package/packages/pi-tui/dist/tui.js +9 -0
  490. package/packages/pi-tui/dist/tui.js.map +1 -1
  491. package/packages/pi-tui/src/terminal.ts +14 -0
  492. package/packages/pi-tui/src/tui.ts +8 -0
  493. package/pkg/package.json +1 -1
  494. package/scripts/ensure-workspace-builds.cjs +45 -14
  495. package/src/resources/agents/researcher.md +1 -1
  496. package/src/resources/extensions/ask-user-questions.ts +21 -3
  497. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  498. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  499. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  500. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  501. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  502. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  503. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  504. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  505. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  506. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  507. package/src/resources/extensions/google-search/index.ts +2 -1
  508. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  509. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  510. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  511. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  512. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  513. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
  514. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  515. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  516. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  517. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  518. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  519. package/src/resources/extensions/gsd/auto-worktree.ts +197 -11
  520. package/src/resources/extensions/gsd/auto.ts +5 -0
  521. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  522. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
  523. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  524. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
  525. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
  526. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  527. package/src/resources/extensions/gsd/captures.ts +63 -3
  528. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  529. package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
  530. package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
  531. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  532. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  533. package/src/resources/extensions/gsd/doctor.ts +3 -1
  534. package/src/resources/extensions/gsd/error-classifier.ts +14 -11
  535. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  536. package/src/resources/extensions/gsd/forensics.ts +144 -20
  537. package/src/resources/extensions/gsd/git-service.ts +26 -3
  538. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  539. package/src/resources/extensions/gsd/gsd-db.ts +49 -8
  540. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  541. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  542. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  543. package/src/resources/extensions/gsd/index.ts +1 -0
  544. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  545. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  546. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  547. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  548. package/src/resources/extensions/gsd/model-router.ts +35 -1
  549. package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
  550. package/src/resources/extensions/gsd/notifications.ts +16 -0
  551. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  552. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  553. package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
  554. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  555. package/src/resources/extensions/gsd/paths.ts +42 -0
  556. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  557. package/src/resources/extensions/gsd/preferences-types.ts +2 -1
  558. package/src/resources/extensions/gsd/preferences.ts +45 -29
  559. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  560. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  561. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  562. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  563. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  564. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  565. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  566. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  567. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  568. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  569. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  570. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  571. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  572. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  573. package/src/resources/extensions/gsd/rethink.ts +6 -0
  574. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  575. package/src/resources/extensions/gsd/state.ts +84 -32
  576. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  577. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  578. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  579. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  580. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  581. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  582. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  583. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  584. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  585. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  586. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  587. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  588. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  589. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  590. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  591. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
  592. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  593. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  594. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  595. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  596. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  597. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  598. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  599. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  600. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  601. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  602. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  603. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  604. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  605. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  606. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  607. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
  608. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  609. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  610. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  611. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  612. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  613. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  614. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  615. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  616. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  617. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  618. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  619. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  620. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  621. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  622. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  623. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
  624. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  625. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  626. package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
  627. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  628. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
  629. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  630. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  631. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  632. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  633. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  634. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  635. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  636. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  637. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  638. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  639. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  640. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  641. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  642. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  643. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  644. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  645. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  646. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  647. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  648. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  649. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  650. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  651. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
  652. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
  653. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  654. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  655. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  656. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  657. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  658. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  659. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
  660. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  661. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  662. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  663. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  664. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  665. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  666. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  667. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
  668. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  669. package/src/resources/extensions/gsd/types.ts +4 -2
  670. package/src/resources/extensions/gsd/undo.ts +2 -2
  671. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  672. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  673. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  674. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  675. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  676. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  677. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  678. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  679. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  680. package/src/resources/extensions/mcp-client/index.ts +13 -7
  681. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  682. package/src/resources/extensions/ollama/index.ts +130 -0
  683. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  684. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  685. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  686. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  687. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  688. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  689. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  690. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  691. package/src/resources/extensions/ollama/types.ts +130 -0
  692. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  693. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  694. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  695. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  696. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  697. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  698. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  699. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  700. package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
  701. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  702. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  703. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  704. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  705. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  706. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
  707. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
@@ -8,7 +8,7 @@
8
8
  "provides": {
9
9
  "tools": ["bg_shell"],
10
10
  "commands": ["bg"],
11
- "hooks": ["session_shutdown"],
11
+ "hooks": ["session_shutdown", "session_compact", "session_tree", "session_switch", "before_agent_start", "session_start", "turn_end", "agent_end", "tool_execution_end"],
12
12
  "shortcuts": ["Ctrl+Alt+B"]
13
13
  }
14
14
  }
@@ -29,7 +29,7 @@
29
29
  "browser_visual_diff", "browser_zoom_region",
30
30
  "browser_generate_test", "browser_action_cache", "browser_check_injection"
31
31
  ],
32
- "hooks": ["session_shutdown"]
32
+ "hooks": ["session_start", "session_shutdown"]
33
33
  },
34
34
  "dependencies": {
35
35
  "runtime": ["playwright"]
@@ -16,6 +16,7 @@ import type {
16
16
  Usage,
17
17
  WebSearchResultContent,
18
18
  } from "@gsd/pi-ai";
19
+ import { repairToolJson } from "@gsd/pi-ai";
19
20
  import type { BetaContentBlock, BetaRawMessageStreamEvent, NonNullableUsage } from "./sdk-types.js";
20
21
 
21
22
  // ---------------------------------------------------------------------------
@@ -244,12 +245,18 @@ export class PartialMessageBuilder {
244
245
  try {
245
246
  block.arguments = JSON.parse(jsonStr);
246
247
  } catch {
247
- // Stream was truncated mid-tool-call JSON is garbage.
248
- // Preserve the raw string for diagnostics but signal the
249
- // malformation explicitly so downstream consumers can
250
- // distinguish this from a healthy tool completion (#2574).
251
- block.arguments = { _raw: jsonStr };
252
- return { type: "toolcall_end", contentIndex, toolCall: block, partial: this.partial, malformedArguments: true };
248
+ // JSON.parse failed attempt repair for YAML-style bullet
249
+ // lists that LLMs copy from template formatting (#2660).
250
+ try {
251
+ block.arguments = JSON.parse(repairToolJson(jsonStr));
252
+ } catch {
253
+ // Repair also failed stream was truncated or garbage.
254
+ // Preserve the raw string for diagnostics but signal the
255
+ // malformation explicitly so downstream consumers can
256
+ // distinguish this from a healthy tool completion (#2574).
257
+ block.arguments = { _raw: jsonStr };
258
+ return { type: "toolcall_end", contentIndex, toolCall: block, partial: this.partial, malformedArguments: true };
259
+ }
253
260
  }
254
261
  return { type: "toolcall_end", contentIndex, toolCall: block, partial: this.partial };
255
262
  }
@@ -23,9 +23,6 @@ import type {
23
23
  SDKMessage,
24
24
  SDKPartialAssistantMessage,
25
25
  SDKResultMessage,
26
- SDKSystemMessage,
27
- SDKStatusMessage,
28
- SDKUserMessage,
29
26
  } from "./sdk-types.js";
30
27
 
31
28
  // ---------------------------------------------------------------------------
@@ -71,30 +68,49 @@ function getClaudePath(): string {
71
68
  }
72
69
 
73
70
  // ---------------------------------------------------------------------------
74
- // Prompt extraction
71
+ // Prompt construction
75
72
  // ---------------------------------------------------------------------------
76
73
 
77
74
  /**
78
- * Extract the last user prompt text from GSD's context messages.
79
- * The SDK manages its own conversation history — we only send
80
- * the latest user message as the prompt.
75
+ * Extract text content from a single message regardless of content shape.
81
76
  */
82
- function extractLastUserPrompt(context: Context): string {
83
- for (let i = context.messages.length - 1; i >= 0; i--) {
84
- const msg = context.messages[i];
85
- if (msg.role === "user") {
86
- if (typeof msg.content === "string") return msg.content;
87
- if (Array.isArray(msg.content)) {
88
- const textParts = msg.content
89
- .filter((part: any) => part.type === "text")
90
- .map((part: any) => part.text);
91
- if (textParts.length > 0) return textParts.join("\n");
92
- }
93
- }
77
+ function extractMessageText(msg: { role: string; content: unknown }): string {
78
+ if (typeof msg.content === "string") return msg.content;
79
+ if (Array.isArray(msg.content)) {
80
+ const textParts = msg.content
81
+ .filter((part: any) => part.type === "text")
82
+ .map((part: any) => part.text ?? part.thinking ?? "");
83
+ if (textParts.length > 0) return textParts.join("\n");
94
84
  }
95
85
  return "";
96
86
  }
97
87
 
88
+ /**
89
+ * Build a full conversational prompt from GSD's context messages.
90
+ *
91
+ * Previous behaviour sent only the last user message, making every SDK
92
+ * call effectively stateless. This version serialises the complete
93
+ * conversation history (system prompt + all user/assistant turns) so
94
+ * Claude Code has full context for multi-turn continuity.
95
+ */
96
+ export function buildPromptFromContext(context: Context): string {
97
+ const parts: string[] = [];
98
+
99
+ if (context.systemPrompt) {
100
+ parts.push(`[System]\n${context.systemPrompt}`);
101
+ }
102
+
103
+ for (const msg of context.messages) {
104
+ const text = extractMessageText(msg);
105
+ if (!text) continue;
106
+
107
+ const label = msg.role === "user" ? "User" : msg.role === "assistant" ? "Assistant" : "System";
108
+ parts.push(`[${label}]\n${text}`);
109
+ }
110
+
111
+ return parts.join("\n\n");
112
+ }
113
+
98
114
  // ---------------------------------------------------------------------------
99
115
  // Error helper
100
116
  // ---------------------------------------------------------------------------
@@ -127,6 +143,31 @@ export function makeStreamExhaustedErrorMessage(model: string, lastTextContent:
127
143
  return message;
128
144
  }
129
145
 
146
+ // ---------------------------------------------------------------------------
147
+ // SDK options builder
148
+ // ---------------------------------------------------------------------------
149
+
150
+ /**
151
+ * Build the options object passed to the Claude Agent SDK's `query()` call.
152
+ *
153
+ * Extracted for testability — callers can verify session persistence,
154
+ * beta flags, and other configuration without mocking the full SDK.
155
+ */
156
+ export function buildSdkOptions(modelId: string, prompt: string): Record<string, unknown> {
157
+ return {
158
+ pathToClaudeCodeExecutable: getClaudePath(),
159
+ model: modelId,
160
+ includePartialMessages: true,
161
+ persistSession: true,
162
+ cwd: process.cwd(),
163
+ permissionMode: "bypassPermissions",
164
+ allowDangerouslySkipPermissions: true,
165
+ settingSources: ["project"],
166
+ systemPrompt: { type: "preset", preset: "claude_code" },
167
+ betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
168
+ };
169
+ }
170
+
130
171
  // ---------------------------------------------------------------------------
131
172
  // streamSimple implementation
132
173
  // ---------------------------------------------------------------------------
@@ -180,22 +221,14 @@ async function pumpSdkMessages(
180
221
  options.signal.addEventListener("abort", () => controller.abort(), { once: true });
181
222
  }
182
223
 
183
- const prompt = extractLastUserPrompt(context);
224
+ const prompt = buildPromptFromContext(context);
225
+ const sdkOpts = buildSdkOptions(modelId, prompt);
184
226
 
185
227
  const queryResult = sdk.query({
186
228
  prompt,
187
229
  options: {
188
- pathToClaudeCodeExecutable: getClaudePath(),
189
- model: modelId,
190
- includePartialMessages: true,
191
- persistSession: false,
230
+ ...sdkOpts,
192
231
  abortController: controller,
193
- cwd: process.cwd(),
194
- permissionMode: "bypassPermissions",
195
- allowDangerouslySkipPermissions: true,
196
- settingSources: ["project"],
197
- systemPrompt: { type: "preset", preset: "claude_code" },
198
- betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
199
232
  },
200
233
  });
201
234
 
@@ -225,7 +258,6 @@ async function pumpSdkMessages(
225
258
  // -- Streaming partial messages --
226
259
  case "stream_event": {
227
260
  const partial = msg as SDKPartialAssistantMessage;
228
- if (partial.parent_tool_use_id !== null) break; // skip subagent
229
261
 
230
262
  const event = partial.event;
231
263
 
@@ -256,7 +288,6 @@ async function pumpSdkMessages(
256
288
  // -- Complete assistant message (non-streaming fallback) --
257
289
  case "assistant": {
258
290
  const sdkAssistant = msg as SDKAssistantMessage;
259
- if (sdkAssistant.parent_tool_use_id !== null) break;
260
291
 
261
292
  // Capture text content from complete messages
262
293
  for (const block of sdkAssistant.message.content) {
@@ -271,9 +302,6 @@ async function pumpSdkMessages(
271
302
 
272
303
  // -- User message (synthetic tool result — signals turn boundary) --
273
304
  case "user": {
274
- const userMsg = msg as SDKUserMessage;
275
- if (userMsg.parent_tool_use_id !== null) break;
276
-
277
305
  // Capture content from the completed turn before resetting
278
306
  if (builder) {
279
307
  for (const block of builder.message.content) {
@@ -102,4 +102,32 @@ describe("PartialMessageBuilder — malformed tool arguments (#2574)", () => {
102
102
  "non-JSON content should set malformedArguments: true",
103
103
  );
104
104
  });
105
+
106
+ test("YAML bullet lists repaired to JSON arrays (#2660)", () => {
107
+ const builder = new PartialMessageBuilder("claude-sonnet-4-20250514");
108
+ const malformedJson =
109
+ '{"milestoneId": "M005", "keyDecisions": - Used Web Notification API, "keyFiles": - src/lib.rs, "title": "done"}';
110
+ const event = feedToolCall(builder, [malformedJson]);
111
+
112
+ assert.ok(event, "event should not be null");
113
+ assert.equal(event!.type, "toolcall_end");
114
+ // Repaired YAML bullets should NOT set malformedArguments
115
+ assert.equal(
116
+ (event as any).malformedArguments,
117
+ undefined,
118
+ "repaired YAML bullets should not set malformedArguments",
119
+ );
120
+ if (event!.type === "toolcall_end") {
121
+ assert.equal(event!.toolCall.arguments.milestoneId, "M005");
122
+ assert.ok(
123
+ Array.isArray(event!.toolCall.arguments.keyDecisions),
124
+ "keyDecisions should be repaired to an array",
125
+ );
126
+ assert.ok(
127
+ Array.isArray(event!.toolCall.arguments.keyFiles),
128
+ "keyFiles should be repaired to an array",
129
+ );
130
+ assert.equal(event!.toolCall.arguments.title, "done");
131
+ }
132
+ });
105
133
  });
@@ -1,6 +1,15 @@
1
1
  import { describe, test } from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { makeStreamExhaustedErrorMessage } from "../stream-adapter.ts";
3
+ import {
4
+ makeStreamExhaustedErrorMessage,
5
+ buildPromptFromContext,
6
+ buildSdkOptions,
7
+ } from "../stream-adapter.ts";
8
+ import type { Context, Message } from "@gsd/pi-ai";
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Existing tests — exhausted stream fallback (#2575)
12
+ // ---------------------------------------------------------------------------
4
13
 
5
14
  describe("stream-adapter — exhausted stream fallback (#2575)", () => {
6
15
  test("generator exhaustion becomes an error message instead of clean completion", () => {
@@ -19,3 +28,101 @@ describe("stream-adapter — exhausted stream fallback (#2575)", () => {
19
28
  assert.match(String((message.content[0] as any)?.text ?? ""), /Claude Code error: stream_exhausted_without_result/);
20
29
  });
21
30
  });
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Bug #2859 — stateless provider regression tests
34
+ // ---------------------------------------------------------------------------
35
+
36
+ describe("stream-adapter — full context prompt (#2859)", () => {
37
+ test("buildPromptFromContext includes all user and assistant messages, not just the last user message", () => {
38
+ const context: Context = {
39
+ systemPrompt: "You are a helpful assistant.",
40
+ messages: [
41
+ { role: "user", content: "What is 2+2?" } as Message,
42
+ {
43
+ role: "assistant",
44
+ content: [{ type: "text", text: "4" }],
45
+ api: "anthropic-messages",
46
+ provider: "claude-code",
47
+ model: "claude-sonnet-4-20250514",
48
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
49
+ stopReason: "stop",
50
+ timestamp: Date.now(),
51
+ } as Message,
52
+ { role: "user", content: "Now multiply that by 3" } as Message,
53
+ ],
54
+ };
55
+
56
+ const prompt = buildPromptFromContext(context);
57
+
58
+ // Must contain content from BOTH user messages, not just the last
59
+ assert.ok(prompt.includes("2+2"), "prompt must include first user message");
60
+ assert.ok(prompt.includes("multiply"), "prompt must include second user message");
61
+ // Must contain assistant response for continuity
62
+ assert.ok(prompt.includes("4"), "prompt must include assistant reply for context");
63
+ });
64
+
65
+ test("buildPromptFromContext includes system prompt when present", () => {
66
+ const context: Context = {
67
+ systemPrompt: "You are a coding assistant.",
68
+ messages: [
69
+ { role: "user", content: "Write a function" } as Message,
70
+ ],
71
+ };
72
+
73
+ const prompt = buildPromptFromContext(context);
74
+ assert.ok(prompt.includes("coding assistant"), "prompt must include system prompt");
75
+ });
76
+
77
+ test("buildPromptFromContext handles array content parts in user messages", () => {
78
+ const context: Context = {
79
+ messages: [
80
+ {
81
+ role: "user",
82
+ content: [
83
+ { type: "text", text: "First part" },
84
+ { type: "text", text: "Second part" },
85
+ ],
86
+ } as Message,
87
+ { role: "user", content: "Follow-up" } as Message,
88
+ ],
89
+ };
90
+
91
+ const prompt = buildPromptFromContext(context);
92
+ assert.ok(prompt.includes("First part"), "prompt must include array content parts");
93
+ assert.ok(prompt.includes("Second part"), "prompt must include all text parts");
94
+ assert.ok(prompt.includes("Follow-up"), "prompt must include follow-up message");
95
+ });
96
+
97
+ test("buildPromptFromContext returns empty string for empty messages", () => {
98
+ const context: Context = { messages: [] };
99
+ const prompt = buildPromptFromContext(context);
100
+ assert.equal(prompt, "");
101
+ });
102
+ });
103
+
104
+ describe("stream-adapter — session persistence (#2859)", () => {
105
+ test("buildSdkOptions enables persistSession by default", () => {
106
+ const options = buildSdkOptions("claude-sonnet-4-20250514", "test prompt");
107
+ assert.equal(options.persistSession, true, "persistSession must default to true");
108
+ });
109
+
110
+ test("buildSdkOptions sets model and prompt correctly", () => {
111
+ const options = buildSdkOptions("claude-sonnet-4-20250514", "hello world");
112
+ assert.equal(options.model, "claude-sonnet-4-20250514");
113
+ });
114
+
115
+ test("buildSdkOptions enables betas for sonnet models", () => {
116
+ const sonnetOpts = buildSdkOptions("claude-sonnet-4-20250514", "test");
117
+ assert.ok(
118
+ Array.isArray(sonnetOpts.betas) && sonnetOpts.betas.length > 0,
119
+ "sonnet models should have betas enabled",
120
+ );
121
+
122
+ const opusOpts = buildSdkOptions("claude-opus-4-20250514", "test");
123
+ assert.ok(
124
+ Array.isArray(opusOpts.betas) && opusOpts.betas.length === 0,
125
+ "non-sonnet models should have empty betas",
126
+ );
127
+ });
128
+ });
@@ -7,6 +7,6 @@
7
7
  "requires": { "platform": ">=2.29.0" },
8
8
  "provides": {
9
9
  "tools": ["resolve_library", "get_library_docs"],
10
- "hooks": ["session_start"]
10
+ "hooks": ["session_start", "session_shutdown"]
11
11
  }
12
12
  }
@@ -54,6 +54,9 @@ function hydrateProcessEnv(key: string, value: string): void {
54
54
  }
55
55
 
56
56
  async function writeEnvKey(filePath: string, key: string, value: string): Promise<void> {
57
+ if (typeof value !== "string") {
58
+ throw new TypeError(`writeEnvKey expects a string value for key "${key}", got ${typeof value}`);
59
+ }
57
60
  let content = "";
58
61
  try {
59
62
  content = await readFile(filePath, "utf8");
@@ -419,7 +422,7 @@ export async function collectSecretsFromManifest(
419
422
  for (const { key, value } of collected) {
420
423
  const entry = manifest.entries.find((e) => e.key === key);
421
424
  if (entry) {
422
- entry.status = value !== null ? "collected" : "skipped";
425
+ entry.status = value != null ? "collected" : "skipped";
423
426
  }
424
427
  }
425
428
 
@@ -427,14 +430,14 @@ export async function collectSecretsFromManifest(
427
430
  await writeFile(manifestPath, formatSecretsManifest(manifest), "utf8");
428
431
 
429
432
  // (j) Apply collected values to destination
430
- const provided = collected.filter((c) => c.value !== null) as Array<{ key: string; value: string }>;
433
+ const provided = collected.filter((c) => c.value != null) as Array<{ key: string; value: string }>;
431
434
  const { applied } = await applySecrets(provided, destination, {
432
435
  envFilePath: resolve(ctx.cwd, ".env"),
433
436
  });
434
437
 
435
438
  const skipped = [
436
439
  ...alreadySkipped,
437
- ...collected.filter((c) => c.value === null).map((c) => c.key),
440
+ ...collected.filter((c) => c.value == null).map((c) => c.key),
438
441
  ];
439
442
 
440
443
  return { applied, skipped, existingSkipped };
@@ -505,8 +508,8 @@ export default function secureEnv(pi: ExtensionAPI) {
505
508
  collected.push({ key: item.key, value });
506
509
  }
507
510
 
508
- const provided = collected.filter((c) => c.value !== null) as Array<{ key: string; value: string }>;
509
- const skipped = collected.filter((c) => c.value === null).map((c) => c.key);
511
+ const provided = collected.filter((c) => c.value != null) as Array<{ key: string; value: string }>;
512
+ const skipped = collected.filter((c) => c.value == null).map((c) => c.key);
510
513
 
511
514
  // Apply to destination via shared helper
512
515
  const { applied, errors } = await applySecrets(provided, destination, {
@@ -7,6 +7,6 @@
7
7
  "requires": { "platform": ">=2.29.0" },
8
8
  "provides": {
9
9
  "tools": ["google_search"],
10
- "hooks": ["session_start"]
10
+ "hooks": ["session_start", "session_shutdown"]
11
11
  }
12
12
  }
@@ -79,7 +79,7 @@ async function searchWithOAuth(
79
79
  signal?: AbortSignal,
80
80
  ): Promise<SearchResult> {
81
81
  const model = process.env.GEMINI_SEARCH_MODEL || "gemini-2.5-flash";
82
- const url = `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent`;
82
+ const url = `https://cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse`;
83
83
 
84
84
  const GEMINI_CLI_HEADERS = {
85
85
  ideType: "IDE_UNSPECIFIED",
@@ -104,6 +104,7 @@ async function searchWithOAuth(
104
104
  contents: [{ parts: [{ text: query }] }],
105
105
  tools: [{ googleSearch: {} }],
106
106
  },
107
+ userAgent: "pi-coding-agent",
107
108
  }),
108
109
  signal,
109
110
  });
@@ -41,5 +41,8 @@ export function isInfrastructureError(err: unknown): string | null {
41
41
  for (const code of INFRA_ERROR_CODES) {
42
42
  if (msg.includes(code)) return code;
43
43
  }
44
+ // SQLite WAL corruption is not transient — retrying burns LLM budget
45
+ // for guaranteed failures (#2823).
46
+ if (msg.includes("database disk image is malformed")) return "SQLITE_CORRUPT";
44
47
  return null;
45
48
  }
@@ -93,6 +93,7 @@ export interface LoopDeps {
93
93
  body: string,
94
94
  kind: string,
95
95
  category: string,
96
+ projectName?: string,
96
97
  ) => void;
97
98
  setActiveMilestoneId: (basePath: string, mid: string) => void;
98
99
  pruneQueueOrder: (basePath: string, pendingIds: string[]) => void;
@@ -26,7 +26,7 @@ import { runUnit } from "./run-unit.js";
26
26
  import { debugLog } from "../debug-logger.js";
27
27
  import { PROJECT_FILES } from "../detection.js";
28
28
  import { MergeConflictError } from "../git-service.js";
29
- import { join } from "node:path";
29
+ import { join, basename } from "node:path";
30
30
  import { existsSync, cpSync } from "node:fs";
31
31
  import { logWarning, logError } from "../workflow-logger.js";
32
32
  import { gsdRoot } from "../paths.js";
@@ -230,6 +230,7 @@ export async function runPreDispatch(
230
230
  `Milestone ${s.currentMilestoneId} complete!`,
231
231
  "success",
232
232
  "milestone",
233
+ basename(s.originalBasePath || s.basePath),
233
234
  );
234
235
  deps.logCmuxEvent(
235
236
  prefs,
@@ -388,6 +389,7 @@ export async function runPreDispatch(
388
389
  "All milestones complete!",
389
390
  "success",
390
391
  "milestone",
392
+ basename(s.originalBasePath || s.basePath),
391
393
  );
392
394
  deps.logCmuxEvent(
393
395
  prefs,
@@ -411,7 +413,7 @@ export async function runPreDispatch(
411
413
  const blockerMsg = `Blocked: ${state.blockers.join(", ")}`;
412
414
  await deps.stopAuto(ctx, pi, blockerMsg);
413
415
  ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto.`, "warning");
414
- deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention");
416
+ deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention", basename(s.originalBasePath || s.basePath));
415
417
  deps.logCmuxEvent(prefs, blockerMsg, "error");
416
418
  } else {
417
419
  const ids = incomplete.map((m: { id: string }) => m.id).join(", ");
@@ -492,6 +494,7 @@ export async function runPreDispatch(
492
494
  `Milestone ${mid} complete!`,
493
495
  "success",
494
496
  "milestone",
497
+ basename(s.originalBasePath || s.basePath),
495
498
  );
496
499
  deps.logCmuxEvent(
497
500
  prefs,
@@ -509,7 +512,7 @@ export async function runPreDispatch(
509
512
  const blockerMsg = `Blocked: ${state.blockers.join(", ")}`;
510
513
  await closeoutAndStop(ctx, pi, s, deps, blockerMsg);
511
514
  ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto.`, "warning");
512
- deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention");
515
+ deps.sendDesktopNotification("GSD", blockerMsg, "error", "attention", basename(s.originalBasePath || s.basePath));
513
516
  deps.logCmuxEvent(prefs, blockerMsg, "error");
514
517
  debugLog("autoLoop", { phase: "exit", reason: "blocked" });
515
518
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "blocked", blockers: state.blockers } });
@@ -755,7 +758,7 @@ export async function runGuards(
755
758
  // 100% — special enforcement logic (halt/pause/warn)
756
759
  const msg = `Budget ceiling ${deps.formatCost(budgetCeiling)} reached (spent ${deps.formatCost(totalCost)}).`;
757
760
  if (budgetEnforcementAction === "halt") {
758
- deps.sendDesktopNotification("GSD", msg, "error", "budget");
761
+ deps.sendDesktopNotification("GSD", msg, "error", "budget", basename(s.originalBasePath || s.basePath));
759
762
  await deps.stopAuto(ctx, pi, "Budget ceiling reached");
760
763
  debugLog("autoLoop", { phase: "exit", reason: "budget-halt" });
761
764
  return { action: "break", reason: "budget-halt" };
@@ -765,14 +768,14 @@ export async function runGuards(
765
768
  `${msg} Pausing auto-mode — /gsd auto to override and continue.`,
766
769
  "warning",
767
770
  );
768
- deps.sendDesktopNotification("GSD", msg, "warning", "budget");
771
+ deps.sendDesktopNotification("GSD", msg, "warning", "budget", basename(s.originalBasePath || s.basePath));
769
772
  deps.logCmuxEvent(prefs, msg, "warning");
770
773
  await deps.pauseAuto(ctx, pi);
771
774
  debugLog("autoLoop", { phase: "exit", reason: "budget-pause" });
772
775
  return { action: "break", reason: "budget-pause" };
773
776
  }
774
777
  ctx.ui.notify(`${msg} Continuing (enforcement: warn).`, "warning");
775
- deps.sendDesktopNotification("GSD", msg, "warning", "budget");
778
+ deps.sendDesktopNotification("GSD", msg, "warning", "budget", basename(s.originalBasePath || s.basePath));
776
779
  deps.logCmuxEvent(prefs, msg, "warning");
777
780
  } else if (threshold.pct < 100) {
778
781
  // Sub-100% — simple notification
@@ -783,6 +786,7 @@ export async function runGuards(
783
786
  msg,
784
787
  threshold.notifyLevel,
785
788
  "budget",
789
+ basename(s.originalBasePath || s.basePath),
786
790
  );
787
791
  deps.logCmuxEvent(prefs, msg, threshold.cmuxLevel);
788
792
  }
@@ -812,6 +816,7 @@ export async function runGuards(
812
816
  `Context ${contextUsage.percent}% — paused`,
813
817
  "warning",
814
818
  "attention",
819
+ basename(s.originalBasePath || s.basePath),
815
820
  );
816
821
  await deps.pauseAuto(ctx, pi);
817
822
  debugLog("autoLoop", { phase: "exit", reason: "context-window" });
@@ -929,6 +934,23 @@ export async function runUnitPhase(
929
934
  },
930
935
  );
931
936
 
937
+ // Select and apply model (with tier escalation on retry — normal units only)
938
+ const modelResult = await deps.selectAndApplyModel(
939
+ ctx,
940
+ pi,
941
+ unitType,
942
+ unitId,
943
+ s.basePath,
944
+ prefs,
945
+ s.verbose,
946
+ s.autoModeStartModel,
947
+ sidecarItem ? undefined : { isRetry, previousTier },
948
+ );
949
+ s.currentUnitRouting =
950
+ modelResult.routing as AutoSession["currentUnitRouting"];
951
+ s.currentUnitModel =
952
+ modelResult.appliedModel as AutoSession["currentUnitModel"];
953
+
932
954
  // Status bar + progress widget
933
955
  ctx.ui.setStatus("gsd-auto", "auto");
934
956
  if (mid)
@@ -1001,23 +1023,6 @@ export async function runUnitPhase(
1001
1023
  logWarning("engine", "Prompt reorder failed", { error: msg });
1002
1024
  }
1003
1025
 
1004
- // Select and apply model (with tier escalation on retry — normal units only)
1005
- const modelResult = await deps.selectAndApplyModel(
1006
- ctx,
1007
- pi,
1008
- unitType,
1009
- unitId,
1010
- s.basePath,
1011
- prefs,
1012
- s.verbose,
1013
- s.autoModeStartModel,
1014
- sidecarItem ? undefined : { isRetry, previousTier },
1015
- );
1016
- s.currentUnitRouting =
1017
- modelResult.routing as AutoSession["currentUnitRouting"];
1018
- s.currentUnitModel =
1019
- modelResult.appliedModel as AutoSession["currentUnitModel"];
1020
-
1021
1026
  // Apply sidecar/pre-dispatch hook model override (takes priority over standard model selection)
1022
1027
  const hookModelOverride = sidecarItem?.model ?? iterData.hookModelOverride;
1023
1028
  if (hookModelOverride) {
@@ -1142,14 +1147,18 @@ export async function runUnitPhase(
1142
1147
  // ── Immediate unit closeout (metrics, activity log, memory) ────────
1143
1148
  // Run right after runUnit() returns so telemetry is never lost to a
1144
1149
  // crash between iterations.
1145
- await deps.closeoutUnit(
1146
- ctx,
1147
- s.basePath,
1148
- unitType,
1149
- unitId,
1150
- s.currentUnit.startedAt,
1151
- deps.buildSnapshotOpts(unitType, unitId),
1152
- );
1150
+ // Guard: stopAuto() may have nulled s.currentUnit via s.reset() while
1151
+ // this coroutine was suspended at `await runUnit(...)` (#2939).
1152
+ if (s.currentUnit) {
1153
+ await deps.closeoutUnit(
1154
+ ctx,
1155
+ s.basePath,
1156
+ unitType,
1157
+ unitId,
1158
+ s.currentUnit.startedAt,
1159
+ deps.buildSnapshotOpts(unitType, unitId),
1160
+ );
1161
+ }
1153
1162
 
1154
1163
  // ── Zero tool-call guard (#1833) ──────────────────────────────────
1155
1164
  // An execute-task agent that completes with 0 tool calls made no
@@ -1159,7 +1168,7 @@ export async function runUnitPhase(
1159
1168
  const currentLedger = deps.getLedger() as { units: Array<{ type: string; id: string; startedAt: number; toolCalls: number }> } | null;
1160
1169
  if (currentLedger?.units) {
1161
1170
  const lastUnit = [...currentLedger.units].reverse().find(
1162
- (u: { type: string; id: string; startedAt: number; toolCalls: number }) => u.type === unitType && u.id === unitId && u.startedAt === s.currentUnit!.startedAt,
1171
+ (u: { type: string; id: string; startedAt: number; toolCalls: number }) => u.type === unitType && u.id === unitId && u.startedAt === s.currentUnit?.startedAt,
1163
1172
  );
1164
1173
  if (lastUnit && lastUnit.toolCalls === 0) {
1165
1174
  debugLog("runUnitPhase", {
@@ -1174,7 +1183,7 @@ export async function runUnitPhase(
1174
1183
  );
1175
1184
  // Fall through to next iteration where dispatch will re-derive
1176
1185
  // and re-dispatch this task.
1177
- return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
1186
+ return { action: "next", data: { unitStartedAt: s.currentUnit?.startedAt } };
1178
1187
  }
1179
1188
  }
1180
1189
  }
@@ -1198,7 +1207,7 @@ export async function runUnitPhase(
1198
1207
 
1199
1208
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "unit-end", data: { unitType, unitId, status: unitResult.status, artifactVerified, ...(unitResult.errorContext ? { errorContext: unitResult.errorContext } : {}) }, causedBy: { flowId: ic.flowId, seq: unitStartSeq } });
1200
1209
 
1201
- return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
1210
+ return { action: "next", data: { unitStartedAt: s.currentUnit?.startedAt } };
1202
1211
  }
1203
1212
 
1204
1213
  // ─── runFinalize ──────────────────────────────────────────────────────────────