mixdog 1.2.5 → 1.3.0
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/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/gate-scheduler.mjs +2 -2
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +5 -14
- package/scripts/provider-pingpong-live.mjs +9 -9
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +5 -4
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -0
- package/src/defaults/skills/browser-use/SKILL.md +7 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +56 -7
- package/src/output-styles/common.md +22 -6
- package/src/output-styles/detailed.md +7 -5
- package/src/output-styles/minimal.md +7 -3
- package/src/output-styles/simple.md +2 -3
- package/src/rules/agent/AGENT.md +7 -1
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +21 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +9 -4
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
- package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
- package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.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 +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
- package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
- package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
- package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
- package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/office-extract.mjs +11 -9
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
- package/src/runtime/office/core/tabular.mjs +1 -1
- package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
- package/src/runtime/office/portable/docx-formatting.mjs +1 -1
- package/src/runtime/office/portable/docx-runs.mjs +1 -1
- package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
- package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
- package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
- package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
- package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
- package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
- package/src/runtime/office/portable/portable-opc.mjs +27 -13
- package/src/runtime/office/portable/portable-pivot.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
- package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
- package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
- package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
- package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
- package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
- package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
- package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
- package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
- package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
- package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
- package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
- package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
- package/src/runtime/office/portable/portable-xml.mjs +1 -1
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +36 -14
- package/src/runtime/shared/background-tasks.mjs +60 -20
- package/src/runtime/shared/child-spawn-gate.mjs +26 -16
- package/src/runtime/shared/config.mjs +8 -11
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/file-lock.mjs +7 -1
- package/src/runtime/shared/file-permissions-worker.mjs +38 -0
- package/src/runtime/shared/file-permissions.d.mts +19 -4
- package/src/runtime/shared/file-permissions.mjs +310 -4
- package/src/runtime/shared/git-runner-worker.mjs +6 -78
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/llm/http-agent.mjs +7 -3
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
- package/src/runtime/shared/memory-snapshot.mjs +5 -1
- package/src/runtime/shared/notify-trace.mjs +8 -1
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -0
- package/src/runtime/shared/pristine-execution-contract.json +5 -1
- package/src/runtime/shared/process-runner-worker.mjs +7 -0
- package/src/runtime/shared/process-runner.mjs +38 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -1
- package/src/runtime/shared/provider-api-key.mjs +0 -1
- package/src/runtime/shared/read-row-numbers.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +60 -18
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/run-child.mjs +84 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/session-activity-signal.mjs +23 -0
- package/src/runtime/shared/shell-output-summary.mjs +23 -0
- package/src/runtime/shared/singleton-owner.mjs +126 -42
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +56 -0
- package/src/runtime/shared/user-data-guard.mjs +131 -34
- package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
- package/src/runtime/shared/worktrees/git-head.mjs +20 -2
- package/src/runtime/shared/worktrees/lock.mjs +3 -2
- package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
- package/src/runtime/tidy/runners/biome.mjs +3 -1
- package/src/runtime/tidy/shadow.mjs +2 -1
- package/src/runtime/web-search/index.mjs +5 -7
- package/src/runtime/web-search/lib/formatter.mjs +42 -6
- package/src/runtime/web-search/tool-defs.mjs +6 -1
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +25 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +5 -2
- package/src/session-runtime/lifecycle-api.mjs +3 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/set-route.mjs +14 -3
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/provider-auth/login.mjs +10 -6
- package/src/session-runtime/provider-auth/setup.mjs +19 -2
- package/src/session-runtime/provider-catalog-cache.mjs +101 -25
- package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
- package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
- package/src/session-runtime/provider-models.mjs +76 -10
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
- package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
- package/src/session-runtime/services/agent-tool.mjs +20 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +166 -59
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
- package/src/session-runtime/services/usage-dashboard.mjs +27 -69
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +238 -29
- package/src/session-runtime/turn/session-ops.mjs +10 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon-session-control.mjs +11 -2
- package/src/standalone/daemon.mjs +61 -17
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +28 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/standalone/session-transport/routes.mjs +7 -6
- package/src/tui/app/model-options.mjs +39 -2
- package/src/tui/app/model-picker.mjs +16 -2
- package/src/tui/app/provider-setup-picker.mjs +1 -2
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +487 -128
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -4
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +12 -13
- package/src/tui/session/session-api/integrations.mjs +9 -5
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +48 -3
- package/src/tui/session/session-flow/drain.mjs +20 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +104 -24
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +6 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +56 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +50 -7
- package/src/ui/statusline.mjs +1 -6
- package/src/ui/streaming-markdown-heal.mjs +24 -7
- package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
- package/src/workflows/default/WORKFLOW.md +9 -13
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { readFile, rm } from 'node:fs/promises';
|
|
3
4
|
import { join } from 'node:path';
|
|
4
5
|
import { withFileLock, writeFileAtomicAsync } from '../../../shared/atomic-file.mjs';
|
|
5
6
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
7
|
+
import { canForceAccountChoice } from './oauth-account.mjs';
|
|
6
8
|
import { reauthenticationRequired } from './oauth-shared.mjs';
|
|
7
9
|
|
|
8
10
|
// Same lease as the provider OAuth refresh (openai-oauth-tokens.mjs): a
|
|
@@ -35,6 +37,31 @@ function readRevisionMarker(account) {
|
|
|
35
37
|
return readFile(credentialFile(account, 'rev'), 'utf8').catch(() => null);
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
// Who the stored sign-in belongs to, beside the entry (never a credential), so
|
|
41
|
+
// the status lists it without decrypting the keychain:
|
|
42
|
+
// `{ account, workspace, forcedChoice }`; absent when unknown or signed out.
|
|
43
|
+
export function writeIdentityFile(account, creds) {
|
|
44
|
+
const file = credentialFile(account, 'who');
|
|
45
|
+
if (!creds?.tokens) return rm(file, { force: true });
|
|
46
|
+
const identity = creds.identity || {};
|
|
47
|
+
return writeFileAtomicAsync(
|
|
48
|
+
file,
|
|
49
|
+
JSON.stringify({
|
|
50
|
+
account: identity.account || '',
|
|
51
|
+
workspace: identity.workspace || '',
|
|
52
|
+
forcedChoice: canForceAccountChoice(creds.discovery?.authorizationServerMetadata?.authorization_endpoint),
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
export function readIdentityFile(account) {
|
|
57
|
+
try {
|
|
58
|
+
const value = JSON.parse(readFileSync(credentialFile(account, 'who'), 'utf8'));
|
|
59
|
+
return value && typeof value === 'object' ? value : null;
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
38
65
|
// The stored value as another process may have just written it, not this
|
|
39
66
|
// process's cached copy.
|
|
40
67
|
export function readStoredCredentials(credentialStore, account) {
|
|
@@ -57,6 +84,7 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
57
84
|
clientInformation: undefined,
|
|
58
85
|
redirectUrl: undefined,
|
|
59
86
|
discovery: undefined,
|
|
87
|
+
identity: undefined,
|
|
60
88
|
observed: undefined,
|
|
61
89
|
loaded: undefined,
|
|
62
90
|
};
|
|
@@ -74,10 +102,25 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
74
102
|
clientInformation: creds.clientInformation,
|
|
75
103
|
redirectUrl: creds.redirectUrl,
|
|
76
104
|
discovery: creds.discovery,
|
|
105
|
+
identity: creds.identity,
|
|
77
106
|
} = value);
|
|
78
107
|
creds.observed = revisionOf(saved);
|
|
79
108
|
hold();
|
|
80
109
|
};
|
|
110
|
+
// Whether the stored entry is still the one this process last read or wrote:
|
|
111
|
+
// its revision marker says so without a keychain read (on Windows each read
|
|
112
|
+
// is a DPAPI PowerShell round trip of ~250 ms). Every writer changes the
|
|
113
|
+
// marker under the credential lock before the entry, so under that lock an
|
|
114
|
+
// unchanged marker is an unchanged entry.
|
|
115
|
+
const unchanged = async (expected = creds.observed) =>
|
|
116
|
+
expected !== undefined &&
|
|
117
|
+
expected === creds.observed &&
|
|
118
|
+
(await readRevisionMarker(account)) === markerOf(expected, Boolean(creds.tokens));
|
|
119
|
+
// The stored entry as of now, adopted (skipped when unchanged).
|
|
120
|
+
async function adoptStored() {
|
|
121
|
+
if (await unchanged()) return;
|
|
122
|
+
adopt(await readStoredCredentials(credentialStore, account));
|
|
123
|
+
}
|
|
81
124
|
// A failed read (locked keychain) is retried by the next request.
|
|
82
125
|
const ready = () =>
|
|
83
126
|
(creds.loaded ??= credentialStore
|
|
@@ -93,25 +136,31 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
93
136
|
// the newer entry, or its deletion by a log-out, and changes nothing.
|
|
94
137
|
function update(change, { expected = creds.observed, remove = false } = {}) {
|
|
95
138
|
return withCredentialLock(account, async () => {
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
139
|
+
let exists = creds.observed !== null;
|
|
140
|
+
if (!(await unchanged(expected))) {
|
|
141
|
+
const saved = await readStoredCredentials(credentialStore, account);
|
|
142
|
+
if (revisionOf(saved) !== expected) {
|
|
143
|
+
adopt(saved);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
exists = Boolean(saved);
|
|
100
147
|
}
|
|
101
148
|
change();
|
|
102
149
|
hold();
|
|
103
150
|
if (remove) {
|
|
104
151
|
await writeRevisionMarker(account, null);
|
|
105
|
-
if (
|
|
152
|
+
if (exists) await credentialStore.deleteSecretAsync(account);
|
|
153
|
+
await writeIdentityFile(account, null);
|
|
106
154
|
creds.observed = null;
|
|
107
155
|
} else {
|
|
108
156
|
const revision = randomBytes(16).toString('hex');
|
|
109
157
|
await writeRevisionMarker(account, revision, Boolean(creds.tokens));
|
|
110
|
-
const { tokens, clientInformation, redirectUrl, discovery } = creds;
|
|
158
|
+
const { tokens, clientInformation, redirectUrl, discovery, identity } = creds;
|
|
111
159
|
await credentialStore.setSecretAsync(
|
|
112
160
|
account,
|
|
113
|
-
JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery })
|
|
161
|
+
JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity })
|
|
114
162
|
);
|
|
163
|
+
await writeIdentityFile(account, creds);
|
|
115
164
|
creds.observed = revision;
|
|
116
165
|
}
|
|
117
166
|
return true;
|
|
@@ -133,7 +182,7 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
133
182
|
}
|
|
134
183
|
// Forget the in-memory credentials; the next request re-reads the keychain.
|
|
135
184
|
function clear() {
|
|
136
|
-
creds.tokens = creds.clientInformation = creds.redirectUrl = creds.discovery = undefined;
|
|
185
|
+
creds.tokens = creds.clientInformation = creds.redirectUrl = creds.discovery = creds.identity = undefined;
|
|
137
186
|
creds.loaded = creds.observed = undefined;
|
|
138
187
|
}
|
|
139
188
|
return {
|
|
@@ -141,6 +190,7 @@ export function createCredentialCache({ url, credentialStore, account }) {
|
|
|
141
190
|
held,
|
|
142
191
|
ready,
|
|
143
192
|
adopt,
|
|
193
|
+
adoptStored,
|
|
144
194
|
update,
|
|
145
195
|
observeStoredRevision,
|
|
146
196
|
clear,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
import { normalizeMcpTransportUrl } from './client-config.mjs';
|
|
4
|
+
import { identityFromTokenResponse } from './oauth-account.mjs';
|
|
4
5
|
import { answerOAuthCallback } from './oauth-callback.mjs';
|
|
5
6
|
import { anySignal, loginFailed, reauthenticationRequired } from './oauth-shared.mjs';
|
|
6
7
|
|
|
@@ -49,12 +50,34 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
49
50
|
flow.browserOpened = false;
|
|
50
51
|
flow.launchBrowser = browser || openBrowser;
|
|
51
52
|
const signal = AbortSignal.any([lifetimeSignal, requestSignal, AbortSignal.timeout(timeoutMs)]);
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
// Who this login's tokens belong to (oauth-account.mjs): the SDK keeps only
|
|
54
|
+
// the token fields, so the token endpoint's answer is read here.
|
|
55
|
+
flow.identity = undefined;
|
|
56
|
+
const safeFetch = async (input, init = {}) => {
|
|
57
|
+
const response = await fetchImpl(normalizeMcpTransportUrl(input), {
|
|
54
58
|
...init,
|
|
55
59
|
redirect: 'error',
|
|
56
60
|
signal: anySignal(signal, init.signal),
|
|
57
61
|
});
|
|
62
|
+
if (response.ok && /(^|&)grant_type=/.test(String(init.body ?? ''))) {
|
|
63
|
+
flow.identity = identityFromTokenResponse(
|
|
64
|
+
await response
|
|
65
|
+
.clone()
|
|
66
|
+
.json()
|
|
67
|
+
.catch(() => null)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return response;
|
|
71
|
+
};
|
|
72
|
+
// The caller's progress hooks (mcp-oauth-login.mjs): the callback arrived,
|
|
73
|
+
// then the tokens are stored.
|
|
74
|
+
const progress = (hook) => {
|
|
75
|
+
try {
|
|
76
|
+
browser?.[hook]?.();
|
|
77
|
+
} catch {
|
|
78
|
+
/* progress reporting never fails the login */
|
|
79
|
+
}
|
|
80
|
+
};
|
|
58
81
|
let abort;
|
|
59
82
|
const callback = new Promise((resolve, reject) => {
|
|
60
83
|
const finish = (code) => (code ? resolve(code) : reject(loginFailed()));
|
|
@@ -72,9 +95,10 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
72
95
|
// refreshed (and rotated) the tokens this request was rejected with:
|
|
73
96
|
// decide on the stored credentials, under the cross-process lock.
|
|
74
97
|
const result = await cache.withLock(async () => {
|
|
75
|
-
|
|
98
|
+
await cache.adoptStored();
|
|
76
99
|
if (creds.tokens && creds.tokens.access_token !== attemptedToken?.access_token) return 'AUTHORIZED';
|
|
77
|
-
|
|
100
|
+
const registered = provider.preRegistered || creds.clientInformation;
|
|
101
|
+
if (!interactive && (!creds.tokens?.refresh_token || !registered || !creds.redirectUrl)) {
|
|
78
102
|
throw reauthenticationRequired();
|
|
79
103
|
}
|
|
80
104
|
flow.state = randomBytes(32).toString('base64url');
|
|
@@ -85,16 +109,17 @@ export function createLoginFlow({ url, cache, flow, provider, lifetimeSignal, op
|
|
|
85
109
|
if (result === 'REDIRECT') {
|
|
86
110
|
const code = await callback;
|
|
87
111
|
signal.throwIfAborted();
|
|
112
|
+
progress('onCallback');
|
|
88
113
|
const exchanged = await cache.withLock(async () => {
|
|
89
114
|
// The entry this login registered in is gone only after a log-out
|
|
90
115
|
// since it began, which wins: never recreate it.
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
cache.adopt(saved);
|
|
116
|
+
await cache.adoptStored();
|
|
117
|
+
if (creds.observed === null) throw loginFailed();
|
|
94
118
|
return auth(provider, { ...options, authorizationCode: code });
|
|
95
119
|
});
|
|
96
120
|
if (exchanged !== 'AUTHORIZED') throw loginFailed();
|
|
97
121
|
}
|
|
122
|
+
progress('onAuthorized');
|
|
98
123
|
signal.throwIfAborted();
|
|
99
124
|
} catch (error) {
|
|
100
125
|
// SDK errors may contain authorization server response bodies/secrets.
|
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
import { normalizeMcpTransportUrl } from './client-config.mjs';
|
|
2
|
+
import { withAccountParams } from './oauth-account.mjs';
|
|
2
3
|
import { loginFailed, reauthenticationRequired } from './oauth-shared.mjs';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* The SDK's OAuth client provider over one connection's credential `cache`
|
|
6
7
|
* and login `flow` state.
|
|
7
8
|
*/
|
|
8
|
-
export function createOAuthProvider({ cache, flow, lifetimeSignal }) {
|
|
9
|
+
export function createOAuthProvider({ cache, flow, lifetimeSignal, client = null, credentialStore = null }) {
|
|
9
10
|
const { creds, ready, update } = cache;
|
|
10
11
|
// The SDK saves only inside a login, which holds the lock and has just
|
|
11
12
|
// adopted the stored entry.
|
|
12
13
|
const save = async (change) => {
|
|
13
14
|
if (!(await update(change))) throw loginFailed();
|
|
14
15
|
};
|
|
16
|
+
// A pre-registered client (oauth-client.mjs) is the static client
|
|
17
|
+
// information: nothing is registered, and its secret (the user's lives in
|
|
18
|
+
// the keychain) goes with the token requests.
|
|
19
|
+
const staticClient = async () => {
|
|
20
|
+
const secret = client.secretAccount
|
|
21
|
+
? await credentialStore?.getSecretAsync(client.secretAccount)
|
|
22
|
+
: client.clientSecret;
|
|
23
|
+
return { client_id: client.clientId, ...(secret ? { client_secret: secret } : {}) };
|
|
24
|
+
};
|
|
15
25
|
return {
|
|
26
|
+
/** A pre-registered client: a refresh needs no stored registration. */
|
|
27
|
+
preRegistered: Boolean(client),
|
|
28
|
+
// A pre-registered client's provider issues tokens for its own APIs
|
|
29
|
+
// (Google): no RFC 8707 resource indicator is sent.
|
|
30
|
+
...(client ? { validateResourceURL: async () => undefined } : {}),
|
|
16
31
|
get redirectUrl() {
|
|
17
32
|
return creds.redirectUrl;
|
|
18
33
|
},
|
|
@@ -23,11 +38,13 @@ export function createOAuthProvider({ cache, flow, lifetimeSignal }) {
|
|
|
23
38
|
grant_types: ['authorization_code', 'refresh_token'],
|
|
24
39
|
response_types: ['code'],
|
|
25
40
|
token_endpoint_auth_method: 'none',
|
|
41
|
+
...(client?.scopes ? { scope: client.scopes.join(' ') } : {}),
|
|
26
42
|
};
|
|
27
43
|
},
|
|
28
44
|
state: () => flow.state,
|
|
29
45
|
clientInformation: async () => {
|
|
30
46
|
await ready();
|
|
47
|
+
if (client) return staticClient();
|
|
31
48
|
// A connect that cannot open a sign-in never registers a client (the
|
|
32
49
|
// SDK registers one after dropping a rejected registration): the next
|
|
33
50
|
// explicit sign-in registers it.
|
|
@@ -46,6 +63,11 @@ export function createOAuthProvider({ cache, flow, lifetimeSignal }) {
|
|
|
46
63
|
lifetimeSignal.throwIfAborted();
|
|
47
64
|
await save(() => {
|
|
48
65
|
creds.tokens = value;
|
|
66
|
+
// A browser sign-in may be another account: its identity replaces the
|
|
67
|
+
// stored one (null when the server named nobody). A refresh keeps it
|
|
68
|
+
// unless the response names the account again.
|
|
69
|
+
if (flow.browserOpened) creds.identity = flow.identity ?? null;
|
|
70
|
+
else if (flow.identity) creds.identity = flow.identity;
|
|
49
71
|
});
|
|
50
72
|
},
|
|
51
73
|
saveCodeVerifier: (value) => {
|
|
@@ -56,10 +78,11 @@ export function createOAuthProvider({ cache, flow, lifetimeSignal }) {
|
|
|
56
78
|
return flow.verifier;
|
|
57
79
|
},
|
|
58
80
|
discoveryState: () => creds.discovery,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
// Kept in memory and stored with the login's next write (the client
|
|
82
|
+
// registration or the tokens), sparing a keychain write of its own.
|
|
83
|
+
saveDiscoveryState: (value) => {
|
|
84
|
+
creds.discovery = value;
|
|
85
|
+
},
|
|
63
86
|
// The SDK invalidates 'all' when the token endpoint rejects the client
|
|
64
87
|
// (invalid_client / unauthorized_client) and 'tokens' when it rejects the
|
|
65
88
|
// grant (invalid_grant). The registration goes in both cases: an
|
|
@@ -88,8 +111,24 @@ export function createOAuthProvider({ cache, flow, lifetimeSignal }) {
|
|
|
88
111
|
!flow.verifier
|
|
89
112
|
)
|
|
90
113
|
throw loginFailed();
|
|
114
|
+
// A pre-registered client is stored with this login's redirect, as a
|
|
115
|
+
// registration would be: the exchange and later refreshes (and the
|
|
116
|
+
// revocation on 연결 해제) read them from the entry.
|
|
117
|
+
if (client) {
|
|
118
|
+
const issuedTo = await staticClient();
|
|
119
|
+
await save(() => {
|
|
120
|
+
creds.clientInformation = issuedTo;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
91
123
|
flow.browserOpened = true;
|
|
92
|
-
|
|
124
|
+
// A pre-registered client asks for its own scopes (the server's list
|
|
125
|
+
// may name far more) plus its provider's parameters (Google's
|
|
126
|
+
// access_type=offline, without which no refresh token is issued).
|
|
127
|
+
if (client?.scopes) target.searchParams.set('scope', client.scopes.join(' '));
|
|
128
|
+
for (const [key, value] of Object.entries(client?.authParams || {})) target.searchParams.set(key, value);
|
|
129
|
+
// The explicit sign-in's account mode (mcp-oauth-login.mjs) decides the
|
|
130
|
+
// provider's documented account-choice parameter, if any.
|
|
131
|
+
await flow.launchBrowser(withAccountParams(target.href, flow.launchBrowser.accountMode || 'connect').href);
|
|
93
132
|
},
|
|
94
133
|
};
|
|
95
134
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import keychain from '../../../../lib/keychain-cjs.cjs';
|
|
4
4
|
import { openInBrowser } from '../../../shared/open-url.mjs';
|
|
@@ -12,8 +12,10 @@ import {
|
|
|
12
12
|
TOKENS_FLAG,
|
|
13
13
|
createCredentialCache,
|
|
14
14
|
credentialFile,
|
|
15
|
+
readIdentityFile,
|
|
15
16
|
readStoredCredentials,
|
|
16
17
|
withCredentialLock,
|
|
18
|
+
writeIdentityFile,
|
|
17
19
|
writeRevisionMarker,
|
|
18
20
|
} from './oauth-credentials.mjs';
|
|
19
21
|
import { createLoginFlow } from './oauth-login.mjs';
|
|
@@ -55,18 +57,198 @@ export function hasStoredMcpOAuthTokens(url) {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
/** Who the stored sign-in of one MCP server URL belongs to, without a keychain
|
|
61
|
+
* read: `{ account, workspace, forcedChoice }` (empty strings when the server
|
|
62
|
+
* named nobody), or null when signed out. */
|
|
63
|
+
export function storedMcpOAuthIdentity(url) {
|
|
64
|
+
return readIdentityFile(mcpOAuthAccount(normalizeMcpTransportUrl(url)));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// RFC 7009 revocation of the stored grant, only where the authorization server
|
|
68
|
+
// advertises its revocation endpoint (RFC 8414 metadata): it revokes the token
|
|
69
|
+
// this client was issued, nothing workspace-wide. True when the server
|
|
70
|
+
// confirmed it.
|
|
71
|
+
async function revokeStoredGrant(saved, fetchImpl) {
|
|
72
|
+
let value;
|
|
73
|
+
try {
|
|
74
|
+
value = JSON.parse(saved);
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const endpoint = value?.discovery?.authorizationServerMetadata?.revocation_endpoint;
|
|
79
|
+
const token = value?.tokens?.refresh_token || value?.tokens?.access_token;
|
|
80
|
+
const clientId = value?.clientInformation?.client_id;
|
|
81
|
+
if (typeof endpoint !== 'string' || !/^https:\/\//.test(endpoint) || !token || !clientId) return false;
|
|
82
|
+
const body = new URLSearchParams({
|
|
83
|
+
token,
|
|
84
|
+
token_type_hint: value.tokens.refresh_token ? 'refresh_token' : 'access_token',
|
|
85
|
+
client_id: clientId,
|
|
86
|
+
});
|
|
87
|
+
if (value.clientInformation.client_secret) body.set('client_secret', value.clientInformation.client_secret);
|
|
88
|
+
try {
|
|
89
|
+
const response = await fetchImpl(endpoint, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
92
|
+
body,
|
|
93
|
+
redirect: 'error',
|
|
94
|
+
signal: AbortSignal.timeout(5_000),
|
|
95
|
+
});
|
|
96
|
+
return response.ok;
|
|
97
|
+
} catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
58
102
|
/** Log out of one MCP server URL: delete its stored tokens and client
|
|
59
103
|
* registration and drop them from live connections, which then need an
|
|
60
|
-
* explicit reconnect to log in again.
|
|
61
|
-
|
|
104
|
+
* explicit reconnect to log in again. With `revoke`, the grant is first
|
|
105
|
+
* revoked at the authorization server where it documents a revocation
|
|
106
|
+
* endpoint. Resolves `{ revoked }`. */
|
|
107
|
+
export async function clearMcpOAuth({ url, credentialStore = keychain, revoke = false, fetchImpl = fetch }) {
|
|
62
108
|
url = normalizeMcpTransportUrl(url);
|
|
63
109
|
const account = mcpOAuthAccount(url);
|
|
110
|
+
let revoked = false;
|
|
64
111
|
await withCredentialLock(account, async () => {
|
|
112
|
+
const saved = await readStoredCredentials(credentialStore, account);
|
|
113
|
+
if (revoke && saved != null) revoked = await revokeStoredGrant(saved, fetchImpl);
|
|
65
114
|
await writeRevisionMarker(account, null);
|
|
66
|
-
if (
|
|
67
|
-
|
|
115
|
+
if (saved != null) await credentialStore.deleteSecretAsync(account);
|
|
116
|
+
await writeIdentityFile(account, null);
|
|
68
117
|
});
|
|
69
118
|
scopes.get(credentialStore)?.get(url)?.oauth.clear();
|
|
119
|
+
return { revoked };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function storeEntry(account, url, value, credentialStore) {
|
|
123
|
+
const revision = randomBytes(16).toString('hex');
|
|
124
|
+
const { tokens, clientInformation, redirectUrl, discovery, identity } = value;
|
|
125
|
+
await writeRevisionMarker(account, revision, Boolean(tokens));
|
|
126
|
+
await credentialStore.setSecretAsync(
|
|
127
|
+
account,
|
|
128
|
+
JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity })
|
|
129
|
+
);
|
|
130
|
+
await writeIdentityFile(account, value);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 계정 바꾸기 for one MCP server URL, transactionally: a browser sign-in with
|
|
135
|
+
* the provider's documented account choice that runs beside the stored
|
|
136
|
+
* sign-in, reusing its client registration and discovery but never its tokens,
|
|
137
|
+
* and stores nothing. `done` resolves the new sign-in (`{ tokens, identity, … }`)
|
|
138
|
+
* or rejects (cancel, denial, timeout), leaving the stored sign-in and every
|
|
139
|
+
* live connection as they were. `answer(pasted)` completes it with a pasted
|
|
140
|
+
* redirect URL (remote sign-in); `cancel()` aborts it.
|
|
141
|
+
*/
|
|
142
|
+
export function startMcpOAuthSwitch({
|
|
143
|
+
url,
|
|
144
|
+
launch,
|
|
145
|
+
serverName,
|
|
146
|
+
credentialStore = keychain,
|
|
147
|
+
fetchImpl = fetch,
|
|
148
|
+
timeoutMs = MCP_OAUTH_TIMEOUT_MS,
|
|
149
|
+
oauthClient = null,
|
|
150
|
+
}) {
|
|
151
|
+
url = normalizeMcpTransportUrl(url);
|
|
152
|
+
const lifetime = new AbortController();
|
|
153
|
+
const creds = {
|
|
154
|
+
tokens: undefined,
|
|
155
|
+
clientInformation: undefined,
|
|
156
|
+
redirectUrl: undefined,
|
|
157
|
+
discovery: undefined,
|
|
158
|
+
identity: undefined,
|
|
159
|
+
// Never null: the in-memory entry always exists.
|
|
160
|
+
observed: 'switch',
|
|
161
|
+
};
|
|
162
|
+
// An in-memory entry: a registration made during the switch stays here
|
|
163
|
+
// until the commit stores it with the tokens.
|
|
164
|
+
const cache = {
|
|
165
|
+
creds,
|
|
166
|
+
held: new Set(),
|
|
167
|
+
ready: async () => {},
|
|
168
|
+
adoptStored: async () => {},
|
|
169
|
+
update: async (change) => {
|
|
170
|
+
change();
|
|
171
|
+
return true;
|
|
172
|
+
},
|
|
173
|
+
withLock: (fn) => fn(),
|
|
174
|
+
};
|
|
175
|
+
const flow = {
|
|
176
|
+
listener: undefined,
|
|
177
|
+
state: undefined,
|
|
178
|
+
verifier: undefined,
|
|
179
|
+
allowBrowser: false,
|
|
180
|
+
browserOpened: false,
|
|
181
|
+
launchBrowser: launch,
|
|
182
|
+
finishCallback: undefined,
|
|
183
|
+
};
|
|
184
|
+
const provider = createOAuthProvider({
|
|
185
|
+
cache,
|
|
186
|
+
flow,
|
|
187
|
+
lifetimeSignal: lifetime.signal,
|
|
188
|
+
client: oauthClient,
|
|
189
|
+
credentialStore,
|
|
190
|
+
});
|
|
191
|
+
const loginFlow = createLoginFlow({
|
|
192
|
+
url,
|
|
193
|
+
cache,
|
|
194
|
+
flow,
|
|
195
|
+
provider,
|
|
196
|
+
lifetimeSignal: lifetime.signal,
|
|
197
|
+
openBrowser: launch,
|
|
198
|
+
fetchImpl,
|
|
199
|
+
timeoutMs,
|
|
200
|
+
});
|
|
201
|
+
const done = (async () => {
|
|
202
|
+
const saved = await readStoredCredentials(credentialStore, mcpOAuthAccount(url));
|
|
203
|
+
if (saved) {
|
|
204
|
+
const value = JSON.parse(saved);
|
|
205
|
+
if (value.url === url) {
|
|
206
|
+
creds.clientInformation = value.clientInformation;
|
|
207
|
+
creds.redirectUrl = value.redirectUrl;
|
|
208
|
+
creds.discovery = value.discovery;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
await loginFlow.login({}, lifetime.signal, true, launch, undefined, serverName);
|
|
212
|
+
const { tokens, clientInformation, redirectUrl, discovery, identity } = creds;
|
|
213
|
+
if (!tokens) throw new Error('MCP OAuth login failed, cancelled, or timed out');
|
|
214
|
+
return { tokens, clientInformation, redirectUrl, discovery, identity: identity ?? null };
|
|
215
|
+
})();
|
|
216
|
+
return {
|
|
217
|
+
done,
|
|
218
|
+
answer(pasted) {
|
|
219
|
+
if (!flow.finishCallback || !flow.browserOpened || !flow.state || !creds.redirectUrl) {
|
|
220
|
+
throw new Error(MCP_OAUTH_CALLBACK_NOT_PENDING);
|
|
221
|
+
}
|
|
222
|
+
const { code } = parsePastedMcpOAuthCallback(pasted, { redirectUrl: creds.redirectUrl, state: flow.state });
|
|
223
|
+
loginFlow.stopListening();
|
|
224
|
+
loginFlow.answerCallback(code);
|
|
225
|
+
},
|
|
226
|
+
cancel() {
|
|
227
|
+
lifetime.abort();
|
|
228
|
+
flow.finishCallback?.();
|
|
229
|
+
loginFlow.closeListener();
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** Store the sign-in a switch returned as the URL's sign-in; resolves a
|
|
235
|
+
* `rollback()` that restores the previous one (or none). Live connections
|
|
236
|
+
* adopt either through the revision marker on their next request. */
|
|
237
|
+
export async function commitMcpOAuthSwitch({ url, signIn, credentialStore = keychain }) {
|
|
238
|
+
url = normalizeMcpTransportUrl(url);
|
|
239
|
+
const account = mcpOAuthAccount(url);
|
|
240
|
+
let previous = null;
|
|
241
|
+
await withCredentialLock(account, async () => {
|
|
242
|
+
previous = await readStoredCredentials(credentialStore, account);
|
|
243
|
+
await storeEntry(account, url, signIn, credentialStore);
|
|
244
|
+
});
|
|
245
|
+
return () =>
|
|
246
|
+
withCredentialLock(account, async () => {
|
|
247
|
+
if (previous) return storeEntry(account, url, JSON.parse(previous), credentialStore);
|
|
248
|
+
await writeRevisionMarker(account, null);
|
|
249
|
+
await credentialStore.deleteSecretAsync(account);
|
|
250
|
+
await writeIdentityFile(account, null);
|
|
251
|
+
});
|
|
70
252
|
}
|
|
71
253
|
|
|
72
254
|
// The keychain is the only durable store. Exact URLs, including query strings,
|
|
@@ -166,6 +348,7 @@ function createSharedOAuth({
|
|
|
166
348
|
openBrowser = openInBrowser,
|
|
167
349
|
fetchImpl = fetch,
|
|
168
350
|
timeoutMs = MCP_OAUTH_TIMEOUT_MS,
|
|
351
|
+
oauthClient = null,
|
|
169
352
|
}) {
|
|
170
353
|
const lifetime = new AbortController();
|
|
171
354
|
const cache = createCredentialCache({ url, credentialStore, account: mcpOAuthAccount(url) });
|
|
@@ -179,7 +362,13 @@ function createSharedOAuth({
|
|
|
179
362
|
launchBrowser: openBrowser,
|
|
180
363
|
finishCallback: undefined,
|
|
181
364
|
};
|
|
182
|
-
const provider = createOAuthProvider({
|
|
365
|
+
const provider = createOAuthProvider({
|
|
366
|
+
cache,
|
|
367
|
+
flow,
|
|
368
|
+
lifetimeSignal: lifetime.signal,
|
|
369
|
+
client: oauthClient,
|
|
370
|
+
credentialStore,
|
|
371
|
+
});
|
|
183
372
|
const { login, stopListening, closeListener, answerCallback } = createLoginFlow({
|
|
184
373
|
url,
|
|
185
374
|
cache,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Which catalog connector each connected MCP server is (connector-catalog.mjs
|
|
2
|
+
// connectorOfServer), recorded by the client as servers connect, so a tool
|
|
3
|
+
// name alone (`mcp__<server>__<tool>`) finds its catalog defaults at dispatch.
|
|
4
|
+
import { connectorOfServer } from '../../../shared/connector-catalog.mjs';
|
|
5
|
+
|
|
6
|
+
const byServer = new Map();
|
|
7
|
+
|
|
8
|
+
export function rememberServerConnector(name, cfg) {
|
|
9
|
+
const id = connectorOfServer(cfg);
|
|
10
|
+
if (id) byServer.set(String(name), id);
|
|
11
|
+
else byServer.delete(String(name));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** The catalog id of connected server `name`, or ''. */
|
|
15
|
+
export function serverConnector(name) {
|
|
16
|
+
return byServer.get(String(name)) || '';
|
|
17
|
+
}
|
|
@@ -378,14 +378,21 @@ function poolSend(providerName, account) {
|
|
|
378
378
|
// remaining wait budget is waited out; otherwise the send fails as before.
|
|
379
379
|
const waitOrThrow = async (error, ids) => {
|
|
380
380
|
const { rows, now, all } = exhaustion(ids);
|
|
381
|
-
const
|
|
382
|
-
|
|
381
|
+
const bound = waitBoundMs(ids);
|
|
382
|
+
// Persisting a short cooldown can outlast its deadline. Release only
|
|
383
|
+
// attempts cooled by this send, and only under an enabled wait policy.
|
|
384
|
+
const expired = bound > 0 && rows.some((row) => cooled.has(row.id) && !(Number(row.blockedUntil) > now));
|
|
385
|
+
const wait = all ? null : expired ? 0 : earliestCooldownMs(rows, now);
|
|
386
|
+
if (wait == null || waitedMs + wait > bound) throw markExhausted(error, ids);
|
|
383
387
|
options.onStageChange?.('reconnecting', {
|
|
384
388
|
message: `Rate limited — every account is cooling down; retrying in ${Math.ceil(wait / 1000)}s`,
|
|
385
389
|
reason: 'rate_limited',
|
|
386
390
|
waitMs: wait,
|
|
387
391
|
retryAt: now + wait,
|
|
388
392
|
});
|
|
393
|
+
// A zero-duration sleep does not check cancellation, including on the
|
|
394
|
+
// final allowed send when no next loop iteration will check it either.
|
|
395
|
+
options.signal?.throwIfAborted();
|
|
389
396
|
await sleepWithAbort(wait, options.signal);
|
|
390
397
|
waitedMs += wait;
|
|
391
398
|
const lifted = Date.now();
|
|
@@ -10,7 +10,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
|
|
|
10
10
|
// source release just to advance the user-agent version.
|
|
11
11
|
// Claude Opus 5.5 requires 2.1.280 or newer. The release workflow raises this
|
|
12
12
|
// to the published CLI version (scripts/sync-client-version-floors.mjs).
|
|
13
|
-
export const DEFAULT_CLI_VERSION = '2.1.
|
|
13
|
+
export const DEFAULT_CLI_VERSION = '2.1.304';
|
|
14
14
|
export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
|
|
15
15
|
|
|
16
16
|
const CACHE_SCHEMA_VERSION = 1;
|