gsd-pi 2.57.0-dev.f22a903 → 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 (643) 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/phases.js +25 -21
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  26. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  28. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  29. package/dist/resources/extensions/gsd/auto-worktree.js +196 -12
  30. package/dist/resources/extensions/gsd/auto.js +4 -0
  31. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
  33. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  37. package/dist/resources/extensions/gsd/captures.js +56 -4
  38. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  39. package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
  40. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  41. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  42. package/dist/resources/extensions/gsd/doctor.js +3 -1
  43. package/dist/resources/extensions/gsd/error-classifier.js +13 -10
  44. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  45. package/dist/resources/extensions/gsd/forensics.js +123 -20
  46. package/dist/resources/extensions/gsd/git-service.js +23 -1
  47. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  48. package/dist/resources/extensions/gsd/gsd-db.js +36 -9
  49. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  50. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  51. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  52. package/dist/resources/extensions/gsd/index.js +1 -1
  53. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  54. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  55. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  56. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  57. package/dist/resources/extensions/gsd/model-router.js +35 -1
  58. package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
  59. package/dist/resources/extensions/gsd/notifications.js +16 -1
  60. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  61. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  62. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  63. package/dist/resources/extensions/gsd/paths.js +43 -0
  64. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  65. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  66. package/dist/resources/extensions/gsd/preferences.js +13 -16
  67. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  68. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  70. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  71. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  73. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  74. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  77. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  79. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  80. package/dist/resources/extensions/gsd/rethink.js +5 -0
  81. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  82. package/dist/resources/extensions/gsd/state.js +85 -27
  83. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  84. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  85. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  86. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  87. package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
  88. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  89. package/dist/resources/extensions/gsd/undo.js +2 -2
  90. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  91. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  92. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  93. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  94. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  95. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  96. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  97. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  98. package/dist/resources/extensions/mcp-client/index.js +11 -7
  99. package/dist/resources/extensions/ollama/index.js +112 -0
  100. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  101. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  102. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  103. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  104. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  105. package/dist/resources/extensions/ollama/types.js +2 -0
  106. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  107. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  108. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  109. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  110. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  111. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  112. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  113. package/dist/startup-model-validation.d.ts +39 -0
  114. package/dist/startup-model-validation.js +50 -0
  115. package/dist/web/standalone/.next/BUILD_ID +1 -1
  116. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  117. package/dist/web/standalone/.next/build-manifest.json +3 -3
  118. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  119. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  122. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  138. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/index.html +1 -1
  193. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  194. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  196. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  198. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  199. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  201. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  202. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  205. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  206. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  207. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  208. package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
  209. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  210. package/dist/web-mode.js +2 -1
  211. package/package.json +2 -2
  212. package/packages/daemon/src/cli.ts +49 -0
  213. package/packages/daemon/src/daemon.test.ts +104 -1
  214. package/packages/daemon/src/daemon.ts +24 -1
  215. package/packages/daemon/src/discord-bot.ts +73 -3
  216. package/packages/daemon/src/event-bridge.ts +15 -9
  217. package/packages/daemon/src/event-formatter.ts +30 -2
  218. package/packages/daemon/src/index.ts +9 -0
  219. package/packages/daemon/src/launchd.test.ts +356 -0
  220. package/packages/daemon/src/launchd.ts +242 -0
  221. package/packages/daemon/src/message-batcher.test.ts +2 -2
  222. package/packages/daemon/src/message-batcher.ts +9 -3
  223. package/packages/daemon/src/orchestrator.test.ts +1 -0
  224. package/packages/daemon/src/orchestrator.ts +106 -2
  225. package/packages/native/dist/ast/index.js +9 -5
  226. package/packages/native/dist/ast/types.js +2 -1
  227. package/packages/native/dist/clipboard/index.js +12 -7
  228. package/packages/native/dist/clipboard/types.js +2 -1
  229. package/packages/native/dist/diff/index.js +12 -7
  230. package/packages/native/dist/diff/types.js +2 -1
  231. package/packages/native/dist/fd/index.js +6 -3
  232. package/packages/native/dist/fd/types.js +2 -1
  233. package/packages/native/dist/glob/index.js +9 -5
  234. package/packages/native/dist/glob/types.js +2 -1
  235. package/packages/native/dist/grep/index.js +9 -5
  236. package/packages/native/dist/grep/types.js +2 -1
  237. package/packages/native/dist/gsd-parser/index.js +18 -11
  238. package/packages/native/dist/gsd-parser/types.js +2 -1
  239. package/packages/native/dist/highlight/index.js +12 -7
  240. package/packages/native/dist/highlight/types.js +2 -1
  241. package/packages/native/dist/html/index.js +6 -3
  242. package/packages/native/dist/html/types.js +2 -1
  243. package/packages/native/dist/image/index.js +10 -5
  244. package/packages/native/dist/image/types.js +7 -4
  245. package/packages/native/dist/index.js +70 -17
  246. package/packages/native/dist/json-parse/index.js +13 -8
  247. package/packages/native/dist/native.js +47 -10
  248. package/packages/native/dist/ps/index.js +15 -9
  249. package/packages/native/dist/ps/types.js +2 -1
  250. package/packages/native/dist/stream-process/index.js +12 -7
  251. package/packages/native/dist/text/index.js +24 -14
  252. package/packages/native/dist/text/types.js +5 -2
  253. package/packages/native/dist/truncate/index.js +12 -7
  254. package/packages/native/dist/ttsr/index.js +12 -7
  255. package/packages/native/dist/ttsr/types.js +2 -1
  256. package/packages/native/dist/xxhash/index.js +9 -5
  257. package/packages/native/package.json +19 -19
  258. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  259. package/packages/native/src/native.ts +9 -8
  260. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  261. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  262. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  263. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  264. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  265. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  266. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  267. package/packages/pi-agent-core/src/proxy.ts +1 -1
  268. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  269. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  270. package/packages/pi-ai/dist/index.d.ts +1 -0
  271. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  272. package/packages/pi-ai/dist/index.js +1 -0
  273. package/packages/pi-ai/dist/index.js.map +1 -1
  274. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  275. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  276. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  277. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  278. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  279. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  280. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  281. package/packages/pi-ai/dist/types.d.ts +3 -3
  282. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  283. package/packages/pi-ai/dist/types.js.map +1 -1
  284. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  285. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  286. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  287. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  288. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  289. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  290. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  291. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  292. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  293. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  294. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  295. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  296. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  297. package/packages/pi-ai/src/index.ts +1 -0
  298. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  299. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  300. package/packages/pi-ai/src/types.ts +3 -2
  301. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  302. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  303. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  304. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  305. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  307. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  309. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  311. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  313. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  315. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  318. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  320. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  324. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  325. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  326. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  327. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  328. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  330. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  332. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  334. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  336. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  338. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  340. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  341. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  342. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  344. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  346. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  347. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  348. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  349. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  350. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  351. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  352. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  354. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  356. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  357. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  360. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  363. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  365. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  366. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  367. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  368. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  370. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  372. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  374. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  376. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  378. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  380. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  382. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  385. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  388. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  390. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  391. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  392. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  393. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  394. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/index.js +1 -1
  396. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  398. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
  399. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  400. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  401. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  403. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  404. package/packages/pi-coding-agent/package.json +1 -1
  405. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  406. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  407. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  408. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  409. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  410. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  411. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  412. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  413. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  414. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  415. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  416. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  417. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  418. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  419. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  420. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  421. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  422. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  423. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  424. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  425. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  426. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  427. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  428. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  429. package/packages/pi-coding-agent/src/index.ts +6 -0
  430. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
  431. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  432. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  433. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  434. package/packages/pi-tui/dist/terminal.js +9 -0
  435. package/packages/pi-tui/dist/terminal.js.map +1 -1
  436. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  437. package/packages/pi-tui/dist/tui.js +9 -0
  438. package/packages/pi-tui/dist/tui.js.map +1 -1
  439. package/packages/pi-tui/src/terminal.ts +14 -0
  440. package/packages/pi-tui/src/tui.ts +8 -0
  441. package/pkg/package.json +1 -1
  442. package/scripts/ensure-workspace-builds.cjs +45 -14
  443. package/src/resources/agents/researcher.md +1 -1
  444. package/src/resources/extensions/ask-user-questions.ts +21 -3
  445. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  446. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  447. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  448. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  449. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  450. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  451. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  452. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  453. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  454. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  455. package/src/resources/extensions/google-search/index.ts +2 -1
  456. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  457. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  458. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  459. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  460. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  461. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  462. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  463. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  464. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  465. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  466. package/src/resources/extensions/gsd/auto-worktree.ts +190 -9
  467. package/src/resources/extensions/gsd/auto.ts +5 -0
  468. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  469. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
  470. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  471. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
  472. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
  473. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  474. package/src/resources/extensions/gsd/captures.ts +63 -3
  475. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  476. package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
  477. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  478. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  479. package/src/resources/extensions/gsd/doctor.ts +3 -1
  480. package/src/resources/extensions/gsd/error-classifier.ts +14 -11
  481. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  482. package/src/resources/extensions/gsd/forensics.ts +144 -20
  483. package/src/resources/extensions/gsd/git-service.ts +26 -3
  484. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  485. package/src/resources/extensions/gsd/gsd-db.ts +43 -7
  486. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  487. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  488. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  489. package/src/resources/extensions/gsd/index.ts +1 -0
  490. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  491. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  492. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  493. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  494. package/src/resources/extensions/gsd/model-router.ts +35 -1
  495. package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
  496. package/src/resources/extensions/gsd/notifications.ts +16 -0
  497. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  498. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  499. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  500. package/src/resources/extensions/gsd/paths.ts +42 -0
  501. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  502. package/src/resources/extensions/gsd/preferences-types.ts +2 -1
  503. package/src/resources/extensions/gsd/preferences.ts +13 -15
  504. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  505. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  506. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  507. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  508. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  509. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  510. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  511. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  512. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  513. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  514. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  515. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  516. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  517. package/src/resources/extensions/gsd/rethink.ts +6 -0
  518. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  519. package/src/resources/extensions/gsd/state.ts +84 -32
  520. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  521. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  522. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  523. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  524. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  525. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  526. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  527. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  528. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  529. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  530. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  531. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  533. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  534. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  535. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  536. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  537. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  538. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  539. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  540. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  541. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  542. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  543. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  544. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  545. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  546. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  547. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  548. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  549. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  550. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
  551. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  552. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  553. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  554. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  555. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  556. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  557. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  558. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  559. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  560. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  561. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  562. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  563. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  564. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  565. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  566. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  567. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  568. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  569. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
  570. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  571. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  572. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  573. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  574. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  575. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  576. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  577. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  578. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  579. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  580. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  581. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  582. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  583. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  584. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  585. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  586. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  587. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  588. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  589. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  590. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  591. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  592. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
  593. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  594. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  595. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  596. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  597. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  598. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  599. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  600. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  601. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  602. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  603. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  604. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  605. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  606. package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
  607. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  608. package/src/resources/extensions/gsd/types.ts +4 -2
  609. package/src/resources/extensions/gsd/undo.ts +2 -2
  610. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  611. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  612. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  613. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  614. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  615. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  616. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  617. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  618. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  619. package/src/resources/extensions/mcp-client/index.ts +13 -7
  620. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  621. package/src/resources/extensions/ollama/index.ts +130 -0
  622. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  623. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  624. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  625. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  626. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  627. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  628. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  629. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  630. package/src/resources/extensions/ollama/types.ts +130 -0
  631. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  632. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  633. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  634. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  635. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  636. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  637. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  638. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  639. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
  640. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  641. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  642. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
  643. /package/dist/web/standalone/.next/static/{OS7_z6QaL6uqp8q5pjHSJ → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
@@ -15,79 +15,41 @@ import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
15
15
  import { saveFile, clearParseCache } from "../files.js";
16
16
  import { invalidateStateCache } from "../state.js";
17
17
  import { renderPlanCheckboxes } from "../markdown-renderer.js";
18
- import { renderAllProjections } from "../workflow-projections.js";
18
+ import { renderAllProjections, renderSummaryContent } from "../workflow-projections.js";
19
19
  import { writeManifest } from "../workflow-manifest.js";
20
20
  import { appendEvent } from "../workflow-events.js";
21
21
  /**
22
- * Render task summary markdown matching the template format.
23
- * YAML frontmatter uses snake_case keys for parseSummary() compatibility.
22
+ * Build a TaskRow-shaped object from CompleteTaskParams so the unified
23
+ * renderSummaryContent() can be used at completion time (#2720).
24
24
  */
25
- function renderSummaryMarkdown(params) {
26
- const now = new Date().toISOString();
27
- const keyFilesYaml = params.keyFiles.length > 0
28
- ? params.keyFiles.map(f => ` - ${f}`).join("\n")
29
- : " - (none)";
30
- const keyDecisionsYaml = params.keyDecisions.length > 0
31
- ? params.keyDecisions.map(d => ` - ${d}`).join("\n")
32
- : " - (none)";
33
- // Build verification evidence table rows
34
- let evidenceTable = "| # | Command | Exit Code | Verdict | Duration |\n|---|---------|-----------|---------|----------|\n";
35
- if (params.verificationEvidence.length > 0) {
36
- params.verificationEvidence.forEach((e, i) => {
37
- evidenceTable += `| ${i + 1} | \`${e.command}\` | ${e.exitCode} | ${e.verdict} | ${e.durationMs}ms |\n`;
38
- });
39
- }
40
- else {
41
- evidenceTable += "| — | No verification commands discovered | — | — | — |\n";
42
- }
43
- // Determine verification_result from evidence
44
- const allPassed = params.verificationEvidence.length > 0 &&
45
- params.verificationEvidence.every(e => e.exitCode === 0 || e.verdict.includes("✅") || e.verdict.toLowerCase().includes("pass"));
46
- const verificationResult = allPassed ? "passed" : (params.verificationEvidence.length === 0 ? "untested" : "mixed");
47
- // Extract a title from the oneLiner or taskId
48
- const title = params.oneLiner || params.taskId;
49
- return `---
50
- id: ${params.taskId}
51
- parent: ${params.sliceId}
52
- milestone: ${params.milestoneId}
53
- key_files:
54
- ${keyFilesYaml}
55
- key_decisions:
56
- ${keyDecisionsYaml}
57
- duration: ""
58
- verification_result: ${verificationResult}
59
- completed_at: ${now}
60
- blocker_discovered: ${params.blockerDiscovered}
61
- ---
62
-
63
- # ${params.taskId}: ${title}
64
-
65
- **${params.oneLiner}**
66
-
67
- ## What Happened
68
-
69
- ${params.narrative}
70
-
71
- ## Verification
72
-
73
- ${params.verification}
74
-
75
- ## Verification Evidence
76
-
77
- ${evidenceTable}
78
-
79
- ## Deviations
80
-
81
- ${params.deviations || "None."}
82
-
83
- ## Known Issues
84
-
85
- ${params.knownIssues || "None."}
86
-
87
- ## Files Created/Modified
88
-
89
- ${params.keyFiles.map(f => `- \`${f}\``).join("\n") || "None."}
90
- `;
25
+ function paramsToTaskRow(params, completedAt) {
26
+ return {
27
+ milestone_id: params.milestoneId,
28
+ slice_id: params.sliceId,
29
+ id: params.taskId,
30
+ title: params.oneLiner || params.taskId,
31
+ status: "complete",
32
+ one_liner: params.oneLiner,
33
+ narrative: params.narrative,
34
+ verification_result: params.verification,
35
+ duration: "",
36
+ completed_at: completedAt,
37
+ blocker_discovered: params.blockerDiscovered,
38
+ deviations: params.deviations,
39
+ known_issues: params.knownIssues,
40
+ key_files: params.keyFiles,
41
+ key_decisions: params.keyDecisions,
42
+ full_summary_md: "",
43
+ description: "",
44
+ estimate: "",
45
+ files: [],
46
+ verify: "",
47
+ inputs: [],
48
+ expected_output: [],
49
+ observability_impact: "",
50
+ full_plan_md: "",
51
+ sequence: 0,
52
+ };
91
53
  }
92
54
  /**
93
55
  * Handle the complete_task operation end-to-end.
@@ -174,8 +136,9 @@ export async function handleCompleteTask(params, basePath) {
174
136
  // ── Filesystem operations (outside transaction) ─────────────────────────
175
137
  // If disk render fails, roll back the DB status so deriveState() and
176
138
  // verifyExpectedArtifact() stay consistent (both say "not done").
177
- // Render summary markdown
178
- const summaryMd = renderSummaryMarkdown(params);
139
+ // Render summary markdown via the single source of truth (#2720)
140
+ const taskRow = paramsToTaskRow(params, completedAt);
141
+ const summaryMd = renderSummaryContent(taskRow, params.sliceId, params.milestoneId, params.verificationEvidence);
179
142
  // Resolve and write summary to disk
180
143
  let summaryPath;
181
144
  const tasksDir = resolveTasksDir(basePath, params.milestoneId, params.sliceId);
@@ -1,7 +1,7 @@
1
1
  import { clearParseCache } from "../files.js";
2
2
  import { isClosedStatus } from "../status-guards.js";
3
3
  import { isNonEmptyString, validateStringArray } from "../validation.js";
4
- import { transaction, getMilestone, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
4
+ import { transaction, getMilestone, getMilestoneSlices, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
5
5
  import { invalidateStateCache } from "../state.js";
6
6
  import { renderRoadmapFromDb } from "../markdown-renderer.js";
7
7
  import { renderAllProjections } from "../workflow-projections.js";
@@ -146,6 +146,16 @@ export async function handlePlanMilestone(rawParams, basePath) {
146
146
  guardError = `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
147
147
  return;
148
148
  }
149
+ // Guard: refuse to re-plan a milestone that has completed slices (#2960).
150
+ // INSERT OR IGNORE on slices won't overwrite existing rows, but a full
151
+ // re-plan after worktree recreation or DB resync can create new slice rows
152
+ // that shadow completed work. Block early when any slice is already done.
153
+ const existingSlices = getMilestoneSlices(params.milestoneId);
154
+ const completedSlices = existingSlices.filter(s => isClosedStatus(s.status));
155
+ if (completedSlices.length > 0) {
156
+ guardError = `cannot re-plan milestone ${params.milestoneId}: ${completedSlices.length} slice(s) already completed (${completedSlices.map(s => s.id).join(", ")}). Use gsd_reassess_roadmap to modify the roadmap.`;
157
+ return;
158
+ }
149
159
  // Validate depends_on: all dependencies must exist and be complete
150
160
  if (params.dependsOn && params.dependsOn.length > 0) {
151
161
  for (const depId of params.dependsOn) {
@@ -178,7 +188,7 @@ export async function handlePlanMilestone(rawParams, basePath) {
178
188
  definitionOfDone: params.definitionOfDone,
179
189
  requirementCoverage: params.requirementCoverage,
180
190
  boundaryMapMarkdown: params.boundaryMapMarkdown,
181
- });
191
+ }, params.title);
182
192
  for (const slice of params.slices) {
183
193
  insertSlice({
184
194
  id: slice.sliceId,
@@ -1,8 +1,9 @@
1
1
  import { join } from "node:path";
2
+ import { existsSync, unlinkSync } from "node:fs";
2
3
  import { clearParseCache } from "../files.js";
3
4
  import { isClosedStatus } from "../status-guards.js";
4
5
  import { isNonEmptyString } from "../validation.js";
5
- import { transaction, getMilestone, getMilestoneSlices, getSlice, insertSlice, updateSliceFields, insertAssessment, deleteSlice, } from "../gsd-db.js";
6
+ import { transaction, getMilestone, getMilestoneSlices, getSlice, insertSlice, updateSliceFields, insertAssessment, deleteAssessmentByScope, deleteSlice, } from "../gsd-db.js";
6
7
  import { invalidateStateCache } from "../state.js";
7
8
  import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.js";
8
9
  import { renderAllProjections } from "../workflow-projections.js";
@@ -143,6 +144,18 @@ export async function handleReassessRoadmap(rawParams, basePath) {
143
144
  for (const removedId of params.sliceChanges.removed) {
144
145
  deleteSlice(params.milestoneId, removedId);
145
146
  }
147
+ // ── Invalidate stale milestone validation (#2957) ──────────────
148
+ // When roadmap structure changes (slices added/modified/removed),
149
+ // any prior milestone-validation verdict is stale. Delete the DB
150
+ // row so deriveState() returns phase: 'validating-milestone' once
151
+ // the new slices complete, rather than advancing directly to
152
+ // 'completing-milestone' with a stale needs-remediation verdict.
153
+ const hasStructuralChanges = params.sliceChanges.added.length > 0 ||
154
+ params.sliceChanges.modified.length > 0 ||
155
+ params.sliceChanges.removed.length > 0;
156
+ if (hasStructuralChanges) {
157
+ deleteAssessmentByScope(params.milestoneId, "milestone-validation");
158
+ }
146
159
  });
147
160
  }
148
161
  catch (err) {
@@ -159,6 +172,21 @@ export async function handleReassessRoadmap(rawParams, basePath) {
159
172
  assessment: params.assessment,
160
173
  completedSliceId: params.completedSliceId,
161
174
  });
175
+ // ── Remove stale VALIDATION file from disk (#2957) ────────────
176
+ const hasStructuralChanges = params.sliceChanges.added.length > 0 ||
177
+ params.sliceChanges.modified.length > 0 ||
178
+ params.sliceChanges.removed.length > 0;
179
+ if (hasStructuralChanges) {
180
+ const validationFile = join(basePath, ".gsd", "milestones", params.milestoneId, `${params.milestoneId}-VALIDATION.md`);
181
+ try {
182
+ if (existsSync(validationFile))
183
+ unlinkSync(validationFile);
184
+ }
185
+ catch {
186
+ // Best-effort: DB row is already deleted, so state derivation
187
+ // will not see the file-based verdict as authoritative.
188
+ }
189
+ }
162
190
  // ── Invalidate caches ─────────────────────────────────────────
163
191
  invalidateStateCache();
164
192
  clearParseCache();
@@ -1,15 +1,20 @@
1
1
  /**
2
2
  * validate-milestone handler — the core operation behind gsd_validate_milestone.
3
3
  *
4
- * Persists milestone validation results to the assessments table,
5
- * renders VALIDATION.md to disk, and invalidates caches.
4
+ * Persists milestone validation results to the assessments table and
5
+ * quality_gates table, renders VALIDATION.md to disk, and invalidates caches.
6
+ *
7
+ * #2945 Bug 4: Previously only wrote to assessments — quality_gates records
8
+ * were never persisted, causing M002+ milestones to have zero gate records
9
+ * despite passing validation.
6
10
  */
7
11
  import { join } from "node:path";
8
- import { transaction, insertAssessment, deleteAssessmentByScope, } from "../gsd-db.js";
12
+ import { transaction, insertAssessment, deleteAssessmentByScope, getMilestoneSlices, } from "../gsd-db.js";
9
13
  import { resolveMilestonePath, clearPathCache } from "../paths.js";
10
14
  import { saveFile, clearParseCache } from "../files.js";
11
15
  import { invalidateStateCache } from "../state.js";
12
16
  import { VALIDATION_VERDICTS, isValidMilestoneVerdict } from "../verdict-parser.js";
17
+ import { insertMilestoneValidationGates } from "../milestone-validation-gates.js";
13
18
  function renderValidationMarkdown(params) {
14
19
  let md = `---
15
20
  verdict: ${params.verdict}
@@ -77,6 +82,12 @@ export async function handleValidateMilestone(params, basePath) {
77
82
  scope: 'milestone-validation',
78
83
  fullContent: validationMd,
79
84
  });
85
+ // #2945 Bug 4: persist quality_gates records alongside the assessment.
86
+ // Previously only the assessment was written, leaving M002+ milestones
87
+ // with zero quality_gate records despite passing validation.
88
+ const slices = getMilestoneSlices(params.milestoneId);
89
+ const sliceId = slices.length > 0 ? slices[0].id : "_milestone";
90
+ insertMilestoneValidationGates(params.milestoneId, sliceId, params.verdict, validatedAt);
80
91
  });
81
92
  // ── Filesystem render (outside transaction) ────────────────────────────
82
93
  // If disk render fails, roll back the DB row so state stays consistent.
@@ -14,7 +14,7 @@ import { join } from "node:path";
14
14
  import { createRequire } from "node:module";
15
15
  import { gsdRoot, milestonesDir } from "./paths.js";
16
16
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
17
- import { loadAllCaptures, loadActionableCaptures, markCaptureExecuted, } from "./captures.js";
17
+ import { loadAllCaptures, loadActionableCaptures, markCaptureExecuted, stampCaptureMilestone, } from "./captures.js";
18
18
  // ─── Resolution Executors ─────────────────────────────────────────────────────
19
19
  /**
20
20
  * Inject a new task into the current slice plan.
@@ -209,11 +209,15 @@ export function buildQuickTaskPrompt(capture) {
209
209
  ``,
210
210
  `## Instructions`,
211
211
  ``,
212
- `1. Execute this task as a small, self-contained change.`,
213
- `2. Do NOT modify any \`.gsd/\` plan files — this is a one-off, not a planned task.`,
214
- `3. Commit your changes with a descriptive message.`,
215
- `4. Keep changes minimal and focused on the capture text.`,
216
- `5. When done, say: "Quick task complete."`,
212
+ `1. **Verify the issue still exists.** Before making any changes, inspect the`,
213
+ ` relevant code to confirm the problem described above is actually present in`,
214
+ ` the current codebase. If the issue has already been fixed (e.g., by planned`,
215
+ ` milestone work), report "Already resolved no changes needed." and stop.`,
216
+ `2. Execute this task as a small, self-contained change.`,
217
+ `3. Do NOT modify any \`.gsd/\` plan files — this is a one-off, not a planned task.`,
218
+ `4. Commit your changes with a descriptive message.`,
219
+ `5. Keep changes minimal and focused on the capture text.`,
220
+ `6. When done, say: "Quick task complete."`,
217
221
  ].join("\n");
218
222
  }
219
223
  /**
@@ -238,7 +242,18 @@ export function executeTriageResolutions(basePath, mid, sid) {
238
242
  quickTasks: [],
239
243
  actions: [],
240
244
  };
241
- const actionable = loadActionableCaptures(basePath);
245
+ const actionable = loadActionableCaptures(basePath, mid || undefined);
246
+ // Reconciliation: stamp actionable captures that are missing the Milestone field
247
+ // with the current milestone ID. This covers captures resolved by the triage LLM
248
+ // before the prompt included the Milestone instruction, and acts as a safety net
249
+ // when the LLM omits the field (#2872).
250
+ if (mid) {
251
+ for (const capture of actionable) {
252
+ if (!capture.resolvedInMilestone) {
253
+ stampCaptureMilestone(basePath, capture.id, mid);
254
+ }
255
+ }
256
+ }
242
257
  // Also process deferred captures that target milestone IDs — create
243
258
  // milestone directories so deriveState() discovers them.
244
259
  const deferred = loadAllCaptures(basePath).filter(c => c.status === "resolved" && !c.executed && c.classification === "defer");
@@ -3,7 +3,7 @@
3
3
  // handleUndoTask: Reset a single task's DB status to "pending" and re-render markdown.
4
4
  // handleResetSlice: Reset a slice and all its tasks, re-rendering plan + roadmap.
5
5
  import { existsSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
6
- import { join } from "node:path";
6
+ import { join, basename } from "node:path";
7
7
  import { nativeRevertCommit, nativeRevertAbort } from "./native-git-bridge.js";
8
8
  import { parseUnitId } from "./unit-id.js";
9
9
  import { deriveState } from "./state.js";
@@ -124,7 +124,7 @@ export async function handleUndo(args, ctx, _pi, basePath) {
124
124
  results.push(` Review with 'git diff --cached' then 'git commit' or 'git reset HEAD'`);
125
125
  }
126
126
  ctx.ui.notify(results.join("\n"), "success");
127
- sendDesktopNotification("GSD", `Undone: ${unitType} (${unitId})`, "info", "complete");
127
+ sendDesktopNotification("GSD", `Undone: ${unitType} (${unitId})`, "info", "complete", basename(basePath));
128
128
  }
129
129
  // ─── Targeted State Reset ────────────────────────────────────────────────────
130
130
  /**
@@ -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.