mixdog 1.2.3 → 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/package.json +1 -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 +128 -38
- package/scripts/session-sweep.mjs +5 -25
- 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 +6 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/rules/agent/AGENT.md +7 -5
- 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/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-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- 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 +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -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 +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- 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 +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- 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 +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- 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/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- 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/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- 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 +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- 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 +1 -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 +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -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 +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- 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 +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- 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 +29 -8
- 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 +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- 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/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 +5 -11
- 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 -32
- 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 +1 -1
- 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-catalog.mjs +50 -116
- 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 +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- 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/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/external-tool-adapters.mjs +204 -10
- 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 +200 -17
- 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/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-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/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 +178 -178
- 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 +118 -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/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -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/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- 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-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -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 +6 -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/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- 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/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- 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 +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- 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 +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- 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 +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- 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 +7 -16
- 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 +114 -34
- 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.mjs +9 -8
- 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/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/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/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/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 +9 -6
- 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 +3 -9
- 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.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- 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.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- 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 +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -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-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- 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/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +478 -251
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- 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 +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -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 +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- 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 +17 -8
- 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 +5 -1
- package/src/tui/session/turn.mjs +38 -31
- 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/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 -302
- 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
package/src/tui/dist/index.mjs
CHANGED
|
@@ -1825,8 +1825,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
1825
1825
|
currentEntangledActionThenable = {
|
|
1826
1826
|
status: "pending",
|
|
1827
1827
|
value: void 0,
|
|
1828
|
-
then: function(
|
|
1829
|
-
entangledListeners.push(
|
|
1828
|
+
then: function(resolve6) {
|
|
1829
|
+
entangledListeners.push(resolve6);
|
|
1830
1830
|
}
|
|
1831
1831
|
};
|
|
1832
1832
|
}
|
|
@@ -1849,8 +1849,8 @@ var require_react_reconciler_production = __commonJS({
|
|
|
1849
1849
|
status: "pending",
|
|
1850
1850
|
value: null,
|
|
1851
1851
|
reason: null,
|
|
1852
|
-
then: function(
|
|
1853
|
-
listeners.push(
|
|
1852
|
+
then: function(resolve6) {
|
|
1853
|
+
listeners.push(resolve6);
|
|
1854
1854
|
}
|
|
1855
1855
|
};
|
|
1856
1856
|
thenable.then(
|
|
@@ -11449,8 +11449,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
11449
11449
|
currentEntangledActionThenable = {
|
|
11450
11450
|
status: "pending",
|
|
11451
11451
|
value: void 0,
|
|
11452
|
-
then: function(
|
|
11453
|
-
entangledListeners.push(
|
|
11452
|
+
then: function(resolve6) {
|
|
11453
|
+
entangledListeners.push(resolve6);
|
|
11454
11454
|
}
|
|
11455
11455
|
};
|
|
11456
11456
|
}
|
|
@@ -11473,8 +11473,8 @@ var require_react_reconciler_development = __commonJS({
|
|
|
11473
11473
|
status: "pending",
|
|
11474
11474
|
value: null,
|
|
11475
11475
|
reason: null,
|
|
11476
|
-
then: function(
|
|
11477
|
-
listeners.push(
|
|
11476
|
+
then: function(resolve6) {
|
|
11477
|
+
listeners.push(resolve6);
|
|
11478
11478
|
}
|
|
11479
11479
|
};
|
|
11480
11480
|
thenable.then(
|
|
@@ -23274,7 +23274,7 @@ var init_keyed_serial_queue = __esm({
|
|
|
23274
23274
|
|
|
23275
23275
|
// src/runtime/shared/sleep.mjs
|
|
23276
23276
|
function sleep(ms) {
|
|
23277
|
-
return new Promise((
|
|
23277
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
23278
23278
|
}
|
|
23279
23279
|
function sleepSync(ms) {
|
|
23280
23280
|
const buffer = new SharedArrayBuffer(4);
|
|
@@ -23485,11 +23485,12 @@ function* releaseReclaimGuard(reclaim) {
|
|
|
23485
23485
|
} catch {
|
|
23486
23486
|
}
|
|
23487
23487
|
}
|
|
23488
|
-
function lockReclaimable(owner, stat2, staleMs) {
|
|
23488
|
+
function lockReclaimable(owner, stat2, staleMs, strictOwner = false) {
|
|
23489
23489
|
if (owner.pid !== null) return !ownerIsLive(owner);
|
|
23490
|
+
if (strictOwner) return false;
|
|
23490
23491
|
return Date.now() - (Number(stat2.mtimeMs) || 0) >= Math.max(0, staleMs);
|
|
23491
23492
|
}
|
|
23492
|
-
function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
23493
|
+
function* tryReclaimStaleLock(lockPath, staleMs, strictOwner = false) {
|
|
23493
23494
|
let initial;
|
|
23494
23495
|
try {
|
|
23495
23496
|
initial = yield ["stat", lockPath];
|
|
@@ -23497,7 +23498,7 @@ function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
|
23497
23498
|
return false;
|
|
23498
23499
|
}
|
|
23499
23500
|
const owner = yield* readLockOwner(lockPath);
|
|
23500
|
-
if (!lockReclaimable(owner, initial, staleMs)) return false;
|
|
23501
|
+
if (!lockReclaimable(owner, initial, staleMs, strictOwner)) return false;
|
|
23501
23502
|
const reclaim = yield* tryAcquireReclaimGuard(lockPath);
|
|
23502
23503
|
if (reclaim === null) return false;
|
|
23503
23504
|
try {
|
|
@@ -23509,7 +23510,7 @@ function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
|
23509
23510
|
}
|
|
23510
23511
|
const currentOwner = yield* readLockOwner(lockPath);
|
|
23511
23512
|
if (currentOwner.pid !== owner.pid || currentOwner.token !== owner.token) return false;
|
|
23512
|
-
if (lockReclaimable(currentOwner, current, staleMs)) {
|
|
23513
|
+
if (lockReclaimable(currentOwner, current, staleMs, strictOwner)) {
|
|
23513
23514
|
try {
|
|
23514
23515
|
yield ["unlink", lockPath];
|
|
23515
23516
|
return true;
|
|
@@ -23609,7 +23610,7 @@ function* acquireLock(lockPath, opts, mode, markHeld, timing = null) {
|
|
|
23609
23610
|
lastError = error;
|
|
23610
23611
|
if (!LOCK_WAIT_CODES.has(error?.code)) throw error;
|
|
23611
23612
|
try {
|
|
23612
|
-
if (runSync(tryReclaimStaleLock(lockPath, staleMs))) continue;
|
|
23613
|
+
if (runSync(tryReclaimStaleLock(lockPath, staleMs, opts.strictOwner === true))) continue;
|
|
23613
23614
|
} catch {
|
|
23614
23615
|
}
|
|
23615
23616
|
if (timeoutMs <= 0) throw contentionError(lockPath, error, yield* describeLockHolder(lockPath));
|
|
@@ -23764,8 +23765,8 @@ function _drainAdaptiveFileIo() {
|
|
|
23764
23765
|
}
|
|
23765
23766
|
}
|
|
23766
23767
|
function _runAdaptiveFileIo(run) {
|
|
23767
|
-
return new Promise((
|
|
23768
|
-
_ioQueue.push({ run, resolve:
|
|
23768
|
+
return new Promise((resolve6, reject) => {
|
|
23769
|
+
_ioQueue.push({ run, resolve: resolve6, reject });
|
|
23769
23770
|
_drainAdaptiveFileIo();
|
|
23770
23771
|
});
|
|
23771
23772
|
}
|
|
@@ -24076,14 +24077,14 @@ import { createHash as createHash5 } from "node:crypto";
|
|
|
24076
24077
|
import {
|
|
24077
24078
|
chmodSync as chmodSync2,
|
|
24078
24079
|
createReadStream,
|
|
24079
|
-
existsSync as
|
|
24080
|
+
existsSync as existsSync12,
|
|
24080
24081
|
mkdirSync as mkdirSync6,
|
|
24081
|
-
readFileSync as
|
|
24082
|
+
readFileSync as readFileSync13,
|
|
24082
24083
|
readdirSync as readdirSync3,
|
|
24083
24084
|
renameSync as renameSync4,
|
|
24084
24085
|
rmSync as rmSync3
|
|
24085
24086
|
} from "node:fs";
|
|
24086
|
-
import { join as
|
|
24087
|
+
import { join as join13 } from "node:path";
|
|
24087
24088
|
function platformKeyCandidates(platform2 = process.platform, arch = process.arch) {
|
|
24088
24089
|
const native = `${platform2}-${arch}`;
|
|
24089
24090
|
return platform2 === "win32" && arch === "arm64" ? [native, "win32-x64"] : [native];
|
|
@@ -24148,17 +24149,17 @@ import {
|
|
|
24148
24149
|
closeSync as closeSync2,
|
|
24149
24150
|
createReadStream as createReadStream2,
|
|
24150
24151
|
createWriteStream as createWriteStream2,
|
|
24151
|
-
existsSync as
|
|
24152
|
+
existsSync as existsSync13,
|
|
24152
24153
|
mkdirSync as mkdirSync7,
|
|
24153
24154
|
openSync as openSync2,
|
|
24154
|
-
readFileSync as
|
|
24155
|
+
readFileSync as readFileSync14,
|
|
24155
24156
|
readdirSync as readdirSync4,
|
|
24156
24157
|
rmSync as rmSync4,
|
|
24157
|
-
statSync as
|
|
24158
|
+
statSync as statSync5,
|
|
24158
24159
|
writeFileSync as writeFileSync5
|
|
24159
24160
|
} from "node:fs";
|
|
24160
24161
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
24161
|
-
import { join as
|
|
24162
|
+
import { join as join14, dirname as dirname11 } from "node:path";
|
|
24162
24163
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
24163
24164
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
24164
24165
|
import { spawnSync } from "node:child_process";
|
|
@@ -24176,7 +24177,7 @@ function lockAgeMs(holderTs, waitSince) {
|
|
|
24176
24177
|
}
|
|
24177
24178
|
function _readInstallLockToken(lockPath) {
|
|
24178
24179
|
try {
|
|
24179
|
-
const raw =
|
|
24180
|
+
const raw = readFileSync14(lockPath, "utf8").trim();
|
|
24180
24181
|
if (!raw) return null;
|
|
24181
24182
|
const [pidLine, tsLine = ""] = raw.split(/\r?\n/);
|
|
24182
24183
|
const pid = Number(pidLine);
|
|
@@ -24194,15 +24195,15 @@ function _installLockTokenMatches(lockPath, expectedPid, expectedTs, expectedTok
|
|
|
24194
24195
|
}
|
|
24195
24196
|
function chmodExtractedBinariesPosix(rootDir, executable) {
|
|
24196
24197
|
if (process.platform === "win32") return;
|
|
24197
|
-
const execDir =
|
|
24198
|
+
const execDir = join14(rootDir, dirname11(executable));
|
|
24198
24199
|
const targets = /* @__PURE__ */ new Set([
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24200
|
+
join14(rootDir, executable),
|
|
24201
|
+
join14(execDir, "whisper-cli"),
|
|
24202
|
+
join14(execDir, "whisper-server"),
|
|
24203
|
+
join14(execDir, "ffmpeg")
|
|
24203
24204
|
]);
|
|
24204
24205
|
for (const p of targets) {
|
|
24205
|
-
if (
|
|
24206
|
+
if (existsSync13(p)) {
|
|
24206
24207
|
try {
|
|
24207
24208
|
chmodSync3(p, 493);
|
|
24208
24209
|
} catch {
|
|
@@ -24212,7 +24213,7 @@ function chmodExtractedBinariesPosix(rootDir, executable) {
|
|
|
24212
24213
|
}
|
|
24213
24214
|
async function _withInstallLock(rootDir, lockName, fn, { pollMs = 250 } = {}) {
|
|
24214
24215
|
mkdirSync7(rootDir, { recursive: true });
|
|
24215
|
-
const lockPath =
|
|
24216
|
+
const lockPath = join14(rootDir, `.${lockName}.lock`);
|
|
24216
24217
|
let fd = null;
|
|
24217
24218
|
let foreignWaitSince = 0;
|
|
24218
24219
|
let samePidWaitSince = 0;
|
|
@@ -24298,28 +24299,28 @@ ${Date.now()}`);
|
|
|
24298
24299
|
}
|
|
24299
24300
|
}
|
|
24300
24301
|
function readBundledManifest() {
|
|
24301
|
-
return JSON.parse(
|
|
24302
|
+
return JSON.parse(readFileSync14(BUNDLED_MANIFEST_PATH, "utf8"));
|
|
24302
24303
|
}
|
|
24303
24304
|
function readActiveName(rootDir) {
|
|
24304
|
-
const activeFile =
|
|
24305
|
-
if (!
|
|
24306
|
-
return
|
|
24305
|
+
const activeFile = join14(rootDir, "active-version");
|
|
24306
|
+
if (!existsSync13(activeFile)) return "";
|
|
24307
|
+
return readFileSync14(activeFile, "utf8").trim();
|
|
24307
24308
|
}
|
|
24308
24309
|
async function loadManifest(dataDir2) {
|
|
24309
|
-
if (
|
|
24310
|
+
if (existsSync13(BUNDLED_MANIFEST_PATH)) {
|
|
24310
24311
|
return readBundledManifest();
|
|
24311
24312
|
}
|
|
24312
|
-
const cachedPath =
|
|
24313
|
-
if (
|
|
24313
|
+
const cachedPath = join14(dataDir2, "voice-runtime", "manifest.json");
|
|
24314
|
+
if (existsSync13(cachedPath)) {
|
|
24314
24315
|
try {
|
|
24315
|
-
return JSON.parse(
|
|
24316
|
+
return JSON.parse(readFileSync14(cachedPath, "utf8"));
|
|
24316
24317
|
} catch {
|
|
24317
24318
|
}
|
|
24318
24319
|
}
|
|
24319
24320
|
const res = await fetch(MANIFEST_URL, { signal: AbortSignal.timeout(3e4) });
|
|
24320
24321
|
if (!res.ok) throw new Error(`[voice-runtime] manifest fetch failed: ${res.status} ${res.statusText}`);
|
|
24321
24322
|
const manifest = await res.json();
|
|
24322
|
-
mkdirSync7(
|
|
24323
|
+
mkdirSync7(join14(dataDir2, "voice-runtime"), { recursive: true });
|
|
24323
24324
|
writeFileSync5(cachedPath, JSON.stringify(manifest, null, 2));
|
|
24324
24325
|
return manifest;
|
|
24325
24326
|
}
|
|
@@ -24332,20 +24333,20 @@ function detectCudaMajorsWin32() {
|
|
|
24332
24333
|
const envKeys = Object.keys(process.env).filter((k) => k === "CUDA_PATH" || /^CUDA_PATH_V\d+_\d+$/i.test(k));
|
|
24333
24334
|
for (const k of envKeys) {
|
|
24334
24335
|
const p = process.env[k];
|
|
24335
|
-
if (p) dirs.push(
|
|
24336
|
+
if (p) dirs.push(join14(p, "bin"));
|
|
24336
24337
|
}
|
|
24337
24338
|
for (const root of windowsProgramRoots()) {
|
|
24338
|
-
const standardRoot =
|
|
24339
|
-
if (!
|
|
24339
|
+
const standardRoot = join14(root, "NVIDIA GPU Computing Toolkit", "CUDA");
|
|
24340
|
+
if (!existsSync13(standardRoot)) continue;
|
|
24340
24341
|
try {
|
|
24341
24342
|
for (const e of readdirSync4(standardRoot)) {
|
|
24342
|
-
if (/^v\d+\.\d+/.test(e)) dirs.push(
|
|
24343
|
+
if (/^v\d+\.\d+/.test(e)) dirs.push(join14(standardRoot, e, "bin"));
|
|
24343
24344
|
}
|
|
24344
24345
|
} catch {
|
|
24345
24346
|
}
|
|
24346
24347
|
}
|
|
24347
24348
|
for (const d of dirs) {
|
|
24348
|
-
if (!
|
|
24349
|
+
if (!existsSync13(d)) continue;
|
|
24349
24350
|
try {
|
|
24350
24351
|
for (const f of readdirSync4(d)) {
|
|
24351
24352
|
const m = /^cublas64_(\d+)\.dll$/i.exec(f);
|
|
@@ -24367,7 +24368,7 @@ function detectCudaMajorsLinux() {
|
|
|
24367
24368
|
const cudaPath = process.env.CUDA_PATH;
|
|
24368
24369
|
if (cudaPath) dirs.push(`${cudaPath}/lib64`);
|
|
24369
24370
|
for (const d of dirs) {
|
|
24370
|
-
if (!
|
|
24371
|
+
if (!existsSync13(d)) continue;
|
|
24371
24372
|
try {
|
|
24372
24373
|
for (const f of readdirSync4(d)) {
|
|
24373
24374
|
const m = /^libcublas\.so\.(\d+)$/.exec(f);
|
|
@@ -24390,7 +24391,7 @@ function hasNvidiaDriver() {
|
|
|
24390
24391
|
const sys = windowsSystemRoot();
|
|
24391
24392
|
if (!sys) return false;
|
|
24392
24393
|
for (const f of ["System32\\nvidia-smi.exe", "System32\\nvml.dll"]) {
|
|
24393
|
-
if (
|
|
24394
|
+
if (existsSync13(join14(sys, f))) return true;
|
|
24394
24395
|
}
|
|
24395
24396
|
return false;
|
|
24396
24397
|
}
|
|
@@ -24413,7 +24414,7 @@ async function processExtras(extras, stagingDir, onProgress) {
|
|
|
24413
24414
|
if (!Array.isArray(extras) || extras.length === 0) return;
|
|
24414
24415
|
for (const extra of extras) {
|
|
24415
24416
|
const tag = createHash6("sha256").update(extra.url).digest("hex").slice(0, 8);
|
|
24416
|
-
const archivePath =
|
|
24417
|
+
const archivePath = join14(stagingDir, `extra-${tag}.${extra.format}`);
|
|
24417
24418
|
process.stderr.write(`[voice-runtime] fetching extra ${tag} (${(extra.size / 1024 / 1024).toFixed(0)} MB) ...
|
|
24418
24419
|
`);
|
|
24419
24420
|
await downloadFile(extra.url, archivePath, {
|
|
@@ -24422,16 +24423,16 @@ async function processExtras(extras, stagingDir, onProgress) {
|
|
|
24422
24423
|
});
|
|
24423
24424
|
if (!extra.sha256) throw new Error(`[voice-runtime] manifest extra entry missing required sha256: ${extra.url}`);
|
|
24424
24425
|
await verifySha256(archivePath, extra.sha256);
|
|
24425
|
-
const extractDir =
|
|
24426
|
+
const extractDir = join14(stagingDir, `.extra-${tag}`);
|
|
24426
24427
|
mkdirSync7(extractDir, { recursive: true });
|
|
24427
24428
|
extractZip(archivePath, extractDir);
|
|
24428
24429
|
for (const f of extra.files) {
|
|
24429
|
-
const src =
|
|
24430
|
-
const dst =
|
|
24431
|
-
if (!
|
|
24430
|
+
const src = join14(extractDir, f.from);
|
|
24431
|
+
const dst = join14(stagingDir, f.to);
|
|
24432
|
+
if (!existsSync13(src)) {
|
|
24432
24433
|
throw new Error(`[voice-runtime] extra ${tag}: expected file ${f.from} not present after extract`);
|
|
24433
24434
|
}
|
|
24434
|
-
mkdirSync7(
|
|
24435
|
+
mkdirSync7(dirname11(dst), { recursive: true });
|
|
24435
24436
|
renameWithRetrySync(src, dst);
|
|
24436
24437
|
}
|
|
24437
24438
|
try {
|
|
@@ -24445,12 +24446,12 @@ async function processExtras(extras, stagingDir, onProgress) {
|
|
|
24445
24446
|
}
|
|
24446
24447
|
}
|
|
24447
24448
|
function gcStaleVersions(rootDir, activeName, prefix) {
|
|
24448
|
-
if (!
|
|
24449
|
+
if (!existsSync13(rootDir)) return;
|
|
24449
24450
|
for (const entry of readdirSync4(rootDir)) {
|
|
24450
24451
|
if (entry === activeName || entry === "active-version" || entry === "manifest.json") continue;
|
|
24451
24452
|
if (!entry.startsWith(prefix) && !entry.startsWith("staging-")) continue;
|
|
24452
24453
|
try {
|
|
24453
|
-
rmSync4(
|
|
24454
|
+
rmSync4(join14(rootDir, entry), { recursive: true, force: true });
|
|
24454
24455
|
} catch {
|
|
24455
24456
|
}
|
|
24456
24457
|
}
|
|
@@ -24458,7 +24459,7 @@ function gcStaleVersions(rootDir, activeName, prefix) {
|
|
|
24458
24459
|
function gcPublishedRuntimeSiblings(rootDir, prefix) {
|
|
24459
24460
|
try {
|
|
24460
24461
|
const activeName = readActiveName(rootDir);
|
|
24461
|
-
if (!activeName.startsWith(prefix) || !
|
|
24462
|
+
if (!activeName.startsWith(prefix) || !existsSync13(join14(rootDir, activeName))) return;
|
|
24462
24463
|
gcStaleVersions(rootDir, activeName, prefix);
|
|
24463
24464
|
} catch {
|
|
24464
24465
|
}
|
|
@@ -24467,12 +24468,12 @@ async function extractGz(gzPath, destPath) {
|
|
|
24467
24468
|
await pipeline2(createReadStream2(gzPath), createGunzip(), createWriteStream2(destPath));
|
|
24468
24469
|
}
|
|
24469
24470
|
function gcStagingPartials(dir) {
|
|
24470
|
-
if (!
|
|
24471
|
+
if (!existsSync13(dir)) return;
|
|
24471
24472
|
try {
|
|
24472
24473
|
for (const entry of readdirSync4(dir)) {
|
|
24473
24474
|
if (!entry.startsWith(".staging-")) continue;
|
|
24474
24475
|
try {
|
|
24475
|
-
rmSync4(
|
|
24476
|
+
rmSync4(join14(dir, entry), { force: true });
|
|
24476
24477
|
} catch {
|
|
24477
24478
|
}
|
|
24478
24479
|
}
|
|
@@ -24543,24 +24544,24 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24543
24544
|
);
|
|
24544
24545
|
}
|
|
24545
24546
|
const ver = manifest.version;
|
|
24546
|
-
const rootDir =
|
|
24547
|
+
const rootDir = join14(dataDir2, "voice-runtime");
|
|
24547
24548
|
const activeName = `whisper-${ver}-${variant.id}`;
|
|
24548
|
-
const activeDir =
|
|
24549
|
-
const whisperCmd =
|
|
24550
|
-
if (
|
|
24549
|
+
const activeDir = join14(rootDir, activeName);
|
|
24550
|
+
const whisperCmd = join14(activeDir, variant.executable);
|
|
24551
|
+
if (existsSync13(whisperCmd)) {
|
|
24551
24552
|
gcStaleVersions(rootDir, activeName, "whisper-");
|
|
24552
24553
|
return { whisperCmd, version: ver, variantId: variant.id };
|
|
24553
24554
|
}
|
|
24554
24555
|
return _withInstallLock(rootDir, "install", async () => {
|
|
24555
|
-
if (
|
|
24556
|
+
if (existsSync13(whisperCmd)) {
|
|
24556
24557
|
gcStaleVersions(rootDir, activeName, "whisper-");
|
|
24557
24558
|
return { whisperCmd, version: ver, variantId: variant.id };
|
|
24558
24559
|
}
|
|
24559
24560
|
gcStagingPartials(rootDir);
|
|
24560
|
-
const stagingDir =
|
|
24561
|
+
const stagingDir = join14(rootDir, `staging-${process.pid}-${Date.now()}`);
|
|
24561
24562
|
mkdirSync7(stagingDir, { recursive: true });
|
|
24562
24563
|
try {
|
|
24563
|
-
const archivePath =
|
|
24564
|
+
const archivePath = join14(stagingDir, `whisper.${variant.format}`);
|
|
24564
24565
|
process.stderr.write(
|
|
24565
24566
|
`[voice-runtime] fetching whisper-${ver} variant=${variant.id} for ${key} (${(variant.size / 1024 / 1024).toFixed(0)} MB; cuda=${[...env4.cudaMajors].join(",") || "none"} nvidiaDriver=${env4.hasNvidiaDriver}) ...
|
|
24566
24567
|
`
|
|
@@ -24575,13 +24576,13 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24575
24576
|
extractZip(archivePath, stagingDir);
|
|
24576
24577
|
rmSync4(archivePath, { force: true });
|
|
24577
24578
|
chmodExtractedBinariesPosix(stagingDir, variant.executable);
|
|
24578
|
-
const stagedExec =
|
|
24579
|
-
if (!
|
|
24579
|
+
const stagedExec = join14(stagingDir, variant.executable);
|
|
24580
|
+
if (!existsSync13(stagedExec)) {
|
|
24580
24581
|
throw new Error(`[voice-runtime] expected executable ${variant.executable} not present after extract`);
|
|
24581
24582
|
}
|
|
24582
24583
|
await processExtras(variant.extras, stagingDir, onProgress);
|
|
24583
24584
|
renameWithRetrySync(stagingDir, activeDir);
|
|
24584
|
-
writeFileAtomicSync(
|
|
24585
|
+
writeFileAtomicSync(join14(rootDir, "active-version"), activeName, { fsyncDir: true });
|
|
24585
24586
|
process.stderr.write(`[voice-runtime] whisper-${ver} variant=${variant.id} ready at ${activeDir}
|
|
24586
24587
|
`);
|
|
24587
24588
|
gcStaleVersions(rootDir, activeName, "whisper-");
|
|
@@ -24596,9 +24597,9 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24596
24597
|
});
|
|
24597
24598
|
}
|
|
24598
24599
|
function isManagedWhisperStale(dataDir2) {
|
|
24599
|
-
const activeName = readActiveName(
|
|
24600
|
+
const activeName = readActiveName(join14(dataDir2, "voice-runtime"));
|
|
24600
24601
|
if (!activeName) return false;
|
|
24601
|
-
if (!
|
|
24602
|
+
if (!existsSync13(BUNDLED_MANIFEST_PATH)) return false;
|
|
24602
24603
|
try {
|
|
24603
24604
|
const manifest = readBundledManifest();
|
|
24604
24605
|
if (!manifest?.version) return false;
|
|
@@ -24608,10 +24609,10 @@ function isManagedWhisperStale(dataDir2) {
|
|
|
24608
24609
|
}
|
|
24609
24610
|
}
|
|
24610
24611
|
function resolveManagedWhisperCmd(dataDir2) {
|
|
24611
|
-
const activeName = readActiveName(
|
|
24612
|
+
const activeName = readActiveName(join14(dataDir2, "voice-runtime"));
|
|
24612
24613
|
if (!activeName) return null;
|
|
24613
|
-
const activeDir =
|
|
24614
|
-
if (
|
|
24614
|
+
const activeDir = join14(dataDir2, "voice-runtime", activeName);
|
|
24615
|
+
if (existsSync13(BUNDLED_MANIFEST_PATH)) {
|
|
24615
24616
|
try {
|
|
24616
24617
|
const manifest = readBundledManifest();
|
|
24617
24618
|
const key = platformEntryKey(manifest.platforms);
|
|
@@ -24621,26 +24622,26 @@ function resolveManagedWhisperCmd(dataDir2) {
|
|
|
24621
24622
|
const variantId = activeName.startsWith(prefix) ? activeName.slice(prefix.length) : "";
|
|
24622
24623
|
const variant = variants.find((v) => v.id === variantId);
|
|
24623
24624
|
if (variant?.executable) {
|
|
24624
|
-
const p =
|
|
24625
|
-
if (
|
|
24625
|
+
const p = join14(activeDir, variant.executable);
|
|
24626
|
+
if (existsSync13(p)) return p;
|
|
24626
24627
|
}
|
|
24627
24628
|
}
|
|
24628
24629
|
} catch {
|
|
24629
24630
|
}
|
|
24630
24631
|
}
|
|
24631
24632
|
for (const c of ["Release/whisper-cli.exe", "Release/whisper-cli"]) {
|
|
24632
|
-
const p =
|
|
24633
|
-
if (
|
|
24633
|
+
const p = join14(activeDir, c);
|
|
24634
|
+
if (existsSync13(p)) return p;
|
|
24634
24635
|
}
|
|
24635
24636
|
return null;
|
|
24636
24637
|
}
|
|
24637
24638
|
function resolveManagedWhisperModelById(dataDir2, modelId = "standard") {
|
|
24638
|
-
if (!
|
|
24639
|
+
if (!existsSync13(BUNDLED_MANIFEST_PATH)) return null;
|
|
24639
24640
|
const entry = manifestModelEntry(readBundledManifest(), modelId);
|
|
24640
24641
|
if (!entry?.filename) return null;
|
|
24641
|
-
const modelDir =
|
|
24642
|
-
const p =
|
|
24643
|
-
return
|
|
24642
|
+
const modelDir = join14(dataDir2, "voice", "models");
|
|
24643
|
+
const p = join14(modelDir, entry.filename);
|
|
24644
|
+
return existsSync13(p) ? p : null;
|
|
24644
24645
|
}
|
|
24645
24646
|
function gcUnknownModelFiles(manifest, modelDir) {
|
|
24646
24647
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -24657,7 +24658,7 @@ function gcUnknownModelFiles(manifest, modelDir) {
|
|
|
24657
24658
|
for (const name of names) {
|
|
24658
24659
|
if (!name.endsWith(".bin") || keep.has(name)) continue;
|
|
24659
24660
|
try {
|
|
24660
|
-
rmSync4(
|
|
24661
|
+
rmSync4(join14(modelDir, name), { force: true });
|
|
24661
24662
|
process.stderr.write(`[voice-runtime] removed stale model file ${name}
|
|
24662
24663
|
`);
|
|
24663
24664
|
} catch {
|
|
@@ -24675,24 +24676,24 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24675
24676
|
throw new VoiceRuntimeUnsupportedError(key);
|
|
24676
24677
|
}
|
|
24677
24678
|
const ver = manifest.ffmpeg.version;
|
|
24678
|
-
const rootDir =
|
|
24679
|
+
const rootDir = join14(dataDir2, "ffmpeg-runtime");
|
|
24679
24680
|
const activeName = `ffmpeg-${ver}`;
|
|
24680
|
-
const activeDir =
|
|
24681
|
-
const ffmpegPath =
|
|
24682
|
-
if (
|
|
24681
|
+
const activeDir = join14(rootDir, activeName);
|
|
24682
|
+
const ffmpegPath = join14(activeDir, platformEntry.executable);
|
|
24683
|
+
if (existsSync13(ffmpegPath)) {
|
|
24683
24684
|
gcStaleVersions(rootDir, activeName, "ffmpeg-");
|
|
24684
24685
|
return { ffmpegPath, version: ver };
|
|
24685
24686
|
}
|
|
24686
24687
|
return _withInstallLock(rootDir, "install", async () => {
|
|
24687
|
-
if (
|
|
24688
|
+
if (existsSync13(ffmpegPath)) {
|
|
24688
24689
|
gcStaleVersions(rootDir, activeName, "ffmpeg-");
|
|
24689
24690
|
return { ffmpegPath, version: ver };
|
|
24690
24691
|
}
|
|
24691
24692
|
gcStagingPartials(rootDir);
|
|
24692
|
-
const stagingDir =
|
|
24693
|
+
const stagingDir = join14(rootDir, `staging-${process.pid}-${Date.now()}`);
|
|
24693
24694
|
mkdirSync7(stagingDir, { recursive: true });
|
|
24694
24695
|
try {
|
|
24695
|
-
const archivePath =
|
|
24696
|
+
const archivePath = join14(stagingDir, `ffmpeg.${platformEntry.format}`);
|
|
24696
24697
|
process.stderr.write(
|
|
24697
24698
|
`[voice-runtime] fetching ffmpeg-${ver} for ${key} (${(platformEntry.size / 1024 / 1024).toFixed(0)} MB) ...
|
|
24698
24699
|
`
|
|
@@ -24704,7 +24705,7 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24704
24705
|
if (!platformEntry.sha256)
|
|
24705
24706
|
throw new Error(`[voice-runtime] manifest ffmpeg entry for ${key} missing required sha256`);
|
|
24706
24707
|
await verifySha256(archivePath, platformEntry.sha256);
|
|
24707
|
-
const stagedExec =
|
|
24708
|
+
const stagedExec = join14(stagingDir, platformEntry.executable);
|
|
24708
24709
|
if (platformEntry.format === "gz") {
|
|
24709
24710
|
await extractGz(archivePath, stagedExec);
|
|
24710
24711
|
} else if (platformEntry.format === "zip") {
|
|
@@ -24713,7 +24714,7 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24713
24714
|
throw new Error(`[voice-runtime] ffmpeg manifest format must be "gz" or "zip", got "${platformEntry.format}"`);
|
|
24714
24715
|
}
|
|
24715
24716
|
rmSync4(archivePath, { force: true });
|
|
24716
|
-
if (!
|
|
24717
|
+
if (!existsSync13(stagedExec)) {
|
|
24717
24718
|
throw new Error(
|
|
24718
24719
|
`[voice-runtime] expected ffmpeg executable ${platformEntry.executable} not present after extract`
|
|
24719
24720
|
);
|
|
@@ -24722,7 +24723,7 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24722
24723
|
chmodSync3(stagedExec, 493);
|
|
24723
24724
|
}
|
|
24724
24725
|
renameWithRetrySync(stagingDir, activeDir);
|
|
24725
|
-
writeFileAtomicSync(
|
|
24726
|
+
writeFileAtomicSync(join14(rootDir, "active-version"), activeName, { fsyncDir: true });
|
|
24726
24727
|
process.stderr.write(`[voice-runtime] ffmpeg-${ver} ready at ${activeDir}
|
|
24727
24728
|
`);
|
|
24728
24729
|
gcStaleVersions(rootDir, activeName, "ffmpeg-");
|
|
@@ -24737,24 +24738,24 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24737
24738
|
});
|
|
24738
24739
|
}
|
|
24739
24740
|
function resolveManagedFfmpegPath(dataDir2) {
|
|
24740
|
-
const activeName = readActiveName(
|
|
24741
|
+
const activeName = readActiveName(join14(dataDir2, "ffmpeg-runtime"));
|
|
24741
24742
|
if (!activeName) return null;
|
|
24742
|
-
const activeDir =
|
|
24743
|
-
if (
|
|
24743
|
+
const activeDir = join14(dataDir2, "ffmpeg-runtime", activeName);
|
|
24744
|
+
if (existsSync13(BUNDLED_MANIFEST_PATH)) {
|
|
24744
24745
|
try {
|
|
24745
24746
|
const manifest = readBundledManifest();
|
|
24746
24747
|
const key = platformEntryKey(manifest.ffmpeg?.platforms);
|
|
24747
24748
|
const platformEntry = manifest.ffmpeg?.platforms?.[key];
|
|
24748
24749
|
if (platformEntry?.executable) {
|
|
24749
|
-
const p =
|
|
24750
|
-
if (
|
|
24750
|
+
const p = join14(activeDir, platformEntry.executable);
|
|
24751
|
+
if (existsSync13(p)) return p;
|
|
24751
24752
|
}
|
|
24752
24753
|
} catch {
|
|
24753
24754
|
}
|
|
24754
24755
|
}
|
|
24755
24756
|
for (const c of ["ffmpeg.exe", "ffmpeg"]) {
|
|
24756
|
-
const p =
|
|
24757
|
-
if (
|
|
24757
|
+
const p = join14(activeDir, c);
|
|
24758
|
+
if (existsSync13(p)) return p;
|
|
24758
24759
|
}
|
|
24759
24760
|
return null;
|
|
24760
24761
|
}
|
|
@@ -24769,7 +24770,7 @@ function voiceRuntimeInfo(runtime) {
|
|
|
24769
24770
|
let modelBytes = model?.size || 0;
|
|
24770
24771
|
if (runtime.modelPath) {
|
|
24771
24772
|
try {
|
|
24772
|
-
modelBytes =
|
|
24773
|
+
modelBytes = statSync5(runtime.modelPath).size;
|
|
24773
24774
|
} catch {
|
|
24774
24775
|
modelBytes = 0;
|
|
24775
24776
|
}
|
|
@@ -24785,15 +24786,15 @@ function voiceRuntimeInfo(runtime) {
|
|
|
24785
24786
|
}
|
|
24786
24787
|
function resolveVoiceRuntime(dataDir2, { modelId = "standard", cleanup = true } = {}) {
|
|
24787
24788
|
if (cleanup) {
|
|
24788
|
-
gcPublishedRuntimeSiblings(
|
|
24789
|
-
gcPublishedRuntimeSiblings(
|
|
24789
|
+
gcPublishedRuntimeSiblings(join14(dataDir2, "voice-runtime"), "whisper-");
|
|
24790
|
+
gcPublishedRuntimeSiblings(join14(dataDir2, "ffmpeg-runtime"), "ffmpeg-");
|
|
24790
24791
|
}
|
|
24791
24792
|
const managedWhisperCmd = resolveManagedWhisperCmd(dataDir2);
|
|
24792
24793
|
const managedModelPath = resolveManagedWhisperModelById(dataDir2, modelId);
|
|
24793
24794
|
const managedFfmpegPath = resolveManagedFfmpegPath(dataDir2);
|
|
24794
24795
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
24795
|
-
const managedServerCmd = managedWhisperCmd ?
|
|
24796
|
-
const serverCmd = managedServerCmd &&
|
|
24796
|
+
const managedServerCmd = managedWhisperCmd ? join14(dirname11(managedWhisperCmd), `whisper-server${ext}`) : null;
|
|
24797
|
+
const serverCmd = managedServerCmd && existsSync13(managedServerCmd) ? managedServerCmd : null;
|
|
24797
24798
|
return {
|
|
24798
24799
|
kind: "managed-whisper.cpp",
|
|
24799
24800
|
label: "whisper.cpp",
|
|
@@ -24818,9 +24819,9 @@ async function ensureWhisperModel(dataDir2, onProgress = null, modelId = "standa
|
|
|
24818
24819
|
if (!model) {
|
|
24819
24820
|
throw new Error("[voice-runtime] manifest is missing the `model` section \u2014 cannot resolve whisper model");
|
|
24820
24821
|
}
|
|
24821
|
-
const modelDir =
|
|
24822
|
-
const modelPath =
|
|
24823
|
-
if (
|
|
24822
|
+
const modelDir = join14(dataDir2, "voice", "models");
|
|
24823
|
+
const modelPath = join14(modelDir, model.filename);
|
|
24824
|
+
if (existsSync13(modelPath)) {
|
|
24824
24825
|
const actual = await sha256File(modelPath);
|
|
24825
24826
|
if (actual === model.sha256) {
|
|
24826
24827
|
return { modelPath, modelId: model.id, size: model.size };
|
|
@@ -24835,7 +24836,7 @@ async function ensureWhisperModel(dataDir2, onProgress = null, modelId = "standa
|
|
|
24835
24836
|
}
|
|
24836
24837
|
}
|
|
24837
24838
|
return _withInstallLock(modelDir, "install", async () => {
|
|
24838
|
-
if (
|
|
24839
|
+
if (existsSync13(modelPath)) {
|
|
24839
24840
|
const actual = await sha256File(modelPath);
|
|
24840
24841
|
if (actual === model.sha256) {
|
|
24841
24842
|
gcUnknownModelFiles(manifest, modelDir);
|
|
@@ -24847,7 +24848,7 @@ async function ensureWhisperModel(dataDir2, onProgress = null, modelId = "standa
|
|
|
24847
24848
|
}
|
|
24848
24849
|
}
|
|
24849
24850
|
gcStagingPartials(modelDir);
|
|
24850
|
-
const stagingPath =
|
|
24851
|
+
const stagingPath = join14(modelDir, `.staging-${process.pid}-${Date.now()}-${model.filename}`);
|
|
24851
24852
|
try {
|
|
24852
24853
|
process.stderr.write(
|
|
24853
24854
|
`[voice-runtime] fetching model ${model.id} (${(model.size / 1024 / 1024).toFixed(0)} MB) from ${model.url} ...
|
|
@@ -33875,8 +33876,8 @@ var App_default = App;
|
|
|
33875
33876
|
var noop = () => {
|
|
33876
33877
|
};
|
|
33877
33878
|
var textEncoder = new TextEncoder();
|
|
33878
|
-
var yieldImmediate = async () => new Promise((
|
|
33879
|
-
setImmediate(
|
|
33879
|
+
var yieldImmediate = async () => new Promise((resolve6) => {
|
|
33880
|
+
setImmediate(resolve6);
|
|
33880
33881
|
});
|
|
33881
33882
|
var kittyQueryEscapeByte = 27;
|
|
33882
33883
|
var kittyQueryOpenBracketByte = 91;
|
|
@@ -34131,8 +34132,8 @@ var Ink = class {
|
|
|
34131
34132
|
};
|
|
34132
34133
|
}
|
|
34133
34134
|
this.initKittyKeyboard();
|
|
34134
|
-
this.exitPromise = new Promise((
|
|
34135
|
-
this.resolveExitPromise =
|
|
34135
|
+
this.exitPromise = new Promise((resolve6, reject) => {
|
|
34136
|
+
this.resolveExitPromise = resolve6;
|
|
34136
34137
|
this.rejectExitPromise = reject;
|
|
34137
34138
|
});
|
|
34138
34139
|
void this.exitPromise.catch(noop);
|
|
@@ -34572,9 +34573,9 @@ var Ink = class {
|
|
|
34572
34573
|
settleThrottle(this.throttledOnRender, canWriteToStdout);
|
|
34573
34574
|
settleThrottle(this.throttledLog, canWriteToStdout);
|
|
34574
34575
|
if (canWriteToStdout && hasWritableState) {
|
|
34575
|
-
await new Promise((
|
|
34576
|
+
await new Promise((resolve6) => {
|
|
34576
34577
|
this.options.stdout.write("", () => {
|
|
34577
|
-
|
|
34578
|
+
resolve6();
|
|
34578
34579
|
});
|
|
34579
34580
|
});
|
|
34580
34581
|
return;
|
|
@@ -34660,8 +34661,8 @@ var Ink = class {
|
|
|
34660
34661
|
async awaitNextRender() {
|
|
34661
34662
|
if (!this.nextRenderCommit) {
|
|
34662
34663
|
let resolveRender;
|
|
34663
|
-
const promise = new Promise((
|
|
34664
|
-
resolveRender =
|
|
34664
|
+
const promise = new Promise((resolve6) => {
|
|
34665
|
+
resolveRender = resolve6;
|
|
34665
34666
|
});
|
|
34666
34667
|
this.nextRenderCommit = { promise, resolve: resolveRender };
|
|
34667
34668
|
}
|
|
@@ -35114,7 +35115,7 @@ import { useState as useState5, useEffect as useEffect6, useCallback as useCallb
|
|
|
35114
35115
|
// src/tui/index.jsx
|
|
35115
35116
|
import { closeSync as closeSync3, constants as fsConstants, createWriteStream as createWriteStream3, mkdirSync as mkdirSync8, openSync as openSync3, readSync } from "node:fs";
|
|
35116
35117
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
35117
|
-
import { dirname as
|
|
35118
|
+
import { dirname as dirname12, join as join17 } from "node:path";
|
|
35118
35119
|
import { performance as performance2 } from "node:perf_hooks";
|
|
35119
35120
|
import { format } from "node:util";
|
|
35120
35121
|
|
|
@@ -35132,12 +35133,12 @@ import { spawn } from "node:child_process";
|
|
|
35132
35133
|
import path from "node:path";
|
|
35133
35134
|
var DIALOG_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
35134
35135
|
function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
|
|
35135
|
-
return new Promise((
|
|
35136
|
+
return new Promise((resolve6) => {
|
|
35136
35137
|
let child;
|
|
35137
35138
|
try {
|
|
35138
35139
|
child = spawn(cmd, args, { stdio: ["ignore", "pipe", "ignore"], windowsHide: true });
|
|
35139
35140
|
} catch (error) {
|
|
35140
|
-
|
|
35141
|
+
resolve6({ ok: false, code: -1, stdout: "", error });
|
|
35141
35142
|
return;
|
|
35142
35143
|
}
|
|
35143
35144
|
let stdout2 = "";
|
|
@@ -35149,7 +35150,7 @@ function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
|
|
|
35149
35150
|
child.kill();
|
|
35150
35151
|
} catch {
|
|
35151
35152
|
}
|
|
35152
|
-
|
|
35153
|
+
resolve6({ ok: false, code: -1, stdout: "", error: new Error("dialog timed out") });
|
|
35153
35154
|
}, timeoutMs);
|
|
35154
35155
|
timer2.unref?.();
|
|
35155
35156
|
child.stdout.on("data", (chunk) => {
|
|
@@ -35159,13 +35160,13 @@ function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
|
|
|
35159
35160
|
if (settled) return;
|
|
35160
35161
|
settled = true;
|
|
35161
35162
|
clearTimeout(timer2);
|
|
35162
|
-
|
|
35163
|
+
resolve6({ ok: false, code: -1, stdout: "", error });
|
|
35163
35164
|
});
|
|
35164
35165
|
child.on("close", (code) => {
|
|
35165
35166
|
if (settled) return;
|
|
35166
35167
|
settled = true;
|
|
35167
35168
|
clearTimeout(timer2);
|
|
35168
|
-
|
|
35169
|
+
resolve6({ ok: code === 0, code, stdout: stdout2 });
|
|
35169
35170
|
});
|
|
35170
35171
|
});
|
|
35171
35172
|
}
|
|
@@ -35173,10 +35174,10 @@ function spawnFailed(result) {
|
|
|
35173
35174
|
return !!result && result.code === -1;
|
|
35174
35175
|
}
|
|
35175
35176
|
function commandExists(cmd) {
|
|
35176
|
-
return new Promise((
|
|
35177
|
+
return new Promise((resolve6) => {
|
|
35177
35178
|
const probe = process.platform === "win32" ? spawn("where", [cmd], { stdio: "ignore", windowsHide: true }) : spawn("which", [cmd], { stdio: "ignore" });
|
|
35178
|
-
probe.on("error", () =>
|
|
35179
|
-
probe.on("close", (code) =>
|
|
35179
|
+
probe.on("error", () => resolve6(false));
|
|
35180
|
+
probe.on("close", (code) => resolve6(code === 0));
|
|
35180
35181
|
});
|
|
35181
35182
|
}
|
|
35182
35183
|
function psSingleQuoted(value) {
|
|
@@ -35445,6 +35446,12 @@ var SLASH_COMMANDS = [
|
|
|
35445
35446
|
},
|
|
35446
35447
|
{ name: "resume", usage: "/resume", params: "[id]", description: "Resume a saved chat" },
|
|
35447
35448
|
{ name: "context", usage: "/context", description: "Show current context surface" },
|
|
35449
|
+
{
|
|
35450
|
+
name: "shells",
|
|
35451
|
+
usage: "/shells",
|
|
35452
|
+
params: "[release <task_id> [--confirm]]",
|
|
35453
|
+
description: "List shells; release one whose termination is unconfirmed"
|
|
35454
|
+
},
|
|
35448
35455
|
{
|
|
35449
35456
|
name: "fork",
|
|
35450
35457
|
usage: "/fork",
|
|
@@ -37526,7 +37533,7 @@ var DIFF_STAT_SUMMARY_RE = /^\s*\d+\s+files?\s+changed\b/;
|
|
|
37526
37533
|
function colorizeDiffStatLine(line, c) {
|
|
37527
37534
|
const m = DIFF_STAT_FILE_RE.exec(line);
|
|
37528
37535
|
if (m) {
|
|
37529
|
-
const [, indent, path2,
|
|
37536
|
+
const [, indent, path2, sep2, tail] = m;
|
|
37530
37537
|
const countMatch = /^(\d+)(\s*)([+-]*)\s*$/.exec(tail);
|
|
37531
37538
|
let coloredTail;
|
|
37532
37539
|
if (countMatch) {
|
|
@@ -37537,7 +37544,7 @@ function colorizeDiffStatLine(line, c) {
|
|
|
37537
37544
|
} else {
|
|
37538
37545
|
coloredTail = c.diffContext(tail);
|
|
37539
37546
|
}
|
|
37540
|
-
return `${indent}${c.diffContext(path2)}${c.diffContext(
|
|
37547
|
+
return `${indent}${c.diffContext(path2)}${c.diffContext(sep2)}${coloredTail}`;
|
|
37541
37548
|
}
|
|
37542
37549
|
return c.diffContext(line);
|
|
37543
37550
|
}
|
|
@@ -39936,7 +39943,7 @@ function isUserControlCancellation(text) {
|
|
|
39936
39943
|
return USER_CONTROL_CANCELLATION_RE.test(String(text || "").trimStart());
|
|
39937
39944
|
}
|
|
39938
39945
|
function hasBenignExitOutcome(text) {
|
|
39939
|
-
return /^\[outcome:\s*(?:no-match|no-change)\]\s*$/im.test(String(text || ""));
|
|
39946
|
+
return /^\[outcome:\s*(?:no-match|no-change|conflicts)\]\s*$/im.test(String(text || ""));
|
|
39940
39947
|
}
|
|
39941
39948
|
var ENVELOPE_TAG_HEAD_RE = /^<(?:task-notification|task-id|tool-use-id|output-file|status)[\s>]/i;
|
|
39942
39949
|
function toolResultEnvelopeStatus(text) {
|
|
@@ -40108,10 +40115,10 @@ function splitPathAndDelta(value, explicitDelta = "") {
|
|
|
40108
40115
|
let path2 = String(value ?? "").trim();
|
|
40109
40116
|
let delta = String(explicitDelta ?? "").trim();
|
|
40110
40117
|
if (!delta) {
|
|
40111
|
-
const
|
|
40112
|
-
if (
|
|
40113
|
-
delta = path2.slice(
|
|
40114
|
-
path2 = path2.slice(0,
|
|
40118
|
+
const sep2 = path2.lastIndexOf(" \u2014 ");
|
|
40119
|
+
if (sep2 !== -1) {
|
|
40120
|
+
delta = path2.slice(sep2 + 3).trim();
|
|
40121
|
+
path2 = path2.slice(0, sep2).trim();
|
|
40115
40122
|
}
|
|
40116
40123
|
}
|
|
40117
40124
|
return { path: path2, delta };
|
|
@@ -40480,8 +40487,20 @@ function summarizeAgentResult({ text, trimmed, translate }) {
|
|
|
40480
40487
|
return null;
|
|
40481
40488
|
}
|
|
40482
40489
|
var summarizeGeneric = ({ text, translate }) => summarizeGenericResult(text, translate);
|
|
40483
|
-
var summarizeAskUserResult = ({ text }) => {
|
|
40484
|
-
const
|
|
40490
|
+
var summarizeAskUserResult = ({ text, translate }) => {
|
|
40491
|
+
const replied = /^User replied in chat: ("(?:[^"\\]|\\.)*")\. /s.exec(String(text ?? "").trim());
|
|
40492
|
+
if (replied) {
|
|
40493
|
+
let reply = "";
|
|
40494
|
+
try {
|
|
40495
|
+
reply = String(JSON.parse(replied[1]));
|
|
40496
|
+
} catch {
|
|
40497
|
+
}
|
|
40498
|
+
const label = translate("Answered in chat", "Answered in chat", {});
|
|
40499
|
+
return truncateSingleLine(reply ? `${label}: ${reply}` : label, AGENT_SURFACE_BRIEF_MAX);
|
|
40500
|
+
}
|
|
40501
|
+
const answers = /^User has answered your questions:\s*(.*?)(?:\s*You can now continue with these answers in mind\.)?$/s.exec(
|
|
40502
|
+
String(text ?? "").trim()
|
|
40503
|
+
);
|
|
40485
40504
|
return truncateSingleLine(answers ? answers[1] : String(text ?? "").trim(), AGENT_SURFACE_BRIEF_MAX) || null;
|
|
40486
40505
|
};
|
|
40487
40506
|
var TOOL_RESULT_SUMMARIZERS = new Map(
|
|
@@ -40876,12 +40895,18 @@ function officeUnit(a) {
|
|
|
40876
40895
|
}
|
|
40877
40896
|
function visualizeUnit(a) {
|
|
40878
40897
|
const action = String(a.action || "").toLowerCase();
|
|
40879
|
-
if (action === "capture")
|
|
40880
|
-
|
|
40881
|
-
if (action === "
|
|
40882
|
-
|
|
40883
|
-
if (action === "
|
|
40884
|
-
|
|
40898
|
+
if (action === "capture")
|
|
40899
|
+
return unitDescriptor("Visualize", { count: 1, active: "Capturing", done: "Captured", noun: "screenshot" });
|
|
40900
|
+
if (action === "export")
|
|
40901
|
+
return unitDescriptor("Visualize", { count: 1, active: "Exporting", done: "Exported", noun: "file" });
|
|
40902
|
+
if (action === "annotate")
|
|
40903
|
+
return unitDescriptor("Visualize", { count: 1, active: "Marking", done: "Marked", noun: "annotation" });
|
|
40904
|
+
if (action === "check")
|
|
40905
|
+
return unitDescriptor("Visualize", { count: 1, active: "Checking", done: "Checked", noun: "page" });
|
|
40906
|
+
if (action === "inspect")
|
|
40907
|
+
return unitDescriptor("Visualize", { count: 1, active: "Inspecting", done: "Inspected", noun: "page" });
|
|
40908
|
+
if (action === "close")
|
|
40909
|
+
return unitDescriptor("Visualize", { count: 1, active: "Closing", done: "Closed", noun: "tab" });
|
|
40885
40910
|
return unitDescriptor("Visualize", { count: 1, active: "Showing", done: "Showed", noun: "artifact" });
|
|
40886
40911
|
}
|
|
40887
40912
|
function terminalUnit(a) {
|
|
@@ -41095,7 +41120,10 @@ function cwdUnit(a) {
|
|
|
41095
41120
|
}
|
|
41096
41121
|
if (action === "favorite" || action === "archive") {
|
|
41097
41122
|
const off = a.value === false;
|
|
41098
|
-
|
|
41123
|
+
let words;
|
|
41124
|
+
if (action === "favorite") words = off ? ["Unfavoriting", "Unfavorited"] : ["Favoriting", "Favorited"];
|
|
41125
|
+
else words = off ? ["Unarchiving", "Unarchived"] : ["Archiving", "Archived"];
|
|
41126
|
+
const [active, done] = words;
|
|
41099
41127
|
return unitDescriptor("Setup", { active, done, noun: "session", effect: true });
|
|
41100
41128
|
}
|
|
41101
41129
|
if (action.endsWith("-worktree") || action.endsWith("-worktrees")) {
|
|
@@ -41109,7 +41137,12 @@ function cwdUnit(a) {
|
|
|
41109
41137
|
if (action === "status") {
|
|
41110
41138
|
return unitDescriptor("Setup", { active: "Checking", done: "Checked", noun: "session" });
|
|
41111
41139
|
}
|
|
41112
|
-
return unitDescriptor("Setup", {
|
|
41140
|
+
return unitDescriptor("Setup", {
|
|
41141
|
+
active: "Checking",
|
|
41142
|
+
done: "Checked",
|
|
41143
|
+
noun: "working directory",
|
|
41144
|
+
pluralNoun: "working directories"
|
|
41145
|
+
});
|
|
41113
41146
|
}
|
|
41114
41147
|
var TOOL_UNITS = /* @__PURE__ */ new Map([
|
|
41115
41148
|
[
|
|
@@ -41589,7 +41622,8 @@ function summarizeGithub(a, max) {
|
|
|
41589
41622
|
const id = a.number ?? a.id;
|
|
41590
41623
|
const hasId = id != null && String(id).trim() !== "";
|
|
41591
41624
|
const title = truncateToolText(firstText(a.title, a.workflow, a.tag), Math.min(max, 60));
|
|
41592
|
-
|
|
41625
|
+
if (hasId) return compactParts([`${phrase} ${String(id).trim()}`, repo, title]);
|
|
41626
|
+
return compactParts([repo ? `${phrase} ${repo}` : phrase, title]);
|
|
41593
41627
|
}
|
|
41594
41628
|
function formatToolSurface(name, args, opts = {}) {
|
|
41595
41629
|
const parsed = parseToolArgs(args);
|
|
@@ -42308,7 +42342,10 @@ var IN_FLIGHT_BUDGET_MAX_WAIT_MS = 6e4;
|
|
|
42308
42342
|
function inFlightAdviceMs(err) {
|
|
42309
42343
|
const advised = retryAfterMsFromError(err);
|
|
42310
42344
|
if (advised != null) return advised;
|
|
42311
|
-
for (const [name, unitMs] of [
|
|
42345
|
+
for (const [name, unitMs] of [
|
|
42346
|
+
["retry-after-ms", 1],
|
|
42347
|
+
["retry-after", 1e3]
|
|
42348
|
+
]) {
|
|
42312
42349
|
const value = errorHeaderValue(err, name);
|
|
42313
42350
|
const n = Number(value);
|
|
42314
42351
|
if (value != null && String(value).trim() !== "" && Number.isFinite(n) && n >= 0) return n * unitMs;
|
|
@@ -42664,6 +42701,20 @@ function describeError(value) {
|
|
|
42664
42701
|
};
|
|
42665
42702
|
}
|
|
42666
42703
|
|
|
42704
|
+
// src/runtime/shared/provider-timeout-phase.mjs
|
|
42705
|
+
var TIMEOUT_PHASE = Object.freeze({
|
|
42706
|
+
// The response headers did not arrive in the first-byte window.
|
|
42707
|
+
HEADERS: "headers",
|
|
42708
|
+
// The headers arrived, the first chunk did not.
|
|
42709
|
+
FIRST_CHUNK: "first-chunk",
|
|
42710
|
+
// A stream that already produced output went silent.
|
|
42711
|
+
IDLE: "idle"
|
|
42712
|
+
});
|
|
42713
|
+
function isFirstByteTimeout(err) {
|
|
42714
|
+
const phase = err?.timeoutPhase;
|
|
42715
|
+
return phase === TIMEOUT_PHASE.HEADERS || phase === TIMEOUT_PHASE.FIRST_CHUNK;
|
|
42716
|
+
}
|
|
42717
|
+
|
|
42667
42718
|
// src/runtime/shared/err-text.mjs
|
|
42668
42719
|
function errorHttpStatus(err) {
|
|
42669
42720
|
return Number(err?.httpStatus || err?.status || err?.response?.status || 0) || 0;
|
|
@@ -42821,6 +42872,25 @@ function hasTypedEvidence(error) {
|
|
|
42821
42872
|
if (!error || typeof error !== "object") return false;
|
|
42822
42873
|
return Boolean(error.errorKind?.kind) || errorHttpStatus(error) > 0 || Boolean(error.code) || Boolean(error.retryAfterMs);
|
|
42823
42874
|
}
|
|
42875
|
+
var timedOutMs = (text) => Number(/timed out after (\d+)ms/i.exec(text)?.[1]) || 0;
|
|
42876
|
+
function stillThinkingText(error, text) {
|
|
42877
|
+
const ms = Number(error.waitedMs) || timedOutMs(text);
|
|
42878
|
+
const provider = typeof error.providerLabel === "string" && error.providerLabel ? error.providerLabel : "the provider";
|
|
42879
|
+
const attempts = Number(error.attempts) > 0 ? `; attempts: ${Math.floor(Number(error.attempts))}` : "";
|
|
42880
|
+
return `Model still thinking: no output in ${formatDurationMs(ms)}; ${provider} sent nothing yet${attempts}.`;
|
|
42881
|
+
}
|
|
42882
|
+
function typedStreamFailureText(error, text) {
|
|
42883
|
+
if (!error || typeof error !== "object") return null;
|
|
42884
|
+
if (isFirstByteTimeout(error)) return stillThinkingText(error, text);
|
|
42885
|
+
if (error.timeoutPhase === TIMEOUT_PHASE.IDLE) {
|
|
42886
|
+
const ms = timedOutMs(text);
|
|
42887
|
+
return ms > 0 ? `No progress ${formatDurationMs(ms)}.` : "No progress.";
|
|
42888
|
+
}
|
|
42889
|
+
if (error.code === "TRUNCATED_STREAM" && error.streamCorruption !== true) {
|
|
42890
|
+
return "Connection to the provider was lost (TRUNCATED_STREAM).";
|
|
42891
|
+
}
|
|
42892
|
+
return null;
|
|
42893
|
+
}
|
|
42824
42894
|
function presentErrorText(error, options = {}) {
|
|
42825
42895
|
const presentation = describeError(error);
|
|
42826
42896
|
if (["image-size", "payload-size", "request"].includes(presentation.kind)) return presentation.summary;
|
|
@@ -42844,6 +42914,8 @@ function presentErrorText(error, options = {}) {
|
|
|
42844
42914
|
if (embeddedError) text = embeddedError;
|
|
42845
42915
|
text = oneLine(stripErrorPrefix(text));
|
|
42846
42916
|
if (!text) return "Unknown error";
|
|
42917
|
+
const streamFailure = typedStreamFailureText(error, text);
|
|
42918
|
+
if (streamFailure) return streamFailure;
|
|
42847
42919
|
if (code === "PROVIDER_PREFIX_MUTATION" || name === "ProviderPrefixMutationError") {
|
|
42848
42920
|
return "Session state changed unexpectedly.";
|
|
42849
42921
|
}
|
|
@@ -42883,7 +42955,7 @@ function presentErrorText(error, options = {}) {
|
|
|
42883
42955
|
}
|
|
42884
42956
|
const firstTransport = /first (?:transport|semantic response) stale\s*\((\d+)ms\)/i.exec(text);
|
|
42885
42957
|
if (firstTransport) {
|
|
42886
|
-
return `
|
|
42958
|
+
return `Agent watchdog stopped the run: no model response in ${formatDurationMs(firstTransport[1])}.`;
|
|
42887
42959
|
}
|
|
42888
42960
|
const firstResponse = /(?:agent\s+)?first response stale\s*\((\d+)ms\)/i.exec(text);
|
|
42889
42961
|
if (firstResponse) {
|
|
@@ -42918,7 +42990,7 @@ function backgroundTaskFailureStatusLabel(status, error, options = {}) {
|
|
|
42918
42990
|
const watchdog = watchdogMsFromRawError(raw);
|
|
42919
42991
|
let head = "Failed";
|
|
42920
42992
|
if (/^(cancelled|canceled)$/i.test(statusNorm)) head = "Cancelled";
|
|
42921
|
-
else if (/^timeout$/i.test(statusNorm) || watchdog?.kind === "timeout" || /first response stale/i.test(raw) || /no first response from/i.test(presented))
|
|
42993
|
+
else if (/^timeout$/i.test(statusNorm) || watchdog?.kind === "timeout" || /first response stale/i.test(raw) || /no first response from/i.test(presented) || /^(?:Model still thinking|Agent watchdog stopped the run):/.test(presented))
|
|
42922
42994
|
head = "Timeout";
|
|
42923
42995
|
else if (watchdog?.kind === "stale" || /(?:agent )?(?:task|tool running) stale|went stale without/i.test(raw) || /went stale after/i.test(presented))
|
|
42924
42996
|
head = "Stale";
|
|
@@ -43811,7 +43883,8 @@ function headerLabel(base, surface, display, status, detail) {
|
|
|
43811
43883
|
if (display.isBackgroundMetadataResult) return backgroundTaskActionTitle(normalizedName, display.backgroundMeta);
|
|
43812
43884
|
if (isShellSurface) return shellHeader(status.shellStatus, groupCount, parsedArgs?.verifyShell === true);
|
|
43813
43885
|
const described = normalizedName === "load_tool" && !headerPending ? bridgeDescribedToolNames(display.displayedResultText) : null;
|
|
43814
|
-
if (described)
|
|
43886
|
+
if (described)
|
|
43887
|
+
return described.length ? `Described ${described.map(displayToolSearchTarget).join(", ")}` : "Described";
|
|
43815
43888
|
return (isAgentTool(normalizedName) ? agentActionTitle(parsedArgs, display.displayedResultText) : "") || formatToolActionHeader(name, args, {
|
|
43816
43889
|
pending: headerPending,
|
|
43817
43890
|
count: groupCount,
|
|
@@ -45869,8 +45942,8 @@ var notifyRenderFrame = (seq) => {
|
|
|
45869
45942
|
for (const ack of acks) ack(seq);
|
|
45870
45943
|
};
|
|
45871
45944
|
var yieldToRenderer = ({ frames = 1 } = {}) => {
|
|
45872
|
-
if (!hasRenderFrameSource()) return new Promise((
|
|
45873
|
-
return new Promise((
|
|
45945
|
+
if (!hasRenderFrameSource()) return new Promise((resolve6) => setImmediate(resolve6));
|
|
45946
|
+
return new Promise((resolve6) => {
|
|
45874
45947
|
const minSeq = renderAckSeq;
|
|
45875
45948
|
let remainingFrames = Math.max(1, Math.floor(Number(frames) || 1));
|
|
45876
45949
|
let settled = false;
|
|
@@ -45885,7 +45958,7 @@ var yieldToRenderer = ({ frames = 1 } = {}) => {
|
|
|
45885
45958
|
releaseClosedListener();
|
|
45886
45959
|
const idx = pendingRenderAcks.indexOf(onFrame);
|
|
45887
45960
|
if (idx !== -1) pendingRenderAcks.splice(idx, 1);
|
|
45888
|
-
|
|
45961
|
+
resolve6();
|
|
45889
45962
|
};
|
|
45890
45963
|
releaseClosedListener = onRenderFrameSourcesClosed(finish);
|
|
45891
45964
|
const onTimeout = () => {
|
|
@@ -46685,13 +46758,13 @@ function nativeClipboardCommand(text) {
|
|
|
46685
46758
|
function copyToClipboard(text) {
|
|
46686
46759
|
const value = String(text ?? "");
|
|
46687
46760
|
const wroteOsc52 = writeOsc52Clipboard(value);
|
|
46688
|
-
return new Promise((
|
|
46761
|
+
return new Promise((resolve6, reject) => {
|
|
46689
46762
|
const { cmd, args, input } = nativeClipboardCommand(value);
|
|
46690
46763
|
let child;
|
|
46691
46764
|
try {
|
|
46692
46765
|
child = spawn2(cmd, args, { stdio: ["pipe", "ignore", "ignore"], windowsHide: true });
|
|
46693
46766
|
} catch (e) {
|
|
46694
|
-
if (wroteOsc52)
|
|
46767
|
+
if (wroteOsc52) resolve6();
|
|
46695
46768
|
else reject(clipboardHelperError(cmd, e));
|
|
46696
46769
|
return;
|
|
46697
46770
|
}
|
|
@@ -46700,7 +46773,7 @@ function copyToClipboard(text) {
|
|
|
46700
46773
|
});
|
|
46701
46774
|
if (!wroteOsc52) {
|
|
46702
46775
|
child.on("close", (code) => {
|
|
46703
|
-
if (code === 0)
|
|
46776
|
+
if (code === 0) resolve6();
|
|
46704
46777
|
else reject(new Error(`${cmd} exited with code ${code}`));
|
|
46705
46778
|
});
|
|
46706
46779
|
}
|
|
@@ -46709,7 +46782,7 @@ function copyToClipboard(text) {
|
|
|
46709
46782
|
child.stdin.end(input);
|
|
46710
46783
|
if (wroteOsc52) {
|
|
46711
46784
|
child.unref?.();
|
|
46712
|
-
|
|
46785
|
+
resolve6();
|
|
46713
46786
|
}
|
|
46714
46787
|
});
|
|
46715
46788
|
}
|
|
@@ -47013,7 +47086,7 @@ function mimeForPath(path2) {
|
|
|
47013
47086
|
return IMAGE_MIME[extname(String(path2 || "")).toLowerCase()] || null;
|
|
47014
47087
|
}
|
|
47015
47088
|
function execFileBuffer(cmd, args, options = {}) {
|
|
47016
|
-
return new Promise((
|
|
47089
|
+
return new Promise((resolve6) => {
|
|
47017
47090
|
execFile(
|
|
47018
47091
|
cmd,
|
|
47019
47092
|
args,
|
|
@@ -47025,7 +47098,7 @@ function execFileBuffer(cmd, args, options = {}) {
|
|
|
47025
47098
|
...options
|
|
47026
47099
|
},
|
|
47027
47100
|
(error, stdout2, stderr) => {
|
|
47028
|
-
|
|
47101
|
+
resolve6({ ok: !error, code: error?.code ?? 0, stdout: stdout2, stderr, error });
|
|
47029
47102
|
}
|
|
47030
47103
|
);
|
|
47031
47104
|
});
|
|
@@ -47518,7 +47591,10 @@ var SPINNER_MODE_OVERRIDE_VERBS = {
|
|
|
47518
47591
|
compacting: "Compacting conversation",
|
|
47519
47592
|
"auto-clear": "Auto-clearing conversation",
|
|
47520
47593
|
resuming: "Resuming conversation",
|
|
47521
|
-
"task-wait": "\uC791\uC5C5 \uB300\uAE30 \uC911"
|
|
47594
|
+
"task-wait": "\uC791\uC5C5 \uB300\uAE30 \uC911",
|
|
47595
|
+
// The request is sent and its response headers are pending: the model is
|
|
47596
|
+
// queued or thinking server-side.
|
|
47597
|
+
"model-thinking": "Model thinking"
|
|
47522
47598
|
};
|
|
47523
47599
|
function spinnerVerbFor(startedAt = 0, now = 0, pool = SPINNER_VERBS) {
|
|
47524
47600
|
const list = Array.isArray(pool) && pool.length ? pool : SPINNER_VERBS;
|
|
@@ -48418,7 +48494,7 @@ function completeOAuthCode(ctx, target, commandText) {
|
|
|
48418
48494
|
}
|
|
48419
48495
|
oauthSubmitRef.current = true;
|
|
48420
48496
|
setProviderPrompt((prompt) => prompt === target ? { ...prompt, submitting: true } : prompt);
|
|
48421
|
-
const completion = typeof target.login?.completeCode === "function" ? new Promise((
|
|
48497
|
+
const completion = typeof target.login?.completeCode === "function" ? new Promise((resolve6) => resolve6(target.login.completeCode(commandText))) : Promise.reject(new Error("OAuth login is no longer active"));
|
|
48422
48498
|
void completion.then(() => {
|
|
48423
48499
|
const successReturn = target.successReturn;
|
|
48424
48500
|
const afterSave = target.afterSave;
|
|
@@ -49738,6 +49814,44 @@ function useSharedTick(intervalMs, isActive = true, onTick2 = null) {
|
|
|
49738
49814
|
}, [intervalMs, isActive]);
|
|
49739
49815
|
}
|
|
49740
49816
|
|
|
49817
|
+
// src/runtime/shared/quiet-progress.mjs
|
|
49818
|
+
var QUIET_PROGRESS_CUE_MS = 12e4;
|
|
49819
|
+
var MODEL_THINKING_STAGE = "model_thinking";
|
|
49820
|
+
var WAIT_BY_STAGE = {
|
|
49821
|
+
connecting: "provider",
|
|
49822
|
+
requesting: "provider",
|
|
49823
|
+
[MODEL_THINKING_STAGE]: "thinking",
|
|
49824
|
+
streaming: "model",
|
|
49825
|
+
tool_running: "tool",
|
|
49826
|
+
resource_wait: "slot",
|
|
49827
|
+
cancelling: "cancel"
|
|
49828
|
+
};
|
|
49829
|
+
function quietProgressParts(quiet, now, warnMs = 0) {
|
|
49830
|
+
const since = Number(quiet?.since) || 0;
|
|
49831
|
+
if (!since) return null;
|
|
49832
|
+
const quietMs = Math.max(0, now - since);
|
|
49833
|
+
if (quietMs < QUIET_PROGRESS_CUE_MS) return null;
|
|
49834
|
+
return {
|
|
49835
|
+
quietMs,
|
|
49836
|
+
minutes: Math.floor(quietMs / 6e4),
|
|
49837
|
+
wait: String(quiet.wait || ""),
|
|
49838
|
+
tool: typeof quiet.tool === "string" ? quiet.tool : "",
|
|
49839
|
+
escalated: Number(warnMs) > 0 && quietMs >= Number(warnMs)
|
|
49840
|
+
};
|
|
49841
|
+
}
|
|
49842
|
+
var WAIT_TEXT = {
|
|
49843
|
+
provider: "waiting on provider",
|
|
49844
|
+
thinking: "model thinking",
|
|
49845
|
+
model: "waiting on model",
|
|
49846
|
+
slot: "waiting for a slot",
|
|
49847
|
+
cancel: "stopping"
|
|
49848
|
+
};
|
|
49849
|
+
function quietProgressLabel(parts) {
|
|
49850
|
+
if (!parts) return "";
|
|
49851
|
+
const wait = parts.wait === "tool" ? `running ${parts.tool || "a tool"}` : WAIT_TEXT[parts.wait] || "";
|
|
49852
|
+
return [`quiet for ${parts.minutes}m`, wait].filter(Boolean).join(" \xB7 ");
|
|
49853
|
+
}
|
|
49854
|
+
|
|
49741
49855
|
// src/tui/spinner-meta.mjs
|
|
49742
49856
|
var compactNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
49743
49857
|
notation: "compact",
|
|
@@ -49773,9 +49887,13 @@ function buildSpinnerMeta({
|
|
|
49773
49887
|
thinkingSince = 0,
|
|
49774
49888
|
thinkingMs = 0,
|
|
49775
49889
|
effort = "",
|
|
49890
|
+
// The turn's published quiet state (`spinner.quiet`) and the clock it is read at.
|
|
49891
|
+
quiet = null,
|
|
49892
|
+
now = Date.now(),
|
|
49776
49893
|
verbose: _verbose = false
|
|
49777
49894
|
} = {}) {
|
|
49778
49895
|
const tokens = Math.max(0, Number(outputTokens) || 0);
|
|
49896
|
+
const quietParts = quietProgressParts(quiet, now, quiet?.warnMs);
|
|
49779
49897
|
const thinkingParts = spinnerThinkingParts({ thinking, thinkingSince, thinkingMs, effort });
|
|
49780
49898
|
const thinkingText = spinnerThinkingLabel({ thinking, thinkingSince, thinkingMs, effort });
|
|
49781
49899
|
return {
|
|
@@ -49788,7 +49906,11 @@ function buildSpinnerMeta({
|
|
|
49788
49906
|
// mid-turn for no reason the reader could see; now both arrive together.
|
|
49789
49907
|
showTokens: tokens > 0,
|
|
49790
49908
|
thinkingText,
|
|
49791
|
-
thinkingActive: Boolean(thinking || Number(thinkingSince) > 0)
|
|
49909
|
+
thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
|
|
49910
|
+
// Quiet-time cue: structured for the desktop's i18n, English for the TUI;
|
|
49911
|
+
// `escalated` once the silence reaches the stall watchdog's warn point.
|
|
49912
|
+
quietParts,
|
|
49913
|
+
quietText: quietProgressLabel(quietParts)
|
|
49792
49914
|
};
|
|
49793
49915
|
}
|
|
49794
49916
|
function isReducedMotion(env4) {
|
|
@@ -49803,6 +49925,7 @@ var INTERRUPT_HINT = "esc to interrupt";
|
|
|
49803
49925
|
var THINKING_DELAY_MS = 3e3;
|
|
49804
49926
|
var GLIMMER_SPEED_MS = {
|
|
49805
49927
|
requesting: 70,
|
|
49928
|
+
"model-thinking": 70,
|
|
49806
49929
|
reconnecting: 70,
|
|
49807
49930
|
compacting: 120,
|
|
49808
49931
|
"auto-clear": 120,
|
|
@@ -49846,7 +49969,9 @@ function tokenModeGlyph(mode) {
|
|
|
49846
49969
|
case "responding":
|
|
49847
49970
|
case "thinking":
|
|
49848
49971
|
return DOWN_ARROW;
|
|
49972
|
+
// The request is sent and nothing has come back yet.
|
|
49849
49973
|
case "requesting":
|
|
49974
|
+
case "model-thinking":
|
|
49850
49975
|
return UP_ARROW;
|
|
49851
49976
|
default:
|
|
49852
49977
|
return "";
|
|
@@ -49862,6 +49987,8 @@ function SpinnerByline({
|
|
|
49862
49987
|
thinkingActiveSince,
|
|
49863
49988
|
thinkingMs,
|
|
49864
49989
|
effort,
|
|
49990
|
+
quiet = null,
|
|
49991
|
+
now = Date.now(),
|
|
49865
49992
|
interruptible,
|
|
49866
49993
|
columns,
|
|
49867
49994
|
reducedMotion,
|
|
@@ -49895,7 +50022,9 @@ function SpinnerByline({
|
|
|
49895
50022
|
thinking,
|
|
49896
50023
|
thinkingSince: thinkingActiveSince,
|
|
49897
50024
|
thinkingMs,
|
|
49898
|
-
effort
|
|
50025
|
+
effort,
|
|
50026
|
+
quiet,
|
|
50027
|
+
now
|
|
49899
50028
|
});
|
|
49900
50029
|
const tokenGlyph = tokenModeGlyph(mode);
|
|
49901
50030
|
let tokenText = "";
|
|
@@ -49914,8 +50043,11 @@ function SpinnerByline({
|
|
|
49914
50043
|
const interruptW = interruptText.length;
|
|
49915
50044
|
const showInterrupt = Boolean(interruptText) && avail > interruptW;
|
|
49916
50045
|
const usedAfterInterrupt = showInterrupt ? interruptW + SEP_WIDTH : 0;
|
|
49917
|
-
const
|
|
49918
|
-
const
|
|
50046
|
+
const quietText = meta.quietText;
|
|
50047
|
+
const showQuiet = Boolean(quietText) && avail > usedAfterInterrupt + quietText.length;
|
|
50048
|
+
const usedAfterQuiet = usedAfterInterrupt + (showQuiet ? quietText.length + SEP_WIDTH : 0);
|
|
50049
|
+
const showThinkingStatus = Boolean(thinkingStatusText) && avail > usedAfterQuiet + thinkingStatusW;
|
|
50050
|
+
const usedAfterThinking = usedAfterQuiet + (showThinkingStatus ? thinkingStatusW + SEP_WIDTH : 0);
|
|
49919
50051
|
const showTimer = Boolean(timerLabel) && avail > usedAfterThinking + timerW;
|
|
49920
50052
|
const usedAfterTimer = usedAfterThinking + (showTimer ? timerW + SEP_WIDTH : 0);
|
|
49921
50053
|
const showTokens = wantsTokens && tokenText && avail > usedAfterTimer + tokenW;
|
|
@@ -49946,6 +50078,11 @@ function SpinnerByline({
|
|
|
49946
50078
|
) }, "thinking-status") : /* @__PURE__ */ jsx2(Text, { color: theme.statusSubtle, children: thinkingStatusText }, "thinking-status")
|
|
49947
50079
|
);
|
|
49948
50080
|
}
|
|
50081
|
+
if (showQuiet) {
|
|
50082
|
+
segments.push(
|
|
50083
|
+
/* @__PURE__ */ jsx2(Text, { color: meta.quietParts?.escalated ? theme.warning : theme.statusSubtle, children: quietText }, "quiet")
|
|
50084
|
+
);
|
|
50085
|
+
}
|
|
49949
50086
|
if (showInterrupt) {
|
|
49950
50087
|
segments.push(
|
|
49951
50088
|
/* @__PURE__ */ jsx2(Text, { color: theme.statusSubtle, children: interruptText }, "interrupt")
|
|
@@ -50083,6 +50220,8 @@ function Spinner({
|
|
|
50083
50220
|
thinkingActiveSince = 0,
|
|
50084
50221
|
thinkingMs = 0,
|
|
50085
50222
|
effort = "",
|
|
50223
|
+
// The turn's quiet state (`spinner.quiet`), shown as the quiet-time cue.
|
|
50224
|
+
quiet = null,
|
|
50086
50225
|
hasActiveTools = false,
|
|
50087
50226
|
paused = false,
|
|
50088
50227
|
interruptible = false,
|
|
@@ -50125,6 +50264,8 @@ function Spinner({
|
|
|
50125
50264
|
thinkingActiveSince,
|
|
50126
50265
|
thinkingMs,
|
|
50127
50266
|
effort,
|
|
50267
|
+
quiet,
|
|
50268
|
+
now,
|
|
50128
50269
|
interruptible,
|
|
50129
50270
|
columns,
|
|
50130
50271
|
reducedMotion,
|
|
@@ -50322,7 +50463,7 @@ function normalizeStatuslineAnsi(text, colors, { reset = RESET2 } = {}) {
|
|
|
50322
50463
|
// src/runtime/shared/statusline/statusline-segments.mjs
|
|
50323
50464
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
50324
50465
|
import { homedir as homedir2 } from "node:os";
|
|
50325
|
-
import { join as
|
|
50466
|
+
import { join as join10 } from "node:path";
|
|
50326
50467
|
|
|
50327
50468
|
// src/runtime/shared/llm/model-catalog.mjs
|
|
50328
50469
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
|
|
@@ -50361,6 +50502,7 @@ var ANTIGRAVITY_MODELS = Object.freeze([
|
|
|
50361
50502
|
low: "gemini-3.1-pro-low",
|
|
50362
50503
|
high: "gemini-3.1-pro-high"
|
|
50363
50504
|
}),
|
|
50505
|
+
fallbackModel("gemini-4-argon", "Gemini 4 Argon", "gemini-pro", 1048576, "gemini-4-argon", ["low", "medium", "high"]),
|
|
50364
50506
|
fallbackModel("claude-opus-4-6-thinking", "Claude Opus 4.6 (Thinking)", null, 25e4, "claude-opus-4-6-thinking", [
|
|
50365
50507
|
"low",
|
|
50366
50508
|
"medium",
|
|
@@ -50914,9 +51056,17 @@ function isPidAlive(value) {
|
|
|
50914
51056
|
}
|
|
50915
51057
|
}
|
|
50916
51058
|
|
|
51059
|
+
// src/runtime/shared/worktrees/git-head.mjs
|
|
51060
|
+
import { readFileSync as readFileSync9, statSync as statSync2, watch } from "node:fs";
|
|
51061
|
+
import { dirname as dirname8, resolve as resolve4 } from "node:path";
|
|
51062
|
+
|
|
51063
|
+
// src/runtime/shared/worktrees/paths.mjs
|
|
51064
|
+
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "node:fs";
|
|
51065
|
+
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join9, relative, resolve as resolve3, sep } from "node:path";
|
|
51066
|
+
|
|
50917
51067
|
// src/runtime/shared/statusline/statusline-segments.mjs
|
|
50918
|
-
var DEFAULT_MIXDOG_HOME = process.env.MIXDOG_HOME ||
|
|
50919
|
-
var DEFAULT_STANDALONE_DATA_DIR =
|
|
51068
|
+
var DEFAULT_MIXDOG_HOME = process.env.MIXDOG_HOME || join10(homedir2(), ".mixdog");
|
|
51069
|
+
var DEFAULT_STANDALONE_DATA_DIR = join10(DEFAULT_MIXDOG_HOME, "data");
|
|
50920
51070
|
var SHELL_JOBS_SEGMENT_CACHE_MS = 1e3;
|
|
50921
51071
|
var FINISHED_SHELL_JOB_TTL_MS = 30 * 60 * 1e3;
|
|
50922
51072
|
var EMPTY_SHELL_JOBS_SESSION = Object.freeze({
|
|
@@ -50963,6 +51113,10 @@ function shellJobsStatus({ clientHostPid, sessionId } = {}) {
|
|
|
50963
51113
|
if (!scoped) return sessions === own.sessions ? own : { ...own, sessions };
|
|
50964
51114
|
return scope && sessions?.[scope] || EMPTY_SHELL_JOBS_SESSION;
|
|
50965
51115
|
}
|
|
51116
|
+
function unconfirmedShellCount(status) {
|
|
51117
|
+
const jobs = Array.isArray(status?.jobs) ? status.jobs : [];
|
|
51118
|
+
return jobs.filter((job) => job?.terminationUnconfirmed === true).length;
|
|
51119
|
+
}
|
|
50966
51120
|
function freshestShellJobsSessions() {
|
|
50967
51121
|
let freshest = null;
|
|
50968
51122
|
for (const entry of _shellJobsSegmentCache.values()) {
|
|
@@ -50973,7 +51127,7 @@ function freshestShellJobsSessions() {
|
|
|
50973
51127
|
async function refreshShellJobsStatus(ownerPid) {
|
|
50974
51128
|
let value = EMPTY_SHELL_JOBS;
|
|
50975
51129
|
try {
|
|
50976
|
-
const dir =
|
|
51130
|
+
const dir = join10(dataDir(), "shell-jobs");
|
|
50977
51131
|
let names;
|
|
50978
51132
|
try {
|
|
50979
51133
|
names = await readdir(dir);
|
|
@@ -50985,17 +51139,19 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
50985
51139
|
let count = 0;
|
|
50986
51140
|
let oldestMs = Infinity;
|
|
50987
51141
|
const jobs = [];
|
|
51142
|
+
const orphaned = [];
|
|
50988
51143
|
const bySession = /* @__PURE__ */ new Map();
|
|
50989
51144
|
for (const id of ids) {
|
|
50990
|
-
const p =
|
|
51145
|
+
const p = join10(dir, `${id}.json`);
|
|
50991
51146
|
let detail;
|
|
50992
51147
|
try {
|
|
50993
51148
|
detail = JSON.parse(await readFile(p, "utf-8"));
|
|
50994
51149
|
} catch {
|
|
50995
51150
|
continue;
|
|
50996
51151
|
}
|
|
50997
|
-
|
|
50998
|
-
if (detail
|
|
51152
|
+
const unconfirmed = detail?.terminationUnconfirmed === true;
|
|
51153
|
+
if (unconfirmed ? !isPidAlive(ownerByJob.get(id) || 0) : !await isShellJobAlive(detail, p, dir, id)) continue;
|
|
51154
|
+
if (detail?.foreground === true && !unconfirmed) continue;
|
|
50999
51155
|
const ownedByThisHost = ownerByJob.get(id) === ownerPid;
|
|
51000
51156
|
if (ownedByThisHost) count++;
|
|
51001
51157
|
let jobMs = Infinity;
|
|
@@ -51010,9 +51166,11 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51010
51166
|
taskId: id,
|
|
51011
51167
|
command: String(detail?.command || "").trim(),
|
|
51012
51168
|
cwd: String(detail?.cwd || "").trim(),
|
|
51013
|
-
startedAt: detail?.startedAt || (Number.isFinite(jobMs) ? jobMs : null)
|
|
51169
|
+
startedAt: detail?.startedAt || (Number.isFinite(jobMs) ? jobMs : null),
|
|
51170
|
+
...unconfirmed ? { terminationUnconfirmed: true } : {}
|
|
51014
51171
|
};
|
|
51015
51172
|
if (ownedByThisHost) jobs.push(job);
|
|
51173
|
+
if (unconfirmed && detail?.ownerSessionClosed === true) orphaned.push(job);
|
|
51016
51174
|
if (!owner) continue;
|
|
51017
51175
|
const bucket = bySession.get(owner) || { count: 0, oldestMs: Infinity, jobs: [], finished: [] };
|
|
51018
51176
|
bucket.count += 1;
|
|
@@ -51024,7 +51182,7 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51024
51182
|
for (const id of doneIds) {
|
|
51025
51183
|
let detail;
|
|
51026
51184
|
try {
|
|
51027
|
-
detail = JSON.parse(await readFile(
|
|
51185
|
+
detail = JSON.parse(await readFile(join10(dir, `${id}.json`), "utf-8"));
|
|
51028
51186
|
} catch {
|
|
51029
51187
|
continue;
|
|
51030
51188
|
}
|
|
@@ -51046,6 +51204,7 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51046
51204
|
bySession.set(owner, bucket);
|
|
51047
51205
|
}
|
|
51048
51206
|
if (count || bySession.size) value = summarizeShellJobs({ count, oldestMs, jobs, bySession });
|
|
51207
|
+
if (orphaned.length) value = { ...value, orphaned };
|
|
51049
51208
|
} catch {
|
|
51050
51209
|
value = EMPTY_SHELL_JOBS;
|
|
51051
51210
|
}
|
|
@@ -51086,7 +51245,7 @@ async function isShellJobAlive(detail, detailPath, dir, id) {
|
|
|
51086
51245
|
try {
|
|
51087
51246
|
const st = await stat(detailPath);
|
|
51088
51247
|
const timeoutMs = Number(detail?.timeoutMs);
|
|
51089
|
-
const enforced = detail?.timeoutEnforced === true || await stat(
|
|
51248
|
+
const enforced = detail?.timeoutEnforced === true || await stat(join10(dir, `${id}.enforced`)).then(
|
|
51090
51249
|
() => true,
|
|
51091
51250
|
() => false
|
|
51092
51251
|
);
|
|
@@ -51270,11 +51429,17 @@ function localStatusLineL2({ agentWorkers = [], agentJobs = [], activeTools = nu
|
|
|
51270
51429
|
}
|
|
51271
51430
|
const shellScope = String(sessionId ?? "").trim();
|
|
51272
51431
|
const shellStatus = shellScope ? shellJobsStatus({ clientHostPid, sessionId: shellScope }) : shellJobsStatus({ clientHostPid });
|
|
51273
|
-
const
|
|
51432
|
+
const unconfirmed = unconfirmedShellCount(shellStatus);
|
|
51433
|
+
const shellCount = (Number(shellStatus?.count) || 0) - unconfirmed;
|
|
51274
51434
|
if (shellCount > 0) {
|
|
51275
51435
|
const label = `Running ${shellCount} Shell${shellCount === 1 ? "" : "s"}`;
|
|
51276
51436
|
l2Parts.push(`${spin} ${STATUS}${label}${RESET3}${elapsedSuffix(shellStatus.elapsedLabel || "")}`);
|
|
51277
51437
|
}
|
|
51438
|
+
if (unconfirmed > 0) {
|
|
51439
|
+
const { WARNING } = statusColors();
|
|
51440
|
+
const label = `\u26A0 ${unconfirmed} Shell${unconfirmed === 1 ? "" : "s"} termination unconfirmed`;
|
|
51441
|
+
l2Parts.push(`${WARNING}${label}${RESET3} ${SUBTLE}\xB7${RESET3} /shells`);
|
|
51442
|
+
}
|
|
51278
51443
|
const tools = activeTools && typeof activeTools === "object" ? activeTools : {};
|
|
51279
51444
|
const searchInfo = tools.web_search || null;
|
|
51280
51445
|
if (searchInfo && num(searchInfo.count) > 0) {
|
|
@@ -55442,7 +55607,7 @@ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionP
|
|
|
55442
55607
|
toolApproval.id
|
|
55443
55608
|
);
|
|
55444
55609
|
}
|
|
55445
|
-
const
|
|
55610
|
+
const resolve6 = (approved) => {
|
|
55446
55611
|
store.resolveToolApproval?.(toolApproval.id, {
|
|
55447
55612
|
approved,
|
|
55448
55613
|
reason: approved ? "approved by user" : "denied by user"
|
|
@@ -55467,12 +55632,12 @@ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionP
|
|
|
55467
55632
|
description: "run this tool call"
|
|
55468
55633
|
}
|
|
55469
55634
|
],
|
|
55470
|
-
onSelect: (value) =>
|
|
55471
|
-
onCancel: () =>
|
|
55635
|
+
onSelect: (value) => resolve6(value === "approve"),
|
|
55636
|
+
onCancel: () => resolve6(false),
|
|
55472
55637
|
onKey: (input) => {
|
|
55473
55638
|
const value = String(input || "").trim().toLowerCase();
|
|
55474
|
-
if (value === "a" || value === "y")
|
|
55475
|
-
else if (value === "d" || value === "n")
|
|
55639
|
+
if (value === "a" || value === "y") resolve6(true);
|
|
55640
|
+
else if (value === "d" || value === "n") resolve6(false);
|
|
55476
55641
|
},
|
|
55477
55642
|
title: "Tool approval",
|
|
55478
55643
|
description: toolApprovalDescription(toolApproval),
|
|
@@ -56646,6 +56811,7 @@ function renderAppView(ctx) {
|
|
|
56646
56811
|
thinkingActiveSince: liveSpinner?.thinkingSegmentStartedAt ?? 0,
|
|
56647
56812
|
thinkingMs: liveSpinner?.thinkingAccumulatedMs ?? 0,
|
|
56648
56813
|
effort: state.effort || "",
|
|
56814
|
+
quiet: liveSpinner?.quiet ?? null,
|
|
56649
56815
|
hasActiveTools: !!activeTools?.web_search?.count,
|
|
56650
56816
|
paused: !!toolApproval,
|
|
56651
56817
|
interruptible: !!(state.busy && state.spinner?.active),
|
|
@@ -56729,7 +56895,7 @@ function renderAppView(ctx) {
|
|
|
56729
56895
|
StatusLine,
|
|
56730
56896
|
{
|
|
56731
56897
|
sessionId: state.sessionId,
|
|
56732
|
-
clientHostPid: state.
|
|
56898
|
+
clientHostPid: state.clientHostPid,
|
|
56733
56899
|
provider: state.provider,
|
|
56734
56900
|
model: state.model,
|
|
56735
56901
|
effort: state.effort,
|
|
@@ -59356,7 +59522,7 @@ function createOnboardingSteps({
|
|
|
59356
59522
|
import { spawn as spawn3 } from "node:child_process";
|
|
59357
59523
|
|
|
59358
59524
|
// src/runtime/shared/wsl.mjs
|
|
59359
|
-
import { readFileSync as
|
|
59525
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
59360
59526
|
var _isWSL;
|
|
59361
59527
|
function isWSL() {
|
|
59362
59528
|
if (_isWSL !== void 0) return _isWSL;
|
|
@@ -59369,7 +59535,7 @@ function isWSL() {
|
|
|
59369
59535
|
return _isWSL;
|
|
59370
59536
|
}
|
|
59371
59537
|
try {
|
|
59372
|
-
const v =
|
|
59538
|
+
const v = readFileSync10("/proc/version", "utf8").toLowerCase();
|
|
59373
59539
|
_isWSL = v.includes("microsoft") || v.includes("wsl");
|
|
59374
59540
|
} catch {
|
|
59375
59541
|
_isWSL = false;
|
|
@@ -59476,6 +59642,20 @@ function buildProviderItems(setup) {
|
|
|
59476
59642
|
_authenticated: p.authenticated
|
|
59477
59643
|
});
|
|
59478
59644
|
}
|
|
59645
|
+
if (setup.managedByClient === true) {
|
|
59646
|
+
for (const p of setup.local || []) {
|
|
59647
|
+
providerItems.push({
|
|
59648
|
+
value: `local:${p.id}`,
|
|
59649
|
+
label: p.name,
|
|
59650
|
+
meta: providerStatusLabel(p),
|
|
59651
|
+
description: "",
|
|
59652
|
+
_type: "local",
|
|
59653
|
+
_providerId: p.id,
|
|
59654
|
+
_providerName: p.name,
|
|
59655
|
+
_provider: p
|
|
59656
|
+
});
|
|
59657
|
+
}
|
|
59658
|
+
}
|
|
59479
59659
|
providerItems.sort((a, b) => {
|
|
59480
59660
|
const rank = providerItemRank(a) - providerItemRank(b);
|
|
59481
59661
|
if (rank !== 0) return rank;
|
|
@@ -59801,8 +59981,8 @@ function createProviderSetupPicker({
|
|
|
59801
59981
|
}
|
|
59802
59982
|
});
|
|
59803
59983
|
try {
|
|
59804
|
-
await new Promise((
|
|
59805
|
-
return await store.getProviderSetup();
|
|
59984
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
59985
|
+
return await store.getProviderSetup(options.forceRefresh ? { force: true } : void 0);
|
|
59806
59986
|
} catch (e) {
|
|
59807
59987
|
store.pushNotice(`providers failed: ${e?.message || e}`, "error");
|
|
59808
59988
|
return null;
|
|
@@ -59833,6 +60013,9 @@ function createProviderSetupPicker({
|
|
|
59833
60013
|
});
|
|
59834
60014
|
}
|
|
59835
60015
|
items.push(...buildProviderItems(setup));
|
|
60016
|
+
if (setup.managedByClient === true) {
|
|
60017
|
+
items.push({ value: "refresh-client-providers", label: "Refresh", _type: "refresh-client-providers" });
|
|
60018
|
+
}
|
|
59836
60019
|
const flow = {
|
|
59837
60020
|
store,
|
|
59838
60021
|
setProviderPrompt,
|
|
@@ -59858,10 +60041,10 @@ function createProviderSetupPicker({
|
|
|
59858
60041
|
};
|
|
59859
60042
|
flow.paint({
|
|
59860
60043
|
title: options.title || "Providers",
|
|
59861
|
-
description: options.description || "Choose a provider. Enter opens provider actions.",
|
|
60044
|
+
description: setup.managedByClient === true ? "Manage provider sign-ins and accounts in the local desktop window. Refresh to update availability." : options.description || "Choose a provider. Enter opens provider actions.",
|
|
59862
60045
|
footer: providerFooter,
|
|
59863
60046
|
footerGapRows: 1,
|
|
59864
|
-
help: options.confirmBar ? void 0 : "\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc Back",
|
|
60047
|
+
help: options.confirmBar ? void 0 : setup.managedByClient === true ? "\u2191/\u2193 Select \xB7 Enter Refresh \xB7 Esc Back" : "\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc Back",
|
|
59865
60048
|
indexMode: "always",
|
|
59866
60049
|
labelWidth: 18,
|
|
59867
60050
|
metaWidth: 12,
|
|
@@ -59873,6 +60056,12 @@ function createProviderSetupPicker({
|
|
|
59873
60056
|
if (item?._providerId) flow.rememberProviderSelection(item);
|
|
59874
60057
|
},
|
|
59875
60058
|
onSelect: (_value, item) => {
|
|
60059
|
+
if (setup.managedByClient === true && item._type !== "continue") {
|
|
60060
|
+
if (item._type === "refresh-client-providers") {
|
|
60061
|
+
void openProviderSetupPicker({ ...options, preloadedSetup: null, forceRefresh: true });
|
|
60062
|
+
}
|
|
60063
|
+
return;
|
|
60064
|
+
}
|
|
59876
60065
|
flow.releaseSurface();
|
|
59877
60066
|
if (item._type === "continue") {
|
|
59878
60067
|
onContinue?.();
|
|
@@ -59914,7 +60103,7 @@ function createModelCatalog({ store, providerModelsCacheRef, webSearchModelsCach
|
|
|
59914
60103
|
let renderedQuickModels = false;
|
|
59915
60104
|
if (!providerModels.length || options.refreshModels === true) {
|
|
59916
60105
|
paintLoading();
|
|
59917
|
-
await new Promise((
|
|
60106
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
59918
60107
|
try {
|
|
59919
60108
|
if (options.refreshModels !== true && options.cacheRef !== "webSearch") {
|
|
59920
60109
|
refreshModelsPromise = Promise.resolve(loadModels({ force: false }));
|
|
@@ -60915,8 +61104,8 @@ function createSettingsNavigation({ openers, openSettingsPicker, setSettingsProm
|
|
|
60915
61104
|
}
|
|
60916
61105
|
|
|
60917
61106
|
// src/runtime/shared/config.mjs
|
|
60918
|
-
import { readFileSync as
|
|
60919
|
-
import { join as
|
|
61107
|
+
import { readFileSync as readFileSync12, statSync as statSync4, mkdirSync as mkdirSync5, existsSync as existsSync11, watch as fsWatch } from "node:fs";
|
|
61108
|
+
import { join as join12, dirname as dirname10 } from "node:path";
|
|
60920
61109
|
import { createRequire as createRequire3 } from "node:module";
|
|
60921
61110
|
|
|
60922
61111
|
// src/runtime/shared/object.mjs
|
|
@@ -60933,12 +61122,12 @@ init_atomic_file();
|
|
|
60933
61122
|
// src/runtime/shared/user-data-guard.mjs
|
|
60934
61123
|
import {
|
|
60935
61124
|
copyFileSync,
|
|
60936
|
-
existsSync as
|
|
61125
|
+
existsSync as existsSync10,
|
|
60937
61126
|
mkdirSync as mkdirSync4,
|
|
60938
61127
|
readdirSync as readdirSync2,
|
|
60939
|
-
readFileSync as
|
|
61128
|
+
readFileSync as readFileSync11,
|
|
60940
61129
|
rmSync,
|
|
60941
|
-
statSync as
|
|
61130
|
+
statSync as statSync3,
|
|
60942
61131
|
writeFileSync as writeFileSync4
|
|
60943
61132
|
} from "node:fs";
|
|
60944
61133
|
import {
|
|
@@ -60948,11 +61137,11 @@ import {
|
|
|
60948
61137
|
rm as rmP,
|
|
60949
61138
|
stat as statP
|
|
60950
61139
|
} from "node:fs/promises";
|
|
60951
|
-
import { basename as basename5, dirname as
|
|
61140
|
+
import { basename as basename5, dirname as dirname9, join as join11, resolve as resolve5 } from "node:path";
|
|
60952
61141
|
import { homedir as homedir3 } from "node:os";
|
|
60953
61142
|
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
60954
61143
|
function getBackupRoot() {
|
|
60955
|
-
return process.env.MIXDOG_USER_DATA_BACKUP_ROOT ||
|
|
61144
|
+
return process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join11(process.env.MIXDOG_HOME || process.env.MIXDOG_CONFIG_DIR || mixdogHome(), "backups", "user-data");
|
|
60956
61145
|
}
|
|
60957
61146
|
var USER_DATA_FILES = ["mixdog-config.json"];
|
|
60958
61147
|
var USER_DATA_DIRS = ["schedules", "webhooks", "workflows"];
|
|
@@ -60960,12 +61149,12 @@ var BACKUP_MANIFEST = "backup.json";
|
|
|
60960
61149
|
var INIT_MARKER = ".mixdog-user-data.json";
|
|
60961
61150
|
var SCOPE_PREFIX = "scope-";
|
|
60962
61151
|
function normalizeDataDir(dataDir2) {
|
|
60963
|
-
const full =
|
|
61152
|
+
const full = resolve5(String(dataDir2));
|
|
60964
61153
|
return process.platform === "win32" ? full.toLowerCase() : full;
|
|
60965
61154
|
}
|
|
60966
61155
|
function scopeDirFor(dataDir2) {
|
|
60967
61156
|
const id = createHash4("sha256").update(normalizeDataDir(dataDir2)).digest("hex").slice(0, 16);
|
|
60968
|
-
return
|
|
61157
|
+
return join11(getBackupRoot(), `${SCOPE_PREFIX}${id}`);
|
|
60969
61158
|
}
|
|
60970
61159
|
function stamp() {
|
|
60971
61160
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -60976,7 +61165,7 @@ function safeReason(reason) {
|
|
|
60976
61165
|
function readInitInstanceId(dataDir2) {
|
|
60977
61166
|
if (!dataDir2) return null;
|
|
60978
61167
|
try {
|
|
60979
|
-
const marker = JSON.parse(
|
|
61168
|
+
const marker = JSON.parse(readFileSync11(join11(dataDir2, INIT_MARKER), "utf8"));
|
|
60980
61169
|
return typeof marker?.instanceId === "string" && marker.instanceId ? marker.instanceId : null;
|
|
60981
61170
|
} catch {
|
|
60982
61171
|
return null;
|
|
@@ -60986,13 +61175,13 @@ function hasUserDataInitMarker(dataDir2) {
|
|
|
60986
61175
|
return readInitInstanceId(dataDir2) != null;
|
|
60987
61176
|
}
|
|
60988
61177
|
function legacyBackupRoots() {
|
|
60989
|
-
const legacy = process.env.MIXDOG_USER_DATA_BACKUP_ROOT ||
|
|
61178
|
+
const legacy = process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join11(process.env.MIXDOG_CONFIG_DIR || join11(homedir3(), ".mixdog"), "backups", "user-data");
|
|
60990
61179
|
const current = getBackupRoot();
|
|
60991
61180
|
return normalizeDataDir(legacy) === normalizeDataDir(current) ? [current] : [current, legacy];
|
|
60992
61181
|
}
|
|
60993
61182
|
function manifestDataDirMatches(backupDir, dataDirKey) {
|
|
60994
61183
|
try {
|
|
60995
|
-
const manifest = JSON.parse(
|
|
61184
|
+
const manifest = JSON.parse(readFileSync11(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
60996
61185
|
return typeof manifest?.dataDir === "string" && normalizeDataDir(manifest.dataDir) === dataDirKey;
|
|
60997
61186
|
} catch {
|
|
60998
61187
|
return false;
|
|
@@ -61000,7 +61189,7 @@ function manifestDataDirMatches(backupDir, dataDirKey) {
|
|
|
61000
61189
|
}
|
|
61001
61190
|
function legacyMarkersFor(root, dataDir2, dataDirKey) {
|
|
61002
61191
|
const hashed = new Set(
|
|
61003
|
-
[String(dataDir2),
|
|
61192
|
+
[String(dataDir2), resolve5(String(dataDir2))].map(
|
|
61004
61193
|
(value) => `.initialized-${createHash4("sha256").update(value).digest("hex").slice(0, 16)}.json`
|
|
61005
61194
|
)
|
|
61006
61195
|
);
|
|
@@ -61013,12 +61202,12 @@ function legacyMarkersFor(root, dataDir2, dataDirKey) {
|
|
|
61013
61202
|
return names.filter((name) => {
|
|
61014
61203
|
if (hashed.has(name)) return true;
|
|
61015
61204
|
try {
|
|
61016
|
-
const marker = JSON.parse(
|
|
61205
|
+
const marker = JSON.parse(readFileSync11(join11(root, name), "utf8"));
|
|
61017
61206
|
return typeof marker?.dataDir === "string" && normalizeDataDir(marker.dataDir) === dataDirKey;
|
|
61018
61207
|
} catch {
|
|
61019
61208
|
return false;
|
|
61020
61209
|
}
|
|
61021
|
-
}).map((name) =>
|
|
61210
|
+
}).map((name) => join11(root, name));
|
|
61022
61211
|
}
|
|
61023
61212
|
function findLegacyUserDataEvidence(dataDir2, { fresh = false } = {}) {
|
|
61024
61213
|
if (!dataDir2 || hasUserDataInitMarker(dataDir2)) return null;
|
|
@@ -61039,7 +61228,7 @@ function scanLegacyUserDataEvidence(dataDir2, key) {
|
|
|
61039
61228
|
markers.push(...legacyMarkersFor(root, dataDir2, key));
|
|
61040
61229
|
for (const name of backupDirsNewestFirst(root)) {
|
|
61041
61230
|
if (name.startsWith(SCOPE_PREFIX)) continue;
|
|
61042
|
-
if (manifestDataDirMatches(
|
|
61231
|
+
if (manifestDataDirMatches(join11(root, name), key)) backups.push(join11(root, name));
|
|
61043
61232
|
}
|
|
61044
61233
|
}
|
|
61045
61234
|
backups.sort((x, y) => basename5(y).localeCompare(basename5(x)));
|
|
@@ -61063,10 +61252,10 @@ function backupDirsNewestFirst(dir) {
|
|
|
61063
61252
|
}
|
|
61064
61253
|
function readRestorableConfig(backupDir, dataDirKey, instanceId) {
|
|
61065
61254
|
try {
|
|
61066
|
-
const manifest = JSON.parse(
|
|
61255
|
+
const manifest = JSON.parse(readFileSync11(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
61067
61256
|
if (typeof manifest?.dataDir !== "string" || normalizeDataDir(manifest.dataDir) !== dataDirKey) return null;
|
|
61068
61257
|
if (manifest.instanceId !== instanceId) return null;
|
|
61069
|
-
const parsed = JSON.parse(
|
|
61258
|
+
const parsed = JSON.parse(readFileSync11(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61070
61259
|
return isStructurallyCompleteMixdogConfigBackup(parsed) ? parsed : null;
|
|
61071
61260
|
} catch {
|
|
61072
61261
|
return null;
|
|
@@ -61076,13 +61265,13 @@ function findRestorableConfig(dataDir2, instanceId) {
|
|
|
61076
61265
|
const key = normalizeDataDir(dataDir2);
|
|
61077
61266
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61078
61267
|
for (const name of backupDirsNewestFirst(scopeDir)) {
|
|
61079
|
-
const parsed = readRestorableConfig(
|
|
61268
|
+
const parsed = readRestorableConfig(join11(scopeDir, name), key, instanceId);
|
|
61080
61269
|
if (parsed) return parsed;
|
|
61081
61270
|
}
|
|
61082
61271
|
const root = getBackupRoot();
|
|
61083
61272
|
for (const name of backupDirsNewestFirst(root)) {
|
|
61084
61273
|
if (name.startsWith(SCOPE_PREFIX)) continue;
|
|
61085
|
-
const parsed = readRestorableConfig(
|
|
61274
|
+
const parsed = readRestorableConfig(join11(root, name), key, instanceId);
|
|
61086
61275
|
if (parsed) return parsed;
|
|
61087
61276
|
}
|
|
61088
61277
|
return null;
|
|
@@ -61104,7 +61293,7 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61104
61293
|
const evidence = findLegacyUserDataEvidence(dataDir2, options);
|
|
61105
61294
|
for (const backupDir of evidence?.backups || []) {
|
|
61106
61295
|
try {
|
|
61107
|
-
const parsed = JSON.parse(
|
|
61296
|
+
const parsed = JSON.parse(readFileSync11(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61108
61297
|
if (isStructurallyCompleteMixdogConfigBackup(parsed)) return parsed;
|
|
61109
61298
|
} catch {
|
|
61110
61299
|
}
|
|
@@ -61112,40 +61301,40 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61112
61301
|
return null;
|
|
61113
61302
|
}
|
|
61114
61303
|
function copyTree(src, dst, copied) {
|
|
61115
|
-
const st =
|
|
61304
|
+
const st = statSync3(src);
|
|
61116
61305
|
if (st.isDirectory()) {
|
|
61117
61306
|
for (const name of readdirSync2(src)) {
|
|
61118
|
-
copyTree(
|
|
61307
|
+
copyTree(join11(src, name), join11(dst, name), copied);
|
|
61119
61308
|
}
|
|
61120
61309
|
return;
|
|
61121
61310
|
}
|
|
61122
61311
|
if (!st.isFile()) return;
|
|
61123
|
-
mkdirSync4(
|
|
61312
|
+
mkdirSync4(dirname9(dst), { recursive: true });
|
|
61124
61313
|
copyFileSync(src, dst);
|
|
61125
61314
|
copied.push(dst);
|
|
61126
61315
|
}
|
|
61127
61316
|
function pruneBackups(scopeDir, keep = 40) {
|
|
61128
61317
|
for (const name of backupDirsNewestFirst(scopeDir).slice(keep)) {
|
|
61129
61318
|
try {
|
|
61130
|
-
rmSync(
|
|
61319
|
+
rmSync(join11(scopeDir, name), { recursive: true, force: true });
|
|
61131
61320
|
} catch {
|
|
61132
61321
|
}
|
|
61133
61322
|
}
|
|
61134
61323
|
}
|
|
61135
61324
|
function markUserDataInitialized(dataDir2) {
|
|
61136
61325
|
const existing = readInitInstanceId(dataDir2);
|
|
61137
|
-
if (existing || !dataDir2 || !
|
|
61326
|
+
if (existing || !dataDir2 || !existsSync10(dataDir2)) return existing;
|
|
61138
61327
|
try {
|
|
61139
61328
|
writeFileSync4(
|
|
61140
|
-
|
|
61329
|
+
join11(dataDir2, INIT_MARKER),
|
|
61141
61330
|
`${JSON.stringify(
|
|
61142
|
-
{ instanceId: randomUUID(), dataDir:
|
|
61331
|
+
{ instanceId: randomUUID(), dataDir: resolve5(dataDir2), createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
61143
61332
|
null,
|
|
61144
61333
|
2
|
|
61145
61334
|
)}
|
|
61146
61335
|
`,
|
|
61147
61336
|
// An unreadable marker is replaced; a concurrent creator's valid one wins.
|
|
61148
|
-
{ encoding: "utf8", flag:
|
|
61337
|
+
{ encoding: "utf8", flag: existsSync10(join11(dataDir2, INIT_MARKER)) ? "w" : "wx" }
|
|
61149
61338
|
);
|
|
61150
61339
|
} catch {
|
|
61151
61340
|
}
|
|
@@ -61164,14 +61353,14 @@ function skipBackups() {
|
|
|
61164
61353
|
}
|
|
61165
61354
|
function backupTarget(dataDir2, reason) {
|
|
61166
61355
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61167
|
-
return { scopeDir, backupDir:
|
|
61356
|
+
return { scopeDir, backupDir: join11(scopeDir, `${stamp()}-${safeReason(reason)}`) };
|
|
61168
61357
|
}
|
|
61169
61358
|
function finishBackup(dataDir2, backupDir, reason) {
|
|
61170
61359
|
const instanceId = markUserDataInitialized(dataDir2);
|
|
61171
61360
|
writeFileSync4(
|
|
61172
|
-
|
|
61361
|
+
join11(backupDir, BACKUP_MANIFEST),
|
|
61173
61362
|
`${JSON.stringify(
|
|
61174
|
-
{ dataDir:
|
|
61363
|
+
{ dataDir: resolve5(dataDir2), instanceId, reason, createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
61175
61364
|
null,
|
|
61176
61365
|
2
|
|
61177
61366
|
)}
|
|
@@ -61183,16 +61372,16 @@ function finishBackup(dataDir2, backupDir, reason) {
|
|
|
61183
61372
|
}
|
|
61184
61373
|
function backupUserData(dataDir2, reason = "snapshot") {
|
|
61185
61374
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61186
|
-
if (!dataDir2 || !
|
|
61375
|
+
if (!dataDir2 || !existsSync10(dataDir2)) return { dir: null, copied: [] };
|
|
61187
61376
|
const { scopeDir, backupDir } = backupTarget(dataDir2, reason);
|
|
61188
61377
|
const copied = [];
|
|
61189
61378
|
for (const rel of USER_DATA_FILES) {
|
|
61190
|
-
const src =
|
|
61191
|
-
if (
|
|
61379
|
+
const src = join11(dataDir2, rel);
|
|
61380
|
+
if (existsSync10(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
61192
61381
|
}
|
|
61193
61382
|
for (const rel of USER_DATA_DIRS) {
|
|
61194
|
-
const src =
|
|
61195
|
-
if (
|
|
61383
|
+
const src = join11(dataDir2, rel);
|
|
61384
|
+
if (existsSync10(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
61196
61385
|
}
|
|
61197
61386
|
if (copied.length > 0) {
|
|
61198
61387
|
finishBackup(dataDir2, backupDir, reason);
|
|
@@ -61208,12 +61397,12 @@ async function copyTreeAsync(src, dst, copied) {
|
|
|
61208
61397
|
const st = await statP(src);
|
|
61209
61398
|
if (st.isDirectory()) {
|
|
61210
61399
|
for (const name of await readdirP(src)) {
|
|
61211
|
-
await copyTreeAsync(
|
|
61400
|
+
await copyTreeAsync(join11(src, name), join11(dst, name), copied);
|
|
61212
61401
|
}
|
|
61213
61402
|
return;
|
|
61214
61403
|
}
|
|
61215
61404
|
if (!st.isFile()) return;
|
|
61216
|
-
await mkdirP(
|
|
61405
|
+
await mkdirP(dirname9(dst), { recursive: true });
|
|
61217
61406
|
await copyFileP(src, dst);
|
|
61218
61407
|
copied.push(dst);
|
|
61219
61408
|
}
|
|
@@ -61226,23 +61415,23 @@ async function pruneBackupsAsync(scopeDir, keep = 40) {
|
|
|
61226
61415
|
}
|
|
61227
61416
|
for (const name of entries.slice(keep)) {
|
|
61228
61417
|
try {
|
|
61229
|
-
await rmP(
|
|
61418
|
+
await rmP(join11(scopeDir, name), { recursive: true, force: true });
|
|
61230
61419
|
} catch {
|
|
61231
61420
|
}
|
|
61232
61421
|
}
|
|
61233
61422
|
}
|
|
61234
61423
|
async function backupUserDataAsync(dataDir2, reason = "snapshot") {
|
|
61235
61424
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61236
|
-
if (!dataDir2 || !
|
|
61425
|
+
if (!dataDir2 || !existsSync10(dataDir2)) return { dir: null, copied: [] };
|
|
61237
61426
|
const { scopeDir, backupDir } = backupTarget(dataDir2, reason);
|
|
61238
61427
|
const copied = [];
|
|
61239
61428
|
for (const rel of USER_DATA_FILES) {
|
|
61240
|
-
const src =
|
|
61241
|
-
if (
|
|
61429
|
+
const src = join11(dataDir2, rel);
|
|
61430
|
+
if (existsSync10(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
61242
61431
|
}
|
|
61243
61432
|
for (const rel of USER_DATA_DIRS) {
|
|
61244
|
-
const src =
|
|
61245
|
-
if (
|
|
61433
|
+
const src = join11(dataDir2, rel);
|
|
61434
|
+
if (existsSync10(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
61246
61435
|
}
|
|
61247
61436
|
if (copied.length > 0) {
|
|
61248
61437
|
finishBackup(dataDir2, backupDir, reason);
|
|
@@ -61287,7 +61476,7 @@ var {
|
|
|
61287
61476
|
onKeychainRecovered: _onKeychainRecovered
|
|
61288
61477
|
} = _require("../../lib/keychain-cjs.cjs");
|
|
61289
61478
|
function configPath() {
|
|
61290
|
-
return
|
|
61479
|
+
return join12(resolvePluginData(), "mixdog-config.json");
|
|
61291
61480
|
}
|
|
61292
61481
|
var GENERATED_KEY = "_generated";
|
|
61293
61482
|
var DEFAULTS_VERSION = 2;
|
|
@@ -61316,7 +61505,7 @@ function readConfigRawCached() {
|
|
|
61316
61505
|
return _configReadCache.raw;
|
|
61317
61506
|
}
|
|
61318
61507
|
try {
|
|
61319
|
-
const st2 =
|
|
61508
|
+
const st2 = statSync4(configPath());
|
|
61320
61509
|
if (st2.mtimeMs === _configReadCache.mtimeMs && st2.size === _configReadCache.size) {
|
|
61321
61510
|
_configReadCache.atMs = now;
|
|
61322
61511
|
return _configReadCache.raw;
|
|
@@ -61326,7 +61515,7 @@ function readConfigRawCached() {
|
|
|
61326
61515
|
}
|
|
61327
61516
|
let st = null;
|
|
61328
61517
|
try {
|
|
61329
|
-
st =
|
|
61518
|
+
st = statSync4(configPath());
|
|
61330
61519
|
} catch (err) {
|
|
61331
61520
|
if (err.code === "ENOENT") {
|
|
61332
61521
|
_configReadCache = null;
|
|
@@ -61338,7 +61527,7 @@ function readConfigRawCached() {
|
|
|
61338
61527
|
}
|
|
61339
61528
|
let raw;
|
|
61340
61529
|
try {
|
|
61341
|
-
raw =
|
|
61530
|
+
raw = readFileSync12(configPath(), "utf8");
|
|
61342
61531
|
} catch (err) {
|
|
61343
61532
|
if (err.code === "ENOENT") {
|
|
61344
61533
|
_configReadCache = null;
|
|
@@ -61413,7 +61602,7 @@ function readConfigFile() {
|
|
|
61413
61602
|
}
|
|
61414
61603
|
}
|
|
61415
61604
|
function writeConfigFile(data, postBackupReason = "post-config-write") {
|
|
61416
|
-
mkdirSync5(
|
|
61605
|
+
mkdirSync5(dirname10(configPath()), { recursive: true, mode: 448 });
|
|
61417
61606
|
try {
|
|
61418
61607
|
backupUserData(resolvePluginData(), "pre-config-write");
|
|
61419
61608
|
} catch {
|
|
@@ -61437,7 +61626,7 @@ function persistRestoredConfig(restored) {
|
|
|
61437
61626
|
const wrote = withFileLockSync(
|
|
61438
61627
|
`${path2}.lock`,
|
|
61439
61628
|
() => {
|
|
61440
|
-
if (
|
|
61629
|
+
if (existsSync11(path2)) return false;
|
|
61441
61630
|
writeAll(restored, "post-restore");
|
|
61442
61631
|
return true;
|
|
61443
61632
|
},
|
|
@@ -61479,7 +61668,7 @@ function readAll() {
|
|
|
61479
61668
|
function quarantineMalformedConfig(parseErr) {
|
|
61480
61669
|
const corrupt = `${configPath()}.corrupt-${Date.now()}`;
|
|
61481
61670
|
try {
|
|
61482
|
-
if (
|
|
61671
|
+
if (existsSync11(configPath())) renameWithRetrySync(configPath(), corrupt);
|
|
61483
61672
|
} catch {
|
|
61484
61673
|
}
|
|
61485
61674
|
process.stderr.write(
|
|
@@ -61509,7 +61698,7 @@ function restoreAllForRmWOrThrow(reason) {
|
|
|
61509
61698
|
function readAllForRmW() {
|
|
61510
61699
|
let raw;
|
|
61511
61700
|
try {
|
|
61512
|
-
raw =
|
|
61701
|
+
raw = readFileSync12(configPath(), "utf8");
|
|
61513
61702
|
} catch (err) {
|
|
61514
61703
|
if (err.code === "ENOENT") {
|
|
61515
61704
|
if (isUserDataRecoveryExpected(resolvePluginData(), { fresh: true })) {
|
|
@@ -61556,7 +61745,7 @@ function readSection(section) {
|
|
|
61556
61745
|
return stripGeneratedMarker(readAll()[section] ?? null) ?? {};
|
|
61557
61746
|
}
|
|
61558
61747
|
async function writeConfigFileAsync(data) {
|
|
61559
|
-
mkdirSync5(
|
|
61748
|
+
mkdirSync5(dirname10(configPath()), { recursive: true, mode: 448 });
|
|
61560
61749
|
try {
|
|
61561
61750
|
await backupUserDataAsync(resolvePluginData(), "pre-config-write");
|
|
61562
61751
|
} catch {
|
|
@@ -62550,6 +62739,44 @@ var sessionCommands = {
|
|
|
62550
62739
|
}).catch((e) => store.pushNotice(`fork failed: ${e?.message || e}`, "error"));
|
|
62551
62740
|
return true;
|
|
62552
62741
|
},
|
|
62742
|
+
// /shells — this session's shells, each marked running or "termination
|
|
62743
|
+
// unconfirmed". `/shells release <id>` explains what releasing means and
|
|
62744
|
+
// asks for `--confirm`; only then is the workspace hold dropped.
|
|
62745
|
+
shells(ctx, arg) {
|
|
62746
|
+
const { store } = ctx;
|
|
62747
|
+
const [action, taskId, flag] = String(arg || "").trim().split(/\s+/).filter(Boolean);
|
|
62748
|
+
if (!action) {
|
|
62749
|
+
void Promise.resolve(store.listShellJobs?.()).then((result) => {
|
|
62750
|
+
const jobs = Array.isArray(result?.jobs) ? result.jobs : [];
|
|
62751
|
+
if (!jobs.length) {
|
|
62752
|
+
store.pushNotice("No shells are running.", "info");
|
|
62753
|
+
return;
|
|
62754
|
+
}
|
|
62755
|
+
const lines = jobs.map(
|
|
62756
|
+
(job) => `${job.taskId} ${job.terminationUnconfirmed ? "termination unconfirmed" : "running"} ${job.command}`
|
|
62757
|
+
);
|
|
62758
|
+
const held = jobs.some((job) => job.terminationUnconfirmed);
|
|
62759
|
+
if (held) lines.push("Release a held shell with /shells release <task_id>.");
|
|
62760
|
+
store.pushNotice(lines.join("\n"), held ? "warn" : "info");
|
|
62761
|
+
}).catch((error) => store.pushNotice(`Couldn\u2019t list shells: ${error?.message || error}`, "error"));
|
|
62762
|
+
return true;
|
|
62763
|
+
}
|
|
62764
|
+
if (action !== "release" || !taskId) {
|
|
62765
|
+
store.pushNotice("usage: /shells [release <task_id> [--confirm]]", "warn");
|
|
62766
|
+
return true;
|
|
62767
|
+
}
|
|
62768
|
+
if (flag !== "--confirm") {
|
|
62769
|
+
store.pushNotice(
|
|
62770
|
+
`Releasing ${taskId} unlocks its folder although its processes may still be running. To proceed, run /shells release ${taskId} --confirm`,
|
|
62771
|
+
"warn"
|
|
62772
|
+
);
|
|
62773
|
+
return true;
|
|
62774
|
+
}
|
|
62775
|
+
void Promise.resolve(store.releaseShellJob?.(taskId)).then(
|
|
62776
|
+
(result) => result?.released ? store.pushNotice(`Released ${taskId}.`, "info") : store.pushNotice(`Couldn\u2019t release ${taskId}: ${result?.error || "unavailable"}`, "warn")
|
|
62777
|
+
).catch((error) => store.pushNotice(`Couldn\u2019t release ${taskId}: ${error?.message || error}`, "error"));
|
|
62778
|
+
return true;
|
|
62779
|
+
},
|
|
62553
62780
|
doctor(ctx) {
|
|
62554
62781
|
const { state, store, deps } = ctx;
|
|
62555
62782
|
if (state.commandBusy) {
|
|
@@ -63023,8 +63250,8 @@ function usePromptQueueHistory({
|
|
|
63023
63250
|
let timer2 = null;
|
|
63024
63251
|
Promise.race([
|
|
63025
63252
|
Promise.resolve(store.dispose?.("cli-react-exit", { detach: true })),
|
|
63026
|
-
new Promise((
|
|
63027
|
-
timer2 = setTimeout(
|
|
63253
|
+
new Promise((resolve6) => {
|
|
63254
|
+
timer2 = setTimeout(resolve6, 350);
|
|
63028
63255
|
})
|
|
63029
63256
|
]).finally(() => {
|
|
63030
63257
|
if (timer2) clearTimeout(timer2);
|
|
@@ -63229,15 +63456,15 @@ function useTerminalChrome({ stdout: stdout2, isRawModeSupported, setResizeState
|
|
|
63229
63456
|
import { useCallback as useCallback21, useEffect as useEffect27, useLayoutEffect as useLayoutEffect8 } from "react";
|
|
63230
63457
|
|
|
63231
63458
|
// src/tui/session/transcript-spill.mjs
|
|
63232
|
-
import { readFileSync as
|
|
63233
|
-
import { join as
|
|
63459
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
63460
|
+
import { join as join16 } from "node:path";
|
|
63234
63461
|
import { Worker } from "node:worker_threads";
|
|
63235
63462
|
|
|
63236
63463
|
// src/tui/session/transcript-spill/spill-dir.mjs
|
|
63237
63464
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
63238
|
-
import { mkdtempSync, readdirSync as readdirSync5, readFileSync as
|
|
63465
|
+
import { mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync15, rmSync as rmSync5, statSync as statSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
63239
63466
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
63240
|
-
import { join as
|
|
63467
|
+
import { join as join15 } from "node:path";
|
|
63241
63468
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
63242
63469
|
var PROCESS_NONCE = randomUUID2();
|
|
63243
63470
|
|
|
@@ -65611,8 +65838,8 @@ function waitWithTimeout(promise, ms) {
|
|
|
65611
65838
|
let timer2 = null;
|
|
65612
65839
|
return Promise.race([
|
|
65613
65840
|
Promise.resolve(promise).then(() => true),
|
|
65614
|
-
new Promise((
|
|
65615
|
-
timer2 = setTimeout(() =>
|
|
65841
|
+
new Promise((resolve6) => {
|
|
65842
|
+
timer2 = setTimeout(() => resolve6(false), ms);
|
|
65616
65843
|
})
|
|
65617
65844
|
]).finally(() => {
|
|
65618
65845
|
if (timer2) clearTimeout(timer2);
|
|
@@ -65631,7 +65858,7 @@ function scheduleHardExit(code = 0) {
|
|
|
65631
65858
|
timer2.unref?.();
|
|
65632
65859
|
}
|
|
65633
65860
|
function resolveTuiStderrLogPath() {
|
|
65634
|
-
return process.env.MIXDOG_TUI_STDERR_LOG ||
|
|
65861
|
+
return process.env.MIXDOG_TUI_STDERR_LOG || join17(process.env.MIXDOG_RUNTIME_ROOT || join17(tmpdir3(), "mixdog"), "mixdog-tui.stderr.log");
|
|
65635
65862
|
}
|
|
65636
65863
|
function ansiFg(rgb2) {
|
|
65637
65864
|
const m = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/.exec(String(rgb2 || ""));
|
|
@@ -65712,7 +65939,7 @@ function installTuiStderrGuard() {
|
|
|
65712
65939
|
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
65713
65940
|
const logPath = resolveTuiStderrLogPath();
|
|
65714
65941
|
try {
|
|
65715
|
-
mkdirSync8(
|
|
65942
|
+
mkdirSync8(dirname12(logPath), { recursive: true });
|
|
65716
65943
|
} catch {
|
|
65717
65944
|
}
|
|
65718
65945
|
(0, import_mixdog_debug.rotateBoundedLog)(logPath, import_mixdog_debug.PLUGIN_LOG_MAX_BYTES, import_mixdog_debug.PLUGIN_LOG_KEEP_BYTES);
|