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
@@ -11,7 +11,7 @@ import { resolve } from 'node:path';
11
11
  import { readFileSync, existsSync, statSync } from 'node:fs';
12
12
  import { resolveGsdRootFile } from './paths.js';
13
13
  import { saveFile } from './files.js';
14
- import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
14
+ import { GSDError, GSD_IO_ERROR } from './errors.js';
15
15
  import { logWarning, logError } from './workflow-logger.js';
16
16
  import { invalidateStateCache } from './state.js';
17
17
  import { clearPathCache } from './paths.js';
@@ -205,6 +205,98 @@ export async function nextDecisionId() {
205
205
  return 'D001';
206
206
  }
207
207
  }
208
+ // ─── Next Requirement ID ─────────────────────────────────────────────────
209
+ /**
210
+ * Compute the next requirement ID from the current DB state.
211
+ * Queries MAX(CAST(SUBSTR(id, 2) AS INTEGER)) from requirements table.
212
+ * Returns R001 if no requirements exist. Zero-pads to 3 digits.
213
+ */
214
+ export async function nextRequirementId() {
215
+ try {
216
+ const db = await import('./gsd-db.js');
217
+ const adapter = db._getAdapter();
218
+ if (!adapter)
219
+ return 'R001';
220
+ const row = adapter
221
+ .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM requirements')
222
+ .get();
223
+ const maxNum = row ? row['max_num'] : null;
224
+ if (maxNum == null || isNaN(maxNum))
225
+ return 'R001';
226
+ const next = maxNum + 1;
227
+ return `R${String(next).padStart(3, '0')}`;
228
+ }
229
+ catch (err) {
230
+ logError('manifest', 'nextRequirementId failed', { fn: 'nextRequirementId', error: String(err.message) });
231
+ return 'R001';
232
+ }
233
+ }
234
+ /**
235
+ * Save a new requirement to DB and regenerate REQUIREMENTS.md.
236
+ * Auto-assigns the next ID via nextRequirementId().
237
+ * Returns the assigned ID.
238
+ */
239
+ export async function saveRequirementToDb(fields, basePath) {
240
+ try {
241
+ const db = await import('./gsd-db.js');
242
+ const id = await nextRequirementId();
243
+ const requirement = {
244
+ id,
245
+ class: fields.class,
246
+ status: fields.status ?? 'active',
247
+ description: fields.description,
248
+ why: fields.why,
249
+ source: fields.source,
250
+ primary_owner: fields.primary_owner ?? '',
251
+ supporting_slices: fields.supporting_slices ?? '',
252
+ validation: fields.validation ?? '',
253
+ notes: fields.notes ?? '',
254
+ full_content: '',
255
+ superseded_by: null,
256
+ };
257
+ db.upsertRequirement(requirement);
258
+ // Fetch all requirements for full file regeneration
259
+ const adapter = db._getAdapter();
260
+ let allRequirements = [];
261
+ if (adapter) {
262
+ const rows = adapter.prepare('SELECT * FROM requirements ORDER BY id').all();
263
+ allRequirements = rows.map(row => ({
264
+ id: row['id'],
265
+ class: row['class'],
266
+ status: row['status'],
267
+ description: row['description'],
268
+ why: row['why'],
269
+ source: row['source'],
270
+ primary_owner: row['primary_owner'],
271
+ supporting_slices: row['supporting_slices'],
272
+ validation: row['validation'],
273
+ notes: row['notes'],
274
+ full_content: row['full_content'],
275
+ superseded_by: row['superseded_by'] ?? null,
276
+ }));
277
+ }
278
+ const nonSuperseded = allRequirements.filter(r => r.superseded_by == null);
279
+ const md = generateRequirementsMd(nonSuperseded);
280
+ const filePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
281
+ try {
282
+ await saveFile(filePath, md);
283
+ }
284
+ catch (diskErr) {
285
+ logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveRequirementToDb', error: String(diskErr.message) });
286
+ const rollbackAdapter = db._getAdapter();
287
+ rollbackAdapter?.prepare('DELETE FROM requirements WHERE id = :id').run({ ':id': id });
288
+ throw diskErr;
289
+ }
290
+ invalidateStateCache();
291
+ clearPathCache();
292
+ clearParseCache();
293
+ return { id };
294
+ }
295
+ catch (err) {
296
+ logError('manifest', 'saveRequirementToDb failed', { fn: 'saveRequirementToDb', error: String(err.message) });
297
+ throw err;
298
+ }
299
+ }
208
300
  /**
209
301
  * Save a new decision to DB and regenerate DECISIONS.md.
210
302
  * Auto-assigns the next ID via nextDecisionId().
@@ -295,14 +387,28 @@ export async function updateRequirementInDb(id, updates, basePath) {
295
387
  try {
296
388
  const db = await import('./gsd-db.js');
297
389
  const existing = db.getRequirementById(id);
298
- if (!existing) {
299
- throw new GSDError(GSD_STALE_STATE, `Requirement ${id} not found`);
300
- }
301
- // Merge updates into existing
390
+ // If requirement doesn't exist in DB, create a skeleton and merge updates.
391
+ // This handles the case where requirements were written to REQUIREMENTS.md
392
+ // but never imported into the database (see #2919).
393
+ const base = existing ?? {
394
+ id,
395
+ class: '',
396
+ status: 'active',
397
+ description: '',
398
+ why: '',
399
+ source: '',
400
+ primary_owner: '',
401
+ supporting_slices: '',
402
+ validation: '',
403
+ notes: '',
404
+ full_content: '',
405
+ superseded_by: null,
406
+ };
407
+ // Merge updates into existing (or skeleton)
302
408
  const merged = {
303
- ...existing,
409
+ ...base,
304
410
  ...updates,
305
- id: existing.id, // ID cannot be changed
411
+ id: base.id, // ID cannot be changed
306
412
  };
307
413
  db.upsertRequirement(merged);
308
414
  // Fetch ALL requirements (including superseded) for full file regeneration
@@ -335,7 +441,9 @@ export async function updateRequirementInDb(id, updates, basePath) {
335
441
  }
336
442
  catch (diskErr) {
337
443
  logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String(diskErr.message) });
338
- db.upsertRequirement(existing);
444
+ if (existing) {
445
+ db.upsertRequirement(existing);
446
+ }
339
447
  throw diskErr;
340
448
  }
341
449
  // Invalidate file-read caches so deriveState() sees the updated markdown.
@@ -18,9 +18,19 @@ export function getPriorSliceCompletionBlocker(base, _mainBranch, unitType, unit
18
18
  const { milestone: targetMid, slice: targetSid } = parseUnitId(unitId);
19
19
  if (!targetMid || !targetSid)
20
20
  return null;
21
+ // Parallel worker isolation: when GSD_MILESTONE_LOCK is set, this worker
22
+ // is scoped to a single milestone. Skip the cross-milestone dependency
23
+ // check — other milestones are being handled by their own workers.
24
+ // Without this, the dispatch guard sees incomplete slices in M010/M011
25
+ // (cloned into the worktree DB) and blocks M012 from ever starting. #2797
26
+ const milestoneLock = process.env.GSD_MILESTONE_LOCK;
21
27
  // Use findMilestoneIds to respect custom queue order.
22
28
  // Only check milestones that come BEFORE the target in queue order.
23
- const allIds = findMilestoneIds(base);
29
+ // When locked to a specific milestone, only check that milestone's
30
+ // intra-slice dependencies — skip all cross-milestone checks.
31
+ const allIds = milestoneLock && targetMid === milestoneLock
32
+ ? [targetMid]
33
+ : findMilestoneIds(base);
24
34
  const targetIdx = allIds.indexOf(targetMid);
25
35
  if (targetIdx < 0)
26
36
  return null;
@@ -11,6 +11,29 @@ import { RUNTIME_EXCLUSION_PATHS, resolveMilestoneIntegrationBranch, writeIntegr
11
11
  import { nativeIsRepo, nativeWorktreeList, nativeWorktreeRemove, nativeBranchList, nativeBranchDelete, nativeLsFiles, nativeRmCached } from "./native-git-bridge.js";
12
12
  import { getAllWorktreeHealth } from "./worktree-health.js";
13
13
  import { loadEffectiveGSDPreferences } from "./preferences.js";
14
+ /**
15
+ * Returns true if the directory contains only doctor artifacts
16
+ * (e.g. `.gsd/doctor-history.jsonl`). These dirs are created by
17
+ * appendDoctorHistory() writing to worktree-scoped paths during the audit
18
+ * and should not be flagged as orphaned worktrees (#3105).
19
+ */
20
+ function isDoctorArtifactOnly(dirPath) {
21
+ try {
22
+ const entries = readdirSync(dirPath);
23
+ // Empty dir — not a doctor artifact, still orphaned
24
+ if (entries.length === 0)
25
+ return false;
26
+ // Only a .gsd subdirectory
27
+ if (entries.length === 1 && entries[0] === ".gsd") {
28
+ const gsdEntries = readdirSync(join(dirPath, ".gsd"));
29
+ return gsdEntries.length <= 1 && gsdEntries.every(e => e === "doctor-history.jsonl");
30
+ }
31
+ return false;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
14
37
  export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode = "none") {
15
38
  // Degrade gracefully if not a git repo
16
39
  if (!nativeIsRepo(basePath)) {
@@ -307,6 +330,11 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
307
330
  }
308
331
  const normalizedFullPath = normalizePath(fullPath);
309
332
  if (!registeredPaths.has(normalizedFullPath)) {
333
+ // Skip directories that only contain doctor artifacts (.gsd/doctor-history.jsonl).
334
+ // appendDoctorHistory() can recreate these dirs during the audit itself,
335
+ // causing a circular false positive (#3105 Bug 1).
336
+ if (isDoctorArtifactOnly(fullPath))
337
+ continue;
310
338
  issues.push({
311
339
  severity: "warning",
312
340
  code: "worktree_directory_orphaned",
@@ -144,7 +144,8 @@ function resolveKey(providerId) {
144
144
  */
145
145
  const PROVIDER_ROUTES = {
146
146
  anthropic: ["github-copilot"],
147
- openai: ["github-copilot"],
147
+ openai: ["github-copilot", "openai-codex"],
148
+ google: ["google-gemini-cli"],
148
149
  };
149
150
  function checkLlmProviders() {
150
151
  const required = collectConfiguredModelProviders();
@@ -108,11 +108,12 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
108
108
  const orphaned = [];
109
109
  for (const key of keys) {
110
110
  // Key format: "unitType/unitId" e.g. "execute-task/M001/S01/T01"
111
- const slashIdx = key.indexOf("/");
112
- if (slashIdx === -1)
111
+ // Hook units have compound types: "hook/<hookName>/unitId"
112
+ const { splitCompletedKey } = await import("./forensics.js");
113
+ const parsed = splitCompletedKey(key);
114
+ if (!parsed)
113
115
  continue;
114
- const unitType = key.slice(0, slashIdx);
115
- const unitId = key.slice(slashIdx + 1);
116
+ const { unitType, unitId } = parsed;
116
117
  // Only validate artifact-producing unit types
117
118
  const { verifyExpectedArtifact } = await import("./auto-recovery.js");
118
119
  if (!verifyExpectedArtifact(unitType, unitId, basePath)) {
@@ -689,8 +689,10 @@ export async function runGSDDoctor(basePath, options) {
689
689
  allTasksDone = allTasksDone && task.done;
690
690
  }
691
691
  // Blocker-without-replan detection
692
+ // Skip when all tasks are done — the blocker was implicitly resolved
693
+ // within the task and the slice is not stuck (#3105 Bug 2).
692
694
  const replanPath = resolveSliceFile(basePath, milestoneId, slice.id, "REPLAN");
693
- if (!replanPath) {
695
+ if (!replanPath && !allTasksDone) {
694
696
  for (const task of plan.tasks) {
695
697
  if (!task.done)
696
698
  continue;
@@ -24,7 +24,7 @@ const NETWORK_RE = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fet
24
24
  const SERVER_RE = /internal server error|500|502|503|overloaded|server_error|api_error|service.?unavailable/i;
25
25
  // ECONNRESET/ECONNREFUSED are in NETWORK_RE (same-model retry first).
26
26
  const CONNECTION_RE = /terminated|connection.?refused|other side closed|EPIPE|network.?(?:is\s+)?unavailable|stream_exhausted(?:_without_result)?/i;
27
- const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected double-quoted property name|SyntaxError.*JSON/i;
27
+ const STREAM_RE = /Unexpected end of JSON|Unexpected token.*JSON|Expected.*in JSON|Unterminated.*in JSON|SyntaxError.*JSON/i;
28
28
  const RESET_DELAY_RE = /reset in (\d+)s/i;
29
29
  /**
30
30
  * Classify an error message into one of the ErrorClass kinds.
@@ -33,9 +33,9 @@ const RESET_DELAY_RE = /reset in (\d+)s/i;
33
33
  * 1. Permanent (auth/billing/quota) — unless also rate-limited
34
34
  * 2. Rate limit (429, rate.?limit, too many requests)
35
35
  * 3. Network (ECONNRESET, ETIMEDOUT, socket hang up, fetch failed, dns)
36
- * 4. Server (500/502/503, overloaded, server_error)
37
- * 5. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
38
- * 6. Stream truncation (malformed JSON from mid-stream cut)
36
+ * 4. Stream truncation (malformed JSON from mid-stream cut)
37
+ * 5. Server (500/502/503, overloaded, server_error)
38
+ * 6. Connection (terminated, ECONNREFUSED, EPIPE, other side closed)
39
39
  * 7. Unknown
40
40
  */
41
41
  export function classifyError(errorMsg, retryAfterMs) {
@@ -61,18 +61,21 @@ export function classifyError(errorMsg, retryAfterMs) {
61
61
  // "billing" appearing alongside "network").
62
62
  return { kind: "network", retryAfterMs: retryAfterMs ?? 3_000 };
63
63
  }
64
- // 4. Server errorstry fallback model
64
+ // 4. Stream truncationdownstream symptom of connection drop
65
+ // Checked before server/connection because JSON parse errors can contain
66
+ // substrings like "position 500" (matches SERVER_RE) or "Unterminated"
67
+ // (matches CONNECTION_RE's "terminated" pattern).
68
+ if (STREAM_RE.test(errorMsg)) {
69
+ return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
70
+ }
71
+ // 5. Server errors — try fallback model
65
72
  if (SERVER_RE.test(errorMsg)) {
66
73
  return { kind: "server", retryAfterMs: retryAfterMs ?? 30_000 };
67
74
  }
68
- // 5. Connection errors — try fallback model
75
+ // 6. Connection errors — try fallback model
69
76
  if (CONNECTION_RE.test(errorMsg)) {
70
77
  return { kind: "connection", retryAfterMs: retryAfterMs ?? 15_000 };
71
78
  }
72
- // 6. Stream truncation — downstream symptom of connection drop
73
- if (STREAM_RE.test(errorMsg)) {
74
- return { kind: "stream", retryAfterMs: retryAfterMs ?? 15_000 };
75
- }
76
79
  // 7. Unknown
77
80
  return { kind: "unknown" };
78
81
  }
@@ -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
  }
@@ -22,6 +22,8 @@ import { deriveState } from "./state.js";
22
22
  import { isAutoActive } from "./auto.js";
23
23
  import { loadPrompt } from "./prompt-loader.js";
24
24
  import { gsdRoot } from "./paths.js";
25
+ import { isDbAvailable, getAllMilestones, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
26
+ import { isClosedStatus } from "./status-guards.js";
25
27
  import { formatDuration } from "../shared/format-utils.js";
26
28
  import { getAutoWorktreePath } from "./auto-worktree.js";
27
29
  import { loadEffectiveGSDPreferences, loadGlobalGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
@@ -29,13 +31,15 @@ import { showNextAction } from "../shared/tui.js";
29
31
  import { ensurePreferencesFile, serializePreferencesToFrontmatter } from "./commands-prefs-wizard.js";
30
32
  // ─── Duplicate Detection ──────────────────────────────────────────────────────
31
33
  const DEDUP_PROMPT_SECTION = `
32
- ## Duplicate Detection (REQUIRED before issue creation)
34
+ ## Pre-Investigation: Duplicate Check (REQUIRED)
33
35
 
34
- Before offering to create a GitHub issue, you MUST search for existing issues and PRs that may already address this bug. This step uses the user's AI tokens for analysis.
36
+ Before reading GSD source code or performing deep analysis, you MUST search for existing issues and PRs that may already address this bug. This avoids wasting tokens on already-fixed bugs.
35
37
 
36
38
  ### Search Steps
37
39
 
38
- 1. **Search closed issues** for similar keywords from your diagnosis:
40
+ Use keywords from the user's problem description and the anomaly summaries in the forensic report above.
41
+
42
+ 1. **Search closed issues** for similar keywords:
39
43
  \`\`\`
40
44
  gh issue list --repo gsd-build/gsd-2 --state closed --search "<keywords from root cause>" --limit 20
41
45
  \`\`\`
@@ -52,20 +56,16 @@ Before offering to create a GitHub issue, you MUST search for existing issues an
52
56
 
53
57
  ### Analysis
54
58
 
55
- For each result, compare it against your root-cause diagnosis:
59
+ For each result, compare it against the user's reported symptoms and the forensic anomalies:
56
60
  - Does the issue describe the same code path or file?
57
- - Does the PR modify the same file:line you identified?
61
+ - Does the PR modify the area related to the reported symptoms?
58
62
  - Is the symptom description semantically similar even if keywords differ?
59
63
 
60
- ### Present Findings
61
-
62
- If you find potential matches, present them to the user:
63
-
64
- 1. **"Already fixed by PR #X — skip issue creation"** — when a merged PR or closed issue clearly addresses the same root cause. Explain why you believe it matches.
65
- 2. **"Add my findings to existing issue #Y"** — when an open issue exists for the same bug. Use \`gh issue comment #Y --repo gsd-build/gsd-2\` to add forensic evidence.
66
- 3. **"Create new issue anyway"** — when existing results do not cover this specific failure.
64
+ ### Decision Gate
67
65
 
68
- Only proceed to issue creation if no matches were found OR the user explicitly chooses "Create new issue anyway".
66
+ - **Merged PR clearly fixes the described symptom** Report "Already fixed by PR #X" with brief explanation. Skip full investigation.
67
+ - **Open issue matches** → Report "Existing issue #Y covers this." Offer to add forensic evidence. Skip full investigation unless user asks for deeper analysis.
68
+ - **No matches** → Proceed to full investigation below.
69
69
  `;
70
70
  async function writeForensicsDedupPref(ctx, enabled) {
71
71
  const prefsPath = getGlobalGSDPreferencesPath();
@@ -148,6 +148,8 @@ export async function handleForensics(args, ctx, pi) {
148
148
  });
149
149
  ctx.ui.notify(`Forensic report saved: ${relative(basePath, savedPath)}`, "info");
150
150
  pi.sendMessage({ customType: "gsd-forensics", content, display: false }, { triggerTurn: true });
151
+ // Persist forensics context so follow-up turns can re-inject it (#2941)
152
+ writeForensicsMarker(basePath, savedPath, content);
151
153
  }
152
154
  // ─── Report Builder ───────────────────────────────────────────────────────────
153
155
  export async function buildForensicReport(basePath) {
@@ -167,8 +169,9 @@ export async function buildForensicReport(basePath) {
167
169
  const unitTraces = scanActivityLogs(basePath, activeMilestone);
168
170
  // 3. Load metrics
169
171
  const metrics = loadLedgerFromDisk(basePath);
170
- // 4. Load completed keys
172
+ // 4. Load completed keys (legacy) and DB completion counts
171
173
  const completedKeys = loadCompletedKeys(basePath);
174
+ const dbCompletionCounts = getDbCompletionCounts();
172
175
  // 5. Check crash lock
173
176
  const crashLock = readCrashLock(basePath);
174
177
  // 6. Run doctor
@@ -222,6 +225,7 @@ export async function buildForensicReport(basePath) {
222
225
  unitTraces,
223
226
  metrics,
224
227
  completedKeys,
228
+ dbCompletionCounts,
225
229
  crashLock,
226
230
  doctorIssues,
227
231
  anomalies,
@@ -458,6 +462,41 @@ function loadCompletedKeys(basePath) {
458
462
  catch { /* non-fatal */ }
459
463
  return [];
460
464
  }
465
+ // ─── DB Completion Counts ────────────────────────────────────────────────────
466
+ function getDbCompletionCounts() {
467
+ if (!isDbAvailable())
468
+ return null;
469
+ const milestones = getAllMilestones();
470
+ let completedMilestones = 0;
471
+ let totalSlices = 0;
472
+ let completedSlices = 0;
473
+ let totalTasks = 0;
474
+ let completedTasks = 0;
475
+ for (const m of milestones) {
476
+ if (isClosedStatus(m.status))
477
+ completedMilestones++;
478
+ const slices = getMilestoneSlices(m.id);
479
+ for (const s of slices) {
480
+ totalSlices++;
481
+ if (isClosedStatus(s.status))
482
+ completedSlices++;
483
+ const tasks = getSliceTasks(m.id, s.id);
484
+ for (const t of tasks) {
485
+ totalTasks++;
486
+ if (isClosedStatus(t.status))
487
+ completedTasks++;
488
+ }
489
+ }
490
+ }
491
+ return {
492
+ milestones: completedMilestones,
493
+ milestonesTotal: milestones.length,
494
+ slices: completedSlices,
495
+ slicesTotal: totalSlices,
496
+ tasks: completedTasks,
497
+ tasksTotal: totalTasks,
498
+ };
499
+ }
461
500
  // ─── Anomaly Detectors ───────────────────────────────────────────────────────
462
501
  function detectStuckLoops(units, anomalies) {
463
502
  const counts = new Map();
@@ -515,15 +554,42 @@ function detectTimeouts(traces, anomalies) {
515
554
  }
516
555
  }
517
556
  }
557
+ /**
558
+ * Parse a completed-unit key into its unitType and unitId.
559
+ *
560
+ * Hook units use a compound slash-delimited type ("hook/<hookName>"), so a
561
+ * naive `key.indexOf("/")` would split "hook/telegram-progress/M007/S01" into
562
+ * unitType="hook" (wrong) instead of "hook/telegram-progress".
563
+ *
564
+ * Returns `null` for malformed keys that cannot be split.
565
+ */
566
+ export function splitCompletedKey(key) {
567
+ if (key.startsWith("hook/")) {
568
+ // Hook unit types are two segments: "hook/<hookName>/<unitId...>"
569
+ const secondSlash = key.indexOf("/", 5); // skip past "hook/"
570
+ if (secondSlash === -1)
571
+ return null; // malformed — no unitId after hook name
572
+ return {
573
+ unitType: key.slice(0, secondSlash),
574
+ unitId: key.slice(secondSlash + 1),
575
+ };
576
+ }
577
+ const slashIdx = key.indexOf("/");
578
+ if (slashIdx === -1)
579
+ return null;
580
+ return {
581
+ unitType: key.slice(0, slashIdx),
582
+ unitId: key.slice(slashIdx + 1),
583
+ };
584
+ }
518
585
  function detectMissingArtifacts(completedKeys, basePath, activeMilestone, anomalies) {
519
586
  // Also check the worktree path for artifacts — they may exist there but not at root
520
587
  const wtBasePath = activeMilestone ? getAutoWorktreePath(basePath, activeMilestone) : null;
521
588
  for (const key of completedKeys) {
522
- const slashIdx = key.indexOf("/");
523
- if (slashIdx === -1)
589
+ const parsed = splitCompletedKey(key);
590
+ if (!parsed)
524
591
  continue;
525
- const unitType = key.slice(0, slashIdx);
526
- const unitId = key.slice(slashIdx + 1);
592
+ const { unitType, unitId } = parsed;
527
593
  const rootHasArtifact = verifyExpectedArtifact(unitType, unitId, basePath);
528
594
  const wtHasArtifact = wtBasePath ? verifyExpectedArtifact(unitType, unitId, wtBasePath) : false;
529
595
  if (!rootHasArtifact && !wtHasArtifact) {
@@ -749,6 +815,34 @@ function saveForensicReport(basePath, report, problemDescription) {
749
815
  writeFileSync(filePath, sections.join("\n"), "utf-8");
750
816
  return filePath;
751
817
  }
818
+ /**
819
+ * Write a marker file so that buildBeforeAgentStartResult() can re-inject
820
+ * the forensics prompt on follow-up turns. (#2941)
821
+ */
822
+ export function writeForensicsMarker(basePath, reportPath, promptContent) {
823
+ const dir = join(gsdRoot(basePath), "runtime");
824
+ mkdirSync(dir, { recursive: true });
825
+ const marker = {
826
+ reportPath,
827
+ promptContent,
828
+ createdAt: new Date().toISOString(),
829
+ };
830
+ writeFileSync(join(dir, "active-forensics.json"), JSON.stringify(marker), "utf-8");
831
+ }
832
+ /**
833
+ * Read the active forensics marker, or null if none exists.
834
+ */
835
+ export function readForensicsMarker(basePath) {
836
+ const markerPath = join(gsdRoot(basePath), "runtime", "active-forensics.json");
837
+ if (!existsSync(markerPath))
838
+ return null;
839
+ try {
840
+ return JSON.parse(readFileSync(markerPath, "utf-8"));
841
+ }
842
+ catch {
843
+ return null;
844
+ }
845
+ }
752
846
  // ─── Prompt Formatter ─────────────────────────────────────────────────────────
753
847
  function formatReportForPrompt(report) {
754
848
  const MAX_BYTES = 30 * 1024;
@@ -856,8 +950,17 @@ function formatReportForPrompt(report) {
856
950
  }
857
951
  sections.push("");
858
952
  }
859
- // Completed keys count
860
- sections.push(`### Completed Keys: ${report.completedKeys.length}`);
953
+ // Completion status — prefer DB counts, fall back to legacy completed-units.json
954
+ if (report.dbCompletionCounts) {
955
+ const c = report.dbCompletionCounts;
956
+ sections.push(`### Completion Status (from DB)`);
957
+ sections.push(`- ${c.milestones}/${c.milestonesTotal} milestones complete`);
958
+ sections.push(`- ${c.slices}/${c.slicesTotal} slices complete`);
959
+ sections.push(`- ${c.tasks}/${c.tasksTotal} tasks complete`);
960
+ }
961
+ else {
962
+ sections.push(`### Completed Keys: ${report.completedKeys.length}`);
963
+ }
861
964
  sections.push(`### GSD Version: ${report.gsdVersion}`);
862
965
  sections.push(`### Active Milestone: ${report.activeMilestone ?? "none"}`);
863
966
  sections.push(`### Active Slice: ${report.activeSlice ?? "none"}`);
@@ -8,7 +8,7 @@
8
8
  * paths, commit type inference, and the runGit shell helper.
9
9
  */
10
10
  import { execFileSync, execSync } from "node:child_process";
11
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
@@ -348,6 +348,28 @@ export class GitServiceImpl {
348
348
  // If .gsd/ IS in .gitignore (the default for external state projects),
349
349
  // git add -A already skips it and the exclusions are harmless no-ops.
350
350
  const allExclusions = [...RUNTIME_EXCLUSION_PATHS, ...extraExclusions];
351
+ // ── Parallel worker milestone scope (#1991) ──
352
+ // When GSD_MILESTONE_LOCK is set, this process is a parallel worker that
353
+ // must only commit files belonging to its own milestone. Exclude all other
354
+ // milestone directories from staging to prevent cross-milestone pollution
355
+ // (e.g., an M033 worker fabricating M032 artifacts in the same commit).
356
+ const milestoneLock = process.env.GSD_MILESTONE_LOCK;
357
+ if (milestoneLock) {
358
+ const msDir = join(gsdRoot(this.basePath), "milestones");
359
+ if (existsSync(msDir)) {
360
+ try {
361
+ const entries = readdirSync(msDir, { withFileTypes: true });
362
+ for (const entry of entries) {
363
+ if (entry.isDirectory() && entry.name !== milestoneLock) {
364
+ allExclusions.push(`.gsd/milestones/${entry.name}/`);
365
+ }
366
+ }
367
+ }
368
+ catch {
369
+ // Best-effort — if we can't read the milestones dir, proceed without scoping
370
+ }
371
+ }
372
+ }
351
373
  nativeAddAllWithExclusions(this.basePath, allExclusions);
352
374
  }
353
375
  /** Tracks whether runtime file cleanup has run this session. */
@@ -38,6 +38,7 @@ const GSD_RUNTIME_PATTERNS = [
38
38
  const BASELINE_PATTERNS = [
39
39
  // ── GSD state directory (symlink to external storage) ──
40
40
  ".gsd",
41
+ ".gsd-id",
41
42
  // ── OS junk ──
42
43
  ".DS_Store",
43
44
  "Thumbs.db",
@@ -72,6 +73,38 @@ const BASELINE_PATTERNS = [
72
73
  ".cache/",
73
74
  "tmp/",
74
75
  ];
76
+ /**
77
+ * Check whether `.gsd` is covered by the project's `.gitignore`.
78
+ *
79
+ * Uses `git check-ignore` for accurate evaluation — this respects nested
80
+ * .gitignore files, global gitignore, and negation patterns. Returns true
81
+ * only when git would actually ignore `.gsd/`.
82
+ *
83
+ * Returns false (not ignored) if:
84
+ * - No `.gitignore` exists
85
+ * - `.gsd` is not listed in any active ignore rule
86
+ * - Not a git repo or git is unavailable
87
+ */
88
+ export function isGsdGitignored(basePath) {
89
+ // Check both `.gsd` and `.gsd/` because `.gsd/` in .gitignore (trailing
90
+ // slash = directory-only pattern) only matches the directory form. Using
91
+ // both paths covers all gitignore pattern variants.
92
+ for (const path of [".gsd", ".gsd/"]) {
93
+ try {
94
+ // git check-ignore exits 0 when the path IS ignored, 1 when it is NOT.
95
+ execFileSync("git", ["check-ignore", "-q", path], {
96
+ cwd: basePath,
97
+ stdio: "pipe",
98
+ env: GIT_NO_PROMPT_ENV,
99
+ });
100
+ return true; // exit 0 → .gsd is ignored
101
+ }
102
+ catch {
103
+ // exit 1 → this form is NOT ignored, try the other
104
+ }
105
+ }
106
+ return false; // neither form is ignored (or git unavailable)
107
+ }
75
108
  /**
76
109
  * Check whether `.gsd/` contains files tracked by git.
77
110
  * If so, the project intentionally keeps `.gsd/` in version control