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
|
@@ -20,6 +20,60 @@ import { assertWorktreeMutationAllowed, worktreeCallerScope } from '../services/
|
|
|
20
20
|
|
|
21
21
|
const loadManager = () => import('../../runtime/shared/worktrees/manager.mjs');
|
|
22
22
|
|
|
23
|
+
async function enter(lane, request) {
|
|
24
|
+
if (request.branch) {
|
|
25
|
+
return lane.call('selectBranch', {
|
|
26
|
+
branch: request.branch,
|
|
27
|
+
create: request.create === true,
|
|
28
|
+
confirmLarge: request.confirmLarge === true,
|
|
29
|
+
txId: request.txId,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// A valid slug names the worktree; any other text is a hint the slug is made from.
|
|
33
|
+
const name = typeof request.name === 'string' ? request.name.trim() : '';
|
|
34
|
+
const slug = name && !worktreeNameError(name) ? name : null;
|
|
35
|
+
return lane.call('requestWorktree', {
|
|
36
|
+
provision: true,
|
|
37
|
+
name: slug,
|
|
38
|
+
prompt: slug ? '' : name,
|
|
39
|
+
...(request.carry ? { carryChanges: request.carry } : {}),
|
|
40
|
+
confirmLarge: request.confirmLarge === true,
|
|
41
|
+
txId: request.txId,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Back to the project folder (the branch checked out there); the worktree stays retained. */
|
|
46
|
+
async function back(lane, request) {
|
|
47
|
+
const menu = await lane.menu();
|
|
48
|
+
const workspace = menu.workspace;
|
|
49
|
+
if (!workspace.worktreeId && samePath(workspace.cwd, workspace.projectPath)) {
|
|
50
|
+
return { revision: workspace.revision, workspace, unchanged: true };
|
|
51
|
+
}
|
|
52
|
+
const projectBranch = menu.occupancy.find((row) => row.kind === 'current')?.branch ?? null;
|
|
53
|
+
if (!projectBranch) {
|
|
54
|
+
throw worktreeError(
|
|
55
|
+
'WORKTREE_UNSUPPORTED_REPO',
|
|
56
|
+
'The project folder has no checked-out branch to return to (detached HEAD).'
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return lane.call('selectBranch', {
|
|
60
|
+
branch: projectBranch,
|
|
61
|
+
expectedRevision: workspace.revision,
|
|
62
|
+
txId: request.txId,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The desktop's "merge": into the confirmed merge target, then the cleanup autoCleanup allows. */
|
|
67
|
+
async function merge(lane) {
|
|
68
|
+
const { workspace } = await lane.menu();
|
|
69
|
+
return lane.call('mergeWorkspace', {
|
|
70
|
+
confirmed: true,
|
|
71
|
+
target: workspace.mergeTarget ?? null,
|
|
72
|
+
expectedRevision: workspace.revision,
|
|
73
|
+
cleanup: true,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
23
77
|
/**
|
|
24
78
|
* @param {object} deps
|
|
25
79
|
* @param {() => any} deps.getSession The Lead session this runtime hosts (its trusted caller scope).
|
|
@@ -27,12 +81,7 @@ const loadManager = () => import('../../runtime/shared/worktrees/manager.mjs');
|
|
|
27
81
|
* @param {((args: object, context: object) => Promise<any>)|null} [deps.executeSessionControl] Cross-session lane.
|
|
28
82
|
* @param {object|null} [deps.manager] Managed-worktree backend override (tests).
|
|
29
83
|
*/
|
|
30
|
-
export function createWorktreeToolHost({
|
|
31
|
-
getSession,
|
|
32
|
-
getWorkspaceApi,
|
|
33
|
-
executeSessionControl = null,
|
|
34
|
-
manager = null,
|
|
35
|
-
}) {
|
|
84
|
+
export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSessionControl = null, manager = null }) {
|
|
36
85
|
const backend = () => (manager ? Promise.resolve(manager) : loadManager());
|
|
37
86
|
|
|
38
87
|
function workspaceApi() {
|
|
@@ -66,54 +115,13 @@ export function createWorktreeToolHost({
|
|
|
66
115
|
return { own: false, menu: () => control('getBranchMenu'), call: control };
|
|
67
116
|
}
|
|
68
117
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
// A valid slug names the worktree; any other text is a hint the slug is made from.
|
|
79
|
-
const name = typeof request.name === 'string' ? request.name.trim() : '';
|
|
80
|
-
const slug = name && !worktreeNameError(name) ? name : null;
|
|
81
|
-
return lane.call('requestWorktree', {
|
|
82
|
-
provision: true,
|
|
83
|
-
name: slug,
|
|
84
|
-
prompt: slug ? '' : name,
|
|
85
|
-
...(request.carry ? { carryChanges: request.carry } : {}),
|
|
86
|
-
confirmLarge: request.confirmLarge === true,
|
|
87
|
-
txId: request.txId,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Back to the project folder (the branch checked out there); the worktree stays retained. */
|
|
92
|
-
async function back(lane, request) {
|
|
93
|
-
const menu = await lane.menu();
|
|
94
|
-
const workspace = menu.workspace;
|
|
95
|
-
if (!workspace.worktreeId && samePath(workspace.cwd, workspace.projectPath)) {
|
|
96
|
-
return { revision: workspace.revision, workspace, unchanged: true };
|
|
97
|
-
}
|
|
98
|
-
const projectBranch = menu.occupancy.find((row) => row.kind === 'current')?.branch ?? null;
|
|
99
|
-
if (!projectBranch) {
|
|
100
|
-
throw worktreeError(
|
|
101
|
-
'WORKTREE_UNSUPPORTED_REPO',
|
|
102
|
-
'The project folder has no checked-out branch to return to (detached HEAD).'
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
return lane.call('selectBranch', { branch: projectBranch, expectedRevision: workspace.revision, txId: request.txId });
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** The desktop's "merge": into the confirmed merge target, then the cleanup autoCleanup allows. */
|
|
109
|
-
async function merge(lane) {
|
|
110
|
-
const { workspace } = await lane.menu();
|
|
111
|
-
return lane.call('mergeWorkspace', {
|
|
112
|
-
confirmed: true,
|
|
113
|
-
target: workspace.mergeTarget ?? null,
|
|
114
|
-
expectedRevision: workspace.revision,
|
|
115
|
-
cleanup: true,
|
|
116
|
-
});
|
|
118
|
+
/**
|
|
119
|
+
* The listed worktree matching `predicate` whose owner is gone and that the
|
|
120
|
+
* list reports removable, or null: no owner lane can remove it.
|
|
121
|
+
*/
|
|
122
|
+
async function orphan(predicate) {
|
|
123
|
+
const rows = await workspaceApi().listWorktrees();
|
|
124
|
+
return rows.find((row) => predicate(row) && row.ownerLive === false && row.removable === true) ?? null;
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
/**
|
|
@@ -129,6 +137,9 @@ export function createWorktreeToolHost({
|
|
|
129
137
|
);
|
|
130
138
|
}
|
|
131
139
|
if (entry.kind === 'snapshot') return workspaceApi().removeSnapshot({ path: entry.path, force: request.force });
|
|
140
|
+
if (entry.ownerSessionId !== callerSessionId && (await orphan((row) => row.id === entry.id))) {
|
|
141
|
+
return workspaceApi().removeOrphanWorktree({ entryId: entry.id, force: request.force === true });
|
|
142
|
+
}
|
|
132
143
|
if (!entry.ownerSessionId) {
|
|
133
144
|
throw new Error(
|
|
134
145
|
`git worktree remove: no session retains ${entry.path}; git worktree prune removes it once it is clean and merged`
|
|
@@ -161,8 +172,14 @@ export function createWorktreeToolHost({
|
|
|
161
172
|
return back(lane(), request);
|
|
162
173
|
case 'merge':
|
|
163
174
|
return merge(lane());
|
|
164
|
-
case 'remove':
|
|
165
|
-
|
|
175
|
+
case 'remove': {
|
|
176
|
+
const force = request.force === true;
|
|
177
|
+
if (request.sessionId && request.sessionId !== callerSessionId) {
|
|
178
|
+
const gone = await orphan((row) => row.ownerSessionId === request.sessionId);
|
|
179
|
+
if (gone) return workspaceApi().removeOrphanWorktree({ entryId: gone.id, force });
|
|
180
|
+
}
|
|
181
|
+
return lane().call('removeWorktree', { force });
|
|
182
|
+
}
|
|
166
183
|
case 'list':
|
|
167
184
|
return workspaceApi().listWorktrees({ includeSnapshots: true });
|
|
168
185
|
case 'prune':
|
|
@@ -66,6 +66,8 @@ export function createDesktopRuntime({ getLocalSessionBridge }) {
|
|
|
66
66
|
loadDocumentPreview: () => import('../runtime/office/pdf/document-preview.mjs'),
|
|
67
67
|
// The desktop service's git children start on this worker, off the loop.
|
|
68
68
|
loadProcessRunner: () => import('../runtime/shared/process-runner.mjs'),
|
|
69
|
+
// The desktop app on this PC answers this daemon's per-origin proxy lookups.
|
|
70
|
+
loadSystemProxy: () => import('../runtime/shared/llm/system-proxy.mjs'),
|
|
69
71
|
async executeCodeGraphTool(name, args, cwd) {
|
|
70
72
|
const graph = await import('../runtime/agent/orchestrator/tools/code-graph/dispatch.mjs');
|
|
71
73
|
return graph.executeCodeGraphTool(name, args, cwd);
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import { createAgentTaskSessions, taskSessionPendingWork } from '../session-runtime/agent-task-sessions.mjs';
|
|
8
8
|
import { createBotStatus, scanCatalog, scopedBot } from '../session-runtime/bot-status.mjs';
|
|
9
9
|
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
10
|
+
import { BOT_TARGET_ACTIONS, isBotShaped, unknownBotError } from '../session-runtime/bot-target.mjs';
|
|
10
11
|
import { checkEffort, readModelCatalog } from '../session-runtime/task-session-route.mjs';
|
|
11
12
|
import { assertBotChainTarget, botChainOf } from '../runtime/shared/bot-hops.mjs';
|
|
12
13
|
import { agentIdOfHomeSession } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
@@ -79,10 +80,159 @@ async function storedTitle(sessionId) {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
/** Model-facing session operations over the same service used by desktop and TUI. */
|
|
83
|
+
/** `session action=list`: live sessions first, then the filtered catalog scan. */
|
|
84
|
+
async function listSessions({ service, liveWork, readRow }, args, context, limit) {
|
|
85
|
+
assertListFlags(args);
|
|
86
|
+
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
87
|
+
// list everything with previews, a bot (or its unattended run) lists the
|
|
88
|
+
// same rows (so it can find a session to send to) but only its own carry
|
|
89
|
+
// the bot, activity, preview and working state, anything else the plain
|
|
90
|
+
// rows without previews. Sub-agent sessions (a
|
|
91
|
+
// parent finds its own through the agent tool) and archived ones (the
|
|
92
|
+
// desktop's flag) only on request; the scan pages past the rows left
|
|
93
|
+
// out, so a page is never short while more rows match.
|
|
94
|
+
const own = scopedBot(context.callerScope);
|
|
95
|
+
const archived = (await readSessionSidebarState())?.archived ?? {};
|
|
96
|
+
const keep = listRowFilter(args, archived);
|
|
97
|
+
// Live work is overlaid on every row: a catalog row keeps the status and
|
|
98
|
+
// recency of its last settled turn, so a long-running agent read `idle`
|
|
99
|
+
// and sorted by its first prompt. The first page lists the live rows
|
|
100
|
+
// first (newest sign of work first); a later page keeps catalog order,
|
|
101
|
+
// where such a row may show again (never skipped).
|
|
102
|
+
const live = await liveWork();
|
|
103
|
+
const withLive = liveRowOverlay(live);
|
|
104
|
+
// Each live session's row is read by id (wherever it sits in the
|
|
105
|
+
// catalog), filtered like the listing, and the newest `limit` lead.
|
|
106
|
+
const candidates = liveCandidates(live);
|
|
107
|
+
let pinned = [];
|
|
108
|
+
if (!args.cursor && candidates.length) {
|
|
109
|
+
pinned = pinnedLiveRows(await Promise.all(candidates.map((id) => readRow(id))), keep, withLive, limit);
|
|
110
|
+
}
|
|
111
|
+
const pinnedIds = new Set(pinned.map((row) => row.id));
|
|
112
|
+
const want = limit - pinned.length;
|
|
113
|
+
// Bounded: past 10000 rows scanned with fewer than `limit` matching, the
|
|
114
|
+
// page ends (possibly empty) with a nextCursor to continue from.
|
|
115
|
+
const scan =
|
|
116
|
+
want > 0
|
|
117
|
+
? await scanCatalog(service, (row) => !pinnedIds.has(row.id) && keep(row), {
|
|
118
|
+
cursor: args.cursor || null,
|
|
119
|
+
want,
|
|
120
|
+
maxRows: 10_000,
|
|
121
|
+
})
|
|
122
|
+
: { rows: [], nextCursor: TOP_CURSOR };
|
|
123
|
+
const sessions = listedSessions(pinned, scan.rows, withLive, archived);
|
|
124
|
+
return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, listOutputOptions(own, pinnedIds));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** `session action=send`: queue a prompt in another session (a room member, a task session or any session). */
|
|
128
|
+
async function sendToSession({ service, agentTasks }, args, context, sessionId, caller) {
|
|
129
|
+
assertSendRequest(args, sessionId);
|
|
130
|
+
// A send to a room's log is a message to one member there (`to`, or a
|
|
131
|
+
// leading @name), run by the desktop room host; the member's turn in
|
|
132
|
+
// its member session is the turn that answers and reports.
|
|
133
|
+
const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
|
|
134
|
+
if (room?.sessionId === caller) throw new Error('session: send must target another session');
|
|
135
|
+
// Work goes on to a bot (a room seat's, or a bot's home) only outside
|
|
136
|
+
// the caller's bot chain (`callerBotChain`, bot-chain.mjs), never back
|
|
137
|
+
// to the caller's own bot; the turn it starts carries that chain on.
|
|
138
|
+
const botChain = botChainOf(context.callerBotChain);
|
|
139
|
+
assertBotChainTarget(
|
|
140
|
+
room ? room.agentId : agentIdOfHomeSession(sessionId),
|
|
141
|
+
{ chain: botChain, self: context.callerBotId || context.callerAgentId || '' },
|
|
142
|
+
'session'
|
|
143
|
+
);
|
|
144
|
+
// An agent conversation's send reports its turn back to the agent's
|
|
145
|
+
// home: a task session it created by its stored origin, any other
|
|
146
|
+
// session by an origin for this send only.
|
|
147
|
+
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
148
|
+
const prompt = handoffContent(room ? room.text : args.prompt, context.attachmentParts);
|
|
149
|
+
const turnSessionId = room ? room.sessionId : sessionId;
|
|
150
|
+
const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
|
|
151
|
+
const submit = room ? roomSubmitter(room, sessionId, prompt, from) : null;
|
|
152
|
+
const addressed = room ? { to: room.agentId } : {};
|
|
153
|
+
let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
|
|
154
|
+
// `effort` is the menu's effort pick on the target: checked now against the
|
|
155
|
+
// levels of its model, applied just before the prompt is queued.
|
|
156
|
+
let applyEffort = async () => {};
|
|
157
|
+
if (args.effort !== undefined) {
|
|
158
|
+
if (room) throw new Error('session: effort applies to a session, not a group room');
|
|
159
|
+
// Any bot, attended or not (`callerBotId`), changes only the task
|
|
160
|
+
// sessions it created; reports go only to a bot conversation.
|
|
161
|
+
const botId = context.callerBotId || context.callerAgentId || '';
|
|
162
|
+
if (botId && (await agentTasks.reportOrigin(sessionId, botId, caller))?.target === 'session') {
|
|
163
|
+
throw new Error('session: a bot may set the effort only of the task sessions it created');
|
|
164
|
+
}
|
|
165
|
+
const target = (await service.readSession({ sessionId, transcriptItemLimit: 1 })).full;
|
|
166
|
+
if (!target) throw new Error(`session: ${sessionId} is unavailable`);
|
|
167
|
+
const level = checkEffort(args.effort, target, await readModelCatalog(service, caller));
|
|
168
|
+
applyEffort = effortApplier(service, sessionId, level);
|
|
169
|
+
}
|
|
170
|
+
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
171
|
+
// another session, extends the chain by one; a bot's own task session
|
|
172
|
+
// only continues it. Refused past the limit, whatever the target.
|
|
173
|
+
const turnHop = Number(context.callerHop) || 0;
|
|
174
|
+
if (origin) {
|
|
175
|
+
const hop = chainedHop(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
176
|
+
origin = chainedOrigin(origin, hop, botChain);
|
|
177
|
+
// The task session a bot created acts as the sending conversation does
|
|
178
|
+
// from now on (attended chat or run); another's session keeps its own.
|
|
179
|
+
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
180
|
+
await applyEffort();
|
|
181
|
+
const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
|
|
182
|
+
return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
183
|
+
}
|
|
184
|
+
const hop = turnHop > 0 ? chainedHop(turnHop + 1) : 0;
|
|
185
|
+
await applyEffort();
|
|
186
|
+
const chainMeta = { ...(hop > 0 ? { hop } : {}), ...(botChain.length ? { botChain } : {}) };
|
|
187
|
+
let accepted;
|
|
188
|
+
if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
|
|
189
|
+
else {
|
|
190
|
+
// New work from this sender: a delegated target acts as the sender does.
|
|
191
|
+
await rebindDelegation(sessionId, caller);
|
|
192
|
+
const result = await service.submitSession({
|
|
193
|
+
sessionId,
|
|
194
|
+
prompt,
|
|
195
|
+
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...chainMeta } },
|
|
196
|
+
});
|
|
197
|
+
accepted = result.accepted === true;
|
|
198
|
+
}
|
|
199
|
+
return unreportedSendResult(sessionId, addressed, accepted, hop);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** `session action=status` (and the default read): one session's route, busy state and pending work. */
|
|
203
|
+
async function readSessionStatus({ service, readTitle, pendingWork }, action, sessionId, limit) {
|
|
204
|
+
const result = await service.readSession({
|
|
205
|
+
sessionId,
|
|
206
|
+
transcriptItemLimit: action === 'status' ? 1 : limit,
|
|
207
|
+
transcriptByteBudget: SESSION_TOOL_OUTPUT_BYTES,
|
|
208
|
+
});
|
|
209
|
+
const snapshot = result.full;
|
|
210
|
+
if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
|
|
211
|
+
// The snapshot carries no title: it lives on the session record. Quoted
|
|
212
|
+
// like a listed title.
|
|
213
|
+
const title = await readTitle(sessionId);
|
|
214
|
+
return {
|
|
215
|
+
sessionId,
|
|
216
|
+
title: title ? escapeHarnessTags(truncateToolText(title, SESSION_TITLE_LIMIT)) : null,
|
|
217
|
+
cwd: snapshot.cwd ?? null,
|
|
218
|
+
provider: snapshot.provider ?? null,
|
|
219
|
+
model: snapshot.model ?? null,
|
|
220
|
+
effort: snapshot.effort ?? null,
|
|
221
|
+
autoEffort: snapshot.autoEffort ?? null,
|
|
222
|
+
fast: snapshot.fast ?? null,
|
|
223
|
+
busy: snapshot.busy === true,
|
|
224
|
+
// A Lead idle between turns while its agents run is still working:
|
|
225
|
+
// their results wake it, so `busy` alone would read as stalled.
|
|
226
|
+
agentsWorking: (await pendingWork(sessionId)) === true,
|
|
227
|
+
quotaResume: snapshot.quotaResume ?? null,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
82
231
|
export function createSessionControl({
|
|
83
232
|
getSessionService,
|
|
84
233
|
agentTasks = createAgentTaskSessions({ getSessionService }),
|
|
85
|
-
|
|
234
|
+
listBots,
|
|
235
|
+
botStatus = createBotStatus({ getSessionService, listBots }),
|
|
86
236
|
// Agent work a session handed off and still waits on (agent-task-sessions.mjs).
|
|
87
237
|
pendingWork = taskSessionPendingWork,
|
|
88
238
|
liveWork = storedLiveWork,
|
|
@@ -92,7 +242,7 @@ export function createSessionControl({
|
|
|
92
242
|
const worktreeControl = createWorktreeControl(getSessionService);
|
|
93
243
|
const routeControl = createRouteControl(getSessionService);
|
|
94
244
|
|
|
95
|
-
|
|
245
|
+
async function control(args = {}, context = {}) {
|
|
96
246
|
const action = args.action;
|
|
97
247
|
const caller = requestCaller(action, context);
|
|
98
248
|
// `callerAgentId`: set only for an attended agent conversation (workspace-tools.mjs).
|
|
@@ -106,119 +256,10 @@ export function createSessionControl({
|
|
|
106
256
|
const service = getSessionService();
|
|
107
257
|
if (!service) throw new Error('session: session service is unavailable');
|
|
108
258
|
if (action === 'list') {
|
|
109
|
-
|
|
110
|
-
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
111
|
-
// list everything with previews, a bot (or its unattended run) lists the
|
|
112
|
-
// same rows (so it can find a session to send to) but only its own carry
|
|
113
|
-
// the bot, activity, preview and working state, anything else the plain
|
|
114
|
-
// rows without previews. Sub-agent sessions (a
|
|
115
|
-
// parent finds its own through the agent tool) and archived ones (the
|
|
116
|
-
// desktop's flag) only on request; the scan pages past the rows left
|
|
117
|
-
// out, so a page is never short while more rows match.
|
|
118
|
-
const own = scopedBot(context.callerScope);
|
|
119
|
-
const archived = (await readSessionSidebarState())?.archived ?? {};
|
|
120
|
-
const keep = listRowFilter(args, archived);
|
|
121
|
-
// Live work is overlaid on every row: a catalog row keeps the status and
|
|
122
|
-
// recency of its last settled turn, so a long-running agent read `idle`
|
|
123
|
-
// and sorted by its first prompt. The first page lists the live rows
|
|
124
|
-
// first (newest sign of work first); a later page keeps catalog order,
|
|
125
|
-
// where such a row may show again (never skipped).
|
|
126
|
-
const live = await liveWork();
|
|
127
|
-
const withLive = liveRowOverlay(live);
|
|
128
|
-
// Each live session's row is read by id (wherever it sits in the
|
|
129
|
-
// catalog), filtered like the listing, and the newest `limit` lead.
|
|
130
|
-
const candidates = liveCandidates(live);
|
|
131
|
-
let pinned = [];
|
|
132
|
-
if (!args.cursor && candidates.length) {
|
|
133
|
-
pinned = pinnedLiveRows(await Promise.all(candidates.map((id) => readRow(id))), keep, withLive, limit);
|
|
134
|
-
}
|
|
135
|
-
const pinnedIds = new Set(pinned.map((row) => row.id));
|
|
136
|
-
const want = limit - pinned.length;
|
|
137
|
-
// Bounded: past 10000 rows scanned with fewer than `limit` matching, the
|
|
138
|
-
// page ends (possibly empty) with a nextCursor to continue from.
|
|
139
|
-
const scan =
|
|
140
|
-
want > 0
|
|
141
|
-
? await scanCatalog(service, (row) => !pinnedIds.has(row.id) && keep(row), {
|
|
142
|
-
cursor: args.cursor || null,
|
|
143
|
-
want,
|
|
144
|
-
maxRows: 10_000,
|
|
145
|
-
})
|
|
146
|
-
: { rows: [], nextCursor: TOP_CURSOR };
|
|
147
|
-
const sessions = listedSessions(pinned, scan.rows, withLive, archived);
|
|
148
|
-
return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, listOutputOptions(own, pinnedIds));
|
|
259
|
+
return listSessions({ service, liveWork, readRow }, args, context, limit);
|
|
149
260
|
}
|
|
150
261
|
if (action === 'send') {
|
|
151
|
-
|
|
152
|
-
// A send to a room's log is a message to one member there (`to`, or a
|
|
153
|
-
// leading @name), run by the desktop room host; the member's turn in
|
|
154
|
-
// its member session is the turn that answers and reports.
|
|
155
|
-
const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
|
|
156
|
-
if (room?.sessionId === caller) throw new Error('session: send must target another session');
|
|
157
|
-
// Work goes on to a bot (a room seat's, or a bot's home) only outside
|
|
158
|
-
// the caller's bot chain (`callerBotChain`, bot-chain.mjs), never back
|
|
159
|
-
// to the caller's own bot; the turn it starts carries that chain on.
|
|
160
|
-
const botChain = botChainOf(context.callerBotChain);
|
|
161
|
-
assertBotChainTarget(
|
|
162
|
-
room ? room.agentId : agentIdOfHomeSession(sessionId),
|
|
163
|
-
{ chain: botChain, self: context.callerBotId || context.callerAgentId || '' },
|
|
164
|
-
'session'
|
|
165
|
-
);
|
|
166
|
-
// An agent conversation's send reports its turn back to the agent's
|
|
167
|
-
// home: a task session it created by its stored origin, any other
|
|
168
|
-
// session by an origin for this send only.
|
|
169
|
-
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
170
|
-
const prompt = handoffContent(room ? room.text : args.prompt, context.attachmentParts);
|
|
171
|
-
const turnSessionId = room ? room.sessionId : sessionId;
|
|
172
|
-
const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
|
|
173
|
-
const submit = room ? roomSubmitter(room, sessionId, prompt, from) : null;
|
|
174
|
-
const addressed = room ? { to: room.agentId } : {};
|
|
175
|
-
let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
|
|
176
|
-
// `effort` is the menu's effort pick on the target: checked now against the
|
|
177
|
-
// levels of its model, applied just before the prompt is queued.
|
|
178
|
-
let applyEffort = async () => {};
|
|
179
|
-
if (args.effort !== undefined) {
|
|
180
|
-
if (room) throw new Error('session: effort applies to a session, not a group room');
|
|
181
|
-
// Any bot, attended or not (`callerBotId`), changes only the task
|
|
182
|
-
// sessions it created; reports go only to a bot conversation.
|
|
183
|
-
const botId = context.callerBotId || context.callerAgentId || '';
|
|
184
|
-
if (botId && (await agentTasks.reportOrigin(sessionId, botId, caller))?.target === 'session') {
|
|
185
|
-
throw new Error('session: a bot may set the effort only of the task sessions it created');
|
|
186
|
-
}
|
|
187
|
-
const target = (await service.readSession({ sessionId, transcriptItemLimit: 1 })).full;
|
|
188
|
-
if (!target) throw new Error(`session: ${sessionId} is unavailable`);
|
|
189
|
-
const level = checkEffort(args.effort, target, await readModelCatalog(service, caller));
|
|
190
|
-
applyEffort = effortApplier(service, sessionId, level);
|
|
191
|
-
}
|
|
192
|
-
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
193
|
-
// another session, extends the chain by one; a bot's own task session
|
|
194
|
-
// only continues it. Refused past the limit, whatever the target.
|
|
195
|
-
const turnHop = Number(context.callerHop) || 0;
|
|
196
|
-
if (origin) {
|
|
197
|
-
const hop = chainedHop(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
198
|
-
origin = chainedOrigin(origin, hop, botChain);
|
|
199
|
-
// The task session a bot created acts as the sending conversation does
|
|
200
|
-
// from now on (attended chat or run); another's session keeps its own.
|
|
201
|
-
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
202
|
-
await applyEffort();
|
|
203
|
-
const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
|
|
204
|
-
return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
205
|
-
}
|
|
206
|
-
const hop = turnHop > 0 ? chainedHop(turnHop + 1) : 0;
|
|
207
|
-
await applyEffort();
|
|
208
|
-
const chainMeta = { ...(hop > 0 ? { hop } : {}), ...(botChain.length ? { botChain } : {}) };
|
|
209
|
-
let accepted;
|
|
210
|
-
if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
|
|
211
|
-
else {
|
|
212
|
-
// New work from this sender: a delegated target acts as the sender does.
|
|
213
|
-
await rebindDelegation(sessionId, caller);
|
|
214
|
-
const result = await service.submitSession({
|
|
215
|
-
sessionId,
|
|
216
|
-
prompt,
|
|
217
|
-
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...chainMeta } },
|
|
218
|
-
});
|
|
219
|
-
accepted = result.accepted === true;
|
|
220
|
-
}
|
|
221
|
-
return unreportedSendResult(sessionId, addressed, accepted, hop);
|
|
262
|
+
return sendToSession({ service, agentTasks }, args, context, sessionId, caller);
|
|
222
263
|
}
|
|
223
264
|
if (action === 'cancel') {
|
|
224
265
|
// A room's exchange is run by the desktop room host, so its stop (the UI
|
|
@@ -238,30 +279,20 @@ export function createSessionControl({
|
|
|
238
279
|
const result = await service.readSession({ sessionId, transcriptRange: { offset, limit } });
|
|
239
280
|
return sessionReadOutput(sessionId, result.range, { textOffset, itemId: args.item_id });
|
|
240
281
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
model: snapshot.model ?? null,
|
|
257
|
-
effort: snapshot.effort ?? null,
|
|
258
|
-
autoEffort: snapshot.autoEffort ?? null,
|
|
259
|
-
fast: snapshot.fast ?? null,
|
|
260
|
-
busy: snapshot.busy === true,
|
|
261
|
-
// A Lead idle between turns while its agents run is still working:
|
|
262
|
-
// their results wake it, so `busy` alone would read as stalled.
|
|
263
|
-
agentsWorking: (await pendingWork(sessionId)) === true,
|
|
264
|
-
quotaResume: snapshot.quotaResume ?? null,
|
|
265
|
-
};
|
|
282
|
+
return readSessionStatus({ service, readTitle, pendingWork }, action, sessionId, limit);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return async function executeSessionControl(args = {}, context = {}) {
|
|
286
|
+
try {
|
|
287
|
+
return await control(args, context);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
// A bot id is resolved to its home chat before this (workspace-tools.mjs),
|
|
290
|
+
// so a bot-shaped id the session service found no session for is no bot
|
|
291
|
+
// either: say which ids are.
|
|
292
|
+
const id = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
293
|
+
const missing = [`${id} is not available`, `${id} is unavailable`].some((text) => error?.message?.includes(text));
|
|
294
|
+
if (!BOT_TARGET_ACTIONS.has(args.action) || !isBotShaped(id) || !missing) throw error;
|
|
295
|
+
throw await unknownBotError(id, listBots, error);
|
|
296
|
+
}
|
|
266
297
|
};
|
|
267
298
|
}
|
|
@@ -22,6 +22,13 @@ process.env.MIXDOG_DAEMON_HOST = '1';
|
|
|
22
22
|
await import('../runtime/shared/uv-threadpool-boot.mjs');
|
|
23
23
|
// Before anything can import sharp: Electron on Linux must use its wasm build.
|
|
24
24
|
await import('../runtime/shared/sharp-electron-linux.mjs');
|
|
25
|
+
// Proxy variables (the user's, or the desktop's system proxy): fetch goes
|
|
26
|
+
// through the proxy while local and LAN hosts stay direct. The system proxy
|
|
27
|
+
// (handed over by the CLI or desktop that started this daemon, or read on
|
|
28
|
+
// Windows when started alone) is applied to this process's fetch only; its
|
|
29
|
+
// handoff variable is removed here so no child inherits it.
|
|
30
|
+
(await import('../runtime/shared/llm/system-proxy.mjs')).adoptSystemProxy();
|
|
31
|
+
(await import('../runtime/shared/llm/http-agent.mjs')).adoptEnvProxy();
|
|
25
32
|
|
|
26
33
|
// No V8 compile cache here, on purpose. Measured on this runtime: a cache hit
|
|
27
34
|
// saves nothing (spawn→ready 316-347ms with the cache vs 318-323ms without,
|
|
@@ -4,6 +4,7 @@ import { sanitizeForWire } from './session-wire-values.mjs';
|
|
|
4
4
|
import { annotateSpan } from '../runtime/shared/slow-span.mjs';
|
|
5
5
|
import { modelProxyClientMode } from '../runtime/shared/model-proxy-mode.mjs';
|
|
6
6
|
import { getModelProxyChannel } from '../runtime/agent/orchestrator/providers/model-proxy-channel.mjs';
|
|
7
|
+
import { SYSTEM_PROXY_REQUEST_EVENT } from '../runtime/shared/llm/system-proxy.mjs';
|
|
7
8
|
|
|
8
9
|
const requireDesktopModule = createRequire(import.meta.url);
|
|
9
10
|
|
|
@@ -40,6 +41,8 @@ function desktopEventKey(desktopId, message) {
|
|
|
40
41
|
let terminalId = '';
|
|
41
42
|
if (name === 'terminal-data') terminalId = String(message?.value?.id || '');
|
|
42
43
|
else if (name === 'session-runtime-released') terminalId = String(message?.value?.sessionId || '');
|
|
44
|
+
// Each lookup waits for its own answer: a backed-up stream must not drop one.
|
|
45
|
+
else if (name === SYSTEM_PROXY_REQUEST_EVENT) terminalId = String(message?.value?.id || '');
|
|
43
46
|
return `desktop-event:${desktopId}:${kind}:${name}${terminalId ? `:${terminalId}` : ''}`;
|
|
44
47
|
}
|
|
45
48
|
return `desktop-event:${desktopId}:${kind}`;
|
|
@@ -236,6 +239,12 @@ export class DesktopServiceRegistry {
|
|
|
236
239
|
}
|
|
237
240
|
callArgs = [callArgs[0], callArgs[1], epoch];
|
|
238
241
|
}
|
|
242
|
+
// The resolver stays attached while this client is: its epoch is released with it.
|
|
243
|
+
if (name === 'invokeDesktopOperation' && callArgs[0] === 'systemProxyAttach') {
|
|
244
|
+
const epoch = token ? service.visibilityEpochs.get(token) : undefined;
|
|
245
|
+
if (epoch === undefined) throw new Error('desktop service client is not initialized');
|
|
246
|
+
callArgs = ['systemProxyAttach', [epoch]];
|
|
247
|
+
}
|
|
239
248
|
// `[slow-op] desktop.invoke` names the call it timed: a desktop operation
|
|
240
249
|
// (Git reads) or a session capability, not only the generic route.
|
|
241
250
|
const target = name === 'invokeDesktopOperation' || name === 'invokeCapability' ? String(args?.[0] || '') : '';
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
tuiDebug,
|
|
40
40
|
nextId,
|
|
41
41
|
createTranscriptSpillBuffer,
|
|
42
|
+
spillWarningToStderr,
|
|
42
43
|
sweepStaleTranscriptSpillDirsOnce,
|
|
43
44
|
} from '../tui/session/transcript-spill.mjs';
|
|
44
45
|
import { importInStages } from './staged-import.mjs';
|
|
@@ -278,7 +279,8 @@ export async function createLocalSessionRuntime({
|
|
|
278
279
|
const { getState, getPublishedState, set, flushEmit, flushEmitImmediate } = store;
|
|
279
280
|
|
|
280
281
|
const itemIndexById = new Map();
|
|
281
|
-
|
|
282
|
+
// stderr is daemon.log in the daemon: a pinned spill must not stay silent.
|
|
283
|
+
const transcriptSpill = createTranscriptSpillBuffer({ onWarning: spillWarningToStderr });
|
|
282
284
|
const { markToolCallActive, markToolCallDone, clearActiveToolSummary, resetActiveToolCalls } =
|
|
283
285
|
createActiveToolTracker({ getState, set });
|
|
284
286
|
const {
|
|
@@ -457,6 +459,8 @@ export async function createLocalSessionRuntime({
|
|
|
457
459
|
snapshotTranscriptSpill: () => transcriptSpill.snapshot(),
|
|
458
460
|
restoreTranscriptSpill: (snapshot) => transcriptSpill.restoreSnapshot(snapshot),
|
|
459
461
|
releaseTranscriptSpill: (snapshot) => transcriptSpill.releaseSnapshot(snapshot),
|
|
462
|
+
// Paged views read the rows spilled out of memory (transcript-window.mjs).
|
|
463
|
+
readSpilledTranscript: (range) => transcriptSpill.readSpilled(range),
|
|
460
464
|
presentNextToolApproval,
|
|
461
465
|
finishToolApproval,
|
|
462
466
|
denyAllToolApprovals,
|
|
@@ -8,6 +8,9 @@ export const DAEMON_UNAVAILABLE_MESSAGE = 'daemon session endpoint is unavailabl
|
|
|
8
8
|
|
|
9
9
|
function exitCodeText(code) {
|
|
10
10
|
// Windows reports NTSTATUS crash codes as large unsigned values.
|
|
11
|
+
// 0xE0000008 is Chromium's kOomExceptionCode; 134 is a V8 fatal error (abort).
|
|
12
|
+
if (code === 0xe0000008 || code === -536870904) return `${code === -536870904 ? code : '0xE0000008'} (out of memory)`;
|
|
13
|
+
if (code === 134) return '134 (V8 fatal error (JavaScript heap out of memory))';
|
|
11
14
|
return Number.isSafeInteger(code) && code > 0x7fffffff ? `0x${code.toString(16).toUpperCase()}` : String(code);
|
|
12
15
|
}
|
|
13
16
|
|
|
@@ -18,6 +18,7 @@ import { readSingletonOwner } from '../runtime/shared/singleton-owner.mjs';
|
|
|
18
18
|
import { isPidAlive } from '../runtime/shared/pid-liveness.mjs';
|
|
19
19
|
import { resolveRuntimeRoot } from '../runtime/shared/runtime-root.mjs';
|
|
20
20
|
import { withHeapCap } from '../runtime/shared/heap-cap.mjs';
|
|
21
|
+
import { systemProxyHandoffEnv } from '../runtime/shared/llm/system-proxy.mjs';
|
|
21
22
|
import { daemonCrashCaptureDir, daemonDataDir } from '../session-runtime/services/daemon-crash-capture.mjs';
|
|
22
23
|
import { forkDaemonCandidate } from '../session-runtime/services/daemon-candidate.mjs';
|
|
23
24
|
import { daemonOwnerIsStale, proveDaemonOwnerRecord } from './daemon-owner.mjs';
|
|
@@ -338,7 +339,7 @@ async function replaceLowerDaemon(discovery, initialHealth, { log, onUpgradeWait
|
|
|
338
339
|
// PostgreSQL stop included — so the launcher's quit stops it first.
|
|
339
340
|
const inTreeDaemons = new Map();
|
|
340
341
|
|
|
341
|
-
export function spawnDaemonCandidate({ cwd, log, timeoutMs = 30_000, entry = daemonEntry() }) {
|
|
342
|
+
export async function spawnDaemonCandidate({ cwd, log, timeoutMs = 30_000, entry = daemonEntry() }) {
|
|
342
343
|
const t0 = performance.now();
|
|
343
344
|
const at = () => Math.round(performance.now() - t0);
|
|
344
345
|
const detached = daemonShouldDetach();
|
|
@@ -353,6 +354,9 @@ export function spawnDaemonCandidate({ cwd, log, timeoutMs = 30_000, entry = dae
|
|
|
353
354
|
detached,
|
|
354
355
|
env: {
|
|
355
356
|
...process.env,
|
|
357
|
+
// The fallback system proxy this launcher settled (the CLI), not as
|
|
358
|
+
// standard proxy env; a desktop is asked per origin once attached.
|
|
359
|
+
...systemProxyHandoffEnv(),
|
|
356
360
|
ELECTRON_RUN_AS_NODE: '1',
|
|
357
361
|
MIXDOG_DAEMON_HOST: '1',
|
|
358
362
|
MIXDOG_RUNTIME_ROOT: resolveRuntimeRoot(),
|