mixdog 1.3.5 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -27,6 +27,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
27
27
|
'getChannelSettings',
|
|
28
28
|
'getChannelSetup',
|
|
29
29
|
'getChannelWorkerStatus',
|
|
30
|
+
'getCacheWarmingSettings',
|
|
30
31
|
'getCompactionSettings',
|
|
31
32
|
'getConversationImportJobs',
|
|
32
33
|
'getDeveloperSettings',
|
|
@@ -40,6 +41,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
40
41
|
'getOAuthProviderLoginStatus',
|
|
41
42
|
'getOutputStyle',
|
|
42
43
|
'getOrchestrationMode',
|
|
44
|
+
'getConfiguredOrchestrationMode',
|
|
43
45
|
'getProfile',
|
|
44
46
|
'getProviderSetup',
|
|
45
47
|
'getProviderAccounts',
|
|
@@ -211,6 +213,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
211
213
|
'setAgentRoute',
|
|
212
214
|
'setAutoClear',
|
|
213
215
|
'setAutoUpdate',
|
|
216
|
+
'setCacheWarmingEnabled',
|
|
214
217
|
'setCompactionSettings',
|
|
215
218
|
'setCwd',
|
|
216
219
|
'setDeveloperOption',
|
|
@@ -242,6 +245,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
242
245
|
'setRecapEnabled',
|
|
243
246
|
'setAiSessionTitles',
|
|
244
247
|
'setHeartbeatEnabled',
|
|
248
|
+
'setHeartbeatInterval',
|
|
249
|
+
'noteUserInput',
|
|
245
250
|
'setReactionsEnabled',
|
|
246
251
|
'setLeadAppearance',
|
|
247
252
|
'setBotOrder',
|
|
@@ -31,6 +31,7 @@ export function createAgentChildFactory({ registry, rehydrateAgentSessions, crea
|
|
|
31
31
|
sourceName: spec.sourceName || spec.agent || 'agent',
|
|
32
32
|
clientHostPid: spec.clientHostPid || null,
|
|
33
33
|
...(preset.fallbacks !== undefined ? { routeFallbacks: preset.fallbacks } : {}),
|
|
34
|
+
...(preset.fallbackSource ? { routeFallbackSource: preset.fallbackSource } : {}),
|
|
34
35
|
};
|
|
35
36
|
const created = await createSession({
|
|
36
37
|
cwd: spec.cwd || process.cwd(),
|
|
@@ -5,8 +5,12 @@ import { randomUUID } from 'node:crypto';
|
|
|
5
5
|
import { createAgentChildFactory } from './agent-child.mjs';
|
|
6
6
|
import { partialHandoffTextFromSession } from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
7
7
|
import { attachmentsForIntake } from '../../../runtime/attachments/store.mjs';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { producedFileLines } from '../../../runtime/shared/handoff-artifacts.mjs';
|
|
9
|
+
import {
|
|
10
|
+
collectUnreportedWrites,
|
|
11
|
+
handoffContent,
|
|
12
|
+
sessionRoots,
|
|
13
|
+
} from '../../../session-runtime/handoff-attachments.mjs';
|
|
10
14
|
|
|
11
15
|
/** An agent turn's prompt: text, or text with forwarded attachment parts
|
|
12
16
|
* (handoff-attachments.mjs), never any other shape. */
|
|
@@ -25,18 +29,19 @@ export function agentTurnTranscriptMeta(content) {
|
|
|
25
29
|
return { sender: 'lead', ...(attachments.length ? { attachments } : {}) };
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
/** The
|
|
29
|
-
*
|
|
30
|
-
|
|
32
|
+
/** The lines for files the turn that began at `messageStart` created or
|
|
33
|
+
* modified and `report` does not already name; [] on any failure to read it
|
|
34
|
+
* (the handoff still goes out). */
|
|
35
|
+
async function turnArtifactLines(runtime, messageStart, descriptor, report) {
|
|
31
36
|
try {
|
|
32
37
|
const { messages } = await runtime.readModelMessages(messageStart);
|
|
33
38
|
const session = runtime.session || descriptor;
|
|
34
|
-
const { files, omitted } =
|
|
39
|
+
const { files, omitted } = collectUnreportedWrites(messages, {
|
|
35
40
|
cwd: descriptor.cwd,
|
|
36
41
|
roots: sessionRoots(session, descriptor.cwd),
|
|
42
|
+
report,
|
|
37
43
|
});
|
|
38
|
-
|
|
39
|
-
return artifactLines(files, omitted, { ids: false });
|
|
44
|
+
return producedFileLines(files, omitted);
|
|
40
45
|
} catch {
|
|
41
46
|
return [];
|
|
42
47
|
}
|
|
@@ -131,10 +136,9 @@ export function createAgentTurns({
|
|
|
131
136
|
}
|
|
132
137
|
let result = detail?.result || { content: '' };
|
|
133
138
|
// The files the turn produced reach the owner with its handoff.
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
139
|
+
const report = String(result.content || '');
|
|
140
|
+
const files = await turnArtifactLines(entry.runtime, messageStart, descriptor, report);
|
|
141
|
+
if (files.length) result = { ...result, content: [report, files.join('\n')].join('\n\n') };
|
|
138
142
|
descriptor.status = 'idle';
|
|
139
143
|
descriptor.stage = 'idle';
|
|
140
144
|
descriptor.lastHandoff = typeof result?.content === 'string' ? result.content : '';
|
|
@@ -44,6 +44,9 @@ async function resumeDueEntry(entry, { store, materializeSession, readQuotaUsabl
|
|
|
44
44
|
try {
|
|
45
45
|
usable = await readQuotaUsable(provider, model);
|
|
46
46
|
} catch (error) {
|
|
47
|
+
// A disconnected PC supplies no quota reading. The scheduler's outer
|
|
48
|
+
// deferral keeps this reservation without spending an exhaustion attempt.
|
|
49
|
+
if (error?.code === 'MODEL_PROXY_UNAVAILABLE') throw error;
|
|
47
50
|
log(`quota resume usage reading failed provider=${provider}: ${error?.message || error}`);
|
|
48
51
|
}
|
|
49
52
|
if (!isCurrent(store, entry)) return 'cancelled';
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
* turn. The eviction sweep that consumes this lives in ../retention.mjs.
|
|
8
8
|
*/
|
|
9
9
|
import { activeBackgroundTaskSessionIds, hasActiveBackgroundTasks } from '../../../runtime/shared/background-tasks.mjs';
|
|
10
|
+
import { emitSessionApprovalCardChange } from '../../../runtime/shared/session-activity-signal.mjs';
|
|
11
|
+
import { roomMemberOfSession } from '../../../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
12
|
+
|
|
13
|
+
/** A room member session's copies of the questions of sessions it handed work
|
|
14
|
+
* to (tui/session/tool-approval.mjs `handoffQuestions`); empty for any other
|
|
15
|
+
* session. The room shows them from the member's catalog row (agent-rooms.ts),
|
|
16
|
+
* as no view watches a member session. */
|
|
17
|
+
function roomHandoffQuestionsOf(sessionId, state) {
|
|
18
|
+
if (!roomMemberOfSession(sessionId)) return [];
|
|
19
|
+
return Array.isArray(state?.handoffQuestions) ? state.handoffQuestions : [];
|
|
20
|
+
}
|
|
10
21
|
|
|
11
22
|
export function createBusyTracker({ sessions, currentSessionId }) {
|
|
12
23
|
function stateBusy(state) {
|
|
@@ -18,9 +29,54 @@ export function createBusyTracker({ sessions, currentSessionId }) {
|
|
|
18
29
|
function updateEntryBusy(entry, state) {
|
|
19
30
|
const next = stateBusy(state);
|
|
20
31
|
entry.busy = next;
|
|
32
|
+
// Every runtime state change passes here, watched or headless: a session
|
|
33
|
+
// that starts or stops showing an approval card (any kind, a sub-agent's
|
|
34
|
+
// delegated copy included) announces it, so the session catalog — the one
|
|
35
|
+
// status source every list row has, open pane or not — re-reads it.
|
|
36
|
+
const awaitingApproval = Boolean(state?.toolApproval);
|
|
37
|
+
const awaitingQuestion = state?.toolApproval?.kind === 'question';
|
|
38
|
+
// A room member's handed-off questions coming and going re-read it too.
|
|
39
|
+
const sessionId = currentSessionId(entry) || '';
|
|
40
|
+
const handoffQuestions = roomHandoffQuestionsOf(sessionId, state)
|
|
41
|
+
.map((question) => String(question?.id ?? ''))
|
|
42
|
+
.join('\n');
|
|
43
|
+
if (
|
|
44
|
+
awaitingApproval !== (entry.awaitingApproval === true) ||
|
|
45
|
+
awaitingQuestion !== (entry.awaitingQuestion === true) ||
|
|
46
|
+
handoffQuestions !== (entry.handoffQuestions ?? '')
|
|
47
|
+
) {
|
|
48
|
+
entry.awaitingApproval = awaitingApproval;
|
|
49
|
+
entry.awaitingQuestion = awaitingQuestion;
|
|
50
|
+
entry.handoffQuestions = handoffQuestions;
|
|
51
|
+
emitSessionApprovalCardChange(sessionId);
|
|
52
|
+
}
|
|
21
53
|
return next;
|
|
22
54
|
}
|
|
23
55
|
|
|
56
|
+
/** Room member session id -> its pending handed-off question copies, for
|
|
57
|
+
* every live member runtime holding one. */
|
|
58
|
+
function roomHandoffQuestions() {
|
|
59
|
+
const byMember = new Map();
|
|
60
|
+
for (const entry of sessions) {
|
|
61
|
+
const sessionId = currentSessionId(entry);
|
|
62
|
+
const questions = sessionId ? roomHandoffQuestionsOf(sessionId, entry.runtime?.getState?.()) : [];
|
|
63
|
+
if (questions.length) byMember.set(sessionId, questions);
|
|
64
|
+
}
|
|
65
|
+
return byMember;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Session id -> the kind of its pending card ('approval' | 'question') for
|
|
69
|
+
* every session whose live runtime shows one waiting on the user. */
|
|
70
|
+
function awaitingApprovalSessionKinds() {
|
|
71
|
+
const kinds = new Map();
|
|
72
|
+
for (const entry of sessions) {
|
|
73
|
+
const sessionId = currentSessionId(entry);
|
|
74
|
+
const pending = sessionId ? entry.runtime?.getState?.()?.toolApproval : null;
|
|
75
|
+
if (pending) kinds.set(sessionId, pending.kind === 'question' ? 'question' : 'approval');
|
|
76
|
+
}
|
|
77
|
+
return kinds;
|
|
78
|
+
}
|
|
79
|
+
|
|
24
80
|
function sessionBusy(entry) {
|
|
25
81
|
const sessionId = currentSessionId(entry);
|
|
26
82
|
// Detached views do not make their background commands disposable. Keep
|
|
@@ -65,5 +121,13 @@ export function createBusyTracker({ sessions, currentSessionId }) {
|
|
|
65
121
|
return count;
|
|
66
122
|
}
|
|
67
123
|
|
|
68
|
-
return {
|
|
124
|
+
return {
|
|
125
|
+
stateBusy,
|
|
126
|
+
updateEntryBusy,
|
|
127
|
+
awaitingApprovalSessionKinds,
|
|
128
|
+
roomHandoffQuestions,
|
|
129
|
+
sessionBusy,
|
|
130
|
+
liveBusyCount,
|
|
131
|
+
liveTurnBusyCount,
|
|
132
|
+
};
|
|
69
133
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { SESSION_CONFIGURE_ACTION_SET, SESSION_READ_ACTION_SET } from '../../session-protocol.mjs';
|
|
5
5
|
import { annotateSpan, markPhase } from '../../../runtime/shared/slow-span.mjs';
|
|
6
6
|
import { sanitizeForWire } from '../../session-wire-values.mjs';
|
|
7
|
+
import { botWorkBySession } from '../../../runtime/shared/bot-owned-work.mjs';
|
|
7
8
|
|
|
8
9
|
/** Reads a session without a live runtime answers from disk (readStoredReview). */
|
|
9
10
|
const STORED_REVIEW_ACTIONS = new Set([
|
|
@@ -40,7 +41,7 @@ export function createSessionActionCalls(ctx) {
|
|
|
40
41
|
responseSessionId,
|
|
41
42
|
} = ctx;
|
|
42
43
|
const { bodyForClient } = ctx.projection;
|
|
43
|
-
const { retainUnwatched } = ctx.retention;
|
|
44
|
+
const { retainUnwatched, awaitingApprovalSessionKinds, roomHandoffQuestions } = ctx.retention;
|
|
44
45
|
const { assertAvailable, hostedEntryForSession, entryForSession } = ctx.entries;
|
|
45
46
|
|
|
46
47
|
/** A cold session's review, read from its durable turn record (the same
|
|
@@ -111,6 +112,33 @@ export function createSessionActionCalls(ctx) {
|
|
|
111
112
|
return result;
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
/** Rows with `awaitingApproval` on every session whose live runtime shows an
|
|
116
|
+
* approval card: a list row reads "needs you" from it whether or not any
|
|
117
|
+
* pane receives that session's lane. A room member's row also carries the
|
|
118
|
+
* handed-off questions it holds (`handoffQuestions`), which its room shows.
|
|
119
|
+
* A session holding work a bot sent (bot-owned-work.mjs) carries those bots
|
|
120
|
+
* (`handedBy`): the work there is theirs, and a turn nobody sent (the
|
|
121
|
+
* user's own) is nobody's but the user's. */
|
|
122
|
+
function withApprovalWaits(rows) {
|
|
123
|
+
if (!Array.isArray(rows)) return rows;
|
|
124
|
+
const waiting = awaitingApprovalSessionKinds();
|
|
125
|
+
const questions = roomHandoffQuestions();
|
|
126
|
+
const sent = botWorkBySession();
|
|
127
|
+
if (!waiting.size && !questions.size && !sent.size) return rows;
|
|
128
|
+
return rows.map((row) => {
|
|
129
|
+
const kind = waiting.get(row?.id);
|
|
130
|
+
const asked = questions.get(row?.id);
|
|
131
|
+
const bots = sent.get(row?.id);
|
|
132
|
+
if (!kind && !asked && !bots) return row;
|
|
133
|
+
return {
|
|
134
|
+
...row,
|
|
135
|
+
...(kind ? { awaitingApproval: true, ...(kind === 'question' ? { awaitingQuestion: true } : {}) } : {}),
|
|
136
|
+
...(asked ? { handoffQuestions: asked } : {}),
|
|
137
|
+
...(bots ? { handedBy: bots } : {}),
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
114
142
|
async function listSessionCatalog(options = {}) {
|
|
115
143
|
if (isClosed()) throw new Error('session service is closed');
|
|
116
144
|
if (typeof listSessions !== 'function') {
|
|
@@ -124,7 +152,7 @@ export function createSessionActionCalls(ctx) {
|
|
|
124
152
|
});
|
|
125
153
|
// A `page: { limit, cursor }` request answers one page: { sessions, nextCursor }.
|
|
126
154
|
const page = listed && !Array.isArray(listed) && Array.isArray(listed.sessions) ? listed : null;
|
|
127
|
-
const sessions = page ? page.sessions : listed;
|
|
155
|
+
const sessions = withApprovalWaits(page ? page.sessions : listed);
|
|
128
156
|
const remoteSession = typeof getRemoteSessionState === 'function' ? await getRemoteSessionState() : null;
|
|
129
157
|
const nextCursor = typeof page?.nextCursor === 'string' ? page.nextCursor : null;
|
|
130
158
|
return {
|
|
@@ -131,6 +131,14 @@ export function createSessionViewCalls(ctx) {
|
|
|
131
131
|
notePrependViewer(viewer, params);
|
|
132
132
|
const id = String(sessionId || '');
|
|
133
133
|
if (!id) throw new TypeError('sessionId is required');
|
|
134
|
+
if (params.attachmentHistory === true) {
|
|
135
|
+
// Apart from every window: nothing here reads, fills or replaces a
|
|
136
|
+
// transcript projection.
|
|
137
|
+
const stored =
|
|
138
|
+
typeof readStoredSession === 'function' ? await readStoredSession(id, { attachmentHistory: true }) : null;
|
|
139
|
+
assertAvailable();
|
|
140
|
+
return { history: stored ? { items: stored.items } : null };
|
|
141
|
+
}
|
|
134
142
|
const live = await liveEntryFor(id);
|
|
135
143
|
assertAvailable(live);
|
|
136
144
|
if (params.transcriptRange) {
|
|
@@ -7,6 +7,8 @@ import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
|
|
|
7
7
|
import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/shared/tool-output-budget.mjs';
|
|
8
8
|
|
|
9
9
|
export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
|
|
10
|
+
// A session title as the session tool quotes it, listed or read.
|
|
11
|
+
export const SESSION_TITLE_LIMIT = 160;
|
|
10
12
|
const MESSAGE_TEXT_LIMIT = 2000;
|
|
11
13
|
const LIST_PREVIEW_LIMIT = 100;
|
|
12
14
|
const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
@@ -15,24 +17,30 @@ const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
|
15
17
|
* `rich` adds the owning bot, last activity, latest line and working state
|
|
16
18
|
* (never for a background caller: bot-status.mjs scopedBot). `rich` may be a
|
|
17
19
|
* per-row predicate: a bot gets them only for its own sessions. */
|
|
18
|
-
export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
20
|
+
export function sessionListOutput(page, limit, { rich = true, cursorOf = encodeCatalogCursor } = {}) {
|
|
19
21
|
const raw = page.sessions;
|
|
20
22
|
const sessions = raw.slice(0, limit).map((row) => {
|
|
21
23
|
// Decided first: a session that is not the caller's carries its real
|
|
22
24
|
// title only, never a preview standing in for it.
|
|
23
25
|
const own = typeof rich === 'function' ? rich(row) : rich;
|
|
24
26
|
const title = own ? row.title || row.preview : row.title;
|
|
27
|
+
// Live work, for every caller: its own turn or pool row (`working`)
|
|
28
|
+
// reads `running` whatever the settled catalog status; an Agent session
|
|
29
|
+
// working for it (`agentWorking`) marks it working too.
|
|
30
|
+
const status = row.working === true ? 'running' : row.status;
|
|
31
|
+
const working = row.working === true || row.agentWorking === true ? { working: true } : {};
|
|
25
32
|
const base = {
|
|
26
33
|
id: row.id,
|
|
27
|
-
...(title ? { title: escapeHarnessTags(truncateToolText(title,
|
|
28
|
-
...(
|
|
34
|
+
...(title ? { title: escapeHarnessTags(truncateToolText(title, SESSION_TITLE_LIMIT)) } : {}),
|
|
35
|
+
...(status ? { status } : {}),
|
|
29
36
|
...(row.cwd ? { cwd: row.cwd } : {}),
|
|
30
37
|
...(row.archived === true ? { archived: true } : {}),
|
|
31
38
|
};
|
|
32
|
-
if (!own) return base;
|
|
39
|
+
if (!own) return { ...base, ...working };
|
|
33
40
|
// The bot it belongs to: its chat, room seat or the task's creator.
|
|
34
41
|
const bot = sessionBotOf(row);
|
|
35
|
-
|
|
42
|
+
// A live row's latest sign of work (`liveAt`) is newer than its last settled turn.
|
|
43
|
+
const lastUsedAt = Math.max(Number(row.lastUsedAt) || 0, Number(row.liveAt) || 0);
|
|
36
44
|
const preview = String(row.lastMessagePreview || '').replace(/\s+/g, ' ');
|
|
37
45
|
return {
|
|
38
46
|
...base,
|
|
@@ -40,7 +48,7 @@ export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
|
40
48
|
...(lastUsedAt ? { lastUsedAt: new Date(lastUsedAt).toISOString() } : {}),
|
|
41
49
|
// The latest user or assistant line, quoted data.
|
|
42
50
|
...(preview.trim() ? { preview: escapeHarnessTags(truncateToolText(preview, LIST_PREVIEW_LIMIT)) } : {}),
|
|
43
|
-
...
|
|
51
|
+
...working,
|
|
44
52
|
};
|
|
45
53
|
});
|
|
46
54
|
const result = {
|
|
@@ -50,7 +58,7 @@ export function sessionListOutput(page, limit, { rich = true } = {}) {
|
|
|
50
58
|
};
|
|
51
59
|
for (;;) {
|
|
52
60
|
if (sessions.length < raw.length && sessions.length) {
|
|
53
|
-
result.nextCursor =
|
|
61
|
+
result.nextCursor = cursorOf(raw[sessions.length - 1]);
|
|
54
62
|
}
|
|
55
63
|
if (outputBytes(result) <= TOOL_OUTPUT_PAGE_BYTES) return result;
|
|
56
64
|
if (sessions.length <= 1) throw new Error('session: one catalog row exceeds the output budget');
|
|
@@ -70,15 +70,18 @@ export function createClientGrace({
|
|
|
70
70
|
// tick for as long as the daemon took to go down. A lifecycle client that
|
|
71
71
|
// attaches again clears the latch, because that daemon is staying up.
|
|
72
72
|
if (graceTimer || signalled) return;
|
|
73
|
-
graceTimer = setTimeout(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
graceTimer = setTimeout(
|
|
74
|
+
() => {
|
|
75
|
+
graceTimer = null;
|
|
76
|
+
if (isClosed() || lifecycleClientCount() > 0) return;
|
|
77
|
+
signalled = true;
|
|
78
|
+
log(`no clients remain (${reason}) — signalling shutdown`);
|
|
79
|
+
try {
|
|
80
|
+
onClientsEmpty();
|
|
81
|
+
} catch {}
|
|
82
|
+
},
|
|
83
|
+
lastLifecycleWasRemote ? remoteClientGraceMs() : clientGraceMs
|
|
84
|
+
);
|
|
82
85
|
graceTimer.unref?.();
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -38,9 +38,7 @@ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionP
|
|
|
38
38
|
onSubmit={(answers) =>
|
|
39
39
|
store.resolveToolApproval?.(toolApproval.id, { approved: true, reason: 'answered by user', answers })
|
|
40
40
|
}
|
|
41
|
-
onDismiss={() =>
|
|
42
|
-
store.resolveToolApproval?.(toolApproval.id, { approved: false, reason: 'dismissed by user' })
|
|
43
|
-
}
|
|
41
|
+
onDismiss={() => store.resolveToolApproval?.(toolApproval.id, { approved: false, reason: 'dismissed by user' })}
|
|
44
42
|
/>
|
|
45
43
|
);
|
|
46
44
|
}
|
|
@@ -249,7 +247,12 @@ export function renderFloatingPanel(ctx) {
|
|
|
249
247
|
}
|
|
250
248
|
if (btwPanel) {
|
|
251
249
|
return (
|
|
252
|
-
<BtwPanel
|
|
250
|
+
<BtwPanel
|
|
251
|
+
panel={btwPanel}
|
|
252
|
+
columns={frameColumns}
|
|
253
|
+
panelRows={floatingPanelRows}
|
|
254
|
+
themeEpoch={ctx.state?.themeEpoch || 0}
|
|
255
|
+
/>
|
|
253
256
|
);
|
|
254
257
|
}
|
|
255
258
|
return null;
|
|
@@ -9,6 +9,7 @@ import { theme } from '../theme.mjs';
|
|
|
9
9
|
import { displayModelName, effortDisplayLabel } from '../../runtime/shared/model-display.mjs';
|
|
10
10
|
import { isRollingModelAlias } from '../../runtime/shared/model-alias.mjs';
|
|
11
11
|
import { describeError } from '../../runtime/shared/error-presentation.mjs';
|
|
12
|
+
import { providerDisplayName } from '../../runtime/shared/provider-display-name.mjs';
|
|
12
13
|
import { DAYBREAK_PROVIDER, daybreakBlueOn } from '../../runtime/shared/llm/openai-daybreak.mjs';
|
|
13
14
|
|
|
14
15
|
export const parsedModelVersion = (id) => {
|
|
@@ -165,34 +166,8 @@ export const normalizeModelOptions = (models) => {
|
|
|
165
166
|
return normalized;
|
|
166
167
|
};
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
['anthropic-oauth', 'Anthropic OAuth'],
|
|
171
|
-
['grok-oauth', 'Grok OAuth'],
|
|
172
|
-
['muse-code-oauth', 'Muse Code'],
|
|
173
|
-
['command-code-oauth', 'Command Code'],
|
|
174
|
-
['mimo-oauth', 'MiMo'],
|
|
175
|
-
['cursor-oauth', 'Cursor OAuth'],
|
|
176
|
-
['devin-oauth', 'Devin'],
|
|
177
|
-
['antigravity-oauth', 'Antigravity OAuth'],
|
|
178
|
-
['openai', 'OpenAI API'],
|
|
179
|
-
['openai-api', 'OpenAI API'],
|
|
180
|
-
['anthropic', 'Anthropic API'],
|
|
181
|
-
['anthropic-api', 'Anthropic API'],
|
|
182
|
-
['gemini', 'Gemini API'],
|
|
183
|
-
['gemini-api', 'Gemini API'],
|
|
184
|
-
['xai', 'xAI API'],
|
|
185
|
-
['xai-api', 'xAI API'],
|
|
186
|
-
['deepseek', 'DeepSeek API'],
|
|
187
|
-
['deepseek-api', 'DeepSeek API'],
|
|
188
|
-
['opencode-go-oauth', 'OpenCode Go OAuth'],
|
|
189
|
-
['openrouter', 'OpenRouter'],
|
|
190
|
-
['mixdog-local', 'Local Provider'],
|
|
191
|
-
['default', 'Default'],
|
|
192
|
-
]);
|
|
193
|
-
|
|
194
|
-
export const providerDisplayName = (provider) =>
|
|
195
|
-
PROVIDER_DISPLAY_NAMES.get(String(provider || '').toLowerCase()) ?? (provider || 'Provider');
|
|
169
|
+
// Provider display names live in runtime/shared so error text can name the provider too.
|
|
170
|
+
export { providerDisplayName };
|
|
196
171
|
|
|
197
172
|
export const resolveProviderDisplayName = (provider, providerNames = null) =>
|
|
198
173
|
(String(provider || '')
|
|
@@ -89,9 +89,7 @@ export function createFastParameterSelection({ state, currentRoute, isCurrentRou
|
|
|
89
89
|
* on/off) to its next option; false when the model has none. Fast is
|
|
90
90
|
* dropped when the new parameters rule it out. */
|
|
91
91
|
const cycleThinking = (model) => {
|
|
92
|
-
const definition = (model.modelParameterOptions || []).find((parameter) =>
|
|
93
|
-
TOGGLE_PARAMETER_IDS.has(parameter.id)
|
|
94
|
-
);
|
|
92
|
+
const definition = (model.modelParameterOptions || []).find((parameter) => TOGGLE_PARAMETER_IDS.has(parameter.id));
|
|
95
93
|
if (!definition?.options?.length) return false;
|
|
96
94
|
const wanted = definition.id;
|
|
97
95
|
const parameters = modelParametersFor(model);
|
|
@@ -27,9 +27,10 @@ export function createRouteSelection({ providerModels, state, currentRoute }) {
|
|
|
27
27
|
const fastCapable = fast.fastAvailableFor(selected, coercedEffort);
|
|
28
28
|
const contextSelection = context.contextSelectionFor(selected);
|
|
29
29
|
const { serviceTier, ...otherParameters } = fast.modelParametersFor(selected);
|
|
30
|
-
const modelParameters =
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const modelParameters =
|
|
31
|
+
serviceTier && fastCapable && fast.getSelectedFast(selected)
|
|
32
|
+
? { ...otherParameters, serviceTier }
|
|
33
|
+
: otherParameters;
|
|
33
34
|
return {
|
|
34
35
|
effort: coercedEffort,
|
|
35
36
|
routeInput: {
|
|
@@ -38,9 +39,7 @@ export function createRouteSelection({ providerModels, state, currentRoute }) {
|
|
|
38
39
|
...(coercedEffort ? { effort: coercedEffort } : {}),
|
|
39
40
|
...(contextSelection ? { contextPercent: contextSelection.percent } : {}),
|
|
40
41
|
...(selected.fastCapable ? { fast: fastCapable && fast.getSelectedFast(selected) } : {}),
|
|
41
|
-
...((selected.modelParameterOptions || []).length
|
|
42
|
-
? { modelParameters }
|
|
43
|
-
: {}),
|
|
42
|
+
...((selected.modelParameterOptions || []).length ? { modelParameters } : {}),
|
|
44
43
|
},
|
|
45
44
|
};
|
|
46
45
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// progress and result panels, the interactive (code prompt) login through
|
|
4
4
|
// store.beginOAuthProviderLogin, and the legacy store.loginOAuthProvider
|
|
5
5
|
// path. `flow` is the per-open picker state built by provider-setup-picker.mjs.
|
|
6
|
+
import { canOpenBrowser } from '../../../runtime/shared/open-url.mjs';
|
|
6
7
|
import { providerDetailText } from '../app-format.mjs';
|
|
7
8
|
import { forgetProviderAuth, providerStatusFooter } from './provider-items.mjs';
|
|
8
9
|
|
|
@@ -27,7 +28,7 @@ function showOAuthProgress(flow, providerItem, message, onBack) {
|
|
|
27
28
|
value: 'waiting',
|
|
28
29
|
label: 'Waiting for login',
|
|
29
30
|
meta: 'Running',
|
|
30
|
-
description: 'finish the
|
|
31
|
+
description: 'finish the sign-in shown above',
|
|
31
32
|
_action: 'waiting',
|
|
32
33
|
},
|
|
33
34
|
{
|
|
@@ -71,6 +72,20 @@ function showOAuthResult(flow, providerItem, ok, message = '') {
|
|
|
71
72
|
});
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
function oauthCodeHint(manualUrl, loginUrl, providerName) {
|
|
76
|
+
if (manualUrl) return 'If the browser callback does not finish, open the URL below manually and paste code#state.';
|
|
77
|
+
if (loginUrl) {
|
|
78
|
+
return `Open the URL below to sign in, then paste the authorization code or full redirect URL for ${providerName}.`;
|
|
79
|
+
}
|
|
80
|
+
return `Paste the authorization code or full redirect URL for ${providerName}.`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function pollingLoginMessage(userCode, loginUrl, opened) {
|
|
84
|
+
if (userCode) return `Enter code ${userCode} at:\n${loginUrl}${opened}`;
|
|
85
|
+
if (loginUrl) return `Open this URL to sign in:\n${loginUrl}${opened}`;
|
|
86
|
+
return 'Finish signing in for this provider.';
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
/** Login through store.beginOAuthProviderLogin: a code-completing login hands
|
|
75
90
|
* the surface to the OAuth code prompt; the callback (or the prompt) finishes. */
|
|
76
91
|
function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
@@ -91,26 +106,26 @@ function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
|
91
106
|
message || (ok ? `${providerName} login complete.` : `${providerName} login failed.`)
|
|
92
107
|
);
|
|
93
108
|
};
|
|
109
|
+
// Headless machines never try a browser; the URL is shown in the panel either way.
|
|
110
|
+
const openBrowser = canOpenBrowser();
|
|
94
111
|
void flow.store
|
|
95
|
-
.beginOAuthProviderLogin(providerItem._providerId)
|
|
112
|
+
.beginOAuthProviderLogin(providerItem._providerId, { openBrowser })
|
|
96
113
|
.then((started) => {
|
|
114
|
+
const loginUrl = started?.manualUrl || started?.url || '';
|
|
97
115
|
if (typeof started?.completeCode === 'function') {
|
|
98
116
|
// Post-await handover to the OAuth code prompt: only if this flow
|
|
99
117
|
// still owns the surface (Esc during beginOAuthProviderLogin).
|
|
100
118
|
if (!flow.ownsSurface()) return;
|
|
101
119
|
flow.releaseSurface();
|
|
102
|
-
const manualUrl = started?.manualUrl || '';
|
|
103
120
|
flow.setProviderPrompt({
|
|
104
121
|
kind: 'oauth-code',
|
|
105
122
|
providerId: providerItem._providerId,
|
|
106
123
|
providerName,
|
|
107
124
|
label: `${providerName} OAuth code`,
|
|
108
|
-
hint: manualUrl
|
|
109
|
-
? 'If the browser callback does not finish, open the URL below manually and paste code#state.'
|
|
110
|
-
: `Paste the authorization code or full redirect URL for ${providerName}.`,
|
|
125
|
+
hint: oauthCodeHint(started?.manualUrl, loginUrl, providerName),
|
|
111
126
|
// Shown inside the live panel only — never written to the
|
|
112
127
|
// transcript, so it cannot linger in scrollback after the flow.
|
|
113
|
-
detail:
|
|
128
|
+
detail: loginUrl,
|
|
114
129
|
login: started,
|
|
115
130
|
afterSave: flow.returnTo,
|
|
116
131
|
successReturn: () => {
|
|
@@ -124,16 +139,16 @@ function beginInteractiveOAuthLogin(flow, providerItem, login) {
|
|
|
124
139
|
},
|
|
125
140
|
});
|
|
126
141
|
flow.store.pushNotice(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
} else if (started?.userCode) {
|
|
131
|
-
flow.store.pushNotice(
|
|
132
|
-
`${providerName}: enter code ${started.userCode} in the browser to finish signing in`,
|
|
142
|
+
openBrowser
|
|
143
|
+
? `browser opened for ${providerName}; paste code/redirect here if callback does not finish`
|
|
144
|
+
: `open the URL shown to sign in to ${providerName}, then paste the code/redirect here`,
|
|
133
145
|
'info'
|
|
134
146
|
);
|
|
135
|
-
} else {
|
|
136
|
-
|
|
147
|
+
} else if (!login.backedOut && flow.ownsSurface()) {
|
|
148
|
+
// Device-code and URL-only polling logins stay in the progress panel,
|
|
149
|
+
// with the code and URL, until the result panel replaces it or Back.
|
|
150
|
+
const opened = openBrowser ? ' (browser opened)' : '';
|
|
151
|
+
showOAuthProgress(flow, providerItem, pollingLoginMessage(started?.userCode, loginUrl, opened), login.onBack);
|
|
137
152
|
}
|
|
138
153
|
started.waitForCallback
|
|
139
154
|
?.then((result) => {
|
|
@@ -171,11 +186,14 @@ function runLegacyOAuthLogin(flow, providerItem, login) {
|
|
|
171
186
|
function startOAuthLogin(flow, providerItem) {
|
|
172
187
|
// Back on the progress panel returns to the actions; a login that settles
|
|
173
188
|
// afterwards becomes a notice instead of a result panel.
|
|
174
|
-
const login = {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
189
|
+
const login = {
|
|
190
|
+
backedOut: false,
|
|
191
|
+
onBack: () => {
|
|
192
|
+
login.backedOut = true;
|
|
193
|
+
openOAuthProviderActions(flow, providerItem);
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
showOAuthProgress(flow, providerItem, 'Starting login flow…', login.onBack);
|
|
179
197
|
if (typeof flow.store.beginOAuthProviderLogin === 'function') {
|
|
180
198
|
beginInteractiveOAuthLogin(flow, providerItem, login);
|
|
181
199
|
return;
|
|
@@ -80,8 +80,14 @@ export function buildProviderItems(setup) {
|
|
|
80
80
|
if (setup.managedByClient === true) {
|
|
81
81
|
for (const p of setup.local || []) {
|
|
82
82
|
providerItems.push({
|
|
83
|
-
value: `local:${p.id}`,
|
|
84
|
-
|
|
83
|
+
value: `local:${p.id}`,
|
|
84
|
+
label: p.name,
|
|
85
|
+
meta: providerStatusLabel(p),
|
|
86
|
+
description: '',
|
|
87
|
+
_type: 'local',
|
|
88
|
+
_providerId: p.id,
|
|
89
|
+
_providerName: p.name,
|
|
90
|
+
_provider: p,
|
|
85
91
|
});
|
|
86
92
|
}
|
|
87
93
|
}
|
|
@@ -129,13 +129,17 @@ export function createProviderSetupPicker({
|
|
|
129
129
|
|
|
130
130
|
flow.paint({
|
|
131
131
|
title: options.title || 'Providers',
|
|
132
|
-
description:
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
description:
|
|
133
|
+
setup.managedByClient === true
|
|
134
|
+
? 'Manage provider sign-ins and accounts in the local desktop window. Refresh to update availability.'
|
|
135
|
+
: options.description || 'Choose a provider. Enter opens provider actions.',
|
|
135
136
|
footer: providerFooter,
|
|
136
137
|
footerGapRows: 1,
|
|
137
|
-
help: options.confirmBar
|
|
138
|
-
?
|
|
138
|
+
help: options.confirmBar
|
|
139
|
+
? undefined
|
|
140
|
+
: setup.managedByClient === true
|
|
141
|
+
? '↑/↓ Select · Enter Refresh · Esc Back'
|
|
142
|
+
: '↑/↓ Select · Enter Open · Esc Back',
|
|
139
143
|
indexMode: 'always',
|
|
140
144
|
labelWidth: 18,
|
|
141
145
|
metaWidth: 12,
|