gsd-pi 2.58.0-dev.d63175c → 2.58.0-dev.e002a57

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 (777) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +60 -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 +199 -12
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  36. package/dist/resources/extensions/gsd/captures.js +56 -4
  37. package/dist/resources/extensions/gsd/codebase-generator.js +279 -0
  38. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  40. package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
  41. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
  42. package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
  43. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  44. package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
  45. package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
  46. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  47. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  48. package/dist/resources/extensions/gsd/doctor.js +3 -1
  49. package/dist/resources/extensions/gsd/error-classifier.js +12 -10
  50. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  51. package/dist/resources/extensions/gsd/forensics.js +123 -20
  52. package/dist/resources/extensions/gsd/git-service.js +105 -2
  53. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  54. package/dist/resources/extensions/gsd/gsd-db.js +36 -9
  55. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  56. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  57. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  58. package/dist/resources/extensions/gsd/index.js +1 -1
  59. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  60. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  61. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  62. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  63. package/dist/resources/extensions/gsd/model-router.js +35 -1
  64. package/dist/resources/extensions/gsd/native-git-bridge.js +39 -0
  65. package/dist/resources/extensions/gsd/notifications.js +16 -1
  66. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  67. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  68. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  69. package/dist/resources/extensions/gsd/paths.js +45 -0
  70. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  71. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  72. package/dist/resources/extensions/gsd/preferences.js +13 -16
  73. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  74. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  76. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  79. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  83. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  85. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  86. package/dist/resources/extensions/gsd/rethink.js +5 -0
  87. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  88. package/dist/resources/extensions/gsd/state.js +85 -27
  89. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  91. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  92. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  93. package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
  94. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  95. package/dist/resources/extensions/gsd/undo.js +2 -2
  96. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  97. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  98. package/dist/resources/extensions/gsd/watch/header-renderer.js +241 -0
  99. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  100. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  101. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  102. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  103. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  104. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  105. package/dist/resources/extensions/mcp-client/index.js +11 -7
  106. package/dist/resources/extensions/ollama/index.js +112 -0
  107. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  108. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  109. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  110. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  111. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  112. package/dist/resources/extensions/ollama/types.js +2 -0
  113. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  114. package/dist/resources/extensions/search-the-web/url-utils.js +17 -0
  115. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  116. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  117. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  118. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  119. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  120. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  121. package/dist/security-overrides.d.ts +11 -0
  122. package/dist/security-overrides.js +41 -0
  123. package/dist/startup-model-validation.d.ts +39 -0
  124. package/dist/startup-model-validation.js +50 -0
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  127. package/dist/web/standalone/.next/build-manifest.json +3 -3
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  130. package/dist/web/standalone/.next/required-server-files.json +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  133. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  149. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  210. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  212. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  213. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  216. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  217. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  218. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  219. package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
  220. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  221. package/dist/web/standalone/server.js +1 -1
  222. package/dist/web-mode.js +2 -1
  223. package/dist/welcome-screen.d.ts +1 -0
  224. package/dist/welcome-screen.js +32 -6
  225. package/package.json +2 -2
  226. package/packages/native/dist/ast/index.js +9 -5
  227. package/packages/native/dist/ast/types.js +2 -1
  228. package/packages/native/dist/clipboard/index.js +12 -7
  229. package/packages/native/dist/clipboard/types.js +2 -1
  230. package/packages/native/dist/diff/index.js +12 -7
  231. package/packages/native/dist/diff/types.js +2 -1
  232. package/packages/native/dist/fd/index.js +6 -3
  233. package/packages/native/dist/fd/types.js +2 -1
  234. package/packages/native/dist/glob/index.js +9 -5
  235. package/packages/native/dist/glob/types.js +2 -1
  236. package/packages/native/dist/grep/index.js +9 -5
  237. package/packages/native/dist/grep/types.js +2 -1
  238. package/packages/native/dist/gsd-parser/index.js +18 -11
  239. package/packages/native/dist/gsd-parser/types.js +2 -1
  240. package/packages/native/dist/highlight/index.js +12 -7
  241. package/packages/native/dist/highlight/types.js +2 -1
  242. package/packages/native/dist/html/index.js +6 -3
  243. package/packages/native/dist/html/types.js +2 -1
  244. package/packages/native/dist/image/index.js +10 -5
  245. package/packages/native/dist/image/types.js +7 -4
  246. package/packages/native/dist/index.js +70 -17
  247. package/packages/native/dist/json-parse/index.js +13 -8
  248. package/packages/native/dist/native.js +47 -10
  249. package/packages/native/dist/ps/index.js +15 -9
  250. package/packages/native/dist/ps/types.js +2 -1
  251. package/packages/native/dist/stream-process/index.js +12 -7
  252. package/packages/native/dist/text/index.js +24 -14
  253. package/packages/native/dist/text/types.js +5 -2
  254. package/packages/native/dist/truncate/index.js +12 -7
  255. package/packages/native/dist/ttsr/index.js +12 -7
  256. package/packages/native/dist/ttsr/types.js +2 -1
  257. package/packages/native/dist/xxhash/index.js +9 -5
  258. package/packages/native/package.json +19 -19
  259. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  260. package/packages/native/src/native.ts +9 -8
  261. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  262. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  263. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  264. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  265. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  266. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  267. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  268. package/packages/pi-agent-core/src/proxy.ts +1 -1
  269. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  270. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  271. package/packages/pi-ai/dist/index.d.ts +1 -0
  272. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  273. package/packages/pi-ai/dist/index.js +1 -0
  274. package/packages/pi-ai/dist/index.js.map +1 -1
  275. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  276. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  277. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  278. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  279. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  280. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  281. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  282. package/packages/pi-ai/dist/types.d.ts +3 -3
  283. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  284. package/packages/pi-ai/dist/types.js.map +1 -1
  285. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  286. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  287. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  288. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  289. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  290. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  291. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  292. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  293. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  294. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  295. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  296. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  297. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  298. package/packages/pi-ai/src/index.ts +1 -0
  299. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  300. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  301. package/packages/pi-ai/src/types.ts +3 -2
  302. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  303. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  304. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  305. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  306. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  308. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  310. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  312. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  314. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  315. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  316. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  317. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  319. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  324. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  325. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  327. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  329. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  330. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  331. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  332. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  333. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  335. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  337. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  339. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  341. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  343. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  345. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  347. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  348. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  351. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  352. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  353. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  355. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  358. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  360. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  361. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  364. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  366. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  367. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  368. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  369. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  370. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  371. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +8 -0
  373. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/resolve-config-value.js +23 -2
  375. package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +89 -2
  377. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  379. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  381. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  383. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  385. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  387. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  388. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  389. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  390. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts +2 -0
  391. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts.map +1 -0
  392. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js +83 -0
  393. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js.map +1 -0
  394. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -0
  395. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  396. package/packages/pi-coding-agent/dist/core/settings-manager.js +36 -3
  397. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  400. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  401. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  403. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  405. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  406. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  407. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  408. package/packages/pi-coding-agent/dist/index.d.ts +3 -2
  409. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  410. package/packages/pi-coding-agent/dist/index.js +2 -1
  411. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  412. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
  413. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
  418. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  420. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
  424. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
  426. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
  431. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
  433. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
  439. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  440. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
  441. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
  442. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
  443. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  445. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
  446. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  447. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  448. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
  449. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  450. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  451. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
  452. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
  453. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  454. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
  455. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  456. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
  457. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  458. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
  459. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  460. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
  461. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  462. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  463. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
  464. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  465. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
  466. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  467. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  468. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  469. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  470. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
  471. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  472. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  473. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
  474. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  475. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  476. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +19 -1
  477. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  478. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  479. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
  480. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  481. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
  482. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  483. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +27 -4
  484. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  485. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  486. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
  487. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  488. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  489. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  490. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  491. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  492. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  493. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  494. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  495. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  496. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  497. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  498. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  499. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  500. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  501. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  502. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  503. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  504. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  505. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  506. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  507. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  508. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  509. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  510. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  511. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  512. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +111 -1
  513. package/packages/pi-coding-agent/src/core/resolve-config-value.ts +26 -2
  514. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  515. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  516. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  517. package/packages/pi-coding-agent/src/core/settings-manager-security.test.ts +102 -0
  518. package/packages/pi-coding-agent/src/core/settings-manager.ts +44 -3
  519. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  520. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  521. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  522. package/packages/pi-coding-agent/src/index.ts +11 -0
  523. package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
  524. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
  525. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
  526. package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
  527. package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
  528. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
  529. package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
  530. package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
  531. package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
  532. package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
  533. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
  534. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
  535. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
  536. package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
  537. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
  538. package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
  539. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
  540. package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
  541. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
  542. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
  543. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
  544. package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
  545. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
  546. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
  547. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
  548. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
  549. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  550. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  551. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  552. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  553. package/packages/pi-tui/dist/terminal.js +9 -0
  554. package/packages/pi-tui/dist/terminal.js.map +1 -1
  555. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  556. package/packages/pi-tui/dist/tui.js +9 -0
  557. package/packages/pi-tui/dist/tui.js.map +1 -1
  558. package/packages/pi-tui/src/terminal.ts +14 -0
  559. package/packages/pi-tui/src/tui.ts +8 -0
  560. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  561. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  562. package/scripts/ensure-workspace-builds.cjs +45 -14
  563. package/src/resources/agents/researcher.md +1 -1
  564. package/src/resources/extensions/ask-user-questions.ts +21 -3
  565. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  566. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  567. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  568. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  569. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  570. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  571. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  572. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  573. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  574. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  575. package/src/resources/extensions/google-search/index.ts +2 -1
  576. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  577. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  578. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  579. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  580. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  581. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  582. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  583. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  584. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  585. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  586. package/src/resources/extensions/gsd/auto-worktree.ts +193 -9
  587. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  588. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
  589. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  590. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
  591. package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
  592. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  593. package/src/resources/extensions/gsd/captures.ts +63 -3
  594. package/src/resources/extensions/gsd/codebase-generator.ts +351 -0
  595. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  596. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  597. package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
  598. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
  599. package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
  600. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  601. package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
  602. package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
  603. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  604. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  605. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  606. package/src/resources/extensions/gsd/doctor.ts +3 -1
  607. package/src/resources/extensions/gsd/error-classifier.ts +13 -11
  608. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  609. package/src/resources/extensions/gsd/forensics.ts +144 -20
  610. package/src/resources/extensions/gsd/git-service.ts +119 -3
  611. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  612. package/src/resources/extensions/gsd/gsd-db.ts +43 -7
  613. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  614. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  615. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  616. package/src/resources/extensions/gsd/index.ts +1 -0
  617. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  618. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  619. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  620. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  621. package/src/resources/extensions/gsd/model-router.ts +35 -1
  622. package/src/resources/extensions/gsd/native-git-bridge.ts +41 -0
  623. package/src/resources/extensions/gsd/notifications.ts +16 -0
  624. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  625. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  626. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  627. package/src/resources/extensions/gsd/paths.ts +44 -0
  628. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  629. package/src/resources/extensions/gsd/preferences-types.ts +10 -1
  630. package/src/resources/extensions/gsd/preferences.ts +13 -15
  631. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  632. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  633. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  634. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  635. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  636. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  637. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  638. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  639. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  640. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  641. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  642. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  643. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  644. package/src/resources/extensions/gsd/rethink.ts +6 -0
  645. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  646. package/src/resources/extensions/gsd/state.ts +84 -32
  647. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +29 -0
  648. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  649. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  650. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  651. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  652. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +488 -0
  653. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  654. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  655. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  656. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +4 -4
  657. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  658. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  659. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  660. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  661. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  662. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  663. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  664. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  665. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  666. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  667. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  668. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  669. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  670. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  671. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  672. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  673. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  674. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  675. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  676. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  677. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  678. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  679. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +134 -0
  680. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  681. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  682. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +72 -0
  683. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -0
  684. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  685. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  686. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  687. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  688. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  689. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  690. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  691. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  692. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  693. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  694. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  695. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  696. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  697. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  698. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  699. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  700. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
  701. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  702. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  703. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  704. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  705. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  706. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  707. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  708. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  709. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  710. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  711. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  712. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  713. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  714. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  715. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  716. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  717. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  718. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +44 -0
  719. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  720. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  721. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  722. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  723. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  724. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
  725. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  726. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  727. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  728. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  729. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  730. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  731. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  732. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  733. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  734. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  735. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  736. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  737. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  738. package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
  739. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  740. package/src/resources/extensions/gsd/types.ts +4 -2
  741. package/src/resources/extensions/gsd/undo.ts +2 -2
  742. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  743. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  744. package/src/resources/extensions/gsd/watch/header-renderer.ts +275 -0
  745. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  746. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  747. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  748. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  749. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  750. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  751. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  752. package/src/resources/extensions/mcp-client/index.ts +13 -7
  753. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  754. package/src/resources/extensions/ollama/index.ts +130 -0
  755. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  756. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  757. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  758. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  759. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  760. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  761. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  762. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  763. package/src/resources/extensions/ollama/types.ts +130 -0
  764. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  765. package/src/resources/extensions/search-the-web/url-utils.ts +19 -0
  766. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  767. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  768. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  769. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  770. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  771. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  772. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  773. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
  774. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  775. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  776. /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_buildManifest.js +0 -0
  777. /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_ssgManifest.js +0 -0
@@ -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) {
@@ -1,19 +1,53 @@
1
1
  import { join } from "node:path";
2
2
  import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
3
+ import { logWarning, logError } from "./workflow-logger.js";
3
4
  import { readEvents, findForkPoint, appendEvent, getSessionId } from "./workflow-events.js";
4
5
  import type { WorkflowEvent } from "./workflow-events.js";
5
6
  import {
6
7
  transaction,
7
8
  updateTaskStatus,
8
9
  updateSliceStatus,
10
+ getSliceTasks,
9
11
  insertVerificationEvidence,
10
12
  upsertDecision,
11
13
  openDatabase,
12
14
  } from "./gsd-db.js";
15
+ import { isClosedStatus } from "./status-guards.js";
13
16
  import { writeManifest } from "./workflow-manifest.js";
14
17
  import { atomicWriteSync } from "./atomic-write.js";
15
18
  import { acquireSyncLock, releaseSyncLock } from "./sync-lock.js";
16
19
 
20
+ // ─── Replay Helpers ──────────────────────────────────────────────────────────
21
+
22
+ /**
23
+ * Replay a complete_slice event with task validation.
24
+ *
25
+ * #2945 Bug 2: The original replay blindly called updateSliceStatus("done")
26
+ * without checking whether all tasks in the slice are actually complete.
27
+ * During API overload or partial execution, a complete_slice event could
28
+ * be logged even when tasks were skipped, causing the milestone completion
29
+ * guard to see the slice as "done" and allow premature milestone completion.
30
+ *
31
+ * This function validates that every task in the slice has a closed status
32
+ * before marking the slice as done. If any task is still pending, the slice
33
+ * status is left unchanged.
34
+ */
35
+ export function replaySliceComplete(milestoneId: string, sliceId: string, ts: string): void {
36
+ const tasks = getSliceTasks(milestoneId, sliceId);
37
+ // If there are tasks and any are not closed, skip the status update
38
+ if (tasks.length > 0) {
39
+ const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
40
+ if (incompleteTasks.length > 0) {
41
+ process.stderr.write(
42
+ `[gsd] reconcile: skipping complete_slice replay for ${sliceId} — ` +
43
+ `${incompleteTasks.length} task(s) still pending\n`,
44
+ );
45
+ return;
46
+ }
47
+ }
48
+ updateSliceStatus(milestoneId, sliceId, "done", ts);
49
+ }
50
+
17
51
  // ─── Public Types ─────────────────────────────────────────────────────────────
18
52
 
19
53
  export interface ConflictEntry {
@@ -82,7 +116,8 @@ function replayEvents(events: WorkflowEvent[]): void {
82
116
  case "complete_slice": {
83
117
  const milestoneId = p["milestoneId"] as string;
84
118
  const sliceId = p["sliceId"] as string;
85
- updateSliceStatus(milestoneId, sliceId, "done", event.ts);
119
+ // #2945 Bug 2: validate tasks before marking slice done
120
+ replaySliceComplete(milestoneId, sliceId, event.ts);
86
121
  break;
87
122
  }
88
123
  case "plan_slice": {
@@ -274,9 +309,7 @@ export function reconcileWorktreeLogs(
274
309
  // Acquire advisory lock to prevent concurrent reconcile + append races
275
310
  const lock = acquireSyncLock(mainBasePath);
276
311
  if (!lock.acquired) {
277
- process.stderr.write(
278
- `[gsd] reconcile: could not acquire sync lock — another reconciliation may be in progress\n`,
279
- );
312
+ logWarning("reconcile", "could not acquire sync lock — another reconciliation may be in progress");
280
313
  return { autoMerged: 0, conflicts: [] };
281
314
  }
282
315
 
@@ -315,9 +348,7 @@ function _reconcileWorktreeLogsInner(
315
348
  if (conflicts.length > 0) {
316
349
  // D-04: atomic all-or-nothing — block entire merge
317
350
  writeConflictsFile(mainBasePath, conflicts, worktreeBasePath);
318
- process.stderr.write(
319
- `[gsd] reconcile: ${conflicts.length} conflict(s) detected — see ${join(mainBasePath, ".gsd", "CONFLICTS.md")}\n`,
320
- );
351
+ logError("reconcile", `${conflicts.length} conflict(s) detected`, { count: String(conflicts.length), path: join(mainBasePath, ".gsd", "CONFLICTS.md") });
321
352
  return { autoMerged: 0, conflicts };
322
353
  }
323
354
 
@@ -341,9 +372,7 @@ function _reconcileWorktreeLogsInner(
341
372
  try {
342
373
  writeManifest(mainBasePath);
343
374
  } catch (err) {
344
- process.stderr.write(
345
- `[gsd] reconcile: manifest write failed (non-fatal): ${(err as Error).message}\n`,
346
- );
375
+ logWarning("reconcile", "manifest write failed (non-fatal)", { error: (err as Error).message });
347
376
  }
348
377
 
349
378
  return { autoMerged: merged.length, conflicts: [] };
@@ -11,6 +11,7 @@ import {
11
11
  resolveTasksDir,
12
12
  } from "./paths.js";
13
13
  import { deriveState } from "./state.js";
14
+ import { extractVerdict } from "./verdict-parser.js";
14
15
  import { milestoneIdSort, findMilestoneIds } from "./guided-flow.js";
15
16
  import type { RiskLevel } from "./types.js";
16
17
  import { getSliceBranchName, detectWorktreeName } from "./worktree.js";
@@ -42,6 +43,10 @@ export interface WorkspaceMilestoneTarget {
42
43
  id: string;
43
44
  title: string;
44
45
  roadmapPath?: string;
46
+ /** Authoritative milestone lifecycle status from the GSD state registry. */
47
+ status?: "complete" | "active" | "pending" | "parked";
48
+ /** Milestone validation verdict, when validation has been performed. */
49
+ validationVerdict?: "pass" | "needs-attention" | "needs-remediation";
45
50
  slices: WorkspaceSliceTarget[];
46
51
  }
47
52
 
@@ -192,6 +197,31 @@ export async function indexWorkspace(basePath: string, opts: IndexWorkspaceOptio
192
197
  phase: state.phase,
193
198
  };
194
199
 
200
+ // Enrich milestones with authoritative status from state registry (#2807)
201
+ if (state.registry) {
202
+ const registryMap = new Map(state.registry.map(e => [e.id, e]));
203
+ for (const milestone of milestones) {
204
+ const entry = registryMap.get(milestone.id);
205
+ if (entry) {
206
+ milestone.status = entry.status;
207
+ }
208
+ }
209
+ }
210
+
211
+ // Populate validationVerdict from VALIDATION files (#2807)
212
+ for (const milestone of milestones) {
213
+ const validationPath = resolveMilestoneFile(basePath, milestone.id, "VALIDATION");
214
+ if (validationPath) {
215
+ const validationContent = await loadFile(validationPath);
216
+ if (validationContent) {
217
+ const verdict = extractVerdict(validationContent);
218
+ if (verdict === "pass" || verdict === "needs-attention" || verdict === "needs-remediation") {
219
+ milestone.validationVerdict = verdict;
220
+ }
221
+ }
222
+ }
223
+ }
224
+
195
225
  const scopes: WorkspaceScopeTarget[] = [{ scope: "project", label: "project", kind: "project" }];
196
226
  for (const milestone of milestones) {
197
227
  scopes.push({ scope: milestone.id, label: `${milestone.id}: ${milestone.title}`, kind: "milestone" });
@@ -15,7 +15,7 @@
15
15
  * 4. remove() — git worktree remove + branch cleanup
16
16
  */
17
17
 
18
- import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
18
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
19
19
  import { execFileSync } from "node:child_process";
20
20
  import { join, resolve, sep } from "node:path";
21
21
  import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
@@ -277,6 +277,78 @@ export function listWorktrees(basePath: string): WorktreeInfo[] {
277
277
  return worktrees;
278
278
  }
279
279
 
280
+ // ─── Nested .git Detection (#2616) ──────────────────────────────────────
281
+ //
282
+ // Scaffolding tools (create-next-app, cargo init, etc.) create nested .git
283
+ // directories inside worktrees. Git records these as gitlinks (mode 160000)
284
+ // without a .gitmodules entry — so worktree cleanup destroys the only copy
285
+ // of their object database, causing permanent silent data loss.
286
+
287
+ /** Directories to skip when scanning for nested .git dirs. */
288
+ const NESTED_GIT_SKIP_DIRS = new Set([
289
+ ".git", ".gsd", "node_modules", ".next", ".nuxt", "dist", "build",
290
+ "__pycache__", ".tox", ".venv", "venv", "target", "vendor",
291
+ ]);
292
+
293
+ /**
294
+ * Recursively find nested .git directories inside a worktree root.
295
+ * Returns paths to directories that contain their own .git (directory, not file).
296
+ * Skips node_modules, .gsd, and other non-project directories for performance.
297
+ *
298
+ * A nested .git *directory* (not a .git file — which is a legitimate worktree
299
+ * pointer) indicates a scaffolded repo that will become an orphaned gitlink.
300
+ */
301
+ export function findNestedGitDirs(rootPath: string): string[] {
302
+ const results: string[] = [];
303
+
304
+ function walk(dir: string, depth: number): void {
305
+ // Cap recursion depth to avoid runaway scanning
306
+ if (depth > 10) return;
307
+
308
+ let entries: string[];
309
+ try {
310
+ entries = readdirSync(dir);
311
+ } catch {
312
+ return; // Permission denied, broken symlink, etc.
313
+ }
314
+
315
+ for (const entry of entries) {
316
+ if (NESTED_GIT_SKIP_DIRS.has(entry)) continue;
317
+
318
+ const fullPath = join(dir, entry);
319
+
320
+ // Only follow real directories, not symlinks
321
+ let stat;
322
+ try {
323
+ stat = lstatSync(fullPath);
324
+ } catch {
325
+ continue;
326
+ }
327
+ if (!stat.isDirectory()) continue;
328
+
329
+ // Check if this directory contains a .git *directory* (not a .git file).
330
+ // A .git file is a worktree pointer and is legitimate.
331
+ // A .git directory is a standalone repo created by scaffolding.
332
+ const innerGit = join(fullPath, ".git");
333
+ try {
334
+ const innerStat = lstatSync(innerGit);
335
+ if (innerStat.isDirectory()) {
336
+ results.push(fullPath);
337
+ // Don't recurse into the nested repo — we found what we need
338
+ continue;
339
+ }
340
+ } catch {
341
+ // No .git here — continue scanning
342
+ }
343
+
344
+ walk(fullPath, depth + 1);
345
+ }
346
+ }
347
+
348
+ walk(rootPath, 0);
349
+ return results;
350
+ }
351
+
280
352
  /**
281
353
  * Remove a worktree and optionally delete its branch.
282
354
  * If the process is currently inside the worktree, chdir out first.
@@ -355,6 +427,30 @@ export function removeWorktree(
355
427
  }
356
428
  }
357
429
 
430
+ // Nested .git safety (#2616): detect nested .git directories created by
431
+ // scaffolding tools (create-next-app, cargo init, etc.). These produce
432
+ // gitlink entries (mode 160000) without .gitmodules — cleanup would destroy
433
+ // the only copy of the nested object database, causing permanent data loss.
434
+ // Fix: remove the nested .git dirs so git tracks the files as regular content.
435
+ const nestedGitDirs = findNestedGitDirs(resolvedWtPath);
436
+ if (nestedGitDirs.length > 0) {
437
+ for (const nestedDir of nestedGitDirs) {
438
+ const nestedGitPath = join(nestedDir, ".git");
439
+ try {
440
+ rmSync(nestedGitPath, { recursive: true, force: true });
441
+ logWarning("reconcile",
442
+ `Removed nested .git directory from scaffolded project to prevent data loss (#2616)`,
443
+ { worktree: name, nestedRepo: nestedDir },
444
+ );
445
+ } catch {
446
+ logWarning("reconcile",
447
+ `Failed to remove nested .git directory — files may be lost as orphaned gitlink`,
448
+ { worktree: name, nestedRepo: nestedDir },
449
+ );
450
+ }
451
+ }
452
+ }
453
+
358
454
  // Remove worktree: try non-force first when submodules have changes,
359
455
  // falling back to force only after submodule state has been preserved.
360
456
  const useForce = hasSubmoduleChanges ? false : force;
@@ -365,6 +461,29 @@ export function removeWorktree(
365
461
  try { nativeWorktreeRemove(basePath, resolvedWtPath, true); } catch { /* may fail */ }
366
462
  }
367
463
 
464
+ // (#2821) If the worktree directory STILL exists after both native removal
465
+ // attempts (e.g. untracked files like ASSESSMENT/UAT-RESULT prevent git
466
+ // worktree remove), force-remove the git internal worktree metadata first,
467
+ // then remove the filesystem directory. Without this, the .git/worktrees/<name>
468
+ // lock prevents rmSync from cleaning up, and the orphaned worktree directory
469
+ // causes every subsequent `/gsd auto` to re-enter the stale worktree.
470
+ if (existsSync(resolvedWtPath)) {
471
+ try {
472
+ const wtInternalDir = join(basePath, ".git", "worktrees", name);
473
+ if (existsSync(wtInternalDir)) {
474
+ rmSync(wtInternalDir, { recursive: true, force: true });
475
+ }
476
+ rmSync(resolvedWtPath, { recursive: true, force: true });
477
+ } catch {
478
+ logWarning(
479
+ "reconcile",
480
+ `Worktree directory could not be removed after git internal cleanup: ${resolvedWtPath}. ` +
481
+ `Manual cleanup: rm -rf "${resolvedWtPath.replaceAll("\\", "/")}"`,
482
+ { worktree: name },
483
+ );
484
+ }
485
+ }
486
+
368
487
  // Prune stale entries so git knows the worktree is gone
369
488
  nativeWorktreePrune(basePath);
370
489
 
@@ -350,7 +350,13 @@ export class WorktreeResolver {
350
350
  data: { milestoneId, mode },
351
351
  });
352
352
 
353
- if (mode === "none") {
353
+ // #2625: If we are physically inside an auto-worktree, we MUST merge
354
+ // regardless of the current isolation config. This prevents data loss when
355
+ // the default isolation mode changes between versions (e.g., "worktree" ->
356
+ // "none"): the worktree branch still holds real commits that need merging.
357
+ const inWorktree = this.deps.isInAutoWorktree(this.s.basePath) && this.s.originalBasePath;
358
+
359
+ if (mode === "none" && !inWorktree) {
354
360
  debugLog("WorktreeResolver", {
355
361
  action: "mergeAndExit",
356
362
  milestoneId,
@@ -361,8 +367,7 @@ export class WorktreeResolver {
361
367
  }
362
368
 
363
369
  if (
364
- mode === "worktree" ||
365
- (this.deps.isInAutoWorktree(this.s.basePath) && this.s.originalBasePath)
370
+ mode === "worktree" || inWorktree
366
371
  ) {
367
372
  this._mergeWorktreeMode(milestoneId, ctx);
368
373
  } else if (mode === "branch") {
@@ -432,6 +437,20 @@ export class WorktreeResolver {
432
437
  milestoneId,
433
438
  roadmapContent,
434
439
  );
440
+
441
+ // #2945 Bug 3: mergeMilestoneToMain performs best-effort worktree
442
+ // cleanup internally (step 12), but it can silently fail on Windows
443
+ // or when the worktree directory is locked. Perform a secondary
444
+ // teardown here to ensure the worktree is properly cleaned up.
445
+ // This is idempotent — if the worktree was already removed,
446
+ // teardownAutoWorktree handles the no-op case gracefully.
447
+ try {
448
+ this.deps.teardownAutoWorktree(originalBase, milestoneId);
449
+ } catch {
450
+ // Best-effort — the primary cleanup in mergeMilestoneToMain may
451
+ // have already removed the worktree.
452
+ }
453
+
435
454
  if (mergeResult.codeFilesChanged) {
436
455
  ctx.notify(
437
456
  `Milestone ${milestoneId} merged to main.${mergeResult.pushed ? " Pushed to remote." : ""}`,
@@ -111,7 +111,11 @@ function readConfigs(): McpServerConfig[] {
111
111
  }
112
112
 
113
113
  function getServerConfig(name: string): McpServerConfig | undefined {
114
- return readConfigs().find((s) => s.name === name);
114
+ const trimmed = name.trim();
115
+ return readConfigs().find((s) =>
116
+ s.name === trimmed ||
117
+ s.name.toLowerCase() === trimmed.toLowerCase(),
118
+ );
115
119
  }
116
120
 
117
121
  /** Resolve ${VAR} references in env values against process.env. */
@@ -131,12 +135,14 @@ function resolveEnv(env: Record<string, string>): Record<string, string> {
131
135
  }
132
136
 
133
137
  async function getOrConnect(name: string, signal?: AbortSignal): Promise<Client> {
134
- const existing = connections.get(name);
135
- if (existing) return existing.client;
136
-
137
138
  const config = getServerConfig(name);
138
139
  if (!config) throw new Error(`Unknown MCP server: "${name}". Use mcp_servers to list available servers.`);
139
140
 
141
+ // Always use config.name as the canonical cache key so that variant
142
+ // casing / whitespace still hits the same connection.
143
+ const existing = connections.get(config.name);
144
+ if (existing) return existing.client;
145
+
140
146
  const client = new Client({ name: "gsd", version: "1.0.0" });
141
147
  let transport: StdioClientTransport | StreamableHTTPClientTransport;
142
148
 
@@ -151,15 +157,15 @@ async function getOrConnect(name: string, signal?: AbortSignal): Promise<Client>
151
157
  } else if (config.transport === "http" && config.url) {
152
158
  const resolvedUrl = config.url.replace(
153
159
  /\$\{([^}]+)\}/g,
154
- (_, name) => process.env[name] ?? "",
160
+ (_, varName) => process.env[varName] ?? "",
155
161
  );
156
162
  transport = new StreamableHTTPClientTransport(new URL(resolvedUrl));
157
163
  } else {
158
- throw new Error(`Server "${name}" has unsupported transport: ${config.transport}`);
164
+ throw new Error(`Server "${config.name}" has unsupported transport: ${config.transport}`);
159
165
  }
160
166
 
161
167
  await client.connect(transport, { signal, timeout: 30000 });
162
- connections.set(name, { client, transport });
168
+ connections.set(config.name, { client, transport });
163
169
  return client;
164
170
  }
165
171