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
@@ -3,17 +3,112 @@
3
3
  //
4
4
  // An agent can claim a unit (task, slice) before working on it.
5
5
  // complete-task and complete-slice enforce ownership when claims exist.
6
- // If no claim file is present, ownership is not enforced (backward compatible).
6
+ // Claims are stored in SQLite (.gsd/unit-claims.db) for atomic
7
+ // first-writer-wins semantics via INSERT OR IGNORE.
7
8
  //
8
- // Claim file location: .gsd/unit-claims.json
9
9
  // Unit key format:
10
10
  // task: "<milestoneId>/<sliceId>/<taskId>"
11
11
  // slice: "<milestoneId>/<sliceId>"
12
12
  //
13
13
  // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
14
- import { existsSync, readFileSync, mkdirSync } from "node:fs";
14
+ import { createRequire } from "node:module";
15
+ import { mkdirSync } from "node:fs";
15
16
  import { join } from "node:path";
16
- import { atomicWriteSync } from "./atomic-write.js";
17
+ const _require = createRequire(import.meta.url);
18
+ let providerName = null;
19
+ let providerModule = null;
20
+ let loadAttempted = false;
21
+ function suppressSqliteWarning() {
22
+ const origEmit = process.emit;
23
+ // @ts-expect-error overriding process.emit for warning filter
24
+ process.emit = function (event, ...args) {
25
+ if (event === "warning" &&
26
+ args[0] &&
27
+ typeof args[0] === "object" &&
28
+ "name" in args[0] &&
29
+ args[0].name === "ExperimentalWarning" &&
30
+ "message" in args[0] &&
31
+ typeof args[0].message === "string" &&
32
+ args[0].message.includes("SQLite")) {
33
+ return false;
34
+ }
35
+ return origEmit.apply(process, [event, ...args]);
36
+ };
37
+ }
38
+ function loadProvider() {
39
+ if (loadAttempted)
40
+ return;
41
+ loadAttempted = true;
42
+ try {
43
+ suppressSqliteWarning();
44
+ const mod = _require("node:sqlite");
45
+ if (mod.DatabaseSync) {
46
+ providerModule = mod;
47
+ providerName = "node:sqlite";
48
+ return;
49
+ }
50
+ }
51
+ catch {
52
+ // unavailable
53
+ }
54
+ try {
55
+ const mod = _require("better-sqlite3");
56
+ if (typeof mod === "function" || (mod && mod.default)) {
57
+ providerModule = mod.default || mod;
58
+ providerName = "better-sqlite3";
59
+ return;
60
+ }
61
+ }
62
+ catch {
63
+ // unavailable
64
+ }
65
+ }
66
+ function normalizeRow(row) {
67
+ if (row == null)
68
+ return undefined;
69
+ if (Object.getPrototypeOf(row) === null) {
70
+ return { ...row };
71
+ }
72
+ return row;
73
+ }
74
+ function openRawDb(path) {
75
+ loadProvider();
76
+ if (!providerModule || !providerName)
77
+ return null;
78
+ if (providerName === "node:sqlite") {
79
+ const { DatabaseSync } = providerModule;
80
+ return new DatabaseSync(path);
81
+ }
82
+ const Database = providerModule;
83
+ return new Database(path);
84
+ }
85
+ function wrapDb(rawDb) {
86
+ const db = rawDb;
87
+ return {
88
+ exec(sql) { db.exec(sql); },
89
+ prepare(sql) {
90
+ const raw = db.prepare(sql);
91
+ return {
92
+ run(...params) { return raw.run(...params); },
93
+ get(...params) {
94
+ return normalizeRow(raw.get(...params));
95
+ },
96
+ };
97
+ },
98
+ close() { db.close(); },
99
+ };
100
+ }
101
+ // ─── Per-basePath DB pool ────────────────────────────────────────────────
102
+ const dbPool = new Map();
103
+ function claimsDbPath(basePath) {
104
+ return join(basePath, ".gsd", "unit-claims.db");
105
+ }
106
+ function getDb(basePath) {
107
+ const existing = dbPool.get(basePath);
108
+ if (existing)
109
+ return existing;
110
+ return null;
111
+ }
17
112
  // ─── Key Builders ────────────────────────────────────────────────────────
18
113
  export function taskUnitKey(milestoneId, sliceId, taskId) {
19
114
  return `${milestoneId}/${sliceId}/${taskId}`;
@@ -21,56 +116,92 @@ export function taskUnitKey(milestoneId, sliceId, taskId) {
21
116
  export function sliceUnitKey(milestoneId, sliceId) {
22
117
  return `${milestoneId}/${sliceId}`;
23
118
  }
24
- // ─── File Path ───────────────────────────────────────────────────────────
25
- function claimsPath(basePath) {
26
- return join(basePath, ".gsd", "unit-claims.json");
119
+ // ─── Lifecycle ───────────────────────────────────────────────────────────
120
+ /**
121
+ * Initialize the ownership SQLite database for a given basePath.
122
+ * Creates .gsd/ directory and unit-claims.db with the unit_claims table.
123
+ * Safe to call multiple times (idempotent).
124
+ */
125
+ export function initOwnershipTable(basePath) {
126
+ if (dbPool.has(basePath))
127
+ return;
128
+ const dir = join(basePath, ".gsd");
129
+ mkdirSync(dir, { recursive: true });
130
+ const raw = openRawDb(claimsDbPath(basePath));
131
+ if (!raw) {
132
+ throw new Error("No SQLite provider available for unit-ownership");
133
+ }
134
+ const db = wrapDb(raw);
135
+ db.exec("PRAGMA journal_mode=WAL");
136
+ db.exec("PRAGMA busy_timeout = 5000");
137
+ db.exec("PRAGMA synchronous = NORMAL");
138
+ db.exec(`
139
+ CREATE TABLE IF NOT EXISTS unit_claims (
140
+ unit_key TEXT PRIMARY KEY,
141
+ agent_name TEXT NOT NULL,
142
+ claimed_at TEXT NOT NULL
143
+ )
144
+ `);
145
+ dbPool.set(basePath, db);
27
146
  }
28
- // ─── Read Claims ─────────────────────────────────────────────────────────
29
- function readClaims(basePath) {
30
- const path = claimsPath(basePath);
31
- if (!existsSync(path))
32
- return null;
147
+ /**
148
+ * Close the ownership database for a given basePath.
149
+ * Safe to call even if not initialized.
150
+ */
151
+ export function closeOwnershipDb(basePath) {
152
+ const db = dbPool.get(basePath);
153
+ if (!db)
154
+ return;
33
155
  try {
34
- return JSON.parse(readFileSync(path, "utf-8"));
35
- }
36
- catch {
37
- return null;
156
+ db.close();
38
157
  }
158
+ catch { /* swallow */ }
159
+ dbPool.delete(basePath);
39
160
  }
40
161
  // ─── Public API ──────────────────────────────────────────────────────────
41
162
  /**
42
163
  * Claim a unit for an agent.
43
- * Overwrites any existing claim for this unit (last writer wins).
164
+ * Uses INSERT OR IGNORE for atomic first-writer-wins semantics.
165
+ * Returns true if the claim was acquired (or the same agent already owns it).
166
+ * Returns false if a different agent already owns the unit.
44
167
  */
45
168
  export function claimUnit(basePath, unitKey, agentName) {
46
- const claims = readClaims(basePath) ?? {};
47
- claims[unitKey] = { agent: agentName, claimed_at: new Date().toISOString() };
48
- const dir = join(basePath, ".gsd");
49
- mkdirSync(dir, { recursive: true });
50
- atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
169
+ const db = getDb(basePath);
170
+ if (!db) {
171
+ // Auto-init if not already initialized (backward compat)
172
+ initOwnershipTable(basePath);
173
+ return claimUnit(basePath, unitKey, agentName);
174
+ }
175
+ // INSERT OR IGNORE: if the row already exists, this is a no-op.
176
+ // The PRIMARY KEY constraint on unit_key prevents duplicate claims.
177
+ db.prepare("INSERT OR IGNORE INTO unit_claims (unit_key, agent_name, claimed_at) VALUES (?, ?, ?)").run(unitKey, agentName, new Date().toISOString());
178
+ // Check who owns it now
179
+ const row = db.prepare("SELECT agent_name FROM unit_claims WHERE unit_key = ?").get(unitKey);
180
+ const owner = row?.agent_name;
181
+ return owner === agentName;
51
182
  }
52
183
  /**
53
- * Release a unit claim (remove it from the claims map).
184
+ * Release a unit claim (remove it from the claims table).
54
185
  */
55
186
  export function releaseUnit(basePath, unitKey) {
56
- const claims = readClaims(basePath);
57
- if (!claims || !(unitKey in claims))
187
+ const db = getDb(basePath);
188
+ if (!db)
58
189
  return;
59
- delete claims[unitKey];
60
- atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
190
+ db.prepare("DELETE FROM unit_claims WHERE unit_key = ?").run(unitKey);
61
191
  }
62
192
  /**
63
- * Get the current owner of a unit, or null if unclaimed / no claims file.
193
+ * Get the current owner of a unit, or null if unclaimed.
64
194
  */
65
195
  export function getOwner(basePath, unitKey) {
66
- const claims = readClaims(basePath);
67
- if (!claims)
196
+ const db = getDb(basePath);
197
+ if (!db)
68
198
  return null;
69
- return claims[unitKey]?.agent ?? null;
199
+ const row = db.prepare("SELECT agent_name FROM unit_claims WHERE unit_key = ?").get(unitKey);
200
+ return row?.agent_name ?? null;
70
201
  }
71
202
  /**
72
203
  * Check if an actor is authorized to operate on a unit.
73
- * Returns null if ownership passes (or is unclaimed / no file).
204
+ * Returns null if ownership passes (or is unclaimed).
74
205
  * Returns an error string if a different agent owns the unit.
75
206
  */
76
207
  export function checkOwnership(basePath, unitKey, actorName) {
@@ -78,7 +209,7 @@ export function checkOwnership(basePath, unitKey, actorName) {
78
209
  return null; // no actor identity provided — opt-in, so allow
79
210
  const owner = getOwner(basePath, unitKey);
80
211
  if (owner === null)
81
- return null; // unit unclaimed or no claims file
212
+ return null; // unit unclaimed
82
213
  if (owner === actorName)
83
214
  return null; // actor is the owner
84
215
  return `Unit ${unitKey} is owned by ${owner}, not ${actorName}`;
@@ -16,16 +16,28 @@ import { extractUatType } from "./files.js";
16
16
  * Returns `undefined` when frontmatter is absent or has no `verdict` field.
17
17
  */
18
18
  export function extractVerdict(content) {
19
+ // Primary: YAML frontmatter verdict (canonical format)
19
20
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
20
- if (!fmMatch)
21
+ if (fmMatch) {
22
+ const verdictMatch = fmMatch[1].match(/verdict:\s*([\w-]+)/i);
23
+ if (verdictMatch) {
24
+ let v = verdictMatch[1].toLowerCase();
25
+ if (v === "passed")
26
+ v = "pass";
27
+ return v;
28
+ }
21
29
  return undefined;
22
- const verdictMatch = fmMatch[1].match(/verdict:\s*([\w-]+)/i);
23
- if (!verdictMatch)
24
- return undefined;
25
- let v = verdictMatch[1].toLowerCase();
26
- if (v === "passed")
27
- v = "pass";
28
- return v;
30
+ }
31
+ // Fallback: detect verdict in markdown body (LLM manual writes, #2960).
32
+ // Matches patterns like: **Verdict:** PASS, **Verdict:** ✅ PASS, **Verdict** needs-remediation
33
+ const bodyMatch = content.match(/\*\*Verdict:?\*\*\s*(?:✅\s*)?(\w[\w-]*)/i);
34
+ if (bodyMatch) {
35
+ let v = bodyMatch[1].toLowerCase();
36
+ if (v === "passed")
37
+ v = "pass";
38
+ return v;
39
+ }
40
+ return undefined;
29
41
  }
30
42
  /**
31
43
  * Returns `true` when the content's frontmatter contains a `verdict` field.
@@ -9,6 +9,25 @@ function requireDb() {
9
9
  throw new Error("workflow-manifest: No database open");
10
10
  return db;
11
11
  }
12
+ /**
13
+ * Coerce a raw DB value to a number, returning `fallback` for
14
+ * null/undefined/non-numeric strings (e.g. "-", "N/A", "").
15
+ * SQLite can store TEXT in INTEGER columns after migrations or manual inserts.
16
+ */
17
+ export function toNumeric(value, fallback = null) {
18
+ if (value === null || value === undefined)
19
+ return fallback;
20
+ if (typeof value === "number")
21
+ return Number.isFinite(value) ? value : fallback;
22
+ if (typeof value === "string") {
23
+ const trimmed = value.trim();
24
+ if (trimmed === "" || trimmed === "-" || trimmed === "N/A")
25
+ return fallback;
26
+ const n = Number(trimmed);
27
+ return Number.isFinite(n) ? n : fallback;
28
+ }
29
+ return fallback;
30
+ }
12
31
  // ─── snapshotState ───────────────────────────────────────────────────────
13
32
  /**
14
33
  * Capture complete DB state as a StateManifest.
@@ -62,7 +81,7 @@ export function snapshotState() {
62
81
  proof_level: r["proof_level"] ?? "",
63
82
  integration_closure: r["integration_closure"] ?? "",
64
83
  observability_impact: r["observability_impact"] ?? "",
65
- sequence: r["sequence"] ?? 0,
84
+ sequence: toNumeric(r["sequence"], 0),
66
85
  replan_triggered_at: r["replan_triggered_at"] ?? null,
67
86
  }));
68
87
  const rawTasks = db.prepare("SELECT * FROM tasks ORDER BY milestone_id, slice_id, sequence, id").all();
@@ -91,11 +110,11 @@ export function snapshotState() {
91
110
  expected_output: JSON.parse(r["expected_output"] || "[]"),
92
111
  observability_impact: r["observability_impact"] ?? "",
93
112
  full_plan_md: r["full_plan_md"] ?? "",
94
- sequence: r["sequence"] ?? 0,
113
+ sequence: toNumeric(r["sequence"], 0),
95
114
  }));
96
115
  const rawDecisions = db.prepare("SELECT * FROM decisions ORDER BY seq").all();
97
116
  const decisions = rawDecisions.map((r) => ({
98
- seq: r["seq"],
117
+ seq: toNumeric(r["seq"], 0),
99
118
  id: r["id"],
100
119
  when_context: r["when_context"] ?? "",
101
120
  scope: r["scope"] ?? "",
@@ -113,9 +132,9 @@ export function snapshotState() {
113
132
  slice_id: r["slice_id"],
114
133
  milestone_id: r["milestone_id"],
115
134
  command: r["command"],
116
- exit_code: r["exit_code"] ?? null,
135
+ exit_code: toNumeric(r["exit_code"]),
117
136
  verdict: r["verdict"] ?? "",
118
- duration_ms: r["duration_ms"] ?? null,
137
+ duration_ms: toNumeric(r["duration_ms"]),
119
138
  created_at: r["created_at"],
120
139
  }));
121
140
  const result = {
@@ -1,7 +1,7 @@
1
1
  // GSD Extension — Projection Renderers (DB -> Markdown)
2
2
  // Renders PLAN.md, ROADMAP.md, SUMMARY.md, and STATE.md from database rows.
3
3
  // Projections are read-only views of engine state (Layer 3 of the architecture).
4
- import { _getAdapter, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, } from "./gsd-db.js";
4
+ import { _getAdapter, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, getVerificationEvidence, } from "./gsd-db.js";
5
5
  import { atomicWriteSync } from "./atomic-write.js";
6
6
  import { join } from "node:path";
7
7
  import { mkdirSync, existsSync } from "node:fs";
@@ -16,8 +16,10 @@ export function renderPlanContent(sliceRow, taskRows) {
16
16
  const lines = [];
17
17
  lines.push(`# ${sliceRow.id}: ${sliceRow.title}`);
18
18
  lines.push("");
19
- lines.push(`**Goal:** ${sliceRow.goal || sliceRow.full_summary_md || "TBD"}`);
20
- lines.push(`**Demo:** After this: ${sliceRow.demo || sliceRow.full_uat_md || "TBD"}`);
19
+ // #2945: never use full_summary_md/full_uat_md as display fallbacks —
20
+ // they contain multi-line rendered markdown that corrupts single-line fields.
21
+ lines.push(`**Goal:** ${sliceRow.goal || "TBD"}`);
22
+ lines.push(`**Demo:** After this: ${sliceRow.demo || "TBD"}`);
21
23
  lines.push("");
22
24
  lines.push("## Tasks");
23
25
  for (const task of taskRows) {
@@ -85,7 +87,10 @@ export function renderRoadmapContent(milestoneRow, sliceRows) {
85
87
  depends = slice.depends.join(", ");
86
88
  }
87
89
  const risk = (slice.risk || "low").toLowerCase();
88
- const demo = slice.demo || slice.full_uat_md || "TBD";
90
+ // #2945 Bug 1: never use full_uat_md as a table cell fallback — it contains
91
+ // multi-line UAT content (preconditions, steps, expected results) that
92
+ // corrupts the markdown table and makes subsequent slices invisible.
93
+ const demo = slice.demo || "TBD";
89
94
  lines.push(`| ${slice.id} | ${slice.title} | ${risk} | ${depends} | ${done} | ${demo} |`);
90
95
  }
91
96
  lines.push("");
@@ -108,64 +113,85 @@ export function renderRoadmapProjection(basePath, milestoneId) {
108
113
  // ─── SUMMARY.md Projection ──────────────────────────────────────────────
109
114
  /**
110
115
  * Render SUMMARY.md content from a task row.
111
- * Pure functionno side effects.
116
+ * Single source of truth for summary rendering used both at completion
117
+ * time and at projection regeneration time (#2720).
118
+ *
119
+ * @param evidence - Optional verification evidence rows. When called from
120
+ * complete-task, these are passed directly. When called from projection
121
+ * regeneration, they are queried from the DB by renderSummaryProjection.
112
122
  */
113
- export function renderSummaryContent(taskRow, sliceId, milestoneId) {
114
- const lines = [];
115
- // Frontmatter
116
- lines.push("---");
117
- lines.push(`id: ${taskRow.id}`);
118
- lines.push(`parent: ${sliceId}`);
119
- lines.push(`milestone: ${milestoneId}`);
120
- lines.push("provides: []");
121
- lines.push("requires: []");
122
- lines.push("affects: []");
123
- // key_files is already parsed to string[]
124
- if (taskRow.key_files && taskRow.key_files.length > 0) {
125
- lines.push(`key_files: [${taskRow.key_files.map(f => `"${f}"`).join(", ")}]`);
126
- }
127
- else {
128
- lines.push("key_files: []");
129
- }
130
- // key_decisions is already parsed to string[]
131
- if (taskRow.key_decisions && taskRow.key_decisions.length > 0) {
132
- lines.push(`key_decisions: [${taskRow.key_decisions.map(d => `"${d}"`).join(", ")}]`);
123
+ export function renderSummaryContent(taskRow, sliceId, milestoneId, evidence) {
124
+ // ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
125
+ const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
126
+ ? taskRow.key_files.map(f => ` - ${f}`).join("\n")
127
+ : " - (none)";
128
+ const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
129
+ ? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
130
+ : " - (none)";
131
+ // Derive verification_result from evidence if available
132
+ const evidenceList = evidence ?? [];
133
+ const allPassed = evidenceList.length > 0 &&
134
+ evidenceList.every(e => {
135
+ const code = e.exitCode ?? e.exit_code ?? -1;
136
+ return code === 0 || e.verdict.includes("\u2705") || e.verdict.toLowerCase().includes("pass");
137
+ });
138
+ const verificationResult = taskRow.verification_result
139
+ ? (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"))
140
+ : (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"));
141
+ // Build verification evidence table
142
+ let evidenceTable = "| # | Command | Exit Code | Verdict | Duration |\n|---|---------|-----------|---------|----------|\n";
143
+ if (evidenceList.length > 0) {
144
+ evidenceList.forEach((e, i) => {
145
+ const code = e.exitCode ?? e.exit_code ?? 0;
146
+ const dur = e.durationMs ?? e.duration_ms ?? 0;
147
+ evidenceTable += `| ${i + 1} | \`${e.command}\` | ${code} | ${e.verdict} | ${dur}ms |\n`;
148
+ });
133
149
  }
134
150
  else {
135
- lines.push("key_decisions: []");
136
- }
137
- lines.push("patterns_established: []");
138
- lines.push("drill_down_paths: []");
139
- lines.push("observability_surfaces: []");
140
- lines.push(`duration: "${taskRow.duration || ""}"`);
141
- lines.push(`verification_result: "${taskRow.verification_result || ""}"`);
142
- lines.push(`completed_at: ${taskRow.completed_at || ""}`);
143
- lines.push(`blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}`);
144
- lines.push("---");
145
- lines.push("");
146
- lines.push(`# ${taskRow.id}: ${taskRow.title}`);
147
- lines.push("");
148
- // One-liner (if present)
149
- if (taskRow.one_liner) {
150
- lines.push(`> ${taskRow.one_liner}`);
151
- lines.push("");
151
+ evidenceTable += "| \u2014 | No verification commands discovered | \u2014 | \u2014 | \u2014 |\n";
152
152
  }
153
- lines.push("## What Happened");
154
- lines.push(taskRow.full_summary_md || taskRow.narrative || "No summary recorded.");
155
- lines.push("");
156
- // Deviations (if present)
157
- if (taskRow.deviations) {
158
- lines.push("## Deviations");
159
- lines.push(taskRow.deviations);
160
- lines.push("");
161
- }
162
- // Known issues (if present)
163
- if (taskRow.known_issues) {
164
- lines.push("## Known Issues");
165
- lines.push(taskRow.known_issues);
166
- lines.push("");
167
- }
168
- return lines.join("\n");
153
+ const title = taskRow.one_liner || taskRow.title || taskRow.id;
154
+ return `---
155
+ id: ${taskRow.id}
156
+ parent: ${sliceId}
157
+ milestone: ${milestoneId}
158
+ key_files:
159
+ ${keyFilesYaml}
160
+ key_decisions:
161
+ ${keyDecisionsYaml}
162
+ duration: ${taskRow.duration || ""}
163
+ verification_result: ${verificationResult}
164
+ completed_at: ${taskRow.completed_at || ""}
165
+ blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}
166
+ ---
167
+
168
+ # ${taskRow.id}: ${title}
169
+
170
+ **${taskRow.one_liner || ""}**
171
+
172
+ ## What Happened
173
+
174
+ ${taskRow.narrative || "No summary recorded."}
175
+
176
+ ## Verification
177
+
178
+ ${taskRow.verification_result || "No verification recorded."}
179
+
180
+ ## Verification Evidence
181
+
182
+ ${evidenceTable}
183
+ ## Deviations
184
+
185
+ ${taskRow.deviations || "None."}
186
+
187
+ ## Known Issues
188
+
189
+ ${taskRow.known_issues || "None."}
190
+
191
+ ## Files Created/Modified
192
+
193
+ ${taskRow.key_files && taskRow.key_files.length > 0 ? taskRow.key_files.map(f => `- \`${f}\``).join("\n") : "None."}
194
+ `;
169
195
  }
170
196
  /**
171
197
  * Render SUMMARY.md projection to disk for a specific task.
@@ -176,7 +202,8 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
176
202
  const taskRow = taskRows.find(t => t.id === taskId);
177
203
  if (!taskRow)
178
204
  return;
179
- const content = renderSummaryContent(taskRow, sliceId, milestoneId);
205
+ const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
206
+ const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
180
207
  const dir = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks");
181
208
  mkdirSync(dir, { recursive: true });
182
209
  atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
@@ -190,13 +217,18 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
190
217
  export function renderStateContent(state) {
191
218
  const lines = [];
192
219
  lines.push("# GSD State", "");
193
- const activeMilestone = state.activeMilestone
194
- ? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
195
- : "None";
196
220
  const activeSlice = state.activeSlice
197
221
  ? `${state.activeSlice.id}: ${state.activeSlice.title}`
198
222
  : "None";
199
- lines.push(`**Active Milestone:** ${activeMilestone}`);
223
+ if (state.phase === 'complete' && state.lastCompletedMilestone) {
224
+ lines.push(`**Last Completed Milestone:** ${state.lastCompletedMilestone.id}: ${state.lastCompletedMilestone.title}`);
225
+ }
226
+ else {
227
+ const activeMilestone = state.activeMilestone
228
+ ? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
229
+ : "None";
230
+ lines.push(`**Active Milestone:** ${activeMilestone}`);
231
+ }
200
232
  lines.push(`**Active Slice:** ${activeSlice}`);
201
233
  lines.push(`**Phase:** ${state.phase}`);
202
234
  if (state.requirements) {
@@ -1,10 +1,39 @@
1
1
  import { join } from "node:path";
2
2
  import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
3
+ import { logWarning, logError } from "./workflow-logger.js";
3
4
  import { readEvents, findForkPoint, appendEvent, getSessionId } from "./workflow-events.js";
4
- import { transaction, updateTaskStatus, updateSliceStatus, insertVerificationEvidence, upsertDecision, openDatabase, } from "./gsd-db.js";
5
+ import { transaction, updateTaskStatus, updateSliceStatus, getSliceTasks, insertVerificationEvidence, upsertDecision, openDatabase, } from "./gsd-db.js";
6
+ import { isClosedStatus } from "./status-guards.js";
5
7
  import { writeManifest } from "./workflow-manifest.js";
6
8
  import { atomicWriteSync } from "./atomic-write.js";
7
9
  import { acquireSyncLock, releaseSyncLock } from "./sync-lock.js";
10
+ // ─── Replay Helpers ──────────────────────────────────────────────────────────
11
+ /**
12
+ * Replay a complete_slice event with task validation.
13
+ *
14
+ * #2945 Bug 2: The original replay blindly called updateSliceStatus("done")
15
+ * without checking whether all tasks in the slice are actually complete.
16
+ * During API overload or partial execution, a complete_slice event could
17
+ * be logged even when tasks were skipped, causing the milestone completion
18
+ * guard to see the slice as "done" and allow premature milestone completion.
19
+ *
20
+ * This function validates that every task in the slice has a closed status
21
+ * before marking the slice as done. If any task is still pending, the slice
22
+ * status is left unchanged.
23
+ */
24
+ export function replaySliceComplete(milestoneId, sliceId, ts) {
25
+ const tasks = getSliceTasks(milestoneId, sliceId);
26
+ // If there are tasks and any are not closed, skip the status update
27
+ if (tasks.length > 0) {
28
+ const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
29
+ if (incompleteTasks.length > 0) {
30
+ process.stderr.write(`[gsd] reconcile: skipping complete_slice replay for ${sliceId} — ` +
31
+ `${incompleteTasks.length} task(s) still pending\n`);
32
+ return;
33
+ }
34
+ }
35
+ updateSliceStatus(milestoneId, sliceId, "done", ts);
36
+ }
8
37
  // ─── replayEvents ─────────────────────────────────────────────────────────────
9
38
  /**
10
39
  * Replay a list of WorkflowEvents by dispatching each to the appropriate
@@ -58,7 +87,8 @@ function replayEvents(events) {
58
87
  case "complete_slice": {
59
88
  const milestoneId = p["milestoneId"];
60
89
  const sliceId = p["sliceId"];
61
- updateSliceStatus(milestoneId, sliceId, "done", event.ts);
90
+ // #2945 Bug 2: validate tasks before marking slice done
91
+ replaySliceComplete(milestoneId, sliceId, event.ts);
62
92
  break;
63
93
  }
64
94
  case "plan_slice": {
@@ -221,7 +251,7 @@ export function reconcileWorktreeLogs(mainBasePath, worktreeBasePath) {
221
251
  // Acquire advisory lock to prevent concurrent reconcile + append races
222
252
  const lock = acquireSyncLock(mainBasePath);
223
253
  if (!lock.acquired) {
224
- process.stderr.write(`[gsd] reconcile: could not acquire sync lock — another reconciliation may be in progress\n`);
254
+ logWarning("reconcile", "could not acquire sync lock — another reconciliation may be in progress");
225
255
  return { autoMerged: 0, conflicts: [] };
226
256
  }
227
257
  try {
@@ -251,7 +281,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
251
281
  if (conflicts.length > 0) {
252
282
  // D-04: atomic all-or-nothing — block entire merge
253
283
  writeConflictsFile(mainBasePath, conflicts, worktreeBasePath);
254
- process.stderr.write(`[gsd] reconcile: ${conflicts.length} conflict(s) detected see ${join(mainBasePath, ".gsd", "CONFLICTS.md")}\n`);
284
+ logError("reconcile", `${conflicts.length} conflict(s) detected`, { count: String(conflicts.length), path: join(mainBasePath, ".gsd", "CONFLICTS.md") });
255
285
  return { autoMerged: 0, conflicts };
256
286
  }
257
287
  // Step 6: Clean merge — stable sort by timestamp (index-based tiebreaker)
@@ -272,7 +302,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
272
302
  writeManifest(mainBasePath);
273
303
  }
274
304
  catch (err) {
275
- process.stderr.write(`[gsd] reconcile: manifest write failed (non-fatal): ${err.message}\n`);
305
+ logWarning("reconcile", "manifest write failed (non-fatal)", { error: err.message });
276
306
  }
277
307
  return { autoMerged: merged.length, conflicts: [] };
278
308
  }