mixdog 1.2.1 → 1.2.3
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 +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +6 -0
- 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 +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
- 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/client-config.mjs +36 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
- 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 +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
- 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 +75 -10
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -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 +80 -18
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
- package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
- 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 +246 -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 +388 -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/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 +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -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 +33 -1
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
- 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 +27 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -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 +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -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 +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
- 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 +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
- 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 +43 -15
- 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 +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- 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 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
- 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-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
- 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 +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -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 +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
- 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 +14 -3
- 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 +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- 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/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -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 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -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 +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
- 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 +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- 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 +77 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- 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/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/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- 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/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +65 -50
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
- 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 +2 -2
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- 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 +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- 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/office/shared/values.mjs +0 -5
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -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 +31 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- 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 +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -40
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- 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/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -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 +114 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -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-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +670 -274
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
- package/src/runtime/shared/turn-snapshot.mjs +986 -690
- package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -24
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- 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 +19 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +12 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +73 -8
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +46 -14
- package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
- package/src/session-runtime/mcp-glue.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +174 -0
- package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
- package/src/session-runtime/model-route/set-route.mjs +85 -17
- package/src/session-runtime/model-route/web-search-route.mjs +1 -1
- package/src/session-runtime/native-web-search/routes.mjs +22 -3
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- 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-models/model-meta.mjs +12 -3
- package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
- package/src/session-runtime/quick-web-search-models.mjs +13 -38
- package/src/session-runtime/resource-extension-sync.mjs +4 -0
- package/src/session-runtime/resource-mcp-api.mjs +98 -2
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +21 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
- 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.mjs +73 -7
- package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -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 +46 -7
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/agent-tool.mjs +3 -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 +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- 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 +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- 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 +51 -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 +2 -0
- package/src/standalone/daemon-telemetry.mjs +74 -0
- package/src/standalone/daemon.mjs +64 -8
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- 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 +1 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
- package/src/standalone/session-service/agent-tree.mjs +12 -0
- package/src/standalone/session-service/quota-resume.mjs +8 -0
- package/src/standalone/session-service/retention/busy.mjs +15 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +11 -1
- package/src/standalone/session-service.mjs +1 -0
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- 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 +1 -0
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +6 -0
- package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
- package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +11 -16
- 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 +20 -5
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -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/StatusLine.jsx +2 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/components/status-line/local-line.mjs +5 -2
- package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
- package/src/tui/dist/index.mjs +3221 -1500
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +43 -24
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/extensions.mjs +22 -0
- package/src/tui/session/session-api/integrations.mjs +16 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +7 -2
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +11 -14
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/session-flow/drain.mjs +7 -1
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +46 -16
- package/src/tui/statusline-ansi-bridge.mjs +1 -1
- package/src/ui/statusline-agents.mjs +15 -4
- package/src/ui/statusline.mjs +7 -3
- package/src/ui/streaming-markdown-heal.mjs +34 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
- package/src/workflows/default/WORKFLOW.md +3 -1
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -10,14 +10,14 @@ 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`. |
|
|
17
17
|
| `design/` | Design tokens, content model, composition, creative direction for the Word and Excel composers (`compose_document`, `compose_sheet`); `design-discipline.mjs` owns the safe typeface list, palette repair (tinted dark fields, WCAG contrast, paired accent tints), and the brief rules; `docx/`, `xlsx/` format compilers; `library/` template library with the bundled `templates/`. Decks are never composed here — a slide is authored by the model as a script (`authoring/`), and `compose_slide` is refused with that route. |
|
|
18
18
|
| `quality/` | Reviews and gates: `assurance-*.mjs` (trust, structure, rendered pages, checklist), aesthetics, design review, scoring, visual diff. |
|
|
19
19
|
| `bench/` | Benchmarks behind `npm run bench:office*`; `bench-support.mjs` holds the shared tool-call helpers. |
|
|
20
|
-
| `shared/` | Tiny helpers used across folders: `values.mjs` (`plainObject`, `clone`, `stableValue`, `sha256`, `clamp`, `compact
|
|
20
|
+
| `shared/` | Tiny helpers used across folders: `values.mjs` (`plainObject`, `clone`, `stableValue`, `sha256`, `clamp`, `compact`), `page-sizes.mjs` (the paper sizes PDF create and Word `set_page` share), `column-widths.mjs` (the widths a Word or PDF table given none takes from its text), and `asar-path.mjs`. |
|
|
21
21
|
|
|
22
22
|
## Dependency direction
|
|
23
23
|
|
|
@@ -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 },
|
|
@@ -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
|
|
|
@@ -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';
|
|
@@ -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
|
{
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* office-write-ledger.mjs — the workspace files one Office Use call wrote,
|
|
3
|
+
* with their exact before/after state, so the session's turn review counts
|
|
4
|
+
* them as its own changes and Undo can restore them.
|
|
5
|
+
*
|
|
6
|
+
* Ownership is never inferred from the folder: every route that writes a
|
|
7
|
+
* workspace file — the session's working copy, a created or converted
|
|
8
|
+
* document, a render's preview and page images, a split/extract/query output,
|
|
9
|
+
* an authored document and its sidecars, a secured PDF — hands the path to
|
|
10
|
+
* noteOfficeWrite BEFORE it writes, which captures the file's prior state.
|
|
11
|
+
* After the call, only noted files whose bytes changed are recorded. Scratch
|
|
12
|
+
* files outside the workspace (the system temp folder, the Office data
|
|
13
|
+
* folder) are never noted.
|
|
14
|
+
*/
|
|
15
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
16
|
+
import { statSync } from 'node:fs';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { isAbsolute, relative, resolve } from 'node:path';
|
|
19
|
+
import {
|
|
20
|
+
PATCH_EDIT_BUDGET_BYTES,
|
|
21
|
+
createSnapshotBudget,
|
|
22
|
+
reviewFileContent,
|
|
23
|
+
} from '../../shared/bounded-file-read.mjs';
|
|
24
|
+
|
|
25
|
+
const ledgers = new AsyncLocalStorage();
|
|
26
|
+
|
|
27
|
+
const pathKey = (path) => (process.platform === 'win32' ? path.toLowerCase() : path);
|
|
28
|
+
|
|
29
|
+
function inside(parent, child) {
|
|
30
|
+
if (!parent) return false;
|
|
31
|
+
const rel = relative(resolve(parent), child);
|
|
32
|
+
return !rel || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function fileStamp(path) {
|
|
36
|
+
try {
|
|
37
|
+
const info = statSync(path);
|
|
38
|
+
return info.isFile() ? { size: info.size, mtimeMs: info.mtimeMs } : null;
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Run one Office call with a ledger its write routes report into. */
|
|
45
|
+
export function runWithOfficeWriteLedger({ cwd, dataDir }, task) {
|
|
46
|
+
const ledger = {
|
|
47
|
+
cwd: resolve(cwd || process.cwd()),
|
|
48
|
+
dataDir: dataDir ? resolve(dataDir) : '',
|
|
49
|
+
budget: createSnapshotBudget(PATCH_EDIT_BUDGET_BYTES),
|
|
50
|
+
before: new Map(),
|
|
51
|
+
};
|
|
52
|
+
return { ledger, run: ledgers.run(ledger, task) };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** A write receipt: the call is about to write `path`. The first receipt of a
|
|
56
|
+
* path captures its state before the write; a call without a ledger (no
|
|
57
|
+
* session to credit) and scratch paths are ignored. */
|
|
58
|
+
export function noteOfficeWrite(path) {
|
|
59
|
+
const ledger = ledgers.getStore();
|
|
60
|
+
const text = typeof path === 'string' ? path.trim() : '';
|
|
61
|
+
if (!ledger || !text) return;
|
|
62
|
+
const fullPath = resolve(ledger.cwd, text);
|
|
63
|
+
const key = pathKey(fullPath);
|
|
64
|
+
if (ledger.before.has(key)) return;
|
|
65
|
+
if (inside(ledger.dataDir, fullPath)) return;
|
|
66
|
+
if (inside(tmpdir(), fullPath) && !inside(ledger.cwd, fullPath)) return;
|
|
67
|
+
let content;
|
|
68
|
+
try {
|
|
69
|
+
content = reviewFileContent(fullPath, { budget: ledger.budget });
|
|
70
|
+
} catch {
|
|
71
|
+
return; // not a regular file: never recorded
|
|
72
|
+
}
|
|
73
|
+
ledger.before.set(key, { fullPath, content, stamp: fileStamp(fullPath) });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const sameBytes = (left, right) => Buffer.isBuffer(left) && Buffer.isBuffer(right) && left.equals(right);
|
|
77
|
+
|
|
78
|
+
/** Every noted file the call created, changed or removed, as
|
|
79
|
+
* `{ fullPath, before, after }` (null = absent). */
|
|
80
|
+
export function officeWriteChanges(ledger) {
|
|
81
|
+
const changes = [];
|
|
82
|
+
for (const { fullPath, content: before, stamp: priorStamp } of ledger.before.values()) {
|
|
83
|
+
const stamp = fileStamp(fullPath);
|
|
84
|
+
if (!priorStamp && !stamp) continue;
|
|
85
|
+
// Uncaptured bytes compare by their stamp; captured ones byte for byte.
|
|
86
|
+
const untouched = priorStamp && stamp && priorStamp.size === stamp.size && priorStamp.mtimeMs === stamp.mtimeMs;
|
|
87
|
+
if (untouched && !Buffer.isBuffer(before)) continue;
|
|
88
|
+
let after = null;
|
|
89
|
+
try {
|
|
90
|
+
after = stamp ? reviewFileContent(fullPath) : null;
|
|
91
|
+
} catch {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (sameBytes(before, after)) continue;
|
|
95
|
+
changes.push({ fullPath, before, after });
|
|
96
|
+
}
|
|
97
|
+
return changes;
|
|
98
|
+
}
|
|
Binary file
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
toolResult,
|
|
15
15
|
} from './core/office-core.mjs';
|
|
16
16
|
import { resolveSession } from './core/office-sessions.mjs';
|
|
17
|
+
import { officeWriteChanges, runWithOfficeWriteLedger } from './core/office-write-ledger.mjs';
|
|
17
18
|
|
|
18
19
|
// Office work is minutes of real application time, and guessing which action carries it is how
|
|
19
20
|
// tuning goes wrong. MIXDOG_OFFICE_TRACE writes one line per call so a slow run maps itself; it
|
|
@@ -27,6 +28,35 @@ const OFFICE_TRACE = process.env.MIXDOG_OFFICE_TRACE || '';
|
|
|
27
28
|
const READ_ONLY_ACTIONS = new Set(['snapshot', 'get', 'query', 'issues', 'validate', 'describe', 'render', 'qa']);
|
|
28
29
|
|
|
29
30
|
export async function executeOfficeTool(args = {}, context = {}) {
|
|
31
|
+
const sessionId = String(context.sessionId || '');
|
|
32
|
+
if (!sessionId) return await tracedOfficeTool(args, context);
|
|
33
|
+
const cwd = context.cwd || process.cwd();
|
|
34
|
+
const { ledger, run } = runWithOfficeWriteLedger(
|
|
35
|
+
{ cwd, dataDir: context.dataDir || defaultOfficeDataDir() },
|
|
36
|
+
() => tracedOfficeTool(args, context)
|
|
37
|
+
);
|
|
38
|
+
try {
|
|
39
|
+
return await run;
|
|
40
|
+
} finally {
|
|
41
|
+
await recordOfficeWrites(ledger, sessionId, cwd);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// The files this call's write routes reported join the session's turn review
|
|
46
|
+
// as its own changes (counted, and undoable where their bytes were captured).
|
|
47
|
+
// The recorder is loaded on first use; recording never affects the result.
|
|
48
|
+
async function recordOfficeWrites(ledger, sessionId, cwd) {
|
|
49
|
+
try {
|
|
50
|
+
const changes = officeWriteChanges(ledger);
|
|
51
|
+
if (changes.length === 0) return;
|
|
52
|
+
const { recordToolFileChanges } = await import('../agent/orchestrator/tools/patch/ui-diff.mjs');
|
|
53
|
+
recordToolFileChanges({ sessionId, basePath: cwd, changes });
|
|
54
|
+
} catch {
|
|
55
|
+
/* best-effort review channel */
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function tracedOfficeTool(args, context) {
|
|
30
60
|
if (!OFFICE_TRACE) return await runOfficeTool(args, context);
|
|
31
61
|
const startedAt = performance.now();
|
|
32
62
|
try {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
7
7
|
import { dirname, resolve } from 'node:path';
|
|
8
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
8
9
|
import {
|
|
9
10
|
PDFDocument,
|
|
10
11
|
PDFArray,
|
|
@@ -130,6 +131,7 @@ export async function writeSibling(path, target, bytes) {
|
|
|
130
131
|
if (output.toLowerCase() === resolve(path).toLowerCase())
|
|
131
132
|
throw new Error('output must differ from the document being edited');
|
|
132
133
|
await mkdir(dirname(output), { recursive: true });
|
|
134
|
+
noteOfficeWrite(output);
|
|
133
135
|
await writeFile(output, bytes);
|
|
134
136
|
return output;
|
|
135
137
|
}
|
|
@@ -5,6 +5,7 @@ import { createCanvas, loadImage } from '@napi-rs/canvas';
|
|
|
5
5
|
import { pdfjsStandardFontDataUrl, resolvedPdfJs } from '../../attachments/pdfjs-runtime.mjs';
|
|
6
6
|
import { installPdfGlobals } from './pdf-document.mjs';
|
|
7
7
|
import { workerExecArgv } from '../../shared/worker-exec-argv.mjs';
|
|
8
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
8
9
|
|
|
9
10
|
const PAGE_NUMBER_PATTERN = /^\s*(?:(?:page\s*)?\d+\s*(?:of|\/)\s*\d+|페이지\s*\d+|\d+\s*페이지)\s*$/i;
|
|
10
11
|
|
|
@@ -144,8 +145,8 @@ async function runPdfRenderWorker(data, signal = null) {
|
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
// Many pages are reviewed as contact sheets: one labelled grid image per group
|
|
147
|
-
// of pages,
|
|
148
|
-
async function
|
|
148
|
+
// of pages, for a file next to the PDF.
|
|
149
|
+
async function contactSheet(group, width, imagePath, renderPage) {
|
|
149
150
|
const columns = group.length <= 2 ? 1 : Math.max(2, Math.ceil(Math.sqrt(group.length * 0.75)));
|
|
150
151
|
const rows = Math.ceil(group.length / columns);
|
|
151
152
|
const gap = 12;
|
|
@@ -182,7 +183,6 @@ async function writeContactSheet(group, width, imagePath, renderPage) {
|
|
|
182
183
|
context.strokeRect(x, y + labelHeight, image.width, image.height);
|
|
183
184
|
}
|
|
184
185
|
const data = sheet.toBuffer('image/png');
|
|
185
|
-
await writeFile(imagePath, data);
|
|
186
186
|
return {
|
|
187
187
|
page: group[0],
|
|
188
188
|
pages: group,
|
|
@@ -204,7 +204,18 @@ async function writeContactSheet(group, width, imagePath, renderPage) {
|
|
|
204
204
|
};
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
// The page images land beside the PDF, each reported as an Office write first.
|
|
208
|
+
async function writePageImages(images) {
|
|
209
|
+
for (const image of images) {
|
|
210
|
+
noteOfficeWrite(image.path);
|
|
211
|
+
await writeFile(image.path, Buffer.from(image.data, 'base64'));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function renderPdfPagesDirect(
|
|
216
|
+
path,
|
|
217
|
+
{ pages = null, maxWidth = 1400, maximumScale = 2, signal = null, writeImages = true } = {}
|
|
218
|
+
) {
|
|
208
219
|
if (signal?.aborted) throw new Error('PDF rendering was cancelled');
|
|
209
220
|
installPdfGlobals();
|
|
210
221
|
const { getDocument, VerbosityLevel } = await resolvedPdfJs();
|
|
@@ -248,7 +259,6 @@ async function renderPdfPagesDirect(path, { pages = null, maxWidth = 1400, maxim
|
|
|
248
259
|
for (const pageNumber of selected) {
|
|
249
260
|
const { canvas, data } = await renderPage(pageNumber, maxWidth);
|
|
250
261
|
const imagePath = join(dirname(path), `${stem}-page-${pageNumber}.png`);
|
|
251
|
-
await writeFile(imagePath, data);
|
|
252
262
|
output.push({
|
|
253
263
|
page: pageNumber,
|
|
254
264
|
path: imagePath,
|
|
@@ -264,9 +274,10 @@ async function renderPdfPagesDirect(path, { pages = null, maxWidth = 1400, maxim
|
|
|
264
274
|
for (let offset = 0; offset < selected.length; offset += pagesPerSheet) {
|
|
265
275
|
const group = selected.slice(offset, offset + pagesPerSheet);
|
|
266
276
|
const imagePath = join(dirname(path), `${stem}-pages-${group[0]}-${group.at(-1)}.png`);
|
|
267
|
-
output.push(await
|
|
277
|
+
output.push(await contactSheet(group, width, imagePath, renderPage));
|
|
268
278
|
}
|
|
269
279
|
}
|
|
280
|
+
if (writeImages) await writePageImages(output);
|
|
270
281
|
const reviewedPages = output.flatMap((image) => image.pages || [image.page]);
|
|
271
282
|
const reviewedPageSet = new Set(reviewedPages);
|
|
272
283
|
return {
|
|
@@ -293,7 +304,9 @@ export async function renderPdfPages(path, options = {}) {
|
|
|
293
304
|
const signal = options.signal || null;
|
|
294
305
|
if (signal?.aborted) throw new Error('PDF rendering was cancelled');
|
|
295
306
|
if (!isMainThread) return await renderPdfPagesDirect(path, options);
|
|
296
|
-
|
|
307
|
+
// The worker rasterizes; this thread writes the images, where the call's
|
|
308
|
+
// write ledger can see each one before it lands.
|
|
309
|
+
const rendered = await runPdfRenderWorker(
|
|
297
310
|
{
|
|
298
311
|
kind: PDF_RENDER_WORKER_KIND,
|
|
299
312
|
path,
|
|
@@ -301,10 +314,13 @@ export async function renderPdfPages(path, options = {}) {
|
|
|
301
314
|
pages: options.pages ?? null,
|
|
302
315
|
maxWidth: options.maxWidth ?? 1400,
|
|
303
316
|
maximumScale: options.maximumScale ?? 2,
|
|
317
|
+
writeImages: false,
|
|
304
318
|
},
|
|
305
319
|
},
|
|
306
320
|
signal
|
|
307
321
|
);
|
|
322
|
+
await writePageImages(rendered.images);
|
|
323
|
+
return rendered;
|
|
308
324
|
}
|
|
309
325
|
|
|
310
326
|
if (!isMainThread && [PDF_RENDER_WORKER_KIND, PDF_RENDER_PAGE_WORKER_KIND].includes(workerData?.kind)) {
|
|
@@ -2,6 +2,7 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { writeFile, rm, rename } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
5
6
|
|
|
6
7
|
// qpdf on PATH, or wherever MIXDOG_QPDF_PATH points (the Windows installer
|
|
7
8
|
// does not add itself to PATH).
|
|
@@ -89,6 +90,7 @@ export async function securePdf({ input, output, mode, password = '', ownerPassw
|
|
|
89
90
|
? ['--encrypt', password, ownerPassword || password, '256', '--', input, target]
|
|
90
91
|
: [`--password=${password}`, '--decrypt', input, target];
|
|
91
92
|
await writeFile(responsePath, `${args.join('\n')}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
93
|
+
noteOfficeWrite(output);
|
|
92
94
|
try {
|
|
93
95
|
await run(QPDF, [`@${responsePath}`]);
|
|
94
96
|
if (samePath) await rename(target, output);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { posix } from 'node:path';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
4
5
|
import { koreanParticleReplacements } from '../shared/korean-particles.mjs';
|
|
5
6
|
import { presetLabels } from '../shared/labels.mjs';
|
|
6
7
|
import {
|
|
@@ -137,7 +138,9 @@ export async function packageBuffer(zip) {
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
export async function savePackage(zip, path) {
|
|
140
|
-
|
|
141
|
+
const bytes = await packageBuffer(zip);
|
|
142
|
+
noteOfficeWrite(path);
|
|
143
|
+
await writeFile(path, bytes);
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
export function relationshipMap(xml) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, extname, basename, join } from 'node:path';
|
|
3
3
|
import { createCanvas, loadImage } from '@napi-rs/canvas';
|
|
4
|
+
import { noteOfficeWrite } from '../core/office-write-ledger.mjs';
|
|
4
5
|
|
|
5
6
|
function imageByPage(images) {
|
|
6
7
|
return new Map((images || []).map((image) => [Number(image.page), image]));
|
|
@@ -61,6 +62,7 @@ export async function compareRenderedPages(beforeImages, afterImages, outputPdf)
|
|
|
61
62
|
diffContext.putImageData(diff, 0, 0);
|
|
62
63
|
const data = diffCanvas.toBuffer('image/png');
|
|
63
64
|
const path = join(dirname(outputPdf), `${stem}-visual-diff-page-${page}.png`);
|
|
65
|
+
noteOfficeWrite(path);
|
|
64
66
|
await writeFile(path, data);
|
|
65
67
|
const total = width * height;
|
|
66
68
|
metrics.push({
|
|
@@ -32,8 +32,3 @@ export function compact(value, maximum = 120) {
|
|
|
32
32
|
.replace(/\s+/g, ' ')
|
|
33
33
|
.slice(0, maximum);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
export function imageBuffer(image) {
|
|
37
|
-
if (Buffer.isBuffer(image?.data)) return image.data;
|
|
38
|
-
return Buffer.from(String(image?.data || ''), 'base64');
|
|
39
|
-
}
|