mixdog 1.3.5 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -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 +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- 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 +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- 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-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- 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 +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- 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 +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- 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 +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- 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 +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- 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/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- 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/shell-runtime.mjs +7 -1
- 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/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- 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/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- 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/lib/embedding-worker.mjs +6 -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/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- 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 +3 -1
- 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/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- 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-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- 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/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- 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 +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- 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 +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- 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/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- 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/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -304,6 +304,31 @@ export function skillOutsideScopeError(name) {
|
|
|
304
304
|
return `Error: skill "${name}" is not available in this project (its project scope excludes the current folder)`;
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
/** Why the Skill tool refuses `name` at `cwd` now (missing feature, switched
|
|
308
|
+
* off, outside the project scope), or null when nothing refuses it. `config`
|
|
309
|
+
* and `skills` let a batch of checks share one config read and one scan. */
|
|
310
|
+
export function skillLoadRefusal(name, cwd, config = null, skills = null) {
|
|
311
|
+
const missing = skillMissingFeature(name, config, skills);
|
|
312
|
+
if (missing) {
|
|
313
|
+
return `Error: skill "${name}" needs the ${missing} built-in feature, which is not installed or is switched off in Extensions → Plugin → Built-in`;
|
|
314
|
+
}
|
|
315
|
+
if (isSkillDisabled(name, config, skills)) return `Error: skill "${name}" is disabled`;
|
|
316
|
+
if (skillOutsideScope(name, cwd, config, skills)) return skillOutsideScopeError(name);
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* What the Skill tool would deliver for `name` at `cwd` now: the injected
|
|
322
|
+
* `<skill>` body and the resource it came from, or null when the skill no
|
|
323
|
+
* longer loads there (refused by skillLoadRefusal, or removed).
|
|
324
|
+
*/
|
|
325
|
+
export function currentSkillDelivery(name, cwd, config = null, skills = null) {
|
|
326
|
+
if (skillLoadRefusal(name, cwd, config, skills)) return null;
|
|
327
|
+
const resource = loadSkillResource(name, cwd);
|
|
328
|
+
if (!resource) return null;
|
|
329
|
+
return { body: buildSkillResultEnvelope(name, resource.content, resource.dir), resource };
|
|
330
|
+
}
|
|
331
|
+
|
|
307
332
|
/**
|
|
308
333
|
* Skills a session may see: not switched off, feature available, and — when
|
|
309
334
|
* `cwd` is given — inside the skill's (or its plugin's) project scope. Without
|
|
@@ -348,11 +373,16 @@ const _skillsCache = new Map();
|
|
|
348
373
|
// every plain-file gate path are stat'ed on every call as before.
|
|
349
374
|
const _ROOT_WATCH_LIMIT = 64;
|
|
350
375
|
const _rootWatches = new Map(); // root -> { watcher, dirty, text, settled }
|
|
376
|
+
// Bumped by every closed root watch; part of each cached SKILL.md text stamp.
|
|
377
|
+
let _skillTextGeneration = 0;
|
|
351
378
|
|
|
352
379
|
function _closeRootWatch(root) {
|
|
353
380
|
const watch = _rootWatches.get(root);
|
|
354
381
|
if (!watch) return;
|
|
355
382
|
_rootWatches.delete(root);
|
|
383
|
+
// Any change under a skill root (or a lost watcher, or an invalidation)
|
|
384
|
+
// makes the next load re-read SKILL.md text, whatever the file stamps say.
|
|
385
|
+
_skillTextGeneration += 1;
|
|
356
386
|
try {
|
|
357
387
|
watch.watcher.close();
|
|
358
388
|
} catch {
|
|
@@ -452,6 +482,26 @@ export function skillExecutionDir(dir, source) {
|
|
|
452
482
|
return String(dir).replace(/([\\/])runtime\.asar(?=[\\/]|$)/, '$1runtime.asar.unpacked');
|
|
453
483
|
}
|
|
454
484
|
|
|
485
|
+
// SKILL.md text per catalog entry, with the stamp it was read at: the
|
|
486
|
+
// file's own mtime and size (any depth) plus the skills watcher generation
|
|
487
|
+
// (an edit that keeps both, e.g. inside one timestamp tick).
|
|
488
|
+
const _skillFileText = new WeakMap();
|
|
489
|
+
|
|
490
|
+
function skillFileText(skill) {
|
|
491
|
+
let stamp;
|
|
492
|
+
try {
|
|
493
|
+
const stat = statSync(skill.filePath);
|
|
494
|
+
stamp = `${_skillTextGeneration}:${stat.mtimeMs}:${stat.size}`;
|
|
495
|
+
} catch {
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
const cached = _skillFileText.get(skill);
|
|
499
|
+
if (cached?.stamp === stamp) return cached.text;
|
|
500
|
+
const text = readSafe(skill.filePath);
|
|
501
|
+
_skillFileText.set(skill, { stamp, text });
|
|
502
|
+
return text;
|
|
503
|
+
}
|
|
504
|
+
|
|
455
505
|
/**
|
|
456
506
|
* Load full skill content plus its on-disk directory (for base-dir + ${MIXDOG_SKILL_DIR};
|
|
457
507
|
* ${MIXDOG_SKILL_NODE} is resolved at render time in buildSkillResultEnvelope).
|
|
@@ -462,7 +512,10 @@ export function loadSkillResource(name, cwd) {
|
|
|
462
512
|
const skills = collectSkillsCached(cwd);
|
|
463
513
|
const skill = skills.find((s) => s.name === skillName);
|
|
464
514
|
if (!skill) return null;
|
|
465
|
-
|
|
515
|
+
// The catalog's freshness signature does not see every nested SKILL.md, so
|
|
516
|
+
// the text follows the file itself: one stat per load, re-read only when
|
|
517
|
+
// that file's own mtime or size moved.
|
|
518
|
+
const content = skillFileText(skill);
|
|
466
519
|
if (content == null) return null;
|
|
467
520
|
try {
|
|
468
521
|
return {
|
|
@@ -616,7 +669,9 @@ export function buildSkillManifest(skills, { limit = 80, charBudget = SKILL_MANI
|
|
|
616
669
|
for (const skill of visible) skill.trigger = compactPromptManifestText(skill.trigger, triggerCap);
|
|
617
670
|
const lines = [
|
|
618
671
|
'# available-skills',
|
|
619
|
-
|
|
672
|
+
visible.some((skill) => skill.linkedTools.some((tool) => tool.startsWith('mcp:')))
|
|
673
|
+
? 'Selection triggers and linked tools. mcp:<server> denotes that server’s tools.'
|
|
674
|
+
: 'Selection triggers and linked tools.',
|
|
620
675
|
'<available_skills>',
|
|
621
676
|
...visible.map(
|
|
622
677
|
(skill) => (skill.trigger ? `- ${skill.name}: ${skill.trigger}` : `- ${skill.name}`) + toolSuffix(skill)
|
|
@@ -203,7 +203,7 @@ export function readProjectConnectorsFile(path) {
|
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
function projectConnectorPolicies(dataDir = resolvePluginData()) {
|
|
207
207
|
return cachedRead(join(dataDir, PROJECT_CONNECTORS_FILE), readProjectConnectorsFile);
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -219,7 +219,7 @@ export function connectorToolPermission(policy, toolOrName) {
|
|
|
219
219
|
return policy?.tools?.[mcp.server]?.[mcp.tool] || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
222
|
+
export const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
223
223
|
export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do without asking; make it on the desktop.';
|
|
224
224
|
|
|
225
225
|
/** Whether replacing the stored policy `before` (a stored value, a parsed
|
|
@@ -229,7 +229,7 @@ export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do wit
|
|
|
229
229
|
* default, which is `needs_approval` for a catalog connector's high-risk
|
|
230
230
|
* tools and `auto` otherwise). A legacy allow list or an unreadable policy is
|
|
231
231
|
* not compared: it counts as widening. */
|
|
232
|
-
|
|
232
|
+
function connectorPolicyWidens(before, after) {
|
|
233
233
|
let old;
|
|
234
234
|
try {
|
|
235
235
|
old = before == null ? { off: [], tools: {} } : parseConnectorPolicy(before);
|
|
@@ -8,6 +8,13 @@ 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 { connectorAccountRequest, withConnectorAccountsMcp } from '../../../connectors/connector-accounts-mcp.mjs';
|
|
12
|
+
import {
|
|
13
|
+
connectorAccountsOf,
|
|
14
|
+
connectorLiveAccountServers,
|
|
15
|
+
gmailAppPasswordAccount,
|
|
16
|
+
} from '../../../shared/connector-catalog.mjs';
|
|
17
|
+
import { isMcpOAuthReauthenticationRequired } from './oauth.mjs';
|
|
11
18
|
import {
|
|
12
19
|
AUTO_DETECT_PORTS,
|
|
13
20
|
expandEnvVars,
|
|
@@ -63,10 +70,65 @@ export function hasConfiguredMcpAuth(cfg) {
|
|
|
63
70
|
return (
|
|
64
71
|
Boolean(String(cfg.bearer_token_env_var || '').trim()) ||
|
|
65
72
|
configured(cfg.headers) ||
|
|
66
|
-
configured(cfg.env_http_headers)
|
|
73
|
+
configured(cfg.env_http_headers) ||
|
|
74
|
+
// A multi-account connector's server: each account authenticates itself.
|
|
75
|
+
connectorAccountsOf(cfg).length > 0
|
|
67
76
|
);
|
|
68
77
|
}
|
|
69
78
|
|
|
79
|
+
/** One account of a multi-account connector server (connector-catalog.mjs
|
|
80
|
+
* connectorAccountServer) as connector-accounts-mcp.mjs calls it: through
|
|
81
|
+
* the transport the account had as a server of its own — its app-password
|
|
82
|
+
* header, or its own non-interactive OAuth sign-in (refreshed as needed; a
|
|
83
|
+
* new sign-in goes through 계정 바꾸기, never through a tool call). */
|
|
84
|
+
function connectorAccountClient(serverName, accountCfg, oauthOptions) {
|
|
85
|
+
const base = { name: accountCfg.name, email: '', appPassword: false, close() {} };
|
|
86
|
+
let url;
|
|
87
|
+
try {
|
|
88
|
+
url = resolveMcpOAuthUrl(accountCfg);
|
|
89
|
+
if (hasConfiguredMcpAuth(accountCfg)) {
|
|
90
|
+
const email = gmailAppPasswordAccount(accountCfg);
|
|
91
|
+
const fetchImpl = gmailAppPasswordService(url) ? withGmailAppPasswordMcp() : fetch;
|
|
92
|
+
return {
|
|
93
|
+
...base,
|
|
94
|
+
email,
|
|
95
|
+
appPassword: Boolean(email),
|
|
96
|
+
request: connectorAccountRequest(url, fetchImpl, resolveMcpHttpHeaders(accountCfg)),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const oauth = createMcpOAuth({
|
|
100
|
+
url,
|
|
101
|
+
serverName: mcpOAuthDisplayName(accountCfg, serverName),
|
|
102
|
+
oauthClient: mcpOAuthClientFor(accountCfg, url),
|
|
103
|
+
...(oauthOptions?.fetchImpl ? { fetchImpl: oauthOptions.fetchImpl } : {}),
|
|
104
|
+
...(googleMcpService(url) ? { fetchImpl: withGoogleMcp(oauthOptions?.fetchImpl) } : {}),
|
|
105
|
+
});
|
|
106
|
+
const send = connectorAccountRequest(url, (input, init) => oauth.fetch(input, init));
|
|
107
|
+
return {
|
|
108
|
+
...base,
|
|
109
|
+
async request(message, options) {
|
|
110
|
+
try {
|
|
111
|
+
return await send(message, options);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
const reason = scrubMcpConnectionMessage(error?.message || String(error), accountCfg);
|
|
114
|
+
const scrubbed = new Error(
|
|
115
|
+
isMcpOAuthReauthenticationRequired(error)
|
|
116
|
+
? 'Sign-in required; sign this account in again in Connectors.'
|
|
117
|
+
: reason
|
|
118
|
+
);
|
|
119
|
+
if (isMcpOAuthReauthenticationRequired(error)) scrubbed.authRequired = true;
|
|
120
|
+
throw scrubbed;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
close: () => oauth.close(),
|
|
124
|
+
};
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// A broken account (no sign-in client, an invalid address) stays listed with why.
|
|
127
|
+
const failed = new Error(error?.message || String(error));
|
|
128
|
+
return { ...base, request: async () => Promise.reject(failed) };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
70
132
|
// The SDK's WebSocket transport opens its socket without a way to set request
|
|
71
133
|
// headers. This subclass changes only socket creation: Node's WebSocket takes
|
|
72
134
|
// `{ protocols, headers }`; the guard and event wiring match the stock start().
|
|
@@ -101,24 +163,115 @@ function createHeaderWebSocketTransport(Base, messageSchema, url, headers) {
|
|
|
101
163
|
}
|
|
102
164
|
})(url);
|
|
103
165
|
}
|
|
166
|
+
// Unset variables a config references: a failure under `strictEnv`,
|
|
167
|
+
// otherwise warnings (names only), each logged.
|
|
168
|
+
function missingEnvWarnings(name, cfg, strictEnv, log) {
|
|
169
|
+
const warnings = [];
|
|
170
|
+
const missing = findMissingMcpEnvVars(cfg);
|
|
171
|
+
if (missing.length) {
|
|
172
|
+
const message = `missing environment variable(s): ${missing.join(', ')}`;
|
|
173
|
+
if (strictEnv === true) throw new Error(message);
|
|
174
|
+
warnings.push(message);
|
|
175
|
+
log(`[mcp-client] "${name}": ${message}\n`);
|
|
176
|
+
}
|
|
177
|
+
return warnings;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// A multi-account connector: one server, every account behind it; closing the
|
|
181
|
+
// transport closes every account client.
|
|
182
|
+
function connectorAccountsTransport({ name, cfg, Transport, url, accountServers, oauthOptions, log }) {
|
|
183
|
+
const accounts = accountServers.map((accountCfg) => connectorAccountClient(name, accountCfg, oauthOptions));
|
|
184
|
+
const transport = new Transport(new URL(url), {
|
|
185
|
+
fetch: withConnectorAccountsMcp({ connector: cfg.connector, accounts }),
|
|
186
|
+
});
|
|
187
|
+
const close = transport.close.bind(transport);
|
|
188
|
+
transport.close = async () => {
|
|
189
|
+
for (const account of accounts) account.close();
|
|
190
|
+
await close();
|
|
191
|
+
};
|
|
192
|
+
log(`[mcp-client] Connecting "${name}" with ${accounts.length} account(s)\n`);
|
|
193
|
+
return transport;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// A streamable HTTP or SSE server: its configured authentication, or else an
|
|
197
|
+
// OAuth sign-in the transport owns (and closes with it).
|
|
198
|
+
function remoteHttpTransport({ name, cfg, kind, Transport, url, oauthOptions, log }) {
|
|
199
|
+
const opts = requestInitFor(cfg);
|
|
200
|
+
// Explicit authentication remains authoritative (including custom API-key
|
|
201
|
+
// headers). Never forward those credentials to OAuth discovery endpoints.
|
|
202
|
+
let transport;
|
|
203
|
+
let oauth = null;
|
|
204
|
+
if (!hasConfiguredMcpAuth(cfg)) {
|
|
205
|
+
oauth = createMcpOAuth({
|
|
206
|
+
url,
|
|
207
|
+
serverName: mcpOAuthDisplayName(cfg, name),
|
|
208
|
+
oauthClient: mcpOAuthClientFor(cfg, url),
|
|
209
|
+
...oauthOptions,
|
|
210
|
+
// A built-in Google connector is answered in-process.
|
|
211
|
+
...(googleMcpService(url) ? { fetchImpl: withGoogleMcp(oauthOptions?.fetchImpl) } : {}),
|
|
212
|
+
// SSE advertises its POST endpoint on the authenticated event stream.
|
|
213
|
+
// No other path on the origin is allowed to receive this server's token.
|
|
214
|
+
isTransportEndpoint: (input) => kind === 'sse' && transport?._endpoint?.href === new URL(input).href,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Gmail with an app password is answered in-process too (its account
|
|
218
|
+
// header is the configured authentication; the password is in the keychain).
|
|
219
|
+
const local = !oauth && gmailAppPasswordService(url) ? { ...opts, fetch: withGmailAppPasswordMcp() } : opts;
|
|
220
|
+
transport = new Transport(new URL(url), oauth ? { fetch: oauth.fetch } : local);
|
|
221
|
+
if (oauth) {
|
|
222
|
+
transport.oauth = oauth;
|
|
223
|
+
const close = transport.close.bind(transport);
|
|
224
|
+
transport.close = async () => {
|
|
225
|
+
oauth.close();
|
|
226
|
+
await close();
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
log(`[mcp-client] Connecting "${name}" via ${kind.toUpperCase()}: ${mcpUrlForLog(url)}\n`);
|
|
230
|
+
return transport;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function webSocketTransport(name, cfg, sdk, log) {
|
|
234
|
+
const { WebSocketClientTransport } = sdk;
|
|
235
|
+
const url = normalizeMcpTransportUrl(expandEnvVars(String(cfg.url ?? '')), 'ws');
|
|
236
|
+
const opts = requestInitFor(cfg);
|
|
237
|
+
log(`[mcp-client] Connecting "${name}" via WebSocket: ${mcpUrlForLog(url)}\n`);
|
|
238
|
+
return opts
|
|
239
|
+
? createHeaderWebSocketTransport(
|
|
240
|
+
WebSocketClientTransport,
|
|
241
|
+
sdk.JSONRPCMessageSchema,
|
|
242
|
+
new URL(url),
|
|
243
|
+
opts.requestInit.headers
|
|
244
|
+
)
|
|
245
|
+
: new WebSocketClientTransport(new URL(url));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// A stdio child, its stderr logged and its bounded (scrubbed) tail kept.
|
|
249
|
+
function stdioTransport(name, cfg, StdioClientTransport, log) {
|
|
250
|
+
const transport = new StdioClientTransport({
|
|
251
|
+
command: expandEnvVars(String(cfg.command ?? '')),
|
|
252
|
+
args: Array.isArray(cfg.args) ? expandEnvVars(cfg.args) : cfg.args,
|
|
253
|
+
cwd: cfg.cwd == null ? cfg.cwd : expandEnvVars(String(cfg.cwd)),
|
|
254
|
+
env: resolveMcpStdioEnvironment(cfg),
|
|
255
|
+
stderr: cfg.stderr ?? 'pipe',
|
|
256
|
+
});
|
|
257
|
+
let tail = '';
|
|
258
|
+
transport.stderr?.on?.('data', (chunk) => {
|
|
259
|
+
const text = scrubMcpConnectionMessage(chunk, cfg);
|
|
260
|
+
tail = (tail + text).slice(-MCP_STDERR_TAIL_CHARS);
|
|
261
|
+
log(`[mcp:${name}:stderr] ${text}`);
|
|
262
|
+
});
|
|
263
|
+
return { transport, stderrTail: () => tail.trim() };
|
|
264
|
+
}
|
|
265
|
+
|
|
104
266
|
/** Returns { transport, autoDetectAdvert, stderrTail, warnings } — stderrTail()
|
|
105
267
|
* is the last ~4 KB of a stdio server's (scrubbed) stderr, '' for remote
|
|
106
268
|
* transports. `strictEnv` (the caller passes it for plugin-declared servers)
|
|
107
269
|
* makes unset variables without a default fail the server; otherwise they
|
|
108
270
|
* expand to empty and are reported in `warnings` (names only). */
|
|
109
271
|
export function createMcpTransport({ name, cfg, sdk, log, strictEnv, oauthOptions }) {
|
|
110
|
-
const { StdioClientTransport, StreamableHTTPClientTransport, SSEClientTransport
|
|
272
|
+
const { StdioClientTransport, StreamableHTTPClientTransport, SSEClientTransport } = sdk;
|
|
111
273
|
const kind = resolveMcpTransportKind(cfg);
|
|
112
|
-
const warnings = [];
|
|
113
|
-
if (kind !== 'autoDetect') {
|
|
114
|
-
const missing = findMissingMcpEnvVars(cfg);
|
|
115
|
-
if (missing.length) {
|
|
116
|
-
const message = `missing environment variable(s): ${missing.join(', ')}`;
|
|
117
|
-
if (strictEnv === true) throw new Error(message);
|
|
118
|
-
warnings.push(message);
|
|
119
|
-
log(`[mcp-client] "${name}": ${message}\n`);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
274
|
+
const warnings = kind !== 'autoDetect' ? missingEnvWarnings(name, cfg, strictEnv, log) : [];
|
|
122
275
|
if (kind === 'autoDetect') {
|
|
123
276
|
const { url, advert } = resolveAutoDetectUrl(name, cfg);
|
|
124
277
|
log(`[mcp-client] Connecting "${name}" via autoDetect HTTP: ${url}\n`);
|
|
@@ -132,72 +285,23 @@ export function createMcpTransport({ name, cfg, sdk, log, strictEnv, oauthOption
|
|
|
132
285
|
if (kind === 'http' || kind === 'sse') {
|
|
133
286
|
const Transport = kind === 'http' ? StreamableHTTPClientTransport : SSEClientTransport;
|
|
134
287
|
const url = resolveMcpOAuthUrl(cfg);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const oauth = hasConfiguredMcpAuth(cfg)
|
|
140
|
-
? null
|
|
141
|
-
: createMcpOAuth({
|
|
142
|
-
url,
|
|
143
|
-
serverName: mcpOAuthDisplayName(cfg, name),
|
|
144
|
-
oauthClient: mcpOAuthClientFor(cfg, url),
|
|
145
|
-
...oauthOptions,
|
|
146
|
-
// A built-in Google connector is answered in-process.
|
|
147
|
-
...(googleMcpService(url) ? { fetchImpl: withGoogleMcp(oauthOptions?.fetchImpl) } : {}),
|
|
148
|
-
// SSE advertises its POST endpoint on the authenticated event stream.
|
|
149
|
-
// No other path on the origin is allowed to receive this server's token.
|
|
150
|
-
isTransportEndpoint: (input) => kind === 'sse' && transport?._endpoint?.href === new URL(input).href,
|
|
151
|
-
});
|
|
152
|
-
// Gmail with an app password is answered in-process too (its account
|
|
153
|
-
// header is the configured authentication; the password is in the keychain).
|
|
154
|
-
const local = !oauth && gmailAppPasswordService(url) ? { ...opts, fetch: withGmailAppPasswordMcp() } : opts;
|
|
155
|
-
transport = new Transport(new URL(url), oauth ? { fetch: oauth.fetch } : local);
|
|
156
|
-
if (oauth) {
|
|
157
|
-
transport.oauth = oauth;
|
|
158
|
-
const close = transport.close.bind(transport);
|
|
159
|
-
transport.close = async () => {
|
|
160
|
-
oauth.close();
|
|
161
|
-
await close();
|
|
162
|
-
};
|
|
288
|
+
// A disabled account is neither connected nor routed to.
|
|
289
|
+
const accountServers = connectorLiveAccountServers(cfg);
|
|
290
|
+
if (!accountServers.length && connectorAccountsOf(cfg).length) {
|
|
291
|
+
throw new Error(`Every account of "${name}" is disabled`);
|
|
163
292
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
stderrTail: noStderrTail,
|
|
169
|
-
warnings,
|
|
170
|
-
};
|
|
293
|
+
const transport = accountServers.length
|
|
294
|
+
? connectorAccountsTransport({ name, cfg, Transport, url, accountServers, oauthOptions, log })
|
|
295
|
+
: remoteHttpTransport({ name, cfg, kind, Transport, url, oauthOptions, log });
|
|
296
|
+
return { transport, autoDetectAdvert: null, stderrTail: noStderrTail, warnings };
|
|
171
297
|
}
|
|
172
298
|
if (kind === 'ws') {
|
|
173
|
-
const
|
|
174
|
-
const opts = requestInitFor(cfg);
|
|
175
|
-
log(`[mcp-client] Connecting "${name}" via WebSocket: ${mcpUrlForLog(url)}\n`);
|
|
176
|
-
const transport = opts
|
|
177
|
-
? createHeaderWebSocketTransport(
|
|
178
|
-
WebSocketClientTransport,
|
|
179
|
-
sdk.JSONRPCMessageSchema,
|
|
180
|
-
new URL(url),
|
|
181
|
-
opts.requestInit.headers
|
|
182
|
-
)
|
|
183
|
-
: new WebSocketClientTransport(new URL(url));
|
|
299
|
+
const transport = webSocketTransport(name, cfg, sdk, log);
|
|
184
300
|
return { transport, autoDetectAdvert: null, stderrTail: noStderrTail, warnings };
|
|
185
301
|
}
|
|
186
302
|
if (kind === 'stdio') {
|
|
187
|
-
const transport =
|
|
188
|
-
|
|
189
|
-
args: Array.isArray(cfg.args) ? expandEnvVars(cfg.args) : cfg.args,
|
|
190
|
-
cwd: cfg.cwd == null ? cfg.cwd : expandEnvVars(String(cfg.cwd)),
|
|
191
|
-
env: resolveMcpStdioEnvironment(cfg),
|
|
192
|
-
stderr: cfg.stderr ?? 'pipe',
|
|
193
|
-
});
|
|
194
|
-
let tail = '';
|
|
195
|
-
transport.stderr?.on?.('data', (chunk) => {
|
|
196
|
-
const text = scrubMcpConnectionMessage(chunk, cfg);
|
|
197
|
-
tail = (tail + text).slice(-MCP_STDERR_TAIL_CHARS);
|
|
198
|
-
log(`[mcp:${name}:stderr] ${text}`);
|
|
199
|
-
});
|
|
200
|
-
return { transport, autoDetectAdvert: null, stderrTail: () => tail.trim(), warnings };
|
|
303
|
+
const { transport, stderrTail } = stdioTransport(name, cfg, StdioClientTransport, log);
|
|
304
|
+
return { transport, autoDetectAdvert: null, stderrTail, warnings };
|
|
201
305
|
}
|
|
202
306
|
throw new Error(
|
|
203
307
|
`Invalid config for "${name}": need autoDetect, type (stdio/http/sse/ws), url (http), or command (stdio)`
|
|
@@ -37,6 +37,8 @@ import { listAllMcpTools, MCP_CONNECT_CANCELLED, runBoundedHandshake } from './c
|
|
|
37
37
|
import { rememberServerConnector } from './server-connectors.mjs';
|
|
38
38
|
import { mcpOAuthClientFor, mcpOAuthDisplayName } from './oauth-client.mjs';
|
|
39
39
|
import { googleMcpService, withGoogleMcp } from '../../../connectors/google-mcp.mjs';
|
|
40
|
+
import { gmailAppPasswordService } from '../../../connectors/gmail-app-password.mjs';
|
|
41
|
+
import { connectorLiveAccountServers } from '../../../shared/connector-catalog.mjs';
|
|
40
42
|
import {
|
|
41
43
|
clearMcpOAuth,
|
|
42
44
|
commitMcpOAuthSwitch,
|
|
@@ -1117,6 +1119,23 @@ export function isMcpTool(name) {
|
|
|
1117
1119
|
export function isRegisteredMcpTool(name, scopeId = DEFAULT_MCP_SCOPE_ID) {
|
|
1118
1120
|
return Boolean(resolveMcpToolTarget(scopeId, name)?.definition);
|
|
1119
1121
|
}
|
|
1122
|
+
/** True when the prefixed name is `read_email` of a server whose every
|
|
1123
|
+
* endpoint Mixdog answers in-process (the Gmail app-password connector,
|
|
1124
|
+
* alone or behind the multi-account server): its result is a mail as the
|
|
1125
|
+
* mailbox holds it, never another server's text (browser-bridge/mail-links.mjs). */
|
|
1126
|
+
export function isBuiltinMailRead(name, scopeId = DEFAULT_MCP_SCOPE_ID) {
|
|
1127
|
+
const target = resolveMcpToolTarget(normalizeMcpScopeId(scopeId), name);
|
|
1128
|
+
if (!target || (target.definition?.mcpToolName || MCP_TOOL_NAME_RE.exec(name)?.[2]) !== 'read_email') return false;
|
|
1129
|
+
const accounts = connectorLiveAccountServers(target.server.cfg);
|
|
1130
|
+
return (accounts.length ? accounts : [target.server.cfg]).every((cfg) => {
|
|
1131
|
+
try {
|
|
1132
|
+
const url = resolveMcpOAuthUrl(cfg);
|
|
1133
|
+
return Boolean(gmailAppPasswordService(url) || googleMcpService(url));
|
|
1134
|
+
} catch {
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1120
1139
|
/**
|
|
1121
1140
|
* Check whether the inputSchema for an MCP tool declares the given top-level
|
|
1122
1141
|
* property. Used to decide if the orchestrator should auto-inject context
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
|
+
import { listenOnFetchSafePort } from '../../../shared/fetch-safe-listen.mjs';
|
|
2
3
|
import { randomBytes } from 'node:crypto';
|
|
3
4
|
import { normalizeMcpTransportUrl } from './client-config.mjs';
|
|
4
5
|
import { identityFromTokenResponse } from './oauth-account.mjs';
|
|
@@ -48,8 +49,10 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
48
49
|
await new Promise((resolve, reject) => {
|
|
49
50
|
flow.listener.once('error', reject);
|
|
50
51
|
// Retain the registered redirect URI if this connection later needs
|
|
51
|
-
// refresh or reauthorization; never register a different callback.
|
|
52
|
-
|
|
52
|
+
// refresh or reauthorization; never register a different callback. A new
|
|
53
|
+
// one is a port the browser can be redirected to.
|
|
54
|
+
if (creds.redirectUrl) flow.listener.listen(Number(new URL(creds.redirectUrl).port), '127.0.0.1', resolve);
|
|
55
|
+
else listenOnFetchSafePort(flow.listener, '127.0.0.1', resolve);
|
|
53
56
|
});
|
|
54
57
|
creds.redirectUrl = `http://127.0.0.1:${flow.listener.address().port}/oauth/callback`;
|
|
55
58
|
}
|