@poolzin/pool-bot 2026.2.21 → 2026.2.23
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 +25 -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/device-pair/index.ts +2 -2
- 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/irc/src/accounts.ts +1 -1
- package/extensions/irc/src/onboarding.ts +4 -4
- 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 +10 -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 +10 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +10 -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 +10 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +10 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +10 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +10 -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
- package/dist/agents/openclaw-tools.js +0 -151
- package/dist/agents/tool-security.js +0 -96
- package/dist/gateway/url-validation.js +0 -94
- package/dist/infra/openclaw-root.js +0 -109
- package/dist/infra/tmp-openclaw-dir.js +0 -81
- package/dist/media/path-sanitization.js +0 -78
package/dist/daemon/inspect.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
const EXTRA_MARKERS = ["poolbot"];
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
3
|
+
import { GATEWAY_SERVICE_KIND, GATEWAY_SERVICE_MARKER, resolveGatewayLaunchAgentLabel, resolveGatewaySystemdServiceName, resolveGatewayWindowsTaskName, } from "./constants.js";
|
|
4
|
+
import { execSchtasks } from "./schtasks-exec.js";
|
|
5
|
+
const EXTRA_MARKERS = ["poolbot", "clawdbot", "moltbot"];
|
|
8
6
|
export function renderGatewayServiceCleanupHints(env = process.env) {
|
|
9
|
-
const profile = env.POOLBOT_PROFILE
|
|
7
|
+
const profile = env.POOLBOT_PROFILE;
|
|
10
8
|
switch (process.platform) {
|
|
11
9
|
case "darwin": {
|
|
12
10
|
const label = resolveGatewayLaunchAgentLabel(profile);
|
|
@@ -29,127 +27,173 @@ export function renderGatewayServiceCleanupHints(env = process.env) {
|
|
|
29
27
|
}
|
|
30
28
|
function resolveHomeDir(env) {
|
|
31
29
|
const home = env.HOME?.trim() || env.USERPROFILE?.trim();
|
|
32
|
-
if (!home)
|
|
30
|
+
if (!home) {
|
|
33
31
|
throw new Error("Missing HOME");
|
|
32
|
+
}
|
|
34
33
|
return home;
|
|
35
34
|
}
|
|
36
|
-
function
|
|
35
|
+
function detectMarker(content) {
|
|
37
36
|
const lower = content.toLowerCase();
|
|
38
|
-
|
|
37
|
+
for (const marker of EXTRA_MARKERS) {
|
|
38
|
+
if (lower.includes(marker)) {
|
|
39
|
+
return marker;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
39
43
|
}
|
|
40
44
|
function hasGatewayServiceMarker(content) {
|
|
41
45
|
const lower = content.toLowerCase();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
const markerKeys = ["poolbot_service_marker"];
|
|
47
|
+
const kindKeys = ["poolbot_service_kind"];
|
|
48
|
+
const markerValues = [GATEWAY_SERVICE_MARKER.toLowerCase()];
|
|
49
|
+
const hasMarkerKey = markerKeys.some((key) => lower.includes(key));
|
|
50
|
+
const hasKindKey = kindKeys.some((key) => lower.includes(key));
|
|
51
|
+
const hasMarkerValue = markerValues.some((value) => lower.includes(value));
|
|
52
|
+
return (hasMarkerKey &&
|
|
53
|
+
hasKindKey &&
|
|
54
|
+
hasMarkerValue &&
|
|
45
55
|
lower.includes(GATEWAY_SERVICE_KIND.toLowerCase()));
|
|
46
56
|
}
|
|
47
|
-
function
|
|
48
|
-
if (hasGatewayServiceMarker(contents))
|
|
57
|
+
function isPoolBotGatewayLaunchdService(label, contents) {
|
|
58
|
+
if (hasGatewayServiceMarker(contents)) {
|
|
49
59
|
return true;
|
|
60
|
+
}
|
|
50
61
|
const lowerContents = contents.toLowerCase();
|
|
51
|
-
if (!lowerContents.includes("gateway"))
|
|
62
|
+
if (!lowerContents.includes("gateway")) {
|
|
52
63
|
return false;
|
|
53
|
-
|
|
64
|
+
}
|
|
65
|
+
return label.startsWith("ai.poolbot.");
|
|
54
66
|
}
|
|
55
|
-
function
|
|
56
|
-
if (hasGatewayServiceMarker(contents))
|
|
67
|
+
function isPoolBotGatewaySystemdService(name, contents) {
|
|
68
|
+
if (hasGatewayServiceMarker(contents)) {
|
|
57
69
|
return true;
|
|
58
|
-
|
|
70
|
+
}
|
|
71
|
+
if (!name.startsWith("poolbot-gateway")) {
|
|
59
72
|
return false;
|
|
73
|
+
}
|
|
60
74
|
return contents.toLowerCase().includes("gateway");
|
|
61
75
|
}
|
|
62
|
-
function
|
|
76
|
+
function isPoolBotGatewayTaskName(name) {
|
|
63
77
|
const normalized = name.trim().toLowerCase();
|
|
64
|
-
if (!normalized)
|
|
78
|
+
if (!normalized) {
|
|
65
79
|
return false;
|
|
80
|
+
}
|
|
66
81
|
const defaultName = resolveGatewayWindowsTaskName().toLowerCase();
|
|
67
82
|
return normalized === defaultName || normalized.startsWith("poolbot gateway");
|
|
68
83
|
}
|
|
69
84
|
function tryExtractPlistLabel(contents) {
|
|
70
85
|
const match = contents.match(/<key>Label<\/key>\s*<string>([\s\S]*?)<\/string>/i);
|
|
71
|
-
if (!match)
|
|
86
|
+
if (!match) {
|
|
72
87
|
return null;
|
|
88
|
+
}
|
|
73
89
|
return match[1]?.trim() || null;
|
|
74
90
|
}
|
|
75
91
|
function isIgnoredLaunchdLabel(label) {
|
|
76
|
-
return
|
|
92
|
+
return label === resolveGatewayLaunchAgentLabel();
|
|
77
93
|
}
|
|
78
94
|
function isIgnoredSystemdName(name) {
|
|
79
|
-
return
|
|
80
|
-
LEGACY_GATEWAY_SYSTEMD_SERVICE_NAMES.includes(name));
|
|
95
|
+
return name === resolveGatewaySystemdServiceName();
|
|
81
96
|
}
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
97
|
+
function isLegacyLabel(label) {
|
|
98
|
+
const lower = label.toLowerCase();
|
|
99
|
+
return lower.includes("clawdbot") || lower.includes("moltbot");
|
|
100
|
+
}
|
|
101
|
+
async function readDirEntries(dir) {
|
|
85
102
|
try {
|
|
86
|
-
|
|
103
|
+
return await fs.readdir(dir);
|
|
87
104
|
}
|
|
88
105
|
catch {
|
|
89
|
-
return
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function readUtf8File(filePath) {
|
|
110
|
+
try {
|
|
111
|
+
return await fs.readFile(filePath, "utf8");
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
90
115
|
}
|
|
116
|
+
}
|
|
117
|
+
async function scanLaunchdDir(params) {
|
|
118
|
+
const results = [];
|
|
119
|
+
const entries = await readDirEntries(params.dir);
|
|
91
120
|
for (const entry of entries) {
|
|
92
|
-
if (!entry.endsWith(".plist"))
|
|
121
|
+
if (!entry.endsWith(".plist")) {
|
|
93
122
|
continue;
|
|
123
|
+
}
|
|
94
124
|
const labelFromName = entry.replace(/\.plist$/, "");
|
|
95
|
-
if (isIgnoredLaunchdLabel(labelFromName))
|
|
125
|
+
if (isIgnoredLaunchdLabel(labelFromName)) {
|
|
96
126
|
continue;
|
|
97
|
-
const fullPath = path.join(params.dir, entry);
|
|
98
|
-
let contents = "";
|
|
99
|
-
try {
|
|
100
|
-
contents = await fs.readFile(fullPath, "utf8");
|
|
101
127
|
}
|
|
102
|
-
|
|
128
|
+
const fullPath = path.join(params.dir, entry);
|
|
129
|
+
const contents = await readUtf8File(fullPath);
|
|
130
|
+
if (contents === null) {
|
|
103
131
|
continue;
|
|
104
132
|
}
|
|
105
|
-
|
|
106
|
-
continue;
|
|
133
|
+
const marker = detectMarker(contents);
|
|
107
134
|
const label = tryExtractPlistLabel(contents) ?? labelFromName;
|
|
108
|
-
if (
|
|
135
|
+
if (!marker) {
|
|
136
|
+
const legacyLabel = isLegacyLabel(labelFromName) || isLegacyLabel(label);
|
|
137
|
+
if (!legacyLabel) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
results.push({
|
|
141
|
+
platform: "darwin",
|
|
142
|
+
label,
|
|
143
|
+
detail: `plist: ${fullPath}`,
|
|
144
|
+
scope: params.scope,
|
|
145
|
+
marker: isLegacyLabel(label) ? "clawdbot" : "moltbot",
|
|
146
|
+
legacy: true,
|
|
147
|
+
});
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (isIgnoredLaunchdLabel(label)) {
|
|
109
151
|
continue;
|
|
110
|
-
|
|
152
|
+
}
|
|
153
|
+
if (marker === "poolbot" && isPoolBotGatewayLaunchdService(label, contents)) {
|
|
111
154
|
continue;
|
|
155
|
+
}
|
|
112
156
|
results.push({
|
|
113
157
|
platform: "darwin",
|
|
114
158
|
label,
|
|
115
159
|
detail: `plist: ${fullPath}`,
|
|
116
160
|
scope: params.scope,
|
|
161
|
+
marker,
|
|
162
|
+
legacy: marker !== "poolbot" || isLegacyLabel(label),
|
|
117
163
|
});
|
|
118
164
|
}
|
|
119
165
|
return results;
|
|
120
166
|
}
|
|
121
167
|
async function scanSystemdDir(params) {
|
|
122
168
|
const results = [];
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
entries = await fs.readdir(params.dir);
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
return results;
|
|
129
|
-
}
|
|
169
|
+
const entries = await readDirEntries(params.dir);
|
|
130
170
|
for (const entry of entries) {
|
|
131
|
-
if (!entry.endsWith(".service"))
|
|
171
|
+
if (!entry.endsWith(".service")) {
|
|
132
172
|
continue;
|
|
173
|
+
}
|
|
133
174
|
const name = entry.replace(/\.service$/, "");
|
|
134
|
-
if (isIgnoredSystemdName(name))
|
|
175
|
+
if (isIgnoredSystemdName(name)) {
|
|
135
176
|
continue;
|
|
136
|
-
const fullPath = path.join(params.dir, entry);
|
|
137
|
-
let contents = "";
|
|
138
|
-
try {
|
|
139
|
-
contents = await fs.readFile(fullPath, "utf8");
|
|
140
177
|
}
|
|
141
|
-
|
|
178
|
+
const fullPath = path.join(params.dir, entry);
|
|
179
|
+
const contents = await readUtf8File(fullPath);
|
|
180
|
+
if (contents === null) {
|
|
142
181
|
continue;
|
|
143
182
|
}
|
|
144
|
-
|
|
183
|
+
const marker = detectMarker(contents);
|
|
184
|
+
if (!marker) {
|
|
145
185
|
continue;
|
|
146
|
-
|
|
186
|
+
}
|
|
187
|
+
if (marker === "poolbot" && isPoolBotGatewaySystemdService(name, contents)) {
|
|
147
188
|
continue;
|
|
189
|
+
}
|
|
148
190
|
results.push({
|
|
149
191
|
platform: "linux",
|
|
150
192
|
label: entry,
|
|
151
193
|
detail: `unit: ${fullPath}`,
|
|
152
194
|
scope: params.scope,
|
|
195
|
+
marker,
|
|
196
|
+
legacy: marker !== "poolbot",
|
|
153
197
|
});
|
|
154
198
|
}
|
|
155
199
|
return results;
|
|
@@ -167,56 +211,41 @@ function parseSchtasksList(output) {
|
|
|
167
211
|
continue;
|
|
168
212
|
}
|
|
169
213
|
const idx = line.indexOf(":");
|
|
170
|
-
if (idx <= 0)
|
|
214
|
+
if (idx <= 0) {
|
|
171
215
|
continue;
|
|
216
|
+
}
|
|
172
217
|
const key = line.slice(0, idx).trim().toLowerCase();
|
|
173
218
|
const value = line.slice(idx + 1).trim();
|
|
174
|
-
if (!value)
|
|
219
|
+
if (!value) {
|
|
175
220
|
continue;
|
|
221
|
+
}
|
|
176
222
|
if (key === "taskname") {
|
|
177
|
-
if (current)
|
|
223
|
+
if (current) {
|
|
178
224
|
tasks.push(current);
|
|
225
|
+
}
|
|
179
226
|
current = { name: value };
|
|
180
227
|
continue;
|
|
181
228
|
}
|
|
182
|
-
if (!current)
|
|
229
|
+
if (!current) {
|
|
183
230
|
continue;
|
|
231
|
+
}
|
|
184
232
|
if (key === "task to run") {
|
|
185
233
|
current.taskToRun = value;
|
|
186
234
|
}
|
|
187
235
|
}
|
|
188
|
-
if (current)
|
|
236
|
+
if (current) {
|
|
189
237
|
tasks.push(current);
|
|
190
|
-
return tasks;
|
|
191
|
-
}
|
|
192
|
-
async function execSchtasks(args) {
|
|
193
|
-
try {
|
|
194
|
-
const { stdout, stderr } = await execFileAsync("schtasks", args, {
|
|
195
|
-
encoding: "utf8",
|
|
196
|
-
windowsHide: true,
|
|
197
|
-
});
|
|
198
|
-
return {
|
|
199
|
-
stdout: String(stdout ?? ""),
|
|
200
|
-
stderr: String(stderr ?? ""),
|
|
201
|
-
code: 0,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
catch (error) {
|
|
205
|
-
const e = error;
|
|
206
|
-
return {
|
|
207
|
-
stdout: typeof e.stdout === "string" ? e.stdout : "",
|
|
208
|
-
stderr: typeof e.stderr === "string" ? e.stderr : typeof e.message === "string" ? e.message : "",
|
|
209
|
-
code: typeof e.code === "number" ? e.code : 1,
|
|
210
|
-
};
|
|
211
238
|
}
|
|
239
|
+
return tasks;
|
|
212
240
|
}
|
|
213
241
|
export async function findExtraGatewayServices(env, opts = {}) {
|
|
214
242
|
const results = [];
|
|
215
243
|
const seen = new Set();
|
|
216
244
|
const push = (svc) => {
|
|
217
245
|
const key = `${svc.platform}:${svc.label}:${svc.detail}:${svc.scope}`;
|
|
218
|
-
if (seen.has(key))
|
|
246
|
+
if (seen.has(key)) {
|
|
219
247
|
return;
|
|
248
|
+
}
|
|
220
249
|
seen.add(key);
|
|
221
250
|
results.push(svc);
|
|
222
251
|
};
|
|
@@ -281,30 +310,41 @@ export async function findExtraGatewayServices(env, opts = {}) {
|
|
|
281
310
|
return results;
|
|
282
311
|
}
|
|
283
312
|
if (process.platform === "win32") {
|
|
284
|
-
if (!opts.deep)
|
|
313
|
+
if (!opts.deep) {
|
|
285
314
|
return results;
|
|
315
|
+
}
|
|
286
316
|
const res = await execSchtasks(["/Query", "/FO", "LIST", "/V"]);
|
|
287
|
-
if (res.code !== 0)
|
|
317
|
+
if (res.code !== 0) {
|
|
288
318
|
return results;
|
|
319
|
+
}
|
|
289
320
|
const tasks = parseSchtasksList(res.stdout);
|
|
290
321
|
for (const task of tasks) {
|
|
291
322
|
const name = task.name.trim();
|
|
292
|
-
if (!name)
|
|
323
|
+
if (!name) {
|
|
293
324
|
continue;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (LEGACY_GATEWAY_WINDOWS_TASK_NAMES.includes(name))
|
|
325
|
+
}
|
|
326
|
+
if (isPoolBotGatewayTaskName(name)) {
|
|
297
327
|
continue;
|
|
328
|
+
}
|
|
298
329
|
const lowerName = name.toLowerCase();
|
|
299
330
|
const lowerCommand = task.taskToRun?.toLowerCase() ?? "";
|
|
300
|
-
|
|
301
|
-
|
|
331
|
+
let marker = null;
|
|
332
|
+
for (const candidate of EXTRA_MARKERS) {
|
|
333
|
+
if (lowerName.includes(candidate) || lowerCommand.includes(candidate)) {
|
|
334
|
+
marker = candidate;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (!marker) {
|
|
302
339
|
continue;
|
|
340
|
+
}
|
|
303
341
|
push({
|
|
304
342
|
platform: "win32",
|
|
305
343
|
label: name,
|
|
306
344
|
detail: task.taskToRun ? `task: ${name}, run: ${task.taskToRun}` : name,
|
|
307
345
|
scope: "system",
|
|
346
|
+
marker,
|
|
347
|
+
legacy: marker !== "poolbot",
|
|
308
348
|
});
|
|
309
349
|
}
|
|
310
350
|
return results;
|
|
@@ -16,6 +16,11 @@ const VERSION_MANAGER_MARKERS = [
|
|
|
16
16
|
function getPathModule(platform) {
|
|
17
17
|
return platform === "win32" ? path.win32 : path.posix;
|
|
18
18
|
}
|
|
19
|
+
function isNodeExecPath(execPath, platform) {
|
|
20
|
+
const pathModule = getPathModule(platform);
|
|
21
|
+
const base = pathModule.basename(execPath).toLowerCase();
|
|
22
|
+
return base === "node" || base === "node.exe";
|
|
23
|
+
}
|
|
19
24
|
function normalizeForCompare(input, platform) {
|
|
20
25
|
const pathModule = getPathModule(platform);
|
|
21
26
|
const normalized = pathModule.normalize(input).replaceAll("\\", "/");
|
|
@@ -83,8 +88,9 @@ export async function resolveSystemNodeInfo(params) {
|
|
|
83
88
|
const env = params.env ?? process.env;
|
|
84
89
|
const platform = params.platform ?? process.platform;
|
|
85
90
|
const systemNode = await resolveSystemNodePath(env, platform);
|
|
86
|
-
if (!systemNode)
|
|
91
|
+
if (!systemNode) {
|
|
87
92
|
return null;
|
|
93
|
+
}
|
|
88
94
|
const version = await resolveNodeVersion(systemNode, params.execFile ?? execFileAsync);
|
|
89
95
|
return {
|
|
90
96
|
path: systemNode,
|
|
@@ -93,17 +99,32 @@ export async function resolveSystemNodeInfo(params) {
|
|
|
93
99
|
};
|
|
94
100
|
}
|
|
95
101
|
export function renderSystemNodeWarning(systemNode, selectedNodePath) {
|
|
96
|
-
if (!systemNode || systemNode.supported)
|
|
102
|
+
if (!systemNode || systemNode.supported) {
|
|
97
103
|
return null;
|
|
104
|
+
}
|
|
98
105
|
const versionLabel = systemNode.version ?? "unknown";
|
|
99
106
|
const selectedLabel = selectedNodePath ? ` Using ${selectedNodePath} for the daemon.` : "";
|
|
100
107
|
return `System Node ${versionLabel} at ${systemNode.path} is below the required Node 22+.${selectedLabel} Install Node 22+ from nodejs.org or Homebrew.`;
|
|
101
108
|
}
|
|
102
109
|
export async function resolvePreferredNodePath(params) {
|
|
103
|
-
if (params.runtime !== "node")
|
|
110
|
+
if (params.runtime !== "node") {
|
|
104
111
|
return undefined;
|
|
112
|
+
}
|
|
113
|
+
// Prefer the node that is currently running `poolbot gateway install`.
|
|
114
|
+
// This respects the user's active version manager (fnm/nvm/volta/etc.).
|
|
115
|
+
const platform = params.platform ?? process.platform;
|
|
116
|
+
const currentExecPath = params.execPath ?? process.execPath;
|
|
117
|
+
if (currentExecPath && isNodeExecPath(currentExecPath, platform)) {
|
|
118
|
+
const execFileImpl = params.execFile ?? execFileAsync;
|
|
119
|
+
const version = await resolveNodeVersion(currentExecPath, execFileImpl);
|
|
120
|
+
if (isSupportedNodeVersion(version)) {
|
|
121
|
+
return currentExecPath;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Fall back to system node.
|
|
105
125
|
const systemNode = await resolveSystemNodeInfo(params);
|
|
106
|
-
if (!systemNode?.supported)
|
|
126
|
+
if (!systemNode?.supported) {
|
|
107
127
|
return undefined;
|
|
128
|
+
}
|
|
108
129
|
return systemNode.path;
|
|
109
130
|
}
|
|
@@ -10,15 +10,16 @@ export const SERVICE_AUDIT_CODES = {
|
|
|
10
10
|
gatewayPathMissing: "gateway-path-missing",
|
|
11
11
|
gatewayPathMissingDirs: "gateway-path-missing-dirs",
|
|
12
12
|
gatewayPathNonMinimal: "gateway-path-nonminimal",
|
|
13
|
+
gatewayTokenMismatch: "gateway-token-mismatch",
|
|
13
14
|
gatewayRuntimeBun: "gateway-runtime-bun",
|
|
14
15
|
gatewayRuntimeNodeVersionManager: "gateway-runtime-node-version-manager",
|
|
15
16
|
gatewayRuntimeNodeSystemMissing: "gateway-runtime-node-system-missing",
|
|
17
|
+
gatewayTokenDrift: "gateway-token-drift",
|
|
16
18
|
launchdKeepAlive: "launchd-keep-alive",
|
|
17
19
|
launchdRunAtLoad: "launchd-run-at-load",
|
|
18
20
|
systemdAfterNetworkOnline: "systemd-after-network-online",
|
|
19
21
|
systemdRestartSec: "systemd-restart-sec",
|
|
20
22
|
systemdWantsNetworkOnline: "systemd-wants-network-online",
|
|
21
|
-
gatewayTokenDrift: "gateway-token-drift",
|
|
22
23
|
};
|
|
23
24
|
export function needsNodeRuntimeMigration(issues) {
|
|
24
25
|
return issues.some((issue) => issue.code === SERVICE_AUDIT_CODES.gatewayRuntimeBun ||
|
|
@@ -33,29 +34,36 @@ function parseSystemdUnit(content) {
|
|
|
33
34
|
let restartSec;
|
|
34
35
|
for (const rawLine of content.split(/\r?\n/)) {
|
|
35
36
|
const line = rawLine.trim();
|
|
36
|
-
if (!line)
|
|
37
|
+
if (!line) {
|
|
37
38
|
continue;
|
|
38
|
-
|
|
39
|
+
}
|
|
40
|
+
if (line.startsWith("#") || line.startsWith(";")) {
|
|
39
41
|
continue;
|
|
40
|
-
|
|
42
|
+
}
|
|
43
|
+
if (line.startsWith("[")) {
|
|
41
44
|
continue;
|
|
45
|
+
}
|
|
42
46
|
const idx = line.indexOf("=");
|
|
43
|
-
if (idx <= 0)
|
|
47
|
+
if (idx <= 0) {
|
|
44
48
|
continue;
|
|
49
|
+
}
|
|
45
50
|
const key = line.slice(0, idx).trim();
|
|
46
51
|
const value = line.slice(idx + 1).trim();
|
|
47
|
-
if (!value)
|
|
52
|
+
if (!value) {
|
|
48
53
|
continue;
|
|
54
|
+
}
|
|
49
55
|
if (key === "After") {
|
|
50
56
|
for (const entry of value.split(/\s+/)) {
|
|
51
|
-
if (entry)
|
|
57
|
+
if (entry) {
|
|
52
58
|
after.add(entry);
|
|
59
|
+
}
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
else if (key === "Wants") {
|
|
56
63
|
for (const entry of value.split(/\s+/)) {
|
|
57
|
-
if (entry)
|
|
64
|
+
if (entry) {
|
|
58
65
|
wants.add(entry);
|
|
66
|
+
}
|
|
59
67
|
}
|
|
60
68
|
}
|
|
61
69
|
else if (key === "RestartSec") {
|
|
@@ -65,11 +73,13 @@ function parseSystemdUnit(content) {
|
|
|
65
73
|
return { after, wants, restartSec };
|
|
66
74
|
}
|
|
67
75
|
function isRestartSecPreferred(value) {
|
|
68
|
-
if (!value)
|
|
76
|
+
if (!value) {
|
|
69
77
|
return false;
|
|
78
|
+
}
|
|
70
79
|
const parsed = Number.parseFloat(value);
|
|
71
|
-
if (!Number.isFinite(parsed))
|
|
80
|
+
if (!Number.isFinite(parsed)) {
|
|
72
81
|
return false;
|
|
82
|
+
}
|
|
73
83
|
return Math.abs(parsed - 5) < 0.01;
|
|
74
84
|
}
|
|
75
85
|
async function auditSystemdUnit(env, issues) {
|
|
@@ -136,8 +146,9 @@ async function auditLaunchdPlist(env, issues) {
|
|
|
136
146
|
}
|
|
137
147
|
}
|
|
138
148
|
function auditGatewayCommand(programArguments, issues) {
|
|
139
|
-
if (!programArguments || programArguments.length === 0)
|
|
149
|
+
if (!programArguments || programArguments.length === 0) {
|
|
140
150
|
return;
|
|
151
|
+
}
|
|
141
152
|
if (!hasGatewaySubcommand(programArguments)) {
|
|
142
153
|
issues.push({
|
|
143
154
|
code: SERVICE_AUDIT_CODES.gatewayCommandMissing,
|
|
@@ -146,6 +157,22 @@ function auditGatewayCommand(programArguments, issues) {
|
|
|
146
157
|
});
|
|
147
158
|
}
|
|
148
159
|
}
|
|
160
|
+
function auditGatewayToken(command, issues, expectedGatewayToken) {
|
|
161
|
+
const expectedToken = expectedGatewayToken?.trim();
|
|
162
|
+
if (!expectedToken) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const serviceToken = command?.environment?.POOLBOT_GATEWAY_TOKEN?.trim();
|
|
166
|
+
if (serviceToken === expectedToken) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
issues.push({
|
|
170
|
+
code: SERVICE_AUDIT_CODES.gatewayTokenMismatch,
|
|
171
|
+
message: "Gateway service POOLBOT_GATEWAY_TOKEN does not match gateway.auth.token in poolbot.json",
|
|
172
|
+
detail: serviceToken ? "service token is stale" : "service token is missing",
|
|
173
|
+
level: "recommended",
|
|
174
|
+
});
|
|
175
|
+
}
|
|
149
176
|
function isNodeRuntime(execPath) {
|
|
150
177
|
const base = path.basename(execPath).toLowerCase();
|
|
151
178
|
return base === "node" || base === "node.exe";
|
|
@@ -166,8 +193,9 @@ function normalizePathEntry(entry, platform) {
|
|
|
166
193
|
return normalized;
|
|
167
194
|
}
|
|
168
195
|
function auditGatewayServicePath(command, issues, env, platform) {
|
|
169
|
-
if (platform === "win32")
|
|
196
|
+
if (platform === "win32") {
|
|
170
197
|
return;
|
|
198
|
+
}
|
|
171
199
|
const servicePath = command?.environment?.PATH;
|
|
172
200
|
if (!servicePath) {
|
|
173
201
|
issues.push({
|
|
@@ -182,11 +210,11 @@ function auditGatewayServicePath(command, issues, env, platform) {
|
|
|
182
210
|
.split(getPathModule(platform).delimiter)
|
|
183
211
|
.map((entry) => entry.trim())
|
|
184
212
|
.filter(Boolean);
|
|
185
|
-
const normalizedParts = parts.map((entry) => normalizePathEntry(entry, platform));
|
|
213
|
+
const normalizedParts = new Set(parts.map((entry) => normalizePathEntry(entry, platform)));
|
|
186
214
|
const normalizedExpected = new Set(expected.map((entry) => normalizePathEntry(entry, platform)));
|
|
187
215
|
const missing = expected.filter((entry) => {
|
|
188
216
|
const normalized = normalizePathEntry(entry, platform);
|
|
189
|
-
return !normalizedParts.
|
|
217
|
+
return !normalizedParts.has(normalized);
|
|
190
218
|
});
|
|
191
219
|
if (missing.length > 0) {
|
|
192
220
|
issues.push({
|
|
@@ -223,8 +251,9 @@ function auditGatewayServicePath(command, issues, env, platform) {
|
|
|
223
251
|
}
|
|
224
252
|
async function auditGatewayRuntime(env, command, issues, platform) {
|
|
225
253
|
const execPath = command?.programArguments?.[0];
|
|
226
|
-
if (!execPath)
|
|
254
|
+
if (!execPath) {
|
|
227
255
|
return;
|
|
256
|
+
}
|
|
228
257
|
if (isBunRuntime(execPath)) {
|
|
229
258
|
issues.push({
|
|
230
259
|
code: SERVICE_AUDIT_CODES.gatewayRuntimeBun,
|
|
@@ -234,8 +263,9 @@ async function auditGatewayRuntime(env, command, issues, platform) {
|
|
|
234
263
|
});
|
|
235
264
|
return;
|
|
236
265
|
}
|
|
237
|
-
if (!isNodeRuntime(execPath))
|
|
266
|
+
if (!isNodeRuntime(execPath)) {
|
|
238
267
|
return;
|
|
268
|
+
}
|
|
239
269
|
if (isVersionManagedNodePath(execPath, platform)) {
|
|
240
270
|
issues.push({
|
|
241
271
|
code: SERVICE_AUDIT_CODES.gatewayRuntimeNodeVersionManager,
|
|
@@ -280,6 +310,7 @@ export async function auditGatewayServiceConfig(params) {
|
|
|
280
310
|
const issues = [];
|
|
281
311
|
const platform = params.platform ?? process.platform;
|
|
282
312
|
auditGatewayCommand(params.command?.programArguments, issues);
|
|
313
|
+
auditGatewayToken(params.command, issues, params.expectedGatewayToken);
|
|
283
314
|
auditGatewayServicePath(params.command, issues, params.env, platform);
|
|
284
315
|
await auditGatewayRuntime(params.env, params.command, issues, platform);
|
|
285
316
|
if (platform === "linux") {
|
package/dist/discord/accounts.js
CHANGED
|
@@ -1,27 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createAccountListHelpers } from "../channels/plugins/account-helpers.js";
|
|
2
|
+
import { normalizeAccountId } from "../routing/session-key.js";
|
|
2
3
|
import { resolveDiscordToken } from "./token.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return [];
|
|
7
|
-
return Object.keys(accounts).filter(Boolean);
|
|
8
|
-
}
|
|
9
|
-
export function listDiscordAccountIds(cfg) {
|
|
10
|
-
const ids = listConfiguredAccountIds(cfg);
|
|
11
|
-
if (ids.length === 0)
|
|
12
|
-
return [DEFAULT_ACCOUNT_ID];
|
|
13
|
-
return ids.sort((a, b) => a.localeCompare(b));
|
|
14
|
-
}
|
|
15
|
-
export function resolveDefaultDiscordAccountId(cfg) {
|
|
16
|
-
const ids = listDiscordAccountIds(cfg);
|
|
17
|
-
if (ids.includes(DEFAULT_ACCOUNT_ID))
|
|
18
|
-
return DEFAULT_ACCOUNT_ID;
|
|
19
|
-
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
|
20
|
-
}
|
|
4
|
+
const { listAccountIds, resolveDefaultAccountId } = createAccountListHelpers("discord");
|
|
5
|
+
export const listDiscordAccountIds = listAccountIds;
|
|
6
|
+
export const resolveDefaultDiscordAccountId = resolveDefaultAccountId;
|
|
21
7
|
function resolveAccountConfig(cfg, accountId) {
|
|
22
8
|
const accounts = cfg.channels?.discord?.accounts;
|
|
23
|
-
if (!accounts || typeof accounts !== "object")
|
|
9
|
+
if (!accounts || typeof accounts !== "object") {
|
|
24
10
|
return undefined;
|
|
11
|
+
}
|
|
25
12
|
return accounts[accountId];
|
|
26
13
|
}
|
|
27
14
|
function mergeDiscordAccountConfig(cfg, accountId) {
|
|
@@ -29,6 +16,22 @@ function mergeDiscordAccountConfig(cfg, accountId) {
|
|
|
29
16
|
const account = resolveAccountConfig(cfg, accountId) ?? {};
|
|
30
17
|
return { ...base, ...account };
|
|
31
18
|
}
|
|
19
|
+
export function createDiscordActionGate(params) {
|
|
20
|
+
const accountId = normalizeAccountId(params.accountId);
|
|
21
|
+
const baseActions = params.cfg.channels?.discord?.actions;
|
|
22
|
+
const accountActions = resolveAccountConfig(params.cfg, accountId)?.actions;
|
|
23
|
+
return (key, defaultValue = true) => {
|
|
24
|
+
const accountValue = accountActions?.[key];
|
|
25
|
+
if (accountValue !== undefined) {
|
|
26
|
+
return accountValue;
|
|
27
|
+
}
|
|
28
|
+
const baseValue = baseActions?.[key];
|
|
29
|
+
if (baseValue !== undefined) {
|
|
30
|
+
return baseValue;
|
|
31
|
+
}
|
|
32
|
+
return defaultValue;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
32
35
|
export function resolveDiscordAccount(params) {
|
|
33
36
|
const accountId = normalizeAccountId(params.accountId);
|
|
34
37
|
const baseEnabled = params.cfg.channels?.discord?.enabled !== false;
|