mixdog 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +31 -0
- package/.claude-plugin/plugin.json +20 -0
- package/.gitattributes +34 -0
- package/.mcp.json +14 -0
- package/ARCHITECTURE.md +77 -0
- package/CHANGELOG.md +7 -0
- package/CONTRIBUTING.md +45 -0
- package/DATA-FLOW.md +79 -0
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/SECURITY.md +138 -0
- package/UNINSTALL.md +112 -0
- package/agents/maintenance.md +5 -0
- package/agents/memory-classification.md +30 -0
- package/agents/scheduler-task.md +18 -0
- package/agents/webhook-handler.md +27 -0
- package/agents/worker.md +24 -0
- package/bin/bridge +133 -0
- package/bin/statusline-launcher.mjs +78 -0
- package/bin/statusline-lib.mjs +550 -0
- package/bin/statusline.mjs +607 -0
- package/bun.lock +802 -0
- package/commands/config.md +16 -0
- package/commands/doctor.md +13 -0
- package/commands/setup.md +17 -0
- package/defaults/cycle3-review-prompt.md +90 -0
- package/defaults/hidden-roles.json +65 -0
- package/defaults/memory-chunk-prompt.md +63 -0
- package/defaults/memory-promote-prompt.md +135 -0
- package/defaults/mixdog-config.template.json +27 -0
- package/defaults/user-workflow.json +8 -0
- package/defaults/user-workflow.md +12 -0
- package/hooks/hooks.json +73 -0
- package/hooks/lib/active-instance.cjs +77 -0
- package/hooks/lib/permission-evaluator.cjs +411 -0
- package/hooks/lib/permission-route.cjs +63 -0
- package/hooks/lib/permission-rules.cjs +170 -0
- package/hooks/lib/settings-loader.cjs +116 -0
- package/hooks/post-tool-use.cjs +84 -0
- package/hooks/pre-mcp-sandbox.cjs +158 -0
- package/hooks/pre-tool-subagent.cjs +253 -0
- package/hooks/session-start.cjs +1372 -0
- package/hooks/turn-timer.cjs +82 -0
- package/lib/claude-md-writer.cjs +386 -0
- package/lib/config-cjs.cjs +61 -0
- package/lib/hook-pipe-path.cjs +10 -0
- package/lib/keychain-cjs.cjs +263 -0
- package/lib/plugin-paths.cjs +61 -0
- package/lib/rules-builder.cjs +241 -0
- package/lib/text-utils.cjs +61 -0
- package/native/README.md +117 -0
- package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
- package/package.json +107 -0
- package/prompts/code-review.txt +16 -0
- package/prompts/security-audit.txt +17 -0
- package/rules/bridge/00-common.md +39 -0
- package/rules/bridge/20-skip-protocol.md +18 -0
- package/rules/bridge/30-explorer.md +33 -0
- package/rules/bridge/40-cycle1-agent.md +52 -0
- package/rules/bridge/41-cycle2-agent.md +62 -0
- package/rules/bridge/42-cycle3-agent.md +44 -0
- package/rules/lead/00-tool-lead.md +61 -0
- package/rules/lead/01-general.md +23 -0
- package/rules/lead/02-channels.md +49 -0
- package/rules/lead/03-team.md +27 -0
- package/rules/lead/04-workflow.md +20 -0
- package/rules/shared/00-language.md +14 -0
- package/rules/shared/01-tool.md +138 -0
- package/scripts/bootstrap.mjs +184 -0
- package/scripts/bridge-unify-smoke.mjs +308 -0
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/builtin-utils-smoke.mjs +392 -0
- package/scripts/check-json.mjs +45 -0
- package/scripts/check-syntax-changed.mjs +102 -0
- package/scripts/check-syntax.mjs +58 -0
- package/scripts/code-graph-batch.test.mjs +33 -0
- package/scripts/config-preserve-smoke.mjs +180 -0
- package/scripts/doctor.mjs +484 -0
- package/scripts/edit-normalize-fuzz.mjs +130 -0
- package/scripts/edit-normalize-smoke.mjs +401 -0
- package/scripts/edit-operation-smoke.mjs +369 -0
- package/scripts/edit2-smoke.mjs +63 -0
- package/scripts/fuzzy-e2e.mjs +28 -0
- package/scripts/fuzzy-smoke.mjs +26 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/guard-smoke.mjs +66 -0
- package/scripts/hidden-role-schema-smoke.mjs +162 -0
- package/scripts/hook-routing-smoke.mjs +29 -0
- package/scripts/inject-input.ps1 +204 -0
- package/scripts/io-complex-smoke.mjs +667 -0
- package/scripts/io-explore-bench.mjs +424 -0
- package/scripts/io-guardrails-smoke.mjs +205 -0
- package/scripts/io-mini-bench-baseline.json +11 -0
- package/scripts/io-mini-bench.mjs +216 -0
- package/scripts/io-route-harness.mjs +933 -0
- package/scripts/io-telemetry-report.mjs +691 -0
- package/scripts/mutation-bench.mjs +564 -0
- package/scripts/mutation-io-smoke.mjs +1081 -0
- package/scripts/native-patch-bridge-smoke.mjs +288 -0
- package/scripts/native-patch-smoke.mjs +304 -0
- package/scripts/patch-interior-context-smoke.mjs +49 -0
- package/scripts/patch-newline-utf8-smoke.mjs +157 -0
- package/scripts/perf-hook-smoke.mjs +71 -0
- package/scripts/permission-eval-smoke.mjs +426 -0
- package/scripts/prep-patch.mjs +53 -0
- package/scripts/prep-shim.mjs +96 -0
- package/scripts/provider-cache-smoke.mjs +687 -0
- package/scripts/report-runtime-health.mjs +132 -0
- package/scripts/run-mcp.mjs +1547 -0
- package/scripts/salvage-v4a-shatter.test.mjs +58 -0
- package/scripts/scoped-cache-io-smoke.mjs +103 -0
- package/scripts/shell-policy-round3-smoke.mjs +46 -0
- package/scripts/smoke-runtime-negative.ps1 +100 -0
- package/scripts/smoke-runtime-negative.sh +95 -0
- package/scripts/stall-policy-smoke.mjs +50 -0
- package/scripts/start-memory-worker.mjs +23 -0
- package/scripts/statusline-launcher-smoke.mjs +82 -0
- package/scripts/stress-atomic-write.mjs +1028 -0
- package/scripts/test-config-rmw-restore.mjs +122 -0
- package/scripts/test-fault-inject.mjs +164 -0
- package/scripts/test-large-file.mjs +174 -0
- package/scripts/tool-edge-smoke.mjs +209 -0
- package/scripts/uninstall.mjs +201 -0
- package/scripts/webhook-selfheal-smoke.mjs +29 -0
- package/scripts/write-overwrite-guard-smoke.mjs +56 -0
- package/server-main.mjs +3055 -0
- package/server.mjs +468 -0
- package/setup/config-merge.mjs +254 -0
- package/setup/install.mjs +120 -0
- package/setup/launch-core.mjs +507 -0
- package/setup/launch.mjs +101 -0
- package/setup/setup-server.mjs +3206 -0
- package/setup/setup.html +3693 -0
- package/skills/retro-skill-proposer/SKILL.md +92 -0
- package/skills/schedule-add/SKILL.md +77 -0
- package/skills/setup/SKILL.md +346 -0
- package/skills/webhook-add/SKILL.md +81 -0
- package/src/agent/bridge-stall-watchdog.mjs +337 -0
- package/src/agent/index.mjs +2138 -0
- package/src/agent/orchestrator/activity-bus.mjs +38 -0
- package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
- package/src/agent/orchestrator/bridge-retry.mjs +220 -0
- package/src/agent/orchestrator/bridge-trace.mjs +583 -0
- package/src/agent/orchestrator/cache-mtime.mjs +58 -0
- package/src/agent/orchestrator/config.mjs +358 -0
- package/src/agent/orchestrator/context/collect.mjs +651 -0
- package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
- package/src/agent/orchestrator/drain-registry.mjs +50 -0
- package/src/agent/orchestrator/explore-validator.mjs +8 -0
- package/src/agent/orchestrator/internal-roles.mjs +118 -0
- package/src/agent/orchestrator/internal-tools.mjs +88 -0
- package/src/agent/orchestrator/jobs.mjs +116 -0
- package/src/agent/orchestrator/mcp/client.mjs +364 -0
- package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
- package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
- package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
- package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
- package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
- package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
- package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
- package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
- package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
- package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
- package/src/agent/orchestrator/providers/registry.mjs +192 -0
- package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
- package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
- package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
- package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
- package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
- package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
- package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
- package/src/agent/orchestrator/session/cache/util.mjs +49 -0
- package/src/agent/orchestrator/session/loop.mjs +1478 -0
- package/src/agent/orchestrator/session/manager.mjs +1975 -0
- package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
- package/src/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
- package/src/agent/orchestrator/session/store.mjs +624 -0
- package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
- package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
- package/src/agent/orchestrator/session/trim.mjs +491 -0
- package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
- package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
- package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
- package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
- package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
- package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
- package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
- package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
- package/src/agent/orchestrator/stall-policy.mjs +195 -0
- package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
- package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
- package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
- package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
- package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
- package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
- package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
- package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
- package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
- package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
- package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
- package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
- package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
- package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
- package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
- package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
- package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
- package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
- package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
- package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
- package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
- package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
- package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
- package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
- package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
- package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
- package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
- package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
- package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
- package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
- package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
- package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
- package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
- package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
- package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
- package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
- package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
- package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
- package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
- package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
- package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
- package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
- package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
- package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
- package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
- package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
- package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
- package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
- package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
- package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
- package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
- package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
- package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
- package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
- package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
- package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
- package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
- package/src/agent/orchestrator/tools/builtin.mjs +500 -0
- package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
- package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
- package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
- package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
- package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
- package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
- package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
- package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
- package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
- package/src/agent/orchestrator/tools/host-input.mjs +204 -0
- package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
- package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
- package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
- package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
- package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
- package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
- package/src/agent/orchestrator/tools/patch.mjs +2754 -0
- package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
- package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
- package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
- package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
- package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
- package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
- package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
- package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
- package/src/agent/orchestrator/workflow-store.mjs +93 -0
- package/src/agent/tool-defs.mjs +103 -0
- package/src/channels/backends/discord.mjs +784 -0
- package/src/channels/data/voice-runtime-manifest.json +138 -0
- package/src/channels/index.mjs +3229 -0
- package/src/channels/lib/cli-worker-host.mjs +12 -0
- package/src/channels/lib/config-lock.mjs +13 -0
- package/src/channels/lib/config.mjs +292 -0
- package/src/channels/lib/drop-trace.mjs +71 -0
- package/src/channels/lib/event-pipeline.mjs +81 -0
- package/src/channels/lib/event-queue.mjs +345 -0
- package/src/channels/lib/executor.mjs +168 -0
- package/src/channels/lib/format.mjs +188 -0
- package/src/channels/lib/holidays.mjs +138 -0
- package/src/channels/lib/hook-pipe-server.mjs +802 -0
- package/src/channels/lib/interaction-workflows.mjs +184 -0
- package/src/channels/lib/memory-client.mjs +149 -0
- package/src/channels/lib/output-forwarder.mjs +765 -0
- package/src/channels/lib/runtime-paths.mjs +479 -0
- package/src/channels/lib/scheduler.mjs +723 -0
- package/src/channels/lib/session-control.mjs +36 -0
- package/src/channels/lib/session-discovery.mjs +103 -0
- package/src/channels/lib/settings.mjs +11 -0
- package/src/channels/lib/state-file.mjs +68 -0
- package/src/channels/lib/status-snapshot.mjs +219 -0
- package/src/channels/lib/tool-format.mjs +140 -0
- package/src/channels/lib/transcript-discovery.mjs +195 -0
- package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
- package/src/channels/lib/webhook.mjs +1179 -0
- package/src/channels/lib/whisper-server.mjs +477 -0
- package/src/channels/tool-defs.mjs +170 -0
- package/src/daemon/host.mjs +118 -0
- package/src/daemon/mcp-transport.mjs +47 -0
- package/src/daemon/session.mjs +100 -0
- package/src/daemon/thin-client.mjs +71 -0
- package/src/daemon/transport.mjs +163 -0
- package/src/memory/data/runtime-manifest.json +40 -0
- package/src/memory/index.mjs +3305 -0
- package/src/memory/lib/agent-ipc.mjs +93 -0
- package/src/memory/lib/bridge-trace-queries.mjs +120 -0
- package/src/memory/lib/core-memory-store.mjs +330 -0
- package/src/memory/lib/embedding-provider.mjs +269 -0
- package/src/memory/lib/embedding-worker.mjs +323 -0
- package/src/memory/lib/llm-worker-host.mjs +17 -0
- package/src/memory/lib/memory-cycle.mjs +11 -0
- package/src/memory/lib/memory-cycle1.mjs +641 -0
- package/src/memory/lib/memory-cycle2.mjs +1284 -0
- package/src/memory/lib/memory-cycle3.mjs +540 -0
- package/src/memory/lib/memory-embed.mjs +299 -0
- package/src/memory/lib/memory-extraction.mjs +5 -0
- package/src/memory/lib/memory-maintenance-store.mjs +32 -0
- package/src/memory/lib/memory-ops-policy.mjs +190 -0
- package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
- package/src/memory/lib/memory-recall-read-query.mjs +7 -0
- package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
- package/src/memory/lib/memory-recall-store.mjs +621 -0
- package/src/memory/lib/memory-retrievers.mjs +112 -0
- package/src/memory/lib/memory-score.mjs +71 -0
- package/src/memory/lib/memory-text-utils.mjs +58 -0
- package/src/memory/lib/memory.mjs +412 -0
- package/src/memory/lib/model-profile.mjs +85 -0
- package/src/memory/lib/pg/adapter.mjs +308 -0
- package/src/memory/lib/pg/process.mjs +360 -0
- package/src/memory/lib/pg/supervisor.mjs +396 -0
- package/src/memory/lib/project-id-resolver.mjs +86 -0
- package/src/memory/lib/runtime-fetcher.mjs +442 -0
- package/src/memory/lib/trace-store.mjs +728 -0
- package/src/memory/tool-defs.mjs +79 -0
- package/src/search/index.mjs +1173 -0
- package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
- package/src/search/lib/backends/exa.mjs +50 -0
- package/src/search/lib/backends/firecrawl.mjs +61 -0
- package/src/search/lib/backends/gemini-api.mjs +83 -0
- package/src/search/lib/backends/grok-oauth.mjs +86 -0
- package/src/search/lib/backends/index.mjs +150 -0
- package/src/search/lib/backends/openai-api.mjs +144 -0
- package/src/search/lib/backends/openai-oauth.mjs +98 -0
- package/src/search/lib/backends/openai-web-search.mjs +76 -0
- package/src/search/lib/backends/tavily.mjs +55 -0
- package/src/search/lib/backends/xai-api.mjs +113 -0
- package/src/search/lib/cache.mjs +131 -0
- package/src/search/lib/config.mjs +192 -0
- package/src/search/lib/formatter.mjs +115 -0
- package/src/search/lib/provider-usage.mjs +67 -0
- package/src/search/lib/providers.mjs +47 -0
- package/src/search/lib/search-intent.mjs +109 -0
- package/src/search/lib/setup-handler.mjs +261 -0
- package/src/search/lib/state.mjs +201 -0
- package/src/search/lib/web-tools.mjs +1207 -0
- package/src/search/tool-defs.mjs +83 -0
- package/src/setup/defender-exclusion.mjs +183 -0
- package/src/shared/abort-controller.mjs +15 -0
- package/src/shared/atomic-file.mjs +420 -0
- package/src/shared/config.mjs +350 -0
- package/src/shared/daemon-recycle.mjs +108 -0
- package/src/shared/disable-claude-builtins.mjs +88 -0
- package/src/shared/err-text.mjs +12 -0
- package/src/shared/llm/cost.mjs +66 -0
- package/src/shared/llm/http-agent.mjs +123 -0
- package/src/shared/llm/index.mjs +41 -0
- package/src/shared/llm/pid-cleanup.mjs +27 -0
- package/src/shared/llm/usage-log.mjs +47 -0
- package/src/shared/plugin-paths.mjs +58 -0
- package/src/shared/schedules-store.mjs +70 -0
- package/src/shared/seed.mjs +119 -0
- package/src/shared/user-cwd.mjs +213 -0
- package/src/shared/user-data-guard.mjs +238 -0
- package/src/status/aggregator.mjs +584 -0
- package/src/status/server.mjs +413 -0
- package/tools.json +1653 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// pg-process.mjs — lower-level PG lifecycle helpers for mixdog 0.4.0
|
|
2
|
+
// Track B can wire these into the supervisor; pg-adapter calls them directly.
|
|
3
|
+
//
|
|
4
|
+
// Public API:
|
|
5
|
+
// startPg({ runtimeDir, pgdataDir, port?, logPath? }) → { pid, port }
|
|
6
|
+
// stopPg({ runtimeDir, pgdataDir }) → void
|
|
7
|
+
// healthcheckPg({ port, host? }) → boolean
|
|
8
|
+
|
|
9
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'
|
|
10
|
+
import { join } from 'path'
|
|
11
|
+
import { spawnSync } from 'child_process'
|
|
12
|
+
import { createConnection } from 'net'
|
|
13
|
+
import { createServer } from 'net'
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Helpers
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
function pgBin(runtimeDir, name) {
|
|
20
|
+
const ext = process.platform === 'win32' ? '.exe' : ''
|
|
21
|
+
return join(runtimeDir, 'bin', `${name}${ext}`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function libEnv(runtimeDir) {
|
|
25
|
+
// Bundled shared libraries must be visible to the PG binaries at runtime.
|
|
26
|
+
const libDir = join(runtimeDir, 'lib')
|
|
27
|
+
if (process.platform === 'linux') {
|
|
28
|
+
return { ...process.env, LD_LIBRARY_PATH: libDir }
|
|
29
|
+
}
|
|
30
|
+
if (process.platform === 'darwin') {
|
|
31
|
+
return { ...process.env, DYLD_LIBRARY_PATH: libDir }
|
|
32
|
+
}
|
|
33
|
+
// win32: DLLs live in bin/ — add to PATH.
|
|
34
|
+
return { ...process.env, PATH: `${join(runtimeDir, 'bin')};${process.env.PATH}` }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Free port detection
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
function isTcpPortFree(port) {
|
|
42
|
+
return new Promise(resolve => {
|
|
43
|
+
const srv = createServer()
|
|
44
|
+
srv.once('error', () => resolve(false))
|
|
45
|
+
srv.once('listening', () => { srv.close(); resolve(true) })
|
|
46
|
+
srv.listen(port, '127.0.0.1')
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const PG_PORT_MIN = 55432
|
|
51
|
+
const PG_PORT_MAX = 55632
|
|
52
|
+
|
|
53
|
+
async function findFreePort(preferred) {
|
|
54
|
+
// I2: clamp out-of-range callers to the valid window.
|
|
55
|
+
if (preferred < PG_PORT_MIN || preferred > PG_PORT_MAX) preferred = PG_PORT_MIN
|
|
56
|
+
if (await isTcpPortFree(preferred)) return preferred
|
|
57
|
+
for (let p = preferred + 1; p <= PG_PORT_MAX; p++) {
|
|
58
|
+
if (await isTcpPortFree(p)) return p
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`[pg-process] no free port found in range ${preferred}–${PG_PORT_MAX}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// postgresql.conf v2 reconcile — appended on every startPg call so existing
|
|
65
|
+
// pgdata directories pick up the bgwriter / checkpoint-distribution tuning
|
|
66
|
+
// without requiring a fresh initdb.
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
const MIXDOG_CONF_V2_MARKER = '# mixdog overrides v2 — bgwriter / checkpoint distribution'
|
|
70
|
+
|
|
71
|
+
// Lines emitted into postgresql.conf for v2. effective_io_concurrency is
|
|
72
|
+
// posix_fadvise-only; PG rejects non-zero values on Windows with an invalid-
|
|
73
|
+
// parameter error on every reload. Skip it there.
|
|
74
|
+
function buildV2Block() {
|
|
75
|
+
const lines = [
|
|
76
|
+
'',
|
|
77
|
+
MIXDOG_CONF_V2_MARKER,
|
|
78
|
+
'checkpoint_completion_target = 0.9', // spread checkpoint write across 90% of timeout window
|
|
79
|
+
'bgwriter_lru_maxpages = 1000', // up to 1000 dirty pages per round (default 100)
|
|
80
|
+
'bgwriter_delay = 50ms', // wake bgwriter every 50ms (default 200ms)
|
|
81
|
+
]
|
|
82
|
+
if (process.platform !== 'win32') {
|
|
83
|
+
lines.push('effective_io_concurrency = 32') // I/O concurrency hint (POSIX only)
|
|
84
|
+
}
|
|
85
|
+
return lines.join('\n') + '\n'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Migration: an earlier v2 always emitted effective_io_concurrency. On Windows
|
|
89
|
+
// that line is invalid — strip it so pg_ctl reload stops logging a parse error
|
|
90
|
+
// every cycle.
|
|
91
|
+
function stripWindowsInvalidLines(conf) {
|
|
92
|
+
if (process.platform !== 'win32') return conf
|
|
93
|
+
return conf.replace(/^effective_io_concurrency\s*=\s*\d+\s*\r?\n/m, '')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function ensureConfV2(pgdataDir) {
|
|
97
|
+
const confPath = join(pgdataDir, 'postgresql.conf')
|
|
98
|
+
if (!existsSync(confPath)) return false
|
|
99
|
+
const original = readFileSync(confPath, 'utf8')
|
|
100
|
+
let conf = stripWindowsInvalidLines(original)
|
|
101
|
+
const stripped = conf !== original
|
|
102
|
+
const hasMarker = conf.includes(MIXDOG_CONF_V2_MARKER)
|
|
103
|
+
if (hasMarker && !stripped) return false
|
|
104
|
+
if (!hasMarker) conf = conf + buildV2Block()
|
|
105
|
+
writeFileSync(confPath, conf)
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Public reconcile: idempotent conf v2 append + pg_ctl reload on a running
|
|
110
|
+
// instance. Single source of truth for v2 application — supervisor and other
|
|
111
|
+
// callers route through this rather than re-implementing the conf/reload pair.
|
|
112
|
+
// All v2 settings are reload-applicable (no restart required).
|
|
113
|
+
export function reconcileConfV2(runtimeDir, pgdataDir) {
|
|
114
|
+
const applied = ensureConfV2(pgdataDir)
|
|
115
|
+
if (!applied) return { applied: false, reloaded: false }
|
|
116
|
+
const reload = spawnSync(pgBin(runtimeDir, 'pg_ctl'), ['reload', '-D', pgdataDir], {
|
|
117
|
+
env: libEnv(runtimeDir), stdio: 'pipe', timeout: 5_000, windowsHide: true,
|
|
118
|
+
})
|
|
119
|
+
const reloaded = reload.status === 0
|
|
120
|
+
if (reloaded) {
|
|
121
|
+
process.stderr.write('[pg-process] postgresql.conf v2 overrides applied via pg_ctl reload\n')
|
|
122
|
+
} else {
|
|
123
|
+
process.stderr.write(`[pg-process] pg_ctl reload after v2 append failed (non-fatal): ${reload.stderr?.toString() || ''}\n`)
|
|
124
|
+
}
|
|
125
|
+
return { applied, reloaded }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// startPg
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
export async function startPg({ runtimeDir, pgdataDir, port: preferredPort = 55432, logPath }) {
|
|
133
|
+
mkdirSync(pgdataDir, { recursive: true })
|
|
134
|
+
|
|
135
|
+
if (process.platform === 'darwin') {
|
|
136
|
+
try { writeFileSync(join(pgdataDir, '.metadata_never_index'), '') } catch {}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Idempotent v2 conf reconcile — runs before attach/init. Returns true if
|
|
140
|
+
// the block was just appended (so the attach path can trigger pg_ctl reload).
|
|
141
|
+
// Fresh-init path falls through to confAppend below which already includes v2.
|
|
142
|
+
const v2Applied = ensureConfV2(pgdataDir)
|
|
143
|
+
|
|
144
|
+
// Pre-check: if postmaster.pid exists and the instance is reachable, attach
|
|
145
|
+
// rather than attempting a second pg_ctl start (which would crash the worker).
|
|
146
|
+
const postmasterPidPath = join(pgdataDir, 'postmaster.pid')
|
|
147
|
+
if (existsSync(postmasterPidPath)) {
|
|
148
|
+
try {
|
|
149
|
+
const lines = readFileSync(postmasterPidPath, 'utf8').split('\n')
|
|
150
|
+
const existingPid = parseInt(lines[0], 10)
|
|
151
|
+
// Line 4 (index 3) in postmaster.pid holds the port number.
|
|
152
|
+
const existingPort = parseInt(lines[3], 10)
|
|
153
|
+
if (existingPid > 0 && existingPort > 0) {
|
|
154
|
+
// Liveness must be confirmed by pg_isready (status 0). A bare open TCP
|
|
155
|
+
// port is insufficient: any unrelated listener that happened to grab
|
|
156
|
+
// this port would be mistaken for our PG instance, causing a false
|
|
157
|
+
// attach. pg_isready performs a real PG protocol handshake, so a
|
|
158
|
+
// non-Postgres listener returns non-zero and we correctly fall through
|
|
159
|
+
// to normal startup (which reclaims the stale postmaster.pid).
|
|
160
|
+
const pgIsReady = pgBin(runtimeDir, 'pg_isready')
|
|
161
|
+
const probe = spawnSync(pgIsReady, ['-h', '127.0.0.1', '-p', String(existingPort)], {
|
|
162
|
+
env: libEnv(runtimeDir), stdio: 'pipe', timeout: 3_000, windowsHide: true,
|
|
163
|
+
})
|
|
164
|
+
const alive = probe.status === 0
|
|
165
|
+
if (alive) {
|
|
166
|
+
process.stderr.write(`[pg-process] attaching to existing PG pid=${existingPid} port=${existingPort}\n`)
|
|
167
|
+
// Route through the single reconcile entry point so v1 → v2 conf
|
|
168
|
+
// upgrades land on already-running instances without restart.
|
|
169
|
+
if (v2Applied) reconcileConfV2(runtimeDir, pgdataDir)
|
|
170
|
+
return { pid: existingPid, port: existingPort, attached: true }
|
|
171
|
+
}
|
|
172
|
+
// Dead instance — fall through to normal startup; pg_ctl will reclaim stale lock.
|
|
173
|
+
}
|
|
174
|
+
} catch {}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const env = libEnv(runtimeDir)
|
|
178
|
+
const initdb = pgBin(runtimeDir, 'initdb')
|
|
179
|
+
const pgctl = pgBin(runtimeDir, 'pg_ctl')
|
|
180
|
+
|
|
181
|
+
// initdb if pgdata is not yet initialised (no PG_VERSION file).
|
|
182
|
+
const pgVersionFile = join(pgdataDir, 'PG_VERSION')
|
|
183
|
+
if (!existsSync(pgVersionFile)) {
|
|
184
|
+
process.stderr.write(`[pg-process] initdb → ${pgdataDir}\n`)
|
|
185
|
+
const r = spawnSync(initdb, [
|
|
186
|
+
'-D', pgdataDir,
|
|
187
|
+
'--auth-local=trust',
|
|
188
|
+
'--no-locale',
|
|
189
|
+
'-E', 'UTF8',
|
|
190
|
+
'-U', 'postgres',
|
|
191
|
+
], { env, stdio: 'pipe', windowsHide: true })
|
|
192
|
+
|
|
193
|
+
if (r.status !== 0) {
|
|
194
|
+
const detail = r.error?.message
|
|
195
|
+
|| r.stderr?.toString()
|
|
196
|
+
|| r.stdout?.toString()
|
|
197
|
+
|| `status=${r.status} signal=${r.signal} (no captured output)`
|
|
198
|
+
throw new Error(`[pg-process] initdb failed: ${detail}`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Append mixdog-specific postgresql.conf overrides.
|
|
202
|
+
// default_transaction_isolation: native PG default is read committed.
|
|
203
|
+
// Native PG does not default to serializable; set isolation level explicitly
|
|
204
|
+
// so behaviour is unambiguous across PG major versions.
|
|
205
|
+
const confPath = join(pgdataDir, 'postgresql.conf')
|
|
206
|
+
const confAppend = [
|
|
207
|
+
'',
|
|
208
|
+
'# mixdog overrides — appended by pg-process.mjs',
|
|
209
|
+
"default_transaction_isolation = 'read committed'",
|
|
210
|
+
"listen_addresses = '127.0.0.1'",
|
|
211
|
+
'log_min_messages = warning',
|
|
212
|
+
'log_line_prefix = \'%t [%p]: \'',
|
|
213
|
+
'',
|
|
214
|
+
'# Defender/AV latency mitigations',
|
|
215
|
+
'synchronous_commit = off', // defers fsync ack; trade-off: crash → latest async commits since last WAL flush may be lost; acceptable for local memory store
|
|
216
|
+
'checkpoint_timeout = 15min', // halves checkpoint frequency vs 5min default; fewer sync storms
|
|
217
|
+
'max_wal_size = 2GB', // suppresses forced checkpoints driven by WAL volume
|
|
218
|
+
'wal_compression = on', // smaller WAL segments; fewer bytes for Defender to scan per segment
|
|
219
|
+
'wal_init_zero = off', // skips zero-fill on new WAL segment; cuts Defender contact at segment creation
|
|
220
|
+
'wal_recycle = off', // disables WAL rename/recycle loop; eliminates rename-storm EPERM pattern in pgdata
|
|
221
|
+
].join('\n') + '\n' + buildV2Block()
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const existing = readFileSync(confPath, 'utf8')
|
|
225
|
+
writeFileSync(confPath, existing + confAppend)
|
|
226
|
+
} catch (e) {
|
|
227
|
+
process.stderr.write(`[pg-process] postgresql.conf append failed: ${e?.message}\n`)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (process.platform === 'win32') {
|
|
231
|
+
process.stderr.write(
|
|
232
|
+
`[pg-process] Windows tip: if startup feels slow, add the data folder to Defender exclusions.\n` +
|
|
233
|
+
` Folder: ${pgdataDir}\n` +
|
|
234
|
+
` PowerShell (run as admin): Add-MpPreference -ExclusionPath '${pgdataDir}'\n`
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Choose a free port (guards against stale postmaster from prior crash).
|
|
240
|
+
const port = await findFreePort(preferredPort)
|
|
241
|
+
const logFile = logPath ?? join(pgdataDir, 'pg.log')
|
|
242
|
+
|
|
243
|
+
process.stderr.write(`[pg-process] pg_ctl start -D ${pgdataDir} -p ${port}\n`)
|
|
244
|
+
|
|
245
|
+
const r = spawnSync(pgctl, [
|
|
246
|
+
'start', '-w',
|
|
247
|
+
'-D', pgdataDir,
|
|
248
|
+
'-l', logFile,
|
|
249
|
+
'-o', `-p ${port} -h 127.0.0.1`,
|
|
250
|
+
], { env, stdio: 'pipe', timeout: 30_000, windowsHide: true })
|
|
251
|
+
|
|
252
|
+
if (r.status !== 0) {
|
|
253
|
+
const errText = r.stderr?.toString() || r.stdout?.toString() || ''
|
|
254
|
+
// "another server might be running" — try status + immediate stop before failing.
|
|
255
|
+
if (errText.includes('another server might be running')) {
|
|
256
|
+
process.stderr.write(`[pg-process] pg_ctl start: "another server might be running" — probing status\n`)
|
|
257
|
+
const statusR = spawnSync(pgctl, ['status', '-D', pgdataDir], { env, stdio: 'pipe', timeout: 3_000, windowsHide: true })
|
|
258
|
+
process.stderr.write(`[pg-process] pg_ctl status: ${statusR.stdout?.toString() || statusR.stderr?.toString() || 'no output'}\n`)
|
|
259
|
+
const stopR = spawnSync(pgctl, ['stop', '-m', 'immediate', '-D', pgdataDir], { env, stdio: 'pipe', timeout: 3_000, windowsHide: true })
|
|
260
|
+
if (stopR.status === 0) {
|
|
261
|
+
// Retry start once after clearing the stale instance.
|
|
262
|
+
const r2 = spawnSync(pgctl, [
|
|
263
|
+
'start', '-w',
|
|
264
|
+
'-D', pgdataDir,
|
|
265
|
+
'-l', logPath ?? join(pgdataDir, 'pg.log'),
|
|
266
|
+
'-o', `-p ${port} -h 127.0.0.1`,
|
|
267
|
+
], { env, stdio: 'pipe', timeout: 30_000, windowsHide: true })
|
|
268
|
+
if (r2.status === 0) {
|
|
269
|
+
let pid = null
|
|
270
|
+
try {
|
|
271
|
+
const pidFile = join(pgdataDir, 'postmaster.pid')
|
|
272
|
+
if (existsSync(pidFile)) pid = parseInt(readFileSync(pidFile, 'utf8').split('\n')[0], 10) || null
|
|
273
|
+
} catch {}
|
|
274
|
+
return { pid, port }
|
|
275
|
+
}
|
|
276
|
+
process.stderr.write(`[pg-process] retry start after stop also failed: ${r2.stderr?.toString() || ''}\n`)
|
|
277
|
+
} else {
|
|
278
|
+
process.stderr.write(`[pg-process] immediate stop failed: ${stopR.stderr?.toString() || ''} — treating as degraded\n`)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
throw new Error(`[pg-process] pg_ctl start failed: ${errText}`)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Read PID from postmaster.pid (first line).
|
|
285
|
+
let pid = null
|
|
286
|
+
try {
|
|
287
|
+
const pidFile = join(pgdataDir, 'postmaster.pid')
|
|
288
|
+
if (existsSync(pidFile)) {
|
|
289
|
+
pid = parseInt(readFileSync(pidFile, 'utf8').split('\n')[0], 10) || null
|
|
290
|
+
}
|
|
291
|
+
} catch {}
|
|
292
|
+
|
|
293
|
+
return { pid, port }
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ---------------------------------------------------------------------------
|
|
297
|
+
// stopPg
|
|
298
|
+
// ---------------------------------------------------------------------------
|
|
299
|
+
|
|
300
|
+
export async function stopPg({ runtimeDir, pgdataDir }) {
|
|
301
|
+
const pgctl = pgBin(runtimeDir, 'pg_ctl')
|
|
302
|
+
const env = libEnv(runtimeDir)
|
|
303
|
+
|
|
304
|
+
const r = spawnSync(pgctl, ['stop', '-m', 'fast', '-w', '-D', pgdataDir], {
|
|
305
|
+
env,
|
|
306
|
+
stdio: 'pipe',
|
|
307
|
+
timeout: 15_000,
|
|
308
|
+
windowsHide: true,
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
if (r.status !== 0) {
|
|
312
|
+
const msg = r.stderr?.toString() || r.stdout?.toString() || ''
|
|
313
|
+
// Stale postmaster.pid — PG is already down; clean up and continue.
|
|
314
|
+
if (
|
|
315
|
+
msg.includes('no server running') ||
|
|
316
|
+
msg.includes('PID file') ||
|
|
317
|
+
msg.includes('not running')
|
|
318
|
+
) {
|
|
319
|
+
process.stderr.write(`[pg-process] stopPg: already stopped (${msg.slice(0, 80)})\n`)
|
|
320
|
+
try { rmSync(join(pgdataDir, 'postmaster.pid'), { force: true }) } catch {}
|
|
321
|
+
} else {
|
|
322
|
+
process.stderr.write(`[pg-process] pg_ctl stop warning: ${msg}\n`)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
// healthcheckPg
|
|
329
|
+
// ---------------------------------------------------------------------------
|
|
330
|
+
|
|
331
|
+
export async function healthcheckPg({ port, host = '127.0.0.1' }) {
|
|
332
|
+
// Phase 1: TCP listen check (fast, no PG client dependency).
|
|
333
|
+
const tcpOk = await new Promise(resolve => {
|
|
334
|
+
const sock = createConnection({ host, port })
|
|
335
|
+
sock.setTimeout(1000)
|
|
336
|
+
sock.once('connect', () => { sock.destroy(); resolve(true) })
|
|
337
|
+
sock.once('error', () => { sock.destroy(); resolve(false) })
|
|
338
|
+
sock.once('timeout', () => { sock.destroy(); resolve(false) })
|
|
339
|
+
})
|
|
340
|
+
if (!tcpOk) return false
|
|
341
|
+
|
|
342
|
+
// Phase 2: SELECT 1 via a transient pg client.
|
|
343
|
+
let client
|
|
344
|
+
try {
|
|
345
|
+
const { default: pg } = await import('pg')
|
|
346
|
+
client = new pg.Client({
|
|
347
|
+
host, port, user: 'postgres', database: 'postgres', password: '',
|
|
348
|
+
connectionTimeoutMillis: 2000,
|
|
349
|
+
})
|
|
350
|
+
await client.connect()
|
|
351
|
+
await client.query('SELECT 1')
|
|
352
|
+
return true
|
|
353
|
+
} catch {
|
|
354
|
+
return false
|
|
355
|
+
} finally {
|
|
356
|
+
if (client) {
|
|
357
|
+
try { await client.end() } catch {}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|