mixdog 1.1.2 → 1.2.1
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 -5
- package/package.json +2 -1
- package/scripts/lib/run-node-tests.mjs +9 -0
- package/scripts/prune-desktop-runtime.mjs +3 -0
- package/scripts/test-direct.mjs +4 -2
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +18 -5
- package/src/defaults/skills/visualize/SKILL.md +160 -0
- package/src/defaults/skills/visualize/references/craft.md +88 -0
- package/src/headless-command.mjs +56 -3
- package/src/headless-exec.mjs +17 -1
- package/src/help.mjs +2 -0
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +2 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +17 -11
- package/src/runtime/agent/orchestrator/config-storage.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -5
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +133 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +55 -8
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +86 -8
- package/src/runtime/agent/orchestrator/mcp/client.mjs +474 -164
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/mcp/reconnect-singleflight.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +108 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +444 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +21 -6
- package/src/runtime/agent/orchestrator/providers/effort-rejection.mjs +244 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +41 -28
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +8 -40
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +51 -12
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +37 -2
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +82 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +556 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +251 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth-tokens.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +69 -102
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +15 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +47 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +10 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +36 -3
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -11
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +16 -1
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +278 -84
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -3
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +268 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +24 -13
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +362 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +253 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/diagnostic.mjs +1 -7
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/refusal.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +9 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +37 -16
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +17 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +123 -0
- package/src/runtime/agent/orchestrator/session/message-ids.test-support.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +33 -22
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +10 -3
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +817 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +23 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +202 -374
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +48 -9
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +52 -2
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +32 -22
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-cache-policy.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +203 -33
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +32 -35
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +11 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +9 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +83 -68
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +8 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +20 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +16 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +137 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +11 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +21 -11
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +56 -13
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +58 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +25 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +78 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/attachments/store.mjs +38 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/shared/atomic-file.mjs +33 -6
- package/src/runtime/shared/best-effort-stderr.mjs +8 -0
- package/src/runtime/shared/code-graph-state.mjs +12 -0
- package/src/runtime/shared/defaults-separation.mjs +2 -0
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/git-runner-worker.mjs +3 -2
- package/src/runtime/shared/git-runner.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +14 -0
- package/src/runtime/shared/llm/default-context-window.mjs +6 -0
- package/src/runtime/shared/llm/model-catalog-projection.mjs +5 -4
- package/src/runtime/shared/llm/model-catalog.mjs +240 -130
- package/src/runtime/shared/llm/provider-catalog-cache.mjs +36 -28
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +162 -0
- package/src/runtime/shared/llm/provider-seed-rosters.mjs +130 -0
- package/src/runtime/shared/model-proxy-mode.d.mts +3 -0
- package/src/runtime/shared/model-proxy-mode.mjs +19 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +125 -21
- package/src/runtime/shared/provider-api-key.mjs +33 -1
- package/src/runtime/shared/schedule-model-ref.mjs +11 -2
- package/src/runtime/shared/session-usage-totals.mjs +19 -0
- package/src/runtime/shared/sharp-electron-linux.mjs +25 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/singleton-owner.mjs +36 -6
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +68 -14
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/tool-surface.mjs +7 -0
- package/src/runtime/shared/tool-work-units.mjs +14 -0
- package/src/runtime/shared/transcript-metadata.mjs +17 -1
- package/src/runtime/shared/turn-changes.mjs +791 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +346 -12
- package/src/runtime/shared/turn-snapshot.mjs +690 -81
- package/src/runtime/shared/turn-worktree-snapshot.mjs +185 -15
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/cache-cleanups.mjs +52 -0
- package/src/runtime/shared/worktrees/contract.mjs +551 -0
- package/src/runtime/shared/worktrees/disk.mjs +57 -0
- package/src/runtime/shared/worktrees/git.mjs +247 -0
- package/src/runtime/shared/worktrees/include.mjs +480 -0
- package/src/runtime/shared/worktrees/lock.mjs +46 -0
- package/src/runtime/shared/worktrees/maintenance.mjs +96 -0
- package/src/runtime/shared/worktrees/manager.mjs +1215 -0
- package/src/runtime/shared/worktrees/merge.mjs +182 -0
- package/src/runtime/shared/worktrees/owner.mjs +46 -0
- package/src/runtime/shared/worktrees/paths.mjs +62 -0
- package/src/runtime/shared/worktrees/registry.mjs +110 -0
- package/src/runtime/shared/worktrees/settings.mjs +84 -0
- package/src/runtime/shared/worktrees/slug.mjs +62 -0
- package/src/runtime/shared/worktrees/test-support.mjs +96 -0
- package/src/runtime/visualize-bridge/client.mjs +181 -0
- package/src/runtime/visualize-bridge/tool-defs.mjs +97 -0
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +90 -0
- package/src/session-runtime/boot/config.mjs +7 -2
- package/src/session-runtime/boot/facade.mjs +21 -0
- package/src/session-runtime/boot/infrastructure.mjs +30 -18
- package/src/session-runtime/boot/session.mjs +1 -0
- package/src/session-runtime/boot/tools.mjs +4 -0
- package/src/session-runtime/config-lifecycle.mjs +10 -1
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +21 -6
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/global-extensions.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +27 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +32 -1
- package/src/session-runtime/internal-tool-executor.mjs +9 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +8 -1
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +5 -0
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +21 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +16 -0
- package/src/session-runtime/mcp-glue/connect.mjs +68 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +122 -33
- package/src/session-runtime/mcp-glue/server-input.mjs +29 -0
- package/src/session-runtime/mcp-glue.mjs +22 -2
- package/src/session-runtime/model-route/route-persist.mjs +3 -0
- package/src/session-runtime/model-route/set-route.mjs +15 -2
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +18 -3
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/row-hydration.mjs +2 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- package/src/session-runtime/resource-extension-sync.mjs +45 -7
- package/src/session-runtime/resource-mcp-api.mjs +121 -84
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/route-resolution.mjs +10 -1
- package/src/session-runtime/route-state.mjs +16 -2
- package/src/session-runtime/runtime-core.mjs +5 -0
- package/src/session-runtime/runtime-facade.mjs +8 -0
- package/src/session-runtime/runtime-review-api.mjs +9 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +5 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +3 -0
- package/src/session-runtime/services/agent-tool/job-views/job-lookup.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/spawn-meta.mjs +1 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +15 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +1 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -7
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +2 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -0
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +1 -0
- package/src/session-runtime/services/agent-tool.mjs +1 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/daemon-candidate.mjs +3 -2
- package/src/session-runtime/services/daemon-crash-capture/spawn-capture.mjs +55 -0
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/session-create/session-options.mjs +10 -1
- package/src/session-runtime/session-turn-api.mjs +1 -0
- package/src/session-runtime/settings-api.mjs +4 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -2
- package/src/session-runtime/settings-worktree-api.mjs +17 -0
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +38 -4
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/agent-ops.mjs +12 -1
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +14 -3
- package/src/session-runtime/turn/turn-run/snapshot-tracker.mjs +20 -15
- package/src/session-runtime/turn/turn-run/turn-open.mjs +4 -5
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +29 -1
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +6 -1
- package/src/session-runtime/turn/turn-run.mjs +6 -7
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -3
- package/src/session-runtime/workspace/admission-gate.mjs +197 -0
- package/src/session-runtime/workspace/project-branches.mjs +136 -0
- package/src/session-runtime/workspace/transition-steps.mjs +364 -0
- package/src/session-runtime/workspace/transitions.mjs +651 -0
- package/src/session-runtime/workspace/workspace-state.mjs +112 -0
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/channel-transport/http-routes.mjs +17 -0
- package/src/standalone/channel-transport.mjs +13 -1
- package/src/standalone/daemon-desktop-runtime.mjs +1 -0
- package/src/standalone/daemon-owner.mjs +372 -0
- package/src/standalone/daemon-stored-session-views.mjs +15 -4
- package/src/standalone/daemon.mjs +179 -8
- package/src/standalone/desktop-service-registry.mjs +20 -0
- package/src/standalone/local-session-runtime.mjs +11 -0
- package/src/standalone/session-client/attachment-calls.mjs +3 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +62 -0
- package/src/standalone/session-client/lease-heartbeat.mjs +47 -0
- package/src/standalone/session-client.mjs +104 -13
- package/src/standalone/session-protocol.mjs +21 -0
- package/src/standalone/session-proxy.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-rehydrate.mjs +1 -0
- package/src/standalone/session-service/entries/lifecycle.mjs +6 -0
- package/src/standalone/session-service/projection/revisions.mjs +2 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +149 -19
- package/src/standalone/session-service/projection/workspace.mjs +14 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +17 -4
- package/src/standalone/session-transport/call-route.mjs +13 -0
- package/src/standalone/session-transport/client-registry/client-grace.mjs +45 -3
- package/src/standalone/session-transport/client-registry/registration-replays.mjs +1 -0
- package/src/standalone/session-transport/client-registry.mjs +20 -3
- package/src/standalone/session-transport/routes.mjs +79 -2
- package/src/standalone/session-transport/stack.mjs +2 -0
- package/src/standalone/session-transport.mjs +24 -1
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +6 -0
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/message-selector.mjs +2 -1
- package/src/tui/app/model-options.mjs +37 -5
- package/src/tui/app/model-picker/provider-models-list.mjs +2 -2
- package/src/tui/app/model-picker.mjs +4 -2
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +839 -207
- package/src/tui/index.jsx +10 -2
- package/src/tui/session/compaction-view.mjs +147 -0
- package/src/tui/session/context-state.mjs +6 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +2 -1
- package/src/tui/session/session-api/commands.mjs +10 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +4 -2
- package/src/tui/session/session-api/intake/rewind.mjs +2 -1
- package/src/tui/session/session-api/integrations.mjs +17 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +6 -1
- package/src/tui/session/session-api/lifecycle/inheritance.mjs +2 -0
- package/src/tui/session/session-api/lifecycle/resume.mjs +3 -0
- package/src/tui/session/session-api/routes.mjs +10 -1
- package/src/tui/session/session-api/settings.mjs +9 -0
- package/src/tui/session/session-api/worktree.mjs +60 -0
- package/src/tui/session/session-api.mjs +2 -0
- package/src/tui/session/session-flow/auto-clear.mjs +31 -12
- package/src/tui/session/session-flow/drain.mjs +27 -3
- package/src/tui/session/session-flow/session-reset.mjs +4 -3
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/transcript-intake.mjs +14 -5
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn-stream.mjs +32 -4
- package/src/tui/session/turn-tool-cards.mjs +10 -2
- package/src/tui/session/turn.mjs +56 -10
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
|
@@ -47,7 +47,7 @@ export async function prepareCodexBatch({ patchStr, requestedFormat, basePath, p
|
|
|
47
47
|
let v4aRenamePlan = null;
|
|
48
48
|
if (isV4APatchInput(patchStr, requestedFormat)) {
|
|
49
49
|
try {
|
|
50
|
-
const parsedSections = preParsedV4ASections || rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath);
|
|
50
|
+
const parsedSections = preParsedV4ASections || (await rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath));
|
|
51
51
|
const allSections = coalesceCompatibleV4ASections(parsedSections, basePath);
|
|
52
52
|
v4aRenamePlan = await planV4ARenameSections(allSections, basePath);
|
|
53
53
|
inputPatchStr = await convertV4ASectionsToUnifiedPatch(v4aRenamePlan.remainingSections, basePath, v4aConvertOpts);
|
|
@@ -56,7 +56,7 @@ export async function prepareCodexBatch({ patchStr, requestedFormat, basePath, p
|
|
|
56
56
|
}
|
|
57
57
|
} else if (requestedFormat !== 'unified' && hasUnifiedBareV4AHunk(patchStr)) {
|
|
58
58
|
try {
|
|
59
|
-
const sections = rewriteV4AReadRedirects(parseUnifiedBareV4APatch(patchStr), basePath);
|
|
59
|
+
const sections = await rewriteV4AReadRedirects(parseUnifiedBareV4APatch(patchStr), basePath);
|
|
60
60
|
inputPatchStr = await convertV4ASectionsToUnifiedPatch(sections, basePath, v4aConvertOpts);
|
|
61
61
|
} catch (err) {
|
|
62
62
|
throw new Error(`apply_patch: bare @@ parse failed — ${err?.message || String(err)}`);
|
|
@@ -82,7 +82,7 @@ export async function prepareCodexBatch({ patchStr, requestedFormat, basePath, p
|
|
|
82
82
|
);
|
|
83
83
|
}
|
|
84
84
|
try {
|
|
85
|
-
const sections = rewriteV4AReadRedirects(parseUnifiedCountedAsV4APatch(patchStr), basePath);
|
|
85
|
+
const sections = await rewriteV4AReadRedirects(parseUnifiedCountedAsV4APatch(patchStr), basePath);
|
|
86
86
|
inputPatchStr = await convertV4ASectionsToUnifiedPatch(sections, basePath, v4aConvertOpts);
|
|
87
87
|
parsed = parsePatch(prepareInput(inputPatchStr));
|
|
88
88
|
} catch (fallbackErr) {
|
|
@@ -91,7 +91,7 @@ export async function prepareCodexBatch({ patchStr, requestedFormat, basePath, p
|
|
|
91
91
|
);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
|
-
parsed = rewriteParsedReadRedirects(parsed, basePath);
|
|
94
|
+
parsed = await rewriteParsedReadRedirects(parsed, basePath);
|
|
95
95
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
96
96
|
return { error: 'Error: patch contained no file sections' };
|
|
97
97
|
}
|
|
@@ -7,11 +7,11 @@ import { pathKey, resolveV4AEntryPath } from '../paths.mjs';
|
|
|
7
7
|
import { rewriteV4AReadRedirects } from '../read-redirects.mjs';
|
|
8
8
|
import { isV4ARenameSection } from '../v4a-convert.mjs';
|
|
9
9
|
|
|
10
|
-
export function selectApplyPatchRoute({ args, patchStr, requestedFormat, basePath }) {
|
|
10
|
+
export async function selectApplyPatchRoute({ args, patchStr, requestedFormat, basePath }) {
|
|
11
11
|
let preParsedV4ASections = null;
|
|
12
12
|
if (isV4APatchInput(patchStr, requestedFormat)) {
|
|
13
13
|
try {
|
|
14
|
-
preParsedV4ASections = rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath);
|
|
14
|
+
preParsedV4ASections = await rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath);
|
|
15
15
|
} catch {
|
|
16
16
|
// The selected execution path reports the authoritative parse error.
|
|
17
17
|
}
|
|
@@ -34,7 +34,7 @@ async function apply_patch(rawArgs, cwd, options = {}) {
|
|
|
34
34
|
}
|
|
35
35
|
const rejectedV4AHunks = [];
|
|
36
36
|
const v4aConvertOpts = { rejectPartial, rejectedHunks: rejectedV4AHunks, fuzzy, dryRun, readStateScope };
|
|
37
|
-
const route = selectApplyPatchRoute({ args, patchStr, requestedFormat, basePath });
|
|
37
|
+
const route = await selectApplyPatchRoute({ args, patchStr, requestedFormat, basePath });
|
|
38
38
|
if (route.useSequence) {
|
|
39
39
|
const seqOut = await applyPatchSequence(patchStr, requestedFormat, basePath, {
|
|
40
40
|
v4aConvertOpts,
|
|
@@ -6,7 +6,7 @@ import { resolve as pathResolve, relative as pathRelative, isAbsolute } from 'no
|
|
|
6
6
|
import { findBySuffixStrip, findFileByBasename } from '../builtin/path-diagnostics.mjs';
|
|
7
7
|
import { resolveEntryPath, resolveV4AEntryPath, classifyEntry, pathKey } from './paths.mjs';
|
|
8
8
|
|
|
9
|
-
function uniqueExistingPatchTarget(basePath, requestedFullPath) {
|
|
9
|
+
async function uniqueExistingPatchTarget(basePath, requestedFullPath) {
|
|
10
10
|
// Auto-relocation is only valid for a missing target lexically inside the
|
|
11
11
|
// patch root. An explicit outside-root path must never be pulled back into
|
|
12
12
|
// the project merely because a basename happens to match.
|
|
@@ -23,14 +23,14 @@ function uniqueExistingPatchTarget(basePath, requestedFullPath) {
|
|
|
23
23
|
};
|
|
24
24
|
const suffix = asFile(findBySuffixStrip(basePath, requestedFullPath));
|
|
25
25
|
if (suffix) return suffix;
|
|
26
|
-
const basenameHits = findFileByBasename(basePath, requestedFullPath, { limit: 2 });
|
|
26
|
+
const basenameHits = await findFileByBasename(basePath, requestedFullPath, { limit: 2 });
|
|
27
27
|
return basenameHits.length === 1 ? asFile(basenameHits[0]) : null;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function redirectedPatchPath(requestedFullPath, basePath) {
|
|
30
|
+
async function redirectedPatchPath(requestedFullPath, basePath) {
|
|
31
31
|
// An existing requested path always wins over relocation.
|
|
32
32
|
if (!requestedFullPath || existsSync(requestedFullPath)) return requestedFullPath;
|
|
33
|
-
return uniqueExistingPatchTarget(basePath, requestedFullPath) || requestedFullPath;
|
|
33
|
+
return (await uniqueExistingPatchTarget(basePath, requestedFullPath)) || requestedFullPath;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function patchHeaderPathForResolved(basePath, fullPath) {
|
|
@@ -41,33 +41,37 @@ export function patchHeaderPathForResolved(basePath, fullPath) {
|
|
|
41
41
|
return fullPath;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export function rewriteV4AReadRedirects(sections, basePath) {
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
export async function rewriteV4AReadRedirects(sections, basePath) {
|
|
45
|
+
return Promise.all(
|
|
46
|
+
(sections || []).map(async (section) => {
|
|
47
|
+
if (!section || section.kind === 'add' || !section.path) return section;
|
|
48
|
+
const requested = resolveV4AEntryPath(basePath, section.path);
|
|
49
|
+
const redirected = await redirectedPatchPath(requested, basePath);
|
|
50
|
+
if (pathKey(redirected) === pathKey(requested)) return section;
|
|
51
|
+
return { ...section, path: patchHeaderPathForResolved(basePath, redirected) };
|
|
52
|
+
})
|
|
53
|
+
);
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
export function rewriteParsedReadRedirects(parsed, basePath) {
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
56
|
+
export async function rewriteParsedReadRedirects(parsed, basePath) {
|
|
57
|
+
return Promise.all(
|
|
58
|
+
(parsed || []).map(async (entry) => {
|
|
59
|
+
const kind = classifyEntry(entry);
|
|
60
|
+
if (kind === 'create' || !entry?.oldFileName) return entry;
|
|
61
|
+
const requested = resolveEntryPath(basePath, entry.oldFileName);
|
|
62
|
+
const redirected = await redirectedPatchPath(requested, basePath);
|
|
63
|
+
if (pathKey(redirected) === pathKey(requested)) return entry;
|
|
64
|
+
const rewritten = {
|
|
65
|
+
...entry,
|
|
66
|
+
oldFileName: patchHeaderPathForResolved(basePath, redirected),
|
|
67
|
+
};
|
|
68
|
+
if (kind === 'modify' && entry.newFileName) {
|
|
69
|
+
const newRequested = resolveEntryPath(basePath, entry.newFileName);
|
|
70
|
+
if (pathKey(newRequested) === pathKey(requested)) {
|
|
71
|
+
rewritten.newFileName = rewritten.oldFileName;
|
|
72
|
+
}
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
return rewritten;
|
|
75
|
+
})
|
|
76
|
+
);
|
|
73
77
|
}
|
|
@@ -84,10 +84,10 @@ function parsedEntryUnit(entry, basePath) {
|
|
|
84
84
|
// Parse the patch body into V4A-style sections (V4A envelope, bare-@@ hunks,
|
|
85
85
|
// or counted-unified salvaged as V4A), or into parsed unified entries for a
|
|
86
86
|
// plain unified diff.
|
|
87
|
-
function parsePatchSections(patchStr, requestedFormat, basePath, { coalesceByFile }) {
|
|
87
|
+
async function parsePatchSections(patchStr, requestedFormat, basePath, { coalesceByFile }) {
|
|
88
88
|
if (isV4APatchInput(patchStr, requestedFormat)) {
|
|
89
89
|
try {
|
|
90
|
-
const parsedSections = rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath);
|
|
90
|
+
const parsedSections = await rewriteV4AReadRedirects(parseV4APatch(patchStr), basePath);
|
|
91
91
|
return { sections: coalesceByFile ? coalesceCompatibleV4ASections(parsedSections, basePath) : parsedSections };
|
|
92
92
|
} catch (err) {
|
|
93
93
|
throw new Error(`apply_patch: V4A parse failed — ${err?.message || String(err)}`);
|
|
@@ -98,7 +98,7 @@ function parsePatchSections(patchStr, requestedFormat, basePath, { coalesceByFil
|
|
|
98
98
|
// section's conversion into its own unit (ordered-stop preserved) rather
|
|
99
99
|
// than converting the whole patch up front.
|
|
100
100
|
try {
|
|
101
|
-
return { sections: rewriteV4AReadRedirects(parseUnifiedBareV4APatch(patchStr), basePath) };
|
|
101
|
+
return { sections: await rewriteV4AReadRedirects(parseUnifiedBareV4APatch(patchStr), basePath) };
|
|
102
102
|
} catch (err) {
|
|
103
103
|
throw new Error(`apply_patch: bare @@ parse failed — ${err?.message || String(err)}`);
|
|
104
104
|
}
|
|
@@ -116,18 +116,18 @@ function parsePatchSections(patchStr, requestedFormat, basePath, { coalesceByFil
|
|
|
116
116
|
// V4A-style sections and defer per-section conversion — same ordered-stop
|
|
117
117
|
// guarantee as the V4A path (no whole-patch up-front convert).
|
|
118
118
|
try {
|
|
119
|
-
return { sections: rewriteV4AReadRedirects(parseUnifiedCountedAsV4APatch(patchStr), basePath) };
|
|
119
|
+
return { sections: await rewriteV4AReadRedirects(parseUnifiedCountedAsV4APatch(patchStr), basePath) };
|
|
120
120
|
} catch (fallbackErr) {
|
|
121
121
|
throw new Error(
|
|
122
122
|
`apply_patch: parse failed — ${err?.message || String(err)}; V4A fallback failed — ${fallbackErr?.message || String(fallbackErr)}`
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
return { parsed: rewriteParsedReadRedirects(parsed, basePath) };
|
|
126
|
+
return { parsed: await rewriteParsedReadRedirects(parsed, basePath) };
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
export function buildPatchUnits(patchStr, requestedFormat, basePath, ctx) {
|
|
130
|
-
const { sections, parsed } = parsePatchSections(patchStr, requestedFormat, basePath, ctx);
|
|
129
|
+
export async function buildPatchUnits(patchStr, requestedFormat, basePath, ctx) {
|
|
130
|
+
const { sections, parsed } = await parsePatchSections(patchStr, requestedFormat, basePath, ctx);
|
|
131
131
|
if (sections) return sections.map((section) => sectionUnit(section, basePath, ctx));
|
|
132
132
|
return (parsed || []).map((entry) => parsedEntryUnit(entry, basePath));
|
|
133
133
|
}
|
|
@@ -30,7 +30,7 @@ export async function applyPatchSequence(patchStr, requestedFormat, basePath, ct
|
|
|
30
30
|
coalesceByFile = false,
|
|
31
31
|
} = ctx;
|
|
32
32
|
|
|
33
|
-
const units = buildPatchUnits(patchStr, requestedFormat, basePath, {
|
|
33
|
+
const units = await buildPatchUnits(patchStr, requestedFormat, basePath, {
|
|
34
34
|
v4aConvertOpts,
|
|
35
35
|
dryRun,
|
|
36
36
|
readStateScope,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// UI-diff side channel: a committed apply_patch (or edit-tool write) records
|
|
2
2
|
// a turn-review change entry and a per-call diff the desktop/TUI tool cards
|
|
3
3
|
// pick up. Display only — never affects edit semantics.
|
|
4
|
+
import { createTwoFilesPatch } from 'diff';
|
|
4
5
|
import { boundReviewPatch } from '../../../../shared/review-diff.mjs';
|
|
5
6
|
import { recordTurnDiffChanges } from '../../../../shared/turn-snapshot.mjs';
|
|
6
7
|
import { pathKey, resolveV4AEntryPath } from './paths.mjs';
|
|
@@ -29,6 +30,77 @@ export function takeApplyPatchUiDiff(callId) {
|
|
|
29
30
|
return value;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
// A display path is a plain relative or absolute path; the patch header only
|
|
34
|
+
// needs forward slashes. Its own leading "a/" is part of the name.
|
|
35
|
+
function headerPath(value) {
|
|
36
|
+
return String(value || '')
|
|
37
|
+
.trim()
|
|
38
|
+
.replace(/\\/g, '/');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const DIFF_TIMEOUT_MS = 100;
|
|
42
|
+
|
|
43
|
+
const utf8 = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
44
|
+
|
|
45
|
+
function isOmitted(value) {
|
|
46
|
+
return Boolean(value) && typeof value === 'object' && !(value instanceof Uint8Array) && value.omitted === true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Text of one side: '' for an absent file, null when it is not UTF-8 text.
|
|
50
|
+
function sideText(value) {
|
|
51
|
+
if (value == null) return '';
|
|
52
|
+
if (typeof value === 'string') return value;
|
|
53
|
+
if (value instanceof Uint8Array) {
|
|
54
|
+
try {
|
|
55
|
+
return utf8.decode(value);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// One file's change, from the call's own before and after states: absent
|
|
64
|
+
// (null), bytes or text, or an omitted marker when the bytes were not kept.
|
|
65
|
+
function renderCallChange({ displayPath, newDisplayPath, before, after }) {
|
|
66
|
+
const oldName = headerPath(displayPath) || 'unknown file';
|
|
67
|
+
const newName = headerPath(newDisplayPath) || oldName;
|
|
68
|
+
const oldHeader = before == null ? '/dev/null' : `a/${oldName}`;
|
|
69
|
+
const newHeader = after == null ? '/dev/null' : `b/${newName}`;
|
|
70
|
+
let head = `diff --git a/${oldName} b/${newName}\n`;
|
|
71
|
+
if (before == null && after != null) head += 'new file mode 100644\n';
|
|
72
|
+
else if (before != null && after == null) head += 'deleted file mode 100644\n';
|
|
73
|
+
if (isOmitted(before) || isOmitted(after)) {
|
|
74
|
+
return `${head}Binary files ${oldHeader} and ${newHeader} differ\n`;
|
|
75
|
+
}
|
|
76
|
+
const oldText = sideText(before);
|
|
77
|
+
const newText = sideText(after);
|
|
78
|
+
if (oldText === null || newText === null) return `${head}Binary files ${oldHeader} and ${newHeader} differ\n`;
|
|
79
|
+
if (oldText === newText) {
|
|
80
|
+
// An empty file created or deleted still changed: git writes the mode line alone.
|
|
81
|
+
if ((before == null) !== (after == null)) return head;
|
|
82
|
+
return oldName === newName ? '' : `${head}similarity index 100%\nrename from ${oldName}\nrename to ${newName}\n`;
|
|
83
|
+
}
|
|
84
|
+
const rename = oldName === newName ? '' : `rename from ${oldName}\nrename to ${newName}\n`;
|
|
85
|
+
try {
|
|
86
|
+
const generated = createTwoFilesPatch(oldHeader, newHeader, oldText, newText, '', '', {
|
|
87
|
+
context: 3,
|
|
88
|
+
timeout: DIFF_TIMEOUT_MS,
|
|
89
|
+
});
|
|
90
|
+
const start = generated.search(/^--- /m);
|
|
91
|
+
if (start >= 0) return `${head}${rename}${generated.slice(start).replace(/\n*$/, '\n')}`;
|
|
92
|
+
} catch {
|
|
93
|
+
// A pathological diff timing out must not stall tool completion.
|
|
94
|
+
}
|
|
95
|
+
return `${head}${rename}Binary files ${oldHeader} and ${newHeader} differ\n`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// A call's card shows the change that call made — its own before against its
|
|
99
|
+
// own after — never the turn's running total for the same files.
|
|
100
|
+
export function callUiDiff(changes) {
|
|
101
|
+
return (changes || []).map(renderCallChange).join('');
|
|
102
|
+
}
|
|
103
|
+
|
|
32
104
|
// Edit-tool UI diff: a successful single-file str-replace edit records the
|
|
33
105
|
// same turn-review change entry and per-call UI diff side channel that a
|
|
34
106
|
// committed apply_patch gets, so desktop/TUI tool cards render both edit
|
|
@@ -36,15 +108,16 @@ export function takeApplyPatchUiDiff(callId) {
|
|
|
36
108
|
export function registerEditToolUiDiff({ callId, sessionId, basePath, fullPath, before, after }) {
|
|
37
109
|
if (!callId || !sessionId || typeof fullPath !== 'string') return;
|
|
38
110
|
try {
|
|
39
|
-
const
|
|
111
|
+
const changes = [
|
|
40
112
|
{
|
|
41
113
|
path: fullPath,
|
|
42
114
|
displayPath: patchHeaderPathForResolved(basePath || '', fullPath),
|
|
43
115
|
before: before ?? null,
|
|
44
116
|
after: after ?? null,
|
|
45
117
|
},
|
|
46
|
-
]
|
|
47
|
-
|
|
118
|
+
];
|
|
119
|
+
recordTurnDiffChanges(sessionId, changes);
|
|
120
|
+
registerApplyPatchUiDiff(callId, callUiDiff(changes));
|
|
48
121
|
} catch {
|
|
49
122
|
// best-effort display channel
|
|
50
123
|
}
|
|
@@ -111,8 +184,8 @@ export function registerCommittedPatchUiDiff({
|
|
|
111
184
|
after: snapshotContent(after),
|
|
112
185
|
});
|
|
113
186
|
}
|
|
114
|
-
|
|
115
|
-
registerApplyPatchUiDiff(callId,
|
|
187
|
+
recordTurnDiffChanges(sessionId, changes);
|
|
188
|
+
registerApplyPatchUiDiff(callId, callUiDiff(changes));
|
|
116
189
|
} catch {
|
|
117
190
|
// Review collection is a side channel and must never affect committed
|
|
118
191
|
// apply_patch success/failure semantics.
|
|
@@ -75,6 +75,8 @@ export function formatToolStartProgress(name, args = {}) {
|
|
|
75
75
|
}
|
|
76
76
|
case 'terminal':
|
|
77
77
|
return a.action === 'read' ? `reading terminal${a.tab ? ` ${_t(a.tab)}` : ''}` : 'listing terminals';
|
|
78
|
+
case 'visualize':
|
|
79
|
+
return `visualize ${_t(a.action || 'command')}`;
|
|
78
80
|
case 'office':
|
|
79
81
|
return a.path ? `office ${_t(a.action || 'command')} ${_t(a.path)}` : `office ${_t(a.action || 'command')}`;
|
|
80
82
|
case 'media': {
|
|
@@ -18,6 +18,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
18
18
|
import { getPluginData } from '../config.mjs';
|
|
19
19
|
import { scrubLoaderVars, scrubProviderSecrets, scrubRuntimeRootVars } from './env-scrub.mjs';
|
|
20
20
|
import { spawnShellWithRetry } from './lib/shell-spawn-retry.mjs';
|
|
21
|
+
import { ensureSkillLauncherDir } from '../../../shared/skill-script-runtime.mjs';
|
|
21
22
|
|
|
22
23
|
const SNAPSHOT_TIMEOUT_MS = 10_000;
|
|
23
24
|
|
|
@@ -146,6 +147,9 @@ echo "# Shell options" >> "$SNAPSHOT_FILE"
|
|
|
146
147
|
${optDump}
|
|
147
148
|
echo "# Aliases" >> "$SNAPSHOT_FILE"
|
|
148
149
|
${aliasDump}
|
|
150
|
+
# The sourced PATH replaces the model shell's own, so it carries the
|
|
151
|
+
# skill-launcher entry buildShellSpawnEnv prepends (mixdog-skill-node).
|
|
152
|
+
PATH=${_shellQuote(ensureSkillLauncherDir())}:"$PATH"
|
|
149
153
|
# PATH may contain $, backticks, or quotes that would re-expand if we
|
|
150
154
|
# emitted it inside double quotes. Emit a shell-safe single-quoted PATH
|
|
151
155
|
# export line via printf %q-style escaping inside the dump shell.
|
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { createHash, randomBytes } from 'node:crypto';
|
|
10
10
|
import {
|
|
11
|
+
closeSync,
|
|
11
12
|
existsSync,
|
|
13
|
+
fstatSync,
|
|
12
14
|
mkdirSync,
|
|
15
|
+
openSync,
|
|
13
16
|
readFileSync,
|
|
17
|
+
readSync,
|
|
14
18
|
renameSync,
|
|
15
19
|
statSync,
|
|
16
20
|
unlinkSync,
|
|
@@ -303,6 +307,40 @@ function readAttachmentText(value) {
|
|
|
303
307
|
return readAttachmentBuffer(value).toString('utf8');
|
|
304
308
|
}
|
|
305
309
|
|
|
310
|
+
/**
|
|
311
|
+
* A referenced blob's UTF-8 text when the blob on disk holds at most
|
|
312
|
+
* `maxBytes`, else null. The size comes from the opened file, never from the
|
|
313
|
+
* reference's claimed sizeBytes, and at most `maxBytes + 1` bytes are read, so
|
|
314
|
+
* a blob that grows between the check and the read is rejected too. Missing,
|
|
315
|
+
* invalid or tampered blobs throw like readAttachmentBuffer.
|
|
316
|
+
*/
|
|
317
|
+
export function readAttachmentTextWithin(value, maxBytes) {
|
|
318
|
+
const ref = typeof value === 'string' ? value : value?.attachmentRef;
|
|
319
|
+
const fd = openSync(attachmentPath(ref), 'r');
|
|
320
|
+
try {
|
|
321
|
+
const info = fstatSync(fd);
|
|
322
|
+
if (!info.isFile() || info.size <= 0) {
|
|
323
|
+
throw Object.assign(new Error('prompt attachment blob is invalid'), { code: ATTACHMENT_INVALID });
|
|
324
|
+
}
|
|
325
|
+
if (info.size > maxBytes) return null;
|
|
326
|
+
const buffer = Buffer.alloc(info.size + 1);
|
|
327
|
+
let length = 0;
|
|
328
|
+
while (length < buffer.length) {
|
|
329
|
+
const read = readSync(fd, buffer, length, buffer.length - length, length);
|
|
330
|
+
if (read === 0) break;
|
|
331
|
+
length += read;
|
|
332
|
+
}
|
|
333
|
+
if (length > maxBytes) return null;
|
|
334
|
+
const bytes = buffer.subarray(0, length);
|
|
335
|
+
if (attachmentRefForBuffer(bytes) !== ref) {
|
|
336
|
+
throw Object.assign(new Error('prompt attachment integrity check failed'), { code: ATTACHMENT_INTEGRITY });
|
|
337
|
+
}
|
|
338
|
+
return bytes.toString('utf8');
|
|
339
|
+
} finally {
|
|
340
|
+
closeSync(fd);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
306
344
|
export function attachmentTextForPart(part) {
|
|
307
345
|
if (!isAttachmentReference(part)) return typeof part?.text === 'string' ? part.text : '';
|
|
308
346
|
const text = readAttachmentText(part);
|
|
@@ -97,7 +97,7 @@ export function createOwnedStarter({
|
|
|
97
97
|
state.automationRunning = true;
|
|
98
98
|
}
|
|
99
99
|
// DEGRADED MODE: a messaging connect failure — packaged runtime without
|
|
100
|
-
//
|
|
100
|
+
// the provider library, bad token, gateway outage — must not take schedules/webhooks
|
|
101
101
|
// down with it. Sends stay dead (connected=false) but session runs, the
|
|
102
102
|
// webhook server and the relay tunnel keep working.
|
|
103
103
|
async function degradeToAutomation() {
|
|
@@ -27,6 +27,14 @@ ${payload}
|
|
|
27
27
|
<<<${_UNTRUSTED}_END>>>`;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/** The run's model-visible prompt (endpoint instructions + fenced external
|
|
31
|
+
* payload) and its trusted skill-selection input: the endpoint-authored
|
|
32
|
+
* instructions alone, so nothing in the payload or headers selects a skill. */
|
|
33
|
+
function webhookRunPrompt(instructions, body, headers) {
|
|
34
|
+
const trusted = String(instructions ?? '');
|
|
35
|
+
return { prompt: `${trusted}\n\n${buildFencedPayload(body, headers)}`, skillSelection: trusted };
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
function trackDispatch({ name, deliveryId, dispatchP, controller }) {
|
|
31
39
|
let settled = false;
|
|
32
40
|
const timeoutHandle = setTimeout(
|
|
@@ -89,6 +97,10 @@ function createWebhookSessionDispatcher({ getConfig, getBridgeDispatch }) {
|
|
|
89
97
|
workflow: extra.workflow || null,
|
|
90
98
|
attachments: extra.attachments || null,
|
|
91
99
|
delivery: extra.delivery || null,
|
|
100
|
+
// Trusted skill-selection input: only the endpoint-authored
|
|
101
|
+
// instructions, never the fenced external body/headers that share
|
|
102
|
+
// the model-visible prompt.
|
|
103
|
+
skillSelection: String(extra.skillSelection ?? ''),
|
|
92
104
|
context: {
|
|
93
105
|
source: 'webhook',
|
|
94
106
|
endpoint: name,
|
|
@@ -105,14 +117,14 @@ function createWebhookSessionDispatcher({ getConfig, getBridgeDispatch }) {
|
|
|
105
117
|
async function dispatchEndpoint({ name, body, headers, res, deliveryId, endpoint }) {
|
|
106
118
|
try {
|
|
107
119
|
const { model, instructions, cwd, workflow, attachments, delivery } = endpoint;
|
|
108
|
-
const
|
|
120
|
+
const run = webhookRunPrompt(instructions, body, headers);
|
|
109
121
|
if (!getBridgeDispatch()) throw new Error(`[webhook] session dispatch requires bridgeDispatch`);
|
|
110
|
-
|
|
111
|
-
await dispatchSessionRun(name, model || null, fullPrompt, headers, deliveryId, res, {
|
|
122
|
+
await dispatchSessionRun(name, model || null, run.prompt, headers, deliveryId, res, {
|
|
112
123
|
cwd: cwd || null,
|
|
113
124
|
workflow: workflow || null,
|
|
114
125
|
attachments: attachments || null,
|
|
115
126
|
delivery: delivery || null,
|
|
127
|
+
skillSelection: run.skillSelection,
|
|
116
128
|
});
|
|
117
129
|
return true;
|
|
118
130
|
} catch (err) {
|
|
@@ -125,4 +137,4 @@ function createWebhookSessionDispatcher({ getConfig, getBridgeDispatch }) {
|
|
|
125
137
|
return { dispatchEndpoint };
|
|
126
138
|
}
|
|
127
139
|
|
|
128
|
-
export { buildFencedPayload, createWebhookSessionDispatcher };
|
|
140
|
+
export { buildFencedPayload, createWebhookSessionDispatcher, webhookRunPrompt };
|
|
@@ -218,20 +218,23 @@ function wireWebhookHandlers() {
|
|
|
218
218
|
webhookServer.setEventPipeline(eventPipeline);
|
|
219
219
|
// Webhook fires run as sessions (schedules parity); the Automations
|
|
220
220
|
// session row is the only surface (channel relay retired).
|
|
221
|
-
webhookServer.setBridgeDispatch(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
221
|
+
webhookServer.setBridgeDispatch(
|
|
222
|
+
async ({ prompt, skillSelection, model, cwd, workflow, attachments, context, signal }) => {
|
|
223
|
+
const { runWebhookSession } = await import('../../../session-runtime/webhook-session-run.mjs');
|
|
224
|
+
const run = await runWebhookSession({
|
|
225
|
+
name: context?.endpoint || 'webhook',
|
|
226
|
+
model: model || null,
|
|
227
|
+
cwd: cwd || null,
|
|
228
|
+
workflow: workflow || null,
|
|
229
|
+
attachments: attachments || null,
|
|
230
|
+
// Dispatch-timeout cancellation only works if the signal reaches the run.
|
|
231
|
+
signal: signal || null,
|
|
232
|
+
prompt,
|
|
233
|
+
skillSelection,
|
|
234
|
+
});
|
|
235
|
+
return run;
|
|
236
|
+
}
|
|
237
|
+
);
|
|
235
238
|
}
|
|
236
239
|
function wireEventQueueHandlers(eventQueue) {
|
|
237
240
|
if (!eventQueue) return;
|
|
@@ -17,8 +17,6 @@ export const INPUT_GROUP_SECURITY_NOTE =
|
|
|
17
17
|
export const GNOME_EXTENSION_UUID = 'mixdog-windows@mixdog.io';
|
|
18
18
|
/** The oldest helper interface this app can use (2 added Screenshot and StopRequested, 3 the in-shell indicator). */
|
|
19
19
|
export const MIN_WINDOW_HELPER_VERSION = 3;
|
|
20
|
-
export const WINDOW_CONTROL_HINT =
|
|
21
|
-
'wayland_window_control_unavailable: this compositor offers no window control to other programs; on GNOME the Mixdog Windows extension (mixdog-windows@mixdog.io) provides it and must be enabled and loaded';
|
|
22
20
|
export const WINDOW_HELPER_RELOGIN_HINT =
|
|
23
21
|
'wayland_window_control_unavailable: the Mixdog Windows GNOME extension is installed and enabled but GNOME Shell has not loaded it yet; the user must sign out and sign in again once';
|
|
24
22
|
export const WINDOW_HELPER_ENABLE_HINT =
|
|
@@ -20,12 +20,19 @@ const MODEL_FILES = ['model.onnx', 'tokenizer.json'];
|
|
|
20
20
|
// The worker runs one judgment at a time, so requests are sent one by one:
|
|
21
21
|
// each answer's deadline starts when it is sent, and the wait for earlier
|
|
22
22
|
// requests is bounded separately so a burst of turns queues instead of
|
|
23
|
-
// timing out behind each other.
|
|
23
|
+
// timing out behind each other. The next request is sent only once the worker
|
|
24
|
+
// has answered the previous one: an answer that missed its deadline still
|
|
25
|
+
// occupies the worker, and sending into it would start the next deadline
|
|
26
|
+
// while the worker is busy, failing it too.
|
|
27
|
+
// 500 ms covers the 18-layer judge's tail while parallel agents share the CPU.
|
|
24
28
|
// MIXDOG_EFFORT_JUDGE_TIMEOUT_MS raises it on a host whose CPUs are shared
|
|
25
29
|
// with heavy work (parallel benchmark containers).
|
|
26
30
|
const WARM_TIMEOUT_MS =
|
|
27
|
-
Number(process.env.MIXDOG_EFFORT_JUDGE_TIMEOUT_MS) > 0 ? Number(process.env.MIXDOG_EFFORT_JUDGE_TIMEOUT_MS) :
|
|
31
|
+
Number(process.env.MIXDOG_EFFORT_JUDGE_TIMEOUT_MS) > 0 ? Number(process.env.MIXDOG_EFFORT_JUDGE_TIMEOUT_MS) : 500;
|
|
28
32
|
const QUEUE_WAIT_MS = 1000;
|
|
33
|
+
// A worker that has not answered for this long is stuck; it is replaced so
|
|
34
|
+
// the queue does not stay blocked behind it.
|
|
35
|
+
const STUCK_MS = 10_000;
|
|
29
36
|
let queueTail = Promise.resolve();
|
|
30
37
|
// A turn that arrives while the judge is still loading (its first use, or the
|
|
31
38
|
// first turn after a model update) waits at most this long; loading takes about 2 s on a desktop CPU.
|
|
@@ -107,7 +114,7 @@ function settle(id, fn) {
|
|
|
107
114
|
const entry = pending.get(id);
|
|
108
115
|
if (!entry) return;
|
|
109
116
|
pending.delete(id);
|
|
110
|
-
|
|
117
|
+
entry.done();
|
|
111
118
|
fn(entry);
|
|
112
119
|
}
|
|
113
120
|
|
|
@@ -151,11 +158,27 @@ function ensureWorker(dir) {
|
|
|
151
158
|
return created;
|
|
152
159
|
}
|
|
153
160
|
|
|
161
|
+
// `answer` settles with the probabilities or fails at the deadline; `done`
|
|
162
|
+
// resolves once the worker has answered (or exited), when it can take the next request.
|
|
154
163
|
function request(target, { request: text, prev, prevRequest, step }) {
|
|
155
164
|
const id = ++msgId;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
let finish;
|
|
166
|
+
const done = new Promise((resolve) => {
|
|
167
|
+
finish = resolve;
|
|
168
|
+
});
|
|
169
|
+
const answer = new Promise((resolve, reject) => {
|
|
170
|
+
const timer = setTimeout(() => reject(new Error('timeout')), WARM_TIMEOUT_MS);
|
|
171
|
+
const stuck = setTimeout(() => void target.terminate().catch(() => {}), STUCK_MS);
|
|
172
|
+
stuck.unref();
|
|
173
|
+
pending.set(id, {
|
|
174
|
+
resolve,
|
|
175
|
+
reject,
|
|
176
|
+
done: () => {
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
clearTimeout(stuck);
|
|
179
|
+
finish();
|
|
180
|
+
},
|
|
181
|
+
});
|
|
159
182
|
// The worker formats the text the way its model was trained.
|
|
160
183
|
target.postMessage({
|
|
161
184
|
action: 'judge',
|
|
@@ -169,6 +192,9 @@ function request(target, { request: text, prev, prevRequest, step }) {
|
|
|
169
192
|
...(step ? { step } : {}),
|
|
170
193
|
});
|
|
171
194
|
});
|
|
195
|
+
// A caller that gave up while queued never reads its answer.
|
|
196
|
+
answer.catch(() => {});
|
|
197
|
+
return { answer, done };
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
// One install at a time (the settings install and the boot refresh can overlap).
|
|
@@ -257,19 +283,31 @@ export async function judgeTurn(input) {
|
|
|
257
283
|
if (!ready && !(await waitReady(COLD_WAIT_MS))) {
|
|
258
284
|
return { skipped: lastLoadError ? `load-error: ${lastLoadError}` : 'warming' };
|
|
259
285
|
}
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
try {
|
|
266
|
-
return { probs: await request(target, input), ms: Date.now() - startedAt };
|
|
267
|
-
} catch (error) {
|
|
268
|
-
return { skipped: String(error?.message || error) };
|
|
269
|
-
}
|
|
286
|
+
let abandoned = false;
|
|
287
|
+
const turn = queueTail.then(() => {
|
|
288
|
+
if (abandoned) return null;
|
|
289
|
+
if (worker !== target || !ready) return { exited: true };
|
|
290
|
+
return { startedAt: Date.now(), ...request(target, input) };
|
|
270
291
|
});
|
|
271
|
-
queueTail =
|
|
272
|
-
|
|
292
|
+
queueTail = turn.then((sent) => sent?.done);
|
|
293
|
+
let timer;
|
|
294
|
+
const sent = await Promise.race([
|
|
295
|
+
turn,
|
|
296
|
+
new Promise((resolve) => {
|
|
297
|
+
timer = setTimeout(resolve, QUEUE_WAIT_MS, null);
|
|
298
|
+
}),
|
|
299
|
+
]);
|
|
300
|
+
clearTimeout(timer);
|
|
301
|
+
if (!sent) {
|
|
302
|
+
abandoned = true;
|
|
303
|
+
return { skipped: 'busy' };
|
|
304
|
+
}
|
|
305
|
+
if (sent.exited) return { skipped: 'effort judge exited' };
|
|
306
|
+
try {
|
|
307
|
+
return { probs: await sent.answer, ms: Date.now() - sent.startedAt };
|
|
308
|
+
} catch (error) {
|
|
309
|
+
return { skipped: String(error?.message || error) };
|
|
310
|
+
}
|
|
273
311
|
}
|
|
274
312
|
|
|
275
313
|
// MIXDOG_EFFORT_DECISIONS_LOG redirects the log, e.g. for benchmark runs whose
|
|
@@ -161,7 +161,7 @@ async function _migrateRecallIndexesIfStale(db) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// One-time cleanup: attachment-only placeholder rows ('(attachment)' user
|
|
164
|
-
// content
|
|
164
|
+
// content from the former channel provider) predate the
|
|
165
165
|
// shouldExcludeIngestMessage() ingest-time filter (session-ingest.mjs).
|
|
166
166
|
// Delete any already-persisted rows so they stop polluting recall/cycle1.
|
|
167
167
|
// Idempotent (no-op once cleaned); best-effort so a failure never blocks boot.
|