@poolzin/pool-bot 2026.2.2 → 2026.2.4

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.
Files changed (127) hide show
  1. package/dist/acp/server.js +2 -0
  2. package/dist/agents/agent-paths.js +5 -1
  3. package/dist/agents/anthropic-payload-log.js +3 -2
  4. package/dist/agents/bash-tools.exec.js +2 -1
  5. package/dist/agents/bash-tools.shared.js +2 -1
  6. package/dist/agents/cache-trace.js +9 -5
  7. package/dist/agents/cli-runner.js +1 -1
  8. package/dist/agents/live-auth-keys.js +3 -2
  9. package/dist/agents/pi-embedded-runner/session-manager-cache.js +2 -1
  10. package/dist/agents/pi-embedded-subscribe.raw-stream.js +3 -2
  11. package/dist/agents/sandbox/browser.js +5 -0
  12. package/dist/agents/shell-utils.js +1 -1
  13. package/dist/agents/skills/bundled-dir.js +2 -1
  14. package/dist/agents/synthetic-models.js +8 -0
  15. package/dist/agents/workspace.js +1 -1
  16. package/dist/auto-reply/reply/get-reply.js +1 -1
  17. package/dist/build-info.json +3 -3
  18. package/dist/canvas-host/server.js +1 -1
  19. package/dist/channels/plugins/catalog.js +6 -1
  20. package/dist/cli/banner.js +12 -12
  21. package/dist/cli/browser-cli-manage.js +10 -10
  22. package/dist/cli/browser-cli.js +1 -1
  23. package/dist/cli/channel-options.js +1 -1
  24. package/dist/cli/cli-name.js +1 -1
  25. package/dist/cli/command-format.js +1 -1
  26. package/dist/cli/daemon-cli/install.js +4 -1
  27. package/dist/cli/daemon-cli/shared.js +8 -3
  28. package/dist/cli/daemon-cli/status.gather.js +2 -0
  29. package/dist/cli/daemon-cli/status.print.js +3 -3
  30. package/dist/cli/gateway-cli/dev.js +1 -1
  31. package/dist/cli/gateway-cli/run.js +11 -6
  32. package/dist/cli/gateway-cli/shared.js +1 -1
  33. package/dist/cli/memory-cli.js +9 -3
  34. package/dist/cli/node-cli/daemon.js +2 -1
  35. package/dist/cli/profile.js +14 -4
  36. package/dist/cli/program/help.js +1 -1
  37. package/dist/cli/program/preaction.js +1 -1
  38. package/dist/cli/program/register.agent.js +4 -4
  39. package/dist/cli/program/register.onboard.js +1 -1
  40. package/dist/cli/program/register.setup.js +1 -1
  41. package/dist/cli/program/register.subclis.js +2 -2
  42. package/dist/cli/route.js +1 -1
  43. package/dist/cli/tagline.js +8 -8
  44. package/dist/cli/update-cli.js +12 -10
  45. package/dist/commands/auth-choice-options.js +104 -33
  46. package/dist/commands/configure.wizard.js +28 -9
  47. package/dist/commands/daemon-install-helpers.js +1 -1
  48. package/dist/commands/dashboard.js +4 -1
  49. package/dist/commands/doctor-format.js +3 -3
  50. package/dist/commands/doctor-gateway-daemon-flow.js +9 -3
  51. package/dist/commands/doctor-gateway-services.js +6 -2
  52. package/dist/commands/doctor-platform-notes.js +25 -8
  53. package/dist/commands/doctor-update.js +1 -1
  54. package/dist/commands/gateway-status/helpers.js +4 -2
  55. package/dist/commands/health.js +2 -2
  56. package/dist/commands/node-daemon-install-helpers.js +1 -1
  57. package/dist/commands/onboard-helpers.js +6 -6
  58. package/dist/commands/status-all.js +4 -2
  59. package/dist/commands/status.gateway-probe.js +4 -2
  60. package/dist/commands/status.scan.js +3 -2
  61. package/dist/config/io.js +5 -3
  62. package/dist/config/paths.js +27 -14
  63. package/dist/config/schema.field-metadata.js +1 -1
  64. package/dist/config/schema.js +1 -1
  65. package/dist/config/sessions/store.js +1 -1
  66. package/dist/daemon/inspect.js +1 -1
  67. package/dist/daemon/launchd.js +8 -5
  68. package/dist/daemon/node-service.js +14 -0
  69. package/dist/daemon/paths.js +2 -2
  70. package/dist/daemon/schtasks.js +9 -6
  71. package/dist/daemon/service-env.js +25 -5
  72. package/dist/daemon/systemd.js +9 -6
  73. package/dist/entry.js +5 -2
  74. package/dist/gateway/auth.js +6 -3
  75. package/dist/gateway/call.js +3 -1
  76. package/dist/gateway/server/ws-connection/message-handler.js +4 -1
  77. package/dist/gateway/server-browser.js +4 -2
  78. package/dist/gateway/server-constants.js +5 -2
  79. package/dist/gateway/server-cron.js +3 -1
  80. package/dist/gateway/server-discovery-runtime.js +4 -1
  81. package/dist/gateway/server-discovery.js +2 -2
  82. package/dist/gateway/server-reload-handlers.js +4 -4
  83. package/dist/gateway/server-runtime-config.js +2 -2
  84. package/dist/gateway/server-startup.js +4 -4
  85. package/dist/gateway/server.impl.js +3 -2
  86. package/dist/gateway/test-helpers.mocks.js +3 -0
  87. package/dist/gateway/test-helpers.server.js +60 -22
  88. package/dist/hooks/bundled-dir.js +1 -1
  89. package/dist/hooks/gmail-watcher.js +1 -1
  90. package/dist/infra/bonjour.js +1 -1
  91. package/dist/infra/diagnostic-flags.js +3 -2
  92. package/dist/infra/dotenv.js +1 -1
  93. package/dist/infra/gateway-lock.js +1 -1
  94. package/dist/infra/home-dir.js +1 -1
  95. package/dist/infra/path-env.js +2 -1
  96. package/dist/infra/restart.js +4 -3
  97. package/dist/infra/shell-env.js +4 -3
  98. package/dist/infra/state-migrations.js +5 -3
  99. package/dist/infra/system-presence.js +4 -1
  100. package/dist/infra/update-runner.js +4 -1
  101. package/dist/infra/widearea-dns.js +1 -1
  102. package/dist/macos/gateway-daemon.js +6 -1
  103. package/dist/macos/relay-smoke.js +5 -1
  104. package/dist/macos/relay.js +1 -0
  105. package/dist/media/image-ops.js +4 -2
  106. package/dist/memory/batch-gemini.js +1 -1
  107. package/dist/memory/embeddings-gemini.js +1 -1
  108. package/dist/node-host/runner.js +4 -2
  109. package/dist/plugins/bundled-dir.js +2 -1
  110. package/dist/plugins/manifest-registry.js +3 -2
  111. package/dist/security/audit-extra.sync.js +1 -1
  112. package/dist/security/audit.js +4 -2
  113. package/dist/telegram/accounts.js +1 -1
  114. package/dist/telegram/bot-message-dispatch.js +1 -1
  115. package/dist/telegram/network-config.js +8 -4
  116. package/dist/terminal/palette.js +8 -6
  117. package/dist/terminal/theme.js +12 -12
  118. package/dist/test-helpers/state-dir-env.js +8 -0
  119. package/dist/tts/tts.js +1 -1
  120. package/dist/tui/gateway-chat.js +3 -1
  121. package/dist/tui/theme/theme.js +5 -5
  122. package/dist/tui/tui.js +12 -6
  123. package/dist/utils.js +2 -2
  124. package/dist/version.js +1 -0
  125. package/dist/wizard/onboarding.finalize.js +1 -1
  126. package/dist/wizard/onboarding.js +6 -2
  127. package/package.json +1 -1
package/dist/entry.js CHANGED
@@ -25,13 +25,16 @@ function hasExperimentalWarningSuppressed() {
25
25
  return false;
26
26
  }
27
27
  function ensureExperimentalWarningSuppressed() {
28
- if (isTruthyEnvValue(process.env.CLAWDBOT_NO_RESPAWN))
28
+ if (isTruthyEnvValue(process.env.POOLBOT_NO_RESPAWN) ||
29
+ isTruthyEnvValue(process.env.CLAWDBOT_NO_RESPAWN))
29
30
  return false;
30
- if (isTruthyEnvValue(process.env.CLAWDBOT_NODE_OPTIONS_READY))
31
+ if (isTruthyEnvValue(process.env.POOLBOT_NODE_OPTIONS_READY) ||
32
+ isTruthyEnvValue(process.env.CLAWDBOT_NODE_OPTIONS_READY))
31
33
  return false;
32
34
  if (hasExperimentalWarningSuppressed())
33
35
  return false;
34
36
  // Respawn guard (and keep recursion bounded if something goes wrong).
37
+ process.env.POOLBOT_NODE_OPTIONS_READY = "1";
35
38
  process.env.CLAWDBOT_NODE_OPTIONS_READY = "1";
36
39
  // Pass flag as a Node CLI option, not via NODE_OPTIONS (--disable-warning is disallowed in NODE_OPTIONS).
37
40
  const child = spawn(process.execPath, [EXPERIMENTAL_WARNING_FLAG, ...process.execArgv, ...process.argv.slice(1)], {
@@ -127,8 +127,11 @@ async function resolveVerifiedTailscaleUser(params) {
127
127
  export function resolveGatewayAuth(params) {
128
128
  const authConfig = params.authConfig ?? {};
129
129
  const env = params.env ?? process.env;
130
- const token = authConfig.token ?? env.CLAWDBOT_GATEWAY_TOKEN ?? undefined;
131
- const password = authConfig.password ?? env.CLAWDBOT_GATEWAY_PASSWORD ?? undefined;
130
+ const token = authConfig.token ?? env.POOLBOT_GATEWAY_TOKEN ?? env.CLAWDBOT_GATEWAY_TOKEN ?? undefined;
131
+ const password = authConfig.password ??
132
+ env.POOLBOT_GATEWAY_PASSWORD ??
133
+ env.CLAWDBOT_GATEWAY_PASSWORD ??
134
+ undefined;
132
135
  const mode = authConfig.mode ?? (password ? "password" : "token");
133
136
  const allowTailscale = authConfig.allowTailscale ?? (params.tailscaleMode === "serve" && mode !== "password");
134
137
  return {
@@ -142,7 +145,7 @@ export function assertGatewayAuthConfigured(auth) {
142
145
  if (auth.mode === "token" && !auth.token) {
143
146
  if (auth.allowTailscale)
144
147
  return;
145
- throw new Error("gateway auth mode is token, but no token was configured (set gateway.auth.token or CLAWDBOT_GATEWAY_TOKEN)");
148
+ throw new Error("gateway auth mode is token, but no token was configured (set gateway.auth.token or POOLBOT_GATEWAY_TOKEN)");
146
149
  }
147
150
  if (auth.mode === "password" && !auth.password) {
148
151
  throw new Error("gateway auth mode is password, but no password was configured");
@@ -95,13 +95,15 @@ export async function callGateway(opts) {
95
95
  ? typeof remote?.token === "string" && remote.token.trim().length > 0
96
96
  ? remote.token.trim()
97
97
  : undefined
98
- : process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
98
+ : process.env.POOLBOT_GATEWAY_TOKEN?.trim() ||
99
+ process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
99
100
  (typeof authToken === "string" && authToken.trim().length > 0
100
101
  ? authToken.trim()
101
102
  : undefined));
102
103
  const password = (typeof opts.password === "string" && opts.password.trim().length > 0
103
104
  ? opts.password.trim()
104
105
  : undefined) ||
106
+ process.env.POOLBOT_GATEWAY_PASSWORD?.trim() ||
105
107
  process.env.CLAWDBOT_GATEWAY_PASSWORD?.trim() ||
106
108
  (isRemoteMode
107
109
  ? typeof remote?.password === "string" && remote.password.trim().length > 0
@@ -642,7 +642,10 @@ export function attachGatewayWsMessageHandler(params) {
642
642
  type: "hello-ok",
643
643
  protocol: PROTOCOL_VERSION,
644
644
  server: {
645
- version: process.env.CLAWDBOT_VERSION ?? process.env.npm_package_version ?? "dev",
645
+ version: process.env.POOLBOT_VERSION ??
646
+ process.env.CLAWDBOT_VERSION ??
647
+ process.env.npm_package_version ??
648
+ "dev",
646
649
  commit: process.env.GIT_COMMIT,
647
650
  host: os.hostname(),
648
651
  connId,
@@ -1,10 +1,12 @@
1
1
  import { isTruthyEnvValue } from "../infra/env.js";
2
2
  export async function startBrowserControlServerIfEnabled() {
3
- if (isTruthyEnvValue(process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER))
3
+ if (isTruthyEnvValue(process.env.POOLBOT_SKIP_BROWSER_CONTROL_SERVER ||
4
+ process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER))
4
5
  return null;
5
6
  // Lazy import: keeps startup fast, but still bundles for the embedded
6
7
  // gateway (bun --compile) via the static specifier path.
7
- const override = process.env.CLAWDBOT_BROWSER_CONTROL_MODULE?.trim();
8
+ const override = process.env.POOLBOT_BROWSER_CONTROL_MODULE?.trim() ||
9
+ process.env.CLAWDBOT_BROWSER_CONTROL_MODULE?.trim();
8
10
  const mod = override ? await import(override) : await import("../browser/control-service.js");
9
11
  const start = typeof mod
10
12
  .startBrowserControlServiceFromConfig === "function"
@@ -16,8 +16,11 @@ export const __setMaxChatHistoryMessagesBytesForTest = (value) => {
16
16
  };
17
17
  export const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
18
18
  export const getHandshakeTimeoutMs = () => {
19
- if (process.env.VITEST && process.env.CLAWDBOT_TEST_HANDSHAKE_TIMEOUT_MS) {
20
- const parsed = Number(process.env.CLAWDBOT_TEST_HANDSHAKE_TIMEOUT_MS);
19
+ if (process.env.VITEST &&
20
+ (process.env.POOLBOT_TEST_HANDSHAKE_TIMEOUT_MS ||
21
+ process.env.CLAWDBOT_TEST_HANDSHAKE_TIMEOUT_MS)) {
22
+ const parsed = Number(process.env.POOLBOT_TEST_HANDSHAKE_TIMEOUT_MS ||
23
+ process.env.CLAWDBOT_TEST_HANDSHAKE_TIMEOUT_MS);
21
24
  if (Number.isFinite(parsed) && parsed > 0)
22
25
  return parsed;
23
26
  }
@@ -14,7 +14,9 @@ import { defaultRuntime } from "../runtime.js";
14
14
  export function buildGatewayCronService(params) {
15
15
  const cronLogger = getChildLogger({ module: "cron" });
16
16
  const storePath = resolveCronStorePath(params.cfg.cron?.store);
17
- const cronEnabled = process.env.CLAWDBOT_SKIP_CRON !== "1" && params.cfg.cron?.enabled !== false;
17
+ const cronEnabled = process.env.POOLBOT_SKIP_CRON !== "1" &&
18
+ process.env.CLAWDBOT_SKIP_CRON !== "1" &&
19
+ params.cfg.cron?.enabled !== false;
18
20
  const resolveCronAgent = (requested) => {
19
21
  const runtimeConfig = loadConfig();
20
22
  const normalized = typeof requested === "string" && requested.trim() ? normalizeAgentId(requested) : undefined;
@@ -7,6 +7,7 @@ export async function startGatewayDiscovery(params) {
7
7
  const mdnsMode = params.mdnsMode ?? "minimal";
8
8
  // mDNS can be disabled via config (mdnsMode: off) or env var.
9
9
  const bonjourEnabled = mdnsMode !== "off" &&
10
+ process.env.POOLBOT_DISABLE_BONJOUR !== "1" &&
10
11
  process.env.CLAWDBOT_DISABLE_BONJOUR !== "1" &&
11
12
  process.env.NODE_ENV !== "test" &&
12
13
  !process.env.VITEST;
@@ -16,7 +17,9 @@ export async function startGatewayDiscovery(params) {
16
17
  const tailnetDns = needsTailnetDns
17
18
  ? await resolveTailnetDnsHint({ enabled: tailscaleEnabled })
18
19
  : undefined;
19
- const sshPortEnv = mdnsMinimal ? undefined : process.env.CLAWDBOT_SSH_PORT?.trim();
20
+ const sshPortEnv = mdnsMinimal
21
+ ? undefined
22
+ : process.env.POOLBOT_SSH_PORT?.trim() || process.env.CLAWDBOT_SSH_PORT?.trim();
20
23
  const sshPortParsed = sshPortEnv ? Number.parseInt(sshPortEnv, 10) : NaN;
21
24
  const sshPort = Number.isFinite(sshPortParsed) && sshPortParsed > 0 ? sshPortParsed : undefined;
22
25
  const cliPath = mdnsMinimal ? undefined : resolveBonjourCliPath();
@@ -12,7 +12,7 @@ export function formatBonjourInstanceName(displayName) {
12
12
  }
13
13
  export function resolveBonjourCliPath(opts = {}) {
14
14
  const env = opts.env ?? process.env;
15
- const envPath = env.CLAWDBOT_CLI_PATH?.trim();
15
+ const envPath = env.POOLBOT_CLI_PATH?.trim() || env.CLAWDBOT_CLI_PATH?.trim();
16
16
  if (envPath)
17
17
  return envPath;
18
18
  const statSync = opts.statSync ?? fs.statSync;
@@ -45,7 +45,7 @@ export function resolveBonjourCliPath(opts = {}) {
45
45
  }
46
46
  export async function resolveTailnetDnsHint(opts) {
47
47
  const env = opts?.env ?? process.env;
48
- const envRaw = env.CLAWDBOT_TAILNET_DNS?.trim();
48
+ const envRaw = env.POOLBOT_TAILNET_DNS?.trim() || env.CLAWDBOT_TAILNET_DNS?.trim();
49
49
  const envValue = envRaw && envRaw.length > 0 ? envRaw.replace(/\.$/, "") : "";
50
50
  if (envValue)
51
51
  return envValue;
@@ -48,7 +48,7 @@ export function createGatewayReloadHandlers(params) {
48
48
  }
49
49
  if (plan.restartGmailWatcher) {
50
50
  await stopGmailWatcher().catch(() => { });
51
- if (!isTruthyEnvValue(process.env.CLAWDBOT_SKIP_GMAIL_WATCHER)) {
51
+ if (!isTruthyEnvValue(process.env.POOLBOT_SKIP_GMAIL_WATCHER || process.env.CLAWDBOT_SKIP_GMAIL_WATCHER)) {
52
52
  try {
53
53
  const gmailResult = await startGmailWatcher(nextConfig);
54
54
  if (gmailResult.started) {
@@ -65,13 +65,13 @@ export function createGatewayReloadHandlers(params) {
65
65
  }
66
66
  }
67
67
  else {
68
- params.logHooks.info("skipping gmail watcher restart (CLAWDBOT_SKIP_GMAIL_WATCHER=1)");
68
+ params.logHooks.info("skipping gmail watcher restart (POOLBOT_SKIP_GMAIL_WATCHER=1)");
69
69
  }
70
70
  }
71
71
  if (plan.restartChannels.size > 0) {
72
- if (isTruthyEnvValue(process.env.CLAWDBOT_SKIP_CHANNELS) ||
72
+ if (isTruthyEnvValue(process.env.POOLBOT_SKIP_CHANNELS || process.env.CLAWDBOT_SKIP_CHANNELS) ||
73
73
  isTruthyEnvValue(process.env.CLAWDBOT_SKIP_PROVIDERS)) {
74
- params.logChannels.info("skipping channel reload (CLAWDBOT_SKIP_CHANNELS=1 or CLAWDBOT_SKIP_PROVIDERS=1)");
74
+ params.logChannels.info("skipping channel reload (POOLBOT_SKIP_CHANNELS=1 / CLAWDBOT_SKIP_CHANNELS=1 or CLAWDBOT_SKIP_PROVIDERS=1)");
75
75
  }
76
76
  else {
77
77
  const restartChannel = async (name) => {
@@ -39,13 +39,13 @@ export async function resolveGatewayRuntimeConfig(params) {
39
39
  const canvasHostEnabled = process.env.CLAWDBOT_SKIP_CANVAS_HOST !== "1" && params.cfg.canvasHost?.enabled !== false;
40
40
  assertGatewayAuthConfigured(resolvedAuth);
41
41
  if (tailscaleMode === "funnel" && authMode !== "password") {
42
- throw new Error("tailscale funnel requires gateway auth mode=password (set gateway.auth.password or CLAWDBOT_GATEWAY_PASSWORD)");
42
+ throw new Error("tailscale funnel requires gateway auth mode=password (set gateway.auth.password or POOLBOT_GATEWAY_PASSWORD)");
43
43
  }
44
44
  if (tailscaleMode !== "off" && !isLoopbackHost(bindHost)) {
45
45
  throw new Error("tailscale serve/funnel requires gateway bind=loopback (127.0.0.1)");
46
46
  }
47
47
  if (!isLoopbackHost(bindHost) && !hasSharedSecret) {
48
- throw new Error(`refusing to bind gateway to ${bindHost}:${params.port} without auth (set gateway.auth.token/password, or set CLAWDBOT_GATEWAY_TOKEN/CLAWDBOT_GATEWAY_PASSWORD)`);
48
+ throw new Error(`refusing to bind gateway to ${bindHost}:${params.port} without auth (set gateway.auth.token/password, or set POOLBOT_GATEWAY_TOKEN/POOLBOT_GATEWAY_PASSWORD)`);
49
49
  }
50
50
  return {
51
51
  bindHost,
@@ -18,7 +18,7 @@ export async function startGatewaySidecars(params) {
18
18
  params.logBrowser.error(`server failed to start: ${String(err)}`);
19
19
  }
20
20
  // Start Gmail watcher if configured (hooks.gmail.account).
21
- if (!isTruthyEnvValue(process.env.CLAWDBOT_SKIP_GMAIL_WATCHER)) {
21
+ if (!isTruthyEnvValue(process.env.POOLBOT_SKIP_GMAIL_WATCHER || process.env.CLAWDBOT_SKIP_GMAIL_WATCHER)) {
22
22
  try {
23
23
  const gmailResult = await startGmailWatcher(params.cfg);
24
24
  if (gmailResult.started) {
@@ -75,8 +75,8 @@ export async function startGatewaySidecars(params) {
75
75
  params.logHooks.error(`failed to load hooks: ${String(err)}`);
76
76
  }
77
77
  // Launch configured channels so gateway replies via the surface the message came from.
78
- // Tests can opt out via CLAWDBOT_SKIP_CHANNELS (or legacy CLAWDBOT_SKIP_PROVIDERS).
79
- const skipChannels = isTruthyEnvValue(process.env.CLAWDBOT_SKIP_CHANNELS) ||
78
+ // Tests can opt out via POOLBOT_SKIP_CHANNELS / CLAWDBOT_SKIP_CHANNELS (or legacy CLAWDBOT_SKIP_PROVIDERS).
79
+ const skipChannels = isTruthyEnvValue(process.env.POOLBOT_SKIP_CHANNELS || process.env.CLAWDBOT_SKIP_CHANNELS) ||
80
80
  isTruthyEnvValue(process.env.CLAWDBOT_SKIP_PROVIDERS);
81
81
  if (!skipChannels) {
82
82
  try {
@@ -87,7 +87,7 @@ export async function startGatewaySidecars(params) {
87
87
  }
88
88
  }
89
89
  else {
90
- params.logChannels.info("skipping channel start (CLAWDBOT_SKIP_CHANNELS=1 or CLAWDBOT_SKIP_PROVIDERS=1)");
90
+ params.logChannels.info("skipping channel start (POOLBOT_SKIP_CHANNELS=1 / CLAWDBOT_SKIP_CHANNELS=1 or CLAWDBOT_SKIP_PROVIDERS=1)");
91
91
  }
92
92
  if (params.cfg.hooks?.internal?.enabled) {
93
93
  setTimeout(() => {
@@ -66,13 +66,14 @@ const logWsControl = log.child("ws");
66
66
  const canvasRuntime = runtimeForLogger(logCanvas);
67
67
  export async function startGatewayServer(port = 18789, opts = {}) {
68
68
  // Ensure all default port derivations (browser/canvas) see the actual runtime port.
69
+ process.env.POOLBOT_GATEWAY_PORT = String(port);
69
70
  process.env.CLAWDBOT_GATEWAY_PORT = String(port);
70
71
  logAcceptedEnvOption({
71
- key: "CLAWDBOT_RAW_STREAM",
72
+ key: "POOLBOT_RAW_STREAM",
72
73
  description: "raw stream logging enabled",
73
74
  });
74
75
  logAcceptedEnvOption({
75
- key: "CLAWDBOT_RAW_STREAM_PATH",
76
+ key: "POOLBOT_RAW_STREAM_PATH",
76
77
  description: "raw stream log path override",
77
78
  });
78
79
  let configSnapshot = await readConfigFileSnapshot();
@@ -167,6 +167,7 @@ const testConfigRoot = {
167
167
  };
168
168
  export const setTestConfigRoot = (root) => {
169
169
  testConfigRoot.value = root;
170
+ process.env.POOLBOT_CONFIG_PATH = path.join(root, "poolbot.json");
170
171
  process.env.CLAWDBOT_CONFIG_PATH = path.join(root, "poolbot.json");
171
172
  };
172
173
  export const testTailnetIPv4 = hoisted.testTailnetIPv4;
@@ -502,5 +503,7 @@ vi.mock("../cli/deps.js", async () => {
502
503
  }),
503
504
  };
504
505
  });
506
+ process.env.POOLBOT_SKIP_CHANNELS = "1";
505
507
  process.env.CLAWDBOT_SKIP_CHANNELS = "1";
508
+ process.env.POOLBOT_SKIP_CRON = "1";
506
509
  process.env.CLAWDBOT_SKIP_CRON = "1";
@@ -52,25 +52,37 @@ export async function writeSessionStore(params) {
52
52
  async function setupGatewayTestHome() {
53
53
  previousHome = process.env.HOME;
54
54
  previousUserProfile = process.env.USERPROFILE;
55
- previousStateDir = process.env.CLAWDBOT_STATE_DIR;
56
- previousConfigPath = process.env.CLAWDBOT_CONFIG_PATH;
57
- previousSkipBrowserControl = process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER;
58
- previousSkipGmailWatcher = process.env.CLAWDBOT_SKIP_GMAIL_WATCHER;
59
- previousSkipCanvasHost = process.env.CLAWDBOT_SKIP_CANVAS_HOST;
60
- previousBundledPluginsDir = process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR;
55
+ previousStateDir = process.env.POOLBOT_STATE_DIR ?? process.env.CLAWDBOT_STATE_DIR;
56
+ previousConfigPath = process.env.POOLBOT_CONFIG_PATH ?? process.env.CLAWDBOT_CONFIG_PATH;
57
+ previousSkipBrowserControl =
58
+ process.env.POOLBOT_SKIP_BROWSER_CONTROL_SERVER ??
59
+ process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER;
60
+ previousSkipGmailWatcher =
61
+ process.env.POOLBOT_SKIP_GMAIL_WATCHER ?? process.env.CLAWDBOT_SKIP_GMAIL_WATCHER;
62
+ previousSkipCanvasHost =
63
+ process.env.POOLBOT_SKIP_CANVAS_HOST ?? process.env.CLAWDBOT_SKIP_CANVAS_HOST;
64
+ previousBundledPluginsDir =
65
+ process.env.POOLBOT_BUNDLED_PLUGINS_DIR ?? process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR;
61
66
  tempHome = await fs.mkdtemp(path.join(os.tmpdir(), "poolbot-gateway-home-"));
62
67
  process.env.HOME = tempHome;
63
68
  process.env.USERPROFILE = tempHome;
69
+ process.env.POOLBOT_STATE_DIR = path.join(tempHome, ".poolbot");
64
70
  process.env.CLAWDBOT_STATE_DIR = path.join(tempHome, ".poolbot");
71
+ delete process.env.POOLBOT_CONFIG_PATH;
65
72
  delete process.env.CLAWDBOT_CONFIG_PATH;
66
73
  }
67
74
  function applyGatewaySkipEnv() {
75
+ process.env.POOLBOT_SKIP_BROWSER_CONTROL_SERVER = "1";
68
76
  process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER = "1";
77
+ process.env.POOLBOT_SKIP_GMAIL_WATCHER = "1";
69
78
  process.env.CLAWDBOT_SKIP_GMAIL_WATCHER = "1";
79
+ process.env.POOLBOT_SKIP_CANVAS_HOST = "1";
70
80
  process.env.CLAWDBOT_SKIP_CANVAS_HOST = "1";
71
- process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR = tempHome
81
+ const bundledDir = tempHome
72
82
  ? path.join(tempHome, "poolbot-test-no-bundled-extensions")
73
83
  : "poolbot-test-no-bundled-extensions";
84
+ process.env.POOLBOT_BUNDLED_PLUGINS_DIR = bundledDir;
85
+ process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR = bundledDir;
74
86
  }
75
87
  async function resetGatewayTestState(options) {
76
88
  // Some tests intentionally use fake timers; ensure they don't leak into gateway suites.
@@ -131,30 +143,54 @@ async function cleanupGatewayTestHome(options) {
131
143
  delete process.env.USERPROFILE;
132
144
  else
133
145
  process.env.USERPROFILE = previousUserProfile;
134
- if (previousStateDir === undefined)
146
+ if (previousStateDir === undefined) {
147
+ delete process.env.POOLBOT_STATE_DIR;
135
148
  delete process.env.CLAWDBOT_STATE_DIR;
136
- else
149
+ }
150
+ else {
151
+ process.env.POOLBOT_STATE_DIR = previousStateDir;
137
152
  process.env.CLAWDBOT_STATE_DIR = previousStateDir;
138
- if (previousConfigPath === undefined)
153
+ }
154
+ if (previousConfigPath === undefined) {
155
+ delete process.env.POOLBOT_CONFIG_PATH;
139
156
  delete process.env.CLAWDBOT_CONFIG_PATH;
140
- else
157
+ }
158
+ else {
159
+ process.env.POOLBOT_CONFIG_PATH = previousConfigPath;
141
160
  process.env.CLAWDBOT_CONFIG_PATH = previousConfigPath;
142
- if (previousSkipBrowserControl === undefined)
161
+ }
162
+ if (previousSkipBrowserControl === undefined) {
163
+ delete process.env.POOLBOT_SKIP_BROWSER_CONTROL_SERVER;
143
164
  delete process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER;
144
- else
165
+ }
166
+ else {
167
+ process.env.POOLBOT_SKIP_BROWSER_CONTROL_SERVER = previousSkipBrowserControl;
145
168
  process.env.CLAWDBOT_SKIP_BROWSER_CONTROL_SERVER = previousSkipBrowserControl;
146
- if (previousSkipGmailWatcher === undefined)
169
+ }
170
+ if (previousSkipGmailWatcher === undefined) {
171
+ delete process.env.POOLBOT_SKIP_GMAIL_WATCHER;
147
172
  delete process.env.CLAWDBOT_SKIP_GMAIL_WATCHER;
148
- else
173
+ }
174
+ else {
175
+ process.env.POOLBOT_SKIP_GMAIL_WATCHER = previousSkipGmailWatcher;
149
176
  process.env.CLAWDBOT_SKIP_GMAIL_WATCHER = previousSkipGmailWatcher;
150
- if (previousSkipCanvasHost === undefined)
177
+ }
178
+ if (previousSkipCanvasHost === undefined) {
179
+ delete process.env.POOLBOT_SKIP_CANVAS_HOST;
151
180
  delete process.env.CLAWDBOT_SKIP_CANVAS_HOST;
152
- else
181
+ }
182
+ else {
183
+ process.env.POOLBOT_SKIP_CANVAS_HOST = previousSkipCanvasHost;
153
184
  process.env.CLAWDBOT_SKIP_CANVAS_HOST = previousSkipCanvasHost;
154
- if (previousBundledPluginsDir === undefined)
185
+ }
186
+ if (previousBundledPluginsDir === undefined) {
187
+ delete process.env.POOLBOT_BUNDLED_PLUGINS_DIR;
155
188
  delete process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR;
156
- else
189
+ }
190
+ else {
191
+ process.env.POOLBOT_BUNDLED_PLUGINS_DIR = previousBundledPluginsDir;
157
192
  process.env.CLAWDBOT_BUNDLED_PLUGINS_DIR = previousBundledPluginsDir;
193
+ }
158
194
  }
159
195
  if (options.restoreEnv && tempHome) {
160
196
  await fs.rm(tempHome, {
@@ -238,7 +274,7 @@ export async function startGatewayServer(port, opts) {
238
274
  }
239
275
  export async function startServerWithClient(token, opts) {
240
276
  let port = await getFreePort();
241
- const prev = process.env.CLAWDBOT_GATEWAY_TOKEN;
277
+ const prev = process.env.POOLBOT_GATEWAY_TOKEN ?? process.env.CLAWDBOT_GATEWAY_TOKEN;
242
278
  if (typeof token === "string") {
243
279
  testState.gatewayAuth = { mode: "token", token };
244
280
  }
@@ -247,9 +283,11 @@ export async function startServerWithClient(token, opts) {
247
283
  ? testState.gatewayAuth.token
248
284
  : undefined);
249
285
  if (fallbackToken === undefined) {
286
+ delete process.env.POOLBOT_GATEWAY_TOKEN;
250
287
  delete process.env.CLAWDBOT_GATEWAY_TOKEN;
251
288
  }
252
289
  else {
290
+ process.env.POOLBOT_GATEWAY_TOKEN = fallbackToken;
253
291
  process.env.CLAWDBOT_GATEWAY_TOKEN = fallbackToken;
254
292
  }
255
293
  let server = null;
@@ -309,12 +347,12 @@ export async function connectReq(ws, opts) {
309
347
  ? undefined
310
348
  : typeof testState.gatewayAuth?.token === "string"
311
349
  ? (testState.gatewayAuth.token ?? undefined)
312
- : process.env.CLAWDBOT_GATEWAY_TOKEN;
350
+ : (process.env.POOLBOT_GATEWAY_TOKEN ?? process.env.CLAWDBOT_GATEWAY_TOKEN);
313
351
  const defaultPassword = opts?.skipDefaultAuth === true
314
352
  ? undefined
315
353
  : typeof testState.gatewayAuth?.password === "string"
316
354
  ? (testState.gatewayAuth.password ?? undefined)
317
- : process.env.CLAWDBOT_GATEWAY_PASSWORD;
355
+ : (process.env.POOLBOT_GATEWAY_PASSWORD ?? process.env.CLAWDBOT_GATEWAY_PASSWORD);
318
356
  const token = opts?.token ?? defaultToken;
319
357
  const password = opts?.password ?? defaultPassword;
320
358
  const requestedScopes = Array.isArray(opts?.scopes) ? opts?.scopes : [];
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  export function resolveBundledHooksDir() {
5
- const override = process.env.CLAWDBOT_BUNDLED_HOOKS_DIR?.trim();
5
+ const override = process.env.POOLBOT_BUNDLED_HOOKS_DIR?.trim() || process.env.CLAWDBOT_BUNDLED_HOOKS_DIR?.trim();
6
6
  if (override)
7
7
  return override;
8
8
  // bun --compile: ship a sibling `hooks/bundled/` next to the executable.
@@ -78,7 +78,7 @@ function spawnGogServe(cfg) {
78
78
  return;
79
79
  if (addressInUse) {
80
80
  log.warn("gog serve failed to bind (address already in use); stopping restarts. " +
81
- "Another watcher is likely running. Set CLAWDBOT_SKIP_GMAIL_WATCHER=1 or stop the other process.");
81
+ "Another watcher is likely running. Set POOLBOT_SKIP_GMAIL_WATCHER=1 or stop the other process.");
82
82
  watcherProcess = null;
83
83
  return;
84
84
  }
@@ -6,7 +6,7 @@ import { formatBonjourError } from "./bonjour-errors.js";
6
6
  import { isTruthyEnvValue } from "./env.js";
7
7
  import { registerUnhandledRejectionHandler } from "./unhandled-rejections.js";
8
8
  function isDisabledByEnv() {
9
- if (isTruthyEnvValue(process.env.CLAWDBOT_DISABLE_BONJOUR))
9
+ if (isTruthyEnvValue(process.env.POOLBOT_DISABLE_BONJOUR ?? process.env.CLAWDBOT_DISABLE_BONJOUR))
10
10
  return true;
11
11
  if (process.env.NODE_ENV === "test")
12
12
  return true;
@@ -1,4 +1,5 @@
1
- const DIAGNOSTICS_ENV = "CLAWDBOT_DIAGNOSTICS";
1
+ const DIAGNOSTICS_ENV = "POOLBOT_DIAGNOSTICS";
2
+ const DIAGNOSTICS_ENV_LEGACY = "CLAWDBOT_DIAGNOSTICS";
2
3
  function normalizeFlag(value) {
3
4
  return value.trim().toLowerCase();
4
5
  }
@@ -32,7 +33,7 @@ function uniqueFlags(flags) {
32
33
  }
33
34
  export function resolveDiagnosticFlags(cfg, env = process.env) {
34
35
  const configFlags = Array.isArray(cfg?.diagnostics?.flags) ? cfg?.diagnostics?.flags : [];
35
- const envFlags = parseEnvFlags(env[DIAGNOSTICS_ENV]);
36
+ const envFlags = parseEnvFlags(env[DIAGNOSTICS_ENV] ?? env[DIAGNOSTICS_ENV_LEGACY]);
36
37
  return uniqueFlags([...configFlags, ...envFlags]);
37
38
  }
38
39
  export function matchesDiagnosticFlag(flag, enabledFlags) {
@@ -6,7 +6,7 @@ export function loadDotEnv(opts) {
6
6
  const quiet = opts?.quiet ?? true;
7
7
  // Load from process CWD first (dotenv default).
8
8
  dotenv.config({ quiet });
9
- // Then load global fallback: ~/.poolbot/.env (or CLAWDBOT_STATE_DIR/.env),
9
+ // Then load global fallback: ~/.poolbot/.env (or POOLBOT_STATE_DIR/.env),
10
10
  // without overriding any env vars already present.
11
11
  const globalEnvPath = path.join(resolveConfigDir(process.env), ".env");
12
12
  if (!fs.existsSync(globalEnvPath))
@@ -126,7 +126,7 @@ function resolveGatewayLockPath(env) {
126
126
  export async function acquireGatewayLock(opts = {}) {
127
127
  const env = opts.env ?? process.env;
128
128
  const allowInTests = opts.allowInTests === true;
129
- if (env.CLAWDBOT_ALLOW_MULTI_GATEWAY === "1" ||
129
+ if ((env.POOLBOT_ALLOW_MULTI_GATEWAY ?? env.CLAWDBOT_ALLOW_MULTI_GATEWAY) === "1" ||
130
130
  (!allowInTests && (env.VITEST || env.NODE_ENV === "test"))) {
131
131
  return null;
132
132
  }
@@ -9,7 +9,7 @@ export function resolveEffectiveHomeDir(env = process.env, homedir = os.homedir)
9
9
  return raw ? path.resolve(raw) : undefined;
10
10
  }
11
11
  function resolveRawHomeDir(env, homedir) {
12
- const explicitHome = normalize(env.CLAWDBOT_HOME);
12
+ const explicitHome = normalize(env.POOLBOT_HOME) ?? normalize(env.CLAWDBOT_HOME);
13
13
  if (explicitHome) {
14
14
  if (explicitHome === "~" || explicitHome.startsWith("~/") || explicitHome.startsWith("~\\")) {
15
15
  const fallbackHome = normalize(env.HOME) ?? normalize(env.USERPROFILE) ?? normalizeSafe(homedir);
@@ -80,8 +80,9 @@ function candidateBinDirs(opts) {
80
80
  * under launchd/minimal environments (and inside the macOS app bundle).
81
81
  */
82
82
  export function ensurePoolbotCliOnPath(opts = {}) {
83
- if (isTruthyEnvValue(process.env.CLAWDBOT_PATH_BOOTSTRAPPED))
83
+ if (isTruthyEnvValue(process.env.POOLBOT_PATH_BOOTSTRAPPED ?? process.env.CLAWDBOT_PATH_BOOTSTRAPPED))
84
84
  return;
85
+ process.env.POOLBOT_PATH_BOOTSTRAPPED = "1";
85
86
  process.env.CLAWDBOT_PATH_BOOTSTRAPPED = "1";
86
87
  const existing = opts.pathEnv ?? process.env.PATH ?? "";
87
88
  const prepend = candidateBinDirs(opts);
@@ -78,7 +78,7 @@ export function triggerPoolbotRestart() {
78
78
  const tried = [];
79
79
  if (process.platform !== "darwin") {
80
80
  if (process.platform === "linux") {
81
- const unit = normalizeSystemdUnit(process.env.CLAWDBOT_SYSTEMD_UNIT, process.env.CLAWDBOT_PROFILE);
81
+ const unit = normalizeSystemdUnit(process.env.POOLBOT_SYSTEMD_UNIT ?? process.env.CLAWDBOT_SYSTEMD_UNIT, process.env.POOLBOT_PROFILE ?? process.env.CLAWDBOT_PROFILE);
82
82
  const userArgs = ["--user", "restart", unit];
83
83
  tried.push(`systemctl ${userArgs.join(" ")}`);
84
84
  const userRestart = spawnSync("systemctl", userArgs, {
@@ -109,8 +109,9 @@ export function triggerPoolbotRestart() {
109
109
  detail: "unsupported platform restart",
110
110
  };
111
111
  }
112
- const label = process.env.CLAWDBOT_LAUNCHD_LABEL ||
113
- resolveGatewayLaunchAgentLabel(process.env.CLAWDBOT_PROFILE);
112
+ const label = process.env.POOLBOT_LAUNCHD_LABEL ||
113
+ process.env.CLAWDBOT_LAUNCHD_LABEL ||
114
+ resolveGatewayLaunchAgentLabel(process.env.POOLBOT_PROFILE ?? process.env.CLAWDBOT_PROFILE);
114
115
  const uid = typeof process.getuid === "function" ? process.getuid() : undefined;
115
116
  const target = uid !== undefined ? `gui/${uid}/${label}` : label;
116
117
  const args = ["kickstart", "-k", target];
@@ -72,13 +72,14 @@ export function loadShellEnvFallback(opts) {
72
72
  return { ok: true, applied };
73
73
  }
74
74
  export function shouldEnableShellEnvFallback(env) {
75
- return isTruthyEnvValue(env.CLAWDBOT_LOAD_SHELL_ENV);
75
+ return (isTruthyEnvValue(env.POOLBOT_LOAD_SHELL_ENV) || isTruthyEnvValue(env.CLAWDBOT_LOAD_SHELL_ENV));
76
76
  }
77
77
  export function shouldDeferShellEnvFallback(env) {
78
- return isTruthyEnvValue(env.CLAWDBOT_DEFER_SHELL_ENV_FALLBACK);
78
+ return (isTruthyEnvValue(env.POOLBOT_DEFER_SHELL_ENV_FALLBACK) ||
79
+ isTruthyEnvValue(env.CLAWDBOT_DEFER_SHELL_ENV_FALLBACK));
79
80
  }
80
81
  export function resolveShellEnvFallbackTimeoutMs(env) {
81
- const raw = env.CLAWDBOT_SHELL_ENV_TIMEOUT_MS?.trim();
82
+ const raw = env.POOLBOT_SHELL_ENV_TIMEOUT_MS?.trim() || env.CLAWDBOT_SHELL_ENV_TIMEOUT_MS?.trim();
82
83
  if (!raw)
83
84
  return DEFAULT_TIMEOUT_MS;
84
85
  const parsed = Number.parseInt(raw, 10);
@@ -324,7 +324,7 @@ export async function autoMigrateLegacyStateDir(params) {
324
324
  }
325
325
  autoMigrateStateDirChecked = true;
326
326
  const env = params.env ?? process.env;
327
- if (env.CLAWDBOT_STATE_DIR?.trim()) {
327
+ if (env.POOLBOT_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim()) {
328
328
  return { migrated: false, skipped: true, changes: [], warnings: [] };
329
329
  }
330
330
  const homedir = params.homedir ?? os.homedir;
@@ -439,7 +439,7 @@ export async function autoMigrateLegacyStateDir(params) {
439
439
  }
440
440
  catch (rollbackErr) {
441
441
  warnings.push(`State dir moved but failed to link legacy path (${legacyDir ?? "unknown"} → ${targetDir}): ${String(fallbackErr)}`);
442
- warnings.push(`Rollback failed; set CLAWDBOT_STATE_DIR=${targetDir} to avoid split state: ${String(rollbackErr)}`);
442
+ warnings.push(`Rollback failed; set POOLBOT_STATE_DIR=${targetDir} to avoid split state: ${String(rollbackErr)}`);
443
443
  changes.push(`State dir: ${legacyDir ?? "unknown"} → ${targetDir}`);
444
444
  }
445
445
  }
@@ -726,7 +726,9 @@ export async function autoMigrateLegacyState(params) {
726
726
  homedir: params.homedir,
727
727
  log: params.log,
728
728
  });
729
- if (env.CLAWDBOT_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim()) {
729
+ if (env.POOLBOT_AGENT_DIR?.trim() ||
730
+ env.CLAWDBOT_AGENT_DIR?.trim() ||
731
+ env.PI_CODING_AGENT_DIR?.trim()) {
730
732
  return {
731
733
  migrated: stateDirResult.migrated,
732
734
  skipped: true,
@@ -33,7 +33,10 @@ function resolvePrimaryIPv4() {
33
33
  function initSelfPresence() {
34
34
  const host = os.hostname();
35
35
  const ip = resolvePrimaryIPv4() ?? undefined;
36
- const version = process.env.CLAWDBOT_VERSION ?? process.env.npm_package_version ?? "unknown";
36
+ const version = process.env.POOLBOT_VERSION ??
37
+ process.env.CLAWDBOT_VERSION ??
38
+ process.env.npm_package_version ??
39
+ "unknown";
37
40
  const modelIdentifier = (() => {
38
41
  const p = os.platform();
39
42
  if (p === "darwin") {
@@ -560,7 +560,10 @@ export async function runGatewayUpdate(opts = {}) {
560
560
  };
561
561
  }
562
562
  const doctorArgv = [process.execPath, doctorEntry, "doctor", "--non-interactive"];
563
- const doctorStep = await runStep(step("poolbot doctor", doctorArgv, gitRoot, { CLAWDBOT_UPDATE_IN_PROGRESS: "1" }));
563
+ const doctorStep = await runStep(step("poolbot doctor", doctorArgv, gitRoot, {
564
+ POOLBOT_UPDATE_IN_PROGRESS: "1",
565
+ CLAWDBOT_UPDATE_IN_PROGRESS: "1",
566
+ }));
564
567
  steps.push(doctorStep);
565
568
  const uiIndexHealth = await resolveControlUiDistIndexHealth({ root: gitRoot });
566
569
  if (!uiIndexHealth.exists) {
@@ -11,7 +11,7 @@ export function normalizeWideAreaDomain(raw) {
11
11
  }
12
12
  export function resolveWideAreaDiscoveryDomain(params) {
13
13
  const env = params?.env ?? process.env;
14
- const candidate = params?.configDomain ?? env.CLAWDBOT_WIDE_AREA_DOMAIN ?? null;
14
+ const candidate = params?.configDomain ?? env.POOLBOT_WIDE_AREA_DOMAIN ?? env.CLAWDBOT_WIDE_AREA_DOMAIN ?? null;
15
15
  return normalizeWideAreaDomain(candidate);
16
16
  }
17
17
  function zoneFilenameForDomain(domain) {