gsd-pi 2.77.0-dev.c9c8932c6 → 2.77.0-dev.cfd69e714

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 (708) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/cli-web-branch.d.ts +1 -0
  4. package/dist/cli-web-branch.js +3 -0
  5. package/dist/cli.js +24 -2
  6. package/dist/headless.js +49 -4
  7. package/dist/provider-migrations.d.ts +18 -0
  8. package/dist/provider-migrations.js +14 -0
  9. package/dist/resource-loader.d.ts +40 -0
  10. package/dist/resource-loader.js +32 -13
  11. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  12. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  13. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  14. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  15. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  16. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  17. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  18. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +495 -27
  19. package/dist/resources/extensions/github-sync/templates.js +103 -0
  20. package/dist/resources/extensions/google-search/index.js +3 -2
  21. package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
  22. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  23. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  24. package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
  25. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
  26. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  27. package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +166 -29
  29. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +181 -64
  32. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  33. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  34. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  35. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
  36. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  37. package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
  38. package/dist/resources/extensions/gsd/auto-worktree.js +180 -34
  39. package/dist/resources/extensions/gsd/auto.js +80 -21
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  41. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  42. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -6
  43. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  45. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
  46. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  47. package/dist/resources/extensions/gsd/component-types.js +69 -0
  48. package/dist/resources/extensions/gsd/context-store.js +23 -7
  49. package/dist/resources/extensions/gsd/detection.js +49 -1
  50. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  52. package/dist/resources/extensions/gsd/file-lock.js +49 -9
  53. package/dist/resources/extensions/gsd/forensics.js +106 -0
  54. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  55. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  56. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  57. package/dist/resources/extensions/gsd/git-service.js +127 -2
  58. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  59. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  60. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
  61. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  62. package/dist/resources/extensions/gsd/journal.js +17 -2
  63. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  64. package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
  65. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  66. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  67. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  68. package/dist/resources/extensions/gsd/model-router.js +6 -0
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  70. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  71. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  72. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  73. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  74. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  75. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  76. package/dist/resources/extensions/gsd/reports.js +5 -4
  77. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  78. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  79. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  80. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  81. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  83. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  84. package/dist/resources/extensions/gsd/state.js +69 -58
  85. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  86. package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
  87. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
  88. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  89. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  90. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  91. package/dist/resources/extensions/gsd/uok/audit.js +18 -2
  92. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  93. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  94. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  95. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  96. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  97. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  98. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  99. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  100. package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
  101. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  102. package/dist/resources/extensions/gsd/worktree-manager.js +86 -8
  103. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  104. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  105. package/dist/resources/extensions/mcp-client/auth.js +10 -1
  106. package/dist/resources/extensions/mcp-client/index.js +121 -10
  107. package/dist/resources/extensions/ollama/index.js +5 -1
  108. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  109. package/dist/resources/skills/create-skill/SKILL.md +2 -2
  110. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  111. package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  112. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  113. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  116. package/dist/web/standalone/.next/build-manifest.json +3 -3
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  207. package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
  208. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  211. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/{webpack-1832629448831fdc.js → webpack-2e68521d7c82f7c2.js} +1 -1
  217. package/package.json +4 -5
  218. package/packages/daemon/src/logger.ts +4 -3
  219. package/packages/mcp-server/README.md +3 -3
  220. package/packages/mcp-server/dist/env-writer.d.ts +1 -0
  221. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
  222. package/packages/mcp-server/dist/env-writer.js +74 -6
  223. package/packages/mcp-server/dist/env-writer.js.map +1 -1
  224. package/packages/mcp-server/dist/server.d.ts +24 -0
  225. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  226. package/packages/mcp-server/dist/server.js +111 -87
  227. package/packages/mcp-server/dist/server.js.map +1 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/src/env-writer.test.ts +79 -1
  232. package/packages/mcp-server/src/env-writer.ts +76 -6
  233. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  234. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  235. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  236. package/packages/mcp-server/src/server.ts +158 -105
  237. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  238. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  239. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  240. package/packages/native/package.json +1 -1
  241. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  242. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  243. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  244. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  245. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  246. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  247. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  248. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  249. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  250. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  251. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  252. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  253. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  255. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  256. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  257. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  258. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  259. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  261. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  262. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  263. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  264. package/packages/pi-ai/dist/models.test.js +36 -11
  265. package/packages/pi-ai/dist/models.test.js.map +1 -1
  266. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  267. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  268. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  269. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  270. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  271. package/packages/pi-ai/src/models.test.ts +48 -11
  272. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  273. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  274. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  276. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  278. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +21 -16
  282. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
  285. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
  286. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
  287. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  288. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  290. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  292. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  294. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  296. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  299. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  301. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  303. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  305. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
  307. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
  309. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
  311. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  313. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  315. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -0
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  340. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  347. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  352. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  353. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  354. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  355. package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
  356. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +24 -17
  357. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  358. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  359. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  360. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  361. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  362. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  363. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  364. package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
  365. package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
  366. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  367. package/packages/pi-coding-agent/src/index.ts +1 -0
  368. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
  369. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  370. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  371. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
  372. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  374. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  375. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  376. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  377. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  378. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  379. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  380. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  381. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  382. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  383. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  384. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +51 -6
  385. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  386. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  387. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  388. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  389. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  390. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  391. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  392. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  393. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  394. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  395. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  396. package/packages/pi-tui/dist/components/editor.js +19 -0
  397. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  398. package/packages/pi-tui/dist/components/image.test.js +6 -5
  399. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  400. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  401. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  403. package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
  404. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/stdin-buffer.js +20 -0
  406. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  407. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  408. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  409. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +62 -6
  410. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  411. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  412. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  413. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  414. package/packages/pi-tui/src/components/editor.ts +22 -0
  415. package/packages/pi-tui/src/components/image.test.ts +10 -5
  416. package/packages/pi-tui/src/editor-component.ts +3 -0
  417. package/packages/pi-tui/src/stdin-buffer.ts +26 -0
  418. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  419. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  420. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  421. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  422. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  423. package/scripts/install.js +15 -1
  424. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  425. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  426. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  427. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  428. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  429. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  430. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  431. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +532 -29
  432. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +941 -91
  433. package/src/resources/extensions/github-sync/templates.ts +151 -0
  434. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  435. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  436. package/src/resources/extensions/google-search/index.ts +3 -2
  437. package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
  438. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  439. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  440. package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
  441. package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
  442. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  443. package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
  444. package/src/resources/extensions/gsd/auto-dispatch.ts +176 -29
  445. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  446. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  447. package/src/resources/extensions/gsd/auto-post-unit.ts +193 -73
  448. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  449. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  450. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  451. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
  452. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  453. package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
  454. package/src/resources/extensions/gsd/auto-worktree.ts +190 -31
  455. package/src/resources/extensions/gsd/auto.ts +95 -23
  456. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  457. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  458. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -6
  459. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  460. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  461. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
  462. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  463. package/src/resources/extensions/gsd/component-types.ts +362 -0
  464. package/src/resources/extensions/gsd/context-store.ts +25 -8
  465. package/src/resources/extensions/gsd/detection.ts +58 -1
  466. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  468. package/src/resources/extensions/gsd/file-lock.ts +84 -11
  469. package/src/resources/extensions/gsd/forensics.ts +118 -1
  470. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  471. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  472. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  473. package/src/resources/extensions/gsd/git-service.ts +150 -2
  474. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  475. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  476. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
  477. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  478. package/src/resources/extensions/gsd/journal.ts +38 -3
  479. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  480. package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
  481. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  482. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  483. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  484. package/src/resources/extensions/gsd/model-router.ts +6 -0
  485. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  486. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  487. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  488. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  489. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  490. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  491. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  492. package/src/resources/extensions/gsd/reports.ts +5 -4
  493. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  494. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  495. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  496. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  497. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  498. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  499. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  500. package/src/resources/extensions/gsd/state.ts +76 -66
  501. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  502. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  503. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  505. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  506. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -285
  507. package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
  508. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  509. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  510. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  511. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  512. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  513. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  514. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  515. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  516. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  517. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  518. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  519. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  520. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  521. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  522. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  523. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  524. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  525. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  526. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  527. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  528. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  529. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  530. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  531. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  532. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  533. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  534. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  535. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  536. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  537. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  538. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  539. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  540. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  541. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  542. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  543. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  544. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  545. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  546. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  547. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  548. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  549. package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
  550. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  551. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  552. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  553. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  554. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  555. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  556. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  557. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  558. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
  559. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  560. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  561. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  562. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  563. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  564. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  565. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  566. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  567. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  568. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  569. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +47 -0
  570. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  571. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  572. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  573. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  574. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  575. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  576. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  577. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  578. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  579. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  580. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  581. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  582. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  583. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  584. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  585. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +54 -41
  586. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +213 -0
  587. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  588. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  589. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
  590. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  591. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  592. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  593. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  594. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
  595. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  596. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  597. package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
  598. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  599. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  600. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  601. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  602. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  603. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  604. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  605. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  606. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  607. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  608. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  609. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  610. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  611. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  612. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  613. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  614. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  615. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
  616. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  617. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  618. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  619. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  620. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  621. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  622. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  623. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  624. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  625. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
  626. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
  627. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  628. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  629. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  630. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  631. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  632. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  633. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  634. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  635. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  636. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  637. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  638. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  639. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  640. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  641. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  642. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  643. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  644. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  645. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  646. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  647. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  648. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  649. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  650. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  651. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  652. package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
  653. package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
  654. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  655. package/src/resources/extensions/gsd/types.ts +3 -3
  656. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  657. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  658. package/src/resources/extensions/gsd/uok/audit.ts +20 -2
  659. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  660. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  661. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  662. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  663. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  664. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  665. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  666. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  667. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  668. package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
  669. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  670. package/src/resources/extensions/gsd/worktree-manager.ts +109 -7
  671. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  672. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  673. package/src/resources/extensions/mcp-client/auth.ts +12 -1
  674. package/src/resources/extensions/mcp-client/index.ts +132 -11
  675. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  676. package/src/resources/extensions/ollama/index.ts +5 -1
  677. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  678. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  679. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  680. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  681. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  682. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  683. package/src/resources/skills/create-skill/SKILL.md +2 -2
  684. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  685. package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  686. package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  687. package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
  688. package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +0 -9
  689. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  690. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  691. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  692. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  693. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  694. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  695. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  696. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  697. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  698. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  699. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  700. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  701. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  702. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  703. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  704. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  705. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  706. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  707. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
  708. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
@@ -87,20 +87,21 @@ export function clearInFlightTools(): void {
87
87
  // ─── Tool invocation error classification (#2883) ────────────────────────
88
88
 
89
89
  /**
90
- * Patterns that indicate a tool invocation failed due to malformed or truncated
91
- * JSON arguments — as opposed to a normal business-logic error from the tool
92
- * handler. When these errors occur, retrying the same unit will produce the same
93
- * failure, so the retry loop must be broken.
90
+ * Patterns that indicate a tool invocation failed deterministically before
91
+ * useful work could be completed — as opposed to a normal business-logic error
92
+ * from the tool handler. When these errors occur, retrying the same unit will
93
+ * produce the same failure, so the retry loop must be broken.
94
94
  */
95
95
  const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON/i;
96
+ const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
96
97
 
97
98
  /**
98
- * Returns true if the error message indicates a tool invocation failure due to
99
- * malformed/truncated arguments (as opposed to a normal tool execution error).
99
+ * Returns true if the error message indicates a deterministic invocation or
100
+ * policy failure (as opposed to a normal tool execution error).
100
101
  */
101
102
  export function isToolInvocationError(errorMsg: string): boolean {
102
103
  if (!errorMsg) return false;
103
- return TOOL_INVOCATION_ERROR_RE.test(errorMsg);
104
+ return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
104
105
  }
105
106
 
106
107
  /**
@@ -112,3 +113,46 @@ export function isQueuedUserMessageSkip(errorMsg: string): boolean {
112
113
  if (!errorMsg) return false;
113
114
  return /^Skipped due to queued user message\.?$/i.test(errorMsg.trim());
114
115
  }
116
+
117
+ // ─── Deterministic policy error classification (#4973, #4974) ──────────────
118
+
119
+ /**
120
+ * Known deterministic policy error substrings. Each entry is a stable string
121
+ * that will appear in the tool error text content when the corresponding
122
+ * policy gate fires. Retrying these errors will always produce the same outcome.
123
+ *
124
+ * Add new entries here as new deterministic gates are introduced. Do NOT use
125
+ * regex — explicit substrings keep the list auditable.
126
+ */
127
+ export const DETERMINISTIC_POLICY_ERROR_STRINGS = [
128
+ // gsd_summary_save write-gate: CONTEXT artifact blocked pending depth verification (#4973).
129
+ // Matches the fallback text in workflow-tool-executors.ts and the verbose reason
130
+ // from shouldBlockContextArtifactSaveInSnapshot at write-gate.ts:432-442.
131
+ "context write blocked",
132
+ "CONTEXT without depth verification",
133
+ // Raw write tool gate (#4973): shouldBlockContextWrite at write-gate.ts:390-399 emits
134
+ // "Cannot write to milestone CONTEXT.md without depth verification." for direct
135
+ // write tool calls to *-CONTEXT.md paths (different code path than gsd_summary_save).
136
+ "CONTEXT.md without depth verification",
137
+ ] as const;
138
+
139
+ /**
140
+ * Returns true if the error message indicates a deterministic policy gate
141
+ * blocked the tool call before execution. Retrying the same unit without
142
+ * changing behavior will hit the same gate, so auto-mode should pause instead
143
+ * of re-dispatching.
144
+ *
145
+ * Combines the regex-based gate set from #4974 (HARD BLOCK / queue planning /
146
+ * STATE.md / mechanical gate) and the substring-based set from #4973 (context
147
+ * write block / CONTEXT depth verification). Both branches landed on main
148
+ * independently and their parallel `isDeterministicPolicyError` declarations
149
+ * were not deduplicated at merge — this consolidated form preserves both
150
+ * matchers under a single export.
151
+ */
152
+ export function isDeterministicPolicyError(errorMsg: string): boolean {
153
+ if (!errorMsg) return false;
154
+ return (
155
+ DETERMINISTIC_POLICY_ERROR_RE.test(errorMsg) ||
156
+ DETERMINISTIC_POLICY_ERROR_STRINGS.some(s => errorMsg.includes(s))
157
+ );
158
+ }
@@ -45,9 +45,20 @@ export async function closeoutUnit(
45
45
  const { buildMemoryLLMCall, extractMemoriesFromUnit } = await import('./memory-extractor.js');
46
46
  const llmCallFn = buildMemoryLLMCall(ctx);
47
47
  if (llmCallFn) {
48
- extractMemoriesFromUnit(activityFile, unitType, unitId, llmCallFn).catch((err) => {
49
- logWarning("engine", `memory extraction failed for ${unitType}/${unitId}: ${(err as Error).message}`);
50
- });
48
+ // Awaited: a fire-and-forget here lets memory-extractor writes land in
49
+ // .gsd/ after closeoutUnit returns but before the milestone merge
50
+ // runs, which made the working tree appear dirty to `git merge
51
+ // --squash` (root cause class of #4704). Completion latency is now
52
+ // bounded by the extractor's LLM call, which is the acceptable price
53
+ // for not racing the merge boundary.
54
+ try {
55
+ await extractMemoriesFromUnit(activityFile, unitType, unitId, llmCallFn);
56
+ } catch (err) {
57
+ logWarning(
58
+ "engine",
59
+ `memory extraction failed for ${unitType}/${unitId}: ${(err as Error).message}`,
60
+ );
61
+ }
51
62
  }
52
63
  } catch (err) { /* non-fatal */
53
64
  logWarning("engine", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -26,6 +26,9 @@ import {
26
26
  isDbAvailable,
27
27
  getMilestone,
28
28
  getMilestoneSlices,
29
+ closeDatabase,
30
+ openDatabase,
31
+ getDbPath,
29
32
  } from "./gsd-db.js";
30
33
  import { atomicWriteSync } from "./atomic-write.js";
31
34
  import { execFileSync } from "node:child_process";
@@ -95,6 +98,66 @@ const ROOT_STATE_FILES = [
95
98
  // because the project root is authoritative for preferences (#2684).
96
99
  ] as const;
97
100
 
101
+ /**
102
+ * Pop a stash entry by tracking the unique marker embedded in its message so
103
+ * concurrent stash operations against the same project root cannot cause us to
104
+ * pop the wrong entry.
105
+ *
106
+ * If `stashMarker` is null or no longer present in the stash list (e.g. a
107
+ * concurrent process popped/dropped it), leaves the stash list untouched and
108
+ * returns null.
109
+ *
110
+ * Throws on pop failure so callers can handle conflict cases the same way
111
+ * they would with the prior `git stash pop` form. When throwing after a
112
+ * targeted pop attempt, the error is annotated with the targeted stash ref.
113
+ *
114
+ * (Issue #4980 HIGH-6)
115
+ */
116
+ function popStashByRef(basePath: string, stashMarker: string | null): string | null {
117
+ let popArg: string | null = null;
118
+ if (stashMarker) {
119
+ try {
120
+ const list = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
121
+ cwd: basePath,
122
+ stdio: ["ignore", "pipe", "pipe"],
123
+ encoding: "utf-8",
124
+ }).trim().split("\n").filter(Boolean);
125
+ for (const entry of list) {
126
+ const [ref, subject] = entry.split("\0");
127
+ if (ref && subject?.includes(stashMarker)) {
128
+ popArg = ref;
129
+ break;
130
+ }
131
+ }
132
+ } catch (err) {
133
+ logWarning("worktree", `stash list lookup failed; leaving stash untouched: ${err instanceof Error ? err.message : String(err)}`);
134
+ }
135
+ }
136
+ if (!popArg) {
137
+ logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic pop");
138
+ return null;
139
+ }
140
+ try {
141
+ execFileSync("git", ["stash", "pop", popArg], {
142
+ cwd: basePath,
143
+ stdio: ["ignore", "pipe", "pipe"],
144
+ encoding: "utf-8",
145
+ });
146
+ } catch (err) {
147
+ if (err && typeof err === "object") {
148
+ (err as { stashRef?: string }).stashRef = popArg;
149
+ }
150
+ throw err;
151
+ }
152
+ return popArg;
153
+ }
154
+
155
+ function stashRefFromError(err: unknown): string | null {
156
+ if (!err || typeof err !== "object") return null;
157
+ const stashRef = (err as { stashRef?: unknown }).stashRef;
158
+ return typeof stashRef === "string" && stashRef.length > 0 ? stashRef : null;
159
+ }
160
+
98
161
  /**
99
162
  * Check if two filesystem paths resolve to the same real location.
100
163
  * Returns false if either path cannot be resolved (e.g. doesn't exist).
@@ -968,6 +1031,32 @@ export function enterBranchModeForMilestone(
968
1031
  validatedPrefBranch ??
969
1032
  nativeDetectMainBranch(basePath);
970
1033
 
1034
+ // TOCTOU ancestry guard (Issue #4980 HIGH-3).
1035
+ //
1036
+ // The outer `branchExists` check at line 1012 is racy: a concurrent
1037
+ // process (parallel-orchestrator worker, side-by-side `gsd` instance,
1038
+ // or manual `git branch` invocation) may have created the branch with
1039
+ // real commits between that check and this point. `nativeBranchForceReset`
1040
+ // does `git branch -f`, which silently overwrites the branch ref —
1041
+ // orphaning any commits not reachable from `startPoint`. Re-check
1042
+ // immediately before the destructive call and refuse if the branch
1043
+ // suddenly exists with non-ancestor commits.
1044
+ //
1045
+ // Note: under single-threaded execution this is rarely reached, but it
1046
+ // is NOT dead code — it is the only barrier against a TOCTOU-induced
1047
+ // commit loss in this code path.
1048
+ const concurrentlyCreated = nativeBranchExists(basePath, branch);
1049
+ if (
1050
+ concurrentlyCreated &&
1051
+ !nativeIsAncestor(basePath, branch, startPoint)
1052
+ ) {
1053
+ throw new GSDError(
1054
+ GSD_GIT_ERROR,
1055
+ `Branch "${branch}" was created concurrently with commits not reachable from "${startPoint}". ` +
1056
+ `Refusing to force-reset — would orphan prior work. ` +
1057
+ `Resume the existing milestone or run \`git branch -D ${branch}\` to discard.`,
1058
+ );
1059
+ }
971
1060
  // nativeBranchForceReset creates (or resets) branch at startPoint,
972
1061
  // then checkout switches HEAD to it.
973
1062
  nativeBranchForceReset(basePath, branch, startPoint);
@@ -1573,7 +1662,20 @@ export function mergeMilestoneToMain(
1573
1662
 
1574
1663
  // 5. Checkout integration branch (skip if already current — avoids git error
1575
1664
  // when main is already checked out in the project-root worktree, #757)
1665
+ //
1666
+ // Refuse to proceed if the project root is in detached HEAD state. Silently
1667
+ // running `nativeCheckoutBranch(mainBranch)` on a detached HEAD would
1668
+ // abandon the user's deliberately-checked-out commit (mid-bisect, reviewing
1669
+ // a tag, CI checkout-sha) without warning. (Issue #4980 HIGH-10)
1576
1670
  const currentBranchAtBase = nativeGetCurrentBranch(originalBasePath_);
1671
+ if (!currentBranchAtBase || currentBranchAtBase.length === 0) {
1672
+ process.chdir(previousCwd);
1673
+ throw new GSDError(
1674
+ GSD_GIT_ERROR,
1675
+ `Project root is in detached HEAD state — cannot perform milestone merge. ` +
1676
+ `Checkout an integration branch (e.g. \`git checkout ${mainBranch}\`) before resuming.`,
1677
+ );
1678
+ }
1577
1679
  if (currentBranchAtBase !== mainBranch) {
1578
1680
  nativeCheckoutBranch(originalBasePath_, mainBranch);
1579
1681
  }
@@ -1668,22 +1770,51 @@ export function mergeMilestoneToMain(
1668
1770
  const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
1669
1771
  const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
1670
1772
  const shelteredDirs: string[] = [];
1773
+ let shelterRestored = false;
1671
1774
 
1672
1775
  // Helper: restore sheltered milestone directories (#2505).
1673
1776
  // Called on both success and error paths to ensure queued CONTEXT files
1674
- // are never permanently lost.
1777
+ // are never permanently lost. Idempotent — the error path may fire after
1778
+ // the success path has already restored and removed the shelter dir; a
1779
+ // second call is a no-op instead of logging a misleading "shelter restore
1780
+ // failed: ENOENT" error for shelter sources that were cleaned up legitimately.
1675
1781
  const restoreShelter = (): void => {
1782
+ if (shelterRestored) return;
1783
+ shelterRestored = true;
1676
1784
  if (shelteredDirs.length === 0) return;
1785
+ let restoreFailed = false;
1677
1786
  for (const dirName of shelteredDirs) {
1787
+ const src = join(shelterDir, dirName);
1788
+ // If the shelter source is missing the restore cannot proceed for this
1789
+ // entry. Distinguish "legitimately missing" (shelter dir removed by a
1790
+ // prior successful restore or never copied) from a surprising ENOENT
1791
+ // inside an otherwise-populated shelter.
1792
+ if (!existsSync(src)) {
1793
+ logWarning(
1794
+ "worktree",
1795
+ `shelter source missing for ${dirName}; skipping restore (shelter already cleaned or entry never staged)`,
1796
+ );
1797
+ continue;
1798
+ }
1678
1799
  try {
1679
1800
  mkdirSync(milestonesDir, { recursive: true });
1680
- cpSync(join(shelterDir, dirName), join(milestonesDir, dirName), { recursive: true, force: true });
1801
+ cpSync(src, join(milestonesDir, dirName), { recursive: true, force: true });
1681
1802
  } catch (err) { /* best-effort */
1682
- logError("worktree", `shelter restore failed: ${err instanceof Error ? err.message : String(err)}`);
1803
+ restoreFailed = true;
1804
+ logError("worktree", `shelter restore failed (${dirName}): ${err instanceof Error ? err.message : String(err)}`);
1683
1805
  }
1684
1806
  }
1685
- try { rmSync(shelterDir, { recursive: true, force: true }); } catch (err) { /* best-effort */
1686
- logWarning("worktree", `shelter cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1807
+ // Preserve the shelter if any per-entry restore failed it is the only
1808
+ // surviving copy of the queued milestone dirs (sources were deleted during
1809
+ // shelter). Deleting it here would permanently lose those files (#2505).
1810
+ if (restoreFailed) {
1811
+ logWarning("worktree", `shelter retained at ${shelterDir} — manual recovery required for unrestored entries`);
1812
+ return;
1813
+ }
1814
+ if (existsSync(shelterDir)) {
1815
+ try { rmSync(shelterDir, { recursive: true, force: true }); } catch (err) { /* best-effort */
1816
+ logWarning("worktree", `shelter cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1817
+ }
1687
1818
  }
1688
1819
  };
1689
1820
 
@@ -1720,7 +1851,27 @@ export function mergeMilestoneToMain(
1720
1851
  // entries (e.g. a gitignored `.gsd` symlink under ADR-002) (#4573).
1721
1852
  // Queued CONTEXT files under `.gsd/milestones/*` are already sheltered
1722
1853
  // in step 7 above, so they won't be swept into the stash.
1854
+ // On Windows, SQLite holds mandatory file locks on the gsd.db WAL/SHM
1855
+ // sidecars while the connection is open. `git stash --include-untracked`
1856
+ // walks those files and fails with EBUSY (#4704). Close the DB before
1857
+ // stashing so Windows releases the handles; reopen after. No-op on
1858
+ // POSIX, where advisory locks don't block git.
1859
+ const needsDbCycle = process.platform === "win32" && isDbAvailable();
1860
+ const dbPathToReopen = needsDbCycle ? getDbPath() : null;
1861
+ if (needsDbCycle) {
1862
+ try {
1863
+ closeDatabase();
1864
+ } catch (err) {
1865
+ logWarning("worktree", `pre-stash db close failed: ${err instanceof Error ? err.message : String(err)}`);
1866
+ }
1867
+ }
1868
+
1723
1869
  let stashed = false;
1870
+ // Embed a unique marker in the stash message so subsequent pop/drop targets
1871
+ // the entry we created, not whatever happens to be at stash@{0} (concurrent
1872
+ // milestone merges share the project-root stash list and can shift positions).
1873
+ // (Issue #4980 HIGH-6)
1874
+ let stashMarker: string | null = null;
1724
1875
  try {
1725
1876
  const status = execFileSync("git", ["status", "--porcelain"], {
1726
1877
  cwd: originalBasePath_,
@@ -1728,9 +1879,10 @@ export function mergeMilestoneToMain(
1728
1879
  encoding: "utf-8",
1729
1880
  }).trim();
1730
1881
  if (status) {
1882
+ stashMarker = `gsd-pre-merge:${milestoneId}:${process.pid}:${Date.now()}:${process.hrtime.bigint().toString(36)}`;
1731
1883
  execFileSync(
1732
1884
  "git",
1733
- ["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId}`],
1885
+ ["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId} [${stashMarker}]`],
1734
1886
  { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
1735
1887
  );
1736
1888
  stashed = true;
@@ -1741,6 +1893,14 @@ export function mergeMilestoneToMain(
1741
1893
  logWarning("worktree", `git stash failed: ${err instanceof Error ? err.message : String(err)}`);
1742
1894
  }
1743
1895
 
1896
+ if (needsDbCycle && dbPathToReopen) {
1897
+ try {
1898
+ openDatabase(dbPathToReopen);
1899
+ } catch (err) {
1900
+ logWarning("worktree", `post-stash db reopen failed: ${err instanceof Error ? err.message : String(err)}`);
1901
+ }
1902
+ }
1903
+
1744
1904
  // 7b. Clean up stale merge state before attempting squash merge (#2912).
1745
1905
  // A leftover MERGE_HEAD (from a previous failed merge, libgit2 native path,
1746
1906
  // or interrupted operation) causes `git merge --squash` to refuse with
@@ -1779,11 +1939,7 @@ export function mergeMilestoneToMain(
1779
1939
  // Pop stash before throwing so local work is not lost.
1780
1940
  if (stashed) {
1781
1941
  try {
1782
- execFileSync("git", ["stash", "pop"], {
1783
- cwd: originalBasePath_,
1784
- stdio: ["ignore", "pipe", "pipe"],
1785
- encoding: "utf-8",
1786
- });
1942
+ popStashByRef(originalBasePath_, stashMarker);
1787
1943
  } catch (err) { /* stash pop conflict is non-fatal */
1788
1944
  logWarning("worktree", `git stash pop failed: ${err instanceof Error ? err.message : String(err)}`);
1789
1945
  }
@@ -1855,11 +2011,7 @@ export function mergeMilestoneToMain(
1855
2011
  // Pop stash before throwing so local work is not lost (#2151).
1856
2012
  if (stashed) {
1857
2013
  try {
1858
- execFileSync("git", ["stash", "pop"], {
1859
- cwd: originalBasePath_,
1860
- stdio: ["ignore", "pipe", "pipe"],
1861
- encoding: "utf-8",
1862
- });
2014
+ popStashByRef(originalBasePath_, stashMarker);
1863
2015
  } catch (err) { /* stash pop conflict is non-fatal */
1864
2016
  logWarning("worktree", `git stash pop failed: ${err instanceof Error ? err.message : String(err)}`);
1865
2017
  }
@@ -1907,13 +2059,11 @@ export function mergeMilestoneToMain(
1907
2059
  // or the commit content. Conflict on pop is non-fatal — the stash entry is
1908
2060
  // preserved and the user can resolve manually with `git stash pop`.
1909
2061
  if (stashed) {
2062
+ let stashRefForDrop: string | null = null;
1910
2063
  try {
1911
- execFileSync("git", ["stash", "pop"], {
1912
- cwd: originalBasePath_,
1913
- stdio: ["ignore", "pipe", "pipe"],
1914
- encoding: "utf-8",
1915
- });
2064
+ stashRefForDrop = popStashByRef(originalBasePath_, stashMarker);
1916
2065
  } catch (e) {
2066
+ stashRefForDrop = stashRefFromError(e);
1917
2067
  logWarning("worktree", `git stash pop failed, attempting conflict resolution: ${(e as Error).message}`);
1918
2068
  // Stash pop after squash merge can conflict on .gsd/ state files that
1919
2069
  // diverged between branches. Left unresolved, these UU entries block
@@ -1942,22 +2092,31 @@ export function mergeMilestoneToMain(
1942
2092
  }
1943
2093
  }
1944
2094
 
1945
- if (nonGsdUU.length === 0) {
2095
+ if (gsdUU.length > 0 && nonGsdUU.length === 0) {
1946
2096
  // All conflicts were .gsd/ files — safe to drop the stash
1947
- try {
1948
- execFileSync("git", ["stash", "drop"], {
1949
- cwd: originalBasePath_,
1950
- stdio: ["ignore", "pipe", "pipe"],
1951
- encoding: "utf-8",
1952
- });
1953
- } catch (err) { /* stash may already be consumed */
1954
- logWarning("worktree", `git stash drop failed: ${err instanceof Error ? err.message : String(err)}`);
2097
+ if (stashRefForDrop) {
2098
+ try {
2099
+ execFileSync("git", ["stash", "drop", stashRefForDrop], {
2100
+ cwd: originalBasePath_,
2101
+ stdio: ["ignore", "pipe", "pipe"],
2102
+ encoding: "utf-8",
2103
+ });
2104
+ } catch (err) { /* stash may already be consumed */
2105
+ logWarning("worktree", `git stash drop failed: ${err instanceof Error ? err.message : String(err)}`);
2106
+ }
2107
+ } else {
2108
+ logWarning("worktree", "recorded stash entry could not be resolved; skipping automatic drop");
1955
2109
  }
1956
- } else {
2110
+ } else if (nonGsdUU.length > 0) {
1957
2111
  // Non-.gsd conflicts remain — leave stash for manual resolution
1958
2112
  logWarning("reconcile", "Stash pop conflict on non-.gsd files after merge", {
1959
2113
  files: nonGsdUU.join(", "),
1960
2114
  });
2115
+ } else {
2116
+ logWarning(
2117
+ "worktree",
2118
+ "git stash pop failed without resolvable conflict files; leaving stash for manual recovery",
2119
+ );
1961
2120
  }
1962
2121
  }
1963
2122
  }
@@ -84,10 +84,11 @@ import {
84
84
  clearInFlightTools,
85
85
  isToolInvocationError,
86
86
  isQueuedUserMessageSkip,
87
+ isDeterministicPolicyError,
87
88
  } from "./auto-tool-tracking.js";
88
89
  import { closeoutUnit } from "./auto-unit-closeout.js";
89
90
  import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
90
- import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
91
+ import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
91
92
  import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
92
93
  import {
93
94
  checkPostUnitHooks,
@@ -169,6 +170,7 @@ import {
169
170
  buildLoopRemediationSteps,
170
171
  reconcileMergeState,
171
172
  } from "./auto-recovery.js";
173
+ import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
172
174
  import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
173
175
  import { getErrorMessage } from "./error-utils.js";
174
176
  import { recoverFailedMigration } from "./migrate-external.js";
@@ -231,9 +233,7 @@ import { reorderForCaching } from "./prompt-ordering.js";
231
233
 
232
234
  import {
233
235
  AutoSession,
234
- MAX_UNIT_DISPATCHES,
235
236
  STUB_RECOVERY_THRESHOLD,
236
- MAX_LIFETIME_DISPATCHES,
237
237
  NEW_SESSION_TIMEOUT_MS,
238
238
  } from "./auto/session.js";
239
239
  import type {
@@ -242,9 +242,7 @@ import type {
242
242
  StartModel,
243
243
  } from "./auto/session.js";
244
244
  export {
245
- MAX_UNIT_DISPATCHES,
246
245
  STUB_RECOVERY_THRESHOLD,
247
- MAX_LIFETIME_DISPATCHES,
248
246
  NEW_SESSION_TIMEOUT_MS,
249
247
  } from "./auto/session.js";
250
248
  export type {
@@ -336,6 +334,25 @@ function normalizeSessionFilePath(raw: unknown): string | null {
336
334
  return candidate;
337
335
  }
338
336
 
337
+ function synthesizePausedSessionRecovery(
338
+ basePath: string,
339
+ unitType: string,
340
+ unitId: string,
341
+ sessionFile: string,
342
+ ): ReturnType<typeof synthesizeCrashRecovery> {
343
+ const activityDir = join(gsdRoot(basePath), "activity");
344
+ return synthesizeCrashRecovery(basePath, unitType, unitId, sessionFile, activityDir);
345
+ }
346
+
347
+ export function _synthesizePausedSessionRecoveryForTest(
348
+ basePath: string,
349
+ unitType: string,
350
+ unitId: string,
351
+ sessionFile: string,
352
+ ): ReturnType<typeof synthesizeCrashRecovery> {
353
+ return synthesizePausedSessionRecovery(basePath, unitType, unitId, sessionFile);
354
+ }
355
+
339
356
  export function startAutoDetached(
340
357
  ctx: ExtensionCommandContext,
341
358
  pi: ExtensionAPI,
@@ -485,6 +502,11 @@ export function isAutoActive(): boolean {
485
502
  return s.active;
486
503
  }
487
504
 
505
+ /** Test-only seam for validating auto-mode guards (#4704). Do not use in production code. */
506
+ export function _setAutoActiveForTest(active: boolean): void {
507
+ s.active = active;
508
+ }
509
+
488
510
  export function isAutoPaused(): boolean {
489
511
  return s.paused;
490
512
  }
@@ -538,12 +560,14 @@ export function markToolEnd(toolCallId: string): void {
538
560
  /**
539
561
  * Record a tool invocation error on the current session (#2883).
540
562
  * Called from tool_execution_end when a GSD tool fails with isError.
541
- * Only stores the error if it matches the tool-invocation-error pattern
542
- * (malformed/truncated JSON), not normal business-logic errors.
563
+ * Stores the error if it matches:
564
+ * - tool-invocation-error pattern (malformed/truncated JSON)
565
+ * - queued-user-message skip pattern
566
+ * - deterministic policy rejection (#4973, e.g. context_write_blocked)
543
567
  */
544
568
  export function recordToolInvocationError(toolName: string, errorMsg: string): void {
545
569
  if (!s.active) return;
546
- if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg)) {
570
+ if (isToolInvocationError(errorMsg) || isQueuedUserMessageSkip(errorMsg) || isDeterministicPolicyError(errorMsg)) {
547
571
  s.lastToolInvocationError = `${toolName}: ${errorMsg}`;
548
572
  }
549
573
  }
@@ -790,6 +814,43 @@ export async function stopAuto(
790
814
  const loadedPreferences = loadEffectiveGSDPreferences(s.basePath || undefined)?.preferences;
791
815
  const reasonSuffix = reason ? ` — ${reason}` : "";
792
816
 
817
+ // #4764 — telemetry: record the exit reason and whether the current milestone
818
+ // was merged before we entered stopAuto. This is the producer-side signal for
819
+ // the #4761 orphan class: milestoneMerged=false + currentMilestoneId present
820
+ // is exactly the pattern that strands work.
821
+ try {
822
+ const { emitAutoExit } = await import("./worktree-telemetry.js");
823
+ type AutoExitReason =
824
+ | "pause" | "stop" | "blocked" | "merge-conflict" | "merge-failed"
825
+ | "slice-merge-conflict" | "all-complete" | "no-active-milestone" | "other";
826
+ // Normalize the free-form reason to a closed set so the telemetry
827
+ // aggregator buckets stably. Raw detail is preserved in the phases.ts
828
+ // notification and the notify'd error string.
829
+ const rawReason = reason ?? "stop";
830
+ const normalizedReason: AutoExitReason = rawReason.startsWith("Blocked:")
831
+ ? "blocked"
832
+ : rawReason.startsWith("Merge conflict")
833
+ ? "merge-conflict"
834
+ : rawReason.startsWith("Merge error") || rawReason.startsWith("Merge failed")
835
+ ? "merge-failed"
836
+ : rawReason.startsWith("slice-merge-conflict")
837
+ ? "slice-merge-conflict"
838
+ : rawReason === "All milestones complete"
839
+ ? "all-complete"
840
+ : rawReason === "No active milestone"
841
+ ? "no-active-milestone"
842
+ : rawReason === "stop" || rawReason === "pause"
843
+ ? rawReason
844
+ : "other";
845
+ emitAutoExit(s.originalBasePath || s.basePath, {
846
+ reason: normalizedReason,
847
+ milestoneId: s.currentMilestoneId ?? undefined,
848
+ milestoneMerged: s.milestoneMergedInPhases === true,
849
+ });
850
+ } catch (err) {
851
+ logWarning("engine", `auto-exit telemetry failed: ${err instanceof Error ? err.message : String(err)}`);
852
+ }
853
+
793
854
  try {
794
855
  // ── Step 1: Timers and locks ──
795
856
  try {
@@ -1045,6 +1106,12 @@ export async function stopAuto(
1045
1106
  restoreProjectRootEnv();
1046
1107
  restoreMilestoneLockEnv();
1047
1108
 
1109
+ // Drop the active-tool baseline so a subsequent /gsd auto run on the
1110
+ // same `pi` instance recaptures from the live tool set rather than
1111
+ // restoring this session's snapshot and silently undoing any tool
1112
+ // changes the user made between sessions (#4959 / CodeRabbit).
1113
+ if (pi) clearToolBaseline(pi);
1114
+
1048
1115
  // Reset all session state in one call
1049
1116
  s.reset();
1050
1117
  }
@@ -1345,6 +1412,15 @@ export async function startAuto(
1345
1412
  return;
1346
1413
  }
1347
1414
 
1415
+ // On a *fresh* start, drop any stale active-tool baseline left by a prior
1416
+ // auto session that didn't run stopAuto cleanly. Skip on resume: pauseAuto
1417
+ // leaves the last provider-trimmed active tools in place, so clearing here
1418
+ // would let the next selectAndApplyModel recapture that already-narrowed
1419
+ // set as the new baseline — exactly the cross-unit poisoning this PR is
1420
+ // fixing (#4959 / CodeRabbit Major). The pre-pause baseline survives in
1421
+ // the WeakMap keyed by `pi`.
1422
+ if (!s.paused) clearToolBaseline(pi);
1423
+
1348
1424
  const requestedStepMode = options?.step ?? false;
1349
1425
  const interruptedAssessment = options?.interrupted ?? null;
1350
1426
  if (options?.milestoneLock !== undefined) {
@@ -1414,7 +1490,15 @@ export async function startAuto(
1414
1490
  // Validate the milestone still exists and isn't already complete (#1664).
1415
1491
  const mDir = resolveMilestonePath(base, meta.milestoneId);
1416
1492
  const summaryFile = resolveMilestoneFile(base, meta.milestoneId, "SUMMARY");
1417
- if (!mDir || summaryFile) {
1493
+ let summaryIsTerminal = false;
1494
+ if (summaryFile) {
1495
+ try {
1496
+ summaryIsTerminal = classifyMilestoneSummaryContent(readFileSync(summaryFile, "utf-8")) !== "failure";
1497
+ } catch {
1498
+ summaryIsTerminal = false;
1499
+ }
1500
+ }
1501
+ if (!mDir || summaryIsTerminal) {
1418
1502
  try { unlinkSync(pausedPath); } catch (err) {
1419
1503
  if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
1420
1504
  logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
@@ -1505,16 +1589,6 @@ export async function startAuto(
1505
1589
  return;
1506
1590
  }
1507
1591
 
1508
- // Lock acquired — now safe to delete the pause file
1509
- if (s.pausedSessionFile) {
1510
- try { unlinkSync(s.pausedSessionFile); } catch (err) {
1511
- if ((err as NodeJS.ErrnoException).code !== "ENOENT") {
1512
- logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
1513
- }
1514
- }
1515
- s.pausedSessionFile = null;
1516
- }
1517
-
1518
1592
  s.paused = false;
1519
1593
  s.active = true;
1520
1594
  s.verbose = verboseMode;
@@ -1612,13 +1686,11 @@ export async function startAuto(
1612
1686
  invalidateAllCaches();
1613
1687
 
1614
1688
  if (s.pausedSessionFile) {
1615
- const activityDir = join(gsdRoot(s.basePath), "activity");
1616
- const recovery = synthesizeCrashRecovery(
1689
+ const recovery = synthesizePausedSessionRecovery(
1617
1690
  s.basePath,
1618
1691
  s.currentUnit?.type ?? s.pausedUnitType ?? "unknown",
1619
1692
  s.currentUnit?.id ?? s.pausedUnitId ?? "unknown",
1620
- s.pausedSessionFile ?? undefined,
1621
- activityDir,
1693
+ s.pausedSessionFile,
1622
1694
  );
1623
1695
  if (recovery && recovery.trace.toolCallCount > 0) {
1624
1696
  s.pendingCrashRecovery = recovery.prompt;