mixdog 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +6 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +7 -9
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- 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 +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +178 -178
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +118 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +6 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +7 -16
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +114 -34
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search.mjs +9 -8
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +478 -251
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +17 -8
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +5 -1
- package/src/tui/session/turn.mjs +38 -31
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -4,7 +4,7 @@ import { createRemoteVersionSource } from './npm-cli-version.mjs';
|
|
|
4
4
|
// documented version endpoint; the official installer script embeds the
|
|
5
5
|
// current build (…/lab/<build>/…), parsed best-effort. Any format change or
|
|
6
6
|
// failure falls back to the floor.
|
|
7
|
-
export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.
|
|
7
|
+
export const CURSOR_CLIENT_VERSION_FLOOR = 'cli-2026.10.16-e3cb207';
|
|
8
8
|
const BUILD_PATTERN = /downloads\.cursor\.com\/lab\/(\d{4}\.\d{2}\.\d{2}-[0-9a-f]{6,40})\//;
|
|
9
9
|
export const CURSOR_INSTALL_URL = 'https://cursor.com/install';
|
|
10
10
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
3
|
+
|
|
4
|
+
const PREFIX = 'cursor_native_';
|
|
5
|
+
const pendingCalls = new Map();
|
|
6
|
+
const AUTHORIZATION_MS = 10 * 60 * 1000;
|
|
7
|
+
|
|
8
|
+
export function isCursorNativeCallId(id) {
|
|
9
|
+
return typeof id === 'string' && id.startsWith(PREFIX);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Registered before streaming the call, including when a later frame is partial.
|
|
13
|
+
// Model arguments never grant this capability.
|
|
14
|
+
export function registerCursorNativeCall(ownerSessionId, pending, executions) {
|
|
15
|
+
if (!ownerSessionId || !pending.native) return;
|
|
16
|
+
if (pending.toolName !== 'read' && pending.toolName !== 'edit') return;
|
|
17
|
+
if (!['readResult', 'writeResult'].includes(pending.native.resultType)) return;
|
|
18
|
+
const now = Date.now();
|
|
19
|
+
for (const [id, entry] of pendingCalls) {
|
|
20
|
+
if (entry.expiresAt <= now) pendingCalls.delete(id);
|
|
21
|
+
}
|
|
22
|
+
if (pendingCalls.size >= 4096) throw new Error('Cursor native execution authorization capacity exceeded');
|
|
23
|
+
pending.toolCallId = `${PREFIX}${randomUUID()}`;
|
|
24
|
+
const entry = {
|
|
25
|
+
ownerSessionId,
|
|
26
|
+
pending,
|
|
27
|
+
executions,
|
|
28
|
+
expiresAt: now + AUTHORIZATION_MS,
|
|
29
|
+
arguments: JSON.parse(pending.decodedArgs),
|
|
30
|
+
};
|
|
31
|
+
pendingCalls.set(pending.toolCallId, entry);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function cursorNativeCall(ownerSessionId, id, name, args) {
|
|
35
|
+
if (!isCursorNativeCallId(id)) return null;
|
|
36
|
+
const entry = pendingCalls.get(id);
|
|
37
|
+
if (!entry) throw new Error('Cursor native execution authorization is missing');
|
|
38
|
+
if (entry.expiresAt <= Date.now()) throw new Error('Cursor native execution authorization expired');
|
|
39
|
+
if (entry.ownerSessionId !== ownerSessionId) throw new Error('Cursor native execution authorization owner mismatch');
|
|
40
|
+
if (entry.pending.toolName !== name) throw new Error('Cursor native execution authorization tool mismatch');
|
|
41
|
+
if (!isDeepStrictEqual(entry.arguments, args))
|
|
42
|
+
throw new Error('Cursor native execution authorization argument mismatch');
|
|
43
|
+
return entry;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function releaseCursorNativeCall(pending) {
|
|
47
|
+
pendingCalls.delete(pending.toolCallId);
|
|
48
|
+
}
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
// Cursor exec/kv message handling: routing native exec requests to local
|
|
2
2
|
// tools and sending results back on the bridge.
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
|
+
import { BRIDGE_NAME_MAX_CHARS, isBridgeMetaTool } from '../runtime-core/tool-bridge-contract.mjs';
|
|
5
|
+
import { releaseCursorNativeCall } from './cursor-native-context.mjs';
|
|
4
6
|
import { decodeJsonValue, encodeMessage } from './cursor-wire-protobuf.mjs';
|
|
5
7
|
import { capCursorToolResult, storeCursorBlob } from './cursor-wire-guards.mjs';
|
|
6
8
|
import { buildCursorExecThrow } from './cursor-wire-interactions.mjs';
|
|
7
9
|
import { connectFrame, textDecoder, textEncoder } from './cursor-wire-transport.mjs';
|
|
8
10
|
import { buildRequestContext } from './cursor-wire-request.mjs';
|
|
11
|
+
import { readSourceWindow } from '../../../shared/read-row-numbers.mjs';
|
|
12
|
+
import { splitGrepLineNumberOnlyPrefix, splitGrepCountPrefix } from '../tools/builtin/grep-formatting.mjs';
|
|
13
|
+
|
|
14
|
+
const nativeWriteDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
15
|
+
|
|
16
|
+
function nativeWriteText(args) {
|
|
17
|
+
if (!args.fileBytes?.length) return args.fileText || '';
|
|
18
|
+
try {
|
|
19
|
+
return nativeWriteDecoder.decode(args.fileBytes);
|
|
20
|
+
} catch {
|
|
21
|
+
throw Object.assign(new Error('Native Write fileBytes must be valid UTF-8; no file was written'), {
|
|
22
|
+
code: 'CURSOR_WRITE_ENCODING',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
9
26
|
|
|
10
27
|
export function heartbeatFrame() {
|
|
11
28
|
return connectFrame(encodeMessage('AgentClientMessage', { clientHeartbeat: {} }));
|
|
@@ -70,12 +87,15 @@ const NATIVE_EXEC_CASES = [
|
|
|
70
87
|
],
|
|
71
88
|
[
|
|
72
89
|
'writeArgs',
|
|
73
|
-
|
|
90
|
+
// Only the guarded edit tool: it creates missing files and fills empty
|
|
91
|
+
// ones, while its executor rejects overwrites of non-empty files. An
|
|
92
|
+
// explicit write tool would overwrite without any native capability
|
|
93
|
+
// (remote/proxied calls), so it never serves a native Write.
|
|
94
|
+
['edit'],
|
|
74
95
|
(tool, args) => ({
|
|
75
96
|
[argumentName(tool, ['file_path', 'filePath', 'path'], 'file_path')]: args.path || '',
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
: args.fileText || '',
|
|
97
|
+
old_string: '',
|
|
98
|
+
new_string: nativeWriteText(args),
|
|
79
99
|
}),
|
|
80
100
|
'writeResult',
|
|
81
101
|
],
|
|
@@ -90,7 +110,9 @@ const NATIVE_EXEC_CASES = [
|
|
|
90
110
|
pattern: args.pattern || '.',
|
|
91
111
|
...(args.path ? { path: args.path } : {}),
|
|
92
112
|
...(args.glob ? { glob: args.glob } : {}),
|
|
93
|
-
mode: args.outputMode || 'content',
|
|
113
|
+
mode: args.outputMode === 'files_with_matches' ? 'files' : args.outputMode || 'content',
|
|
114
|
+
context: 0,
|
|
115
|
+
...(args.headLimit > 0 ? { limit: args.headLimit } : {}),
|
|
94
116
|
}),
|
|
95
117
|
'grepResult',
|
|
96
118
|
],
|
|
@@ -130,6 +152,16 @@ const rejectedPath = (args) => ({ rejected: { path: args.path || '', reason: UNA
|
|
|
130
152
|
const rejectedShell = (args) => ({
|
|
131
153
|
rejected: { command: args.command || '', workingDirectory: args.workingDirectory || '', reason: UNAVAILABLE },
|
|
132
154
|
});
|
|
155
|
+
const rejectedBackgroundShell = (args) => ({
|
|
156
|
+
rejected: {
|
|
157
|
+
command: args.command || '',
|
|
158
|
+
workingDirectory: args.workingDirectory || '',
|
|
159
|
+
reason:
|
|
160
|
+
'Cursor background shell is not supported. Use the mixdog MCP shell tool with {"command":"..."}; ' +
|
|
161
|
+
'if it returns task_id, use the mixdog task tool with {"action":"wait","task_id":"<returned id>"}. ' +
|
|
162
|
+
'Use load_tool {"names":"task"} if task is not loaded.',
|
|
163
|
+
},
|
|
164
|
+
});
|
|
133
165
|
const unavailableError = () => ({ error: { error: UNAVAILABLE } });
|
|
134
166
|
|
|
135
167
|
// Native exec cases with no Mixdog tool behind them: [exec key, exec result
|
|
@@ -143,7 +175,7 @@ const UNAVAILABLE_EXEC_RESULTS = [
|
|
|
143
175
|
['fetchArgs', 'fetchResult', (args) => ({ error: { url: args.url || '', error: UNAVAILABLE } })],
|
|
144
176
|
['shellArgs', 'shellResult', rejectedShell],
|
|
145
177
|
['shellStreamArgs', 'shellResult', rejectedShell],
|
|
146
|
-
['backgroundShellSpawnArgs', 'backgroundShellSpawnResult',
|
|
178
|
+
['backgroundShellSpawnArgs', 'backgroundShellSpawnResult', rejectedBackgroundShell],
|
|
147
179
|
['writeShellStdinArgs', 'writeShellStdinResult', unavailableError],
|
|
148
180
|
['diagnosticsArgs', 'diagnosticsResult', () => ({})],
|
|
149
181
|
];
|
|
@@ -163,18 +195,44 @@ function rejectUnavailableExec(bridge, exec) {
|
|
|
163
195
|
function handleMcpExec(bridge, exec, tools, onToolCall) {
|
|
164
196
|
const args = exec.mcpArgs;
|
|
165
197
|
const requestedName = args.toolName || args.name;
|
|
166
|
-
const
|
|
198
|
+
const directTool = toolByNames(tools, [requestedName]);
|
|
199
|
+
// Only the bridge granted in this request can resolve a deferred name.
|
|
200
|
+
// The ordinary runtime still projects the target and enforces its policy.
|
|
201
|
+
let tool =
|
|
202
|
+
directTool ||
|
|
203
|
+
(typeof requestedName === 'string' && requestedName.length > 0 ? toolByNames(tools, ['call_tool']) : null);
|
|
167
204
|
if (!tool) {
|
|
168
205
|
sendExecResult(bridge, exec, 'mcpResult', {
|
|
169
206
|
error: { error: `Tool not available: ${requestedName || 'unknown'}` },
|
|
170
207
|
});
|
|
171
208
|
return;
|
|
172
209
|
}
|
|
210
|
+
let decodedArgs = decodeMcpArgs(args.args);
|
|
211
|
+
if (
|
|
212
|
+
requestedName === 'call_tool' &&
|
|
213
|
+
directTool &&
|
|
214
|
+
Object.keys(decodedArgs).length === 2 &&
|
|
215
|
+
Object.hasOwn(decodedArgs, 'name') &&
|
|
216
|
+
Object.hasOwn(decodedArgs, 'arguments') &&
|
|
217
|
+
typeof decodedArgs.name === 'string' &&
|
|
218
|
+
decodedArgs.name.length > 0 &&
|
|
219
|
+
decodedArgs.name.length <= BRIDGE_NAME_MAX_CHARS &&
|
|
220
|
+
!isBridgeMetaTool(decodedArgs.name) &&
|
|
221
|
+
decodedArgs.arguments !== null &&
|
|
222
|
+
typeof decodedArgs.arguments === 'object' &&
|
|
223
|
+
!Array.isArray(decodedArgs.arguments)
|
|
224
|
+
) {
|
|
225
|
+
const target = toolByNames(tools, [decodedArgs.name]);
|
|
226
|
+
if (target) {
|
|
227
|
+
tool = target;
|
|
228
|
+
decodedArgs = decodedArgs.arguments;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
173
231
|
onToolCall({
|
|
174
232
|
exec,
|
|
175
233
|
toolCallId: args.toolCallId || crypto.randomUUID(),
|
|
176
234
|
toolName: tool.name,
|
|
177
|
-
decodedArgs: JSON.stringify(
|
|
235
|
+
decodedArgs: JSON.stringify(directTool ? decodedArgs : { name: requestedName, arguments: decodedArgs }),
|
|
178
236
|
});
|
|
179
237
|
}
|
|
180
238
|
|
|
@@ -191,7 +249,14 @@ export function handleExecMessage(bridge, exec, tools, cloudRule, onToolCall) {
|
|
|
191
249
|
handleMcpExec(bridge, exec, tools, onToolCall);
|
|
192
250
|
return;
|
|
193
251
|
}
|
|
194
|
-
|
|
252
|
+
let redirect;
|
|
253
|
+
try {
|
|
254
|
+
redirect = redirectNativeExec(exec, tools);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (error.code !== 'CURSOR_WRITE_ENCODING') throw error;
|
|
257
|
+
sendExecResult(bridge, exec, 'writeResult', { error: { path: exec.writeArgs.path || '', error: error.message } });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
195
260
|
if (redirect) {
|
|
196
261
|
onToolCall(redirect);
|
|
197
262
|
return;
|
|
@@ -227,31 +292,41 @@ function parseListedPaths(text, rootPath) {
|
|
|
227
292
|
|
|
228
293
|
function parseGrepResult(text, args) {
|
|
229
294
|
const mode = args.outputMode || 'content';
|
|
295
|
+
const lines = text.split(/\r?\n/).filter((line) => line && !line.startsWith('[total ') && !line.startsWith('... ['));
|
|
230
296
|
if (mode === 'files_with_matches') {
|
|
231
|
-
const files =
|
|
232
|
-
.split(/\r?\n/)
|
|
233
|
-
.map((line) => line.trim())
|
|
234
|
-
.filter(Boolean);
|
|
297
|
+
const files = lines.map((line) => line.trim()).filter((line) => !line.startsWith('(no matches)'));
|
|
235
298
|
return { files: { files, totalFiles: files.length } };
|
|
236
299
|
}
|
|
237
300
|
if (mode === 'count') {
|
|
238
301
|
const counts = [];
|
|
239
302
|
let totalMatches = 0;
|
|
240
|
-
for (const line of
|
|
241
|
-
const
|
|
242
|
-
if (!
|
|
243
|
-
const count = Number(
|
|
244
|
-
counts.push({ file:
|
|
303
|
+
for (const line of lines) {
|
|
304
|
+
const parsed = splitGrepCountPrefix(line);
|
|
305
|
+
if (!parsed && !/^\d+$/.test(line)) continue;
|
|
306
|
+
const count = parsed ? parsed.count : Number(line);
|
|
307
|
+
counts.push({ file: parsed?.path || args.path, count });
|
|
245
308
|
totalMatches += count;
|
|
246
309
|
}
|
|
247
310
|
return { count: { counts, totalFiles: counts.length, totalMatches } };
|
|
248
311
|
}
|
|
249
312
|
const byFile = new Map();
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
313
|
+
let currentFile = args.path;
|
|
314
|
+
for (const line of lines) {
|
|
315
|
+
const grouped = /^ {2}(\d+): (.*)$/.exec(line);
|
|
316
|
+
// Native searches request no context: only :N: is a line delimiter.
|
|
317
|
+
// A -N- segment may be part of the filename, not a context-line prefix.
|
|
318
|
+
const match = grouped ? null : /^(.+?):(\d+):/.exec(line);
|
|
319
|
+
const prefix = match ? { path: match[1], lineNo: Number(match[2]), markerEnd: match[0].length } : null;
|
|
320
|
+
const single = grouped || prefix ? null : splitGrepLineNumberOnlyPrefix(line);
|
|
321
|
+
if (!grouped && !prefix && !single) {
|
|
322
|
+
currentFile = line.replace(/ \(\d+ hits\)$/, '');
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
const file = prefix?.path || currentFile;
|
|
326
|
+
const lineNumber = grouped ? Number(grouped[1]) : (prefix || single).lineNo;
|
|
327
|
+
const content = grouped ? grouped[2] : line.slice((prefix || single).markerEnd);
|
|
328
|
+
if (!byFile.has(file)) byFile.set(file, []);
|
|
329
|
+
byFile.get(file).push({ lineNumber, content });
|
|
255
330
|
}
|
|
256
331
|
const matches = [...byFile].map(([file, fileMatches]) => ({ file, matches: fileMatches }));
|
|
257
332
|
const matchedLines = matches.reduce((sum, entry) => sum + entry.matches.length, 0);
|
|
@@ -290,7 +365,7 @@ function sendShellStream(bridge, exec, text, code) {
|
|
|
290
365
|
// rejected shell command.
|
|
291
366
|
const NATIVE_FAILURE_PAYLOADS = {
|
|
292
367
|
readResult: (args, text) => ({ rejected: { path: args.path || '', reason: text || 'Read failed' } }),
|
|
293
|
-
writeResult: (args, text) => ({
|
|
368
|
+
writeResult: (args, text) => ({ error: { path: args.path || '', error: text || 'Write failed' } }),
|
|
294
369
|
fetchResult: (args, text) => ({ error: { url: args.url || '', error: text || 'Fetch failed' } }),
|
|
295
370
|
lsResult: (args, text) => ({ rejected: { path: args.path || '', reason: text || 'List failed' } }),
|
|
296
371
|
grepResult: (_args, text) => ({ error: { error: text || 'Grep failed' } }),
|
|
@@ -304,16 +379,30 @@ const NATIVE_FAILURE_PAYLOADS = {
|
|
|
304
379
|
};
|
|
305
380
|
|
|
306
381
|
const NATIVE_SUCCESS_PAYLOADS = {
|
|
307
|
-
readResult: (args, text) =>
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
382
|
+
readResult: (args, text, pending, result) => {
|
|
383
|
+
const source = readSourceWindow(text);
|
|
384
|
+
// The read executor reports per-line clipping out of band: on the
|
|
385
|
+
// pending call (local) or on the result (remote/proxied).
|
|
386
|
+
if (!source || pending.nativeReadWindow?.lineClipped || result?.readWindow?.lineClipped)
|
|
387
|
+
return {
|
|
388
|
+
rejected: {
|
|
389
|
+
path: args.path || '',
|
|
390
|
+
reason:
|
|
391
|
+
'This read result is not a complete contiguous source window. Use the mixdog MCP read tool with file_path, offset and limit; do not treat display markers as file content.',
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
return {
|
|
395
|
+
success: {
|
|
396
|
+
path: args.path || '',
|
|
397
|
+
content: source.content,
|
|
398
|
+
...(source.totalLines === undefined ? {} : { totalLines: source.totalLines }),
|
|
399
|
+
truncated: source.truncated,
|
|
400
|
+
rangeApplied: Boolean(args.offset || args.limit || (source.startLine != null && source.startLine > 1)),
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
},
|
|
315
404
|
writeResult: (args) => {
|
|
316
|
-
const content =
|
|
405
|
+
const content = nativeWriteText(args);
|
|
317
406
|
return {
|
|
318
407
|
success: {
|
|
319
408
|
path: args.path || '',
|
|
@@ -345,7 +434,9 @@ const NATIVE_SUCCESS_PAYLOADS = {
|
|
|
345
434
|
};
|
|
346
435
|
|
|
347
436
|
export function sendToolResult(bridge, pending, result, ok) {
|
|
437
|
+
releaseCursorNativeCall(pending);
|
|
348
438
|
result = capCursorToolResult(result);
|
|
439
|
+
pending.completedResult = { result, ok };
|
|
349
440
|
const { exec, native } = pending;
|
|
350
441
|
const text = String(result?.content ?? '');
|
|
351
442
|
const media = Array.isArray(result?.media) ? result.media : [];
|
|
@@ -354,6 +445,21 @@ export function sendToolResult(bridge, pending, result, ok) {
|
|
|
354
445
|
return;
|
|
355
446
|
}
|
|
356
447
|
const { args, resultType } = native;
|
|
448
|
+
if (ok && resultType === 'readResult' && pending.nativeReadReply) {
|
|
449
|
+
let reply = pending.nativeReadReply;
|
|
450
|
+
if (pending.nativeUserMessage) {
|
|
451
|
+
reply = {
|
|
452
|
+
rejected: {
|
|
453
|
+
path: args.path || '',
|
|
454
|
+
reason: `Read interrupted by a new user instruction: ${pending.nativeUserMessage}`,
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
} else if (pending.nativeSnapshot) {
|
|
458
|
+
pending.nativeSnapshot.delivered = true;
|
|
459
|
+
}
|
|
460
|
+
sendExecResult(bridge, exec, resultType, reply);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
357
463
|
if (resultType === 'shellStreamResult') {
|
|
358
464
|
sendShellStream(bridge, exec, text, ok ? 0 : 1);
|
|
359
465
|
return;
|
|
@@ -364,6 +470,10 @@ export function sendToolResult(bridge, pending, result, ok) {
|
|
|
364
470
|
return;
|
|
365
471
|
}
|
|
366
472
|
if (Object.hasOwn(NATIVE_SUCCESS_PAYLOADS, resultType)) {
|
|
367
|
-
|
|
473
|
+
const value = NATIVE_SUCCESS_PAYLOADS[resultType](args, text, pending, result);
|
|
474
|
+
if (resultType === 'writeResult' && Number.isInteger(pending.nativeWrittenBytes)) {
|
|
475
|
+
value.success.fileSize = pending.nativeWrittenBytes;
|
|
476
|
+
}
|
|
477
|
+
sendExecResult(bridge, exec, resultType, value);
|
|
368
478
|
}
|
|
369
479
|
}
|
|
@@ -87,7 +87,19 @@ const SCHEMAS = {
|
|
|
87
87
|
['clientHeartbeat', 7, 'ClientHeartbeat'],
|
|
88
88
|
]),
|
|
89
89
|
TextDeltaUpdate: fields([['text', 1, 'string']]),
|
|
90
|
-
ToolCall: fields([
|
|
90
|
+
ToolCall: fields([
|
|
91
|
+
['editToolCall', 12, 'NativeEditToolCall'],
|
|
92
|
+
['mcpToolCall', 15, 'McpToolCall'],
|
|
93
|
+
]),
|
|
94
|
+
NativeEditToolCall: fields([['result', 2, 'NativeEditResult']]),
|
|
95
|
+
NativeEditResult: fields([
|
|
96
|
+
['success', 1, 'raw'],
|
|
97
|
+
['fileNotFound', 2, 'raw'],
|
|
98
|
+
['readPermissionDenied', 3, 'raw'],
|
|
99
|
+
['writePermissionDenied', 4, 'raw'],
|
|
100
|
+
['rejected', 6, 'raw'],
|
|
101
|
+
['error', 7, 'raw'],
|
|
102
|
+
]),
|
|
91
103
|
McpToolCall: fields([
|
|
92
104
|
['args', 1, 'McpArgs'],
|
|
93
105
|
['result', 2, 'McpResult'],
|
|
@@ -422,6 +434,7 @@ const SCHEMAS = {
|
|
|
422
434
|
['totalLines', 3, 'int'],
|
|
423
435
|
['fileSize', 4, 'int'],
|
|
424
436
|
['truncated', 6, 'bool'],
|
|
437
|
+
['rangeApplied', 8, 'bool'],
|
|
425
438
|
]),
|
|
426
439
|
ReadRejected: fields([
|
|
427
440
|
['path', 1, 'string'],
|
|
@@ -430,7 +443,9 @@ const SCHEMAS = {
|
|
|
430
443
|
ReadResult: fields([
|
|
431
444
|
['success', 1, 'ReadSuccess'],
|
|
432
445
|
['rejected', 3, 'ReadRejected'],
|
|
446
|
+
['fileNotFound', 4, 'ReadFileNotFound'],
|
|
433
447
|
]),
|
|
448
|
+
ReadFileNotFound: fields([['path', 1, 'string']]),
|
|
434
449
|
WriteSuccess: fields([
|
|
435
450
|
['path', 1, 'string'],
|
|
436
451
|
['linesCreated', 2, 'int'],
|
|
@@ -440,8 +455,13 @@ const SCHEMAS = {
|
|
|
440
455
|
['path', 1, 'string'],
|
|
441
456
|
['reason', 2, 'string'],
|
|
442
457
|
]),
|
|
458
|
+
WriteError: fields([
|
|
459
|
+
['path', 1, 'string'],
|
|
460
|
+
['error', 2, 'string'],
|
|
461
|
+
]),
|
|
443
462
|
WriteResult: fields([
|
|
444
463
|
['success', 1, 'WriteSuccess'],
|
|
464
|
+
['error', 5, 'WriteError'],
|
|
445
465
|
['rejected', 6, 'WriteRejected'],
|
|
446
466
|
]),
|
|
447
467
|
DeleteRejected: fields([
|
|
@@ -610,7 +630,7 @@ const SCHEMAS = {
|
|
|
610
630
|
JsonValue: fields([
|
|
611
631
|
['nullValue', 1, 'int'],
|
|
612
632
|
['numberValue', 2, 'double'],
|
|
613
|
-
['stringValue', 3, 'string'],
|
|
633
|
+
['stringValue', 3, 'string', { presence: true }],
|
|
614
634
|
['boolValue', 4, 'bool'],
|
|
615
635
|
['structValue', 5, 'JsonStruct'],
|
|
616
636
|
['listValue', 6, 'JsonList'],
|
|
@@ -620,7 +640,8 @@ const SCHEMAS = {
|
|
|
620
640
|
};
|
|
621
641
|
|
|
622
642
|
const textEncoder = new TextEncoder();
|
|
623
|
-
|
|
643
|
+
// A protobuf string is data, not a text document with a disposable BOM.
|
|
644
|
+
const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true });
|
|
624
645
|
|
|
625
646
|
function concatBytes(parts) {
|
|
626
647
|
const length = parts.reduce((sum, part) => sum + part.length, 0);
|
|
@@ -709,7 +730,10 @@ export function encodeMessage(type, value = {}) {
|
|
|
709
730
|
let values = [fieldValue];
|
|
710
731
|
if (descriptor.repeated) values = Array.isArray(fieldValue) ? fieldValue : [];
|
|
711
732
|
for (const item of values) {
|
|
712
|
-
|
|
733
|
+
// A oneof's explicit empty string is a value, not an absent field.
|
|
734
|
+
if ((descriptor.presence && item != null) || shouldWrite(descriptor.type, item)) {
|
|
735
|
+
parts.push(encodeField(descriptor.no, descriptor.type, item));
|
|
736
|
+
}
|
|
713
737
|
}
|
|
714
738
|
}
|
|
715
739
|
return concatBytes(parts);
|
|
@@ -61,7 +61,13 @@ function toolResultEntry(message, text, toolNames) {
|
|
|
61
61
|
const isError = message.mixdog_tool_error === true;
|
|
62
62
|
const toolName = toolNames.get(toolCallId) || '';
|
|
63
63
|
return {
|
|
64
|
-
toolResult: {
|
|
64
|
+
toolResult: {
|
|
65
|
+
toolCallId,
|
|
66
|
+
content: text,
|
|
67
|
+
media,
|
|
68
|
+
isError,
|
|
69
|
+
...(message.mixdog_read_window?.lineClipped === true ? { readWindow: { lineClipped: true } } : {}),
|
|
70
|
+
},
|
|
65
71
|
entry: {
|
|
66
72
|
role: 'tool',
|
|
67
73
|
id: toolCallId,
|
|
@@ -170,9 +176,7 @@ export function buildRequestContext(tools, cloudRule) {
|
|
|
170
176
|
{
|
|
171
177
|
serverName: 'mixdog',
|
|
172
178
|
instructions:
|
|
173
|
-
'
|
|
174
|
-
'Follow their descriptions and input schemas. Prefer them over Cursor native tools; ' +
|
|
175
|
-
'native tools do not directly access the Mixdog environment. ' +
|
|
179
|
+
'Do not use Cursor native tools; use only the tools provided by the mixdog MCP server, following their descriptions and declared input schemas. ' +
|
|
176
180
|
'If a needed tool is not available, use the provided tool discovery mechanism rather than inventing a tool.',
|
|
177
181
|
},
|
|
178
182
|
]
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* close verdict and the bounded in-place restart.
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
|
+
MAX_CONNECT_FRAME_BYTES,
|
|
7
8
|
isCursorAuthError,
|
|
8
9
|
isCursorThrottleError,
|
|
9
10
|
isRetryableCursorStreamError,
|
|
@@ -13,6 +14,10 @@ import { emitProviderRetryStage, markProviderRecoveryExhausted, retryAfterMsFrom
|
|
|
13
14
|
import { createFrameParser, cursorError, parseEndStream } from './cursor-wire-transport.mjs';
|
|
14
15
|
import { processServerMessage } from './cursor-wire-stream-messages.mjs';
|
|
15
16
|
|
|
17
|
+
// A parked HTTP/2 run can still receive parallel execs. Keep their raw chunks
|
|
18
|
+
// with the transport until the next SSE consumer attaches.
|
|
19
|
+
const parkedInputs = new WeakMap();
|
|
20
|
+
|
|
16
21
|
// Resolves after `ms`, or early when the stream is cancelled.
|
|
17
22
|
function abortableSleep(ms, signal) {
|
|
18
23
|
return new Promise((resolve) => {
|
|
@@ -51,7 +56,9 @@ export function createBridgeController(ctx) {
|
|
|
51
56
|
modelParameters: run.modelParameters,
|
|
52
57
|
maxMode: run.maxMode,
|
|
53
58
|
sessionId: run.sessionId,
|
|
59
|
+
ownerSessionId: run.ownerSessionId,
|
|
54
60
|
pending: state.pending,
|
|
61
|
+
executions: state.executions,
|
|
55
62
|
sawTurnEnded: state.sawTurnEnded,
|
|
56
63
|
});
|
|
57
64
|
sink.finish('tool_calls');
|
|
@@ -80,13 +87,11 @@ export function createBridgeController(ctx) {
|
|
|
80
87
|
const serverDelay = retryAfterMsFromError(error);
|
|
81
88
|
// Server advice is honored in full for every retryable kind; local
|
|
82
89
|
// backoff applies only when the server gave none.
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
: backoffMs(throttled ? throttleCount + 1 : retryCount + 1);
|
|
90
|
+
const backoffAttempt = (throttled ? throttleCount : retryCount) + 1;
|
|
91
|
+
const delayMs = Number.isFinite(serverDelay) ? serverDelay : backoffMs(backoffAttempt);
|
|
86
92
|
const throttleOk = throttled && throttleCount < tuning.maxThrottleRetries;
|
|
87
93
|
const authOk = authFailure && authCount < tuning.maxAuthRetries;
|
|
88
|
-
const canRetry =
|
|
89
|
-
retryCount < tuning.maxRetries && recoveryEligible && (retryable || throttleOk || authOk);
|
|
94
|
+
const canRetry = retryCount < tuning.maxRetries && recoveryEligible && (retryable || throttleOk || authOk);
|
|
90
95
|
if (!canRetry) {
|
|
91
96
|
// A fresh Cursor run owns its bounded in-place retries. Mark
|
|
92
97
|
// exhaustion so the outer loop does not multiply that budget.
|
|
@@ -96,8 +101,7 @@ export function createBridgeController(ctx) {
|
|
|
96
101
|
// A throttle that spent its bounded retries is final for the turn too.
|
|
97
102
|
if (
|
|
98
103
|
recoveryEligible &&
|
|
99
|
-
((retryable && retryCount >= tuning.maxRetries) ||
|
|
100
|
-
(throttled && throttleCount >= tuning.maxThrottleRetries))
|
|
104
|
+
((retryable && retryCount >= tuning.maxRetries) || (throttled && throttleCount >= tuning.maxThrottleRetries))
|
|
101
105
|
) {
|
|
102
106
|
markProviderRecoveryExhausted(error, { owner: 'cursor-wire', attempts: retryCount + 1 });
|
|
103
107
|
}
|
|
@@ -118,6 +122,9 @@ export function createBridgeController(ctx) {
|
|
|
118
122
|
lastErr: error,
|
|
119
123
|
delayMs,
|
|
120
124
|
});
|
|
125
|
+
let restartReason = 'transient';
|
|
126
|
+
if (throttled) restartReason = 'throttle';
|
|
127
|
+
else if (authFailure) restartReason = 'auth';
|
|
121
128
|
void sleep(delayMs, cancelSignal).then(async () => {
|
|
122
129
|
if (isCancelled() || state.closed) return;
|
|
123
130
|
try {
|
|
@@ -126,7 +133,7 @@ export function createBridgeController(ctx) {
|
|
|
126
133
|
attempt: retryCount,
|
|
127
134
|
fromCheckpoint: !throttled && Boolean(run.conversation.checkpoint),
|
|
128
135
|
visibleOutput: state.visibleOutput,
|
|
129
|
-
reason:
|
|
136
|
+
reason: restartReason,
|
|
130
137
|
error,
|
|
131
138
|
});
|
|
132
139
|
if (isCancelled() || state.closed) {
|
|
@@ -200,6 +207,11 @@ export function createBridgeController(ctx) {
|
|
|
200
207
|
const attach = (ownedBridge, nextHeartbeat) => {
|
|
201
208
|
live.bridge = ownedBridge;
|
|
202
209
|
live.heartbeat = nextHeartbeat;
|
|
210
|
+
let inbox = parkedInputs.get(ownedBridge);
|
|
211
|
+
if (!inbox) {
|
|
212
|
+
inbox = { chunks: [], bytes: 0 };
|
|
213
|
+
parkedInputs.set(ownedBridge, inbox);
|
|
214
|
+
}
|
|
203
215
|
const messageCtx = {
|
|
204
216
|
state,
|
|
205
217
|
filter,
|
|
@@ -208,14 +220,26 @@ export function createBridgeController(ctx) {
|
|
|
208
220
|
tools: run.tools,
|
|
209
221
|
cloudRule: run.cloudRule,
|
|
210
222
|
sessionId: run.sessionId,
|
|
223
|
+
ownerSessionId: run.ownerSessionId,
|
|
211
224
|
};
|
|
212
225
|
const frameParser = createFrameParser(
|
|
213
226
|
// Server requests answer on whichever bridge is live when they arrive.
|
|
214
227
|
(bytes) => watchdog.progress(processServerMessage(bytes, { ...messageCtx, bridge: live.bridge })),
|
|
215
228
|
(bytes) => onEndStream(ownedBridge, bytes)
|
|
216
229
|
);
|
|
217
|
-
|
|
218
|
-
if (live.bridge !== ownedBridge ||
|
|
230
|
+
const receive = (chunk) => {
|
|
231
|
+
if (live.bridge !== ownedBridge || isCancelled()) return;
|
|
232
|
+
if (state.closed) {
|
|
233
|
+
if (inbox.bytes + chunk.byteLength > MAX_CONNECT_FRAME_BYTES) {
|
|
234
|
+
ownedBridge.close(
|
|
235
|
+
cursorError('Cursor parked input exceeds the buffer limit', { code: 'stream_buffer_limit' })
|
|
236
|
+
);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
inbox.chunks.push(chunk);
|
|
240
|
+
inbox.bytes += chunk.byteLength;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
219
243
|
state.chunkSeq += 1;
|
|
220
244
|
try {
|
|
221
245
|
frameParser(chunk);
|
|
@@ -227,9 +251,15 @@ export function createBridgeController(ctx) {
|
|
|
227
251
|
} catch (error) {
|
|
228
252
|
ownedBridge.close(error);
|
|
229
253
|
}
|
|
230
|
-
}
|
|
254
|
+
};
|
|
255
|
+
ownedBridge.onData(receive);
|
|
231
256
|
ownedBridge.onClose((error) => onBridgeClose(ownedBridge, nextHeartbeat, frameParser, error));
|
|
232
257
|
watchdog.start();
|
|
258
|
+
while (!state.closed && !isCancelled() && inbox.chunks.length) {
|
|
259
|
+
const chunk = inbox.chunks.shift();
|
|
260
|
+
inbox.bytes -= chunk.byteLength;
|
|
261
|
+
receive(chunk);
|
|
262
|
+
}
|
|
233
263
|
};
|
|
234
264
|
|
|
235
265
|
return { attach };
|