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
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// side-question.mjs — /btw: a quick question answered while the main turn
|
|
2
|
+
// keeps working. The answer comes from a cache-sharing fork of the session's
|
|
3
|
+
// latest provider request (side-question-store.mjs): the same model, system
|
|
4
|
+
// prompt, tools and cache-relevant options and the same message prefix, so
|
|
5
|
+
// the provider's prompt cache serves the prefix. Only the reply that request
|
|
6
|
+
// produced and one question are appended. One provider call, no tool loop;
|
|
7
|
+
// the answer is returned to the caller and never enters the transcript.
|
|
8
|
+
import { collectAssistantToolCallIds } from './context-tool-pairs.mjs';
|
|
9
|
+
import { buildIntermediateAssistantMessage, buildToolCallAssistantMessage } from './loop/assistant-commit.mjs';
|
|
10
|
+
import { logSessionLlmUsage } from './manager/ask-turn-commit.mjs';
|
|
11
|
+
import { disposeTransportScope, forkTransportScope } from '../providers/transport-scope.mjs';
|
|
12
|
+
import { isAgentOwner } from '../agent-owner.mjs';
|
|
13
|
+
import { getProvider } from '../providers/registry.mjs';
|
|
14
|
+
import { prepareTurnEffortConfiguration } from '../providers/effort-configuration.mjs';
|
|
15
|
+
import { providerNativeToolPrefixCount } from '../runtime-core/provider-request-tools.mjs';
|
|
16
|
+
import { snapshotProviderRequestTools } from '../runtime-core/tool-catalog.mjs';
|
|
17
|
+
import { repairTranscriptBeforeProviderSend } from './loop/transcript-repair.mjs';
|
|
18
|
+
import { buildRequestSendOptions } from './manager/ask-turn-loop-options.mjs';
|
|
19
|
+
import { filterModelVisibleSessionMessages } from './manager/message-sanitize.mjs';
|
|
20
|
+
import { hasUserConversationMessage } from './manager/prompt-utils.mjs';
|
|
21
|
+
import { loadSession } from './store.mjs';
|
|
22
|
+
import { projectSyntheticUserEnvelopes } from './synthetic-user-envelope.mjs';
|
|
23
|
+
import { beginSideQuestion, sideQuestionRequest, sideQuestionRequestSnapshot } from './side-question-store.mjs';
|
|
24
|
+
|
|
25
|
+
export { cancelSideQuestion } from './side-question-store.mjs';
|
|
26
|
+
|
|
27
|
+
export const SIDE_QUESTION_NO_REQUEST = 'Send a message first, then try /btw.';
|
|
28
|
+
export const SIDE_QUESTION_TOOL_ATTEMPT =
|
|
29
|
+
'The model tried to use a tool instead of answering. A side question cannot run tools; try asking it differently.';
|
|
30
|
+
const SIDE_QUESTION_EMPTY_ANSWER = 'The model returned no answer.';
|
|
31
|
+
|
|
32
|
+
// The reply's tool calls run in the main session; the fork only needs each
|
|
33
|
+
// call answered so the request stays well-formed.
|
|
34
|
+
const SIDE_QUESTION_TOOL_STUB =
|
|
35
|
+
'This tool call belongs to the main task and is handled there; its result is not part of this side question.';
|
|
36
|
+
|
|
37
|
+
function sideQuestionPrompt(question) {
|
|
38
|
+
return [
|
|
39
|
+
'<side-question>',
|
|
40
|
+
'The user is asking you a quick side question. The main agent keeps working on the task on its own;',
|
|
41
|
+
'this exchange does not reach it and does not change that work.',
|
|
42
|
+
'Answer directly, in this one response, from what this conversation already contains.',
|
|
43
|
+
'No tools are available here: do not call any, and do not offer or promise to do anything.',
|
|
44
|
+
'If the conversation does not tell you the answer, say that you do not know.',
|
|
45
|
+
'',
|
|
46
|
+
question,
|
|
47
|
+
'</side-question>',
|
|
48
|
+
].join('\n');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The assistant turn the saved request produced, built the way the loop
|
|
52
|
+
// commits it (without the turn's one-shot transcript metadata), plus a stub
|
|
53
|
+
// result per tool call.
|
|
54
|
+
function replyMessages(response) {
|
|
55
|
+
if (!response) return [];
|
|
56
|
+
const reply = response.toolCalls?.length
|
|
57
|
+
? buildToolCallAssistantMessage(response, { calls: response.toolCalls, opts: {} })
|
|
58
|
+
: buildIntermediateAssistantMessage(response, {});
|
|
59
|
+
if (!reply) return [];
|
|
60
|
+
const stubs = collectAssistantToolCallIds(reply).map((id) => ({
|
|
61
|
+
role: 'tool',
|
|
62
|
+
toolCallId: id,
|
|
63
|
+
content: SIDE_QUESTION_TOOL_STUB,
|
|
64
|
+
}));
|
|
65
|
+
return [reply, ...stubs];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The fork of a saved request: its messages unchanged, then the reply and
|
|
70
|
+
* the question. The send options are the saved ones; the provider
|
|
71
|
+
* continuation state follows the reply when it is appended, exactly as the
|
|
72
|
+
* main loop's next request would carry it. `sharedCachePrefixCount` (the
|
|
73
|
+
* shared prefix's message count, which survives model-proxy serialization)
|
|
74
|
+
* keeps an Anthropic message breakpoint on the shared prefix, so the fork reads the
|
|
75
|
+
* saved request's cache entry and writes none for its suffix.
|
|
76
|
+
*/
|
|
77
|
+
export function buildSideQuestionRequest(request, question) {
|
|
78
|
+
const reply = replyMessages(request.response);
|
|
79
|
+
const opts = { ...request.opts };
|
|
80
|
+
if (reply.length && Object.hasOwn(request.response, 'providerState')) {
|
|
81
|
+
opts.providerState = request.response.providerState;
|
|
82
|
+
}
|
|
83
|
+
if (request.messages.length) opts.sharedCachePrefixCount = request.messages.length;
|
|
84
|
+
const messages = [
|
|
85
|
+
...request.messages,
|
|
86
|
+
...reply,
|
|
87
|
+
// A user interjection keeps its own turn (never folded into a preceding
|
|
88
|
+
// tool result), so the prefix's last block reaches the provider unchanged.
|
|
89
|
+
{ role: 'user', content: sideQuestionPrompt(question), meta: { source: 'steering' } },
|
|
90
|
+
];
|
|
91
|
+
return { messages, opts };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The request the main loop would send next for a session that has none saved
|
|
96
|
+
* (the runtime restarted, or the saved one was forgotten): the session's own
|
|
97
|
+
* provider, model, tools, send options and transcript, assembled by the same
|
|
98
|
+
* pieces the loop uses, without the loop's side effects (no compaction, no
|
|
99
|
+
* transcript repair in place, nothing written to the session). Null when the
|
|
100
|
+
* session has no conversation, no resolvable provider, or is an agent's.
|
|
101
|
+
*/
|
|
102
|
+
function nextMainRequest(sessionId) {
|
|
103
|
+
const session = sessionId ? loadSession(sessionId) : null;
|
|
104
|
+
if (!session || session.closed === true || isAgentOwner(session)) return null;
|
|
105
|
+
if (!hasUserConversationMessage(session.messages)) return null;
|
|
106
|
+
const provider = getProvider(session.provider);
|
|
107
|
+
if (!provider) return null;
|
|
108
|
+
const transcript = filterModelVisibleSessionMessages(session.messages);
|
|
109
|
+
repairTranscriptBeforeProviderSend(transcript, sessionId);
|
|
110
|
+
const opts = buildRequestSendOptions({
|
|
111
|
+
sessionId,
|
|
112
|
+
session,
|
|
113
|
+
turnEffort: session.effort || null,
|
|
114
|
+
effortConfiguration: prepareTurnEffortConfiguration(session, provider),
|
|
115
|
+
stepAutoEffort: null,
|
|
116
|
+
codexTurnId: null,
|
|
117
|
+
startedAtMs: Date.now(),
|
|
118
|
+
signal: undefined,
|
|
119
|
+
});
|
|
120
|
+
const sendTools = snapshotProviderRequestTools({
|
|
121
|
+
provider: session.provider || provider.name,
|
|
122
|
+
tools: session.tools,
|
|
123
|
+
nativeTools: opts.nativeTools,
|
|
124
|
+
messages: transcript,
|
|
125
|
+
session,
|
|
126
|
+
});
|
|
127
|
+
opts.iteration = 1;
|
|
128
|
+
opts.providerToolSnapshotAuthoritative = true;
|
|
129
|
+
opts.providerNativeToolPrefixCount = providerNativeToolPrefixCount(sendTools);
|
|
130
|
+
return sideQuestionRequestSnapshot({
|
|
131
|
+
provider,
|
|
132
|
+
model: session.model,
|
|
133
|
+
messages: projectSyntheticUserEnvelopes(transcript).messages,
|
|
134
|
+
tools: sendTools,
|
|
135
|
+
opts,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function answerText(response) {
|
|
140
|
+
if (response?.toolCalls?.length) return SIDE_QUESTION_TOOL_ATTEMPT;
|
|
141
|
+
const text = typeof response?.content === 'string' ? response.content.trim() : '';
|
|
142
|
+
return text || SIDE_QUESTION_EMPTY_ANSWER;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Answer `question` from the session's latest provider request. One side
|
|
147
|
+
* question runs per session: a new one aborts the previous, and
|
|
148
|
+
* cancelSideQuestion aborts it. A session without a saved request forks the
|
|
149
|
+
* request its next turn would send. Rejects when the session has no
|
|
150
|
+
* conversation or provider, with the provider's error, or with the cancel
|
|
151
|
+
* reason.
|
|
152
|
+
*/
|
|
153
|
+
export async function askSideQuestion(sessionId, question) {
|
|
154
|
+
const text = typeof question === 'string' ? question.trim() : '';
|
|
155
|
+
if (!text) throw new TypeError('Side question is empty.');
|
|
156
|
+
const request = sideQuestionRequest(sessionId) || nextMainRequest(sessionId);
|
|
157
|
+
if (!request) throw new Error(SIDE_QUESTION_NO_REQUEST);
|
|
158
|
+
const run = beginSideQuestion(sessionId);
|
|
159
|
+
const startedAt = Date.now();
|
|
160
|
+
// The fork keeps the session id (prompt cache routing) but runs on its own
|
|
161
|
+
// transport scope: no pooled socket, response-chain anchor, turn-state
|
|
162
|
+
// token or provider run of the main session is waited on, read or replaced.
|
|
163
|
+
const transportScope = forkTransportScope(sessionId, 'side');
|
|
164
|
+
try {
|
|
165
|
+
const { messages, opts } = buildSideQuestionRequest(request, text);
|
|
166
|
+
let response;
|
|
167
|
+
try {
|
|
168
|
+
response = await request.provider.send(
|
|
169
|
+
messages,
|
|
170
|
+
request.model,
|
|
171
|
+
request.tools.length ? request.tools : undefined,
|
|
172
|
+
{
|
|
173
|
+
...opts,
|
|
174
|
+
transportScope,
|
|
175
|
+
admissionOwner: sessionId,
|
|
176
|
+
signal: run.signal,
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
throw run.signal.aborted ? run.signal.reason : error;
|
|
181
|
+
}
|
|
182
|
+
if (run.signal.aborted) throw run.signal.reason;
|
|
183
|
+
const session = request.opts.session;
|
|
184
|
+
if (response?.usage && session?.id) {
|
|
185
|
+
void logSessionLlmUsage({
|
|
186
|
+
session: { ...session, model: request.model },
|
|
187
|
+
usage: response.usage,
|
|
188
|
+
startedAt,
|
|
189
|
+
mode: 'side-question',
|
|
190
|
+
}).catch(() => {});
|
|
191
|
+
}
|
|
192
|
+
return { text: answerText(response) };
|
|
193
|
+
} finally {
|
|
194
|
+
run.end();
|
|
195
|
+
disposeTransportScope(transportScope, request.provider);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -11,7 +11,7 @@ import { join } from 'node:path';
|
|
|
11
11
|
import { getPluginData } from '../../config.mjs';
|
|
12
12
|
import { PLUGIN_LOG_MAX_BYTES, PLUGIN_LOG_KEEP_BYTES } from '../../../../../lib/mixdog-debug.cjs';
|
|
13
13
|
import { createAsyncLogAppender } from '../../../../shared/async-log-appender.mjs';
|
|
14
|
-
import { sessionPath
|
|
14
|
+
import { sessionPath } from './session-paths.mjs';
|
|
15
15
|
import {
|
|
16
16
|
readCanonicalSessionRecord as _readCanonicalRecord,
|
|
17
17
|
CANONICAL_RECORD_UNREADABLE as LIFECYCLE_AMBIGUOUS,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
} from './live-state.mjs';
|
|
37
37
|
import { _uncacheSessionSummary, _queueSessionSummaryUpsert } from './summary-cache.mjs';
|
|
38
38
|
import { _savePending, _clearDebounce } from './pending-saves.mjs';
|
|
39
|
-
import { _runtimeLivenessVeto
|
|
39
|
+
import { _runtimeLivenessVeto } from './liveness-veto.mjs';
|
|
40
40
|
import { loadSession } from './load-session.mjs';
|
|
41
41
|
|
|
42
42
|
// Cancellation truth, single rule: an UNCONFIRMED stop outranks a confirmed
|
|
@@ -158,9 +158,23 @@ function _logSessionCloseMetric(id, existing, closedAt, reason) {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/**
|
|
162
|
+
* A barrier that found no record at all — nothing on disk and no live or
|
|
163
|
+
* pending copy in memory — fenced nothing because there is nothing to fence:
|
|
164
|
+
* its pending writes were already cancelled under the commit lock. It still
|
|
165
|
+
* returns null (no generation exists), but a caller passing `options.outcome`
|
|
166
|
+
* learns that the record was legitimately gone rather than vetoed, contended
|
|
167
|
+
* or failed.
|
|
168
|
+
*/
|
|
169
|
+
function _recordAbsent(options) {
|
|
170
|
+
if (options?.outcome && typeof options.outcome === 'object') options.outcome.absent = true;
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
161
174
|
/**
|
|
162
175
|
* Atomically mark a session closed on disk with a bumped generation.
|
|
163
176
|
* Returns the new generation, or null if the session file doesn't exist.
|
|
177
|
+
* `options.outcome` (an object) gets `absent: true` when no record existed.
|
|
164
178
|
* Used by closeSession() to plant a tombstone that races against in-flight
|
|
165
179
|
* saveSession() calls.
|
|
166
180
|
*/
|
|
@@ -171,15 +185,11 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
171
185
|
// Caller-provided probes may re-enter the store, so evaluate them before
|
|
172
186
|
// taking the non-reentrant Atomics commit lock. A veto must also precede
|
|
173
187
|
// pending-save cancellation so debounce durability remains intact.
|
|
174
|
-
if (_runtimeLivenessVeto(id, options)
|
|
188
|
+
if (_runtimeLivenessVeto(id, options)) return null;
|
|
175
189
|
const closeGuard = _guardedSaveOptions(id);
|
|
176
190
|
const commitControl = _acquireWriteCommit(closeGuard);
|
|
177
191
|
if (commitControl === false) return null;
|
|
178
192
|
try {
|
|
179
|
-
// Cross-process heartbeat revival after full-TTL silence is accepted as a
|
|
180
|
-
// best-effort race: the tombstone resurrection guard is the authoritative
|
|
181
|
-
// post-race arbiter. Re-stat here, but never invoke caller code under lock.
|
|
182
|
-
if (_heartbeatLivenessVeto(id, options)) return null;
|
|
183
193
|
const authority = _readLifecycleAuthority(id, reason, 'close');
|
|
184
194
|
if (authority === LIFECYCLE_AMBIGUOUS) return null;
|
|
185
195
|
// Only a committed close may disrupt pending persistence.
|
|
@@ -187,7 +197,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
187
197
|
_cancelSessionWrites(id);
|
|
188
198
|
_uncacheSessionSummary(id);
|
|
189
199
|
const existing = loadSession(id);
|
|
190
|
-
if (!existing) return
|
|
200
|
+
if (!existing) return _recordAbsent(options);
|
|
191
201
|
// Re-close idempotence: a session that is ALREADY tombstoned keeps its
|
|
192
202
|
// ORIGINAL close time (updatedAt) and generation. The old code refreshed
|
|
193
203
|
// updatedAt=Date.now() on every call, so the 5-min idle sweep re-closing a
|
|
@@ -216,7 +226,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
216
226
|
const tombstone = {
|
|
217
227
|
...base,
|
|
218
228
|
closed: true,
|
|
219
|
-
closedReason: alreadyClosed ? base.closedReason || reason : reason,
|
|
229
|
+
closedReason: alreadyClosed && reason !== 'desktop-session-delete' ? base.closedReason || reason : reason,
|
|
220
230
|
status: 'closed',
|
|
221
231
|
generation: newGen,
|
|
222
232
|
updatedAt: closeTime,
|
|
@@ -226,8 +236,6 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
226
236
|
_savePending.delete(id);
|
|
227
237
|
clearSessionSaveError(id);
|
|
228
238
|
_clearLiveSession(id);
|
|
229
|
-
// Preserve a sidecar published strictly after the sweep's scan snapshot.
|
|
230
|
-
_deleteHeartbeatUnlessNewer(id, options);
|
|
231
239
|
_queueSessionSummaryUpsert(tombstone);
|
|
232
240
|
_droppedSaveIds.delete(id);
|
|
233
241
|
// Emit the close metric only on the FIRST close — a re-close of an
|
|
@@ -243,7 +251,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
243
251
|
/**
|
|
244
252
|
* Bump a session's generation WITHOUT planting a closed:true tombstone.
|
|
245
253
|
* Used by closeSession(id, reason, { tombstone: false }) — the runtime side
|
|
246
|
-
* (
|
|
254
|
+
* (bash shells, controller, in-memory entry) is detached, but the
|
|
247
255
|
* session file itself stays valid/resumable. The generation bump alone is
|
|
248
256
|
* what protects it from a late save race: any saveSession() still in flight
|
|
249
257
|
* from the detached turn was issued with the OLD generation as its
|
|
@@ -253,7 +261,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
253
261
|
* of clobbering whatever the resumed session writes next.
|
|
254
262
|
* Returns the new generation, or null if the session file doesn't exist.
|
|
255
263
|
*/
|
|
256
|
-
export function bumpSessionGeneration(id, reason = 'detach') {
|
|
264
|
+
export function bumpSessionGeneration(id, reason = 'detach', options = {}) {
|
|
257
265
|
clearSessionLifecycleCommitError(id);
|
|
258
266
|
// The detach barrier is a canonical write and MUST take the same commit
|
|
259
267
|
// lock as markSessionClosed. Cancellation alone is not a barrier: a writer
|
|
@@ -278,14 +286,13 @@ export function bumpSessionGeneration(id, reason = 'detach') {
|
|
|
278
286
|
_cancelSessionWrites(id);
|
|
279
287
|
_uncacheSessionSummary(id);
|
|
280
288
|
const existing = loadSession(id);
|
|
281
|
-
if (!existing) return
|
|
289
|
+
if (!existing) return _recordAbsent(options);
|
|
282
290
|
const newGen = (typeof existing.generation === 'number' ? existing.generation : 0) + 1;
|
|
283
291
|
const detached = { ...existing, generation: newGen, updatedAt: Date.now(), detachedReason: reason };
|
|
284
292
|
if (!_writeLifecycleRecord(id, detached, existing, reason)) return null;
|
|
285
293
|
_savePending.delete(id);
|
|
286
294
|
clearSessionSaveError(id);
|
|
287
295
|
_clearLiveSession(id);
|
|
288
|
-
deleteHeartbeat(id);
|
|
289
296
|
_queueSessionSummaryUpsert(detached);
|
|
290
297
|
_droppedSaveIds.delete(id);
|
|
291
298
|
return newGen;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* path and of the in-memory snapshot caches.
|
|
7
7
|
*/
|
|
8
8
|
import { readCanonicalSessionRecord, CANONICAL_RECORD_UNREADABLE } from './canonical-reader.mjs';
|
|
9
|
-
import { sessionPath } from './paths
|
|
9
|
+
import { sessionPath } from './session-paths.mjs';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Cheap authoritative lifecycle read straight from disk (no live/pending
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { readFileSync, readdirSync } from 'node:fs';
|
|
6
6
|
import { Worker } from 'node:worker_threads';
|
|
7
7
|
import { getPluginData } from '../../config.mjs';
|
|
8
|
-
import { getStoreDir } from './paths
|
|
8
|
+
import { getStoreDir } from './session-paths.mjs';
|
|
9
9
|
import { probePath, PROBE_PRESENT, PROBE_ABSENT } from './fs-probe.mjs';
|
|
10
10
|
import { isCancelledWrite as _isCancelledWrite } from './write-guards.mjs';
|
|
11
11
|
import {
|
|
@@ -29,7 +29,6 @@ import {
|
|
|
29
29
|
import { _saveAsyncQueued, _saveWorkerPending } from './save-worker.mjs';
|
|
30
30
|
import { STORED_SESSION_UNREADABLE, _ensureLifecycleFields, _storedSessionFromFile } from './serialize.mjs';
|
|
31
31
|
import { _savePending } from './pending-saves.mjs';
|
|
32
|
-
import { isOrdinarySession } from '../store-summary-visibility.mjs';
|
|
33
32
|
import { closeSessionCatalogDb } from '../catalog-db/index.mjs';
|
|
34
33
|
|
|
35
34
|
// Disk mtime of the summary index when the in-memory cache was last refreshed
|
|
@@ -63,10 +62,7 @@ export function listStoredSessions(options = {}) {
|
|
|
63
62
|
options.includeLive === true
|
|
64
63
|
? _withUnpersistedSessions(stored, invalidStorageIds)
|
|
65
64
|
: stored.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
66
|
-
|
|
67
|
-
// uses the durable summary/worker indexes instead; callers that explicitly
|
|
68
|
-
// own an Agent surface can request the unfiltered internal rows.
|
|
69
|
-
return options.includeAgentOnly === true ? listed : listed.filter(isOrdinarySession);
|
|
65
|
+
return listed;
|
|
70
66
|
}
|
|
71
67
|
|
|
72
68
|
function _withUnpersistedSessions(stored, invalidStorageIds = new Set()) {
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from './live-state.mjs';
|
|
14
14
|
import { _summaryCacheVersions } from './summary-cache.mjs';
|
|
15
15
|
import { probePath, PROBE_PRESENT } from './fs-probe.mjs';
|
|
16
|
-
import { sessionPath } from './paths
|
|
16
|
+
import { sessionPath } from './session-paths.mjs';
|
|
17
17
|
import { _hasPendingPersistence } from './pending-saves.mjs';
|
|
18
18
|
import { forgetSessionLoadCache } from './load-cache.mjs';
|
|
19
19
|
|
|
@@ -124,6 +124,29 @@ export function _retireSessionIncarnation(id) {
|
|
|
124
124
|
if (id) _sessionIncarnations.delete(id);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
// ── Delete fence ────────────────────────────────────────────────────────────
|
|
128
|
+
// An explicitly deleted session may still own a running turn whose later saves
|
|
129
|
+
// carry a brand-new write guard and incarnation, so neither the cancellation
|
|
130
|
+
// counter nor the retired incarnation stops them: an absent file reads as
|
|
131
|
+
// "creatable". The fence is the id-level refusal every write-admission check
|
|
132
|
+
// consults. Only explicit user deletes fence (ids are never reused); the cap
|
|
133
|
+
// only ever forgets the oldest, long-settled entries.
|
|
134
|
+
const SESSION_DELETE_FENCE_MAX = 4096;
|
|
135
|
+
const _deleteFence = new Set();
|
|
136
|
+
|
|
137
|
+
export function fenceSessionWrites(id) {
|
|
138
|
+
if (!id) return;
|
|
139
|
+
_deleteFence.delete(id);
|
|
140
|
+
_deleteFence.add(id);
|
|
141
|
+
if (_deleteFence.size > SESSION_DELETE_FENCE_MAX) {
|
|
142
|
+
_deleteFence.delete(_deleteFence.values().next().value);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function isSessionWriteFenced(id) {
|
|
147
|
+
return _deleteFence.has(id);
|
|
148
|
+
}
|
|
149
|
+
|
|
127
150
|
/** Clear every save marker for an id (successful hard delete). */
|
|
128
151
|
export function _clearSessionSaveState(id) {
|
|
129
152
|
if (!id) return;
|
|
@@ -1,53 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime-liveness
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Runtime-liveness veto for the destructive paths (close, delete): the
|
|
3
|
+
* caller-supplied `isSessionLive` probe over the daemon's in-memory runtime
|
|
4
|
+
* state, plus — for the sweep (`legacyOwnerVeto`) — the legacy `.hb` / `.own`
|
|
5
|
+
* markers an OLDER Mixdog process still running beside this one (mid-upgrade)
|
|
6
|
+
* keeps publishing. No current build writes those markers; they are only ever
|
|
7
|
+
* READ here, never refreshed.
|
|
5
8
|
*
|
|
6
9
|
* Separate from the write pipeline on purpose — a veto is a pure READ taken
|
|
7
10
|
* before any commit lock is held, and markSessionClosed / deleteSession must
|
|
8
|
-
* apply exactly the same
|
|
11
|
+
* apply exactly the same rule.
|
|
9
12
|
*/
|
|
10
|
-
import { existsSync, statSync } from 'node:fs';
|
|
11
13
|
import { join } from 'node:path';
|
|
12
|
-
import { getStoreDir
|
|
14
|
+
import { getStoreDir } from './session-paths.mjs';
|
|
15
|
+
import { probePath, readTextFile, PROBE_PRESENT } from './fs-probe.mjs';
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
export const LEGACY_MARKER_SUFFIXES = ['.hb', '.own'];
|
|
18
|
+
// An older live owner rewrote `.hb` every ≤5s mid-turn and `.own` every ~20s
|
|
19
|
+
// while holding the session open; one untouched this long holds nothing.
|
|
20
|
+
export const LEGACY_MARKER_FRESH_MS = 2 * 60 * 1000;
|
|
21
|
+
|
|
22
|
+
function processAlive(pid) {
|
|
15
23
|
try {
|
|
16
|
-
|
|
17
|
-
return
|
|
18
|
-
} catch {
|
|
19
|
-
|
|
24
|
+
process.kill(pid, 0);
|
|
25
|
+
return true;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
// ESRCH: no such process. EPERM means the pid exists.
|
|
28
|
+
return error?.code === 'EPERM';
|
|
20
29
|
}
|
|
21
30
|
}
|
|
22
31
|
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
/** A legacy marker's evidence, or null when it is not there to judge. The
|
|
33
|
+
* marker holds `<msTimestamp>\n<pid>\n`; a pid-less (pre-pid) marker names
|
|
34
|
+
* no owner, so it is neither live nor dead. */
|
|
35
|
+
export function readLegacyMarker(path, now = Date.now()) {
|
|
36
|
+
const probe = probePath(path);
|
|
37
|
+
if (probe.state !== PROBE_PRESENT) return null;
|
|
38
|
+
const read = readTextFile(path);
|
|
39
|
+
const pid = read.state === PROBE_PRESENT ? Number(read.text.split('\n')[1]) || 0 : 0;
|
|
40
|
+
const alive = pid > 0 && processAlive(pid);
|
|
41
|
+
return {
|
|
42
|
+
fresh: now - (probe.mtimeMs || 0) <= LEGACY_MARKER_FRESH_MS,
|
|
43
|
+
ownerAlive: alive,
|
|
44
|
+
ownerDead: pid > 0 && !alive,
|
|
45
|
+
};
|
|
35
46
|
}
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
/** Whether a legacy marker of the session names a live owner pid with a
|
|
49
|
+
* fresh heartbeat: that session is driven by another live process. */
|
|
50
|
+
export function _legacyOwnerLivenessVeto(id, now = Date.now()) {
|
|
51
|
+
if (typeof id !== 'string' || !/^[A-Za-z0-9_-]+$/.test(id)) return false;
|
|
52
|
+
const dir = getStoreDir();
|
|
53
|
+
return LEGACY_MARKER_SUFFIXES.some((suffix) => {
|
|
54
|
+
const marker = readLegacyMarker(join(dir, `${id}${suffix}`), now);
|
|
55
|
+
return Boolean(marker?.fresh && marker.ownerAlive);
|
|
56
|
+
});
|
|
45
57
|
}
|
|
46
58
|
|
|
47
|
-
export function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (!hasHeartbeatSnapshot || _heartbeatMtime(id) <= snapshotMtime) {
|
|
51
|
-
deleteHeartbeat(id);
|
|
52
|
-
}
|
|
59
|
+
export function _runtimeLivenessVeto(id, options = {}) {
|
|
60
|
+
if (typeof options.isSessionLive === 'function' && options.isSessionLive(id)) return true;
|
|
61
|
+
return options.legacyOwnerVeto === true && _legacyOwnerLivenessVeto(id);
|
|
53
62
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
readCanonicalSessionRecord,
|
|
9
9
|
acceptStrictSessionRecords,
|
|
10
10
|
} from './canonical-reader.mjs';
|
|
11
|
-
import { sessionPath } from './paths
|
|
11
|
+
import { sessionPath } from './session-paths.mjs';
|
|
12
12
|
import { noteMemoryRelease } from '../../../../shared/idle-gc.mjs';
|
|
13
13
|
|
|
14
14
|
// Recent full-session reads are much hotter than writes while a user hops
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* snapshot, or the evidence-backed failed-save snapshot. Nothing here writes;
|
|
5
5
|
* the precedence rules are the whole responsibility.
|
|
6
6
|
*/
|
|
7
|
-
import { sessionPath } from './paths
|
|
7
|
+
import { sessionPath } from './session-paths.mjs';
|
|
8
8
|
import { _savePending } from './pending-saves.mjs';
|
|
9
9
|
import { _liveSessions, _droppedSaveIds, getFailedSaveSnapshot } from './live-state.mjs';
|
|
10
10
|
import { _readStoredSessionCached } from './load-cache.mjs';
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* edge plus the full local-state purge that must happen under the same lock
|
|
5
5
|
* (incarnation retirement, pending slots, purge hooks, markers, summary row).
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { join } from 'node:path';
|
|
7
|
+
import { unlinkSync } from 'node:fs';
|
|
9
8
|
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { listStoredAgentWorkerLinks } from '../store-agent-worker-rows.mjs';
|
|
10
|
+
import { listStoredSessionSummaries } from './listing.mjs';
|
|
11
|
+
import { STORED_SESSION_UNREADABLE, _storedSessionFromFile } from './serialize.mjs';
|
|
12
|
+
import { getStoreDir, sessionPath } from './session-paths.mjs';
|
|
12
13
|
import {
|
|
13
14
|
readCanonicalSessionRecord as _readCanonicalRecord,
|
|
14
15
|
CANONICAL_RECORD_UNREADABLE as LIFECYCLE_AMBIGUOUS,
|
|
@@ -22,60 +23,66 @@ import {
|
|
|
22
23
|
} from './write-guards.mjs';
|
|
23
24
|
import {
|
|
24
25
|
_clearLiveSession,
|
|
26
|
+
_liveSessions,
|
|
25
27
|
_retireSessionIncarnation,
|
|
26
28
|
_clearSessionSaveState,
|
|
27
29
|
clearSessionLifecycleCommitError,
|
|
30
|
+
fenceSessionWrites,
|
|
28
31
|
} from './live-state.mjs';
|
|
29
32
|
import { purgeSessionSaveBookkeeping as _purgeSessionSaveBookkeeping } from './save-worker.mjs';
|
|
30
|
-
import { _uncacheSessionSummary, _queueSessionSummaryRemoval } from './summary-cache.mjs';
|
|
33
|
+
import { _uncacheSessionSummary, _queueSessionSummaryRemoval, _cachedSummaryRows } from './summary-cache.mjs';
|
|
31
34
|
import { _savePending, _clearDebounce, _releasePendingSlot } from './pending-saves.mjs';
|
|
32
|
-
import { _runtimeLivenessVeto
|
|
35
|
+
import { _runtimeLivenessVeto } from './liveness-veto.mjs';
|
|
33
36
|
import { _runSessionPurgeHooks } from './session-observers.mjs';
|
|
34
37
|
import { deleteCompactionArchive } from '../compaction-archive.mjs';
|
|
35
38
|
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
+
/** Child-agent session ids linked to one visible parent. Candidates come from
|
|
40
|
+
* metadata only (the summary rows and the agent-worker links — no folder
|
|
41
|
+
* scan); each candidate's own file is then read strictly and must still be an
|
|
42
|
+
* agent-owned record linked to this parent, so a stale/foreign metadata row
|
|
43
|
+
* can never name a deletion target. Parent deletion no longer removes these
|
|
44
|
+
* children; they outlive the parent as independent sessions. */
|
|
39
45
|
export function listOwnedAgentSessionIds(ownerSessionId) {
|
|
40
46
|
const ownerId = String(ownerSessionId || '').trim();
|
|
41
47
|
if (!/^[A-Za-z0-9_-]+$/.test(ownerId)) return [];
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const linksTo = (row) => row?.ownerSessionId === ownerId || row?.parentSessionId === ownerId;
|
|
49
|
+
const candidates = new Set();
|
|
50
|
+
for (const row of [...listStoredSessionSummaries(), ...listStoredAgentWorkerLinks()]) {
|
|
51
|
+
const candidateId = String(row?.id || row?.sessionId || '').trim();
|
|
52
|
+
if (linksTo(row) && candidateId !== ownerId && /^[A-Za-z0-9_-]+$/.test(candidateId)) {
|
|
53
|
+
candidates.add(candidateId);
|
|
54
|
+
}
|
|
49
55
|
}
|
|
56
|
+
const dir = getStoreDir();
|
|
50
57
|
const ids = [];
|
|
51
|
-
for (const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const session = record.doc;
|
|
58
|
-
if (!isAgentOwner(session)) continue;
|
|
59
|
-
const linkedOwner = String(session.ownerSessionId || session.parentSessionId || '').trim();
|
|
60
|
-
if (linkedOwner === ownerId) ids.push(candidateId);
|
|
61
|
-
} catch {
|
|
62
|
-
/* unreadable/vanished records are never deletion targets */
|
|
63
|
-
}
|
|
58
|
+
for (const candidateId of candidates) {
|
|
59
|
+
const session = _storedSessionFromFile(dir, `${candidateId}.json`, false);
|
|
60
|
+
// Unreadable, vanished, corrupt or foreign records are never deletion targets.
|
|
61
|
+
if (!session || session === STORED_SESSION_UNREADABLE || !isAgentOwner(session)) continue;
|
|
62
|
+
const linkedOwner = String(session.ownerSessionId || session.parentSessionId || '').trim();
|
|
63
|
+
if (linkedOwner === ownerId) ids.push(candidateId);
|
|
64
64
|
}
|
|
65
65
|
return ids;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/** Working folders the session is known to have used (its cached summary row
|
|
69
|
+
* and live snapshot — no file read, no scan); the purge hooks derive
|
|
70
|
+
* per-folder artifacts such as the transcript path from them. */
|
|
71
|
+
function knownSessionCwds(id) {
|
|
72
|
+
const row = _cachedSummaryRows()?.find((candidate) => candidate.id === id);
|
|
73
|
+
const live = _liveSessions.get(id);
|
|
74
|
+
const cwds = [row?.cwd, row?.workspace?.cwd, row?.workspace?.projectPath, live?.cwd];
|
|
75
|
+
return [...new Set(cwds.filter((cwd) => typeof cwd === 'string' && cwd))];
|
|
76
|
+
}
|
|
77
|
+
|
|
68
78
|
export function deleteSession(id, options = {}) {
|
|
69
79
|
// Keep caller probes and all vetoes ahead of the non-reentrant lock and
|
|
70
80
|
// ahead of pending-save disruption, matching markSessionClosed().
|
|
71
|
-
if (_runtimeLivenessVeto(id, options)
|
|
81
|
+
if (_runtimeLivenessVeto(id, options)) return false;
|
|
72
82
|
const deleteGuard = _guardedSaveOptions(id);
|
|
73
83
|
const commitControl = _acquireWriteCommit(deleteGuard);
|
|
74
84
|
if (commitControl === false) return false;
|
|
75
85
|
try {
|
|
76
|
-
// Cross-process revival after full-TTL silence remains best-effort; the
|
|
77
|
-
// tombstone resurrection guard is authoritative. Only re-stat .hb here.
|
|
78
|
-
if (_heartbeatLivenessVeto(id, options)) return false;
|
|
79
86
|
// ── 1. unlink FIRST, still holding the commit lock ─────────────────────
|
|
80
87
|
// A failed unlink is NOT a delete: the canonical bytes are still there, so
|
|
81
88
|
// nothing may be purged, cancelled or closed — every pending write, parked
|
|
@@ -122,15 +129,15 @@ export function deleteSession(id, options = {}) {
|
|
|
122
129
|
// its settlement moves no marker and touches no bookkeeping — and a
|
|
123
130
|
// re-created id gets a brand new incarnation of its own.
|
|
124
131
|
_retireSessionIncarnation(id);
|
|
132
|
+
// An explicit user delete also fences the id: a still-running turn's later
|
|
133
|
+
// saves get fresh guards/incarnations and would otherwise recreate the file.
|
|
134
|
+
if (options.fenceWrites === true) fenceSessionWrites(id);
|
|
125
135
|
_cancelSessionWrites(id);
|
|
126
136
|
_clearDebounce(id);
|
|
127
137
|
_releasePendingSlot(_savePending.get(id));
|
|
128
138
|
_savePending.delete(id);
|
|
129
139
|
_purgeSessionSaveBookkeeping(id);
|
|
130
|
-
_runSessionPurgeHooks(id);
|
|
131
|
-
// Preserve a sidecar published strictly after the sweep's scan snapshot.
|
|
132
|
-
_deleteHeartbeatUnlessNewer(id, options);
|
|
133
|
-
deleteSessionPresence(id);
|
|
140
|
+
_runSessionPurgeHooks(id, { cwds: knownSessionCwds(id) });
|
|
134
141
|
// The display-only compaction archive has no meaning without its session.
|
|
135
142
|
deleteCompactionArchive(getStoreDir(), id);
|
|
136
143
|
_clearLiveSession(id);
|