mixdog 1.2.3 → 1.2.5
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/mobile-release.mjs +5 -4
- 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 +7 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/output-styles/common.md +2 -1
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +13 -13
- 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 +160 -212
- 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/desktop-service-registry.mjs +32 -5
- 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 +529 -270
- 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/ui/streaming-markdown-heal.mjs +70 -18
- 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
|
}
|
|
@@ -38481,19 +38488,34 @@ var HEALABLE_MARKDOWN_SYNTAX = /[`*_~[]/;
|
|
|
38481
38488
|
function openFence(text) {
|
|
38482
38489
|
let marker = "";
|
|
38483
38490
|
let length = 0;
|
|
38491
|
+
let start = 0;
|
|
38492
|
+
let lineStart2 = 0;
|
|
38484
38493
|
for (const rawLine of String(text ?? "").split("\n")) {
|
|
38485
38494
|
const fence = FENCE_LINE.exec(rawLine.replace(/\r$/, ""));
|
|
38486
|
-
if (
|
|
38487
|
-
|
|
38488
|
-
|
|
38489
|
-
|
|
38490
|
-
|
|
38491
|
-
|
|
38492
|
-
marker
|
|
38493
|
-
|
|
38495
|
+
if (fence) {
|
|
38496
|
+
const marks = fence[1];
|
|
38497
|
+
if (!marker) {
|
|
38498
|
+
marker = marks[0];
|
|
38499
|
+
length = marks.length;
|
|
38500
|
+
start = lineStart2;
|
|
38501
|
+
} else if (marks[0] === marker && marks.length >= length && !fence[2].trim()) {
|
|
38502
|
+
marker = "";
|
|
38503
|
+
length = 0;
|
|
38504
|
+
}
|
|
38494
38505
|
}
|
|
38506
|
+
lineStart2 += rawLine.length + 1;
|
|
38495
38507
|
}
|
|
38496
|
-
return marker ? { marker, length } : null;
|
|
38508
|
+
return marker ? { marker, length, start } : null;
|
|
38509
|
+
}
|
|
38510
|
+
function trimPartialOpeningFence(text, fence) {
|
|
38511
|
+
const lineEnd2 = text.indexOf("\n", fence.start);
|
|
38512
|
+
return lineEnd2 >= 0 && /\S/.test(text.slice(lineEnd2 + 1)) ? text : text.slice(0, fence.start);
|
|
38513
|
+
}
|
|
38514
|
+
var PENDING_BLOCK_MARKER_LINE = /(?:^|\n)[ \t]*(?:[-+*=_#>~`]+|\d{1,9}[.)]?)[ \t]*$/;
|
|
38515
|
+
function trimPendingBlockMarker(text) {
|
|
38516
|
+
const pending = PENDING_BLOCK_MARKER_LINE.exec(text);
|
|
38517
|
+
if (!pending) return text;
|
|
38518
|
+
return text.slice(0, pending.index + (pending[0].startsWith("\n") ? 1 : 0));
|
|
38497
38519
|
}
|
|
38498
38520
|
function trimPartialClosingFence(text, fence) {
|
|
38499
38521
|
const partial = /(?:^|\r?\n) {0,3}([`~]+)$/.exec(text);
|
|
@@ -38524,7 +38546,7 @@ function closeInlineCode(text, isPendingLocalPath) {
|
|
|
38524
38546
|
} else if (run === open) open = 0;
|
|
38525
38547
|
index = end;
|
|
38526
38548
|
}
|
|
38527
|
-
if (open && isPendingLocalPath?.(text.slice(openIndex + open))) {
|
|
38549
|
+
if (open && (!text.slice(openIndex + open) || isPendingLocalPath?.(text.slice(openIndex + open)))) {
|
|
38528
38550
|
return text.slice(0, openIndex);
|
|
38529
38551
|
}
|
|
38530
38552
|
return open > 0 ? `${text}${"`".repeat(open)}` : text;
|
|
@@ -38554,6 +38576,7 @@ function scanEmphasisRuns(masked) {
|
|
|
38554
38576
|
let end = index + 1;
|
|
38555
38577
|
while (masked[end] === marker) end += 1;
|
|
38556
38578
|
const length = end - index;
|
|
38579
|
+
const at = index;
|
|
38557
38580
|
const before = index > 0 ? masked[index - 1] : "";
|
|
38558
38581
|
const after = end < masked.length ? masked[end] : "";
|
|
38559
38582
|
const beforeSpace = isMarkdownSpace(before);
|
|
@@ -38563,16 +38586,25 @@ function scanEmphasisRuns(masked) {
|
|
|
38563
38586
|
const left = !afterSpace && (!afterPunctuation || beforeSpace || beforePunctuation);
|
|
38564
38587
|
const right = !beforeSpace && (!beforePunctuation || afterSpace || afterPunctuation);
|
|
38565
38588
|
if (marker === "~") {
|
|
38566
|
-
|
|
38589
|
+
runs.push({
|
|
38590
|
+
marker,
|
|
38591
|
+
length: Math.min(length, 2),
|
|
38592
|
+
canOpen: left && length >= 2,
|
|
38593
|
+
canClose: right && length >= 2,
|
|
38594
|
+
at,
|
|
38595
|
+
end
|
|
38596
|
+
});
|
|
38567
38597
|
} else if (marker === "_") {
|
|
38568
38598
|
runs.push({
|
|
38569
38599
|
marker,
|
|
38570
38600
|
length,
|
|
38571
38601
|
canOpen: left && (!right || beforePunctuation),
|
|
38572
|
-
canClose: right && (!left || afterPunctuation)
|
|
38602
|
+
canClose: right && (!left || afterPunctuation),
|
|
38603
|
+
at,
|
|
38604
|
+
end
|
|
38573
38605
|
});
|
|
38574
38606
|
} else {
|
|
38575
|
-
runs.push({ marker, length, canOpen: left, canClose: right });
|
|
38607
|
+
runs.push({ marker, length, canOpen: left, canClose: right, at, end });
|
|
38576
38608
|
}
|
|
38577
38609
|
index = end;
|
|
38578
38610
|
}
|
|
@@ -38580,7 +38612,9 @@ function scanEmphasisRuns(masked) {
|
|
|
38580
38612
|
}
|
|
38581
38613
|
function closeEmphasis(text) {
|
|
38582
38614
|
const open = [];
|
|
38583
|
-
|
|
38615
|
+
const runs = scanEmphasisRuns(maskCode(text));
|
|
38616
|
+
const last = runs[runs.length - 1];
|
|
38617
|
+
for (const run of runs) {
|
|
38584
38618
|
let length = run.length;
|
|
38585
38619
|
while (run.canClose && length > 0) {
|
|
38586
38620
|
let match = -1;
|
|
@@ -38597,13 +38631,17 @@ function closeEmphasis(text) {
|
|
|
38597
38631
|
length -= used;
|
|
38598
38632
|
open.length = opener.length > 0 ? match + 1 : match;
|
|
38599
38633
|
}
|
|
38634
|
+
if (run === last && run.end === text.length && length === run.length) {
|
|
38635
|
+
return closeEmphasis(text.slice(0, run.at));
|
|
38636
|
+
}
|
|
38600
38637
|
if (length > 0 && run.canOpen) open.push({ marker: run.marker, length });
|
|
38601
38638
|
}
|
|
38602
|
-
|
|
38639
|
+
const body = text.trimEnd();
|
|
38640
|
+
let closers = "";
|
|
38603
38641
|
for (let index = open.length - 1; index >= 0; index -= 1) {
|
|
38604
|
-
|
|
38642
|
+
closers += open[index].marker.repeat(Math.min(open[index].length, 3));
|
|
38605
38643
|
}
|
|
38606
|
-
return
|
|
38644
|
+
return closers ? `${body}${closers}${text.slice(body.length)}` : text;
|
|
38607
38645
|
}
|
|
38608
38646
|
function linkDestinationEnd(text, start) {
|
|
38609
38647
|
let depth = 1;
|
|
@@ -38687,8 +38725,9 @@ function trimPendingTableHead(text) {
|
|
|
38687
38725
|
function healStreamingMarkdownTail(text, isPendingLocalPath) {
|
|
38688
38726
|
const source = String(text ?? "");
|
|
38689
38727
|
const fence = source.includes("`") || source.includes("~") ? openFence(source) : null;
|
|
38690
|
-
if (fence) return trimPartialClosingFence(source, fence);
|
|
38691
|
-
const
|
|
38728
|
+
if (fence) return trimPartialOpeningFence(trimPartialClosingFence(source, fence), fence);
|
|
38729
|
+
const unmarked = trimPendingBlockMarker(source);
|
|
38730
|
+
const value = unmarked.includes("|") ? trimPendingTableHead(unmarked) : unmarked;
|
|
38692
38731
|
const hasSyntax = HEALABLE_MARKDOWN_SYNTAX.test(value);
|
|
38693
38732
|
if (!value || !hasSyntax && !isPendingLocalPath) return value;
|
|
38694
38733
|
const healed = hasSyntax ? closeEmphasis(healIncompleteLink(closeInlineCode(value, isPendingLocalPath), isPendingLocalPath)) : value;
|
|
@@ -39936,7 +39975,7 @@ function isUserControlCancellation(text) {
|
|
|
39936
39975
|
return USER_CONTROL_CANCELLATION_RE.test(String(text || "").trimStart());
|
|
39937
39976
|
}
|
|
39938
39977
|
function hasBenignExitOutcome(text) {
|
|
39939
|
-
return /^\[outcome:\s*(?:no-match|no-change)\]\s*$/im.test(String(text || ""));
|
|
39978
|
+
return /^\[outcome:\s*(?:no-match|no-change|conflicts)\]\s*$/im.test(String(text || ""));
|
|
39940
39979
|
}
|
|
39941
39980
|
var ENVELOPE_TAG_HEAD_RE = /^<(?:task-notification|task-id|tool-use-id|output-file|status)[\s>]/i;
|
|
39942
39981
|
function toolResultEnvelopeStatus(text) {
|
|
@@ -40108,10 +40147,10 @@ function splitPathAndDelta(value, explicitDelta = "") {
|
|
|
40108
40147
|
let path2 = String(value ?? "").trim();
|
|
40109
40148
|
let delta = String(explicitDelta ?? "").trim();
|
|
40110
40149
|
if (!delta) {
|
|
40111
|
-
const
|
|
40112
|
-
if (
|
|
40113
|
-
delta = path2.slice(
|
|
40114
|
-
path2 = path2.slice(0,
|
|
40150
|
+
const sep2 = path2.lastIndexOf(" \u2014 ");
|
|
40151
|
+
if (sep2 !== -1) {
|
|
40152
|
+
delta = path2.slice(sep2 + 3).trim();
|
|
40153
|
+
path2 = path2.slice(0, sep2).trim();
|
|
40115
40154
|
}
|
|
40116
40155
|
}
|
|
40117
40156
|
return { path: path2, delta };
|
|
@@ -40480,8 +40519,20 @@ function summarizeAgentResult({ text, trimmed, translate }) {
|
|
|
40480
40519
|
return null;
|
|
40481
40520
|
}
|
|
40482
40521
|
var summarizeGeneric = ({ text, translate }) => summarizeGenericResult(text, translate);
|
|
40483
|
-
var summarizeAskUserResult = ({ text }) => {
|
|
40484
|
-
const
|
|
40522
|
+
var summarizeAskUserResult = ({ text, translate }) => {
|
|
40523
|
+
const replied = /^User replied in chat: ("(?:[^"\\]|\\.)*")\. /s.exec(String(text ?? "").trim());
|
|
40524
|
+
if (replied) {
|
|
40525
|
+
let reply = "";
|
|
40526
|
+
try {
|
|
40527
|
+
reply = String(JSON.parse(replied[1]));
|
|
40528
|
+
} catch {
|
|
40529
|
+
}
|
|
40530
|
+
const label = translate("Answered in chat", "Answered in chat", {});
|
|
40531
|
+
return truncateSingleLine(reply ? `${label}: ${reply}` : label, AGENT_SURFACE_BRIEF_MAX);
|
|
40532
|
+
}
|
|
40533
|
+
const answers = /^User has answered your questions:\s*(.*?)(?:\s*You can now continue with these answers in mind\.)?$/s.exec(
|
|
40534
|
+
String(text ?? "").trim()
|
|
40535
|
+
);
|
|
40485
40536
|
return truncateSingleLine(answers ? answers[1] : String(text ?? "").trim(), AGENT_SURFACE_BRIEF_MAX) || null;
|
|
40486
40537
|
};
|
|
40487
40538
|
var TOOL_RESULT_SUMMARIZERS = new Map(
|
|
@@ -40876,12 +40927,18 @@ function officeUnit(a) {
|
|
|
40876
40927
|
}
|
|
40877
40928
|
function visualizeUnit(a) {
|
|
40878
40929
|
const action = String(a.action || "").toLowerCase();
|
|
40879
|
-
if (action === "capture")
|
|
40880
|
-
|
|
40881
|
-
if (action === "
|
|
40882
|
-
|
|
40883
|
-
if (action === "
|
|
40884
|
-
|
|
40930
|
+
if (action === "capture")
|
|
40931
|
+
return unitDescriptor("Visualize", { count: 1, active: "Capturing", done: "Captured", noun: "screenshot" });
|
|
40932
|
+
if (action === "export")
|
|
40933
|
+
return unitDescriptor("Visualize", { count: 1, active: "Exporting", done: "Exported", noun: "file" });
|
|
40934
|
+
if (action === "annotate")
|
|
40935
|
+
return unitDescriptor("Visualize", { count: 1, active: "Marking", done: "Marked", noun: "annotation" });
|
|
40936
|
+
if (action === "check")
|
|
40937
|
+
return unitDescriptor("Visualize", { count: 1, active: "Checking", done: "Checked", noun: "page" });
|
|
40938
|
+
if (action === "inspect")
|
|
40939
|
+
return unitDescriptor("Visualize", { count: 1, active: "Inspecting", done: "Inspected", noun: "page" });
|
|
40940
|
+
if (action === "close")
|
|
40941
|
+
return unitDescriptor("Visualize", { count: 1, active: "Closing", done: "Closed", noun: "tab" });
|
|
40885
40942
|
return unitDescriptor("Visualize", { count: 1, active: "Showing", done: "Showed", noun: "artifact" });
|
|
40886
40943
|
}
|
|
40887
40944
|
function terminalUnit(a) {
|
|
@@ -41095,7 +41152,10 @@ function cwdUnit(a) {
|
|
|
41095
41152
|
}
|
|
41096
41153
|
if (action === "favorite" || action === "archive") {
|
|
41097
41154
|
const off = a.value === false;
|
|
41098
|
-
|
|
41155
|
+
let words;
|
|
41156
|
+
if (action === "favorite") words = off ? ["Unfavoriting", "Unfavorited"] : ["Favoriting", "Favorited"];
|
|
41157
|
+
else words = off ? ["Unarchiving", "Unarchived"] : ["Archiving", "Archived"];
|
|
41158
|
+
const [active, done] = words;
|
|
41099
41159
|
return unitDescriptor("Setup", { active, done, noun: "session", effect: true });
|
|
41100
41160
|
}
|
|
41101
41161
|
if (action.endsWith("-worktree") || action.endsWith("-worktrees")) {
|
|
@@ -41109,7 +41169,12 @@ function cwdUnit(a) {
|
|
|
41109
41169
|
if (action === "status") {
|
|
41110
41170
|
return unitDescriptor("Setup", { active: "Checking", done: "Checked", noun: "session" });
|
|
41111
41171
|
}
|
|
41112
|
-
return unitDescriptor("Setup", {
|
|
41172
|
+
return unitDescriptor("Setup", {
|
|
41173
|
+
active: "Checking",
|
|
41174
|
+
done: "Checked",
|
|
41175
|
+
noun: "working directory",
|
|
41176
|
+
pluralNoun: "working directories"
|
|
41177
|
+
});
|
|
41113
41178
|
}
|
|
41114
41179
|
var TOOL_UNITS = /* @__PURE__ */ new Map([
|
|
41115
41180
|
[
|
|
@@ -41589,7 +41654,8 @@ function summarizeGithub(a, max) {
|
|
|
41589
41654
|
const id = a.number ?? a.id;
|
|
41590
41655
|
const hasId = id != null && String(id).trim() !== "";
|
|
41591
41656
|
const title = truncateToolText(firstText(a.title, a.workflow, a.tag), Math.min(max, 60));
|
|
41592
|
-
|
|
41657
|
+
if (hasId) return compactParts([`${phrase} ${String(id).trim()}`, repo, title]);
|
|
41658
|
+
return compactParts([repo ? `${phrase} ${repo}` : phrase, title]);
|
|
41593
41659
|
}
|
|
41594
41660
|
function formatToolSurface(name, args, opts = {}) {
|
|
41595
41661
|
const parsed = parseToolArgs(args);
|
|
@@ -42308,7 +42374,10 @@ var IN_FLIGHT_BUDGET_MAX_WAIT_MS = 6e4;
|
|
|
42308
42374
|
function inFlightAdviceMs(err) {
|
|
42309
42375
|
const advised = retryAfterMsFromError(err);
|
|
42310
42376
|
if (advised != null) return advised;
|
|
42311
|
-
for (const [name, unitMs] of [
|
|
42377
|
+
for (const [name, unitMs] of [
|
|
42378
|
+
["retry-after-ms", 1],
|
|
42379
|
+
["retry-after", 1e3]
|
|
42380
|
+
]) {
|
|
42312
42381
|
const value = errorHeaderValue(err, name);
|
|
42313
42382
|
const n = Number(value);
|
|
42314
42383
|
if (value != null && String(value).trim() !== "" && Number.isFinite(n) && n >= 0) return n * unitMs;
|
|
@@ -42664,6 +42733,20 @@ function describeError(value) {
|
|
|
42664
42733
|
};
|
|
42665
42734
|
}
|
|
42666
42735
|
|
|
42736
|
+
// src/runtime/shared/provider-timeout-phase.mjs
|
|
42737
|
+
var TIMEOUT_PHASE = Object.freeze({
|
|
42738
|
+
// The response headers did not arrive in the first-byte window.
|
|
42739
|
+
HEADERS: "headers",
|
|
42740
|
+
// The headers arrived, the first chunk did not.
|
|
42741
|
+
FIRST_CHUNK: "first-chunk",
|
|
42742
|
+
// A stream that already produced output went silent.
|
|
42743
|
+
IDLE: "idle"
|
|
42744
|
+
});
|
|
42745
|
+
function isFirstByteTimeout(err) {
|
|
42746
|
+
const phase = err?.timeoutPhase;
|
|
42747
|
+
return phase === TIMEOUT_PHASE.HEADERS || phase === TIMEOUT_PHASE.FIRST_CHUNK;
|
|
42748
|
+
}
|
|
42749
|
+
|
|
42667
42750
|
// src/runtime/shared/err-text.mjs
|
|
42668
42751
|
function errorHttpStatus(err) {
|
|
42669
42752
|
return Number(err?.httpStatus || err?.status || err?.response?.status || 0) || 0;
|
|
@@ -42821,6 +42904,25 @@ function hasTypedEvidence(error) {
|
|
|
42821
42904
|
if (!error || typeof error !== "object") return false;
|
|
42822
42905
|
return Boolean(error.errorKind?.kind) || errorHttpStatus(error) > 0 || Boolean(error.code) || Boolean(error.retryAfterMs);
|
|
42823
42906
|
}
|
|
42907
|
+
var timedOutMs = (text) => Number(/timed out after (\d+)ms/i.exec(text)?.[1]) || 0;
|
|
42908
|
+
function stillThinkingText(error, text) {
|
|
42909
|
+
const ms = Number(error.waitedMs) || timedOutMs(text);
|
|
42910
|
+
const provider = typeof error.providerLabel === "string" && error.providerLabel ? error.providerLabel : "the provider";
|
|
42911
|
+
const attempts = Number(error.attempts) > 0 ? `; attempts: ${Math.floor(Number(error.attempts))}` : "";
|
|
42912
|
+
return `Model still thinking: no output in ${formatDurationMs(ms)}; ${provider} sent nothing yet${attempts}.`;
|
|
42913
|
+
}
|
|
42914
|
+
function typedStreamFailureText(error, text) {
|
|
42915
|
+
if (!error || typeof error !== "object") return null;
|
|
42916
|
+
if (isFirstByteTimeout(error)) return stillThinkingText(error, text);
|
|
42917
|
+
if (error.timeoutPhase === TIMEOUT_PHASE.IDLE) {
|
|
42918
|
+
const ms = timedOutMs(text);
|
|
42919
|
+
return ms > 0 ? `No progress ${formatDurationMs(ms)}.` : "No progress.";
|
|
42920
|
+
}
|
|
42921
|
+
if (error.code === "TRUNCATED_STREAM" && error.streamCorruption !== true) {
|
|
42922
|
+
return "Connection to the provider was lost (TRUNCATED_STREAM).";
|
|
42923
|
+
}
|
|
42924
|
+
return null;
|
|
42925
|
+
}
|
|
42824
42926
|
function presentErrorText(error, options = {}) {
|
|
42825
42927
|
const presentation = describeError(error);
|
|
42826
42928
|
if (["image-size", "payload-size", "request"].includes(presentation.kind)) return presentation.summary;
|
|
@@ -42844,6 +42946,8 @@ function presentErrorText(error, options = {}) {
|
|
|
42844
42946
|
if (embeddedError) text = embeddedError;
|
|
42845
42947
|
text = oneLine(stripErrorPrefix(text));
|
|
42846
42948
|
if (!text) return "Unknown error";
|
|
42949
|
+
const streamFailure = typedStreamFailureText(error, text);
|
|
42950
|
+
if (streamFailure) return streamFailure;
|
|
42847
42951
|
if (code === "PROVIDER_PREFIX_MUTATION" || name === "ProviderPrefixMutationError") {
|
|
42848
42952
|
return "Session state changed unexpectedly.";
|
|
42849
42953
|
}
|
|
@@ -42883,7 +42987,7 @@ function presentErrorText(error, options = {}) {
|
|
|
42883
42987
|
}
|
|
42884
42988
|
const firstTransport = /first (?:transport|semantic response) stale\s*\((\d+)ms\)/i.exec(text);
|
|
42885
42989
|
if (firstTransport) {
|
|
42886
|
-
return `
|
|
42990
|
+
return `Agent watchdog stopped the run: no model response in ${formatDurationMs(firstTransport[1])}.`;
|
|
42887
42991
|
}
|
|
42888
42992
|
const firstResponse = /(?:agent\s+)?first response stale\s*\((\d+)ms\)/i.exec(text);
|
|
42889
42993
|
if (firstResponse) {
|
|
@@ -42918,7 +43022,7 @@ function backgroundTaskFailureStatusLabel(status, error, options = {}) {
|
|
|
42918
43022
|
const watchdog = watchdogMsFromRawError(raw);
|
|
42919
43023
|
let head = "Failed";
|
|
42920
43024
|
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))
|
|
43025
|
+
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
43026
|
head = "Timeout";
|
|
42923
43027
|
else if (watchdog?.kind === "stale" || /(?:agent )?(?:task|tool running) stale|went stale without/i.test(raw) || /went stale after/i.test(presented))
|
|
42924
43028
|
head = "Stale";
|
|
@@ -43811,7 +43915,8 @@ function headerLabel(base, surface, display, status, detail) {
|
|
|
43811
43915
|
if (display.isBackgroundMetadataResult) return backgroundTaskActionTitle(normalizedName, display.backgroundMeta);
|
|
43812
43916
|
if (isShellSurface) return shellHeader(status.shellStatus, groupCount, parsedArgs?.verifyShell === true);
|
|
43813
43917
|
const described = normalizedName === "load_tool" && !headerPending ? bridgeDescribedToolNames(display.displayedResultText) : null;
|
|
43814
|
-
if (described)
|
|
43918
|
+
if (described)
|
|
43919
|
+
return described.length ? `Described ${described.map(displayToolSearchTarget).join(", ")}` : "Described";
|
|
43815
43920
|
return (isAgentTool(normalizedName) ? agentActionTitle(parsedArgs, display.displayedResultText) : "") || formatToolActionHeader(name, args, {
|
|
43816
43921
|
pending: headerPending,
|
|
43817
43922
|
count: groupCount,
|
|
@@ -45869,8 +45974,8 @@ var notifyRenderFrame = (seq) => {
|
|
|
45869
45974
|
for (const ack of acks) ack(seq);
|
|
45870
45975
|
};
|
|
45871
45976
|
var yieldToRenderer = ({ frames = 1 } = {}) => {
|
|
45872
|
-
if (!hasRenderFrameSource()) return new Promise((
|
|
45873
|
-
return new Promise((
|
|
45977
|
+
if (!hasRenderFrameSource()) return new Promise((resolve6) => setImmediate(resolve6));
|
|
45978
|
+
return new Promise((resolve6) => {
|
|
45874
45979
|
const minSeq = renderAckSeq;
|
|
45875
45980
|
let remainingFrames = Math.max(1, Math.floor(Number(frames) || 1));
|
|
45876
45981
|
let settled = false;
|
|
@@ -45885,7 +45990,7 @@ var yieldToRenderer = ({ frames = 1 } = {}) => {
|
|
|
45885
45990
|
releaseClosedListener();
|
|
45886
45991
|
const idx = pendingRenderAcks.indexOf(onFrame);
|
|
45887
45992
|
if (idx !== -1) pendingRenderAcks.splice(idx, 1);
|
|
45888
|
-
|
|
45993
|
+
resolve6();
|
|
45889
45994
|
};
|
|
45890
45995
|
releaseClosedListener = onRenderFrameSourcesClosed(finish);
|
|
45891
45996
|
const onTimeout = () => {
|
|
@@ -46685,13 +46790,13 @@ function nativeClipboardCommand(text) {
|
|
|
46685
46790
|
function copyToClipboard(text) {
|
|
46686
46791
|
const value = String(text ?? "");
|
|
46687
46792
|
const wroteOsc52 = writeOsc52Clipboard(value);
|
|
46688
|
-
return new Promise((
|
|
46793
|
+
return new Promise((resolve6, reject) => {
|
|
46689
46794
|
const { cmd, args, input } = nativeClipboardCommand(value);
|
|
46690
46795
|
let child;
|
|
46691
46796
|
try {
|
|
46692
46797
|
child = spawn2(cmd, args, { stdio: ["pipe", "ignore", "ignore"], windowsHide: true });
|
|
46693
46798
|
} catch (e) {
|
|
46694
|
-
if (wroteOsc52)
|
|
46799
|
+
if (wroteOsc52) resolve6();
|
|
46695
46800
|
else reject(clipboardHelperError(cmd, e));
|
|
46696
46801
|
return;
|
|
46697
46802
|
}
|
|
@@ -46700,7 +46805,7 @@ function copyToClipboard(text) {
|
|
|
46700
46805
|
});
|
|
46701
46806
|
if (!wroteOsc52) {
|
|
46702
46807
|
child.on("close", (code) => {
|
|
46703
|
-
if (code === 0)
|
|
46808
|
+
if (code === 0) resolve6();
|
|
46704
46809
|
else reject(new Error(`${cmd} exited with code ${code}`));
|
|
46705
46810
|
});
|
|
46706
46811
|
}
|
|
@@ -46709,7 +46814,7 @@ function copyToClipboard(text) {
|
|
|
46709
46814
|
child.stdin.end(input);
|
|
46710
46815
|
if (wroteOsc52) {
|
|
46711
46816
|
child.unref?.();
|
|
46712
|
-
|
|
46817
|
+
resolve6();
|
|
46713
46818
|
}
|
|
46714
46819
|
});
|
|
46715
46820
|
}
|
|
@@ -47013,7 +47118,7 @@ function mimeForPath(path2) {
|
|
|
47013
47118
|
return IMAGE_MIME[extname(String(path2 || "")).toLowerCase()] || null;
|
|
47014
47119
|
}
|
|
47015
47120
|
function execFileBuffer(cmd, args, options = {}) {
|
|
47016
|
-
return new Promise((
|
|
47121
|
+
return new Promise((resolve6) => {
|
|
47017
47122
|
execFile(
|
|
47018
47123
|
cmd,
|
|
47019
47124
|
args,
|
|
@@ -47025,7 +47130,7 @@ function execFileBuffer(cmd, args, options = {}) {
|
|
|
47025
47130
|
...options
|
|
47026
47131
|
},
|
|
47027
47132
|
(error, stdout2, stderr) => {
|
|
47028
|
-
|
|
47133
|
+
resolve6({ ok: !error, code: error?.code ?? 0, stdout: stdout2, stderr, error });
|
|
47029
47134
|
}
|
|
47030
47135
|
);
|
|
47031
47136
|
});
|
|
@@ -47518,7 +47623,10 @@ var SPINNER_MODE_OVERRIDE_VERBS = {
|
|
|
47518
47623
|
compacting: "Compacting conversation",
|
|
47519
47624
|
"auto-clear": "Auto-clearing conversation",
|
|
47520
47625
|
resuming: "Resuming conversation",
|
|
47521
|
-
"task-wait": "\uC791\uC5C5 \uB300\uAE30 \uC911"
|
|
47626
|
+
"task-wait": "\uC791\uC5C5 \uB300\uAE30 \uC911",
|
|
47627
|
+
// The request is sent and its response headers are pending: the model is
|
|
47628
|
+
// queued or thinking server-side.
|
|
47629
|
+
"model-thinking": "Model thinking"
|
|
47522
47630
|
};
|
|
47523
47631
|
function spinnerVerbFor(startedAt = 0, now = 0, pool = SPINNER_VERBS) {
|
|
47524
47632
|
const list = Array.isArray(pool) && pool.length ? pool : SPINNER_VERBS;
|
|
@@ -48418,7 +48526,7 @@ function completeOAuthCode(ctx, target, commandText) {
|
|
|
48418
48526
|
}
|
|
48419
48527
|
oauthSubmitRef.current = true;
|
|
48420
48528
|
setProviderPrompt((prompt) => prompt === target ? { ...prompt, submitting: true } : prompt);
|
|
48421
|
-
const completion = typeof target.login?.completeCode === "function" ? new Promise((
|
|
48529
|
+
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
48530
|
void completion.then(() => {
|
|
48423
48531
|
const successReturn = target.successReturn;
|
|
48424
48532
|
const afterSave = target.afterSave;
|
|
@@ -49738,6 +49846,44 @@ function useSharedTick(intervalMs, isActive = true, onTick2 = null) {
|
|
|
49738
49846
|
}, [intervalMs, isActive]);
|
|
49739
49847
|
}
|
|
49740
49848
|
|
|
49849
|
+
// src/runtime/shared/quiet-progress.mjs
|
|
49850
|
+
var QUIET_PROGRESS_CUE_MS = 12e4;
|
|
49851
|
+
var MODEL_THINKING_STAGE = "model_thinking";
|
|
49852
|
+
var WAIT_BY_STAGE = {
|
|
49853
|
+
connecting: "provider",
|
|
49854
|
+
requesting: "provider",
|
|
49855
|
+
[MODEL_THINKING_STAGE]: "thinking",
|
|
49856
|
+
streaming: "model",
|
|
49857
|
+
tool_running: "tool",
|
|
49858
|
+
resource_wait: "slot",
|
|
49859
|
+
cancelling: "cancel"
|
|
49860
|
+
};
|
|
49861
|
+
function quietProgressParts(quiet, now, warnMs = 0) {
|
|
49862
|
+
const since = Number(quiet?.since) || 0;
|
|
49863
|
+
if (!since) return null;
|
|
49864
|
+
const quietMs = Math.max(0, now - since);
|
|
49865
|
+
if (quietMs < QUIET_PROGRESS_CUE_MS) return null;
|
|
49866
|
+
return {
|
|
49867
|
+
quietMs,
|
|
49868
|
+
minutes: Math.floor(quietMs / 6e4),
|
|
49869
|
+
wait: String(quiet.wait || ""),
|
|
49870
|
+
tool: typeof quiet.tool === "string" ? quiet.tool : "",
|
|
49871
|
+
escalated: Number(warnMs) > 0 && quietMs >= Number(warnMs)
|
|
49872
|
+
};
|
|
49873
|
+
}
|
|
49874
|
+
var WAIT_TEXT = {
|
|
49875
|
+
provider: "waiting on provider",
|
|
49876
|
+
thinking: "model thinking",
|
|
49877
|
+
model: "waiting on model",
|
|
49878
|
+
slot: "waiting for a slot",
|
|
49879
|
+
cancel: "stopping"
|
|
49880
|
+
};
|
|
49881
|
+
function quietProgressLabel(parts) {
|
|
49882
|
+
if (!parts) return "";
|
|
49883
|
+
const wait = parts.wait === "tool" ? `running ${parts.tool || "a tool"}` : WAIT_TEXT[parts.wait] || "";
|
|
49884
|
+
return [`quiet for ${parts.minutes}m`, wait].filter(Boolean).join(" \xB7 ");
|
|
49885
|
+
}
|
|
49886
|
+
|
|
49741
49887
|
// src/tui/spinner-meta.mjs
|
|
49742
49888
|
var compactNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
49743
49889
|
notation: "compact",
|
|
@@ -49773,9 +49919,13 @@ function buildSpinnerMeta({
|
|
|
49773
49919
|
thinkingSince = 0,
|
|
49774
49920
|
thinkingMs = 0,
|
|
49775
49921
|
effort = "",
|
|
49922
|
+
// The turn's published quiet state (`spinner.quiet`) and the clock it is read at.
|
|
49923
|
+
quiet = null,
|
|
49924
|
+
now = Date.now(),
|
|
49776
49925
|
verbose: _verbose = false
|
|
49777
49926
|
} = {}) {
|
|
49778
49927
|
const tokens = Math.max(0, Number(outputTokens) || 0);
|
|
49928
|
+
const quietParts = quietProgressParts(quiet, now, quiet?.warnMs);
|
|
49779
49929
|
const thinkingParts = spinnerThinkingParts({ thinking, thinkingSince, thinkingMs, effort });
|
|
49780
49930
|
const thinkingText = spinnerThinkingLabel({ thinking, thinkingSince, thinkingMs, effort });
|
|
49781
49931
|
return {
|
|
@@ -49788,7 +49938,11 @@ function buildSpinnerMeta({
|
|
|
49788
49938
|
// mid-turn for no reason the reader could see; now both arrive together.
|
|
49789
49939
|
showTokens: tokens > 0,
|
|
49790
49940
|
thinkingText,
|
|
49791
|
-
thinkingActive: Boolean(thinking || Number(thinkingSince) > 0)
|
|
49941
|
+
thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
|
|
49942
|
+
// Quiet-time cue: structured for the desktop's i18n, English for the TUI;
|
|
49943
|
+
// `escalated` once the silence reaches the stall watchdog's warn point.
|
|
49944
|
+
quietParts,
|
|
49945
|
+
quietText: quietProgressLabel(quietParts)
|
|
49792
49946
|
};
|
|
49793
49947
|
}
|
|
49794
49948
|
function isReducedMotion(env4) {
|
|
@@ -49803,6 +49957,7 @@ var INTERRUPT_HINT = "esc to interrupt";
|
|
|
49803
49957
|
var THINKING_DELAY_MS = 3e3;
|
|
49804
49958
|
var GLIMMER_SPEED_MS = {
|
|
49805
49959
|
requesting: 70,
|
|
49960
|
+
"model-thinking": 70,
|
|
49806
49961
|
reconnecting: 70,
|
|
49807
49962
|
compacting: 120,
|
|
49808
49963
|
"auto-clear": 120,
|
|
@@ -49846,7 +50001,9 @@ function tokenModeGlyph(mode) {
|
|
|
49846
50001
|
case "responding":
|
|
49847
50002
|
case "thinking":
|
|
49848
50003
|
return DOWN_ARROW;
|
|
50004
|
+
// The request is sent and nothing has come back yet.
|
|
49849
50005
|
case "requesting":
|
|
50006
|
+
case "model-thinking":
|
|
49850
50007
|
return UP_ARROW;
|
|
49851
50008
|
default:
|
|
49852
50009
|
return "";
|
|
@@ -49862,6 +50019,8 @@ function SpinnerByline({
|
|
|
49862
50019
|
thinkingActiveSince,
|
|
49863
50020
|
thinkingMs,
|
|
49864
50021
|
effort,
|
|
50022
|
+
quiet = null,
|
|
50023
|
+
now = Date.now(),
|
|
49865
50024
|
interruptible,
|
|
49866
50025
|
columns,
|
|
49867
50026
|
reducedMotion,
|
|
@@ -49895,7 +50054,9 @@ function SpinnerByline({
|
|
|
49895
50054
|
thinking,
|
|
49896
50055
|
thinkingSince: thinkingActiveSince,
|
|
49897
50056
|
thinkingMs,
|
|
49898
|
-
effort
|
|
50057
|
+
effort,
|
|
50058
|
+
quiet,
|
|
50059
|
+
now
|
|
49899
50060
|
});
|
|
49900
50061
|
const tokenGlyph = tokenModeGlyph(mode);
|
|
49901
50062
|
let tokenText = "";
|
|
@@ -49914,8 +50075,11 @@ function SpinnerByline({
|
|
|
49914
50075
|
const interruptW = interruptText.length;
|
|
49915
50076
|
const showInterrupt = Boolean(interruptText) && avail > interruptW;
|
|
49916
50077
|
const usedAfterInterrupt = showInterrupt ? interruptW + SEP_WIDTH : 0;
|
|
49917
|
-
const
|
|
49918
|
-
const
|
|
50078
|
+
const quietText = meta.quietText;
|
|
50079
|
+
const showQuiet = Boolean(quietText) && avail > usedAfterInterrupt + quietText.length;
|
|
50080
|
+
const usedAfterQuiet = usedAfterInterrupt + (showQuiet ? quietText.length + SEP_WIDTH : 0);
|
|
50081
|
+
const showThinkingStatus = Boolean(thinkingStatusText) && avail > usedAfterQuiet + thinkingStatusW;
|
|
50082
|
+
const usedAfterThinking = usedAfterQuiet + (showThinkingStatus ? thinkingStatusW + SEP_WIDTH : 0);
|
|
49919
50083
|
const showTimer = Boolean(timerLabel) && avail > usedAfterThinking + timerW;
|
|
49920
50084
|
const usedAfterTimer = usedAfterThinking + (showTimer ? timerW + SEP_WIDTH : 0);
|
|
49921
50085
|
const showTokens = wantsTokens && tokenText && avail > usedAfterTimer + tokenW;
|
|
@@ -49946,6 +50110,11 @@ function SpinnerByline({
|
|
|
49946
50110
|
) }, "thinking-status") : /* @__PURE__ */ jsx2(Text, { color: theme.statusSubtle, children: thinkingStatusText }, "thinking-status")
|
|
49947
50111
|
);
|
|
49948
50112
|
}
|
|
50113
|
+
if (showQuiet) {
|
|
50114
|
+
segments.push(
|
|
50115
|
+
/* @__PURE__ */ jsx2(Text, { color: meta.quietParts?.escalated ? theme.warning : theme.statusSubtle, children: quietText }, "quiet")
|
|
50116
|
+
);
|
|
50117
|
+
}
|
|
49949
50118
|
if (showInterrupt) {
|
|
49950
50119
|
segments.push(
|
|
49951
50120
|
/* @__PURE__ */ jsx2(Text, { color: theme.statusSubtle, children: interruptText }, "interrupt")
|
|
@@ -50083,6 +50252,8 @@ function Spinner({
|
|
|
50083
50252
|
thinkingActiveSince = 0,
|
|
50084
50253
|
thinkingMs = 0,
|
|
50085
50254
|
effort = "",
|
|
50255
|
+
// The turn's quiet state (`spinner.quiet`), shown as the quiet-time cue.
|
|
50256
|
+
quiet = null,
|
|
50086
50257
|
hasActiveTools = false,
|
|
50087
50258
|
paused = false,
|
|
50088
50259
|
interruptible = false,
|
|
@@ -50125,6 +50296,8 @@ function Spinner({
|
|
|
50125
50296
|
thinkingActiveSince,
|
|
50126
50297
|
thinkingMs,
|
|
50127
50298
|
effort,
|
|
50299
|
+
quiet,
|
|
50300
|
+
now,
|
|
50128
50301
|
interruptible,
|
|
50129
50302
|
columns,
|
|
50130
50303
|
reducedMotion,
|
|
@@ -50322,7 +50495,7 @@ function normalizeStatuslineAnsi(text, colors, { reset = RESET2 } = {}) {
|
|
|
50322
50495
|
// src/runtime/shared/statusline/statusline-segments.mjs
|
|
50323
50496
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
50324
50497
|
import { homedir as homedir2 } from "node:os";
|
|
50325
|
-
import { join as
|
|
50498
|
+
import { join as join10 } from "node:path";
|
|
50326
50499
|
|
|
50327
50500
|
// src/runtime/shared/llm/model-catalog.mjs
|
|
50328
50501
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
|
|
@@ -50361,6 +50534,7 @@ var ANTIGRAVITY_MODELS = Object.freeze([
|
|
|
50361
50534
|
low: "gemini-3.1-pro-low",
|
|
50362
50535
|
high: "gemini-3.1-pro-high"
|
|
50363
50536
|
}),
|
|
50537
|
+
fallbackModel("gemini-4-argon", "Gemini 4 Argon", "gemini-pro", 1048576, "gemini-4-argon", ["low", "medium", "high"]),
|
|
50364
50538
|
fallbackModel("claude-opus-4-6-thinking", "Claude Opus 4.6 (Thinking)", null, 25e4, "claude-opus-4-6-thinking", [
|
|
50365
50539
|
"low",
|
|
50366
50540
|
"medium",
|
|
@@ -50914,9 +51088,17 @@ function isPidAlive(value) {
|
|
|
50914
51088
|
}
|
|
50915
51089
|
}
|
|
50916
51090
|
|
|
51091
|
+
// src/runtime/shared/worktrees/git-head.mjs
|
|
51092
|
+
import { readFileSync as readFileSync9, statSync as statSync2, watch } from "node:fs";
|
|
51093
|
+
import { dirname as dirname8, resolve as resolve4 } from "node:path";
|
|
51094
|
+
|
|
51095
|
+
// src/runtime/shared/worktrees/paths.mjs
|
|
51096
|
+
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "node:fs";
|
|
51097
|
+
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join9, relative, resolve as resolve3, sep } from "node:path";
|
|
51098
|
+
|
|
50917
51099
|
// src/runtime/shared/statusline/statusline-segments.mjs
|
|
50918
|
-
var DEFAULT_MIXDOG_HOME = process.env.MIXDOG_HOME ||
|
|
50919
|
-
var DEFAULT_STANDALONE_DATA_DIR =
|
|
51100
|
+
var DEFAULT_MIXDOG_HOME = process.env.MIXDOG_HOME || join10(homedir2(), ".mixdog");
|
|
51101
|
+
var DEFAULT_STANDALONE_DATA_DIR = join10(DEFAULT_MIXDOG_HOME, "data");
|
|
50920
51102
|
var SHELL_JOBS_SEGMENT_CACHE_MS = 1e3;
|
|
50921
51103
|
var FINISHED_SHELL_JOB_TTL_MS = 30 * 60 * 1e3;
|
|
50922
51104
|
var EMPTY_SHELL_JOBS_SESSION = Object.freeze({
|
|
@@ -50963,6 +51145,10 @@ function shellJobsStatus({ clientHostPid, sessionId } = {}) {
|
|
|
50963
51145
|
if (!scoped) return sessions === own.sessions ? own : { ...own, sessions };
|
|
50964
51146
|
return scope && sessions?.[scope] || EMPTY_SHELL_JOBS_SESSION;
|
|
50965
51147
|
}
|
|
51148
|
+
function unconfirmedShellCount(status) {
|
|
51149
|
+
const jobs = Array.isArray(status?.jobs) ? status.jobs : [];
|
|
51150
|
+
return jobs.filter((job) => job?.terminationUnconfirmed === true).length;
|
|
51151
|
+
}
|
|
50966
51152
|
function freshestShellJobsSessions() {
|
|
50967
51153
|
let freshest = null;
|
|
50968
51154
|
for (const entry of _shellJobsSegmentCache.values()) {
|
|
@@ -50973,7 +51159,7 @@ function freshestShellJobsSessions() {
|
|
|
50973
51159
|
async function refreshShellJobsStatus(ownerPid) {
|
|
50974
51160
|
let value = EMPTY_SHELL_JOBS;
|
|
50975
51161
|
try {
|
|
50976
|
-
const dir =
|
|
51162
|
+
const dir = join10(dataDir(), "shell-jobs");
|
|
50977
51163
|
let names;
|
|
50978
51164
|
try {
|
|
50979
51165
|
names = await readdir(dir);
|
|
@@ -50985,17 +51171,19 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
50985
51171
|
let count = 0;
|
|
50986
51172
|
let oldestMs = Infinity;
|
|
50987
51173
|
const jobs = [];
|
|
51174
|
+
const orphaned = [];
|
|
50988
51175
|
const bySession = /* @__PURE__ */ new Map();
|
|
50989
51176
|
for (const id of ids) {
|
|
50990
|
-
const p =
|
|
51177
|
+
const p = join10(dir, `${id}.json`);
|
|
50991
51178
|
let detail;
|
|
50992
51179
|
try {
|
|
50993
51180
|
detail = JSON.parse(await readFile(p, "utf-8"));
|
|
50994
51181
|
} catch {
|
|
50995
51182
|
continue;
|
|
50996
51183
|
}
|
|
50997
|
-
|
|
50998
|
-
if (detail
|
|
51184
|
+
const unconfirmed = detail?.terminationUnconfirmed === true;
|
|
51185
|
+
if (unconfirmed ? !isPidAlive(ownerByJob.get(id) || 0) : !await isShellJobAlive(detail, p, dir, id)) continue;
|
|
51186
|
+
if (detail?.foreground === true && !unconfirmed) continue;
|
|
50999
51187
|
const ownedByThisHost = ownerByJob.get(id) === ownerPid;
|
|
51000
51188
|
if (ownedByThisHost) count++;
|
|
51001
51189
|
let jobMs = Infinity;
|
|
@@ -51010,9 +51198,11 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51010
51198
|
taskId: id,
|
|
51011
51199
|
command: String(detail?.command || "").trim(),
|
|
51012
51200
|
cwd: String(detail?.cwd || "").trim(),
|
|
51013
|
-
startedAt: detail?.startedAt || (Number.isFinite(jobMs) ? jobMs : null)
|
|
51201
|
+
startedAt: detail?.startedAt || (Number.isFinite(jobMs) ? jobMs : null),
|
|
51202
|
+
...unconfirmed ? { terminationUnconfirmed: true } : {}
|
|
51014
51203
|
};
|
|
51015
51204
|
if (ownedByThisHost) jobs.push(job);
|
|
51205
|
+
if (unconfirmed && detail?.ownerSessionClosed === true) orphaned.push(job);
|
|
51016
51206
|
if (!owner) continue;
|
|
51017
51207
|
const bucket = bySession.get(owner) || { count: 0, oldestMs: Infinity, jobs: [], finished: [] };
|
|
51018
51208
|
bucket.count += 1;
|
|
@@ -51024,7 +51214,7 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51024
51214
|
for (const id of doneIds) {
|
|
51025
51215
|
let detail;
|
|
51026
51216
|
try {
|
|
51027
|
-
detail = JSON.parse(await readFile(
|
|
51217
|
+
detail = JSON.parse(await readFile(join10(dir, `${id}.json`), "utf-8"));
|
|
51028
51218
|
} catch {
|
|
51029
51219
|
continue;
|
|
51030
51220
|
}
|
|
@@ -51046,6 +51236,7 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51046
51236
|
bySession.set(owner, bucket);
|
|
51047
51237
|
}
|
|
51048
51238
|
if (count || bySession.size) value = summarizeShellJobs({ count, oldestMs, jobs, bySession });
|
|
51239
|
+
if (orphaned.length) value = { ...value, orphaned };
|
|
51049
51240
|
} catch {
|
|
51050
51241
|
value = EMPTY_SHELL_JOBS;
|
|
51051
51242
|
}
|
|
@@ -51086,7 +51277,7 @@ async function isShellJobAlive(detail, detailPath, dir, id) {
|
|
|
51086
51277
|
try {
|
|
51087
51278
|
const st = await stat(detailPath);
|
|
51088
51279
|
const timeoutMs = Number(detail?.timeoutMs);
|
|
51089
|
-
const enforced = detail?.timeoutEnforced === true || await stat(
|
|
51280
|
+
const enforced = detail?.timeoutEnforced === true || await stat(join10(dir, `${id}.enforced`)).then(
|
|
51090
51281
|
() => true,
|
|
51091
51282
|
() => false
|
|
51092
51283
|
);
|
|
@@ -51270,11 +51461,17 @@ function localStatusLineL2({ agentWorkers = [], agentJobs = [], activeTools = nu
|
|
|
51270
51461
|
}
|
|
51271
51462
|
const shellScope = String(sessionId ?? "").trim();
|
|
51272
51463
|
const shellStatus = shellScope ? shellJobsStatus({ clientHostPid, sessionId: shellScope }) : shellJobsStatus({ clientHostPid });
|
|
51273
|
-
const
|
|
51464
|
+
const unconfirmed = unconfirmedShellCount(shellStatus);
|
|
51465
|
+
const shellCount = (Number(shellStatus?.count) || 0) - unconfirmed;
|
|
51274
51466
|
if (shellCount > 0) {
|
|
51275
51467
|
const label = `Running ${shellCount} Shell${shellCount === 1 ? "" : "s"}`;
|
|
51276
51468
|
l2Parts.push(`${spin} ${STATUS}${label}${RESET3}${elapsedSuffix(shellStatus.elapsedLabel || "")}`);
|
|
51277
51469
|
}
|
|
51470
|
+
if (unconfirmed > 0) {
|
|
51471
|
+
const { WARNING } = statusColors();
|
|
51472
|
+
const label = `\u26A0 ${unconfirmed} Shell${unconfirmed === 1 ? "" : "s"} termination unconfirmed`;
|
|
51473
|
+
l2Parts.push(`${WARNING}${label}${RESET3} ${SUBTLE}\xB7${RESET3} /shells`);
|
|
51474
|
+
}
|
|
51278
51475
|
const tools = activeTools && typeof activeTools === "object" ? activeTools : {};
|
|
51279
51476
|
const searchInfo = tools.web_search || null;
|
|
51280
51477
|
if (searchInfo && num(searchInfo.count) > 0) {
|
|
@@ -55442,7 +55639,7 @@ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionP
|
|
|
55442
55639
|
toolApproval.id
|
|
55443
55640
|
);
|
|
55444
55641
|
}
|
|
55445
|
-
const
|
|
55642
|
+
const resolve6 = (approved) => {
|
|
55446
55643
|
store.resolveToolApproval?.(toolApproval.id, {
|
|
55447
55644
|
approved,
|
|
55448
55645
|
reason: approved ? "approved by user" : "denied by user"
|
|
@@ -55467,12 +55664,12 @@ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionP
|
|
|
55467
55664
|
description: "run this tool call"
|
|
55468
55665
|
}
|
|
55469
55666
|
],
|
|
55470
|
-
onSelect: (value) =>
|
|
55471
|
-
onCancel: () =>
|
|
55667
|
+
onSelect: (value) => resolve6(value === "approve"),
|
|
55668
|
+
onCancel: () => resolve6(false),
|
|
55472
55669
|
onKey: (input) => {
|
|
55473
55670
|
const value = String(input || "").trim().toLowerCase();
|
|
55474
|
-
if (value === "a" || value === "y")
|
|
55475
|
-
else if (value === "d" || value === "n")
|
|
55671
|
+
if (value === "a" || value === "y") resolve6(true);
|
|
55672
|
+
else if (value === "d" || value === "n") resolve6(false);
|
|
55476
55673
|
},
|
|
55477
55674
|
title: "Tool approval",
|
|
55478
55675
|
description: toolApprovalDescription(toolApproval),
|
|
@@ -56646,6 +56843,7 @@ function renderAppView(ctx) {
|
|
|
56646
56843
|
thinkingActiveSince: liveSpinner?.thinkingSegmentStartedAt ?? 0,
|
|
56647
56844
|
thinkingMs: liveSpinner?.thinkingAccumulatedMs ?? 0,
|
|
56648
56845
|
effort: state.effort || "",
|
|
56846
|
+
quiet: liveSpinner?.quiet ?? null,
|
|
56649
56847
|
hasActiveTools: !!activeTools?.web_search?.count,
|
|
56650
56848
|
paused: !!toolApproval,
|
|
56651
56849
|
interruptible: !!(state.busy && state.spinner?.active),
|
|
@@ -56729,7 +56927,7 @@ function renderAppView(ctx) {
|
|
|
56729
56927
|
StatusLine,
|
|
56730
56928
|
{
|
|
56731
56929
|
sessionId: state.sessionId,
|
|
56732
|
-
clientHostPid: state.
|
|
56930
|
+
clientHostPid: state.clientHostPid,
|
|
56733
56931
|
provider: state.provider,
|
|
56734
56932
|
model: state.model,
|
|
56735
56933
|
effort: state.effort,
|
|
@@ -59356,7 +59554,7 @@ function createOnboardingSteps({
|
|
|
59356
59554
|
import { spawn as spawn3 } from "node:child_process";
|
|
59357
59555
|
|
|
59358
59556
|
// src/runtime/shared/wsl.mjs
|
|
59359
|
-
import { readFileSync as
|
|
59557
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
59360
59558
|
var _isWSL;
|
|
59361
59559
|
function isWSL() {
|
|
59362
59560
|
if (_isWSL !== void 0) return _isWSL;
|
|
@@ -59369,7 +59567,7 @@ function isWSL() {
|
|
|
59369
59567
|
return _isWSL;
|
|
59370
59568
|
}
|
|
59371
59569
|
try {
|
|
59372
|
-
const v =
|
|
59570
|
+
const v = readFileSync10("/proc/version", "utf8").toLowerCase();
|
|
59373
59571
|
_isWSL = v.includes("microsoft") || v.includes("wsl");
|
|
59374
59572
|
} catch {
|
|
59375
59573
|
_isWSL = false;
|
|
@@ -59476,6 +59674,20 @@ function buildProviderItems(setup) {
|
|
|
59476
59674
|
_authenticated: p.authenticated
|
|
59477
59675
|
});
|
|
59478
59676
|
}
|
|
59677
|
+
if (setup.managedByClient === true) {
|
|
59678
|
+
for (const p of setup.local || []) {
|
|
59679
|
+
providerItems.push({
|
|
59680
|
+
value: `local:${p.id}`,
|
|
59681
|
+
label: p.name,
|
|
59682
|
+
meta: providerStatusLabel(p),
|
|
59683
|
+
description: "",
|
|
59684
|
+
_type: "local",
|
|
59685
|
+
_providerId: p.id,
|
|
59686
|
+
_providerName: p.name,
|
|
59687
|
+
_provider: p
|
|
59688
|
+
});
|
|
59689
|
+
}
|
|
59690
|
+
}
|
|
59479
59691
|
providerItems.sort((a, b) => {
|
|
59480
59692
|
const rank = providerItemRank(a) - providerItemRank(b);
|
|
59481
59693
|
if (rank !== 0) return rank;
|
|
@@ -59801,8 +60013,8 @@ function createProviderSetupPicker({
|
|
|
59801
60013
|
}
|
|
59802
60014
|
});
|
|
59803
60015
|
try {
|
|
59804
|
-
await new Promise((
|
|
59805
|
-
return await store.getProviderSetup();
|
|
60016
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
60017
|
+
return await store.getProviderSetup(options.forceRefresh ? { force: true } : void 0);
|
|
59806
60018
|
} catch (e) {
|
|
59807
60019
|
store.pushNotice(`providers failed: ${e?.message || e}`, "error");
|
|
59808
60020
|
return null;
|
|
@@ -59833,6 +60045,9 @@ function createProviderSetupPicker({
|
|
|
59833
60045
|
});
|
|
59834
60046
|
}
|
|
59835
60047
|
items.push(...buildProviderItems(setup));
|
|
60048
|
+
if (setup.managedByClient === true) {
|
|
60049
|
+
items.push({ value: "refresh-client-providers", label: "Refresh", _type: "refresh-client-providers" });
|
|
60050
|
+
}
|
|
59836
60051
|
const flow = {
|
|
59837
60052
|
store,
|
|
59838
60053
|
setProviderPrompt,
|
|
@@ -59858,10 +60073,10 @@ function createProviderSetupPicker({
|
|
|
59858
60073
|
};
|
|
59859
60074
|
flow.paint({
|
|
59860
60075
|
title: options.title || "Providers",
|
|
59861
|
-
description: options.description || "Choose a provider. Enter opens provider actions.",
|
|
60076
|
+
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
60077
|
footer: providerFooter,
|
|
59863
60078
|
footerGapRows: 1,
|
|
59864
|
-
help: options.confirmBar ? void 0 : "\u2191/\u2193 Select \xB7 Enter Open \xB7 Esc Back",
|
|
60079
|
+
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
60080
|
indexMode: "always",
|
|
59866
60081
|
labelWidth: 18,
|
|
59867
60082
|
metaWidth: 12,
|
|
@@ -59873,6 +60088,12 @@ function createProviderSetupPicker({
|
|
|
59873
60088
|
if (item?._providerId) flow.rememberProviderSelection(item);
|
|
59874
60089
|
},
|
|
59875
60090
|
onSelect: (_value, item) => {
|
|
60091
|
+
if (setup.managedByClient === true && item._type !== "continue") {
|
|
60092
|
+
if (item._type === "refresh-client-providers") {
|
|
60093
|
+
void openProviderSetupPicker({ ...options, preloadedSetup: null, forceRefresh: true });
|
|
60094
|
+
}
|
|
60095
|
+
return;
|
|
60096
|
+
}
|
|
59876
60097
|
flow.releaseSurface();
|
|
59877
60098
|
if (item._type === "continue") {
|
|
59878
60099
|
onContinue?.();
|
|
@@ -59914,7 +60135,7 @@ function createModelCatalog({ store, providerModelsCacheRef, webSearchModelsCach
|
|
|
59914
60135
|
let renderedQuickModels = false;
|
|
59915
60136
|
if (!providerModels.length || options.refreshModels === true) {
|
|
59916
60137
|
paintLoading();
|
|
59917
|
-
await new Promise((
|
|
60138
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
59918
60139
|
try {
|
|
59919
60140
|
if (options.refreshModels !== true && options.cacheRef !== "webSearch") {
|
|
59920
60141
|
refreshModelsPromise = Promise.resolve(loadModels({ force: false }));
|
|
@@ -60915,8 +61136,8 @@ function createSettingsNavigation({ openers, openSettingsPicker, setSettingsProm
|
|
|
60915
61136
|
}
|
|
60916
61137
|
|
|
60917
61138
|
// src/runtime/shared/config.mjs
|
|
60918
|
-
import { readFileSync as
|
|
60919
|
-
import { join as
|
|
61139
|
+
import { readFileSync as readFileSync12, statSync as statSync4, mkdirSync as mkdirSync5, existsSync as existsSync11, watch as fsWatch } from "node:fs";
|
|
61140
|
+
import { join as join12, dirname as dirname10 } from "node:path";
|
|
60920
61141
|
import { createRequire as createRequire3 } from "node:module";
|
|
60921
61142
|
|
|
60922
61143
|
// src/runtime/shared/object.mjs
|
|
@@ -60933,12 +61154,12 @@ init_atomic_file();
|
|
|
60933
61154
|
// src/runtime/shared/user-data-guard.mjs
|
|
60934
61155
|
import {
|
|
60935
61156
|
copyFileSync,
|
|
60936
|
-
existsSync as
|
|
61157
|
+
existsSync as existsSync10,
|
|
60937
61158
|
mkdirSync as mkdirSync4,
|
|
60938
61159
|
readdirSync as readdirSync2,
|
|
60939
|
-
readFileSync as
|
|
61160
|
+
readFileSync as readFileSync11,
|
|
60940
61161
|
rmSync,
|
|
60941
|
-
statSync as
|
|
61162
|
+
statSync as statSync3,
|
|
60942
61163
|
writeFileSync as writeFileSync4
|
|
60943
61164
|
} from "node:fs";
|
|
60944
61165
|
import {
|
|
@@ -60948,11 +61169,11 @@ import {
|
|
|
60948
61169
|
rm as rmP,
|
|
60949
61170
|
stat as statP
|
|
60950
61171
|
} from "node:fs/promises";
|
|
60951
|
-
import { basename as basename5, dirname as
|
|
61172
|
+
import { basename as basename5, dirname as dirname9, join as join11, resolve as resolve5 } from "node:path";
|
|
60952
61173
|
import { homedir as homedir3 } from "node:os";
|
|
60953
61174
|
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
60954
61175
|
function getBackupRoot() {
|
|
60955
|
-
return process.env.MIXDOG_USER_DATA_BACKUP_ROOT ||
|
|
61176
|
+
return process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join11(process.env.MIXDOG_HOME || process.env.MIXDOG_CONFIG_DIR || mixdogHome(), "backups", "user-data");
|
|
60956
61177
|
}
|
|
60957
61178
|
var USER_DATA_FILES = ["mixdog-config.json"];
|
|
60958
61179
|
var USER_DATA_DIRS = ["schedules", "webhooks", "workflows"];
|
|
@@ -60960,12 +61181,12 @@ var BACKUP_MANIFEST = "backup.json";
|
|
|
60960
61181
|
var INIT_MARKER = ".mixdog-user-data.json";
|
|
60961
61182
|
var SCOPE_PREFIX = "scope-";
|
|
60962
61183
|
function normalizeDataDir(dataDir2) {
|
|
60963
|
-
const full =
|
|
61184
|
+
const full = resolve5(String(dataDir2));
|
|
60964
61185
|
return process.platform === "win32" ? full.toLowerCase() : full;
|
|
60965
61186
|
}
|
|
60966
61187
|
function scopeDirFor(dataDir2) {
|
|
60967
61188
|
const id = createHash4("sha256").update(normalizeDataDir(dataDir2)).digest("hex").slice(0, 16);
|
|
60968
|
-
return
|
|
61189
|
+
return join11(getBackupRoot(), `${SCOPE_PREFIX}${id}`);
|
|
60969
61190
|
}
|
|
60970
61191
|
function stamp() {
|
|
60971
61192
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -60976,7 +61197,7 @@ function safeReason(reason) {
|
|
|
60976
61197
|
function readInitInstanceId(dataDir2) {
|
|
60977
61198
|
if (!dataDir2) return null;
|
|
60978
61199
|
try {
|
|
60979
|
-
const marker = JSON.parse(
|
|
61200
|
+
const marker = JSON.parse(readFileSync11(join11(dataDir2, INIT_MARKER), "utf8"));
|
|
60980
61201
|
return typeof marker?.instanceId === "string" && marker.instanceId ? marker.instanceId : null;
|
|
60981
61202
|
} catch {
|
|
60982
61203
|
return null;
|
|
@@ -60986,13 +61207,13 @@ function hasUserDataInitMarker(dataDir2) {
|
|
|
60986
61207
|
return readInitInstanceId(dataDir2) != null;
|
|
60987
61208
|
}
|
|
60988
61209
|
function legacyBackupRoots() {
|
|
60989
|
-
const legacy = process.env.MIXDOG_USER_DATA_BACKUP_ROOT ||
|
|
61210
|
+
const legacy = process.env.MIXDOG_USER_DATA_BACKUP_ROOT || join11(process.env.MIXDOG_CONFIG_DIR || join11(homedir3(), ".mixdog"), "backups", "user-data");
|
|
60990
61211
|
const current = getBackupRoot();
|
|
60991
61212
|
return normalizeDataDir(legacy) === normalizeDataDir(current) ? [current] : [current, legacy];
|
|
60992
61213
|
}
|
|
60993
61214
|
function manifestDataDirMatches(backupDir, dataDirKey) {
|
|
60994
61215
|
try {
|
|
60995
|
-
const manifest = JSON.parse(
|
|
61216
|
+
const manifest = JSON.parse(readFileSync11(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
60996
61217
|
return typeof manifest?.dataDir === "string" && normalizeDataDir(manifest.dataDir) === dataDirKey;
|
|
60997
61218
|
} catch {
|
|
60998
61219
|
return false;
|
|
@@ -61000,7 +61221,7 @@ function manifestDataDirMatches(backupDir, dataDirKey) {
|
|
|
61000
61221
|
}
|
|
61001
61222
|
function legacyMarkersFor(root, dataDir2, dataDirKey) {
|
|
61002
61223
|
const hashed = new Set(
|
|
61003
|
-
[String(dataDir2),
|
|
61224
|
+
[String(dataDir2), resolve5(String(dataDir2))].map(
|
|
61004
61225
|
(value) => `.initialized-${createHash4("sha256").update(value).digest("hex").slice(0, 16)}.json`
|
|
61005
61226
|
)
|
|
61006
61227
|
);
|
|
@@ -61013,12 +61234,12 @@ function legacyMarkersFor(root, dataDir2, dataDirKey) {
|
|
|
61013
61234
|
return names.filter((name) => {
|
|
61014
61235
|
if (hashed.has(name)) return true;
|
|
61015
61236
|
try {
|
|
61016
|
-
const marker = JSON.parse(
|
|
61237
|
+
const marker = JSON.parse(readFileSync11(join11(root, name), "utf8"));
|
|
61017
61238
|
return typeof marker?.dataDir === "string" && normalizeDataDir(marker.dataDir) === dataDirKey;
|
|
61018
61239
|
} catch {
|
|
61019
61240
|
return false;
|
|
61020
61241
|
}
|
|
61021
|
-
}).map((name) =>
|
|
61242
|
+
}).map((name) => join11(root, name));
|
|
61022
61243
|
}
|
|
61023
61244
|
function findLegacyUserDataEvidence(dataDir2, { fresh = false } = {}) {
|
|
61024
61245
|
if (!dataDir2 || hasUserDataInitMarker(dataDir2)) return null;
|
|
@@ -61039,7 +61260,7 @@ function scanLegacyUserDataEvidence(dataDir2, key) {
|
|
|
61039
61260
|
markers.push(...legacyMarkersFor(root, dataDir2, key));
|
|
61040
61261
|
for (const name of backupDirsNewestFirst(root)) {
|
|
61041
61262
|
if (name.startsWith(SCOPE_PREFIX)) continue;
|
|
61042
|
-
if (manifestDataDirMatches(
|
|
61263
|
+
if (manifestDataDirMatches(join11(root, name), key)) backups.push(join11(root, name));
|
|
61043
61264
|
}
|
|
61044
61265
|
}
|
|
61045
61266
|
backups.sort((x, y) => basename5(y).localeCompare(basename5(x)));
|
|
@@ -61063,10 +61284,10 @@ function backupDirsNewestFirst(dir) {
|
|
|
61063
61284
|
}
|
|
61064
61285
|
function readRestorableConfig(backupDir, dataDirKey, instanceId) {
|
|
61065
61286
|
try {
|
|
61066
|
-
const manifest = JSON.parse(
|
|
61287
|
+
const manifest = JSON.parse(readFileSync11(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
61067
61288
|
if (typeof manifest?.dataDir !== "string" || normalizeDataDir(manifest.dataDir) !== dataDirKey) return null;
|
|
61068
61289
|
if (manifest.instanceId !== instanceId) return null;
|
|
61069
|
-
const parsed = JSON.parse(
|
|
61290
|
+
const parsed = JSON.parse(readFileSync11(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61070
61291
|
return isStructurallyCompleteMixdogConfigBackup(parsed) ? parsed : null;
|
|
61071
61292
|
} catch {
|
|
61072
61293
|
return null;
|
|
@@ -61076,13 +61297,13 @@ function findRestorableConfig(dataDir2, instanceId) {
|
|
|
61076
61297
|
const key = normalizeDataDir(dataDir2);
|
|
61077
61298
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61078
61299
|
for (const name of backupDirsNewestFirst(scopeDir)) {
|
|
61079
|
-
const parsed = readRestorableConfig(
|
|
61300
|
+
const parsed = readRestorableConfig(join11(scopeDir, name), key, instanceId);
|
|
61080
61301
|
if (parsed) return parsed;
|
|
61081
61302
|
}
|
|
61082
61303
|
const root = getBackupRoot();
|
|
61083
61304
|
for (const name of backupDirsNewestFirst(root)) {
|
|
61084
61305
|
if (name.startsWith(SCOPE_PREFIX)) continue;
|
|
61085
|
-
const parsed = readRestorableConfig(
|
|
61306
|
+
const parsed = readRestorableConfig(join11(root, name), key, instanceId);
|
|
61086
61307
|
if (parsed) return parsed;
|
|
61087
61308
|
}
|
|
61088
61309
|
return null;
|
|
@@ -61104,7 +61325,7 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61104
61325
|
const evidence = findLegacyUserDataEvidence(dataDir2, options);
|
|
61105
61326
|
for (const backupDir of evidence?.backups || []) {
|
|
61106
61327
|
try {
|
|
61107
|
-
const parsed = JSON.parse(
|
|
61328
|
+
const parsed = JSON.parse(readFileSync11(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61108
61329
|
if (isStructurallyCompleteMixdogConfigBackup(parsed)) return parsed;
|
|
61109
61330
|
} catch {
|
|
61110
61331
|
}
|
|
@@ -61112,40 +61333,40 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61112
61333
|
return null;
|
|
61113
61334
|
}
|
|
61114
61335
|
function copyTree(src, dst, copied) {
|
|
61115
|
-
const st =
|
|
61336
|
+
const st = statSync3(src);
|
|
61116
61337
|
if (st.isDirectory()) {
|
|
61117
61338
|
for (const name of readdirSync2(src)) {
|
|
61118
|
-
copyTree(
|
|
61339
|
+
copyTree(join11(src, name), join11(dst, name), copied);
|
|
61119
61340
|
}
|
|
61120
61341
|
return;
|
|
61121
61342
|
}
|
|
61122
61343
|
if (!st.isFile()) return;
|
|
61123
|
-
mkdirSync4(
|
|
61344
|
+
mkdirSync4(dirname9(dst), { recursive: true });
|
|
61124
61345
|
copyFileSync(src, dst);
|
|
61125
61346
|
copied.push(dst);
|
|
61126
61347
|
}
|
|
61127
61348
|
function pruneBackups(scopeDir, keep = 40) {
|
|
61128
61349
|
for (const name of backupDirsNewestFirst(scopeDir).slice(keep)) {
|
|
61129
61350
|
try {
|
|
61130
|
-
rmSync(
|
|
61351
|
+
rmSync(join11(scopeDir, name), { recursive: true, force: true });
|
|
61131
61352
|
} catch {
|
|
61132
61353
|
}
|
|
61133
61354
|
}
|
|
61134
61355
|
}
|
|
61135
61356
|
function markUserDataInitialized(dataDir2) {
|
|
61136
61357
|
const existing = readInitInstanceId(dataDir2);
|
|
61137
|
-
if (existing || !dataDir2 || !
|
|
61358
|
+
if (existing || !dataDir2 || !existsSync10(dataDir2)) return existing;
|
|
61138
61359
|
try {
|
|
61139
61360
|
writeFileSync4(
|
|
61140
|
-
|
|
61361
|
+
join11(dataDir2, INIT_MARKER),
|
|
61141
61362
|
`${JSON.stringify(
|
|
61142
|
-
{ instanceId: randomUUID(), dataDir:
|
|
61363
|
+
{ instanceId: randomUUID(), dataDir: resolve5(dataDir2), createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
61143
61364
|
null,
|
|
61144
61365
|
2
|
|
61145
61366
|
)}
|
|
61146
61367
|
`,
|
|
61147
61368
|
// An unreadable marker is replaced; a concurrent creator's valid one wins.
|
|
61148
|
-
{ encoding: "utf8", flag:
|
|
61369
|
+
{ encoding: "utf8", flag: existsSync10(join11(dataDir2, INIT_MARKER)) ? "w" : "wx" }
|
|
61149
61370
|
);
|
|
61150
61371
|
} catch {
|
|
61151
61372
|
}
|
|
@@ -61164,14 +61385,14 @@ function skipBackups() {
|
|
|
61164
61385
|
}
|
|
61165
61386
|
function backupTarget(dataDir2, reason) {
|
|
61166
61387
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61167
|
-
return { scopeDir, backupDir:
|
|
61388
|
+
return { scopeDir, backupDir: join11(scopeDir, `${stamp()}-${safeReason(reason)}`) };
|
|
61168
61389
|
}
|
|
61169
61390
|
function finishBackup(dataDir2, backupDir, reason) {
|
|
61170
61391
|
const instanceId = markUserDataInitialized(dataDir2);
|
|
61171
61392
|
writeFileSync4(
|
|
61172
|
-
|
|
61393
|
+
join11(backupDir, BACKUP_MANIFEST),
|
|
61173
61394
|
`${JSON.stringify(
|
|
61174
|
-
{ dataDir:
|
|
61395
|
+
{ dataDir: resolve5(dataDir2), instanceId, reason, createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
61175
61396
|
null,
|
|
61176
61397
|
2
|
|
61177
61398
|
)}
|
|
@@ -61183,16 +61404,16 @@ function finishBackup(dataDir2, backupDir, reason) {
|
|
|
61183
61404
|
}
|
|
61184
61405
|
function backupUserData(dataDir2, reason = "snapshot") {
|
|
61185
61406
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61186
|
-
if (!dataDir2 || !
|
|
61407
|
+
if (!dataDir2 || !existsSync10(dataDir2)) return { dir: null, copied: [] };
|
|
61187
61408
|
const { scopeDir, backupDir } = backupTarget(dataDir2, reason);
|
|
61188
61409
|
const copied = [];
|
|
61189
61410
|
for (const rel of USER_DATA_FILES) {
|
|
61190
|
-
const src =
|
|
61191
|
-
if (
|
|
61411
|
+
const src = join11(dataDir2, rel);
|
|
61412
|
+
if (existsSync10(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
61192
61413
|
}
|
|
61193
61414
|
for (const rel of USER_DATA_DIRS) {
|
|
61194
|
-
const src =
|
|
61195
|
-
if (
|
|
61415
|
+
const src = join11(dataDir2, rel);
|
|
61416
|
+
if (existsSync10(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
61196
61417
|
}
|
|
61197
61418
|
if (copied.length > 0) {
|
|
61198
61419
|
finishBackup(dataDir2, backupDir, reason);
|
|
@@ -61208,12 +61429,12 @@ async function copyTreeAsync(src, dst, copied) {
|
|
|
61208
61429
|
const st = await statP(src);
|
|
61209
61430
|
if (st.isDirectory()) {
|
|
61210
61431
|
for (const name of await readdirP(src)) {
|
|
61211
|
-
await copyTreeAsync(
|
|
61432
|
+
await copyTreeAsync(join11(src, name), join11(dst, name), copied);
|
|
61212
61433
|
}
|
|
61213
61434
|
return;
|
|
61214
61435
|
}
|
|
61215
61436
|
if (!st.isFile()) return;
|
|
61216
|
-
await mkdirP(
|
|
61437
|
+
await mkdirP(dirname9(dst), { recursive: true });
|
|
61217
61438
|
await copyFileP(src, dst);
|
|
61218
61439
|
copied.push(dst);
|
|
61219
61440
|
}
|
|
@@ -61226,23 +61447,23 @@ async function pruneBackupsAsync(scopeDir, keep = 40) {
|
|
|
61226
61447
|
}
|
|
61227
61448
|
for (const name of entries.slice(keep)) {
|
|
61228
61449
|
try {
|
|
61229
|
-
await rmP(
|
|
61450
|
+
await rmP(join11(scopeDir, name), { recursive: true, force: true });
|
|
61230
61451
|
} catch {
|
|
61231
61452
|
}
|
|
61232
61453
|
}
|
|
61233
61454
|
}
|
|
61234
61455
|
async function backupUserDataAsync(dataDir2, reason = "snapshot") {
|
|
61235
61456
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61236
|
-
if (!dataDir2 || !
|
|
61457
|
+
if (!dataDir2 || !existsSync10(dataDir2)) return { dir: null, copied: [] };
|
|
61237
61458
|
const { scopeDir, backupDir } = backupTarget(dataDir2, reason);
|
|
61238
61459
|
const copied = [];
|
|
61239
61460
|
for (const rel of USER_DATA_FILES) {
|
|
61240
|
-
const src =
|
|
61241
|
-
if (
|
|
61461
|
+
const src = join11(dataDir2, rel);
|
|
61462
|
+
if (existsSync10(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
61242
61463
|
}
|
|
61243
61464
|
for (const rel of USER_DATA_DIRS) {
|
|
61244
|
-
const src =
|
|
61245
|
-
if (
|
|
61465
|
+
const src = join11(dataDir2, rel);
|
|
61466
|
+
if (existsSync10(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
61246
61467
|
}
|
|
61247
61468
|
if (copied.length > 0) {
|
|
61248
61469
|
finishBackup(dataDir2, backupDir, reason);
|
|
@@ -61287,7 +61508,7 @@ var {
|
|
|
61287
61508
|
onKeychainRecovered: _onKeychainRecovered
|
|
61288
61509
|
} = _require("../../lib/keychain-cjs.cjs");
|
|
61289
61510
|
function configPath() {
|
|
61290
|
-
return
|
|
61511
|
+
return join12(resolvePluginData(), "mixdog-config.json");
|
|
61291
61512
|
}
|
|
61292
61513
|
var GENERATED_KEY = "_generated";
|
|
61293
61514
|
var DEFAULTS_VERSION = 2;
|
|
@@ -61316,7 +61537,7 @@ function readConfigRawCached() {
|
|
|
61316
61537
|
return _configReadCache.raw;
|
|
61317
61538
|
}
|
|
61318
61539
|
try {
|
|
61319
|
-
const st2 =
|
|
61540
|
+
const st2 = statSync4(configPath());
|
|
61320
61541
|
if (st2.mtimeMs === _configReadCache.mtimeMs && st2.size === _configReadCache.size) {
|
|
61321
61542
|
_configReadCache.atMs = now;
|
|
61322
61543
|
return _configReadCache.raw;
|
|
@@ -61326,7 +61547,7 @@ function readConfigRawCached() {
|
|
|
61326
61547
|
}
|
|
61327
61548
|
let st = null;
|
|
61328
61549
|
try {
|
|
61329
|
-
st =
|
|
61550
|
+
st = statSync4(configPath());
|
|
61330
61551
|
} catch (err) {
|
|
61331
61552
|
if (err.code === "ENOENT") {
|
|
61332
61553
|
_configReadCache = null;
|
|
@@ -61338,7 +61559,7 @@ function readConfigRawCached() {
|
|
|
61338
61559
|
}
|
|
61339
61560
|
let raw;
|
|
61340
61561
|
try {
|
|
61341
|
-
raw =
|
|
61562
|
+
raw = readFileSync12(configPath(), "utf8");
|
|
61342
61563
|
} catch (err) {
|
|
61343
61564
|
if (err.code === "ENOENT") {
|
|
61344
61565
|
_configReadCache = null;
|
|
@@ -61413,7 +61634,7 @@ function readConfigFile() {
|
|
|
61413
61634
|
}
|
|
61414
61635
|
}
|
|
61415
61636
|
function writeConfigFile(data, postBackupReason = "post-config-write") {
|
|
61416
|
-
mkdirSync5(
|
|
61637
|
+
mkdirSync5(dirname10(configPath()), { recursive: true, mode: 448 });
|
|
61417
61638
|
try {
|
|
61418
61639
|
backupUserData(resolvePluginData(), "pre-config-write");
|
|
61419
61640
|
} catch {
|
|
@@ -61437,7 +61658,7 @@ function persistRestoredConfig(restored) {
|
|
|
61437
61658
|
const wrote = withFileLockSync(
|
|
61438
61659
|
`${path2}.lock`,
|
|
61439
61660
|
() => {
|
|
61440
|
-
if (
|
|
61661
|
+
if (existsSync11(path2)) return false;
|
|
61441
61662
|
writeAll(restored, "post-restore");
|
|
61442
61663
|
return true;
|
|
61443
61664
|
},
|
|
@@ -61479,7 +61700,7 @@ function readAll() {
|
|
|
61479
61700
|
function quarantineMalformedConfig(parseErr) {
|
|
61480
61701
|
const corrupt = `${configPath()}.corrupt-${Date.now()}`;
|
|
61481
61702
|
try {
|
|
61482
|
-
if (
|
|
61703
|
+
if (existsSync11(configPath())) renameWithRetrySync(configPath(), corrupt);
|
|
61483
61704
|
} catch {
|
|
61484
61705
|
}
|
|
61485
61706
|
process.stderr.write(
|
|
@@ -61509,7 +61730,7 @@ function restoreAllForRmWOrThrow(reason) {
|
|
|
61509
61730
|
function readAllForRmW() {
|
|
61510
61731
|
let raw;
|
|
61511
61732
|
try {
|
|
61512
|
-
raw =
|
|
61733
|
+
raw = readFileSync12(configPath(), "utf8");
|
|
61513
61734
|
} catch (err) {
|
|
61514
61735
|
if (err.code === "ENOENT") {
|
|
61515
61736
|
if (isUserDataRecoveryExpected(resolvePluginData(), { fresh: true })) {
|
|
@@ -61556,7 +61777,7 @@ function readSection(section) {
|
|
|
61556
61777
|
return stripGeneratedMarker(readAll()[section] ?? null) ?? {};
|
|
61557
61778
|
}
|
|
61558
61779
|
async function writeConfigFileAsync(data) {
|
|
61559
|
-
mkdirSync5(
|
|
61780
|
+
mkdirSync5(dirname10(configPath()), { recursive: true, mode: 448 });
|
|
61560
61781
|
try {
|
|
61561
61782
|
await backupUserDataAsync(resolvePluginData(), "pre-config-write");
|
|
61562
61783
|
} catch {
|
|
@@ -62550,6 +62771,44 @@ var sessionCommands = {
|
|
|
62550
62771
|
}).catch((e) => store.pushNotice(`fork failed: ${e?.message || e}`, "error"));
|
|
62551
62772
|
return true;
|
|
62552
62773
|
},
|
|
62774
|
+
// /shells — this session's shells, each marked running or "termination
|
|
62775
|
+
// unconfirmed". `/shells release <id>` explains what releasing means and
|
|
62776
|
+
// asks for `--confirm`; only then is the workspace hold dropped.
|
|
62777
|
+
shells(ctx, arg) {
|
|
62778
|
+
const { store } = ctx;
|
|
62779
|
+
const [action, taskId, flag] = String(arg || "").trim().split(/\s+/).filter(Boolean);
|
|
62780
|
+
if (!action) {
|
|
62781
|
+
void Promise.resolve(store.listShellJobs?.()).then((result) => {
|
|
62782
|
+
const jobs = Array.isArray(result?.jobs) ? result.jobs : [];
|
|
62783
|
+
if (!jobs.length) {
|
|
62784
|
+
store.pushNotice("No shells are running.", "info");
|
|
62785
|
+
return;
|
|
62786
|
+
}
|
|
62787
|
+
const lines = jobs.map(
|
|
62788
|
+
(job) => `${job.taskId} ${job.terminationUnconfirmed ? "termination unconfirmed" : "running"} ${job.command}`
|
|
62789
|
+
);
|
|
62790
|
+
const held = jobs.some((job) => job.terminationUnconfirmed);
|
|
62791
|
+
if (held) lines.push("Release a held shell with /shells release <task_id>.");
|
|
62792
|
+
store.pushNotice(lines.join("\n"), held ? "warn" : "info");
|
|
62793
|
+
}).catch((error) => store.pushNotice(`Couldn\u2019t list shells: ${error?.message || error}`, "error"));
|
|
62794
|
+
return true;
|
|
62795
|
+
}
|
|
62796
|
+
if (action !== "release" || !taskId) {
|
|
62797
|
+
store.pushNotice("usage: /shells [release <task_id> [--confirm]]", "warn");
|
|
62798
|
+
return true;
|
|
62799
|
+
}
|
|
62800
|
+
if (flag !== "--confirm") {
|
|
62801
|
+
store.pushNotice(
|
|
62802
|
+
`Releasing ${taskId} unlocks its folder although its processes may still be running. To proceed, run /shells release ${taskId} --confirm`,
|
|
62803
|
+
"warn"
|
|
62804
|
+
);
|
|
62805
|
+
return true;
|
|
62806
|
+
}
|
|
62807
|
+
void Promise.resolve(store.releaseShellJob?.(taskId)).then(
|
|
62808
|
+
(result) => result?.released ? store.pushNotice(`Released ${taskId}.`, "info") : store.pushNotice(`Couldn\u2019t release ${taskId}: ${result?.error || "unavailable"}`, "warn")
|
|
62809
|
+
).catch((error) => store.pushNotice(`Couldn\u2019t release ${taskId}: ${error?.message || error}`, "error"));
|
|
62810
|
+
return true;
|
|
62811
|
+
},
|
|
62553
62812
|
doctor(ctx) {
|
|
62554
62813
|
const { state, store, deps } = ctx;
|
|
62555
62814
|
if (state.commandBusy) {
|
|
@@ -63023,8 +63282,8 @@ function usePromptQueueHistory({
|
|
|
63023
63282
|
let timer2 = null;
|
|
63024
63283
|
Promise.race([
|
|
63025
63284
|
Promise.resolve(store.dispose?.("cli-react-exit", { detach: true })),
|
|
63026
|
-
new Promise((
|
|
63027
|
-
timer2 = setTimeout(
|
|
63285
|
+
new Promise((resolve6) => {
|
|
63286
|
+
timer2 = setTimeout(resolve6, 350);
|
|
63028
63287
|
})
|
|
63029
63288
|
]).finally(() => {
|
|
63030
63289
|
if (timer2) clearTimeout(timer2);
|
|
@@ -63229,15 +63488,15 @@ function useTerminalChrome({ stdout: stdout2, isRawModeSupported, setResizeState
|
|
|
63229
63488
|
import { useCallback as useCallback21, useEffect as useEffect27, useLayoutEffect as useLayoutEffect8 } from "react";
|
|
63230
63489
|
|
|
63231
63490
|
// src/tui/session/transcript-spill.mjs
|
|
63232
|
-
import { readFileSync as
|
|
63233
|
-
import { join as
|
|
63491
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
63492
|
+
import { join as join16 } from "node:path";
|
|
63234
63493
|
import { Worker } from "node:worker_threads";
|
|
63235
63494
|
|
|
63236
63495
|
// src/tui/session/transcript-spill/spill-dir.mjs
|
|
63237
63496
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
63238
|
-
import { mkdtempSync, readdirSync as readdirSync5, readFileSync as
|
|
63497
|
+
import { mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync15, rmSync as rmSync5, statSync as statSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
63239
63498
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
63240
|
-
import { join as
|
|
63499
|
+
import { join as join15 } from "node:path";
|
|
63241
63500
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
63242
63501
|
var PROCESS_NONCE = randomUUID2();
|
|
63243
63502
|
|
|
@@ -65611,8 +65870,8 @@ function waitWithTimeout(promise, ms) {
|
|
|
65611
65870
|
let timer2 = null;
|
|
65612
65871
|
return Promise.race([
|
|
65613
65872
|
Promise.resolve(promise).then(() => true),
|
|
65614
|
-
new Promise((
|
|
65615
|
-
timer2 = setTimeout(() =>
|
|
65873
|
+
new Promise((resolve6) => {
|
|
65874
|
+
timer2 = setTimeout(() => resolve6(false), ms);
|
|
65616
65875
|
})
|
|
65617
65876
|
]).finally(() => {
|
|
65618
65877
|
if (timer2) clearTimeout(timer2);
|
|
@@ -65631,7 +65890,7 @@ function scheduleHardExit(code = 0) {
|
|
|
65631
65890
|
timer2.unref?.();
|
|
65632
65891
|
}
|
|
65633
65892
|
function resolveTuiStderrLogPath() {
|
|
65634
|
-
return process.env.MIXDOG_TUI_STDERR_LOG ||
|
|
65893
|
+
return process.env.MIXDOG_TUI_STDERR_LOG || join17(process.env.MIXDOG_RUNTIME_ROOT || join17(tmpdir3(), "mixdog"), "mixdog-tui.stderr.log");
|
|
65635
65894
|
}
|
|
65636
65895
|
function ansiFg(rgb2) {
|
|
65637
65896
|
const m = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/.exec(String(rgb2 || ""));
|
|
@@ -65712,7 +65971,7 @@ function installTuiStderrGuard() {
|
|
|
65712
65971
|
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
65713
65972
|
const logPath = resolveTuiStderrLogPath();
|
|
65714
65973
|
try {
|
|
65715
|
-
mkdirSync8(
|
|
65974
|
+
mkdirSync8(dirname12(logPath), { recursive: true });
|
|
65716
65975
|
} catch {
|
|
65717
65976
|
}
|
|
65718
65977
|
(0, import_mixdog_debug.rotateBoundedLog)(logPath, import_mixdog_debug.PLUGIN_LOG_MAX_BYTES, import_mixdog_debug.PLUGIN_LOG_KEEP_BYTES);
|