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
@@ -5,7 +5,7 @@
5
5
 
6
6
  import type { ExtensionCommandContext, ExtensionAPI } from "@gsd/pi-coding-agent";
7
7
  import { existsSync, readFileSync, writeFileSync, unlinkSync, readdirSync } from "node:fs";
8
- import { join } from "node:path";
8
+ import { join, basename } from "node:path";
9
9
  import { nativeRevertCommit, nativeRevertAbort } from "./native-git-bridge.js";
10
10
  import { parseUnitId } from "./unit-id.js";
11
11
  import { deriveState } from "./state.js";
@@ -133,7 +133,7 @@ export async function handleUndo(args: string, ctx: ExtensionCommandContext, _pi
133
133
  }
134
134
 
135
135
  ctx.ui.notify(results.join("\n"), "success");
136
- sendDesktopNotification("GSD", `Undone: ${unitType} (${unitId})`, "info", "complete");
136
+ sendDesktopNotification("GSD", `Undone: ${unitType} (${unitId})`, "info", "complete", basename(basePath));
137
137
  }
138
138
 
139
139
  // ─── Targeted State Reset ────────────────────────────────────────────────────
@@ -3,18 +3,20 @@
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
14
 
15
- import { existsSync, readFileSync, mkdirSync } from "node:fs";
15
+ import { createRequire } from "node:module";
16
+ import { mkdirSync } from "node:fs";
16
17
  import { join } from "node:path";
17
- import { atomicWriteSync } from "./atomic-write.js";
18
+
19
+ const _require = createRequire(import.meta.url);
18
20
 
19
21
  // ─── Types ───────────────────────────────────────────────────────────────
20
22
 
@@ -23,7 +25,133 @@ export interface UnitClaim {
23
25
  claimed_at: string;
24
26
  }
25
27
 
26
- type ClaimsMap = Record<string, UnitClaim>;
28
+ // ─── SQLite Provider (mirrors gsd-db.ts pattern) ─────────────────────────
29
+
30
+ interface StmtLike {
31
+ run(...params: unknown[]): unknown;
32
+ get(...params: unknown[]): Record<string, unknown> | undefined;
33
+ }
34
+
35
+ interface DbLike {
36
+ exec(sql: string): void;
37
+ prepare(sql: string): StmtLike;
38
+ close(): void;
39
+ }
40
+
41
+ type ProviderName = "node:sqlite" | "better-sqlite3";
42
+
43
+ let providerName: ProviderName | null = null;
44
+ let providerModule: unknown = null;
45
+ let loadAttempted = false;
46
+
47
+ function suppressSqliteWarning(): void {
48
+ const origEmit = process.emit;
49
+ // @ts-expect-error overriding process.emit for warning filter
50
+ process.emit = function (event: string, ...args: unknown[]): boolean {
51
+ if (
52
+ event === "warning" &&
53
+ args[0] &&
54
+ typeof args[0] === "object" &&
55
+ "name" in args[0] &&
56
+ (args[0] as { name: string }).name === "ExperimentalWarning" &&
57
+ "message" in args[0] &&
58
+ typeof (args[0] as { message: string }).message === "string" &&
59
+ (args[0] as { message: string }).message.includes("SQLite")
60
+ ) {
61
+ return false;
62
+ }
63
+ return origEmit.apply(process, [event, ...args] as Parameters<typeof process.emit>) as unknown as boolean;
64
+ };
65
+ }
66
+
67
+ function loadProvider(): void {
68
+ if (loadAttempted) return;
69
+ loadAttempted = true;
70
+
71
+ try {
72
+ suppressSqliteWarning();
73
+ const mod = _require("node:sqlite");
74
+ if (mod.DatabaseSync) {
75
+ providerModule = mod;
76
+ providerName = "node:sqlite";
77
+ return;
78
+ }
79
+ } catch {
80
+ // unavailable
81
+ }
82
+
83
+ try {
84
+ const mod = _require("better-sqlite3");
85
+ if (typeof mod === "function" || (mod && mod.default)) {
86
+ providerModule = mod.default || mod;
87
+ providerName = "better-sqlite3";
88
+ return;
89
+ }
90
+ } catch {
91
+ // unavailable
92
+ }
93
+ }
94
+
95
+ function normalizeRow(row: unknown): Record<string, unknown> | undefined {
96
+ if (row == null) return undefined;
97
+ if (Object.getPrototypeOf(row) === null) {
98
+ return { ...(row as Record<string, unknown>) };
99
+ }
100
+ return row as Record<string, unknown>;
101
+ }
102
+
103
+ function openRawDb(path: string): unknown {
104
+ loadProvider();
105
+ if (!providerModule || !providerName) return null;
106
+
107
+ if (providerName === "node:sqlite") {
108
+ const { DatabaseSync } = providerModule as {
109
+ DatabaseSync: new (path: string) => unknown;
110
+ };
111
+ return new DatabaseSync(path);
112
+ }
113
+
114
+ const Database = providerModule as new (path: string) => unknown;
115
+ return new Database(path);
116
+ }
117
+
118
+ function wrapDb(rawDb: unknown): DbLike {
119
+ const db = rawDb as {
120
+ exec(sql: string): void;
121
+ prepare(sql: string): {
122
+ run(...args: unknown[]): unknown;
123
+ get(...args: unknown[]): unknown;
124
+ };
125
+ close(): void;
126
+ };
127
+ return {
128
+ exec(sql: string): void { db.exec(sql); },
129
+ prepare(sql: string): StmtLike {
130
+ const raw = db.prepare(sql);
131
+ return {
132
+ run(...params: unknown[]): unknown { return raw.run(...params); },
133
+ get(...params: unknown[]): Record<string, unknown> | undefined {
134
+ return normalizeRow(raw.get(...params));
135
+ },
136
+ };
137
+ },
138
+ close(): void { db.close(); },
139
+ };
140
+ }
141
+
142
+ // ─── Per-basePath DB pool ────────────────────────────────────────────────
143
+
144
+ const dbPool = new Map<string, DbLike>();
145
+
146
+ function claimsDbPath(basePath: string): string {
147
+ return join(basePath, ".gsd", "unit-claims.db");
148
+ }
149
+
150
+ function getDb(basePath: string): DbLike | null {
151
+ const existing = dbPool.get(basePath);
152
+ if (existing) return existing;
153
+ return null;
154
+ }
27
155
 
28
156
  // ─── Key Builders ────────────────────────────────────────────────────────
29
157
 
@@ -35,60 +163,103 @@ export function sliceUnitKey(milestoneId: string, sliceId: string): string {
35
163
  return `${milestoneId}/${sliceId}`;
36
164
  }
37
165
 
38
- // ─── File Path ───────────────────────────────────────────────────────────
166
+ // ─── Lifecycle ───────────────────────────────────────────────────────────
39
167
 
40
- function claimsPath(basePath: string): string {
41
- return join(basePath, ".gsd", "unit-claims.json");
42
- }
168
+ /**
169
+ * Initialize the ownership SQLite database for a given basePath.
170
+ * Creates .gsd/ directory and unit-claims.db with the unit_claims table.
171
+ * Safe to call multiple times (idempotent).
172
+ */
173
+ export function initOwnershipTable(basePath: string): void {
174
+ if (dbPool.has(basePath)) return;
43
175
 
44
- // ─── Read Claims ─────────────────────────────────────────────────────────
176
+ const dir = join(basePath, ".gsd");
177
+ mkdirSync(dir, { recursive: true });
45
178
 
46
- function readClaims(basePath: string): ClaimsMap | null {
47
- const path = claimsPath(basePath);
48
- if (!existsSync(path)) return null;
49
- try {
50
- return JSON.parse(readFileSync(path, "utf-8")) as ClaimsMap;
51
- } catch {
52
- return null;
179
+ const raw = openRawDb(claimsDbPath(basePath));
180
+ if (!raw) {
181
+ throw new Error("No SQLite provider available for unit-ownership");
53
182
  }
183
+
184
+ const db = wrapDb(raw);
185
+
186
+ db.exec("PRAGMA journal_mode=WAL");
187
+ db.exec("PRAGMA busy_timeout = 5000");
188
+ db.exec("PRAGMA synchronous = NORMAL");
189
+
190
+ db.exec(`
191
+ CREATE TABLE IF NOT EXISTS unit_claims (
192
+ unit_key TEXT PRIMARY KEY,
193
+ agent_name TEXT NOT NULL,
194
+ claimed_at TEXT NOT NULL
195
+ )
196
+ `);
197
+
198
+ dbPool.set(basePath, db);
199
+ }
200
+
201
+ /**
202
+ * Close the ownership database for a given basePath.
203
+ * Safe to call even if not initialized.
204
+ */
205
+ export function closeOwnershipDb(basePath: string): void {
206
+ const db = dbPool.get(basePath);
207
+ if (!db) return;
208
+ try { db.close(); } catch { /* swallow */ }
209
+ dbPool.delete(basePath);
54
210
  }
55
211
 
56
212
  // ─── Public API ──────────────────────────────────────────────────────────
57
213
 
58
214
  /**
59
215
  * Claim a unit for an agent.
60
- * Overwrites any existing claim for this unit (last writer wins).
216
+ * Uses INSERT OR IGNORE for atomic first-writer-wins semantics.
217
+ * Returns true if the claim was acquired (or the same agent already owns it).
218
+ * Returns false if a different agent already owns the unit.
61
219
  */
62
- export function claimUnit(basePath: string, unitKey: string, agentName: string): void {
63
- const claims = readClaims(basePath) ?? {};
64
- claims[unitKey] = { agent: agentName, claimed_at: new Date().toISOString() };
65
- const dir = join(basePath, ".gsd");
66
- mkdirSync(dir, { recursive: true });
67
- atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
220
+ export function claimUnit(basePath: string, unitKey: string, agentName: string): boolean {
221
+ const db = getDb(basePath);
222
+ if (!db) {
223
+ // Auto-init if not already initialized (backward compat)
224
+ initOwnershipTable(basePath);
225
+ return claimUnit(basePath, unitKey, agentName);
226
+ }
227
+
228
+ // INSERT OR IGNORE: if the row already exists, this is a no-op.
229
+ // The PRIMARY KEY constraint on unit_key prevents duplicate claims.
230
+ db.prepare(
231
+ "INSERT OR IGNORE INTO unit_claims (unit_key, agent_name, claimed_at) VALUES (?, ?, ?)",
232
+ ).run(unitKey, agentName, new Date().toISOString());
233
+
234
+ // Check who owns it now
235
+ const row = db.prepare("SELECT agent_name FROM unit_claims WHERE unit_key = ?").get(unitKey);
236
+ const owner = row?.agent_name as string | undefined;
237
+
238
+ return owner === agentName;
68
239
  }
69
240
 
70
241
  /**
71
- * Release a unit claim (remove it from the claims map).
242
+ * Release a unit claim (remove it from the claims table).
72
243
  */
73
244
  export function releaseUnit(basePath: string, unitKey: string): void {
74
- const claims = readClaims(basePath);
75
- if (!claims || !(unitKey in claims)) return;
76
- delete claims[unitKey];
77
- atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
245
+ const db = getDb(basePath);
246
+ if (!db) return;
247
+ db.prepare("DELETE FROM unit_claims WHERE unit_key = ?").run(unitKey);
78
248
  }
79
249
 
80
250
  /**
81
- * Get the current owner of a unit, or null if unclaimed / no claims file.
251
+ * Get the current owner of a unit, or null if unclaimed.
82
252
  */
83
253
  export function getOwner(basePath: string, unitKey: string): string | null {
84
- const claims = readClaims(basePath);
85
- if (!claims) return null;
86
- return claims[unitKey]?.agent ?? null;
254
+ const db = getDb(basePath);
255
+ if (!db) return null;
256
+ const row = db.prepare("SELECT agent_name FROM unit_claims WHERE unit_key = ?").get(unitKey);
257
+ return (row?.agent_name as string) ?? null;
87
258
  }
88
259
 
89
260
  /**
90
261
  * Check if an actor is authorized to operate on a unit.
91
- * Returns null if ownership passes (or is unclaimed / no file).
262
+ * Returns null if ownership passes (or is unclaimed).
92
263
  * Returns an error string if a different agent owns the unit.
93
264
  */
94
265
  export function checkOwnership(
@@ -98,7 +269,7 @@ export function checkOwnership(
98
269
  ): string | null {
99
270
  if (!actorName) return null; // no actor identity provided — opt-in, so allow
100
271
  const owner = getOwner(basePath, unitKey);
101
- if (owner === null) return null; // unit unclaimed or no claims file
272
+ if (owner === null) return null; // unit unclaimed
102
273
  if (owner === actorName) return null; // actor is the owner
103
274
  return `Unit ${unitKey} is owned by ${owner}, not ${actorName}`;
104
275
  }
@@ -20,13 +20,28 @@ import type { UatType } from "./files.js";
20
20
  * Returns `undefined` when frontmatter is absent or has no `verdict` field.
21
21
  */
22
22
  export function extractVerdict(content: string): string | undefined {
23
+ // Primary: YAML frontmatter verdict (canonical format)
23
24
  const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
24
- if (!fmMatch) return undefined;
25
- const verdictMatch = fmMatch[1].match(/verdict:\s*([\w-]+)/i);
26
- if (!verdictMatch) return undefined;
27
- let v = verdictMatch[1].toLowerCase();
28
- if (v === "passed") v = "pass";
29
- return v;
25
+ if (fmMatch) {
26
+ const verdictMatch = fmMatch[1].match(/verdict:\s*([\w-]+)/i);
27
+ if (verdictMatch) {
28
+ let v = verdictMatch[1].toLowerCase();
29
+ if (v === "passed") v = "pass";
30
+ return v;
31
+ }
32
+ return undefined;
33
+ }
34
+
35
+ // Fallback: detect verdict in markdown body (LLM manual writes, #2960).
36
+ // Matches patterns like: **Verdict:** PASS, **Verdict:** ✅ PASS, **Verdict** needs-remediation
37
+ const bodyMatch = content.match(/\*\*Verdict:?\*\*\s*(?:✅\s*)?(\w[\w-]*)/i);
38
+ if (bodyMatch) {
39
+ let v = bodyMatch[1].toLowerCase();
40
+ if (v === "passed") v = "pass";
41
+ return v;
42
+ }
43
+
44
+ return undefined;
30
45
  }
31
46
 
32
47
  /**
@@ -31,7 +31,9 @@ export type LogComponent =
31
31
  | "state" // deriveState fallback/degradation
32
32
  | "tool" // Tool handler errors
33
33
  | "compaction" // Event compaction
34
- | "reconcile"; // Worktree reconciliation
34
+ | "reconcile" // Worktree reconciliation
35
+ | "db" // Database operations (gsd-db)
36
+ | "dispatch"; // Auto-dispatch rule evaluation
35
37
 
36
38
  export interface LogEntry {
37
39
  ts: string;
@@ -42,6 +42,23 @@ function requireDb() {
42
42
  return db;
43
43
  }
44
44
 
45
+ /**
46
+ * Coerce a raw DB value to a number, returning `fallback` for
47
+ * null/undefined/non-numeric strings (e.g. "-", "N/A", "").
48
+ * SQLite can store TEXT in INTEGER columns after migrations or manual inserts.
49
+ */
50
+ export function toNumeric(value: unknown, fallback: number | null = null): number | null {
51
+ if (value === null || value === undefined) return fallback;
52
+ if (typeof value === "number") return Number.isFinite(value) ? value : fallback;
53
+ if (typeof value === "string") {
54
+ const trimmed = value.trim();
55
+ if (trimmed === "" || trimmed === "-" || trimmed === "N/A") return fallback;
56
+ const n = Number(trimmed);
57
+ return Number.isFinite(n) ? n : fallback;
58
+ }
59
+ return fallback;
60
+ }
61
+
45
62
  // ─── snapshotState ───────────────────────────────────────────────────────
46
63
 
47
64
  /**
@@ -99,7 +116,7 @@ export function snapshotState(): StateManifest {
99
116
  proof_level: (r["proof_level"] as string) ?? "",
100
117
  integration_closure: (r["integration_closure"] as string) ?? "",
101
118
  observability_impact: (r["observability_impact"] as string) ?? "",
102
- sequence: (r["sequence"] as number) ?? 0,
119
+ sequence: toNumeric(r["sequence"], 0) as number,
103
120
  replan_triggered_at: (r["replan_triggered_at"] as string) ?? null,
104
121
  }));
105
122
 
@@ -129,12 +146,12 @@ export function snapshotState(): StateManifest {
129
146
  expected_output: JSON.parse((r["expected_output"] as string) || "[]"),
130
147
  observability_impact: (r["observability_impact"] as string) ?? "",
131
148
  full_plan_md: (r["full_plan_md"] as string) ?? "",
132
- sequence: (r["sequence"] as number) ?? 0,
149
+ sequence: toNumeric(r["sequence"], 0) as number,
133
150
  }));
134
151
 
135
152
  const rawDecisions = db.prepare("SELECT * FROM decisions ORDER BY seq").all() as Record<string, unknown>[];
136
153
  const decisions: Decision[] = rawDecisions.map((r) => ({
137
- seq: r["seq"] as number,
154
+ seq: toNumeric(r["seq"], 0) as number,
138
155
  id: r["id"] as string,
139
156
  when_context: (r["when_context"] as string) ?? "",
140
157
  scope: (r["scope"] as string) ?? "",
@@ -153,9 +170,9 @@ export function snapshotState(): StateManifest {
153
170
  slice_id: r["slice_id"] as string,
154
171
  milestone_id: r["milestone_id"] as string,
155
172
  command: r["command"] as string,
156
- exit_code: (r["exit_code"] as number) ?? null,
173
+ exit_code: toNumeric(r["exit_code"]),
157
174
  verdict: (r["verdict"] as string) ?? "",
158
- duration_ms: (r["duration_ms"] as number) ?? null,
175
+ duration_ms: toNumeric(r["duration_ms"]),
159
176
  created_at: r["created_at"] as string,
160
177
  }));
161
178
 
@@ -9,8 +9,9 @@ import {
9
9
  getMilestone,
10
10
  getMilestoneSlices,
11
11
  getSliceTasks,
12
+ getVerificationEvidence,
12
13
  } from "./gsd-db.js";
13
- import type { MilestoneRow, SliceRow, TaskRow } from "./gsd-db.js";
14
+ import type { MilestoneRow, SliceRow, TaskRow, VerificationEvidenceRow } from "./gsd-db.js";
14
15
  import { atomicWriteSync } from "./atomic-write.js";
15
16
  import { join } from "node:path";
16
17
  import { mkdirSync, existsSync } from "node:fs";
@@ -29,8 +30,10 @@ export function renderPlanContent(sliceRow: SliceRow, taskRows: TaskRow[]): stri
29
30
 
30
31
  lines.push(`# ${sliceRow.id}: ${sliceRow.title}`);
31
32
  lines.push("");
32
- lines.push(`**Goal:** ${sliceRow.goal || sliceRow.full_summary_md || "TBD"}`);
33
- lines.push(`**Demo:** After this: ${sliceRow.demo || sliceRow.full_uat_md || "TBD"}`);
33
+ // #2945: never use full_summary_md/full_uat_md as display fallbacks —
34
+ // they contain multi-line rendered markdown that corrupts single-line fields.
35
+ lines.push(`**Goal:** ${sliceRow.goal || "TBD"}`);
36
+ lines.push(`**Demo:** After this: ${sliceRow.demo || "TBD"}`);
34
37
  lines.push("");
35
38
  lines.push("## Tasks");
36
39
 
@@ -113,7 +116,10 @@ export function renderRoadmapContent(milestoneRow: MilestoneRow, sliceRows: Slic
113
116
  }
114
117
 
115
118
  const risk = (slice.risk || "low").toLowerCase();
116
- const demo = slice.demo || slice.full_uat_md || "TBD";
119
+ // #2945 Bug 1: never use full_uat_md as a table cell fallback — it contains
120
+ // multi-line UAT content (preconditions, steps, expected results) that
121
+ // corrupts the markdown table and makes subsequent slices invisible.
122
+ const demo = slice.demo || "TBD";
117
123
 
118
124
  lines.push(`| ${slice.id} | ${slice.title} | ${risk} | ${depends} | ${done} | ${demo} |`);
119
125
  }
@@ -142,71 +148,93 @@ export function renderRoadmapProjection(basePath: string, milestoneId: string):
142
148
 
143
149
  /**
144
150
  * Render SUMMARY.md content from a task row.
145
- * Pure functionno side effects.
151
+ * Single source of truth for summary rendering used both at completion
152
+ * time and at projection regeneration time (#2720).
153
+ *
154
+ * @param evidence - Optional verification evidence rows. When called from
155
+ * complete-task, these are passed directly. When called from projection
156
+ * regeneration, they are queried from the DB by renderSummaryProjection.
146
157
  */
147
- export function renderSummaryContent(taskRow: TaskRow, sliceId: string, milestoneId: string): string {
148
- const lines: string[] = [];
149
-
150
- // Frontmatter
151
- lines.push("---");
152
- lines.push(`id: ${taskRow.id}`);
153
- lines.push(`parent: ${sliceId}`);
154
- lines.push(`milestone: ${milestoneId}`);
155
- lines.push("provides: []");
156
- lines.push("requires: []");
157
- lines.push("affects: []");
158
-
159
- // key_files is already parsed to string[]
160
- if (taskRow.key_files && taskRow.key_files.length > 0) {
161
- lines.push(`key_files: [${taskRow.key_files.map(f => `"${f}"`).join(", ")}]`);
158
+ export function renderSummaryContent(
159
+ taskRow: TaskRow,
160
+ sliceId: string,
161
+ milestoneId: string,
162
+ evidence?: Array<{ command: string; exitCode?: number; exit_code?: number; verdict: string; durationMs?: number; duration_ms?: number }>,
163
+ ): string {
164
+ // ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
165
+ const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
166
+ ? taskRow.key_files.map(f => ` - ${f}`).join("\n")
167
+ : " - (none)";
168
+ const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
169
+ ? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
170
+ : " - (none)";
171
+
172
+ // Derive verification_result from evidence if available
173
+ const evidenceList = evidence ?? [];
174
+ const allPassed = evidenceList.length > 0 &&
175
+ evidenceList.every(e => {
176
+ const code = e.exitCode ?? e.exit_code ?? -1;
177
+ return code === 0 || e.verdict.includes("\u2705") || e.verdict.toLowerCase().includes("pass");
178
+ });
179
+ const verificationResult = taskRow.verification_result
180
+ ? (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"))
181
+ : (allPassed ? "passed" : (evidenceList.length === 0 ? "untested" : "mixed"));
182
+
183
+ // Build verification evidence table
184
+ let evidenceTable = "| # | Command | Exit Code | Verdict | Duration |\n|---|---------|-----------|---------|----------|\n";
185
+ if (evidenceList.length > 0) {
186
+ evidenceList.forEach((e, i) => {
187
+ const code = e.exitCode ?? e.exit_code ?? 0;
188
+ const dur = e.durationMs ?? e.duration_ms ?? 0;
189
+ evidenceTable += `| ${i + 1} | \`${e.command}\` | ${code} | ${e.verdict} | ${dur}ms |\n`;
190
+ });
162
191
  } else {
163
- lines.push("key_files: []");
192
+ evidenceTable += "| \u2014 | No verification commands discovered | \u2014 | \u2014 | \u2014 |\n";
164
193
  }
165
194
 
166
- // key_decisions is already parsed to string[]
167
- if (taskRow.key_decisions && taskRow.key_decisions.length > 0) {
168
- lines.push(`key_decisions: [${taskRow.key_decisions.map(d => `"${d}"`).join(", ")}]`);
169
- } else {
170
- lines.push("key_decisions: []");
171
- }
195
+ const title = taskRow.one_liner || taskRow.title || taskRow.id;
172
196
 
173
- lines.push("patterns_established: []");
174
- lines.push("drill_down_paths: []");
175
- lines.push("observability_surfaces: []");
176
- lines.push(`duration: "${taskRow.duration || ""}"`);
177
- lines.push(`verification_result: "${taskRow.verification_result || ""}"`);
178
- lines.push(`completed_at: ${taskRow.completed_at || ""}`);
179
- lines.push(`blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}`);
180
- lines.push("---");
181
- lines.push("");
182
- lines.push(`# ${taskRow.id}: ${taskRow.title}`);
183
- lines.push("");
197
+ return `---
198
+ id: ${taskRow.id}
199
+ parent: ${sliceId}
200
+ milestone: ${milestoneId}
201
+ key_files:
202
+ ${keyFilesYaml}
203
+ key_decisions:
204
+ ${keyDecisionsYaml}
205
+ duration: ${taskRow.duration || ""}
206
+ verification_result: ${verificationResult}
207
+ completed_at: ${taskRow.completed_at || ""}
208
+ blocker_discovered: ${taskRow.blocker_discovered ? "true" : "false"}
209
+ ---
184
210
 
185
- // One-liner (if present)
186
- if (taskRow.one_liner) {
187
- lines.push(`> ${taskRow.one_liner}`);
188
- lines.push("");
189
- }
211
+ # ${taskRow.id}: ${title}
190
212
 
191
- lines.push("## What Happened");
192
- lines.push(taskRow.full_summary_md || taskRow.narrative || "No summary recorded.");
193
- lines.push("");
213
+ **${taskRow.one_liner || ""}**
194
214
 
195
- // Deviations (if present)
196
- if (taskRow.deviations) {
197
- lines.push("## Deviations");
198
- lines.push(taskRow.deviations);
199
- lines.push("");
200
- }
215
+ ## What Happened
201
216
 
202
- // Known issues (if present)
203
- if (taskRow.known_issues) {
204
- lines.push("## Known Issues");
205
- lines.push(taskRow.known_issues);
206
- lines.push("");
207
- }
217
+ ${taskRow.narrative || "No summary recorded."}
208
218
 
209
- return lines.join("\n");
219
+ ## Verification
220
+
221
+ ${taskRow.verification_result || "No verification recorded."}
222
+
223
+ ## Verification Evidence
224
+
225
+ ${evidenceTable}
226
+ ## Deviations
227
+
228
+ ${taskRow.deviations || "None."}
229
+
230
+ ## Known Issues
231
+
232
+ ${taskRow.known_issues || "None."}
233
+
234
+ ## Files Created/Modified
235
+
236
+ ${taskRow.key_files && taskRow.key_files.length > 0 ? taskRow.key_files.map(f => `- \`${f}\``).join("\n") : "None."}
237
+ `;
210
238
  }
211
239
 
212
240
  /**
@@ -218,7 +246,8 @@ export function renderSummaryProjection(basePath: string, milestoneId: string, s
218
246
  const taskRow = taskRows.find(t => t.id === taskId);
219
247
  if (!taskRow) return;
220
248
 
221
- const content = renderSummaryContent(taskRow, sliceId, milestoneId);
249
+ const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
250
+ const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
222
251
  const dir = join(basePath, ".gsd", "milestones", milestoneId, "slices", sliceId, "tasks");
223
252
  mkdirSync(dir, { recursive: true });
224
253
  atomicWriteSync(join(dir, `${taskId}-SUMMARY.md`), content);
@@ -235,14 +264,18 @@ export function renderStateContent(state: GSDState): string {
235
264
  const lines: string[] = [];
236
265
  lines.push("# GSD State", "");
237
266
 
238
- const activeMilestone = state.activeMilestone
239
- ? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
240
- : "None";
241
267
  const activeSlice = state.activeSlice
242
268
  ? `${state.activeSlice.id}: ${state.activeSlice.title}`
243
269
  : "None";
244
270
 
245
- lines.push(`**Active Milestone:** ${activeMilestone}`);
271
+ if (state.phase === 'complete' && state.lastCompletedMilestone) {
272
+ lines.push(`**Last Completed Milestone:** ${state.lastCompletedMilestone.id}: ${state.lastCompletedMilestone.title}`);
273
+ } else {
274
+ const activeMilestone = state.activeMilestone
275
+ ? `${state.activeMilestone.id}: ${state.activeMilestone.title}`
276
+ : "None";
277
+ lines.push(`**Active Milestone:** ${activeMilestone}`);
278
+ }
246
279
  lines.push(`**Active Slice:** ${activeSlice}`);
247
280
  lines.push(`**Phase:** ${state.phase}`);
248
281
  if (state.requirements) {