mixdog 1.4.1 → 1.4.3
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 +4 -3
- package/scripts/build-shipped-history.mjs +125 -33
- package/scripts/gate-local.mjs +220 -63
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +139 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +71 -34
- package/scripts/lib/scoped-temp.mjs +1 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +9 -4
- package/scripts/lib/test-spawn-ledger.mjs +43 -3
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/pptx-kit-index.mjs +5 -6
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/scripts/suite-health.mjs +110 -28
- 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/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +38 -2
- package/src/defaults/skills/browser-use/SKILL.md +4 -1
- 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 +12 -2
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +28 -9
- package/src/defaults/skills/setup/references/surfaces.md +5 -2
- package/src/defaults/skills/setup-guide/SKILL.md +11 -3
- 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/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +40 -50
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/rules/lead/LEAD.md +3 -3
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +4 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
- package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
- 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-sse-turn/turn-events/content-block-stop.mjs +3 -3
- 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.mjs +1 -1
- 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/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
- 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.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-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
- 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 +33 -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 +576 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- 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/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- 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 +18 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- 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 +105 -15
- 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 +35 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-port.mjs +19 -10
- package/src/runtime/channels/lib/whisper-server.mjs +22 -13
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
- package/src/runtime/connectors/gmail-app-password.mjs +4 -4
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +88 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +15 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +37 -10
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +14 -8
- package/src/runtime/shared/connector-catalog.mjs +70 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +21 -18
- 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/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/cost.mjs +6 -1
- package/src/runtime/shared/llm/http-agent.mjs +316 -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 +453 -0
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- 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.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-surface.mjs +110 -36
- package/src/runtime/shared/tool-work-units.mjs +35 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
- package/src/runtime/shared/worker-requests.mjs +17 -3
- 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 +5 -3
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +97 -7
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +962 -197
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +9 -5
- 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 +4 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +4 -23
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/agent-task-sessions.mjs +410 -353
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +71 -25
- package/src/session-runtime/bot-status.mjs +103 -103
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/discovery.mjs +245 -47
- package/src/session-runtime/conversation-import/service.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/handoff-attachments.mjs +1 -1
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- 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 +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
- package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- 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 +28 -7
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- 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/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +14 -6
- package/src/session-runtime/services/provider-admin.mjs +281 -10
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
- 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 +14 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +33 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- 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 +128 -1070
- 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 +200 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +8 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon-session-control.mjs +151 -136
- package/src/standalone/daemon.mjs +61 -2
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +21 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +15 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- 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/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/tui/App.jsx +162 -164
- package/src/tui/app/app-view/floating-panel.jsx +3 -0
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +22 -11
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- 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 +25 -6
- package/src/tui/app/provider-setup-picker.mjs +20 -13
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
- package/src/tui/app/slash-commands.mjs +2 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
- 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 +5 -4
- 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 +48 -33
- 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 +20 -6
- 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/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +2205 -1371
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/quota-resume.mjs +1 -1
- 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/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- 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/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -8,24 +8,32 @@ import { createMcpOAuth } from './oauth.mjs';
|
|
|
8
8
|
import { mcpOAuthClientFor, mcpOAuthDisplayName } from './oauth-client.mjs';
|
|
9
9
|
import { googleMcpService, withGoogleMcp } from '../../../connectors/google-mcp.mjs';
|
|
10
10
|
import { gmailAppPasswordService, withGmailAppPasswordMcp } from '../../../connectors/gmail-app-password.mjs';
|
|
11
|
-
import {
|
|
11
|
+
import { withConnectorAccountsMcp } from '../../../connectors/connector-accounts-mcp.mjs';
|
|
12
12
|
import {
|
|
13
|
+
connectorAccountEnabled,
|
|
14
|
+
connectorAccountId,
|
|
13
15
|
connectorAccountsOf,
|
|
14
16
|
connectorLiveAccountServers,
|
|
15
17
|
gmailAppPasswordAccount,
|
|
16
18
|
} from '../../../shared/connector-catalog.mjs';
|
|
17
|
-
import {
|
|
19
|
+
import { runAbortable } from '../../../shared/abort-race.mjs';
|
|
20
|
+
import { isMcpOAuthReauthenticationRequired, storedMcpOAuthIdentity } from './oauth.mjs';
|
|
21
|
+
import { shutdownStdioChild } from './child-tree.mjs';
|
|
22
|
+
import { listAllMcpTools } from './client-handshake.mjs';
|
|
18
23
|
import {
|
|
19
24
|
AUTO_DETECT_PORTS,
|
|
25
|
+
MCP_MAX_TIMER_MS,
|
|
20
26
|
expandEnvVars,
|
|
21
27
|
findMissingMcpEnvVars,
|
|
22
28
|
mcpUrlForLog,
|
|
23
29
|
normalizeMcpTransportUrl,
|
|
24
30
|
resolveMcpHttpHeaders,
|
|
31
|
+
resolveMcpOAuthCredentialKey,
|
|
25
32
|
resolveMcpOAuthUrl,
|
|
26
33
|
resolveMcpStdioEnvironment,
|
|
27
34
|
resolveMcpTransportKind,
|
|
28
35
|
scrubMcpConnectionMessage,
|
|
36
|
+
scrubMcpSecrets,
|
|
29
37
|
} from './client-config.mjs';
|
|
30
38
|
|
|
31
39
|
/**
|
|
@@ -76,57 +84,142 @@ export function hasConfiguredMcpAuth(cfg) {
|
|
|
76
84
|
);
|
|
77
85
|
}
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
// A stdio account (Postgres) runs one process per account config, shared by
|
|
88
|
+
// the connector server of every scope like any stdio server (client.mjs):
|
|
89
|
+
// account config → its connection, which closes with its last holder.
|
|
90
|
+
const sharedAccountConnections = new Map();
|
|
91
|
+
|
|
92
|
+
/** Close one account connection: a stdio child with its whole process tree. */
|
|
93
|
+
async function closeAccountConnection(connection) {
|
|
94
|
+
connection.dead = true;
|
|
95
|
+
if (connection.transport?._process) await shutdownStdioChild(connection.transport).catch(() => {});
|
|
96
|
+
await connection.client.close().catch(() => {});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Whether a call failure is the account server's own JSON-RPC answer: its
|
|
100
|
+
* connection stays. */
|
|
101
|
+
const answeredError = (error) => error?.name === 'McpError' && error.code !== -32000;
|
|
102
|
+
|
|
103
|
+
/** The address a remote account is signed in as, '' when none is known. */
|
|
104
|
+
function signedInAs(accountCfg) {
|
|
87
105
|
try {
|
|
88
|
-
url = resolveMcpOAuthUrl(accountCfg);
|
|
89
|
-
if (hasConfiguredMcpAuth(accountCfg))
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
106
|
+
const url = resolveMcpOAuthUrl(accountCfg);
|
|
107
|
+
if (!url || hasConfiguredMcpAuth(accountCfg)) return '';
|
|
108
|
+
return storedMcpOAuthIdentity(url, resolveMcpOAuthCredentialKey(accountCfg))?.account || '';
|
|
109
|
+
} catch {
|
|
110
|
+
return '';
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** One account of a connector server (connector-catalog.mjs
|
|
115
|
+
* connectorAccountServer) as connector-accounts-mcp.mjs calls it: its own
|
|
116
|
+
* MCP connection through the transport it had as a server of its own — its
|
|
117
|
+
* key header, its app password, its local command, or its own
|
|
118
|
+
* non-interactive OAuth sign-in (refreshed as needed; a new sign-in goes
|
|
119
|
+
* through 계정 바꾸기, never through a tool call). Connected on first use and
|
|
120
|
+
* again after its connection failed. */
|
|
121
|
+
function connectorAccountClient(serverName, accountCfg, { sdk, log, oauthOptions }) {
|
|
122
|
+
const { interactive: _interactive, ...ownOAuth } = oauthOptions || {};
|
|
123
|
+
const address = gmailAppPasswordAccount(accountCfg);
|
|
124
|
+
const shareKey = resolveMcpTransportKind(accountCfg) === 'stdio' ? JSON.stringify(accountCfg) : null;
|
|
125
|
+
const secretsOf = (connection) => connection?.transport?.oauth?.secrets() || [];
|
|
126
|
+
const accountError = (error, connection) => {
|
|
127
|
+
if (isMcpOAuthReauthenticationRequired(error)) {
|
|
128
|
+
return Object.assign(new Error('Sign-in required; sign this account in again in Connectors.'), {
|
|
129
|
+
authRequired: true,
|
|
130
|
+
});
|
|
98
131
|
}
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
close: () => oauth.close(),
|
|
132
|
+
const reason = scrubMcpConnectionMessage(error?.message || String(error), accountCfg, secretsOf(connection));
|
|
133
|
+
return new Error(appendMcpStderrTail(reason, connection?.stderrTail?.() || ''));
|
|
134
|
+
};
|
|
135
|
+
const open = () => {
|
|
136
|
+
const connection = { users: 0, dead: false };
|
|
137
|
+
try {
|
|
138
|
+
const made = createMcpTransport({ name: accountCfg.name, cfg: accountCfg, sdk, log, oauthOptions: ownOAuth });
|
|
139
|
+
connection.transport = made.transport;
|
|
140
|
+
connection.stderrTail = made.stderrTail;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
// A broken account (no sign-in client, an invalid address) stays listed with why.
|
|
143
|
+
connection.dead = true;
|
|
144
|
+
connection.client = { close: async () => {} };
|
|
145
|
+
connection.ready = Promise.reject(error);
|
|
146
|
+
connection.ready.catch(() => {});
|
|
147
|
+
return connection;
|
|
148
|
+
}
|
|
149
|
+
const client = new sdk.Client({ name: `mixdog-agent/${serverName}`, version: '1.0.0' });
|
|
150
|
+
connection.client = client;
|
|
151
|
+
const retire = () => {
|
|
152
|
+
connection.dead = true;
|
|
153
|
+
if (shareKey && sharedAccountConnections.get(shareKey) === connection) sharedAccountConnections.delete(shareKey);
|
|
124
154
|
};
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
155
|
+
client.onclose = retire;
|
|
156
|
+
connection.retire = retire;
|
|
157
|
+
connection.ready = (async () => {
|
|
158
|
+
await client.connect(connection.transport, { timeout: MCP_MAX_TIMER_MS });
|
|
159
|
+
const tools = client.getServerCapabilities()?.tools
|
|
160
|
+
? (await listAllMcpTools(client, { timeout: MCP_MAX_TIMER_MS }))?.tools
|
|
161
|
+
: [];
|
|
162
|
+
if (!Array.isArray(tools)) throw new Error('The account listed its tools in an invalid shape');
|
|
163
|
+
return { instructions: client.getInstructions() || '', tools };
|
|
164
|
+
})();
|
|
165
|
+
connection.ready.catch(() => {
|
|
166
|
+
retire();
|
|
167
|
+
void closeAccountConnection(connection);
|
|
168
|
+
});
|
|
169
|
+
return connection;
|
|
170
|
+
};
|
|
171
|
+
let held = null;
|
|
172
|
+
const release = () => {
|
|
173
|
+
const connection = held;
|
|
174
|
+
held = null;
|
|
175
|
+
if (!connection || --connection.users > 0) return;
|
|
176
|
+
connection.retire?.();
|
|
177
|
+
void closeAccountConnection(connection);
|
|
178
|
+
};
|
|
179
|
+
const acquire = () => {
|
|
180
|
+
if (held && !held.dead) return held;
|
|
181
|
+
release();
|
|
182
|
+
let connection = shareKey ? sharedAccountConnections.get(shareKey) : null;
|
|
183
|
+
if (!connection || connection.dead) {
|
|
184
|
+
connection = open();
|
|
185
|
+
if (shareKey && !connection.dead) sharedAccountConnections.set(shareKey, connection);
|
|
186
|
+
}
|
|
187
|
+
connection.users += 1;
|
|
188
|
+
held = connection;
|
|
189
|
+
return connection;
|
|
190
|
+
};
|
|
191
|
+
return {
|
|
192
|
+
name: accountCfg.name,
|
|
193
|
+
email: address || signedInAs(accountCfg),
|
|
194
|
+
async connect(signal) {
|
|
195
|
+
const connection = acquire();
|
|
196
|
+
try {
|
|
197
|
+
return await runAbortable(signal, () => connection.ready);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
throw accountError(error, connection);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
async callTool(params, { signal, onprogress } = {}) {
|
|
203
|
+
const connection = acquire();
|
|
204
|
+
try {
|
|
205
|
+
await runAbortable(signal, () => connection.ready);
|
|
206
|
+
// The caller's deadline governs (it resets on the progress passed up).
|
|
207
|
+
const result = await connection.client.callTool(params, undefined, {
|
|
208
|
+
signal,
|
|
209
|
+
timeout: MCP_MAX_TIMER_MS,
|
|
210
|
+
...(onprogress ? { onprogress } : {}),
|
|
211
|
+
});
|
|
212
|
+
return scrubMcpSecrets(result, secretsOf(connection));
|
|
213
|
+
} catch (error) {
|
|
214
|
+
const failed = accountError(error, connection);
|
|
215
|
+
if (answeredError(error)) return { content: [{ type: 'text', text: failed.message }], isError: true };
|
|
216
|
+
// A connection a call failed on is opened again for the next call.
|
|
217
|
+
if (!signal?.aborted) connection.retire?.();
|
|
218
|
+
throw failed;
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
close: release,
|
|
222
|
+
};
|
|
130
223
|
}
|
|
131
224
|
|
|
132
225
|
// The SDK's WebSocket transport opens its socket without a way to set request
|
|
@@ -177,13 +270,19 @@ function missingEnvWarnings(name, cfg, strictEnv, log) {
|
|
|
177
270
|
return warnings;
|
|
178
271
|
}
|
|
179
272
|
|
|
180
|
-
// A
|
|
181
|
-
// transport closes every account client.
|
|
182
|
-
function connectorAccountsTransport({ name, cfg, Transport, url, accountServers, oauthOptions, log }) {
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
273
|
+
// A connector server: one server, every account behind it (its account choice
|
|
274
|
+
// on `connectorAccounts`); closing the transport closes every account client.
|
|
275
|
+
function connectorAccountsTransport({ name, cfg, Transport, url, accountServers, sdk, oauthOptions, log }) {
|
|
276
|
+
// `accountServers` are the switched-on stored accounts, in order.
|
|
277
|
+
const stored = connectorAccountsOf(cfg).filter(connectorAccountEnabled);
|
|
278
|
+
const accounts = accountServers.map((accountCfg, index) => {
|
|
279
|
+
const account = connectorAccountClient(name, accountCfg, { sdk, log, oauthOptions });
|
|
280
|
+
account.id = connectorAccountId(cfg, stored[index]);
|
|
281
|
+
return account;
|
|
186
282
|
});
|
|
283
|
+
const fetchImpl = withConnectorAccountsMcp({ connector: cfg.connector, accounts });
|
|
284
|
+
const transport = new Transport(new URL(url), { fetch: fetchImpl });
|
|
285
|
+
transport.connectorAccounts = fetchImpl.connectorAccounts;
|
|
187
286
|
const close = transport.close.bind(transport);
|
|
188
287
|
transport.close = async () => {
|
|
189
288
|
for (const account of accounts) account.close();
|
|
@@ -204,6 +303,7 @@ function remoteHttpTransport({ name, cfg, kind, Transport, url, oauthOptions, lo
|
|
|
204
303
|
if (!hasConfiguredMcpAuth(cfg)) {
|
|
205
304
|
oauth = createMcpOAuth({
|
|
206
305
|
url,
|
|
306
|
+
credentialKey: resolveMcpOAuthCredentialKey(cfg),
|
|
207
307
|
serverName: mcpOAuthDisplayName(cfg, name),
|
|
208
308
|
oauthClient: mcpOAuthClientFor(cfg, url),
|
|
209
309
|
...oauthOptions,
|
|
@@ -291,7 +391,7 @@ export function createMcpTransport({ name, cfg, sdk, log, strictEnv, oauthOption
|
|
|
291
391
|
throw new Error(`Every account of "${name}" is disabled`);
|
|
292
392
|
}
|
|
293
393
|
const transport = accountServers.length
|
|
294
|
-
? connectorAccountsTransport({ name, cfg, Transport, url, accountServers, oauthOptions, log })
|
|
394
|
+
? connectorAccountsTransport({ name, cfg, Transport, url, accountServers, sdk, oauthOptions, log })
|
|
295
395
|
: remoteHttpTransport({ name, cfg, kind, Transport, url, oauthOptions, log });
|
|
296
396
|
return { transport, autoDetectAdvert: null, stderrTail: noStderrTail, warnings };
|
|
297
397
|
}
|
|
@@ -25,6 +25,7 @@ import { currentToolExecutionOwner } from '../../../shared/tool-execution-owner.
|
|
|
25
25
|
import { positiveInt } from '../../../shared/numbers.mjs';
|
|
26
26
|
import {
|
|
27
27
|
providerSafeMcpToolName,
|
|
28
|
+
resolveMcpOAuthCredentialKey,
|
|
28
29
|
resolveMcpOAuthUrl,
|
|
29
30
|
resolveMcpRequestTimeouts,
|
|
30
31
|
resolveMcpTransportKind,
|
|
@@ -39,6 +40,7 @@ import { mcpOAuthClientFor, mcpOAuthDisplayName } from './oauth-client.mjs';
|
|
|
39
40
|
import { googleMcpService, withGoogleMcp } from '../../../connectors/google-mcp.mjs';
|
|
40
41
|
import { gmailAppPasswordService } from '../../../connectors/gmail-app-password.mjs';
|
|
41
42
|
import { connectorLiveAccountServers } from '../../../shared/connector-catalog.mjs';
|
|
43
|
+
import { CONVERSATION_META } from '../../../connectors/connector-accounts-mcp.mjs';
|
|
42
44
|
import {
|
|
43
45
|
clearMcpOAuth,
|
|
44
46
|
commitMcpOAuthSwitch,
|
|
@@ -52,8 +54,9 @@ import {
|
|
|
52
54
|
export { probeMcpServerAuth } from './oauth-probe.mjs';
|
|
53
55
|
|
|
54
56
|
// Config interpretation (transport kind, URL policy, env expansion, headers,
|
|
55
|
-
// timeouts, log scrubbing) lives in client-config.mjs;
|
|
56
|
-
//
|
|
57
|
+
// timeouts, log scrubbing) lives in client-config.mjs; the names importers
|
|
58
|
+
// use (including through namespace loads such as boot.mcpClient) are
|
|
59
|
+
// re-exported here.
|
|
57
60
|
export {
|
|
58
61
|
normalizeMcpTransportUrl,
|
|
59
62
|
mcpUrlForLog,
|
|
@@ -62,9 +65,6 @@ export {
|
|
|
62
65
|
resolveMcpHttpHeaders,
|
|
63
66
|
resolveMcpTransportKind,
|
|
64
67
|
resolveMcpStartupTimeoutMs,
|
|
65
|
-
resolveMcpCallTimeoutMs,
|
|
66
|
-
resolveMcpMaxTotalTimeoutMs,
|
|
67
|
-
resolveMcpRequestTimeouts,
|
|
68
68
|
} from './client-config.mjs';
|
|
69
69
|
const servers = new Map();
|
|
70
70
|
const reconnects = createKeyedSingleflight();
|
|
@@ -503,10 +503,15 @@ export async function executeMcpTool(name, args, options = {}) {
|
|
|
503
503
|
const serverName = server.name;
|
|
504
504
|
const toolName = definition?.mcpToolName || match[2];
|
|
505
505
|
const callSignal = options?.signal || null;
|
|
506
|
+
// A connector server's call names the conversation it is made in: its
|
|
507
|
+
// account default, and the account it makes the last used.
|
|
508
|
+
const conversation = String(options?.conversation || '').trim();
|
|
509
|
+
const metaFor = (target) =>
|
|
510
|
+
conversation && target.transport?.connectorAccounts ? { [CONVERSATION_META]: conversation } : undefined;
|
|
506
511
|
const dispatch = (target) =>
|
|
507
512
|
definition?.mcpOperation
|
|
508
513
|
? _callMcpFeatureWithTimeout(target, definition.mcpOperation, args, callSignal)
|
|
509
|
-
: _callToolWithTimeout(target, toolName, args, callSignal);
|
|
514
|
+
: _callToolWithTimeout(target, toolName, args, callSignal, metaFor(target));
|
|
510
515
|
let retryServer = null;
|
|
511
516
|
const secrets = () => oauthSecrets(server.transport, retryServer?.transport);
|
|
512
517
|
const gate = callAdmissionFor(server);
|
|
@@ -999,7 +1004,7 @@ export function raceMcpAbort(promise, signal, message) {
|
|
|
999
1004
|
});
|
|
1000
1005
|
}
|
|
1001
1006
|
|
|
1002
|
-
async function _callToolWithTimeout(server, toolName, args, signal = null) {
|
|
1007
|
+
async function _callToolWithTimeout(server, toolName, args, signal = null, meta = undefined) {
|
|
1003
1008
|
// The request's signal goes INTO the SDK: an aborted caller (or our own
|
|
1004
1009
|
// timeout) cancels the live JSON-RPC request (notifications/cancelled)
|
|
1005
1010
|
// instead of merely walking away from it. The abort race additionally frees
|
|
@@ -1008,7 +1013,8 @@ async function _callToolWithTimeout(server, toolName, args, signal = null) {
|
|
|
1008
1013
|
return runMcpRequest(
|
|
1009
1014
|
server,
|
|
1010
1015
|
signal,
|
|
1011
|
-
(options) =>
|
|
1016
|
+
(options) =>
|
|
1017
|
+
server.client.callTool({ name: toolName, arguments: args, ...(meta ? { _meta: meta } : {}) }, undefined, options),
|
|
1012
1018
|
{
|
|
1013
1019
|
abortMessage: `MCP tool call aborted (server="${server?.name}", tool="${toolName}")`,
|
|
1014
1020
|
timeoutMessage: (ms) =>
|
|
@@ -1119,6 +1125,24 @@ export function isMcpTool(name) {
|
|
|
1119
1125
|
export function isRegisteredMcpTool(name, scopeId = DEFAULT_MCP_SCOPE_ID) {
|
|
1120
1126
|
return Boolean(resolveMcpToolTarget(scopeId, name)?.definition);
|
|
1121
1127
|
}
|
|
1128
|
+
/**
|
|
1129
|
+
* The account (`{ name, label }`: its unique name, which binds a call to it,
|
|
1130
|
+
* and what it is shown as) a call of the prefixed tool `name` with `args`
|
|
1131
|
+
* would use on its connector server, made in `conversation`
|
|
1132
|
+
* (connectors/connector-accounts-mcp.mjs): the one `args.account` names, else
|
|
1133
|
+
* the one used last. Null when the tool's server holds no accounts. Throws the
|
|
1134
|
+
* refusal (usable accounts listed) when that account cannot be used.
|
|
1135
|
+
*/
|
|
1136
|
+
export function resolveMcpToolAccount(name, args, { scopeId = DEFAULT_MCP_SCOPE_ID, conversation = '' } = {}) {
|
|
1137
|
+
const target = resolveMcpToolTarget(normalizeMcpScopeId(scopeId), name);
|
|
1138
|
+
const accounts = target?.server?.transport?.connectorAccounts;
|
|
1139
|
+
if (!accounts || target.definition?.mcpOperation) return null;
|
|
1140
|
+
return accounts.choose({
|
|
1141
|
+
tool: target.definition?.mcpToolName || MCP_TOOL_NAME_RE.exec(name)?.[2],
|
|
1142
|
+
wanted: args?.account,
|
|
1143
|
+
conversation: String(conversation || '').trim(),
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1122
1146
|
/** True when the prefixed name is `read_email` of a server whose every
|
|
1123
1147
|
* endpoint Mixdog answers in-process (the Gmail app-password connector,
|
|
1124
1148
|
* alone or behind the multi-account server): its result is a mail as the
|
|
@@ -1272,18 +1296,19 @@ export function isMcpLoginPending(name, options = {}) {
|
|
|
1272
1296
|
* for servers that never use MCP OAuth.
|
|
1273
1297
|
*/
|
|
1274
1298
|
export function getMcpServerOAuthState(cfg) {
|
|
1275
|
-
let
|
|
1299
|
+
let key;
|
|
1276
1300
|
try {
|
|
1277
|
-
|
|
1301
|
+
key = resolveMcpOAuthCredentialKey(cfg);
|
|
1278
1302
|
} catch {
|
|
1279
1303
|
return null;
|
|
1280
1304
|
}
|
|
1281
|
-
if (!
|
|
1282
|
-
const
|
|
1305
|
+
if (!key || hasConfiguredMcpAuth(cfg)) return null;
|
|
1306
|
+
const url = resolveMcpOAuthUrl(cfg);
|
|
1307
|
+
const signedIn = hasStoredMcpOAuthTokens(url, key);
|
|
1283
1308
|
if (!signedIn) return { signedIn };
|
|
1284
1309
|
// Who it is signed in as (never guessed: empty when the server named nobody)
|
|
1285
1310
|
// and whether 계정 바꾸기 can make the provider show its account choice.
|
|
1286
|
-
const who = storedMcpOAuthIdentity(url);
|
|
1311
|
+
const who = storedMcpOAuthIdentity(url, key);
|
|
1287
1312
|
return {
|
|
1288
1313
|
signedIn,
|
|
1289
1314
|
account: typeof who?.account === 'string' ? who.account : '',
|
|
@@ -1298,32 +1323,38 @@ export function startMcpServerOAuthSwitch(cfg, launch, serverName) {
|
|
|
1298
1323
|
if (!url) throw new Error(`MCP server "${serverName}" does not use OAuth sign-in`);
|
|
1299
1324
|
return startMcpOAuthSwitch({
|
|
1300
1325
|
url,
|
|
1326
|
+
credentialKey: resolveMcpOAuthCredentialKey(cfg),
|
|
1301
1327
|
launch,
|
|
1302
1328
|
serverName: mcpOAuthDisplayName(cfg, serverName),
|
|
1303
1329
|
oauthClient: mcpOAuthClientFor(cfg, url),
|
|
1304
1330
|
...(googleMcpService(url) ? { fetchImpl: withGoogleMcp() } : {}),
|
|
1305
1331
|
});
|
|
1306
1332
|
}
|
|
1307
|
-
/** Store a switch's sign-in
|
|
1333
|
+
/** Store a switch's sign-in as the server's (its URL's, or its own key's);
|
|
1334
|
+
* resolves its rollback. */
|
|
1308
1335
|
export function commitMcpServerOAuthSwitch(cfg, signIn) {
|
|
1309
|
-
return commitMcpOAuthSwitch({
|
|
1336
|
+
return commitMcpOAuthSwitch({
|
|
1337
|
+
url: resolveMcpOAuthUrl(cfg),
|
|
1338
|
+
credentialKey: resolveMcpOAuthCredentialKey(cfg),
|
|
1339
|
+
signIn,
|
|
1340
|
+
});
|
|
1310
1341
|
}
|
|
1311
1342
|
/**
|
|
1312
|
-
* Log out of an HTTP/SSE server
|
|
1313
|
-
* registration stored for it
|
|
1314
|
-
* exact URL, and drop them from live
|
|
1315
|
-
* revokes the grant where the
|
|
1316
|
-
* `{ revoked }`.
|
|
1343
|
+
* Log out of an HTTP/SSE server: delete the OAuth tokens and client
|
|
1344
|
+
* registration stored for it (shared by every server configured with that
|
|
1345
|
+
* exact URL, unless it has its own credential key), and drop them from live
|
|
1346
|
+
* connections. `options.revoke` also revokes the grant where the
|
|
1347
|
+
* authorization server documents how; resolves `{ revoked }`.
|
|
1317
1348
|
*/
|
|
1318
1349
|
export async function clearMcpServerOAuth(cfg, options = {}) {
|
|
1319
|
-
let
|
|
1350
|
+
let key;
|
|
1320
1351
|
try {
|
|
1321
|
-
|
|
1352
|
+
key = resolveMcpOAuthCredentialKey(cfg);
|
|
1322
1353
|
} catch {
|
|
1323
1354
|
// A config without a valid remote URL never connected, so never logged in.
|
|
1324
1355
|
return { revoked: false };
|
|
1325
1356
|
}
|
|
1326
|
-
if (
|
|
1357
|
+
if (key) return clearMcpOAuth({ url: resolveMcpOAuthUrl(cfg), credentialKey: key, revoke: options.revoke === true });
|
|
1327
1358
|
return { revoked: false };
|
|
1328
1359
|
}
|
|
1329
1360
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// - else the catalog connector's (connector-catalog.mjs `oauthClient`), with
|
|
7
7
|
// its scopes and the provider's offline-access parameter.
|
|
8
8
|
import { createHash } from 'node:crypto';
|
|
9
|
-
import keychain from '
|
|
9
|
+
import { keychainSecretStore as keychain } from '../../../shared/config.mjs';
|
|
10
10
|
import { connectorById, connectorOfServer, gmailAppPasswordAccount } from '../../../shared/connector-catalog.mjs';
|
|
11
11
|
import { GOOGLE_AUTH_PARAMS, googleOAuthClient } from '../../../shared/google-oauth-client.mjs';
|
|
12
12
|
import { normalizeMcpTransportUrl } from './client-config.mjs';
|
|
@@ -145,11 +145,16 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
145
145
|
}
|
|
146
146
|
exists = Boolean(saved);
|
|
147
147
|
}
|
|
148
|
+
const signedIn = Boolean(creds.tokens);
|
|
148
149
|
change();
|
|
149
150
|
hold();
|
|
151
|
+
// Other processes follow a refresh through the revision marker; only a
|
|
152
|
+
// sign-in or sign-out is announced as a settings change (it may let a
|
|
153
|
+
// server that needed sign-in connect, or end its connection).
|
|
154
|
+
const announce = remove ? signedIn : Boolean(creds.tokens) !== signedIn;
|
|
150
155
|
if (remove) {
|
|
151
156
|
await writeRevisionMarker(account, null);
|
|
152
|
-
if (exists) await credentialStore.deleteSecretAsync(account);
|
|
157
|
+
if (exists) await credentialStore.deleteSecretAsync(account, { announce });
|
|
153
158
|
await writeIdentityFile(account, null);
|
|
154
159
|
creds.observed = null;
|
|
155
160
|
} else {
|
|
@@ -158,7 +163,8 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
158
163
|
const { tokens, clientInformation, redirectUrl, discovery, identity } = creds;
|
|
159
164
|
await credentialStore.setSecretAsync(
|
|
160
165
|
account,
|
|
161
|
-
JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity })
|
|
166
|
+
JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity }),
|
|
167
|
+
{ announce }
|
|
162
168
|
);
|
|
163
169
|
await writeIdentityFile(account, creds);
|
|
164
170
|
creds.observed = revision;
|
|
@@ -6,6 +6,72 @@ import { identityFromTokenResponse } from './oauth-account.mjs';
|
|
|
6
6
|
import { answerOAuthCallback } from './oauth-callback.mjs';
|
|
7
7
|
import { anySignal, loginFailed, reauthenticationRequired, scopeNotGranted } from './oauth-shared.mjs';
|
|
8
8
|
|
|
9
|
+
// Fetch for the SDK: transport-URL normalized, no redirects, bounded by the
|
|
10
|
+
// login `signal`. The token endpoint's answer is read for who the tokens
|
|
11
|
+
// belong to (oauth-account.mjs): the SDK keeps only the token fields.
|
|
12
|
+
function makeSafeFetch({ fetchImpl, flow, signal }) {
|
|
13
|
+
return async (input, init = {}) => {
|
|
14
|
+
const response = await fetchImpl(normalizeMcpTransportUrl(input), {
|
|
15
|
+
...init,
|
|
16
|
+
redirect: 'error',
|
|
17
|
+
signal: anySignal(signal, init.signal),
|
|
18
|
+
});
|
|
19
|
+
if (response.ok && /(^|&)grant_type=/.test(String(init.body ?? ''))) {
|
|
20
|
+
flow.identity = identityFromTokenResponse(
|
|
21
|
+
await response
|
|
22
|
+
.clone()
|
|
23
|
+
.json()
|
|
24
|
+
.catch(() => null)
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return response;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The caller's progress hooks (mcp-oauth-login.mjs): the callback arrived,
|
|
32
|
+
// then the tokens are stored.
|
|
33
|
+
function reportProgress(browser, hook) {
|
|
34
|
+
try {
|
|
35
|
+
browser?.[hook]?.();
|
|
36
|
+
} catch {
|
|
37
|
+
/* progress reporting never fails the login */
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// The callback promise of one login, and the browser page held open for the
|
|
42
|
+
// loopback callback until the code exchange and scope check end: `settle()` is
|
|
43
|
+
// success, `settle({ code })` a failure. Bounded by `signal`, like the
|
|
44
|
+
// exchange itself. `setFlushing` receives each answered page's flush.
|
|
45
|
+
function awaitCallback({ flow, signal, stopListening, setFlushing }) {
|
|
46
|
+
let abort;
|
|
47
|
+
let respond;
|
|
48
|
+
const settle = (failure) => {
|
|
49
|
+
const answer = respond;
|
|
50
|
+
respond = undefined;
|
|
51
|
+
if (!answer) return undefined;
|
|
52
|
+
const flushed = answer(failure);
|
|
53
|
+
setFlushing(flushed);
|
|
54
|
+
return flushed;
|
|
55
|
+
};
|
|
56
|
+
const callback = new Promise((resolve, reject) => {
|
|
57
|
+
const finish = (code, page) => {
|
|
58
|
+
if (page) respond = page;
|
|
59
|
+
return code ? resolve(code) : reject(loginFailed());
|
|
60
|
+
};
|
|
61
|
+
flow.finishCallback = finish;
|
|
62
|
+
// Timeout, cancel or abort: the held page gets the generic failure now
|
|
63
|
+
// (the exchange or a credential write may be stalled past the deadline),
|
|
64
|
+
// and the listener closes once it is flushed.
|
|
65
|
+
abort = () => {
|
|
66
|
+
finish();
|
|
67
|
+
settle({});
|
|
68
|
+
stopListening();
|
|
69
|
+
};
|
|
70
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
71
|
+
});
|
|
72
|
+
return { callback, settle, abort };
|
|
73
|
+
}
|
|
74
|
+
|
|
9
75
|
/**
|
|
10
76
|
* The browser login of one connection over its credential `cache` and login
|
|
11
77
|
* `flow` state: the loopback callback listener and the SDK authorization
|
|
@@ -65,61 +131,19 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
65
131
|
// the token fields, so the token endpoint's answer is read here.
|
|
66
132
|
flow.identity = undefined;
|
|
67
133
|
flow.signal = signal;
|
|
68
|
-
const safeFetch =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.clone()
|
|
78
|
-
.json()
|
|
79
|
-
.catch(() => null)
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
return response;
|
|
83
|
-
};
|
|
84
|
-
// The caller's progress hooks (mcp-oauth-login.mjs): the callback arrived,
|
|
85
|
-
// then the tokens are stored.
|
|
86
|
-
const progress = (hook) => {
|
|
87
|
-
try {
|
|
88
|
-
browser?.[hook]?.();
|
|
89
|
-
} catch {
|
|
90
|
-
/* progress reporting never fails the login */
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
let abort;
|
|
94
|
-
// The browser page held open for the loopback callback until the code
|
|
95
|
-
// exchange and scope check end: `settle()` is success, `settle({ code })`
|
|
96
|
-
// a failure. Bounded by `signal`, like the exchange itself.
|
|
97
|
-
let respond;
|
|
98
|
-
const settle = (failure) => {
|
|
99
|
-
const answer = respond;
|
|
100
|
-
respond = undefined;
|
|
101
|
-
if (!answer) return undefined;
|
|
102
|
-
flushing = answer(failure);
|
|
103
|
-
return flushing;
|
|
104
|
-
};
|
|
105
|
-
const callback = new Promise((resolve, reject) => {
|
|
106
|
-
const finish = (code, page) => {
|
|
107
|
-
if (page) respond = page;
|
|
108
|
-
return code ? resolve(code) : reject(loginFailed());
|
|
109
|
-
};
|
|
110
|
-
flow.finishCallback = finish;
|
|
111
|
-
// Timeout, cancel or abort: the held page gets the generic failure now
|
|
112
|
-
// (the exchange or a credential write may be stalled past the deadline),
|
|
113
|
-
// and the listener closes once it is flushed.
|
|
114
|
-
abort = () => {
|
|
115
|
-
finish();
|
|
116
|
-
settle({});
|
|
117
|
-
stopListening();
|
|
118
|
-
};
|
|
119
|
-
signal.addEventListener('abort', abort, { once: true });
|
|
134
|
+
const safeFetch = makeSafeFetch({ fetchImpl, flow, signal });
|
|
135
|
+
const progress = (hook) => reportProgress(browser, hook);
|
|
136
|
+
const { callback, settle, abort } = awaitCallback({
|
|
137
|
+
flow,
|
|
138
|
+
signal,
|
|
139
|
+
stopListening,
|
|
140
|
+
setFlushing: (page) => {
|
|
141
|
+
flushing = page;
|
|
142
|
+
},
|
|
120
143
|
});
|
|
121
144
|
// A discovery/registration error can precede waiting for the callback.
|
|
122
145
|
callback.catch(() => {});
|
|
146
|
+
let codeReceived = false;
|
|
123
147
|
try {
|
|
124
148
|
signal.throwIfAborted();
|
|
125
149
|
const { auth } = await import('@modelcontextprotocol/sdk/client/auth.js');
|
|
@@ -141,6 +165,7 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
141
165
|
});
|
|
142
166
|
if (result === 'REDIRECT') {
|
|
143
167
|
const code = await callback;
|
|
168
|
+
codeReceived = true;
|
|
144
169
|
signal.throwIfAborted();
|
|
145
170
|
progress('onCallback');
|
|
146
171
|
const exchanged = await cache.withLock(async () => {
|
|
@@ -157,6 +182,12 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
157
182
|
await settle();
|
|
158
183
|
} catch (error) {
|
|
159
184
|
await settle({ code: error?.code });
|
|
185
|
+
// An authorization server that no longer knows our client_id answers the
|
|
186
|
+
// browser with an HTTP error, never a redirect or a token-endpoint
|
|
187
|
+
// invalid_client, so the SDK cannot see it: register again next time.
|
|
188
|
+
if (interactive && flow.browserOpened && !codeReceived && !provider.preRegistered) {
|
|
189
|
+
await provider.invalidateCredentials('client').catch(() => {});
|
|
190
|
+
}
|
|
160
191
|
// SDK errors may contain authorization server response bodies/secrets.
|
|
161
192
|
if (error?.code === 'reauthenticationRequired' || !interactive) throw reauthenticationRequired();
|
|
162
193
|
// Our own error names scopes only (no token data): the one to pass on.
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from './client-config.mjs';
|
|
13
13
|
import { hasConfiguredMcpAuth } from './client-transport.mjs';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
const MCP_AUTH_PROBE_TIMEOUT_MS = 10_000;
|
|
16
16
|
|
|
17
17
|
const INITIALIZE_PROBE = JSON.stringify({
|
|
18
18
|
jsonrpc: '2.0',
|