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.
- package/README.md +8 -5
- package/package.json +2 -1
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +18 -5
- package/src/defaults/skills/visualize/SKILL.md +160 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/help.mjs +2 -0
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -5
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
- package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/shared/atomic-file.mjs +33 -6
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -130
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +125 -21
- package/src/runtime/shared/provider-api-key.mjs +33 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/tool-surface.mjs +7 -0
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +90 -0
- package/src/session-runtime/boot/config.mjs +7 -2
- package/src/session-runtime/boot/facade.mjs +21 -0
- package/src/session-runtime/boot/infrastructure.mjs +30 -18
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +4 -0
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +68 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/mcp-glue.mjs +22 -2
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +18 -3
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- package/src/session-runtime/resource-extension-sync.mjs +45 -7
- package/src/session-runtime/resource-mcp-api.mjs +121 -84
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +15 -4
- package/src/standalone/daemon.mjs +179 -8
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +11 -0
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +21 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +6 -0
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +37 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +839 -207
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +4 -2
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +17 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +9 -0
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +27 -3
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +56 -10
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- 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
|
+
}
|