mixdog 1.1.2 → 1.2.1

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 (424) hide show
  1. package/README.md +8 -5
  2. package/package.json +2 -1
  3. package/scripts/lib/run-node-tests.mjs +9 -0
  4. package/scripts/prune-desktop-runtime.mjs +3 -0
  5. package/scripts/test-direct.mjs +4 -2
  6. package/src/defaults/shipped-history.json +10 -0
  7. package/src/defaults/skills/pptx/SKILL.md +6 -6
  8. package/src/defaults/skills/pptx/references/review.md +6 -4
  9. package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
  10. package/src/defaults/skills/setup/references/actions.md +18 -5
  11. package/src/defaults/skills/visualize/SKILL.md +160 -0
  12. package/src/defaults/skills/visualize/references/craft.md +88 -0
  13. package/src/headless-command.mjs +56 -3
  14. package/src/headless-exec.mjs +17 -1
  15. package/src/help.mjs +2 -0
  16. package/src/rules/shared/60-verification.md +3 -1
  17. package/src/rules/shared/70-delivery.md +4 -2
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
  20. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
  21. package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
  22. package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
  23. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
  24. package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +19 -5
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
  33. package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
  34. package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
  35. package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
  36. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
  37. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  38. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
  40. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
  41. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
  42. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
  43. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
  44. package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
  45. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
  46. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
  47. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
  49. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
  50. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
  51. package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
  52. package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
  53. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  54. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  55. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
  56. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
  57. package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
  58. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
  59. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
  60. package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
  61. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
  62. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
  63. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
  64. package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
  65. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
  66. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
  67. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
  68. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
  72. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
  73. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
  77. package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
  78. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
  79. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
  80. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
  81. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
  82. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
  83. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
  84. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
  85. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
  86. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
  87. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
  88. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
  89. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
  90. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
  91. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
  92. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
  93. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
  94. package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
  95. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
  96. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
  97. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
  98. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
  99. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
  100. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
  101. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
  102. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
  103. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
  104. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
  105. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
  106. package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
  107. package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
  108. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
  109. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
  111. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
  112. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
  113. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
  114. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
  115. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
  116. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
  117. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
  118. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
  120. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
  121. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
  122. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
  123. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
  124. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
  125. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
  126. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
  127. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
  128. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
  131. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
  133. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
  136. package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
  137. package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
  138. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
  139. package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
  140. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
  141. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
  142. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
  143. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
  144. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
  145. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
  146. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
  147. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
  148. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
  149. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
  150. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
  151. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
  152. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
  153. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
  155. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
  156. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
  157. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
  158. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
  159. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
  160. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
  161. package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
  162. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
  163. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
  164. package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
  165. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
  166. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
  167. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
  168. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
  169. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
  173. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
  174. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
  175. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
  176. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
  177. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
  179. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
  180. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
  181. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
  182. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  183. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
  184. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
  185. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
  186. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  187. package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
  188. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
  189. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
  190. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
  191. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
  192. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
  193. package/src/runtime/attachments/store.d.mts +3 -0
  194. package/src/runtime/attachments/store.mjs +38 -0
  195. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
  196. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
  197. package/src/runtime/channels/lib/worker-main.mjs +17 -14
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
  199. package/src/runtime/effort-judge/judge-client.mjs +56 -18
  200. package/src/runtime/memory/lib/memory.mjs +1 -1
  201. package/src/runtime/memory/lib/session-ingest.mjs +2 -2
  202. package/src/runtime/shared/atomic-file.mjs +33 -6
  203. package/src/runtime/shared/best-effort-stderr.mjs +8 -0
  204. package/src/runtime/shared/code-graph-state.mjs +12 -0
  205. package/src/runtime/shared/defaults-separation.mjs +2 -0
  206. package/src/runtime/shared/extension-scopes.mjs +5 -3
  207. package/src/runtime/shared/file-lock.mjs +37 -11
  208. package/src/runtime/shared/git-runner-worker.mjs +3 -2
  209. package/src/runtime/shared/git-runner.mjs +4 -3
  210. package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
  211. package/src/runtime/shared/llm/default-context-window.mjs +6 -0
  212. package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
  213. package/src/runtime/shared/llm/model-catalog.mjs +240 -130
  214. package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
  215. package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
  216. package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
  217. package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
  218. package/src/runtime/shared/model-proxy-mode.mjs +19 -0
  219. package/src/runtime/shared/plugin-manifest.mjs +18 -9
  220. package/src/runtime/shared/pristine-execution-contract.json +9 -2
  221. package/src/runtime/shared/pristine-execution.mjs +28 -4
  222. package/src/runtime/shared/provider-accounts.mjs +125 -21
  223. package/src/runtime/shared/provider-api-key.mjs +33 -1
  224. package/src/runtime/shared/schedule-model-ref.mjs +11 -2
  225. package/src/runtime/shared/session-usage-totals.mjs +19 -0
  226. package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
  227. package/src/runtime/shared/shell-display.mjs +9 -3
  228. package/src/runtime/shared/singleton-owner.mjs +36 -6
  229. package/src/runtime/shared/skill-mentions.d.mts +10 -0
  230. package/src/runtime/shared/skill-mentions.mjs +133 -0
  231. package/src/runtime/shared/skill-script-runtime.mjs +264 -0
  232. package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
  233. package/src/runtime/shared/tool-primitives.mjs +35 -2
  234. package/src/runtime/shared/tool-surface.mjs +7 -0
  235. package/src/runtime/shared/tool-work-units.mjs +14 -0
  236. package/src/runtime/shared/transcript-metadata.mjs +17 -1
  237. package/src/runtime/shared/turn-changes.mjs +791 -0
  238. package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
  239. package/src/runtime/shared/turn-snapshot.mjs +690 -81
  240. package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
  241. package/src/runtime/shared/worker-requests.mjs +15 -2
  242. package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
  243. package/src/runtime/shared/worktrees/contract.mjs +551 -0
  244. package/src/runtime/shared/worktrees/disk.mjs +57 -0
  245. package/src/runtime/shared/worktrees/git.mjs +247 -0
  246. package/src/runtime/shared/worktrees/include.mjs +480 -0
  247. package/src/runtime/shared/worktrees/lock.mjs +46 -0
  248. package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
  249. package/src/runtime/shared/worktrees/manager.mjs +1215 -0
  250. package/src/runtime/shared/worktrees/merge.mjs +182 -0
  251. package/src/runtime/shared/worktrees/owner.mjs +46 -0
  252. package/src/runtime/shared/worktrees/paths.mjs +62 -0
  253. package/src/runtime/shared/worktrees/registry.mjs +110 -0
  254. package/src/runtime/shared/worktrees/settings.mjs +84 -0
  255. package/src/runtime/shared/worktrees/slug.mjs +62 -0
  256. package/src/runtime/shared/worktrees/test-support.mjs +96 -0
  257. package/src/runtime/visualize-bridge/client.mjs +181 -0
  258. package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
  259. package/src/session-runtime/automation-agents.mjs +8 -2
  260. package/src/session-runtime/boot/apis.mjs +90 -0
  261. package/src/session-runtime/boot/config.mjs +7 -2
  262. package/src/session-runtime/boot/facade.mjs +21 -0
  263. package/src/session-runtime/boot/infrastructure.mjs +30 -18
  264. package/src/session-runtime/boot/session.mjs +1 -0
  265. package/src/session-runtime/boot/tools.mjs +4 -0
  266. package/src/session-runtime/config-lifecycle.mjs +10 -1
  267. package/src/session-runtime/conversation-import/discovery.mjs +698 -0
  268. package/src/session-runtime/conversation-import/service.mjs +369 -0
  269. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
  270. package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
  271. package/src/session-runtime/global-extensions.mjs +2 -2
  272. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
  273. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
  274. package/src/session-runtime/internal-tool-executor.mjs +9 -1
  275. package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
  276. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
  277. package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
  278. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
  279. package/src/session-runtime/mcp-glue/connect.mjs +68 -16
  280. package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
  281. package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
  282. package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
  283. package/src/session-runtime/mcp-glue.mjs +22 -2
  284. package/src/session-runtime/model-route/route-persist.mjs +3 -0
  285. package/src/session-runtime/model-route/set-route.mjs +15 -2
  286. package/src/session-runtime/new-session-config.mjs +3 -2
  287. package/src/session-runtime/notification-bus.mjs +18 -3
  288. package/src/session-runtime/provider-auth/accounts.mjs +33 -15
  289. package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
  290. package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
  291. package/src/session-runtime/provider-readiness.mjs +16 -10
  292. package/src/session-runtime/resource-extension-sync.mjs +45 -7
  293. package/src/session-runtime/resource-mcp-api.mjs +121 -84
  294. package/src/session-runtime/resource-plugins-api.mjs +29 -41
  295. package/src/session-runtime/resource-scope-decorate.mjs +6 -8
  296. package/src/session-runtime/resource-skills-api.mjs +23 -2
  297. package/src/session-runtime/route-resolution.mjs +10 -1
  298. package/src/session-runtime/route-state.mjs +16 -2
  299. package/src/session-runtime/runtime-core.mjs +5 -0
  300. package/src/session-runtime/runtime-facade.mjs +8 -0
  301. package/src/session-runtime/runtime-review-api.mjs +9 -0
  302. package/src/session-runtime/schedule-session-run.mjs +1 -1
  303. package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
  304. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
  305. package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
  306. package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
  307. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
  308. package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
  309. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
  310. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
  311. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  312. package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
  313. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
  314. package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
  315. package/src/session-runtime/services/agent-tool.mjs +1 -0
  316. package/src/session-runtime/services/channel-session-router.mjs +4 -1
  317. package/src/session-runtime/services/daemon-candidate.mjs +3 -2
  318. package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
  319. package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
  320. package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
  321. package/src/session-runtime/services/provider-admin.mjs +64 -18
  322. package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
  323. package/src/session-runtime/session-create/session-options.mjs +10 -1
  324. package/src/session-runtime/session-turn-api.mjs +1 -0
  325. package/src/session-runtime/settings-api.mjs +4 -2
  326. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
  327. package/src/session-runtime/settings-worktree-api.mjs +17 -0
  328. package/src/session-runtime/setup-tool/executor.mjs +23 -5
  329. package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
  330. package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
  331. package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
  332. package/src/session-runtime/skills-api.mjs +7 -3
  333. package/src/session-runtime/turn/agent-ops.mjs +12 -1
  334. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
  335. package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
  336. package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
  337. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
  338. package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
  339. package/src/session-runtime/turn/turn-run.mjs +6 -7
  340. package/src/session-runtime/webhook-session-run.mjs +16 -4
  341. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
  342. package/src/session-runtime/workspace/admission-gate.mjs +197 -0
  343. package/src/session-runtime/workspace/project-branches.mjs +136 -0
  344. package/src/session-runtime/workspace/transition-steps.mjs +364 -0
  345. package/src/session-runtime/workspace/transitions.mjs +651 -0
  346. package/src/session-runtime/workspace/workspace-state.mjs +112 -0
  347. package/src/skill-script-entry.mjs +36 -0
  348. package/src/standalone/channel-transport/http-routes.mjs +17 -0
  349. package/src/standalone/channel-transport.mjs +13 -1
  350. package/src/standalone/daemon-desktop-runtime.mjs +1 -0
  351. package/src/standalone/daemon-owner.mjs +372 -0
  352. package/src/standalone/daemon-stored-session-views.mjs +15 -4
  353. package/src/standalone/daemon.mjs +179 -8
  354. package/src/standalone/desktop-service-registry.mjs +20 -0
  355. package/src/standalone/local-session-runtime.mjs +11 -0
  356. package/src/standalone/session-client/attachment-calls.mjs +3 -1
  357. package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
  358. package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
  359. package/src/standalone/session-client.mjs +104 -13
  360. package/src/standalone/session-protocol.mjs +21 -0
  361. package/src/standalone/session-proxy.mjs +3 -0
  362. package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
  363. package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
  364. package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
  365. package/src/standalone/session-service/projection/revisions.mjs +2 -0
  366. package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
  367. package/src/standalone/session-service/projection/workspace.mjs +14 -0
  368. package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
  369. package/src/standalone/session-transport/call-route.mjs +13 -0
  370. package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
  371. package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
  372. package/src/standalone/session-transport/client-registry.mjs +20 -3
  373. package/src/standalone/session-transport/routes.mjs +79 -2
  374. package/src/standalone/session-transport/stack.mjs +2 -0
  375. package/src/standalone/session-transport.mjs +24 -1
  376. package/src/tui/App.jsx +9 -1
  377. package/src/tui/app/app-view/floating-panel.jsx +9 -1
  378. package/src/tui/app/app-view.jsx +6 -0
  379. package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
  380. package/src/tui/app/message-selector.mjs +2 -1
  381. package/src/tui/app/model-options.mjs +37 -5
  382. package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
  383. package/src/tui/app/model-picker.mjs +4 -2
  384. package/src/tui/app/skill-mention-palette.mjs +88 -0
  385. package/src/tui/app/slash-palette.mjs +23 -7
  386. package/src/tui/app/transcript-row-estimate.mjs +11 -3
  387. package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
  388. package/src/tui/app/use-prompt-state.mjs +5 -0
  389. package/src/tui/components/Message.jsx +22 -1
  390. package/src/tui/components/PromptInput.jsx +21 -3
  391. package/src/tui/components/SlashCommandPalette.jsx +12 -3
  392. package/src/tui/components/TranscriptItem.jsx +9 -1
  393. package/src/tui/components/prompt-input/key-handler.mjs +21 -8
  394. package/src/tui/components/user-message-skills.mjs +38 -0
  395. package/src/tui/dist/index.mjs +839 -207
  396. package/src/tui/index.jsx +10 -2
  397. package/src/tui/session/compaction-view.mjs +147 -0
  398. package/src/tui/session/context-state.mjs +6 -0
  399. package/src/tui/session/initial-state.mjs +3 -0
  400. package/src/tui/session/queue-helpers.mjs +7 -2
  401. package/src/tui/session/quota-resume.mjs +2 -1
  402. package/src/tui/session/session-api/commands.mjs +10 -2
  403. package/src/tui/session/session-api/controls.mjs +4 -0
  404. package/src/tui/session/session-api/extensions.mjs +4 -2
  405. package/src/tui/session/session-api/intake/rewind.mjs +2 -1
  406. package/src/tui/session/session-api/integrations.mjs +17 -0
  407. package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
  408. package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
  409. package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
  410. package/src/tui/session/session-api/routes.mjs +10 -1
  411. package/src/tui/session/session-api/settings.mjs +9 -0
  412. package/src/tui/session/session-api/worktree.mjs +60 -0
  413. package/src/tui/session/session-api.mjs +2 -0
  414. package/src/tui/session/session-flow/auto-clear.mjs +31 -12
  415. package/src/tui/session/session-flow/drain.mjs +27 -3
  416. package/src/tui/session/session-flow/session-reset.mjs +4 -3
  417. package/src/tui/session/session-flow.mjs +2 -0
  418. package/src/tui/session/transcript-intake.mjs +14 -5
  419. package/src/tui/session/tui-steering-persist.mjs +25 -9
  420. package/src/tui/session/turn-stream.mjs +32 -4
  421. package/src/tui/session/turn-tool-cards.mjs +10 -2
  422. package/src/tui/session/turn.mjs +56 -10
  423. package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
  424. package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
@@ -0,0 +1,364 @@
1
+ /**
2
+ * The steps of one Lead workspace transaction (transitions.mjs runs them
3
+ * serialized): commit a new workspace, enter the retained or a new worktree,
4
+ * move to a project-folder branch, remove the retained worktree. Every step
5
+ * pushes the exact undo of what it changed onto the transaction `journal`;
6
+ * the caller runs it (undoAll) when the transaction fails.
7
+ */
8
+ import { existsSync, mkdirSync } from 'node:fs';
9
+ import {
10
+ isWorktreeBound,
11
+ isWorktreeError,
12
+ nextRevision,
13
+ normalizeSessionWorkspace,
14
+ worktreeError,
15
+ } from '../../runtime/shared/worktrees/contract.mjs';
16
+ import { throwIfAborted } from '../../runtime/shared/worktrees/git.mjs';
17
+ import { checkoutFolder, projectSubdirOf, samePath } from '../../runtime/shared/worktrees/paths.mjs';
18
+ import { setWorkspaceCwdLock, workspaceCwdLock } from './admission-gate.mjs';
19
+ import { copyProjectIdentity } from './workspace-state.mjs';
20
+
21
+ const PROMPT_FIELDS = ['bp3EnvironmentContext', 'bp3CoreContext', 'sessionStartMetaInjected'];
22
+
23
+ /** Everything a prompt refresh rewrites on `target`, restorable exactly. */
24
+ function snapshotPrompt(target) {
25
+ const fields = PROMPT_FIELDS.map((name) => [name, Object.hasOwn(target, name), target[name]]);
26
+ const messages = Array.isArray(target.messages) ? [...target.messages] : null;
27
+ return () => {
28
+ for (const [name, had, value] of fields) {
29
+ if (had) target[name] = value;
30
+ else delete target[name];
31
+ }
32
+ if (!messages) return;
33
+ if (Array.isArray(target.messages)) target.messages.splice(0, target.messages.length, ...messages);
34
+ else target.messages = messages;
35
+ };
36
+ }
37
+
38
+ /** Run a failed transaction's undo steps newest first; every step runs. */
39
+ export async function undoAll(journal, error) {
40
+ const failures = [];
41
+ for (const undo of journal.reverse()) {
42
+ try {
43
+ await undo();
44
+ } catch (cause) {
45
+ failures.push(cause);
46
+ }
47
+ }
48
+ if (failures.length && error && typeof error === 'object') error.rollbackErrors = failures;
49
+ }
50
+
51
+ /**
52
+ * WORKTREE_PROJECT_MISMATCH unless the retained `entry` was created for the
53
+ * same repository and the same Project folder inside it (a Project switch may
54
+ * have left it behind).
55
+ */
56
+ export function assertRetainedFits(entry, project, projectPath) {
57
+ const subdir = projectSubdirOf(project.topLevel, project.projectPath || projectPath);
58
+ if (samePath(entry.repoCommonDir, project.repoCommonDir) && (entry.projectSubdir || '') === subdir) return;
59
+ throw worktreeError('WORKTREE_PROJECT_MISMATCH', undefined, {
60
+ worktreeId: entry.id,
61
+ worktreeProject: entry.projectPath,
62
+ projectPath,
63
+ });
64
+ }
65
+
66
+ /**
67
+ * WORKTREE_REMOVAL_INCOMPLETE: the deletion started (the record stays
68
+ * `deleting`) but something in the folder is still held. The session keeps
69
+ * the project folder — never a cwd that may already be deleted — and
70
+ * removeWorktree again resumes the deletion.
71
+ */
72
+ function incompleteRemoval(journal, entry, result, outcome) {
73
+ journal.length = 0;
74
+ return worktreeError('WORKTREE_REMOVAL_INCOMPLETE', undefined, {
75
+ entryId: entry.id,
76
+ path: entry.path,
77
+ retryable: outcome?.retryable !== false,
78
+ remaining: Array.isArray(outcome?.remaining) ? outcome.remaining : [],
79
+ ...(outcome?.reason ? { reason: outcome.reason } : {}),
80
+ revision: result.revision,
81
+ });
82
+ }
83
+
84
+ /**
85
+ * @param {object} deps The host hooks of createWorkspaceTransitions plus its
86
+ * `backend()` loader, `workersOf(session)` and `withProjectFolder`.
87
+ */
88
+ export function createTransitionSteps({
89
+ backend,
90
+ inspectProject,
91
+ runtimeToken,
92
+ getCurrentCwd,
93
+ applyResolvedCwd,
94
+ persistSession,
95
+ refreshWorkspaceContext,
96
+ invalidateCaches,
97
+ updateLeadWorkerCwd,
98
+ workersOf,
99
+ withProjectFolder,
100
+ }) {
101
+ const owner = (sessionId) => ({ sessionId, runtimeToken, pid: process.pid });
102
+
103
+ /** Point this Lead's idle workers at the new root so a reused worker never keeps an old workspace. */
104
+ async function retargetWorkers(session, cwd, journal) {
105
+ for (const worker of workersOf(session)) {
106
+ if (samePath(worker.cwd || '', cwd)) continue;
107
+ const priorCwd = worker.cwd;
108
+ const restorePrompt = snapshotPrompt(worker);
109
+ journal.push(() => {
110
+ worker.cwd = priorCwd;
111
+ restorePrompt();
112
+ worker.updatedAt = Date.now();
113
+ persistSession(worker);
114
+ });
115
+ worker.cwd = cwd;
116
+ await refreshWorkspaceContext(worker, cwd);
117
+ worker.updatedAt = Date.now();
118
+ persistSession(worker);
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Apply the new workspace: runtime cwd, record, worker lock, prompt context
124
+ * of the Lead and its idle workers, persistence. Journals the exact undo
125
+ * (cwd, record, lock, prompts, worker roots) for a transaction that fails
126
+ * after this point.
127
+ */
128
+ async function commit(session, previous, fields, journal) {
129
+ const moveLeadRow = (cwd) => {
130
+ try {
131
+ updateLeadWorkerCwd(session.id, cwd);
132
+ } catch {
133
+ /* the Lead pool must never break a transition */
134
+ }
135
+ };
136
+ const next = normalizeSessionWorkspace({
137
+ ...fields,
138
+ revision: nextRevision(previous),
139
+ transition: { state: 'idle', txId: null },
140
+ });
141
+ const prior = {
142
+ cwd: getCurrentCwd(),
143
+ sessionCwd: session.cwd,
144
+ workspace: session.workspace,
145
+ lock: workspaceCwdLock([session.id]),
146
+ prompt: snapshotPrompt(session),
147
+ };
148
+ journal.push(() => {
149
+ applyResolvedCwd(prior.cwd);
150
+ session.cwd = prior.sessionCwd;
151
+ session.workspace = prior.workspace;
152
+ setWorkspaceCwdLock(session.id, prior.lock);
153
+ prior.prompt();
154
+ session.updatedAt = Date.now();
155
+ persistSession(session);
156
+ moveLeadRow(prior.sessionCwd || prior.cwd);
157
+ invalidateCaches();
158
+ });
159
+ applyResolvedCwd(next.cwd);
160
+ session.cwd = next.cwd;
161
+ session.workspace = next;
162
+ moveLeadRow(next.cwd);
163
+ setWorkspaceCwdLock(session.id, isWorktreeBound(next) ? next.cwd : null);
164
+ await refreshWorkspaceContext(session, next.cwd);
165
+ await retargetWorkers(session, next.cwd, journal);
166
+ session.updatedAt = Date.now();
167
+ persistSession(session);
168
+ invalidateCaches();
169
+ return { revision: next.revision, workspace: next };
170
+ }
171
+
172
+ async function releaseOwner(backendApi, entryId, sessionId) {
173
+ try {
174
+ await backendApi.releaseWorktreeOwner(entryId, owner(sessionId));
175
+ } catch (error) {
176
+ // A worktree that vanished has no owner left to release.
177
+ if (!isWorktreeError(error, 'WORKTREE_MISSING')) throw error;
178
+ }
179
+ }
180
+
181
+ async function enterWorktree(session, previous, { name, nameHint, confirmLarge, signal, txId, journal }) {
182
+ const backendApi = await backend();
183
+ const projectPath = previous.projectPath;
184
+ const project = await inspectProject(projectPath, { signal });
185
+ let entry = await backendApi.getSessionWorktree(session.id);
186
+ if (entry) {
187
+ if (!existsSync(entry.path)) {
188
+ throw worktreeError('WORKTREE_MISSING', undefined, { worktreeId: entry.id, path: entry.path });
189
+ }
190
+ if (isWorktreeBound(previous) && previous.worktreeId === entry.id) {
191
+ return { revision: previous.revision, workspace: previous };
192
+ }
193
+ assertRetainedFits(entry, project, projectPath);
194
+ await backendApi.claimWorktreeOwner(entry.id, owner(session.id));
195
+ journal.push(() => releaseOwner(backendApi, entry.id, session.id));
196
+ } else {
197
+ // The backend resolves the base branch commit (from the project
198
+ // folder's checked-out branch), sizes and creates the checkout; the
199
+ // txId makes a retried or duplicate send return the same worktree.
200
+ entry = await backendApi.createManagedWorktree({
201
+ projectPath,
202
+ sessionId: session.id,
203
+ runtimeToken,
204
+ baseBranch: project.currentBranch,
205
+ nameHint: name ?? nameHint ?? '',
206
+ confirmLarge: confirmLarge === true,
207
+ txId,
208
+ signal,
209
+ });
210
+ }
211
+ // Cancelled after the worktree exists: it stays retained (same txId on
212
+ // retry), the session does not move.
213
+ throwIfAborted(signal);
214
+ // A Project registered below the repository root runs in the same
215
+ // subfolder of the worktree (and returns to its own folder on the way back).
216
+ const cwd = checkoutFolder(entry.path, projectSubdirOf(project.topLevel, project.projectPath || projectPath));
217
+ if (!existsSync(cwd)) mkdirSync(cwd, { recursive: true });
218
+ copyProjectIdentity(projectPath, cwd);
219
+ const entered = await commit(
220
+ session,
221
+ previous,
222
+ {
223
+ projectPath,
224
+ repoCommonDir: entry.repoCommonDir || project.repoCommonDir,
225
+ cwd,
226
+ worktreeId: entry.id,
227
+ branch: entry.branch,
228
+ baseCommit: entry.baseCommit,
229
+ mergeTarget: project.currentBranch,
230
+ },
231
+ journal
232
+ );
233
+ // Creation notes (submodules, include entries missing or already present).
234
+ return { ...entered, warnings: Array.isArray(entry.warnings) ? [...entry.warnings] : [] };
235
+ }
236
+
237
+ async function enterProjectBranch(session, previous, { branch, create, signal, journal }) {
238
+ const backendApi = await backend();
239
+ const projectPath = previous.projectPath;
240
+ const project = await inspectProject(projectPath, { signal });
241
+ const bound = isWorktreeBound(previous);
242
+ const finalize = async () => {
243
+ const result = await commit(
244
+ session,
245
+ previous,
246
+ { projectPath, repoCommonDir: project.repoCommonDir, cwd: projectPath, branch },
247
+ journal
248
+ );
249
+ if (bound) await releaseOwner(backendApi, previous.worktreeId, session.id);
250
+ return result;
251
+ };
252
+ if (create !== true && project.currentBranch === branch) {
253
+ if (!bound && previous.branch === branch && samePath(previous.cwd, projectPath)) {
254
+ return { revision: previous.revision, workspace: previous };
255
+ }
256
+ return finalize();
257
+ }
258
+ // The checkout stays held until the session is finalized on it, or put
259
+ // back: no other session's turn starts on a half-switched folder.
260
+ return withProjectFolder(session.id, project.topLevel || projectPath, async () => {
261
+ await backendApi.checkoutProjectBranch({ projectPath, branch, create: create === true });
262
+ try {
263
+ return await finalize();
264
+ } catch (error) {
265
+ await undoAll(journal, error);
266
+ journal.length = 0;
267
+ const context = { backendApi, projectPath, project, branch, bound, error };
268
+ throw await revertProjectCheckout(session, previous, context);
269
+ }
270
+ });
271
+ }
272
+
273
+ /**
274
+ * A branch switch whose finalization failed after git switched: switch the
275
+ * project folder back when that is safe (the manager refuses a dirty tree
276
+ * or a vanished branch) and rethrow the cause. Otherwise the session record
277
+ * is made to match the real checkout and the failure becomes
278
+ * WORKTREE_PARTIAL_TRANSITION naming the branch actually checked out.
279
+ */
280
+ async function revertProjectCheckout(session, previous, context) {
281
+ const { backendApi, projectPath, project, branch, bound, error } = context;
282
+ const previousBranch = project.currentBranch;
283
+ let revertError = null;
284
+ if (previousBranch) {
285
+ try {
286
+ await backendApi.checkoutProjectBranch({ projectPath, branch: previousBranch });
287
+ return error;
288
+ } catch (cause) {
289
+ revertError = cause;
290
+ }
291
+ }
292
+ if (!bound) {
293
+ // The session runs in the project folder, which is now on `branch`.
294
+ session.workspace = normalizeSessionWorkspace({
295
+ ...previous,
296
+ repoCommonDir: project.repoCommonDir,
297
+ branch,
298
+ revision: nextRevision(previous),
299
+ transition: { state: 'idle', txId: null },
300
+ });
301
+ session.updatedAt = Date.now();
302
+ persistSession(session);
303
+ invalidateCaches();
304
+ }
305
+ return worktreeError(
306
+ 'WORKTREE_PARTIAL_TRANSITION',
307
+ `The branch change failed (${error?.message || error}) and the project folder could not be switched back` +
308
+ `${previousBranch ? ` to "${previousBranch}"` : ''}; it is now on "${branch}".`,
309
+ {
310
+ checkout: branch,
311
+ previousBranch: previousBranch ?? null,
312
+ reason: String(error?.message || error),
313
+ revertReason: revertError ? String(revertError.message || revertError) : 'detached',
314
+ }
315
+ );
316
+ }
317
+
318
+ /**
319
+ * Validate the removal first (a dirty or unmerged worktree without `force`
320
+ * refuses with the session untouched), then return the session to its
321
+ * project folder, release the live lease and remove. A removal that still
322
+ * fails puts the session back exactly (the transaction journal).
323
+ */
324
+ async function removeRetainedWorktree(session, previous, { force, signal, journal }) {
325
+ const backendApi = await backend();
326
+ const entry = await backendApi.getSessionWorktree(session.id);
327
+ if (entry) await backendApi.assertWorktreeRemovable({ entryId: entry.id, force: force === true });
328
+ let result = { revision: previous.revision, workspace: previous };
329
+ if (isWorktreeBound(previous)) {
330
+ const project = await inspectProject(previous.projectPath, { signal });
331
+ result = await commit(
332
+ session,
333
+ previous,
334
+ {
335
+ projectPath: previous.projectPath,
336
+ repoCommonDir: project.repoCommonDir,
337
+ cwd: previous.projectPath,
338
+ branch: project.currentBranch,
339
+ },
340
+ journal
341
+ );
342
+ if (entry) {
343
+ await releaseOwner(backendApi, entry.id, session.id);
344
+ journal.push(() => backendApi.claimWorktreeOwner(entry.id, owner(session.id)));
345
+ }
346
+ }
347
+ if (!entry) return { ...result, removed: null };
348
+ let removed;
349
+ try {
350
+ removed = await backendApi.removeManagedWorktree({ entryId: entry.id, force: force === true });
351
+ } catch (error) {
352
+ // Refused before anything was deleted: the journal puts the session back.
353
+ // Once the checkout may be (partly) gone, the session stays in the
354
+ // project folder and the removal is reported incomplete.
355
+ const now = await backendApi.getSessionWorktree(session.id).catch(() => entry);
356
+ if (now?.id === entry.id && now.state === 'ready' && existsSync(entry.path)) throw error;
357
+ throw incompleteRemoval(journal, entry, result, { reason: String(error?.message || error) });
358
+ }
359
+ if (removed?.removed !== true) throw incompleteRemoval(journal, entry, result, removed);
360
+ return { ...result, removed };
361
+ }
362
+
363
+ return { enterWorktree, enterProjectBranch, removeRetainedWorktree };
364
+ }