mixdog 1.4.0 → 1.4.2
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/package.json +3 -2
- package/scripts/build-shipped-history.mjs +115 -33
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/gate-local.mjs +183 -63
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/gate-scheduler.mjs +138 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +91 -66
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +124 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +16 -4
- package/scripts/lib/test-spawn-ledger.mjs +12 -3
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -5
- package/scripts/suite-health.mjs +115 -24
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/app.mjs +4 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +23 -2
- package/src/defaults/skills/browser-use/SKILL.md +10 -5
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +16 -4
- package/src/defaults/skills/goal-management/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +12 -6
- package/src/defaults/skills/setup/references/surfaces.md +2 -2
- package/src/defaults/skills/setup-guide/SKILL.md +5 -2
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/rules-builder.cjs +35 -42
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +5 -4
- package/src/rules/lead/LEAD.md +12 -7
- package/src/rules/shared/10-tool-workflow.md +3 -1
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +8 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
- package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/whisper-port.mjs +29 -11
- package/src/runtime/channels/lib/whisper-server.mjs +10 -1
- package/src/runtime/computer-bridge/action-schema.mjs +2 -2
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
- package/src/runtime/connectors/gmail-app-password.mjs +3 -3
- package/src/runtime/explore/explorer.mjs +93 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/index.mjs +4 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +15 -6
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +11 -4
- package/src/runtime/shared/connector-catalog.mjs +60 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/defaults-separation.mjs +1 -4
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +13 -15
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
- package/src/runtime/shared/llm/cost.mjs +11 -2
- package/src/runtime/shared/llm/http-agent.mjs +313 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +452 -0
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/session-activity-signal.mjs +14 -0
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +113 -36
- package/src/runtime/shared/tool-work-units.mjs +6 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +72 -0
- package/src/runtime/shared/worktrees/manager.mjs +285 -168
- package/src/runtime/shared/worktrees/test-support.mjs +6 -10
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +7 -4
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +6 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +1 -1
- package/src/session-runtime/agent-home-delivery.mjs +41 -0
- package/src/session-runtime/agent-task-sessions.mjs +458 -312
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/bot-status.mjs +107 -101
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +401 -36
- package/src/session-runtime/conversation-import/service.mjs +35 -8
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
- package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +10 -6
- package/src/session-runtime/services/provider-admin.mjs +283 -11
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +6 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
- package/src/session-runtime/turn/agent-ops.mjs +23 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +108 -1041
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
- package/src/standalone/daemon-desktop-runtime.mjs +2 -0
- package/src/standalone/daemon-session-control.mjs +169 -138
- package/src/standalone/daemon.mjs +7 -0
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +5 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/App.jsx +154 -164
- package/src/tui/app/app-view/floating-panel.jsx +10 -4
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +21 -10
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +29 -18
- package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
- package/src/tui/app/slash-commands.mjs +1 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +3 -2
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +47 -32
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/dist/index.mjs +1963 -1361
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed checkouts the hosted Lead makes without moving into them: a branch
|
|
3
|
+
* worktree (`git worktree add`) and the read-only snapshots of its turns,
|
|
4
|
+
* which the turn's admission release removes once nothing runs in them.
|
|
5
|
+
*/
|
|
6
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
7
|
+
import { WORKTREE_SNAPSHOT_KIND, worktreeError } from '../../runtime/shared/worktrees/contract.mjs';
|
|
8
|
+
import { admitTurn } from './admission-gate.mjs';
|
|
9
|
+
|
|
10
|
+
// A settled turn's snapshot cleanup waits at most 2^5 times its first delay between attempts.
|
|
11
|
+
const SNAPSHOT_BACKOFF_STEPS = 5;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A managed worktree for `branch` without moving the session (`git
|
|
15
|
+
* worktree add`): retained by this session like a branch it selected, so
|
|
16
|
+
* entering it later (selectBranch) reuses it. A branch already checked out
|
|
17
|
+
* elsewhere is WORKTREE_BRANCH_OCCUPIED, except in this session's own
|
|
18
|
+
* managed worktree, which is returned as it is. `startPoint` (with
|
|
19
|
+
* `create`): the commit the new branch starts at.
|
|
20
|
+
*/
|
|
21
|
+
async function addBranchWorktree(
|
|
22
|
+
{ hostedSession, sessionProject, backend, runtimeToken, newTxId },
|
|
23
|
+
{ branch, create = false, startPoint = null, confirmLarge = false, txId = '', repoCommonDir = null } = {}
|
|
24
|
+
) {
|
|
25
|
+
const session = hostedSession(null);
|
|
26
|
+
const { workspace } = await sessionProject(session, repoCommonDir);
|
|
27
|
+
const backendApi = await backend();
|
|
28
|
+
const { occupancy } = await backendApi.listBranchOccupancy({
|
|
29
|
+
projectPath: workspace.projectPath,
|
|
30
|
+
sessionId: session.id,
|
|
31
|
+
});
|
|
32
|
+
const held = occupancy.find((row) => row.branch === branch && row.kind !== 'free');
|
|
33
|
+
if (held && !(held.kind === 'session' && held.sessionId === session.id)) {
|
|
34
|
+
throw worktreeError('WORKTREE_BRANCH_OCCUPIED', `Branch ${branch} is checked out in ${held.path}.`, {
|
|
35
|
+
branch,
|
|
36
|
+
path: held.path,
|
|
37
|
+
kind: held.kind,
|
|
38
|
+
...(held.sessionId ? { sessionId: held.sessionId } : {}),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const resolved = await backendApi.resolveBranchWorkspace({
|
|
42
|
+
projectPath: workspace.projectPath,
|
|
43
|
+
branch,
|
|
44
|
+
create: create === true,
|
|
45
|
+
startPoint,
|
|
46
|
+
sessionId: session.id,
|
|
47
|
+
runtimeToken,
|
|
48
|
+
txId: String(txId || '').trim() || newTxId(),
|
|
49
|
+
confirmLarge: confirmLarge === true,
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
path: resolved.path,
|
|
53
|
+
branch,
|
|
54
|
+
worktreeId: resolved.entry?.id ?? null,
|
|
55
|
+
created: resolved.created === true,
|
|
56
|
+
baseCommit: resolved.entry?.baseCommit ?? null,
|
|
57
|
+
mergeTarget: resolved.entry?.mergeTarget ?? null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Remove this session's snapshot at `path` now; a dirty one only with
|
|
63
|
+
* `force`, and none while a worker or background shell runs in it.
|
|
64
|
+
*/
|
|
65
|
+
async function removeSnapshot({ hostedSession, backend }, { path, force = false } = {}) {
|
|
66
|
+
const session = hostedSession(null);
|
|
67
|
+
const backendApi = await backend();
|
|
68
|
+
const entry = await backendApi.getWorktreeByPath(path);
|
|
69
|
+
if (entry?.kind !== WORKTREE_SNAPSHOT_KIND) throw worktreeError('WORKTREE_MISSING', undefined, { path });
|
|
70
|
+
if (entry.holderSessionId !== session.id) {
|
|
71
|
+
throw worktreeError(
|
|
72
|
+
'WORKTREE_BUSY_JOBS',
|
|
73
|
+
"This snapshot belongs to another session's turn; it is removed when that turn ends, or by a prune.",
|
|
74
|
+
{ reason: 'snapshot-held', sessionId: entry.holderSessionId, entryId: entry.id }
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const removed = await backendApi.removeSnapshotWorktree({ entryId: entry.id, force: force === true });
|
|
78
|
+
return { ...removed, entryId: entry.id, path: entry.path };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {object} deps The session view (hostedSession, sessionProject), the
|
|
83
|
+
* `backend()` loader, the runtime identity and the snapshot retry bounds.
|
|
84
|
+
*/
|
|
85
|
+
export function createSideCheckouts({
|
|
86
|
+
getSession,
|
|
87
|
+
getCurrentCwd,
|
|
88
|
+
hostedSession,
|
|
89
|
+
sessionProject,
|
|
90
|
+
backend,
|
|
91
|
+
runtimeToken,
|
|
92
|
+
newTxId,
|
|
93
|
+
snapshotRetryMs,
|
|
94
|
+
snapshotRetryLimit,
|
|
95
|
+
}) {
|
|
96
|
+
// The creation txIds of the read-only snapshots the current admitted turn
|
|
97
|
+
// made. Each turn owns its own set, so its cleanup never touches a later
|
|
98
|
+
// turn's snapshots (a txId, unlike a freed slug, is never reused).
|
|
99
|
+
let turnSnapshots = null;
|
|
100
|
+
// The running cleanups of settled turns' snapshots (controller → session id).
|
|
101
|
+
const snapshotCleanups = new Map();
|
|
102
|
+
let disposed = false;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Turn admission (see admission-gate admitTurn); resolves the release. The
|
|
106
|
+
* release also starts the removal of the read-only snapshots this turn
|
|
107
|
+
* made — only those (removeTurnSnapshots).
|
|
108
|
+
*/
|
|
109
|
+
async function admitTurnWorkspace({ signal } = {}) {
|
|
110
|
+
const release = await admitTurn({ sessionId: getSession()?.id || '', cwd: () => getCurrentCwd() || '', signal });
|
|
111
|
+
const made = new Set();
|
|
112
|
+
turnSnapshots = made;
|
|
113
|
+
return () => {
|
|
114
|
+
release();
|
|
115
|
+
if (turnSnapshots === made) turnSnapshots = null;
|
|
116
|
+
const sessionId = getSession()?.id;
|
|
117
|
+
if (made.size && sessionId) void removeTurnSnapshots(sessionId, [...made]);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Remove a settled turn's snapshots (by creation `txIds`) once nothing runs
|
|
123
|
+
* in them: a worker turn or background shell holding a workspace lease
|
|
124
|
+
* inside one keeps it (manager removeSessionSnapshots reports it `in-use`).
|
|
125
|
+
* Those are retried with a doubling delay (`snapshotRetryMs`, at most
|
|
126
|
+
* 2^SNAPSHOT_BACKOFF_STEPS times it) for at most `snapshotRetryLimit`
|
|
127
|
+
* attempts; a snapshot removal that fails otherwise is not retried. What is
|
|
128
|
+
* left then — or when the runtime is disposed, the session closes, is
|
|
129
|
+
* deleted or is no longer the one hosted here — is the prune's and the
|
|
130
|
+
* startup reconcile's. Admission is not held meanwhile: the removal only
|
|
131
|
+
* ever names this turn's snapshots.
|
|
132
|
+
*/
|
|
133
|
+
async function removeTurnSnapshots(sessionId, txIds) {
|
|
134
|
+
if (disposed) return;
|
|
135
|
+
const controller = new AbortController();
|
|
136
|
+
snapshotCleanups.set(controller, sessionId);
|
|
137
|
+
try {
|
|
138
|
+
let pending = txIds;
|
|
139
|
+
for (let attempt = 0; pending.length && attempt < snapshotRetryLimit; attempt++) {
|
|
140
|
+
if (attempt > 0) {
|
|
141
|
+
const wait = snapshotRetryMs * 2 ** Math.min(attempt - 1, SNAPSHOT_BACKOFF_STEPS);
|
|
142
|
+
await delay(wait, undefined, { ref: false, signal: controller.signal });
|
|
143
|
+
}
|
|
144
|
+
const session = getSession();
|
|
145
|
+
if (session?.id !== sessionId || session.closed === true) return;
|
|
146
|
+
const report = await (await backend()).removeSessionSnapshots(sessionId, { txIds: pending });
|
|
147
|
+
pending = report.kept.filter((row) => row.reason === 'in-use').map((row) => row.txId);
|
|
148
|
+
}
|
|
149
|
+
} catch {
|
|
150
|
+
// Cancelled, or the backend failed: the rest is the maintenance's.
|
|
151
|
+
} finally {
|
|
152
|
+
snapshotCleanups.delete(controller);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Stop the snapshot cleanups of `sessionId` (every session's when null). */
|
|
157
|
+
function cancelSnapshotCleanups(sessionId = null) {
|
|
158
|
+
for (const [controller, owner] of snapshotCleanups) {
|
|
159
|
+
if (sessionId === null || owner === sessionId) controller.abort();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Runtime teardown: no snapshot cleanup runs on (prune / startup reconcile finish them). */
|
|
164
|
+
function dispose() {
|
|
165
|
+
disposed = true;
|
|
166
|
+
cancelSnapshotCleanups();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* A read-only snapshot of `commit` for this session's turn (`git worktree
|
|
171
|
+
* add --detach`): a detached managed checkout no session works in,
|
|
172
|
+
* removed when the turn settles (and nothing runs in it any more). The
|
|
173
|
+
* session does not move. Only inside an admitted turn: a snapshot always
|
|
174
|
+
* belongs to the turn that made it.
|
|
175
|
+
*/
|
|
176
|
+
async function createSnapshot({ commit = 'HEAD', confirmLarge = false, txId = '', repoCommonDir = null } = {}) {
|
|
177
|
+
const session = hostedSession(null);
|
|
178
|
+
const made = turnSnapshots;
|
|
179
|
+
if (!made) throw new Error('A read-only snapshot belongs to a turn; none is running in this session.');
|
|
180
|
+
const { workspace } = await sessionProject(session, repoCommonDir);
|
|
181
|
+
const tx = String(txId || '').trim() || newTxId();
|
|
182
|
+
const entry = await (await backend()).createSnapshotWorktree({
|
|
183
|
+
projectPath: workspace.projectPath,
|
|
184
|
+
sessionId: session.id,
|
|
185
|
+
runtimeToken,
|
|
186
|
+
commit,
|
|
187
|
+
txId: tx,
|
|
188
|
+
confirmLarge: confirmLarge === true,
|
|
189
|
+
});
|
|
190
|
+
made.add(tx);
|
|
191
|
+
return entry;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
admitTurnWorkspace,
|
|
196
|
+
addBranchWorktree: (input) =>
|
|
197
|
+
addBranchWorktree({ hostedSession, sessionProject, backend, runtimeToken, newTxId }, input),
|
|
198
|
+
createSnapshot,
|
|
199
|
+
removeSnapshot: (input) => removeSnapshot({ hostedSession, backend }, input),
|
|
200
|
+
cancelSnapshotCleanups,
|
|
201
|
+
dispose,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The serialized moves of the hosted Lead: every workspace transition (enter
|
|
3
|
+
* a worktree, run in a branch's checkout, remove the retained worktree) and
|
|
4
|
+
* the Project switch. Each one is admitted against turns and other workspace
|
|
5
|
+
* changes, checks the Lead is idle, and journals its steps so a failure puts
|
|
6
|
+
* back exactly what already moved. Also the input checks the workspace API
|
|
7
|
+
* shares (worktree name, target, expected revision).
|
|
8
|
+
*/
|
|
9
|
+
import {
|
|
10
|
+
isWorktreeBound,
|
|
11
|
+
normalizeSessionWorkspace,
|
|
12
|
+
worktreeError,
|
|
13
|
+
worktreeNameError,
|
|
14
|
+
} from '../../runtime/shared/worktrees/contract.mjs';
|
|
15
|
+
import { throwIfAborted } from '../../runtime/shared/worktrees/git.mjs';
|
|
16
|
+
import { beginWorkspaceTransition } from './admission-gate.mjs';
|
|
17
|
+
import { undoAll } from './transition-steps.mjs';
|
|
18
|
+
import { readSessionWorkspace } from './workspace-state.mjs';
|
|
19
|
+
|
|
20
|
+
const WORKTREE_BOUND_SWITCH =
|
|
21
|
+
'The session works in a managed worktree; exit the worktree first (switch to a project-folder branch, or merge or remove the worktree) before moving it to another project.';
|
|
22
|
+
|
|
23
|
+
/** The in-flight marker state of each transition kind. */
|
|
24
|
+
const TRANSITION_STATE = { worktree: 'provisioning', branch: 'switching', 'remove-worktree': 'removing' };
|
|
25
|
+
|
|
26
|
+
export function validName(name) {
|
|
27
|
+
if (name === undefined || name === null) return null;
|
|
28
|
+
const error = worktreeNameError(name);
|
|
29
|
+
if (error) throw new TypeError(`worktree name is invalid: ${error}`);
|
|
30
|
+
return name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function normalizeTarget(target) {
|
|
34
|
+
const kind = target?.kind;
|
|
35
|
+
if (kind === 'worktree') return { kind, name: validName(target.name) };
|
|
36
|
+
if (kind === 'branch') {
|
|
37
|
+
if (typeof target.branch !== 'string' || !target.branch.trim()) {
|
|
38
|
+
throw new TypeError('workspace target branch must be a non-empty string.');
|
|
39
|
+
}
|
|
40
|
+
return { kind, branch: target.branch.trim(), create: target.create === true };
|
|
41
|
+
}
|
|
42
|
+
if (kind === 'remove-worktree') return { kind, force: target.force === true };
|
|
43
|
+
throw new TypeError('workspace target kind must be branch, worktree or remove-worktree.');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function validRevision(value) {
|
|
47
|
+
if (value === undefined || value === null) return undefined;
|
|
48
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
49
|
+
throw new TypeError('expectedRevision must be a non-negative integer.');
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** WORKTREE_REVISION_CONFLICT when the caller expected another workspace revision. */
|
|
55
|
+
export function assertRevision(revision, expectedRevision) {
|
|
56
|
+
if (expectedRevision !== undefined && expectedRevision !== revision) {
|
|
57
|
+
throw worktreeError('WORKTREE_REVISION_CONFLICT', undefined, { expectedRevision, revision });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {object} deps The session view (hostedSession, currentWorkspace),
|
|
63
|
+
* assertLeadIdle, the transition `steps` and the host's cwd hooks.
|
|
64
|
+
*/
|
|
65
|
+
export function createTransitionRunner({
|
|
66
|
+
getSession,
|
|
67
|
+
hostedSession,
|
|
68
|
+
currentWorkspace,
|
|
69
|
+
assertLeadIdle,
|
|
70
|
+
steps,
|
|
71
|
+
newTxId,
|
|
72
|
+
applyResolvedCwd,
|
|
73
|
+
getCurrentCwd,
|
|
74
|
+
}) {
|
|
75
|
+
async function transition(session, target, options = {}) {
|
|
76
|
+
throwIfAborted(options.signal);
|
|
77
|
+
const previous = currentWorkspace(session);
|
|
78
|
+
assertRevision(previous.revision, options.expectedRevision);
|
|
79
|
+
const txId = String(options.txId || '').trim() || newTxId();
|
|
80
|
+
const leave = beginWorkspaceTransition(session.id, txId);
|
|
81
|
+
const hadRecord = Object.hasOwn(session, 'workspace');
|
|
82
|
+
const stored = session.workspace;
|
|
83
|
+
const marker = normalizeSessionWorkspace({
|
|
84
|
+
...previous,
|
|
85
|
+
transition: { state: TRANSITION_STATE[target.kind], txId },
|
|
86
|
+
});
|
|
87
|
+
session.workspace = marker;
|
|
88
|
+
const restore = () => {
|
|
89
|
+
if (hadRecord) session.workspace = stored;
|
|
90
|
+
else delete session.workspace;
|
|
91
|
+
};
|
|
92
|
+
const journal = [];
|
|
93
|
+
try {
|
|
94
|
+
await assertLeadIdle(session, { ownTurn: options.ownTurn === true });
|
|
95
|
+
const run = { signal: options.signal, txId, journal };
|
|
96
|
+
// A new checkout gets its dependencies prepared at the start of the
|
|
97
|
+
// first turn a session runs there (runPendingSetup, from its registry entry).
|
|
98
|
+
if (target.kind === 'worktree') {
|
|
99
|
+
return await steps.enterWorktree(session, previous, {
|
|
100
|
+
...run,
|
|
101
|
+
name: target.name,
|
|
102
|
+
nameHint: options.nameHint,
|
|
103
|
+
confirmLarge: options.confirmLarge,
|
|
104
|
+
changes: options.changes,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (target.kind === 'branch') {
|
|
108
|
+
return await steps.enterProjectBranch(session, previous, {
|
|
109
|
+
...run,
|
|
110
|
+
branch: target.branch,
|
|
111
|
+
create: target.create,
|
|
112
|
+
confirmLarge: options.confirmLarge,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return await steps.removeRetainedWorktree(session, previous, { ...run, force: target.force });
|
|
116
|
+
} catch (error) {
|
|
117
|
+
// Whatever already moved (cwd, record, prompts, worker roots, lease)
|
|
118
|
+
// goes back exactly; the previous workspace stays authoritative.
|
|
119
|
+
await undoAll(journal, error);
|
|
120
|
+
throw error;
|
|
121
|
+
} finally {
|
|
122
|
+
if (session.workspace === marker) restore();
|
|
123
|
+
leave();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The one entry of every transition. `ownTurn` (internal: the Lead's own
|
|
129
|
+
* tool call) tolerates the calling turn; `txId` keys the creation.
|
|
130
|
+
*/
|
|
131
|
+
async function runTransition(sessionRef, target, options = {}, { ownTurn = false, txId = '' } = {}) {
|
|
132
|
+
const session = hostedSession(sessionRef);
|
|
133
|
+
return transition(session, normalizeTarget(target), {
|
|
134
|
+
expectedRevision: validRevision(options.expectedRevision),
|
|
135
|
+
confirmLarge: options.confirmLarge === true,
|
|
136
|
+
signal: options.signal,
|
|
137
|
+
ownTurn: ownTurn === true,
|
|
138
|
+
txId,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function removeWorktree({ force = false, expectedRevision } = {}, { ownTurn = false } = {}) {
|
|
143
|
+
const expected = validRevision(expectedRevision);
|
|
144
|
+
const session = hostedSession(null);
|
|
145
|
+
return transition(
|
|
146
|
+
session,
|
|
147
|
+
{ kind: 'remove-worktree', force: force === true },
|
|
148
|
+
{ ownTurn: ownTurn === true, expectedRevision: expected }
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Move the hosted Lead to another Project folder (session set-project, the
|
|
154
|
+
* desktop/remote setCwd): the one authority for a Project switch, admitted
|
|
155
|
+
* like a workspace transition. Refused while a turn runs (`ownTurn`: the
|
|
156
|
+
* Lead's own tool call tolerates its calling turn), while workers run, and
|
|
157
|
+
* while the session works in a managed worktree. Serialized with turns and
|
|
158
|
+
* other workspace changes; the prompt refresh of the Lead and its idle
|
|
159
|
+
* workers completes (or rolls the switch back) before it resolves. Without
|
|
160
|
+
* a session (a draft) only the runtime cwd and the selection move.
|
|
161
|
+
* `classifyByMembership` (the desktop/remote move): a folder outside every
|
|
162
|
+
* registered Project is classified as a task (cwd-apply).
|
|
163
|
+
* @returns {Promise<string>} the runtime cwd after the switch
|
|
164
|
+
*/
|
|
165
|
+
async function switchProject(cwd, { ownTurn = false, classifyByMembership = false } = {}) {
|
|
166
|
+
const selection = { classifyByMembership: classifyByMembership === true };
|
|
167
|
+
const session = getSession();
|
|
168
|
+
if (!session?.id) {
|
|
169
|
+
applyResolvedCwd(cwd, { persistProjectSelection: true, ...selection });
|
|
170
|
+
return getCurrentCwd();
|
|
171
|
+
}
|
|
172
|
+
const leave = beginWorkspaceTransition(session.id, `project:${newTxId()}`);
|
|
173
|
+
const journal = [];
|
|
174
|
+
try {
|
|
175
|
+
await assertLeadIdle(session, { ownTurn: ownTurn === true, shellJobs: false });
|
|
176
|
+
if (isWorktreeBound(readSessionWorkspace(session))) throw new Error(WORKTREE_BOUND_SWITCH);
|
|
177
|
+
await steps.switchProject(session, cwd, journal, selection);
|
|
178
|
+
return getCurrentCwd();
|
|
179
|
+
} catch (error) {
|
|
180
|
+
await undoAll(journal, error);
|
|
181
|
+
throw error;
|
|
182
|
+
} finally {
|
|
183
|
+
leave();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return { transition, runTransition, removeWorktree, switchProject };
|
|
188
|
+
}
|