mixdog 1.3.5 → 1.4.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/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
package/NOTICE.md
CHANGED
|
@@ -186,9 +186,9 @@ attributions.
|
|
|
186
186
|
|
|
187
187
|
The connector brand marks in
|
|
188
188
|
`apps/desktop/src/renderer/connectors-brand-icons.ts` carry Simple Icons path
|
|
189
|
-
data and brand colours unmodified (Airtable, Blender, Confluence,
|
|
189
|
+
data and brand colours unmodified (Airtable, Blender, Confluence,
|
|
190
190
|
Dropbox, Figma, GitHub, Gmail, Google Calendar, Google Drive, Hugging Face,
|
|
191
|
-
Jira, Linear, Notion, PostgreSQL, Sentry, Stripe, Supabase,
|
|
191
|
+
Jira, Linear, Notion, PostgreSQL, Sentry, Stripe, Supabase, Trello,
|
|
192
192
|
Unity, Vercel); Unity's mark is drawn in black, as its listed colour is white.
|
|
193
193
|
Simple Icons is dedicated to the public domain under CC0 1.0; each
|
|
194
194
|
mark remains the trademark of its owner and is shown only to name that
|
package/README.md
CHANGED
|
@@ -177,8 +177,8 @@ you tokens, a star helps others find it.
|
|
|
177
177
|
|
|
178
178
|
## Sponsor
|
|
179
179
|
|
|
180
|
-
Mixdog is free and
|
|
181
|
-
|
|
180
|
+
Mixdog is free and open source. Sponsorship pays for development time and the
|
|
181
|
+
model tokens used for testing:
|
|
182
182
|
[github.com/sponsors/JYP8877](https://github.com/sponsors/JYP8877).
|
|
183
183
|
|
|
184
184
|
### Supporters
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixdog",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Open-source coding agent that matches Codex on Terminal-Bench 2.1 with 63% fewer tokens.",
|
|
@@ -71,8 +71,6 @@
|
|
|
71
71
|
"smoke:all": "npm run smoke && npm run smoke:boot && npm run smoke:patch && npm run smoke:compact",
|
|
72
72
|
"smoke:boot": "node scripts/boot-smoke.mjs",
|
|
73
73
|
"smoke:compact": "node scripts/compact-smoke.mjs",
|
|
74
|
-
"test:compact": "node scripts/test-direct.mjs scripts/suite-compact-test.mjs src/runtime/agent/orchestrator/session/compact-fresh-context.test.mjs src/runtime/agent/orchestrator/session/compaction-read-reset.test.mjs src/runtime/agent/orchestrator/session/token-estimate.test.mjs",
|
|
75
|
-
"test:markdown": "node scripts/test-direct.mjs scripts/markdown-surface-test.mjs",
|
|
76
74
|
"smoke:loop": "node scripts/smoke-loop.mjs",
|
|
77
75
|
"smoke:loop:final": "node scripts/smoke-loop-report.mjs --require-complete --min-elapsed 5h --min-iterations 400 --max-gap 60s --max-smoke-ms 10000 --max-avg-smoke-ms 8500 --max-step-ms smoke.mjs=4000 --max-step-ms boot-smoke.mjs=8000 --max-rss-mb 140 --max-rss-growth-mb 50",
|
|
78
76
|
"smoke:loop:report": "node scripts/smoke-loop-report.mjs",
|
|
@@ -87,18 +85,12 @@
|
|
|
87
85
|
"test:release-critical": "npm run test:release-assets && npm run smoke:patch && npm run test:providers",
|
|
88
86
|
"test:spec-advisory": "node scripts/run-advisory-spec.mjs && npm run test:spec-advisory --prefix apps/desktop",
|
|
89
87
|
"test:session-transport": "node scripts/test-direct.mjs \"scripts/session-transport/*.test.mjs\" scripts/daemon-bootstrap-test.mjs src/standalone/session-runtime-inline-host.test.mjs",
|
|
90
|
-
"test:session": "node scripts/test-direct.mjs scripts/runtime-turn-contract-test.mjs scripts/session-save-fault-store.slow.test.mjs scripts/turn-review-revert.slow.test.mjs src/runtime/shared/tool-surface.test.mjs src/runtime/bridge-clients.test.mjs src/runtime/browser-bridge/action-schema.test.mjs src/runtime/computer-bridge/client-semantic-error.test.mjs src/runtime/agent/orchestrator/session/tool-envelope.test.mjs src/runtime/agent/orchestrator/session/eager-dispatch.test.mjs",
|
|
91
|
-
"test:quick": "npm run test:session && npm run test:session-transport && npm run test:desktop-main --prefix apps/desktop",
|
|
92
88
|
"test:office": "node scripts/test-direct.mjs scripts/run-office-live-tests.test.mjs src/runtime/office/office-runtime-contract.test.mjs src/runtime/office/office-runtime-com.test.mjs src/runtime/office/office-runtime-portable.slow.test.mjs src/runtime/office/xlsx-formula-audit.test.mjs src/runtime/office/xlsx-portable-snapshot.test.mjs src/runtime/office/office-runtime-pdf.slow.test.mjs src/runtime/office/office-runtime-design.test.mjs src/runtime/office/office-assurance.slow.test.mjs src/runtime/office/office-design-aesthetics.test.mjs src/runtime/office/portable-authoring.slow.test.mjs src/runtime/office/slide-quality.test.mjs src/runtime/office/authoring/pptx-brief.test.mjs src/runtime/office/authoring/pptx-receipt.test.mjs src/runtime/office/quality/render-air.test.mjs src/runtime/office/quality/pptx-deck-rubric.test.mjs && npm run test:office-approval --prefix apps/desktop",
|
|
93
89
|
"test:office:live": "node scripts/run-office-live-tests.mjs",
|
|
94
|
-
"test:office:preview": "node scripts/test-direct.mjs src/runtime/office/office-render-preview.test.mjs",
|
|
95
|
-
"test:office:review": "node scripts/test-direct.mjs src/runtime/office/pptx-independent-review.test.mjs src/runtime/office/pptx-chart-styling.test.mjs",
|
|
96
|
-
"test:office:cleanup": "node scripts/test-direct.mjs src/runtime/office/com/office-cleanup.test.mjs src/runtime/office/office-runtime-com.test.mjs",
|
|
97
90
|
"test:office:compat": "node scripts/run-office-live-tests.mjs compat",
|
|
98
91
|
"test:office:live:all": "node scripts/run-office-live-tests.mjs all",
|
|
99
92
|
"test:office:render": "node scripts/test-direct.mjs src/runtime/office/pptx-skill-kit.slow.test.mjs",
|
|
100
93
|
"office:icons": "node scripts/office/build-pptx-icons.mjs",
|
|
101
|
-
"test:media": "node scripts/test-direct.mjs src/runtime/media/catalog.test.mjs src/runtime/media/lanes.test.mjs src/runtime/media/tool.test.mjs src/runtime/media/defaults.test.mjs src/runtime/media/store.test.mjs src/runtime/media/renditions.test.mjs src/runtime/media/adapters/codex-image.test.mjs src/runtime/media/adapters/gemini-image.test.mjs src/runtime/media/adapters/image-api.test.mjs src/tui/session/session-api/media-lanes.test.mjs",
|
|
102
94
|
"failures": "node scripts/tool-failures.mjs",
|
|
103
95
|
"trace:llm": "node scripts/llm-trace-summary.mjs",
|
|
104
96
|
"bench:office": "node src/runtime/office/bench/benchmark.mjs",
|
|
@@ -117,8 +109,6 @@
|
|
|
117
109
|
"bench:run": "node scripts/bench-run.mjs",
|
|
118
110
|
"bench:recall": "node scripts/recall-bench.mjs",
|
|
119
111
|
"bench:recall:strict": "node scripts/recall-bench.mjs --strict",
|
|
120
|
-
"test:recall-validator": "node scripts/test-direct.mjs scripts/recall-bench-test.mjs",
|
|
121
|
-
"test:suite-health": "node scripts/test-direct.mjs scripts/suite-health.test.mjs",
|
|
122
112
|
"bench:tui-load": "node scripts/tui-runtime-load-bench.mjs",
|
|
123
113
|
"bench:output-style": "node scripts/output-style-bench.mjs",
|
|
124
114
|
"bench:session-context": "node scripts/session-context-bench.mjs",
|
|
@@ -186,6 +176,7 @@
|
|
|
186
176
|
"string-width": "^8.2.1",
|
|
187
177
|
"strip-ansi": "^7.2.0",
|
|
188
178
|
"tesseract.js": "^7.0.0",
|
|
179
|
+
"tldts": "^7.4.18",
|
|
189
180
|
"undici": "^8.10.2",
|
|
190
181
|
"unpdf": "^1.8.0",
|
|
191
182
|
"wrap-ansi": "^10.0.0",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Release Gate guard for the immutable voice runtime release. Deploy reuses the
|
|
2
|
+
// published runtime only while the build-input hash of the checkout matches it,
|
|
3
|
+
// so a change to any hash input (scripts/voice-runtime-config.json, the build
|
|
4
|
+
// scripts and workflow, generate-voice-runtime-manifest.mjs) without a
|
|
5
|
+
// runtimeVersion bump fails here on push instead of stopping a live Deploy.
|
|
6
|
+
// A formatter pass that only re-indents those files counts as a change.
|
|
7
|
+
// Run it on a Linux checkout: the hash covers the files as checked out there.
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
VOICE_RUNTIME_VERSION,
|
|
12
|
+
assertVoiceRuntimeManifestIdentity,
|
|
13
|
+
compareSemver,
|
|
14
|
+
} from './generate-voice-runtime-manifest.mjs';
|
|
15
|
+
|
|
16
|
+
const bundled = JSON.parse(
|
|
17
|
+
await readFile(new URL('../src/runtime/channels/data/voice-runtime-manifest.json', import.meta.url), 'utf8')
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (compareSemver(VOICE_RUNTIME_VERSION, bundled.version) > 0) {
|
|
21
|
+
console.log(`voice runtime ${VOICE_RUNTIME_VERSION} is not released yet; Deploy builds it`);
|
|
22
|
+
} else {
|
|
23
|
+
await assertVoiceRuntimeManifestIdentity(bundled);
|
|
24
|
+
console.log(`voice runtime ${bundled.version} build inputs match the published runtime`);
|
|
25
|
+
}
|
package/scripts/daemon-stub.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Stub channel service for the flip smoke: same lifecycle contract as
|
|
2
2
|
// src/standalone/daemon.mjs (pid-verified singleton claim, HTTP+SSE
|
|
3
3
|
// transport, discovery file, ready handshake, client-grace self-shutdown) but
|
|
4
|
-
// with a STUB runtime instead of worker-main
|
|
4
|
+
// with a STUB runtime instead of worker-main. The
|
|
5
5
|
// real channel-worker.mjs spawn-or-attach path forks THIS via
|
|
6
6
|
// MIXDOG_DAEMON_ENTRY, so the flip is exercised end to end.
|
|
7
7
|
process.env.MIXDOG_WORKER_MODE = process.env.MIXDOG_WORKER_MODE || '1';
|
package/scripts/gate-local.mjs
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
// Not covered locally: runtime-macos, computer-backend (cargo + Linux X11),
|
|
11
11
|
// desktop-tests `computer` lane (windows-latest, src/main/computer/ only),
|
|
12
12
|
// relay (apps/relay tests), graph (cargo test), patch (cargo test of the
|
|
13
|
-
// checked-out engine),
|
|
13
|
+
// checked-out engine), browser-import (windows-latest cargo test of the Chrome
|
|
14
|
+
// importer against a fetched upstream checkout), mobile-scripts (Python
|
|
15
|
+
// unittest). The gate's path
|
|
14
16
|
// filtering is not applied: every check and leg always runs. Run `npm ci`
|
|
15
17
|
// (root and apps/desktop) first.
|
|
16
18
|
import { spawn, spawnSync } from 'node:child_process';
|
|
@@ -19,6 +21,7 @@ import os from 'node:os';
|
|
|
19
21
|
import path from 'node:path';
|
|
20
22
|
import { fileURLToPath } from 'node:url';
|
|
21
23
|
import { gateTestBudget, runGateLegs } from './lib/gate-scheduler.mjs';
|
|
24
|
+
import { pruneStaleTempDirs, removeTempDirSync } from './lib/stale-temp.mjs';
|
|
22
25
|
|
|
23
26
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
24
27
|
const started = Date.now();
|
|
@@ -45,8 +48,15 @@ if (build.status !== 0) {
|
|
|
45
48
|
process.exit(1);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
// Each run owns its log directory, so concurrent runs never touch each other's
|
|
52
|
+
// logs and the paths the summary prints stay valid after any outcome. Log
|
|
53
|
+
// directories are kept until they go stale; a resources directory a killed
|
|
54
|
+
// run left behind goes the same way. Both are swept at start.
|
|
55
|
+
const LOG_PREFIX = 'mixdog-gate-local-';
|
|
56
|
+
const RESOURCE_PREFIX = 'mixdog-gate-resources-';
|
|
57
|
+
pruneStaleTempDirs([LOG_PREFIX, RESOURCE_PREFIX]);
|
|
58
|
+
const logDir = fs.mkdtempSync(path.join(os.tmpdir(), LOG_PREFIX));
|
|
59
|
+
const resourceDir = fs.mkdtempSync(path.join(os.tmpdir(), RESOURCE_PREFIX));
|
|
50
60
|
const budget = gateTestBudget();
|
|
51
61
|
// weight: relative worker share, roughly each leg's measured duration x its 3 workers
|
|
52
62
|
// (runtime ~440s, runtime-slow ~545s, desktop fast ~390s, desktop slow ~280s).
|
|
@@ -64,6 +74,7 @@ function runCmd(cmd, logFd, concurrency) {
|
|
|
64
74
|
const child = spawn(cmd, {
|
|
65
75
|
cwd: root,
|
|
66
76
|
shell: true,
|
|
77
|
+
windowsHide: true,
|
|
67
78
|
stdio: ['ignore', logFd, logFd],
|
|
68
79
|
env: {
|
|
69
80
|
...process.env,
|
|
@@ -97,7 +108,7 @@ try {
|
|
|
97
108
|
await runLeg(legs.at(-1), budget);
|
|
98
109
|
await runGateLegs(legs.slice(0, -1), budget, runLeg);
|
|
99
110
|
} finally {
|
|
100
|
-
|
|
111
|
+
removeTempDirSync(resourceDir);
|
|
101
112
|
}
|
|
102
113
|
|
|
103
114
|
console.log('\n=== gate:local summary ===');
|
|
@@ -112,7 +123,7 @@ for (const leg of legs) {
|
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
125
|
console.log(
|
|
115
|
-
'Not covered locally: runtime-macos, computer-backend, desktop-tests computer lane (Windows-only), relay, graph, patch, mobile-scripts'
|
|
126
|
+
'Not covered locally: runtime-macos, computer-backend, desktop-tests computer lane (Windows-only), relay, graph, patch, browser-import, mobile-scripts'
|
|
116
127
|
);
|
|
117
128
|
console.log(`Total: ${((Date.now() - started) / 1000).toFixed(1)}s`);
|
|
118
129
|
process.exit(legs.every((l) => l.ok) ? 0 : 1);
|
package/scripts/latest-guard.mjs
CHANGED
|
@@ -17,10 +17,20 @@ function report(text) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function openIssue(repo, body) {
|
|
20
|
-
const existing = JSON.parse(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const existing = JSON.parse(
|
|
21
|
+
gh([
|
|
22
|
+
'issue',
|
|
23
|
+
'list',
|
|
24
|
+
'--repo',
|
|
25
|
+
repo,
|
|
26
|
+
'--state',
|
|
27
|
+
'open',
|
|
28
|
+
'--search',
|
|
29
|
+
`"${ISSUE_TITLE}" in:title`,
|
|
30
|
+
'--json',
|
|
31
|
+
'number,title',
|
|
32
|
+
])
|
|
33
|
+
).find((issue) => issue.title === ISSUE_TITLE);
|
|
24
34
|
if (existing) {
|
|
25
35
|
gh(['issue', 'comment', String(existing.number), '--repo', repo, '--body', body]);
|
|
26
36
|
return `commented on issue #${existing.number}`;
|
|
@@ -44,11 +54,13 @@ export function main(repo = process.env.GITHUB_REPOSITORY) {
|
|
|
44
54
|
const problem = `GitHub Latest was \`${actual ?? 'none'}\` but the newest published app release is \`${expected.tag_name}\`.`;
|
|
45
55
|
gh(['release', 'edit', expected.tag_name, '--repo', repo, '--latest']);
|
|
46
56
|
const repaired = currentLatestTag(repo);
|
|
47
|
-
const outcome =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
const outcome =
|
|
58
|
+
repaired === expected.tag_name
|
|
59
|
+
? `Set Latest back to \`${expected.tag_name}\`.`
|
|
60
|
+
: `Could not set Latest to \`${expected.tag_name}\`; it is now \`${repaired ?? 'none'}\`.`;
|
|
61
|
+
const detail =
|
|
62
|
+
`${problem}\n${outcome}\n\nWorkflow run: ${process.env.GITHUB_SERVER_URL ?? ''}/${repo}/actions/runs/${process.env.GITHUB_RUN_ID ?? ''}\n` +
|
|
63
|
+
'Check which release or workflow published a non-app release without `--latest=false` / `make_latest: false`.';
|
|
52
64
|
report(`## Latest release guard\n${detail}`);
|
|
53
65
|
try {
|
|
54
66
|
report(`Issue: ${openIssue(repo, detail)}.`);
|
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
// evaluates imports in order) so the data/home dirs resolve to a scratch dir
|
|
3
3
|
// before any module under test reads them, even under plain `node --test` from a
|
|
4
4
|
// shell that exports the signed-in profile's MIXDOG_DATA_DIR.
|
|
5
|
-
import { mkdtempSync
|
|
5
|
+
import { mkdtempSync } from 'node:fs';
|
|
6
6
|
import { tmpdir } from 'node:os';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
|
+
import { registerOwnedTempDir } from './scoped-temp.mjs';
|
|
9
|
+
import { pruneStaleTempDirs, removeTempDirSync } from './stale-temp.mjs';
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
// The exit handler below never runs for a killed process, so each start sweeps
|
|
12
|
+
// what earlier killed processes left.
|
|
13
|
+
const PREFIX = 'mixdog-test-profile-';
|
|
14
|
+
pruneStaleTempDirs([PREFIX]);
|
|
15
|
+
const root = mkdtempSync(join(tmpdir(), PREFIX));
|
|
16
|
+
registerOwnedTempDir(root);
|
|
10
17
|
process.env.MIXDOG_DATA_DIR = join(root, 'data');
|
|
11
18
|
process.env.MIXDOG_HOME = join(root, 'home');
|
|
12
19
|
process.on('exit', () => {
|
|
13
|
-
|
|
14
|
-
rmSync(root, { recursive: true, force: true });
|
|
15
|
-
} catch {}
|
|
20
|
+
removeTempDirSync(root);
|
|
16
21
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import { appendFile, mkdtemp,
|
|
2
|
+
import { appendFile, mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
3
3
|
import { availableParallelism, tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
6
|
+
import { pruneStaleTempDirs } from './stale-temp.mjs';
|
|
6
7
|
import { FAILURE_RECORDS_ENV, spawnLedgerPath } from './test-failure-records.mjs';
|
|
7
8
|
import { classifyRerunOutcomes, formatFailureSummary } from './test-failure-summary.mjs';
|
|
8
9
|
|
|
@@ -20,28 +21,14 @@ const HEAP_FLAG = /^--(?:max-old-space-size|max-semi-space-size)=\d+$/;
|
|
|
20
21
|
// An argument costs its own characters plus the separator and its quotes.
|
|
21
22
|
const argCost = (arg) => arg.length + 3;
|
|
22
23
|
|
|
23
|
-
//
|
|
24
|
+
// A green run removes its log directory; a failed run keeps it (the failure
|
|
25
|
+
// summary points at it) until the start-of-run prune finds it stale. The
|
|
26
|
+
// failure and scratch directories are removed when their run ends, so only a
|
|
27
|
+
// killed runner leaves them for that same prune.
|
|
24
28
|
const TEST_LOG_PREFIX = 'mixdog-test-output-';
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let names = [];
|
|
29
|
-
try {
|
|
30
|
-
names = await readdir(root);
|
|
31
|
-
} catch {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const cutoff = Date.now() - TEST_LOG_RETENTION_MS;
|
|
35
|
-
for (const name of names) {
|
|
36
|
-
if (!name.startsWith(TEST_LOG_PREFIX)) continue;
|
|
37
|
-
const path = join(root, name);
|
|
38
|
-
try {
|
|
39
|
-
if ((await stat(path)).mtimeMs < cutoff) await rm(path, { recursive: true, force: true });
|
|
40
|
-
} catch {
|
|
41
|
-
/* another run may own or be removing it */
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
29
|
+
const TEST_FAILURES_PREFIX = 'mixdog-test-failures-';
|
|
30
|
+
const TEST_SCRATCH_PREFIX = 'mixdog-test-scratch-';
|
|
31
|
+
export const RUNNER_TEMP_PREFIXES = [TEST_LOG_PREFIX, TEST_FAILURES_PREFIX, TEST_SCRATCH_PREFIX];
|
|
45
32
|
|
|
46
33
|
// Batches keep the file order Node was given; a single path larger than the
|
|
47
34
|
// budget still gets its own batch rather than being dropped. An empty list
|
|
@@ -331,14 +318,14 @@ function spawnBatch(args, env, { files, ledger, scratchDir, timeoutMs }) {
|
|
|
331
318
|
// rm's own maxRetries re-walks the tree on every nested retry, so one held
|
|
332
319
|
// file a few directories down multiplied its delay into hours. Each pass here
|
|
333
320
|
// is a single bounded walk.
|
|
334
|
-
async function
|
|
321
|
+
async function removeTempDir(dir) {
|
|
335
322
|
for (let attempt = 1; ; attempt += 1) {
|
|
336
323
|
try {
|
|
337
324
|
await rm(dir, { recursive: true, force: true });
|
|
338
325
|
return;
|
|
339
326
|
} catch (error) {
|
|
340
327
|
if (attempt === 5) {
|
|
341
|
-
console.error(`Test
|
|
328
|
+
console.error(`Test temp dir left behind (${error.code}): ${dir}`);
|
|
342
329
|
return;
|
|
343
330
|
}
|
|
344
331
|
await delay(200 * attempt);
|
|
@@ -372,21 +359,37 @@ async function readFailureRecords(path) {
|
|
|
372
359
|
// log can still name what failed.
|
|
373
360
|
//
|
|
374
361
|
// `testTimeoutMs` is the per-file --test-timeout default (see testTimeoutArg).
|
|
375
|
-
export async function runNodeTests(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
) {
|
|
380
|
-
await pruneStaleTestLogs(tmpdir());
|
|
381
|
-
const logPath = join(await mkdtemp(join(tmpdir(), TEST_LOG_PREFIX)), 'full.log');
|
|
362
|
+
export async function runNodeTests(nodeArgs, fileArgs, options = {}) {
|
|
363
|
+
pruneStaleTempDirs(RUNNER_TEMP_PREFIXES);
|
|
364
|
+
const outputDir = await mkdtemp(join(tmpdir(), TEST_LOG_PREFIX));
|
|
365
|
+
const logPath = join(outputDir, 'full.log');
|
|
382
366
|
console.error(`Full test log: ${logPath}`);
|
|
383
367
|
// Failure records live outside the log directory: the log directory holds
|
|
384
368
|
// exactly one merged log, and these records are an internal artifact.
|
|
385
|
-
const failureDir = await mkdtemp(join(tmpdir(),
|
|
369
|
+
const failureDir = await mkdtemp(join(tmpdir(), TEST_FAILURES_PREFIX));
|
|
386
370
|
// Test processes get a private temp root that is removed after the run, so
|
|
387
371
|
// every fixture directory a test forgets to delete goes with it instead of
|
|
388
372
|
// piling up in the system temp directory.
|
|
389
|
-
const scratchDir = await mkdtemp(join(tmpdir(),
|
|
373
|
+
const scratchDir = await mkdtemp(join(tmpdir(), TEST_SCRATCH_PREFIX));
|
|
374
|
+
let status = 1;
|
|
375
|
+
try {
|
|
376
|
+
status = await executeRun(nodeArgs, fileArgs, options, { logPath, failureDir, scratchDir });
|
|
377
|
+
} finally {
|
|
378
|
+
await removeTempDir(failureDir);
|
|
379
|
+
// Leftover processes are already killed; what a process outside the run
|
|
380
|
+
// still holds stays behind.
|
|
381
|
+
await removeTempDir(scratchDir);
|
|
382
|
+
// A throw keeps the log too: the run did not pass.
|
|
383
|
+
if (status === 0) await removeTempDir(outputDir);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function executeRun(
|
|
388
|
+
nodeArgs,
|
|
389
|
+
fileArgs,
|
|
390
|
+
{ argBudget = ARG_BUDGET, coverage = false, rerunFailed = 0, testTimeoutMs = DEFAULT_TEST_TIMEOUT_MS },
|
|
391
|
+
{ logPath, failureDir, scratchDir }
|
|
392
|
+
) {
|
|
390
393
|
// The explicit entry also accepts Node options alongside its file paths.
|
|
391
394
|
const concurrencyArg = testConcurrencyArg([...nodeArgs, ...fileArgs]);
|
|
392
395
|
const timeoutArg = testTimeoutArg([...nodeArgs, ...fileArgs], process.env, testTimeoutMs);
|
|
@@ -509,10 +512,6 @@ export async function runNodeTests(
|
|
|
509
512
|
status = 0;
|
|
510
513
|
process.exitCode = status;
|
|
511
514
|
|
|
512
|
-
await rm(failureDir, { recursive: true, force: true });
|
|
513
|
-
// Leftover processes are already killed; what a process outside the run
|
|
514
|
-
// still holds stays behind.
|
|
515
|
-
await removeScratch(scratchDir);
|
|
516
515
|
if (coverageDir) {
|
|
517
516
|
const { reportCoverage } = await import('./coverage.mjs');
|
|
518
517
|
await reportCoverage(coverageDir);
|
|
@@ -520,4 +519,5 @@ export async function runNodeTests(
|
|
|
520
519
|
}
|
|
521
520
|
// Last line of the run, after every reporter and the coverage report.
|
|
522
521
|
process.stdout.write(`\n${formatFailureSummary({ failed, flaky, rerunFailed, hung, exitCode: status })}`);
|
|
522
|
+
return status;
|
|
523
523
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function makeTempDirSync(prefix: string): string;
|
|
2
|
+
export function registerOwnedTempDir(dir: string): string;
|
|
3
|
+
export function redirectSystemTemp(prefix?: string): string;
|
|
4
|
+
export function removeTempDirSync(dir: string): void;
|
|
5
|
+
export function removeTempDir(dir: string): Promise<void>;
|
|
6
|
+
export function tempDirFor(t: { after(fn: () => unknown): void }, prefix: string): string;
|
|
7
|
+
export interface ScopedTempDir {
|
|
8
|
+
path: string;
|
|
9
|
+
join(...parts: string[]): string;
|
|
10
|
+
remove(): Promise<void>;
|
|
11
|
+
removeSync(): void;
|
|
12
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
13
|
+
[Symbol.dispose](): void;
|
|
14
|
+
}
|
|
15
|
+
export function scopedTempDir(prefix: string): ScopedTempDir;
|
|
16
|
+
export function withTempDir<T>(prefix: string, fn: (dir: string) => T | Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Scoped scratch directories for tests: every directory this module creates is
|
|
2
|
+
// named `mixdog-<prefix>-*` in the system temp dir and is removed whether the
|
|
3
|
+
// test passed or failed. Removal retries a bounded number of times, because on
|
|
4
|
+
// Windows a just-closed file or a just-exited child can hold a path for a
|
|
5
|
+
// moment (EBUSY / EPERM / ENOTEMPTY).
|
|
6
|
+
//
|
|
7
|
+
// Pick the narrowest scope that fits the test:
|
|
8
|
+
// tempDirFor(t, prefix) removed after the node:test context `t`
|
|
9
|
+
// scopedTempDir(prefix) `.path` + dispose; use `await using` on
|
|
10
|
+
// Node 24+, or `try { } finally { await d.remove() }`
|
|
11
|
+
// withTempDir(prefix, fn) removed when `fn` settles
|
|
12
|
+
// makeTempDirSync(prefix) removed by removeTempDirSync, and always swept at
|
|
13
|
+
// process exit (a late write may recreate it)
|
|
14
|
+
// Close anything holding files inside the directory (sqlite handles, servers,
|
|
15
|
+
// child processes) before the removal runs.
|
|
16
|
+
import { mkdtempSync } from 'node:fs';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
19
|
+
import { removeTempDirSync as removeDirWithRetrySync } from './stale-temp.mjs';
|
|
20
|
+
|
|
21
|
+
const live = new Set();
|
|
22
|
+
let exitHookInstalled = false;
|
|
23
|
+
|
|
24
|
+
function directoryPrefix(prefix) {
|
|
25
|
+
const bare = String(prefix)
|
|
26
|
+
.replace(/^mixdog-/, '')
|
|
27
|
+
.replace(/-+$/, '');
|
|
28
|
+
return `mixdog-${bare}-`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function removeAllAtExit() {
|
|
32
|
+
for (const dir of live) removeDirWithRetrySync(dir);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function installExitHook() {
|
|
36
|
+
if (exitHookInstalled) return;
|
|
37
|
+
exitHookInstalled = true;
|
|
38
|
+
process.on('exit', removeAllAtExit);
|
|
39
|
+
// A module under test may add its own exit handler (a final flush can
|
|
40
|
+
// recreate its directory), so keep this one the last to run.
|
|
41
|
+
process.on('newListener', (event, listener) => {
|
|
42
|
+
if (event !== 'exit' || listener === removeAllAtExit) return;
|
|
43
|
+
queueMicrotask(() => {
|
|
44
|
+
process.removeListener('exit', removeAllAtExit);
|
|
45
|
+
process.on('exit', removeAllAtExit);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Creates `mixdog-<prefix>-*` in the system temp dir; removed at process exit unless removed sooner. */
|
|
51
|
+
export function makeTempDirSync(prefix) {
|
|
52
|
+
const dir = mkdtempSync(join(tmpdir(), directoryPrefix(prefix)));
|
|
53
|
+
live.add(dir);
|
|
54
|
+
installExitHook();
|
|
55
|
+
return dir;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Registers a directory its creator made as test-owned, so it is swept again
|
|
60
|
+
* as the last exit step (a late write by the code under test can recreate it
|
|
61
|
+
* after the creator's own exit handler ran). Only an exact `mixdog-*` child of
|
|
62
|
+
* the system temp dir is accepted; nothing is ever inferred from an env var.
|
|
63
|
+
*/
|
|
64
|
+
export function registerOwnedTempDir(dir) {
|
|
65
|
+
const resolved = resolve(dir);
|
|
66
|
+
const same = (a, b) => (process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b);
|
|
67
|
+
if (!basename(resolved).startsWith('mixdog-') || !same(dirname(resolved), resolve(tmpdir()))) {
|
|
68
|
+
throw new Error(`refusing to own a directory outside the system temp root: ${dir}`);
|
|
69
|
+
}
|
|
70
|
+
live.add(resolved);
|
|
71
|
+
installExitHook();
|
|
72
|
+
return resolved;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* For code under test that makes its own mixdog-* directories in the system
|
|
76
|
+
* temp dir: points TEMP/TMP/TMPDIR at one scoped directory for the rest of the
|
|
77
|
+
* process, so everything created there is removed with it at exit.
|
|
78
|
+
*/
|
|
79
|
+
export function redirectSystemTemp(prefix = 'temp-root') {
|
|
80
|
+
const dir = makeTempDirSync(prefix);
|
|
81
|
+
process.env.TEMP = dir;
|
|
82
|
+
process.env.TMP = dir;
|
|
83
|
+
process.env.TMPDIR = dir;
|
|
84
|
+
return dir;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function removeTempDirSync(dir) {
|
|
88
|
+
if (!removeDirWithRetrySync(dir)) process.stderr.write(`scratch folder ${dir} could not be removed\n`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function removeTempDir(dir) {
|
|
92
|
+
removeTempDirSync(dir);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** A directory removed after the node:test context (test or suite) `t` finishes, pass or fail. */
|
|
96
|
+
export function tempDirFor(t, prefix) {
|
|
97
|
+
const dir = makeTempDirSync(prefix);
|
|
98
|
+
t.after(() => removeTempDir(dir));
|
|
99
|
+
return dir;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** A directory with `.path`, `join()` and `remove()`; also `await using` / `using` disposable. */
|
|
103
|
+
export function scopedTempDir(prefix) {
|
|
104
|
+
const path = makeTempDirSync(prefix);
|
|
105
|
+
return {
|
|
106
|
+
path,
|
|
107
|
+
join: (...parts) => join(path, ...parts),
|
|
108
|
+
remove: () => removeTempDir(path),
|
|
109
|
+
removeSync: () => removeTempDirSync(path),
|
|
110
|
+
[Symbol.asyncDispose]: () => removeTempDir(path),
|
|
111
|
+
[Symbol.dispose]: () => removeTempDirSync(path),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Runs `fn(dir)` with a fresh directory and removes it when `fn` settles. */
|
|
116
|
+
export async function withTempDir(prefix, fn) {
|
|
117
|
+
const dir = makeTempDirSync(prefix);
|
|
118
|
+
try {
|
|
119
|
+
return await fn(dir);
|
|
120
|
+
} finally {
|
|
121
|
+
await removeTempDir(dir);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Temp dirs a test run or the local gate owns. A normal exit removes them, but
|
|
2
|
+
// a killed process runs no exit handler, so each run starts by sweeping what an
|
|
3
|
+
// earlier killed run left behind.
|
|
4
|
+
import { lstatSync, readdirSync, rmSync } from 'node:fs';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
|
|
8
|
+
// How long a kept test log stays readable; also what counts as a leftover.
|
|
9
|
+
export const STALE_TEMP_MS = 3 * 24 * 60 * 60 * 1000;
|
|
10
|
+
|
|
11
|
+
// rmSync retries the lock errors itself (EBUSY, EPERM, ENOTEMPTY, ...) a
|
|
12
|
+
// bounded number of times per entry before it throws. Returns whether the
|
|
13
|
+
// directory is gone; a held file leaves it for the next start-of-run sweep.
|
|
14
|
+
export function removeTempDirSync(dir) {
|
|
15
|
+
try {
|
|
16
|
+
rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Removes every directory in `root` whose name starts with one of `prefixes`
|
|
24
|
+
// and whose mtime is older than `maxAgeMs`.
|
|
25
|
+
export function pruneStaleTempDirs(prefixes, { root = tmpdir(), maxAgeMs = STALE_TEMP_MS, now = Date.now() } = {}) {
|
|
26
|
+
let names = [];
|
|
27
|
+
try {
|
|
28
|
+
names = readdirSync(root);
|
|
29
|
+
} catch {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const cutoff = now - maxAgeMs;
|
|
33
|
+
for (const name of names) {
|
|
34
|
+
if (!prefixes.some((prefix) => name.startsWith(prefix))) continue;
|
|
35
|
+
const path = join(root, name);
|
|
36
|
+
try {
|
|
37
|
+
// lstat: a link or a plain file that merely matches the prefix is not ours to remove.
|
|
38
|
+
const info = lstatSync(path);
|
|
39
|
+
if (info.isDirectory() && info.mtimeMs < cutoff) removeTempDirSync(path);
|
|
40
|
+
} catch {
|
|
41
|
+
/* another run may own or be removing it */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
// node scripts/native-release-status.mjs --check exit 1 when a tool is unreleased
|
|
16
16
|
// node scripts/native-release-status.mjs --warn-dev warnings for a dev build, exit 0
|
|
17
17
|
//
|
|
18
|
-
// native/mixdog-computer, native/mixdog-browser-import
|
|
19
|
-
// have no release/manifest: the desktop package builds them from source, keyed
|
|
18
|
+
// native/mixdog-computer, native/mixdog-browser-import, native/mixdog-secure-desktop
|
|
19
|
+
// and native/gnome-extension have no release/manifest: the desktop package builds them from source, keyed
|
|
20
20
|
// on a hash of that source (desktop-package.yml), so they cannot go stale.
|
|
21
21
|
import { spawn, spawnSync } from 'node:child_process';
|
|
22
22
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
@@ -215,12 +215,7 @@ export function getReleaseByTag(repo, tag, run = gh) {
|
|
|
215
215
|
* rethrown, so an API outage fails the job instead of silently skipping
|
|
216
216
|
* verification of a release that may be public.
|
|
217
217
|
*/
|
|
218
|
-
export async function detectPublished({
|
|
219
|
-
fetchRelease,
|
|
220
|
-
sleep = defaultSleep,
|
|
221
|
-
attempts = 5,
|
|
222
|
-
firstDelayMs = 2000,
|
|
223
|
-
}) {
|
|
218
|
+
export async function detectPublished({ fetchRelease, sleep = defaultSleep, attempts = 5, firstDelayMs = 2000 }) {
|
|
224
219
|
let delay = firstDelayMs;
|
|
225
220
|
for (let attempt = 1; ; attempt++) {
|
|
226
221
|
try {
|
|
@@ -22,7 +22,11 @@ const SOURCES = [
|
|
|
22
22
|
const WHOLE_STATEMENT = 240;
|
|
23
23
|
|
|
24
24
|
const propertyName = (property) =>
|
|
25
|
-
property.type === 'Property'
|
|
25
|
+
property.type === 'Property'
|
|
26
|
+
? String(property.key.name ?? property.key.value ?? '')
|
|
27
|
+
: property.type === 'SpreadElement'
|
|
28
|
+
? '…'
|
|
29
|
+
: '';
|
|
26
30
|
|
|
27
31
|
// The keys an object literal offers a script, one level into object-valued keys ("body: { x, y, w, h }"). A table of
|
|
28
32
|
// like entries (STYLES: an id per style, each with the same fields) reads as its ids and the fields each carries.
|
|
@@ -30,7 +34,9 @@ function objectShape(node) {
|
|
|
30
34
|
const properties = node.properties.filter((property) => propertyName(property));
|
|
31
35
|
const nested = properties.filter((property) => property.value?.type === 'ObjectExpression');
|
|
32
36
|
if (properties.length >= 4 && nested.length === properties.length) {
|
|
33
|
-
const fields = [...new Set(nested.flatMap((property) => property.value.properties.map(propertyName)))].filter(
|
|
37
|
+
const fields = [...new Set(nested.flatMap((property) => property.value.properties.map(propertyName)))].filter(
|
|
38
|
+
Boolean
|
|
39
|
+
);
|
|
34
40
|
return `{ ${properties.map(propertyName).join(', ')} } each { ${fields.join(', ')} }`;
|
|
35
41
|
}
|
|
36
42
|
const keys = properties.map((property) =>
|
|
@@ -48,7 +54,8 @@ function returnedShape(fn) {
|
|
|
48
54
|
const visit = (node) => {
|
|
49
55
|
if (!node || typeof node.type !== 'string') return;
|
|
50
56
|
if (node !== fn.body && /Function/.test(node.type)) return;
|
|
51
|
-
if (node.type === 'ReturnStatement' && node.argument?.type === 'ObjectExpression')
|
|
57
|
+
if (node.type === 'ReturnStatement' && node.argument?.type === 'ObjectExpression')
|
|
58
|
+
shapes.push(objectShape(node.argument));
|
|
52
59
|
for (const value of Object.values(node)) {
|
|
53
60
|
if (Array.isArray(value)) value.forEach(visit);
|
|
54
61
|
else if (value && typeof value === 'object' && typeof value.type === 'string') visit(value);
|
|
@@ -116,7 +123,13 @@ function summarizeFile({ file, prose }) {
|
|
|
116
123
|
output.push('```js', summarizeCode(part).trimEnd(), '```');
|
|
117
124
|
return;
|
|
118
125
|
}
|
|
119
|
-
const kept =
|
|
126
|
+
const kept =
|
|
127
|
+
prose === 'all'
|
|
128
|
+
? part.trim()
|
|
129
|
+
: part
|
|
130
|
+
.split('\n')
|
|
131
|
+
.filter((line) => /^#{1,3} /.test(line))
|
|
132
|
+
.join('\n');
|
|
120
133
|
if (kept) output.push(kept.replace(/^# /m, '## '));
|
|
121
134
|
});
|
|
122
135
|
return [`# ${file}`, ...output].join('\n\n');
|
|
@@ -289,7 +289,7 @@
|
|
|
289
289
|
"id": "history-network-3",
|
|
290
290
|
"label": "network interruption natural paraphrase 3",
|
|
291
291
|
"args": {
|
|
292
|
-
"query": "
|
|
292
|
+
"query": "웹소켓 게이트웨이 재연결 때문에 실패 화면이 나온 사건 결론은?",
|
|
293
293
|
"period": "2026-08-02 17:35~18:15",
|
|
294
294
|
"projectScope": "mixdog",
|
|
295
295
|
"limit": 10
|