mixdog 1.2.2 → 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/README.md +18 -0
- package/package.json +2 -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 +599 -0
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- 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 +11 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +20 -15
- package/src/output-styles/common.md +11 -10
- package/src/rules/agent/AGENT.md +6 -4
- 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/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- 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-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
- 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 +31 -15
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -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 +131 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
- 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 +42 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- 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 +19 -14
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
- 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/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
- package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- 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/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- 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 +5 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- 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 +3 -2
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -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 +89 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -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 +24 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
- 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 +23 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- 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 +231 -16
- 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 +47 -17
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
- 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/live-state.mjs +23 -0
- 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 +44 -37
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- 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 -21
- 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 +4 -2
- 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-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
- 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 +17 -10
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
- 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/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- 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/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
- 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 +247 -49
- 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/runtime-capabilities.mjs +23 -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/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- 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/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- 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 +219 -196
- 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 +208 -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/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +36 -33
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +1 -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/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +94 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +29 -0
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- 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-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +191 -0
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +48 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/loopback-listener.mjs +9 -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 +8 -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/review-diff.mjs +52 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +121 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
- package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +22 -1
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +20 -6
- package/src/runtime/shared/tool-work-units.mjs +54 -11
- 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/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +24 -6
- package/src/runtime/shared/turn-changes.mjs +269 -100
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
- package/src/runtime/shared/turn-snapshot.mjs +865 -683
- package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- 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 +533 -0
- package/src/runtime/shared/worktrees/contract.mjs +60 -0
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
- package/src/runtime/shared/worktrees/git-head.mjs +214 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- 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 +525 -31
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- 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 +57 -20
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +20 -6
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +4 -0
- package/src/session-runtime/boot/infrastructure.mjs +6 -1
- package/src/session-runtime/boot/session.mjs +3 -3
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
- package/src/session-runtime/internal-tool-executor.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
- 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 +70 -14
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +17 -5
- 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 +116 -36
- 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-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +19 -9
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- 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/resource-scope-decorate.mjs +10 -3
- 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/runtime-review-api.mjs +8 -2
- 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/index-write-queue.mjs +81 -20
- 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/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- 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 +82 -13
- 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 +18 -10
- 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/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
- package/src/session-runtime/services/agent-tool.mjs +7 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +158 -15
- 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-purge.mjs +32 -0
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +17 -14
- package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
- package/src/session-runtime/setup-tool/executor.mjs +57 -9
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +19 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +26 -45
- package/src/session-runtime/usage-stats-api.mjs +46 -11
- 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 +35 -41
- package/src/session-runtime/workspace/transition-steps.mjs +215 -116
- package/src/session-runtime/workspace/transitions.mjs +428 -73
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +49 -0
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +25 -3
- package/src/standalone/daemon-telemetry.mjs +19 -0
- package/src/standalone/daemon.mjs +63 -1
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +80 -30
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +14 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +3 -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-action.mjs +18 -3
- 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-service-api.mjs +6 -1
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +2 -0
- 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/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +19 -3
- package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +2897 -1722
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +4 -5
- 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 +14 -10
- package/src/tui/session/session-api/controls.mjs +14 -2
- package/src/tui/session/session-api/integrations.mjs +9 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +14 -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 +9 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-api.mjs +1 -0
- 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 +20 -8
- package/src/tui/session/transcript-spill.mjs +14 -7
- 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 +179 -32
- package/src/tui/session/turn.mjs +50 -36
- 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/workflows/default/WORKFLOW.md +3 -1
- 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 -246
- 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
|
@@ -12,24 +12,67 @@
|
|
|
12
12
|
* The owner marker disappears when the job settles and a `.done` marker keeps
|
|
13
13
|
* the terminal JSON out of live counters. Terminal metadata remains available
|
|
14
14
|
* for a bounded manual-recovery window.
|
|
15
|
+
*
|
|
16
|
+
* Ordering: a promoted job keeps its foreground id, so the foreground marker's
|
|
17
|
+
* retire and the promoted job's publish address the same files. Every publish,
|
|
18
|
+
* complete and retire for one jobId therefore runs on a per-job chain, strictly
|
|
19
|
+
* in call order and never overlapping. A record is written atomically (temp
|
|
20
|
+
* file + rename) and always before its owner marker, so a reader never sees a
|
|
21
|
+
* partial `.json`, and a marker never exists without its `.json`.
|
|
15
22
|
*/
|
|
16
23
|
import { access, mkdir, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
|
|
24
|
+
import { unlinkSync } from 'node:fs';
|
|
17
25
|
import { homedir } from 'node:os';
|
|
18
26
|
import { join } from 'node:path';
|
|
27
|
+
import { writeJsonAtomicAsync } from '../../../../../shared/atomic-file.mjs';
|
|
19
28
|
import { isPidAlive } from '../../../../../shared/pid-liveness.mjs';
|
|
20
29
|
import { displayShellCommand } from '../../../../../shared/shell-display.mjs';
|
|
30
|
+
import { tryAdmitWorkspaceActivity } from '../../../../../shared/worktrees/activity-gate.mjs';
|
|
31
|
+
import { worktreeError } from '../../../../../shared/worktrees/contract.mjs';
|
|
32
|
+
import { workspaceSees } from '../../../../../shared/worktrees/workspace-visibility.mjs';
|
|
33
|
+
|
|
34
|
+
const workspaceLeases = new Map();
|
|
35
|
+
|
|
36
|
+
/** Transfer a foreground reader to a surviving-descendant task without a lease gap. */
|
|
37
|
+
export function adoptShellWorkspaceAdmission(jobId, leave) {
|
|
38
|
+
const prior = workspaceLeases.get(jobId);
|
|
39
|
+
workspaceLeases.set(
|
|
40
|
+
jobId,
|
|
41
|
+
prior
|
|
42
|
+
? () => {
|
|
43
|
+
prior();
|
|
44
|
+
leave();
|
|
45
|
+
}
|
|
46
|
+
: leave
|
|
47
|
+
);
|
|
48
|
+
}
|
|
21
49
|
|
|
22
50
|
// A record whose owner process is gone is garbage. Age alone never deletes a
|
|
23
51
|
// live owner's job, so an unlimited long-running shell keeps its record.
|
|
24
52
|
const ORPHAN_GRACE_MS = 60 * 60 * 1000;
|
|
25
53
|
const COMPLETED_SHELL_JOB_TTL_MS = 30 * 60 * 1000;
|
|
26
54
|
|
|
27
|
-
const
|
|
55
|
+
const chains = new Map();
|
|
28
56
|
const paths = new Map();
|
|
29
57
|
const records = new Map();
|
|
30
|
-
|
|
58
|
+
// jobId -> token of the live terminal record. Every publish/retire clears it and
|
|
59
|
+
// every completion replaces it, so a TTL timer armed for an older incarnation
|
|
60
|
+
// can tell its files are no longer the ones it was armed for.
|
|
61
|
+
const incarnations = new Map();
|
|
62
|
+
let incarnationSeq = 0;
|
|
31
63
|
let sweepStarted = false;
|
|
32
64
|
|
|
65
|
+
/** Run `operation` after every earlier operation for `jobId` has finished. */
|
|
66
|
+
function enqueue(jobId, operation) {
|
|
67
|
+
const run = (chains.get(jobId) || Promise.resolve()).then(operation);
|
|
68
|
+
const tail = run.catch(() => {});
|
|
69
|
+
chains.set(jobId, tail);
|
|
70
|
+
void tail.then(() => {
|
|
71
|
+
if (chains.get(jobId) === tail) chains.delete(jobId);
|
|
72
|
+
});
|
|
73
|
+
return run;
|
|
74
|
+
}
|
|
75
|
+
|
|
33
76
|
function dataDir() {
|
|
34
77
|
return process.env.MIXDOG_DATA_DIR || join(process.env.MIXDOG_HOME || join(homedir(), '.mixdog'), 'data');
|
|
35
78
|
}
|
|
@@ -132,17 +175,32 @@ async function sweepOrphanRecords(dir) {
|
|
|
132
175
|
/** Publish the record for a job that has just started or been promoted. */
|
|
133
176
|
export function publishShellJobRecord(
|
|
134
177
|
task,
|
|
135
|
-
{
|
|
178
|
+
{
|
|
179
|
+
ownerSessionId = null,
|
|
180
|
+
clientHostPid = null,
|
|
181
|
+
startedAtMs = 0,
|
|
182
|
+
foreground = false,
|
|
183
|
+
terminationUnconfirmed = false,
|
|
184
|
+
} = {}
|
|
136
185
|
) {
|
|
137
186
|
const jobId = String(task?.jobId || '').trim();
|
|
138
187
|
if (!jobId) return;
|
|
188
|
+
if (task?.cwd) {
|
|
189
|
+
const leave = tryAdmitWorkspaceActivity(ownerSessionId || jobId, task.cwd, {
|
|
190
|
+
pid: Number(task.pid) || process.pid,
|
|
191
|
+
kind: 'command',
|
|
192
|
+
});
|
|
193
|
+
if (!leave) throw worktreeError('WORKTREE_BUSY_JOBS', 'The command folder is being managed.');
|
|
194
|
+
// A descendant handoff can reuse the job id with a different live pid.
|
|
195
|
+
// Acquire its reader before releasing any predecessor's admission.
|
|
196
|
+
adoptShellWorkspaceAdmission(jobId, leave);
|
|
197
|
+
}
|
|
139
198
|
const ownerPid = Number(clientHostPid ?? task?.clientHostPid) || process.pid;
|
|
140
199
|
const dir = jobsDir();
|
|
141
200
|
const jsonPath = join(dir, `${jobId}.json`);
|
|
142
201
|
const ownerPath = join(dir, `${jobId}.owner-${ownerPid}`);
|
|
143
|
-
retired.delete(jobId);
|
|
144
202
|
paths.set(jobId, [jsonPath, ownerPath]);
|
|
145
|
-
|
|
203
|
+
void enqueue(jobId, async () => {
|
|
146
204
|
try {
|
|
147
205
|
await mkdir(dir, { recursive: true });
|
|
148
206
|
if (!sweepStarted) {
|
|
@@ -170,88 +228,230 @@ export function publishShellJobRecord(
|
|
|
170
228
|
// removed on settle. Restart recovery skips them: there is no
|
|
171
229
|
// task id to report and no waiter to notify.
|
|
172
230
|
...(foreground ? { foreground: true } : {}),
|
|
231
|
+
// A killed command whose processes are not confirmed gone: its
|
|
232
|
+
// result is reported, but the readouts keep listing it.
|
|
233
|
+
...(terminationUnconfirmed ? { terminationUnconfirmed: true } : {}),
|
|
234
|
+
// Its owner session closed: any session that sees the folder lists
|
|
235
|
+
// (and may release) it.
|
|
236
|
+
...(closedOwnerSessions.has(String(ownerSessionId || '')) ? { ownerSessionClosed: true } : {}),
|
|
173
237
|
};
|
|
174
238
|
records.set(jobId, record);
|
|
175
|
-
|
|
239
|
+
incarnations.delete(jobId);
|
|
240
|
+
// The record lands whole before the marker that advertises it.
|
|
241
|
+
await writeJsonAtomicAsync(jsonPath, record, { fsync: false });
|
|
176
242
|
await writeFile(ownerPath, '', 'utf8');
|
|
177
243
|
} catch {
|
|
178
244
|
/* the record is presentation only; never fail a job for it */
|
|
179
245
|
}
|
|
180
|
-
// A job that settled while the write was in flight must not leave a
|
|
181
|
-
// record behind.
|
|
182
|
-
if (retired.has(jobId)) await removePaths([jsonPath, ownerPath]);
|
|
183
|
-
})();
|
|
184
|
-
publishing.set(jobId, work);
|
|
185
|
-
void work.finally(() => {
|
|
186
|
-
if (publishing.get(jobId) === work) publishing.delete(jobId);
|
|
187
246
|
});
|
|
188
247
|
}
|
|
189
248
|
|
|
190
249
|
/** Preserve a bounded terminal snapshot for manual recovery after restart. */
|
|
250
|
+
// jobId -> { ownerSessionId, release } for every job whose result is reported
|
|
251
|
+
// but whose processes are not confirmed gone. The hold is dropped by the
|
|
252
|
+
// termination watch on confirmation, or by an explicit user force-release —
|
|
253
|
+
// never by a timer.
|
|
254
|
+
const terminationHolds = new Map();
|
|
255
|
+
// Owner sessions that closed in this runtime: their holds have no owner left
|
|
256
|
+
// to release them, so any session that sees the workspace may.
|
|
257
|
+
const closedOwnerSessions = new Set();
|
|
258
|
+
|
|
259
|
+
export function registerTerminationHold(jobId, { ownerSessionId = null, cwd = null, release }) {
|
|
260
|
+
const key = String(jobId || '').trim();
|
|
261
|
+
if (key && typeof release === 'function') terminationHolds.set(key, { ownerSessionId, cwd, release });
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function clearTerminationHold(jobId) {
|
|
265
|
+
terminationHolds.delete(String(jobId || '').trim());
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** The owner session closed: its live records are flagged so every surface
|
|
269
|
+
* can list them for the sessions that see their folder. */
|
|
270
|
+
export function noteShellOwnerSessionClosed(sessionId) {
|
|
271
|
+
const id = String(sessionId || '').trim();
|
|
272
|
+
if (!id) return;
|
|
273
|
+
closedOwnerSessions.add(id);
|
|
274
|
+
for (const [jobId, record] of records) {
|
|
275
|
+
if (record?.ownerSessionId === id) void patchRunningShellJobRecord(jobId, { ownerSessionClosed: true });
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const releaseRequestPath = (key) => join(jobsDir(), `${key}.release-requested`);
|
|
280
|
+
|
|
281
|
+
async function requestRemoteRelease(key, caller) {
|
|
282
|
+
const id = validJobId(key);
|
|
283
|
+
const record = id ? JSON.parse(await readFile(join(jobsDir(), `${id}.json`), 'utf8')) : null;
|
|
284
|
+
if (record?.status !== 'running' || record.terminationUnconfirmed !== true) throw new Error('not held');
|
|
285
|
+
const hold = { ownerSessionId: record.ownerSessionId || null, cwd: record.cwd };
|
|
286
|
+
if (!mayRelease(hold, { ...caller, ownerClosed: record.ownerSessionClosed === true })) {
|
|
287
|
+
throw new Error('not permitted');
|
|
288
|
+
}
|
|
289
|
+
await writeFile(releaseRequestPath(id), '', 'utf8');
|
|
290
|
+
return { released: true, deferred: true };
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** Consume a cross-process release request for `jobId`; true when one existed. */
|
|
294
|
+
export function takeReleaseRequest(jobId) {
|
|
295
|
+
const key = validJobId(jobId);
|
|
296
|
+
if (!key) return false;
|
|
297
|
+
try {
|
|
298
|
+
unlinkSync(releaseRequestPath(key));
|
|
299
|
+
return true;
|
|
300
|
+
} catch {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function mayRelease(hold, { callerSessionId, callerCwd, ownerClosed = closedOwnerSessions.has(hold.ownerSessionId) }) {
|
|
306
|
+
if (!hold.ownerSessionId || hold.ownerSessionId === callerSessionId) return true;
|
|
307
|
+
return ownerClosed && workspaceSees(hold.cwd, callerCwd);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Explicit user action ("Release anyway"): drop the workspace hold of a job
|
|
311
|
+
* whose termination is unconfirmed. The surface asks for confirmation first.
|
|
312
|
+
* The owning session may release it; once that session has closed, any
|
|
313
|
+
* session whose workspace (`callerCwd`) sees the hold's folder may. */
|
|
314
|
+
export async function forceReleaseTerminationHold(jobId, { callerSessionId = null, callerCwd = null } = {}) {
|
|
315
|
+
const key = String(jobId || '').trim();
|
|
316
|
+
const refused = { released: false, error: `no unconfirmed termination hold: ${key}` };
|
|
317
|
+
const hold = terminationHolds.get(key);
|
|
318
|
+
// The hold lives in another runtime process (a desktop pane's session shard):
|
|
319
|
+
// its own observation loop honours the request at its next pass.
|
|
320
|
+
if (!hold) return requestRemoteRelease(key, { callerSessionId, callerCwd }).catch(() => refused);
|
|
321
|
+
if (!mayRelease(hold, { callerSessionId, callerCwd })) return refused;
|
|
322
|
+
try {
|
|
323
|
+
await hold.release();
|
|
324
|
+
} catch (error) {
|
|
325
|
+
return { released: false, error: error instanceof Error ? error.message : String(error) };
|
|
326
|
+
}
|
|
327
|
+
if (terminationHolds.get(key) === hold) terminationHolds.delete(key);
|
|
328
|
+
return { released: true };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Release the workspace admission adopted under `jobId` without a record of
|
|
332
|
+
* its own (survivors a finished foreground command left behind), once they
|
|
333
|
+
* are confirmed gone. */
|
|
334
|
+
export function releaseShellJobWorkspace(jobId) {
|
|
335
|
+
const key = String(jobId || '').trim();
|
|
336
|
+
const leave = workspaceLeases.get(key);
|
|
337
|
+
if (!leave) return;
|
|
338
|
+
leave();
|
|
339
|
+
if (workspaceLeases.get(key) === leave) workspaceLeases.delete(key);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** Flag a still-open job record as "termination unconfirmed" for the readouts. */
|
|
343
|
+
export function markShellJobTerminationUnconfirmed(jobId) {
|
|
344
|
+
return patchRunningShellJobRecord(jobId, { terminationUnconfirmed: true });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function patchRunningShellJobRecord(jobId, patch) {
|
|
348
|
+
const key = validJobId(jobId);
|
|
349
|
+
if (!key) return Promise.resolve(false);
|
|
350
|
+
const jsonPath = join(jobsDir(), `${key}.json`);
|
|
351
|
+
return enqueue(key, async () => {
|
|
352
|
+
const record = records.get(key);
|
|
353
|
+
if (record?.status !== 'running') return false;
|
|
354
|
+
const next = { ...record, ...patch };
|
|
355
|
+
records.set(key, next);
|
|
356
|
+
await writeJsonAtomicAsync(jsonPath, next, { fsync: false });
|
|
357
|
+
return true;
|
|
358
|
+
}).catch(() => false);
|
|
359
|
+
}
|
|
360
|
+
|
|
191
361
|
export function completeShellJobRecord(jobId, detail) {
|
|
192
362
|
const key = validJobId(jobId);
|
|
193
363
|
if (!key) return Promise.resolve(false);
|
|
364
|
+
const leaveWorkspace = workspaceLeases.get(key);
|
|
194
365
|
const dir = jobsDir();
|
|
195
366
|
const jsonPath = join(dir, `${key}.json`);
|
|
196
367
|
const donePath = join(dir, `${key}.done`);
|
|
197
368
|
const list = paths.get(key) || [jsonPath];
|
|
198
369
|
const ownerPaths = list.filter((path) => path.includes('.owner-'));
|
|
199
|
-
|
|
200
|
-
const work = (async () => {
|
|
370
|
+
return enqueue(key, async () => {
|
|
201
371
|
try {
|
|
202
|
-
await
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
372
|
+
await mkdir(dir, { recursive: true });
|
|
373
|
+
let base = records.get(key) || null;
|
|
374
|
+
if (!base) {
|
|
375
|
+
try {
|
|
376
|
+
base = JSON.parse(await readFile(jsonPath, 'utf8'));
|
|
377
|
+
} catch {}
|
|
378
|
+
}
|
|
379
|
+
const record = terminalRecord(base, { ...detail, jobId: key });
|
|
380
|
+
records.set(key, record);
|
|
381
|
+
await writeJsonAtomicAsync(jsonPath, record, { fsync: false });
|
|
382
|
+
await writeFile(donePath, '', 'utf8');
|
|
383
|
+
} finally {
|
|
384
|
+
// Callers complete a record only once its processes are confirmed gone
|
|
385
|
+
// (or explicitly released): the workspace admission follows that, not
|
|
386
|
+
// the record write, so a failed write cannot strand it with no handle.
|
|
387
|
+
leaveWorkspace?.();
|
|
388
|
+
if (workspaceLeases.get(key) === leaveWorkspace) workspaceLeases.delete(key);
|
|
210
389
|
}
|
|
211
|
-
const record = terminalRecord(base, { ...detail, jobId: key });
|
|
212
|
-
records.set(key, record);
|
|
213
|
-
await writeFile(jsonPath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
|
|
214
|
-
await writeFile(donePath, '', 'utf8');
|
|
215
390
|
await removePaths(ownerPaths);
|
|
216
391
|
paths.set(key, [jsonPath, donePath]);
|
|
392
|
+
const incarnation = ++incarnationSeq;
|
|
393
|
+
incarnations.set(key, incarnation);
|
|
217
394
|
const timer = setTimeout(() => {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
void
|
|
395
|
+
// Expire through the job's queue and only if no publish, retire or newer
|
|
396
|
+
// completion has replaced the files this timer was armed for.
|
|
397
|
+
void enqueue(key, async () => {
|
|
398
|
+
if (incarnations.get(key) !== incarnation) return;
|
|
399
|
+
incarnations.delete(key);
|
|
400
|
+
records.delete(key);
|
|
401
|
+
paths.delete(key);
|
|
402
|
+
await removePaths([jsonPath, donePath]);
|
|
403
|
+
});
|
|
221
404
|
}, COMPLETED_SHELL_JOB_TTL_MS);
|
|
222
405
|
timer.unref?.();
|
|
223
406
|
return true;
|
|
224
|
-
})
|
|
225
|
-
|
|
407
|
+
}).catch(() => false);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/** Test support: settles once every record write queued so far for `jobId`
|
|
411
|
+
* has finished, so a test waits on the write itself, not on elapsed turns. */
|
|
412
|
+
export function _shellJobRecordWritesSettledForTest(jobId) {
|
|
413
|
+
return chains.get(String(jobId || '').trim()) || Promise.resolve();
|
|
226
414
|
}
|
|
227
415
|
|
|
228
|
-
export async function readShellJobRecord(jobId) {
|
|
416
|
+
export async function readShellJobRecord(jobId, { strict = false } = {}) {
|
|
229
417
|
const key = validJobId(jobId);
|
|
230
418
|
if (!key) return null;
|
|
231
419
|
const dir = jobsDir();
|
|
232
420
|
const jsonPath = join(dir, `${key}.json`);
|
|
233
421
|
try {
|
|
234
422
|
const record = JSON.parse(await readFile(jsonPath, 'utf8'));
|
|
423
|
+
if (
|
|
424
|
+
strict &&
|
|
425
|
+
(!record ||
|
|
426
|
+
!['running', 'completed', 'failed', 'cancelled'].includes(record.status) ||
|
|
427
|
+
(record.status === 'running' && !record.cwd))
|
|
428
|
+
)
|
|
429
|
+
throw new Error(`Cannot inspect shell job ${key}.`);
|
|
235
430
|
const done = await access(join(dir, `${key}.done`)).then(
|
|
236
431
|
() => true,
|
|
237
|
-
() =>
|
|
432
|
+
(error) => {
|
|
433
|
+
if (strict && error?.code !== 'ENOENT') throw error;
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
238
436
|
);
|
|
239
437
|
return { ...record, recovered: true, terminal: done || record?.status !== 'running' };
|
|
240
|
-
} catch {
|
|
438
|
+
} catch (error) {
|
|
439
|
+
if (strict && error?.code !== 'ENOENT') throw error;
|
|
241
440
|
return null;
|
|
242
441
|
}
|
|
243
442
|
}
|
|
244
443
|
|
|
245
|
-
export async function listShellJobRecords() {
|
|
444
|
+
export async function listShellJobRecords({ strict = false } = {}) {
|
|
246
445
|
const dir = jobsDir();
|
|
247
446
|
let names;
|
|
248
447
|
try {
|
|
249
448
|
names = await readdir(dir);
|
|
250
|
-
} catch {
|
|
449
|
+
} catch (error) {
|
|
450
|
+
if (strict && error?.code !== 'ENOENT') throw error;
|
|
251
451
|
return [];
|
|
252
452
|
}
|
|
253
453
|
const rows = await Promise.all(
|
|
254
|
-
names.filter((name) => name.endsWith('.json')).map((name) => readShellJobRecord(name.slice(0, -5)))
|
|
454
|
+
names.filter((name) => name.endsWith('.json')).map((name) => readShellJobRecord(name.slice(0, -5), { strict }))
|
|
255
455
|
);
|
|
256
456
|
const cutoff = Date.now() - COMPLETED_SHELL_JOB_TTL_MS;
|
|
257
457
|
return rows.filter((record) => {
|
|
@@ -266,18 +466,16 @@ export async function listShellJobRecords() {
|
|
|
266
466
|
export function retireShellJobRecord(jobId) {
|
|
267
467
|
const key = String(jobId || '').trim();
|
|
268
468
|
if (!key) return;
|
|
269
|
-
|
|
270
|
-
|
|
469
|
+
const leaveWorkspace = workspaceLeases.get(key);
|
|
470
|
+
workspaceLeases.delete(key);
|
|
271
471
|
const list = paths.get(key);
|
|
272
472
|
paths.delete(key);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
/* the publish path owns its failure */
|
|
279
|
-
}
|
|
473
|
+
// Queued behind every earlier publish and ahead of any later one: a promoted
|
|
474
|
+
// job publishing after this call is written only once this removal is done.
|
|
475
|
+
void enqueue(key, async () => {
|
|
476
|
+
records.delete(key);
|
|
477
|
+
incarnations.delete(key);
|
|
280
478
|
await removePaths(list);
|
|
281
|
-
|
|
282
|
-
})
|
|
479
|
+
leaveWorkspace?.();
|
|
480
|
+
});
|
|
283
481
|
}
|
|
@@ -2,9 +2,10 @@ import { closeSync, fstatSync, openSync, readSync } from 'node:fs';
|
|
|
2
2
|
import { stripAnsi } from '../../shell-exec-output.mjs';
|
|
3
3
|
import { FileEncodingSniffer, ShellStreamDecoder, alignedOffset, oemTextEncoding } from '../../shell-codepage.mjs';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const COMPLETION_BYTES = 12 * 1024;
|
|
5
|
+
import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../../../../../shared/tool-output-budget.mjs';
|
|
7
6
|
const cursors = new WeakMap();
|
|
7
|
+
const ESC = '\x1b';
|
|
8
|
+
const PENDING_ANSI_INTRODUCER = new RegExp(`${ESC}(?:\\[[0-?]*[ -/]*|\\](?:(?!${ESC}\\\\)[^\x07\x9c])*)?$`);
|
|
8
9
|
|
|
9
10
|
function newCursor() {
|
|
10
11
|
return {
|
|
@@ -36,7 +37,7 @@ function visibleText(cursor, text) {
|
|
|
36
37
|
const value = cursor.ansi + text;
|
|
37
38
|
// Retain only the introducer of an unfinished CSI/OSC, not its potentially
|
|
38
39
|
// unbounded payload. It will be stripped with the following chunk.
|
|
39
|
-
const pending =
|
|
40
|
+
const pending = PENDING_ANSI_INTRODUCER.exec(value);
|
|
40
41
|
cursor.ansi = '';
|
|
41
42
|
if (!pending) return stripAnsi(value);
|
|
42
43
|
const sequence = pending[0];
|
|
@@ -53,7 +54,7 @@ function visibleText(cursor, text) {
|
|
|
53
54
|
export function readShellTaskOutput(task, result = {}, { output = 'new' } = {}) {
|
|
54
55
|
const replay = output === 'tail';
|
|
55
56
|
const terminal = task.status !== 'running';
|
|
56
|
-
const limit = terminal || replay ?
|
|
57
|
+
const limit = terminal || replay ? TOOL_OUTPUT_TAIL_BYTES : TOOL_OUTPUT_PAGE_BYTES;
|
|
57
58
|
let streams = replay ? new Map() : cursors.get(task);
|
|
58
59
|
if (!streams) {
|
|
59
60
|
streams = new Map();
|
|
@@ -79,10 +79,15 @@ export function parseLineLimitArg(value, defaultValue) {
|
|
|
79
79
|
return Math.max(1, Math.trunc(n));
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/** Whether the read display clips this source line. */
|
|
83
|
+
export function isReadLineClipped(line, { truncateLongLine = true } = {}) {
|
|
84
|
+
return truncateLongLine && String(line ?? '').length > READ_MAX_RENDERED_LINE_CHARS;
|
|
85
|
+
}
|
|
86
|
+
|
|
82
87
|
export function truncateReadLineText(line, { truncateLongLine = true } = {}) {
|
|
83
88
|
let text = String(line ?? '');
|
|
84
89
|
const originalLength = text.length;
|
|
85
|
-
if (
|
|
90
|
+
if (isReadLineClipped(text, { truncateLongLine })) {
|
|
86
91
|
const cps = [...text];
|
|
87
92
|
const head = cps.slice(0, 1_500).join('');
|
|
88
93
|
const tail = cps.slice(-300).join('');
|
|
@@ -41,7 +41,29 @@ function _posixStartupShell(candidates = ['/bin/bash', '/usr/bin/bash', '/bin/sh
|
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
// Every session composes this line. Probing it means up to names×PATHEXT×PATH
|
|
45
|
+
// stats on Windows (~40ms) or a login-shell spawn on POSIX, both on the event
|
|
46
|
+
// loop, so one answer per PATH/shell is reused for a short window — the same
|
|
47
|
+
// rule as gitExecutablePresent: a session opened after an install still picks
|
|
48
|
+
// the tool up once the window passes.
|
|
49
|
+
const SHELL_TOOLS_STARTUP_TTL_MS = 30_000;
|
|
50
|
+
let _shellToolsStartup = null;
|
|
51
|
+
|
|
52
|
+
export function describeShellToolsStartupState(options = {}) {
|
|
53
|
+
if (options._spawnSync) return _probeShellToolsStartupState(options);
|
|
54
|
+
const { platform = process.platform, names = SHELL_TOOL_STARTUP_NAMES, shellPath = null } = options;
|
|
55
|
+
const pathValue = options.pathValue ?? (process.env.PATH || '');
|
|
56
|
+
const key = JSON.stringify([platform, names, shellPath, pathValue]);
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
if (_shellToolsStartup?.key === key && now - _shellToolsStartup.at < SHELL_TOOLS_STARTUP_TTL_MS) {
|
|
59
|
+
return _shellToolsStartup.value;
|
|
60
|
+
}
|
|
61
|
+
const value = _probeShellToolsStartupState(options);
|
|
62
|
+
_shellToolsStartup = { key, at: now, value };
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function _probeShellToolsStartupState({
|
|
45
67
|
platform = process.platform,
|
|
46
68
|
names = SHELL_TOOL_STARTUP_NAMES,
|
|
47
69
|
shellPath = null,
|
|
@@ -3,6 +3,7 @@ import { assertPathReachable, assertPathsReachable } from './fs-reachability.mjs
|
|
|
3
3
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { isBuiltin } from 'node:module';
|
|
6
7
|
import { cwdRelativePath, normalizeInputPath, normalizeOutputPath, resolveAgainstCwd } from './path-utils.mjs';
|
|
7
8
|
|
|
8
9
|
// Hard-block patterns live exclusively in ../shell-policy.mjs (BLOCKED_PATTERNS /
|
|
@@ -661,6 +662,24 @@ const LONG_INLINE_SCRIPT_RE =
|
|
|
661
662
|
/\b(node(?:\.exe)?|python3?|py)((?:\s+--?[\w-]+(?:=[^\s"']+)?)*)\s+(-e|--eval|-c)\s+(?:"((?:[^"\\]|\\.)*)"|'((?:[^']|'')*)')/i;
|
|
662
663
|
const POWERSHELL_FILE_SEMANTIC_RE = /\$(?:PSScriptRoot|PSCommandPath|MyInvocation)\b|^\s*(?:param\s*\(|#requires\b)/im;
|
|
663
664
|
|
|
665
|
+
// `node -e` resolves a package name from the working directory; a hoisted file
|
|
666
|
+
// resolves it from the temp directory it lives in, where no node_modules is.
|
|
667
|
+
// Any package specifier (not a Node builtin), require.resolve, or a specifier
|
|
668
|
+
// that is not a string literal therefore keeps the -e form.
|
|
669
|
+
const NODE_SPECIFIER_RE = /(?:\brequire\s*\(\s*|\bimport\s*\(\s*|\bfrom\s+|\bimport\s+)['"]([^'"]+)['"]/g;
|
|
670
|
+
const NODE_LOADER_CALL_RE = /\b(?:require|import)\s*\(/g;
|
|
671
|
+
const NODE_LITERAL_LOADER_CALL_RE = /\b(?:require|import)\s*\(\s*['"][^'"]+['"]/g;
|
|
672
|
+
function importsPackage(body) {
|
|
673
|
+
if (/\brequire\s*\.\s*resolve\b/.test(body)) return true;
|
|
674
|
+
if ((body.match(NODE_LOADER_CALL_RE) || []).length !== (body.match(NODE_LITERAL_LOADER_CALL_RE) || []).length) {
|
|
675
|
+
return true;
|
|
676
|
+
}
|
|
677
|
+
for (const [, specifier] of body.matchAll(NODE_SPECIFIER_RE)) {
|
|
678
|
+
if (!isBuiltin(specifier)) return true;
|
|
679
|
+
}
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
|
|
664
683
|
/** File extension a hoisted inline script gets: Python, or the Node module kind the flags declare. */
|
|
665
684
|
function inlineScriptExtension(isNode, esm) {
|
|
666
685
|
if (!isNode) return '.py';
|
|
@@ -684,6 +703,7 @@ export function planInlineScriptHoist(command) {
|
|
|
684
703
|
const [whole, exe, rawFlags, , body] = match;
|
|
685
704
|
if (INLINE_UNSAFE_BODY.test(body)) return null;
|
|
686
705
|
if (INLINE_FILE_RELATIVE.test(body)) return null;
|
|
706
|
+
if (/^node/i.test(exe) && importsPackage(body)) return null;
|
|
687
707
|
const { extension, keptFlags } = inlineScriptFileShape(exe, rawFlags);
|
|
688
708
|
return {
|
|
689
709
|
exe,
|