gsd-pi 2.80.0 → 2.81.0-dev.3cddbbba2

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 (1345) hide show
  1. package/README.md +47 -59
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/github-sync/templates.js +90 -74
  18. package/dist/resources/extensions/gsd/auto/contracts.js +2 -0
  19. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +53 -0
  20. package/dist/resources/extensions/gsd/auto/loop.js +566 -526
  21. package/dist/resources/extensions/gsd/auto/orchestrator.js +48 -4
  22. package/dist/resources/extensions/gsd/auto/phases.js +402 -157
  23. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +105 -46
  25. package/dist/resources/extensions/gsd/auto/session.js +18 -1
  26. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -0
  27. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
  28. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-dispatch-outcome.js +12 -0
  29. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-iteration.js +24 -0
  30. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-reconcile-outcome.js +33 -0
  31. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-reconcile.js +26 -0
  32. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-retry.js +49 -0
  33. package/dist/resources/extensions/gsd/auto/workflow-custom-engine-verify-outcome.js +25 -0
  34. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +80 -0
  35. package/dist/resources/extensions/gsd/auto/workflow-dispatch-ledger.js +26 -0
  36. package/dist/resources/extensions/gsd/auto/workflow-iteration-completion.js +10 -0
  37. package/dist/resources/extensions/gsd/auto/workflow-journal-reporter.js +16 -0
  38. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +263 -0
  39. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +36 -0
  40. package/dist/resources/extensions/gsd/auto/workflow-phase-reporter.js +9 -0
  41. package/dist/resources/extensions/gsd/auto/workflow-session-lock.js +35 -0
  42. package/dist/resources/extensions/gsd/auto/workflow-sidecar-iteration.js +24 -0
  43. package/dist/resources/extensions/gsd/auto/workflow-sidecar-queue.js +26 -0
  44. package/dist/resources/extensions/gsd/auto/workflow-turn-reporter.js +36 -0
  45. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +44 -0
  46. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +23 -0
  47. package/dist/resources/extensions/gsd/auto-dashboard.js +248 -187
  48. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  49. package/dist/resources/extensions/gsd/auto-dispatch.js +40 -11
  50. package/dist/resources/extensions/gsd/auto-post-unit.js +129 -89
  51. package/dist/resources/extensions/gsd/auto-prompts.js +382 -20
  52. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  53. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
  54. package/dist/resources/extensions/gsd/auto-start.js +253 -19
  55. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  56. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  57. package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
  58. package/dist/resources/extensions/gsd/auto-verification.js +14 -17
  59. package/dist/resources/extensions/gsd/auto-worktree.js +324 -374
  60. package/dist/resources/extensions/gsd/auto.js +502 -130
  61. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +147 -12
  62. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +54 -37
  63. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
  64. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
  65. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
  66. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
  67. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
  68. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  69. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +356 -58
  70. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
  71. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  72. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  73. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +147 -2
  74. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  75. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  76. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
  77. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  78. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  79. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  80. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  81. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  82. package/dist/resources/extensions/gsd/commands-ship.js +23 -46
  83. package/dist/resources/extensions/gsd/commands-workflow-templates.js +12 -7
  84. package/dist/resources/extensions/gsd/component-loader.js +5 -11
  85. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  86. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  87. package/dist/resources/extensions/gsd/custom-workflow-engine.js +25 -1
  88. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  89. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  90. package/dist/resources/extensions/gsd/db-adapter.js +47 -0
  91. package/dist/resources/extensions/gsd/db-base-schema.js +353 -0
  92. package/dist/resources/extensions/gsd/db-connection-cache.js +31 -0
  93. package/dist/resources/extensions/gsd/db-coordination-schema.js +104 -0
  94. package/dist/resources/extensions/gsd/db-decision-requirement-rows.js +71 -0
  95. package/dist/resources/extensions/gsd/db-gate-rows.js +16 -0
  96. package/dist/resources/extensions/gsd/db-lightweight-query-rows.js +29 -0
  97. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +56 -0
  98. package/dist/resources/extensions/gsd/db-migration-backup.js +22 -0
  99. package/dist/resources/extensions/gsd/db-migration-steps.js +416 -0
  100. package/dist/resources/extensions/gsd/db-milestone-artifact-rows.js +35 -0
  101. package/dist/resources/extensions/gsd/db-open-state.js +32 -0
  102. package/dist/resources/extensions/gsd/db-provider.js +108 -0
  103. package/dist/resources/extensions/gsd/db-runtime-kv-schema.js +27 -0
  104. package/dist/resources/extensions/gsd/db-schema-metadata.js +23 -0
  105. package/dist/resources/extensions/gsd/db-task-slice-rows.js +86 -0
  106. package/dist/resources/extensions/gsd/db-transaction.js +63 -0
  107. package/dist/resources/extensions/gsd/db-verification-evidence-rows.js +3 -0
  108. package/dist/resources/extensions/gsd/db-verification-evidence-schema.js +19 -0
  109. package/dist/resources/extensions/gsd/detection.js +106 -0
  110. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  111. package/dist/resources/extensions/gsd/escalation.js +2 -0
  112. package/dist/resources/extensions/gsd/git-service.js +75 -6
  113. package/dist/resources/extensions/gsd/graph.js +9 -3
  114. package/dist/resources/extensions/gsd/gsd-db.js +331 -1535
  115. package/dist/resources/extensions/gsd/guided-flow.js +149 -48
  116. package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
  117. package/dist/resources/extensions/gsd/health-widget.js +6 -9
  118. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  119. package/dist/resources/extensions/gsd/legacy-telemetry.js +70 -0
  120. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -0
  121. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  122. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  123. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  124. package/dist/resources/extensions/gsd/model-router.js +9 -6
  125. package/dist/resources/extensions/gsd/native-git-bridge.js +46 -22
  126. package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
  127. package/dist/resources/extensions/gsd/notification-widget.js +21 -3
  128. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  129. package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
  130. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
  131. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  132. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  133. package/dist/resources/extensions/gsd/post-execution-checks.js +2 -0
  134. package/dist/resources/extensions/gsd/pr-evidence.js +117 -0
  135. package/dist/resources/extensions/gsd/pre-execution-checks.js +24 -0
  136. package/dist/resources/extensions/gsd/process-task-path.js +61 -0
  137. package/dist/resources/extensions/gsd/prompt-loader.js +37 -7
  138. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +41 -35
  139. package/dist/resources/extensions/gsd/prompts/complete-slice.md +25 -34
  140. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +70 -98
  141. package/dist/resources/extensions/gsd/prompts/discuss.md +101 -183
  142. package/dist/resources/extensions/gsd/prompts/execute-task.md +42 -67
  143. package/dist/resources/extensions/gsd/prompts/forensics.md +41 -84
  144. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +29 -39
  145. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +30 -65
  146. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +25 -52
  147. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +36 -36
  148. package/dist/resources/extensions/gsd/prompts/guided-research-project.md +20 -38
  149. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  150. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +47 -59
  151. package/dist/resources/extensions/gsd/prompts/plan-slice.md +25 -87
  152. package/dist/resources/extensions/gsd/prompts/queue.md +46 -53
  153. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  154. package/dist/resources/extensions/gsd/prompts/refine-slice.md +23 -23
  155. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  156. package/dist/resources/extensions/gsd/prompts/research-slice.md +23 -23
  157. package/dist/resources/extensions/gsd/prompts/rethink.md +10 -10
  158. package/dist/resources/extensions/gsd/prompts/system.md +65 -107
  159. package/dist/resources/extensions/gsd/prompts/triage-captures.md +15 -15
  160. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +24 -24
  161. package/dist/resources/extensions/gsd/prompts/worktree-merge.md +35 -35
  162. package/dist/resources/extensions/gsd/quick.js +34 -2
  163. package/dist/resources/extensions/gsd/recovery-classification.js +94 -0
  164. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  165. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  166. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  167. package/dist/resources/extensions/gsd/state-reconciliation.js +27 -0
  168. package/dist/resources/extensions/gsd/state.js +4 -0
  169. package/dist/resources/extensions/gsd/tool-contract.js +50 -0
  170. package/dist/resources/extensions/gsd/tools/complete-milestone.js +20 -16
  171. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -1
  172. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  173. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  174. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  175. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  176. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  177. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  178. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  179. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +7 -2
  180. package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
  181. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  182. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  183. package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
  184. package/dist/resources/extensions/gsd/uok/plan-v2.js +2 -0
  185. package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
  186. package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
  187. package/dist/resources/extensions/gsd/workflow-logger.js +13 -13
  188. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  189. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  190. package/dist/resources/extensions/gsd/workflow-projections.js +2 -0
  191. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  192. package/dist/resources/extensions/gsd/workflow-templates.js +9 -0
  193. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  194. package/dist/resources/extensions/gsd/worktree-lifecycle.js +1364 -0
  195. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  196. package/dist/resources/extensions/gsd/worktree-safety.js +119 -0
  197. package/dist/resources/extensions/gsd/worktree-state-projection.js +317 -0
  198. package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
  199. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  200. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  201. package/dist/web/standalone/.next/BUILD_ID +1 -1
  202. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  203. package/dist/web/standalone/.next/build-manifest.json +4 -4
  204. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  205. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  206. package/dist/web/standalone/.next/required-server-files.json +4 -4
  207. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  208. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  210. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  211. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  212. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  213. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  217. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  218. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  220. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  221. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  222. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  223. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  224. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  225. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  226. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  227. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  237. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  251. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  252. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  253. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  255. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  256. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  259. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  260. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  262. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  267. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  268. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  269. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  270. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  271. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  272. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  273. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  274. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  276. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  277. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  278. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  279. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  280. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  281. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  282. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  283. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  284. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  285. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  286. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  287. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  288. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  289. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  290. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  291. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  292. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  293. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  294. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  295. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  296. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  297. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  298. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  299. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  300. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  301. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  302. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  303. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  304. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  305. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  306. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  307. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  308. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  309. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  310. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  311. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  312. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  313. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  314. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  315. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  316. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  317. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  318. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  319. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  320. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  321. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  322. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  323. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  324. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  325. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  326. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  327. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  328. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  329. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  330. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  331. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  332. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  333. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  334. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  335. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  336. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  337. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  338. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  339. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  340. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  341. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  342. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  343. package/dist/web/standalone/.next/server/app/index.html +1 -1
  344. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  345. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  346. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  347. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  348. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  349. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  350. package/dist/web/standalone/.next/server/app/page.js +2 -2
  351. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  352. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  353. package/dist/web/standalone/.next/server/chunks/167.js +2 -0
  354. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  355. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  356. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  357. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  358. package/dist/web/standalone/.next/server/middleware.js +2 -2
  359. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  360. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  361. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  362. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  363. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  364. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  365. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  366. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  367. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
  368. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  369. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  370. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-de742b64187e13fe.js} +1 -1
  371. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  372. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  373. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  374. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  375. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  376. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  377. package/dist/web/standalone/package.json +1 -0
  378. package/dist/web/standalone/server.js +1 -1
  379. package/dist/welcome-screen.d.ts +2 -7
  380. package/dist/welcome-screen.js +68 -75
  381. package/package.json +20 -9
  382. package/packages/contracts/dist/index.d.ts +3 -0
  383. package/packages/contracts/dist/index.d.ts.map +1 -0
  384. package/packages/contracts/dist/index.js +5 -0
  385. package/packages/contracts/dist/index.js.map +1 -0
  386. package/packages/contracts/dist/rpc.d.ts +549 -0
  387. package/packages/contracts/dist/rpc.d.ts.map +1 -0
  388. package/packages/contracts/dist/rpc.js +53 -0
  389. package/packages/contracts/dist/rpc.js.map +1 -0
  390. package/packages/contracts/dist/rpc.test.d.ts +2 -0
  391. package/packages/contracts/dist/rpc.test.d.ts.map +1 -0
  392. package/packages/contracts/dist/rpc.test.js +47 -0
  393. package/packages/contracts/dist/rpc.test.js.map +1 -0
  394. package/packages/contracts/dist/workflow.d.ts +180 -0
  395. package/packages/contracts/dist/workflow.d.ts.map +1 -0
  396. package/packages/contracts/dist/workflow.js +201 -0
  397. package/packages/contracts/dist/workflow.js.map +1 -0
  398. package/packages/contracts/package.json +39 -0
  399. package/packages/contracts/src/index.ts +5 -0
  400. package/packages/contracts/src/rpc.test.ts +72 -0
  401. package/packages/contracts/src/rpc.ts +286 -0
  402. package/packages/contracts/src/workflow.ts +213 -0
  403. package/packages/contracts/tsconfig.json +25 -0
  404. package/packages/daemon/package.json +3 -2
  405. package/packages/daemon/src/event-bridge.test.ts +2 -1
  406. package/packages/daemon/src/event-bridge.ts +1 -1
  407. package/packages/daemon/src/event-formatter.test.ts +1 -2
  408. package/packages/daemon/src/event-formatter.ts +1 -2
  409. package/packages/daemon/src/session-manager.ts +2 -2
  410. package/packages/daemon/src/types.ts +3 -18
  411. package/packages/mcp-server/dist/server.d.ts +13 -0
  412. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  413. package/packages/mcp-server/dist/server.js +77 -0
  414. package/packages/mcp-server/dist/server.js.map +1 -1
  415. package/packages/mcp-server/dist/session-manager.js +1 -1
  416. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  417. package/packages/mcp-server/dist/types.d.ts +3 -11
  418. package/packages/mcp-server/dist/types.d.ts.map +1 -1
  419. package/packages/mcp-server/dist/types.js.map +1 -1
  420. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
  421. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  422. package/packages/mcp-server/dist/workflow-tools.js +24 -57
  423. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  424. package/packages/mcp-server/package.json +3 -2
  425. package/packages/mcp-server/src/mcp-server.test.ts +138 -0
  426. package/packages/mcp-server/src/server.ts +99 -1
  427. package/packages/mcp-server/src/session-manager.ts +2 -2
  428. package/packages/mcp-server/src/types.ts +7 -18
  429. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  430. package/packages/mcp-server/src/workflow-tools.ts +32 -56
  431. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  432. package/packages/native/package.json +1 -1
  433. package/packages/native/tsconfig.tsbuildinfo +1 -1
  434. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  435. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  436. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  437. package/packages/pi-agent-core/dist/agent.d.ts +9 -2
  438. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  439. package/packages/pi-agent-core/dist/agent.js +43 -11
  440. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  441. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  442. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  443. package/packages/pi-agent-core/dist/index.js +2 -0
  444. package/packages/pi-agent-core/dist/index.js.map +1 -1
  445. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  446. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  447. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  448. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  449. package/packages/pi-agent-core/dist/types.d.ts +31 -0
  450. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  451. package/packages/pi-agent-core/dist/types.js.map +1 -1
  452. package/packages/pi-agent-core/package.json +1 -1
  453. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  454. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  455. package/packages/pi-agent-core/src/agent.ts +52 -11
  456. package/packages/pi-agent-core/src/index.ts +2 -0
  457. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  458. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  459. package/packages/pi-agent-core/src/types.ts +26 -10
  460. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  461. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  462. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  463. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  464. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  465. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  466. package/packages/pi-ai/dist/models/index.js +8 -0
  467. package/packages/pi-ai/dist/models/index.js.map +1 -1
  468. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  469. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  470. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  471. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  472. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  473. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  474. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  475. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  476. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  477. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  478. package/packages/pi-ai/dist/providers/fake.js +319 -0
  479. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  480. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  481. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  482. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  483. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  484. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  485. package/packages/pi-ai/dist/types.d.ts +2 -0
  486. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  487. package/packages/pi-ai/dist/types.js.map +1 -1
  488. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  489. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  490. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  491. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  492. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  493. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  494. package/packages/pi-ai/package.json +1 -1
  495. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  496. package/packages/pi-ai/src/models/index.ts +9 -0
  497. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  498. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  499. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  500. package/packages/pi-ai/src/providers/fake.ts +376 -0
  501. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  502. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  503. package/packages/pi-ai/src/types.ts +3 -0
  504. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  505. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  506. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  507. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  508. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +36 -1
  509. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  510. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
  511. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  512. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +21 -2
  513. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  514. package/packages/pi-coding-agent/dist/core/agent-session.js +94 -16
  515. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  516. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +78 -0
  517. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  518. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  519. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  520. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  521. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  522. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  523. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  524. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  525. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  526. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  527. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  528. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  529. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  530. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  531. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  532. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  533. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  534. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  535. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  536. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  537. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  538. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  539. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  540. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  541. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  542. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  543. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +60 -4
  544. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  545. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  546. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  547. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  548. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  549. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  550. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  551. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  552. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  553. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  554. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  555. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  556. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  557. package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
  558. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  559. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  560. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  561. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  562. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  563. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  564. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  565. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  566. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  567. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  568. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  569. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  570. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  571. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  572. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  573. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  574. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  575. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  576. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  577. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  578. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  579. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  580. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  581. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  582. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  583. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  584. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  585. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  586. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  587. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  588. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  589. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  590. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  591. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  592. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  593. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  594. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  595. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  596. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  597. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  598. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  599. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  600. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  601. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  602. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  603. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  604. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  605. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  606. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  607. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  608. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  609. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  610. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  611. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  612. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  613. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  614. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  615. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  616. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  617. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  618. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  619. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  620. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
  621. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
  622. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
  623. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
  624. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  625. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  626. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +225 -18
  627. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  628. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
  629. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
  630. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
  631. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
  632. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +25 -0
  633. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  634. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +113 -0
  635. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  636. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  637. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  638. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +58 -0
  639. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  640. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  641. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
  642. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  643. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
  644. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  645. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
  646. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  647. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  648. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  649. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  650. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
  651. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  652. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
  653. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  654. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  655. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
  656. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  657. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  658. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  659. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  660. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  661. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +51 -6
  662. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  663. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +21 -0
  664. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  665. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +302 -56
  666. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  667. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
  668. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
  669. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
  670. package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
  671. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
  672. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
  673. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
  674. package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
  675. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
  676. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  677. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
  678. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  679. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  680. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +86 -2
  681. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  682. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +111 -1
  683. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  684. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  685. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  686. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  687. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  688. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  689. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -1
  690. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  691. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +77 -11
  692. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  693. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  694. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  695. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  696. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  697. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  698. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  699. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  700. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  701. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  702. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  703. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  704. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  705. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  706. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  707. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  708. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  709. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  710. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +123 -2
  711. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  712. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  713. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +39 -29
  714. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  715. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  716. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  717. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  718. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  719. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  720. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  721. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +51 -0
  722. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  723. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  724. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  725. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -512
  726. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  727. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js +3 -7
  728. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  729. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  730. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  731. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  732. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  733. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  734. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  735. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  736. package/packages/pi-coding-agent/package.json +2 -1
  737. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +40 -1
  738. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
  739. package/packages/pi-coding-agent/src/core/agent-session.ts +102 -16
  740. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +91 -0
  741. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  742. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  743. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  744. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  745. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  746. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  747. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  748. package/packages/pi-coding-agent/src/core/extensions/types.ts +63 -2
  749. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  750. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  751. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  752. package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
  753. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  754. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  755. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  756. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  757. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  758. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  759. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  760. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  761. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  762. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  763. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  764. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  765. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  766. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  767. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  768. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  769. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  770. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
  771. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  772. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +325 -20
  773. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
  774. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +66 -0
  775. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +161 -0
  776. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -13
  777. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
  778. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  779. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
  780. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
  781. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  782. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +71 -9
  783. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +327 -68
  784. package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
  785. package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
  786. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
  787. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +118 -1
  788. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +108 -3
  789. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  790. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  791. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +101 -11
  792. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  793. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  794. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
  795. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  796. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +138 -3
  797. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +39 -29
  798. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +68 -0
  799. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  800. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
  801. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +3 -336
  802. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  803. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  804. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  805. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
  806. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  807. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  808. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  809. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  810. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  811. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  812. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  813. package/packages/pi-tui/dist/index.d.ts +1 -0
  814. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  815. package/packages/pi-tui/dist/index.js +2 -0
  816. package/packages/pi-tui/dist/index.js.map +1 -1
  817. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
  818. package/packages/pi-tui/dist/overlay-layout.js +9 -6
  819. package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
  820. package/packages/pi-tui/dist/style.d.ts +41 -0
  821. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  822. package/packages/pi-tui/dist/style.js +158 -0
  823. package/packages/pi-tui/dist/style.js.map +1 -0
  824. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  825. package/packages/pi-tui/dist/tui.js +19 -8
  826. package/packages/pi-tui/dist/tui.js.map +1 -1
  827. package/packages/pi-tui/package.json +1 -1
  828. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
  829. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  830. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  831. package/packages/pi-tui/src/index.ts +9 -0
  832. package/packages/pi-tui/src/overlay-layout.ts +10 -7
  833. package/packages/pi-tui/src/style.ts +225 -0
  834. package/packages/pi-tui/src/tui.ts +21 -8
  835. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  836. package/packages/rpc-client/README.md +10 -3
  837. package/packages/rpc-client/dist/index.d.ts +1 -1
  838. package/packages/rpc-client/dist/index.d.ts.map +1 -1
  839. package/packages/rpc-client/dist/index.js.map +1 -1
  840. package/packages/rpc-client/dist/rpc-client.d.ts +2 -6
  841. package/packages/rpc-client/dist/rpc-client.d.ts.map +1 -1
  842. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  843. package/packages/rpc-client/dist/rpc-types.d.ts +1 -565
  844. package/packages/rpc-client/dist/rpc-types.d.ts.map +1 -1
  845. package/packages/rpc-client/dist/rpc-types.js +3 -11
  846. package/packages/rpc-client/dist/rpc-types.js.map +1 -1
  847. package/packages/rpc-client/package.json +4 -1
  848. package/packages/rpc-client/src/index.ts +1 -1
  849. package/packages/rpc-client/src/rpc-client.ts +3 -6
  850. package/packages/rpc-client/src/rpc-types.ts +3 -398
  851. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  852. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
  853. package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
  854. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
  855. package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
  856. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  857. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  858. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  859. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  860. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  861. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  862. package/pkg/dist/modes/interactive/theme/theme.js +123 -2
  863. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  864. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  865. package/pkg/dist/modes/interactive/theme/themes.js +39 -29
  866. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  867. package/pkg/package.json +1 -1
  868. package/src/resources/GSD-WORKFLOW.md +2 -2
  869. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  870. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
  871. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
  872. package/src/resources/extensions/github-sync/sync.ts +8 -1
  873. package/src/resources/extensions/github-sync/templates.ts +93 -88
  874. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  875. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  876. package/src/resources/extensions/github-sync/tests/templates.test.ts +10 -2
  877. package/src/resources/extensions/gsd/auto/contracts.ts +19 -2
  878. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +72 -0
  879. package/src/resources/extensions/gsd/auto/loop-deps.ts +20 -16
  880. package/src/resources/extensions/gsd/auto/loop.ts +645 -603
  881. package/src/resources/extensions/gsd/auto/orchestrator.ts +52 -4
  882. package/src/resources/extensions/gsd/auto/phases.ts +546 -222
  883. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  884. package/src/resources/extensions/gsd/auto/run-unit.ts +119 -46
  885. package/src/resources/extensions/gsd/auto/session.ts +19 -1
  886. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  887. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +15 -0
  888. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
  889. package/src/resources/extensions/gsd/auto/workflow-custom-engine-dispatch-outcome.ts +28 -0
  890. package/src/resources/extensions/gsd/auto/workflow-custom-engine-iteration.ts +52 -0
  891. package/src/resources/extensions/gsd/auto/workflow-custom-engine-reconcile-outcome.ts +58 -0
  892. package/src/resources/extensions/gsd/auto/workflow-custom-engine-reconcile.ts +71 -0
  893. package/src/resources/extensions/gsd/auto/workflow-custom-engine-retry.ts +90 -0
  894. package/src/resources/extensions/gsd/auto/workflow-custom-engine-verify-outcome.ts +50 -0
  895. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +159 -0
  896. package/src/resources/extensions/gsd/auto/workflow-dispatch-ledger.ts +45 -0
  897. package/src/resources/extensions/gsd/auto/workflow-iteration-completion.ts +26 -0
  898. package/src/resources/extensions/gsd/auto/workflow-journal-reporter.ts +33 -0
  899. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +520 -0
  900. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +58 -0
  901. package/src/resources/extensions/gsd/auto/workflow-phase-reporter.ts +22 -0
  902. package/src/resources/extensions/gsd/auto/workflow-session-lock.ts +68 -0
  903. package/src/resources/extensions/gsd/auto/workflow-sidecar-iteration.ts +46 -0
  904. package/src/resources/extensions/gsd/auto/workflow-sidecar-queue.ts +46 -0
  905. package/src/resources/extensions/gsd/auto/workflow-turn-reporter.ts +68 -0
  906. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +89 -0
  907. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +51 -0
  908. package/src/resources/extensions/gsd/auto-dashboard.ts +304 -184
  909. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  910. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -1
  911. package/src/resources/extensions/gsd/auto-post-unit.ts +141 -91
  912. package/src/resources/extensions/gsd/auto-prompts.ts +398 -19
  913. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  914. package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
  915. package/src/resources/extensions/gsd/auto-start.ts +328 -27
  916. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  917. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  918. package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
  919. package/src/resources/extensions/gsd/auto-verification.ts +17 -7
  920. package/src/resources/extensions/gsd/auto-worktree.ts +352 -396
  921. package/src/resources/extensions/gsd/auto.ts +590 -127
  922. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +181 -12
  923. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +56 -37
  924. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
  925. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
  926. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
  927. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
  928. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
  929. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  930. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +411 -58
  931. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
  932. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  933. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  934. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +153 -2
  935. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  936. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  937. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
  938. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  939. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  940. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  941. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  942. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  943. package/src/resources/extensions/gsd/commands-ship.ts +24 -51
  944. package/src/resources/extensions/gsd/commands-workflow-templates.ts +13 -0
  945. package/src/resources/extensions/gsd/component-loader.ts +5 -11
  946. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  947. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  948. package/src/resources/extensions/gsd/custom-workflow-engine.ts +29 -0
  949. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  950. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  951. package/src/resources/extensions/gsd/db-adapter.ts +75 -0
  952. package/src/resources/extensions/gsd/db-base-schema.ts +385 -0
  953. package/src/resources/extensions/gsd/db-connection-cache.ts +45 -0
  954. package/src/resources/extensions/gsd/db-coordination-schema.ts +109 -0
  955. package/src/resources/extensions/gsd/db-decision-requirement-rows.ts +77 -0
  956. package/src/resources/extensions/gsd/db-gate-rows.ts +19 -0
  957. package/src/resources/extensions/gsd/db-lightweight-query-rows.ts +50 -0
  958. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +66 -0
  959. package/src/resources/extensions/gsd/db-migration-backup.ts +34 -0
  960. package/src/resources/extensions/gsd/db-migration-steps.ts +459 -0
  961. package/src/resources/extensions/gsd/db-milestone-artifact-rows.ts +70 -0
  962. package/src/resources/extensions/gsd/db-open-state.ts +47 -0
  963. package/src/resources/extensions/gsd/db-provider.ts +148 -0
  964. package/src/resources/extensions/gsd/db-runtime-kv-schema.ts +30 -0
  965. package/src/resources/extensions/gsd/db-schema-metadata.ts +33 -0
  966. package/src/resources/extensions/gsd/db-task-slice-rows.ts +146 -0
  967. package/src/resources/extensions/gsd/db-transaction.ts +76 -0
  968. package/src/resources/extensions/gsd/db-verification-evidence-rows.ts +14 -0
  969. package/src/resources/extensions/gsd/db-verification-evidence-schema.ts +22 -0
  970. package/src/resources/extensions/gsd/detection.ts +128 -0
  971. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  972. package/src/resources/extensions/gsd/escalation.ts +3 -1
  973. package/src/resources/extensions/gsd/git-service.ts +89 -10
  974. package/src/resources/extensions/gsd/graph.ts +12 -5
  975. package/src/resources/extensions/gsd/gsd-db.ts +399 -1677
  976. package/src/resources/extensions/gsd/guided-flow.ts +175 -55
  977. package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
  978. package/src/resources/extensions/gsd/health-widget.ts +8 -9
  979. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  980. package/src/resources/extensions/gsd/journal.ts +2 -0
  981. package/src/resources/extensions/gsd/legacy-telemetry.ts +99 -0
  982. package/src/resources/extensions/gsd/markdown-renderer.ts +4 -1
  983. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  984. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  985. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  986. package/src/resources/extensions/gsd/model-router.ts +10 -6
  987. package/src/resources/extensions/gsd/native-git-bridge.ts +53 -19
  988. package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
  989. package/src/resources/extensions/gsd/notification-widget.ts +25 -4
  990. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  991. package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
  992. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
  993. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  994. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  995. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -1
  996. package/src/resources/extensions/gsd/pr-evidence.ts +182 -0
  997. package/src/resources/extensions/gsd/pre-execution-checks.ts +27 -1
  998. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  999. package/src/resources/extensions/gsd/process-task-path.ts +81 -0
  1000. package/src/resources/extensions/gsd/prompt-loader.ts +36 -7
  1001. package/src/resources/extensions/gsd/prompts/complete-milestone.md +41 -35
  1002. package/src/resources/extensions/gsd/prompts/complete-slice.md +25 -34
  1003. package/src/resources/extensions/gsd/prompts/discuss-headless.md +70 -98
  1004. package/src/resources/extensions/gsd/prompts/discuss.md +101 -183
  1005. package/src/resources/extensions/gsd/prompts/execute-task.md +42 -67
  1006. package/src/resources/extensions/gsd/prompts/forensics.md +41 -84
  1007. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +29 -39
  1008. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +30 -65
  1009. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +25 -52
  1010. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +36 -36
  1011. package/src/resources/extensions/gsd/prompts/guided-research-project.md +20 -38
  1012. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  1013. package/src/resources/extensions/gsd/prompts/plan-milestone.md +47 -59
  1014. package/src/resources/extensions/gsd/prompts/plan-slice.md +25 -87
  1015. package/src/resources/extensions/gsd/prompts/queue.md +46 -53
  1016. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  1017. package/src/resources/extensions/gsd/prompts/refine-slice.md +23 -23
  1018. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  1019. package/src/resources/extensions/gsd/prompts/research-slice.md +23 -23
  1020. package/src/resources/extensions/gsd/prompts/rethink.md +10 -10
  1021. package/src/resources/extensions/gsd/prompts/system.md +65 -107
  1022. package/src/resources/extensions/gsd/prompts/triage-captures.md +15 -15
  1023. package/src/resources/extensions/gsd/prompts/validate-milestone.md +24 -24
  1024. package/src/resources/extensions/gsd/prompts/worktree-merge.md +35 -35
  1025. package/src/resources/extensions/gsd/quick.ts +37 -2
  1026. package/src/resources/extensions/gsd/recovery-classification.ts +122 -0
  1027. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  1028. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  1029. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  1030. package/src/resources/extensions/gsd/state-reconciliation.ts +57 -0
  1031. package/src/resources/extensions/gsd/state.ts +6 -3
  1032. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  1033. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  1034. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  1035. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  1036. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +232 -9
  1037. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1269 -242
  1038. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  1039. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +119 -2
  1040. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  1041. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +363 -18
  1042. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +175 -11
  1043. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -76
  1044. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  1045. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  1046. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  1047. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +16 -1
  1048. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  1049. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  1050. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  1051. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  1052. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +160 -0
  1053. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  1054. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  1055. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  1056. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
  1057. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  1058. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  1059. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  1060. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  1061. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  1062. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  1063. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  1064. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  1065. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  1066. package/src/resources/extensions/gsd/tests/commands-eval-review.test.ts +2 -2
  1067. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  1068. package/src/resources/extensions/gsd/tests/commands-ship-eval-warn.test.ts +3 -2
  1069. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  1070. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  1071. package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +47 -0
  1072. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +159 -5
  1073. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  1074. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  1075. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  1076. package/src/resources/extensions/gsd/tests/component-loader.test.ts +2 -9
  1077. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  1078. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  1079. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  1080. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  1081. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +190 -11
  1082. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +139 -0
  1083. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +50 -0
  1084. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  1085. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  1086. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +82 -0
  1087. package/src/resources/extensions/gsd/tests/db-base-schema.test.ts +62 -0
  1088. package/src/resources/extensions/gsd/tests/db-connection-cache.test.ts +60 -0
  1089. package/src/resources/extensions/gsd/tests/db-coordination-schema.test.ts +39 -0
  1090. package/src/resources/extensions/gsd/tests/db-decision-requirement-rows.test.ts +135 -0
  1091. package/src/resources/extensions/gsd/tests/db-gate-rows.test.ts +53 -0
  1092. package/src/resources/extensions/gsd/tests/db-lightweight-query-rows.test.ts +45 -0
  1093. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +86 -0
  1094. package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +105 -0
  1095. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  1096. package/src/resources/extensions/gsd/tests/db-migration-steps.test.ts +159 -0
  1097. package/src/resources/extensions/gsd/tests/db-milestone-artifact-rows.test.ts +53 -0
  1098. package/src/resources/extensions/gsd/tests/db-open-state.test.ts +56 -0
  1099. package/src/resources/extensions/gsd/tests/db-provider.test.ts +105 -0
  1100. package/src/resources/extensions/gsd/tests/db-runtime-kv-schema.test.ts +37 -0
  1101. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +115 -0
  1102. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +128 -0
  1103. package/src/resources/extensions/gsd/tests/db-transaction.test.ts +110 -0
  1104. package/src/resources/extensions/gsd/tests/db-verification-evidence-schema.test.ts +76 -0
  1105. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +24 -11
  1106. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  1107. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  1108. package/src/resources/extensions/gsd/tests/discuss-headless-rendering.test.ts +37 -0
  1109. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  1110. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +100 -38
  1111. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  1112. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  1113. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  1114. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  1115. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  1116. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  1117. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  1118. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +62 -0
  1119. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  1120. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +151 -0
  1121. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  1122. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  1123. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  1124. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  1125. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  1126. package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +36 -0
  1127. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  1128. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  1129. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  1130. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +43 -0
  1131. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +41 -0
  1132. package/src/resources/extensions/gsd/tests/guided-discuss-requirements-prompt-rendering.test.ts +45 -0
  1133. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  1134. package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
  1135. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
  1136. package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
  1137. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  1138. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +77 -0
  1139. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  1140. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  1141. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +92 -0
  1142. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  1143. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
  1144. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +5 -3
  1145. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  1146. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  1147. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +248 -11
  1148. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  1149. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  1150. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  1151. package/src/resources/extensions/gsd/tests/legacy-component-format-telemetry.test.ts +62 -0
  1152. package/src/resources/extensions/gsd/tests/legacy-telemetry.test.ts +144 -0
  1153. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  1154. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +53 -43
  1155. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +77 -12
  1156. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  1157. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  1158. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +267 -0
  1159. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +88 -98
  1160. package/src/resources/extensions/gsd/tests/model-router.test.ts +33 -12
  1161. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  1162. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  1163. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  1164. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  1165. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
  1166. package/src/resources/extensions/gsd/tests/notification-store.test.ts +8 -0
  1167. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +40 -1
  1168. package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
  1169. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -182
  1170. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +144 -0
  1171. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  1172. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
  1173. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  1174. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  1175. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  1176. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +95 -75
  1177. package/src/resources/extensions/gsd/tests/plan-milestone-rendering.test.ts +45 -0
  1178. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +65 -16
  1179. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  1180. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  1181. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
  1182. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  1183. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  1184. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  1185. package/src/resources/extensions/gsd/tests/pr-evidence.test.ts +79 -0
  1186. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  1187. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  1188. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  1189. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  1190. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  1191. package/src/resources/extensions/gsd/tests/process-task-path.test.ts +51 -0
  1192. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  1193. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  1194. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  1195. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -1
  1196. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  1197. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  1198. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -91
  1199. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  1200. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  1201. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  1202. package/src/resources/extensions/gsd/tests/queue-prompt-rendering.test.ts +37 -0
  1203. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  1204. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  1205. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  1206. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  1207. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  1208. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  1209. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  1210. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +36 -164
  1211. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  1212. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  1213. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +91 -0
  1214. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  1215. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  1216. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  1217. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  1218. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  1219. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +222 -0
  1220. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  1221. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  1222. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  1223. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  1224. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  1225. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  1226. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  1227. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  1228. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  1229. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  1230. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  1231. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  1232. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  1233. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  1234. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  1235. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  1236. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +65 -56
  1237. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  1238. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  1239. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  1240. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  1241. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  1242. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  1243. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  1244. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  1245. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +295 -0
  1246. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +32 -9
  1247. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  1248. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +330 -0
  1249. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
  1250. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +140 -8
  1251. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  1252. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  1253. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  1254. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  1255. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +12 -0
  1256. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  1257. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
  1258. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  1259. package/src/resources/extensions/gsd/tests/workflow-custom-engine-dispatch-outcome.test.ts +55 -0
  1260. package/src/resources/extensions/gsd/tests/workflow-custom-engine-iteration.test.ts +93 -0
  1261. package/src/resources/extensions/gsd/tests/workflow-custom-engine-reconcile-outcome.test.ts +108 -0
  1262. package/src/resources/extensions/gsd/tests/workflow-custom-engine-reconcile.test.ts +146 -0
  1263. package/src/resources/extensions/gsd/tests/workflow-custom-engine-retry.test.ts +136 -0
  1264. package/src/resources/extensions/gsd/tests/workflow-custom-engine-verify-outcome.test.ts +95 -0
  1265. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +300 -0
  1266. package/src/resources/extensions/gsd/tests/workflow-dispatch-ledger.test.ts +82 -0
  1267. package/src/resources/extensions/gsd/tests/workflow-iteration-completion.test.ts +44 -0
  1268. package/src/resources/extensions/gsd/tests/workflow-journal-reporter.test.ts +49 -0
  1269. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +607 -0
  1270. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  1271. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +20 -4
  1272. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -57
  1273. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +71 -0
  1274. package/src/resources/extensions/gsd/tests/workflow-phase-reporter.test.ts +40 -0
  1275. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  1276. package/src/resources/extensions/gsd/tests/workflow-session-lock.test.ts +135 -0
  1277. package/src/resources/extensions/gsd/tests/workflow-sidecar-iteration.test.ts +110 -0
  1278. package/src/resources/extensions/gsd/tests/workflow-sidecar-queue.test.ts +116 -0
  1279. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +21 -0
  1280. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +35 -0
  1281. package/src/resources/extensions/gsd/tests/workflow-turn-reporter.test.ts +87 -0
  1282. package/src/resources/extensions/gsd/tests/workflow-unit-dispatch.test.ts +160 -0
  1283. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +154 -0
  1284. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  1285. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  1286. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  1287. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  1288. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +197 -78
  1289. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +888 -0
  1290. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  1291. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  1292. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  1293. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  1294. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  1295. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +327 -0
  1296. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +120 -0
  1297. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +17 -33
  1298. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
  1299. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  1300. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
  1301. package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
  1302. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  1303. package/src/resources/extensions/gsd/tool-contract.ts +82 -0
  1304. package/src/resources/extensions/gsd/tools/complete-milestone.ts +29 -24
  1305. package/src/resources/extensions/gsd/tools/complete-task.ts +5 -2
  1306. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  1307. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  1308. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  1309. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  1310. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  1311. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  1312. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  1313. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +7 -2
  1314. package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
  1315. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  1316. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  1317. package/src/resources/extensions/gsd/uok/kernel.ts +10 -3
  1318. package/src/resources/extensions/gsd/uok/plan-v2.ts +5 -1
  1319. package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
  1320. package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
  1321. package/src/resources/extensions/gsd/workflow-logger.ts +13 -13
  1322. package/src/resources/extensions/gsd/workflow-manifest.ts +6 -15
  1323. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  1324. package/src/resources/extensions/gsd/workflow-projections.ts +5 -1
  1325. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  1326. package/src/resources/extensions/gsd/workflow-templates.ts +11 -0
  1327. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  1328. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1882 -0
  1329. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  1330. package/src/resources/extensions/gsd/worktree-safety.ts +282 -0
  1331. package/src/resources/extensions/gsd/worktree-state-projection.ts +404 -0
  1332. package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
  1333. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  1334. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  1335. package/dist/resources/extensions/gsd/worktree-resolver.js +0 -733
  1336. package/dist/web/standalone/.next/server/chunks/6336.js +0 -1
  1337. package/dist/web/standalone/.next/static/chunks/8336.6f6f30e410419aff.js +0 -10
  1338. package/dist/web/standalone/.next/static/chunks/app/page-ff639266d978f2a0.js +0 -1
  1339. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  1340. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  1341. package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +0 -434
  1342. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1247
  1343. package/src/resources/extensions/gsd/worktree-resolver.ts +0 -909
  1344. /package/dist/web/standalone/.next/static/{V-3Ehy4B24f9FCGiLPWIM → F5x9E6H9k_52fjqyql93y}/_buildManifest.js +0 -0
  1345. /package/dist/web/standalone/.next/static/{V-3Ehy4B24f9FCGiLPWIM → F5x9E6H9k_52fjqyql93y}/_ssgManifest.js +0 -0
@@ -0,0 +1,1882 @@
1
+ // GSD-2 — Worktree Lifecycle module: owns milestone entry/exit lifecycle behind a small, typed Interface.
2
+ /**
3
+ * Worktree Lifecycle module — first-class Module for worktree create/enter/exit/merge.
4
+ *
5
+ * Per ADR-016, this Module is the sole owner of:
6
+ * - `s.basePath` mutation across the session
7
+ * - `process.chdir()` discipline for worktree transitions (delegated to
8
+ * `enterAutoWorktree`/`createAutoWorktree`, which chdir internally)
9
+ * - milestone lease coordination (claim/refresh/release fencing tokens)
10
+ *
11
+ * Phase 1 of the migration ships only `enterMilestone`. The remaining verbs
12
+ * (`exitMilestone`, `degradeToBranchMode`, `restoreToProjectRoot`, queries) are
13
+ * extracted from `WorktreeResolver` in subsequent slices.
14
+ *
15
+ * The implementation lives in `_enterMilestoneCore` so `WorktreeResolver` can
16
+ * call the same body during its internal `mergeAndEnterNext` recursion without
17
+ * a circular reference. Both classes share the body until the Resolver retires.
18
+ */
19
+
20
+ import { existsSync, readFileSync, unlinkSync } from "node:fs";
21
+ import { randomUUID } from "node:crypto";
22
+ import { join } from "node:path";
23
+
24
+ import type { AutoSession } from "./auto/session.js";
25
+ import { debugLog } from "./debug-logger.js";
26
+ import { emitJournalEvent } from "./journal.js";
27
+ import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
28
+ import {
29
+ resolveWorktreeProjectRoot,
30
+ normalizeWorktreePathForCompare,
31
+ } from "./worktree-root.js";
32
+ import {
33
+ claimMilestoneLease,
34
+ refreshMilestoneLease,
35
+ releaseMilestoneLease,
36
+ } from "./db/milestone-leases.js";
37
+ import { MergeConflictError } from "./git-service.js";
38
+ import type { GitPreferences } from "./git-service.js";
39
+ import {
40
+ getCollapseCadence,
41
+ getMilestoneResquash,
42
+ resquashMilestoneOnMain,
43
+ } from "./slice-cadence.js";
44
+ // ADR-016 phase 2 / C3 (#5626): cache + preferences + path helpers inlined
45
+ // as direct imports. They are leaf-level functions that do not vary across
46
+ // callers — production wiring previously injected them via deps; the seam
47
+ // added type churn without enabling test variation.
48
+ import { loadEffectiveGSDPreferences, getIsolationMode } from "./preferences.js";
49
+ import { invalidateAllCaches } from "./cache.js";
50
+ import { resolveMilestoneFile } from "./paths.js";
51
+ import type { WorktreeStateProjection } from "./worktree-state-projection.js";
52
+ import { createWorkspace, scopeMilestone } from "./workspace.js";
53
+ // ADR-016 phase 2 / C1 (#5624): file-system + git-CLI leaf primitives
54
+ // inlined as direct imports rather than injected through `WorktreeLifecycleDeps`.
55
+ // These four symbols (`readFileSync` from node:fs, `getCurrentBranch` and
56
+ // `autoCommitCurrentBranch` from `./worktree.js`, `nativeCheckoutBranch` from
57
+ // `./native-git-bridge.js`) are leaf-level primitives — no environment varies
58
+ // across callers — so the dependency-injection seam they used to inhabit was
59
+ // adding type churn without enabling any test variation.
60
+ import {
61
+ autoCommitCurrentBranch,
62
+ getCurrentBranch,
63
+ } from "./worktree.js";
64
+ import { nativeCheckoutBranch } from "./native-git-bridge.js";
65
+ // ADR-016 phase 2 / C2 (#5625): worktree-manager helpers inlined from
66
+ // `./auto-worktree.js`. These seven functions are not real seams — Lifecycle
67
+ // is the only Module that calls them, and they live alongside the Module's
68
+ // other primitives in `auto-worktree.ts`.
69
+ import {
70
+ autoWorktreeBranch,
71
+ createAutoWorktree,
72
+ enterAutoWorktree,
73
+ enterBranchModeForMilestone,
74
+ getAutoWorktreePath,
75
+ isInAutoWorktree,
76
+ teardownAutoWorktree,
77
+ } from "./auto-worktree.js";
78
+
79
+ // ─── Types ───────────────────────────────────────────────────────────────
80
+
81
+ export interface NotifyCtx {
82
+ notify: (
83
+ msg: string,
84
+ level?: "info" | "warning" | "error" | "success",
85
+ ) => void;
86
+ }
87
+
88
+ /**
89
+ * Dependencies the Worktree Lifecycle Module needs from auto-mode wiring.
90
+ *
91
+ * Structurally a subset of `WorktreeResolverDeps`. `WorktreeResolver` can pass
92
+ * its own deps where these are expected — TypeScript's structural typing
93
+ * handles the narrowing.
94
+ *
95
+ * TODO(#5586): collapse this to the ADR target dep set after the resolver
96
+ * recursion retires; shrinking it now would force a parallel migration.
97
+ */
98
+ export interface WorktreeLifecycleDeps {
99
+ // ── Git service factory (ADR-016 phase 2 / C4) ───────────────────────
100
+ /**
101
+ * Build a fresh `GitService` instance bound to `basePath`.
102
+ *
103
+ * Hides the constructor shape (new GitServiceImpl(basePath, gitConfig))
104
+ * and the gitConfig load from Lifecycle. The factory takes only a
105
+ * `basePath` and is responsible for loading any config it needs.
106
+ * Tests substitute fakes by passing a function that returns a stub.
107
+ */
108
+ gitServiceFactory: (basePath: string) => AutoSession["gitService"];
109
+
110
+ // ── State Projection Module (ADR-016 one-way edge) ───────────────────
111
+ /**
112
+ * State Projection Module called by Lifecycle on enter/exit transitions.
113
+ * Per ADR-016 the dependency direction is one-way: Lifecycle → Projection.
114
+ */
115
+ worktreeProjection: WorktreeStateProjection;
116
+
117
+ // ── Merge primitive ──────────────────────────────────────────────────
118
+ /**
119
+ * Inner squash-merge primitive (`auto-worktree.ts:mergeMilestoneToMain`).
120
+ *
121
+ * **Module-internal seam — do not construct your own.** Only the wiring
122
+ * factory `auto.ts:buildWorktreeLifecycleDeps()` is permitted to populate
123
+ * this field. The primitive is `@internal`; production callers reach the
124
+ * merge body through `WorktreeLifecycle.exitMilestone({ merge: true })`,
125
+ * never by calling this dep directly.
126
+ */
127
+ mergeMilestoneToMain: (
128
+ basePath: string,
129
+ milestoneId: string,
130
+ roadmapContent: string,
131
+ ) => {
132
+ pushed: boolean;
133
+ codeFilesChanged: boolean;
134
+ commitMessage?: string;
135
+ };
136
+
137
+ // ADR-016 phase 2 / C1 + C2 + C3 + C4 inlined the following fields as
138
+ // direct imports — leaf primitives that did not vary across callers:
139
+ // C1 (#5624): readFileSync, getCurrentBranch, checkoutBranch,
140
+ // autoCommitCurrentBranch
141
+ // C2 (#5625): enterAutoWorktree, createAutoWorktree,
142
+ // enterBranchModeForMilestone, getAutoWorktreePath,
143
+ // teardownAutoWorktree, isInAutoWorktree, autoWorktreeBranch
144
+ // C3 (#5626): invalidateAllCaches, loadEffectiveGSDPreferences,
145
+ // getIsolationMode, resolveMilestoneFile
146
+ // C4 (#5627): GitServiceImpl constructor → gitServiceFactory above
147
+ //
148
+ // ADR-016 phase 3 (#5693) deleted the @deprecated optional fields that
149
+ // remained on this Interface for legacy test fixtures. Tests that need to
150
+ // substitute primitive implementations cast their deps to
151
+ // `WorktreeLifecycleTestOverrides` (exported below) — the test seam now
152
+ // lives outside the public Interface.
153
+ //
154
+ // Final dep bag: 3 fields. The ADR's envisioned shape was ≤6.
155
+ }
156
+
157
+ /**
158
+ * Test-only override shim. Production callers do not use this type — it
159
+ * exists so legacy test fixtures can substitute the primitive implementations
160
+ * that were inlined into Lifecycle in ADR-016 phase 2 (C1-C4). Pass an object
161
+ * typed `WorktreeLifecycleDeps & WorktreeLifecycleTestOverrides` to the
162
+ * `WorktreeLifecycle` constructor; Lifecycle reads the overrides through the
163
+ * structural-typing escape hatch in `primitiveOverrides()`.
164
+ *
165
+ * The fields here intentionally duplicate the C1-C4-inlined primitive
166
+ * signatures. Adding new fields is fine when a test needs to vary a primitive
167
+ * that has no other seam.
168
+ */
169
+ export type WorktreeLifecycleTestOverrides = WorktreeLifecyclePrimitiveOverrides;
170
+
171
+ /**
172
+ * Internal sentinel — thrown by `_mergeBranchMode` when it has already
173
+ * emitted a user-visible error. The outer `mergeAndExit` catches the type
174
+ * and skips its own warning toast to avoid duplicate notifications.
175
+ */
176
+ class UserNotifiedError extends Error {
177
+ readonly cause?: unknown;
178
+
179
+ constructor(message: string, cause?: unknown) {
180
+ super(message);
181
+ this.name = "UserNotifiedError";
182
+ this.cause = cause;
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Compare two paths for physical identity, tolerating trailing slashes,
188
+ * symlink differences, and case variations on case-insensitive volumes.
189
+ *
190
+ * Used in place of string `===` / `!==` wherever one operand may be
191
+ * realpath-normalised and the other may not be (e.g. raw caller-supplied
192
+ * basePath vs. realpath-normalised projectRoot).
193
+ */
194
+ function isSamePathPhysical(a: string, b: string): boolean {
195
+ return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
196
+ }
197
+
198
+ export type EnterResult =
199
+ | { ok: true; mode: "worktree" | "branch" | "none"; path: string }
200
+ | {
201
+ ok: false;
202
+ reason:
203
+ | "isolation-degraded"
204
+ | "lease-conflict"
205
+ | "creation-failed"
206
+ | "invalid-milestone-id";
207
+ cause?: unknown;
208
+ };
209
+
210
+ export type ExitResult =
211
+ | { ok: true; merged: boolean; codeFilesChanged: boolean }
212
+ | { ok: false; reason: "merge-conflict" | "teardown-failed"; cause?: unknown };
213
+
214
+ /**
215
+ * Session-less merge entry context. Per ADR-016 phase 2 / A1 (#5616), the
216
+ * merge body is structurally session-less — it reads project root, worktree
217
+ * path, and milestoneId. Single-loop callers (`_mergeAndExit`) build a
218
+ * MergeContext from `this.s`. Parallel callers (`parallel-merge.ts`) build
219
+ * one directly without an `AutoSession`.
220
+ */
221
+ export interface MergeContext {
222
+ /** Project root — merge target (where `git merge --squash` lands). */
223
+ originalBasePath: string;
224
+ /**
225
+ * Current worktree path or project root when in branch mode. Used as the
226
+ * cwd anchor for `mergeMilestoneToMain` and the source for
227
+ * `Projection.finalizeProjectionForMerge`.
228
+ */
229
+ worktreeBasePath: string;
230
+ milestoneId: string;
231
+ /**
232
+ * When true, `mergeMilestoneStandalone` returns `{ merged: false,
233
+ * mode: "skipped" }` immediately (mirrors the single-loop guard). Default
234
+ * `false` for parallel callers, which never run with degraded isolation.
235
+ */
236
+ isolationDegraded?: boolean;
237
+ notify: NotifyCtx["notify"];
238
+ }
239
+
240
+ /**
241
+ * Result of `mergeMilestoneStandalone`. `mode` lets callers decide which
242
+ * session-bound side effects to run (worktree-mode → `restoreToProjectRoot`,
243
+ * branch-mode → `rebuildGitService`, skipped → none).
244
+ */
245
+ export interface MergeStandaloneResult {
246
+ merged: boolean;
247
+ mode: "worktree" | "branch" | "skipped";
248
+ codeFilesChanged: boolean;
249
+ pushed: boolean;
250
+ /**
251
+ * Commit message produced by the squash merge, if available. Forwarded
252
+ * from `mergeMilestoneToMain`. Only populated when `merged === true`.
253
+ */
254
+ commitMessage?: string;
255
+ }
256
+
257
+ // ─── Validation ──────────────────────────────────────────────────────────
258
+
259
+ function isValidMilestoneId(milestoneId: string): boolean {
260
+ return !/[\/\\]|\.\./.test(milestoneId);
261
+ }
262
+
263
+ function invalidMilestoneIdError(milestoneId: string): Error {
264
+ return new Error(
265
+ `Invalid milestoneId: ${milestoneId} — contains path separators or traversal`,
266
+ );
267
+ }
268
+
269
+ type WorktreeLifecyclePrimitiveOverrides = {
270
+ readFileSync?: (path: string, encoding: BufferEncoding) => string;
271
+ getCurrentBranch?: (basePath: string) => string;
272
+ checkoutBranch?: (basePath: string, branch: string) => void;
273
+ autoCommitCurrentBranch?: (
274
+ basePath: string,
275
+ unitType: string,
276
+ unitId: string,
277
+ taskContext?: unknown,
278
+ ) => string | null;
279
+ getAutoWorktreePath?: (
280
+ basePath: string,
281
+ milestoneId: string,
282
+ ) => string | null;
283
+ // ADR-016 phase 2 / C2-inlined worktree-manager primitives. Tests still
284
+ // stub these via the structural-typing escape hatch on `WorktreeLifecycleDeps`,
285
+ // so the call sites below check for an override first and fall back to the
286
+ // imported direct primitive.
287
+ isInAutoWorktree?: (basePath: string) => boolean;
288
+ autoWorktreeBranch?: (milestoneId: string) => string;
289
+ teardownAutoWorktree?: (
290
+ basePath: string,
291
+ milestoneId: string,
292
+ opts?: { preserveBranch?: boolean },
293
+ ) => void;
294
+ createAutoWorktree?: (basePath: string, milestoneId: string) => string;
295
+ enterAutoWorktree?: (basePath: string, milestoneId: string) => string;
296
+ enterBranchModeForMilestone?: (basePath: string, milestoneId: string) => void;
297
+ // ADR-016 phase 2 / C3-inlined cache + preferences + path helpers.
298
+ getIsolationMode?: (basePath?: string) => "worktree" | "branch" | "none";
299
+ invalidateAllCaches?: () => void;
300
+ resolveMilestoneFile?: (
301
+ basePath: string,
302
+ milestoneId: string,
303
+ fileType: string,
304
+ ) => string | null;
305
+ loadEffectiveGSDPreferences?: (basePath?: string) =>
306
+ | { preferences?: { git?: Record<string, unknown> } }
307
+ | null
308
+ | undefined;
309
+ };
310
+
311
+ function primitiveOverrides(
312
+ deps: WorktreeLifecycleDeps,
313
+ ): WorktreeLifecyclePrimitiveOverrides {
314
+ return deps as WorktreeLifecycleDeps & WorktreeLifecyclePrimitiveOverrides;
315
+ }
316
+
317
+ function readLifecycleFile(
318
+ deps: WorktreeLifecycleDeps,
319
+ path: string,
320
+ ): string {
321
+ return primitiveOverrides(deps).readFileSync?.(path, "utf-8") ??
322
+ readFileSync(path, "utf-8");
323
+ }
324
+
325
+ function currentLifecycleBranch(
326
+ deps: WorktreeLifecycleDeps,
327
+ basePath: string,
328
+ ): string {
329
+ return primitiveOverrides(deps).getCurrentBranch?.(basePath) ??
330
+ getCurrentBranch(basePath);
331
+ }
332
+
333
+ function checkoutLifecycleBranch(
334
+ deps: WorktreeLifecycleDeps,
335
+ basePath: string,
336
+ branch: string,
337
+ ): void {
338
+ const checkoutBranch = primitiveOverrides(deps).checkoutBranch;
339
+ if (checkoutBranch) {
340
+ checkoutBranch(basePath, branch);
341
+ return;
342
+ }
343
+ nativeCheckoutBranch(basePath, branch);
344
+ }
345
+
346
+ function autoCommitLifecycleBranch(
347
+ deps: WorktreeLifecycleDeps,
348
+ basePath: string,
349
+ unitType: string,
350
+ unitId: string,
351
+ ): string | null {
352
+ return primitiveOverrides(deps).autoCommitCurrentBranch?.(
353
+ basePath,
354
+ unitType,
355
+ unitId,
356
+ ) ?? autoCommitCurrentBranch(basePath, unitType, unitId);
357
+ }
358
+
359
+ // ADR-016 phase 2 / C2-inlined worktree-manager primitives — helpers that
360
+ // honour the structural-typing override pattern so legacy test fixtures keep
361
+ // working without rewriting them onto real-git fixtures.
362
+ function lifecycleIsInAutoWorktree(
363
+ deps: WorktreeLifecycleDeps,
364
+ basePath: string,
365
+ ): boolean {
366
+ return primitiveOverrides(deps).isInAutoWorktree?.(basePath) ??
367
+ isInAutoWorktree(basePath);
368
+ }
369
+
370
+ function lifecycleAutoWorktreeBranch(
371
+ deps: WorktreeLifecycleDeps,
372
+ milestoneId: string,
373
+ ): string {
374
+ return primitiveOverrides(deps).autoWorktreeBranch?.(milestoneId) ??
375
+ autoWorktreeBranch(milestoneId);
376
+ }
377
+
378
+ function lifecycleTeardownAutoWorktree(
379
+ deps: WorktreeLifecycleDeps,
380
+ basePath: string,
381
+ milestoneId: string,
382
+ opts?: { preserveBranch?: boolean },
383
+ ): void {
384
+ const override = primitiveOverrides(deps).teardownAutoWorktree;
385
+ if (override) {
386
+ override(basePath, milestoneId, opts);
387
+ return;
388
+ }
389
+ teardownAutoWorktree(basePath, milestoneId, opts);
390
+ }
391
+
392
+ function lifecycleCreateAutoWorktree(
393
+ deps: WorktreeLifecycleDeps,
394
+ basePath: string,
395
+ milestoneId: string,
396
+ ): string {
397
+ return primitiveOverrides(deps).createAutoWorktree?.(basePath, milestoneId) ??
398
+ createAutoWorktree(basePath, milestoneId);
399
+ }
400
+
401
+ function lifecycleEnterAutoWorktree(
402
+ deps: WorktreeLifecycleDeps,
403
+ basePath: string,
404
+ milestoneId: string,
405
+ ): string {
406
+ return primitiveOverrides(deps).enterAutoWorktree?.(basePath, milestoneId) ??
407
+ enterAutoWorktree(basePath, milestoneId);
408
+ }
409
+
410
+ function lifecycleEnterBranchMode(
411
+ deps: WorktreeLifecycleDeps,
412
+ basePath: string,
413
+ milestoneId: string,
414
+ ): void {
415
+ const override = primitiveOverrides(deps).enterBranchModeForMilestone;
416
+ if (override) {
417
+ override(basePath, milestoneId);
418
+ return;
419
+ }
420
+ enterBranchModeForMilestone(basePath, milestoneId);
421
+ }
422
+
423
+ // ADR-016 phase 2 / C3-inlined cache + preferences + path helpers.
424
+ function lifecycleGetIsolationMode(
425
+ deps: WorktreeLifecycleDeps,
426
+ basePath?: string,
427
+ ): "worktree" | "branch" | "none" {
428
+ return primitiveOverrides(deps).getIsolationMode?.(basePath) ??
429
+ getIsolationMode(basePath);
430
+ }
431
+
432
+ function lifecycleInvalidateAllCaches(deps: WorktreeLifecycleDeps): void {
433
+ const override = primitiveOverrides(deps).invalidateAllCaches;
434
+ if (override) {
435
+ override();
436
+ return;
437
+ }
438
+ invalidateAllCaches();
439
+ }
440
+
441
+ function lifecycleResolveMilestoneFile(
442
+ deps: WorktreeLifecycleDeps,
443
+ basePath: string,
444
+ milestoneId: string,
445
+ fileType: string,
446
+ ): string | null {
447
+ return primitiveOverrides(deps).resolveMilestoneFile?.(
448
+ basePath,
449
+ milestoneId,
450
+ fileType,
451
+ ) ?? resolveMilestoneFile(basePath, milestoneId, fileType);
452
+ }
453
+
454
+ function lifecycleLoadPreferences(
455
+ deps: WorktreeLifecycleDeps,
456
+ basePath?: string,
457
+ ):
458
+ | { preferences?: { git?: Record<string, unknown> } }
459
+ | null
460
+ | undefined {
461
+ const override = primitiveOverrides(deps).loadEffectiveGSDPreferences;
462
+ if (override) return override(basePath);
463
+ return loadEffectiveGSDPreferences(basePath) as
464
+ | { preferences?: { git?: Record<string, unknown> } }
465
+ | null
466
+ | undefined;
467
+ }
468
+
469
+ /**
470
+ * Throwing variant used by the merge/exit paths that surface failures via
471
+ * the typed `ExitResult` (callers wrap the throw → cause). The enter path
472
+ * uses `isValidMilestoneId` + the typed result directly.
473
+ */
474
+ function validateMilestoneId(milestoneId: string): void {
475
+ if (!isValidMilestoneId(milestoneId)) {
476
+ throw invalidMilestoneIdError(milestoneId);
477
+ }
478
+ }
479
+
480
+ // ─── Implementation core ─────────────────────────────────────────────────
481
+
482
+ /**
483
+ * Shared implementation of milestone entry. Called by both
484
+ * `WorktreeLifecycle.enterMilestone` and the legacy
485
+ * `WorktreeResolver.mergeAndEnterNext` internal recursion until the Resolver
486
+ * retires (slice #5587).
487
+ *
488
+ * Side effects (preserved from the original `WorktreeResolver.enterMilestone`):
489
+ * - mutates `s.milestoneLeaseToken` on lease claim/release/refresh
490
+ * - mutates `s.basePath` on successful worktree entry
491
+ * - mutates `s.gitService` (rebuilt against the new base path)
492
+ * - mutates `s.isolationDegraded` on hard failure of branch/worktree setup
493
+ * - emits journal events: worktree-skip, worktree-enter, worktree-create-failed
494
+ * - emits worktree-created telemetry on successful entry
495
+ * - notifies the caller via `ctx.notify` for every user-visible outcome
496
+ */
497
+ export function _enterMilestoneCore(
498
+ s: AutoSession,
499
+ deps: WorktreeLifecycleDeps,
500
+ milestoneId: string,
501
+ ctx: NotifyCtx,
502
+ ): EnterResult {
503
+ if (!isValidMilestoneId(milestoneId)) {
504
+ debugLog("WorktreeLifecycle", {
505
+ action: "enterMilestone",
506
+ milestoneId,
507
+ rejected: "invalid-milestone-id",
508
+ });
509
+ return {
510
+ ok: false,
511
+ reason: "invalid-milestone-id",
512
+ cause: invalidMilestoneIdError(milestoneId),
513
+ };
514
+ }
515
+
516
+ if (s.isolationDegraded) {
517
+ debugLog("WorktreeLifecycle", {
518
+ action: "enterMilestone",
519
+ milestoneId,
520
+ skipped: true,
521
+ reason: "isolation-degraded",
522
+ });
523
+ return { ok: false, reason: "isolation-degraded" };
524
+ }
525
+
526
+ // Phase B: claim a milestone lease before any worktree mutation. Two
527
+ // workers cannot enter the same milestone concurrently. Best-effort:
528
+ // skip if no worker registered (single-worker fallback) or DB
529
+ // unavailable; reuse existing lease if we already hold it on this
530
+ // milestone (re-entry within the same session).
531
+ if (s.workerId) {
532
+ if (
533
+ s.currentMilestoneId === milestoneId &&
534
+ s.milestoneLeaseToken !== null
535
+ ) {
536
+ const refreshed = refreshMilestoneLease(
537
+ s.workerId,
538
+ milestoneId,
539
+ s.milestoneLeaseToken,
540
+ );
541
+ if (refreshed) {
542
+ debugLog("WorktreeLifecycle", {
543
+ action: "enterMilestone",
544
+ milestoneId,
545
+ leaseRefreshed: true,
546
+ fencingToken: s.milestoneLeaseToken,
547
+ });
548
+ } else {
549
+ debugLog("WorktreeLifecycle", {
550
+ action: "enterMilestone",
551
+ milestoneId,
552
+ staleLeaseToken: s.milestoneLeaseToken,
553
+ });
554
+ s.milestoneLeaseToken = null;
555
+ }
556
+ }
557
+
558
+ // If we held a different milestone, release it first so other
559
+ // workers don't have to wait for TTL.
560
+ if (
561
+ s.currentMilestoneId &&
562
+ s.currentMilestoneId !== milestoneId &&
563
+ s.milestoneLeaseToken !== null
564
+ ) {
565
+ try {
566
+ releaseMilestoneLease(
567
+ s.workerId,
568
+ s.currentMilestoneId,
569
+ s.milestoneLeaseToken,
570
+ );
571
+ } catch (err) {
572
+ debugLog("WorktreeLifecycle", {
573
+ action: "enterMilestone",
574
+ milestoneId,
575
+ releasePriorLeaseError:
576
+ err instanceof Error ? err.message : String(err),
577
+ });
578
+ }
579
+ s.milestoneLeaseToken = null;
580
+ }
581
+
582
+ if (s.milestoneLeaseToken === null) {
583
+ try {
584
+ const claim = claimMilestoneLease(s.workerId, milestoneId);
585
+ if (claim.ok) {
586
+ s.milestoneLeaseToken = claim.token;
587
+ debugLog("WorktreeLifecycle", {
588
+ action: "enterMilestone",
589
+ milestoneId,
590
+ leaseAcquired: true,
591
+ fencingToken: claim.token,
592
+ expiresAt: claim.expiresAt,
593
+ });
594
+ } else {
595
+ // Lease held by another worker — fail loud so the user can
596
+ // see the conflict instead of silently double-running.
597
+ const msg = `Milestone ${milestoneId} is held by worker ${claim.byWorker} until ${claim.expiresAt}.`;
598
+ debugLog("WorktreeLifecycle", {
599
+ action: "enterMilestone",
600
+ milestoneId,
601
+ leaseHeldByOther: claim.byWorker,
602
+ expiresAt: claim.expiresAt,
603
+ });
604
+ ctx.notify(
605
+ `${msg} Another auto-mode worker is active. Stop it before entering ${milestoneId}.`,
606
+ "error",
607
+ );
608
+ return { ok: false, reason: "lease-conflict" };
609
+ }
610
+ } catch (err) {
611
+ // DB unavailable or other error — log and fall through to the
612
+ // pre-Phase-B single-worker behavior so a fresh project before
613
+ // DB init still works.
614
+ debugLog("WorktreeLifecycle", {
615
+ action: "enterMilestone",
616
+ milestoneId,
617
+ leaseError: err instanceof Error ? err.message : String(err),
618
+ });
619
+ }
620
+ }
621
+ }
622
+
623
+ // Resolve the project root for worktree operations via shared helper.
624
+ // Handles the case where originalBasePath is falsy and basePath is itself
625
+ // a worktree path — prevents double-nested worktree paths (#3729).
626
+ const basePath = resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
627
+ const mode = getIsolationMode(basePath);
628
+
629
+ if (mode === "none") {
630
+ debugLog("WorktreeLifecycle", {
631
+ action: "enterMilestone",
632
+ milestoneId,
633
+ skipped: true,
634
+ reason: "isolation-disabled",
635
+ });
636
+ emitJournalEvent(s.originalBasePath || s.basePath, {
637
+ ts: new Date().toISOString(),
638
+ flowId: randomUUID(),
639
+ seq: 0,
640
+ eventType: "worktree-skip",
641
+ data: { milestoneId, reason: "isolation-disabled" },
642
+ });
643
+ return { ok: true, mode: "none", path: basePath };
644
+ }
645
+
646
+ debugLog("WorktreeLifecycle", {
647
+ action: "enterMilestone",
648
+ milestoneId,
649
+ mode,
650
+ basePath,
651
+ });
652
+
653
+ if (
654
+ mode === "worktree" &&
655
+ s.currentMilestoneId === milestoneId &&
656
+ s.basePath !== basePath
657
+ ) {
658
+ debugLog("WorktreeLifecycle", {
659
+ action: "enterMilestone",
660
+ milestoneId,
661
+ mode: "worktree",
662
+ result: "already-entered",
663
+ wtPath: s.basePath,
664
+ });
665
+ return { ok: true, mode: "worktree", path: s.basePath };
666
+ }
667
+
668
+ // ── Branch mode: create/checkout milestone branch, stay in project root ──
669
+ if (mode === "branch") {
670
+ try {
671
+ lifecycleEnterBranchMode(deps, basePath, milestoneId);
672
+ // basePath does not change — no worktree, no chdir.
673
+ // Rebuild GitService so the new HEAD is reflected, then flush any
674
+ // path-keyed caches that may have been populated before the checkout.
675
+ rebuildGitService(s, deps);
676
+ invalidateAllCaches();
677
+ debugLog("WorktreeLifecycle", {
678
+ action: "enterMilestone",
679
+ milestoneId,
680
+ mode: "branch",
681
+ result: "success",
682
+ });
683
+ emitJournalEvent(basePath, {
684
+ ts: new Date().toISOString(),
685
+ flowId: randomUUID(),
686
+ seq: 0,
687
+ eventType: "worktree-skip",
688
+ data: { milestoneId, reason: "branch-mode-no-worktree" },
689
+ });
690
+ ctx.notify(`Switched to branch milestone/${milestoneId}.`, "info");
691
+ return { ok: true, mode: "branch", path: basePath };
692
+ } catch (err) {
693
+ const msg = err instanceof Error ? err.message : String(err);
694
+ debugLog("WorktreeLifecycle", {
695
+ action: "enterMilestone",
696
+ milestoneId,
697
+ mode: "branch",
698
+ result: "error",
699
+ error: msg,
700
+ });
701
+ ctx.notify(
702
+ `Branch isolation setup for ${milestoneId} failed: ${msg}. Continuing on current branch.`,
703
+ "warning",
704
+ );
705
+ s.isolationDegraded = true;
706
+ return { ok: false, reason: "creation-failed", cause: err };
707
+ }
708
+ }
709
+
710
+ // ── Worktree mode ────────────────────────────────────────────────────────
711
+ try {
712
+ const existingPath =
713
+ (primitiveOverrides(deps).getAutoWorktreePath ?? getAutoWorktreePath)(
714
+ basePath,
715
+ milestoneId,
716
+ );
717
+ let wtPath: string;
718
+
719
+ if (existingPath) {
720
+ wtPath = lifecycleEnterAutoWorktree(deps, basePath, milestoneId);
721
+ } else {
722
+ wtPath = lifecycleCreateAutoWorktree(deps, basePath, milestoneId);
723
+ }
724
+
725
+ s.basePath = wtPath;
726
+ rebuildGitService(s, deps);
727
+ invalidateAllCaches();
728
+
729
+ // Per ADR-016: Lifecycle calls Projection on entry, before any Unit
730
+ // dispatches. Build a temporary scope from the new basePath; callers may
731
+ // later set s.scope via their own rebuildScope hook (the two are
732
+ // independent — this scope is only used to drive the projection rules).
733
+ try {
734
+ const enterScope = scopeMilestone(createWorkspace(wtPath), milestoneId);
735
+ deps.worktreeProjection.projectRootToWorktree(enterScope);
736
+ } catch (projErr) {
737
+ // Non-fatal: projection failures must not block worktree entry.
738
+ // The pre-dispatch path in auto/phases.ts performs the same projection
739
+ // on every iteration, so a transient failure here self-heals on the
740
+ // next loop pass.
741
+ debugLog("WorktreeLifecycle", {
742
+ action: "enterMilestone",
743
+ phase: "projection-on-enter",
744
+ error: projErr instanceof Error ? projErr.message : String(projErr),
745
+ });
746
+ }
747
+
748
+ debugLog("WorktreeLifecycle", {
749
+ action: "enterMilestone",
750
+ milestoneId,
751
+ result: "success",
752
+ wtPath,
753
+ });
754
+ emitJournalEvent(s.originalBasePath || s.basePath, {
755
+ ts: new Date().toISOString(),
756
+ flowId: randomUUID(),
757
+ seq: 0,
758
+ eventType: "worktree-enter",
759
+ data: { milestoneId, wtPath, created: !existingPath },
760
+ });
761
+ // #4764 — record creation/enter as a lifecycle event so the telemetry
762
+ // aggregator can pair it with the eventual worktree-merged event.
763
+ try {
764
+ emitWorktreeCreated(s.originalBasePath || s.basePath, milestoneId, {
765
+ reason: existingPath ? "enter-milestone" : "create-milestone",
766
+ });
767
+ } catch (telemetryErr) {
768
+ debugLog("WorktreeLifecycle", {
769
+ action: "enterMilestone",
770
+ phase: "telemetry-emit",
771
+ error:
772
+ telemetryErr instanceof Error
773
+ ? telemetryErr.message
774
+ : String(telemetryErr),
775
+ });
776
+ }
777
+ ctx.notify(`Entered worktree for ${milestoneId} at ${wtPath}`, "info");
778
+ return { ok: true, mode: "worktree", path: wtPath };
779
+ } catch (err) {
780
+ const msg = err instanceof Error ? err.message : String(err);
781
+ debugLog("WorktreeLifecycle", {
782
+ action: "enterMilestone",
783
+ milestoneId,
784
+ result: "error",
785
+ error: msg,
786
+ });
787
+ emitJournalEvent(s.originalBasePath || s.basePath, {
788
+ ts: new Date().toISOString(),
789
+ flowId: randomUUID(),
790
+ seq: 0,
791
+ eventType: "worktree-create-failed",
792
+ data: { milestoneId, error: msg, fallback: "project-root" },
793
+ });
794
+ ctx.notify(
795
+ `Auto-worktree creation for ${milestoneId} failed: ${msg}. Continuing in project root.`,
796
+ "warning",
797
+ );
798
+ // Degrade isolation for the rest of this session so mergeAndExit
799
+ // doesn't try to merge a nonexistent worktree branch (#2483)
800
+ s.isolationDegraded = true;
801
+ // Do NOT update s.basePath — stay in project root
802
+ return { ok: false, reason: "creation-failed", cause: err };
803
+ }
804
+ }
805
+
806
+ /**
807
+ * Resolve the basePath to adopt on resume from a paused session.
808
+ *
809
+ * Returns `persistedWorktreePath` when the path is non-null and exists on
810
+ * disk; otherwise falls back to `base`. Used by
811
+ * `WorktreeLifecycle.resumeFromPausedSession` (#5621). Exported as a pure
812
+ * function so unit tests can exercise the path-resolution logic without
813
+ * constructing a `WorktreeLifecycle` instance.
814
+ *
815
+ * The optional `pathExists` parameter exists only for tests that need to
816
+ * substitute a stub for `existsSync`.
817
+ */
818
+ export function resolvePausedResumeBasePath(
819
+ base: string,
820
+ persistedWorktreePath: string | null | undefined,
821
+ pathExists: (p: string) => boolean = existsSync,
822
+ ): string {
823
+ return persistedWorktreePath && pathExists(persistedWorktreePath)
824
+ ? persistedWorktreePath
825
+ : base;
826
+ }
827
+
828
+ function rebuildGitService(
829
+ s: AutoSession,
830
+ deps: WorktreeLifecycleDeps,
831
+ ): void {
832
+ // ADR-016 phase 2 / C4 (#5627): the gitConfig load and constructor
833
+ // construction live behind `gitServiceFactory`. Lifecycle no longer
834
+ // sees the constructor shape, the gitConfig type, or the unknown→
835
+ // GitService cast.
836
+ s.gitService = deps.gitServiceFactory(s.basePath);
837
+ }
838
+
839
+ // ─── Session-less merge entry (ADR-016 phase 2 / A1) ─────────────────────
840
+
841
+ /**
842
+ * Worktree-mode merge body. Session-less — operates on a `MergeContext`.
843
+ *
844
+ * On error: emits the "worktree-merge-failed" journal event, notifies the
845
+ * user, cleans up stale `SQUASH_MSG` / `MERGE_HEAD` / `MERGE_MSG` files
846
+ * (#1389), and chdirs back to project root before rethrowing. Session-side
847
+ * cleanup (`restoreToProjectRoot`, `gitService` rebuild) is the caller's
848
+ * responsibility.
849
+ */
850
+ function _mergeWorktreeModeImpl(
851
+ deps: WorktreeLifecycleDeps,
852
+ mctx: MergeContext,
853
+ ): MergeStandaloneResult {
854
+ const { originalBasePath, worktreeBasePath, milestoneId, notify } = mctx;
855
+ if (!originalBasePath) {
856
+ debugLog("WorktreeLifecycle", {
857
+ action: "mergeAndExit",
858
+ milestoneId,
859
+ mode: "worktree",
860
+ skipped: true,
861
+ reason: "missing-original-base",
862
+ });
863
+ return {
864
+ merged: false,
865
+ mode: "worktree",
866
+ codeFilesChanged: false,
867
+ pushed: false,
868
+ };
869
+ }
870
+
871
+ try {
872
+ // ADR-016: final projection before teardown. Replaces the legacy
873
+ // syncWorktreeStateBack(originalBase, basePath, milestoneId) call.
874
+ const finalScope = scopeMilestone(
875
+ createWorkspace(worktreeBasePath),
876
+ milestoneId,
877
+ );
878
+ const { synced } = deps.worktreeProjection.finalizeProjectionForMerge(
879
+ finalScope,
880
+ );
881
+ if (synced.length > 0) {
882
+ debugLog("WorktreeLifecycle", {
883
+ action: "mergeAndExit",
884
+ milestoneId,
885
+ phase: "reverse-sync",
886
+ synced: synced.length,
887
+ });
888
+ }
889
+
890
+ // Resolve roadmap — try project root first, then worktree path as
891
+ // fallback. The worktree may hold the only copy when state-back
892
+ // projection silently dropped it or .gsd/ is not symlinked. Without
893
+ // the fallback, a missing roadmap triggers bare teardown which
894
+ // deletes the branch and orphans all milestone commits (#1573).
895
+ let roadmapPath = resolveMilestoneFile(
896
+ originalBasePath,
897
+ milestoneId,
898
+ "ROADMAP",
899
+ );
900
+ if (
901
+ !roadmapPath &&
902
+ !isSamePathPhysical(worktreeBasePath, originalBasePath)
903
+ ) {
904
+ roadmapPath = resolveMilestoneFile(
905
+ worktreeBasePath,
906
+ milestoneId,
907
+ "ROADMAP",
908
+ );
909
+ if (roadmapPath) {
910
+ debugLog("WorktreeLifecycle", {
911
+ action: "mergeAndExit",
912
+ milestoneId,
913
+ phase: "roadmap-fallback",
914
+ note: "resolved from worktree path",
915
+ });
916
+ }
917
+ }
918
+
919
+ if (!roadmapPath) {
920
+ // No roadmap at either location — teardown but PRESERVE the branch
921
+ // so commits are not orphaned (#1573).
922
+ lifecycleTeardownAutoWorktree(deps, originalBasePath, milestoneId, {
923
+ preserveBranch: true,
924
+ });
925
+ notify(
926
+ `Exited worktree for ${milestoneId} (no roadmap found — branch preserved for manual merge).`,
927
+ "warning",
928
+ );
929
+ return {
930
+ merged: false,
931
+ mode: "worktree",
932
+ codeFilesChanged: false,
933
+ pushed: false,
934
+ };
935
+ }
936
+
937
+ const roadmapContent = readLifecycleFile(deps, roadmapPath);
938
+ const mergeResult = deps.mergeMilestoneToMain(
939
+ originalBasePath,
940
+ milestoneId,
941
+ roadmapContent,
942
+ );
943
+
944
+ // #2945 Bug 3: mergeMilestoneToMain performs best-effort worktree
945
+ // cleanup internally (step 12), but it can silently fail on Windows
946
+ // or when the worktree directory is locked. Perform a secondary
947
+ // teardown here to ensure the worktree is properly cleaned up.
948
+ // Idempotent — if already removed, teardownAutoWorktree no-ops.
949
+ try {
950
+ lifecycleTeardownAutoWorktree(deps, originalBasePath, milestoneId);
951
+ } catch {
952
+ // Best-effort — primary cleanup in mergeMilestoneToMain may have
953
+ // already removed the worktree.
954
+ }
955
+
956
+ if (mergeResult.codeFilesChanged) {
957
+ notify(
958
+ `Milestone ${milestoneId} merged to main.${mergeResult.pushed ? " Pushed to remote." : ""}`,
959
+ "info",
960
+ );
961
+ } else {
962
+ // #1906 — milestone produced only .gsd/ metadata. Surface
963
+ // clearly so the user knows the milestone is not truly complete.
964
+ notify(
965
+ `WARNING: Milestone ${milestoneId} merged to main but contained NO code changes — only .gsd/ metadata files. ` +
966
+ `The milestone summary may describe planned work that was never implemented. ` +
967
+ `Review the milestone output and re-run if code is missing.`,
968
+ "warning",
969
+ );
970
+ }
971
+
972
+ return {
973
+ merged: true,
974
+ mode: "worktree",
975
+ codeFilesChanged: mergeResult.codeFilesChanged,
976
+ pushed: mergeResult.pushed,
977
+ commitMessage: mergeResult.commitMessage,
978
+ };
979
+ } catch (err) {
980
+ const msg = err instanceof Error ? err.message : String(err);
981
+ debugLog("WorktreeLifecycle", {
982
+ action: "mergeAndExit",
983
+ milestoneId,
984
+ result: "error",
985
+ error: msg,
986
+ fallback: "chdir-to-project-root",
987
+ });
988
+ emitJournalEvent(originalBasePath || worktreeBasePath, {
989
+ ts: new Date().toISOString(),
990
+ flowId: randomUUID(),
991
+ seq: 0,
992
+ eventType: "worktree-merge-failed",
993
+ data: { milestoneId, error: msg },
994
+ });
995
+ // Surface a clear, actionable error. Worktree and milestone branch
996
+ // are intentionally preserved — nothing has been deleted. User can
997
+ // retry /gsd dispatch complete-milestone or merge manually once the
998
+ // underlying issue is fixed (#1668, #1891).
999
+ notify(
1000
+ `Milestone merge failed: ${msg}. Your worktree and milestone branch are preserved — retry with \`/gsd dispatch complete-milestone\` or merge manually.`,
1001
+ "warning",
1002
+ );
1003
+
1004
+ // Clean up stale merge state left by failed squash-merge (#1389)
1005
+ try {
1006
+ const gitDir = join(originalBasePath || worktreeBasePath, ".git");
1007
+ for (const f of ["SQUASH_MSG", "MERGE_HEAD", "MERGE_MSG"]) {
1008
+ const p = join(gitDir, f);
1009
+ if (existsSync(p)) unlinkSync(p);
1010
+ }
1011
+ } catch {
1012
+ /* best-effort */
1013
+ }
1014
+
1015
+ // Error recovery: chdir back to project root only when no real worktree
1016
+ // path is available. Session-side cleanup (restoreToProjectRoot,
1017
+ // gitService rebuild) is the caller's responsibility.
1018
+ if (originalBasePath && !worktreeBasePath) {
1019
+ try {
1020
+ process.chdir(originalBasePath);
1021
+ } catch {
1022
+ /* best-effort */
1023
+ }
1024
+ }
1025
+
1026
+ // Re-throw: MergeConflictError stops the auto loop (#2330);
1027
+ // non-conflict errors must also propagate so broken states are
1028
+ // diagnosable (#4380).
1029
+ throw err;
1030
+ }
1031
+ }
1032
+
1033
+ /**
1034
+ * Branch-mode merge body. Session-less.
1035
+ *
1036
+ * Session-side `gitService` rebuild after HEAD changes is the caller's
1037
+ * responsibility. The branch-mode `UserNotifiedError` sentinel still flows
1038
+ * through unchanged so the outer caller can suppress duplicate toasts.
1039
+ */
1040
+ function _mergeBranchModeImpl(
1041
+ deps: WorktreeLifecycleDeps,
1042
+ mctx: MergeContext,
1043
+ ): MergeStandaloneResult {
1044
+ const { worktreeBasePath, milestoneId, notify } = mctx;
1045
+ try {
1046
+ const currentBranch = currentLifecycleBranch(deps, worktreeBasePath);
1047
+ const milestoneBranch = lifecycleAutoWorktreeBranch(deps, milestoneId);
1048
+
1049
+ if (currentBranch !== milestoneBranch) {
1050
+ // #5538-followup: previous behaviour was to silently `return false`
1051
+ // when HEAD wasn't on the milestone branch — that let the loop
1052
+ // advance with the milestone's commits stranded on the branch.
1053
+ // Attempt recovery by force-checking-out the milestone branch; if
1054
+ // that fails, throw so the caller pauses auto-mode and the user
1055
+ // sees the failure instead of a silent merge skip.
1056
+ debugLog("WorktreeLifecycle", {
1057
+ action: "mergeAndExit",
1058
+ milestoneId,
1059
+ mode: "branch",
1060
+ recovery: "checkout-milestone-branch",
1061
+ currentBranch,
1062
+ milestoneBranch,
1063
+ });
1064
+ try {
1065
+ checkoutLifecycleBranch(deps, worktreeBasePath, milestoneBranch);
1066
+ } catch (checkoutErr) {
1067
+ const checkoutMsg =
1068
+ checkoutErr instanceof Error
1069
+ ? checkoutErr.message
1070
+ : String(checkoutErr);
1071
+ notify(
1072
+ `Cannot merge milestone ${milestoneId}: working tree is on ${currentBranch} and checkout to ${milestoneBranch} failed (${checkoutMsg}). Resolve manually and run /gsd auto to resume.`,
1073
+ "error",
1074
+ );
1075
+ throw new UserNotifiedError(checkoutMsg, checkoutErr);
1076
+ }
1077
+
1078
+ const reverify = currentLifecycleBranch(deps, worktreeBasePath);
1079
+ if (reverify !== milestoneBranch) {
1080
+ const reverifyMsg = `branch checkout to ${milestoneBranch} reported success but current branch is ${reverify}`;
1081
+ notify(
1082
+ `Cannot merge milestone ${milestoneId}: ${reverifyMsg}. Resolve manually and run /gsd auto to resume.`,
1083
+ "error",
1084
+ );
1085
+ throw new UserNotifiedError(reverifyMsg);
1086
+ }
1087
+ }
1088
+
1089
+ const roadmapPath = resolveMilestoneFile(
1090
+ worktreeBasePath,
1091
+ milestoneId,
1092
+ "ROADMAP",
1093
+ );
1094
+ if (!roadmapPath) {
1095
+ debugLog("WorktreeLifecycle", {
1096
+ action: "mergeAndExit",
1097
+ milestoneId,
1098
+ mode: "branch",
1099
+ skipped: true,
1100
+ reason: "no-roadmap",
1101
+ });
1102
+ return {
1103
+ merged: false,
1104
+ mode: "branch",
1105
+ codeFilesChanged: false,
1106
+ pushed: false,
1107
+ };
1108
+ }
1109
+
1110
+ const roadmapContent = readLifecycleFile(deps, roadmapPath);
1111
+ const mergeResult = deps.mergeMilestoneToMain(
1112
+ worktreeBasePath,
1113
+ milestoneId,
1114
+ roadmapContent,
1115
+ );
1116
+
1117
+ if (mergeResult.codeFilesChanged) {
1118
+ notify(
1119
+ `Milestone ${milestoneId} merged (branch mode).${mergeResult.pushed ? " Pushed to remote." : ""}`,
1120
+ "info",
1121
+ );
1122
+ } else {
1123
+ notify(
1124
+ `WARNING: Milestone ${milestoneId} merged (branch mode) but contained NO code changes — only .gsd/ metadata. ` +
1125
+ `Review the milestone output and re-run if code is missing.`,
1126
+ "warning",
1127
+ );
1128
+ }
1129
+ debugLog("WorktreeLifecycle", {
1130
+ action: "mergeAndExit",
1131
+ milestoneId,
1132
+ mode: "branch",
1133
+ result: "success",
1134
+ });
1135
+ return {
1136
+ merged: true,
1137
+ mode: "branch",
1138
+ codeFilesChanged: mergeResult.codeFilesChanged,
1139
+ pushed: mergeResult.pushed,
1140
+ commitMessage: mergeResult.commitMessage,
1141
+ };
1142
+ } catch (err) {
1143
+ const msg = err instanceof Error ? err.message : String(err);
1144
+ debugLog("WorktreeLifecycle", {
1145
+ action: "mergeAndExit",
1146
+ milestoneId,
1147
+ mode: "branch",
1148
+ result: "error",
1149
+ error: msg,
1150
+ });
1151
+ if (!(err instanceof UserNotifiedError)) {
1152
+ notify(`Milestone merge failed (branch mode): ${msg}`, "warning");
1153
+ }
1154
+ // Re-throw all errors so callers can apply their own recovery (#4380).
1155
+ throw err;
1156
+ }
1157
+ }
1158
+
1159
+ /**
1160
+ * Session-less merge entry (ADR-016 phase 2 / A1, issue #5618).
1161
+ *
1162
+ * Runs the worktree-mode or branch-mode merge body without touching session
1163
+ * state. Used directly by `parallel-merge.ts` and indirectly (via
1164
+ * `_mergeAndExit`) by the single-loop path. Caller is responsible for any
1165
+ * session-side cleanup based on the returned `mode`.
1166
+ *
1167
+ * **CWD anchor**: anchors `process.cwd()` at `originalBasePath` before
1168
+ * non-worktree merge paths to mirror the single-loop guard against ENOENT
1169
+ * after teardown (de73fb43d). Worktree-mode merge paths keep the real
1170
+ * worktree as cwd because `mergeMilestoneToMain()` infers source worktree
1171
+ * state from `process.cwd()`. Best-effort; silent on failure.
1172
+ *
1173
+ * **Failure handling**: `MergeConflictError` and other unrecoverable errors
1174
+ * propagate to the caller. The caller is responsible for any state restore
1175
+ * (single-loop callers re-`chdir` and `restoreToProjectRoot`; parallel
1176
+ * callers surface to the user as a `MergeResult` with `success: false`).
1177
+ */
1178
+ export function mergeMilestoneStandalone(
1179
+ deps: WorktreeLifecycleDeps,
1180
+ mctx: MergeContext,
1181
+ ): MergeStandaloneResult {
1182
+ const { originalBasePath, worktreeBasePath, milestoneId, notify } = mctx;
1183
+ validateMilestoneId(milestoneId);
1184
+
1185
+ if (mctx.isolationDegraded) {
1186
+ if (originalBasePath) {
1187
+ try {
1188
+ process.chdir(originalBasePath);
1189
+ } catch (err) {
1190
+ debugLog("WorktreeLifecycle", {
1191
+ action: "mergeAndExit",
1192
+ phase: "pre-merge-chdir-failed",
1193
+ milestoneId,
1194
+ originalBasePath,
1195
+ error: err instanceof Error ? err.message : String(err),
1196
+ });
1197
+ }
1198
+ }
1199
+ debugLog("WorktreeLifecycle", {
1200
+ action: "mergeAndExit",
1201
+ milestoneId,
1202
+ skipped: true,
1203
+ reason: "isolation-degraded",
1204
+ });
1205
+ notify(
1206
+ `Skipping worktree merge for ${milestoneId} — isolation was degraded (worktree creation failed earlier). Work is on the current branch.`,
1207
+ "info",
1208
+ );
1209
+ return {
1210
+ merged: false,
1211
+ mode: "skipped",
1212
+ codeFilesChanged: false,
1213
+ pushed: false,
1214
+ };
1215
+ }
1216
+
1217
+ const mode = getIsolationMode(originalBasePath || worktreeBasePath);
1218
+ debugLog("WorktreeLifecycle", {
1219
+ action: "mergeAndExit",
1220
+ milestoneId,
1221
+ mode,
1222
+ basePath: worktreeBasePath,
1223
+ });
1224
+ emitJournalEvent(originalBasePath || worktreeBasePath, {
1225
+ ts: new Date().toISOString(),
1226
+ flowId: randomUUID(),
1227
+ seq: 0,
1228
+ eventType: "worktree-merge-start",
1229
+ data: { milestoneId, mode },
1230
+ });
1231
+
1232
+ // #2625: If we are physically inside an auto-worktree, we MUST merge
1233
+ // regardless of the current isolation config. This prevents data loss
1234
+ // when the default isolation mode changes between versions.
1235
+ const inWorktree =
1236
+ lifecycleIsInAutoWorktree(deps, worktreeBasePath) && Boolean(originalBasePath);
1237
+
1238
+ if (mode === "none" && !inWorktree) {
1239
+ debugLog("WorktreeLifecycle", {
1240
+ action: "mergeAndExit",
1241
+ milestoneId,
1242
+ skipped: true,
1243
+ reason: "mode-none",
1244
+ });
1245
+ // Anchor cwd at project root before the early return so subsequent
1246
+ // process.cwd() calls after the skip don't ENOENT if we were inside a
1247
+ // worktree directory that gets torn down later. Best-effort.
1248
+ if (originalBasePath) {
1249
+ try {
1250
+ process.chdir(originalBasePath);
1251
+ } catch {
1252
+ /* best-effort */
1253
+ }
1254
+ }
1255
+ return {
1256
+ merged: false,
1257
+ mode: "skipped",
1258
+ codeFilesChanged: false,
1259
+ pushed: false,
1260
+ };
1261
+ }
1262
+
1263
+ // Set cwd to the correct anchor before dispatching to mode implementations.
1264
+ // Worktree mode / in-worktree override must run from the live worktree so
1265
+ // mergeMilestoneToMain can find worktree-local state; branch mode runs from
1266
+ // the original project root. Best-effort for synthetic test paths.
1267
+ const targetCwd = mode === "worktree" || inWorktree
1268
+ ? worktreeBasePath
1269
+ : originalBasePath;
1270
+ if (targetCwd) {
1271
+ try {
1272
+ process.chdir(targetCwd);
1273
+ } catch (err) {
1274
+ debugLog("WorktreeLifecycle", {
1275
+ action: "mergeAndExit",
1276
+ phase: "pre-merge-chdir-failed",
1277
+ milestoneId,
1278
+ targetCwd,
1279
+ error: err instanceof Error ? err.message : String(err),
1280
+ });
1281
+ }
1282
+ }
1283
+
1284
+ if (mode === "worktree" || inWorktree) {
1285
+ return _mergeWorktreeModeImpl(deps, mctx);
1286
+ }
1287
+ if (mode === "branch") {
1288
+ return _mergeBranchModeImpl(deps, mctx);
1289
+ }
1290
+ // Defensive fallback — should not reach here given the mode-none guard above.
1291
+ return {
1292
+ merged: false,
1293
+ mode: "skipped",
1294
+ codeFilesChanged: false,
1295
+ pushed: false,
1296
+ };
1297
+ }
1298
+
1299
+ // ─── Module class ────────────────────────────────────────────────────────
1300
+
1301
+ /**
1302
+ * Worktree Lifecycle module instance.
1303
+ *
1304
+ * Constructed once per auto-mode session. Holds the session reference so
1305
+ * verbs can mutate `s.basePath` and related coordination state directly
1306
+ * without round-tripping through callers.
1307
+ */
1308
+ export class WorktreeLifecycle {
1309
+ private readonly s: AutoSession;
1310
+ private readonly deps: WorktreeLifecycleDeps;
1311
+
1312
+ constructor(s: AutoSession, deps: WorktreeLifecycleDeps) {
1313
+ this.s = s;
1314
+ this.deps = deps;
1315
+ }
1316
+
1317
+ /**
1318
+ * Enter or create the auto-worktree for `milestoneId`. Idempotent if
1319
+ * already in this milestone (lease refreshed; basePath unchanged).
1320
+ *
1321
+ * Returns a typed `EnterResult` describing the outcome. Callers may
1322
+ * ignore the result if they read `s.basePath` directly afterwards
1323
+ * (legacy behaviour); new callers should branch on the result.
1324
+ */
1325
+ enterMilestone(milestoneId: string, ctx: NotifyCtx): EnterResult {
1326
+ return _enterMilestoneCore(this.s, this.deps, milestoneId, ctx);
1327
+ }
1328
+
1329
+ /**
1330
+ * Exit the current worktree. With `opts.merge === true`, runs the full
1331
+ * merge-and-teardown path (worktree-mode or branch-mode auto-detected).
1332
+ * With `opts.merge === false`, runs auto-commit and teardown without
1333
+ * merging to main.
1334
+ *
1335
+ * Returns a typed `ExitResult`. `MergeConflictError` is surfaced as
1336
+ * `{ ok: false, reason: "merge-conflict", cause }` instead of thrown,
1337
+ * giving callers a typed branch for the expected failure path.
1338
+ * Unexpected failures (filesystem, git permissions, etc.) are wrapped
1339
+ * as `{ ok: false, reason: "teardown-failed", cause }` so callers always
1340
+ * receive a discriminated union — no exceptions for any expected outcome.
1341
+ */
1342
+ exitMilestone(
1343
+ milestoneId: string,
1344
+ opts: { merge: boolean; preserveBranch?: boolean },
1345
+ ctx: NotifyCtx,
1346
+ ): ExitResult {
1347
+ if (opts.merge) {
1348
+ try {
1349
+ const merged = this._mergeAndExit(milestoneId, ctx);
1350
+ return {
1351
+ ok: true,
1352
+ merged: merged.merged,
1353
+ codeFilesChanged: merged.codeFilesChanged,
1354
+ };
1355
+ } catch (err) {
1356
+ if (err instanceof MergeConflictError) {
1357
+ return { ok: false, reason: "merge-conflict", cause: err };
1358
+ }
1359
+ return { ok: false, reason: "teardown-failed", cause: err };
1360
+ }
1361
+ }
1362
+ try {
1363
+ this._exitWithoutMerge(milestoneId, ctx, {
1364
+ preserveBranch: opts.preserveBranch,
1365
+ });
1366
+ return { ok: true, merged: false, codeFilesChanged: false };
1367
+ } catch (err) {
1368
+ return { ok: false, reason: "teardown-failed", cause: err };
1369
+ }
1370
+ }
1371
+
1372
+ /**
1373
+ * Milestone transition: merge the current milestone, then enter the next
1374
+ * one. Pattern used when the loop detects that the active milestone has
1375
+ * changed (current completed, next is now active). Caller is responsible
1376
+ * for re-deriving state between the merge and the enter.
1377
+ */
1378
+ mergeAndEnterNext(
1379
+ currentMilestoneId: string,
1380
+ nextMilestoneId: string,
1381
+ ctx: NotifyCtx,
1382
+ ): void {
1383
+ debugLog("WorktreeLifecycle", {
1384
+ action: "mergeAndEnterNext",
1385
+ currentMilestoneId,
1386
+ nextMilestoneId,
1387
+ });
1388
+ let merged = false;
1389
+ let mergeThrew = false;
1390
+ try {
1391
+ merged = this._mergeAndExit(currentMilestoneId, ctx).merged;
1392
+ } catch (err) {
1393
+ if (err instanceof UserNotifiedError) throw err;
1394
+ mergeThrew = true;
1395
+ // _mergeAndExit emits a warning and restores state on failure during
1396
+ // merge/cleanup. If it throws before recovery runs (e.g. validation,
1397
+ // emitJournalEvent), basePath isn't restored — re-throw so we don't
1398
+ // enter the next milestone with the current one unmerged.
1399
+ const projectRoot = resolveWorktreeProjectRoot(
1400
+ this.s.basePath,
1401
+ this.s.originalBasePath,
1402
+ );
1403
+ if (this.s.basePath !== projectRoot) throw err;
1404
+ // Otherwise: merge attempted, failed cleanly with state restored.
1405
+ // The loop intentionally continues to the next milestone — the
1406
+ // failed milestone's branch is preserved for manual recovery.
1407
+ }
1408
+ if (!merged && !mergeThrew && !this.s.isolationDegraded) {
1409
+ // _mergeAndExit returned without attempting a merge (no roadmap
1410
+ // → preserveBranch path) and state is restored. The current
1411
+ // milestone was deliberately NOT merged; halt before entering the
1412
+ // next so we don't silently strand commits on the preserved
1413
+ // branch. (#5602 halt-on-no-merge regression coverage.)
1414
+ //
1415
+ // mergeThrew=true means a merge was attempted but failed — that
1416
+ // path proceeds (existing test "enters next even if merge fails").
1417
+ // isolationDegraded=true means the loop intentionally continues
1418
+ // without merging — that path proceeds too.
1419
+ throw new Error(
1420
+ `Cannot enter milestone ${nextMilestoneId} because ${currentMilestoneId} was not merged`,
1421
+ );
1422
+ }
1423
+ _enterMilestoneCore(this.s, this.deps, nextMilestoneId, ctx);
1424
+ }
1425
+
1426
+ // ── Private — exit without merge ─────────────────────────────────────
1427
+
1428
+ private _exitWithoutMerge(
1429
+ milestoneId: string,
1430
+ ctx: NotifyCtx,
1431
+ opts: { preserveBranch?: boolean },
1432
+ ): void {
1433
+ validateMilestoneId(milestoneId);
1434
+ if (!lifecycleIsInAutoWorktree(this.deps, this.s.basePath)) {
1435
+ debugLog("WorktreeLifecycle", {
1436
+ action: "exitMilestone",
1437
+ milestoneId,
1438
+ skipped: true,
1439
+ reason: "not-in-worktree",
1440
+ });
1441
+ return;
1442
+ }
1443
+
1444
+ debugLog("WorktreeLifecycle", {
1445
+ action: "exitMilestone",
1446
+ milestoneId,
1447
+ basePath: this.s.basePath,
1448
+ });
1449
+
1450
+ try {
1451
+ autoCommitLifecycleBranch(this.deps, this.s.basePath, "stop", milestoneId);
1452
+ } catch (err) {
1453
+ debugLog("WorktreeLifecycle", {
1454
+ action: "exitMilestone",
1455
+ milestoneId,
1456
+ phase: "auto-commit-failed",
1457
+ error: err instanceof Error ? err.message : String(err),
1458
+ });
1459
+ ctx.notify(
1460
+ `Auto-commit before exiting ${milestoneId} failed: ${err instanceof Error ? err.message : String(err)}. Branch ${lifecycleAutoWorktreeBranch(this.deps, milestoneId)} is preserved for recovery.`,
1461
+ "warning",
1462
+ );
1463
+ }
1464
+
1465
+ if (this.s.originalBasePath) {
1466
+ try {
1467
+ process.chdir(this.s.originalBasePath);
1468
+ } catch (err) {
1469
+ debugLog("WorktreeLifecycle", {
1470
+ action: "exitMilestone",
1471
+ milestoneId,
1472
+ phase: "pre-teardown-chdir-failed",
1473
+ originalBasePath: this.s.originalBasePath,
1474
+ error: err instanceof Error ? err.message : String(err),
1475
+ });
1476
+ ctx.notify(
1477
+ `Could not leave milestone worktree before cleanup: ${err instanceof Error ? err.message : String(err)}. Branch ${lifecycleAutoWorktreeBranch(this.deps, milestoneId)} is preserved for recovery.`,
1478
+ "warning",
1479
+ );
1480
+ }
1481
+ }
1482
+
1483
+ let teardownFailed = false;
1484
+ try {
1485
+ lifecycleTeardownAutoWorktree(this.deps, this.s.originalBasePath, milestoneId, {
1486
+ preserveBranch: opts.preserveBranch ?? false,
1487
+ });
1488
+ } catch (err) {
1489
+ teardownFailed = true;
1490
+ debugLog("WorktreeLifecycle", {
1491
+ action: "exitMilestone",
1492
+ milestoneId,
1493
+ phase: "teardown-failed",
1494
+ error: err instanceof Error ? err.message : String(err),
1495
+ });
1496
+ ctx.notify(
1497
+ `Worktree cleanup failed for ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. Branch ${lifecycleAutoWorktreeBranch(this.deps, milestoneId)} is preserved for recovery.`,
1498
+ "warning",
1499
+ );
1500
+ }
1501
+
1502
+ this.restoreToProjectRoot();
1503
+ debugLog("WorktreeLifecycle", {
1504
+ action: "exitMilestone",
1505
+ milestoneId,
1506
+ result: "done",
1507
+ basePath: this.s.basePath,
1508
+ });
1509
+ ctx.notify(
1510
+ teardownFailed
1511
+ ? `Worktree exit for ${milestoneId} needs manual cleanup.`
1512
+ : `Exited worktree for ${milestoneId}`,
1513
+ teardownFailed ? "warning" : "info",
1514
+ );
1515
+ }
1516
+
1517
+ // ── Private — merge and exit (worktree-mode or branch-mode) ──────────
1518
+
1519
+ /**
1520
+ * Merge the completed milestone branch back to main and exit the worktree.
1521
+ *
1522
+ * Session-bound wrapper around `mergeMilestoneStandalone`. Builds a
1523
+ * `MergeContext` from `this.s`, layers session-side bookkeeping on top of
1524
+ * the result:
1525
+ *
1526
+ * - resquash-on-merge using `s.milestoneStartShas`
1527
+ * - merge-completion telemetry (duration)
1528
+ * - mode-specific session restore: worktree-mode → `restoreToProjectRoot`,
1529
+ * branch-mode → `gitService` rebuild
1530
+ *
1531
+ * Returns the session-less merge result. Errors propagate after
1532
+ * `restoreToProjectRoot()` runs so callers always receive a consistent
1533
+ * session.
1534
+ */
1535
+ private _mergeAndExit(
1536
+ milestoneId: string,
1537
+ ctx: NotifyCtx,
1538
+ ): MergeStandaloneResult {
1539
+ // #4764 — telemetry: record start timestamp so we can emit merge duration.
1540
+ const mergeStartedAt = new Date().toISOString();
1541
+ const mergeStartMs = Date.now();
1542
+
1543
+ let result: MergeStandaloneResult;
1544
+ try {
1545
+ result = mergeMilestoneStandalone(this.deps, {
1546
+ originalBasePath: this.s.originalBasePath,
1547
+ worktreeBasePath: this.s.basePath,
1548
+ milestoneId,
1549
+ isolationDegraded: this.s.isolationDegraded,
1550
+ notify: ctx.notify,
1551
+ });
1552
+ } catch (err) {
1553
+ // Standalone has already done its session-less cleanup
1554
+ // (chdir, SQUASH_MSG cleanup, journal event). Layer session-side
1555
+ // restore on top so callers get a consistent session.
1556
+ this.restoreToProjectRoot();
1557
+ throw err;
1558
+ }
1559
+
1560
+ if (!result.merged) {
1561
+ // Skip / no-roadmap / mode-none paths. milestoneStartShas housekeeping
1562
+ // is unconditional; mode-specific session restore happens for
1563
+ // worktree-mode (preserve-branch path tore down the worktree, so
1564
+ // basePath must restore) and not for branch-mode (no basePath change).
1565
+ this.s.milestoneStartShas.delete(milestoneId);
1566
+ if (result.mode === "worktree") {
1567
+ this.restoreToProjectRoot();
1568
+ debugLog("WorktreeLifecycle", {
1569
+ action: "mergeAndExit",
1570
+ milestoneId,
1571
+ result: "done",
1572
+ basePath: this.s.basePath,
1573
+ });
1574
+ }
1575
+ return result;
1576
+ }
1577
+
1578
+ // #4765 — when collapse_cadence=slice AND milestone_resquash=true, the
1579
+ // N per-slice commits on main should be collapsed into one milestone
1580
+ // commit. Done AFTER the primary merge-and-teardown so the branch and
1581
+ // worktree are already cleaned up; we operate on main directly.
1582
+ try {
1583
+ const startSha = this.s.milestoneStartShas.get(milestoneId);
1584
+ if (startSha) {
1585
+ const prefs = lifecycleLoadPreferences(
1586
+ this.deps,
1587
+ this.s.originalBasePath || this.s.basePath,
1588
+ )?.preferences;
1589
+ if (
1590
+ getCollapseCadence(prefs) === "slice" &&
1591
+ getMilestoneResquash(prefs)
1592
+ ) {
1593
+ const resquashResult = resquashMilestoneOnMain(
1594
+ this.s.originalBasePath || this.s.basePath,
1595
+ milestoneId,
1596
+ startSha,
1597
+ );
1598
+ if (resquashResult.resquashed) {
1599
+ ctx.notify(
1600
+ `slice-cadence: re-squashed slice commits for ${milestoneId} into a single milestone commit.`,
1601
+ "info",
1602
+ );
1603
+ }
1604
+ }
1605
+ this.s.milestoneStartShas.delete(milestoneId);
1606
+ }
1607
+ } catch (err) {
1608
+ debugLog("WorktreeLifecycle", {
1609
+ action: "mergeAndExit",
1610
+ milestoneId,
1611
+ phase: "resquash",
1612
+ error: err instanceof Error ? err.message : String(err),
1613
+ });
1614
+ }
1615
+
1616
+ // #4764 — record merge completion. Only reaches here when an actual
1617
+ // merge ran; failure paths throw out before this point.
1618
+ try {
1619
+ emitWorktreeMerged(
1620
+ this.s.originalBasePath || this.s.basePath,
1621
+ milestoneId,
1622
+ {
1623
+ reason: "milestone-complete",
1624
+ startedAt: mergeStartedAt,
1625
+ durationMs: Date.now() - mergeStartMs,
1626
+ },
1627
+ );
1628
+ } catch (telemetryErr) {
1629
+ debugLog("WorktreeLifecycle", {
1630
+ action: "mergeAndExit",
1631
+ phase: "telemetry-emit",
1632
+ error:
1633
+ telemetryErr instanceof Error
1634
+ ? telemetryErr.message
1635
+ : String(telemetryErr),
1636
+ });
1637
+ }
1638
+
1639
+ // Mode-specific session restore.
1640
+ if (result.mode === "worktree") {
1641
+ this.restoreToProjectRoot();
1642
+ debugLog("WorktreeLifecycle", {
1643
+ action: "mergeAndExit",
1644
+ milestoneId,
1645
+ result: "done",
1646
+ basePath: this.s.basePath,
1647
+ });
1648
+ } else if (result.mode === "branch") {
1649
+ // Rebuild GitService after merge (branch HEAD changed)
1650
+ rebuildGitService(this.s, this.deps);
1651
+ }
1652
+ return result;
1653
+ }
1654
+
1655
+ // ── Removed: _mergeWorktreeMode / _mergeBranchMode bodies ────────────
1656
+ // The merge bodies moved to file-scope `_mergeWorktreeModeImpl` and
1657
+ // `_mergeBranchModeImpl`, callable from the session-less
1658
+ // `mergeMilestoneStandalone` entry. The previous private methods are
1659
+ // gone; `_mergeAndExit` above is the only session-bound caller.
1660
+
1661
+ /**
1662
+ * Fall back to branch-mode for `milestoneId` after a failed worktree
1663
+ * creation, marking the session's isolation as degraded.
1664
+ *
1665
+ * Currently delegates to `enterBranchModeForMilestone` from auto-worktree.
1666
+ * Idempotent: subsequent calls in a degraded session are no-ops.
1667
+ *
1668
+ * Issue #5587 ships this as a thin adapter; the body extraction joins the
1669
+ * other merge-logic move-out in a follow-up cleanup slice.
1670
+ */
1671
+ degradeToBranchMode(milestoneId: string, ctx: NotifyCtx): void {
1672
+ if (this.s.isolationDegraded) {
1673
+ debugLog("WorktreeLifecycle", {
1674
+ action: "degradeToBranchMode",
1675
+ milestoneId,
1676
+ skipped: true,
1677
+ reason: "already-degraded",
1678
+ });
1679
+ return;
1680
+ }
1681
+ const basePath = resolveWorktreeProjectRoot(
1682
+ this.s.basePath,
1683
+ this.s.originalBasePath,
1684
+ );
1685
+ try {
1686
+ lifecycleEnterBranchMode(this.deps, basePath, milestoneId);
1687
+ rebuildGitService(this.s, this.deps);
1688
+ invalidateAllCaches();
1689
+ this.s.isolationDegraded = true;
1690
+ ctx.notify(
1691
+ `Switched to branch milestone/${milestoneId} (isolation degraded).`,
1692
+ "info",
1693
+ );
1694
+ } catch (err) {
1695
+ const msg = err instanceof Error ? err.message : String(err);
1696
+ ctx.notify(
1697
+ `Branch isolation setup for ${milestoneId} failed: ${msg}. Continuing on current branch.`,
1698
+ "warning",
1699
+ );
1700
+ this.s.isolationDegraded = true;
1701
+ }
1702
+ }
1703
+
1704
+ /**
1705
+ * Restore `s.basePath` to `s.originalBasePath` and rebuild `s.gitService`.
1706
+ * No-op when `originalBasePath` is empty (fresh sessions).
1707
+ *
1708
+ * Used by error/cleanup paths that need the session to behave as if the
1709
+ * worktree was never entered. Does NOT teardown the worktree directory —
1710
+ * callers that need teardown go through `exitMilestone({ merge: false })`.
1711
+ */
1712
+ restoreToProjectRoot(): void {
1713
+ if (!this.s.originalBasePath) return;
1714
+ this.s.basePath = this.s.originalBasePath;
1715
+ rebuildGitService(this.s, this.deps);
1716
+ invalidateAllCaches();
1717
+ }
1718
+
1719
+ /**
1720
+ * Adopt a session root (ADR-016 phase 2 / B2, issue #5620).
1721
+ *
1722
+ * Sole owner of `s.basePath` mutation for bootstrap-class transitions:
1723
+ * initial session start, paused-resume entry (before persisted-state
1724
+ * consultation), and hook-trigger session activation. Defensive about
1725
+ * `s.originalBasePath`:
1726
+ *
1727
+ * - When `originalBase` is explicit: overwrite.
1728
+ * - Otherwise, set `s.originalBasePath` only if it is currently empty —
1729
+ * resume paths that already restored `s.originalBasePath` from paused
1730
+ * metadata keep their value.
1731
+ *
1732
+ * Does NOT chdir; callers that need cwd alignment with the new basePath
1733
+ * are responsible for it. Does NOT rebuild `s.gitService` — callers that
1734
+ * mutate `s.basePath` to a non-project-root path (e.g. a worktree on a
1735
+ * subsequent milestone enter) go through `enterMilestone`, which handles
1736
+ * the rebuild.
1737
+ */
1738
+ adoptSessionRoot(base: string, originalBase?: string): void {
1739
+ this.s.basePath = base;
1740
+ if (originalBase !== undefined) {
1741
+ this.s.originalBasePath = originalBase;
1742
+ } else if (!this.s.originalBasePath) {
1743
+ this.s.originalBasePath = base;
1744
+ }
1745
+ }
1746
+
1747
+ /**
1748
+ * Resume from a paused session (ADR-016 phase 2 / B3, issue #5621).
1749
+ *
1750
+ * Adopts `persistedWorktreePath` as `s.basePath` when the path is
1751
+ * non-null and exists on disk; otherwise falls back to `base`. Mirrors
1752
+ * the resume guard at `auto.ts:2164` — a stale or removed worktree
1753
+ * directory must not strand the resumed session in an invalid root.
1754
+ *
1755
+ * Folds in the body of the legacy `_resolvePausedResumeBasePathForTest`
1756
+ * helper (see `resolvePausedResumeBasePath` below). After this verb
1757
+ * lands the helper is deleted from `auto.ts` per the slice-7 closure
1758
+ * decision to retire `_*ForTest` suffixes from production paths.
1759
+ *
1760
+ * Like `adoptSessionRoot`, this is a pure session-state mutation — no
1761
+ * chdir, no git service rebuild, no cache invalidation.
1762
+ */
1763
+ resumeFromPausedSession(
1764
+ base: string,
1765
+ persistedWorktreePath: string | null,
1766
+ ): void {
1767
+ this.s.basePath = resolvePausedResumeBasePath(base, persistedWorktreePath);
1768
+ }
1769
+
1770
+ /**
1771
+ * Adopt an orphan worktree for a bootstrap-time merge (ADR-016 phase 2 / B4,
1772
+ * issue #5622).
1773
+ *
1774
+ * Owns the swap-run-revert protocol that bootstrap previously open-coded:
1775
+ *
1776
+ * 1. Snapshot prior `s.basePath` and `s.originalBasePath`.
1777
+ * 2. Resolve `getAutoWorktreePath(base, milestoneId) ?? base` before
1778
+ * mutating session state, then set `s.originalBasePath = base` and
1779
+ * `s.basePath` to the resolved path.
1780
+ * 3. Invoke the caller-supplied `run` callback under the swap.
1781
+ * 4. On `!result.merged`: revert to `base` and `chdir(base)` so the
1782
+ * caller can return early without leaving the session in a half-
1783
+ * swapped state.
1784
+ * 5. On `result.merged && !s.active`: revert to the snapshotted prior
1785
+ * paths (the orphan merge succeeded but bootstrap chose not to keep
1786
+ * the session active).
1787
+ * 6. On `result.merged && s.active`: leave the swap in place — the
1788
+ * loop will continue from the worktree path.
1789
+ *
1790
+ * The callback shape forces every caller through the same revert
1791
+ * protocol; an open-coded swap that forgets to revert on failure was the
1792
+ * original bug pattern this verb is designed to prevent.
1793
+ */
1794
+ adoptOrphanWorktree<T extends { merged: boolean }>(
1795
+ milestoneId: string,
1796
+ base: string,
1797
+ run: () => T,
1798
+ ): T {
1799
+ validateMilestoneId(milestoneId);
1800
+
1801
+ const priorBasePath = this.s.basePath;
1802
+ const priorOriginalBasePath = this.s.originalBasePath;
1803
+ const restorePriorPaths = (phase: string): void => {
1804
+ this.s.basePath = priorBasePath || base;
1805
+ this.s.originalBasePath = priorOriginalBasePath || base;
1806
+ try {
1807
+ process.chdir(this.s.originalBasePath || base);
1808
+ } catch (err) {
1809
+ debugLog("WorktreeLifecycle", {
1810
+ action: "adoptOrphanWorktree",
1811
+ phase,
1812
+ base: this.s.originalBasePath || base,
1813
+ error: err instanceof Error ? err.message : String(err),
1814
+ });
1815
+ }
1816
+ };
1817
+
1818
+ let adoptedBasePath: string;
1819
+ try {
1820
+ const wtPathFn =
1821
+ primitiveOverrides(this.deps).getAutoWorktreePath ?? getAutoWorktreePath;
1822
+ adoptedBasePath = wtPathFn(base, milestoneId) ?? base;
1823
+ } catch (err) {
1824
+ restorePriorPaths("rollback-resolve-worktree-failed");
1825
+ throw err;
1826
+ }
1827
+
1828
+ // Swap into the orphan worktree.
1829
+ this.s.originalBasePath = base;
1830
+ this.s.basePath = adoptedBasePath;
1831
+
1832
+ let result: T;
1833
+ try {
1834
+ result = run();
1835
+ } catch (err) {
1836
+ restorePriorPaths("rollback-run-failed");
1837
+ throw err;
1838
+ }
1839
+
1840
+ if (!result.merged) {
1841
+ // Failed orphan merge — revert to project root so the caller can
1842
+ // safely return early without leaving the session in an invalid
1843
+ // basePath. Mirror the chdir that bootstrap performed inline.
1844
+ this.s.basePath = base;
1845
+ this.s.originalBasePath = base;
1846
+ try {
1847
+ process.chdir(base);
1848
+ } catch (err) {
1849
+ debugLog("WorktreeLifecycle", {
1850
+ action: "adoptOrphanWorktree",
1851
+ phase: "revert-chdir-failed",
1852
+ base,
1853
+ error: err instanceof Error ? err.message : String(err),
1854
+ });
1855
+ }
1856
+ return result;
1857
+ }
1858
+
1859
+ if (!this.s.active) {
1860
+ // Merge succeeded but the session was not (re)activated — restore
1861
+ // the snapshotted paths so the calling context resumes where it
1862
+ // was, with the orphan branch now merged on main.
1863
+ this.s.basePath = priorBasePath || base;
1864
+ this.s.originalBasePath = priorOriginalBasePath || base;
1865
+ }
1866
+ // else: merged && active — leave the swap; the loop continues from
1867
+ // the worktree path. Subsequent milestone enters mutate `s.basePath`
1868
+ // through their own Lifecycle verbs.
1869
+
1870
+ return result;
1871
+ }
1872
+
1873
+ /** True if `milestoneId` is the session's currently-active milestone. */
1874
+ isInMilestone(milestoneId: string): boolean {
1875
+ return this.s.currentMilestoneId === milestoneId;
1876
+ }
1877
+
1878
+ /** The active milestone id, or `null` if no milestone is active. */
1879
+ getCurrentMilestoneIfAny(): string | null {
1880
+ return this.s.currentMilestoneId;
1881
+ }
1882
+ }