mixdog 0.9.63 → 0.9.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/package.json +9 -2
- package/scripts/code-graph-description-contract.mjs +3 -3
- package/scripts/verify-release-assets.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +11 -14
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +19 -124
- package/src/runtime/agent/orchestrator/context/collect.mjs +6 -6
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +2 -2
- package/src/runtime/agent/orchestrator/internal-agents.mjs +2 -2
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +333 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -277
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +460 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +14 -593
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -280
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +357 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +216 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +2 -188
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/compact/file-reattach.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +17 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +18 -26
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/delivered-completions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +260 -0
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +72 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +163 -0
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -561
- package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -154
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/cwd-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/fs-reachability.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-locks.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +2 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +519 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +5 -449
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +212 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +1 -7
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +9 -36
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +15 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +429 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +2 -395
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/mutation-planner.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/next-call-utils.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +72 -9
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +2 -444
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +505 -0
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/backend-dispatch.mjs +20 -5
- package/src/runtime/channels/lib/scheduler.mjs +1 -1
- package/src/runtime/channels/lib/telegram-format.mjs +1 -1
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +4 -4
- package/src/runtime/channels/tool-defs.mjs +2 -3
- package/src/runtime/memory/index.mjs +1 -5
- package/src/runtime/memory/lib/core-memory-candidates.mjs +357 -0
- package/src/runtime/memory/lib/core-memory-store.mjs +7 -357
- package/src/runtime/memory/lib/cycle-signatures.mjs +1 -1
- package/src/runtime/memory/lib/embedding-model-config.mjs +1 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +1 -5
- package/src/runtime/memory/lib/embedding-worker.mjs +1 -5
- package/src/runtime/memory/lib/ko-morph.mjs +2 -2
- package/src/runtime/memory/lib/memory-config-flags.mjs +2 -5
- package/src/runtime/memory/lib/memory-cycle-requests.mjs +3 -7
- package/src/runtime/memory/lib/memory-cycle1.mjs +4 -8
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +2 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -5
- package/src/runtime/memory/lib/memory-embed.mjs +2 -6
- package/src/runtime/memory/lib/memory-log.mjs +8 -0
- package/src/runtime/memory/lib/memory-ops-policy.mjs +4 -8
- package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +1 -1
- package/src/runtime/memory/lib/memory-recall-store.mjs +2 -193
- package/src/runtime/memory/lib/memory-score.mjs +1 -1
- package/src/runtime/memory/lib/memory-text-utils.mjs +2 -2
- package/src/runtime/memory/lib/memory.mjs +2 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +2 -6
- package/src/runtime/memory/lib/pg/process.mjs +1 -5
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -5
- package/src/runtime/memory/lib/recall-format.mjs +2 -2
- package/src/runtime/memory/lib/recall-scoring.mjs +195 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -5
- package/src/runtime/memory/lib/trace-store.mjs +2 -6
- package/src/runtime/search/lib/http-fetch.mjs +6 -6
- package/src/runtime/search/lib/web-tools.mjs +2 -2
- package/src/runtime/shared/buffered-appender.mjs +1 -1
- package/src/runtime/shared/child-guardian.mjs +1 -1
- package/src/runtime/shared/child-spawn-gate.mjs +1 -1
- package/src/runtime/shared/config.mjs +4 -4
- package/src/runtime/shared/launcher-control.mjs +9 -10
- package/src/runtime/shared/llm/index.mjs +5 -20
- package/src/runtime/shared/markdown-frontmatter.mjs +1 -1
- package/src/runtime/shared/memory-snapshot.mjs +4 -4
- package/src/runtime/shared/pristine-execution.mjs +1 -1
- package/src/runtime/shared/process-lifecycle.mjs +0 -1
- package/src/runtime/shared/process-shutdown.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +2 -2
- package/src/runtime/shared/schedule-session-run.mjs +1 -1
- package/src/runtime/shared/schedules-db.mjs +1 -1
- package/src/runtime/shared/service-discovery.mjs +2 -2
- package/src/runtime/shared/staged-update.mjs +6 -6
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/runtime/shared/tool-primitives.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +2 -2
- package/src/runtime/shared/turn-snapshot.mjs +184 -0
- package/src/runtime/shared/update-checker.mjs +1 -1
- package/src/runtime/shared/user-cwd.mjs +3 -3
- package/src/runtime/shared/user-data-guard.mjs +4 -4
- package/src/runtime/shared/workspace-router.mjs +5 -5
- package/src/session-runtime/config-helpers.mjs +2 -3
- package/src/session-runtime/config-lifecycle.mjs +1 -1
- package/src/session-runtime/hitch-profile.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +6 -4
- package/src/session-runtime/model-recency.mjs +5 -5
- package/src/session-runtime/plugin-mcp.mjs +1 -1
- package/src/session-runtime/provider-request-snapshot.mjs +338 -0
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/session-text.mjs +4 -4
- package/src/session-runtime/session-turn-api.mjs +7 -0
- package/src/session-runtime/tool-catalog-schema.mjs +197 -0
- package/src/session-runtime/tool-catalog.mjs +6 -483
- package/src/session-runtime/tool-defs.mjs +1 -1
- package/src/standalone/agent-task-status.mjs +1 -1
- package/src/standalone/agent-tool/helpers.mjs +2 -2
- package/src/standalone/channel-admin.mjs +4 -4
- package/src/standalone/explore-tool.mjs +3 -3
- package/src/standalone/hook-bus/config.mjs +1 -1
- package/src/standalone/hook-bus/constants.mjs +1 -1
- package/src/standalone/hook-bus/rules.mjs +1 -1
- package/src/standalone/projects.mjs +1 -1
- package/src/standalone/provider-admin.mjs +2 -2
- package/src/tui/App.jsx +1 -1
- package/src/tui/app/app-format.mjs +2 -2
- package/src/tui/app/clipboard.mjs +3 -3
- package/src/tui/app/input-parsers.mjs +1 -1
- package/src/tui/app/text-layout.mjs +1 -1
- package/src/tui/app/transcript-row-estimate.mjs +360 -0
- package/src/tui/app/transcript-window.mjs +5 -347
- package/src/tui/app/use-mouse-input.mjs +1 -1
- package/src/tui/app/use-prompt-handlers.mjs +1 -1
- package/src/tui/components/tool-execution/surface-detail.mjs +9 -9
- package/src/tui/components/tool-execution/text-format.mjs +2 -2
- package/src/tui/components/tool-output-format.mjs +7 -7
- package/src/tui/display-width.mjs +4 -4
- package/src/tui/dist/index.mjs +187 -99
- package/src/tui/engine/agent-envelope.mjs +5 -5
- package/src/tui/engine/live-share.mjs +100 -0
- package/src/tui/engine/notification-plan.mjs +1 -1
- package/src/tui/engine/queue-helpers.mjs +3 -3
- package/src/tui/engine/render-timing.mjs +4 -5
- package/src/tui/engine/session-api-ext.mjs +6 -3
- package/src/tui/engine/tool-result-status.mjs +5 -5
- package/src/tui/engine/tool-result-text.mjs +1 -1
- package/src/tui/engine/transcript-spill.mjs +585 -0
- package/src/tui/engine/tui-steering-persist.mjs +1 -1
- package/src/tui/engine.mjs +29 -474
- package/src/tui/lib/voice-setup.mjs +1 -1
- package/src/tui/markdown/format-token.mjs +1 -1
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/markdown/table-layout.mjs +4 -4
- package/src/tui/paste-attachments.mjs +1 -1
- package/src/tui/prompt-history-store.mjs +3 -3
- package/src/tui/statusline-ansi-bridge.mjs +2 -2
- package/src/tui/theme.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +2 -2
- package/src/ui/ansi.mjs +0 -9
- package/src/ui/statusline-format.mjs +2 -4
- package/scripts/_bench-cwc.json +0 -20
- package/scripts/_jitter-fuzz.jsx +0 -42
- package/scripts/_jitter-fuzz2.jsx +0 -30
- package/scripts/_jitter-probe.jsx +0 -35
- package/scripts/_jp2.jsx +0 -16
- package/scripts/_smoke_wd.mjs +0 -7
- package/scripts/abort-recovery-test.mjs +0 -175
- package/scripts/agent-dispatch-abort-compose-test.mjs +0 -31
- package/scripts/agent-live-arg-guard-smoke.mjs +0 -20
- package/scripts/agent-live-path-suffix-smoke.mjs +0 -34
- package/scripts/agent-live-toolcall-args-smoke.mjs +0 -45
- package/scripts/agent-loop-policy-test.mjs +0 -37
- package/scripts/agent-model-liveness-test.mjs +0 -763
- package/scripts/agent-parallel-smoke.mjs +0 -435
- package/scripts/agent-route-batch-test.mjs +0 -40
- package/scripts/agent-tag-reuse-smoke.mjs +0 -441
- package/scripts/agent-terminal-reap-test.mjs +0 -252
- package/scripts/agent-trace-io-test.mjs +0 -133
- package/scripts/ansi-color-capability-test.mjs +0 -90
- package/scripts/anthropic-admission-retry-integration-test.mjs +0 -119
- package/scripts/anthropic-maxtokens-test.mjs +0 -119
- package/scripts/anthropic-oauth-refresh-race-test.mjs +0 -397
- package/scripts/anthropic-transport-policy-test.mjs +0 -726
- package/scripts/apply-patch-edit-smoke.mjs +0 -71
- package/scripts/arg-guard-test.mjs +0 -93
- package/scripts/async-notify-settlement-test.mjs +0 -99
- package/scripts/atomic-lock-tryonce-test.mjs +0 -125
- package/scripts/background-task-meta-smoke.mjs +0 -38
- package/scripts/bench-run.mjs +0 -508
- package/scripts/boot-smoke.mjs +0 -137
- package/scripts/build-runtime-windows.ps1 +0 -242
- package/scripts/channel-daemon-smoke.mjs +0 -1103
- package/scripts/code-graph-aggregate-cwd-test.mjs +0 -158
- package/scripts/code-graph-disk-hit-test.mjs +0 -290
- package/scripts/code-graph-dispatch-test.mjs +0 -96
- package/scripts/code-graph-root-federation-test.mjs +0 -273
- package/scripts/compact-active-turn-test.mjs +0 -68
- package/scripts/compact-file-reattach-test.mjs +0 -88
- package/scripts/compact-pressure-test.mjs +0 -788
- package/scripts/compact-prior-context-flatten-test.mjs +0 -252
- package/scripts/compact-recall-digest-test.mjs +0 -57
- package/scripts/compact-smoke.mjs +0 -1017
- package/scripts/compact-trigger-migration-smoke.mjs +0 -261
- package/scripts/compacted-placeholder-scrub-test.mjs +0 -63
- package/scripts/context-mcp-metering-test.mjs +0 -1406
- package/scripts/debounced-skills-async-save-test.mjs +0 -57
- package/scripts/deferred-tool-loading-test.mjs +0 -250
- package/scripts/desktop-session-bridge-test.mjs +0 -1013
- package/scripts/dispatch-persist-recovery-test.mjs +0 -141
- package/scripts/embedding-worker-exit-test.mjs +0 -76
- package/scripts/execution-completion-dedup-test.mjs +0 -205
- package/scripts/execution-pending-resume-kick-test.mjs +0 -151
- package/scripts/execution-resume-esc-integration-test.mjs +0 -176
- package/scripts/explore-bench-tmp.mjs +0 -36
- package/scripts/explore-bench.mjs +0 -248
- package/scripts/explore-prompt-policy-test.mjs +0 -256
- package/scripts/explore-timeout-cancel-test.mjs +0 -345
- package/scripts/find-fuzzy-hidden-test.mjs +0 -267
- package/scripts/forwarder-rebind-tail-test.mjs +0 -67
- package/scripts/freevar-smoke.mjs +0 -98
- package/scripts/gemini-provider-test.mjs +0 -1448
- package/scripts/generate-oc-icons.mjs +0 -11
- package/scripts/grok-oauth-refresh-race-test.mjs +0 -273
- package/scripts/headless-pristine-execution-test.mjs +0 -614
- package/scripts/hook-bus-test.mjs +0 -552
- package/scripts/ingest-pure-conversation-smoke.mjs +0 -175
- package/scripts/internal-comms-bench-test.mjs +0 -226
- package/scripts/internal-comms-bench.mjs +0 -853
- package/scripts/internal-comms-smoke.mjs +0 -277
- package/scripts/internal-tools-normalization-test.mjs +0 -62
- package/scripts/interrupted-turn-history-test.mjs +0 -399
- package/scripts/lead-workflow-smoke.mjs +0 -592
- package/scripts/lifecycle-api-test.mjs +0 -137
- package/scripts/live-share-test.mjs +0 -148
- package/scripts/live-worker-smoke.mjs +0 -333
- package/scripts/log-writer-guard-smoke.mjs +0 -131
- package/scripts/maintenance-default-routes-test.mjs +0 -164
- package/scripts/max-output-recovery-persist-test.mjs +0 -81
- package/scripts/max-output-recovery-test.mjs +0 -368
- package/scripts/mcp-client-normalization-test.mjs +0 -45
- package/scripts/mcp-grace-deferred-test.mjs +0 -225
- package/scripts/memory-core-input-test.mjs +0 -167
- package/scripts/memory-cycle-routing-test.mjs +0 -111
- package/scripts/memory-meta-concurrency-test.mjs +0 -20
- package/scripts/memory-pg-recovery-test.mjs +0 -59
- package/scripts/memory-rule-contract-test.mjs +0 -93
- package/scripts/model-list-sanitize-test.mjs +0 -37
- package/scripts/mouse-tracking-restore-smoke.mjs +0 -107
- package/scripts/native-edit-wire-test.mjs +0 -152
- package/scripts/notify-completion-mirror-test.mjs +0 -73
- package/scripts/openai-oauth-refresh-race-test.mjs +0 -120
- package/scripts/openai-oauth-ws-1006-retry-test.mjs +0 -954
- package/scripts/openai-ws-early-settle-test.mjs +0 -216
- package/scripts/output-style-bench.mjs +0 -292
- package/scripts/output-style-smoke.mjs +0 -145
- package/scripts/parent-abort-link-test.mjs +0 -90
- package/scripts/patch-binary-cache-test.mjs +0 -181
- package/scripts/path-suffix-test.mjs +0 -57
- package/scripts/pending-completion-drop-test.mjs +0 -239
- package/scripts/pending-messages-lock-nonblocking-test.mjs +0 -62
- package/scripts/pretool-ask-runtime-test.mjs +0 -54
- package/scripts/process-lifecycle-test.mjs +0 -461
- package/scripts/prompt-immediate-render-test.mjs +0 -89
- package/scripts/prompt-input-parity-test.mjs +0 -145
- package/scripts/provider-admission-scheduler-test.mjs +0 -681
- package/scripts/provider-contract-test.mjs +0 -632
- package/scripts/provider-stream-stall-test.mjs +0 -276
- package/scripts/provider-toolcall-test.mjs +0 -3063
- package/scripts/reactive-compact-persist-smoke.mjs +0 -203
- package/scripts/recall-bench.mjs +0 -359
- package/scripts/resource-admission-test.mjs +0 -792
- package/scripts/result-classification-test.mjs +0 -75
- package/scripts/rg-runner-test.mjs +0 -240
- package/scripts/routing-corpus-test.mjs +0 -349
- package/scripts/sanitize-tool-pairs-test.mjs +0 -260
- package/scripts/session-bench-cache-break-test.mjs +0 -102
- package/scripts/session-bench.mjs +0 -1708
- package/scripts/session-context-bench.mjs +0 -344
- package/scripts/session-heartbeat-lifecycle-test.mjs +0 -68
- package/scripts/session-ingest-compaction-smoke.mjs +0 -279
- package/scripts/session-ingest-smoke.mjs +0 -177
- package/scripts/session-orphan-sweep-test.mjs +0 -109
- package/scripts/set-effort-config-test.mjs +0 -41
- package/scripts/shell-failure-diagnostics-test.mjs +0 -280
- package/scripts/shell-hardening-test.mjs +0 -209
- package/scripts/shell-jobs-windows-hide-test.mjs +0 -164
- package/scripts/ship-mode-test.mjs +0 -98
- package/scripts/smoke-loop-failure-summary-test.mjs +0 -38
- package/scripts/smoke-loop-failure-summary.mjs +0 -16
- package/scripts/smoke-loop-report.mjs +0 -221
- package/scripts/smoke-loop.mjs +0 -202
- package/scripts/smoke-runtime-negative.ps1 +0 -106
- package/scripts/statusline-quota-hysteresis-test.mjs +0 -62
- package/scripts/steering-drain-buckets-test.mjs +0 -467
- package/scripts/steering-fold-provenance-test.mjs +0 -71
- package/scripts/streaming-tail-window-test.mjs +0 -175
- package/scripts/submit-commandbusy-race-test.mjs +0 -257
- package/scripts/task-bench.mjs +0 -205
- package/scripts/terminal-bench-isolation-guards-test.mjs +0 -102
- package/scripts/termio-input-smoke.mjs +0 -199
- package/scripts/tool-result-hook-test.mjs +0 -48
- package/scripts/tool-smoke.mjs +0 -2453
- package/scripts/tool-tui-presentation-test.mjs +0 -286
- package/scripts/toolcall-args-test.mjs +0 -239
- package/scripts/tui-ambiguous-width-test.mjs +0 -113
- package/scripts/tui-background-failure-smoke.mjs +0 -73
- package/scripts/tui-perf-run.ps1 +0 -26
- package/scripts/tui-render-smoke.mjs +0 -90
- package/scripts/tui-runtime-load-bench-entry.jsx +0 -608
- package/scripts/tui-runtime-load-bench.mjs +0 -50
- package/scripts/tui-store-frame-batch-test.mjs +0 -99
- package/scripts/tui-transcript-jitter-harness-entry.jsx +0 -383
- package/scripts/tui-transcript-perf-test.mjs +0 -934
- package/scripts/usage-metrics-epoch-smoke.mjs +0 -114
- package/scripts/verify-release-assets-test.mjs +0 -281
- package/scripts/web-fetch-routing-test.mjs +0 -158
- package/scripts/webhook-smoke.mjs +0 -201
- package/scripts/windows-hide-spawn-options-test.mjs +0 -19
- package/scripts/worker-notify-rejection-test.mjs +0 -51
- package/scripts/write-backpressure-test.mjs +0 -147
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { createRequire } from 'node:module';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const debug = require('../src/lib/mixdog-debug.cjs');
|
|
9
|
-
|
|
10
|
-
const MODE_ENVS = [
|
|
11
|
-
'MIXDOG_MODE',
|
|
12
|
-
'MIXDOG_SHIP',
|
|
13
|
-
'MIXDOG_DIAGNOSTICS',
|
|
14
|
-
'MIXDOG_DEBUG',
|
|
15
|
-
'MIXDOG_DEBUG_SESSION_START',
|
|
16
|
-
'MIXDOG_AGENT_TRACE_LOCAL_DISABLE',
|
|
17
|
-
'MIXDOG_AGENT_TRACE_PATH',
|
|
18
|
-
'MIXDOG_TOOL_FAILURE_LOG_DISABLE',
|
|
19
|
-
'MIXDOG_TOOL_FAILURE_LOG_PATH',
|
|
20
|
-
];
|
|
21
|
-
|
|
22
|
-
function withEnv(overrides, fn) {
|
|
23
|
-
const prev = {};
|
|
24
|
-
for (const k of MODE_ENVS) prev[k] = process.env[k];
|
|
25
|
-
for (const k of MODE_ENVS) delete process.env[k];
|
|
26
|
-
for (const [k, v] of Object.entries(overrides)) process.env[k] = v;
|
|
27
|
-
try { return fn(); }
|
|
28
|
-
finally {
|
|
29
|
-
for (const k of MODE_ENVS) {
|
|
30
|
-
if (prev[k] == null) delete process.env[k];
|
|
31
|
-
else process.env[k] = prev[k];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
test('MIXDOG_MODE=ship forces shipping mode with diagnostics off', () => {
|
|
37
|
-
withEnv({ MIXDOG_MODE: 'ship' }, () => {
|
|
38
|
-
assert.equal(debug.resolveMixdogMode(), 'ship');
|
|
39
|
-
assert.equal(debug.isShippingMode(), true);
|
|
40
|
-
assert.equal(debug.isDevMode(), false);
|
|
41
|
-
assert.equal(debug.isDiagnosticIOEnabled(), false);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test('MIXDOG_MODE=dev forces dev mode with diagnostics on', () => {
|
|
46
|
-
withEnv({ MIXDOG_MODE: 'dev' }, () => {
|
|
47
|
-
assert.equal(debug.resolveMixdogMode(), 'dev');
|
|
48
|
-
assert.equal(debug.isDiagnosticIOEnabled(), true);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test('MIXDOG_DEBUG implies dev mode', () => {
|
|
53
|
-
withEnv({ MIXDOG_MODE: 'ship', MIXDOG_DEBUG: '1' }, () => {
|
|
54
|
-
// explicit MIXDOG_MODE=ship still wins over debug flag by precedence
|
|
55
|
-
assert.equal(debug.resolveMixdogMode(), 'ship');
|
|
56
|
-
});
|
|
57
|
-
withEnv({ MIXDOG_DEBUG: '1' }, () => {
|
|
58
|
-
assert.equal(debug.resolveMixdogMode(), 'dev');
|
|
59
|
-
assert.equal(debug.isDiagnosticIOEnabled(), true);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test('MIXDOG_DIAGNOSTICS force-enables diagnostic IO under shipping', () => {
|
|
64
|
-
withEnv({ MIXDOG_MODE: 'ship', MIXDOG_DIAGNOSTICS: '1' }, () => {
|
|
65
|
-
assert.equal(debug.isShippingMode(), true);
|
|
66
|
-
assert.equal(debug.isDiagnosticIOEnabled(), true);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('shipping mode suppresses default diagnostic file paths', async () => {
|
|
71
|
-
const io = await import('../src/runtime/agent/orchestrator/agent-trace-io.mjs?ship-default');
|
|
72
|
-
withEnv({ MIXDOG_MODE: 'ship' }, () => {
|
|
73
|
-
assert.equal(io._resolveLocalTracePath(), null);
|
|
74
|
-
assert.equal(io._resolveToolFailurePath(), null);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test('explicit diagnostic file paths opt in under shipping mode', async () => {
|
|
79
|
-
const io = await import('../src/runtime/agent/orchestrator/agent-trace-io.mjs?ship-explicit-path');
|
|
80
|
-
const base = join(tmpdir(), `mixdog-ship-mode-test-${process.pid}`);
|
|
81
|
-
const tracePath = join(base, 'explicit-agent-trace.jsonl');
|
|
82
|
-
const failuresPath = join(base, 'explicit-tool-failures.jsonl');
|
|
83
|
-
withEnv({
|
|
84
|
-
MIXDOG_MODE: 'ship',
|
|
85
|
-
MIXDOG_AGENT_TRACE_PATH: tracePath,
|
|
86
|
-
MIXDOG_TOOL_FAILURE_LOG_PATH: failuresPath,
|
|
87
|
-
}, () => {
|
|
88
|
-
assert.equal(io._resolveLocalTracePath(), tracePath);
|
|
89
|
-
assert.equal(io._resolveToolFailurePath(), failuresPath);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('git checkout default stays dev for local diagnostics', () => {
|
|
94
|
-
withEnv({}, () => {
|
|
95
|
-
assert.equal(debug.resolveMixdogMode(), 'dev');
|
|
96
|
-
assert.equal(debug.isDiagnosticIOEnabled(), true);
|
|
97
|
-
});
|
|
98
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { actionableFailureCount } from './smoke-loop-failure-summary.mjs';
|
|
4
|
-
|
|
5
|
-
test('returns a numeric actionable failure count', () => {
|
|
6
|
-
assert.equal(actionableFailureCount('{"actionable_failures":{"matched":0}}'), 0);
|
|
7
|
-
assert.equal(actionableFailureCount('{"actionable_failures":{"matched":1}}'), 1);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('rejects malformed tool-failures JSON', () => {
|
|
11
|
-
assert.throws(
|
|
12
|
-
() => actionableFailureCount('{'),
|
|
13
|
-
/tool failures returned malformed JSON/,
|
|
14
|
-
);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test('rejects a missing or malformed actionable failure count', () => {
|
|
18
|
-
assert.throws(
|
|
19
|
-
() => actionableFailureCount('{}'),
|
|
20
|
-
/tool failures returned malformed result schema/,
|
|
21
|
-
);
|
|
22
|
-
assert.throws(
|
|
23
|
-
() => actionableFailureCount('{"actionable_failures":{"matched":"0"}}'),
|
|
24
|
-
/tool failures returned malformed result schema/,
|
|
25
|
-
);
|
|
26
|
-
assert.throws(
|
|
27
|
-
() => actionableFailureCount('{"actionable_failures":{"matched":-1}}'),
|
|
28
|
-
/tool failures returned malformed result schema/,
|
|
29
|
-
);
|
|
30
|
-
assert.throws(
|
|
31
|
-
() => actionableFailureCount('{"actionable_failures":{"matched":0.5}}'),
|
|
32
|
-
/tool failures returned malformed result schema/,
|
|
33
|
-
);
|
|
34
|
-
assert.throws(
|
|
35
|
-
() => actionableFailureCount('{"actionable_failures":{"matched":1e999}}'),
|
|
36
|
-
/tool failures returned malformed result schema/,
|
|
37
|
-
);
|
|
38
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function actionableFailureCount(stdout) {
|
|
2
|
-
let summary;
|
|
3
|
-
try {
|
|
4
|
-
summary = JSON.parse(stdout);
|
|
5
|
-
} catch {
|
|
6
|
-
throw new Error(`tool failures returned malformed JSON:\n${stdout}`);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const matched = summary?.actionable_failures?.matched;
|
|
10
|
-
if (!Number.isInteger(matched) || matched < 0) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
`tool failures returned malformed result schema: expected actionable_failures.matched to be a non-negative integer:\n${stdout}`,
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
return matched;
|
|
16
|
-
}
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
4
|
-
|
|
5
|
-
function argValue(name, fallback = null) {
|
|
6
|
-
const idx = process.argv.indexOf(name);
|
|
7
|
-
if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
|
|
8
|
-
const prefix = `${name}=`;
|
|
9
|
-
const hit = process.argv.find((arg) => arg.startsWith(prefix));
|
|
10
|
-
return hit ? hit.slice(prefix.length) : fallback;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function parseNumber(value, fallback = null) {
|
|
14
|
-
if (value == null || value === '') return fallback;
|
|
15
|
-
const n = Number(value);
|
|
16
|
-
return Number.isFinite(n) ? n : fallback;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function parseDuration(value, fallback = null) {
|
|
20
|
-
const raw = String(value || '').trim();
|
|
21
|
-
if (!raw) return fallback;
|
|
22
|
-
if (/^\d+$/.test(raw)) return Number(raw);
|
|
23
|
-
const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/i);
|
|
24
|
-
if (!match) throw new Error(`invalid duration: ${raw}`);
|
|
25
|
-
const n = Number(match[1]);
|
|
26
|
-
const unit = match[2].toLowerCase();
|
|
27
|
-
const mult = unit === 'ms' ? 1 : unit === 's' ? 1000 : unit === 'm' ? 60_000 : 3_600_000;
|
|
28
|
-
return Math.max(1, Math.floor(n * mult));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function argValues(name) {
|
|
32
|
-
const values = [];
|
|
33
|
-
const prefix = `${name}=`;
|
|
34
|
-
for (let i = 0; i < process.argv.length; i += 1) {
|
|
35
|
-
const arg = process.argv[i];
|
|
36
|
-
if (arg === name && i + 1 < process.argv.length) values.push(process.argv[i + 1]);
|
|
37
|
-
else if (arg.startsWith(prefix)) values.push(arg.slice(prefix.length));
|
|
38
|
-
}
|
|
39
|
-
return values;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function parseStepCaps(values) {
|
|
43
|
-
const caps = new Map();
|
|
44
|
-
for (const value of values) {
|
|
45
|
-
const raw = String(value || '').trim();
|
|
46
|
-
if (!raw) continue;
|
|
47
|
-
const idx = raw.lastIndexOf('=');
|
|
48
|
-
if (idx <= 0) throw new Error(`invalid --max-step-ms value: ${raw}`);
|
|
49
|
-
const name = raw.slice(0, idx).trim().replace(/^scripts\//, '');
|
|
50
|
-
const cap = Number(raw.slice(idx + 1).trim());
|
|
51
|
-
if (!name || !Number.isFinite(cap) || cap < 0) throw new Error(`invalid --max-step-ms value: ${raw}`);
|
|
52
|
-
caps.set(name, cap);
|
|
53
|
-
}
|
|
54
|
-
return caps;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function summarize(values) {
|
|
58
|
-
if (!values.length) return { min: 0, max: 0, avg: 0 };
|
|
59
|
-
const min = Math.min(...values);
|
|
60
|
-
const max = Math.max(...values);
|
|
61
|
-
const avg = values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
62
|
-
return {
|
|
63
|
-
min: Math.round(min * 10) / 10,
|
|
64
|
-
max: Math.round(max * 10) / 10,
|
|
65
|
-
avg: Math.round(avg * 10) / 10,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function readRows(path) {
|
|
70
|
-
if (!existsSync(path)) throw new Error(`smoke loop log not found: ${path}`);
|
|
71
|
-
return readFileSync(path, 'utf8')
|
|
72
|
-
.split(/\r?\n/)
|
|
73
|
-
.filter(Boolean)
|
|
74
|
-
.map((line, index) => {
|
|
75
|
-
try {
|
|
76
|
-
return JSON.parse(line);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
return { type: 'parse_error', line: index + 1, error: error?.message || String(error), raw: line };
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function formatDuration(ms) {
|
|
84
|
-
const total = Math.max(0, Math.round(Number(ms) || 0));
|
|
85
|
-
const h = Math.floor(total / 3_600_000);
|
|
86
|
-
const m = Math.floor((total % 3_600_000) / 60_000);
|
|
87
|
-
const s = Math.floor((total % 60_000) / 1000);
|
|
88
|
-
if (h > 0) return `${h}h ${m}m ${s}s`;
|
|
89
|
-
if (m > 0) return `${m}m ${s}s`;
|
|
90
|
-
return `${s}s`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function summarizeSteps(iterations) {
|
|
94
|
-
const byScript = new Map();
|
|
95
|
-
for (const row of iterations) {
|
|
96
|
-
if (!Array.isArray(row.steps)) continue;
|
|
97
|
-
for (const step of row.steps) {
|
|
98
|
-
const script = String(step?.script || '').replace(/^scripts\//, '');
|
|
99
|
-
const ms = Number(step?.ms);
|
|
100
|
-
if (!script || !Number.isFinite(ms)) continue;
|
|
101
|
-
const values = byScript.get(script) || [];
|
|
102
|
-
values.push(ms);
|
|
103
|
-
byScript.set(script, values);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return Object.fromEntries([...byScript.entries()].map(([script, values]) => [script, summarize(values)]));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const logPath = resolve(argValue('--log', '.mixdog/data/history/smoke-loop.jsonl'));
|
|
110
|
-
const pidArg = parseNumber(argValue('--pid', null), null);
|
|
111
|
-
const minIterations = parseNumber(argValue('--min-iterations', null), null);
|
|
112
|
-
const minElapsedMs = parseDuration(argValue('--min-elapsed', null), null);
|
|
113
|
-
const maxGapMs = parseDuration(argValue('--max-gap', null), null);
|
|
114
|
-
const maxStaleMs = parseDuration(argValue('--max-stale', null), null);
|
|
115
|
-
const maxSmokeMs = parseNumber(argValue('--max-smoke-ms', null), null);
|
|
116
|
-
const maxAvgSmokeMs = parseNumber(argValue('--max-avg-smoke-ms', null), null);
|
|
117
|
-
const maxStepMs = parseStepCaps(argValues('--max-step-ms'));
|
|
118
|
-
const maxRssMb = parseNumber(argValue('--max-rss-mb', null), null);
|
|
119
|
-
const maxRssGrowthMb = parseNumber(argValue('--max-rss-growth-mb', null), null);
|
|
120
|
-
const jsonMode = process.argv.includes('--json');
|
|
121
|
-
const requireComplete = process.argv.includes('--require-complete');
|
|
122
|
-
|
|
123
|
-
const rows = readRows(logPath);
|
|
124
|
-
const startRows = rows.filter((row) => row?.type === 'start' && (pidArg == null || Number(row.pid) === pidArg));
|
|
125
|
-
const start = startRows.at(-1);
|
|
126
|
-
if (!start) throw new Error(pidArg == null ? 'no smoke loop start row found' : `no smoke loop start row found for pid ${pidArg}`);
|
|
127
|
-
|
|
128
|
-
const startIndex = rows.lastIndexOf(start);
|
|
129
|
-
const runRows = rows.slice(startIndex).filter((row) => Number(row.pid) === Number(start.pid));
|
|
130
|
-
const iterations = runRows.filter((row) => row?.type === 'iteration');
|
|
131
|
-
const errors = runRows.filter((row) => row?.type === 'error' || row?.type === 'parse_error');
|
|
132
|
-
const summaryRows = runRows.filter((row) => row?.type === 'summary');
|
|
133
|
-
const last = iterations.at(-1) || null;
|
|
134
|
-
const smoke = summarize(iterations.map((row) => Number(row.smoke_ms)).filter(Number.isFinite));
|
|
135
|
-
const stepMs = summarizeSteps(iterations);
|
|
136
|
-
const rss = summarize(iterations.map((row) => Number(row.rss_mb)).filter(Number.isFinite));
|
|
137
|
-
const startRss = Number(start.rss_mb);
|
|
138
|
-
const lastRss = Number(last?.rss_mb);
|
|
139
|
-
const rssGrowth = Number.isFinite(startRss) && Number.isFinite(lastRss)
|
|
140
|
-
? Math.round((lastRss - startRss) * 10) / 10
|
|
141
|
-
: 0;
|
|
142
|
-
const elapsedMs = Number(last?.elapsed_ms || summaryRows.at(-1)?.elapsed_ms || 0);
|
|
143
|
-
const durationMs = Number(start.duration_ms || 0);
|
|
144
|
-
const remainingMs = durationMs > 0 ? Math.max(0, durationMs - elapsedMs) : null;
|
|
145
|
-
const startTs = Date.parse(start.ts);
|
|
146
|
-
const finishAt = durationMs > 0 && Number.isFinite(startTs)
|
|
147
|
-
? new Date(startTs + durationMs).toISOString()
|
|
148
|
-
: null;
|
|
149
|
-
const iterationsPerHour = elapsedMs > 0
|
|
150
|
-
? Math.round((iterations.length / (elapsedMs / 3_600_000)) * 10) / 10
|
|
151
|
-
: 0;
|
|
152
|
-
const gaps = [];
|
|
153
|
-
for (let i = 1; i < iterations.length; i += 1) {
|
|
154
|
-
const prev = Date.parse(iterations[i - 1].ts);
|
|
155
|
-
const cur = Date.parse(iterations[i].ts);
|
|
156
|
-
if (Number.isFinite(prev) && Number.isFinite(cur)) gaps.push(cur - prev);
|
|
157
|
-
}
|
|
158
|
-
const gapSummary = summarize(gaps);
|
|
159
|
-
const lastTs = Date.parse(last?.ts || '');
|
|
160
|
-
const staleMs = Number.isFinite(lastTs) ? Date.now() - lastTs : null;
|
|
161
|
-
|
|
162
|
-
const failures = [];
|
|
163
|
-
if (errors.length > 0) failures.push(`errors=${errors.length}`);
|
|
164
|
-
if (requireComplete && summaryRows.length === 0) failures.push('loop has no completed summary row');
|
|
165
|
-
if (minIterations != null && iterations.length < minIterations) failures.push(`iterations ${iterations.length} < ${minIterations}`);
|
|
166
|
-
if (minElapsedMs != null && elapsedMs < minElapsedMs) failures.push(`elapsed ${formatDuration(elapsedMs)} < ${formatDuration(minElapsedMs)}`);
|
|
167
|
-
if (maxGapMs != null && gapSummary.max > maxGapMs) failures.push(`max gap ${formatDuration(gapSummary.max)} > ${formatDuration(maxGapMs)}`);
|
|
168
|
-
if (maxStaleMs != null && staleMs != null && staleMs > maxStaleMs) failures.push(`latest iteration stale ${formatDuration(staleMs)} > ${formatDuration(maxStaleMs)}`);
|
|
169
|
-
if (maxSmokeMs != null && smoke.max > maxSmokeMs) failures.push(`smoke max ${smoke.max}ms > ${maxSmokeMs}ms`);
|
|
170
|
-
if (maxAvgSmokeMs != null && smoke.avg > maxAvgSmokeMs) failures.push(`smoke avg ${smoke.avg}ms > ${maxAvgSmokeMs}ms`);
|
|
171
|
-
for (const [script, cap] of maxStepMs.entries()) {
|
|
172
|
-
const stats = stepMs[script];
|
|
173
|
-
if (stats && stats.max > cap) failures.push(`${script} max ${stats.max}ms > ${cap}ms`);
|
|
174
|
-
}
|
|
175
|
-
if (maxRssMb != null && rss.max > maxRssMb) failures.push(`rss max ${rss.max}MB > ${maxRssMb}MB`);
|
|
176
|
-
if (maxRssGrowthMb != null && rssGrowth > maxRssGrowthMb) failures.push(`rss growth ${rssGrowth}MB > ${maxRssGrowthMb}MB`);
|
|
177
|
-
|
|
178
|
-
const report = {
|
|
179
|
-
ok: failures.length === 0,
|
|
180
|
-
pid: start.pid,
|
|
181
|
-
started_at: start.ts,
|
|
182
|
-
finish_at: finishAt,
|
|
183
|
-
elapsed_ms: elapsedMs,
|
|
184
|
-
elapsed: formatDuration(elapsedMs),
|
|
185
|
-
remaining_ms: remainingMs,
|
|
186
|
-
remaining: remainingMs == null ? null : formatDuration(remainingMs),
|
|
187
|
-
min_elapsed_ms: minElapsedMs,
|
|
188
|
-
iterations: iterations.length,
|
|
189
|
-
iterations_per_hour: iterationsPerHour,
|
|
190
|
-
duration_ms: start.duration_ms,
|
|
191
|
-
interval_ms: start.interval_ms,
|
|
192
|
-
smoke_ms: smoke,
|
|
193
|
-
step_ms: stepMs,
|
|
194
|
-
max_step_ms: Object.fromEntries(maxStepMs.entries()),
|
|
195
|
-
rss_mb: rss,
|
|
196
|
-
rss_growth_mb: rssGrowth,
|
|
197
|
-
gap_ms: gapSummary,
|
|
198
|
-
stale_ms: staleMs,
|
|
199
|
-
errors: errors.length,
|
|
200
|
-
completed: summaryRows.length > 0,
|
|
201
|
-
require_complete: requireComplete,
|
|
202
|
-
latest_iteration: last?.iteration || 0,
|
|
203
|
-
failures,
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
if (jsonMode) {
|
|
207
|
-
console.log(JSON.stringify(report, null, 2));
|
|
208
|
-
} else {
|
|
209
|
-
console.log(`smoke loop report pid=${report.pid} ok=${report.ok}`);
|
|
210
|
-
console.log(`started=${report.started_at} finish=${report.finish_at || '-'} elapsed=${report.elapsed} remaining=${report.remaining || '-'} iterations=${report.iterations} rate=${iterationsPerHour}/h completed=${report.completed}`);
|
|
211
|
-
console.log(`smoke_ms min=${smoke.min} avg=${smoke.avg} max=${smoke.max}`);
|
|
212
|
-
for (const [script, stats] of Object.entries(stepMs)) {
|
|
213
|
-
console.log(`${script} min=${stats.min} avg=${stats.avg} max=${stats.max}`);
|
|
214
|
-
}
|
|
215
|
-
console.log(`rss_mb min=${rss.min} avg=${rss.avg} max=${rss.max} growth=${rssGrowth}`);
|
|
216
|
-
console.log(`gap_ms min=${gapSummary.min} avg=${gapSummary.avg} max=${gapSummary.max} stale=${staleMs == null ? '-' : staleMs}`);
|
|
217
|
-
console.log(`errors=${errors.length}`);
|
|
218
|
-
if (failures.length) console.log(`failures: ${failures.join('; ')}`);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (failures.length) process.exit(1);
|
package/scripts/smoke-loop.mjs
DELETED
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { appendFileSync, mkdirSync } from 'node:fs';
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
4
|
-
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { actionableFailureCount } from './smoke-loop-failure-summary.mjs';
|
|
7
|
-
|
|
8
|
-
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
9
|
-
const DEFAULT_DURATION_MS = 5 * 60 * 60 * 1000;
|
|
10
|
-
|
|
11
|
-
function argValue(name, fallback = null) {
|
|
12
|
-
const idx = process.argv.indexOf(name);
|
|
13
|
-
if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
|
|
14
|
-
const prefix = `${name}=`;
|
|
15
|
-
const hit = process.argv.find((arg) => arg.startsWith(prefix));
|
|
16
|
-
return hit ? hit.slice(prefix.length) : fallback;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function argFlag(name) {
|
|
20
|
-
return process.argv.includes(name);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function parseDuration(value, fallback) {
|
|
24
|
-
const raw = String(value || '').trim();
|
|
25
|
-
if (!raw) return fallback;
|
|
26
|
-
if (/^\d+$/.test(raw)) return Number(raw);
|
|
27
|
-
const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/i);
|
|
28
|
-
if (!match) throw new Error(`invalid duration: ${raw}`);
|
|
29
|
-
const n = Number(match[1]);
|
|
30
|
-
const unit = match[2].toLowerCase();
|
|
31
|
-
const mult = unit === 'ms' ? 1 : unit === 's' ? 1000 : unit === 'm' ? 60_000 : 3_600_000;
|
|
32
|
-
return Math.max(1, Math.floor(n * mult));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function resolveOptionalPath(value, fallback) {
|
|
36
|
-
const raw = String(value || '').trim();
|
|
37
|
-
const picked = raw || fallback;
|
|
38
|
-
if (!picked) return null;
|
|
39
|
-
return isAbsolute(picked) ? picked : resolve(root, picked);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function runNode(args, label, timeoutMs = 180_000) {
|
|
43
|
-
const startedAt = performance.now();
|
|
44
|
-
const result = spawnSync(process.execPath, args, {
|
|
45
|
-
cwd: root,
|
|
46
|
-
encoding: 'utf8',
|
|
47
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
48
|
-
timeout: timeoutMs,
|
|
49
|
-
windowsHide: true,
|
|
50
|
-
});
|
|
51
|
-
const ms = performance.now() - startedAt;
|
|
52
|
-
if (result.status !== 0) {
|
|
53
|
-
const out = `${result.error ? `${result.error}\n` : ''}${result.stdout || ''}${result.stderr || ''}`.trim();
|
|
54
|
-
throw new Error(`${label} failed in ${ms.toFixed(1)}ms:\n${out}`);
|
|
55
|
-
}
|
|
56
|
-
return { ms, stdout: result.stdout || '', stderr: result.stderr || '' };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function runSmokeAll(iteration) {
|
|
60
|
-
let totalMs = 0;
|
|
61
|
-
const steps = [];
|
|
62
|
-
for (const script of ['scripts/smoke.mjs', 'scripts/boot-smoke.mjs']) {
|
|
63
|
-
const result = runNode([script], `${script} iteration ${iteration}`);
|
|
64
|
-
totalMs += result.ms;
|
|
65
|
-
steps.push({
|
|
66
|
-
script,
|
|
67
|
-
ms: Math.round(result.ms * 10) / 10,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
return { ms: totalMs, steps };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function sleep(ms) {
|
|
74
|
-
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function rssMb() {
|
|
78
|
-
return Math.round((process.memoryUsage().rss / 1024 / 1024) * 10) / 10;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function summarize(values) {
|
|
82
|
-
if (!values.length) return { min: 0, max: 0, avg: 0 };
|
|
83
|
-
const min = Math.min(...values);
|
|
84
|
-
const max = Math.max(...values);
|
|
85
|
-
const avg = values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
86
|
-
return {
|
|
87
|
-
min: Math.round(min * 10) / 10,
|
|
88
|
-
max: Math.round(max * 10) / 10,
|
|
89
|
-
avg: Math.round(avg * 10) / 10,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function serializeError(error) {
|
|
94
|
-
return {
|
|
95
|
-
name: error?.name || 'Error',
|
|
96
|
-
message: error?.message || String(error),
|
|
97
|
-
stack: error?.stack || null,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const durationMs = parseDuration(argValue('--duration', process.env.MIXDOG_SMOKE_LOOP_DURATION), DEFAULT_DURATION_MS);
|
|
102
|
-
const intervalMs = parseDuration(argValue('--interval', process.env.MIXDOG_SMOKE_LOOP_INTERVAL), 0);
|
|
103
|
-
const maxIterations = Number(argValue('--iterations', process.env.MIXDOG_SMOKE_LOOP_ITERATIONS || 0)) || Infinity;
|
|
104
|
-
const logPath = argFlag('--no-log')
|
|
105
|
-
? null
|
|
106
|
-
: resolveOptionalPath(
|
|
107
|
-
argValue('--log', process.env.MIXDOG_SMOKE_LOOP_LOG),
|
|
108
|
-
'.mixdog/data/history/smoke-loop.jsonl',
|
|
109
|
-
);
|
|
110
|
-
const startedAt = Date.now();
|
|
111
|
-
const since = new Date(startedAt).toISOString();
|
|
112
|
-
const deadline = startedAt + durationMs;
|
|
113
|
-
let iteration = 0;
|
|
114
|
-
const smokeTimes = [];
|
|
115
|
-
const rssSamples = [];
|
|
116
|
-
|
|
117
|
-
function writeLoopLog(row) {
|
|
118
|
-
if (!logPath) return;
|
|
119
|
-
mkdirSync(dirname(logPath), { recursive: true });
|
|
120
|
-
appendFileSync(logPath, `${JSON.stringify({
|
|
121
|
-
ts: new Date().toISOString(),
|
|
122
|
-
pid: process.pid,
|
|
123
|
-
...row,
|
|
124
|
-
})}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function writeFatalLog(error) {
|
|
128
|
-
writeLoopLog({
|
|
129
|
-
type: 'error',
|
|
130
|
-
iteration,
|
|
131
|
-
elapsed_ms: Date.now() - startedAt,
|
|
132
|
-
error: serializeError(error),
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
process.on('uncaughtException', (error) => {
|
|
137
|
-
writeFatalLog(error);
|
|
138
|
-
process.stderr.write(`${error?.stack || error}\n`);
|
|
139
|
-
process.exit(1);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
process.on('unhandledRejection', (reason) => {
|
|
143
|
-
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
144
|
-
writeFatalLog(error);
|
|
145
|
-
process.stderr.write(`${error.stack || error}\n`);
|
|
146
|
-
process.exit(1);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
const startRss = rssMb();
|
|
150
|
-
writeLoopLog({
|
|
151
|
-
type: 'start',
|
|
152
|
-
duration_ms: durationMs,
|
|
153
|
-
interval_ms: intervalMs,
|
|
154
|
-
max_iterations: Number.isFinite(maxIterations) ? maxIterations : null,
|
|
155
|
-
since,
|
|
156
|
-
rss_mb: startRss,
|
|
157
|
-
});
|
|
158
|
-
process.stdout.write(`smoke loop start duration=${durationMs}ms interval=${intervalMs}ms since=${since} rss_mb=${startRss} log=${logPath || 'off'}\n`);
|
|
159
|
-
|
|
160
|
-
while (Date.now() < deadline && iteration < maxIterations) {
|
|
161
|
-
iteration += 1;
|
|
162
|
-
const iterStartedAt = Date.now();
|
|
163
|
-
const smoke = runSmokeAll(iteration);
|
|
164
|
-
smokeTimes.push(smoke.ms);
|
|
165
|
-
const failure = runNode(['scripts/tool-failures.mjs', '--since', since, '--limit', '1', '--json'], `failures iteration ${iteration}`, 60_000);
|
|
166
|
-
if (actionableFailureCount(failure.stdout) > 0) {
|
|
167
|
-
throw new Error(`tool failures appeared after loop start:\n${failure.stdout}`);
|
|
168
|
-
}
|
|
169
|
-
const currentRss = rssMb();
|
|
170
|
-
rssSamples.push(currentRss);
|
|
171
|
-
const elapsedMs = Date.now() - startedAt;
|
|
172
|
-
writeLoopLog({
|
|
173
|
-
type: 'iteration',
|
|
174
|
-
iteration,
|
|
175
|
-
smoke_ms: Math.round(smoke.ms * 10) / 10,
|
|
176
|
-
steps: smoke.steps,
|
|
177
|
-
rss_mb: currentRss,
|
|
178
|
-
elapsed_ms: elapsedMs,
|
|
179
|
-
});
|
|
180
|
-
const stepSummary = smoke.steps.map((step) => `${step.script.replace(/^scripts\//, '')}=${step.ms}ms`).join(' ');
|
|
181
|
-
process.stdout.write(`iteration ${iteration} ok smoke_ms=${smoke.ms.toFixed(1)} ${stepSummary} rss_mb=${currentRss} elapsed_ms=${elapsedMs}\n`);
|
|
182
|
-
const remaining = deadline - Date.now();
|
|
183
|
-
if (remaining <= 0 || iteration >= maxIterations) break;
|
|
184
|
-
if (intervalMs > 0) await sleep(Math.min(intervalMs, remaining));
|
|
185
|
-
if (Date.now() === iterStartedAt) await sleep(1);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const smokeSummary = summarize(smokeTimes);
|
|
189
|
-
const rssSummary = summarize(rssSamples);
|
|
190
|
-
const totalElapsedMs = Date.now() - startedAt;
|
|
191
|
-
writeLoopLog({
|
|
192
|
-
type: 'summary',
|
|
193
|
-
iterations: iteration,
|
|
194
|
-
elapsed_ms: totalElapsedMs,
|
|
195
|
-
smoke_ms: smokeSummary,
|
|
196
|
-
rss_mb: rssSummary,
|
|
197
|
-
});
|
|
198
|
-
process.stdout.write(
|
|
199
|
-
`smoke loop passed iterations=${iteration} elapsed_ms=${totalElapsedMs} `
|
|
200
|
-
+ `smoke_ms=min:${smokeSummary.min},avg:${smokeSummary.avg},max:${smokeSummary.max} `
|
|
201
|
-
+ `rss_mb=min:${rssSummary.min},avg:${rssSummary.avg},max:${rssSummary.max}\n`,
|
|
202
|
-
);
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# smoke-runtime-negative.ps1 — Negative-path tests against released win32-x64
|
|
2
|
-
# runtime tarball. Validates: download, sha256, corrupt-tarball, fresh-extract
|
|
3
|
-
# boot, double-init refusal, hostile-env survival.
|
|
4
|
-
#
|
|
5
|
-
# Env: TAG / OS / ARCH / RUNTIME_RELEASE_REPOSITORY (default tribgames/mixdog)
|
|
6
|
-
|
|
7
|
-
$ErrorActionPreference = 'Stop'
|
|
8
|
-
|
|
9
|
-
$Tag = if ($env:TAG) { $env:TAG } else { 'runtime-v0.4.0' }
|
|
10
|
-
$Os = if ($env:OS) { $env:OS } else { 'win32' }
|
|
11
|
-
$Arch = if ($env:ARCH) { $env:ARCH } else { 'x64' }
|
|
12
|
-
$ReleaseRepo = if ($env:RUNTIME_RELEASE_REPOSITORY) { $env:RUNTIME_RELEASE_REPOSITORY } else { 'tribgames/mixdog' }
|
|
13
|
-
$PgVer = '16.4'
|
|
14
|
-
$PgvectorVer = '0.8.2'
|
|
15
|
-
|
|
16
|
-
$Asset = "mixdog-runtime-${Os}-${Arch}-pg${PgVer}-pgvector${PgvectorVer}.tar.gz"
|
|
17
|
-
$Url = "https://github.com/${ReleaseRepo}/releases/download/${Tag}/${Asset}"
|
|
18
|
-
|
|
19
|
-
$Work = New-Item -ItemType Directory -Force -Path "$env:TEMP\smoke-$([guid]::NewGuid().ToString('N'))" | Select-Object -ExpandProperty FullName
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
Write-Host "==> Negative-path smoke for ${Os}-${Arch} from $Url"
|
|
23
|
-
|
|
24
|
-
Write-Host "==> Test 1: HEAD reaches release asset"
|
|
25
|
-
$resp = Invoke-WebRequest -Uri $Url -Method Head -UseBasicParsing -ErrorAction Stop
|
|
26
|
-
Write-Host " HTTP $($resp.StatusCode)"
|
|
27
|
-
|
|
28
|
-
Write-Host "==> Test 2: full download + sha256"
|
|
29
|
-
$TarPath = Join-Path $Work $Asset
|
|
30
|
-
Invoke-WebRequest -Uri $Url -OutFile $TarPath -UseBasicParsing
|
|
31
|
-
$sha = (Get-FileHash -Algorithm SHA256 $TarPath).Hash.ToLower()
|
|
32
|
-
Write-Host " sha256=$sha"
|
|
33
|
-
|
|
34
|
-
Write-Host "==> Test 3: corrupt tarball — flip a byte and ensure tar errors"
|
|
35
|
-
$CorruptPath = "$Work\corrupt.tar.gz"
|
|
36
|
-
Copy-Item $TarPath $CorruptPath
|
|
37
|
-
$bytes = [byte[]]::new(1); $rand = [System.Random]::new(); $rand.NextBytes($bytes)
|
|
38
|
-
$stream = [System.IO.File]::OpenWrite($CorruptPath)
|
|
39
|
-
$stream.Position = 102400
|
|
40
|
-
$stream.Write($bytes, 0, 1)
|
|
41
|
-
$stream.Close()
|
|
42
|
-
$CorruptDir = "$Work\corrupt"
|
|
43
|
-
New-Item -ItemType Directory -Force -Path $CorruptDir | Out-Null
|
|
44
|
-
$TarProc = Start-Process -FilePath tar -ArgumentList @('-xzf', $CorruptPath, '-C', $CorruptDir.Replace('\','/')) -Wait:$false -PassThru -WindowStyle Hidden
|
|
45
|
-
if (-not $TarProc.WaitForExit(15000)) {
|
|
46
|
-
Stop-Process -Id $TarProc.Id -Force -ErrorAction SilentlyContinue
|
|
47
|
-
Write-Host " PASS: corrupted tarball extraction timed out and was stopped"
|
|
48
|
-
} elseif ($TarProc.ExitCode -eq 0) {
|
|
49
|
-
Write-Host " WARN: corrupted tarball extracted without error (tar gzip recovery)"
|
|
50
|
-
} else {
|
|
51
|
-
Write-Host " PASS: corrupted tarball rejected by tar (exit $($TarProc.ExitCode))"
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
Write-Host "==> Test 4: fresh-extract boot (extension load + distance query)"
|
|
55
|
-
$FreshDir = "$Work\fresh"
|
|
56
|
-
New-Item -ItemType Directory -Force -Path $FreshDir | Out-Null
|
|
57
|
-
& tar -xzf $TarPath -C ($FreshDir.Replace('\','/'))
|
|
58
|
-
if ($LASTEXITCODE -ne 0) { throw "fresh extract failed" }
|
|
59
|
-
|
|
60
|
-
$PgBin = "$FreshDir\bin"
|
|
61
|
-
$Data = "$FreshDir\pgdata"
|
|
62
|
-
$Log = "$FreshDir\pg.log"
|
|
63
|
-
$Port = 55897
|
|
64
|
-
|
|
65
|
-
# Hostile env: minimal PATH (System32 only), no PGROOT/PGDATA
|
|
66
|
-
$SavedPath = $env:PATH
|
|
67
|
-
$SavedPgRoot = $env:PGROOT
|
|
68
|
-
$env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
|
|
69
|
-
$env:PGROOT = $null
|
|
70
|
-
$env:PGDATA = $null
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
& "$PgBin\postgres.exe" --version
|
|
74
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version" }
|
|
75
|
-
& "$PgBin\initdb.exe" -D $Data --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
|
|
76
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb" }
|
|
77
|
-
& "$PgBin\pg_ctl.exe" -D $Data -o "-p $Port -h 127.0.0.1" -l $Log -w start
|
|
78
|
-
if ($LASTEXITCODE -ne 0) { Get-Content $Log | Select-Object -Last 30; throw "FAIL: pg_ctl start" }
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
& "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
|
|
82
|
-
if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION" }
|
|
83
|
-
$ExtV = & "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
|
|
84
|
-
if ($ExtV.Trim() -ne $PgvectorVer) { throw "FAIL: extversion='$ExtV' expected='$PgvectorVer'" }
|
|
85
|
-
Write-Host " PASS: fresh-extract boot + vector extension"
|
|
86
|
-
} finally {
|
|
87
|
-
& "$PgBin\pg_ctl.exe" -D $Data -m fast stop 2>$null | Out-Null
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Write-Host "==> Test 5: second initdb on initialized dir refused"
|
|
91
|
-
$rc = (Start-Process -FilePath "$PgBin\initdb.exe" -ArgumentList "-D",$Data,"-U","postgres" -Wait -PassThru -NoNewWindow).ExitCode
|
|
92
|
-
if ($rc -eq 0) {
|
|
93
|
-
Write-Host " WARN: second initdb succeeded (unexpected)"
|
|
94
|
-
} else {
|
|
95
|
-
Write-Host " PASS: second initdb refused (exit $rc)"
|
|
96
|
-
}
|
|
97
|
-
} finally {
|
|
98
|
-
$env:PATH = $SavedPath
|
|
99
|
-
$env:PGROOT = $SavedPgRoot
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
Write-Host "==> All negative-path smokes: PASS"
|
|
103
|
-
}
|
|
104
|
-
finally {
|
|
105
|
-
Remove-Item -Recurse -Force $Work -ErrorAction SilentlyContinue
|
|
106
|
-
}
|