mixdog 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/scripts/build-shipped-history.mjs +115 -33
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/gate-local.mjs +183 -63
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/gate-scheduler.mjs +138 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +91 -66
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +124 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +16 -4
- package/scripts/lib/test-spawn-ledger.mjs +12 -3
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -5
- package/scripts/suite-health.mjs +115 -24
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/app.mjs +4 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +23 -2
- package/src/defaults/skills/browser-use/SKILL.md +10 -5
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +16 -4
- package/src/defaults/skills/goal-management/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +12 -6
- package/src/defaults/skills/setup/references/surfaces.md +2 -2
- package/src/defaults/skills/setup-guide/SKILL.md +5 -2
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/rules-builder.cjs +35 -42
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +5 -4
- package/src/rules/lead/LEAD.md +12 -7
- package/src/rules/shared/10-tool-workflow.md +3 -1
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -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 +10 -9
- package/src/rules/shared/70-delivery.md +8 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
- package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- 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 +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
- 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-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- 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 +160 -31
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
- 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 +160 -36
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
- 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 +100 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
- 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 +14 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
- 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/owner-route-fallbacks.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- 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/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- 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/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/whisper-port.mjs +29 -11
- package/src/runtime/channels/lib/whisper-server.mjs +10 -1
- package/src/runtime/computer-bridge/action-schema.mjs +2 -2
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
- 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/connectors/connector-accounts-mcp.mjs +236 -103
- package/src/runtime/connectors/gmail-app-password.mjs +3 -3
- package/src/runtime/explore/explorer.mjs +93 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- 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/index.mjs +4 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +10 -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/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 +4 -2
- 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/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +15 -6
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +11 -4
- package/src/runtime/shared/connector-catalog.mjs +60 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/defaults-separation.mjs +1 -4
- 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-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +13 -15
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
- package/src/runtime/shared/llm/cost.mjs +11 -2
- package/src/runtime/shared/llm/http-agent.mjs +313 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +452 -0
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- 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/provider-accounts.mjs +52 -2
- package/src/runtime/shared/session-activity-signal.mjs +14 -0
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- 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 +1 -1
- package/src/runtime/shared/tool-surface.mjs +113 -36
- package/src/runtime/shared/tool-work-units.mjs +6 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +72 -0
- package/src/runtime/shared/worktrees/manager.mjs +285 -168
- package/src/runtime/shared/worktrees/test-support.mjs +6 -10
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +7 -4
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +6 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +1 -1
- package/src/session-runtime/agent-home-delivery.mjs +41 -0
- package/src/session-runtime/agent-task-sessions.mjs +458 -312
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/bot-status.mjs +107 -101
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +401 -36
- package/src/session-runtime/conversation-import/service.mjs +35 -8
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- 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 +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
- package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- 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/send-flow.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +10 -6
- package/src/session-runtime/services/provider-admin.mjs +283 -11
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +6 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
- package/src/session-runtime/turn/agent-ops.mjs +23 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +108 -1041
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
- package/src/standalone/daemon-desktop-runtime.mjs +2 -0
- package/src/standalone/daemon-session-control.mjs +169 -138
- package/src/standalone/daemon.mjs +7 -0
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +5 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/App.jsx +154 -164
- package/src/tui/app/app-view/floating-panel.jsx +10 -4
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +21 -10
- 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/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +29 -18
- package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
- package/src/tui/app/slash-commands.mjs +1 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +3 -2
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +47 -32
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/dist/index.mjs +1963 -1361
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixdog",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
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.",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"src/",
|
|
54
54
|
"!src/tui/dev",
|
|
55
55
|
"!src/**/*.test.mjs",
|
|
56
|
+
"!src/**/*.test-hook.mjs",
|
|
56
57
|
"!src/**/*.test.jsx"
|
|
57
58
|
],
|
|
58
59
|
"scripts": {
|
|
@@ -182,7 +183,7 @@
|
|
|
182
183
|
"wrap-ansi": "^10.0.0",
|
|
183
184
|
"ws": "^8.21.0",
|
|
184
185
|
"yaml": "^2.9.0",
|
|
185
|
-
"zod": "^
|
|
186
|
+
"zod": "^4.6.7"
|
|
186
187
|
},
|
|
187
188
|
"overrides": {
|
|
188
189
|
"onnxruntime-node": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* node scripts/build-shipped-history.mjs --check (release workflow)
|
|
14
14
|
* A shallow clone has no history: the committed file is left untouched.
|
|
15
15
|
*/
|
|
16
|
-
import { execFileSync } from 'node:child_process';
|
|
16
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
17
17
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
18
18
|
import { dirname, join } from 'node:path';
|
|
19
19
|
import { fileURLToPath } from 'node:url';
|
|
@@ -39,12 +39,81 @@ if (git('rev-parse', '--is-shallow-repository').toString().trim() === 'true') {
|
|
|
39
39
|
process.exit(0);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
/**
|
|
43
|
+
* One long-lived `git cat-file --batch` answers every object read, so the whole
|
|
44
|
+
* history costs a single process. `read(spec)` resolves to {sha, type, body}
|
|
45
|
+
* or null when the object is missing.
|
|
46
|
+
*/
|
|
47
|
+
const catFile = spawn('git', ['cat-file', '--batch'], { cwd: ROOT, stdio: ['pipe', 'pipe', 'inherit'] });
|
|
48
|
+
const waiting = [];
|
|
49
|
+
let pending = Buffer.alloc(0);
|
|
50
|
+
catFile.stdout.on('data', (chunk) => {
|
|
51
|
+
pending = Buffer.concat([pending, chunk]);
|
|
52
|
+
for (;;) {
|
|
53
|
+
const eol = pending.indexOf(10);
|
|
54
|
+
if (eol < 0) return;
|
|
55
|
+
const header = pending.toString('utf8', 0, eol);
|
|
56
|
+
if (header.endsWith(' missing')) {
|
|
57
|
+
pending = pending.subarray(eol + 1);
|
|
58
|
+
waiting.shift()(null);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const [sha, type, size] = header.split(' ');
|
|
62
|
+
const end = eol + 1 + Number(size);
|
|
63
|
+
if (pending.length < end + 1) return;
|
|
64
|
+
const body = pending.subarray(eol + 1, end);
|
|
65
|
+
pending = pending.subarray(end + 1);
|
|
66
|
+
waiting.shift()({ sha, type, body });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const read = (spec) =>
|
|
70
|
+
new Promise((resolve) => {
|
|
71
|
+
waiting.push(resolve);
|
|
72
|
+
catFile.stdin.write(`${spec}\n`);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/** Entries of a tree object body: [{ name, tree, sha }] in git (ls-tree) order. */
|
|
76
|
+
function parseTree(body) {
|
|
77
|
+
const entries = [];
|
|
78
|
+
for (let at = 0; at < body.length; ) {
|
|
79
|
+
const space = body.indexOf(32, at);
|
|
80
|
+
const nul = body.indexOf(0, space);
|
|
81
|
+
const mode = body.toString('latin1', at, space);
|
|
82
|
+
entries.push({
|
|
83
|
+
name: body.toString('utf8', space + 1, nul),
|
|
84
|
+
tree: mode === '40000',
|
|
85
|
+
sha: body.toString('hex', nul + 1, nul + 21),
|
|
86
|
+
});
|
|
87
|
+
at = nul + 21;
|
|
88
|
+
}
|
|
89
|
+
return entries;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const treeCache = new Map();
|
|
93
|
+
const blobCache = new Map();
|
|
94
|
+
const treeOf = async (sha) => {
|
|
95
|
+
if (!treeCache.has(sha)) treeCache.set(sha, read(sha).then(({ body }) => parseTree(body)));
|
|
96
|
+
return treeCache.get(sha);
|
|
97
|
+
};
|
|
98
|
+
const blobOf = async (sha) => {
|
|
99
|
+
if (!blobCache.has(sha)) blobCache.set(sha, read(sha).then(({ body }) => body));
|
|
100
|
+
return blobCache.get(sha);
|
|
46
101
|
};
|
|
47
102
|
|
|
103
|
+
/** Relative path -> blob sha for every file under a tree entry (a lone file keeps its own name). */
|
|
104
|
+
async function filesOf({ name, tree, sha }) {
|
|
105
|
+
if (!tree) return new Map([[name, sha]]);
|
|
106
|
+
const files = new Map();
|
|
107
|
+
const walk = async (treeSha, base) => {
|
|
108
|
+
for (const entry of await treeOf(treeSha)) {
|
|
109
|
+
if (entry.tree) await walk(entry.sha, `${base}${entry.name}/`);
|
|
110
|
+
else files.set(`${base}${entry.name}`, entry.sha);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
await walk(sha, '');
|
|
114
|
+
return files;
|
|
115
|
+
}
|
|
116
|
+
|
|
48
117
|
/** Names (path segment after `prefix`) that ever existed under prefix. */
|
|
49
118
|
function everNames(prefix) {
|
|
50
119
|
const names = new Set();
|
|
@@ -54,29 +123,39 @@ function everNames(prefix) {
|
|
|
54
123
|
return [...names].sort();
|
|
55
124
|
}
|
|
56
125
|
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Every distinct state `prefix/<name>` had in the commits the path-limited
|
|
128
|
+
* `git log -- path` lists (its history simplification decides which commits
|
|
129
|
+
* count). Only the object reads are batched through `cat-file`.
|
|
130
|
+
*/
|
|
131
|
+
async function everVersions(prefix) {
|
|
132
|
+
const out = new Map();
|
|
133
|
+
for (const name of everNames(prefix)) {
|
|
134
|
+
const path = `${prefix}/${name}`;
|
|
135
|
+
const states = new Map();
|
|
136
|
+
for (const commit of lines(git('log', '--format=%H', '--', path))) {
|
|
137
|
+
const object = await read(`${commit}:${path}`);
|
|
138
|
+
if (object) states.set(object.sha, { name, tree: object.type === 'tree', sha: object.sha });
|
|
65
139
|
}
|
|
66
|
-
|
|
140
|
+
const versions = [];
|
|
141
|
+
for (const entry of states.values()) {
|
|
142
|
+
const files = await filesOf(entry);
|
|
143
|
+
if (files.size) versions.push(files);
|
|
144
|
+
}
|
|
145
|
+
out.set(name, versions);
|
|
67
146
|
}
|
|
68
|
-
return
|
|
147
|
+
return out;
|
|
69
148
|
}
|
|
70
|
-
|
|
71
149
|
const unique = (hashes) => [...new Set(hashes)].sort();
|
|
72
150
|
|
|
73
|
-
function packHistory(dir, entry) {
|
|
151
|
+
async function packHistory(dir, entry) {
|
|
74
152
|
const out = {};
|
|
75
|
-
for (const id of
|
|
153
|
+
for (const [id, versions] of await everVersions(dir)) {
|
|
76
154
|
const hashes = [];
|
|
77
|
-
for (const files of
|
|
78
|
-
const
|
|
79
|
-
const
|
|
155
|
+
for (const files of versions) {
|
|
156
|
+
const texts = new Map();
|
|
157
|
+
for (const [file, sha] of files) texts.set(file, (await blobOf(sha)).toString('utf8'));
|
|
158
|
+
const definition = packDefinitionFrom((name) => texts.get(name) ?? null, entry, id);
|
|
80
159
|
if (definition) hashes.push(hashDefinition(definition));
|
|
81
160
|
}
|
|
82
161
|
if (hashes.length) out[id] = unique(hashes);
|
|
@@ -84,32 +163,35 @@ function packHistory(dir, entry) {
|
|
|
84
163
|
return out;
|
|
85
164
|
}
|
|
86
165
|
|
|
87
|
-
function outputStyleHistory() {
|
|
166
|
+
async function outputStyleHistory() {
|
|
88
167
|
const out = {};
|
|
89
|
-
for (const name of
|
|
90
|
-
const hashes =
|
|
168
|
+
for (const [name, versions] of await everVersions('src/output-styles')) {
|
|
169
|
+
const hashes = [];
|
|
170
|
+
for (const files of versions) hashes.push(hashText(await blobOf([...files.values()][0])));
|
|
91
171
|
if (hashes.length) out[name] = unique(hashes);
|
|
92
172
|
}
|
|
93
173
|
return out;
|
|
94
174
|
}
|
|
95
175
|
|
|
96
|
-
function skillHistory() {
|
|
176
|
+
async function skillHistory() {
|
|
97
177
|
const out = {};
|
|
98
|
-
for (const name of
|
|
99
|
-
const hashes =
|
|
100
|
-
|
|
101
|
-
|
|
178
|
+
for (const [name, versions] of await everVersions('src/defaults/skills')) {
|
|
179
|
+
const hashes = [];
|
|
180
|
+
for (const files of versions) {
|
|
181
|
+
hashes.push(hashTree(await Promise.all([...files].map(async ([rel, sha]) => [rel, await blobOf(sha)]))));
|
|
182
|
+
}
|
|
102
183
|
if (hashes.length) out[name] = unique(hashes);
|
|
103
184
|
}
|
|
104
185
|
return out;
|
|
105
186
|
}
|
|
106
187
|
|
|
107
188
|
const history = {
|
|
108
|
-
agents: packHistory('src/agents', 'AGENT.md'),
|
|
109
|
-
workflows: packHistory('src/workflows', 'WORKFLOW.md'),
|
|
110
|
-
outputStyles: outputStyleHistory(),
|
|
111
|
-
skills: skillHistory(),
|
|
189
|
+
agents: await packHistory('src/agents', 'AGENT.md'),
|
|
190
|
+
workflows: await packHistory('src/workflows', 'WORKFLOW.md'),
|
|
191
|
+
outputStyles: await outputStyleHistory(),
|
|
192
|
+
skills: await skillHistory(),
|
|
112
193
|
};
|
|
194
|
+
catFile.stdin.end();
|
|
113
195
|
const text = `${JSON.stringify(history, null, 2)}\n`;
|
|
114
196
|
if (CHECK) {
|
|
115
197
|
let committed = '';
|
|
@@ -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/gate-local.mjs
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// Local pre-push check. Mirrors the test legs of .github/workflows/release-gate.yml
|
|
3
|
-
// (jobs: runtime, runtime-slow, desktop, desktop-tests fast/slow).
|
|
4
|
-
// updated together with that workflow whenever those commands change.
|
|
5
|
-
// Up front
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// (
|
|
3
|
+
// (jobs: runtime, runtime-slow, desktop, desktop-tests fast/slow, shipped-history).
|
|
4
|
+
// It MUST be updated together with that workflow whenever those commands change.
|
|
5
|
+
// Up front it runs the released-section changelog check the desktop fast lane
|
|
6
|
+
// asserts (changelog-locales.test.mjs; Deploy's plan adds the Unreleased
|
|
7
|
+
// section) and stops if it fails. Everything else runs from one shared pool of
|
|
8
|
+
// workers (scripts/lib/gate-scheduler.mjs): every test lane is cut into shards
|
|
9
|
+
// of its own files (each run with the lane's own npm script command), and the
|
|
10
|
+
// desktop build + daemon end-to-end test, the patch smoke and the gate's
|
|
11
|
+
// shipped-history job (build-shipped-history.mjs --check; needs a full clone, a
|
|
12
|
+
// shallow one keeps the committed file) are units of the same pool. A failed
|
|
13
|
+
// shipped-history check stops new starts, so the gate still ends early on it.
|
|
14
|
+
// The whole run is at below-normal priority so the desktop stays responsive.
|
|
10
15
|
// Not covered locally: runtime-macos, computer-backend (cargo + Linux X11),
|
|
11
16
|
// desktop-tests `computer` lane (windows-latest, src/main/computer/ only),
|
|
12
17
|
// relay (apps/relay tests), graph (cargo test), patch (cargo test of the
|
|
@@ -15,22 +20,32 @@
|
|
|
15
20
|
// unittest). The gate's path
|
|
16
21
|
// filtering is not applied: every check and leg always runs. Run `npm ci`
|
|
17
22
|
// (root and apps/desktop) first.
|
|
23
|
+
// Usage: npm run gate:local [-- --test-concurrency=<workers>]
|
|
24
|
+
// (MIXDOG_TEST_CONCURRENCY also sets the pool size; default: half the cores, at most 8).
|
|
18
25
|
import { spawn, spawnSync } from 'node:child_process';
|
|
19
26
|
import fs from 'node:fs';
|
|
20
27
|
import os from 'node:os';
|
|
21
28
|
import path from 'node:path';
|
|
22
29
|
import { fileURLToPath } from 'node:url';
|
|
23
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
DEFAULT_ESTIMATE_MS,
|
|
32
|
+
gateTestBudget,
|
|
33
|
+
measuredFileTimes,
|
|
34
|
+
planShards,
|
|
35
|
+
readTimingHistory,
|
|
36
|
+
runPool,
|
|
37
|
+
saveTimingHistory,
|
|
38
|
+
} from './lib/gate-scheduler.mjs';
|
|
39
|
+
import { pruneStaleTempDirs, removeTempDirSync } from './lib/stale-temp.mjs';
|
|
24
40
|
|
|
25
41
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
26
42
|
const started = Date.now();
|
|
43
|
+
const budget = gateTestBudget(process.argv.slice(2));
|
|
44
|
+
// Inherited by every process the gate starts (Windows and POSIX alike).
|
|
45
|
+
os.setPriority(os.constants.priority.PRIORITY_BELOW_NORMAL);
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
(cmd) => spawnSync(cmd, { cwd: root, stdio: 'inherit', shell: true }).status !== 0
|
|
31
|
-
);
|
|
32
|
-
if (failedPreChecks.length) {
|
|
33
|
-
console.error(`[gate:local] pre-check failed: ${failedPreChecks.join('; ')}`);
|
|
47
|
+
if (spawnSync('node scripts/check-changelog-locales.mjs', { cwd: root, stdio: 'inherit', shell: true }).status !== 0) {
|
|
48
|
+
console.error('[gate:local] pre-check failed: node scripts/check-changelog-locales.mjs');
|
|
34
49
|
process.exit(1);
|
|
35
50
|
}
|
|
36
51
|
|
|
@@ -47,74 +62,179 @@ if (build.status !== 0) {
|
|
|
47
62
|
process.exit(1);
|
|
48
63
|
}
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
// Each run owns its log directory, so concurrent runs never touch each other's
|
|
66
|
+
// logs and the paths the summary prints stay valid after any outcome. Log
|
|
67
|
+
// directories are kept until they go stale; a resources directory a killed
|
|
68
|
+
// run left behind goes the same way. Both are swept at start.
|
|
69
|
+
const LOG_PREFIX = 'mixdog-gate-local-';
|
|
70
|
+
const RESOURCE_PREFIX = 'mixdog-gate-resources-';
|
|
71
|
+
pruneStaleTempDirs([LOG_PREFIX, RESOURCE_PREFIX]);
|
|
72
|
+
const logDir = fs.mkdtempSync(path.join(os.tmpdir(), LOG_PREFIX));
|
|
73
|
+
const resourceDir = fs.mkdtempSync(path.join(os.tmpdir(), RESOURCE_PREFIX));
|
|
74
|
+
|
|
75
|
+
// Measured times live in the repository's common git dir, so every worktree
|
|
76
|
+
// and snapshot of the repo plans from the same history. Keys: a test file's
|
|
77
|
+
// repo-relative path, or `cmd:` + a command unit's commands. Timings only
|
|
78
|
+
// plan the run: without them (no git dir, unreadable or invalid history) the
|
|
79
|
+
// gate plans from default estimates.
|
|
80
|
+
const commonDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], {
|
|
81
|
+
cwd: root,
|
|
82
|
+
encoding: 'utf8',
|
|
83
|
+
});
|
|
84
|
+
const historyPath =
|
|
85
|
+
commonDir.status === 0 ? path.join(commonDir.stdout.trim(), 'mixdog-gate-timings.json') : null;
|
|
86
|
+
if (!historyPath) console.warn(`[gate:local] warning: no git common dir, timings not kept: ${commonDir.stderr}`);
|
|
87
|
+
const history = historyPath ? readTimingHistory(historyPath) : {};
|
|
88
|
+
const measured = {};
|
|
89
|
+
|
|
90
|
+
// Each test lane runs its package's own npm script command, given shard files
|
|
91
|
+
// as filters (scripts/test.mjs), without npm or a shell between: a shell's
|
|
92
|
+
// command line could not hold a shard's paths.
|
|
93
|
+
const testLanes = [
|
|
94
|
+
{ name: 'runtime', pkg: '.', script: 'test', speed: 'fast' },
|
|
95
|
+
{ name: 'runtime-slow', pkg: '.', script: 'test:slow', speed: 'slow' },
|
|
96
|
+
{ name: 'desktop-tests-fast', pkg: 'apps/desktop', script: 'test', speed: 'fast' },
|
|
97
|
+
{ name: 'desktop-tests-slow', pkg: 'apps/desktop', script: 'test:slow', speed: 'slow' },
|
|
98
|
+
].map((lane) => {
|
|
99
|
+
const dir = path.join(root, lane.pkg);
|
|
100
|
+
const command = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')).scripts[lane.script];
|
|
101
|
+
const [program, ...args] = command.split(/\s+/);
|
|
102
|
+
if (program !== 'node') throw new Error(`${lane.pkg}/package.json "${lane.script}" must be a node command: ${command}`);
|
|
103
|
+
const list = spawnSync(process.execPath, [...args, '--list'], { cwd: dir, encoding: 'utf8' });
|
|
104
|
+
if (list.status !== 0) throw new Error(`${command} --list failed: ${list.stderr}`);
|
|
105
|
+
const files = list.stdout
|
|
106
|
+
.split(/\r?\n/)
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.map((line) => line.replace(/^\S+\s+/, ''));
|
|
109
|
+
const key = (file) => path.posix.join(lane.pkg, file);
|
|
110
|
+
return { ...lane, dir, args, files, key, estimateOf: (file) => history[key(file)] ?? DEFAULT_ESTIMATE_MS[lane.speed] };
|
|
111
|
+
});
|
|
112
|
+
const lanesByName = new Map(testLanes.map((lane) => [lane.name, lane]));
|
|
113
|
+
const commandUnits = [
|
|
114
|
+
{ lane: 'shipped-history', cmds: ['node scripts/build-shipped-history.mjs --check'], stopOnFail: true },
|
|
115
|
+
{ lane: 'runtime', cmds: ['npm run smoke:patch'] },
|
|
116
|
+
// Only the daemon end-to-end test reads the build (apps/desktop/out); no
|
|
117
|
+
// test lane does, so the build shares the pool with them.
|
|
118
|
+
{ lane: 'desktop', cmds: ['npm run build --prefix apps/desktop', 'npm run test:daemon:e2e --prefix apps/desktop'] },
|
|
119
|
+
].map((unit) => {
|
|
120
|
+
const key = `cmd:${unit.cmds.join(' && ')}`;
|
|
121
|
+
return { ...unit, key, estimate: history[key] ?? DEFAULT_ESTIMATE_MS.command };
|
|
122
|
+
});
|
|
123
|
+
const units = [...planShards(testLanes, budget), ...commandUnits];
|
|
124
|
+
const laneCounts = new Map();
|
|
125
|
+
for (const unit of units) {
|
|
126
|
+
laneCounts.set(unit.lane, (laneCounts.get(unit.lane) ?? 0) + 1);
|
|
127
|
+
unit.id = `${unit.lane}.${laneCounts.get(unit.lane)}`;
|
|
128
|
+
}
|
|
129
|
+
const laneNames = [...laneCounts.keys()];
|
|
130
|
+
const laneLog = (name) => path.join(logDir, `${name}.log`);
|
|
62
131
|
|
|
63
|
-
|
|
132
|
+
// Every unit is one worker: a shard runs its files one at a time.
|
|
133
|
+
const env = { ...process.env, MIXDOG_TEST_CONCURRENCY: '1', MIXDOG_TEST_OOXML_CACHE_DIR: resourceDir };
|
|
134
|
+
function run(command, args, options, fd) {
|
|
64
135
|
return new Promise((resolve) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
stdio: ['ignore', logFd, logFd],
|
|
70
|
-
env: {
|
|
71
|
-
...process.env,
|
|
72
|
-
MIXDOG_TEST_CONCURRENCY: String(concurrency),
|
|
73
|
-
MIXDOG_TEST_OOXML_CACHE_DIR: resourceDir,
|
|
74
|
-
},
|
|
136
|
+
const child = spawn(command, args, { ...options, env, windowsHide: true, stdio: ['ignore', fd, fd] });
|
|
137
|
+
child.on('error', (error) => {
|
|
138
|
+
fs.writeSync(fd, `${error.stack}\n`);
|
|
139
|
+
resolve(1);
|
|
75
140
|
});
|
|
76
|
-
child.on('error', () => resolve(1));
|
|
77
141
|
child.on('close', (code) => resolve(code ?? 1));
|
|
78
142
|
});
|
|
79
143
|
}
|
|
80
144
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
145
|
+
const TIMING_REPORTER = new URL('./lib/gate-timing-reporter.mjs', import.meta.url).href;
|
|
146
|
+
async function runShard(unit, fd) {
|
|
147
|
+
const lane = lanesByName.get(unit.lane);
|
|
148
|
+
const timings = path.join(logDir, `${unit.id}.timings.jsonl`);
|
|
149
|
+
const args = [...lane.args, `--test-reporter=${TIMING_REPORTER}`, `--test-reporter-destination=${timings}`];
|
|
150
|
+
fs.writeSync(fd, `\n$ (${lane.pkg}) node ${[...args, ...unit.files].join(' ')}\n`);
|
|
151
|
+
const code = await run(process.execPath, [...args, ...unit.files], { cwd: lane.dir }, fd);
|
|
152
|
+
const reported = Object.fromEntries(
|
|
153
|
+
(fs.existsSync(timings) ? fs.readFileSync(timings, 'utf8') : '')
|
|
154
|
+
.split('\n')
|
|
155
|
+
.filter(Boolean)
|
|
156
|
+
.map((line) => {
|
|
157
|
+
const { file, ms } = JSON.parse(line);
|
|
158
|
+
return [file, ms];
|
|
159
|
+
})
|
|
160
|
+
);
|
|
161
|
+
fs.rmSync(timings, { force: true });
|
|
162
|
+
for (const [file, ms] of Object.entries(measuredFileTimes(unit.files, reported, Date.now() - unit.start))) {
|
|
163
|
+
measured[lane.key(file)] = Math.round(ms);
|
|
164
|
+
}
|
|
165
|
+
return code === 0;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function runCommands(unit, fd) {
|
|
169
|
+
let ok = true;
|
|
170
|
+
for (const cmd of unit.cmds) {
|
|
171
|
+
fs.writeSync(fd, `\n$ ${cmd}\n`);
|
|
172
|
+
if ((await run(cmd, [], { cwd: root, shell: true }, fd)) !== 0) {
|
|
173
|
+
ok = false;
|
|
89
174
|
break;
|
|
90
175
|
}
|
|
91
176
|
}
|
|
92
|
-
|
|
93
|
-
|
|
177
|
+
measured[unit.key] = Date.now() - unit.start;
|
|
178
|
+
return ok;
|
|
94
179
|
}
|
|
95
180
|
|
|
96
|
-
|
|
181
|
+
let finished = 0;
|
|
182
|
+
async function runUnit(unit) {
|
|
183
|
+
const part = path.join(logDir, `${unit.id}.part.log`);
|
|
184
|
+
const fd = fs.openSync(part, 'w');
|
|
185
|
+
unit.start = Date.now();
|
|
186
|
+
let ok = false;
|
|
187
|
+
try {
|
|
188
|
+
ok = await (unit.files ? runShard(unit, fd) : runCommands(unit, fd));
|
|
189
|
+
} finally {
|
|
190
|
+
fs.closeSync(fd);
|
|
191
|
+
unit.end = Date.now();
|
|
192
|
+
fs.appendFileSync(laneLog(unit.lane), fs.readFileSync(part));
|
|
193
|
+
fs.rmSync(part);
|
|
194
|
+
}
|
|
195
|
+
console.log(
|
|
196
|
+
`[gate:local] ${ok ? 'ok ' : 'FAIL'} ${unit.id} ${((unit.end - unit.start) / 1000).toFixed(1)}s (${++finished}/${units.length})`
|
|
197
|
+
);
|
|
198
|
+
return ok;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log(
|
|
202
|
+
`[gate:local] ${units.length} units on ${budget} workers at below-normal priority; timings: ${historyPath}; logs: ${logDir}`
|
|
203
|
+
);
|
|
204
|
+
let notStarted = [];
|
|
97
205
|
try {
|
|
98
|
-
|
|
99
|
-
await runLeg(legs.at(-1), budget);
|
|
100
|
-
await runGateLegs(legs.slice(0, -1), budget, runLeg);
|
|
206
|
+
notStarted = await runPool(units, budget, runUnit);
|
|
101
207
|
} finally {
|
|
102
|
-
|
|
208
|
+
removeTempDirSync(resourceDir);
|
|
209
|
+
// The next run plans from these; work this run did not reach keeps its old time.
|
|
210
|
+
const keys = [...testLanes.flatMap((lane) => lane.files.map(lane.key)), ...commandUnits.map((unit) => unit.key)];
|
|
211
|
+
const next = Object.fromEntries(
|
|
212
|
+
keys.filter((key) => (measured[key] ?? history[key]) !== undefined).map((key) => [key, measured[key] ?? history[key]])
|
|
213
|
+
);
|
|
214
|
+
const saveError = historyPath && saveTimingHistory(historyPath, next);
|
|
215
|
+
if (saveError) console.warn(`[gate:local] warning: timings not saved (${saveError.message})`);
|
|
103
216
|
}
|
|
104
217
|
|
|
105
218
|
console.log('\n=== gate:local summary ===');
|
|
106
|
-
for (const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
219
|
+
for (const name of laneNames) {
|
|
220
|
+
const laneUnits = units.filter((unit) => unit.lane === name);
|
|
221
|
+
const ran = laneUnits.filter((unit) => unit.end);
|
|
222
|
+
const status = ran.some((unit) => !unit.ok) ? 'FAIL' : ran.length < laneUnits.length ? 'NOT RUN' : 'PASS';
|
|
223
|
+
const span = ran.length ? Math.max(...ran.map((u) => u.end)) - Math.min(...ran.map((u) => u.start)) : 0;
|
|
224
|
+
const work = ran.reduce((sum, unit) => sum + unit.end - unit.start, 0);
|
|
225
|
+
console.log(
|
|
226
|
+
`${status} ${name} ${(span / 1000).toFixed(1)}s (${(work / 1000).toFixed(1)}s worker time, ${ran.length}/${laneUnits.length} units) ${laneLog(name)}`
|
|
227
|
+
);
|
|
228
|
+
if (status !== 'FAIL') continue;
|
|
229
|
+
const lines = fs
|
|
230
|
+
.readFileSync(laneLog(name), 'utf8')
|
|
231
|
+
.split(/\r?\n/)
|
|
232
|
+
.filter((l) => /\[failure-summary\] (?:RUN FAILED|HUNG|FAILED|FLAKY)/.test(l));
|
|
233
|
+
for (const l of lines) console.log(` ${l}`);
|
|
115
234
|
}
|
|
235
|
+
if (notStarted.length) console.log(`Stopped after a failed ${units.find((u) => u.stopOnFail && u.ok === false).lane} check: ${notStarted.length} unit(s) not run`);
|
|
116
236
|
console.log(
|
|
117
237
|
'Not covered locally: runtime-macos, computer-backend, desktop-tests computer lane (Windows-only), relay, graph, patch, browser-import, mobile-scripts'
|
|
118
238
|
);
|
|
119
239
|
console.log(`Total: ${((Date.now() - started) / 1000).toFixed(1)}s`);
|
|
120
|
-
process.exit(
|
|
240
|
+
process.exit(units.every((unit) => unit.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)}.`);
|