@poolzin/pool-bot 2026.2.21 → 2026.2.22
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/CHANGELOG.md +17 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
|
@@ -1,104 +1,83 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
1
4
|
import path from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
2
6
|
import { resolveGatewayPort, resolveIsNixMode } from "../config/paths.js";
|
|
3
7
|
import { findExtraGatewayServices, renderGatewayServiceCleanupHints } from "../daemon/inspect.js";
|
|
4
|
-
import { findLegacyGatewayServices, uninstallLegacyGatewayServices } from "../daemon/legacy.js";
|
|
5
8
|
import { renderSystemNodeWarning, resolveSystemNodeInfo } from "../daemon/runtime-paths.js";
|
|
6
|
-
import { resolveGatewayService } from "../daemon/service.js";
|
|
7
9
|
import { auditGatewayServiceConfig, needsNodeRuntimeMigration, SERVICE_AUDIT_CODES, } from "../daemon/service-audit.js";
|
|
10
|
+
import { resolveGatewayService } from "../daemon/service.js";
|
|
8
11
|
import { note } from "../terminal/note.js";
|
|
9
|
-
import { buildGatewayInstallPlan
|
|
10
|
-
import { DEFAULT_GATEWAY_DAEMON_RUNTIME
|
|
12
|
+
import { buildGatewayInstallPlan } from "./daemon-install-helpers.js";
|
|
13
|
+
import { DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime.js";
|
|
14
|
+
const execFileAsync = promisify(execFile);
|
|
11
15
|
function detectGatewayRuntime(programArguments) {
|
|
12
16
|
const first = programArguments?.[0];
|
|
13
17
|
if (first) {
|
|
14
18
|
const base = path.basename(first).toLowerCase();
|
|
15
|
-
if (base === "bun" || base === "bun.exe")
|
|
19
|
+
if (base === "bun" || base === "bun.exe") {
|
|
16
20
|
return "bun";
|
|
17
|
-
|
|
21
|
+
}
|
|
22
|
+
if (base === "node" || base === "node.exe") {
|
|
18
23
|
return "node";
|
|
24
|
+
}
|
|
19
25
|
}
|
|
20
26
|
return DEFAULT_GATEWAY_DAEMON_RUNTIME;
|
|
21
27
|
}
|
|
22
28
|
function findGatewayEntrypoint(programArguments) {
|
|
23
|
-
if (!programArguments || programArguments.length === 0)
|
|
29
|
+
if (!programArguments || programArguments.length === 0) {
|
|
24
30
|
return null;
|
|
31
|
+
}
|
|
25
32
|
const gatewayIndex = programArguments.indexOf("gateway");
|
|
26
|
-
if (gatewayIndex <= 0)
|
|
33
|
+
if (gatewayIndex <= 0) {
|
|
27
34
|
return null;
|
|
35
|
+
}
|
|
28
36
|
return programArguments[gatewayIndex - 1] ?? null;
|
|
29
37
|
}
|
|
30
38
|
function normalizeExecutablePath(value) {
|
|
31
39
|
return path.resolve(value);
|
|
32
40
|
}
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
return;
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
await uninstallLegacyGatewayServices({
|
|
46
|
-
env: process.env,
|
|
47
|
-
stdout: process.stdout,
|
|
48
|
-
});
|
|
41
|
+
function resolveGatewayAuthToken(cfg, env) {
|
|
42
|
+
const configToken = cfg.gateway?.auth?.token?.trim();
|
|
43
|
+
if (configToken) {
|
|
44
|
+
return configToken;
|
|
45
|
+
}
|
|
46
|
+
const envToken = env.POOLBOT_GATEWAY_TOKEN ?? env.CLAWDBOT_GATEWAY_TOKEN;
|
|
47
|
+
const trimmedEnvToken = envToken?.trim();
|
|
48
|
+
return trimmedEnvToken || undefined;
|
|
49
|
+
}
|
|
50
|
+
function extractDetailPath(detail, prefix) {
|
|
51
|
+
if (!detail.startsWith(prefix)) {
|
|
52
|
+
return null;
|
|
49
53
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
const value = detail.slice(prefix.length).trim();
|
|
55
|
+
return value.length > 0 ? value : null;
|
|
56
|
+
}
|
|
57
|
+
async function cleanupLegacyLaunchdService(params) {
|
|
58
|
+
const domain = typeof process.getuid === "function" ? `gui/${process.getuid()}` : "gui/501";
|
|
59
|
+
await execFileAsync("launchctl", ["bootout", domain, params.plistPath]).catch(() => undefined);
|
|
60
|
+
await execFileAsync("launchctl", ["unload", params.plistPath]).catch(() => undefined);
|
|
61
|
+
const trashDir = path.join(os.homedir(), ".Trash");
|
|
62
|
+
try {
|
|
63
|
+
await fs.mkdir(trashDir, { recursive: true });
|
|
53
64
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return;
|
|
65
|
+
catch {
|
|
66
|
+
// ignore
|
|
57
67
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return;
|
|
68
|
+
try {
|
|
69
|
+
await fs.access(params.plistPath);
|
|
61
70
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (loaded) {
|
|
65
|
-
note(`Poolbot ${service.label} already ${service.loadedText}.`, "Gateway");
|
|
66
|
-
return;
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
67
73
|
}
|
|
68
|
-
const
|
|
69
|
-
message: "Install Poolbot gateway service now?",
|
|
70
|
-
initialValue: true,
|
|
71
|
-
});
|
|
72
|
-
if (!install)
|
|
73
|
-
return;
|
|
74
|
-
const daemonRuntime = await prompter.select({
|
|
75
|
-
message: "Gateway service runtime",
|
|
76
|
-
options: GATEWAY_DAEMON_RUNTIME_OPTIONS,
|
|
77
|
-
initialValue: DEFAULT_GATEWAY_DAEMON_RUNTIME,
|
|
78
|
-
}, DEFAULT_GATEWAY_DAEMON_RUNTIME);
|
|
79
|
-
const port = resolveGatewayPort(cfg, process.env);
|
|
80
|
-
const { programArguments, workingDirectory, environment } = await buildGatewayInstallPlan({
|
|
81
|
-
env: process.env,
|
|
82
|
-
port,
|
|
83
|
-
token: cfg.gateway?.auth?.token ??
|
|
84
|
-
process.env.POOLBOT_GATEWAY_TOKEN ??
|
|
85
|
-
process.env.CLAWDBOT_GATEWAY_TOKEN,
|
|
86
|
-
runtime: daemonRuntime,
|
|
87
|
-
warn: (message, title) => note(message, title),
|
|
88
|
-
config: cfg,
|
|
89
|
-
});
|
|
74
|
+
const dest = path.join(trashDir, `${params.label}-${Date.now()}.plist`);
|
|
90
75
|
try {
|
|
91
|
-
await
|
|
92
|
-
|
|
93
|
-
stdout: process.stdout,
|
|
94
|
-
programArguments,
|
|
95
|
-
workingDirectory,
|
|
96
|
-
environment,
|
|
97
|
-
});
|
|
76
|
+
await fs.rename(params.plistPath, dest);
|
|
77
|
+
return dest;
|
|
98
78
|
}
|
|
99
|
-
catch
|
|
100
|
-
|
|
101
|
-
note(gatewayInstallErrorHint(), "Gateway");
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
102
81
|
}
|
|
103
82
|
}
|
|
104
83
|
export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompter) {
|
|
@@ -118,11 +97,14 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
118
97
|
catch {
|
|
119
98
|
command = null;
|
|
120
99
|
}
|
|
121
|
-
if (!command)
|
|
100
|
+
if (!command) {
|
|
122
101
|
return;
|
|
102
|
+
}
|
|
103
|
+
const expectedGatewayToken = resolveGatewayAuthToken(cfg, process.env);
|
|
123
104
|
const audit = await auditGatewayServiceConfig({
|
|
124
105
|
env: process.env,
|
|
125
106
|
command,
|
|
107
|
+
expectedGatewayToken,
|
|
126
108
|
});
|
|
127
109
|
const needsNodeRuntime = needsNodeRuntimeMigration(audit.issues);
|
|
128
110
|
const systemNodeInfo = needsNodeRuntime
|
|
@@ -131,8 +113,9 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
131
113
|
const systemNodePath = systemNodeInfo?.supported ? systemNodeInfo.path : null;
|
|
132
114
|
if (needsNodeRuntime && !systemNodePath) {
|
|
133
115
|
const warning = renderSystemNodeWarning(systemNodeInfo);
|
|
134
|
-
if (warning)
|
|
116
|
+
if (warning) {
|
|
135
117
|
note(warning, "Gateway runtime");
|
|
118
|
+
}
|
|
136
119
|
note("System Node 22+ not found. Install via Homebrew/apt/choco and rerun doctor to migrate off Bun/version managers.", "Gateway runtime");
|
|
137
120
|
}
|
|
138
121
|
const port = resolveGatewayPort(cfg, process.env);
|
|
@@ -140,9 +123,7 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
140
123
|
const { programArguments, workingDirectory, environment } = await buildGatewayInstallPlan({
|
|
141
124
|
env: process.env,
|
|
142
125
|
port,
|
|
143
|
-
token:
|
|
144
|
-
process.env.POOLBOT_GATEWAY_TOKEN ??
|
|
145
|
-
process.env.CLAWDBOT_GATEWAY_TOKEN,
|
|
126
|
+
token: expectedGatewayToken,
|
|
146
127
|
runtime: needsNodeRuntime && systemNodePath ? "node" : runtimeChoice,
|
|
147
128
|
nodePath: systemNodePath ?? undefined,
|
|
148
129
|
warn: (message, title) => note(message, title),
|
|
@@ -160,8 +141,9 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
160
141
|
level: "recommended",
|
|
161
142
|
});
|
|
162
143
|
}
|
|
163
|
-
if (audit.issues.length === 0)
|
|
144
|
+
if (audit.issues.length === 0) {
|
|
164
145
|
return;
|
|
146
|
+
}
|
|
165
147
|
note(audit.issues
|
|
166
148
|
.map((issue) => issue.detail ? `- ${issue.message} (${issue.detail})` : `- ${issue.message}`)
|
|
167
149
|
.join("\n"), "Gateway service config");
|
|
@@ -179,8 +161,9 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
179
161
|
message: "Update gateway service config to the recommended defaults now?",
|
|
180
162
|
initialValue: true,
|
|
181
163
|
});
|
|
182
|
-
if (!repair)
|
|
164
|
+
if (!repair) {
|
|
183
165
|
return;
|
|
166
|
+
}
|
|
184
167
|
try {
|
|
185
168
|
await service.install({
|
|
186
169
|
env: process.env,
|
|
@@ -194,13 +177,54 @@ export async function maybeRepairGatewayServiceConfig(cfg, mode, runtime, prompt
|
|
|
194
177
|
runtime.error(`Gateway service update failed: ${String(err)}`);
|
|
195
178
|
}
|
|
196
179
|
}
|
|
197
|
-
export async function maybeScanExtraGatewayServices(options) {
|
|
180
|
+
export async function maybeScanExtraGatewayServices(options, runtime, prompter) {
|
|
198
181
|
const extraServices = await findExtraGatewayServices(process.env, {
|
|
199
182
|
deep: options.deep,
|
|
200
183
|
});
|
|
201
|
-
if (extraServices.length === 0)
|
|
184
|
+
if (extraServices.length === 0) {
|
|
202
185
|
return;
|
|
186
|
+
}
|
|
203
187
|
note(extraServices.map((svc) => `- ${svc.label} (${svc.scope}, ${svc.detail})`).join("\n"), "Other gateway-like services detected");
|
|
188
|
+
const legacyServices = extraServices.filter((svc) => svc.legacy === true);
|
|
189
|
+
if (legacyServices.length > 0) {
|
|
190
|
+
const shouldRemove = await prompter.confirmSkipInNonInteractive({
|
|
191
|
+
message: "Remove legacy gateway services (clawdbot/moltbot) now?",
|
|
192
|
+
initialValue: true,
|
|
193
|
+
});
|
|
194
|
+
if (shouldRemove) {
|
|
195
|
+
const removed = [];
|
|
196
|
+
const failed = [];
|
|
197
|
+
for (const svc of legacyServices) {
|
|
198
|
+
if (svc.platform !== "darwin") {
|
|
199
|
+
failed.push(`${svc.label} (${svc.platform})`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (svc.scope !== "user") {
|
|
203
|
+
failed.push(`${svc.label} (${svc.scope})`);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const plistPath = extractDetailPath(svc.detail, "plist:");
|
|
207
|
+
if (!plistPath) {
|
|
208
|
+
failed.push(`${svc.label} (missing plist path)`);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
const dest = await cleanupLegacyLaunchdService({
|
|
212
|
+
label: svc.label,
|
|
213
|
+
plistPath,
|
|
214
|
+
});
|
|
215
|
+
removed.push(dest ? `${svc.label} -> ${dest}` : svc.label);
|
|
216
|
+
}
|
|
217
|
+
if (removed.length > 0) {
|
|
218
|
+
note(removed.map((line) => `- ${line}`).join("\n"), "Legacy gateway removed");
|
|
219
|
+
}
|
|
220
|
+
if (failed.length > 0) {
|
|
221
|
+
note(failed.map((line) => `- ${line}`).join("\n"), "Legacy gateway cleanup skipped");
|
|
222
|
+
}
|
|
223
|
+
if (removed.length > 0) {
|
|
224
|
+
runtime.log("Legacy gateway services removed. Installing Pool Bot gateway next.");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
204
228
|
const cleanupHints = renderGatewayServiceCleanupHints();
|
|
205
229
|
if (cleanupHints.length > 0) {
|
|
206
230
|
note(cleanupHints.map((hint) => `- ${hint}`).join("\n"), "Cleanup hints");
|
|
@@ -7,7 +7,7 @@ import { note } from "../terminal/note.js";
|
|
|
7
7
|
import { resolveUserPath } from "../utils.js";
|
|
8
8
|
/**
|
|
9
9
|
* Check whether memory search has a usable embedding provider.
|
|
10
|
-
* Runs as part of `
|
|
10
|
+
* Runs as part of `poolbot doctor` — config-only, no network calls.
|
|
11
11
|
*/
|
|
12
12
|
export async function noteMemorySearchHealth(cfg) {
|
|
13
13
|
const agentId = resolveDefaultAgentId(cfg);
|
|
@@ -29,9 +29,9 @@ export async function noteMemorySearchHealth(cfg) {
|
|
|
29
29
|
"",
|
|
30
30
|
"Fix (pick one):",
|
|
31
31
|
`- Install node-llama-cpp and set a local model path in config`,
|
|
32
|
-
`- Switch to a remote provider: ${formatCliCommand("
|
|
32
|
+
`- Switch to a remote provider: ${formatCliCommand("poolbot config set agents.defaults.memorySearch.provider openai")}`,
|
|
33
33
|
"",
|
|
34
|
-
`Verify: ${formatCliCommand("
|
|
34
|
+
`Verify: ${formatCliCommand("poolbot memory status --deep")}`,
|
|
35
35
|
].join("\n"), "Memory search");
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
@@ -46,10 +46,10 @@ export async function noteMemorySearchHealth(cfg) {
|
|
|
46
46
|
"",
|
|
47
47
|
"Fix (pick one):",
|
|
48
48
|
`- Set ${envVar} in your environment`,
|
|
49
|
-
`- Add credentials: ${formatCliCommand(`
|
|
50
|
-
`- To disable: ${formatCliCommand("
|
|
49
|
+
`- Add credentials: ${formatCliCommand(`poolbot auth add --provider ${resolved.provider}`)}`,
|
|
50
|
+
`- To disable: ${formatCliCommand("poolbot config set agents.defaults.memorySearch.enabled false")}`,
|
|
51
51
|
"",
|
|
52
|
-
`Verify: ${formatCliCommand("
|
|
52
|
+
`Verify: ${formatCliCommand("poolbot memory status --deep")}`,
|
|
53
53
|
].join("\n"), "Memory search");
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
@@ -68,11 +68,11 @@ export async function noteMemorySearchHealth(cfg) {
|
|
|
68
68
|
"",
|
|
69
69
|
"Fix (pick one):",
|
|
70
70
|
"- Set OPENAI_API_KEY or GEMINI_API_KEY in your environment",
|
|
71
|
-
`- Add credentials: ${formatCliCommand("
|
|
71
|
+
`- Add credentials: ${formatCliCommand("poolbot auth add --provider openai")}`,
|
|
72
72
|
`- For local embeddings: configure agents.defaults.memorySearch.provider and local model path`,
|
|
73
|
-
`- To disable: ${formatCliCommand("
|
|
73
|
+
`- To disable: ${formatCliCommand("poolbot config set agents.defaults.memorySearch.enabled false")}`,
|
|
74
74
|
"",
|
|
75
|
-
`Verify: ${formatCliCommand("
|
|
75
|
+
`Verify: ${formatCliCommand("poolbot memory status --deep")}`,
|
|
76
76
|
].join("\n"), "Memory search");
|
|
77
77
|
}
|
|
78
78
|
function hasLocalEmbeddings(local) {
|
|
@@ -10,12 +10,15 @@ function resolveHomeDir() {
|
|
|
10
10
|
return process.env.HOME ?? os.homedir();
|
|
11
11
|
}
|
|
12
12
|
export async function noteMacLaunchAgentOverrides() {
|
|
13
|
-
if (process.platform !== "darwin")
|
|
13
|
+
if (process.platform !== "darwin") {
|
|
14
14
|
return;
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
15
|
+
}
|
|
16
|
+
const home = resolveHomeDir();
|
|
17
|
+
const markerCandidates = [path.join(home, ".poolbot", "disable-launchagent")];
|
|
18
|
+
const markerPath = markerCandidates.find((candidate) => fs.existsSync(candidate));
|
|
19
|
+
if (!markerPath) {
|
|
18
20
|
return;
|
|
21
|
+
}
|
|
19
22
|
const displayMarkerPath = shortenHomePath(markerPath);
|
|
20
23
|
const lines = [
|
|
21
24
|
`- LaunchAgent writes are disabled via ${displayMarkerPath}.`,
|
|
@@ -43,41 +46,65 @@ function hasConfigGatewayCreds(cfg) {
|
|
|
43
46
|
}
|
|
44
47
|
export async function noteMacLaunchctlGatewayEnvOverrides(cfg, deps) {
|
|
45
48
|
const platform = deps?.platform ?? process.platform;
|
|
46
|
-
if (platform !== "darwin")
|
|
49
|
+
if (platform !== "darwin") {
|
|
47
50
|
return;
|
|
48
|
-
|
|
51
|
+
}
|
|
52
|
+
if (!hasConfigGatewayCreds(cfg)) {
|
|
49
53
|
return;
|
|
54
|
+
}
|
|
50
55
|
const getenv = deps?.getenv ?? launchctlGetenv;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const deprecatedLaunchctlEntries = [
|
|
57
|
+
["CLAWDBOT_GATEWAY_TOKEN", await getenv("CLAWDBOT_GATEWAY_TOKEN")],
|
|
58
|
+
["CLAWDBOT_GATEWAY_PASSWORD", await getenv("CLAWDBOT_GATEWAY_PASSWORD")],
|
|
59
|
+
].filter((entry) => Boolean(entry[1]?.trim()));
|
|
60
|
+
if (deprecatedLaunchctlEntries.length > 0) {
|
|
61
|
+
const lines = [
|
|
62
|
+
"- Deprecated launchctl environment variables detected (ignored).",
|
|
63
|
+
...deprecatedLaunchctlEntries.map(([key]) => `- \`${key}\` is set; use \`POOLBOT_${key.slice(key.indexOf("_") + 1)}\` instead.`),
|
|
64
|
+
];
|
|
65
|
+
(deps?.noteFn ?? note)(lines.join("\n"), "Gateway (macOS)");
|
|
66
|
+
}
|
|
67
|
+
const tokenEntries = [["POOLBOT_GATEWAY_TOKEN", await getenv("POOLBOT_GATEWAY_TOKEN")]];
|
|
68
|
+
const passwordEntries = [
|
|
69
|
+
["POOLBOT_GATEWAY_PASSWORD", await getenv("POOLBOT_GATEWAY_PASSWORD")],
|
|
70
|
+
];
|
|
71
|
+
const tokenEntry = tokenEntries.find(([, value]) => value?.trim());
|
|
72
|
+
const passwordEntry = passwordEntries.find(([, value]) => value?.trim());
|
|
73
|
+
const envToken = tokenEntry?.[1]?.trim() ?? "";
|
|
74
|
+
const envPassword = passwordEntry?.[1]?.trim() ?? "";
|
|
75
|
+
const envTokenKey = tokenEntry?.[0];
|
|
76
|
+
const envPasswordKey = passwordEntry?.[0];
|
|
77
|
+
if (!envToken && !envPassword) {
|
|
59
78
|
return;
|
|
60
|
-
|
|
61
|
-
if (poolbotToken)
|
|
62
|
-
tokenUnsets.push(" launchctl unsetenv POOLBOT_GATEWAY_TOKEN");
|
|
63
|
-
if (clawdbotToken)
|
|
64
|
-
tokenUnsets.push(" launchctl unsetenv CLAWDBOT_GATEWAY_TOKEN");
|
|
65
|
-
const passwordUnsets = [];
|
|
66
|
-
if (poolbotPassword)
|
|
67
|
-
passwordUnsets.push(" launchctl unsetenv POOLBOT_GATEWAY_PASSWORD");
|
|
68
|
-
if (clawdbotPassword)
|
|
69
|
-
passwordUnsets.push(" launchctl unsetenv CLAWDBOT_GATEWAY_PASSWORD");
|
|
79
|
+
}
|
|
70
80
|
const lines = [
|
|
71
81
|
"- launchctl environment overrides detected (can cause confusing unauthorized errors).",
|
|
72
|
-
|
|
73
|
-
? `- \`${
|
|
82
|
+
envToken && envTokenKey
|
|
83
|
+
? `- \`${envTokenKey}\` is set; it overrides config tokens.`
|
|
74
84
|
: undefined,
|
|
75
|
-
|
|
76
|
-
? `- \`${
|
|
85
|
+
envPassword
|
|
86
|
+
? `- \`${envPasswordKey ?? "POOLBOT_GATEWAY_PASSWORD"}\` is set; it overrides config passwords.`
|
|
77
87
|
: undefined,
|
|
78
88
|
"- Clear overrides and restart the app/gateway:",
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
envTokenKey ? ` launchctl unsetenv ${envTokenKey}` : undefined,
|
|
90
|
+
envPasswordKey ? ` launchctl unsetenv ${envPasswordKey}` : undefined,
|
|
81
91
|
].filter((line) => Boolean(line));
|
|
82
92
|
(deps?.noteFn ?? note)(lines.join("\n"), "Gateway (macOS)");
|
|
83
93
|
}
|
|
94
|
+
export function noteDeprecatedLegacyEnvVars(env = process.env, deps) {
|
|
95
|
+
const entries = Object.entries(env)
|
|
96
|
+
.filter(([key, value]) => key.startsWith("CLAWDBOT_") && value?.trim())
|
|
97
|
+
.map(([key]) => key);
|
|
98
|
+
if (entries.length === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const lines = [
|
|
102
|
+
"- Deprecated legacy environment variables detected (ignored).",
|
|
103
|
+
"- Use POOLBOT_* equivalents instead:",
|
|
104
|
+
...entries.map((key) => {
|
|
105
|
+
const suffix = key.slice(key.indexOf("_") + 1);
|
|
106
|
+
return ` ${key} -> POOLBOT_${suffix}`;
|
|
107
|
+
}),
|
|
108
|
+
];
|
|
109
|
+
(deps?.noteFn ?? note)(lines.join("\n"), "Environment");
|
|
110
|
+
}
|
|
@@ -10,48 +10,59 @@ export function createDoctorPrompter(params) {
|
|
|
10
10
|
const nonInteractive = requestedNonInteractive || (!isTty && !yes);
|
|
11
11
|
const canPrompt = isTty && !yes && !nonInteractive;
|
|
12
12
|
const confirmDefault = async (p) => {
|
|
13
|
-
if (nonInteractive)
|
|
13
|
+
if (nonInteractive) {
|
|
14
14
|
return false;
|
|
15
|
-
|
|
15
|
+
}
|
|
16
|
+
if (shouldRepair) {
|
|
16
17
|
return true;
|
|
17
|
-
|
|
18
|
+
}
|
|
19
|
+
if (!canPrompt) {
|
|
18
20
|
return Boolean(p.initialValue ?? false);
|
|
19
|
-
|
|
21
|
+
}
|
|
22
|
+
return guardCancel(await confirm({
|
|
20
23
|
...p,
|
|
21
24
|
message: stylePromptMessage(p.message),
|
|
22
|
-
}), params.runtime)
|
|
25
|
+
}), params.runtime);
|
|
23
26
|
};
|
|
24
27
|
return {
|
|
25
28
|
confirm: confirmDefault,
|
|
26
29
|
confirmRepair: async (p) => {
|
|
27
|
-
if (nonInteractive)
|
|
30
|
+
if (nonInteractive) {
|
|
28
31
|
return false;
|
|
32
|
+
}
|
|
29
33
|
return confirmDefault(p);
|
|
30
34
|
},
|
|
31
35
|
confirmAggressive: async (p) => {
|
|
32
|
-
if (nonInteractive)
|
|
36
|
+
if (nonInteractive) {
|
|
33
37
|
return false;
|
|
34
|
-
|
|
38
|
+
}
|
|
39
|
+
if (shouldRepair && shouldForce) {
|
|
35
40
|
return true;
|
|
36
|
-
|
|
41
|
+
}
|
|
42
|
+
if (shouldRepair && !shouldForce) {
|
|
37
43
|
return false;
|
|
38
|
-
|
|
44
|
+
}
|
|
45
|
+
if (!canPrompt) {
|
|
39
46
|
return Boolean(p.initialValue ?? false);
|
|
40
|
-
|
|
47
|
+
}
|
|
48
|
+
return guardCancel(await confirm({
|
|
41
49
|
...p,
|
|
42
50
|
message: stylePromptMessage(p.message),
|
|
43
|
-
}), params.runtime)
|
|
51
|
+
}), params.runtime);
|
|
44
52
|
},
|
|
45
53
|
confirmSkipInNonInteractive: async (p) => {
|
|
46
|
-
if (nonInteractive)
|
|
54
|
+
if (nonInteractive) {
|
|
47
55
|
return false;
|
|
48
|
-
|
|
56
|
+
}
|
|
57
|
+
if (shouldRepair) {
|
|
49
58
|
return true;
|
|
59
|
+
}
|
|
50
60
|
return confirmDefault(p);
|
|
51
61
|
},
|
|
52
62
|
select: async (p, fallback) => {
|
|
53
|
-
if (!canPrompt || shouldRepair)
|
|
63
|
+
if (!canPrompt || shouldRepair) {
|
|
54
64
|
return fallback;
|
|
65
|
+
}
|
|
55
66
|
return guardCancel(await select({
|
|
56
67
|
...p,
|
|
57
68
|
message: stylePromptMessage(p.message),
|
|
@@ -64,7 +64,7 @@ export async function noteSessionLockHealth(params) {
|
|
|
64
64
|
];
|
|
65
65
|
if (staleCount > 0 && !shouldRepair) {
|
|
66
66
|
lines.push(`- ${staleCount} lock file${staleCount === 1 ? " is" : "s are"} stale.`);
|
|
67
|
-
lines.push('- Run "
|
|
67
|
+
lines.push('- Run "poolbot doctor --fix" to remove stale lock files automatically.');
|
|
68
68
|
}
|
|
69
69
|
if (shouldRepair && removedCount > 0) {
|
|
70
70
|
lines.push(`- Removed ${removedCount} stale session lock file${removedCount === 1 ? "" : "s"}.`);
|
package/dist/commands/doctor.js
CHANGED
|
@@ -16,21 +16,24 @@ import { note } from "../terminal/note.js";
|
|
|
16
16
|
import { stylePromptTitle } from "../terminal/prompt-style.js";
|
|
17
17
|
import { shortenHomePath } from "../utils.js";
|
|
18
18
|
import { maybeRemoveDeprecatedCliAuthProfiles, maybeRepairAnthropicOAuthProfileId, noteAuthProfileHealth, } from "./doctor-auth.js";
|
|
19
|
+
import { doctorShellCompletion } from "./doctor-completion.js";
|
|
19
20
|
import { loadAndMaybeMigrateDoctorConfig } from "./doctor-config-flow.js";
|
|
20
21
|
import { maybeRepairGatewayDaemon } from "./doctor-gateway-daemon-flow.js";
|
|
21
22
|
import { checkGatewayHealth } from "./doctor-gateway-health.js";
|
|
22
|
-
import {
|
|
23
|
+
import { maybeRepairGatewayServiceConfig, maybeScanExtraGatewayServices, } from "./doctor-gateway-services.js";
|
|
23
24
|
import { noteSourceInstallIssues } from "./doctor-install.js";
|
|
24
|
-
import {
|
|
25
|
+
import { noteMemorySearchHealth } from "./doctor-memory-search.js";
|
|
26
|
+
import { noteMacLaunchAgentOverrides, noteMacLaunchctlGatewayEnvOverrides, noteDeprecatedLegacyEnvVars, } from "./doctor-platform-notes.js";
|
|
25
27
|
import { createDoctorPrompter } from "./doctor-prompter.js";
|
|
26
28
|
import { maybeRepairSandboxImages, noteSandboxScopeWarnings } from "./doctor-sandbox.js";
|
|
27
29
|
import { noteSecurityWarnings } from "./doctor-security.js";
|
|
30
|
+
import { noteSessionLockHealth } from "./doctor-session-locks.js";
|
|
28
31
|
import { noteStateIntegrity, noteWorkspaceBackupTip } from "./doctor-state-integrity.js";
|
|
29
32
|
import { detectLegacyStateMigrations, runLegacyStateMigrations, } from "./doctor-state-migrations.js";
|
|
30
33
|
import { maybeRepairUiProtocolFreshness } from "./doctor-ui.js";
|
|
31
34
|
import { maybeOfferUpdateBeforeDoctor } from "./doctor-update.js";
|
|
32
|
-
import { MEMORY_SYSTEM_PROMPT, shouldSuggestMemorySystem } from "./doctor-workspace.js";
|
|
33
35
|
import { noteWorkspaceStatus } from "./doctor-workspace-status.js";
|
|
36
|
+
import { MEMORY_SYSTEM_PROMPT, shouldSuggestMemorySystem } from "./doctor-workspace.js";
|
|
34
37
|
import { applyWizardMetadata, printWizardHeader, randomToken } from "./onboard-helpers.js";
|
|
35
38
|
import { ensureSystemdUserLingerInteractive } from "./systemd-linger.js";
|
|
36
39
|
const intro = (message) => clackIntro(stylePromptTitle(message) ?? message);
|
|
@@ -41,7 +44,7 @@ function resolveMode(cfg) {
|
|
|
41
44
|
export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
42
45
|
const prompter = createDoctorPrompter({ runtime, options });
|
|
43
46
|
printWizardHeader(runtime);
|
|
44
|
-
intro("
|
|
47
|
+
intro("Pool Bot doctor");
|
|
45
48
|
const root = await resolvePoolBotPackageRoot({
|
|
46
49
|
moduleUrl: import.meta.url,
|
|
47
50
|
argv1: process.argv[1],
|
|
@@ -54,15 +57,19 @@ export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
|
54
57
|
confirm: (p) => prompter.confirm(p),
|
|
55
58
|
outro,
|
|
56
59
|
});
|
|
57
|
-
if (updateResult.handled)
|
|
60
|
+
if (updateResult.handled) {
|
|
58
61
|
return;
|
|
62
|
+
}
|
|
59
63
|
await maybeRepairUiProtocolFreshness(runtime, prompter);
|
|
60
64
|
noteSourceInstallIssues(root);
|
|
65
|
+
noteDeprecatedLegacyEnvVars();
|
|
61
66
|
const configResult = await loadAndMaybeMigrateDoctorConfig({
|
|
62
67
|
options,
|
|
63
68
|
confirm: (p) => prompter.confirm(p),
|
|
64
69
|
});
|
|
65
70
|
let cfg = configResult.cfg;
|
|
71
|
+
const cfgForPersistence = structuredClone(cfg);
|
|
72
|
+
const sourceConfigValid = configResult.sourceConfigValid ?? true;
|
|
66
73
|
const configPath = configResult.path ?? CONFIG_PATH;
|
|
67
74
|
if (!cfg.gateway?.mode) {
|
|
68
75
|
const lines = [
|
|
@@ -86,7 +93,7 @@ export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
|
86
93
|
if (gatewayDetails.remoteFallbackNote) {
|
|
87
94
|
note(gatewayDetails.remoteFallbackNote, "Gateway");
|
|
88
95
|
}
|
|
89
|
-
if (resolveMode(cfg) === "local") {
|
|
96
|
+
if (resolveMode(cfg) === "local" && sourceConfigValid) {
|
|
90
97
|
const auth = resolveGatewayAuth({
|
|
91
98
|
authConfig: cfg.gateway?.auth,
|
|
92
99
|
tailscaleMode: cfg.gateway?.tailscale?.mode ?? "off",
|
|
@@ -141,10 +148,10 @@ export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
await noteStateIntegrity(cfg, prompter, configResult.path ?? CONFIG_PATH);
|
|
151
|
+
await noteSessionLockHealth({ shouldRepair: prompter.shouldRepair });
|
|
144
152
|
cfg = await maybeRepairSandboxImages(cfg, runtime, prompter);
|
|
145
153
|
noteSandboxScopeWarnings(cfg);
|
|
146
|
-
await
|
|
147
|
-
await maybeScanExtraGatewayServices(options);
|
|
154
|
+
await maybeScanExtraGatewayServices(options, runtime, prompter);
|
|
148
155
|
await maybeRepairGatewayServiceConfig(cfg, resolveMode(cfg), runtime, prompter);
|
|
149
156
|
await noteMacLaunchAgentOverrides();
|
|
150
157
|
await noteMacLaunchctlGatewayEnvOverrides(cfg);
|
|
@@ -207,6 +214,11 @@ export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
|
207
214
|
}
|
|
208
215
|
}
|
|
209
216
|
noteWorkspaceStatus(cfg);
|
|
217
|
+
await noteMemorySearchHealth(cfg);
|
|
218
|
+
// Check and fix shell completion
|
|
219
|
+
await doctorShellCompletion(runtime, prompter, {
|
|
220
|
+
nonInteractive: options.nonInteractive,
|
|
221
|
+
});
|
|
210
222
|
const { healthOk } = await checkGatewayHealth({
|
|
211
223
|
runtime,
|
|
212
224
|
cfg,
|
|
@@ -220,7 +232,7 @@ export async function doctorCommand(runtime = defaultRuntime, options = {}) {
|
|
|
220
232
|
gatewayDetailsMessage: gatewayDetails.message,
|
|
221
233
|
healthOk,
|
|
222
234
|
});
|
|
223
|
-
const shouldWriteConfig =
|
|
235
|
+
const shouldWriteConfig = configResult.shouldWriteConfig || JSON.stringify(cfg) !== JSON.stringify(cfgForPersistence);
|
|
224
236
|
if (shouldWriteConfig) {
|
|
225
237
|
cfg = applyWizardMetadata(cfg, { command: "doctor", mode: resolveMode(cfg) });
|
|
226
238
|
await writeConfigFile(cfg);
|