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
@@ -113,14 +113,6 @@ export function registerDbTools(pi) {
113
113
  };
114
114
  }
115
115
  try {
116
- const db = await import("../gsd-db.js");
117
- const existing = db.getRequirementById(params.id);
118
- if (!existing) {
119
- return {
120
- content: [{ type: "text", text: `Error: Requirement ${params.id} not found.` }],
121
- details: { operation: "update_requirement", id: params.id, error: "not_found" },
122
- };
123
- }
124
116
  const { updateRequirementInDb } = await import("../db-writer.js");
125
117
  const updates = {};
126
118
  if (params.status !== undefined)
@@ -193,6 +185,86 @@ export function registerDbTools(pi) {
193
185
  };
194
186
  pi.registerTool(requirementUpdateTool);
195
187
  registerAlias(pi, requirementUpdateTool, "gsd_update_requirement", "gsd_requirement_update");
188
+ // ─── gsd_requirement_save ─────────────────────────────────────────────
189
+ const requirementSaveExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
190
+ const dbAvailable = await ensureDbOpen();
191
+ if (!dbAvailable) {
192
+ return {
193
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot save requirement." }],
194
+ details: { operation: "save_requirement", error: "db_unavailable" },
195
+ };
196
+ }
197
+ try {
198
+ const { saveRequirementToDb } = await import("../db-writer.js");
199
+ const result = await saveRequirementToDb({
200
+ class: params.class,
201
+ status: params.status,
202
+ description: params.description,
203
+ why: params.why,
204
+ source: params.source,
205
+ primary_owner: params.primary_owner,
206
+ supporting_slices: params.supporting_slices,
207
+ validation: params.validation,
208
+ notes: params.notes,
209
+ }, process.cwd());
210
+ return {
211
+ content: [{ type: "text", text: `Saved requirement ${result.id}` }],
212
+ details: { operation: "save_requirement", id: result.id },
213
+ };
214
+ }
215
+ catch (err) {
216
+ const msg = err instanceof Error ? err.message : String(err);
217
+ logError("tool", `gsd_requirement_save tool failed: ${msg}`, { tool: "gsd_requirement_save", error: String(err) });
218
+ return {
219
+ content: [{ type: "text", text: `Error saving requirement: ${msg}` }],
220
+ details: { operation: "save_requirement", error: msg },
221
+ };
222
+ }
223
+ };
224
+ const requirementSaveTool = {
225
+ name: "gsd_requirement_save",
226
+ label: "Save Requirement",
227
+ description: "Record a new requirement to the GSD database and regenerate REQUIREMENTS.md. " +
228
+ "Requirement IDs are auto-assigned — never provide an ID manually.",
229
+ promptSnippet: "Record a new GSD requirement to the database (auto-assigns ID, regenerates REQUIREMENTS.md)",
230
+ promptGuidelines: [
231
+ "Use gsd_requirement_save when recording a new functional, non-functional, or operational requirement.",
232
+ "Requirement IDs are auto-assigned (R001, R002, ...) — never guess or provide an ID.",
233
+ "class, description, why, and source are required. All other fields are optional.",
234
+ "The tool writes to the DB and regenerates .gsd/REQUIREMENTS.md automatically.",
235
+ ],
236
+ parameters: Type.Object({
237
+ class: Type.String({ description: "Requirement class (e.g. 'functional', 'non-functional', 'operational')" }),
238
+ description: Type.String({ description: "Short description of the requirement" }),
239
+ why: Type.String({ description: "Why this requirement matters" }),
240
+ source: Type.String({ description: "Origin of the requirement (e.g. 'user-research', 'design', 'M001')" }),
241
+ status: Type.Optional(Type.String({ description: "Status (default: 'active')" })),
242
+ primary_owner: Type.Optional(Type.String({ description: "Primary owning slice" })),
243
+ supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
244
+ validation: Type.Optional(Type.String({ description: "Validation criteria" })),
245
+ notes: Type.Optional(Type.String({ description: "Additional notes" })),
246
+ }),
247
+ execute: requirementSaveExecute,
248
+ renderCall(args, theme) {
249
+ let text = theme.fg("toolTitle", theme.bold("requirement_save "));
250
+ if (args.class)
251
+ text += theme.fg("accent", `[${args.class}] `);
252
+ if (args.description)
253
+ text += theme.fg("muted", args.description);
254
+ return new Text(text, 0, 0);
255
+ },
256
+ renderResult(result, _options, theme) {
257
+ const d = result.details;
258
+ if (result.isError || d?.error) {
259
+ return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
260
+ }
261
+ let text = theme.fg("success", `Requirement ${d?.id ?? ""} saved`);
262
+ text += theme.fg("dim", ` → REQUIREMENTS.md`);
263
+ return new Text(text, 0, 0);
264
+ },
265
+ };
266
+ pi.registerTool(requirementSaveTool);
267
+ registerAlias(pi, requirementSaveTool, "gsd_save_requirement", "gsd_requirement_save");
196
268
  // ─── gsd_summary_save (formerly gsd_save_summary) ──────────────────────
197
269
  const summarySaveExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
198
270
  const dbAvailable = await ensureDbOpen();
@@ -26,6 +26,29 @@ export function resolveProjectRootDbPath(basePath) {
26
26
  const projectRoot = basePath.slice(0, fwdIdx);
27
27
  return join(projectRoot, ".gsd", "gsd.db");
28
28
  }
29
+ // Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/M001/...
30
+ // The project root is everything before /.gsd/projects/ (#2517)
31
+ const symlinkMarker = `${sep}.gsd${sep}projects${sep}`;
32
+ const symlinkIdx = basePath.indexOf(symlinkMarker);
33
+ if (symlinkIdx !== -1) {
34
+ const afterProjects = basePath.slice(symlinkIdx + symlinkMarker.length);
35
+ // Expect: <hash>/worktrees/...
36
+ const worktreeSeg = `${sep}worktrees${sep}`;
37
+ if (afterProjects.includes(worktreeSeg)) {
38
+ const projectRoot = basePath.slice(0, symlinkIdx);
39
+ return join(projectRoot, ".gsd", "gsd.db");
40
+ }
41
+ }
42
+ // Forward-slash variant for symlink-resolved layout
43
+ const fwdSymlinkMarker = "/.gsd/projects/";
44
+ const fwdSymlinkIdx = basePath.indexOf(fwdSymlinkMarker);
45
+ if (fwdSymlinkIdx !== -1) {
46
+ const afterProjects = basePath.slice(fwdSymlinkIdx + fwdSymlinkMarker.length);
47
+ if (afterProjects.includes("/worktrees/")) {
48
+ const projectRoot = basePath.slice(0, fwdSymlinkIdx);
49
+ return join(projectRoot, ".gsd", "gsd.db");
50
+ }
51
+ }
29
52
  return join(basePath, ".gsd", "gsd.db");
30
53
  }
31
54
  export async function ensureDbOpen() {
@@ -70,9 +93,17 @@ export async function ensureDbOpen() {
70
93
  setLogBasePath(projectRoot);
71
94
  return opened;
72
95
  }
96
+ process.stderr.write(`gsd-db: ensureDbOpen failed — no .gsd directory found (resolvedPath=${resolveProjectRootDbPath(basePath)}, cwd=${basePath})\n`);
73
97
  return false;
74
98
  }
75
- catch {
99
+ catch (err) {
100
+ const basePath = process.cwd();
101
+ const diagnostic = {
102
+ resolvedPath: resolveProjectRootDbPath(basePath),
103
+ cwd: basePath,
104
+ error: err.message ?? String(err),
105
+ };
106
+ process.stderr.write(`gsd-db: ensureDbOpen failed — ${JSON.stringify(diagnostic)}\n`);
76
107
  return false;
77
108
  }
78
109
  }
@@ -3,8 +3,9 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
3
3
  import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
4
4
  import { buildBeforeAgentStartResult } from "./system-context.js";
5
5
  import { handleAgentEnd } from "./agent-end-recovery.js";
6
- import { clearDiscussionFlowState, isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite } from "./write-gate.js";
6
+ import { clearDiscussionFlowState, isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockQueueExecution } from "./write-gate.js";
7
7
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
8
+ import { cleanupQuickBranch } from "../quick.js";
8
9
  import { getDiscussionMilestoneId } from "../guided-flow.js";
9
10
  import { loadToolApiKeys } from "../commands-config.js";
10
11
  import { loadFile, saveFile, formatContinue } from "../files.js";
@@ -13,8 +14,6 @@ import { getAutoDashboardData, isAutoActive, isAutoPaused, markToolEnd, markTool
13
14
  import { isParallelActive, shutdownParallel } from "../parallel-orchestrator.js";
14
15
  import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
15
16
  import { saveActivityLog } from "../activity-log.js";
16
- import { startRtkStatusUpdates, stopRtkStatusUpdates } from "../rtk-status.js";
17
- import { rewriteCommandWithRtk } from "../../shared/rtk.js";
18
17
  // Skip the welcome screen on the very first session_start — cli.ts already
19
18
  // printed it before the TUI launched. Only re-print on /clear (subsequent sessions).
20
19
  let isFirstSession = true;
@@ -23,19 +22,10 @@ async function syncServiceTierStatus(ctx) {
23
22
  ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
24
23
  }
25
24
  export function registerHooks(pi) {
26
- // Route all agent bash tool commands through RTK rewrite when opted in.
27
- // This is a no-op when RTK is disabled or not installed.
28
- pi.on("bash_transform", async (event) => {
29
- const rewritten = rewriteCommandWithRtk(event.command);
30
- if (rewritten === event.command)
31
- return undefined;
32
- return { command: rewritten };
33
- });
34
25
  pi.on("session_start", async (_event, ctx) => {
35
26
  resetWriteGateState();
36
27
  resetToolCallLoopGuard();
37
28
  await syncServiceTierStatus(ctx);
38
- startRtkStatusUpdates(ctx);
39
29
  // Apply show_token_cost preference (#1515)
40
30
  try {
41
31
  const { loadEffectiveGSDPreferences } = await import("../preferences.js");
@@ -52,27 +42,20 @@ export function registerHooks(pi) {
52
42
  if (gsdBinPath) {
53
43
  const { dirname } = await import("node:path");
54
44
  const { printWelcomeScreen } = await import(join(dirname(gsdBinPath), "welcome-screen.js"));
55
- printWelcomeScreen({ version: process.env.GSD_VERSION || "0.0.0" });
45
+ let remoteChannel;
46
+ try {
47
+ const { resolveRemoteConfig } = await import("../../remote-questions/config.js");
48
+ const rc = resolveRemoteConfig();
49
+ if (rc)
50
+ remoteChannel = rc.channel;
51
+ }
52
+ catch { /* non-fatal */ }
53
+ printWelcomeScreen({ version: process.env.GSD_VERSION || "0.0.0", remoteChannel });
56
54
  }
57
55
  }
58
56
  catch { /* non-fatal */ }
59
57
  }
60
58
  loadToolApiKeys();
61
- try {
62
- const [{ getRemoteConfigStatus }, { getLatestPromptSummary }] = await Promise.all([
63
- import("../../remote-questions/config.js"),
64
- import("../../remote-questions/status.js"),
65
- ]);
66
- const status = getRemoteConfigStatus();
67
- const latest = getLatestPromptSummary();
68
- if (!status.includes("not configured")) {
69
- const suffix = latest ? `\nLast remote prompt: ${latest.id} (${latest.status})` : "";
70
- ctx.ui.notify(`${status}${suffix}`, status.includes("disabled") ? "warning" : "info");
71
- }
72
- }
73
- catch {
74
- // ignore
75
- }
76
59
  });
77
60
  pi.on("session_switch", async (_event, ctx) => {
78
61
  resetWriteGateState();
@@ -80,10 +63,6 @@ export function registerHooks(pi) {
80
63
  clearDiscussionFlowState();
81
64
  await syncServiceTierStatus(ctx);
82
65
  loadToolApiKeys();
83
- startRtkStatusUpdates(ctx);
84
- });
85
- pi.on("session_fork", async (_event, ctx) => {
86
- startRtkStatusUpdates(ctx);
87
66
  });
88
67
  pi.on("before_agent_start", async (event, ctx) => {
89
68
  return buildBeforeAgentStartResult(event, ctx);
@@ -92,6 +71,17 @@ export function registerHooks(pi) {
92
71
  resetToolCallLoopGuard();
93
72
  await handleAgentEnd(pi, event, ctx);
94
73
  });
74
+ // Squash-merge quick-task branch back to the original branch after the
75
+ // agent turn completes (#2668). cleanupQuickBranch is a no-op when no
76
+ // quick-return state is pending, so this is safe to call on every turn.
77
+ pi.on("turn_end", async () => {
78
+ try {
79
+ cleanupQuickBranch();
80
+ }
81
+ catch {
82
+ // Best-effort: don't break the turn lifecycle if cleanup fails.
83
+ }
84
+ });
95
85
  pi.on("session_before_compact", async () => {
96
86
  if (isAutoActive() || isAutoPaused()) {
97
87
  return { cancel: true };
@@ -130,7 +120,6 @@ export function registerHooks(pi) {
130
120
  }));
131
121
  });
132
122
  pi.on("session_shutdown", async (_event, ctx) => {
133
- stopRtkStatusUpdates(ctx);
134
123
  if (isParallelActive()) {
135
124
  try {
136
125
  await shutdownParallel(process.cwd());
@@ -152,6 +141,25 @@ export function registerHooks(pi) {
152
141
  if (loopCheck.block) {
153
142
  return { block: true, reason: loopCheck.reason };
154
143
  }
144
+ // ── Queue-mode execution guard (#2545): block source-code mutations ──
145
+ // When /gsd queue is active, the agent should only create milestones,
146
+ // not execute work. Block write/edit to non-.gsd/ paths and bash commands
147
+ // that would modify files.
148
+ if (isQueuePhaseActive()) {
149
+ let queueInput = "";
150
+ if (isToolCallEventType("write", event)) {
151
+ queueInput = event.input.path;
152
+ }
153
+ else if (isToolCallEventType("edit", event)) {
154
+ queueInput = event.input.path;
155
+ }
156
+ else if (isToolCallEventType("bash", event)) {
157
+ queueInput = event.input.command;
158
+ }
159
+ const queueGuard = shouldBlockQueueExecution(event.toolName, queueInput, true);
160
+ if (queueGuard.block)
161
+ return queueGuard;
162
+ }
155
163
  // ── Single-writer engine: block direct writes to STATE.md ──────────
156
164
  // Covers write, edit, and bash tools to prevent bypass vectors.
157
165
  if (isToolCallEventType("write", event)) {
@@ -227,7 +235,7 @@ export function registerHooks(pi) {
227
235
  pi.on("tool_execution_start", async (event) => {
228
236
  if (!isAutoActive())
229
237
  return;
230
- markToolStart(event.toolCallId, event.toolName);
238
+ markToolStart(event.toolCallId);
231
239
  });
232
240
  pi.on("tool_execution_end", async (event) => {
233
241
  markToolEnd(event.toolCallId);
@@ -1,8 +1,9 @@
1
- import { existsSync, readFileSync } from "node:fs";
1
+ import { existsSync, readFileSync, unlinkSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { debugTime } from "../debug-logger.js";
5
5
  import { loadPrompt } from "../prompt-loader.js";
6
+ import { readForensicsMarker } from "../forensics.js";
6
7
  import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
7
8
  import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
8
9
  import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
@@ -70,27 +71,48 @@ export async function buildBeforeAgentStartResult(event, ctx) {
70
71
  newSkillsBlock = formatSkillsXml(newSkills);
71
72
  }
72
73
  }
74
+ let codebaseBlock = "";
75
+ const codebasePath = resolveGsdRootFile(process.cwd(), "CODEBASE");
76
+ if (existsSync(codebasePath)) {
77
+ try {
78
+ const rawContent = readFileSync(codebasePath, "utf-8").trim();
79
+ if (rawContent) {
80
+ // Cap injection size to ~2 000 tokens to avoid bloating every request.
81
+ // Full map is always available at .gsd/CODEBASE.md.
82
+ const MAX_CODEBASE_CHARS = 8_000;
83
+ const generatedMatch = rawContent.match(/Generated: (\S+)/);
84
+ const generatedAt = generatedMatch?.[1] ?? "unknown";
85
+ const content = rawContent.length > MAX_CODEBASE_CHARS
86
+ ? rawContent.slice(0, MAX_CODEBASE_CHARS) + "\n\n*(truncated — see .gsd/CODEBASE.md for full map)*"
87
+ : rawContent;
88
+ codebaseBlock = `\n\n[PROJECT CODEBASE — File structure and descriptions (generated ${generatedAt}, may be stale — run /gsd codebase update to refresh)]\n\n${content}`;
89
+ }
90
+ }
91
+ catch {
92
+ // skip
93
+ }
94
+ }
73
95
  warnDeprecatedAgentInstructions();
74
96
  const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
97
+ // Re-inject forensics context on follow-up turns (#2941)
98
+ const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd()) : null;
75
99
  const worktreeBlock = buildWorktreeContextBlock();
76
- const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
100
+ const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${memoryBlock}${newSkillsBlock}${worktreeBlock}`;
77
101
  stopContextTimer({
78
102
  systemPromptSize: fullSystem.length,
79
- injectionSize: injection?.length ?? 0,
103
+ injectionSize: injection?.length ?? forensicsInjection?.length ?? 0,
80
104
  hasPreferences: preferenceBlock.length > 0,
81
105
  hasNewSkills: newSkillsBlock.length > 0,
82
106
  });
107
+ // Determine which context message to inject (guided execute takes priority)
108
+ const contextMessage = injection
109
+ ? { customType: "gsd-guided-context", content: injection, display: false }
110
+ : forensicsInjection
111
+ ? { customType: "gsd-forensics", content: forensicsInjection, display: false }
112
+ : null;
83
113
  return {
84
114
  systemPrompt: fullSystem,
85
- ...(injection
86
- ? {
87
- message: {
88
- customType: "gsd-guided-context",
89
- content: injection,
90
- display: false,
91
- },
92
- }
93
- : {}),
115
+ ...(contextMessage ? { message: contextMessage } : {}),
94
116
  };
95
117
  }
96
118
  export function loadKnowledgeBlock(gsdHomeDir, cwd) {
@@ -332,3 +354,35 @@ function escapeRegExp(value) {
332
354
  function oneLine(text) {
333
355
  return text.replace(/\s+/g, " ").trim();
334
356
  }
357
+ // ─── Forensics Context Re-injection (#2941) ──────────────────────────────────
358
+ /**
359
+ * Check for an active forensics session and return the prompt content
360
+ * so it can be re-injected on follow-up turns.
361
+ */
362
+ function buildForensicsContextInjection(basePath) {
363
+ const marker = readForensicsMarker(basePath);
364
+ if (!marker)
365
+ return null;
366
+ // Expire markers older than 2 hours to avoid stale context
367
+ const age = Date.now() - new Date(marker.createdAt).getTime();
368
+ if (age > 2 * 60 * 60 * 1000) {
369
+ clearForensicsMarker(basePath);
370
+ return null;
371
+ }
372
+ return marker.promptContent;
373
+ }
374
+ /**
375
+ * Remove the active forensics marker file, e.g. when the investigation
376
+ * is complete or the session expires.
377
+ */
378
+ export function clearForensicsMarker(basePath) {
379
+ const markerPath = join(basePath, ".gsd", "runtime", "active-forensics.json");
380
+ if (existsSync(markerPath)) {
381
+ try {
382
+ unlinkSync(markerPath);
383
+ }
384
+ catch {
385
+ // non-fatal
386
+ }
387
+ }
388
+ }
@@ -1,4 +1,27 @@
1
1
  const MILESTONE_CONTEXT_RE = /M\d+(?:-[a-z0-9]{6})?-CONTEXT\.md$/;
2
+ /**
3
+ * Path segment that identifies .gsd/ planning artifacts.
4
+ * Writes to these paths are allowed during queue mode.
5
+ */
6
+ const GSD_DIR_RE = /(^|[/\\])\.gsd([/\\]|$)/;
7
+ /**
8
+ * Read-only tool names that are always safe during queue mode.
9
+ */
10
+ const QUEUE_SAFE_TOOLS = new Set([
11
+ "read", "grep", "find", "ls", "glob",
12
+ // Discussion & planning tools
13
+ "ask_user_questions",
14
+ "gsd_milestone_generate_id",
15
+ "gsd_summary_save",
16
+ // Web research tools used during queue discussion
17
+ "search-the-web", "resolve_library", "get_library_docs", "fetch_page",
18
+ "search_and_read",
19
+ ]);
20
+ /**
21
+ * Bash commands that are read-only / investigative — safe during queue mode.
22
+ * Matches the leading command in a bash invocation.
23
+ */
24
+ const BASH_READ_ONLY_RE = /^\s*(cat|head|tail|less|more|wc|file|stat|du|df|which|type|echo|printf|ls|find|grep|rg|awk|sed\b(?!.*-i)|sort|uniq|diff|comm|tr|cut|tee\s+-a\s+\/dev\/null|git\s+(log|show|diff|status|branch|tag|remote|rev-parse|ls-files|blame|shortlog|describe|stash\s+list|config\s+--get|cat-file)|gh\s+(issue|pr|api|repo|release)\s+(view|list|diff|status|checks)|mkdir\s+-p\s+\.gsd|rtk\s)/;
2
25
  let depthVerificationDone = false;
3
26
  let activeQueuePhase = false;
4
27
  export function isDepthVerified() {
@@ -36,3 +59,47 @@ export function shouldBlockContextWrite(toolName, inputPath, milestoneId, depthV
36
59
  reason: `Blocked: Cannot write to milestone CONTEXT.md during discussion phase without depth verification. Call ask_user_questions with question id "depth_verification" first to confirm discussion depth before writing context.`,
37
60
  };
38
61
  }
62
+ /**
63
+ * Queue-mode execution guard (#2545).
64
+ *
65
+ * When the queue phase is active, the agent should only create planning
66
+ * artifacts (milestones, CONTEXT.md, QUEUE.md, etc.) — never execute work.
67
+ * This function blocks write/edit/bash tool calls that would modify source
68
+ * code outside of .gsd/.
69
+ *
70
+ * @param toolName The tool being called (write, edit, bash, etc.)
71
+ * @param input For write/edit: the file path. For bash: the command string.
72
+ * @param queuePhaseActive Whether the queue phase is currently active.
73
+ * @returns { block, reason } — block=true if the call should be rejected.
74
+ */
75
+ export function shouldBlockQueueExecution(toolName, input, queuePhaseActive) {
76
+ if (!queuePhaseActive)
77
+ return { block: false };
78
+ // Always-safe tools (read-only, discussion, planning)
79
+ if (QUEUE_SAFE_TOOLS.has(toolName))
80
+ return { block: false };
81
+ // write/edit — allow if targeting .gsd/ planning artifacts
82
+ if (toolName === "write" || toolName === "edit") {
83
+ if (GSD_DIR_RE.test(input))
84
+ return { block: false };
85
+ return {
86
+ block: true,
87
+ reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
88
+ `Cannot ${toolName} to "${input}" during queue mode. ` +
89
+ `Write CONTEXT.md files and update PROJECT.md/QUEUE.md instead.`,
90
+ };
91
+ }
92
+ // bash — allow read-only/investigative commands, block everything else
93
+ if (toolName === "bash") {
94
+ if (BASH_READ_ONLY_RE.test(input))
95
+ return { block: false };
96
+ return {
97
+ block: true,
98
+ reason: `Blocked: /gsd queue is a planning tool — it creates milestones, not executes work. ` +
99
+ `Cannot run "${input.slice(0, 80)}${input.length > 80 ? "…" : ""}" during queue mode. ` +
100
+ `Use read-only commands (cat, grep, git log, etc.) to investigate, then write planning artifacts.`,
101
+ };
102
+ }
103
+ // Unknown tools — allow by default (custom extension tools, etc.)
104
+ return { block: false };
105
+ }
@@ -134,7 +134,7 @@ export function countPendingCaptures(basePath) {
134
134
  * Mark a capture as resolved with classification and rationale.
135
135
  * Rewrites the entry in place, preserving other entries.
136
136
  */
137
- export function markCaptureResolved(basePath, captureId, classification, resolution, rationale) {
137
+ export function markCaptureResolved(basePath, captureId, classification, resolution, rationale, milestoneId) {
138
138
  const filePath = resolveCapturesPath(basePath);
139
139
  if (!existsSync(filePath))
140
140
  return;
@@ -155,12 +155,16 @@ export function markCaptureResolved(basePath, captureId, classification, resolut
155
155
  `**Rationale:** ${rationale}`,
156
156
  `**Resolved:** ${resolvedAt}`,
157
157
  ];
158
- // Remove any existing classification/resolution/rationale/resolved fields
158
+ if (milestoneId) {
159
+ newFields.push(`**Milestone:** ${milestoneId}`);
160
+ }
161
+ // Remove any existing classification/resolution/rationale/resolved/milestone fields
159
162
  // (in case of re-triage)
160
163
  section = section.replace(/\*\*Classification:\*\*\s*.+\n?/g, "");
161
164
  section = section.replace(/\*\*Resolution:\*\*\s*.+\n?/g, "");
162
165
  section = section.replace(/\*\*Rationale:\*\*\s*.+\n?/g, "");
163
166
  section = section.replace(/\*\*Resolved:\*\*\s*.+\n?/g, "");
167
+ section = section.replace(/\*\*Milestone:\*\*\s*.+\n?/g, "");
164
168
  // Add new fields after Status line
165
169
  section = section.trimEnd() + "\n" + newFields.join("\n") + "\n";
166
170
  const updated = content.replace(sectionRegex, section);
@@ -192,13 +196,59 @@ export function markCaptureExecuted(basePath, captureId) {
192
196
  * Load resolved captures that have actionable classifications (inject, replan,
193
197
  * quick-task) but have NOT yet been executed.
194
198
  * These are captures whose resolutions need to be carried out.
199
+ *
200
+ * When `currentMilestoneId` is provided, captures resolved in a *different*
201
+ * milestone are treated as stale and excluded. This prevents quick-task
202
+ * captures from a prior milestone re-executing after the underlying issues
203
+ * were already fixed by planned milestone work (#2872).
204
+ *
205
+ * Captures that have no `resolvedInMilestone` (legacy captures resolved before
206
+ * this field was introduced) are always included for backward compatibility.
195
207
  */
196
- export function loadActionableCaptures(basePath) {
208
+ export function loadActionableCaptures(basePath, currentMilestoneId) {
197
209
  return loadAllCaptures(basePath).filter(c => c.status === "resolved" &&
198
210
  !c.executed &&
199
211
  (c.classification === "inject" ||
200
212
  c.classification === "replan" ||
201
- c.classification === "quick-task"));
213
+ c.classification === "quick-task") &&
214
+ // Staleness gate: exclude captures resolved in a different milestone (#2872)
215
+ (!currentMilestoneId ||
216
+ !c.resolvedInMilestone ||
217
+ c.resolvedInMilestone === currentMilestoneId));
218
+ }
219
+ /**
220
+ * Retroactively stamp a capture with a milestone ID.
221
+ *
222
+ * Used by executeTriageResolutions() as a safety net when the triage LLM
223
+ * resolves a capture without writing the **Milestone:** field. This ensures
224
+ * the staleness gate in loadActionableCaptures() works correctly even for
225
+ * captures resolved before the prompt was updated (#2872).
226
+ */
227
+ export function stampCaptureMilestone(basePath, captureId, milestoneId) {
228
+ const filePath = resolveCapturesPath(basePath);
229
+ if (!existsSync(filePath))
230
+ return;
231
+ const content = readFileSync(filePath, "utf-8");
232
+ const sectionRegex = new RegExp(`(### ${escapeRegex(captureId)}\\n(?:(?!### ).)*?)(?=### |$)`, "s");
233
+ const match = sectionRegex.exec(content);
234
+ if (!match)
235
+ return;
236
+ let section = match[1];
237
+ // Only stamp if not already present
238
+ if (/\*\*Milestone:\*\*/.test(section))
239
+ return;
240
+ // Insert after the Resolved field (or at end of section)
241
+ const resolvedFieldEnd = section.search(/\*\*Resolved:\*\*\s*.+\n?/);
242
+ if (resolvedFieldEnd !== -1) {
243
+ const resolvedMatch = section.match(/\*\*Resolved:\*\*\s*.+\n?/);
244
+ const insertPos = resolvedFieldEnd + (resolvedMatch?.[0]?.length ?? 0);
245
+ section = section.slice(0, insertPos) + `**Milestone:** ${milestoneId}\n` + section.slice(insertPos);
246
+ }
247
+ else {
248
+ section = section.trimEnd() + "\n" + `**Milestone:** ${milestoneId}` + "\n";
249
+ }
250
+ const updated = content.replace(sectionRegex, section);
251
+ writeFileSync(filePath, updated, "utf-8");
202
252
  }
203
253
  // ─── Parser ───────────────────────────────────────────────────────────────────
204
254
  /**
@@ -221,6 +271,7 @@ function parseCapturesContent(content) {
221
271
  const resolution = extractBoldField(body, "Resolution");
222
272
  const rationale = extractBoldField(body, "Rationale");
223
273
  const resolvedAt = extractBoldField(body, "Resolved");
274
+ const milestoneId = extractBoldField(body, "Milestone");
224
275
  const executedAt = extractBoldField(body, "Executed");
225
276
  if (!text || !timestamp)
226
277
  continue;
@@ -236,6 +287,7 @@ function parseCapturesContent(content) {
236
287
  ...(resolution ? { resolution } : {}),
237
288
  ...(rationale ? { rationale } : {}),
238
289
  ...(resolvedAt ? { resolvedAt } : {}),
290
+ ...(milestoneId ? { resolvedInMilestone: milestoneId } : {}),
239
291
  ...(executedAt ? { executed: true } : {}),
240
292
  });
241
293
  }