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,49 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Async child run with spawnSync's result shape ({ status, signal, stdout,
|
|
5
|
+
* stderr, error }) so the PG runtime's tar / initdb / pg_ctl steps never block
|
|
6
|
+
* the event loop of the process hosting them (the daemon serves every client
|
|
7
|
+
* from one loop). `timeoutMs` > 0 kills the child and reports ETIMEDOUT, like
|
|
8
|
+
* spawnSync's `timeout`. Never rejects.
|
|
9
|
+
*/
|
|
10
|
+
export function runChild(file, args, { timeoutMs = 0, ...options } = {}) {
|
|
11
|
+
return new Promise((resolve) => {
|
|
12
|
+
const stdout = [];
|
|
13
|
+
const stderr = [];
|
|
14
|
+
let settled = false;
|
|
15
|
+
let timer = null;
|
|
16
|
+
let error = null;
|
|
17
|
+
const finish = (status, signal) => {
|
|
18
|
+
if (settled) return;
|
|
19
|
+
settled = true;
|
|
20
|
+
if (timer) clearTimeout(timer);
|
|
21
|
+
resolve({ status, signal, stdout: Buffer.concat(stdout), stderr: Buffer.concat(stderr), error });
|
|
22
|
+
};
|
|
23
|
+
let child;
|
|
24
|
+
try {
|
|
25
|
+
child = spawn(file, args, { windowsHide: true, ...options, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
26
|
+
} catch (spawnError) {
|
|
27
|
+
error = spawnError;
|
|
28
|
+
finish(null, null);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
child.stdout?.on('data', (chunk) => stdout.push(chunk));
|
|
32
|
+
child.stderr?.on('data', (chunk) => stderr.push(chunk));
|
|
33
|
+
child.once('error', (childError) => {
|
|
34
|
+
error ??= childError;
|
|
35
|
+
finish(null, null);
|
|
36
|
+
});
|
|
37
|
+
// 'close' (not 'exit'): stdio is flushed, so captured output is complete.
|
|
38
|
+
child.once('close', (status, signal) => finish(status, signal));
|
|
39
|
+
if (timeoutMs > 0) {
|
|
40
|
+
timer = setTimeout(() => {
|
|
41
|
+
error = Object.assign(new Error(`${file} timed out after ${timeoutMs}ms`), { code: 'ETIMEDOUT' });
|
|
42
|
+
try {
|
|
43
|
+
child.kill();
|
|
44
|
+
} catch {}
|
|
45
|
+
finish(null, 'SIGTERM');
|
|
46
|
+
}, timeoutMs);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -6,6 +6,9 @@ import { __mixdogMemoryLog } from '../memory-log.mjs';
|
|
|
6
6
|
* Public API:
|
|
7
7
|
* ensurePgInstance(dataDir) → Promise<{ host, port, runtimeDir, pgdataDir }>
|
|
8
8
|
* stopPgForShutdown() → Promise<void> — call from server-main.mjs shutdown()
|
|
9
|
+
* stopOwnedPgForShutdown() → Promise<boolean> — a host stopping the cluster it ensured
|
|
10
|
+
* installOwnedPgExitStop() → void — last-chance sync stop on process exit
|
|
11
|
+
* pgClusterExists(dataDir) → boolean — initdb already ran for dataDir
|
|
9
12
|
*
|
|
10
13
|
* Uses process.mjs for startPg / stopPg / healthcheckPg (lazy-imported).
|
|
11
14
|
*
|
|
@@ -17,7 +20,7 @@ import { __mixdogMemoryLog } from '../memory-log.mjs';
|
|
|
17
20
|
*/
|
|
18
21
|
|
|
19
22
|
import { createServer } from 'node:net';
|
|
20
|
-
import { unlinkSync, readFileSync, writeFileSync, renameSync, statSync, mkdirSync } from 'node:fs';
|
|
23
|
+
import { existsSync, unlinkSync, readFileSync, writeFileSync, renameSync, statSync, mkdirSync } from 'node:fs';
|
|
21
24
|
import { join, resolve } from 'node:path';
|
|
22
25
|
import {
|
|
23
26
|
discoveryPath as _pgDiscoveryPath,
|
|
@@ -51,6 +54,10 @@ let _live = null;
|
|
|
51
54
|
let _ensureInFlight = null;
|
|
52
55
|
/** Per-process flag — postgresql.conf reconcile attempted once per supervisor. */
|
|
53
56
|
let _v2ReconcileTried = false;
|
|
57
|
+
/** Set by stopOwnedPgForShutdown: this process is exiting, no further ensure. */
|
|
58
|
+
let _ownedShutdownStarted = false;
|
|
59
|
+
/** installOwnedPgExitStop registers its 'exit' hook once. */
|
|
60
|
+
let _ownedExitStopInstalled = false;
|
|
54
61
|
|
|
55
62
|
// ── Constants ────────────────────────────────────────────────────────────────
|
|
56
63
|
const PG_PORT_MIN = 55432;
|
|
@@ -537,9 +544,20 @@ async function tryReusePgInstance({ pgdata, runtimeDir, healthcheckPg, source =
|
|
|
537
544
|
|
|
538
545
|
// ── Internal: full ensure logic (runs exclusively via _ensureInFlight) ────────
|
|
539
546
|
|
|
547
|
+
function _pgdataDir(dataDir) {
|
|
548
|
+
return join(dataDir, 'pgdata');
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/** True once `dataDir` holds an initialized cluster (initdb ran). Before that
|
|
552
|
+
* no store in it can hold rows, so a read may answer empty without starting
|
|
553
|
+
* PostgreSQL — the first start downloads/extracts the runtime and runs initdb. */
|
|
554
|
+
export function pgClusterExists(dataDir) {
|
|
555
|
+
return existsSync(join(_pgdataDir(dataDir), 'PG_VERSION'));
|
|
556
|
+
}
|
|
557
|
+
|
|
540
558
|
async function _doEnsure(dataDir) {
|
|
541
559
|
const { healthcheckPg } = await _getPgProc();
|
|
542
|
-
const pgdata =
|
|
560
|
+
const pgdata = _pgdataDir(dataDir);
|
|
543
561
|
|
|
544
562
|
// Resolve runtimeDir via runtime-fetcher (cache-hits immediately when already downloaded).
|
|
545
563
|
const { ensureRuntime } = await import('../runtime-fetcher.mjs');
|
|
@@ -552,7 +570,7 @@ async function _doEnsure(dataDir) {
|
|
|
552
570
|
_v2ReconcileTried = true;
|
|
553
571
|
try {
|
|
554
572
|
const { reconcileConfV2 } = await _getPgProc();
|
|
555
|
-
reconcileConfV2(runtimeDir, pgdata);
|
|
573
|
+
await reconcileConfV2(runtimeDir, pgdata);
|
|
556
574
|
} catch (e) {
|
|
557
575
|
__mixdogMemoryLog(`[supervisor-pg] reconcileConfV2 error (non-fatal): ${e?.message}\n`);
|
|
558
576
|
}
|
|
@@ -699,6 +717,12 @@ async function _doEnsure(dataDir) {
|
|
|
699
717
|
* @returns {Promise<{ host: string, port: number, runtimeDir: string, pgdataDir: string }>}
|
|
700
718
|
*/
|
|
701
719
|
export function ensurePgInstance(dataDir) {
|
|
720
|
+
// Once this process began stopping the cluster it owns, nothing may start
|
|
721
|
+
// or re-attach one: a late connection-loss recovery would otherwise bring a
|
|
722
|
+
// postmaster back up right after the stop and leave it running past exit.
|
|
723
|
+
if (_ownedShutdownStarted) {
|
|
724
|
+
return Promise.reject(new Error('[supervisor-pg] process is shutting down; PG start refused'));
|
|
725
|
+
}
|
|
702
726
|
// Every route to a live PG passes here — start, attach, reuse and the
|
|
703
727
|
// in-process fast path — so this is the one place the sweep cannot be
|
|
704
728
|
// skipped. Latched internally, so repeated calls schedule it only once.
|
|
@@ -804,5 +828,89 @@ export function stopPgForShutdownSync() {
|
|
|
804
828
|
} catch {}
|
|
805
829
|
// The postmaster is gone, so drop its advert too (same guarded clear as the
|
|
806
830
|
// async path: never another live owner's); otherwise pg.json outlives the run.
|
|
807
|
-
patchActiveInstance(
|
|
831
|
+
patchActiveInstance(
|
|
832
|
+
{ pg_port: null, pg_started_at: null, pg_pgdata: null, pg_runtime_dir: null },
|
|
833
|
+
{ timeoutMs: 1000 }
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// ── Owned-cluster shutdown (a host that starts PG through its stores) ────────
|
|
838
|
+
//
|
|
839
|
+
// `pg_ctl start` daemonizes the postmaster outside the starting process tree,
|
|
840
|
+
// so nothing ends it when that process exits: the process that brought a
|
|
841
|
+
// cluster up (or adopted one whose owner died) owns stopping it. Unlike
|
|
842
|
+
// stopPgForShutdown above, these never act on a cluster this process did not
|
|
843
|
+
// ensure, and never on one a different live process owns (pg_owner_pid) —
|
|
844
|
+
// that owner stops it on its own exit.
|
|
845
|
+
|
|
846
|
+
/** `_live` cluster's advert is held by another live process. */
|
|
847
|
+
function _liveClusterForeignOwned(snap) {
|
|
848
|
+
let advert = null;
|
|
849
|
+
try {
|
|
850
|
+
advert = _readPgAdvert();
|
|
851
|
+
} catch {}
|
|
852
|
+
if (!advert?.pg_pgdata || resolve(advert.pg_pgdata) !== resolve(snap.pgdata)) return false;
|
|
853
|
+
return _pgAdvertIsForeignLive(advert);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Graceful, bounded stop (`pg_ctl stop -m fast`) of the cluster this process
|
|
858
|
+
* ensured. Latches the process into shutdown first, so no later ensure can
|
|
859
|
+
* start another one. Resolves true when a cluster was stopped; rejects when
|
|
860
|
+
* pg_ctl failed (the 'exit' hook then retries synchronously).
|
|
861
|
+
*/
|
|
862
|
+
export async function stopOwnedPgForShutdown({ timeoutMs = 6_000 } = {}) {
|
|
863
|
+
_ownedShutdownStarted = true;
|
|
864
|
+
// A start still under way (pg_ctl start already spawned, readiness pending)
|
|
865
|
+
// publishes its cluster only when it settles; stopping before that would
|
|
866
|
+
// miss the postmaster it is about to own. Bounded: a cold first start can
|
|
867
|
+
// be a download.
|
|
868
|
+
if (_ensureInFlight) {
|
|
869
|
+
let timer = null;
|
|
870
|
+
await Promise.race([
|
|
871
|
+
_ensureInFlight.catch(() => {}),
|
|
872
|
+
new Promise((resolveWait) => {
|
|
873
|
+
timer = setTimeout(resolveWait, timeoutMs);
|
|
874
|
+
timer.unref?.();
|
|
875
|
+
}),
|
|
876
|
+
]);
|
|
877
|
+
clearTimeout(timer);
|
|
878
|
+
}
|
|
879
|
+
const snap = _live;
|
|
880
|
+
if (!snap) return false;
|
|
881
|
+
if (_liveClusterForeignOwned(snap)) {
|
|
882
|
+
__mixdogMemoryLog(`[supervisor-pg] PG on port ${snap.port} is owned by another live process; leaving it running\n`);
|
|
883
|
+
_live = null;
|
|
884
|
+
return false;
|
|
885
|
+
}
|
|
886
|
+
const { stopPg } = await _getPgProc();
|
|
887
|
+
await stopPg({ runtimeDir: snap.runtimeDir, pgdataDir: snap.pgdata, timeoutMs });
|
|
888
|
+
_live = null;
|
|
889
|
+
__mixdogMemoryLog(`[supervisor-pg] owned PG on port ${snap.port} stopped on shutdown\n`);
|
|
890
|
+
patchActiveInstance(
|
|
891
|
+
{ pg_port: null, pg_started_at: null, pg_pgdata: null, pg_runtime_dir: null },
|
|
892
|
+
{ timeoutMs: 2000, syncRetries: 1 }
|
|
893
|
+
);
|
|
894
|
+
return true;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/** Last-chance synchronous stop for a process 'exit' hook: acts only while the
|
|
898
|
+
* cluster this process ensured is still recorded as live (an exit the async
|
|
899
|
+
* stop never reached, or one where it failed). */
|
|
900
|
+
export function stopOwnedPgForShutdownSync() {
|
|
901
|
+
if (!_live) return;
|
|
902
|
+
stopPgForShutdownSync();
|
|
903
|
+
_live = null;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/** Register stopOwnedPgForShutdownSync on process 'exit', once. Cheap when this
|
|
907
|
+
* process never ensures a cluster: the hook is then a no-op. */
|
|
908
|
+
export function installOwnedPgExitStop() {
|
|
909
|
+
if (_ownedExitStopInstalled) return;
|
|
910
|
+
_ownedExitStopInstalled = true;
|
|
911
|
+
process.on('exit', () => {
|
|
912
|
+
try {
|
|
913
|
+
stopOwnedPgForShutdownSync();
|
|
914
|
+
} catch {}
|
|
915
|
+
});
|
|
808
916
|
}
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
} from 'node:fs';
|
|
33
33
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
34
34
|
import { fileURLToPath } from 'node:url';
|
|
35
|
-
import {
|
|
35
|
+
import { runChild } from './pg/run-child.mjs';
|
|
36
36
|
import { renameWithRetrySync, writeFileAtomicSync, writeJsonAtomicSync } from '../../shared/atomic-file.mjs';
|
|
37
37
|
import { downloadToFileWithRetry } from '../../shared/bounded-download.mjs';
|
|
38
38
|
import { platformKey, platformKeyCandidates, verifySha256File } from '../../shared/native-asset.mjs';
|
|
@@ -250,21 +250,23 @@ export function _validateRuntimeTarEntries(entries, details, stagingBase) {
|
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
// Async throughout: the first boot extracts the whole PG runtime here, and a
|
|
254
|
+
// synchronous tar froze the daemon loop for seconds.
|
|
255
|
+
export async function _extractRuntimeTarGz(tarPath, destDir, stagingBase) {
|
|
254
256
|
mkdirSync(destDir, { recursive: true });
|
|
255
257
|
const resolvedTarPath = resolve(tarPath);
|
|
256
|
-
const tarOptions = { cwd: dirname(resolvedTarPath)
|
|
258
|
+
const tarOptions = { cwd: dirname(resolvedTarPath) };
|
|
257
259
|
const tarName = basename(resolvedTarPath);
|
|
258
260
|
|
|
259
261
|
// List entries first and validate — reject traversal, external links, and
|
|
260
262
|
// special files before the extractor can materialize archive content.
|
|
261
263
|
// Keep the archive argument relative to cwd: GNU tar otherwise interprets
|
|
262
264
|
// an absolute Windows path such as C:\runtime.tar.gz as a remote host path.
|
|
263
|
-
const listResult =
|
|
265
|
+
const listResult = await runChild('tar', ['-tzf', tarName], tarOptions);
|
|
264
266
|
if (listResult.status !== 0) {
|
|
265
267
|
throw new Error(`[runtime-fetcher] tar list failed: ${listResult.stderr?.toString() || 'unknown'}`);
|
|
266
268
|
}
|
|
267
|
-
const detailResult =
|
|
269
|
+
const detailResult = await runChild('tar', ['-tvzf', tarName], tarOptions);
|
|
268
270
|
if (detailResult.status !== 0) {
|
|
269
271
|
throw new Error(`[runtime-fetcher] tar detail list failed: ${detailResult.stderr?.toString() || 'unknown'}`);
|
|
270
272
|
}
|
|
@@ -274,10 +276,7 @@ export function _extractRuntimeTarGz(tarPath, destDir, stagingBase) {
|
|
|
274
276
|
|
|
275
277
|
const resolvedDestDir = resolve(destDir);
|
|
276
278
|
const extractionArchive = relative(resolvedDestDir, resolvedTarPath);
|
|
277
|
-
const r =
|
|
278
|
-
...tarOptions,
|
|
279
|
-
cwd: resolvedDestDir,
|
|
280
|
-
});
|
|
279
|
+
const r = await runChild('tar', ['-xzf', extractionArchive], { cwd: resolvedDestDir });
|
|
281
280
|
if (r.status !== 0) {
|
|
282
281
|
throw new Error(`[runtime-fetcher] tar extraction failed: ${r.stderr?.toString() || 'unknown error'}`);
|
|
283
282
|
}
|
|
@@ -438,9 +437,9 @@ const runtimeCache = new Map();
|
|
|
438
437
|
|
|
439
438
|
// One-shot tar availability probe; result cached after first call.
|
|
440
439
|
let _tarProbed = false;
|
|
441
|
-
function probeTar() {
|
|
440
|
+
async function probeTar() {
|
|
442
441
|
if (_tarProbed) return;
|
|
443
|
-
const r =
|
|
442
|
+
const r = await runChild('tar', ['--version']);
|
|
444
443
|
if (r.status !== 0 || r.error) {
|
|
445
444
|
throw new Error(
|
|
446
445
|
'[runtime-fetcher] `tar` not found or not executable. ' +
|
|
@@ -532,7 +531,7 @@ async function installRuntimeVersion({ runtimeBaseDir, url, sha256, size, versio
|
|
|
532
531
|
// tar is only required for the download/extract path. Probe here (not at
|
|
533
532
|
// ensureRuntime entry) so a machine without tar can still reuse an
|
|
534
533
|
// already-extracted, sha-matching cached runtime via the fast path.
|
|
535
|
-
probeTar();
|
|
534
|
+
await probeTar();
|
|
536
535
|
|
|
537
536
|
__mixdogMemoryLog(`[runtime-fetcher] downloading runtime ${version} for ${pkey} (~${size} bytes) …\n`);
|
|
538
537
|
|
|
@@ -574,7 +573,7 @@ async function installRuntimeVersion({ runtimeBaseDir, url, sha256, size, versio
|
|
|
574
573
|
}
|
|
575
574
|
}
|
|
576
575
|
if (!downloadOk && lastDownloadErr) throw lastDownloadErr;
|
|
577
|
-
_extractRuntimeTarGz(tarPath, stagingDir, stagingDir);
|
|
576
|
+
await _extractRuntimeTarGz(tarPath, stagingDir, stagingDir);
|
|
578
577
|
} finally {
|
|
579
578
|
try {
|
|
580
579
|
rmSync(tarPath, { force: true });
|
|
@@ -53,7 +53,21 @@ export function createTranscriptIngest({
|
|
|
53
53
|
return run;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/** A deleted session's transcripts: wait out any ingest of each file, then
|
|
57
|
+
* drop its persisted read position. Returns the number of entries removed. */
|
|
58
|
+
async function forgetTranscripts(transcriptPaths) {
|
|
59
|
+
let removed = 0;
|
|
60
|
+
for (const transcriptPath of transcriptPaths) {
|
|
61
|
+
const resolved = path.resolve(transcriptPath);
|
|
62
|
+
await tails.get(resolved);
|
|
63
|
+
for (const key of new Set([transcriptPath, resolved])) if (offsets.forget(key)) removed += 1;
|
|
64
|
+
}
|
|
65
|
+
if (removed > 0) await offsets.persist();
|
|
66
|
+
return removed;
|
|
67
|
+
}
|
|
68
|
+
|
|
56
69
|
return {
|
|
70
|
+
forgetTranscripts,
|
|
57
71
|
loadTranscriptOffsets: offsets.load,
|
|
58
72
|
persistTranscriptOffsets: offsets.persist,
|
|
59
73
|
ingestTranscriptFile,
|
|
@@ -10,7 +10,7 @@ Microsoft Office installed.
|
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| `(root)` | Public surface only: `index.mjs` (tool executor), `tool-defs.mjs`, `capabilities.mjs`. Test suites and `office-test-support.mjs` also live here. |
|
|
12
12
|
| `authoring/` | The `author` action — the only way a deck is made: `pptx-script-contract.mjs` (what a script may require and how long it may run; the model-facing guide is the built-in `pptx` skill in `src/defaults/skills/pptx`), `pptx-script-runner.mjs` (runs a pptxgenjs script in-process with a scoped `require`, injecting `MEASURE` and `ICON`), `pptx-script-normalize.mjs` (paragraph properties, hanging punctuation, accent-series merge), `pptx-html-runner.mjs` + `pptx-html-measure.mjs` + `pptx-html-build.mjs` (the HTML input: a local Chrome/Edge lays the slides out, the measurement becomes native text boxes, shapes, tables, charts, and pictures, and the browser's pages are kept for the HTML-beside-PPTX comparison), `pptx-author-action.mjs` (writes the deck, opens an `authored` session, renders, returns the composition receipt and contact sheet), `pptx-receipt.mjs`, `pptx-contact-sheet.mjs`, `pptx-icons.mjs` + `pptx-icons.json` (offline Lucide subset built by `npm run office:icons`), `pptx-brief.mjs`. Sits beside the root and imports `core`. |
|
|
13
|
-
| `core/` | Sessions, transactions, journal, snapshot pagination, tabular sessions,
|
|
13
|
+
| `core/` | Sessions, transactions, journal, snapshot pagination, tabular sessions, the action pipeline (`office-actions-*.mjs`), and the write ledger (`office-write-ledger.mjs`: every route that writes a workspace file reports it with `noteOfficeWrite` before writing; `index.mjs` records the reported files that changed in the session's turn review as its own changes). |
|
|
14
14
|
| `com/` | Windows-native path: `com-adapter.mjs` plus the PowerShell hosts `office-com-host.ps1` and `office-com-session-host.ps1`. |
|
|
15
15
|
| `portable/` | OOXML read/write without Office, package validation, XLSX contracts, the backend-neutral XLSX audits shared by portable `issues`, Excel's `issues` merge, and the quality review (`xlsx-audit-support.mjs` cell reading and the capped issue list, `xlsx-sheet-hygiene.mjs` every-profile hygiene and layout information, `xlsx-formula-audit.mjs` the financial-model discipline and the orchestration), the workbook conventions summary a snapshot carries (`xlsx-conventions.mjs`), LibreOffice recalculation with its error summary (`portable-soffice.mjs` holds one private user profile for the life of the process, runs conversions one at a time behind it, and drops the profile after a failed run; `xlsx-recalculate.mjs` asks LibreOffice first and falls back to `xlsx-formula-engine.mjs`, which evaluates the formulas in this process and refuses — never guesses — the ones it cannot read; `portable-shared-formulas.mjs` gives every cell a shared or array formula covers the formula it actually holds, so a filled-down column is never read as pasted numbers), the sheet content audits (`portable-sheet-audits.mjs`: percent scale, column fit, protected inputs, unreadable ink, a hardcode inside a row of formulas), the leftover scan (`placeholder-scan.mjs`: template wording and tools' citation markers, read on slides, a document's body, headers and footers, and PDF pages), `convertLegacyOffice` in `portable-soffice.mjs` (a `.doc`/`.xls`/`.ppt` saved once as its package beside the original when `open` meets one), text and image metrics. |
|
|
16
16
|
| `pdf/` | `pdf-adapter.mjs` (session surface: snapshot, batch — including the marks `highlight`, `add_link`, `preview_fields` — validate, issues; re-exports `createPdf`), `pdf-writer.mjs` (blocks → pages, tables, page numbers), `pdf-forms.mjs` (field lint, add, describe, fill), `pdf-draw.mjs` (colors, page sizes, wrapping, images), `pdf-fonts.mjs` (system Unicode font fallback shared by create, marks, forms, and OCR), `pdf-analysis.mjs` (text layout with rules, boxes, and links, ruled and aligned tables, images, OCR), `pdf-search.mjs` (text search over a layout: lines from runs, glyph-width placement, whole words), `pdf-safety.mjs` (active-content report: JavaScript, Launch, non-web links), `pdf-render.mjs`, `pdf-security.mjs` (qpdf), `document-preview.mjs`. |
|
|
@@ -39,7 +39,7 @@ export async function runDocxHtmlAuthoring(html, output, { target, signal = null
|
|
|
39
39
|
const scratch = await mkdtemp(join(tmpdir(), 'mixdog-docx-captures-'));
|
|
40
40
|
let browser;
|
|
41
41
|
try {
|
|
42
|
-
browser = await launchHtmlBrowser('docx-html-browser');
|
|
42
|
+
browser = await launchHtmlBrowser('docx-html-browser', { signal });
|
|
43
43
|
} catch (error) {
|
|
44
44
|
await rm(scratch, { recursive: true, force: true }).catch(() => {});
|
|
45
45
|
return htmlFailure(error, startedAt);
|
|
@@ -2,17 +2,25 @@
|
|
|
2
2
|
// deadline and abort wiring around the layout work, the failure result, and the photographs of captured elements.
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
buildPuppeteerLaunchArgs,
|
|
7
|
+
launchPuppeteerBrowser,
|
|
8
|
+
resolveBrowserLaunchOptions,
|
|
9
|
+
} from '../../shared/browser-launch.mjs';
|
|
6
10
|
import { startChildGuardian } from '../../shared/child-guardian.mjs';
|
|
7
11
|
|
|
8
12
|
/** Launches the local browser the HTML is laid out in, under a guardian that reaps it with this process. */
|
|
9
|
-
export async function launchHtmlBrowser(label) {
|
|
13
|
+
export async function launchHtmlBrowser(label, { signal = null } = {}) {
|
|
10
14
|
const puppeteer = (await import('puppeteer-core')).default;
|
|
11
|
-
const browser = await
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const browser = await launchPuppeteerBrowser(
|
|
16
|
+
puppeteer,
|
|
17
|
+
{
|
|
18
|
+
headless: true,
|
|
19
|
+
...resolveBrowserLaunchOptions(),
|
|
20
|
+
args: buildPuppeteerLaunchArgs(['--font-render-hinting=none']),
|
|
21
|
+
},
|
|
22
|
+
{ signal }
|
|
23
|
+
);
|
|
16
24
|
try {
|
|
17
25
|
startChildGuardian({ childPid: browser.process?.()?.pid, label });
|
|
18
26
|
} catch {}
|
|
@@ -22,7 +30,9 @@ export async function launchHtmlBrowser(label) {
|
|
|
22
30
|
/** Runs `work` against the browser under a deadline and an abort signal, and closes the browser afterwards. */
|
|
23
31
|
export async function runInBrowser(browser, { signal, timeoutMs }, work) {
|
|
24
32
|
const abort = () => browser.close().catch(() => {});
|
|
25
|
-
|
|
33
|
+
// A cancel that landed while the browser was launching closes it at once.
|
|
34
|
+
if (signal?.aborted) abort();
|
|
35
|
+
else signal?.addEventListener('abort', abort, { once: true });
|
|
26
36
|
let timer = null;
|
|
27
37
|
const running = work();
|
|
28
38
|
const timeout = new Promise((_, reject) => {
|
|
@@ -8,6 +8,7 @@ import { render } from '../core/office-actions.mjs';
|
|
|
8
8
|
import { documentFormat, officeSessionForDocument } from '../core/office-core.mjs';
|
|
9
9
|
import { createAuthoredSession, exists, fullPath, validatePptxAuthorMode } from '../core/office-sessions.mjs';
|
|
10
10
|
import { inlineOfficeAudit } from '../quality/inline-audit.mjs';
|
|
11
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
11
12
|
import { parseAuthoringBrief } from './pptx-brief.mjs';
|
|
12
13
|
import { htmlBriefScript } from './pptx-html-runner.mjs';
|
|
13
14
|
import {
|
|
@@ -68,6 +69,7 @@ async function writeComparisons(target, htmlPages, officePages) {
|
|
|
68
69
|
(await scaled(officePages.find((image) => image.page === page && (image.pages?.length || 1) === 1))) ||
|
|
69
70
|
(await blank(left.width));
|
|
70
71
|
const path = `${target}.mixdog-compare-page-${page}.png`;
|
|
72
|
+
noteOfficeWrite(path);
|
|
71
73
|
await sharp({ create: { width: left.width + right.width + gap, height, channels: 3, background: '#808080' } })
|
|
72
74
|
.composite([
|
|
73
75
|
{ input: left.data, left: 0, top: 0 },
|
|
@@ -262,7 +262,7 @@ export async function printHtmlPdf(
|
|
|
262
262
|
await rm(output, { force: true });
|
|
263
263
|
let browser;
|
|
264
264
|
try {
|
|
265
|
-
browser = await launchHtmlBrowser('pdf-html-browser');
|
|
265
|
+
browser = await launchHtmlBrowser('pdf-html-browser', { signal });
|
|
266
266
|
} catch (error) {
|
|
267
267
|
return htmlFailure(error, startedAt);
|
|
268
268
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { writeFile } from 'node:fs/promises';
|
|
8
8
|
import { basename, dirname, extname, join } from 'node:path';
|
|
9
9
|
import { createCanvas, loadImage } from '@napi-rs/canvas';
|
|
10
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
10
11
|
|
|
11
12
|
function pageImages(images = []) {
|
|
12
13
|
const pages = [];
|
|
@@ -51,6 +52,7 @@ export async function writeContactSheet(images, output, { width = 1600 } = {}) {
|
|
|
51
52
|
const data = sheet.toBuffer('image/png');
|
|
52
53
|
const stem = basename(output, extname(output));
|
|
53
54
|
const path = join(dirname(output), `${stem}.mixdog-contact.png`);
|
|
55
|
+
noteOfficeWrite(path);
|
|
54
56
|
await writeFile(path, data);
|
|
55
57
|
return {
|
|
56
58
|
path,
|
|
@@ -9,6 +9,7 @@ import { createRequire } from 'node:module';
|
|
|
9
9
|
import { pathToFileURL } from 'node:url';
|
|
10
10
|
|
|
11
11
|
import { launchHtmlBrowser, runInBrowser } from './html-browser.mjs';
|
|
12
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
12
13
|
import { iconGlobal } from './pptx-icons.mjs';
|
|
13
14
|
import { GEOMETRY_TOLERANCE_PX, NEAR_MISS_PX, readGeometry } from './pptx-html-geometry.mjs';
|
|
14
15
|
|
|
@@ -558,7 +559,7 @@ export async function measureHtmlDeck(
|
|
|
558
559
|
{ sourcePath, shotPath, timeoutMs = 90_000, signal = null, prepare = null }
|
|
559
560
|
) {
|
|
560
561
|
await writeFile(sourcePath, html, 'utf8');
|
|
561
|
-
const browser = await launchHtmlBrowser('pptx-html-browser');
|
|
562
|
+
const browser = await launchHtmlBrowser('pptx-html-browser', { signal });
|
|
562
563
|
const work = async () => {
|
|
563
564
|
const page = await browser.newPage();
|
|
564
565
|
await page.setViewport(viewport(HTML_CANVAS, 1));
|
|
@@ -598,6 +599,7 @@ export async function measureHtmlDeck(
|
|
|
598
599
|
);
|
|
599
600
|
}
|
|
600
601
|
const shot = shotPath(index + 1);
|
|
602
|
+
noteOfficeWrite(shot);
|
|
601
603
|
await element.screenshot({ path: shot });
|
|
602
604
|
shots.push(shot);
|
|
603
605
|
const measured = await page.evaluate(extractSlide, index);
|
|
@@ -6,6 +6,7 @@ import { dirname } from 'node:path';
|
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
7
|
|
|
8
8
|
import { HTML_CANVAS, measureHtmlDeck } from './pptx-html-measure.mjs';
|
|
9
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
9
10
|
import { buildPptxFromMeasure } from './pptx-html-build.mjs';
|
|
10
11
|
import { normalizeAuthoredPptx } from './pptx-script-normalize.mjs';
|
|
11
12
|
|
|
@@ -312,6 +313,7 @@ export async function writeHtmlComparisons(target, htmlShots, renderedImages) {
|
|
|
312
313
|
const left = await sharp(html).resize(width, height, { fit: 'fill' }).png().toBuffer();
|
|
313
314
|
const right = await sharp(image.path).resize(width, height, { fit: 'fill' }).png().toBuffer();
|
|
314
315
|
const path = artifacts.compare(image.page);
|
|
316
|
+
noteOfficeWrite(path);
|
|
315
317
|
await sharp({ create: { width: width * 2 + gap, height, channels: 3, background: '#808080' } })
|
|
316
318
|
.composite([
|
|
317
319
|
{ input: left, left: 0, top: 0 },
|
|
@@ -6,6 +6,7 @@ import { dirname, join } from 'node:path';
|
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
7
|
|
|
8
8
|
import { htmlFailure, launchHtmlBrowser, photographCaptures, runInBrowser } from './html-browser.mjs';
|
|
9
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
9
10
|
import { iconTable, injectIcons } from './pptx-html-measure.mjs';
|
|
10
11
|
import { extractXlsxSheets } from './xlsx-html-measure.mjs';
|
|
11
12
|
import { drawDataCharts } from './pdf-html-charts.mjs';
|
|
@@ -65,7 +66,7 @@ export async function runXlsxHtmlAuthoring(html, output, { target, signal = null
|
|
|
65
66
|
const scratch = await mkdtemp(join(tmpdir(), 'mixdog-xlsx-captures-'));
|
|
66
67
|
let browser;
|
|
67
68
|
try {
|
|
68
|
-
browser = await launchHtmlBrowser('xlsx-html-browser');
|
|
69
|
+
browser = await launchHtmlBrowser('xlsx-html-browser', { signal });
|
|
69
70
|
} catch (error) {
|
|
70
71
|
await rm(scratch, { recursive: true, force: true }).catch(() => {});
|
|
71
72
|
return htmlFailure(error, startedAt);
|
|
@@ -106,6 +107,7 @@ export async function runXlsxHtmlAuthoring(html, output, { target, signal = null
|
|
|
106
107
|
const htmlPages = [];
|
|
107
108
|
for (const [index, clip] of extents.entries()) {
|
|
108
109
|
const path = artifacts.shot(index + 1);
|
|
110
|
+
noteOfficeWrite(path);
|
|
109
111
|
await page.screenshot({ path, clip, captureBeyondViewport: true });
|
|
110
112
|
htmlPages.push({ page: index + 1, path });
|
|
111
113
|
}
|
|
@@ -2,6 +2,7 @@ import { mkdir, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { extractPdfImages, extractPdfTextLayout, findPdfText, inferPdfTables } from '../pdf/pdf-analysis.mjs';
|
|
4
4
|
import { findByDocumentPath, fullPath, queryObject, snapshot, snapshotSelectionForTarget } from './office-sessions.mjs';
|
|
5
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
5
6
|
|
|
6
7
|
/** RFC 4180 quoting so a table cell that contains a comma or quote round-trips. */
|
|
7
8
|
export function csvCell(text) {
|
|
@@ -94,6 +95,7 @@ async function queryPdfTables(session, args, cwd, signal) {
|
|
|
94
95
|
const ordinal = (counters.get(table.page) || 0) + 1;
|
|
95
96
|
counters.set(table.page, ordinal);
|
|
96
97
|
const file = join(directory, `page-${table.page}-table-${ordinal}.csv`);
|
|
98
|
+
noteOfficeWrite(file);
|
|
97
99
|
await writeFile(
|
|
98
100
|
file,
|
|
99
101
|
`${table.rows.map((row) => row.map((cell) => csvCell(String(cell ?? ''))).join(',')).join('\r\n')}\r\n`,
|
|
@@ -115,6 +117,7 @@ async function queryPdfImages(session, args, cwd, signal) {
|
|
|
115
117
|
const written = [];
|
|
116
118
|
for (const image of extracted._images) {
|
|
117
119
|
const file = join(directory, `page-${image.page}-image-${image.index}.png`);
|
|
120
|
+
noteOfficeWrite(file);
|
|
118
121
|
await writeFile(file, Buffer.from(image.data, 'base64'));
|
|
119
122
|
written.push(file);
|
|
120
123
|
}
|
|
@@ -8,6 +8,7 @@ import { resolveOfficeRenderOutput } from '../quality/quality-pipeline.mjs';
|
|
|
8
8
|
import { defaultRenderOutput, exists, fullPath } from './office-sessions.mjs';
|
|
9
9
|
import { completePageCoverage, pptxPageSignatures, reusablePptxPages } from './pptx-page-cache.mjs';
|
|
10
10
|
import { numberDocxTableOfContents } from './docx-toc-pages.mjs';
|
|
11
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
11
12
|
|
|
12
13
|
function request(session, args, cwd) {
|
|
13
14
|
return {
|
|
@@ -136,6 +137,7 @@ export async function renderOfficePreview(
|
|
|
136
137
|
const exportKey = `${session.target}\0${Number(session.snapshotVersion || 0)}\0${requested.output}`;
|
|
137
138
|
if (!incremental || session.previewExportKey !== exportKey || !(await exists(requested.output))) {
|
|
138
139
|
session.previewExportKey = null;
|
|
140
|
+
noteOfficeWrite(requested.output);
|
|
139
141
|
await exportPreview(session, requested.output);
|
|
140
142
|
if (incremental) session.previewExportKey = exportKey;
|
|
141
143
|
}
|
|
@@ -9,6 +9,7 @@ import { describeOfficeCapabilities } from '../capabilities.mjs';
|
|
|
9
9
|
import { applyBatch, closeSession, finalize, issues, qa, render, save, validate } from './office-actions.mjs';
|
|
10
10
|
import { getOfficeElement, queryOfficeDocument } from './office-actions-read.mjs';
|
|
11
11
|
import { snapshot } from './office-sessions.mjs';
|
|
12
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
12
13
|
import { noteBatchAgainstHtml } from '../authoring/html-source-drift.mjs';
|
|
13
14
|
import {
|
|
14
15
|
assertTransactionUnchanged,
|
|
@@ -59,7 +60,13 @@ async function batchAction(session, args, cwd, signal) {
|
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
// Verbs that never write the session's document.
|
|
64
|
+
const READ_ACTIONS = new Set(['describe', 'begin', 'diff', 'snapshot', 'get', 'query', 'issues', 'validate']);
|
|
65
|
+
|
|
62
66
|
export async function dispatchOfficeSessionAction({ action, session, args, cwd, signal }) {
|
|
67
|
+
// Write receipt: every other verb may write the session's document (an
|
|
68
|
+
// edit, save, rollback, autoFix, or a render that numbers its contents).
|
|
69
|
+
if (!READ_ACTIONS.has(action)) noteOfficeWrite(session.target);
|
|
63
70
|
if (action === 'describe') {
|
|
64
71
|
return describeOfficeCapabilities({
|
|
65
72
|
format: session.format,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
toolResult,
|
|
30
30
|
} from './office-core.mjs';
|
|
31
31
|
import { fullPath, selectMode } from './office-sessions.mjs';
|
|
32
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
32
33
|
import { pendingOfficeTransactions, recoverOfficeTransaction } from './office-transactions.mjs';
|
|
33
34
|
|
|
34
35
|
async function detectAction(args, cwd, dataDir) {
|
|
@@ -102,6 +103,13 @@ async function authorAction(args, cwd, dataDir, signal, startedAt) {
|
|
|
102
103
|
const extension = extname(String(args.path || args.output || '')).toLowerCase();
|
|
103
104
|
const author =
|
|
104
105
|
{ '.pdf': authorPdf, '.docx': authorHtmlDocument, '.xlsx': authorHtmlDocument }[extension] || authorPptx;
|
|
106
|
+
// Write receipts: the authored document and the sidecars kept beside it
|
|
107
|
+
// (its HTML source and print); per-page images report themselves.
|
|
108
|
+
for (const value of [args.path, args.output]) {
|
|
109
|
+
if (!String(value || '').trim()) continue;
|
|
110
|
+
const target = fullPath(String(value).trim(), cwd);
|
|
111
|
+
for (const path of [target, `${target}.mixdog-source.html`, `${target}.mixdog-html.pdf`]) noteOfficeWrite(path);
|
|
112
|
+
}
|
|
105
113
|
const authored = await author(args, { cwd, dataDir, signal });
|
|
106
114
|
const images = Array.isArray(authored?._images) ? authored._images : [];
|
|
107
115
|
delete authored._images;
|
|
@@ -4,6 +4,7 @@ import { basename, dirname, extname, isAbsolute, join, resolve } from 'node:path
|
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { assertOfficeOperationContracts } from '../capabilities.mjs';
|
|
7
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
7
8
|
import {
|
|
8
9
|
callMicrosoftOffice,
|
|
9
10
|
detectMicrosoftOffice,
|
|
@@ -258,6 +259,7 @@ async function packageSource(path, signal) {
|
|
|
258
259
|
`${path} is a legacy binary file and ${converted} already exists; open ${converted} directly, or move it aside to convert again.`
|
|
259
260
|
);
|
|
260
261
|
}
|
|
262
|
+
noteOfficeWrite(converted);
|
|
261
263
|
await convertLegacyOffice(path, converted, { signal });
|
|
262
264
|
return { source: converted, convertedFrom: path };
|
|
263
265
|
}
|
|
@@ -280,6 +282,7 @@ export async function openSession(args, cwd, dataDir, { readOnly = false } = {})
|
|
|
280
282
|
if (existing) return existing;
|
|
281
283
|
if (copies) {
|
|
282
284
|
await mkdir(dirname(target), { recursive: true });
|
|
285
|
+
noteOfficeWrite(target);
|
|
283
286
|
await copyFile(source, target);
|
|
284
287
|
}
|
|
285
288
|
const designContext = await resolveOfficeDesignContext({
|
|
@@ -533,6 +536,7 @@ export async function createSession(args, cwd, dataDir) {
|
|
|
533
536
|
// Whether this call brings the file into being decides what a failed create
|
|
534
537
|
// may clean up afterwards: a file it wrote itself, never one already there.
|
|
535
538
|
const targetExisted = await exists(target);
|
|
539
|
+
noteOfficeWrite(target);
|
|
536
540
|
const designContext = await resolveOfficeDesignContext({ args, dataDir, target, format, created: true });
|
|
537
541
|
const creation = { target, fileKind, format, dataDir, targetExisted, designContext };
|
|
538
542
|
await releaseOverwrittenSession(target, args.overwrite);
|
|
@@ -645,6 +649,7 @@ export async function materializeWorkingCopy(session) {
|
|
|
645
649
|
throw new Error('portable editing requires an output path different from the source');
|
|
646
650
|
}
|
|
647
651
|
await mkdir(dirname(target), { recursive: true });
|
|
652
|
+
noteOfficeWrite(target);
|
|
648
653
|
await copyFile(session.source, target);
|
|
649
654
|
if (documentSessions.get(documentSessionKey(session.target)) === session.id) {
|
|
650
655
|
documentSessions.delete(documentSessionKey(session.target));
|
|
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
|
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { callMicrosoftOffice, detectMicrosoftOffice, openMicrosoftOfficeSession } from '../com/com-adapter.mjs';
|
|
6
6
|
import { listOfficeJournals, readOfficeJournal, removeOfficeJournal, writeOfficeJournal } from './journal.mjs';
|
|
7
|
+
import { noteOfficeWrite } from './office-write-ledger.mjs';
|
|
7
8
|
import {
|
|
8
9
|
OfficeConflictError,
|
|
9
10
|
documentFingerprint,
|
|
@@ -299,6 +300,8 @@ export async function rollbackTransaction(session) {
|
|
|
299
300
|
transaction.diff = transactionDocumentDiff(transaction, current.document);
|
|
300
301
|
transaction.phase = 'rolling_back';
|
|
301
302
|
await persistOfficeTransaction(session);
|
|
303
|
+
// A recovered rollback restores the document outside any session verb.
|
|
304
|
+
noteOfficeWrite(session.target);
|
|
302
305
|
if (isMicrosoftOfficeSession(session)) {
|
|
303
306
|
const result = await callMicrosoftOffice(
|
|
304
307
|
{
|