@poolzin/pool-bot 2026.2.0 → 2026.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +118 -0
- package/README-header.png +0 -0
- package/dist/agents/bash-tools.exec.js +76 -25
- package/dist/agents/cli-runner/helpers.js +9 -11
- package/dist/agents/context.js +1 -1
- package/dist/agents/identity.js +47 -7
- package/dist/agents/memory-search.js +25 -8
- package/dist/agents/model-catalog.js +1 -1
- package/dist/agents/model-selection.js +21 -0
- package/dist/agents/pi-embedded-block-chunker.js +117 -42
- package/dist/agents/pi-embedded-helpers/errors.js +183 -78
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +8 -10
- package/dist/agents/pi-embedded-runner/model.js +62 -3
- package/dist/agents/pi-embedded-runner/run/attempt.js +21 -11
- package/dist/agents/pi-embedded-runner/run.js +199 -46
- package/dist/agents/pi-embedded-runner/system-prompt.js +10 -2
- package/dist/agents/pi-embedded-subscribe.js +118 -29
- package/dist/agents/pi-tools.js +10 -5
- package/dist/agents/poolbot-tools.js +15 -10
- package/dist/agents/sandbox-paths.js +31 -0
- package/dist/agents/session-tool-result-guard.js +94 -15
- package/dist/agents/shell-utils.js +51 -0
- package/dist/agents/skills/bundled-context.js +23 -0
- package/dist/agents/skills/bundled-dir.js +41 -7
- package/dist/agents/skills-install.js +60 -23
- package/dist/agents/subagent-announce.js +79 -34
- package/dist/agents/tool-policy.conformance.js +14 -0
- package/dist/agents/tool-policy.js +24 -0
- package/dist/agents/tools/cron-tool.js +166 -19
- package/dist/agents/tools/discord-actions-presence.js +78 -0
- package/dist/agents/tools/image-tool.js +1 -1
- package/dist/agents/tools/message-tool.js +56 -2
- package/dist/agents/tools/sessions-history-tool.js +69 -1
- package/dist/agents/tools/web-search.js +211 -42
- package/dist/agents/usage.js +23 -1
- package/dist/agents/workspace-run.js +67 -0
- package/dist/agents/workspace-templates.js +44 -0
- package/dist/auto-reply/command-auth.js +121 -6
- package/dist/auto-reply/envelope.js +74 -82
- package/dist/auto-reply/reply/commands-compact.js +1 -0
- package/dist/auto-reply/reply/commands-context-report.js +1 -0
- package/dist/auto-reply/reply/commands-context.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +107 -60
- package/dist/auto-reply/reply/commands-ptt.js +171 -0
- package/dist/auto-reply/reply/get-reply-run.js +2 -1
- package/dist/auto-reply/reply/inbound-context.js +5 -1
- package/dist/auto-reply/reply/mentions.js +1 -1
- package/dist/auto-reply/reply/model-selection.js +3 -3
- package/dist/auto-reply/thinking.js +88 -43
- package/dist/browser/bridge-server.js +13 -0
- package/dist/browser/cdp.helpers.js +38 -24
- package/dist/browser/client-fetch.js +50 -7
- package/dist/browser/config.js +1 -10
- package/dist/browser/extension-relay.js +101 -40
- package/dist/browser/pw-ai.js +1 -1
- package/dist/browser/pw-session.js +143 -8
- package/dist/browser/pw-tools-core.interactions.js +125 -27
- package/dist/browser/pw-tools-core.responses.js +1 -1
- package/dist/browser/pw-tools-core.state.js +1 -1
- package/dist/browser/routes/agent.act.js +86 -41
- package/dist/browser/routes/dispatcher.js +4 -4
- package/dist/browser/screenshot.js +1 -1
- package/dist/browser/server.js +13 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui/index.html +28 -28
- package/dist/channels/reply-prefix.js +8 -1
- package/dist/cli/cron-cli/register.cron-add.js +61 -40
- package/dist/cli/cron-cli/register.cron-edit.js +60 -34
- package/dist/cli/cron-cli/shared.js +56 -41
- package/dist/cli/dns-cli.js +26 -14
- package/dist/cli/gateway-cli/register.js +37 -19
- package/dist/cli/memory-cli.js +5 -5
- package/dist/cli/parse-bytes.js +37 -0
- package/dist/cli/update-cli.js +173 -52
- package/dist/commands/agent.js +1 -0
- package/dist/commands/auth-choice.apply.oauth.js +1 -1
- package/dist/commands/doctor-config-flow.js +61 -5
- package/dist/commands/doctor-state-migrations.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/model-allowlist.js +29 -0
- package/dist/commands/model-picker.js +2 -1
- package/dist/commands/models/list.registry.js +1 -1
- package/dist/commands/models/list.status-command.js +43 -23
- package/dist/commands/models/shared.js +15 -0
- package/dist/commands/onboard-custom.js +384 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +35 -0
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +6 -3
- package/dist/commands/onboard-skills.js +63 -38
- package/dist/commands/openai-model-default.js +41 -0
- package/dist/compat/legacy-names.js +2 -0
- package/dist/config/defaults.js +3 -2
- package/dist/config/paths.js +136 -35
- package/dist/config/plugin-auto-enable.js +21 -5
- package/dist/config/redact-snapshot.js +153 -0
- package/dist/config/schema.field-metadata.js +590 -0
- package/dist/config/schema.js +2 -2
- package/dist/config/sessions/store.js +291 -23
- package/dist/config/zod-schema.agent-defaults.js +3 -0
- package/dist/config/zod-schema.agent-runtime.js +13 -2
- package/dist/config/zod-schema.providers-core.js +142 -0
- package/dist/config/zod-schema.session.js +3 -0
- package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
- package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
- package/dist/control-ui/index.html +4 -4
- package/dist/cron/delivery.js +57 -0
- package/dist/cron/isolated-agent/delivery-target.js +18 -3
- package/dist/cron/isolated-agent/helpers.js +22 -5
- package/dist/cron/isolated-agent/run.js +172 -63
- package/dist/cron/isolated-agent/session.js +2 -0
- package/dist/cron/normalize.js +356 -28
- package/dist/cron/parse.js +10 -5
- package/dist/cron/run-log.js +35 -10
- package/dist/cron/schedule.js +41 -6
- package/dist/cron/service/jobs.js +208 -35
- package/dist/cron/service/ops.js +72 -16
- package/dist/cron/service/state.js +2 -0
- package/dist/cron/service/store.js +386 -14
- package/dist/cron/service/timer.js +390 -147
- package/dist/cron/session-reaper.js +86 -0
- package/dist/cron/store.js +23 -8
- package/dist/cron/validate-timestamp.js +43 -0
- package/dist/discord/monitor/agent-components.js +438 -0
- package/dist/discord/monitor/allow-list.js +28 -5
- package/dist/discord/monitor/gateway-registry.js +29 -0
- package/dist/discord/monitor/native-command.js +44 -23
- package/dist/discord/monitor/sender-identity.js +45 -0
- package/dist/discord/pluralkit.js +27 -0
- package/dist/discord/send.outbound.js +92 -5
- package/dist/discord/send.shared.js +60 -23
- package/dist/discord/targets.js +84 -1
- package/dist/entry.js +15 -9
- package/dist/extensionAPI.js +8 -0
- package/dist/gateway/control-ui.js +8 -1
- package/dist/gateway/hooks-mapping.js +3 -0
- package/dist/gateway/hooks.js +65 -0
- package/dist/gateway/net.js +96 -31
- package/dist/gateway/node-command-policy.js +50 -15
- package/dist/gateway/origin-check.js +56 -0
- package/dist/gateway/protocol/client-info.js +9 -0
- package/dist/gateway/protocol/index.js +9 -2
- package/dist/gateway/protocol/schema/agents-models-skills.js +71 -1
- package/dist/gateway/protocol/schema/cron.js +22 -10
- package/dist/gateway/protocol/schema/protocol-schemas.js +16 -2
- package/dist/gateway/protocol/schema/sessions.js +12 -0
- package/dist/gateway/server/hooks.js +1 -1
- package/dist/gateway/server-broadcast.js +26 -9
- package/dist/gateway/server-chat.js +112 -23
- package/dist/gateway/server-discovery-runtime.js +10 -2
- package/dist/gateway/server-http.js +109 -11
- package/dist/gateway/server-methods/agent-timestamp.js +60 -0
- package/dist/gateway/server-methods/agents.js +321 -2
- package/dist/gateway/server-methods/usage.js +559 -16
- package/dist/gateway/server-runtime-state.js +22 -8
- package/dist/gateway/server-startup-memory.js +16 -0
- package/dist/gateway/server.impl.js +5 -1
- package/dist/gateway/session-utils.fs.js +23 -25
- package/dist/gateway/session-utils.js +20 -10
- package/dist/gateway/sessions-patch.js +7 -22
- package/dist/gateway/test-helpers.mocks.js +11 -7
- package/dist/gateway/test-helpers.server.js +35 -2
- package/dist/imessage/constants.js +2 -0
- package/dist/imessage/monitor/deliver.js +4 -1
- package/dist/imessage/monitor/monitor-provider.js +51 -1
- package/dist/infra/bonjour-discovery.js +131 -70
- package/dist/infra/control-ui-assets.js +134 -12
- package/dist/infra/errors.js +12 -0
- package/dist/infra/exec-approvals.js +266 -57
- package/dist/infra/format-time/format-datetime.js +79 -0
- package/dist/infra/format-time/format-duration.js +81 -0
- package/dist/infra/format-time/format-relative.js +80 -0
- package/dist/infra/heartbeat-runner.js +140 -49
- package/dist/infra/home-dir.js +54 -0
- package/dist/infra/net/fetch-guard.js +122 -0
- package/dist/infra/net/ssrf.js +65 -29
- package/dist/infra/outbound/abort.js +14 -0
- package/dist/infra/outbound/message-action-runner.js +77 -13
- package/dist/infra/outbound/outbound-session.js +143 -37
- package/dist/infra/poolbot-root.js +43 -1
- package/dist/infra/session-cost-usage.js +631 -41
- package/dist/infra/state-migrations.js +317 -47
- package/dist/infra/update-global.js +35 -0
- package/dist/infra/update-runner.js +149 -43
- package/dist/infra/warning-filter.js +65 -0
- package/dist/infra/widearea-dns.js +30 -9
- package/dist/logging/redact-identifier.js +12 -0
- package/dist/media/fetch.js +81 -58
- package/dist/media/store.js +2 -0
- package/dist/media-understanding/apply.js +403 -3
- package/dist/media-understanding/attachments.js +38 -27
- package/dist/media-understanding/defaults.js +16 -0
- package/dist/media-understanding/providers/deepgram/audio.js +22 -14
- package/dist/media-understanding/providers/google/audio.js +24 -17
- package/dist/media-understanding/providers/google/video.js +24 -17
- package/dist/media-understanding/providers/image.js +3 -3
- package/dist/media-understanding/providers/index.js +4 -1
- package/dist/media-understanding/providers/openai/audio.js +22 -14
- package/dist/media-understanding/providers/shared.js +16 -11
- package/dist/media-understanding/providers/zai/index.js +6 -0
- package/dist/media-understanding/runner.js +158 -90
- package/dist/memory/batch-voyage.js +277 -0
- package/dist/memory/embeddings-voyage.js +75 -0
- package/dist/memory/embeddings.js +28 -16
- package/dist/memory/internal.js +101 -18
- package/dist/memory/manager.js +154 -48
- package/dist/memory/search-manager.js +173 -0
- package/dist/memory/session-files.js +9 -3
- package/dist/node-host/runner.js +34 -24
- package/dist/node-host/with-timeout.js +27 -0
- package/dist/plugins/commands.js +5 -1
- package/dist/plugins/config-state.js +86 -7
- package/dist/plugins/source-display.js +51 -0
- package/dist/process/exec.js +20 -2
- package/dist/routing/resolve-route.js +12 -0
- package/dist/routing/session-key.js +15 -0
- package/dist/runtime.js +2 -0
- package/dist/security/audit-extra.async.js +601 -0
- package/dist/security/audit-extra.js +2 -830
- package/dist/security/audit-extra.sync.js +505 -0
- package/dist/security/channel-metadata.js +34 -0
- package/dist/security/external-content.js +88 -6
- package/dist/security/skill-scanner.js +330 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/signal/monitor/event-handler.js +80 -1
- package/dist/slack/monitor/media.js +85 -15
- package/dist/tailscale/detect.js +1 -2
- package/dist/telegram/bot/helpers.js +109 -28
- package/dist/telegram/bot-handlers.js +144 -3
- package/dist/telegram/bot-message-context.js +37 -10
- package/dist/telegram/bot-message-dispatch.js +54 -17
- package/dist/telegram/bot-native-commands.js +86 -29
- package/dist/telegram/bot.js +30 -29
- package/dist/telegram/model-buttons.js +163 -0
- package/dist/telegram/monitor.js +110 -85
- package/dist/telegram/send.js +129 -47
- package/dist/terminal/restore.js +45 -0
- package/dist/test-helpers/state-dir-env.js +16 -0
- package/dist/tts/tts.js +12 -6
- package/dist/tui/tui-session-actions.js +166 -54
- package/dist/utils/fetch-timeout.js +20 -0
- package/dist/utils/normalize-secret-input.js +19 -0
- package/dist/utils/transcript-tools.js +58 -0
- package/dist/utils.js +45 -14
- package/dist/version.js +42 -5
- package/dist/wizard/clack-prompter.js +9 -6
- package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
- package/extensions/googlechat/package.json +2 -2
- package/extensions/line/node_modules/.bin/poolbot +21 -0
- package/extensions/line/package.json +1 -1
- package/extensions/matrix/node_modules/.bin/poolbot +21 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
- package/extensions/memory-core/package.json +4 -1
- package/extensions/twitch/node_modules/.bin/poolbot +21 -0
- package/extensions/twitch/package.json +1 -1
- package/package.json +183 -24
- package/dist/control-ui/assets/index-CmNMuoem.js.map +0 -1
|
@@ -2,32 +2,37 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { runCommandWithTimeout } from "../process/exec.js";
|
|
5
|
-
import {
|
|
6
|
-
import { DEV_BRANCH, isBetaTag, isStableTag } from "./update-channels.js";
|
|
7
|
-
import { detectGlobalInstallManagerForRoot, globalInstallArgs } from "./update-global.js";
|
|
5
|
+
import { resolveControlUiDistIndexHealth, resolveControlUiDistIndexPathForRoot, } from "./control-ui-assets.js";
|
|
8
6
|
import { trimLogTail } from "./restart-sentinel.js";
|
|
7
|
+
import { channelToNpmTag, DEFAULT_PACKAGE_CHANNEL, DEV_BRANCH, isBetaTag, isStableTag, } from "./update-channels.js";
|
|
8
|
+
import { compareSemverStrings } from "./update-check.js";
|
|
9
|
+
import { cleanupGlobalRenameDirs, detectGlobalInstallManagerForRoot, globalInstallArgs, } from "./update-global.js";
|
|
9
10
|
const DEFAULT_TIMEOUT_MS = 20 * 60_000;
|
|
10
11
|
const MAX_LOG_CHARS = 8000;
|
|
11
12
|
const PREFLIGHT_MAX_COMMITS = 10;
|
|
12
13
|
const START_DIRS = ["cwd", "argv1", "process"];
|
|
13
14
|
const DEFAULT_PACKAGE_NAME = "poolbot";
|
|
14
|
-
const CORE_PACKAGE_NAMES = new Set([DEFAULT_PACKAGE_NAME
|
|
15
|
+
const CORE_PACKAGE_NAMES = new Set([DEFAULT_PACKAGE_NAME]);
|
|
15
16
|
function normalizeDir(value) {
|
|
16
|
-
if (!value)
|
|
17
|
+
if (!value) {
|
|
17
18
|
return null;
|
|
19
|
+
}
|
|
18
20
|
const trimmed = value.trim();
|
|
19
|
-
if (!trimmed)
|
|
21
|
+
if (!trimmed) {
|
|
20
22
|
return null;
|
|
23
|
+
}
|
|
21
24
|
return path.resolve(trimmed);
|
|
22
25
|
}
|
|
23
26
|
function resolveNodeModulesBinPackageRoot(argv1) {
|
|
24
27
|
const normalized = path.resolve(argv1);
|
|
25
28
|
const parts = normalized.split(path.sep);
|
|
26
29
|
const binIndex = parts.lastIndexOf(".bin");
|
|
27
|
-
if (binIndex <= 0)
|
|
30
|
+
if (binIndex <= 0) {
|
|
28
31
|
return null;
|
|
29
|
-
|
|
32
|
+
}
|
|
33
|
+
if (parts[binIndex - 1] !== "node_modules") {
|
|
30
34
|
return null;
|
|
35
|
+
}
|
|
31
36
|
const binName = path.basename(normalized);
|
|
32
37
|
const nodeModulesDir = parts.slice(0, binIndex).join(path.sep);
|
|
33
38
|
return path.join(nodeModulesDir, binName);
|
|
@@ -35,18 +40,21 @@ function resolveNodeModulesBinPackageRoot(argv1) {
|
|
|
35
40
|
function buildStartDirs(opts) {
|
|
36
41
|
const dirs = [];
|
|
37
42
|
const cwd = normalizeDir(opts.cwd);
|
|
38
|
-
if (cwd)
|
|
43
|
+
if (cwd) {
|
|
39
44
|
dirs.push(cwd);
|
|
45
|
+
}
|
|
40
46
|
const argv1 = normalizeDir(opts.argv1);
|
|
41
47
|
if (argv1) {
|
|
42
48
|
dirs.push(path.dirname(argv1));
|
|
43
49
|
const packageRoot = resolveNodeModulesBinPackageRoot(argv1);
|
|
44
|
-
if (packageRoot)
|
|
50
|
+
if (packageRoot) {
|
|
45
51
|
dirs.push(packageRoot);
|
|
52
|
+
}
|
|
46
53
|
}
|
|
47
54
|
const proc = normalizeDir(process.cwd());
|
|
48
|
-
if (proc)
|
|
55
|
+
if (proc) {
|
|
49
56
|
dirs.push(proc);
|
|
57
|
+
}
|
|
50
58
|
return Array.from(new Set(dirs));
|
|
51
59
|
}
|
|
52
60
|
async function readPackageVersion(root) {
|
|
@@ -74,8 +82,9 @@ async function readBranchName(runCommand, root, timeoutMs) {
|
|
|
74
82
|
const res = await runCommand(["git", "-C", root, "rev-parse", "--abbrev-ref", "HEAD"], {
|
|
75
83
|
timeoutMs,
|
|
76
84
|
}).catch(() => null);
|
|
77
|
-
if (!res || res.code !== 0)
|
|
85
|
+
if (!res || res.code !== 0) {
|
|
78
86
|
return null;
|
|
87
|
+
}
|
|
79
88
|
const branch = res.stdout.trim();
|
|
80
89
|
return branch || null;
|
|
81
90
|
}
|
|
@@ -83,8 +92,9 @@ async function listGitTags(runCommand, root, timeoutMs, pattern = "v*") {
|
|
|
83
92
|
const res = await runCommand(["git", "-C", root, "tag", "--list", pattern, "--sort=-v:refname"], {
|
|
84
93
|
timeoutMs,
|
|
85
94
|
}).catch(() => null);
|
|
86
|
-
if (!res || res.code !== 0)
|
|
95
|
+
if (!res || res.code !== 0) {
|
|
87
96
|
return [];
|
|
97
|
+
}
|
|
88
98
|
return res.stdout
|
|
89
99
|
.split("\n")
|
|
90
100
|
.map((line) => line.trim())
|
|
@@ -95,13 +105,16 @@ async function resolveChannelTag(runCommand, root, timeoutMs, channel) {
|
|
|
95
105
|
if (channel === "beta") {
|
|
96
106
|
const betaTag = tags.find((tag) => isBetaTag(tag)) ?? null;
|
|
97
107
|
const stableTag = tags.find((tag) => isStableTag(tag)) ?? null;
|
|
98
|
-
if (!betaTag)
|
|
108
|
+
if (!betaTag) {
|
|
99
109
|
return stableTag;
|
|
100
|
-
|
|
110
|
+
}
|
|
111
|
+
if (!stableTag) {
|
|
101
112
|
return betaTag;
|
|
113
|
+
}
|
|
102
114
|
const cmp = compareSemverStrings(betaTag, stableTag);
|
|
103
|
-
if (cmp != null && cmp < 0)
|
|
115
|
+
if (cmp != null && cmp < 0) {
|
|
104
116
|
return stableTag;
|
|
117
|
+
}
|
|
105
118
|
return betaTag;
|
|
106
119
|
}
|
|
107
120
|
return tags.find((tag) => isStableTag(tag)) ?? null;
|
|
@@ -113,8 +126,9 @@ async function resolveGitRoot(runCommand, candidates, timeoutMs) {
|
|
|
113
126
|
});
|
|
114
127
|
if (res.code === 0) {
|
|
115
128
|
const root = res.stdout.trim();
|
|
116
|
-
if (root)
|
|
129
|
+
if (root) {
|
|
117
130
|
return root;
|
|
131
|
+
}
|
|
118
132
|
}
|
|
119
133
|
}
|
|
120
134
|
return null;
|
|
@@ -128,15 +142,17 @@ async function findPackageRoot(candidates) {
|
|
|
128
142
|
const raw = await fs.readFile(pkgPath, "utf-8");
|
|
129
143
|
const parsed = JSON.parse(raw);
|
|
130
144
|
const name = parsed?.name?.trim();
|
|
131
|
-
if (name && CORE_PACKAGE_NAMES.has(name))
|
|
145
|
+
if (name && CORE_PACKAGE_NAMES.has(name)) {
|
|
132
146
|
return current;
|
|
147
|
+
}
|
|
133
148
|
}
|
|
134
149
|
catch {
|
|
135
150
|
// ignore
|
|
136
151
|
}
|
|
137
152
|
const parent = path.dirname(current);
|
|
138
|
-
if (parent === current)
|
|
153
|
+
if (parent === current) {
|
|
139
154
|
break;
|
|
155
|
+
}
|
|
140
156
|
current = parent;
|
|
141
157
|
}
|
|
142
158
|
}
|
|
@@ -147,19 +163,23 @@ async function detectPackageManager(root) {
|
|
|
147
163
|
const raw = await fs.readFile(path.join(root, "package.json"), "utf-8");
|
|
148
164
|
const parsed = JSON.parse(raw);
|
|
149
165
|
const pm = parsed?.packageManager?.split("@")[0]?.trim();
|
|
150
|
-
if (pm === "pnpm" || pm === "bun" || pm === "npm")
|
|
166
|
+
if (pm === "pnpm" || pm === "bun" || pm === "npm") {
|
|
151
167
|
return pm;
|
|
168
|
+
}
|
|
152
169
|
}
|
|
153
170
|
catch {
|
|
154
171
|
// ignore
|
|
155
172
|
}
|
|
156
173
|
const files = await fs.readdir(root).catch(() => []);
|
|
157
|
-
if (files.includes("pnpm-lock.yaml"))
|
|
174
|
+
if (files.includes("pnpm-lock.yaml")) {
|
|
158
175
|
return "pnpm";
|
|
159
|
-
|
|
176
|
+
}
|
|
177
|
+
if (files.includes("bun.lockb")) {
|
|
160
178
|
return "bun";
|
|
161
|
-
|
|
179
|
+
}
|
|
180
|
+
if (files.includes("package-lock.json")) {
|
|
162
181
|
return "npm";
|
|
182
|
+
}
|
|
163
183
|
return "npm";
|
|
164
184
|
}
|
|
165
185
|
async function runStep(opts) {
|
|
@@ -193,27 +213,34 @@ async function runStep(opts) {
|
|
|
193
213
|
};
|
|
194
214
|
}
|
|
195
215
|
function managerScriptArgs(manager, script, args = []) {
|
|
196
|
-
if (manager === "pnpm")
|
|
216
|
+
if (manager === "pnpm") {
|
|
197
217
|
return ["pnpm", script, ...args];
|
|
198
|
-
|
|
218
|
+
}
|
|
219
|
+
if (manager === "bun") {
|
|
199
220
|
return ["bun", "run", script, ...args];
|
|
200
|
-
|
|
221
|
+
}
|
|
222
|
+
if (args.length > 0) {
|
|
201
223
|
return ["npm", "run", script, "--", ...args];
|
|
224
|
+
}
|
|
202
225
|
return ["npm", "run", script];
|
|
203
226
|
}
|
|
204
227
|
function managerInstallArgs(manager) {
|
|
205
|
-
if (manager === "pnpm")
|
|
228
|
+
if (manager === "pnpm") {
|
|
206
229
|
return ["pnpm", "install"];
|
|
207
|
-
|
|
230
|
+
}
|
|
231
|
+
if (manager === "bun") {
|
|
208
232
|
return ["bun", "install"];
|
|
233
|
+
}
|
|
209
234
|
return ["npm", "install"];
|
|
210
235
|
}
|
|
211
236
|
function normalizeTag(tag) {
|
|
212
237
|
const trimmed = tag?.trim();
|
|
213
|
-
if (!trimmed)
|
|
238
|
+
if (!trimmed) {
|
|
214
239
|
return "latest";
|
|
215
|
-
|
|
240
|
+
}
|
|
241
|
+
if (trimmed.startsWith("poolbot@")) {
|
|
216
242
|
return trimmed.slice("poolbot@".length);
|
|
243
|
+
}
|
|
217
244
|
if (trimmed.startsWith(`${DEFAULT_PACKAGE_NAME}@`)) {
|
|
218
245
|
return trimmed.slice(`${DEFAULT_PACKAGE_NAME}@`.length);
|
|
219
246
|
}
|
|
@@ -392,20 +419,24 @@ export async function runGatewayUpdate(opts = {}) {
|
|
|
392
419
|
const shortSha = sha.slice(0, 8);
|
|
393
420
|
const checkoutStep = await runStep(step(`preflight checkout (${shortSha})`, ["git", "-C", worktreeDir, "checkout", "--detach", sha], worktreeDir));
|
|
394
421
|
steps.push(checkoutStep);
|
|
395
|
-
if (checkoutStep.exitCode !== 0)
|
|
422
|
+
if (checkoutStep.exitCode !== 0) {
|
|
396
423
|
continue;
|
|
424
|
+
}
|
|
397
425
|
const depsStep = await runStep(step(`preflight deps install (${shortSha})`, managerInstallArgs(manager), worktreeDir));
|
|
398
426
|
steps.push(depsStep);
|
|
399
|
-
if (depsStep.exitCode !== 0)
|
|
400
|
-
continue;
|
|
401
|
-
const lintStep = await runStep(step(`preflight lint (${shortSha})`, managerScriptArgs(manager, "lint"), worktreeDir));
|
|
402
|
-
steps.push(lintStep);
|
|
403
|
-
if (lintStep.exitCode !== 0)
|
|
427
|
+
if (depsStep.exitCode !== 0) {
|
|
404
428
|
continue;
|
|
429
|
+
}
|
|
405
430
|
const buildStep = await runStep(step(`preflight build (${shortSha})`, managerScriptArgs(manager, "build"), worktreeDir));
|
|
406
431
|
steps.push(buildStep);
|
|
407
|
-
if (buildStep.exitCode !== 0)
|
|
432
|
+
if (buildStep.exitCode !== 0) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const lintStep = await runStep(step(`preflight lint (${shortSha})`, managerScriptArgs(manager, "lint"), worktreeDir));
|
|
436
|
+
steps.push(lintStep);
|
|
437
|
+
if (lintStep.exitCode !== 0) {
|
|
408
438
|
continue;
|
|
439
|
+
}
|
|
409
440
|
selectedSha = sha;
|
|
410
441
|
break;
|
|
411
442
|
}
|
|
@@ -504,12 +535,81 @@ export async function runGatewayUpdate(opts = {}) {
|
|
|
504
535
|
steps.push(buildStep);
|
|
505
536
|
const uiBuildStep = await runStep(step("ui:build", managerScriptArgs(manager, "ui:build"), gitRoot));
|
|
506
537
|
steps.push(uiBuildStep);
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
538
|
+
const doctorEntry = path.join(gitRoot, "poolbot.mjs");
|
|
539
|
+
const doctorEntryExists = await fs
|
|
540
|
+
.stat(doctorEntry)
|
|
541
|
+
.then(() => true)
|
|
542
|
+
.catch(() => false);
|
|
543
|
+
if (!doctorEntryExists) {
|
|
544
|
+
steps.push({
|
|
545
|
+
name: "poolbot doctor entry",
|
|
546
|
+
command: `verify ${doctorEntry}`,
|
|
547
|
+
cwd: gitRoot,
|
|
548
|
+
durationMs: 0,
|
|
549
|
+
exitCode: 1,
|
|
550
|
+
stderrTail: `missing ${doctorEntry}`,
|
|
551
|
+
});
|
|
552
|
+
return {
|
|
553
|
+
status: "error",
|
|
554
|
+
mode: "git",
|
|
555
|
+
root: gitRoot,
|
|
556
|
+
reason: "doctor-entry-missing",
|
|
557
|
+
before: { sha: beforeSha, version: beforeVersion },
|
|
558
|
+
steps,
|
|
559
|
+
durationMs: Date.now() - startedAt,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
const doctorArgv = [process.execPath, doctorEntry, "doctor", "--non-interactive"];
|
|
563
|
+
const doctorStep = await runStep(step("poolbot doctor", doctorArgv, gitRoot, { CLAWDBOT_UPDATE_IN_PROGRESS: "1" }));
|
|
512
564
|
steps.push(doctorStep);
|
|
565
|
+
const uiIndexHealth = await resolveControlUiDistIndexHealth({ root: gitRoot });
|
|
566
|
+
if (!uiIndexHealth.exists) {
|
|
567
|
+
const repairArgv = managerScriptArgs(manager, "ui:build");
|
|
568
|
+
const started = Date.now();
|
|
569
|
+
const repairResult = await runCommand(repairArgv, { cwd: gitRoot, timeoutMs });
|
|
570
|
+
const repairStep = {
|
|
571
|
+
name: "ui:build (post-doctor repair)",
|
|
572
|
+
command: repairArgv.join(" "),
|
|
573
|
+
cwd: gitRoot,
|
|
574
|
+
durationMs: Date.now() - started,
|
|
575
|
+
exitCode: repairResult.code,
|
|
576
|
+
stdoutTail: trimLogTail(repairResult.stdout, MAX_LOG_CHARS),
|
|
577
|
+
stderrTail: trimLogTail(repairResult.stderr, MAX_LOG_CHARS),
|
|
578
|
+
};
|
|
579
|
+
steps.push(repairStep);
|
|
580
|
+
if (repairResult.code !== 0) {
|
|
581
|
+
return {
|
|
582
|
+
status: "error",
|
|
583
|
+
mode: "git",
|
|
584
|
+
root: gitRoot,
|
|
585
|
+
reason: repairStep.name,
|
|
586
|
+
before: { sha: beforeSha, version: beforeVersion },
|
|
587
|
+
steps,
|
|
588
|
+
durationMs: Date.now() - startedAt,
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
const repairedUiIndexHealth = await resolveControlUiDistIndexHealth({ root: gitRoot });
|
|
592
|
+
if (!repairedUiIndexHealth.exists) {
|
|
593
|
+
const uiIndexPath = repairedUiIndexHealth.indexPath ?? resolveControlUiDistIndexPathForRoot(gitRoot);
|
|
594
|
+
steps.push({
|
|
595
|
+
name: "ui assets verify",
|
|
596
|
+
command: `verify ${uiIndexPath}`,
|
|
597
|
+
cwd: gitRoot,
|
|
598
|
+
durationMs: 0,
|
|
599
|
+
exitCode: 1,
|
|
600
|
+
stderrTail: `missing ${uiIndexPath}`,
|
|
601
|
+
});
|
|
602
|
+
return {
|
|
603
|
+
status: "error",
|
|
604
|
+
mode: "git",
|
|
605
|
+
root: gitRoot,
|
|
606
|
+
reason: "ui-assets-missing",
|
|
607
|
+
before: { sha: beforeSha, version: beforeVersion },
|
|
608
|
+
steps,
|
|
609
|
+
durationMs: Date.now() - startedAt,
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
}
|
|
513
613
|
const failedStep = steps.find((s) => s.exitCode !== 0);
|
|
514
614
|
const afterShaStep = await runStep(step("git rev-parse HEAD (after)", ["git", "-C", gitRoot, "rev-parse", "HEAD"], gitRoot));
|
|
515
615
|
steps.push(afterShaStep);
|
|
@@ -541,7 +641,13 @@ export async function runGatewayUpdate(opts = {}) {
|
|
|
541
641
|
const globalManager = await detectGlobalInstallManagerForRoot(runCommand, pkgRoot, timeoutMs);
|
|
542
642
|
if (globalManager) {
|
|
543
643
|
const packageName = (await readPackageName(pkgRoot)) ?? DEFAULT_PACKAGE_NAME;
|
|
544
|
-
|
|
644
|
+
await cleanupGlobalRenameDirs({
|
|
645
|
+
globalRoot: path.dirname(pkgRoot),
|
|
646
|
+
packageName,
|
|
647
|
+
});
|
|
648
|
+
const channel = opts.channel ?? DEFAULT_PACKAGE_CHANNEL;
|
|
649
|
+
const tag = normalizeTag(opts.tag ?? channelToNpmTag(channel));
|
|
650
|
+
const spec = `${packageName}@${tag}`;
|
|
545
651
|
const updateStep = await runStep({
|
|
546
652
|
runCommand,
|
|
547
653
|
name: "global update",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const warningFilterKey = Symbol.for("poolbot.warning-filter");
|
|
2
|
+
export function shouldIgnoreWarning(warning) {
|
|
3
|
+
if (warning.code === "DEP0040" && warning.message?.includes("punycode")) {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
if (warning.code === "DEP0060" && warning.message?.includes("util._extend")) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (warning.name === "ExperimentalWarning" &&
|
|
10
|
+
warning.message?.includes("SQLite is an experimental feature")) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
function normalizeWarningArgs(args) {
|
|
16
|
+
const warningArg = args[0];
|
|
17
|
+
const secondArg = args[1];
|
|
18
|
+
const thirdArg = args[2];
|
|
19
|
+
let name;
|
|
20
|
+
let code;
|
|
21
|
+
let message;
|
|
22
|
+
if (warningArg instanceof Error) {
|
|
23
|
+
name = warningArg.name;
|
|
24
|
+
message = warningArg.message;
|
|
25
|
+
code = warningArg.code;
|
|
26
|
+
}
|
|
27
|
+
else if (typeof warningArg === "string") {
|
|
28
|
+
message = warningArg;
|
|
29
|
+
}
|
|
30
|
+
if (secondArg && typeof secondArg === "object" && !Array.isArray(secondArg)) {
|
|
31
|
+
const options = secondArg;
|
|
32
|
+
if (typeof options.type === "string") {
|
|
33
|
+
name = options.type;
|
|
34
|
+
}
|
|
35
|
+
if (typeof options.code === "string") {
|
|
36
|
+
code = options.code;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (typeof secondArg === "string") {
|
|
41
|
+
name = secondArg;
|
|
42
|
+
}
|
|
43
|
+
if (typeof thirdArg === "string") {
|
|
44
|
+
code = thirdArg;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { name, code, message };
|
|
48
|
+
}
|
|
49
|
+
export function installProcessWarningFilter() {
|
|
50
|
+
const globalState = globalThis;
|
|
51
|
+
if (globalState[warningFilterKey]?.installed) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const originalEmitWarning = process.emitWarning.bind(process);
|
|
55
|
+
const wrappedEmitWarning = ((...args) => {
|
|
56
|
+
if (shouldIgnoreWarning(normalizeWarningArgs(args))) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
return Reflect.apply(originalEmitWarning, process, args);
|
|
60
|
+
});
|
|
61
|
+
process.emitWarning = wrappedEmitWarning;
|
|
62
|
+
globalState[warningFilterKey] = {
|
|
63
|
+
installed: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -2,10 +2,23 @@ import fs from "node:fs";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { CONFIG_DIR, ensureDir } from "../utils.js";
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
export function normalizeWideAreaDomain(raw) {
|
|
6
|
+
const trimmed = raw?.trim();
|
|
7
|
+
if (!trimmed) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return trimmed.endsWith(".") ? trimmed : `${trimmed}.`;
|
|
11
|
+
}
|
|
12
|
+
export function resolveWideAreaDiscoveryDomain(params) {
|
|
13
|
+
const env = params?.env ?? process.env;
|
|
14
|
+
const candidate = params?.configDomain ?? env.CLAWDBOT_WIDE_AREA_DOMAIN ?? null;
|
|
15
|
+
return normalizeWideAreaDomain(candidate);
|
|
16
|
+
}
|
|
17
|
+
function zoneFilenameForDomain(domain) {
|
|
18
|
+
return `${domain.replace(/\.$/, "")}.db`;
|
|
19
|
+
}
|
|
20
|
+
export function getWideAreaZonePath(domain) {
|
|
21
|
+
return path.join(CONFIG_DIR, "dns", zoneFilenameForDomain(domain));
|
|
9
22
|
}
|
|
10
23
|
function dnsLabel(raw, fallback) {
|
|
11
24
|
const normalized = raw
|
|
@@ -30,17 +43,20 @@ function formatYyyyMmDd(date) {
|
|
|
30
43
|
function nextSerial(existingSerial, now) {
|
|
31
44
|
const today = formatYyyyMmDd(now);
|
|
32
45
|
const base = Number.parseInt(`${today}01`, 10);
|
|
33
|
-
if (!existingSerial || !Number.isFinite(existingSerial))
|
|
46
|
+
if (!existingSerial || !Number.isFinite(existingSerial)) {
|
|
34
47
|
return base;
|
|
48
|
+
}
|
|
35
49
|
const existing = String(existingSerial);
|
|
36
|
-
if (existing.startsWith(today))
|
|
50
|
+
if (existing.startsWith(today)) {
|
|
37
51
|
return existingSerial + 1;
|
|
52
|
+
}
|
|
38
53
|
return base;
|
|
39
54
|
}
|
|
40
55
|
function extractSerial(zoneText) {
|
|
41
56
|
const match = zoneText.match(/^\s*@\s+IN\s+SOA\s+\S+\s+\S+\s+(\d+)\s+/m);
|
|
42
|
-
if (!match)
|
|
57
|
+
if (!match) {
|
|
43
58
|
return null;
|
|
59
|
+
}
|
|
44
60
|
const parsed = Number.parseInt(match[1], 10);
|
|
45
61
|
return Number.isFinite(parsed) ? parsed : null;
|
|
46
62
|
}
|
|
@@ -61,6 +77,7 @@ function renderZone(opts) {
|
|
|
61
77
|
const hostname = os.hostname().split(".")[0] ?? "poolbot";
|
|
62
78
|
const hostLabel = dnsLabel(opts.hostLabel ?? hostname, "poolbot");
|
|
63
79
|
const instanceLabel = dnsLabel(opts.instanceLabel ?? `${hostname}-gateway`, "poolbot-gw");
|
|
80
|
+
const domain = normalizeWideAreaDomain(opts.domain) ?? "local.";
|
|
64
81
|
const txt = [
|
|
65
82
|
`displayName=${opts.displayName.trim() || hostname}`,
|
|
66
83
|
`role=gateway`,
|
|
@@ -83,7 +100,7 @@ function renderZone(opts) {
|
|
|
83
100
|
txt.push(`cliPath=${opts.cliPath.trim()}`);
|
|
84
101
|
}
|
|
85
102
|
const records = [];
|
|
86
|
-
records.push(`$ORIGIN ${
|
|
103
|
+
records.push(`$ORIGIN ${domain}`);
|
|
87
104
|
records.push(`$TTL 60`);
|
|
88
105
|
const soaLine = `@ IN SOA ns1 hostmaster ${opts.serial} 7200 3600 1209600 60`;
|
|
89
106
|
records.push(soaLine);
|
|
@@ -107,7 +124,11 @@ export function renderWideAreaGatewayZoneText(opts) {
|
|
|
107
124
|
return renderZone(opts);
|
|
108
125
|
}
|
|
109
126
|
export async function writeWideAreaGatewayZone(opts) {
|
|
110
|
-
const
|
|
127
|
+
const domain = normalizeWideAreaDomain(opts.domain);
|
|
128
|
+
if (!domain) {
|
|
129
|
+
throw new Error("wide-area discovery domain is required");
|
|
130
|
+
}
|
|
131
|
+
const zonePath = getWideAreaZonePath(domain);
|
|
111
132
|
await ensureDir(path.dirname(zonePath));
|
|
112
133
|
const existing = (() => {
|
|
113
134
|
try {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
export function sha256HexPrefix(value, len = 12) {
|
|
3
|
+
const safeLen = Number.isFinite(len) ? Math.max(1, Math.floor(len)) : 12;
|
|
4
|
+
return crypto.createHash("sha256").update(value).digest("hex").slice(0, safeLen);
|
|
5
|
+
}
|
|
6
|
+
export function redactIdentifier(value, opts) {
|
|
7
|
+
const trimmed = value?.trim();
|
|
8
|
+
if (!trimmed) {
|
|
9
|
+
return "-";
|
|
10
|
+
}
|
|
11
|
+
return `sha256:${sha256HexPrefix(trimmed, opts?.len ?? 12)}`;
|
|
12
|
+
}
|