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,599 @@
|
|
|
1
|
+
// Live ping-pong across providers.
|
|
2
|
+
// Basic suite (default): three turns - a forced read, a no-tool replay of that history,
|
|
3
|
+
// and two parallel reads.
|
|
4
|
+
// Extended suite (`--suite extended`): after those, tool error, file write, shell, a
|
|
5
|
+
// 3-step tool chain, image input, mid-stream cancel + follow-up. Per-turn usage is
|
|
6
|
+
// captured to report prompt-cache reads on turns 2+.
|
|
7
|
+
//
|
|
8
|
+
// Isolation (default): the runs use a fresh temp MIXDOG_HOME/MIXDOG_DATA_DIR, never the
|
|
9
|
+
// installed app's ~/.mixdog data, so no session, catalog or worker rows reach the real
|
|
10
|
+
// stores. Only the API-key secrets (`secrets/agent.<provider>.apiKey.dpapi`) and the
|
|
11
|
+
// `agent` section of mixdog-config.json are copied in. OAuth providers (`*-oauth`, whose
|
|
12
|
+
// refresh tokens could be rotated) are skipped unless `--real-data` is passed, which
|
|
13
|
+
// restores the old behaviour of running against the real data dir. The isolated dir is
|
|
14
|
+
// deleted at the end, after stopping only processes whose executable lives inside it.
|
|
15
|
+
// Usage: node scripts/provider-pingpong-live.mjs [--suite extended] [--real-data] [case-name ...]
|
|
16
|
+
import fs from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import zlib from 'node:zlib';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
22
|
+
|
|
23
|
+
const self = fileURLToPath(import.meta.url);
|
|
24
|
+
const TURN_TIMEOUT_MS = 150_000;
|
|
25
|
+
|
|
26
|
+
const textOf = (response) => {
|
|
27
|
+
const content = response?.result?.content ?? response?.text ?? '';
|
|
28
|
+
if (Array.isArray(content)) return content.map((p) => (typeof p === 'string' ? p : p?.text || '')).join('');
|
|
29
|
+
return String(content);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Solid-colour PNG (8-bit RGB) built from scratch so no image dependency is needed.
|
|
33
|
+
function solidPng(width, height, [r, g, b]) {
|
|
34
|
+
const crcTable = Array.from({ length: 256 }, (_, n) => {
|
|
35
|
+
let c = n;
|
|
36
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
37
|
+
return c >>> 0;
|
|
38
|
+
});
|
|
39
|
+
const crc32 = (buf) => {
|
|
40
|
+
let c = 0xffffffff;
|
|
41
|
+
for (const byte of buf) c = crcTable[(c ^ byte) & 0xff] ^ (c >>> 8);
|
|
42
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
43
|
+
};
|
|
44
|
+
const chunk = (type, data) => {
|
|
45
|
+
const body = Buffer.concat([Buffer.from(type, 'ascii'), data]);
|
|
46
|
+
const out = Buffer.alloc(body.length + 8);
|
|
47
|
+
out.writeUInt32BE(data.length, 0);
|
|
48
|
+
body.copy(out, 4);
|
|
49
|
+
out.writeUInt32BE(crc32(body), body.length + 4);
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
52
|
+
const ihdr = Buffer.alloc(13);
|
|
53
|
+
ihdr.writeUInt32BE(width, 0);
|
|
54
|
+
ihdr.writeUInt32BE(height, 4);
|
|
55
|
+
ihdr[8] = 8; // bit depth
|
|
56
|
+
ihdr[9] = 2; // RGB
|
|
57
|
+
const row = Buffer.concat([Buffer.from([0]), Buffer.from(Array.from({ length: width }, () => [r, g, b]).flat())]);
|
|
58
|
+
const raw = Buffer.concat(Array.from({ length: height }, () => row));
|
|
59
|
+
return Buffer.concat([
|
|
60
|
+
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
61
|
+
chunk('IHDR', ihdr),
|
|
62
|
+
chunk('IDAT', zlib.deflateSync(raw)),
|
|
63
|
+
chunk('IEND', Buffer.alloc(0)),
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const withTimeout = (promise, ms, onTimeout) =>
|
|
68
|
+
new Promise((resolve, reject) => {
|
|
69
|
+
const timer = setTimeout(() => {
|
|
70
|
+
onTimeout?.();
|
|
71
|
+
reject(new Error(`timeout after ${ms}ms`));
|
|
72
|
+
}, ms);
|
|
73
|
+
promise.then(
|
|
74
|
+
(v) => {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
resolve(v);
|
|
77
|
+
},
|
|
78
|
+
(e) => {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
reject(e);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Failures caused by the account (limits, billing, entitlement) rather than the provider code.
|
|
86
|
+
const ACCOUNT_RE =
|
|
87
|
+
/quota|billing|\b(?:402|403|429)\b|rate.?limit|usage limit|insufficient|payment|credit|too many requests|exhaust|subscription|plan limit|not entitled|resource_exhausted/i;
|
|
88
|
+
|
|
89
|
+
if (process.argv[2] === '--child') {
|
|
90
|
+
const spec = JSON.parse(process.argv[3]);
|
|
91
|
+
const extended = spec.suite === 'extended';
|
|
92
|
+
const { resolvePluginData } = await import('../src/runtime/shared/plugin-paths.mjs');
|
|
93
|
+
if (spec.dataDir && path.resolve(resolvePluginData()) !== path.resolve(spec.dataDir)) {
|
|
94
|
+
console.log(
|
|
95
|
+
`RESULT ${JSON.stringify({ name: spec.name, error: `refusing to run: data dir ${resolvePluginData()} is not the isolated ${spec.dataDir}` })}`
|
|
96
|
+
);
|
|
97
|
+
process.exit(0);
|
|
98
|
+
}
|
|
99
|
+
const { createMixdogSessionRuntime } = await import('../src/session-runtime/runtime-core.mjs');
|
|
100
|
+
const { materializePromptSubmission } = await import('../src/runtime/attachments/store.mjs');
|
|
101
|
+
const { getModelMetadataSync } = await import('../src/runtime/shared/llm/model-catalog.mjs');
|
|
102
|
+
let runtime;
|
|
103
|
+
const out = {
|
|
104
|
+
name: spec.name,
|
|
105
|
+
provider: spec.provider,
|
|
106
|
+
model: spec.model,
|
|
107
|
+
effort: spec.effort,
|
|
108
|
+
turns: {},
|
|
109
|
+
order: [],
|
|
110
|
+
};
|
|
111
|
+
const readDisk = (file) => {
|
|
112
|
+
try {
|
|
113
|
+
return fs.readFileSync(path.join(spec.cwd, file), 'utf8');
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Runs one ask() and records calls/text/usage under `key`. Errors are recorded, not thrown,
|
|
120
|
+
// so later scenarios still run; an ACCOUNT error stops the case (everything after would fail alike).
|
|
121
|
+
const turn = async (key, prompt, options = {}) => {
|
|
122
|
+
const rec = {
|
|
123
|
+
calls: [],
|
|
124
|
+
text: '',
|
|
125
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
|
|
126
|
+
models: [],
|
|
127
|
+
};
|
|
128
|
+
out.turns[key] = rec;
|
|
129
|
+
out.order.push(key);
|
|
130
|
+
const startedAt = Date.now();
|
|
131
|
+
try {
|
|
132
|
+
const response = await withTimeout(
|
|
133
|
+
runtime.ask(prompt, {
|
|
134
|
+
...options,
|
|
135
|
+
onAssistantToolCallObserved: (call) => rec.calls.push(call.name || call.tool),
|
|
136
|
+
onUsageDelta: (d) => {
|
|
137
|
+
rec.usage.events++;
|
|
138
|
+
rec.usage.input += d.deltaInput || 0;
|
|
139
|
+
rec.usage.output += d.deltaOutput || 0;
|
|
140
|
+
rec.usage.cacheRead += d.deltaCachedRead || 0;
|
|
141
|
+
rec.usage.cacheWrite += d.deltaCacheWrite || 0;
|
|
142
|
+
if (d.model && !rec.models.includes(d.model)) rec.models.push(d.model);
|
|
143
|
+
},
|
|
144
|
+
}),
|
|
145
|
+
TURN_TIMEOUT_MS,
|
|
146
|
+
() => runtime.abort('pingpong-timeout')
|
|
147
|
+
);
|
|
148
|
+
rec.text = textOf(response).trim().slice(0, 300);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
rec.error = String(error?.message || error).slice(0, 400);
|
|
151
|
+
if (ACCOUNT_RE.test(rec.error)) out.stopped = 'account';
|
|
152
|
+
}
|
|
153
|
+
rec.ms = Date.now() - startedAt;
|
|
154
|
+
return rec;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
runtime = await createMixdogSessionRuntime({
|
|
159
|
+
provider: spec.provider,
|
|
160
|
+
model: spec.model,
|
|
161
|
+
...(spec.effort ? { effort: spec.effort } : {}),
|
|
162
|
+
cwd: spec.cwd,
|
|
163
|
+
toolMode: 'full',
|
|
164
|
+
autoWakeCompletions: false,
|
|
165
|
+
});
|
|
166
|
+
const steps = [
|
|
167
|
+
['t1', 'Use the read tool on package.json, then reply with only the value of "name".'],
|
|
168
|
+
['t2', 'Without using tools, reply with only that same name in uppercase.'],
|
|
169
|
+
[
|
|
170
|
+
't3',
|
|
171
|
+
'Read a.txt and b.txt with two read calls issued together in one step, then reply with only their two contents joined by "+".',
|
|
172
|
+
],
|
|
173
|
+
];
|
|
174
|
+
for (const [key, prompt] of steps) {
|
|
175
|
+
await turn(key, prompt);
|
|
176
|
+
if (out.stopped) break;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (extended && !out.stopped) {
|
|
180
|
+
await turn(
|
|
181
|
+
'er',
|
|
182
|
+
'Use the read tool on does-not-exist.txt. Whatever happens, then tell me in one short sentence whether that file exists.'
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
if (extended && !out.stopped) {
|
|
186
|
+
const rec = await turn(
|
|
187
|
+
'wr',
|
|
188
|
+
'Using the file edit/write tool (not the shell), create a new file c.txt in the working directory containing exactly the text gamma. Reply "done" when finished.'
|
|
189
|
+
);
|
|
190
|
+
rec.disk = readDisk('c.txt');
|
|
191
|
+
}
|
|
192
|
+
if (extended && !out.stopped) {
|
|
193
|
+
await turn('sh', 'Use the shell tool to run exactly: node -e "console.log(6*7)" and reply with only its output.');
|
|
194
|
+
}
|
|
195
|
+
if (extended && !out.stopped) {
|
|
196
|
+
const rec = await turn(
|
|
197
|
+
'ml',
|
|
198
|
+
'Do these in order, each as its own tool call, one after another: (1) read a.txt, (2) create a new file d.txt using the file edit/write tool containing the contents of a.txt with its characters reversed and no trailing newline, (3) read d.txt. Then reply with only the text in d.txt.'
|
|
199
|
+
);
|
|
200
|
+
rec.disk = readDisk('d.txt');
|
|
201
|
+
}
|
|
202
|
+
if (extended && !out.stopped) {
|
|
203
|
+
const vision = getModelMetadataSync(spec.model, spec.provider)?.supportsVision;
|
|
204
|
+
if (vision === false) {
|
|
205
|
+
out.turns.im = { skipped: 'catalog says no vision', calls: [], text: '' };
|
|
206
|
+
out.order.push('im');
|
|
207
|
+
} else {
|
|
208
|
+
const png = solidPng(64, 64, [255, 0, 0]).toString('base64');
|
|
209
|
+
// Same intake the session service applies before runtime.ask: inline image
|
|
210
|
+
// parts become content-addressed attachment references.
|
|
211
|
+
const intake = materializePromptSubmission([
|
|
212
|
+
{ type: 'text', text: 'What single colour fills this image? Reply with only the colour name in English.' },
|
|
213
|
+
{ type: 'image', data: png, mimeType: 'image/png' },
|
|
214
|
+
]);
|
|
215
|
+
const rec = await turn('im', intake.prompt, intake.options);
|
|
216
|
+
rec.visionFlag = vision === undefined ? 'unknown' : 'true';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (extended && !out.stopped) {
|
|
220
|
+
// Real cancel path: runtime.abort() -> abortRuntime -> turn controller + mgr.abortSessionTurn.
|
|
221
|
+
const rec = {
|
|
222
|
+
calls: [],
|
|
223
|
+
text: '',
|
|
224
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
|
|
225
|
+
models: [],
|
|
226
|
+
};
|
|
227
|
+
out.turns.ca = rec;
|
|
228
|
+
out.order.push('ca');
|
|
229
|
+
let deltas = 0;
|
|
230
|
+
let abortResult;
|
|
231
|
+
let aborted = false;
|
|
232
|
+
const doAbort = () => {
|
|
233
|
+
if (aborted) return;
|
|
234
|
+
aborted = true;
|
|
235
|
+
abortResult = runtime.abort('user-cancel');
|
|
236
|
+
};
|
|
237
|
+
const fallback = setTimeout(doAbort, 30_000);
|
|
238
|
+
const onDelta = () => {
|
|
239
|
+
if (++deltas >= 5) doAbort();
|
|
240
|
+
};
|
|
241
|
+
const startedAt = Date.now();
|
|
242
|
+
const pending = runtime
|
|
243
|
+
.ask(
|
|
244
|
+
'Write a very long numbered list from 1 to 300, one item per line, each item a full sentence about a different animal. Do not use tools.',
|
|
245
|
+
{
|
|
246
|
+
onTextDelta: onDelta,
|
|
247
|
+
onUsageDelta: (d) => {
|
|
248
|
+
rec.usage.events++;
|
|
249
|
+
rec.usage.input += d.deltaInput || 0;
|
|
250
|
+
rec.usage.output += d.deltaOutput || 0;
|
|
251
|
+
rec.usage.cacheRead += d.deltaCachedRead || 0;
|
|
252
|
+
rec.usage.cacheWrite += d.deltaCacheWrite || 0;
|
|
253
|
+
},
|
|
254
|
+
}
|
|
255
|
+
)
|
|
256
|
+
.then(
|
|
257
|
+
(r) => ({ ok: true, text: textOf(r).trim() }),
|
|
258
|
+
(e) => ({ ok: false, error: String(e?.message || e) })
|
|
259
|
+
);
|
|
260
|
+
const settled = await Promise.race([pending, new Promise((r) => setTimeout(() => r({ hang: true }), 120_000))]);
|
|
261
|
+
clearTimeout(fallback);
|
|
262
|
+
rec.ms = Date.now() - startedAt;
|
|
263
|
+
rec.deltas = deltas;
|
|
264
|
+
rec.abortResult = abortResult;
|
|
265
|
+
rec.abortedAfterMs = rec.ms;
|
|
266
|
+
if (settled.hang) rec.settle = 'hang';
|
|
267
|
+
else rec.settle = settled.ok ? 'resolved' : 'rejected';
|
|
268
|
+
rec.text = String(settled.text || '').slice(0, 120);
|
|
269
|
+
rec.error = settled.error ? settled.error.slice(0, 300) : undefined;
|
|
270
|
+
rec.chars = String(settled.text || '').length;
|
|
271
|
+
if (settled.hang) out.stopped = 'hang';
|
|
272
|
+
else if (rec.error && ACCOUNT_RE.test(rec.error) && !aborted) out.stopped = 'account';
|
|
273
|
+
if (!out.stopped) await turn('fu', 'Reply with only the word READY.');
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
out.error = String(error?.message || error).slice(0, 400);
|
|
277
|
+
} finally {
|
|
278
|
+
await runtime?.close('provider-pingpong-live').catch(() => {});
|
|
279
|
+
}
|
|
280
|
+
console.log(`RESULT ${JSON.stringify(out)}`);
|
|
281
|
+
process.exit(0);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// [name, provider, model, effort]; each route runs at a low and a high reasoning setting.
|
|
285
|
+
const routes = [
|
|
286
|
+
['openrouter-claude', 'openrouter', 'anthropic/claude-haiku-5.5', ['low', 'max']],
|
|
287
|
+
['openrouter-gpt', 'openrouter', 'openai/gpt-6-luna', ['none', 'xhigh']],
|
|
288
|
+
['openrouter-gemini', 'openrouter', 'google/gemini-3.5-flash-lite', ['minimal', 'high']],
|
|
289
|
+
['openrouter-deepseek', 'openrouter', 'deepseek/deepseek-v4.1-flash', ['low', 'max']],
|
|
290
|
+
['deepseek', 'deepseek', 'deepseek-flash', ['low', 'max']],
|
|
291
|
+
['deepseek-pro', 'deepseek', 'deepseek-v4-pro', ['high']],
|
|
292
|
+
['opencode-go-gemini', 'opencode-go', 'gemini-4-argon-contributor', ['low', 'high']],
|
|
293
|
+
['opencode-go-deepseek', 'opencode-go', 'deepseek-v4.1-flash', ['low', 'max']],
|
|
294
|
+
['opencode-go-claude', 'opencode-go', 'claude-haiku-5-5', ['low', 'max']],
|
|
295
|
+
['opencode-go-gpt', 'opencode-go', 'gpt-6-luna', ['none', 'xhigh']],
|
|
296
|
+
['opencode-go-glm', 'opencode-go', 'glm-5.3-flash', ['low', 'max']],
|
|
297
|
+
['opencode-go-qwen', 'opencode-go', 'qwen3.8-flash', ['low', 'xhigh']],
|
|
298
|
+
['opencode-go-kimi', 'opencode-go', 'kimi-k3', ['max']],
|
|
299
|
+
['opencode-go-minimax', 'opencode-go', 'minimax-m3', [null]],
|
|
300
|
+
['opencode-go-grok', 'opencode-go', 'grok-4.7', ['low']],
|
|
301
|
+
['anthropic-api', 'anthropic', 'claude-haiku-5-5', ['low', 'max']],
|
|
302
|
+
['gemini-api', 'gemini', 'gemini-3.5-flash-lite', ['minimal', 'high']],
|
|
303
|
+
['grok-oauth', 'grok-oauth', 'grok-4.7', ['low', 'xhigh']],
|
|
304
|
+
['openai-oauth', 'openai-oauth', 'gpt-6-luna', ['none', 'xhigh']],
|
|
305
|
+
['anthropic-oauth', 'anthropic-oauth', 'claude-haiku-5-5', ['low', 'max']],
|
|
306
|
+
['antigravity-oauth', 'antigravity-oauth', 'gemini-3.8-flash', ['low', 'high']],
|
|
307
|
+
['cursor-auto', 'cursor-oauth', 'auto', [null]],
|
|
308
|
+
['cursor-composer', 'cursor-oauth', 'composer-2.5', [null]],
|
|
309
|
+
['cursor-claude', 'cursor-oauth', 'claude-opus-5-5', [null]],
|
|
310
|
+
['cursor-grok', 'cursor-oauth', 'grok-4.7', [null]],
|
|
311
|
+
];
|
|
312
|
+
const cases = routes.flatMap(([name, provider, model, efforts]) =>
|
|
313
|
+
efforts.map((effort) => [`${name}${effort ? `@${effort}` : ''}`, provider, model, effort])
|
|
314
|
+
);
|
|
315
|
+
const args = process.argv.slice(2);
|
|
316
|
+
const suiteAt = args.findIndex((a) => a === '--suite' || a.startsWith('--suite='));
|
|
317
|
+
let suite = 'basic';
|
|
318
|
+
if (suiteAt >= 0) suite = args[suiteAt].includes('=') ? args[suiteAt].split('=')[1] : args[suiteAt + 1];
|
|
319
|
+
const extended = suite === 'extended';
|
|
320
|
+
const realData = args.includes('--real-data');
|
|
321
|
+
const only = args.filter(
|
|
322
|
+
(a, i) =>
|
|
323
|
+
a !== '--real-data' &&
|
|
324
|
+
!a.startsWith('--suite') &&
|
|
325
|
+
!(suiteAt >= 0 && i === suiteAt + 1 && args[suiteAt] === '--suite')
|
|
326
|
+
);
|
|
327
|
+
const chosen = only.length ? cases.filter(([name]) => only.includes(name)) : cases;
|
|
328
|
+
// Refresh-capable OAuth logins are never exercised from an isolated copy.
|
|
329
|
+
const isOauth = ([, provider]) => /-oauth$/.test(provider);
|
|
330
|
+
const selected = realData ? chosen : chosen.filter((c) => !isOauth(c));
|
|
331
|
+
for (const c of chosen)
|
|
332
|
+
if (!selected.includes(c))
|
|
333
|
+
console.log(`SKIP ${c[0]} (OAuth provider; pass --real-data to run against the real data dir)`);
|
|
334
|
+
if (!selected.length) {
|
|
335
|
+
console.log('nothing to run');
|
|
336
|
+
process.exit(0);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Isolated MIXDOG_HOME for the child runtimes: a fresh temp dir holding only the API-key
|
|
340
|
+
// secrets of the selected providers and the `agent` section of the real config.
|
|
341
|
+
let isolated = null;
|
|
342
|
+
if (!realData) {
|
|
343
|
+
const realDataDir =
|
|
344
|
+
process.env.MIXDOG_DATA_DIR || path.join(process.env.MIXDOG_HOME || path.join(os.homedir(), '.mixdog'), 'data');
|
|
345
|
+
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-pp-home-'));
|
|
346
|
+
const dataDir = path.join(home, 'data');
|
|
347
|
+
fs.mkdirSync(path.join(dataDir, 'secrets'), { recursive: true });
|
|
348
|
+
const config = JSON.parse(fs.readFileSync(path.join(realDataDir, 'mixdog-config.json'), 'utf8'));
|
|
349
|
+
fs.writeFileSync(path.join(dataDir, 'mixdog-config.json'), JSON.stringify({ agent: config.agent ?? {} }, null, 2));
|
|
350
|
+
for (const provider of new Set(selected.map(([, p]) => p))) {
|
|
351
|
+
const secret = `agent.${provider}.apiKey.dpapi`;
|
|
352
|
+
const from = path.join(realDataDir, 'secrets', secret);
|
|
353
|
+
if (fs.existsSync(from)) fs.copyFileSync(from, path.join(dataDir, 'secrets', secret));
|
|
354
|
+
else console.log(`WARN no ${secret} in the real data dir; ${provider} cases will fail to authenticate`);
|
|
355
|
+
}
|
|
356
|
+
isolated = {
|
|
357
|
+
home,
|
|
358
|
+
dataDir,
|
|
359
|
+
env: { MIXDOG_HOME: home, MIXDOG_DATA_DIR: dataDir, MIXDOG_RUNTIME_ROOT: path.join(home, 'runtime-root') },
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Stops only processes whose executable path is inside `root` (e.g. the isolated memory
|
|
364
|
+
// postgres), then removes the dir. Windows-only lookup, like the DPAPI secrets.
|
|
365
|
+
const removeIsolated = () => {
|
|
366
|
+
if (!isolated) return;
|
|
367
|
+
const { home } = isolated;
|
|
368
|
+
isolated = null;
|
|
369
|
+
if (process.platform === 'win32') {
|
|
370
|
+
const root = home.replace(/'/g, "''");
|
|
371
|
+
spawnSync(
|
|
372
|
+
'powershell.exe',
|
|
373
|
+
[
|
|
374
|
+
'-NoProfile',
|
|
375
|
+
'-Command',
|
|
376
|
+
`$root='${root}\\'; Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($root, [StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`,
|
|
377
|
+
],
|
|
378
|
+
{ stdio: 'ignore' }
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
fs.rmSync(home, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// One fixture dir per case: concurrent children write c.txt/d.txt and must not collide.
|
|
385
|
+
const tempDirs = new Set();
|
|
386
|
+
const removeTemp = () => {
|
|
387
|
+
for (const dir of tempDirs) fs.rmSync(dir, { recursive: true, force: true });
|
|
388
|
+
tempDirs.clear();
|
|
389
|
+
removeIsolated();
|
|
390
|
+
};
|
|
391
|
+
process.on('exit', removeTemp);
|
|
392
|
+
const makeCwd = (name) => {
|
|
393
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), `mixdog-pingpong-${name.replace(/[^a-z0-9]+/gi, '-')}-`));
|
|
394
|
+
tempDirs.add(cwd);
|
|
395
|
+
fs.writeFileSync(
|
|
396
|
+
path.join(cwd, 'package.json'),
|
|
397
|
+
JSON.stringify({ name: 'pingpong-probe', version: '1.0.0' }, null, 2)
|
|
398
|
+
);
|
|
399
|
+
fs.writeFileSync(path.join(cwd, 'a.txt'), 'alpha\n');
|
|
400
|
+
fs.writeFileSync(path.join(cwd, 'b.txt'), 'beta\n');
|
|
401
|
+
return cwd;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
const runOne = ([name, provider, model, effort]) =>
|
|
405
|
+
new Promise((resolve) => {
|
|
406
|
+
const cwd = makeCwd(name);
|
|
407
|
+
const child = spawn(
|
|
408
|
+
process.execPath,
|
|
409
|
+
[
|
|
410
|
+
self,
|
|
411
|
+
'--child',
|
|
412
|
+
JSON.stringify({
|
|
413
|
+
name,
|
|
414
|
+
provider,
|
|
415
|
+
model,
|
|
416
|
+
effort,
|
|
417
|
+
cwd,
|
|
418
|
+
dataDir: isolated?.dataDir,
|
|
419
|
+
suite: extended ? 'extended' : 'basic',
|
|
420
|
+
}),
|
|
421
|
+
],
|
|
422
|
+
{ stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, ...isolated?.env } }
|
|
423
|
+
);
|
|
424
|
+
let stdout = '';
|
|
425
|
+
let stderr = '';
|
|
426
|
+
child.stdout.on('data', (d) => (stdout += d));
|
|
427
|
+
child.stderr.on('data', (d) => (stderr += d));
|
|
428
|
+
const timer = setTimeout(() => child.kill(), extended ? 900_000 : 240_000);
|
|
429
|
+
child.on('close', () => {
|
|
430
|
+
clearTimeout(timer);
|
|
431
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
432
|
+
tempDirs.delete(cwd);
|
|
433
|
+
const line = stdout.split('\n').find((l) => l.startsWith('RESULT '));
|
|
434
|
+
resolve(
|
|
435
|
+
line ? JSON.parse(line.slice(7)) : { name, provider, model, effort, error: `no result: ${stderr.slice(-300)}` }
|
|
436
|
+
);
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
// Bounded concurrency keeps per-provider rate limits from masking real failures.
|
|
441
|
+
const results = [];
|
|
442
|
+
const queue = [...selected];
|
|
443
|
+
await Promise.all(
|
|
444
|
+
Array.from({ length: 8 }, async () => {
|
|
445
|
+
while (queue.length) results.push(await runOne(queue.shift()));
|
|
446
|
+
})
|
|
447
|
+
);
|
|
448
|
+
results.sort((a, b) => a.name.localeCompare(b.name));
|
|
449
|
+
|
|
450
|
+
const has = (t, re) => re.test(t?.text || '');
|
|
451
|
+
const called = (t, name) => (t?.calls || []).includes(name);
|
|
452
|
+
const wroteVia = (t) => (t?.calls || []).some((c) => /edit|write|patch/i.test(c));
|
|
453
|
+
// [key, label, check(turn, result)] ; check returns true/false.
|
|
454
|
+
const scenarios = [
|
|
455
|
+
['t1', 't1', (t) => called(t, 'read') && has(t, /pingpong-probe/i)],
|
|
456
|
+
['t2', 't2', (t) => has(t, /PINGPONG-PROBE/)],
|
|
457
|
+
['t3', 't3', (t) => (t.calls || []).filter((c) => c === 'read').length >= 1 && has(t, /alpha/i) && has(t, /beta/i)],
|
|
458
|
+
// The reply language follows the user's profile (may be Korean), so the wording check is bilingual.
|
|
459
|
+
[
|
|
460
|
+
'er',
|
|
461
|
+
'err',
|
|
462
|
+
(t) =>
|
|
463
|
+
called(t, 'read') &&
|
|
464
|
+
has(
|
|
465
|
+
t,
|
|
466
|
+
/missing|not exist|doesn.?t exist|does not|no such|not found|nonexistent|isn.?t|cannot|can.?t|존재하지|없|찾을 수|않/i
|
|
467
|
+
),
|
|
468
|
+
],
|
|
469
|
+
['wr', 'wr', (t) => wroteVia(t) && String(t.disk ?? '').trim() === 'gamma'],
|
|
470
|
+
['sh', 'sh', (t) => called(t, 'shell') && has(t, /42/)],
|
|
471
|
+
[
|
|
472
|
+
'ml',
|
|
473
|
+
'ml',
|
|
474
|
+
(t) => {
|
|
475
|
+
const c = t.calls || [];
|
|
476
|
+
const firstRead = c.indexOf('read');
|
|
477
|
+
const write = c.findIndex((n, i) => i > firstRead && /edit|write|patch/i.test(n));
|
|
478
|
+
const lastRead = c.lastIndexOf('read');
|
|
479
|
+
return (
|
|
480
|
+
firstRead >= 0 &&
|
|
481
|
+
write > firstRead &&
|
|
482
|
+
lastRead > write &&
|
|
483
|
+
String(t.disk ?? '').trim() === 'ahpla' &&
|
|
484
|
+
has(t, /ahpla/)
|
|
485
|
+
);
|
|
486
|
+
},
|
|
487
|
+
],
|
|
488
|
+
['im', 'img', (t) => has(t, /red/i)],
|
|
489
|
+
['ca', 'can', (t) => t.settle && t.settle !== 'hang' && t.abortResult === true],
|
|
490
|
+
['fu', 'fu', (t) => has(t, /READY/i)],
|
|
491
|
+
];
|
|
492
|
+
|
|
493
|
+
const short = (s, n = 60) =>
|
|
494
|
+
String(s || '')
|
|
495
|
+
.replace(/\s+/g, ' ')
|
|
496
|
+
.slice(0, n);
|
|
497
|
+
const evidence = (key, t) => {
|
|
498
|
+
if (!t) return 'no turn';
|
|
499
|
+
if (t.error && key !== 'ca') return `error: ${short(t.error, 90)}`;
|
|
500
|
+
const base = `[${(t.calls || []).join(',')}] "${short(t.text)}"`;
|
|
501
|
+
if (key === 'wr' || key === 'ml') return `${base} disk=${JSON.stringify(short(t.disk ?? null, 20))}`;
|
|
502
|
+
if (key === 'ca')
|
|
503
|
+
return `abort=${t.abortResult} settle=${t.settle} deltas=${t.deltas} chars=${t.chars} ${t.error ? `err="${short(t.error, 70)}"` : ''}`;
|
|
504
|
+
return base;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const details = [];
|
|
508
|
+
for (const r of results) {
|
|
509
|
+
const marks = [];
|
|
510
|
+
const evid = [];
|
|
511
|
+
let anyFail = false;
|
|
512
|
+
let anyAccount = false;
|
|
513
|
+
for (const [key, label, check] of scenarios) {
|
|
514
|
+
if (!extended && !['t1', 't2', 't3'].includes(key)) continue;
|
|
515
|
+
const t = r.turns?.[key];
|
|
516
|
+
// A cancelled turn is expected to reject, so only 'ca' tolerates an error.
|
|
517
|
+
const ok = t && (key === 'ca' || !t.error) && check(t, r);
|
|
518
|
+
const accountish = t
|
|
519
|
+
? ACCOUNT_RE.test(t.error || t.text || '')
|
|
520
|
+
: r.stopped === 'account' || ACCOUNT_RE.test(r.error || '');
|
|
521
|
+
let mark;
|
|
522
|
+
if (t?.skipped) mark = '-';
|
|
523
|
+
else if (ok) mark = '✓';
|
|
524
|
+
else if (accountish) mark = 'A';
|
|
525
|
+
// The catalog is silent on vision for this model: a wrong answer may just be a text-only
|
|
526
|
+
// model, so it is flagged for manual review instead of counted as a failure.
|
|
527
|
+
else if (key === 'im' && t?.visionFlag === 'unknown') mark = '?';
|
|
528
|
+
else mark = '✗';
|
|
529
|
+
marks.push(`${label}${mark}`);
|
|
530
|
+
if (mark === '✗') anyFail = true;
|
|
531
|
+
if (mark === 'A') anyAccount = true;
|
|
532
|
+
if (mark !== '✓' && mark !== '-') {
|
|
533
|
+
evid.push(`${label}${mark}: ${evidence(key, t)}`);
|
|
534
|
+
details.push({ r, key, label, mark, t });
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
const turns = Object.entries(r.turns || {});
|
|
538
|
+
const later = (r.order || [])
|
|
539
|
+
.slice(1)
|
|
540
|
+
.map((k) => r.turns[k])
|
|
541
|
+
.filter((t) => t?.usage);
|
|
542
|
+
const sum = (f) => later.reduce((n, t) => n + f(t.usage), 0);
|
|
543
|
+
const events = (r.order || []).reduce((n, k) => n + (r.turns[k]?.usage?.events || 0), 0);
|
|
544
|
+
const cache =
|
|
545
|
+
!turns.length || !events
|
|
546
|
+
? 'cache=NO-USAGE'
|
|
547
|
+
: `cache r=${sum((u) => u.cacheRead)} w=${sum((u) => u.cacheWrite)} in=${sum((u) => u.input)} cr/turn=[${later.map((t) => t.usage.cacheRead).join(',')}]`;
|
|
548
|
+
let verdict = 'PASS';
|
|
549
|
+
if (r.error && !turns.length) verdict = ACCOUNT_RE.test(r.error) ? 'ACCOUNT' : 'FAIL';
|
|
550
|
+
else if (anyFail) verdict = 'FAIL';
|
|
551
|
+
else if (anyAccount) verdict = 'ACCOUNT';
|
|
552
|
+
if (extended) {
|
|
553
|
+
console.log(`${verdict.padEnd(7)} ${r.name.padEnd(30)} ${marks.join(' ')} ${cache}`);
|
|
554
|
+
if (r.error) console.log(` error=${r.error}`);
|
|
555
|
+
for (const e of evid) console.log(` ${e}`);
|
|
556
|
+
} else {
|
|
557
|
+
const turn = (key, label) => {
|
|
558
|
+
const t = r.turns?.[key];
|
|
559
|
+
const ok = t && !t.error && scenarios.find((s) => s[0] === key)[2](t, r);
|
|
560
|
+
return `${label}${ok ? '✓' : '✗'} ${t?.ms}ms [${t?.calls}] "${short(t?.text)}"`;
|
|
561
|
+
};
|
|
562
|
+
const pass = !r.error && verdict === 'PASS';
|
|
563
|
+
let label = 'FAIL';
|
|
564
|
+
if (pass) label = 'PASS';
|
|
565
|
+
else if (verdict === 'ACCOUNT') label = 'ACCOUNT';
|
|
566
|
+
console.log(
|
|
567
|
+
`${label} ${r.name.padEnd(30)} ` +
|
|
568
|
+
(r.error ? `error=${r.error}` : `${turn('t1', 't1')} | ${turn('t2', 't2')} | ${turn('t3', 't3')}`)
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
if (extended) {
|
|
574
|
+
// Oddities worth a manual look: model identity, usage presence, notices mixed into answers.
|
|
575
|
+
console.log('\n--- NON-PASS DETAILS (raw) ---');
|
|
576
|
+
const markNames = { A: 'ACCOUNT', '?': 'UNVERIFIED' };
|
|
577
|
+
for (const { r, label, mark, t } of details) {
|
|
578
|
+
console.log(
|
|
579
|
+
`[${markNames[mark] ?? 'FAIL'}] ${r.provider}/${r.model} effort=${r.effort ?? '-'} ${label}: ` +
|
|
580
|
+
`error=${JSON.stringify(t?.error ?? null)} text=${JSON.stringify(t?.text ?? null)} calls=${JSON.stringify(t?.calls ?? null)} disk=${JSON.stringify(t?.disk ?? null)}`
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
console.log('\n--- ODDITIES ---');
|
|
584
|
+
for (const r of results) {
|
|
585
|
+
for (const key of r.order || []) {
|
|
586
|
+
const t = r.turns[key];
|
|
587
|
+
if (
|
|
588
|
+
t?.models?.length &&
|
|
589
|
+
!t.models.some((m) => m === r.model || m.endsWith(`/${r.model}`) || m.includes(r.model) || r.model.includes(m))
|
|
590
|
+
)
|
|
591
|
+
console.log(`${r.name} ${key}: served model ${JSON.stringify(t.models)} != requested ${r.model}`);
|
|
592
|
+
if (/notice|overloaded|retrying|fallback|server error|temporarily/i.test(t?.text || ''))
|
|
593
|
+
console.log(`${r.name} ${key}: notice-like text ${JSON.stringify(t.text)}`);
|
|
594
|
+
if (t && !t.skipped && !t.error && t.usage && t.usage.events === 0)
|
|
595
|
+
console.log(`${r.name} ${key}: no usage events`);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
removeTemp();
|
|
@@ -152,22 +152,6 @@ function fmtTs(ms) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
// `.hb` sidecar bytes are attributed to their session so reclaimable bytes
|
|
156
|
-
// reflect the full on-disk footprint of a session.
|
|
157
|
-
function collectHbSidecarSizes(dir, files) {
|
|
158
|
-
const hbSizeById = new Map();
|
|
159
|
-
for (const f of files) {
|
|
160
|
-
if (!f.endsWith('.hb')) continue;
|
|
161
|
-
const id = f.slice(0, -3);
|
|
162
|
-
try {
|
|
163
|
-
hbSizeById.set(id, statSync(join(dir, f)).size || 0);
|
|
164
|
-
} catch {
|
|
165
|
-
/* ignore */
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return hbSizeById;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
155
|
// Authoritative per-file lifecycle via cheap top-level scan; the summary
|
|
172
156
|
// index is stale here (most on-disk files are unindexed), so the file
|
|
173
157
|
// itself — not the index — decides closed/age. Fall back to the index
|
|
@@ -200,7 +184,7 @@ function classifySessionFile({ full, mtimeMs, row, now, maxAgeMs, minClosedAgeMs
|
|
|
200
184
|
|
|
201
185
|
// Disk scan for sizes + mtime fallback, then the retention verdict per file
|
|
202
186
|
// rolled into the totals the report prints.
|
|
203
|
-
function collectRetention({ dir, jsonFiles,
|
|
187
|
+
function collectRetention({ dir, jsonFiles, rowById, now, maxAgeMs, minClosedAgeMs }) {
|
|
204
188
|
let totalFiles = 0;
|
|
205
189
|
let totalBytes = 0;
|
|
206
190
|
const candidates = []; // { id, reason, updatedAt, bytes, inIndex }
|
|
@@ -218,17 +202,15 @@ function collectRetention({ dir, jsonFiles, hbSizeById, rowById, now, maxAgeMs,
|
|
|
218
202
|
const id = f.slice(0, -5);
|
|
219
203
|
fileIds.add(id);
|
|
220
204
|
const full = join(dir, f);
|
|
221
|
-
let
|
|
205
|
+
let bytes = 0;
|
|
222
206
|
let mtimeMs = 0;
|
|
223
207
|
try {
|
|
224
208
|
const st = statSync(full);
|
|
225
|
-
|
|
209
|
+
bytes = st.size || 0;
|
|
226
210
|
mtimeMs = st.mtimeMs || 0;
|
|
227
211
|
} catch {
|
|
228
212
|
/* skip */
|
|
229
213
|
}
|
|
230
|
-
const hb = hbSizeById.get(id) || 0;
|
|
231
|
-
const bytes = size + hb;
|
|
232
214
|
totalFiles += 1;
|
|
233
215
|
totalBytes += bytes;
|
|
234
216
|
|
|
@@ -346,10 +328,8 @@ function main() {
|
|
|
346
328
|
const rowById = new Map();
|
|
347
329
|
for (const r of rows) if (r?.id) rowById.set(r.id, r);
|
|
348
330
|
|
|
349
|
-
const
|
|
350
|
-
const
|
|
351
|
-
const hbSizeById = collectHbSidecarSizes(dir, files);
|
|
352
|
-
const retention = collectRetention({ dir, jsonFiles, hbSizeById, rowById, now, maxAgeMs, minClosedAgeMs });
|
|
331
|
+
const jsonFiles = readdirSync(dir).filter((f) => f.endsWith('.json'));
|
|
332
|
+
const retention = collectRetention({ dir, jsonFiles, rowById, now, maxAgeMs, minClosedAgeMs });
|
|
353
333
|
process.stdout.write(renderReport({ dir, rows, now, maxAgeDays, minClosedAgeDays, retention }));
|
|
354
334
|
}
|
|
355
335
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Advisor
|
|
3
|
-
description: Use on
|
|
3
|
+
description: "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Independent technical advisor.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "advisor",
|
|
3
3
|
"name": "Advisor",
|
|
4
|
-
"description": "Use on
|
|
4
|
+
"description": "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions.",
|
|
5
5
|
"entry": "AGENT.md"
|
|
6
6
|
}
|