mixdog 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/scripts/build-shipped-history.mjs +115 -33
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/gate-local.mjs +183 -63
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/gate-scheduler.mjs +138 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +91 -66
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +124 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +16 -4
- package/scripts/lib/test-spawn-ledger.mjs +12 -3
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -5
- package/scripts/suite-health.mjs +115 -24
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/app.mjs +4 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +23 -2
- package/src/defaults/skills/browser-use/SKILL.md +10 -5
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +16 -4
- package/src/defaults/skills/goal-management/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +12 -6
- package/src/defaults/skills/setup/references/surfaces.md +2 -2
- package/src/defaults/skills/setup-guide/SKILL.md +5 -2
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/rules-builder.cjs +35 -42
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +5 -4
- package/src/rules/lead/LEAD.md +12 -7
- package/src/rules/shared/10-tool-workflow.md +3 -1
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +8 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
- package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/whisper-port.mjs +29 -11
- package/src/runtime/channels/lib/whisper-server.mjs +10 -1
- package/src/runtime/computer-bridge/action-schema.mjs +2 -2
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
- package/src/runtime/connectors/gmail-app-password.mjs +3 -3
- package/src/runtime/explore/explorer.mjs +93 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/index.mjs +4 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +15 -6
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +11 -4
- package/src/runtime/shared/connector-catalog.mjs +60 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/defaults-separation.mjs +1 -4
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +13 -15
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
- package/src/runtime/shared/llm/cost.mjs +11 -2
- package/src/runtime/shared/llm/http-agent.mjs +313 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +452 -0
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/session-activity-signal.mjs +14 -0
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +113 -36
- package/src/runtime/shared/tool-work-units.mjs +6 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +72 -0
- package/src/runtime/shared/worktrees/manager.mjs +285 -168
- package/src/runtime/shared/worktrees/test-support.mjs +6 -10
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +7 -4
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +6 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +1 -1
- package/src/session-runtime/agent-home-delivery.mjs +41 -0
- package/src/session-runtime/agent-task-sessions.mjs +458 -312
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/bot-status.mjs +107 -101
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +401 -36
- package/src/session-runtime/conversation-import/service.mjs +35 -8
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
- package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +10 -6
- package/src/session-runtime/services/provider-admin.mjs +283 -11
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +6 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
- package/src/session-runtime/turn/agent-ops.mjs +23 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +108 -1041
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
- package/src/standalone/daemon-desktop-runtime.mjs +2 -0
- package/src/standalone/daemon-session-control.mjs +169 -138
- package/src/standalone/daemon.mjs +7 -0
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +5 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/App.jsx +154 -164
- package/src/tui/app/app-view/floating-panel.jsx +10 -4
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +21 -10
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +29 -18
- package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
- package/src/tui/app/slash-commands.mjs +1 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +3 -2
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +47 -32
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/dist/index.mjs +1963 -1361
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
|
@@ -22,7 +22,12 @@ import {
|
|
|
22
22
|
expiryFromAccessToken,
|
|
23
23
|
isDefinitiveOAuthFailure,
|
|
24
24
|
normalizeAccountIdentity,
|
|
25
|
+
oauthBodySummary,
|
|
25
26
|
oauthCredentialStatus,
|
|
27
|
+
oauthFailureReason,
|
|
28
|
+
oauthPublicError,
|
|
29
|
+
oauthRequestError,
|
|
30
|
+
oauthResponseJson,
|
|
26
31
|
scrubOAuthSecrets,
|
|
27
32
|
} from './lib/oauth-token-utils.mjs';
|
|
28
33
|
import { createOAuthPkce, parseOAuthCodeInput } from './lib/oauth-pkce.mjs';
|
|
@@ -271,7 +276,7 @@ export function _scrubTokens(text, secretValues = []) {
|
|
|
271
276
|
}
|
|
272
277
|
|
|
273
278
|
function _tokenEndpointError(operation, status, text, secretValues = []) {
|
|
274
|
-
const safeDetail =
|
|
279
|
+
const safeDetail = oauthBodySummary(text, secretValues);
|
|
275
280
|
const detail = safeDetail ? `: ${safeDetail}` : '';
|
|
276
281
|
const compatibility =
|
|
277
282
|
status === 403
|
|
@@ -282,7 +287,7 @@ function _tokenEndpointError(operation, status, text, secretValues = []) {
|
|
|
282
287
|
' update Mixdog or set MIXDOG_CLI_VERSION to the installed official Claude Code version;' +
|
|
283
288
|
' then retry sign-in via /providers without an intercepting network layer if applicable.'
|
|
284
289
|
: '';
|
|
285
|
-
return new Error(`${operation} ${status}${detail}.${compatibility}`);
|
|
290
|
+
return oauthPublicError(new Error(`${operation} ${status}${detail}.${compatibility}`));
|
|
286
291
|
}
|
|
287
292
|
|
|
288
293
|
export function isAnthropicOAuthRefreshDisabled() {
|
|
@@ -578,21 +583,26 @@ async function exchangeAuthorizationCode({ pkce, code, state, redirectUri, signa
|
|
|
578
583
|
const cleanCode = String(code || '').trim();
|
|
579
584
|
if (!cleanCode) throw new Error('[anthropic-oauth] authorization code is required');
|
|
580
585
|
const timeoutSignal = AbortSignal.timeout(OAUTH_TOKEN_TIMEOUT_MS);
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
586
|
+
let tokenRes;
|
|
587
|
+
try {
|
|
588
|
+
tokenRes = await fetch(TOKEN_URL, {
|
|
589
|
+
method: 'POST',
|
|
590
|
+
headers: tokenEndpointHeaders(),
|
|
591
|
+
body: JSON.stringify({
|
|
592
|
+
grant_type: 'authorization_code',
|
|
593
|
+
code: cleanCode,
|
|
594
|
+
redirect_uri: redirectUri,
|
|
595
|
+
client_id: CLAUDE_CODE_CLIENT_ID,
|
|
596
|
+
code_verifier: pkce.verifier,
|
|
597
|
+
state,
|
|
598
|
+
}),
|
|
599
|
+
redirect: 'error',
|
|
600
|
+
signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal,
|
|
601
|
+
dispatcher: getLlmDispatcher(),
|
|
602
|
+
});
|
|
603
|
+
} catch (err) {
|
|
604
|
+
throw oauthRequestError('[anthropic-oauth] token exchange', err);
|
|
605
|
+
}
|
|
596
606
|
if (!tokenRes.ok) {
|
|
597
607
|
const text = await tokenRes.text().catch(() => '');
|
|
598
608
|
throw _tokenEndpointError('[anthropic-oauth] token exchange', tokenRes.status, text, [
|
|
@@ -601,7 +611,7 @@ async function exchangeAuthorizationCode({ pkce, code, state, redirectUri, signa
|
|
|
601
611
|
state,
|
|
602
612
|
]);
|
|
603
613
|
}
|
|
604
|
-
const json = await tokenRes
|
|
614
|
+
const json = await oauthResponseJson(tokenRes, '[anthropic-oauth] token exchange');
|
|
605
615
|
const accessToken = json?.access_token || json?.accessToken;
|
|
606
616
|
const refreshToken = json?.refresh_token || json?.refreshToken;
|
|
607
617
|
if (!accessToken || !refreshToken) {
|
|
@@ -727,10 +737,10 @@ export async function beginOAuthLogin({ openBrowserFn = null, openBrowser = true
|
|
|
727
737
|
await acceptCode(code, OAUTH_REDIRECT_URI);
|
|
728
738
|
res.writeHead(200, { 'Content-Type': OAUTH_PAGE_CONTENT_TYPE, Connection: 'close' });
|
|
729
739
|
res.end(oauthSuccessHtml('Claude'));
|
|
730
|
-
} catch {
|
|
731
|
-
// The shared exchange reports its error through waitForCallback.
|
|
740
|
+
} catch (err) {
|
|
741
|
+
// The shared exchange also reports its error through waitForCallback.
|
|
732
742
|
res.writeHead(500, { 'Content-Type': OAUTH_PAGE_CONTENT_TYPE, Connection: 'close' });
|
|
733
|
-
res.end(oauthErrorHtml('Claude could not complete the token exchange.'));
|
|
743
|
+
res.end(oauthErrorHtml(oauthFailureReason('Claude could not complete the token exchange.', err)));
|
|
734
744
|
}
|
|
735
745
|
});
|
|
736
746
|
timeout = setTimeout(() => finish(null), OAUTH_LOGIN_TIMEOUT_MS);
|
|
@@ -50,7 +50,9 @@ export function anthropicQuotaError(status, headers, bodyText = '') {
|
|
|
50
50
|
const detail = bodyText ? `: ${String(bodyText).slice(0, 200)}` : '';
|
|
51
51
|
const retry = retryAfter ? ` retryAfter=${retryAfter}` : '';
|
|
52
52
|
const quota = hasQuotaHeaders(headers);
|
|
53
|
-
const err = new Error(
|
|
53
|
+
const err = new Error(
|
|
54
|
+
`Anthropic OAuth API ${status} ${quota ? 'quota/rate limit' : 'request rejected'}${retry}${detail}`
|
|
55
|
+
);
|
|
54
56
|
err.name = quota ? 'ProviderQuotaError' : 'ProviderRequestRejectedError';
|
|
55
57
|
err.headers = headers;
|
|
56
58
|
err.response = { status, headers };
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { traceAgentSse, traceAgentUsage } from '../agent-trace.mjs';
|
|
9
9
|
import {
|
|
10
10
|
anthropicPrefixFingerprint,
|
|
11
|
+
anthropicPrefixSessionId,
|
|
11
12
|
latestAnthropicPrefix,
|
|
12
13
|
recordAnthropicPrefix,
|
|
13
14
|
} from './lib/anthropic-prefix-trace.mjs';
|
|
@@ -555,7 +556,7 @@ export class AnthropicOAuthProvider {
|
|
|
555
556
|
const body = buildRequestBody(messages, useModel, tools, sendOpts);
|
|
556
557
|
body.messages = await prepareAnthropicImages(body.messages, { signal: externalSignal });
|
|
557
558
|
// Diagnostic: per-block prefix hashes of exactly what is sent.
|
|
558
|
-
recordAnthropicPrefix(opts
|
|
559
|
+
recordAnthropicPrefix(anthropicPrefixSessionId(opts), anthropicPrefixFingerprint(body));
|
|
559
560
|
if (body.speed === 'fast') {
|
|
560
561
|
this.fastModeBetaHeaderLatched = true;
|
|
561
562
|
}
|
|
@@ -652,6 +653,7 @@ export class AnthropicOAuthProvider {
|
|
|
652
653
|
iteration,
|
|
653
654
|
useModel,
|
|
654
655
|
requestKind: opts.requestKind || null,
|
|
656
|
+
prefixSessionId: anthropicPrefixSessionId(opts),
|
|
655
657
|
});
|
|
656
658
|
tagMidstreamRetries(result, attemptIndex);
|
|
657
659
|
return result;
|
|
@@ -887,7 +889,16 @@ export class AnthropicOAuthProvider {
|
|
|
887
889
|
}
|
|
888
890
|
|
|
889
891
|
// Traces + catalog upkeep for a streamed turn, then the empty-stream guard.
|
|
890
|
-
_settleStreamedTurn({
|
|
892
|
+
_settleStreamedTurn({
|
|
893
|
+
result,
|
|
894
|
+
midState,
|
|
895
|
+
sseStartedAt,
|
|
896
|
+
sessionId,
|
|
897
|
+
iteration,
|
|
898
|
+
useModel,
|
|
899
|
+
requestKind,
|
|
900
|
+
prefixSessionId,
|
|
901
|
+
}) {
|
|
891
902
|
const ttftMs = midState.ttftAt ? midState.ttftAt - sseStartedAt : null;
|
|
892
903
|
const liveModel = result.model || useModel;
|
|
893
904
|
traceAgentSse({
|
|
@@ -912,7 +923,7 @@ export class AnthropicOAuthProvider {
|
|
|
912
923
|
rawUsage: result.usage?.raw || null,
|
|
913
924
|
provider: 'anthropic-oauth',
|
|
914
925
|
requestKind,
|
|
915
|
-
prefixBlocks: latestAnthropicPrefix(
|
|
926
|
+
prefixBlocks: latestAnthropicPrefix(prefixSessionId),
|
|
916
927
|
});
|
|
917
928
|
|
|
918
929
|
// Phase I: if the live response surfaced a model id we don't know
|
|
@@ -161,6 +161,12 @@ function applyAnthropicSseEvent(framedEvent, { turn, watchdogs, state, progress,
|
|
|
161
161
|
return false;
|
|
162
162
|
case 'message_delta':
|
|
163
163
|
return turn.onMessageDelta(event);
|
|
164
|
+
case 'ping':
|
|
165
|
+
// Anthropic bridges long generation gaps (adaptive thinking, a buffered
|
|
166
|
+
// tool input) with `ping` events. A distinct kind, not 'semantic': the
|
|
167
|
+
// agent watchdog decides how far a keepalive may extend liveness.
|
|
168
|
+
progress('keepalive');
|
|
169
|
+
return false;
|
|
164
170
|
case 'message_stop':
|
|
165
171
|
turn.onMessageStop();
|
|
166
172
|
// Anthropic streams can keep emitting `:ping` keepalive frames after
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { traceAgentUsage } from '../agent-trace.mjs';
|
|
13
13
|
import { reportedCostUsd } from './lib/usage-primitives.mjs';
|
|
14
|
-
import { latestAnthropicPrefix } from './lib/anthropic-prefix-trace.mjs';
|
|
14
|
+
import { anthropicPrefixSessionId, latestAnthropicPrefix } from './lib/anthropic-prefix-trace.mjs';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* @param {object} parseResult the assembled turn (streaming or normalized non-streaming)
|
|
@@ -48,7 +48,7 @@ export function buildAnthropicTurnResult(parseResult, { provider, useModel, opts
|
|
|
48
48
|
// Anthropic usage is additive at this inner transport
|
|
49
49
|
// boundary, even when OpenCode Go supplies the provider id.
|
|
50
50
|
inputTokensInclusive: false,
|
|
51
|
-
prefixBlocks: latestAnthropicPrefix(opts
|
|
51
|
+
prefixBlocks: latestAnthropicPrefix(anthropicPrefixSessionId(opts)),
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -266,7 +266,9 @@ export async function exchangeAuthorizationCode({ code, verifier, fetchFn = fetc
|
|
|
266
266
|
});
|
|
267
267
|
if (!res.ok) {
|
|
268
268
|
const text = await res.text().catch(() => '');
|
|
269
|
-
|
|
269
|
+
// The authorization code is redacted by value: `code` alone is not a secret field.
|
|
270
|
+
const detail = _scrubTokens(text, [cleanCode, verifier]).slice(0, 300);
|
|
271
|
+
throw new Error(`[antigravity-oauth] token exchange ${res.status}: ${detail}`);
|
|
270
272
|
}
|
|
271
273
|
const json = await res.json();
|
|
272
274
|
if (!json?.access_token || !json?.refresh_token) {
|
|
@@ -231,8 +231,8 @@ export function saveTokens(tokens) {
|
|
|
231
231
|
);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
export function _scrubTokens(text) {
|
|
235
|
-
return scrubOAuthSecrets(text);
|
|
234
|
+
export function _scrubTokens(text, secretValues = []) {
|
|
235
|
+
return scrubOAuthSecrets(text, secretValues);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
export function hasAntigravityOAuthCredentials() {
|
|
@@ -20,7 +20,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
|
|
|
20
20
|
// version (gpt-6.1-sol requires >= 0.159.0, measured 2026-10-09), so the
|
|
21
21
|
// release workflow raises this to the published CLI version on every release
|
|
22
22
|
// (scripts/sync-client-version-floors.mjs).
|
|
23
|
-
export const CODEX_CLIENT_VERSION_FLOOR = '0.
|
|
23
|
+
export const CODEX_CLIENT_VERSION_FLOOR = '0.165.0';
|
|
24
24
|
export const CODEX_CLI_NPM_PACKAGE = '@openai/codex';
|
|
25
25
|
const live = createNpmVersionSource(CODEX_CLI_NPM_PACKAGE, { persistKey: 'codex-cli' });
|
|
26
26
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// A pasted key or pasted callback JSON completes the same login by hand. The
|
|
4
4
|
// first sign-in on a machine adopts an existing Command Code CLI login instead.
|
|
5
5
|
import { createServer } from 'node:http';
|
|
6
|
+
import { listenOn } from './lib/listen-on.mjs';
|
|
6
7
|
import { randomBytes } from 'node:crypto';
|
|
7
8
|
import { readFileSync } from 'node:fs';
|
|
8
9
|
import { homedir } from 'node:os';
|
|
@@ -95,16 +96,6 @@ function readLocalAuth(path) {
|
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
function listenOn(server, port, host) {
|
|
99
|
-
return new Promise((resolve, reject) => {
|
|
100
|
-
server.once('error', reject);
|
|
101
|
-
server.listen(port, host, () => {
|
|
102
|
-
server.off('error', reject);
|
|
103
|
-
resolve();
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
99
|
function readBody(req) {
|
|
109
100
|
return new Promise((resolve, reject) => {
|
|
110
101
|
const chunks = [];
|
|
@@ -361,7 +361,7 @@ export class CommandCodeOAuthProvider {
|
|
|
361
361
|
if (Array.isArray(body?.data)) list = body.data;
|
|
362
362
|
else if (Array.isArray(body)) list = body;
|
|
363
363
|
const items = list.filter((item) => modelWire(item));
|
|
364
|
-
publish(items.map(rosterRow));
|
|
364
|
+
await publish(items.map(rosterRow));
|
|
365
365
|
if (this.tokens?.apiKey === apiKey) {
|
|
366
366
|
// Rows accumulate for one key: a later roster that misses a model
|
|
367
367
|
// leaves the endpoints it was last listed with.
|
|
@@ -677,6 +677,9 @@ class CursorProviderBase {
|
|
|
677
677
|
return await consumeCompatChatCompletionStream(responseSseEvents(response, signal), {
|
|
678
678
|
signal,
|
|
679
679
|
label: this.name,
|
|
680
|
+
// The wrapper below always exists; the stream joins the session's
|
|
681
|
+
// logical request only when the caller reports progress into it.
|
|
682
|
+
sessionId: typeof sendOpts.onStreamDelta === 'function' ? sendOpts.sessionId : null,
|
|
680
683
|
onStreamDelta: (delta) => {
|
|
681
684
|
sendOpts.onStreamDelta?.(delta);
|
|
682
685
|
},
|
|
@@ -12,13 +12,21 @@ export const CUSTOM_REASONING_LEVELS = CUSTOM_EFFORT_LEVELS;
|
|
|
12
12
|
export const CUSTOM_REASONING_WIRE_FORMATS = Object.freeze(['standard', 'deepseek', 'together', 'vllm']);
|
|
13
13
|
export const CUSTOM_PROVIDER_AUTH_MODES = Object.freeze(['key', 'none']);
|
|
14
14
|
export const CUSTOM_MODEL_OVERRIDE_LIMIT = 500;
|
|
15
|
+
export const CUSTOM_HEADER_LIMIT = 64;
|
|
15
16
|
|
|
16
17
|
const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
17
18
|
const MAX_MODEL_ID = 256;
|
|
18
19
|
const MAX_NAME = 200;
|
|
19
20
|
const MAX_WIRE_VALUE = 64;
|
|
21
|
+
const MAX_HEADER_TEXT = 4096;
|
|
20
22
|
// biome-ignore lint/suspicious/noControlCharactersInRegex: rejecting control characters is the point.
|
|
21
23
|
const CONTROL_CHARS = /[\u0000-\u001f\u007f]/;
|
|
24
|
+
// RFC 9110 field-name token, and a field value of visible ASCII, space, tab and
|
|
25
|
+
// obs-text (what a fetch Headers value can carry).
|
|
26
|
+
const HEADER_NAME = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
27
|
+
const HEADER_VALUE = /^[\t\x20-\x7e\x80-\xff]*$/;
|
|
28
|
+
// The API key field owns authentication; a header may not carry a credential.
|
|
29
|
+
const AUTH_HEADERS = new Set(['authorization', 'x-api-key', 'api-key']);
|
|
22
30
|
|
|
23
31
|
function fail(message) {
|
|
24
32
|
throw new Error(`[custom-provider] ${message}`);
|
|
@@ -84,6 +92,7 @@ const V2_TOP_LEVEL_KEYS = new Set([
|
|
|
84
92
|
'modelOverrides',
|
|
85
93
|
'wires',
|
|
86
94
|
'modelWires',
|
|
95
|
+
'headers',
|
|
87
96
|
'id',
|
|
88
97
|
'apiKey',
|
|
89
98
|
'apiKeyEnv',
|
|
@@ -295,6 +304,34 @@ function normalizeModelWires(raw, protocol, wires) {
|
|
|
295
304
|
return out;
|
|
296
305
|
}
|
|
297
306
|
|
|
307
|
+
// `headers`: extra HTTP headers sent with every request to the endpoint
|
|
308
|
+
// (inference, model discovery, connection test). Names are case-insensitive
|
|
309
|
+
// tokens; the credential headers belong to the API key field.
|
|
310
|
+
function normalizeHeaders(raw) {
|
|
311
|
+
if (raw === undefined) return {};
|
|
312
|
+
if (!isPlainObject(raw)) fail('headers must be an object of header names to string values');
|
|
313
|
+
const names = Object.keys(raw);
|
|
314
|
+
if (names.length > CUSTOM_HEADER_LIMIT) fail(`at most ${CUSTOM_HEADER_LIMIT} headers are allowed`);
|
|
315
|
+
const seen = new Set();
|
|
316
|
+
const entries = [];
|
|
317
|
+
for (const name of names) {
|
|
318
|
+
if (name.length > MAX_HEADER_TEXT || !HEADER_NAME.test(name))
|
|
319
|
+
fail(`headers has an invalid header name: ${JSON.stringify(name.slice(0, 64))}`);
|
|
320
|
+
const lower = name.toLowerCase();
|
|
321
|
+
if (AUTH_HEADERS.has(lower)) fail(`headers must not set ${name}: authentication belongs to the API key field`);
|
|
322
|
+
if (seen.has(lower)) fail(`headers has duplicate header: ${name}`);
|
|
323
|
+
seen.add(lower);
|
|
324
|
+
if (typeof raw[name] !== 'string') fail(`headers.${name} must be a string`);
|
|
325
|
+
// Validate before trimming, and trim only HTTP whitespace (space, tab), so
|
|
326
|
+
// CR/LF is refused rather than stripped and other characters are kept.
|
|
327
|
+
if (!HEADER_VALUE.test(raw[name])) fail(`headers.${name} has an invalid value`);
|
|
328
|
+
const value = raw[name].replace(/^[ \t]+|[ \t]+$/g, '');
|
|
329
|
+
if (value.length > MAX_HEADER_TEXT) fail(`headers.${name} has an invalid value`);
|
|
330
|
+
entries.push([name, value]);
|
|
331
|
+
}
|
|
332
|
+
return Object.fromEntries(entries);
|
|
333
|
+
}
|
|
334
|
+
|
|
298
335
|
// Legacy (pre-v2) `models: [{ id, name?, contextWindow?, maxOutputTokens? }]`
|
|
299
336
|
// become manual, visible overrides; their presence hides newly discovered ids.
|
|
300
337
|
function migrateLegacy(input) {
|
|
@@ -336,6 +373,7 @@ export function normalizeCustomProviderConfig(input) {
|
|
|
336
373
|
fail('modelOverrides and discovery require schemaVersion 2');
|
|
337
374
|
if (input.wires !== undefined || input.modelWires !== undefined)
|
|
338
375
|
fail('wires and modelWires require schemaVersion 2');
|
|
376
|
+
if (input.headers !== undefined) fail('headers require schemaVersion 2');
|
|
339
377
|
source = migrateLegacy(input);
|
|
340
378
|
} else if (Number.isInteger(version) && version > CUSTOM_PROVIDER_SCHEMA_VERSION)
|
|
341
379
|
fail(`unsupported schemaVersion ${version}; update mixdog to use this provider`);
|
|
@@ -368,6 +406,7 @@ export function normalizeCustomProviderConfig(input) {
|
|
|
368
406
|
const newModelsHidden = optionalBoolean(discovery.newModelsHidden, 'discovery.newModelsHidden') ?? false;
|
|
369
407
|
const wires = normalizeWires(source.wires, protocol);
|
|
370
408
|
const modelWires = normalizeModelWires(source.modelWires, protocol, wires);
|
|
409
|
+
const headers = normalizeHeaders(source.headers);
|
|
371
410
|
return {
|
|
372
411
|
type: 'custom',
|
|
373
412
|
schemaVersion: CUSTOM_PROVIDER_SCHEMA_VERSION,
|
|
@@ -377,6 +416,7 @@ export function normalizeCustomProviderConfig(input) {
|
|
|
377
416
|
enabled: source.enabled !== false,
|
|
378
417
|
auth,
|
|
379
418
|
...(apiKeyEnv && auth === 'key' ? { apiKeyEnv } : {}),
|
|
419
|
+
...(Object.keys(headers).length ? { headers } : {}),
|
|
380
420
|
discovery: { newModelsHidden },
|
|
381
421
|
modelOverrides: normalizeOverrides(source.modelOverrides, protocol, legacy),
|
|
382
422
|
...(wires ? { wires } : {}),
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// The engine a custom provider sends with when one of its additional API keys
|
|
2
|
+
// serves (account-pool.mjs `createCustomKeyPoolProvider`). Every key reaches
|
|
3
|
+
// the same endpoint, so the engine is a view of the primary instance: the
|
|
4
|
+
// catalog, discovered models, wire routes and settings stay the primary's,
|
|
5
|
+
// and only the credential and the client built from it are the key's own.
|
|
6
|
+
|
|
7
|
+
import { readCustomProviderKey } from '../../../shared/custom-provider-keys.mjs';
|
|
8
|
+
|
|
9
|
+
function keyView(engine, providerId, keyId, key) {
|
|
10
|
+
const view = Object.create(engine);
|
|
11
|
+
const rekey = (value) => {
|
|
12
|
+
// The key is the only source: an environment variable names the primary key alone.
|
|
13
|
+
view.config = { ...engine.config, apiKey: value, apiKeyEnv: undefined };
|
|
14
|
+
view.apiKey = value;
|
|
15
|
+
view.client = view._createClient(value);
|
|
16
|
+
};
|
|
17
|
+
rekey(key);
|
|
18
|
+
// An auth retry re-reads this key, never the primary's keychain entry.
|
|
19
|
+
view.reloadApiKey = () => {
|
|
20
|
+
const fresh = readCustomProviderKey(providerId, keyId);
|
|
21
|
+
if (fresh) rekey(fresh);
|
|
22
|
+
};
|
|
23
|
+
return view;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** `primary` sending with additional key `keyId` of custom provider `providerId`. */
|
|
27
|
+
export function customKeyEngine(primary, providerId, keyId) {
|
|
28
|
+
const key = readCustomProviderKey(providerId, keyId);
|
|
29
|
+
if (!key) throw new Error(`An additional API key of ${providerId} is not readable; enter it again in its settings.`);
|
|
30
|
+
const engine = keyView(primary, providerId, keyId, key);
|
|
31
|
+
// A Messages-wire route sends through the bound Anthropic engine.
|
|
32
|
+
if (primary.messagesEngine) engine.messagesEngine = keyView(primary.messagesEngine, providerId, keyId, key);
|
|
33
|
+
return engine;
|
|
34
|
+
}
|
|
@@ -120,6 +120,7 @@ async function discoverAnthropicModels(provider, signal, timeoutMs = DISCOVERY_T
|
|
|
120
120
|
headers: {
|
|
121
121
|
...(provider._customKeyless ? {} : { 'x-api-key': provider._customKey() }),
|
|
122
122
|
'anthropic-version': ANTHROPIC_VERSION,
|
|
123
|
+
...(provider.config.extraHeaders || {}),
|
|
123
124
|
},
|
|
124
125
|
});
|
|
125
126
|
if (!res.ok) throw Object.assign(new Error(`${provider.name} models ${res.status}`), { status: res.status });
|
|
@@ -153,6 +154,8 @@ export async function createCustomProvider(id, config) {
|
|
|
153
154
|
apiKey: apiKey || undefined,
|
|
154
155
|
...(cfg.apiKeyEnv ? { apiKeyEnv: cfg.apiKeyEnv } : {}),
|
|
155
156
|
...(keyless ? { keyless: true } : {}),
|
|
157
|
+
// User-defined headers ride the engines' existing `extraHeaders` path.
|
|
158
|
+
...(cfg.headers ? { extraHeaders: cfg.headers } : {}),
|
|
156
159
|
...(config.preconnect === false ? { preconnect: false } : {}),
|
|
157
160
|
};
|
|
158
161
|
let provider;
|
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
decodeJwtPayload,
|
|
15
15
|
expiryFromAccessToken,
|
|
16
16
|
normalizeAccountIdentity,
|
|
17
|
+
OAUTH_NETWORK_HINT,
|
|
18
|
+
oauthFailureReason,
|
|
19
|
+
oauthNetworkCause,
|
|
20
|
+
oauthPublicError,
|
|
17
21
|
} from './lib/oauth-token-utils.mjs';
|
|
18
22
|
|
|
19
23
|
const AUTHORIZE_URL = 'https://app.devin.ai/auth/cli/continue';
|
|
@@ -46,9 +50,11 @@ export const DEVIN_OAUTH_FAILURE_CODES = Object.freeze([
|
|
|
46
50
|
'DEVIN_OAUTH_TOKEN_EXCHANGE_FAILED',
|
|
47
51
|
]);
|
|
48
52
|
|
|
53
|
+
// Built from fixed text, statuses and error codes only, so a failure page may
|
|
54
|
+
// show it; response bodies are never quoted (they may carry the login token).
|
|
49
55
|
function loginFailure(code, text, props = {}) {
|
|
50
56
|
const failureCode = `DEVIN_OAUTH_${code}`;
|
|
51
|
-
return Object.assign(new Error(`${failureCode}: ${text}`), { failureCode }, props);
|
|
57
|
+
return oauthPublicError(Object.assign(new Error(`${failureCode}: ${text}`), { failureCode }, props));
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
function credentialsPath() {
|
|
@@ -175,12 +181,13 @@ export async function exchangeDevinCode(code, verifier, { fetchFn = fetch, signa
|
|
|
175
181
|
});
|
|
176
182
|
} catch (error) {
|
|
177
183
|
// A cancelled login keeps its own abort; any other failure to get an
|
|
178
|
-
// answer (network, timeout) is a coded exchange failure.
|
|
179
|
-
// quoted: only its
|
|
184
|
+
// answer (network, timeout) is a coded exchange failure. Its message is
|
|
185
|
+
// not quoted: only its error code.
|
|
180
186
|
if (signal?.aborted) throw error;
|
|
187
|
+
const cause = oauthNetworkCause(error) || 'network error';
|
|
181
188
|
throw loginFailure(
|
|
182
189
|
'TOKEN_EXCHANGE_FAILED',
|
|
183
|
-
|
|
190
|
+
`Devin token exchange request failed (${cause}). ${OAUTH_NETWORK_HINT}`
|
|
184
191
|
);
|
|
185
192
|
}
|
|
186
193
|
// Response bodies may carry the login token itself, so none is ever quoted
|
|
@@ -341,9 +348,9 @@ async function startDevinOAuthLogin({ openBrowser = true, timeoutMs = LOGIN_TIME
|
|
|
341
348
|
try {
|
|
342
349
|
await acceptCode(code);
|
|
343
350
|
reply(res, 200, oauthSuccessHtml('Devin'));
|
|
344
|
-
} catch {
|
|
345
|
-
// The shared exchange reports its error through waitForCallback.
|
|
346
|
-
reply(res, 500, oauthErrorHtml('Devin could not complete the token exchange.'));
|
|
351
|
+
} catch (error) {
|
|
352
|
+
// The shared exchange also reports its error through waitForCallback.
|
|
353
|
+
reply(res, 500, oauthErrorHtml(oauthFailureReason('Devin could not complete the token exchange.', error)));
|
|
347
354
|
}
|
|
348
355
|
};
|
|
349
356
|
|
|
@@ -190,10 +190,11 @@ function connectError(
|
|
|
190
190
|
const finalCode = tooLarge ? 'request_too_large' : mixdogCode;
|
|
191
191
|
const head = `Devin ${operation} ${code || 'error'}${status ? ` (HTTP ${status})` : ''}`;
|
|
192
192
|
const text = [head, detail].filter(Boolean).join(': ') + (detailsSummary ? ` [details: ${detailsSummary}]` : '');
|
|
193
|
+
// A reworded throttle reports its throttle status, not the carrier's.
|
|
194
|
+
const carrierStatus = reworded ? mappedStatus : status || mappedStatus;
|
|
193
195
|
const error = new DevinWireError(text, {
|
|
194
196
|
code: finalCode,
|
|
195
|
-
|
|
196
|
-
status: tooLarge ? 413 : (reworded ? mappedStatus : status || mappedStatus),
|
|
197
|
+
status: tooLarge ? 413 : carrierStatus,
|
|
197
198
|
retryable: tooLarge ? false : retryable,
|
|
198
199
|
connectCode: code,
|
|
199
200
|
detail: [detail, detailsSummary].filter(Boolean).join(' '),
|
|
@@ -405,6 +405,9 @@ export class DevinOAuthProvider {
|
|
|
405
405
|
signal,
|
|
406
406
|
label: this.name,
|
|
407
407
|
providerName: this.name,
|
|
408
|
+
// The wrapper below always exists; the stream joins the session's
|
|
409
|
+
// logical request only when the caller reports progress into it.
|
|
410
|
+
sessionId: typeof sendOpts.onStreamDelta === 'function' ? sendOpts.sessionId : null,
|
|
408
411
|
onStreamDelta: (delta) => {
|
|
409
412
|
if (!streaming) {
|
|
410
413
|
streaming = true;
|
|
@@ -115,7 +115,7 @@ export function geminiFailureUsage(opts, cachedContent, useModel) {
|
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
export function resolveGeminiUsage(response, opts, cachedContent, useModel) {
|
|
118
|
+
export function resolveGeminiUsage(response, opts, cachedContent, useModel, provider = 'gemini') {
|
|
119
119
|
const um = response.usageMetadata || null;
|
|
120
120
|
if (!um) return null;
|
|
121
121
|
const iteration = Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null;
|
|
@@ -143,7 +143,7 @@ export function resolveGeminiUsage(response, opts, cachedContent, useModel) {
|
|
|
143
143
|
model: useModel,
|
|
144
144
|
modelDisplay: useModel,
|
|
145
145
|
rawUsage: um,
|
|
146
|
-
provider
|
|
146
|
+
provider,
|
|
147
147
|
});
|
|
148
148
|
return resolvedUsage;
|
|
149
149
|
}
|
|
@@ -589,6 +589,9 @@ export async function consumeGeminiRestStreamResponse(
|
|
|
589
589
|
onChunk = null,
|
|
590
590
|
failureUsage = null,
|
|
591
591
|
firstByteTimeoutMs = GEMINI_FIRST_BYTE_TIMEOUT_MS,
|
|
592
|
+
// A first-byte window longer than the idle window must govern alone until
|
|
593
|
+
// the first payload, or the idle timer would cut the wait short.
|
|
594
|
+
idleAfterFirstChunk = false,
|
|
592
595
|
}
|
|
593
596
|
) {
|
|
594
597
|
const unwrap =
|
|
@@ -649,7 +652,7 @@ export async function consumeGeminiRestStreamResponse(
|
|
|
649
652
|
}
|
|
650
653
|
|
|
651
654
|
try {
|
|
652
|
-
watchdogs.resetIdle();
|
|
655
|
+
if (!idleAfterFirstChunk) watchdogs.resetIdle();
|
|
653
656
|
while (true) {
|
|
654
657
|
let chunk;
|
|
655
658
|
try {
|