mixdog 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +6 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +7 -9
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +178 -178
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +118 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +6 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +7 -16
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +114 -34
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search.mjs +9 -8
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +478 -251
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +17 -8
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +5 -1
- package/src/tui/session/turn.mjs +38 -31
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
// again, and the session's own lane runs the retry under the entry's
|
|
9
9
|
// generation. Overdue entries run as soon as the scheduler starts.
|
|
10
10
|
|
|
11
|
-
import { isAgentOnlySession } from '../../runtime/shared/quota-resume-store.mjs';
|
|
12
|
-
|
|
13
11
|
/** A still-exhausted reading is re-taken once, this much later. */
|
|
14
12
|
export const QUOTA_RESUME_RETRY_MS = 5 * 60_000;
|
|
15
13
|
/** A busy session is re-checked this much later, without spending an attempt. */
|
|
@@ -32,19 +30,33 @@ async function resumeDueEntry(entry, { store, materializeSession, readQuotaUsabl
|
|
|
32
30
|
return 'unavailable';
|
|
33
31
|
}
|
|
34
32
|
if (!isCurrent(store, entry)) return 'cancelled';
|
|
35
|
-
// A delegated agent child never owns a resume (the Lead decides retries), so
|
|
36
|
-
// an entry persisted for one never fires, whatever wrote it.
|
|
37
|
-
if (isAgentOnlySession({ id: sessionId, ...runtime?.session })) {
|
|
38
|
-
store.cancelQuotaResumeEntry(sessionId, { generation });
|
|
39
|
-
return 'agent-session';
|
|
40
|
-
}
|
|
41
33
|
let usable = false;
|
|
34
|
+
const currentRoute = () => {
|
|
35
|
+
const snapshot = runtime.getState?.() ?? {};
|
|
36
|
+
return {
|
|
37
|
+
// The selected route is what the next turn runs on; sessionProvider /
|
|
38
|
+
// sessionModel still hold the previous turn's after a deferred selection.
|
|
39
|
+
provider: snapshot.provider || snapshot.sessionProvider || runtime.session?.provider || entry.provider,
|
|
40
|
+
model: snapshot.model || snapshot.sessionModel || runtime.session?.model || entry.model,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
const { provider, model } = currentRoute();
|
|
42
44
|
try {
|
|
43
|
-
usable = await readQuotaUsable(
|
|
45
|
+
usable = await readQuotaUsable(provider, model);
|
|
44
46
|
} catch (error) {
|
|
45
|
-
log(`quota resume usage reading failed provider=${
|
|
47
|
+
log(`quota resume usage reading failed provider=${provider}: ${error?.message || error}`);
|
|
46
48
|
}
|
|
47
49
|
if (!isCurrent(store, entry)) return 'cancelled';
|
|
50
|
+
const selected = currentRoute();
|
|
51
|
+
if (selected.provider !== provider || selected.model !== model) {
|
|
52
|
+
// The reading belongs to the old route. Preserve the reservation and
|
|
53
|
+
// check the selected route on the normal busy-recheck cadence.
|
|
54
|
+
store.deferQuotaResumeEntry(sessionId, generation, {
|
|
55
|
+
resetAt: now() + QUOTA_RESUME_BUSY_RECHECK_MS,
|
|
56
|
+
attempts: entry.attempts,
|
|
57
|
+
});
|
|
58
|
+
return 'route-changed';
|
|
59
|
+
}
|
|
48
60
|
if (!usable) {
|
|
49
61
|
// One more reading five minutes on; after that the session falls back
|
|
50
62
|
// to the user's own choice.
|
|
@@ -59,8 +71,8 @@ async function resumeDueEntry(entry, { store, materializeSession, readQuotaUsabl
|
|
|
59
71
|
return 'exhausted';
|
|
60
72
|
}
|
|
61
73
|
const outcome =
|
|
62
|
-
typeof runtime?.fireQuotaResume === 'function' ? runtime.fireQuotaResume({ generation }) : 'unsupported';
|
|
63
|
-
if (outcome === 'busy') {
|
|
74
|
+
typeof runtime?.fireQuotaResume === 'function' ? await runtime.fireQuotaResume({ generation }) : 'unsupported';
|
|
75
|
+
if (outcome === 'busy' || outcome === 'rejected') {
|
|
64
76
|
store.deferQuotaResumeEntry(sessionId, generation, {
|
|
65
77
|
resetAt: now() + QUOTA_RESUME_BUSY_RECHECK_MS,
|
|
66
78
|
attempts: entry.attempts,
|
|
@@ -117,7 +129,10 @@ export function createQuotaResumeScheduler({
|
|
|
117
129
|
log(`quota resume session=${entry.sessionId} outcome=${outcome}`);
|
|
118
130
|
} catch (error) {
|
|
119
131
|
log(`quota resume failed session=${entry.sessionId}: ${error?.message || error}`);
|
|
120
|
-
store.
|
|
132
|
+
store.deferQuotaResumeEntry(entry.sessionId, entry.generation, {
|
|
133
|
+
resetAt: now() + QUOTA_RESUME_RETRY_MS,
|
|
134
|
+
attempts: entry.attempts,
|
|
135
|
+
});
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
138
|
})().finally(() => {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// ./goal-recovery.mjs.
|
|
6
6
|
import { createGoalRecovery } from './goal-recovery.mjs';
|
|
7
7
|
import {
|
|
8
|
+
attachmentsForIntake,
|
|
8
9
|
materializePromptSubmission,
|
|
9
10
|
preparePromptSubmissionForProvider,
|
|
10
11
|
} from '../../../runtime/attachments/store.mjs';
|
|
@@ -52,18 +53,28 @@ export function createSessionTurnCalls(ctx) {
|
|
|
52
53
|
const entry = await entryForSession(id, openHints || {});
|
|
53
54
|
const target = entry.runtime.submitAsync;
|
|
54
55
|
if (typeof target !== 'function') throw new TypeError('session runtime must implement submitAsync');
|
|
55
|
-
const intake = await preparePromptSubmissionForProvider(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
56
|
+
const intake = await preparePromptSubmissionForProvider(materializePromptSubmission(prompt, options || {}), {
|
|
57
|
+
nativePdf: providerNativePdf(entry.runtime.provider || entry.runtime.session?.provider || ''),
|
|
58
|
+
});
|
|
59
59
|
// Await intake only: submitAsync resolves once the prompt is represented by
|
|
60
60
|
// the queue/user row, while provider execution remains daemon-owned and
|
|
61
61
|
// detached.
|
|
62
62
|
let submissionOptions = intake.options;
|
|
63
|
-
|
|
63
|
+
// Every send (desktop or paired device) reaches the engine here: the
|
|
64
|
+
// message records its attachments by content hash, so any device can open
|
|
65
|
+
// or download them by id later (and the store's census keeps the blobs).
|
|
66
|
+
const attachments = attachmentsForIntake(intake.prompt, intake.options);
|
|
67
|
+
if (attachments.length || entry.runtime.externalAction === true) {
|
|
64
68
|
const transcriptMeta = intake.options?.transcriptMeta;
|
|
65
69
|
const baseMeta = transcriptMeta && typeof transcriptMeta === 'object' ? transcriptMeta : {};
|
|
66
|
-
submissionOptions = {
|
|
70
|
+
submissionOptions = {
|
|
71
|
+
...intake.options,
|
|
72
|
+
transcriptMeta: {
|
|
73
|
+
...baseMeta,
|
|
74
|
+
...(attachments.length ? { attachments } : {}),
|
|
75
|
+
...(entry.runtime.externalAction === true ? { sender: 'user' } : {}),
|
|
76
|
+
},
|
|
77
|
+
};
|
|
67
78
|
}
|
|
68
79
|
const accepted = await Promise.resolve(target.call(entry.runtime, intake.prompt, submissionOptions));
|
|
69
80
|
if (accepted === true) {
|
|
@@ -6,6 +6,7 @@ import { SESSION_READ_ACTION_SET } from '../../session-protocol.mjs';
|
|
|
6
6
|
import { SESSION_ID_PATTERN } from '../agent-tree.mjs';
|
|
7
7
|
import {
|
|
8
8
|
loadLiveTranscriptHead,
|
|
9
|
+
readTranscriptRange,
|
|
9
10
|
rebudgetTranscriptWindow,
|
|
10
11
|
requestedHeldTranscript,
|
|
11
12
|
requestedTranscriptWindow,
|
|
@@ -132,6 +133,11 @@ export function createSessionViewCalls(ctx) {
|
|
|
132
133
|
if (!id) throw new TypeError('sessionId is required');
|
|
133
134
|
const live = await liveEntryFor(id);
|
|
134
135
|
assertAvailable(live);
|
|
136
|
+
if (params.transcriptRange) {
|
|
137
|
+
const range = await readTranscriptRange(live, id, readStoredSession, params.transcriptRange);
|
|
138
|
+
assertAvailable(live);
|
|
139
|
+
return { range };
|
|
140
|
+
}
|
|
135
141
|
if (live) {
|
|
136
142
|
return liveSessionReadResult(live, params, id, baseRevision);
|
|
137
143
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { encodeCatalogCursor } from '../runtime/agent/orchestrator/session/catalog-db/schema.mjs';
|
|
2
|
+
import { truncateToolText } from '../runtime/shared/tool-primitives.mjs';
|
|
3
|
+
import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
|
|
4
|
+
|
|
5
|
+
import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/shared/tool-output-budget.mjs';
|
|
6
|
+
|
|
7
|
+
export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
|
|
8
|
+
const MESSAGE_TEXT_LIMIT = 2000;
|
|
9
|
+
const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
10
|
+
|
|
11
|
+
/** Keep catalog paging authoritative even when the output budget shortens a page. */
|
|
12
|
+
export function sessionListOutput(page, limit) {
|
|
13
|
+
const raw = page.sessions;
|
|
14
|
+
const sessions = raw.slice(0, limit).map((row) => ({
|
|
15
|
+
id: row.id,
|
|
16
|
+
...(row.title || row.preview ? { title: truncateToolText(row.title || row.preview, 160) } : {}),
|
|
17
|
+
...(row.status ? { status: row.status } : {}),
|
|
18
|
+
...(row.cwd ? { cwd: row.cwd } : {}),
|
|
19
|
+
}));
|
|
20
|
+
const result = { sessions, nextCursor: page.nextCursor ?? null };
|
|
21
|
+
for (;;) {
|
|
22
|
+
if (sessions.length < raw.length && sessions.length) {
|
|
23
|
+
result.nextCursor = encodeCatalogCursor(raw[sessions.length - 1]);
|
|
24
|
+
}
|
|
25
|
+
if (outputBytes(result) <= TOOL_OUTPUT_PAGE_BYTES) return result;
|
|
26
|
+
if (sessions.length <= 1) throw new Error('session: one catalog row exceeds the output budget');
|
|
27
|
+
sessions.pop();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function conversationItem(item, offset, textOffset) {
|
|
32
|
+
const row = { kind: item.kind, offset, ...(item.id != null ? { id: item.id } : {}) };
|
|
33
|
+
if (item.name) row.name = item.name;
|
|
34
|
+
if (item.status) row.status = item.status;
|
|
35
|
+
if (item.isError === true) row.isError = true;
|
|
36
|
+
let text = item.text || item.detail || item.label || '';
|
|
37
|
+
if (item.kind === 'tool') {
|
|
38
|
+
const value = item.rawResult ?? item.result ?? '';
|
|
39
|
+
const raw = typeof value === 'string' ? value : JSON.stringify(value);
|
|
40
|
+
text = raw || summarizeToolResult(item.name, item.args, raw, item.isError === true) || text;
|
|
41
|
+
}
|
|
42
|
+
if (text) {
|
|
43
|
+
// Conversation indentation is significant; do not trim code/prose like a title.
|
|
44
|
+
if (
|
|
45
|
+
textOffset > 0 &&
|
|
46
|
+
/[\uDC00-\uDFFF]/.test(text[textOffset] || '') &&
|
|
47
|
+
/[\uD800-\uDBFF]/.test(text[textOffset - 1])
|
|
48
|
+
)
|
|
49
|
+
throw new Error('session: text_offset splits a surrogate pair');
|
|
50
|
+
let end = Math.min(text.length, textOffset + MESSAGE_TEXT_LIMIT);
|
|
51
|
+
if (end < text.length && /[\uD800-\uDBFF]/.test(text[end - 1])) end--;
|
|
52
|
+
row.text = text.slice(textOffset, end);
|
|
53
|
+
if (end < text.length) row.nextTextOffset = end;
|
|
54
|
+
}
|
|
55
|
+
const attachments = item.attachments ?? item.imageRefs ?? item.images;
|
|
56
|
+
if (attachments?.length) row.attachments = attachments.length;
|
|
57
|
+
return row;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Service windows can be sticky/shared; enforce this tool call's limits locally. */
|
|
61
|
+
export function sessionReadOutput(sessionId, range, { textOffset = 0, itemId } = {}) {
|
|
62
|
+
const byteLimit = range.offset === 0 && textOffset === 0 ? TOOL_OUTPUT_TAIL_BYTES : TOOL_OUTPUT_PAGE_BYTES;
|
|
63
|
+
const source = range.items;
|
|
64
|
+
if (itemId !== undefined && (source.length !== 1 || source[0].id !== itemId)) {
|
|
65
|
+
throw new Error('session: stale item position; read the tail again');
|
|
66
|
+
}
|
|
67
|
+
const items = source.map((item, index) =>
|
|
68
|
+
conversationItem(item, range.offset + source.length - index - 1, textOffset)
|
|
69
|
+
);
|
|
70
|
+
const result = {
|
|
71
|
+
sessionId,
|
|
72
|
+
offset: range.offset,
|
|
73
|
+
items,
|
|
74
|
+
nextOffset: null,
|
|
75
|
+
};
|
|
76
|
+
for (;;) {
|
|
77
|
+
result.nextOffset = range.hasOlder || items.length < source.length ? range.offset + items.length : null;
|
|
78
|
+
if (outputBytes(result) <= byteLimit) return result;
|
|
79
|
+
if (items.length <= 1) throw new Error('session: one transcript item exceeds the output budget');
|
|
80
|
+
items.shift();
|
|
81
|
+
}
|
|
82
|
+
}
|
package/src/tui/app/app-view.jsx
CHANGED
|
@@ -138,6 +138,7 @@ export function renderAppView(ctx) {
|
|
|
138
138
|
thinkingActiveSince={liveSpinner?.thinkingSegmentStartedAt ?? 0}
|
|
139
139
|
thinkingMs={liveSpinner?.thinkingAccumulatedMs ?? 0}
|
|
140
140
|
effort={state.effort || ''}
|
|
141
|
+
quiet={liveSpinner?.quiet ?? null}
|
|
141
142
|
hasActiveTools={!!activeTools?.web_search?.count}
|
|
142
143
|
paused={!!toolApproval}
|
|
143
144
|
interruptible={!!(state.busy && state.spinner?.active)}
|
|
@@ -230,7 +231,7 @@ export function renderAppView(ctx) {
|
|
|
230
231
|
) : null}
|
|
231
232
|
<StatusLine
|
|
232
233
|
sessionId={state.sessionId}
|
|
233
|
-
clientHostPid={state.
|
|
234
|
+
clientHostPid={state.clientHostPid}
|
|
234
235
|
provider={state.provider}
|
|
235
236
|
model={state.model}
|
|
236
237
|
effort={state.effort}
|
|
@@ -77,6 +77,14 @@ export function buildProviderItems(setup) {
|
|
|
77
77
|
_authenticated: p.authenticated,
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
+
if (setup.managedByClient === true) {
|
|
81
|
+
for (const p of setup.local || []) {
|
|
82
|
+
providerItems.push({
|
|
83
|
+
value: `local:${p.id}`, label: p.name, meta: providerStatusLabel(p), description: '',
|
|
84
|
+
_type: 'local', _providerId: p.id, _providerName: p.name, _provider: p,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
80
88
|
providerItems.sort((a, b) => {
|
|
81
89
|
const rank = providerItemRank(a) - providerItemRank(b);
|
|
82
90
|
if (rank !== 0) return rank;
|
|
@@ -54,7 +54,7 @@ export function createProviderSetupPicker({
|
|
|
54
54
|
});
|
|
55
55
|
try {
|
|
56
56
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
57
|
-
return await store.getProviderSetup();
|
|
57
|
+
return await store.getProviderSetup(options.forceRefresh ? { force: true } : undefined);
|
|
58
58
|
} catch (e) {
|
|
59
59
|
store.pushNotice(`providers failed: ${e?.message || e}`, 'error');
|
|
60
60
|
return null;
|
|
@@ -98,6 +98,9 @@ export function createProviderSetupPicker({
|
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
100
|
items.push(...buildProviderItems(setup));
|
|
101
|
+
if (setup.managedByClient === true) {
|
|
102
|
+
items.push({ value: 'refresh-client-providers', label: 'Refresh', _type: 'refresh-client-providers' });
|
|
103
|
+
}
|
|
101
104
|
|
|
102
105
|
const flow = {
|
|
103
106
|
store,
|
|
@@ -127,10 +130,13 @@ export function createProviderSetupPicker({
|
|
|
127
130
|
|
|
128
131
|
flow.paint({
|
|
129
132
|
title: options.title || 'Providers',
|
|
130
|
-
description:
|
|
133
|
+
description: 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.',
|
|
131
136
|
footer: providerFooter,
|
|
132
137
|
footerGapRows: 1,
|
|
133
|
-
help: options.confirmBar ? undefined :
|
|
138
|
+
help: options.confirmBar ? undefined : setup.managedByClient === true
|
|
139
|
+
? '↑/↓ Select · Enter Refresh · Esc Back' : '↑/↓ Select · Enter Open · Esc Back',
|
|
134
140
|
indexMode: 'always',
|
|
135
141
|
labelWidth: 18,
|
|
136
142
|
metaWidth: 12,
|
|
@@ -142,6 +148,12 @@ export function createProviderSetupPicker({
|
|
|
142
148
|
if (item?._providerId) flow.rememberProviderSelection(item);
|
|
143
149
|
},
|
|
144
150
|
onSelect: (_value, item) => {
|
|
151
|
+
if (setup.managedByClient === true && item._type !== 'continue') {
|
|
152
|
+
if (item._type === 'refresh-client-providers') {
|
|
153
|
+
void openProviderSetupPicker({ ...options, preloadedSetup: null, forceRefresh: true });
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
145
157
|
// In-flow navigation (Enter on a provider row): the flow keeps the
|
|
146
158
|
// surface, so clear-and-continue — own.close() would supersede this
|
|
147
159
|
// very flow and paintProviders would then reject the action panel the
|
|
@@ -35,6 +35,12 @@ export const SLASH_COMMANDS = [
|
|
|
35
35
|
},
|
|
36
36
|
{ name: 'resume', usage: '/resume', params: '[id]', description: 'Resume a saved chat' },
|
|
37
37
|
{ name: 'context', usage: '/context', description: 'Show current context surface' },
|
|
38
|
+
{
|
|
39
|
+
name: 'shells',
|
|
40
|
+
usage: '/shells',
|
|
41
|
+
params: '[release <task_id> [--confirm]]',
|
|
42
|
+
description: 'List shells; release one whose termination is unconfirmed',
|
|
43
|
+
},
|
|
38
44
|
{
|
|
39
45
|
name: 'fork',
|
|
40
46
|
usage: '/fork',
|
|
@@ -119,6 +119,55 @@ export const sessionCommands = {
|
|
|
119
119
|
return true;
|
|
120
120
|
},
|
|
121
121
|
|
|
122
|
+
// /shells — this session's shells, each marked running or "termination
|
|
123
|
+
// unconfirmed". `/shells release <id>` explains what releasing means and
|
|
124
|
+
// asks for `--confirm`; only then is the workspace hold dropped.
|
|
125
|
+
shells(ctx, arg) {
|
|
126
|
+
const { store } = ctx;
|
|
127
|
+
const [action, taskId, flag] = String(arg || '')
|
|
128
|
+
.trim()
|
|
129
|
+
.split(/\s+/)
|
|
130
|
+
.filter(Boolean);
|
|
131
|
+
if (!action) {
|
|
132
|
+
void Promise.resolve(store.listShellJobs?.())
|
|
133
|
+
.then((result) => {
|
|
134
|
+
const jobs = Array.isArray(result?.jobs) ? result.jobs : [];
|
|
135
|
+
if (!jobs.length) {
|
|
136
|
+
store.pushNotice('No shells are running.', 'info');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const lines = jobs.map(
|
|
140
|
+
(job) =>
|
|
141
|
+
`${job.taskId} ${job.terminationUnconfirmed ? 'termination unconfirmed' : 'running'} ${job.command}`
|
|
142
|
+
);
|
|
143
|
+
const held = jobs.some((job) => job.terminationUnconfirmed);
|
|
144
|
+
if (held) lines.push('Release a held shell with /shells release <task_id>.');
|
|
145
|
+
store.pushNotice(lines.join('\n'), held ? 'warn' : 'info');
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => store.pushNotice(`Couldn’t list shells: ${error?.message || error}`, 'error'));
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (action !== 'release' || !taskId) {
|
|
151
|
+
store.pushNotice('usage: /shells [release <task_id> [--confirm]]', 'warn');
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
if (flag !== '--confirm') {
|
|
155
|
+
store.pushNotice(
|
|
156
|
+
`Releasing ${taskId} unlocks its folder although its processes may still be running. To proceed, run /shells release ${taskId} --confirm`,
|
|
157
|
+
'warn'
|
|
158
|
+
);
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
void Promise.resolve(store.releaseShellJob?.(taskId))
|
|
162
|
+
.then((result) =>
|
|
163
|
+
result?.released
|
|
164
|
+
? store.pushNotice(`Released ${taskId}.`, 'info')
|
|
165
|
+
: store.pushNotice(`Couldn’t release ${taskId}: ${result?.error || 'unavailable'}`, 'warn')
|
|
166
|
+
)
|
|
167
|
+
.catch((error) => store.pushNotice(`Couldn’t release ${taskId}: ${error?.message || error}`, 'error'));
|
|
168
|
+
return true;
|
|
169
|
+
},
|
|
170
|
+
|
|
122
171
|
doctor(ctx) {
|
|
123
172
|
const { state, store, deps } = ctx;
|
|
124
173
|
if (state.commandBusy) {
|
|
@@ -66,6 +66,8 @@ export function Spinner({
|
|
|
66
66
|
thinkingActiveSince = 0,
|
|
67
67
|
thinkingMs = 0,
|
|
68
68
|
effort = '',
|
|
69
|
+
// The turn's quiet state (`spinner.quiet`), shown as the quiet-time cue.
|
|
70
|
+
quiet = null,
|
|
69
71
|
hasActiveTools = false,
|
|
70
72
|
paused = false,
|
|
71
73
|
interruptible = false,
|
|
@@ -126,6 +128,8 @@ export function Spinner({
|
|
|
126
128
|
thinkingActiveSince={thinkingActiveSince}
|
|
127
129
|
thinkingMs={thinkingMs}
|
|
128
130
|
effort={effort}
|
|
131
|
+
quiet={quiet}
|
|
132
|
+
now={now}
|
|
129
133
|
interruptible={interruptible}
|
|
130
134
|
columns={columns}
|
|
131
135
|
reducedMotion={reducedMotion}
|
|
@@ -20,6 +20,7 @@ const THINKING_DELAY_MS = 3000;
|
|
|
20
20
|
// One-way shimmer. The tail runs past the final character before restarting.
|
|
21
21
|
const GLIMMER_SPEED_MS = {
|
|
22
22
|
requesting: 70,
|
|
23
|
+
'model-thinking': 70,
|
|
23
24
|
reconnecting: 70,
|
|
24
25
|
compacting: 120,
|
|
25
26
|
'auto-clear': 120,
|
|
@@ -91,7 +92,9 @@ function tokenModeGlyph(mode) {
|
|
|
91
92
|
case 'responding':
|
|
92
93
|
case 'thinking':
|
|
93
94
|
return DOWN_ARROW;
|
|
95
|
+
// The request is sent and nothing has come back yet.
|
|
94
96
|
case 'requesting':
|
|
97
|
+
case 'model-thinking':
|
|
95
98
|
return UP_ARROW;
|
|
96
99
|
default:
|
|
97
100
|
return '';
|
|
@@ -108,6 +111,8 @@ export function SpinnerByline({
|
|
|
108
111
|
thinkingActiveSince,
|
|
109
112
|
thinkingMs,
|
|
110
113
|
effort,
|
|
114
|
+
quiet = null,
|
|
115
|
+
now = Date.now(),
|
|
111
116
|
interruptible,
|
|
112
117
|
columns,
|
|
113
118
|
reducedMotion,
|
|
@@ -151,6 +156,8 @@ export function SpinnerByline({
|
|
|
151
156
|
thinkingSince: thinkingActiveSince,
|
|
152
157
|
thinkingMs,
|
|
153
158
|
effort,
|
|
159
|
+
quiet,
|
|
160
|
+
now,
|
|
154
161
|
});
|
|
155
162
|
const tokenGlyph = tokenModeGlyph(mode);
|
|
156
163
|
let tokenText = '';
|
|
@@ -176,8 +183,13 @@ export function SpinnerByline({
|
|
|
176
183
|
const interruptW = interruptText.length;
|
|
177
184
|
const showInterrupt = Boolean(interruptText) && avail > interruptW;
|
|
178
185
|
const usedAfterInterrupt = showInterrupt ? interruptW + SEP_WIDTH : 0;
|
|
179
|
-
|
|
180
|
-
|
|
186
|
+
// A quiet turn says so before any other stat: it is the one that explains a
|
|
187
|
+
// long silence (the interrupt hint beside it is how to stop it).
|
|
188
|
+
const quietText = meta.quietText;
|
|
189
|
+
const showQuiet = Boolean(quietText) && avail > usedAfterInterrupt + quietText.length;
|
|
190
|
+
const usedAfterQuiet = usedAfterInterrupt + (showQuiet ? quietText.length + SEP_WIDTH : 0);
|
|
191
|
+
const showThinkingStatus = Boolean(thinkingStatusText) && avail > usedAfterQuiet + thinkingStatusW;
|
|
192
|
+
const usedAfterThinking = usedAfterQuiet + (showThinkingStatus ? thinkingStatusW + SEP_WIDTH : 0);
|
|
181
193
|
const showTimer = Boolean(timerLabel) && avail > usedAfterThinking + timerW;
|
|
182
194
|
const usedAfterTimer = usedAfterThinking + (showTimer ? timerW + SEP_WIDTH : 0);
|
|
183
195
|
const showTokens = wantsTokens && tokenText && avail > usedAfterTimer + tokenW;
|
|
@@ -223,6 +235,13 @@ export function SpinnerByline({
|
|
|
223
235
|
)
|
|
224
236
|
);
|
|
225
237
|
}
|
|
238
|
+
if (showQuiet) {
|
|
239
|
+
segments.push(
|
|
240
|
+
<Text key="quiet" color={meta.quietParts?.escalated ? theme.warning : theme.statusSubtle}>
|
|
241
|
+
{quietText}
|
|
242
|
+
</Text>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
226
245
|
if (showInterrupt) {
|
|
227
246
|
segments.push(
|
|
228
247
|
<Text key="interrupt" color={theme.statusSubtle}>
|
|
@@ -10,7 +10,7 @@ import { normalizeStatuslineAnsi } from '../../statusline-ansi-bridge.mjs';
|
|
|
10
10
|
// Cache-only synchronous read (never touches fs on the render path), so the
|
|
11
11
|
// instant-local L2 can render the Shell segment itself instead of grafting it
|
|
12
12
|
// out of the previous full line.
|
|
13
|
-
import { shellJobsStatus } from '../../../runtime/shared/statusline/statusline-segments.mjs';
|
|
13
|
+
import { shellJobsStatus, unconfirmedShellCount } from '../../../runtime/shared/statusline/statusline-segments.mjs';
|
|
14
14
|
import { formatElapsed, num, terminalColumns, timeMs } from '../../../runtime/shared/statusline/statusline-format.mjs';
|
|
15
15
|
import { isTerminalStatus } from './boot-schedule.mjs';
|
|
16
16
|
|
|
@@ -137,11 +137,19 @@ export function localStatusLineL2(
|
|
|
137
137
|
const shellStatus = shellScope
|
|
138
138
|
? shellJobsStatus({ clientHostPid, sessionId: shellScope })
|
|
139
139
|
: shellJobsStatus({ clientHostPid });
|
|
140
|
-
|
|
140
|
+
// A shell whose termination is unconfirmed is not "running": it is held,
|
|
141
|
+
// with /shells as the way to inspect or release it.
|
|
142
|
+
const unconfirmed = unconfirmedShellCount(shellStatus);
|
|
143
|
+
const shellCount = (Number(shellStatus?.count) || 0) - unconfirmed;
|
|
141
144
|
if (shellCount > 0) {
|
|
142
145
|
const label = `Running ${shellCount} Shell${shellCount === 1 ? '' : 's'}`;
|
|
143
146
|
l2Parts.push(`${spin} ${STATUS}${label}${RESET}${elapsedSuffix(shellStatus.elapsedLabel || '')}`);
|
|
144
147
|
}
|
|
148
|
+
if (unconfirmed > 0) {
|
|
149
|
+
const { WARNING } = statusColors();
|
|
150
|
+
const label = `⚠ ${unconfirmed} Shell${unconfirmed === 1 ? '' : 's'} termination unconfirmed`;
|
|
151
|
+
l2Parts.push(`${WARNING}${label}${RESET} ${SUBTLE}·${RESET} /shells`);
|
|
152
|
+
}
|
|
145
153
|
// `web_search` is the key the producers publish (session/active-tool-summary
|
|
146
154
|
// and app/use-transcript-activity); the async full render reads the same key,
|
|
147
155
|
// so both paths light the segment on the same snapshot.
|