mixdog 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/package.json +8 -8
- package/scripts/native-release-status.mjs +238 -0
- package/scripts/verify-runtime-dependency-versions.mjs +158 -0
- package/src/agents/reviewer/AGENT.md +5 -7
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +9 -1
- package/src/defaults/skills/browser-use/SKILL.md +6 -3
- package/src/defaults/skills/local-provider/SKILL.md +33 -6
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +50 -3
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +7 -3
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/rules/agent-mode/AGENT_MODE.md +8 -5
- package/src/rules/agent-mode/MIXY.md +6 -8
- package/src/rules/lead/LEAD.md +7 -10
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/rules/shared/45-destructive.md +5 -1
- package/src/rules/shared/60-verification.md +6 -4
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
- package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/legacy-office.mjs +110 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/prompt-restore.mjs +70 -0
- package/src/runtime/attachments/store.mjs +109 -33
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +66 -16
- package/src/runtime/effort-judge/model-install.mjs +47 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +135 -29
- package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
- package/src/runtime/shared/agent-avatar.mjs +3 -2
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-room-host.d.mts +31 -0
- package/src/runtime/shared/agent-room-host.mjs +58 -0
- package/src/runtime/shared/agent-store.mjs +24 -7
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +35 -0
- package/src/runtime/shared/bot-split-migration.mjs +1 -1
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +4 -0
- package/src/runtime/shared/error-presentation.mjs +22 -4
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/redact-directories.mjs +18 -0
- package/src/runtime/shared/remove-directory.mjs +28 -0
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
- package/src/runtime/shared/session-sidebar-host.mjs +16 -3
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +10 -0
- package/src/runtime/shared/tool-work-units.mjs +12 -9
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +277 -124
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +92 -61
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
- package/src/runtime/shared/worktrees/contract.mjs +11 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
- package/src/runtime/shared/worktrees/manager.mjs +419 -52
- package/src/runtime/shared/worktrees/registry.mjs +29 -27
- package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/tidy/process.mjs +41 -8
- package/src/runtime/tidy/resolve.mjs +10 -7
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +542 -204
- package/src/session-runtime/agent-profile-changes.mjs +16 -0
- package/src/session-runtime/agent-room-delivery.mjs +81 -35
- package/src/session-runtime/agent-task-sessions.mjs +811 -179
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +48 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +16 -7
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +2 -2
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +23 -3
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +60 -55
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/held-requests.mjs +31 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-recency.mjs +1 -0
- package/src/session-runtime/model-route/route-tuning.mjs +4 -1
- package/src/session-runtime/model-route/set-route.mjs +61 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
- package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
- package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
- package/src/session-runtime/route-resolution.mjs +16 -8
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-review-api.mjs +4 -1
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +26 -6
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/services/worktree-access.mjs +27 -0
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/session-hooks.mjs +9 -17
- package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +12 -2
- package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +48 -369
- package/src/session-runtime/tool-surface.mjs +10 -4
- package/src/session-runtime/turn/session-ops.mjs +8 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +7 -2
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/transition-steps.mjs +1 -18
- package/src/session-runtime/workspace/transitions.mjs +279 -67
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-lag-profiler.mjs +3 -1
- package/src/standalone/daemon-session-control.mjs +173 -15
- package/src/standalone/daemon-telemetry.mjs +9 -0
- package/src/standalone/daemon.mjs +33 -10
- package/src/standalone/local-session-runtime.mjs +33 -16
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +8 -0
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
- package/src/standalone/session-service/agent-route-follow.mjs +69 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
- package/src/standalone/session-service.mjs +21 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +36 -9
- package/src/standalone/staged-import.mjs +47 -0
- package/src/tui/App.jsx +2 -0
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/message-selector.mjs +15 -2
- package/src/tui/app/model-options.mjs +16 -2
- package/src/tui/app/model-picker.mjs +2 -1
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +617 -369
- package/src/tui/paste-attachments.mjs +0 -1
- package/src/tui/paste-text-policy.mjs +4 -5
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -0
- package/src/tui/session/session-api/intake/abort.mjs +52 -18
- package/src/tui/session/session-api/intake/rewind.mjs +39 -4
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -247
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +142 -14
- package/src/tui/session/transcript-intake.mjs +2 -0
- package/src/tui/session/turn.mjs +23 -14
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
- package/src/session-runtime/room-member-gate.mjs +0 -48
package/src/tui/dist/index.mjs
CHANGED
|
@@ -23113,10 +23113,10 @@ var require_stack_utils = __commonJS({
|
|
|
23113
23113
|
});
|
|
23114
23114
|
|
|
23115
23115
|
// src/runtime/shared/file-permissions.mjs
|
|
23116
|
-
import { existsSync as
|
|
23117
|
-
import { dirname
|
|
23116
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
23117
|
+
import { dirname, join, resolve as resolve2 } from "node:path";
|
|
23118
23118
|
import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn3 } from "node:child_process";
|
|
23119
|
-
import { fileURLToPath
|
|
23119
|
+
import { fileURLToPath } from "node:url";
|
|
23120
23120
|
import { MessageChannel as MessageChannel2, receiveMessageOnPort, SHARE_ENV, Worker } from "node:worker_threads";
|
|
23121
23121
|
function execFileAsync(file, args, options) {
|
|
23122
23122
|
return new Promise((done, fail) => {
|
|
@@ -23169,7 +23169,7 @@ function startAclHelper(icacls, sid) {
|
|
|
23169
23169
|
let child;
|
|
23170
23170
|
try {
|
|
23171
23171
|
child = spawn3(command.executable, command.args, {
|
|
23172
|
-
cwd:
|
|
23172
|
+
cwd: dirname(icacls),
|
|
23173
23173
|
stdio: ["pipe", "pipe", "ignore"],
|
|
23174
23174
|
windowsHide: true
|
|
23175
23175
|
});
|
|
@@ -23250,7 +23250,7 @@ function syncBridge() {
|
|
|
23250
23250
|
if (aclSyncBridge || aclSyncBridgeBroken) return aclSyncBridge;
|
|
23251
23251
|
try {
|
|
23252
23252
|
const url = new URL("./file-permissions-worker.mjs", import.meta.url);
|
|
23253
|
-
if (!
|
|
23253
|
+
if (!existsSync3(fileURLToPath(url))) throw new Error("Windows ACL bridge worker is not shipped here");
|
|
23254
23254
|
const { port1, port2 } = new MessageChannel2();
|
|
23255
23255
|
const signal = new Int32Array(new SharedArrayBuffer(12));
|
|
23256
23256
|
const worker = new Worker(url, {
|
|
@@ -23304,7 +23304,7 @@ function askSyncBridge(targetPath) {
|
|
|
23304
23304
|
}
|
|
23305
23305
|
function systemToolPath(name) {
|
|
23306
23306
|
const systemRoot = process.env.SystemRoot || process.env.windir;
|
|
23307
|
-
return systemRoot ?
|
|
23307
|
+
return systemRoot ? join(systemRoot, "System32", name) : null;
|
|
23308
23308
|
}
|
|
23309
23309
|
function currentUserSid(output) {
|
|
23310
23310
|
return String(output).trim().match(/^"(?:[^"]|"")*","(S-\d+(?:-\d+)+)"$/)?.[1] || null;
|
|
@@ -23316,7 +23316,7 @@ function unresolvedUserError() {
|
|
|
23316
23316
|
}
|
|
23317
23317
|
function resolveCurrentUserPrincipal() {
|
|
23318
23318
|
const whoami = systemToolPath("whoami.exe");
|
|
23319
|
-
if (whoami &&
|
|
23319
|
+
if (whoami && existsSync3(whoami)) {
|
|
23320
23320
|
try {
|
|
23321
23321
|
const output = execFileSync2(whoami, ["/user", "/fo", "csv", "/nh"], {
|
|
23322
23322
|
encoding: "utf8",
|
|
@@ -23332,7 +23332,7 @@ function resolveCurrentUserPrincipal() {
|
|
|
23332
23332
|
}
|
|
23333
23333
|
async function resolveCurrentUserPrincipalAsync() {
|
|
23334
23334
|
const whoami = systemToolPath("whoami.exe");
|
|
23335
|
-
if (whoami &&
|
|
23335
|
+
if (whoami && existsSync3(whoami)) {
|
|
23336
23336
|
try {
|
|
23337
23337
|
const { stdout: stdout2 } = await execFileAsync(whoami, ["/user", "/fo", "csv", "/nh"], {
|
|
23338
23338
|
encoding: "utf8",
|
|
@@ -23352,7 +23352,7 @@ function icaclsPath() {
|
|
|
23352
23352
|
error.code = "EACLNOROOT";
|
|
23353
23353
|
throw error;
|
|
23354
23354
|
}
|
|
23355
|
-
if (!
|
|
23355
|
+
if (!existsSync3(path2)) {
|
|
23356
23356
|
const error = new Error(`icacls.exe not found at ${path2}; refusing to leave secret world-readable`);
|
|
23357
23357
|
error.code = "EACLNOICACLS";
|
|
23358
23358
|
throw error;
|
|
@@ -23361,7 +23361,7 @@ function icaclsPath() {
|
|
|
23361
23361
|
}
|
|
23362
23362
|
function powerShellCommand(icacls, script) {
|
|
23363
23363
|
return {
|
|
23364
|
-
executable:
|
|
23364
|
+
executable: join(dirname(icacls), "WindowsPowerShell", "v1.0", "powershell.exe"),
|
|
23365
23365
|
label: "Windows ACL update",
|
|
23366
23366
|
args: ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")]
|
|
23367
23367
|
};
|
|
@@ -23402,7 +23402,7 @@ function enforceOwnerOnlyAclWin32(targetPath, { fresh = false } = {}) {
|
|
|
23402
23402
|
if (process.platform !== "win32") return;
|
|
23403
23403
|
const icacls = icaclsPath();
|
|
23404
23404
|
if (fresh) {
|
|
23405
|
-
const reply = askSyncBridge(
|
|
23405
|
+
const reply = askSyncBridge(resolve2(targetPath));
|
|
23406
23406
|
if (reply.ok === true) return;
|
|
23407
23407
|
if (reply.ok === false) throw Object.assign(new Error(reply.message), { code: reply.code || "EACLFAIL" });
|
|
23408
23408
|
if (reply.timedOut) {
|
|
@@ -23425,7 +23425,7 @@ async function enforceOwnerOnlyAclWin32Async(targetPath, { fresh = false } = {})
|
|
|
23425
23425
|
if (process.platform !== "win32") return;
|
|
23426
23426
|
const icacls = icaclsPath();
|
|
23427
23427
|
if (cachedUserSid === null) cachedUserSid = await resolveCurrentUserPrincipalAsync();
|
|
23428
|
-
const reply = await askAclHelper(
|
|
23428
|
+
const reply = await askAclHelper(resolve2(targetPath), icacls, cachedUserSid);
|
|
23429
23429
|
if (reply.status === "ok" || reply.status === "fixed") return;
|
|
23430
23430
|
if (reply.status === "err") {
|
|
23431
23431
|
throw aclFailure(targetPath, new Error(reply.detail || "unknown error"), "Windows ACL helper");
|
|
@@ -23500,13 +23500,13 @@ var init_sleep = __esm({
|
|
|
23500
23500
|
// src/runtime/shared/file-lock.mjs
|
|
23501
23501
|
import {
|
|
23502
23502
|
linkSync,
|
|
23503
|
-
mkdirSync
|
|
23503
|
+
mkdirSync,
|
|
23504
23504
|
readdirSync,
|
|
23505
|
-
readFileSync as
|
|
23506
|
-
renameSync
|
|
23505
|
+
readFileSync as readFileSync2,
|
|
23506
|
+
renameSync,
|
|
23507
23507
|
statSync,
|
|
23508
23508
|
unlinkSync as unlinkSync2,
|
|
23509
|
-
writeFileSync
|
|
23509
|
+
writeFileSync
|
|
23510
23510
|
} from "node:fs";
|
|
23511
23511
|
import {
|
|
23512
23512
|
link as linkAsync,
|
|
@@ -23516,7 +23516,7 @@ import {
|
|
|
23516
23516
|
unlink as unlinkAsync,
|
|
23517
23517
|
writeFile as writeFileAsync
|
|
23518
23518
|
} from "node:fs/promises";
|
|
23519
|
-
import { basename as basename2, dirname as
|
|
23519
|
+
import { basename as basename2, dirname as dirname2, join as join2 } from "node:path";
|
|
23520
23520
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
23521
23521
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
23522
23522
|
function markOsHeld(lockPath) {
|
|
@@ -23780,7 +23780,7 @@ function lockStaleMs(opts) {
|
|
|
23780
23780
|
function sweepStagedLockFiles(lockPath, now = Date.now()) {
|
|
23781
23781
|
if (sweptLockPaths.has(lockPath)) return 0;
|
|
23782
23782
|
sweptLockPaths.add(lockPath);
|
|
23783
|
-
const dir =
|
|
23783
|
+
const dir = dirname2(lockPath);
|
|
23784
23784
|
const prefix = `${basename2(lockPath)}.`;
|
|
23785
23785
|
let removed = 0;
|
|
23786
23786
|
let names;
|
|
@@ -23793,7 +23793,7 @@ function sweepStagedLockFiles(lockPath, now = Date.now()) {
|
|
|
23793
23793
|
if (!name.startsWith(prefix)) continue;
|
|
23794
23794
|
const match = /^(?:reclaim\.)?(\d+)\.[0-9a-f]{16}\.tmp$/.exec(name.slice(prefix.length));
|
|
23795
23795
|
if (!match) continue;
|
|
23796
|
-
const path2 =
|
|
23796
|
+
const path2 = join2(dir, name);
|
|
23797
23797
|
try {
|
|
23798
23798
|
if (now - statSync(path2).mtimeMs < STAGED_LOCK_FILE_STALE_MS) continue;
|
|
23799
23799
|
if (ownerIsLive({ pid: Number(match[1]), token: null })) continue;
|
|
@@ -23808,7 +23808,7 @@ function* acquireLock(lockPath, opts, mode, markHeld, timing = null) {
|
|
|
23808
23808
|
const timeoutMs = lockTimeoutMs(opts);
|
|
23809
23809
|
const staleMs = lockStaleMs(opts);
|
|
23810
23810
|
const deadline = Date.now() + timeoutMs;
|
|
23811
|
-
yield ["mkdirp",
|
|
23811
|
+
yield ["mkdirp", dirname2(lockPath)];
|
|
23812
23812
|
sweepStagedLockFiles(lockPath);
|
|
23813
23813
|
const waitStartedAt = Date.now();
|
|
23814
23814
|
let attempt = 0;
|
|
@@ -23907,10 +23907,10 @@ var init_file_lock = __esm({
|
|
|
23907
23907
|
SYNC_IO = {
|
|
23908
23908
|
stat: (path2) => statSync(path2),
|
|
23909
23909
|
statId: (path2) => statSync(path2, { bigint: true }),
|
|
23910
|
-
rename: (from, to) =>
|
|
23911
|
-
read: (path2) =>
|
|
23912
|
-
mkdirp: (path2) =>
|
|
23913
|
-
createExclusive: (path2, data) =>
|
|
23910
|
+
rename: (from, to) => renameSync(from, to),
|
|
23911
|
+
read: (path2) => readFileSync2(path2, "utf8"),
|
|
23912
|
+
mkdirp: (path2) => mkdirSync(path2, { recursive: true }),
|
|
23913
|
+
createExclusive: (path2, data) => writeFileSync(path2, data, { encoding: "utf8", mode: 384, flag: "wx" }),
|
|
23914
23914
|
link: (from, to) => linkSync(from, to),
|
|
23915
23915
|
unlink: (path2) => unlinkSync2(path2),
|
|
23916
23916
|
sleep: (ms) => sleepSync(ms)
|
|
@@ -23932,15 +23932,16 @@ var init_file_lock = __esm({
|
|
|
23932
23932
|
// src/runtime/shared/atomic-file.mjs
|
|
23933
23933
|
import {
|
|
23934
23934
|
closeSync,
|
|
23935
|
-
existsSync as
|
|
23935
|
+
existsSync as existsSync4,
|
|
23936
23936
|
fsyncSync,
|
|
23937
23937
|
linkSync as linkSync2,
|
|
23938
|
-
mkdirSync as
|
|
23938
|
+
mkdirSync as mkdirSync2,
|
|
23939
23939
|
openSync,
|
|
23940
|
-
readFileSync as
|
|
23941
|
-
renameSync as
|
|
23940
|
+
readFileSync as readFileSync3,
|
|
23941
|
+
renameSync as renameSync2,
|
|
23942
|
+
statSync as statSync2,
|
|
23942
23943
|
unlinkSync as unlinkSync3,
|
|
23943
|
-
writeFileSync as
|
|
23944
|
+
writeFileSync as writeFileSync2
|
|
23944
23945
|
} from "node:fs";
|
|
23945
23946
|
import {
|
|
23946
23947
|
link as linkAsync2,
|
|
@@ -23948,11 +23949,10 @@ import {
|
|
|
23948
23949
|
open as openAsync,
|
|
23949
23950
|
readFile as readFileAsync3,
|
|
23950
23951
|
rename as renameAsync,
|
|
23951
|
-
unlink as unlinkAsync2
|
|
23952
|
-
writeFile as writeFileAsync2
|
|
23952
|
+
unlink as unlinkAsync2
|
|
23953
23953
|
} from "node:fs/promises";
|
|
23954
23954
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
23955
|
-
import { dirname as
|
|
23955
|
+
import { dirname as dirname3, basename as basename3, join as join3, relative, isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
|
|
23956
23956
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
23957
23957
|
function _drainAdaptiveFileIo() {
|
|
23958
23958
|
while (_ioActive < _ioLimit && _ioQueue.length > 0) {
|
|
@@ -23987,16 +23987,25 @@ function _runAdaptiveFileIo(run) {
|
|
|
23987
23987
|
function renameBackoffs(opts) {
|
|
23988
23988
|
return Array.isArray(opts.backoffs) && opts.backoffs.length > 0 ? opts.backoffs : DEFAULT_BACKOFFS_MS;
|
|
23989
23989
|
}
|
|
23990
|
-
function
|
|
23990
|
+
function isReadOnlyFile(path2) {
|
|
23991
|
+
try {
|
|
23992
|
+
const stat2 = statSync2(path2);
|
|
23993
|
+
return stat2.isFile() && (stat2.mode & 128) === 0;
|
|
23994
|
+
} catch {
|
|
23995
|
+
return false;
|
|
23996
|
+
}
|
|
23997
|
+
}
|
|
23998
|
+
function nextRenameDelayMs(err, attempt, backoffs, dst) {
|
|
23991
23999
|
if (!RETRY_CODES.has(err?.code) || attempt >= backoffs.length) return null;
|
|
24000
|
+
if ((err.code === "EPERM" || err.code === "EACCES") && isReadOnlyFile(dst)) return null;
|
|
23992
24001
|
return backoffs[attempt] + Math.floor(Math.random() * Math.min(50, Math.max(1, backoffs[attempt])));
|
|
23993
24002
|
}
|
|
23994
24003
|
function renameAttempt(src, dst, attempt, opts = {}) {
|
|
23995
24004
|
try {
|
|
23996
|
-
|
|
24005
|
+
renameSync2(src, dst);
|
|
23997
24006
|
return null;
|
|
23998
24007
|
} catch (err) {
|
|
23999
|
-
const delayMs = nextRenameDelayMs(err, attempt, renameBackoffs(opts));
|
|
24008
|
+
const delayMs = nextRenameDelayMs(err, attempt, renameBackoffs(opts), dst);
|
|
24000
24009
|
if (delayMs === null) throw err;
|
|
24001
24010
|
return delayMs;
|
|
24002
24011
|
}
|
|
@@ -24017,13 +24026,16 @@ async function renameWithRetry(src, dst, opts = {}) {
|
|
|
24017
24026
|
return true;
|
|
24018
24027
|
} catch (err) {
|
|
24019
24028
|
lastErr = err;
|
|
24020
|
-
const delayMs = nextRenameDelayMs(err, attempt, backoffs);
|
|
24029
|
+
const delayMs = nextRenameDelayMs(err, attempt, backoffs, dst);
|
|
24021
24030
|
if (delayMs === null) break;
|
|
24022
24031
|
await sleep(Math.max(1, Number(delayMs) || 1));
|
|
24023
24032
|
}
|
|
24024
24033
|
}
|
|
24025
24034
|
throw lastErr;
|
|
24026
24035
|
}
|
|
24036
|
+
function isFileFsyncUnsupported(err) {
|
|
24037
|
+
return FILE_FSYNC_TOLERATED.includes(err?.code);
|
|
24038
|
+
}
|
|
24027
24039
|
function fsyncPathSync(path2, tolerated) {
|
|
24028
24040
|
let fd = null;
|
|
24029
24041
|
try {
|
|
@@ -24052,120 +24064,188 @@ async function fsyncPathAsync(path2, tolerated) {
|
|
|
24052
24064
|
}
|
|
24053
24065
|
}
|
|
24054
24066
|
}
|
|
24067
|
+
function writeFileDurableSync(path2, data, opts) {
|
|
24068
|
+
const fd = openSync(path2, opts.flag || "wx", opts.mode !== void 0 ? opts.mode : 384);
|
|
24069
|
+
try {
|
|
24070
|
+
writeFileSync2(fd, data, { encoding: opts.encoding || "utf8" });
|
|
24071
|
+
if (opts.fsync !== false) {
|
|
24072
|
+
try {
|
|
24073
|
+
fsyncSync(fd);
|
|
24074
|
+
} catch (err) {
|
|
24075
|
+
if (!isFileFsyncUnsupported(err)) throw err;
|
|
24076
|
+
}
|
|
24077
|
+
}
|
|
24078
|
+
} finally {
|
|
24079
|
+
closeSync(fd);
|
|
24080
|
+
}
|
|
24081
|
+
}
|
|
24082
|
+
async function writeFileDurableAsync(path2, data, opts) {
|
|
24083
|
+
const handle = await openAsync(path2, opts.flag || "wx", opts.mode !== void 0 ? opts.mode : 384);
|
|
24084
|
+
try {
|
|
24085
|
+
await handle.writeFile(data, { encoding: opts.encoding || "utf8" });
|
|
24086
|
+
if (opts.fsync !== false) {
|
|
24087
|
+
try {
|
|
24088
|
+
await handle.sync();
|
|
24089
|
+
} catch (err) {
|
|
24090
|
+
if (!isFileFsyncUnsupported(err)) throw err;
|
|
24091
|
+
}
|
|
24092
|
+
}
|
|
24093
|
+
} finally {
|
|
24094
|
+
await handle.close();
|
|
24095
|
+
}
|
|
24096
|
+
}
|
|
24097
|
+
function holdsNoData(content) {
|
|
24098
|
+
if (typeof content === "string") return /^[\0\s]*$/.test(content);
|
|
24099
|
+
for (const byte of content) {
|
|
24100
|
+
if (byte !== 0 && byte !== 32 && byte !== 9 && byte !== 10 && byte !== 13) return false;
|
|
24101
|
+
}
|
|
24102
|
+
return true;
|
|
24103
|
+
}
|
|
24104
|
+
function keepBackupSync(filePath, opts) {
|
|
24105
|
+
let previous;
|
|
24106
|
+
try {
|
|
24107
|
+
previous = readFileSync3(filePath);
|
|
24108
|
+
} catch (err) {
|
|
24109
|
+
if (err?.code === "ENOENT") return;
|
|
24110
|
+
throw err;
|
|
24111
|
+
}
|
|
24112
|
+
if (keepsAsBackup(opts, previous)) publishFileSync(`${filePath}.bak`, previous, backupWriteOpts(opts));
|
|
24113
|
+
}
|
|
24114
|
+
async function keepBackupAsync(filePath, opts) {
|
|
24115
|
+
let previous;
|
|
24116
|
+
try {
|
|
24117
|
+
previous = await readFileAsync3(filePath);
|
|
24118
|
+
} catch (err) {
|
|
24119
|
+
if (err?.code === "ENOENT") return;
|
|
24120
|
+
throw err;
|
|
24121
|
+
}
|
|
24122
|
+
if (keepsAsBackup(opts, previous)) await publishFileAsync(`${filePath}.bak`, previous, backupWriteOpts(opts));
|
|
24123
|
+
}
|
|
24055
24124
|
function assertTestSecretWriteSafe(filePath, opts) {
|
|
24056
24125
|
if (opts.secret !== true || !process.env.NODE_TEST_CONTEXT) return;
|
|
24057
|
-
const rel = relative(
|
|
24126
|
+
const rel = relative(resolve3(tmpdir2()).toLowerCase(), resolve3(filePath).toLowerCase());
|
|
24058
24127
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute2(rel)) return;
|
|
24059
24128
|
throw new Error(`refusing to write a secret outside the temp dir under node --test: ${filePath}`);
|
|
24060
24129
|
}
|
|
24061
24130
|
function writeFileAtomicSync(filePath, data, opts = {}) {
|
|
24062
24131
|
assertTestSecretWriteSafe(filePath, opts);
|
|
24063
|
-
const run = () =>
|
|
24064
|
-
|
|
24065
|
-
|
|
24066
|
-
|
|
24067
|
-
|
|
24068
|
-
|
|
24069
|
-
|
|
24070
|
-
|
|
24071
|
-
|
|
24072
|
-
|
|
24073
|
-
|
|
24074
|
-
|
|
24075
|
-
|
|
24076
|
-
|
|
24077
|
-
|
|
24078
|
-
|
|
24079
|
-
|
|
24080
|
-
|
|
24081
|
-
|
|
24082
|
-
|
|
24083
|
-
|
|
24084
|
-
if (err?.code === "EEXIST") return false;
|
|
24085
|
-
throw err;
|
|
24086
|
-
}
|
|
24132
|
+
const run = () => publishFileSync(filePath, data, opts);
|
|
24133
|
+
if (opts.lock === true) {
|
|
24134
|
+
return withFileLockSync(`${filePath}.lock`, run, opts);
|
|
24135
|
+
}
|
|
24136
|
+
return run();
|
|
24137
|
+
}
|
|
24138
|
+
function publishTempPath(filePath) {
|
|
24139
|
+
return join3(dirname3(filePath), `${basename3(filePath)}.mixdog-tmp-${randomBytes3(8).toString("hex")}`);
|
|
24140
|
+
}
|
|
24141
|
+
function publishFileSync(filePath, data, opts) {
|
|
24142
|
+
const dir = dirname3(filePath);
|
|
24143
|
+
mkdirSync2(dir, { recursive: true });
|
|
24144
|
+
const tmp = publishTempPath(filePath);
|
|
24145
|
+
try {
|
|
24146
|
+
writeFileDurableSync(tmp, data, { ...opts, flag: "wx" });
|
|
24147
|
+
if (opts.secret === true) enforceOwnerOnlyAclWin32(tmp, { fresh: true });
|
|
24148
|
+
if (opts.backup === true && opts.createOnly !== true) keepBackupSync(filePath, opts);
|
|
24149
|
+
if (opts.createOnly === true) {
|
|
24150
|
+
try {
|
|
24151
|
+
linkSync2(tmp, filePath);
|
|
24152
|
+
} catch (err) {
|
|
24087
24153
|
try {
|
|
24088
24154
|
unlinkSync3(tmp);
|
|
24089
24155
|
} catch {
|
|
24090
24156
|
}
|
|
24091
|
-
|
|
24092
|
-
|
|
24093
|
-
renameWithRetrySync(tmp, filePath, opts);
|
|
24094
|
-
} catch (err) {
|
|
24095
|
-
if (opts.renameFallback === "truncate" && opts.secret !== true && process.platform === "win32" && RETRY_CODES.has(err?.code)) {
|
|
24096
|
-
const data2 = readFileSync4(tmp);
|
|
24097
|
-
writeFileSync3(filePath, data2, { mode: opts.mode !== void 0 ? opts.mode : 384 });
|
|
24098
|
-
try {
|
|
24099
|
-
unlinkSync3(tmp);
|
|
24100
|
-
} catch {
|
|
24101
|
-
}
|
|
24102
|
-
} else {
|
|
24103
|
-
throw err;
|
|
24104
|
-
}
|
|
24105
|
-
}
|
|
24157
|
+
if (err?.code === "EEXIST") return false;
|
|
24158
|
+
throw err;
|
|
24106
24159
|
}
|
|
24107
|
-
if (opts.fsyncDir === true) fsyncPathSync(dir, DIR_FSYNC_TOLERATED);
|
|
24108
|
-
return true;
|
|
24109
|
-
} catch (err) {
|
|
24110
24160
|
try {
|
|
24111
|
-
|
|
24161
|
+
unlinkSync3(tmp);
|
|
24112
24162
|
} catch {
|
|
24113
24163
|
}
|
|
24114
|
-
|
|
24164
|
+
} else {
|
|
24165
|
+
try {
|
|
24166
|
+
renameWithRetrySync(tmp, filePath, opts);
|
|
24167
|
+
} catch (err) {
|
|
24168
|
+
if (opts.renameFallback === "truncate" && opts.secret !== true && process.platform === "win32" && RETRY_CODES.has(err?.code)) {
|
|
24169
|
+
writeFileDurableSync(filePath, readFileSync3(tmp), { ...opts, flag: "w", encoding: void 0 });
|
|
24170
|
+
try {
|
|
24171
|
+
unlinkSync3(tmp);
|
|
24172
|
+
} catch {
|
|
24173
|
+
}
|
|
24174
|
+
} else {
|
|
24175
|
+
throw err;
|
|
24176
|
+
}
|
|
24177
|
+
}
|
|
24115
24178
|
}
|
|
24116
|
-
|
|
24117
|
-
|
|
24118
|
-
|
|
24179
|
+
if (opts.fsyncDir === true) fsyncPathSync(dir, DIR_FSYNC_TOLERATED);
|
|
24180
|
+
return true;
|
|
24181
|
+
} catch (err) {
|
|
24182
|
+
try {
|
|
24183
|
+
if (existsSync4(tmp)) unlinkSync3(tmp);
|
|
24184
|
+
} catch {
|
|
24185
|
+
}
|
|
24186
|
+
throw err;
|
|
24119
24187
|
}
|
|
24120
|
-
return run();
|
|
24121
24188
|
}
|
|
24122
24189
|
function writeJsonAtomicSync(filePath, value, opts = {}) {
|
|
24123
24190
|
return writeFileAtomicSync(filePath, `${JSON.stringify(value, null, opts.compact ? 0 : 2)}
|
|
24124
|
-
`, opts);
|
|
24191
|
+
`, jsonBackupOpts(opts));
|
|
24192
|
+
}
|
|
24193
|
+
function parseJsonText(text) {
|
|
24194
|
+
return JSON.parse(text.charCodeAt(0) === 65279 ? text.slice(1) : text);
|
|
24195
|
+
}
|
|
24196
|
+
function isJsonContent(content) {
|
|
24197
|
+
try {
|
|
24198
|
+
parseJsonText(String(content));
|
|
24199
|
+
return true;
|
|
24200
|
+
} catch {
|
|
24201
|
+
return false;
|
|
24202
|
+
}
|
|
24203
|
+
}
|
|
24204
|
+
function readContentOrNullSync(filePath) {
|
|
24205
|
+
try {
|
|
24206
|
+
return readFileSync3(filePath);
|
|
24207
|
+
} catch (err) {
|
|
24208
|
+
if (err?.code === "ENOENT") return null;
|
|
24209
|
+
throw err;
|
|
24210
|
+
}
|
|
24211
|
+
}
|
|
24212
|
+
function reportDamaged(filePath, error, outcome) {
|
|
24213
|
+
const reason = String(error?.message || error).replace(/[\0-\x1f]/g, (c) => `\\x${c.charCodeAt(0).toString(16)}`);
|
|
24214
|
+
process.stderr.write(`[state] ${filePath} is damaged (${reason}); ${outcome}
|
|
24215
|
+
`);
|
|
24216
|
+
}
|
|
24217
|
+
function recoverDamagedSync(filePath, parse, opts) {
|
|
24218
|
+
const current = parse(readContentOrNullSync(filePath));
|
|
24219
|
+
if (current.state !== "damaged") return current;
|
|
24220
|
+
const backup = opts.restoreBackup === false ? NO_BACKUP : parse(readContentOrNullSync(`${filePath}.bak`));
|
|
24221
|
+
if (backup.state !== "ok" && opts.keepWithoutBackup) {
|
|
24222
|
+
reportDamaged(filePath, current.error, KEPT_IN_PLACE);
|
|
24223
|
+
return { state: "absent" };
|
|
24224
|
+
}
|
|
24225
|
+
const aside = quarantinePath(filePath);
|
|
24226
|
+
renameWithRetrySync(filePath, aside, opts);
|
|
24227
|
+
if (backup.state === "ok") publishFileSync(filePath, backup.content, restoreOpts(opts));
|
|
24228
|
+
reportDamaged(filePath, current.error, recoveredOutcome(aside, backup));
|
|
24229
|
+
return backup.state === "ok" ? backup : { state: "absent" };
|
|
24230
|
+
}
|
|
24231
|
+
function readJsonStateSync(filePath, { validate: validate2, decode, fallback = null, ...opts } = {}) {
|
|
24232
|
+
const parse = stateParser(validate2, decode);
|
|
24233
|
+
const first = parse(readContentOrNullSync(filePath));
|
|
24234
|
+
if (first.state === "ok") return first.value;
|
|
24235
|
+
if (first.state !== "damaged") return fallback;
|
|
24236
|
+
let recovered;
|
|
24237
|
+
try {
|
|
24238
|
+
recovered = withFileLockSync(`${filePath}.lock`, () => recoverDamagedSync(filePath, parse, opts), opts);
|
|
24239
|
+
} catch (err) {
|
|
24240
|
+
if (!LOCK_BUSY_CODES.has(err?.code)) throw err;
|
|
24241
|
+
reportDamaged(filePath, first.error, "left in place while another writer holds its lock");
|
|
24242
|
+
return fallback;
|
|
24243
|
+
}
|
|
24244
|
+
return recovered.state === "ok" ? recovered.value : fallback;
|
|
24125
24245
|
}
|
|
24126
24246
|
async function writeFileAtomicAsync(filePath, data, opts = {}) {
|
|
24127
24247
|
assertTestSecretWriteSafe(filePath, opts);
|
|
24128
|
-
const run =
|
|
24129
|
-
const dir = dirname5(filePath);
|
|
24130
|
-
await mkdirAsync2(dir, { recursive: true });
|
|
24131
|
-
const tmp = join5(dir, `.${basename3(filePath)}.${randomBytes3(12).toString("hex")}.tmp`);
|
|
24132
|
-
try {
|
|
24133
|
-
const writeOpts = {
|
|
24134
|
-
encoding: opts.encoding || "utf8",
|
|
24135
|
-
flag: "wx",
|
|
24136
|
-
mode: opts.mode !== void 0 ? opts.mode : 384
|
|
24137
|
-
};
|
|
24138
|
-
await writeFileAsync2(tmp, data, writeOpts);
|
|
24139
|
-
if (opts.secret === true) await enforceOwnerOnlyAclWin32Async(tmp, { fresh: true });
|
|
24140
|
-
if (opts.fsync !== false) await fsyncPathAsync(tmp, FILE_FSYNC_TOLERATED);
|
|
24141
|
-
if (opts.createOnly === true) {
|
|
24142
|
-
try {
|
|
24143
|
-
await linkAsync2(tmp, filePath);
|
|
24144
|
-
} catch (err) {
|
|
24145
|
-
try {
|
|
24146
|
-
await unlinkAsync2(tmp);
|
|
24147
|
-
} catch {
|
|
24148
|
-
}
|
|
24149
|
-
if (err?.code === "EEXIST") return false;
|
|
24150
|
-
throw err;
|
|
24151
|
-
}
|
|
24152
|
-
try {
|
|
24153
|
-
await unlinkAsync2(tmp);
|
|
24154
|
-
} catch {
|
|
24155
|
-
}
|
|
24156
|
-
} else {
|
|
24157
|
-
await renameWithRetry(tmp, filePath, opts);
|
|
24158
|
-
}
|
|
24159
|
-
if (opts.fsyncDir === true) await fsyncPathAsync(dir, DIR_FSYNC_TOLERATED);
|
|
24160
|
-
return true;
|
|
24161
|
-
} catch (err) {
|
|
24162
|
-
try {
|
|
24163
|
-
await unlinkAsync2(tmp);
|
|
24164
|
-
} catch {
|
|
24165
|
-
}
|
|
24166
|
-
throw err;
|
|
24167
|
-
}
|
|
24168
|
-
};
|
|
24248
|
+
const run = () => publishFileAsync(filePath, data, opts);
|
|
24169
24249
|
if (opts.lock !== true) return _runAdaptiveFileIo(run);
|
|
24170
24250
|
const lockPath = `${filePath}.lock`;
|
|
24171
24251
|
return withFileLock(
|
|
@@ -24189,11 +24269,47 @@ async function writeFileAtomicAsync(filePath, data, opts = {}) {
|
|
|
24189
24269
|
opts
|
|
24190
24270
|
);
|
|
24191
24271
|
}
|
|
24272
|
+
async function publishFileAsync(filePath, data, opts) {
|
|
24273
|
+
const dir = dirname3(filePath);
|
|
24274
|
+
await mkdirAsync2(dir, { recursive: true });
|
|
24275
|
+
const tmp = publishTempPath(filePath);
|
|
24276
|
+
try {
|
|
24277
|
+
await writeFileDurableAsync(tmp, data, { ...opts, flag: "wx" });
|
|
24278
|
+
if (opts.secret === true) await enforceOwnerOnlyAclWin32Async(tmp, { fresh: true });
|
|
24279
|
+
if (opts.backup === true && opts.createOnly !== true) await keepBackupAsync(filePath, opts);
|
|
24280
|
+
if (opts.createOnly === true) {
|
|
24281
|
+
try {
|
|
24282
|
+
await linkAsync2(tmp, filePath);
|
|
24283
|
+
} catch (err) {
|
|
24284
|
+
try {
|
|
24285
|
+
await unlinkAsync2(tmp);
|
|
24286
|
+
} catch {
|
|
24287
|
+
}
|
|
24288
|
+
if (err?.code === "EEXIST") return false;
|
|
24289
|
+
throw err;
|
|
24290
|
+
}
|
|
24291
|
+
try {
|
|
24292
|
+
await unlinkAsync2(tmp);
|
|
24293
|
+
} catch {
|
|
24294
|
+
}
|
|
24295
|
+
} else {
|
|
24296
|
+
await renameWithRetry(tmp, filePath, opts);
|
|
24297
|
+
}
|
|
24298
|
+
if (opts.fsyncDir === true) await fsyncPathAsync(dir, DIR_FSYNC_TOLERATED);
|
|
24299
|
+
return true;
|
|
24300
|
+
} catch (err) {
|
|
24301
|
+
try {
|
|
24302
|
+
await unlinkAsync2(tmp);
|
|
24303
|
+
} catch {
|
|
24304
|
+
}
|
|
24305
|
+
throw err;
|
|
24306
|
+
}
|
|
24307
|
+
}
|
|
24192
24308
|
function writeJsonAtomicAsync(filePath, value, opts = {}) {
|
|
24193
24309
|
return writeFileAtomicAsync(filePath, `${JSON.stringify(value, null, opts.compact ? 0 : 2)}
|
|
24194
|
-
`, opts);
|
|
24310
|
+
`, jsonBackupOpts(opts));
|
|
24195
24311
|
}
|
|
24196
|
-
var _ioCeiling, _ioLimit, _ioActive, _ioFastStreak, _ioQueue, RETRY_CODES, FILE_FSYNC_TOLERATED, DIR_FSYNC_TOLERATED;
|
|
24312
|
+
var _ioCeiling, _ioLimit, _ioActive, _ioFastStreak, _ioQueue, RETRY_CODES, FILE_FSYNC_TOLERATED, DIR_FSYNC_TOLERATED, keepsAsBackup, backupWriteOpts, jsonBackupOpts, quarantinePath, LOCK_BUSY_CODES, STATE_UNSUPPORTED, acceptAny, utf8Text, stateParser, restoreOpts, KEPT_IN_PLACE, NO_BACKUP, recoveredOutcome, parseAnyJson;
|
|
24197
24313
|
var init_atomic_file = __esm({
|
|
24198
24314
|
"src/runtime/shared/atomic-file.mjs"() {
|
|
24199
24315
|
init_file_lock();
|
|
@@ -24207,16 +24323,68 @@ var init_atomic_file = __esm({
|
|
|
24207
24323
|
RETRY_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "EEXIST"]);
|
|
24208
24324
|
FILE_FSYNC_TOLERATED = ["EPERM", "ENOTSUP", "EINVAL"];
|
|
24209
24325
|
DIR_FSYNC_TOLERATED = ["EPERM", "ENOTSUP", "EINVAL", "EACCES"];
|
|
24326
|
+
keepsAsBackup = (opts, content) => opts.backupAccepts ? opts.backupAccepts(content) : !holdsNoData(content);
|
|
24327
|
+
backupWriteOpts = (opts) => ({ mode: opts.mode, secret: opts.secret, fsync: opts.fsync });
|
|
24328
|
+
jsonBackupOpts = (opts) => opts.backup === true && !opts.backupAccepts ? { ...opts, backupAccepts: isJsonContent } : opts;
|
|
24329
|
+
quarantinePath = (filePath) => {
|
|
24330
|
+
let stamp = Date.now();
|
|
24331
|
+
while (existsSync4(`${filePath}.corrupt-${stamp}`)) stamp += 1;
|
|
24332
|
+
return `${filePath}.corrupt-${stamp}`;
|
|
24333
|
+
};
|
|
24334
|
+
LOCK_BUSY_CODES = /* @__PURE__ */ new Set(["ELOCKCONTENDED", "ELOCKTIMEOUT"]);
|
|
24335
|
+
STATE_UNSUPPORTED = "ESTATEUNSUPPORTED";
|
|
24336
|
+
acceptAny = (value) => value;
|
|
24337
|
+
utf8Text = (content) => content.toString("utf8");
|
|
24338
|
+
stateParser = (validate2 = acceptAny, decode = utf8Text) => (content) => {
|
|
24339
|
+
if (content === null) return { state: "absent" };
|
|
24340
|
+
try {
|
|
24341
|
+
return { state: "ok", value: validate2(parseJsonText(decode(content))), content };
|
|
24342
|
+
} catch (error) {
|
|
24343
|
+
return { state: error?.code === STATE_UNSUPPORTED ? "unsupported" : "damaged", error };
|
|
24344
|
+
}
|
|
24345
|
+
};
|
|
24346
|
+
restoreOpts = (opts) => ({ mode: opts.mode, secret: opts.secret });
|
|
24347
|
+
KEPT_IN_PLACE = "left in place: no good copy to restore";
|
|
24348
|
+
NO_BACKUP = { state: "absent" };
|
|
24349
|
+
recoveredOutcome = (aside, backup) => `kept as ${aside}${backup.state === "ok" ? "; restored the last good copy" : "; starting empty"}`;
|
|
24350
|
+
parseAnyJson = stateParser();
|
|
24210
24351
|
}
|
|
24211
24352
|
});
|
|
24212
24353
|
|
|
24213
24354
|
// src/runtime/shared/json-file.mjs
|
|
24214
|
-
import { readFileSync as
|
|
24355
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
24215
24356
|
var init_json_file = __esm({
|
|
24216
24357
|
"src/runtime/shared/json-file.mjs"() {
|
|
24217
24358
|
}
|
|
24218
24359
|
});
|
|
24219
24360
|
|
|
24361
|
+
// src/runtime/shared/file-has-data.mjs
|
|
24362
|
+
import { closeSync as closeSync2, openSync as openSync2, readSync } from "node:fs";
|
|
24363
|
+
function fileHasData(path2) {
|
|
24364
|
+
let fd;
|
|
24365
|
+
try {
|
|
24366
|
+
fd = openSync2(path2, "r");
|
|
24367
|
+
const head = Buffer.alloc(PROBE_BYTES);
|
|
24368
|
+
return !holdsNoData(head.subarray(0, readSync(fd, head, 0, PROBE_BYTES, 0)));
|
|
24369
|
+
} catch (err) {
|
|
24370
|
+
return err?.code !== "ENOENT" && err?.code !== "ENOTDIR";
|
|
24371
|
+
} finally {
|
|
24372
|
+
if (fd !== void 0) {
|
|
24373
|
+
try {
|
|
24374
|
+
closeSync2(fd);
|
|
24375
|
+
} catch {
|
|
24376
|
+
}
|
|
24377
|
+
}
|
|
24378
|
+
}
|
|
24379
|
+
}
|
|
24380
|
+
var PROBE_BYTES;
|
|
24381
|
+
var init_file_has_data = __esm({
|
|
24382
|
+
"src/runtime/shared/file-has-data.mjs"() {
|
|
24383
|
+
init_atomic_file();
|
|
24384
|
+
PROBE_BYTES = 4096;
|
|
24385
|
+
}
|
|
24386
|
+
});
|
|
24387
|
+
|
|
24220
24388
|
// src/runtime/shared/bounded-download.mjs
|
|
24221
24389
|
import { createWriteStream, rmSync as rmSync2 } from "node:fs";
|
|
24222
24390
|
import { Transform as Transform2 } from "node:stream";
|
|
@@ -24241,7 +24409,7 @@ function responseByteLength(response, maximum, label) {
|
|
|
24241
24409
|
}
|
|
24242
24410
|
return advertised;
|
|
24243
24411
|
}
|
|
24244
|
-
async function streamResponseToFile(response, destPath, { maxBytes, expectedBytes = 0, label = "download", onProgress = null } = {}) {
|
|
24412
|
+
async function streamResponseToFile(response, destPath, { maxBytes, expectedBytes = 0, label = "download", onProgress = null, signal = void 0 } = {}) {
|
|
24245
24413
|
const { maximum, expected } = downloadBounds(maxBytes, expectedBytes, label);
|
|
24246
24414
|
const advertised = responseByteLength(response, maximum, label);
|
|
24247
24415
|
if (expected && advertised && advertised !== expected) {
|
|
@@ -24277,7 +24445,7 @@ async function streamResponseToFile(response, destPath, { maxBytes, expectedByte
|
|
|
24277
24445
|
}
|
|
24278
24446
|
});
|
|
24279
24447
|
try {
|
|
24280
|
-
await pipeline(response.body, guard, createWriteStream(destPath));
|
|
24448
|
+
await pipeline(response.body, guard, createWriteStream(destPath, { flush: true }), { signal });
|
|
24281
24449
|
return downloaded;
|
|
24282
24450
|
} catch (error) {
|
|
24283
24451
|
try {
|
|
@@ -24298,13 +24466,13 @@ var init_bounded_download = __esm({
|
|
|
24298
24466
|
// src/runtime/shared/native-asset.mjs
|
|
24299
24467
|
import { createHash as createHash5 } from "node:crypto";
|
|
24300
24468
|
import {
|
|
24301
|
-
chmodSync
|
|
24469
|
+
chmodSync,
|
|
24302
24470
|
createReadStream,
|
|
24303
|
-
existsSync as
|
|
24471
|
+
existsSync as existsSync11,
|
|
24304
24472
|
mkdirSync as mkdirSync6,
|
|
24305
|
-
readFileSync as
|
|
24306
|
-
readdirSync as
|
|
24307
|
-
renameSync as
|
|
24473
|
+
readFileSync as readFileSync12,
|
|
24474
|
+
readdirSync as readdirSync4,
|
|
24475
|
+
renameSync as renameSync3,
|
|
24308
24476
|
rmSync as rmSync3
|
|
24309
24477
|
} from "node:fs";
|
|
24310
24478
|
import { join as join13 } from "node:path";
|
|
@@ -24368,21 +24536,21 @@ __export(voice_runtime_fetcher_exports, {
|
|
|
24368
24536
|
});
|
|
24369
24537
|
import { createHash as createHash6 } from "node:crypto";
|
|
24370
24538
|
import {
|
|
24371
|
-
chmodSync as
|
|
24372
|
-
closeSync as
|
|
24539
|
+
chmodSync as chmodSync2,
|
|
24540
|
+
closeSync as closeSync3,
|
|
24373
24541
|
createReadStream as createReadStream2,
|
|
24374
24542
|
createWriteStream as createWriteStream2,
|
|
24375
|
-
existsSync as
|
|
24543
|
+
existsSync as existsSync12,
|
|
24376
24544
|
mkdirSync as mkdirSync7,
|
|
24377
|
-
openSync as
|
|
24378
|
-
readFileSync as
|
|
24379
|
-
readdirSync as
|
|
24545
|
+
openSync as openSync3,
|
|
24546
|
+
readFileSync as readFileSync13,
|
|
24547
|
+
readdirSync as readdirSync5,
|
|
24380
24548
|
rmSync as rmSync4,
|
|
24381
|
-
statSync as
|
|
24382
|
-
writeFileSync as
|
|
24549
|
+
statSync as statSync6,
|
|
24550
|
+
writeFileSync as writeFileSync3
|
|
24383
24551
|
} from "node:fs";
|
|
24384
24552
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
24385
|
-
import { join as join14, dirname as
|
|
24553
|
+
import { join as join14, dirname as dirname10 } from "node:path";
|
|
24386
24554
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
24387
24555
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
24388
24556
|
import { spawnSync } from "node:child_process";
|
|
@@ -24400,7 +24568,7 @@ function lockAgeMs(holderTs, waitSince) {
|
|
|
24400
24568
|
}
|
|
24401
24569
|
function _readInstallLockToken(lockPath) {
|
|
24402
24570
|
try {
|
|
24403
|
-
const raw =
|
|
24571
|
+
const raw = readFileSync13(lockPath, "utf8").trim();
|
|
24404
24572
|
if (!raw) return null;
|
|
24405
24573
|
const [pidLine, tsLine = ""] = raw.split(/\r?\n/);
|
|
24406
24574
|
const pid = Number(pidLine);
|
|
@@ -24418,7 +24586,7 @@ function _installLockTokenMatches(lockPath, expectedPid, expectedTs, expectedTok
|
|
|
24418
24586
|
}
|
|
24419
24587
|
function chmodExtractedBinariesPosix(rootDir, executable) {
|
|
24420
24588
|
if (process.platform === "win32") return;
|
|
24421
|
-
const execDir = join14(rootDir,
|
|
24589
|
+
const execDir = join14(rootDir, dirname10(executable));
|
|
24422
24590
|
const targets = /* @__PURE__ */ new Set([
|
|
24423
24591
|
join14(rootDir, executable),
|
|
24424
24592
|
join14(execDir, "whisper-cli"),
|
|
@@ -24426,9 +24594,9 @@ function chmodExtractedBinariesPosix(rootDir, executable) {
|
|
|
24426
24594
|
join14(execDir, "ffmpeg")
|
|
24427
24595
|
]);
|
|
24428
24596
|
for (const p of targets) {
|
|
24429
|
-
if (
|
|
24597
|
+
if (existsSync12(p)) {
|
|
24430
24598
|
try {
|
|
24431
|
-
|
|
24599
|
+
chmodSync2(p, 493);
|
|
24432
24600
|
} catch {
|
|
24433
24601
|
}
|
|
24434
24602
|
}
|
|
@@ -24450,9 +24618,9 @@ async function _withInstallLock(rootDir, lockName, fn, { pollMs = 250 } = {}) {
|
|
|
24450
24618
|
};
|
|
24451
24619
|
while (true) {
|
|
24452
24620
|
try {
|
|
24453
|
-
fd =
|
|
24621
|
+
fd = openSync3(lockPath, "wx");
|
|
24454
24622
|
try {
|
|
24455
|
-
|
|
24623
|
+
writeFileSync3(lockPath, `${process.pid}
|
|
24456
24624
|
${Date.now()}`);
|
|
24457
24625
|
} catch {
|
|
24458
24626
|
}
|
|
@@ -24505,7 +24673,7 @@ ${Date.now()}`);
|
|
|
24505
24673
|
if (released) return;
|
|
24506
24674
|
released = true;
|
|
24507
24675
|
try {
|
|
24508
|
-
if (fd != null)
|
|
24676
|
+
if (fd != null) closeSync3(fd);
|
|
24509
24677
|
} catch {
|
|
24510
24678
|
}
|
|
24511
24679
|
try {
|
|
@@ -24522,21 +24690,21 @@ ${Date.now()}`);
|
|
|
24522
24690
|
}
|
|
24523
24691
|
}
|
|
24524
24692
|
function readBundledManifest() {
|
|
24525
|
-
return JSON.parse(
|
|
24693
|
+
return JSON.parse(readFileSync13(BUNDLED_MANIFEST_PATH, "utf8"));
|
|
24526
24694
|
}
|
|
24527
24695
|
function readActiveName(rootDir) {
|
|
24528
24696
|
const activeFile = join14(rootDir, "active-version");
|
|
24529
|
-
if (!
|
|
24530
|
-
return
|
|
24697
|
+
if (!existsSync12(activeFile)) return "";
|
|
24698
|
+
return readFileSync13(activeFile, "utf8").trim();
|
|
24531
24699
|
}
|
|
24532
24700
|
async function loadManifest(dataDir2) {
|
|
24533
|
-
if (
|
|
24701
|
+
if (existsSync12(BUNDLED_MANIFEST_PATH)) {
|
|
24534
24702
|
return readBundledManifest();
|
|
24535
24703
|
}
|
|
24536
24704
|
const cachedPath = join14(dataDir2, "voice-runtime", "manifest.json");
|
|
24537
|
-
if (
|
|
24705
|
+
if (existsSync12(cachedPath)) {
|
|
24538
24706
|
try {
|
|
24539
|
-
return JSON.parse(
|
|
24707
|
+
return JSON.parse(readFileSync13(cachedPath, "utf8"));
|
|
24540
24708
|
} catch {
|
|
24541
24709
|
}
|
|
24542
24710
|
}
|
|
@@ -24544,7 +24712,7 @@ async function loadManifest(dataDir2) {
|
|
|
24544
24712
|
if (!res.ok) throw new Error(`[voice-runtime] manifest fetch failed: ${res.status} ${res.statusText}`);
|
|
24545
24713
|
const manifest = await res.json();
|
|
24546
24714
|
mkdirSync7(join14(dataDir2, "voice-runtime"), { recursive: true });
|
|
24547
|
-
|
|
24715
|
+
writeJsonAtomicSync(cachedPath, manifest);
|
|
24548
24716
|
return manifest;
|
|
24549
24717
|
}
|
|
24550
24718
|
function verifySha256(filePath, expected) {
|
|
@@ -24560,18 +24728,18 @@ function detectCudaMajorsWin32() {
|
|
|
24560
24728
|
}
|
|
24561
24729
|
for (const root of windowsProgramRoots()) {
|
|
24562
24730
|
const standardRoot = join14(root, "NVIDIA GPU Computing Toolkit", "CUDA");
|
|
24563
|
-
if (!
|
|
24731
|
+
if (!existsSync12(standardRoot)) continue;
|
|
24564
24732
|
try {
|
|
24565
|
-
for (const e of
|
|
24733
|
+
for (const e of readdirSync5(standardRoot)) {
|
|
24566
24734
|
if (/^v\d+\.\d+/.test(e)) dirs.push(join14(standardRoot, e, "bin"));
|
|
24567
24735
|
}
|
|
24568
24736
|
} catch {
|
|
24569
24737
|
}
|
|
24570
24738
|
}
|
|
24571
24739
|
for (const d of dirs) {
|
|
24572
|
-
if (!
|
|
24740
|
+
if (!existsSync12(d)) continue;
|
|
24573
24741
|
try {
|
|
24574
|
-
for (const f of
|
|
24742
|
+
for (const f of readdirSync5(d)) {
|
|
24575
24743
|
const m = /^cublas64_(\d+)\.dll$/i.exec(f);
|
|
24576
24744
|
if (m) found.add(Number(m[1]));
|
|
24577
24745
|
}
|
|
@@ -24591,9 +24759,9 @@ function detectCudaMajorsLinux() {
|
|
|
24591
24759
|
const cudaPath = process.env.CUDA_PATH;
|
|
24592
24760
|
if (cudaPath) dirs.push(`${cudaPath}/lib64`);
|
|
24593
24761
|
for (const d of dirs) {
|
|
24594
|
-
if (!
|
|
24762
|
+
if (!existsSync12(d)) continue;
|
|
24595
24763
|
try {
|
|
24596
|
-
for (const f of
|
|
24764
|
+
for (const f of readdirSync5(d)) {
|
|
24597
24765
|
const m = /^libcublas\.so\.(\d+)$/.exec(f);
|
|
24598
24766
|
if (m) found.add(Number(m[1]));
|
|
24599
24767
|
}
|
|
@@ -24614,7 +24782,7 @@ function hasNvidiaDriver() {
|
|
|
24614
24782
|
const sys = windowsSystemRoot();
|
|
24615
24783
|
if (!sys) return false;
|
|
24616
24784
|
for (const f of ["System32\\nvidia-smi.exe", "System32\\nvml.dll"]) {
|
|
24617
|
-
if (
|
|
24785
|
+
if (existsSync12(join14(sys, f))) return true;
|
|
24618
24786
|
}
|
|
24619
24787
|
return false;
|
|
24620
24788
|
}
|
|
@@ -24652,10 +24820,10 @@ async function processExtras(extras, stagingDir, onProgress) {
|
|
|
24652
24820
|
for (const f of extra.files) {
|
|
24653
24821
|
const src = join14(extractDir, f.from);
|
|
24654
24822
|
const dst = join14(stagingDir, f.to);
|
|
24655
|
-
if (!
|
|
24823
|
+
if (!existsSync12(src)) {
|
|
24656
24824
|
throw new Error(`[voice-runtime] extra ${tag}: expected file ${f.from} not present after extract`);
|
|
24657
24825
|
}
|
|
24658
|
-
mkdirSync7(
|
|
24826
|
+
mkdirSync7(dirname10(dst), { recursive: true });
|
|
24659
24827
|
renameWithRetrySync(src, dst);
|
|
24660
24828
|
}
|
|
24661
24829
|
try {
|
|
@@ -24669,8 +24837,8 @@ async function processExtras(extras, stagingDir, onProgress) {
|
|
|
24669
24837
|
}
|
|
24670
24838
|
}
|
|
24671
24839
|
function gcStaleVersions(rootDir, activeName, prefix) {
|
|
24672
|
-
if (!
|
|
24673
|
-
for (const entry of
|
|
24840
|
+
if (!existsSync12(rootDir)) return;
|
|
24841
|
+
for (const entry of readdirSync5(rootDir)) {
|
|
24674
24842
|
if (entry === activeName || entry === "active-version" || entry === "manifest.json") continue;
|
|
24675
24843
|
if (!entry.startsWith(prefix) && !entry.startsWith("staging-")) continue;
|
|
24676
24844
|
try {
|
|
@@ -24682,18 +24850,18 @@ function gcStaleVersions(rootDir, activeName, prefix) {
|
|
|
24682
24850
|
function gcPublishedRuntimeSiblings(rootDir, prefix) {
|
|
24683
24851
|
try {
|
|
24684
24852
|
const activeName = readActiveName(rootDir);
|
|
24685
|
-
if (!activeName.startsWith(prefix) || !
|
|
24853
|
+
if (!activeName.startsWith(prefix) || !existsSync12(join14(rootDir, activeName))) return;
|
|
24686
24854
|
gcStaleVersions(rootDir, activeName, prefix);
|
|
24687
24855
|
} catch {
|
|
24688
24856
|
}
|
|
24689
24857
|
}
|
|
24690
24858
|
async function extractGz(gzPath, destPath) {
|
|
24691
|
-
await pipeline2(createReadStream2(gzPath), createGunzip(), createWriteStream2(destPath));
|
|
24859
|
+
await pipeline2(createReadStream2(gzPath), createGunzip(), createWriteStream2(destPath, { flush: true }));
|
|
24692
24860
|
}
|
|
24693
24861
|
function gcStagingPartials(dir) {
|
|
24694
|
-
if (!
|
|
24862
|
+
if (!existsSync12(dir)) return;
|
|
24695
24863
|
try {
|
|
24696
|
-
for (const entry of
|
|
24864
|
+
for (const entry of readdirSync5(dir)) {
|
|
24697
24865
|
if (!entry.startsWith(".staging-")) continue;
|
|
24698
24866
|
try {
|
|
24699
24867
|
rmSync4(join14(dir, entry), { force: true });
|
|
@@ -24771,12 +24939,12 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24771
24939
|
const activeName = `whisper-${ver}-${variant.id}`;
|
|
24772
24940
|
const activeDir = join14(rootDir, activeName);
|
|
24773
24941
|
const whisperCmd = join14(activeDir, variant.executable);
|
|
24774
|
-
if (
|
|
24942
|
+
if (fileHasData(whisperCmd)) {
|
|
24775
24943
|
gcStaleVersions(rootDir, activeName, "whisper-");
|
|
24776
24944
|
return { whisperCmd, version: ver, variantId: variant.id };
|
|
24777
24945
|
}
|
|
24778
24946
|
return _withInstallLock(rootDir, "install", async () => {
|
|
24779
|
-
if (
|
|
24947
|
+
if (fileHasData(whisperCmd)) {
|
|
24780
24948
|
gcStaleVersions(rootDir, activeName, "whisper-");
|
|
24781
24949
|
return { whisperCmd, version: ver, variantId: variant.id };
|
|
24782
24950
|
}
|
|
@@ -24800,7 +24968,7 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24800
24968
|
rmSync4(archivePath, { force: true });
|
|
24801
24969
|
chmodExtractedBinariesPosix(stagingDir, variant.executable);
|
|
24802
24970
|
const stagedExec = join14(stagingDir, variant.executable);
|
|
24803
|
-
if (!
|
|
24971
|
+
if (!existsSync12(stagedExec)) {
|
|
24804
24972
|
throw new Error(`[voice-runtime] expected executable ${variant.executable} not present after extract`);
|
|
24805
24973
|
}
|
|
24806
24974
|
await processExtras(variant.extras, stagingDir, onProgress);
|
|
@@ -24822,7 +24990,7 @@ async function ensureWhisperRuntime(dataDir2, onProgress = null) {
|
|
|
24822
24990
|
function isManagedWhisperStale(dataDir2) {
|
|
24823
24991
|
const activeName = readActiveName(join14(dataDir2, "voice-runtime"));
|
|
24824
24992
|
if (!activeName) return false;
|
|
24825
|
-
if (!
|
|
24993
|
+
if (!existsSync12(BUNDLED_MANIFEST_PATH)) return false;
|
|
24826
24994
|
try {
|
|
24827
24995
|
const manifest = readBundledManifest();
|
|
24828
24996
|
if (!manifest?.version) return false;
|
|
@@ -24835,7 +25003,7 @@ function resolveManagedWhisperCmd(dataDir2) {
|
|
|
24835
25003
|
const activeName = readActiveName(join14(dataDir2, "voice-runtime"));
|
|
24836
25004
|
if (!activeName) return null;
|
|
24837
25005
|
const activeDir = join14(dataDir2, "voice-runtime", activeName);
|
|
24838
|
-
if (
|
|
25006
|
+
if (existsSync12(BUNDLED_MANIFEST_PATH)) {
|
|
24839
25007
|
try {
|
|
24840
25008
|
const manifest = readBundledManifest();
|
|
24841
25009
|
const key = platformEntryKey(manifest.platforms);
|
|
@@ -24846,7 +25014,7 @@ function resolveManagedWhisperCmd(dataDir2) {
|
|
|
24846
25014
|
const variant = variants.find((v) => v.id === variantId);
|
|
24847
25015
|
if (variant?.executable) {
|
|
24848
25016
|
const p = join14(activeDir, variant.executable);
|
|
24849
|
-
if (
|
|
25017
|
+
if (fileHasData(p)) return p;
|
|
24850
25018
|
}
|
|
24851
25019
|
}
|
|
24852
25020
|
} catch {
|
|
@@ -24854,17 +25022,17 @@ function resolveManagedWhisperCmd(dataDir2) {
|
|
|
24854
25022
|
}
|
|
24855
25023
|
for (const c of ["Release/whisper-cli.exe", "Release/whisper-cli"]) {
|
|
24856
25024
|
const p = join14(activeDir, c);
|
|
24857
|
-
if (
|
|
25025
|
+
if (fileHasData(p)) return p;
|
|
24858
25026
|
}
|
|
24859
25027
|
return null;
|
|
24860
25028
|
}
|
|
24861
25029
|
function resolveManagedWhisperModelById(dataDir2, modelId = "standard") {
|
|
24862
|
-
if (!
|
|
25030
|
+
if (!existsSync12(BUNDLED_MANIFEST_PATH)) return null;
|
|
24863
25031
|
const entry = manifestModelEntry(readBundledManifest(), modelId);
|
|
24864
25032
|
if (!entry?.filename) return null;
|
|
24865
25033
|
const modelDir = join14(dataDir2, "voice", "models");
|
|
24866
25034
|
const p = join14(modelDir, entry.filename);
|
|
24867
|
-
return
|
|
25035
|
+
return fileHasData(p) ? p : null;
|
|
24868
25036
|
}
|
|
24869
25037
|
function gcUnknownModelFiles(manifest, modelDir) {
|
|
24870
25038
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -24874,7 +25042,7 @@ function gcUnknownModelFiles(manifest, modelDir) {
|
|
|
24874
25042
|
if (keep.size === 0) return;
|
|
24875
25043
|
let names = [];
|
|
24876
25044
|
try {
|
|
24877
|
-
names =
|
|
25045
|
+
names = readdirSync5(modelDir);
|
|
24878
25046
|
} catch {
|
|
24879
25047
|
return;
|
|
24880
25048
|
}
|
|
@@ -24903,12 +25071,12 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24903
25071
|
const activeName = `ffmpeg-${ver}`;
|
|
24904
25072
|
const activeDir = join14(rootDir, activeName);
|
|
24905
25073
|
const ffmpegPath = join14(activeDir, platformEntry.executable);
|
|
24906
|
-
if (
|
|
25074
|
+
if (fileHasData(ffmpegPath)) {
|
|
24907
25075
|
gcStaleVersions(rootDir, activeName, "ffmpeg-");
|
|
24908
25076
|
return { ffmpegPath, version: ver };
|
|
24909
25077
|
}
|
|
24910
25078
|
return _withInstallLock(rootDir, "install", async () => {
|
|
24911
|
-
if (
|
|
25079
|
+
if (fileHasData(ffmpegPath)) {
|
|
24912
25080
|
gcStaleVersions(rootDir, activeName, "ffmpeg-");
|
|
24913
25081
|
return { ffmpegPath, version: ver };
|
|
24914
25082
|
}
|
|
@@ -24937,13 +25105,13 @@ async function ensureFfmpegRuntime(dataDir2, onProgress = null) {
|
|
|
24937
25105
|
throw new Error(`[voice-runtime] ffmpeg manifest format must be "gz" or "zip", got "${platformEntry.format}"`);
|
|
24938
25106
|
}
|
|
24939
25107
|
rmSync4(archivePath, { force: true });
|
|
24940
|
-
if (!
|
|
25108
|
+
if (!existsSync12(stagedExec)) {
|
|
24941
25109
|
throw new Error(
|
|
24942
25110
|
`[voice-runtime] expected ffmpeg executable ${platformEntry.executable} not present after extract`
|
|
24943
25111
|
);
|
|
24944
25112
|
}
|
|
24945
25113
|
if (process.platform !== "win32") {
|
|
24946
|
-
|
|
25114
|
+
chmodSync2(stagedExec, 493);
|
|
24947
25115
|
}
|
|
24948
25116
|
renameWithRetrySync(stagingDir, activeDir);
|
|
24949
25117
|
writeFileAtomicSync(join14(rootDir, "active-version"), activeName, { fsyncDir: true });
|
|
@@ -24964,21 +25132,21 @@ function resolveManagedFfmpegPath(dataDir2) {
|
|
|
24964
25132
|
const activeName = readActiveName(join14(dataDir2, "ffmpeg-runtime"));
|
|
24965
25133
|
if (!activeName) return null;
|
|
24966
25134
|
const activeDir = join14(dataDir2, "ffmpeg-runtime", activeName);
|
|
24967
|
-
if (
|
|
25135
|
+
if (existsSync12(BUNDLED_MANIFEST_PATH)) {
|
|
24968
25136
|
try {
|
|
24969
25137
|
const manifest = readBundledManifest();
|
|
24970
25138
|
const key = platformEntryKey(manifest.ffmpeg?.platforms);
|
|
24971
25139
|
const platformEntry = manifest.ffmpeg?.platforms?.[key];
|
|
24972
25140
|
if (platformEntry?.executable) {
|
|
24973
25141
|
const p = join14(activeDir, platformEntry.executable);
|
|
24974
|
-
if (
|
|
25142
|
+
if (fileHasData(p)) return p;
|
|
24975
25143
|
}
|
|
24976
25144
|
} catch {
|
|
24977
25145
|
}
|
|
24978
25146
|
}
|
|
24979
25147
|
for (const c of ["ffmpeg.exe", "ffmpeg"]) {
|
|
24980
25148
|
const p = join14(activeDir, c);
|
|
24981
|
-
if (
|
|
25149
|
+
if (fileHasData(p)) return p;
|
|
24982
25150
|
}
|
|
24983
25151
|
return null;
|
|
24984
25152
|
}
|
|
@@ -24993,7 +25161,7 @@ function voiceRuntimeInfo(runtime) {
|
|
|
24993
25161
|
let modelBytes = model?.size || 0;
|
|
24994
25162
|
if (runtime.modelPath) {
|
|
24995
25163
|
try {
|
|
24996
|
-
modelBytes =
|
|
25164
|
+
modelBytes = statSync6(runtime.modelPath).size;
|
|
24997
25165
|
} catch {
|
|
24998
25166
|
modelBytes = 0;
|
|
24999
25167
|
}
|
|
@@ -25016,8 +25184,8 @@ function resolveVoiceRuntime(dataDir2, { modelId = "standard", cleanup = true }
|
|
|
25016
25184
|
const managedModelPath = resolveManagedWhisperModelById(dataDir2, modelId);
|
|
25017
25185
|
const managedFfmpegPath = resolveManagedFfmpegPath(dataDir2);
|
|
25018
25186
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
25019
|
-
const managedServerCmd = managedWhisperCmd ? join14(
|
|
25020
|
-
const serverCmd = managedServerCmd &&
|
|
25187
|
+
const managedServerCmd = managedWhisperCmd ? join14(dirname10(managedWhisperCmd), `whisper-server${ext}`) : null;
|
|
25188
|
+
const serverCmd = managedServerCmd && fileHasData(managedServerCmd) ? managedServerCmd : null;
|
|
25021
25189
|
return {
|
|
25022
25190
|
kind: "managed-whisper.cpp",
|
|
25023
25191
|
label: "whisper.cpp",
|
|
@@ -25044,7 +25212,7 @@ async function ensureWhisperModel(dataDir2, onProgress = null, modelId = "standa
|
|
|
25044
25212
|
}
|
|
25045
25213
|
const modelDir = join14(dataDir2, "voice", "models");
|
|
25046
25214
|
const modelPath = join14(modelDir, model.filename);
|
|
25047
|
-
if (
|
|
25215
|
+
if (existsSync12(modelPath)) {
|
|
25048
25216
|
const actual = await sha256File(modelPath);
|
|
25049
25217
|
if (actual === model.sha256) {
|
|
25050
25218
|
return { modelPath, modelId: model.id, size: model.size };
|
|
@@ -25059,7 +25227,7 @@ async function ensureWhisperModel(dataDir2, onProgress = null, modelId = "standa
|
|
|
25059
25227
|
}
|
|
25060
25228
|
}
|
|
25061
25229
|
return _withInstallLock(modelDir, "install", async () => {
|
|
25062
|
-
if (
|
|
25230
|
+
if (existsSync12(modelPath)) {
|
|
25063
25231
|
const actual = await sha256File(modelPath);
|
|
25064
25232
|
if (actual === model.sha256) {
|
|
25065
25233
|
gcUnknownModelFiles(manifest, modelDir);
|
|
@@ -25101,6 +25269,7 @@ var BUNDLED_MANIFEST_PATH, MANIFEST_URL, LOCK_WAIT_CODES2, LOCK_MAX_AGE_MS, Voic
|
|
|
25101
25269
|
var init_voice_runtime_fetcher = __esm({
|
|
25102
25270
|
"src/runtime/channels/lib/voice-runtime-fetcher.mjs"() {
|
|
25103
25271
|
init_atomic_file();
|
|
25272
|
+
init_file_has_data();
|
|
25104
25273
|
init_bounded_download();
|
|
25105
25274
|
init_native_asset();
|
|
25106
25275
|
init_windows_roots();
|
|
@@ -35336,9 +35505,9 @@ import { useState as useState4, useEffect as useEffect5 } from "react";
|
|
|
35336
35505
|
import { useState as useState5, useEffect as useEffect6, useCallback as useCallback4, useMemo as useMemo4 } from "react";
|
|
35337
35506
|
|
|
35338
35507
|
// src/tui/index.jsx
|
|
35339
|
-
import { closeSync as
|
|
35508
|
+
import { closeSync as closeSync4, constants as fsConstants, createWriteStream as createWriteStream3, mkdirSync as mkdirSync8, openSync as openSync4, readSync as readSync2 } from "node:fs";
|
|
35340
35509
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
35341
|
-
import { dirname as
|
|
35510
|
+
import { dirname as dirname11, join as join17 } from "node:path";
|
|
35342
35511
|
import { performance as performance2 } from "node:perf_hooks";
|
|
35343
35512
|
import { format } from "node:util";
|
|
35344
35513
|
|
|
@@ -35664,7 +35833,7 @@ var SLASH_COMMANDS = [
|
|
|
35664
35833
|
{
|
|
35665
35834
|
name: "autoclear",
|
|
35666
35835
|
usage: "/autoclear",
|
|
35667
|
-
params: "[on|off|duration]",
|
|
35836
|
+
params: "[on|off|duration|unlimited]",
|
|
35668
35837
|
description: "Reduce cache-miss cost after long idle gaps"
|
|
35669
35838
|
},
|
|
35670
35839
|
{ name: "resume", usage: "/resume", params: "[id]", description: "Resume a saved chat" },
|
|
@@ -41360,6 +41529,14 @@ function gitStageUnit(a) {
|
|
|
41360
41529
|
effect: true
|
|
41361
41530
|
});
|
|
41362
41531
|
}
|
|
41532
|
+
function gitWorktreeUnit(a) {
|
|
41533
|
+
return unitDescriptor("Git", {
|
|
41534
|
+
active: "Managing",
|
|
41535
|
+
done: "Managed",
|
|
41536
|
+
noun: "worktree",
|
|
41537
|
+
effect: String(a.worktree_action || "").toLowerCase() !== "list"
|
|
41538
|
+
});
|
|
41539
|
+
}
|
|
41363
41540
|
function cwdUnit(a) {
|
|
41364
41541
|
const action = String(a.action || a.type || "").toLowerCase();
|
|
41365
41542
|
if (action === "set" || action === "set-project" || !action && a.path) {
|
|
@@ -41390,14 +41567,6 @@ function cwdUnit(a) {
|
|
|
41390
41567
|
const [active, done] = words;
|
|
41391
41568
|
return unitDescriptor("Setup", { active, done, noun: "session", effect: true });
|
|
41392
41569
|
}
|
|
41393
|
-
if (action.endsWith("-worktree") || action.endsWith("-worktrees")) {
|
|
41394
|
-
return unitDescriptor("Setup", {
|
|
41395
|
-
active: "Managing",
|
|
41396
|
-
done: "Managed",
|
|
41397
|
-
noun: "worktree",
|
|
41398
|
-
effect: !action.startsWith("list")
|
|
41399
|
-
});
|
|
41400
|
-
}
|
|
41401
41570
|
if (action === "status") {
|
|
41402
41571
|
return unitDescriptor("Setup", { active: "Checking", done: "Checked", noun: "session" });
|
|
41403
41572
|
}
|
|
@@ -41492,7 +41661,7 @@ var TOOL_UNITS = /* @__PURE__ */ new Map([
|
|
|
41492
41661
|
["job_wait", shellUnit],
|
|
41493
41662
|
[
|
|
41494
41663
|
"git",
|
|
41495
|
-
(a) => a.action === "stage" ? gitStageUnit(a) : unitDescriptor("Git", { count: queryCount(a, "command", "commands") || 1, noun: "Git command" })
|
|
41664
|
+
(a) => a.action === "stage" ? gitStageUnit(a) : a.action === "worktree" ? gitWorktreeUnit(a) : unitDescriptor("Git", { count: queryCount(a, "command", "commands") || 1, noun: "Git command" })
|
|
41496
41665
|
],
|
|
41497
41666
|
["github", githubUnit],
|
|
41498
41667
|
// Preserve the staging work unit when rendering historical transcripts.
|
|
@@ -41995,7 +42164,8 @@ function pathOrId(path2, id, max) {
|
|
|
41995
42164
|
}
|
|
41996
42165
|
|
|
41997
42166
|
// src/tui/transcript-tool-failures.mjs
|
|
41998
|
-
var HOOK_DENIAL_RE = /^Error:\s*tool\s*"[^"]*"\s*denied by hook\b/im;
|
|
42167
|
+
var HOOK_DENIAL_RE = /^Error:\s*tool\s*"[^"]*"\s*(?:denied by hook|was not approved)\b/im;
|
|
42168
|
+
var NOT_APPROVED_INSTRUCTION_RE = /\s*Do not retry it or reach the same result another way; report it\.\s*$/;
|
|
41999
42169
|
var APPROVAL_UNAVAILABLE_RE = /denied by hook:\s*approval required but no approval UI is available/i;
|
|
42000
42170
|
function toolItemResultText(item) {
|
|
42001
42171
|
if (!item) return "";
|
|
@@ -42019,7 +42189,7 @@ function isHookApprovalDenialToolItem(item) {
|
|
|
42019
42189
|
function formatHookDenialDetail(text) {
|
|
42020
42190
|
const raw = String(text ?? "").trim();
|
|
42021
42191
|
if (!raw) return "";
|
|
42022
|
-
const stripped = raw.replace(/^Error:\s*tool\s*"[^"]*"\s*/i, "").trim();
|
|
42192
|
+
const stripped = raw.replace(/^Error:\s*tool\s*"[^"]*"\s*/i, "").replace(NOT_APPROVED_INSTRUCTION_RE, "").trim();
|
|
42023
42193
|
return stripped || raw;
|
|
42024
42194
|
}
|
|
42025
42195
|
function isFullyFailedToolBatch(item) {
|
|
@@ -42759,6 +42929,7 @@ var DETERMINISTIC_KINDS = /* @__PURE__ */ new Set([
|
|
|
42759
42929
|
// src/runtime/shared/error-presentation.mjs
|
|
42760
42930
|
var DETAILS_LIMIT = 12e3;
|
|
42761
42931
|
var SUMMARY_LIMIT = 180;
|
|
42932
|
+
var LATEST_TURN_RE = /The latest message cannot fit this model \(LATEST_TURN_EXCEEDS_CONTEXT\)(: it needs about [\d,]+ tokens, but the [^.]* window leaves [\d,]+ for it\.)([\s\S]*)$/;
|
|
42762
42933
|
function safeErrorDetails(value) {
|
|
42763
42934
|
let text = String(value ?? "").replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "").replace(/\r\n?/g, "\n").replace(/\b((?:https?|ssh):\/\/)[^/\s@]+@/gi, "$1[redacted]@").replace(/\b(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+/gi, "$1 [redacted]").replace(/([?&](?:token|access_token|refresh_token|api_key|key|code|signature|sig)=)[^&\s"'<>]+/gi, "$1[redacted]").replace(
|
|
42764
42935
|
/(["']?(?:api[_-]?key|access[_-]?token|refresh[_-]?token|authorization|cookie|password|secret|client_secret)["']?\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;}]+)/gi,
|
|
@@ -42951,11 +43122,15 @@ function describeError(value) {
|
|
|
42951
43122
|
let recoveryTemplate = "";
|
|
42952
43123
|
let params = null;
|
|
42953
43124
|
const transport = transportErrorText(value) || typed && transportErrorText({ code: code.toUpperCase(), status }) || (!typed || descriptor.kind === "transient" ? transportErrorText(raw) : null);
|
|
42954
|
-
if (value?.reauthRequired === true || !typed && /invalid_grant|refresh token (?:expired|revoked|not available)|sign in again|sign-in expired|Reauth Required/i.test(
|
|
43125
|
+
if (value?.reauthRequired === true || !typed && /invalid_grant|refresh token (?:expired|revoked|not available)|sign in again|sign-in expired|Reauth Required/i.test(
|
|
43126
|
+
raw
|
|
43127
|
+
)) {
|
|
42955
43128
|
kind = "reauth";
|
|
42956
43129
|
summary = "Sign-in expired.";
|
|
42957
43130
|
recovery = "Sign in again from Providers.";
|
|
42958
|
-
} else if (descriptor.kind === "auth" || descriptor.kind === "unknown" && /\b(?:invalid|expired)\s+(?:api[ _-]?key|access token|credentials?)\b|Provider authentication failed/i.test(
|
|
43131
|
+
} else if (descriptor.kind === "auth" || descriptor.kind === "unknown" && /\b(?:invalid|expired)\s+(?:api[ _-]?key|access token|credentials?)\b|Provider authentication failed/i.test(
|
|
43132
|
+
clean3
|
|
43133
|
+
)) {
|
|
42959
43134
|
kind = "authentication";
|
|
42960
43135
|
summary = "Provider authentication failed";
|
|
42961
43136
|
recovery = "Check your sign-in or API key, then try again.";
|
|
@@ -42977,6 +43152,11 @@ function describeError(value) {
|
|
|
42977
43152
|
kind = "not-found";
|
|
42978
43153
|
summary = firstReadableLine(clean3) || NOT_FOUND_SUMMARY;
|
|
42979
43154
|
recovery = MODEL_UNAVAILABLE_COPY[2];
|
|
43155
|
+
} else if (LATEST_TURN_RE.test(clean3)) {
|
|
43156
|
+
const [, headline, rest] = LATEST_TURN_RE.exec(clean3);
|
|
43157
|
+
kind = "latest-turn-size";
|
|
43158
|
+
summary = `The latest message cannot fit this model${headline}`;
|
|
43159
|
+
recovery = rest.trim();
|
|
42980
43160
|
} else if (descriptor.kind === "unknown" && /payload too large|request (?:body )?too large|The request exceeds the size limit/i.test(clean3)) {
|
|
42981
43161
|
[kind, summary, recovery] = KIND_COPY.request_too_large;
|
|
42982
43162
|
} else if (copy) {
|
|
@@ -43003,6 +43183,7 @@ function describeError(value) {
|
|
|
43003
43183
|
}
|
|
43004
43184
|
summary = summary.replace(/\s+/g, " ").trim() || "Something went wrong.";
|
|
43005
43185
|
if (summary.length > SUMMARY_LIMIT) summary = `${summary.slice(0, SUMMARY_LIMIT - 1).trimEnd()}\u2026`;
|
|
43186
|
+
const fingerprintStatus = kind === "reauth" ? "" : status || "";
|
|
43006
43187
|
return {
|
|
43007
43188
|
kind,
|
|
43008
43189
|
summary,
|
|
@@ -43015,7 +43196,7 @@ function describeError(value) {
|
|
|
43015
43196
|
details,
|
|
43016
43197
|
// Known structured failures ignore volatile indexes; unknown failures
|
|
43017
43198
|
// retain their diagnostic identity rather than merging unrelated work.
|
|
43018
|
-
fingerprint: kind === "unknown" ? details : `${kind}:${
|
|
43199
|
+
fingerprint: kind === "unknown" ? details : `${kind}:${fingerprintStatus}`
|
|
43019
43200
|
};
|
|
43020
43201
|
}
|
|
43021
43202
|
|
|
@@ -43228,6 +43409,8 @@ function presentErrorText(error, options = {}) {
|
|
|
43228
43409
|
if (code === "TOOL_SURFACE_EXCEEDS_CONTEXT" || /\(TOOL_SURFACE_EXCEEDS_CONTEXT\)/.test(text)) {
|
|
43229
43410
|
return stripErrorPrefix(text);
|
|
43230
43411
|
}
|
|
43412
|
+
const latestTurn = /The latest message cannot fit this model \(LATEST_TURN_EXCEEDS_CONTEXT\)[\s\S]*$/.exec(text);
|
|
43413
|
+
if (latestTurn) return latestTurn[0].replace(" (LATEST_TURN_EXCEEDS_CONTEXT)", "");
|
|
43231
43414
|
const jsonError = extractJsonError(text);
|
|
43232
43415
|
if (jsonError) text = jsonError;
|
|
43233
43416
|
const embeddedError = extractEmbeddedError(text);
|
|
@@ -47359,17 +47542,14 @@ async function resizeImageBuffer(buffer, ext, { maxTokens = DEFAULT_IMAGE_MAX_TO
|
|
|
47359
47542
|
var TOOL_IMAGE_TARGET_BASE64_SIZE = 256 * 1024;
|
|
47360
47543
|
|
|
47361
47544
|
// src/tui/paste-text-policy.mjs
|
|
47362
|
-
var
|
|
47363
|
-
var PASTE_TOKEN_MIN_CHARS = 200;
|
|
47545
|
+
var PASTE_TOKEN_MIN_CHARS = 1e3;
|
|
47364
47546
|
function pastedTextLineCount(text) {
|
|
47365
47547
|
const value = String(text ?? "").replace(/\r\n?/g, "\n").replace(/\n+$/, "");
|
|
47366
47548
|
if (!value) return 0;
|
|
47367
47549
|
return value.split("\n").length;
|
|
47368
47550
|
}
|
|
47369
47551
|
function shouldFoldPastedText(text) {
|
|
47370
|
-
|
|
47371
|
-
if (!value) return false;
|
|
47372
|
-
return pastedTextLineCount(value) >= PASTE_TOKEN_MIN_LINES || value.length > PASTE_TOKEN_MIN_CHARS;
|
|
47552
|
+
return String(text ?? "").length > PASTE_TOKEN_MIN_CHARS;
|
|
47373
47553
|
}
|
|
47374
47554
|
function formatPastedTextRef(id, text) {
|
|
47375
47555
|
return `[Pasted text #${id} +${pastedTextLineCount(text)} lines]`;
|
|
@@ -47944,15 +48124,16 @@ function projectNameFromPath(value) {
|
|
|
47944
48124
|
}
|
|
47945
48125
|
|
|
47946
48126
|
// src/tui/prompt-history-store.mjs
|
|
48127
|
+
init_atomic_file();
|
|
47947
48128
|
import { createHash as createHash2 } from "node:crypto";
|
|
47948
|
-
import {
|
|
47949
|
-
import {
|
|
47950
|
-
import { dirname as
|
|
48129
|
+
import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
48130
|
+
import { mkdir } from "node:fs/promises";
|
|
48131
|
+
import { dirname as dirname5, join as join5, resolve as resolve4 } from "node:path";
|
|
47951
48132
|
|
|
47952
48133
|
// src/runtime/shared/plugin-paths.mjs
|
|
47953
48134
|
import { homedir } from "node:os";
|
|
47954
|
-
import { dirname, join } from "node:path";
|
|
47955
|
-
import { fileURLToPath } from "node:url";
|
|
48135
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
48136
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
47956
48137
|
var homeBase = null;
|
|
47957
48138
|
var homePath = null;
|
|
47958
48139
|
var dataBase = null;
|
|
@@ -47963,7 +48144,7 @@ function mixdogHome() {
|
|
|
47963
48144
|
const home = homedir();
|
|
47964
48145
|
if (home !== homeBase) {
|
|
47965
48146
|
homeBase = home;
|
|
47966
|
-
homePath =
|
|
48147
|
+
homePath = join4(home, ".mixdog");
|
|
47967
48148
|
}
|
|
47968
48149
|
return homePath;
|
|
47969
48150
|
}
|
|
@@ -47973,7 +48154,7 @@ function resolvePluginData() {
|
|
|
47973
48154
|
const home = mixdogHome();
|
|
47974
48155
|
if (home !== dataBase) {
|
|
47975
48156
|
dataBase = home;
|
|
47976
|
-
dataPath =
|
|
48157
|
+
dataPath = join4(home, "data");
|
|
47977
48158
|
}
|
|
47978
48159
|
return dataPath;
|
|
47979
48160
|
}
|
|
@@ -47985,10 +48166,16 @@ function promptHistoryKey(value) {
|
|
|
47985
48166
|
return String(value || "").trim().replace(/\s+/g, " ");
|
|
47986
48167
|
}
|
|
47987
48168
|
function readEntries(filePath) {
|
|
47988
|
-
if (!filePath
|
|
48169
|
+
if (!filePath) return [];
|
|
47989
48170
|
try {
|
|
47990
|
-
const parsed =
|
|
47991
|
-
|
|
48171
|
+
const parsed = readJsonStateSync(filePath, {
|
|
48172
|
+
mode: 384,
|
|
48173
|
+
validate: (value) => {
|
|
48174
|
+
if (!Array.isArray(value?.entries)) throw new TypeError("prompt history has no entries");
|
|
48175
|
+
return value;
|
|
48176
|
+
}
|
|
48177
|
+
});
|
|
48178
|
+
const entries = parsed ? parsed.entries : [];
|
|
47992
48179
|
return entries.map((entry) => String(entry || "").trim()).filter((entry) => promptHistoryKey(entry));
|
|
47993
48180
|
} catch {
|
|
47994
48181
|
return [];
|
|
@@ -48001,14 +48188,8 @@ function buildPayload(entries) {
|
|
|
48001
48188
|
function writeEntriesSync(filePath, entries) {
|
|
48002
48189
|
if (!filePath) return false;
|
|
48003
48190
|
try {
|
|
48004
|
-
|
|
48005
|
-
|
|
48006
|
-
writeFileSync(tmp, buildPayload(entries), { encoding: "utf8", mode: 384 });
|
|
48007
|
-
renameSync(tmp, filePath);
|
|
48008
|
-
try {
|
|
48009
|
-
chmodSync(filePath, 384);
|
|
48010
|
-
} catch {
|
|
48011
|
-
}
|
|
48191
|
+
mkdirSync3(dirname5(filePath), { recursive: true, mode: 448 });
|
|
48192
|
+
writeFileAtomicSync(filePath, buildPayload(entries), { mode: 384 });
|
|
48012
48193
|
return true;
|
|
48013
48194
|
} catch {
|
|
48014
48195
|
return false;
|
|
@@ -48402,8 +48583,11 @@ function compactElapsed(value) {
|
|
|
48402
48583
|
if (!Number.isFinite(n) || n <= 0) return "";
|
|
48403
48584
|
return `${Math.max(1, Math.ceil(n / 1e3))}s`;
|
|
48404
48585
|
}
|
|
48586
|
+
function compactionRunning(compaction) {
|
|
48587
|
+
return compaction.inProgress === true || compaction.lastStage === "compacting";
|
|
48588
|
+
}
|
|
48405
48589
|
function compactionState(compaction) {
|
|
48406
|
-
const compactRunning = compaction
|
|
48590
|
+
const compactRunning = compactionRunning(compaction);
|
|
48407
48591
|
const autoClearFailed = compaction.lastStage === "auto_clear_failed" || !!compaction.lastClearCompactError;
|
|
48408
48592
|
const autoClearStage = compaction.lastStage === "auto_clear" || compaction.lastClearAt;
|
|
48409
48593
|
const compactInterrupted = compaction.lastStage === "interrupted";
|
|
@@ -48452,7 +48636,7 @@ function contextMetrics({ toolsStatus, mcpStatus, skillsStatus, pluginsStatus, c
|
|
|
48452
48636
|
);
|
|
48453
48637
|
const cacheDenom = Number(usage.lastContextTokens || 0) || cachedRead + freshInput + cacheWrite;
|
|
48454
48638
|
const compactState = compactionState(compaction);
|
|
48455
|
-
const compactDuration = compactElapsed(compaction.lastDurationMs);
|
|
48639
|
+
const compactDuration = compactionRunning(compaction) ? "" : compactElapsed(compaction.lastDurationMs);
|
|
48456
48640
|
return {
|
|
48457
48641
|
tools,
|
|
48458
48642
|
mcp,
|
|
@@ -50026,7 +50210,7 @@ function useGlobalKeyInput({
|
|
|
50026
50210
|
// src/runtime/shared/update-checker.mjs
|
|
50027
50211
|
init_atomic_file();
|
|
50028
50212
|
init_json_file();
|
|
50029
|
-
import { existsSync as
|
|
50213
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, realpathSync } from "node:fs";
|
|
50030
50214
|
import { basename as basename4, delimiter, dirname as dirname6, join as join6 } from "node:path";
|
|
50031
50215
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
50032
50216
|
var PACKAGE_NAME = "mixdog";
|
|
@@ -50039,7 +50223,7 @@ var _localVersionCache = null;
|
|
|
50039
50223
|
function localPackageVersion() {
|
|
50040
50224
|
if (_localVersionCache) return _localVersionCache;
|
|
50041
50225
|
try {
|
|
50042
|
-
const raw = JSON.parse(
|
|
50226
|
+
const raw = JSON.parse(readFileSync5(_PACKAGE_JSON_PATH, "utf8"));
|
|
50043
50227
|
_localVersionCache = String(raw?.version || "0.0.0");
|
|
50044
50228
|
} catch {
|
|
50045
50229
|
_localVersionCache = "0.0.0";
|
|
@@ -50786,13 +50970,13 @@ import { homedir as homedir2 } from "node:os";
|
|
|
50786
50970
|
import { join as join10 } from "node:path";
|
|
50787
50971
|
|
|
50788
50972
|
// src/runtime/shared/llm/model-catalog.mjs
|
|
50789
|
-
import { existsSync as
|
|
50973
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
50790
50974
|
import { join as join8 } from "node:path";
|
|
50791
50975
|
import { createHash as createHash3 } from "node:crypto";
|
|
50792
50976
|
init_atomic_file();
|
|
50793
50977
|
|
|
50794
50978
|
// src/runtime/shared/llm/provider-catalog-cache.mjs
|
|
50795
|
-
import { existsSync as
|
|
50979
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
|
|
50796
50980
|
import { join as join7 } from "node:path";
|
|
50797
50981
|
|
|
50798
50982
|
// src/runtime/shared/llm/provider-model-identities.mjs
|
|
@@ -51187,8 +51371,8 @@ var PRICING_CATALOG_REFRESH_MS = 6 * 60 * 60 * 1e3;
|
|
|
51187
51371
|
var PRICING_CATALOG_RETRY_MS = 6e4;
|
|
51188
51372
|
function readDiskCatalog(filePath) {
|
|
51189
51373
|
try {
|
|
51190
|
-
if (!
|
|
51191
|
-
const raw = JSON.parse(
|
|
51374
|
+
if (!existsSync7(filePath)) return null;
|
|
51375
|
+
const raw = JSON.parse(readFileSync7(filePath, "utf-8"));
|
|
51192
51376
|
return raw?.data ? raw : null;
|
|
51193
51377
|
} catch {
|
|
51194
51378
|
return null;
|
|
@@ -51268,7 +51452,7 @@ function createCatalogSource({ url, cacheFile, project, label = "" }) {
|
|
|
51268
51452
|
warmFromDiskSync() {
|
|
51269
51453
|
if (cache3) return;
|
|
51270
51454
|
try {
|
|
51271
|
-
const raw = JSON.parse(
|
|
51455
|
+
const raw = JSON.parse(readFileSync7(cachePath(), "utf-8"));
|
|
51272
51456
|
if (raw?.data) {
|
|
51273
51457
|
cache3 = project(raw.data);
|
|
51274
51458
|
cacheAt = raw.fetchedAt || Date.now();
|
|
@@ -51392,11 +51576,11 @@ function isPidAlive(value) {
|
|
|
51392
51576
|
}
|
|
51393
51577
|
|
|
51394
51578
|
// src/runtime/shared/worktrees/git-head.mjs
|
|
51395
|
-
import { readFileSync as
|
|
51579
|
+
import { readFileSync as readFileSync8, statSync as statSync3, watch } from "node:fs";
|
|
51396
51580
|
import { dirname as dirname8, resolve as resolve6 } from "node:path";
|
|
51397
51581
|
|
|
51398
51582
|
// src/runtime/shared/worktrees/paths.mjs
|
|
51399
|
-
import { existsSync as
|
|
51583
|
+
import { existsSync as existsSync8, realpathSync as realpathSync2 } from "node:fs";
|
|
51400
51584
|
import { dirname as dirname7, isAbsolute as isAbsolute3, join as join9, relative as relative2, resolve as resolve5, sep } from "node:path";
|
|
51401
51585
|
|
|
51402
51586
|
// src/runtime/shared/statusline/statusline-segments.mjs
|
|
@@ -51485,8 +51669,7 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
51485
51669
|
continue;
|
|
51486
51670
|
}
|
|
51487
51671
|
const unconfirmed = detail?.terminationUnconfirmed === true;
|
|
51488
|
-
if (unconfirmed ? !
|
|
51489
|
-
continue;
|
|
51672
|
+
if (unconfirmed ? !isPidAlive(ownerByJob.get(id) || 0) : !await isShellJobAlive(detail, p, dir, id)) continue;
|
|
51490
51673
|
if (detail?.foreground === true && !unconfirmed) continue;
|
|
51491
51674
|
const ownedByThisHost = ownerByJob.get(id) === ownerPid;
|
|
51492
51675
|
if (ownedByThisHost) count++;
|
|
@@ -51575,12 +51758,6 @@ function summarizeShellJobs({ count, oldestMs, jobs, bySession }) {
|
|
|
51575
51758
|
}
|
|
51576
51759
|
return { count, elapsedLabel, jobs, sessions };
|
|
51577
51760
|
}
|
|
51578
|
-
function isHeldShellJobAlive(detail, ownerPid) {
|
|
51579
|
-
if (!isPidAlive(ownerPid || 0)) return false;
|
|
51580
|
-
if (detail?.ownerSessionClosed !== true) return true;
|
|
51581
|
-
const survivors = Array.isArray(detail?.survivorPids) ? detail.survivorPids : [];
|
|
51582
|
-
return [detail?.pid, ...survivors].some((pid) => isPidAlive(positiveInt(pid)));
|
|
51583
|
-
}
|
|
51584
51761
|
async function isShellJobAlive(detail, detailPath, dir, id) {
|
|
51585
51762
|
const pid = positiveInt(detail?.pid);
|
|
51586
51763
|
if (!pid) return false;
|
|
@@ -58611,7 +58788,9 @@ function createExtensionPickers({
|
|
|
58611
58788
|
|
|
58612
58789
|
// src/tui/app/maintenance-pickers/auto-clear-picker.mjs
|
|
58613
58790
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
58614
|
-
var
|
|
58791
|
+
var UNLIMITED_INPUT = "unlimited";
|
|
58792
|
+
var formatDurationInput = (ms, unlimited = false) => {
|
|
58793
|
+
if (unlimited) return UNLIMITED_INPUT;
|
|
58615
58794
|
const value = Math.max(0, Math.round(Number(ms) || 0));
|
|
58616
58795
|
if (value > 0 && value % HOUR_MS === 0) return `${value / HOUR_MS}h`;
|
|
58617
58796
|
if (value > 0 && value % 6e4 === 0) return `${value / 6e4}m`;
|
|
@@ -58642,7 +58821,7 @@ function createAutoClearPicker({
|
|
|
58642
58821
|
label: entry.provider,
|
|
58643
58822
|
marker: entry.provider === provider ? "\u2713" : "",
|
|
58644
58823
|
markerColor: theme2.success,
|
|
58645
|
-
meta: `${formatDuration2(entry.idleMs)}${entry.custom ? " custom" : ""}`,
|
|
58824
|
+
meta: `${entry.unlimited ? "Unlimited" : formatDuration2(entry.idleMs)}${entry.custom ? " custom" : ""}`,
|
|
58646
58825
|
description: `Default idle window for ${entry.provider}. Enter to edit as text.`,
|
|
58647
58826
|
_action: "provider-default",
|
|
58648
58827
|
_entry: entry
|
|
@@ -58661,10 +58840,10 @@ function createAutoClearPicker({
|
|
|
58661
58840
|
store.pushNotice("autoclear unavailable", "warn");
|
|
58662
58841
|
return;
|
|
58663
58842
|
}
|
|
58664
|
-
|
|
58665
|
-
|
|
58666
|
-
"
|
|
58667
|
-
);
|
|
58843
|
+
let notice = "autoclear off";
|
|
58844
|
+
if (next.enabled)
|
|
58845
|
+
notice = next.unlimited ? "autoclear on \xB7 unlimited" : `autoclear on \xB7 idle ${formatDuration2(next.idleMs)}`;
|
|
58846
|
+
store.pushNotice(notice, "info");
|
|
58668
58847
|
}).catch((e) => store.pushNotice(`autoclear failed: ${e?.message || e}`, "error")).finally(settled);
|
|
58669
58848
|
};
|
|
58670
58849
|
const openProviderDurationEditor = (entry) => {
|
|
@@ -58673,8 +58852,8 @@ function createAutoClearPicker({
|
|
|
58673
58852
|
setSettingsPrompt({
|
|
58674
58853
|
kind: "autoclear-provider",
|
|
58675
58854
|
label: `Auto-clear \xB7 ${entry.provider}`,
|
|
58676
|
-
hint: `Type a duration like 10m, 1h, or 24h. Empty resets to built-in ${formatDurationInput(entry.builtInMs)}.`,
|
|
58677
|
-
initialValue: formatDurationInput(entry.idleMs),
|
|
58855
|
+
hint: `Type a duration like 10m, 1h, or 24h, or ${UNLIMITED_INPUT} to never auto-clear. Empty resets to built-in ${formatDurationInput(entry.builtInMs, entry.builtInUnlimited)}.`,
|
|
58856
|
+
initialValue: formatDurationInput(entry.idleMs, entry.unlimited),
|
|
58678
58857
|
provider: entry.provider,
|
|
58679
58858
|
builtInMs: entry.builtInMs,
|
|
58680
58859
|
returnTo
|
|
@@ -58702,16 +58881,18 @@ function createAutoClearPicker({
|
|
|
58702
58881
|
const current = await readCurrent();
|
|
58703
58882
|
const enabled = current?.enabled !== false;
|
|
58704
58883
|
const idleMs = Number(current?.idleMs || HOUR_MS);
|
|
58884
|
+
const unlimited = current?.unlimited === true;
|
|
58705
58885
|
const cacheTtlLabel = !enabled || idleMs >= HOUR_MS ? "1h" : "5m";
|
|
58706
58886
|
let sourceLabel = `${current?.provider || "default"} default`;
|
|
58707
58887
|
if (current?.providerCustom) sourceLabel = `${current.provider} override`;
|
|
58708
58888
|
else if (current?.custom) sourceLabel = "global";
|
|
58889
|
+
const clearText = unlimited ? `Never clear idle sessions (${sourceLabel})` : `Clear idle sessions after ${formatDuration2(idleMs)} (${sourceLabel})`;
|
|
58709
58890
|
const items = [
|
|
58710
58891
|
{
|
|
58711
58892
|
value: "toggle",
|
|
58712
58893
|
label: "Auto-clear",
|
|
58713
58894
|
meta: enabled ? "On" : "Off",
|
|
58714
|
-
description: enabled ?
|
|
58895
|
+
description: enabled ? `${clearText} \xB7 lead cache TTL ${cacheTtlLabel}.` : "Idle auto-clear disabled.",
|
|
58715
58896
|
_action: "toggle"
|
|
58716
58897
|
},
|
|
58717
58898
|
{
|
|
@@ -58723,7 +58904,7 @@ function createAutoClearPicker({
|
|
|
58723
58904
|
];
|
|
58724
58905
|
own.paint({
|
|
58725
58906
|
title: "Auto-clear",
|
|
58726
|
-
description: `Clear idle context after ${enabled ? `${formatDuration2(idleMs)} (${sourceLabel})` : "never"} \xB7 lead cache TTL ${cacheTtlLabel}.`,
|
|
58907
|
+
description: `Clear idle context after ${enabled && !unlimited ? `${formatDuration2(idleMs)} (${sourceLabel})` : "never"} \xB7 lead cache TTL ${cacheTtlLabel}.`,
|
|
58727
58908
|
help: "\u2191/\u2193 Select \xB7 \u2190/\u2192 Toggle On/Off \xB7 Enter Open/Toggle \xB7 Esc Close",
|
|
58728
58909
|
indexMode: "always",
|
|
58729
58910
|
labelWidth: 10,
|
|
@@ -59386,6 +59567,15 @@ var loadProviderDisplayNames = async (store) => {
|
|
|
59386
59567
|
}
|
|
59387
59568
|
return names;
|
|
59388
59569
|
};
|
|
59570
|
+
var catalogProviderDisplayNames = (models, setupNames = null) => {
|
|
59571
|
+
const names = {};
|
|
59572
|
+
for (const model of Array.isArray(models) ? models : []) {
|
|
59573
|
+
const provider = String(model?.provider || "").trim();
|
|
59574
|
+
const name = String(model?.providerName || "").trim();
|
|
59575
|
+
if (provider.startsWith("custom-") && name) names[provider] = name;
|
|
59576
|
+
}
|
|
59577
|
+
return { ...names, ...setupNames };
|
|
59578
|
+
};
|
|
59389
59579
|
var loadProviderCatalogFailures = async (store) => {
|
|
59390
59580
|
let setup = null;
|
|
59391
59581
|
try {
|
|
@@ -59499,9 +59689,9 @@ var routeSpeedLabel = (route) => {
|
|
|
59499
59689
|
return route.modelParameters?.serviceTier === "ultrafast" ? "Ultrafast" : "Fast";
|
|
59500
59690
|
};
|
|
59501
59691
|
var routeModelDetails = (route) => [routeModelDisplayName(route), route.effort ? effortDisplayLabel(route.effort) : "", routeSpeedLabel(route)].filter(Boolean).join(" \xB7 ");
|
|
59502
|
-
var routeLabel = (route) => {
|
|
59692
|
+
var routeLabel = (route, providerNames = null) => {
|
|
59503
59693
|
if (!route?.provider || !route?.model) return "(unset)";
|
|
59504
|
-
return [
|
|
59694
|
+
return [resolveProviderDisplayName(route.provider, providerNames), routeModelDetails(route)].filter(Boolean).join(" \xB7 ");
|
|
59505
59695
|
};
|
|
59506
59696
|
var routeModelLabel = (route) => route?.model ? routeModelDetails(route) : "(unset)";
|
|
59507
59697
|
var agentModelProfile = (route) => route?.model ? routeModelDetails(route) : "";
|
|
@@ -59891,7 +60081,7 @@ function createOnboardingSteps({
|
|
|
59891
60081
|
import { spawn as spawn4 } from "node:child_process";
|
|
59892
60082
|
|
|
59893
60083
|
// src/runtime/shared/wsl.mjs
|
|
59894
|
-
import { readFileSync as
|
|
60084
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
59895
60085
|
var _isWSL;
|
|
59896
60086
|
function isWSL() {
|
|
59897
60087
|
if (_isWSL !== void 0) return _isWSL;
|
|
@@ -59904,7 +60094,7 @@ function isWSL() {
|
|
|
59904
60094
|
return _isWSL;
|
|
59905
60095
|
}
|
|
59906
60096
|
try {
|
|
59907
|
-
const v =
|
|
60097
|
+
const v = readFileSync9("/proc/version", "utf8").toLowerCase();
|
|
59908
60098
|
_isWSL = v.includes("microsoft") || v.includes("wsl");
|
|
59909
60099
|
} catch {
|
|
59910
60100
|
_isWSL = false;
|
|
@@ -60978,7 +61168,7 @@ function createModelPicker({
|
|
|
60978
61168
|
return;
|
|
60979
61169
|
}
|
|
60980
61170
|
const models = normalizeModelOptions(providerModels);
|
|
60981
|
-
const providerNames = await loadProviderDisplayNames(store);
|
|
61171
|
+
const providerNames = catalogProviderDisplayNames(models, await loadProviderDisplayNames(store));
|
|
60982
61172
|
const catalogFailures = await loadProviderCatalogFailures(store);
|
|
60983
61173
|
const activeRoute = options.currentRoute || {
|
|
60984
61174
|
provider: state.provider,
|
|
@@ -61406,7 +61596,8 @@ function createRoutePickers({
|
|
|
61406
61596
|
store.pushNotice("Web-search model save is already running.", "warn");
|
|
61407
61597
|
return;
|
|
61408
61598
|
}
|
|
61409
|
-
|
|
61599
|
+
const providerNames = await loadProviderDisplayNames(store);
|
|
61600
|
+
store.pushNotice(`Web-search model set to ${routeLabel2(result, providerNames)}`, "info");
|
|
61410
61601
|
return result;
|
|
61411
61602
|
},
|
|
61412
61603
|
onAfterSelect: null
|
|
@@ -61481,8 +61672,8 @@ function createSettingsNavigation({ openers, openSettingsPicker, setSettingsProm
|
|
|
61481
61672
|
}
|
|
61482
61673
|
|
|
61483
61674
|
// src/runtime/shared/config.mjs
|
|
61484
|
-
import { readFileSync as
|
|
61485
|
-
import { join as join12, dirname as
|
|
61675
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, watch as fsWatch } from "node:fs";
|
|
61676
|
+
import { basename as basename6, join as join12, dirname as dirname9 } from "node:path";
|
|
61486
61677
|
import { createRequire as createRequire3 } from "node:module";
|
|
61487
61678
|
|
|
61488
61679
|
// src/runtime/shared/object.mjs
|
|
@@ -61497,24 +61688,16 @@ function isPlainObject(value) {
|
|
|
61497
61688
|
init_atomic_file();
|
|
61498
61689
|
|
|
61499
61690
|
// src/runtime/shared/user-data-guard.mjs
|
|
61691
|
+
init_atomic_file();
|
|
61692
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync10, rmSync, statSync as statSync4 } from "node:fs";
|
|
61500
61693
|
import {
|
|
61501
|
-
copyFileSync,
|
|
61502
|
-
existsSync as existsSync10,
|
|
61503
|
-
mkdirSync as mkdirSync4,
|
|
61504
|
-
readdirSync as readdirSync2,
|
|
61505
|
-
readFileSync as readFileSync11,
|
|
61506
|
-
rmSync,
|
|
61507
|
-
statSync as statSync3,
|
|
61508
|
-
writeFileSync as writeFileSync4
|
|
61509
|
-
} from "node:fs";
|
|
61510
|
-
import {
|
|
61511
|
-
copyFile as copyFileP,
|
|
61512
61694
|
mkdir as mkdirP,
|
|
61695
|
+
readFile as readFileP,
|
|
61513
61696
|
readdir as readdirP,
|
|
61514
61697
|
rm as rmP,
|
|
61515
61698
|
stat as statP
|
|
61516
61699
|
} from "node:fs/promises";
|
|
61517
|
-
import { basename as basename5,
|
|
61700
|
+
import { basename as basename5, join as join11, resolve as resolve7 } from "node:path";
|
|
61518
61701
|
import { homedir as homedir3 } from "node:os";
|
|
61519
61702
|
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
61520
61703
|
function getBackupRoot() {
|
|
@@ -61601,12 +61784,24 @@ function safeReason(reason) {
|
|
|
61601
61784
|
}
|
|
61602
61785
|
function readInitInstanceId(dataDir2) {
|
|
61603
61786
|
if (!dataDir2) return null;
|
|
61787
|
+
const path2 = join11(dataDir2, INIT_MARKER);
|
|
61788
|
+
let raw;
|
|
61604
61789
|
try {
|
|
61605
|
-
|
|
61606
|
-
|
|
61607
|
-
|
|
61608
|
-
|
|
61790
|
+
raw = readFileSync10(path2, "utf8");
|
|
61791
|
+
} catch (error) {
|
|
61792
|
+
if (error?.code === "ENOENT") return null;
|
|
61793
|
+
throw error;
|
|
61794
|
+
}
|
|
61795
|
+
let marker;
|
|
61796
|
+
try {
|
|
61797
|
+
marker = JSON.parse(raw);
|
|
61798
|
+
} catch (error) {
|
|
61799
|
+
throw new SyntaxError(`[user-data] invalid initialization marker at ${path2}`, { cause: error });
|
|
61800
|
+
}
|
|
61801
|
+
if (typeof marker?.instanceId !== "string" || !marker.instanceId) {
|
|
61802
|
+
throw new SyntaxError(`[user-data] initialization marker at ${path2} must have a non-empty instanceId`);
|
|
61609
61803
|
}
|
|
61804
|
+
return marker.instanceId;
|
|
61610
61805
|
}
|
|
61611
61806
|
function hasUserDataInitMarker(dataDir2) {
|
|
61612
61807
|
return readInitInstanceId(dataDir2) != null;
|
|
@@ -61618,7 +61813,7 @@ function legacyBackupRoots() {
|
|
|
61618
61813
|
}
|
|
61619
61814
|
function manifestDataDirMatches(backupDir, dataDirKey) {
|
|
61620
61815
|
try {
|
|
61621
|
-
const manifest = JSON.parse(
|
|
61816
|
+
const manifest = JSON.parse(readFileSync10(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
61622
61817
|
return typeof manifest?.dataDir === "string" && normalizeDataDir(manifest.dataDir) === dataDirKey;
|
|
61623
61818
|
} catch {
|
|
61624
61819
|
return false;
|
|
@@ -61639,7 +61834,7 @@ function legacyMarkersFor(root, dataDir2, dataDirKey) {
|
|
|
61639
61834
|
return names.filter((name) => {
|
|
61640
61835
|
if (hashed.has(name)) return true;
|
|
61641
61836
|
try {
|
|
61642
|
-
const marker = JSON.parse(
|
|
61837
|
+
const marker = JSON.parse(readFileSync10(join11(root, name), "utf8"));
|
|
61643
61838
|
return typeof marker?.dataDir === "string" && normalizeDataDir(marker.dataDir) === dataDirKey;
|
|
61644
61839
|
} catch {
|
|
61645
61840
|
return false;
|
|
@@ -61700,10 +61895,10 @@ function backupDirsNewestFirst(dir) {
|
|
|
61700
61895
|
}
|
|
61701
61896
|
function readRestorableConfig(backupDir, dataDirKey, instanceId) {
|
|
61702
61897
|
try {
|
|
61703
|
-
const manifest = JSON.parse(
|
|
61898
|
+
const manifest = JSON.parse(readFileSync10(join11(backupDir, BACKUP_MANIFEST), "utf8"));
|
|
61704
61899
|
if (typeof manifest?.dataDir !== "string" || normalizeDataDir(manifest.dataDir) !== dataDirKey) return null;
|
|
61705
61900
|
if (manifest.instanceId !== instanceId) return null;
|
|
61706
|
-
const parsed = JSON.parse(
|
|
61901
|
+
const parsed = JSON.parse(readFileSync10(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61707
61902
|
return isStructurallyCompleteMixdogConfigBackup(parsed) ? parsed : null;
|
|
61708
61903
|
} catch (error) {
|
|
61709
61904
|
if (isAbsentBackupError(error)) return null;
|
|
@@ -61743,7 +61938,7 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61743
61938
|
const evidence = findLegacyUserDataEvidence(dataDir2, options);
|
|
61744
61939
|
for (const backupDir of evidence?.backups || []) {
|
|
61745
61940
|
try {
|
|
61746
|
-
const parsed = JSON.parse(
|
|
61941
|
+
const parsed = JSON.parse(readFileSync10(join11(backupDir, "mixdog-config.json"), "utf8"));
|
|
61747
61942
|
if (isStructurallyCompleteMixdogConfigBackup(parsed)) return parsed;
|
|
61748
61943
|
} catch {
|
|
61749
61944
|
}
|
|
@@ -61751,7 +61946,7 @@ function loadLegacyMixdogConfigFromBackup(dataDir2, options) {
|
|
|
61751
61946
|
return null;
|
|
61752
61947
|
}
|
|
61753
61948
|
function copyTree(src, dst, copied) {
|
|
61754
|
-
const st =
|
|
61949
|
+
const st = statSync4(src);
|
|
61755
61950
|
if (st.isDirectory()) {
|
|
61756
61951
|
for (const name of readdirSync2(src)) {
|
|
61757
61952
|
copyTree(join11(src, name), join11(dst, name), copied);
|
|
@@ -61759,12 +61954,19 @@ function copyTree(src, dst, copied) {
|
|
|
61759
61954
|
return;
|
|
61760
61955
|
}
|
|
61761
61956
|
if (!st.isFile()) return;
|
|
61762
|
-
|
|
61763
|
-
copyFileSync(src, dst);
|
|
61957
|
+
writeFileAtomicSync(dst, readFileSync10(src), { mode: st.mode & 511 });
|
|
61764
61958
|
copied.push(dst);
|
|
61765
61959
|
}
|
|
61960
|
+
var manifestPath = (scopeDir, name) => join11(scopeDir, name, BACKUP_MANIFEST);
|
|
61766
61961
|
function pruneBackups(scopeDir, names, own) {
|
|
61767
|
-
|
|
61962
|
+
const completed = names.filter((name) => {
|
|
61963
|
+
try {
|
|
61964
|
+
return statSync4(manifestPath(scopeDir, name)).isFile();
|
|
61965
|
+
} catch {
|
|
61966
|
+
return false;
|
|
61967
|
+
}
|
|
61968
|
+
});
|
|
61969
|
+
for (const name of backupsToPrune(completed, own)) {
|
|
61768
61970
|
try {
|
|
61769
61971
|
rmSync(join11(scopeDir, name), { recursive: true, force: true });
|
|
61770
61972
|
} catch {
|
|
@@ -61773,18 +61975,14 @@ function pruneBackups(scopeDir, names, own) {
|
|
|
61773
61975
|
}
|
|
61774
61976
|
function markUserDataInitialized(dataDir2) {
|
|
61775
61977
|
const existing = readInitInstanceId(dataDir2);
|
|
61776
|
-
if (existing || !dataDir2 || !
|
|
61978
|
+
if (existing || !dataDir2 || !existsSync9(dataDir2)) return existing;
|
|
61777
61979
|
try {
|
|
61778
|
-
|
|
61779
|
-
|
|
61780
|
-
|
|
61781
|
-
|
|
61782
|
-
|
|
61783
|
-
|
|
61784
|
-
)}
|
|
61785
|
-
`,
|
|
61786
|
-
// An unreadable marker is replaced; a concurrent creator's valid one wins.
|
|
61787
|
-
{ encoding: "utf8", flag: existsSync10(join11(dataDir2, INIT_MARKER)) ? "w" : "wx" }
|
|
61980
|
+
const marker = join11(dataDir2, INIT_MARKER);
|
|
61981
|
+
writeJsonAtomicSync(
|
|
61982
|
+
marker,
|
|
61983
|
+
{ instanceId: randomUUID(), dataDir: resolve7(dataDir2), createdAt: (/* @__PURE__ */ new Date()).toISOString() },
|
|
61984
|
+
// Another creator may have published since the absent read; it wins.
|
|
61985
|
+
{ createOnly: true }
|
|
61788
61986
|
);
|
|
61789
61987
|
} catch {
|
|
61790
61988
|
}
|
|
@@ -61795,43 +61993,47 @@ function ensureUserDataInitialized(dataDir2) {
|
|
|
61795
61993
|
if (!dataDir2) return;
|
|
61796
61994
|
const key = normalizeDataDir(dataDir2);
|
|
61797
61995
|
if (ensuredDataDirs.has(key)) return;
|
|
61798
|
-
ensuredDataDirs.add(key);
|
|
61799
61996
|
if (!hasUserDataInitMarker(dataDir2)) backupUserData(dataDir2, "initial-snapshot");
|
|
61997
|
+
ensuredDataDirs.add(key);
|
|
61800
61998
|
}
|
|
61801
61999
|
function skipBackups() {
|
|
61802
62000
|
return process.env.MIXDOG_SKIP_USER_DATA_BACKUP === "1" || process.env.MIXDOG_SKIP_USER_DATA_BACKUP === "true";
|
|
61803
62001
|
}
|
|
61804
62002
|
function finishBackup(dataDir2, backupDir, reason) {
|
|
61805
62003
|
const instanceId = markUserDataInitialized(dataDir2);
|
|
61806
|
-
|
|
61807
|
-
|
|
61808
|
-
|
|
61809
|
-
|
|
61810
|
-
|
|
61811
|
-
|
|
61812
|
-
)}
|
|
61813
|
-
`,
|
|
61814
|
-
"utf8"
|
|
61815
|
-
);
|
|
62004
|
+
writeJsonAtomicSync(join11(backupDir, BACKUP_MANIFEST), {
|
|
62005
|
+
dataDir: resolve7(dataDir2),
|
|
62006
|
+
instanceId,
|
|
62007
|
+
reason,
|
|
62008
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
62009
|
+
});
|
|
61816
62010
|
restoreLookupCache.delete(normalizeDataDir(dataDir2));
|
|
61817
62011
|
legacyEvidenceCache.delete(normalizeDataDir(dataDir2));
|
|
61818
62012
|
}
|
|
61819
62013
|
function backupUserData(dataDir2, reason = "snapshot", { dirs = [] } = {}) {
|
|
61820
62014
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61821
|
-
if (!dataDir2 || !
|
|
62015
|
+
if (!dataDir2 || !existsSync9(dataDir2)) return { dir: null, copied: [] };
|
|
61822
62016
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61823
62017
|
const { backupDir, names } = reserveBackupDir(scopeDir, reason);
|
|
61824
62018
|
const copied = [];
|
|
61825
|
-
|
|
61826
|
-
const
|
|
61827
|
-
|
|
61828
|
-
|
|
61829
|
-
|
|
61830
|
-
const
|
|
61831
|
-
|
|
62019
|
+
try {
|
|
62020
|
+
for (const rel of USER_DATA_FILES) {
|
|
62021
|
+
const src = join11(dataDir2, rel);
|
|
62022
|
+
if (existsSync9(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
62023
|
+
}
|
|
62024
|
+
for (const rel of [...USER_DATA_DIRS, ...dirs]) {
|
|
62025
|
+
const src = join11(dataDir2, rel);
|
|
62026
|
+
if (existsSync9(src)) copyTree(src, join11(backupDir, rel), copied);
|
|
62027
|
+
}
|
|
62028
|
+
if (copied.length > 0) finishBackup(dataDir2, backupDir, reason);
|
|
62029
|
+
} catch (error) {
|
|
62030
|
+
try {
|
|
62031
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
62032
|
+
} catch {
|
|
62033
|
+
}
|
|
62034
|
+
throw error;
|
|
61832
62035
|
}
|
|
61833
62036
|
if (copied.length > 0) {
|
|
61834
|
-
finishBackup(dataDir2, backupDir, reason);
|
|
61835
62037
|
pruneBackups(scopeDir, names, basename5(backupDir));
|
|
61836
62038
|
if (process.env.MIXDOG_SETUP_QUIET !== "1") {
|
|
61837
62039
|
process.stderr.write(`[user-data-backup] ${reason}: copied ${copied.length} file(s) to ${backupDir}
|
|
@@ -61851,12 +62053,18 @@ async function copyTreeAsync(src, dst, copied) {
|
|
|
61851
62053
|
return;
|
|
61852
62054
|
}
|
|
61853
62055
|
if (!st.isFile()) return;
|
|
61854
|
-
await
|
|
61855
|
-
await copyFileP(src, dst);
|
|
62056
|
+
await writeFileAtomicAsync(dst, await readFileP(src), { mode: st.mode & 511 });
|
|
61856
62057
|
copied.push(dst);
|
|
61857
62058
|
}
|
|
61858
62059
|
async function pruneBackupsAsync(scopeDir, names, own) {
|
|
61859
|
-
|
|
62060
|
+
const completed = [];
|
|
62061
|
+
for (const name of names) {
|
|
62062
|
+
try {
|
|
62063
|
+
if ((await statP(manifestPath(scopeDir, name))).isFile()) completed.push(name);
|
|
62064
|
+
} catch {
|
|
62065
|
+
}
|
|
62066
|
+
}
|
|
62067
|
+
for (const name of backupsToPrune(completed, own)) {
|
|
61860
62068
|
try {
|
|
61861
62069
|
await rmP(join11(scopeDir, name), { recursive: true, force: true });
|
|
61862
62070
|
} catch {
|
|
@@ -61865,20 +62073,28 @@ async function pruneBackupsAsync(scopeDir, names, own) {
|
|
|
61865
62073
|
}
|
|
61866
62074
|
async function backupUserDataAsync(dataDir2, reason = "snapshot") {
|
|
61867
62075
|
if (skipBackups()) return { dir: null, copied: [] };
|
|
61868
|
-
if (!dataDir2 || !
|
|
62076
|
+
if (!dataDir2 || !existsSync9(dataDir2)) return { dir: null, copied: [] };
|
|
61869
62077
|
const scopeDir = scopeDirFor(dataDir2);
|
|
61870
62078
|
const { backupDir, names } = await reserveBackupDirAsync(scopeDir, reason);
|
|
61871
62079
|
const copied = [];
|
|
61872
|
-
|
|
61873
|
-
const
|
|
61874
|
-
|
|
61875
|
-
|
|
61876
|
-
|
|
61877
|
-
const
|
|
61878
|
-
|
|
62080
|
+
try {
|
|
62081
|
+
for (const rel of USER_DATA_FILES) {
|
|
62082
|
+
const src = join11(dataDir2, rel);
|
|
62083
|
+
if (existsSync9(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
62084
|
+
}
|
|
62085
|
+
for (const rel of USER_DATA_DIRS) {
|
|
62086
|
+
const src = join11(dataDir2, rel);
|
|
62087
|
+
if (existsSync9(src)) await copyTreeAsync(src, join11(backupDir, rel), copied);
|
|
62088
|
+
}
|
|
62089
|
+
if (copied.length > 0) finishBackup(dataDir2, backupDir, reason);
|
|
62090
|
+
} catch (error) {
|
|
62091
|
+
try {
|
|
62092
|
+
await rmP(backupDir, { recursive: true, force: true });
|
|
62093
|
+
} catch {
|
|
62094
|
+
}
|
|
62095
|
+
throw error;
|
|
61879
62096
|
}
|
|
61880
62097
|
if (copied.length > 0) {
|
|
61881
|
-
finishBackup(dataDir2, backupDir, reason);
|
|
61882
62098
|
await pruneBackupsAsync(scopeDir, names, basename5(backupDir));
|
|
61883
62099
|
if (process.env.MIXDOG_SETUP_QUIET !== "1") {
|
|
61884
62100
|
process.stderr.write(`[user-data-backup] ${reason}: copied ${copied.length} file(s) to ${backupDir}
|
|
@@ -61950,7 +62166,7 @@ function readConfigRawCached() {
|
|
|
61950
62166
|
return _configReadCache.raw;
|
|
61951
62167
|
}
|
|
61952
62168
|
try {
|
|
61953
|
-
const st2 =
|
|
62169
|
+
const st2 = statSync5(configPath());
|
|
61954
62170
|
if (st2.mtimeMs === _configReadCache.mtimeMs && st2.size === _configReadCache.size) {
|
|
61955
62171
|
_configReadCache.atMs = now;
|
|
61956
62172
|
return _configReadCache.raw;
|
|
@@ -61960,7 +62176,7 @@ function readConfigRawCached() {
|
|
|
61960
62176
|
}
|
|
61961
62177
|
let st = null;
|
|
61962
62178
|
try {
|
|
61963
|
-
st =
|
|
62179
|
+
st = statSync5(configPath());
|
|
61964
62180
|
} catch (err) {
|
|
61965
62181
|
if (err.code === "ENOENT") {
|
|
61966
62182
|
_configReadCache = null;
|
|
@@ -61972,7 +62188,7 @@ function readConfigRawCached() {
|
|
|
61972
62188
|
}
|
|
61973
62189
|
let raw;
|
|
61974
62190
|
try {
|
|
61975
|
-
raw =
|
|
62191
|
+
raw = readFileSync11(configPath(), "utf8");
|
|
61976
62192
|
} catch (err) {
|
|
61977
62193
|
if (err.code === "ENOENT") {
|
|
61978
62194
|
_configReadCache = null;
|
|
@@ -62039,7 +62255,7 @@ function readConfigFile() {
|
|
|
62039
62255
|
const raw = readConfigRawCached();
|
|
62040
62256
|
if (raw == null) return null;
|
|
62041
62257
|
try {
|
|
62042
|
-
return
|
|
62258
|
+
return parseJsonText(raw);
|
|
62043
62259
|
} catch (err) {
|
|
62044
62260
|
invalidateConfigReadCache();
|
|
62045
62261
|
quarantineMalformedConfig(err);
|
|
@@ -62047,7 +62263,7 @@ function readConfigFile() {
|
|
|
62047
62263
|
}
|
|
62048
62264
|
}
|
|
62049
62265
|
function writeConfigFile(data, postBackupReason = "post-config-write") {
|
|
62050
|
-
mkdirSync5(
|
|
62266
|
+
mkdirSync5(dirname9(configPath()), { recursive: true, mode: 448 });
|
|
62051
62267
|
try {
|
|
62052
62268
|
backupUserData(resolvePluginData(), "pre-config-write");
|
|
62053
62269
|
} catch {
|
|
@@ -62071,7 +62287,7 @@ function persistRestoredConfig(restored) {
|
|
|
62071
62287
|
const wrote = withFileLockSync(
|
|
62072
62288
|
`${path2}.lock`,
|
|
62073
62289
|
() => {
|
|
62074
|
-
if (
|
|
62290
|
+
if (existsSync10(path2)) return false;
|
|
62075
62291
|
writeAll(restored, "post-restore");
|
|
62076
62292
|
return true;
|
|
62077
62293
|
},
|
|
@@ -62117,23 +62333,42 @@ function readAll() {
|
|
|
62117
62333
|
return {};
|
|
62118
62334
|
}
|
|
62119
62335
|
function quarantineMalformedConfig(parseErr) {
|
|
62120
|
-
const corrupt =
|
|
62336
|
+
const corrupt = quarantinePath(configPath());
|
|
62337
|
+
let keptAside = false;
|
|
62121
62338
|
try {
|
|
62122
|
-
if (
|
|
62339
|
+
if (existsSync10(configPath())) renameWithRetrySync(configPath(), corrupt);
|
|
62340
|
+
keptAside = existsSync10(corrupt);
|
|
62123
62341
|
} catch {
|
|
62124
62342
|
}
|
|
62125
62343
|
process.stderr.write(
|
|
62126
62344
|
`[config] mixdog-config.json is malformed (${parseErr.message}). Renamed to ${corrupt}. Restore it or delete to start fresh.
|
|
62127
62345
|
`
|
|
62128
62346
|
);
|
|
62347
|
+
return keptAside;
|
|
62129
62348
|
}
|
|
62130
|
-
function
|
|
62349
|
+
function hasQuarantinedCopy() {
|
|
62350
|
+
const dir = dirname9(configPath());
|
|
62351
|
+
const prefix = `${basename6(configPath())}.corrupt-`;
|
|
62352
|
+
try {
|
|
62353
|
+
return readdirSync3(dir).some((name) => name.startsWith(prefix));
|
|
62354
|
+
} catch {
|
|
62355
|
+
return false;
|
|
62356
|
+
}
|
|
62357
|
+
}
|
|
62358
|
+
function restoreAllForRmWOrThrow(reason, keptAside = false) {
|
|
62131
62359
|
const restored = loadLatestMixdogConfigFromBackup(resolvePluginData(), { fresh: true });
|
|
62132
62360
|
if (restored && isPlainObject(restored)) {
|
|
62133
62361
|
process.stderr.write(`[config] RMW read: restored mixdog-config.json from latest user-data backup (${reason})
|
|
62134
62362
|
`);
|
|
62135
62363
|
return restored;
|
|
62136
62364
|
}
|
|
62365
|
+
if (keptAside) {
|
|
62366
|
+
process.stderr.write(
|
|
62367
|
+
`[config] RMW read: mixdog-config.json is unusable (${reason}); its bytes are kept aside and no backup exists; starting empty
|
|
62368
|
+
`
|
|
62369
|
+
);
|
|
62370
|
+
return {};
|
|
62371
|
+
}
|
|
62137
62372
|
const legacy = findLegacyUserDataEvidence(resolvePluginData(), { fresh: true });
|
|
62138
62373
|
if (legacy) {
|
|
62139
62374
|
const err = new Error(
|
|
@@ -62149,11 +62384,11 @@ function restoreAllForRmWOrThrow(reason) {
|
|
|
62149
62384
|
function readAllForRmW() {
|
|
62150
62385
|
let raw;
|
|
62151
62386
|
try {
|
|
62152
|
-
raw =
|
|
62387
|
+
raw = readFileSync11(configPath(), "utf8");
|
|
62153
62388
|
} catch (err) {
|
|
62154
62389
|
if (err.code === "ENOENT") {
|
|
62155
62390
|
if (isUserDataRecoveryExpected(resolvePluginData(), { fresh: true })) {
|
|
62156
|
-
return restoreAllForRmWOrThrow("config file missing after user-data was initialized");
|
|
62391
|
+
return restoreAllForRmWOrThrow("config file missing after user-data was initialized", hasQuarantinedCopy());
|
|
62157
62392
|
}
|
|
62158
62393
|
return {};
|
|
62159
62394
|
}
|
|
@@ -62162,12 +62397,11 @@ function readAllForRmW() {
|
|
|
62162
62397
|
throw err;
|
|
62163
62398
|
}
|
|
62164
62399
|
try {
|
|
62165
|
-
const parsed =
|
|
62400
|
+
const parsed = parseJsonText(raw);
|
|
62166
62401
|
if (!isPlainObject(parsed)) throw new SyntaxError("config root must be a JSON object");
|
|
62167
62402
|
return parsed;
|
|
62168
62403
|
} catch (parseErr) {
|
|
62169
|
-
quarantineMalformedConfig(parseErr);
|
|
62170
|
-
return restoreAllForRmWOrThrow(parseErr.message);
|
|
62404
|
+
return restoreAllForRmWOrThrow(parseErr.message, quarantineMalformedConfig(parseErr));
|
|
62171
62405
|
}
|
|
62172
62406
|
}
|
|
62173
62407
|
var CONFIG_CHANGE_DEBOUNCE_MS = 100;
|
|
@@ -62196,7 +62430,7 @@ function readSection(section) {
|
|
|
62196
62430
|
return stripGeneratedMarker(readAll()[section] ?? null) ?? {};
|
|
62197
62431
|
}
|
|
62198
62432
|
async function writeConfigFileAsync(data) {
|
|
62199
|
-
mkdirSync5(
|
|
62433
|
+
mkdirSync5(dirname9(configPath()), { recursive: true, mode: 448 });
|
|
62200
62434
|
try {
|
|
62201
62435
|
await backupUserDataAsync(resolvePluginData(), "pre-config-write");
|
|
62202
62436
|
} catch {
|
|
@@ -62517,8 +62751,8 @@ function buildSettingsItems({
|
|
|
62517
62751
|
{
|
|
62518
62752
|
value: "autoclear",
|
|
62519
62753
|
label: "Auto-clear",
|
|
62520
|
-
meta: autoClearEnabled ? `On (${formatDuration2(autoClear.idleMs)})` : "Off",
|
|
62521
|
-
description: autoClearEnabled ? `Clear idle sessions after ${formatDuration2(autoClear.idleMs)}${autoClearSource}. Enter for options.` : "Idle auto-clear disabled. Enter for options.",
|
|
62754
|
+
meta: autoClearEnabled ? `On (${autoClear.unlimited ? "Unlimited" : formatDuration2(autoClear.idleMs)})` : "Off",
|
|
62755
|
+
description: autoClearEnabled ? `${autoClear.unlimited ? "Never clear idle sessions" : `Clear idle sessions after ${formatDuration2(autoClear.idleMs)}`}${autoClearSource}. Enter for options.` : "Idle auto-clear disabled. Enter for options.",
|
|
62522
62756
|
_action: "autoclear"
|
|
62523
62757
|
},
|
|
62524
62758
|
{
|
|
@@ -63773,7 +64007,9 @@ function useMessageSelector({
|
|
|
63773
64007
|
setPromptDraftOverride,
|
|
63774
64008
|
syncPromptLayoutRows,
|
|
63775
64009
|
showPromptHint,
|
|
63776
|
-
clearPromptHint
|
|
64010
|
+
clearPromptHint,
|
|
64011
|
+
installPastedImages,
|
|
64012
|
+
installPastedTexts
|
|
63777
64013
|
}) {
|
|
63778
64014
|
const hasUserMessages = useMemo7(
|
|
63779
64015
|
() => (Array.isArray(state.items) ? state.items : []).some(
|
|
@@ -63789,11 +64025,21 @@ function useMessageSelector({
|
|
|
63789
64025
|
return false;
|
|
63790
64026
|
}
|
|
63791
64027
|
clearPromptHint();
|
|
64028
|
+
if (restored.pastedImages) installPastedImages?.(restored.pastedImages, { merge: true });
|
|
64029
|
+
if (restored.pastedTexts) installPastedTexts?.(restored.pastedTexts, { merge: true });
|
|
63792
64030
|
syncPromptLayoutRows(text);
|
|
63793
64031
|
setPromptDraftOverride({ id: Date.now(), value: text });
|
|
64032
|
+
if (restored.notice) showPromptHint(restored.notice, "error");
|
|
63794
64033
|
return true;
|
|
63795
64034
|
},
|
|
63796
|
-
[
|
|
64035
|
+
[
|
|
64036
|
+
clearPromptHint,
|
|
64037
|
+
syncPromptLayoutRows,
|
|
64038
|
+
setPromptDraftOverride,
|
|
64039
|
+
showPromptHint,
|
|
64040
|
+
installPastedImages,
|
|
64041
|
+
installPastedTexts
|
|
64042
|
+
]
|
|
63797
64043
|
);
|
|
63798
64044
|
const openMessageSelector = useCallback20(() => {
|
|
63799
64045
|
const items = store.getState?.().items ?? state.items;
|
|
@@ -63813,7 +64059,7 @@ function useMessageSelector({
|
|
|
63813
64059
|
own.close();
|
|
63814
64060
|
let restored;
|
|
63815
64061
|
try {
|
|
63816
|
-
restored = store.rewindToItem?.(value);
|
|
64062
|
+
restored = store.rewindToItem?.(value, { restoreFiles: false });
|
|
63817
64063
|
} catch (error) {
|
|
63818
64064
|
showPromptHint(`rewind failed: ${error?.message || error}`, "error");
|
|
63819
64065
|
return;
|
|
@@ -63907,13 +64153,13 @@ import { useCallback as useCallback21, useEffect as useEffect27, useLayoutEffect
|
|
|
63907
64153
|
|
|
63908
64154
|
// src/tui/session/transcript-spill.mjs
|
|
63909
64155
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
63910
|
-
import { readFileSync as
|
|
64156
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
63911
64157
|
import { join as join16 } from "node:path";
|
|
63912
64158
|
import { Worker as Worker2 } from "node:worker_threads";
|
|
63913
64159
|
|
|
63914
64160
|
// src/tui/session/transcript-spill/spill-dir.mjs
|
|
63915
64161
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
63916
|
-
import { mkdtempSync, readdirSync as
|
|
64162
|
+
import { mkdtempSync, readdirSync as readdirSync6, readFileSync as readFileSync14, rmSync as rmSync5, statSync as statSync7, writeFileSync as writeFileSync4 } from "node:fs";
|
|
63917
64163
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
63918
64164
|
import { join as join15 } from "node:path";
|
|
63919
64165
|
var STALE_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -65724,7 +65970,9 @@ function App2({ store, initialStatusLine = "", forceOnboarding = false, onboardi
|
|
|
65724
65970
|
setPromptDraftOverride,
|
|
65725
65971
|
syncPromptLayoutRows,
|
|
65726
65972
|
showPromptHint,
|
|
65727
|
-
clearPromptHint
|
|
65973
|
+
clearPromptHint,
|
|
65974
|
+
installPastedImages,
|
|
65975
|
+
installPastedTexts
|
|
65728
65976
|
});
|
|
65729
65977
|
const { handlePromptPaste, handlePromptHistoryNavigate, handlePromptEscape, handlePromptInterrupt } = usePromptHandlers({
|
|
65730
65978
|
store,
|
|
@@ -66364,16 +66612,16 @@ function drainStdin(stdin = process.stdin) {
|
|
|
66364
66612
|
let fd = -1;
|
|
66365
66613
|
try {
|
|
66366
66614
|
if (!wasRaw) tty3.setRawMode?.(true);
|
|
66367
|
-
fd =
|
|
66615
|
+
fd = openSync4("/dev/tty", fsConstants.O_RDONLY | fsConstants.O_NONBLOCK);
|
|
66368
66616
|
const buf = Buffer.alloc(1024);
|
|
66369
66617
|
for (let i = 0; i < 64; i++) {
|
|
66370
|
-
if (
|
|
66618
|
+
if (readSync2(fd, buf, 0, buf.length, null) <= 0) break;
|
|
66371
66619
|
}
|
|
66372
66620
|
} catch {
|
|
66373
66621
|
} finally {
|
|
66374
66622
|
if (fd >= 0) {
|
|
66375
66623
|
try {
|
|
66376
|
-
|
|
66624
|
+
closeSync4(fd);
|
|
66377
66625
|
} catch {
|
|
66378
66626
|
}
|
|
66379
66627
|
}
|
|
@@ -66391,7 +66639,7 @@ function installTuiStderrGuard() {
|
|
|
66391
66639
|
const originalWrite = process.stderr.write.bind(process.stderr);
|
|
66392
66640
|
const logPath = resolveTuiStderrLogPath();
|
|
66393
66641
|
try {
|
|
66394
|
-
mkdirSync8(
|
|
66642
|
+
mkdirSync8(dirname11(logPath), { recursive: true });
|
|
66395
66643
|
} catch {
|
|
66396
66644
|
}
|
|
66397
66645
|
(0, import_mixdog_debug.rotateBoundedLog)(logPath, import_mixdog_debug.PLUGIN_LOG_MAX_BYTES, import_mixdog_debug.PLUGIN_LOG_KEEP_BYTES);
|