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
|
@@ -72,6 +72,27 @@ export function createAgentOps(deps) {
|
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
// `/stop`: the background shells this session would stop, then stopping all
|
|
76
|
+
// of them through the same per-task cancel.
|
|
77
|
+
async function listStoppableShellJobs() {
|
|
78
|
+
const session = getSession();
|
|
79
|
+
const { listStoppableShellJobs: list } = await import(
|
|
80
|
+
'../../runtime/agent/orchestrator/tools/builtin/task-tool.mjs'
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
jobs: list({ callerSessionId: session?.id || null, clientHostPid: session?.clientHostPid || process.pid }),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function stopShellJobs() {
|
|
88
|
+
const session = getSession();
|
|
89
|
+
const { stopBackgroundShellJobs } = await import('../../runtime/agent/orchestrator/tools/builtin/task-tool.mjs');
|
|
90
|
+
return stopBackgroundShellJobs({
|
|
91
|
+
callerSessionId: session?.id || null,
|
|
92
|
+
clientHostPid: session?.clientHostPid || process.pid,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
75
96
|
// Explicit user force-release ("Release anyway") of a shell job whose
|
|
76
97
|
// termination is unconfirmed: drops its workspace hold. The surface has
|
|
77
98
|
// already asked the user to confirm. The caller session's own holds, and
|
|
@@ -147,6 +168,8 @@ export function createAgentOps(deps) {
|
|
|
147
168
|
agentControl,
|
|
148
169
|
taskControl,
|
|
149
170
|
stopShellJob,
|
|
171
|
+
listStoppableShellJobs,
|
|
172
|
+
stopShellJobs,
|
|
150
173
|
releaseShellJob,
|
|
151
174
|
listShellJobs,
|
|
152
175
|
onNotification,
|
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
assertConnectorPolicyNotWidened,
|
|
5
5
|
CONNECTOR_PERMISSIONS,
|
|
6
6
|
connectorEnabled,
|
|
7
|
+
connectorGroupId,
|
|
8
|
+
connectorToolEntries,
|
|
9
|
+
connectorToolPermission,
|
|
7
10
|
DENY_ALL_CONNECTORS,
|
|
8
11
|
migrateLegacyConnectorPolicy,
|
|
9
12
|
NO_WIDEN_MESSAGE,
|
|
@@ -108,8 +111,8 @@ export function createAgentConnectorsApi(deps, editor) {
|
|
|
108
111
|
return getAgentConnectors(agentId);
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
//
|
|
112
|
-
// `permission` null drops the tool's entry, so the tool is
|
|
114
|
+
// One tool's permission (the profile's tool list, getAgentConnectorTools):
|
|
115
|
+
// `permission` null drops the tool's entry, so the tool is on its default again.
|
|
113
116
|
async function setAgentConnectorToolPermission(agentId, connectorId, toolName, permission, options) {
|
|
114
117
|
if (permission != null && !CONNECTOR_PERMISSIONS.includes(permission)) {
|
|
115
118
|
throw new Error(`permission must be one of ${CONNECTOR_PERMISSIONS.join(', ')}`);
|
|
@@ -117,19 +120,25 @@ export function createAgentConnectorsApi(deps, editor) {
|
|
|
117
120
|
const server = requireId(connectorId, 'connector id');
|
|
118
121
|
const tool = requireId(toolName, 'tool name');
|
|
119
122
|
const policy = editablePolicy(agentId);
|
|
120
|
-
|
|
123
|
+
// The accounts of one connector (`gmail`, `gmail-2`…) share the permission,
|
|
124
|
+
// stored once under the connector's id; an entry an account kept of its own
|
|
125
|
+
// for this tool goes in the same write.
|
|
126
|
+
const group = connectorGroupId(server);
|
|
127
|
+
const tools = Object.fromEntries(
|
|
128
|
+
Object.entries(policy.tools).map(([id, entries]) => {
|
|
129
|
+
if (id === group || connectorGroupId(id) !== group) return [id, entries];
|
|
130
|
+
const { [tool]: _dropped, ...rest } = entries;
|
|
131
|
+
return [id, rest];
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
const own = { ...tools[group] };
|
|
121
135
|
if (permission == null) delete own[tool];
|
|
122
136
|
else own[tool] = permission;
|
|
137
|
+
tools[group] = own;
|
|
123
138
|
if (options?.noWiden) {
|
|
124
|
-
assertConnectorPolicyNotWidened(editor.getAgentConnectorPolicy(agentId), {
|
|
125
|
-
off: policy.off,
|
|
126
|
-
tools: { ...policy.tools, [server]: own },
|
|
127
|
-
});
|
|
139
|
+
assertConnectorPolicyNotWidened(editor.getAgentConnectorPolicy(agentId), { off: policy.off, tools });
|
|
128
140
|
}
|
|
129
|
-
return editor.setAgentConnectorPolicy(
|
|
130
|
-
agentId,
|
|
131
|
-
storedConnectorPolicy({ off: policy.off, tools: { ...policy.tools, [server]: own } })
|
|
132
|
-
);
|
|
141
|
+
return editor.setAgentConnectorPolicy(agentId, storedConnectorPolicy({ off: policy.off, tools }));
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
// A card's "항상 허용" for a connector tool saves through this same writer.
|
|
@@ -149,6 +158,34 @@ export function createAgentConnectorsApi(deps, editor) {
|
|
|
149
158
|
.sort((a, b) => a.connector.localeCompare(b.connector) || a.tool.localeCompare(b.tool));
|
|
150
159
|
}
|
|
151
160
|
|
|
161
|
+
/** `[{ connector, tool, permission, explicit }]`: each installed connector's
|
|
162
|
+
* tools (the connected server's own, and any the agent's policy names) with
|
|
163
|
+
* the permission the agent has for the tool itself, so a connector switched
|
|
164
|
+
* off does not change it, and whether that is an entry of its own policy
|
|
165
|
+
* rather than the tool's default. The profile's per-tool editor reads it. */
|
|
166
|
+
function getAgentConnectorTools(agentId) {
|
|
167
|
+
const { tools } = editablePolicy(agentId);
|
|
168
|
+
return installedIds().flatMap((connector) => {
|
|
169
|
+
const group = connectorGroupId(connector);
|
|
170
|
+
const accounts = Object.entries(tools).filter(([id]) => connectorGroupId(id) === group);
|
|
171
|
+
const names = new Set([
|
|
172
|
+
...listConnectorTools(connector).map(({ name }) => name),
|
|
173
|
+
...accounts.flatMap(([, entries]) => Object.keys(entries)),
|
|
174
|
+
]);
|
|
175
|
+
// Accounts share one permission (stored under the connector); entries an
|
|
176
|
+
// account kept of its own follow the topmost.
|
|
177
|
+
return [...names].map((tool) => ({
|
|
178
|
+
connector,
|
|
179
|
+
tool,
|
|
180
|
+
permission: connectorToolPermission(
|
|
181
|
+
{ off: [], tools },
|
|
182
|
+
{ mcpServerName: connector, mcpToolName: tool }
|
|
183
|
+
),
|
|
184
|
+
explicit: connectorToolEntries(tools, group, tool).length > 0,
|
|
185
|
+
}));
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
152
189
|
/** Replace the agent's connector policy (null removes it). With `options.noWiden`
|
|
153
190
|
* the replacement may not give any tool more authority than the stored policy. */
|
|
154
191
|
async function setAgentConnectors(agentId, connectors, options) {
|
|
@@ -279,6 +316,7 @@ export function createAgentConnectorsApi(deps, editor) {
|
|
|
279
316
|
setAgentConnectorEnabled,
|
|
280
317
|
setAgentConnectorToolPermission,
|
|
281
318
|
getAgentAlwaysAllowedTools,
|
|
319
|
+
getAgentConnectorTools,
|
|
282
320
|
getProjectConnectors,
|
|
283
321
|
setProjectConnectorEnabled,
|
|
284
322
|
migrateConnectorPolicies,
|
|
@@ -19,7 +19,11 @@ import {
|
|
|
19
19
|
writeJsonAtomicSync,
|
|
20
20
|
} from '../../runtime/shared/atomic-file.mjs';
|
|
21
21
|
import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
agentEntryFile,
|
|
24
|
+
agentEntryPath,
|
|
25
|
+
parseManifestText,
|
|
26
|
+
} from '../../runtime/agent/orchestrator/runtime-core/workflow/agents.mjs';
|
|
23
27
|
import { hasOwn } from '../../runtime/shared/object.mjs';
|
|
24
28
|
import { serializeFrontmatterDoc } from '../../runtime/shared/markdown-frontmatter.mjs';
|
|
25
29
|
import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.mjs';
|
|
@@ -7,6 +7,7 @@ import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-
|
|
|
7
7
|
import { resolveRouteContextState, selectionFastCapable } from '../route-state.mjs';
|
|
8
8
|
import {
|
|
9
9
|
canonicalizeAgentRouteStorage,
|
|
10
|
+
EXPLORE_AGENT_ID,
|
|
10
11
|
isAgentDisabled,
|
|
11
12
|
withAgentDisabled,
|
|
12
13
|
} from '../../runtime/shared/agent-route-config.mjs';
|
|
@@ -22,7 +23,11 @@ import {
|
|
|
22
23
|
|
|
23
24
|
/** Mixy's runtime id (agent-home.mjs MIXY_AGENT_ID). */
|
|
24
25
|
const MIXY_RUNTIME_ID = 'lead';
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
canonicalRouteProvider,
|
|
28
|
+
routeChain,
|
|
29
|
+
validateRouteChainProviders,
|
|
30
|
+
} from '../../runtime/shared/model-route-chain.mjs';
|
|
26
31
|
|
|
27
32
|
// Agent route persistence. Route-scope isolation: an agent route owns its
|
|
28
33
|
// model AND its effort/fast, stored in config.agents[<id>]. The shared
|
|
@@ -183,18 +188,25 @@ export function createAgentRouteApi(deps) {
|
|
|
183
188
|
}
|
|
184
189
|
if (!clean(requested.provider)) return clearOverride(id);
|
|
185
190
|
if (!clean(requested.model)) throw new Error('agent route requires provider and model');
|
|
191
|
+
// An explicit list is validated; the stored one may hold a fallback on the
|
|
192
|
+
// picked model's provider, which stays saved untouched and inactive.
|
|
193
|
+
const explicitFallbacks = hasOwn(requested, 'fallbacks');
|
|
186
194
|
const chain = routeChain({
|
|
187
195
|
...requested,
|
|
188
|
-
fallbacks:
|
|
196
|
+
fallbacks: explicitFallbacks ? requested.fallbacks : stored.fallbacks,
|
|
189
197
|
});
|
|
190
|
-
validateRouteChainProviders(chain);
|
|
198
|
+
validateRouteChainProviders(chain, { allowDuplicates: !explicitFallbacks });
|
|
191
199
|
const storedChain = routeChain(stored);
|
|
192
200
|
const resolved = [];
|
|
201
|
+
const usedProviders = new Set();
|
|
193
202
|
for (const entry of chain) {
|
|
203
|
+
const provider = canonicalRouteProvider(entry.provider);
|
|
204
|
+
const inactive = usedProviders.has(provider);
|
|
205
|
+
usedProviders.add(provider);
|
|
194
206
|
const previous = storedChain.find(
|
|
195
207
|
(candidate) => candidate.provider === entry.provider && candidate.model === entry.model
|
|
196
208
|
);
|
|
197
|
-
resolved.push(await resolveChainEntry(deps, entry, previous || {}));
|
|
209
|
+
resolved.push(inactive ? entry : await resolveChainEntry(deps, entry, previous || {}));
|
|
198
210
|
}
|
|
199
211
|
const [primary, ...fallbacks] = resolved;
|
|
200
212
|
const routeToSave = normalizeWorkflowRoute({ ...primary, fallbacks });
|
|
@@ -215,5 +227,13 @@ export function createAgentRouteApi(deps) {
|
|
|
215
227
|
return stayOff ? { ...routeToSave, id, disabled: true } : routeToSave;
|
|
216
228
|
}
|
|
217
229
|
|
|
218
|
-
|
|
230
|
+
// Explore's route decides whether the explore tool exists, so the empty
|
|
231
|
+
// session rebuilds its tool surface on any change of it.
|
|
232
|
+
async function setAgentRouteAndRefresh(agentId, next) {
|
|
233
|
+
const saved = await setAgentRoute(agentId, next);
|
|
234
|
+
if (agentEditorId(agentId) === EXPLORE_AGENT_ID) await deps.refreshEmptySessionToolPolicy?.();
|
|
235
|
+
return saved;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return { setAgentRoute: setAgentRouteAndRefresh };
|
|
219
239
|
}
|
|
@@ -20,7 +20,7 @@ import { resolveDataDir } from './shared.mjs';
|
|
|
20
20
|
function applyWorkflowSlots(workflowInput, draft) {
|
|
21
21
|
for (const slot of WORKFLOW_ROUTE_SLOTS) {
|
|
22
22
|
if (!hasOwn(workflowInput, slot)) continue;
|
|
23
|
-
const normalized = normalizeWorkflowRoute(workflowInput[slot]);
|
|
23
|
+
const normalized = normalizeWorkflowRoute(workflowInput[slot], {}, { strict: true });
|
|
24
24
|
if (slot === 'lead') {
|
|
25
25
|
if (!normalized) continue;
|
|
26
26
|
draft.presets = upsertWorkflowPreset(draft.presets, 'lead', normalized);
|
|
@@ -40,7 +40,7 @@ function applyAgentRouteInput(agentInput, agentRoutes, configurableIds) {
|
|
|
40
40
|
const nextAgents = { ...agentRoutes };
|
|
41
41
|
for (const id of configurableIds) {
|
|
42
42
|
if (!hasOwn(agentInput, id)) continue;
|
|
43
|
-
const routeToSave = normalizeWorkflowRoute(agentInput[id]);
|
|
43
|
+
const routeToSave = normalizeWorkflowRoute(agentInput[id], {}, { strict: true });
|
|
44
44
|
if (routeToSave) nextAgents[id] = routeToSave;
|
|
45
45
|
else delete nextAgents[id];
|
|
46
46
|
}
|
|
@@ -67,7 +67,7 @@ export function createOnboardingApi(deps) {
|
|
|
67
67
|
const config = getConfig();
|
|
68
68
|
const nextConfig = { ...config };
|
|
69
69
|
const defaultRoute = hasOwn(payload, 'defaultRoute')
|
|
70
|
-
? normalizeWorkflowRoute(payload.defaultRoute, getRoute())
|
|
70
|
+
? normalizeWorkflowRoute(payload.defaultRoute, getRoute(), { strict: true })
|
|
71
71
|
: null;
|
|
72
72
|
const draft = {
|
|
73
73
|
presets: Array.isArray(nextConfig.presets) ? nextConfig.presets.slice() : [],
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The activity checks every workspace change runs first: whether the hosted
|
|
3
|
+
* Lead (its turn, workers and background shells) is idle, and whether other
|
|
4
|
+
* sessions work in a shared checkout — then holding that checkout so new
|
|
5
|
+
* turns there wait until the change settles (admission gate).
|
|
6
|
+
*/
|
|
7
|
+
import { worktreeError, worktreeRefusal } from '../../runtime/shared/worktrees/contract.mjs';
|
|
8
|
+
import { isWithin } from '../../runtime/shared/worktrees/paths.mjs';
|
|
9
|
+
import {
|
|
10
|
+
holdWorkspaceActivity,
|
|
11
|
+
isExternalCheckout,
|
|
12
|
+
releaseAll,
|
|
13
|
+
} from '../../runtime/shared/worktrees/activity-gate.mjs';
|
|
14
|
+
import { AGENT_OWNER } from '../../runtime/agent/orchestrator/agent-owner.mjs';
|
|
15
|
+
import { holdCheckoutFolder } from './admission-gate.mjs';
|
|
16
|
+
|
|
17
|
+
const ACTIVE_STAGES = new Set(['connecting', 'requesting', 'streaming', 'tool_running', 'running', 'cancelling']);
|
|
18
|
+
const BUSY_WORKER_STATES = new Set([...ACTIVE_STAGES, 'starting', 'spawning', 'queued', 'pending']);
|
|
19
|
+
const BUSY_JOB_STATES = new Set(['starting', 'spawning', 'queued', 'pending', 'running']);
|
|
20
|
+
|
|
21
|
+
const lower = (value) => String(value || '').toLowerCase();
|
|
22
|
+
|
|
23
|
+
/** @param {object} deps The activity sources of createWorkspaceTransitions. */
|
|
24
|
+
export function createActivityGuards({
|
|
25
|
+
getActiveTurnCount,
|
|
26
|
+
agentStatusState,
|
|
27
|
+
countOwnShellJobs,
|
|
28
|
+
listLiveSessions,
|
|
29
|
+
sessionManager,
|
|
30
|
+
listWorkspaceConsumers,
|
|
31
|
+
listWorkspaceJobs,
|
|
32
|
+
}) {
|
|
33
|
+
function isSessionActive(session) {
|
|
34
|
+
const runtime = sessionManager?.getSessionRuntime?.(session.id);
|
|
35
|
+
if (runtime?.controller?.signal && !runtime.controller.signal.aborted) return true;
|
|
36
|
+
return ACTIVE_STAGES.has(lower(runtime?.stage || session.status));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const workersOf = (session) =>
|
|
40
|
+
listLiveSessions().filter(
|
|
41
|
+
(candidate) =>
|
|
42
|
+
candidate?.id &&
|
|
43
|
+
candidate.id !== session.id &&
|
|
44
|
+
candidate.owner === AGENT_OWNER &&
|
|
45
|
+
candidate.closed !== true &&
|
|
46
|
+
(candidate.ownerSessionId === session.id || candidate.parentSessionId === session.id)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* WORKTREE_BUSY_JOBS while this Lead has a turn, workers or background
|
|
51
|
+
* shells running (`shellJobs: false` tolerates background shells).
|
|
52
|
+
*/
|
|
53
|
+
async function assertLeadIdle(session, { ownTurn = false, shellJobs: checkShellJobs = true } = {}) {
|
|
54
|
+
if (!ownTurn && getActiveTurnCount() > 0) {
|
|
55
|
+
throw worktreeError('WORKTREE_BUSY_JOBS', 'The session is running a turn; wait for it to finish.', {
|
|
56
|
+
reason: 'turn',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const status = agentStatusState?.() || {};
|
|
60
|
+
const workers = Array.isArray(status.agentWorkers) ? status.agentWorkers : [];
|
|
61
|
+
const jobs = Array.isArray(status.agentJobs) ? status.agentJobs : [];
|
|
62
|
+
const busyWorkers = workers.filter(
|
|
63
|
+
(row) => BUSY_WORKER_STATES.has(lower(row?.status)) || BUSY_WORKER_STATES.has(lower(row?.stage))
|
|
64
|
+
).length;
|
|
65
|
+
const busyJobs = jobs.filter((row) => BUSY_JOB_STATES.has(lower(row?.status))).length;
|
|
66
|
+
if (busyWorkers || busyJobs) {
|
|
67
|
+
throw worktreeError('WORKTREE_BUSY_JOBS', undefined, { reason: 'workers', workers: busyWorkers, jobs: busyJobs });
|
|
68
|
+
}
|
|
69
|
+
if (!checkShellJobs) return;
|
|
70
|
+
const ids = new Set([session.id, ...workers.map((row) => row?.sessionId).filter(Boolean)]);
|
|
71
|
+
for (const worker of workersOf(session)) ids.add(worker.id);
|
|
72
|
+
const shellJobs = await countOwnShellJobs([...ids]);
|
|
73
|
+
if (shellJobs > 0) throw worktreeError('WORKTREE_BUSY_JOBS', undefined, { reason: 'shell-jobs', shellJobs });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A checkout or merge in the shared checkout `folder` refuses while another
|
|
78
|
+
* session (not this Lead's own workers) works there, then holds the folder
|
|
79
|
+
* until the returned release: other sessions' turns that arrive meanwhile
|
|
80
|
+
* wait (admission gate). `sessionId` null: a session-less (draft) change.
|
|
81
|
+
* @returns {() => void}
|
|
82
|
+
*/
|
|
83
|
+
function holdProjectFolder(sessionId, folder, { hold = true } = {}) {
|
|
84
|
+
const users = listLiveSessions().filter(
|
|
85
|
+
(candidate) =>
|
|
86
|
+
candidate?.id &&
|
|
87
|
+
candidate.id !== sessionId &&
|
|
88
|
+
candidate.closed !== true &&
|
|
89
|
+
(!sessionId || (candidate.ownerSessionId !== sessionId && candidate.parentSessionId !== sessionId)) &&
|
|
90
|
+
typeof candidate.cwd === 'string' &&
|
|
91
|
+
isWithin(folder, candidate.cwd) &&
|
|
92
|
+
isSessionActive(candidate)
|
|
93
|
+
);
|
|
94
|
+
if (users.length) throw worktreeRefusal('folder-in-use', { sessions: users.map((candidate) => candidate.id) });
|
|
95
|
+
return holdCheckoutFolder(sessionId, folder, { hold });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Run `fn` holding the checkout `folder` (holdProjectFolder); released when it settles. */
|
|
99
|
+
async function withProjectFolder(sessionId, folder, fn) {
|
|
100
|
+
const release = holdProjectFolder(sessionId, folder);
|
|
101
|
+
try {
|
|
102
|
+
return await fn();
|
|
103
|
+
} finally {
|
|
104
|
+
release();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Before a carry clears the shared checkout `folder` (held by the caller,
|
|
110
|
+
* so no new turn starts there): WORKTREE_BUSY_JOBS while any other session
|
|
111
|
+
* working in it — idle or not, this Lead's workers included — owns a
|
|
112
|
+
* running background shell (holdProjectFolder already refused running
|
|
113
|
+
* turns and agents there, assertLeadIdle this Lead's own). Processes
|
|
114
|
+
* outside Mixdog (editors, watchers) cannot be excluded.
|
|
115
|
+
*/
|
|
116
|
+
async function assertCheckoutQuiet(session, folder) {
|
|
117
|
+
const sharing = listLiveSessions()
|
|
118
|
+
.filter(
|
|
119
|
+
(candidate) =>
|
|
120
|
+
candidate?.id &&
|
|
121
|
+
candidate.id !== session.id &&
|
|
122
|
+
candidate.closed !== true &&
|
|
123
|
+
typeof candidate.cwd === 'string' &&
|
|
124
|
+
isWithin(folder, candidate.cwd)
|
|
125
|
+
)
|
|
126
|
+
.map((candidate) => candidate.id);
|
|
127
|
+
if (!sharing.length) return;
|
|
128
|
+
const shellJobs = await countOwnShellJobs(sharing);
|
|
129
|
+
if (shellJobs > 0) throw worktreeRefusal('folder-shell-jobs', { shellJobs });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The shared admission of every merge and folder cleanup (manageProjectBranch):
|
|
134
|
+
* refuses while a session or worker runs in an affected folder, or a
|
|
135
|
+
* background command does; `removing` refuses while any session still uses
|
|
136
|
+
* one. Then holds the folders — Mixdog checkouts only; an external checkout
|
|
137
|
+
* takes no lease from this profile — so new Mixdog work there waits until `run`
|
|
138
|
+
* settles. `actor`: the session acting on its own checkout, whose own turn
|
|
139
|
+
* and workers its caller already checked (assertLeadIdle).
|
|
140
|
+
*/
|
|
141
|
+
async function withManagementFolders(folders, removing, run, { actor = null } = {}) {
|
|
142
|
+
const release = [];
|
|
143
|
+
try {
|
|
144
|
+
for (const folder of [...new Set(folders)].sort()) {
|
|
145
|
+
release.push(holdProjectFolder(actor, folder, { hold: !isExternalCheckout(folder) }));
|
|
146
|
+
}
|
|
147
|
+
release.push(holdWorkspaceActivity(folders, { sessionId: actor }));
|
|
148
|
+
const stored = await listWorkspaceConsumers();
|
|
149
|
+
const consumers = new Map(stored.map((session) => [session.id, session]));
|
|
150
|
+
for (const session of listLiveSessions()) if (session?.closed !== true) consumers.set(session.id, session);
|
|
151
|
+
const affected = [...consumers.values()].filter((session) =>
|
|
152
|
+
folders.some((folder) => session.cwd && isWithin(folder, session.cwd))
|
|
153
|
+
);
|
|
154
|
+
const blocking = removing
|
|
155
|
+
? affected
|
|
156
|
+
: affected.filter(
|
|
157
|
+
(session) =>
|
|
158
|
+
!(actor && [session.id, session.ownerSessionId, session.parentSessionId].includes(actor)) &&
|
|
159
|
+
isSessionActive(session)
|
|
160
|
+
);
|
|
161
|
+
if (blocking.length) throw worktreeRefusal('folder-in-use', { sessions: blocking.map((session) => session.id) });
|
|
162
|
+
const jobs = await listWorkspaceJobs();
|
|
163
|
+
if (jobs.some((job) => !job.terminal && folders.some((folder) => isWithin(folder, job.cwd)))) {
|
|
164
|
+
throw worktreeRefusal('folder-shell-jobs');
|
|
165
|
+
}
|
|
166
|
+
if ((await countOwnShellJobs(affected.map((session) => session.id))) > 0) {
|
|
167
|
+
throw worktreeRefusal('folder-shell-jobs');
|
|
168
|
+
}
|
|
169
|
+
return await run([...consumers.keys()]);
|
|
170
|
+
} finally {
|
|
171
|
+
releaseAll(release);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return { workersOf, assertLeadIdle, withProjectFolder, assertCheckoutQuiet, withManagementFolders };
|
|
176
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hosted Lead's workspace as the transitions read it: the session this
|
|
3
|
+
* runtime hosts, its stored (or project-folder) workspace record, the live
|
|
4
|
+
* view the session snapshot publishes and the branch menu.
|
|
5
|
+
*/
|
|
6
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
7
|
+
import {
|
|
8
|
+
branchMenuEntries,
|
|
9
|
+
isWorktreeBound,
|
|
10
|
+
normalizeSessionWorkspace,
|
|
11
|
+
worktreeError,
|
|
12
|
+
} from '../../runtime/shared/worktrees/contract.mjs';
|
|
13
|
+
import { samePath } from '../../runtime/shared/worktrees/paths.mjs';
|
|
14
|
+
import { readGitHead } from '../../runtime/shared/worktrees/git-head.mjs';
|
|
15
|
+
import { readSessionWorkspace } from './workspace-state.mjs';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {object} deps The host hooks of createWorkspaceTransitions plus its
|
|
19
|
+
* `backend()` loader and `pendingWorktree()` (the armed worktree intent).
|
|
20
|
+
*/
|
|
21
|
+
export function createSessionWorkspaceView({
|
|
22
|
+
getSession,
|
|
23
|
+
getCurrentCwd,
|
|
24
|
+
getDesktopSession,
|
|
25
|
+
createCurrentSession,
|
|
26
|
+
inspectProject,
|
|
27
|
+
backend,
|
|
28
|
+
pendingWorktree,
|
|
29
|
+
}) {
|
|
30
|
+
function hostedSession(sessionRef) {
|
|
31
|
+
const session = getSession();
|
|
32
|
+
const requested = String(sessionRef?.sessionId || '').trim();
|
|
33
|
+
if (!session?.id || (requested && requested !== session.id)) {
|
|
34
|
+
throw new Error(`workspace: session ${requested || '(none)'} is not hosted by this runtime.`);
|
|
35
|
+
}
|
|
36
|
+
return session;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function ensureSession() {
|
|
40
|
+
if (!getSession()?.id && typeof createCurrentSession === 'function') await createCurrentSession('workspace');
|
|
41
|
+
return hostedSession(null);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function projectPathOf(session) {
|
|
45
|
+
const desktop = getDesktopSession?.() || session?.desktopSession;
|
|
46
|
+
if (desktop?.classification === 'project' && desktop.projectPath) return desktop.projectPath;
|
|
47
|
+
return session?.cwd || getCurrentCwd();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The stored record, or the project-folder workspace (revision 0) of a session that never moved. */
|
|
51
|
+
function currentWorkspace(session) {
|
|
52
|
+
const stored = readSessionWorkspace(session);
|
|
53
|
+
if (stored) return stored;
|
|
54
|
+
const projectPath = projectPathOf(session);
|
|
55
|
+
return normalizeSessionWorkspace({ projectPath, cwd: getCurrentCwd() || projectPath, revision: 0 });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let liveWorkspace = null;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The workspace the session publishes: a worktree-bound record as stored; a
|
|
62
|
+
* project-folder session (never moved, back from a worktree, or carrying a
|
|
63
|
+
* transition stub) with the folder's checked-out branch / detached commit and
|
|
64
|
+
* repoCommonDir read straight from HEAD — no git process. Null outside a git
|
|
65
|
+
* repository for a session without a record. Identity-stable while equal.
|
|
66
|
+
*/
|
|
67
|
+
function getLiveWorkspace() {
|
|
68
|
+
const session = getSession();
|
|
69
|
+
const stored = readSessionWorkspace(session);
|
|
70
|
+
if (isWorktreeBound(stored)) return session.workspace;
|
|
71
|
+
let base;
|
|
72
|
+
try {
|
|
73
|
+
base = stored ?? currentWorkspace(session);
|
|
74
|
+
} catch {
|
|
75
|
+
return session?.workspace ?? null;
|
|
76
|
+
}
|
|
77
|
+
const head = readGitHead(base.cwd);
|
|
78
|
+
if (!head) return session?.workspace ?? null;
|
|
79
|
+
const next = {
|
|
80
|
+
...base,
|
|
81
|
+
repoCommonDir: head.repoCommonDir,
|
|
82
|
+
branch: head.branch,
|
|
83
|
+
baseCommit: head.branch ? base.baseCommit : head.commit,
|
|
84
|
+
};
|
|
85
|
+
if (!liveWorkspace || !isDeepStrictEqual(liveWorkspace, next)) liveWorkspace = next;
|
|
86
|
+
return liveWorkspace;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** WORKTREE_PROJECT_MISMATCH unless `repoCommonDir` (when given) is the session Project's repository. */
|
|
90
|
+
async function sessionProject(session, repoCommonDir) {
|
|
91
|
+
const workspace = currentWorkspace(session);
|
|
92
|
+
const project = await inspectProject(workspace.projectPath);
|
|
93
|
+
if (repoCommonDir && !samePath(repoCommonDir, project.repoCommonDir)) {
|
|
94
|
+
throw worktreeError(
|
|
95
|
+
'WORKTREE_PROJECT_MISMATCH',
|
|
96
|
+
"Managed worktrees belong to this session's Project repository; run the command there.",
|
|
97
|
+
{ projectPath: workspace.projectPath, repoCommonDir }
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return { workspace, project };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function getBranchMenu() {
|
|
104
|
+
const session = getSession();
|
|
105
|
+
const workspace = session?.id
|
|
106
|
+
? currentWorkspace(session)
|
|
107
|
+
: normalizeSessionWorkspace({ projectPath: projectPathOf(null), cwd: getCurrentCwd(), revision: 0 });
|
|
108
|
+
const menu = await (await backend()).listBranchOccupancy({
|
|
109
|
+
projectPath: workspace.projectPath,
|
|
110
|
+
sessionId: session?.id || null,
|
|
111
|
+
});
|
|
112
|
+
const selectedEntry = workspace.worktreeId ? await (await backend()).findWorktreeContaining(workspace.cwd) : null;
|
|
113
|
+
// A session outside a managed worktree (the project folder — never moved,
|
|
114
|
+
// or back from a worktree — or a linked checkout of the selected branch)
|
|
115
|
+
// is on whatever that folder has checked out now.
|
|
116
|
+
// Its repository is the project's (a never-moved session has no stored
|
|
117
|
+
// record), and a detached checkout shows branch null with the commit in
|
|
118
|
+
// baseCommit — never mistaken for "not a repository".
|
|
119
|
+
let view = workspace;
|
|
120
|
+
if (!isWorktreeBound(workspace)) {
|
|
121
|
+
const project = await inspectProject(workspace.cwd);
|
|
122
|
+
const checkedOut = project.currentBranch ?? null;
|
|
123
|
+
view = {
|
|
124
|
+
...workspace,
|
|
125
|
+
repoCommonDir: project.repoCommonDir ?? workspace.repoCommonDir,
|
|
126
|
+
branch: checkedOut,
|
|
127
|
+
baseCommit: checkedOut ? workspace.baseCommit : (project.headCommit ?? null),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
workspace: view,
|
|
132
|
+
pendingWorktree: pendingWorktree(),
|
|
133
|
+
branches: branchMenuEntries(menu.branches, menu.occupancy),
|
|
134
|
+
occupancy: menu.occupancy,
|
|
135
|
+
retainedWorktree: selectedEntry ?? menu.retainedWorktree ?? null,
|
|
136
|
+
// Creation notes of the retained worktree (submodules, include entries).
|
|
137
|
+
warnings: Array.isArray(menu.retainedWorktree?.warnings) ? [...menu.retainedWorktree.warnings] : [],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
hostedSession,
|
|
143
|
+
ensureSession,
|
|
144
|
+
currentWorkspace,
|
|
145
|
+
getLiveWorkspace,
|
|
146
|
+
sessionProject,
|
|
147
|
+
getBranchMenu,
|
|
148
|
+
};
|
|
149
|
+
}
|