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
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, unlinkSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
 
@@ -6,6 +6,7 @@ import type { ExtensionContext } from "@gsd/pi-coding-agent";
6
6
 
7
7
  import { debugTime } from "../debug-logger.js";
8
8
  import { loadPrompt } from "../prompt-loader.js";
9
+ import { readForensicsMarker } from "../forensics.js";
9
10
  import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
10
11
  import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
11
12
  import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
@@ -97,27 +98,30 @@ export async function buildBeforeAgentStartResult(
97
98
  warnDeprecatedAgentInstructions();
98
99
 
99
100
  const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
101
+
102
+ // Re-inject forensics context on follow-up turns (#2941)
103
+ const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd()) : null;
104
+
100
105
  const worktreeBlock = buildWorktreeContextBlock();
101
106
  const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
102
107
 
103
108
  stopContextTimer({
104
109
  systemPromptSize: fullSystem.length,
105
- injectionSize: injection?.length ?? 0,
110
+ injectionSize: injection?.length ?? forensicsInjection?.length ?? 0,
106
111
  hasPreferences: preferenceBlock.length > 0,
107
112
  hasNewSkills: newSkillsBlock.length > 0,
108
113
  });
109
114
 
115
+ // Determine which context message to inject (guided execute takes priority)
116
+ const contextMessage = injection
117
+ ? { customType: "gsd-guided-context", content: injection, display: false as const }
118
+ : forensicsInjection
119
+ ? { customType: "gsd-forensics", content: forensicsInjection, display: false as const }
120
+ : null;
121
+
110
122
  return {
111
123
  systemPrompt: fullSystem,
112
- ...(injection
113
- ? {
114
- message: {
115
- customType: "gsd-guided-context",
116
- content: injection,
117
- display: false as const,
118
- },
119
- }
120
- : {}),
124
+ ...(contextMessage ? { message: contextMessage } : {}),
121
125
  };
122
126
  }
123
127
 
@@ -375,3 +379,38 @@ function oneLine(text: string): string {
375
379
  return text.replace(/\s+/g, " ").trim();
376
380
  }
377
381
 
382
+ // ─── Forensics Context Re-injection (#2941) ──────────────────────────────────
383
+
384
+ /**
385
+ * Check for an active forensics session and return the prompt content
386
+ * so it can be re-injected on follow-up turns.
387
+ */
388
+ function buildForensicsContextInjection(basePath: string): string | null {
389
+ const marker = readForensicsMarker(basePath);
390
+ if (!marker) return null;
391
+
392
+ // Expire markers older than 2 hours to avoid stale context
393
+ const age = Date.now() - new Date(marker.createdAt).getTime();
394
+ if (age > 2 * 60 * 60 * 1000) {
395
+ clearForensicsMarker(basePath);
396
+ return null;
397
+ }
398
+
399
+ return marker.promptContent;
400
+ }
401
+
402
+ /**
403
+ * Remove the active forensics marker file, e.g. when the investigation
404
+ * is complete or the session expires.
405
+ */
406
+ export function clearForensicsMarker(basePath: string): void {
407
+ const markerPath = join(basePath, ".gsd", "runtime", "active-forensics.json");
408
+ if (existsSync(markerPath)) {
409
+ try {
410
+ unlinkSync(markerPath);
411
+ } catch {
412
+ // non-fatal
413
+ }
414
+ }
415
+ }
416
+
@@ -1,5 +1,31 @@
1
1
  const MILESTONE_CONTEXT_RE = /M\d+(?:-[a-z0-9]{6})?-CONTEXT\.md$/;
2
2
 
3
+ /**
4
+ * Path segment that identifies .gsd/ planning artifacts.
5
+ * Writes to these paths are allowed during queue mode.
6
+ */
7
+ const GSD_DIR_RE = /(^|[/\\])\.gsd([/\\]|$)/;
8
+
9
+ /**
10
+ * Read-only tool names that are always safe during queue mode.
11
+ */
12
+ const QUEUE_SAFE_TOOLS = new Set([
13
+ "read", "grep", "find", "ls", "glob",
14
+ // Discussion & planning tools
15
+ "ask_user_questions",
16
+ "gsd_milestone_generate_id",
17
+ "gsd_summary_save",
18
+ // Web research tools used during queue discussion
19
+ "search-the-web", "resolve_library", "get_library_docs", "fetch_page",
20
+ "search_and_read",
21
+ ]);
22
+
23
+ /**
24
+ * Bash commands that are read-only / investigative — safe during queue mode.
25
+ * Matches the leading command in a bash invocation.
26
+ */
27
+ const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s)/;
28
+
3
29
  let depthVerificationDone = false;
4
30
  let activeQueuePhase = false;
5
31
 
@@ -49,3 +75,52 @@ export function shouldBlockContextWrite(
49
75
  };
50
76
  }
51
77
 
78
+ /**
79
+ * Queue-mode execution guard (#2545).
80
+ *
81
+ * When the queue phase is active, the agent should only create planning
82
+ * artifacts (milestones, CONTEXT.md, QUEUE.md, etc.) — never execute work.
83
+ * This function blocks write/edit/bash tool calls that would modify source
84
+ * code outside of .gsd/.
85
+ *
86
+ * @param toolName The tool being called (write, edit, bash, etc.)
87
+ * @param input For write/edit: the file path. For bash: the command string.
88
+ * @param queuePhaseActive Whether the queue phase is currently active.
89
+ * @returns { block, reason } — block=true if the call should be rejected.
90
+ */
91
+ export function shouldBlockQueueExecution(
92
+ toolName: string,
93
+ input: string,
94
+ queuePhaseActive: boolean,
95
+ ): { block: boolean; reason?: string } {
96
+ if (!queuePhaseActive) return { block: false };
97
+
98
+ // Always-safe tools (read-only, discussion, planning)
99
+ if (QUEUE_SAFE_TOOLS.has(toolName)) return { block: false };
100
+
101
+ // write/edit — allow if targeting .gsd/ planning artifacts
102
+ if (toolName === "write" || toolName === "edit") {
103
+ if (GSD_DIR_RE.test(input)) return { block: false };
104
+ return {
105
+ block: true,
106
+ reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
107
+ `Cannot ${toolName} to "${input}" during queue mode. ` +
108
+ `Write CONTEXT.md files and update PROJECT.md/QUEUE.md instead.`,
109
+ };
110
+ }
111
+
112
+ // bash — allow read-only/investigative commands, block everything else
113
+ if (toolName === "bash") {
114
+ if (BASH_READ_ONLY_RE.test(input)) return { block: false };
115
+ return {
116
+ block: true,
117
+ reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
118
+ `Cannot run "${input.slice(0, 80)}${input.length > 80 ? "…" : ""}" during queue mode. ` +
119
+ `Use read-only commands (cat, grep, git log, etc.) to investigate, then write planning artifacts.`,
120
+ };
121
+ }
122
+
123
+ // Unknown tools — allow by default (custom extension tools, etc.)
124
+ return { block: false };
125
+ }
126
+
@@ -26,6 +26,7 @@ export interface CaptureEntry {
26
26
  resolution?: string;
27
27
  rationale?: string;
28
28
  resolvedAt?: string;
29
+ resolvedInMilestone?: string;
29
30
  executed?: boolean;
30
31
  }
31
32
 
@@ -176,6 +177,7 @@ export function markCaptureResolved(
176
177
  classification: Classification,
177
178
  resolution: string,
178
179
  rationale: string,
180
+ milestoneId?: string,
179
181
  ): void {
180
182
  const filePath = resolveCapturesPath(basePath);
181
183
  if (!existsSync(filePath)) return;
@@ -206,13 +208,17 @@ export function markCaptureResolved(
206
208
  `**Rationale:** ${rationale}`,
207
209
  `**Resolved:** ${resolvedAt}`,
208
210
  ];
211
+ if (milestoneId) {
212
+ newFields.push(`**Milestone:** ${milestoneId}`);
213
+ }
209
214
 
210
- // Remove any existing classification/resolution/rationale/resolved fields
215
+ // Remove any existing classification/resolution/rationale/resolved/milestone fields
211
216
  // (in case of re-triage)
212
217
  section = section.replace(/\*\*Classification:\*\*\s*.+\n?/g, "");
213
218
  section = section.replace(/\*\*Resolution:\*\*\s*.+\n?/g, "");
214
219
  section = section.replace(/\*\*Rationale:\*\*\s*.+\n?/g, "");
215
220
  section = section.replace(/\*\*Resolved:\*\*\s*.+\n?/g, "");
221
+ section = section.replace(/\*\*Milestone:\*\*\s*.+\n?/g, "");
216
222
 
217
223
  // Add new fields after Status line
218
224
  section = section.trimEnd() + "\n" + newFields.join("\n") + "\n";
@@ -255,16 +261,68 @@ export function markCaptureExecuted(basePath: string, captureId: string): void {
255
261
  * Load resolved captures that have actionable classifications (inject, replan,
256
262
  * quick-task) but have NOT yet been executed.
257
263
  * These are captures whose resolutions need to be carried out.
264
+ *
265
+ * When `currentMilestoneId` is provided, captures resolved in a *different*
266
+ * milestone are treated as stale and excluded. This prevents quick-task
267
+ * captures from a prior milestone re-executing after the underlying issues
268
+ * were already fixed by planned milestone work (#2872).
269
+ *
270
+ * Captures that have no `resolvedInMilestone` (legacy captures resolved before
271
+ * this field was introduced) are always included for backward compatibility.
258
272
  */
259
- export function loadActionableCaptures(basePath: string): CaptureEntry[] {
273
+ export function loadActionableCaptures(basePath: string, currentMilestoneId?: string): CaptureEntry[] {
260
274
  return loadAllCaptures(basePath).filter(
261
275
  c =>
262
276
  c.status === "resolved" &&
263
277
  !c.executed &&
264
278
  (c.classification === "inject" ||
265
279
  c.classification === "replan" ||
266
- c.classification === "quick-task"),
280
+ c.classification === "quick-task") &&
281
+ // Staleness gate: exclude captures resolved in a different milestone (#2872)
282
+ (!currentMilestoneId ||
283
+ !c.resolvedInMilestone ||
284
+ c.resolvedInMilestone === currentMilestoneId),
285
+ );
286
+ }
287
+
288
+ /**
289
+ * Retroactively stamp a capture with a milestone ID.
290
+ *
291
+ * Used by executeTriageResolutions() as a safety net when the triage LLM
292
+ * resolves a capture without writing the **Milestone:** field. This ensures
293
+ * the staleness gate in loadActionableCaptures() works correctly even for
294
+ * captures resolved before the prompt was updated (#2872).
295
+ */
296
+ export function stampCaptureMilestone(basePath: string, captureId: string, milestoneId: string): void {
297
+ const filePath = resolveCapturesPath(basePath);
298
+ if (!existsSync(filePath)) return;
299
+
300
+ const content = readFileSync(filePath, "utf-8");
301
+
302
+ const sectionRegex = new RegExp(
303
+ `(### ${escapeRegex(captureId)}\\n(?:(?!### ).)*?)(?=### |$)`,
304
+ "s",
267
305
  );
306
+ const match = sectionRegex.exec(content);
307
+ if (!match) return;
308
+
309
+ let section = match[1];
310
+
311
+ // Only stamp if not already present
312
+ if (/\*\*Milestone:\*\*/.test(section)) return;
313
+
314
+ // Insert after the Resolved field (or at end of section)
315
+ const resolvedFieldEnd = section.search(/\*\*Resolved:\*\*\s*.+\n?/);
316
+ if (resolvedFieldEnd !== -1) {
317
+ const resolvedMatch = section.match(/\*\*Resolved:\*\*\s*.+\n?/);
318
+ const insertPos = resolvedFieldEnd + (resolvedMatch?.[0]?.length ?? 0);
319
+ section = section.slice(0, insertPos) + `**Milestone:** ${milestoneId}\n` + section.slice(insertPos);
320
+ } else {
321
+ section = section.trimEnd() + "\n" + `**Milestone:** ${milestoneId}` + "\n";
322
+ }
323
+
324
+ const updated = content.replace(sectionRegex, section);
325
+ writeFileSync(filePath, updated, "utf-8");
268
326
  }
269
327
 
270
328
  // ─── Parser ───────────────────────────────────────────────────────────────────
@@ -291,6 +349,7 @@ function parseCapturesContent(content: string): CaptureEntry[] {
291
349
  const resolution = extractBoldField(body, "Resolution");
292
350
  const rationale = extractBoldField(body, "Rationale");
293
351
  const resolvedAt = extractBoldField(body, "Resolved");
352
+ const milestoneId = extractBoldField(body, "Milestone");
294
353
  const executedAt = extractBoldField(body, "Executed");
295
354
 
296
355
  if (!text || !timestamp) continue;
@@ -308,6 +367,7 @@ function parseCapturesContent(content: string): CaptureEntry[] {
308
367
  ...(resolution ? { resolution } : {}),
309
368
  ...(rationale ? { rationale } : {}),
310
369
  ...(resolvedAt ? { resolvedAt } : {}),
370
+ ...(milestoneId ? { resolvedInMilestone: milestoneId } : {}),
311
371
  ...(executedAt ? { executed: true } : {}),
312
372
  });
313
373
  }
@@ -227,6 +227,122 @@ export async function nextDecisionId(): Promise<string> {
227
227
  }
228
228
  }
229
229
 
230
+ // ─── Next Requirement ID ─────────────────────────────────────────────────
231
+
232
+ /**
233
+ * Compute the next requirement ID from the current DB state.
234
+ * Queries MAX(CAST(SUBSTR(id, 2) AS INTEGER)) from requirements table.
235
+ * Returns R001 if no requirements exist. Zero-pads to 3 digits.
236
+ */
237
+ export async function nextRequirementId(): Promise<string> {
238
+ try {
239
+ const db = await import('./gsd-db.js');
240
+ const adapter = db._getAdapter();
241
+ if (!adapter) return 'R001';
242
+
243
+ const row = adapter
244
+ .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM requirements')
245
+ .get();
246
+
247
+ const maxNum = row ? (row['max_num'] as number | null) : null;
248
+ if (maxNum == null || isNaN(maxNum)) return 'R001';
249
+
250
+ const next = maxNum + 1;
251
+ return `R${String(next).padStart(3, '0')}`;
252
+ } catch (err) {
253
+ logError('manifest', 'nextRequirementId failed', { fn: 'nextRequirementId', error: String((err as Error).message) });
254
+ return 'R001';
255
+ }
256
+ }
257
+
258
+ // ─── Save Requirement to DB + Regenerate Markdown ────────────────────────
259
+
260
+ export interface SaveRequirementFields {
261
+ class: string;
262
+ status?: string;
263
+ description: string;
264
+ why: string;
265
+ source: string;
266
+ primary_owner?: string;
267
+ supporting_slices?: string;
268
+ validation?: string;
269
+ notes?: string;
270
+ }
271
+
272
+ /**
273
+ * Save a new requirement to DB and regenerate REQUIREMENTS.md.
274
+ * Auto-assigns the next ID via nextRequirementId().
275
+ * Returns the assigned ID.
276
+ */
277
+ export async function saveRequirementToDb(
278
+ fields: SaveRequirementFields,
279
+ basePath: string,
280
+ ): Promise<{ id: string }> {
281
+ try {
282
+ const db = await import('./gsd-db.js');
283
+
284
+ const id = await nextRequirementId();
285
+
286
+ const requirement: Requirement = {
287
+ id,
288
+ class: fields.class,
289
+ status: fields.status ?? 'active',
290
+ description: fields.description,
291
+ why: fields.why,
292
+ source: fields.source,
293
+ primary_owner: fields.primary_owner ?? '',
294
+ supporting_slices: fields.supporting_slices ?? '',
295
+ validation: fields.validation ?? '',
296
+ notes: fields.notes ?? '',
297
+ full_content: '',
298
+ superseded_by: null,
299
+ };
300
+
301
+ db.upsertRequirement(requirement);
302
+
303
+ // Fetch all requirements for full file regeneration
304
+ const adapter = db._getAdapter();
305
+ let allRequirements: Requirement[] = [];
306
+ if (adapter) {
307
+ const rows = adapter.prepare('SELECT * FROM requirements ORDER BY id').all();
308
+ allRequirements = rows.map(row => ({
309
+ id: row['id'] as string,
310
+ class: row['class'] as string,
311
+ status: row['status'] as string,
312
+ description: row['description'] as string,
313
+ why: row['why'] as string,
314
+ source: row['source'] as string,
315
+ primary_owner: row['primary_owner'] as string,
316
+ supporting_slices: row['supporting_slices'] as string,
317
+ validation: row['validation'] as string,
318
+ notes: row['notes'] as string,
319
+ full_content: row['full_content'] as string,
320
+ superseded_by: (row['superseded_by'] as string) ?? null,
321
+ }));
322
+ }
323
+
324
+ const nonSuperseded = allRequirements.filter(r => r.superseded_by == null);
325
+ const md = generateRequirementsMd(nonSuperseded);
326
+ const filePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
327
+ try {
328
+ await saveFile(filePath, md);
329
+ } catch (diskErr) {
330
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveRequirementToDb', error: String((diskErr as Error).message) });
331
+ const rollbackAdapter = db._getAdapter();
332
+ rollbackAdapter?.prepare('DELETE FROM requirements WHERE id = :id').run({ ':id': id });
333
+ throw diskErr;
334
+ }
335
+ invalidateStateCache();
336
+ clearPathCache();
337
+ clearParseCache();
338
+
339
+ return { id };
340
+ } catch (err) {
341
+ logError('manifest', 'saveRequirementToDb failed', { fn: 'saveRequirementToDb', error: String((err as Error).message) });
342
+ throw err;
343
+ }
344
+ }
345
+
230
346
  // ─── Save Decision to DB + Regenerate Markdown ────────────────────────────
231
347
 
232
348
  export interface SaveDecisionFields {
@@ -344,15 +460,30 @@ export async function updateRequirementInDb(
344
460
  const db = await import('./gsd-db.js');
345
461
 
346
462
  const existing = db.getRequirementById(id);
347
- if (!existing) {
348
- throw new GSDError(GSD_STALE_STATE, `Requirement ${id} not found`);
349
- }
350
463
 
351
- // Merge updates into existing
464
+ // If requirement doesn't exist in DB, create a skeleton and merge updates.
465
+ // This handles the case where requirements were written to REQUIREMENTS.md
466
+ // but never imported into the database (see #2919).
467
+ const base: Requirement = existing ?? {
468
+ id,
469
+ class: '',
470
+ status: 'active',
471
+ description: '',
472
+ why: '',
473
+ source: '',
474
+ primary_owner: '',
475
+ supporting_slices: '',
476
+ validation: '',
477
+ notes: '',
478
+ full_content: '',
479
+ superseded_by: null,
480
+ };
481
+
482
+ // Merge updates into existing (or skeleton)
352
483
  const merged: Requirement = {
353
- ...existing,
484
+ ...base,
354
485
  ...updates,
355
- id: existing.id, // ID cannot be changed
486
+ id: base.id, // ID cannot be changed
356
487
  };
357
488
 
358
489
  db.upsertRequirement(merged);
@@ -388,7 +519,9 @@ export async function updateRequirementInDb(
388
519
  await saveFile(filePath, md);
389
520
  } catch (diskErr) {
390
521
  logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String((diskErr as Error).message) });
391
- db.upsertRequirement(existing);
522
+ if (existing) {
523
+ db.upsertRequirement(existing);
524
+ }
392
525
  throw diskErr;
393
526
  }
394
527
  // Invalidate file-read caches so deriveState() sees the updated markdown.
@@ -26,9 +26,20 @@ export function getPriorSliceCompletionBlocker(
26
26
  const { milestone: targetMid, slice: targetSid } = parseUnitId(unitId);
27
27
  if (!targetMid || !targetSid) return null;
28
28
 
29
+ // Parallel worker isolation: when GSD_MILESTONE_LOCK is set, this worker
30
+ // is scoped to a single milestone. Skip the cross-milestone dependency
31
+ // check — other milestones are being handled by their own workers.
32
+ // Without this, the dispatch guard sees incomplete slices in M010/M011
33
+ // (cloned into the worktree DB) and blocks M012 from ever starting. #2797
34
+ const milestoneLock = process.env.GSD_MILESTONE_LOCK;
35
+
29
36
  // Use findMilestoneIds to respect custom queue order.
30
37
  // Only check milestones that come BEFORE the target in queue order.
31
- const allIds = findMilestoneIds(base);
38
+ // When locked to a specific milestone, only check that milestone's
39
+ // intra-slice dependencies — skip all cross-milestone checks.
40
+ const allIds = milestoneLock && targetMid === milestoneLock
41
+ ? [targetMid]
42
+ : findMilestoneIds(base);
32
43
  const targetIdx = allIds.indexOf(targetMid);
33
44
  if (targetIdx < 0) return null;
34
45
  const milestoneIds = allIds.slice(0, targetIdx + 1);
@@ -14,6 +14,28 @@ import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchLis
14
14
  import { getAllWorktreeHealth } from "./worktree-health.js";
15
15
  import { loadEffectiveGSDPreferences } from "./preferences.js";
16
16
 
17
+ /**
18
+ * Returns true if the directory contains only doctor artifacts
19
+ * (e.g. `.gsd/doctor-history.jsonl`). These dirs are created by
20
+ * appendDoctorHistory() writing to worktree-scoped paths during the audit
21
+ * and should not be flagged as orphaned worktrees (#3105).
22
+ */
23
+ function isDoctorArtifactOnly(dirPath: string): boolean {
24
+ try {
25
+ const entries = readdirSync(dirPath);
26
+ // Empty dir — not a doctor artifact, still orphaned
27
+ if (entries.length === 0) return false;
28
+ // Only a .gsd subdirectory
29
+ if (entries.length === 1 && entries[0] === ".gsd") {
30
+ const gsdEntries = readdirSync(join(dirPath, ".gsd"));
31
+ return gsdEntries.length <= 1 && gsdEntries.every(e => e === "doctor-history.jsonl");
32
+ }
33
+ return false;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+
17
39
  export async function checkGitHealth(
18
40
  basePath: string,
19
41
  issues: DoctorIssue[],
@@ -314,6 +336,10 @@ export async function checkGitHealth(
314
336
  } catch { continue; }
315
337
  const normalizedFullPath = normalizePath(fullPath);
316
338
  if (!registeredPaths.has(normalizedFullPath)) {
339
+ // Skip directories that only contain doctor artifacts (.gsd/doctor-history.jsonl).
340
+ // appendDoctorHistory() can recreate these dirs during the audit itself,
341
+ // causing a circular false positive (#3105 Bug 1).
342
+ if (isDoctorArtifactOnly(fullPath)) continue;
317
343
  issues.push({
318
344
  severity: "warning",
319
345
  code: "worktree_directory_orphaned",
@@ -181,7 +181,8 @@ function resolveKey(providerId: string): KeyLookup {
181
181
  */
182
182
  const PROVIDER_ROUTES: Record<string, string[]> = {
183
183
  anthropic: ["github-copilot"],
184
- openai: ["github-copilot"],
184
+ openai: ["github-copilot", "openai-codex"],
185
+ google: ["google-gemini-cli"],
185
186
  };
186
187
 
187
188
  function checkLlmProviders(): ProviderCheckResult[] {
@@ -119,10 +119,11 @@ export async function checkRuntimeHealth(
119
119
 
120
120
  for (const key of keys) {
121
121
  // Key format: "unitType/unitId" e.g. "execute-task/M001/S01/T01"
122
- const slashIdx = key.indexOf("/");
123
- if (slashIdx === -1) continue;
124
- const unitType = key.slice(0, slashIdx);
125
- const unitId = key.slice(slashIdx + 1);
122
+ // Hook units have compound types: "hook/<hookName>/unitId"
123
+ const { splitCompletedKey } = await import("./forensics.js");
124
+ const parsed = splitCompletedKey(key);
125
+ if (!parsed) continue;
126
+ const { unitType, unitId } = parsed;
126
127
 
127
128
  // Only validate artifact-producing unit types
128
129
  const { verifyExpectedArtifact } = await import("./auto-recovery.js");
@@ -729,8 +729,10 @@ export async function runGSDDoctor(basePath: string, options?: { fix?: boolean;
729
729
  }
730
730
 
731
731
  // Blocker-without-replan detection
732
+ // Skip when all tasks are done — the blocker was implicitly resolved
733
+ // within the task and the slice is not stuck (#3105 Bug 2).
732
734
  const replanPath = resolveSliceFile(basePath, milestoneId, slice.id, "REPLAN");
733
- if (!replanPath) {
735
+ if (!replanPath && !allTasksDone) {
734
736
  for (const task of plan.tasks) {
735
737
  if (!task.done) continue;
736
738
  const summaryPath = resolveTaskFile(basePath, milestoneId, slice.id, task.id, "SUMMARY");
@@ -48,7 +48,7 @@ const NETWORK_RE = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fet
48
48
  const SERVER_RE = /internal server error|500|502|503|overloaded|server_error|api_error|service.?unavailable/i;
49
49
  // ECONNRESET/ECONNREFUSED are in NETWORK_RE (same-model retry first).
50
50
  const CONNECTION_RE = /terminated|connection.?refused|other side closed|EPIPE|network.?(?:is\s+)?unavailable|stream_exhausted(?:_without_result)?/i;
51
- const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected double-quoted property name|SyntaxError.*JSON/i;
51
+ const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected.*in JSON|Unterminated.*in JSON|SyntaxError.*JSON/i;
52
52
  const RESET_DELAY_RE = /reset in (\d+)s/i;
53
53
 
54
54
  /**
@@ -58,9 +58,9 @@ const RESET_DELAY_RE = /reset in (\d+)s/i;
58
58
  * 1. Permanent (auth/billing/quota) — unless also rate-limited
59
59
  * 2. Rate limit (429, rate.?limit, too many requests)
60
60
  * 3. Network (ECONNRESET, ETIMEDOUT, socket hang up, fetch failed, dns)
61
- * 4. Server (500/502/503, overloaded, server_error)
62
- * 5. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
63
- * 6. Stream truncation (malformed JSON from mid-stream cut)
61
+ * 4. Stream truncation (malformed JSON from mid-stream cut)
62
+ * 5. Server (500/502/503, overloaded, server_error)
63
+ * 6. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
64
64
  * 7. Unknown
65
65
  */
66
66
  export function classifyError(errorMsg: string, retryAfterMs?: number): ErrorClass {
@@ -90,21 +90,24 @@ export function classifyError(errorMsg: string, retryAfterMs?: number): ErrorCla
90
90
  return { kind: "network", retryAfterMs: retryAfterMs ?? 3_000 };
91
91
  }
92
92
 
93
- // 4. Server errorstry fallback model
93
+ // 4. Stream truncationdownstream symptom of connection drop
94
+ // Checked before server/connection because JSON parse errors can contain
95
+ // substrings like "position 500" (matches SERVER_RE) or "Unterminated"
96
+ // (matches CONNECTION_RE's "terminated" pattern).
97
+ if (STREAM_RE.test(errorMsg)) {
98
+ return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
99
+ }
100
+
101
+ // 5. Server errors — try fallback model
94
102
  if (SERVER_RE.test(errorMsg)) {
95
103
  return { kind: "server", retryAfterMs: retryAfterMs ?? 30_000 };
96
104
  }
97
105
 
98
- // 5. Connection errors — try fallback model
106
+ // 6. Connection errors — try fallback model
99
107
  if (CONNECTION_RE.test(errorMsg)) {
100
108
  return { kind: "connection", retryAfterMs: retryAfterMs ?? 15_000 };
101
109
  }
102
110
 
103
- // 6. Stream truncation — downstream symptom of connection drop
104
- if (STREAM_RE.test(errorMsg)) {
105
- return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
106
- }
107
-
108
111
  // 7. Unknown
109
112
  return { kind: "unknown" };
110
113
  }
@@ -12,7 +12,22 @@
12
12
  "gsd_requirement_update", "gsd_milestone_generate_id"
13
13
  ],
14
14
  "commands": ["gsd", "kill", "worktree", "exit"],
15
- "hooks": ["session_start", "session_switch"],
15
+ "hooks": [
16
+ "session_start",
17
+ "session_switch",
18
+ "bash_transform",
19
+ "session_fork",
20
+ "before_agent_start",
21
+ "agent_end",
22
+ "session_before_compact",
23
+ "session_shutdown",
24
+ "tool_call",
25
+ "tool_result",
26
+ "tool_execution_start",
27
+ "tool_execution_end",
28
+ "model_select",
29
+ "before_provider_request"
30
+ ],
16
31
  "shortcuts": ["Ctrl+Alt+G"]
17
32
  }
18
33
  }