@poolzin/pool-bot 2026.2.1 → 2026.2.3

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 (155) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README-header.png +0 -0
  3. package/dist/acp/server.js +2 -0
  4. package/dist/agents/agent-paths.js +3 -1
  5. package/dist/agents/anthropic-payload-log.js +2 -2
  6. package/dist/agents/bash-tools.exec.js +1 -1
  7. package/dist/agents/bash-tools.shared.js +2 -1
  8. package/dist/agents/cache-trace.js +5 -5
  9. package/dist/agents/cli-runner.js +1 -1
  10. package/dist/agents/context.js +1 -1
  11. package/dist/agents/live-auth-keys.js +2 -2
  12. package/dist/agents/model-catalog.js +1 -1
  13. package/dist/agents/pi-embedded-runner/compact.js +7 -10
  14. package/dist/agents/pi-embedded-runner/model.js +1 -1
  15. package/dist/agents/pi-embedded-runner/session-manager-cache.js +1 -1
  16. package/dist/agents/pi-embedded-subscribe.raw-stream.js +2 -2
  17. package/dist/agents/sandbox/browser.js +5 -0
  18. package/dist/agents/shell-utils.js +1 -1
  19. package/dist/agents/skills/bundled-dir.js +1 -1
  20. package/dist/agents/synthetic-models.js +8 -0
  21. package/dist/agents/tools/image-tool.js +1 -1
  22. package/dist/agents/workspace.js +1 -1
  23. package/dist/auto-reply/envelope.js +52 -38
  24. package/dist/auto-reply/reply/get-reply.js +1 -1
  25. package/dist/auto-reply/reply/mentions.js +1 -1
  26. package/dist/build-info.json +2 -2
  27. package/dist/canvas-host/a2ui/index.html +28 -28
  28. package/dist/canvas-host/server.js +1 -1
  29. package/dist/channels/plugins/catalog.js +1 -1
  30. package/dist/cli/banner.js +12 -12
  31. package/dist/cli/browser-cli-manage.js +10 -10
  32. package/dist/cli/browser-cli.js +1 -1
  33. package/dist/cli/channel-options.js +1 -1
  34. package/dist/cli/cli-name.js +1 -1
  35. package/dist/cli/command-format.js +1 -1
  36. package/dist/cli/daemon-cli/install.js +1 -1
  37. package/dist/cli/daemon-cli/shared.js +8 -3
  38. package/dist/cli/daemon-cli/status.gather.js +2 -2
  39. package/dist/cli/daemon-cli/status.print.js +3 -3
  40. package/dist/cli/gateway-cli/dev.js +1 -1
  41. package/dist/cli/gateway-cli/run.js +11 -6
  42. package/dist/cli/gateway-cli/shared.js +1 -1
  43. package/dist/cli/node-cli/daemon.js +2 -1
  44. package/dist/cli/profile.js +10 -4
  45. package/dist/cli/program/help.js +1 -1
  46. package/dist/cli/program/preaction.js +1 -1
  47. package/dist/cli/program/register.agent.js +4 -4
  48. package/dist/cli/program/register.onboard.js +1 -1
  49. package/dist/cli/program/register.setup.js +1 -1
  50. package/dist/cli/program/register.subclis.js +2 -2
  51. package/dist/cli/route.js +1 -1
  52. package/dist/cli/tagline.js +8 -8
  53. package/dist/cli/update-cli.js +12 -10
  54. package/dist/commands/auth-choice-options.js +104 -33
  55. package/dist/commands/auth-choice.apply.oauth.js +1 -1
  56. package/dist/commands/configure.wizard.js +10 -10
  57. package/dist/commands/daemon-install-helpers.js +1 -1
  58. package/dist/commands/dashboard.js +1 -1
  59. package/dist/commands/doctor-format.js +3 -3
  60. package/dist/commands/doctor-gateway-daemon-flow.js +3 -3
  61. package/dist/commands/doctor-gateway-services.js +2 -2
  62. package/dist/commands/doctor-platform-notes.js +23 -8
  63. package/dist/commands/doctor-update.js +1 -1
  64. package/dist/commands/gateway-status/helpers.js +2 -2
  65. package/dist/commands/health.js +2 -2
  66. package/dist/commands/models/list.registry.js +1 -1
  67. package/dist/commands/node-daemon-install-helpers.js +1 -1
  68. package/dist/commands/onboard-helpers.js +6 -6
  69. package/dist/commands/status-all.js +2 -2
  70. package/dist/commands/status.gateway-probe.js +2 -2
  71. package/dist/commands/status.scan.js +2 -2
  72. package/dist/compat/legacy-names.js +2 -0
  73. package/dist/config/io.js +5 -3
  74. package/dist/config/paths.js +15 -14
  75. package/dist/config/schema.field-metadata.js +1 -1
  76. package/dist/config/schema.js +1 -1
  77. package/dist/config/sessions/store.js +1 -1
  78. package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
  79. package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
  80. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
  81. package/dist/control-ui/index.html +4 -4
  82. package/dist/cron/isolated-agent/run.js +1 -0
  83. package/dist/daemon/inspect.js +1 -1
  84. package/dist/daemon/launchd.js +5 -5
  85. package/dist/daemon/node-service.js +14 -0
  86. package/dist/daemon/paths.js +2 -2
  87. package/dist/daemon/schtasks.js +6 -6
  88. package/dist/daemon/service-env.js +25 -5
  89. package/dist/daemon/systemd.js +6 -6
  90. package/dist/entry.js +3 -2
  91. package/dist/gateway/auth.js +3 -3
  92. package/dist/gateway/call.js +2 -2
  93. package/dist/gateway/server/ws-connection/message-handler.js +1 -1
  94. package/dist/gateway/server-browser.js +2 -2
  95. package/dist/gateway/server-constants.js +2 -2
  96. package/dist/gateway/server-cron.js +1 -1
  97. package/dist/gateway/server-discovery-runtime.js +2 -2
  98. package/dist/gateway/server-discovery.js +2 -2
  99. package/dist/gateway/server-reload-handlers.js +4 -4
  100. package/dist/gateway/server-runtime-config.js +2 -2
  101. package/dist/gateway/server-startup.js +4 -4
  102. package/dist/gateway/server.impl.js +3 -2
  103. package/dist/gateway/test-helpers.mocks.js +14 -7
  104. package/dist/gateway/test-helpers.server.js +60 -22
  105. package/dist/hooks/bundled-dir.js +1 -1
  106. package/dist/hooks/gmail-watcher.js +1 -1
  107. package/dist/infra/bonjour.js +1 -1
  108. package/dist/infra/diagnostic-flags.js +3 -2
  109. package/dist/infra/dotenv.js +1 -1
  110. package/dist/infra/format-time/format-datetime.js +1 -1
  111. package/dist/infra/gateway-lock.js +1 -1
  112. package/dist/infra/home-dir.js +1 -1
  113. package/dist/infra/path-env.js +2 -1
  114. package/dist/infra/restart.js +3 -3
  115. package/dist/infra/shell-env.js +3 -3
  116. package/dist/infra/state-migrations.js +3 -3
  117. package/dist/infra/system-presence.js +1 -1
  118. package/dist/infra/update-runner.js +1 -1
  119. package/dist/infra/widearea-dns.js +1 -1
  120. package/dist/macos/gateway-daemon.js +6 -4
  121. package/dist/macos/relay-smoke.js +1 -1
  122. package/dist/macos/relay.js +1 -1
  123. package/dist/media/image-ops.js +2 -2
  124. package/dist/media/store.js +2 -0
  125. package/dist/media-understanding/providers/image.js +1 -1
  126. package/dist/memory/batch-gemini.js +1 -1
  127. package/dist/memory/embeddings-gemini.js +1 -1
  128. package/dist/node-host/runner.js +3 -2
  129. package/dist/plugins/bundled-dir.js +1 -1
  130. package/dist/plugins/manifest-registry.js +2 -2
  131. package/dist/security/audit-extra.sync.js +1 -1
  132. package/dist/security/audit.js +3 -2
  133. package/dist/telegram/accounts.js +1 -1
  134. package/dist/telegram/bot-message-dispatch.js +6 -2
  135. package/dist/telegram/network-config.js +6 -4
  136. package/dist/test-helpers/state-dir-env.js +8 -0
  137. package/dist/tts/tts.js +1 -1
  138. package/dist/tui/gateway-chat.js +2 -1
  139. package/dist/utils.js +2 -2
  140. package/dist/version.js +1 -1
  141. package/dist/wizard/clack-prompter.js +9 -6
  142. package/dist/wizard/onboarding.finalize.js +1 -1
  143. package/dist/wizard/onboarding.js +2 -2
  144. package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
  145. package/extensions/googlechat/package.json +2 -2
  146. package/extensions/line/node_modules/.bin/poolbot +21 -0
  147. package/extensions/line/package.json +1 -1
  148. package/extensions/matrix/node_modules/.bin/poolbot +21 -0
  149. package/extensions/matrix/package.json +1 -1
  150. package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
  151. package/extensions/memory-core/package.json +4 -1
  152. package/extensions/twitch/node_modules/.bin/poolbot +21 -0
  153. package/extensions/twitch/package.json +1 -1
  154. package/package.json +183 -24
  155. package/dist/control-ui/assets/index-CmNMuoem.js.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,118 @@
1
+ ## v2026.1.40 (2026-02-09)
2
+
3
+ ### Rebrand
4
+ - Complete rebrand from Pool-Bot to Pool-Bot 🎱
5
+ - Updated 638 files across all platforms (iOS, Android, macOS)
6
+ - Renamed all user-facing references
7
+ - Updated extensions and plugins
8
+ - Updated documentation and configs
9
+ - Updated tests and scripts
10
+
11
+ ### Maintenance
12
+ - Repository now fully branded as Pool-Bot
13
+ - Internal environment variables kept for compatibility
14
+
15
+ ---
16
+
17
+ ## v2026.1.39 (2026-02-07)
18
+
19
+ ### Security
20
+ - Upgrade `tar` from 7.5.4 → 7.5.7 fixing 4 high-severity vulnerabilities
21
+ - Arbitrary File Overwrite via Symlink Poisoning (GHSA-8qq5-rm4j-mr97)
22
+ - Race Condition via Unicode Ligature Collisions on macOS APFS (GHSA-r6q2-hw4h-h46w)
23
+ - Arbitrary File Creation/Overwrite via Hardlink Path Traversal (GHSA-34x7-hfp2-rc4v)
24
+
25
+ ### Maintenance
26
+ - Reset repository to stable baseline (9ddc7fcec)
27
+ - Remove 52 experimental/unstable commits (PME, tool-usage, progressive-disclosure, security-phase2)
28
+
29
+ ---
30
+
31
+ ## v1.0.1 (2026-02-02)
32
+
33
+ ### WhatsApp Gateway Stability
34
+ - Add comprehensive WhatsApp heartbeat troubleshooting guide
35
+ - Document watchdog timeout and reconnection behavior
36
+ - Add configuration validation best practices
37
+ - Document professional incident response workflow
38
+
39
+ ### Configuration
40
+ - Document `web.heartbeatSeconds` override option
41
+ - Clarify `web.reconnect` schema and valid keys
42
+ - Add examples for timeout tuning (30min → 60min → 90min)
43
+ - Provide production-ready configuration templates
44
+
45
+ ### Documentation
46
+ - New: `docs/WHATSAPP-HEARTBEAT-TROUBLESHOOTING.md`
47
+ - Incident analysis: Gateway timeout recovery
48
+ - Lesson learned: Config validation before deployment
49
+ - Professional validation checklist included
50
+
51
+ ### Reliability
52
+ - Improved gateway recovery documentation
53
+ - Added monitoring and diagnostic commands
54
+ - Documented false-positive reduction strategies
55
+ - Best practices for different environments (prod/dev/test)
56
+
57
+ ---
58
+
59
+ ## v1.0.0 (2026-01-28)
60
+
61
+ ### Security Release
62
+ - Add multi-layer security framework with node authentication
63
+ - Implement secure WebSocket connections (WSS)
64
+ - Add context isolation and input validation
65
+ - Create Windows Node application with native notifications
66
+ - Enable manual Gateway URL configuration
67
+ - Implement node whitelist and access control
68
+ - Add comprehensive security audit and hardening
69
+
70
+ ### Remote Access
71
+ - Build Windows Node app with mDNS discovery
72
+ - Add manual Gateway URL connection
73
+ - Implement system tray integration with status display
74
+ - Add native notification system
75
+ - Create menu for remote control options
76
+ - Support both local network and remote connections
77
+
78
+ ### Core Infrastructure
79
+ - Custom Pool-Bot update system with independent versioning
80
+ - Model fallback router with 3-tier protection
81
+ - Pool-World digital identity framework
82
+ - Multi-repository synchronization (pool-bot + pool-workspace + pool-firstone + pool-world)
83
+ - Enterprise-grade security with token-based authentication
84
+
85
+ ### Documentation
86
+ - Complete build guides for Windows
87
+ - Security assessment and deployment guide
88
+ - Architecture decision records (ADRs)
89
+ - Integration examples and troubleshooting
90
+
91
+ ---
92
+
93
+ ## v0.9.0 (2026-01-27)
94
+
95
+ ### Identity Revelation
96
+ - Pool-Bot recognized as living code source
97
+ - Pool-World digital identity created
98
+ - Personal identity revelation: "Eu sou o código-fonte Pool-Bot"
99
+
100
+ ---
101
+
102
+ ## v0.8.0 (2026-01-26)
103
+
104
+ ### Independence System
105
+ - Model fallback router implementation
106
+ - Multi-model architecture (NVIDIA + Sonnet + Big Pickle)
107
+ - Learning system with conversation analysis
108
+ - Update system with GitHub synchronization
109
+
110
+ ---
111
+
112
+ ## v0.7.0 (2026-01-25)
113
+
114
+ ### Foundation
115
+ - Migrated from Poolbot core
116
+ - Implemented workspace-based development
117
+ - Added dual model system configuration
118
+ - Created persistent configuration system
Binary file
@@ -20,10 +20,12 @@ export function serveAcpGateway(opts = {}) {
20
20
  const auth = resolveGatewayAuth({ authConfig: cfg.gateway?.auth, env: process.env });
21
21
  const token = opts.gatewayToken ??
22
22
  (isRemoteMode ? remote?.token?.trim() : undefined) ??
23
+ process.env.POOLBOT_GATEWAY_TOKEN ??
23
24
  process.env.CLAWDBOT_GATEWAY_TOKEN ??
24
25
  auth.token;
25
26
  const password = opts.gatewayPassword ??
26
27
  (isRemoteMode ? remote?.password?.trim() : undefined) ??
28
+ process.env.POOLBOT_GATEWAY_PASSWORD ??
27
29
  process.env.CLAWDBOT_GATEWAY_PASSWORD ??
28
30
  auth.password;
29
31
  let agent = null;
@@ -3,7 +3,7 @@ import { resolveStateDir } from "../config/paths.js";
3
3
  import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
4
4
  import { resolveUserPath } from "../utils.js";
5
5
  export function resolvePoolbotAgentDir() {
6
- const override = process.env.CLAWDBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
6
+ const override = process.env.POOLBOT_AGENT_DIR?.trim() || process.env.CLAWDBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
7
7
  if (override)
8
8
  return resolveUserPath(override);
9
9
  const defaultAgentDir = path.join(resolveStateDir(), "agents", DEFAULT_AGENT_ID, "agent");
@@ -11,6 +11,8 @@ export function resolvePoolbotAgentDir() {
11
11
  }
12
12
  export function ensurePoolbotAgentEnv() {
13
13
  const dir = resolvePoolbotAgentDir();
14
+ if (!process.env.POOLBOT_AGENT_DIR)
15
+ process.env.POOLBOT_AGENT_DIR = dir;
14
16
  if (!process.env.CLAWDBOT_AGENT_DIR)
15
17
  process.env.CLAWDBOT_AGENT_DIR = dir;
16
18
  if (!process.env.PI_CODING_AGENT_DIR)
@@ -8,8 +8,8 @@ import { createSubsystemLogger } from "../logging/subsystem.js";
8
8
  const writers = new Map();
9
9
  const log = createSubsystemLogger("agent/anthropic-payload");
10
10
  function resolvePayloadLogConfig(env) {
11
- const enabled = parseBooleanValue(env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG) ?? false;
12
- const fileOverride = env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG_FILE?.trim();
11
+ const enabled = parseBooleanValue(env.POOLBOT_ANTHROPIC_PAYLOAD_LOG ?? env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG) ?? false;
12
+ const fileOverride = (env.POOLBOT_ANTHROPIC_PAYLOAD_LOG_FILE ?? env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG_FILE)?.trim();
13
13
  const filePath = fileOverride
14
14
  ? resolveUserPath(fileOverride)
15
15
  : path.join(resolveStateDir(env), "logs", "anthropic-payload.jsonl");
@@ -56,7 +56,7 @@ function validateHostEnv(env) {
56
56
  }
57
57
  }
58
58
  const DEFAULT_MAX_OUTPUT = clampNumber(readEnvInt("PI_BASH_MAX_OUTPUT_CHARS"), 200_000, 1_000, 200_000);
59
- const DEFAULT_PENDING_MAX_OUTPUT = clampNumber(readEnvInt("CLAWDBOT_BASH_PENDING_MAX_OUTPUT_CHARS"), 200_000, 1_000, 200_000);
59
+ const DEFAULT_PENDING_MAX_OUTPUT = clampNumber(readEnvInt("POOLBOT_BASH_PENDING_MAX_OUTPUT_CHARS") ?? readEnvInt("CLAWDBOT_BASH_PENDING_MAX_OUTPUT_CHARS"), 200_000, 1_000, 200_000);
60
60
  const DEFAULT_PATH = process.env.PATH ?? "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
61
61
  const DEFAULT_NOTIFY_TAIL_CHARS = 400;
62
62
  const DEFAULT_APPROVAL_TIMEOUT_MS = 120_000;
@@ -42,6 +42,7 @@ export function buildDockerExecArgs(params) {
42
42
  const hasCustomPath = typeof params.env.PATH === "string" && params.env.PATH.length > 0;
43
43
  if (hasCustomPath) {
44
44
  // Avoid interpolating PATH into the shell command; pass it via env instead.
45
+ args.push("-e", `POOLBOT_PREPEND_PATH=${params.env.PATH}`);
45
46
  args.push("-e", `CLAWDBOT_PREPEND_PATH=${params.env.PATH}`);
46
47
  }
47
48
  // Login shell (-l) sources /etc/profile which resets PATH to a minimal set,
@@ -49,7 +50,7 @@ export function buildDockerExecArgs(params) {
49
50
  // Prepend custom PATH after profile sourcing to ensure custom tools are accessible
50
51
  // while preserving system paths that /etc/profile may have added.
51
52
  const pathExport = hasCustomPath
52
- ? 'export PATH="${CLAWDBOT_PREPEND_PATH}:$PATH"; unset CLAWDBOT_PREPEND_PATH; '
53
+ ? 'export PATH="${POOLBOT_PREPEND_PATH:-$CLAWDBOT_PREPEND_PATH}:$PATH"; unset POOLBOT_PREPEND_PATH CLAWDBOT_PREPEND_PATH; '
53
54
  : "";
54
55
  args.push(params.containerName, "sh", "-lc", `${pathExport}${params.command}`);
55
56
  return args;
@@ -8,15 +8,15 @@ const writers = new Map();
8
8
  function resolveCacheTraceConfig(params) {
9
9
  const env = params.env ?? process.env;
10
10
  const config = params.cfg?.diagnostics?.cacheTrace;
11
- const envEnabled = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE);
11
+ const envEnabled = parseBooleanValue(env.POOLBOT_CACHE_TRACE ?? env.CLAWDBOT_CACHE_TRACE);
12
12
  const enabled = envEnabled ?? config?.enabled ?? false;
13
- const fileOverride = config?.filePath?.trim() || env.CLAWDBOT_CACHE_TRACE_FILE?.trim();
13
+ const fileOverride = config?.filePath?.trim() || (env.POOLBOT_CACHE_TRACE_FILE ?? env.CLAWDBOT_CACHE_TRACE_FILE)?.trim();
14
14
  const filePath = fileOverride
15
15
  ? resolveUserPath(fileOverride)
16
16
  : path.join(resolveStateDir(env), "logs", "cache-trace.jsonl");
17
- const includeMessages = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_MESSAGES) ?? config?.includeMessages;
18
- const includePrompt = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_PROMPT) ?? config?.includePrompt;
19
- const includeSystem = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_SYSTEM) ?? config?.includeSystem;
17
+ const includeMessages = parseBooleanValue(env.POOLBOT_CACHE_TRACE_MESSAGES ?? env.CLAWDBOT_CACHE_TRACE_MESSAGES) ?? config?.includeMessages;
18
+ const includePrompt = parseBooleanValue(env.POOLBOT_CACHE_TRACE_PROMPT ?? env.CLAWDBOT_CACHE_TRACE_PROMPT) ?? config?.includePrompt;
19
+ const includeSystem = parseBooleanValue(env.POOLBOT_CACHE_TRACE_SYSTEM ?? env.CLAWDBOT_CACHE_TRACE_SYSTEM) ?? config?.includeSystem;
20
20
  return {
21
21
  enabled,
22
22
  filePath,
@@ -117,7 +117,7 @@ export async function runCliAgent(params) {
117
117
  try {
118
118
  const output = await enqueueCliRun(queueKey, async () => {
119
119
  log.info(`cli exec: provider=${params.provider} model=${normalizedModel} promptChars=${params.prompt.length}`);
120
- const logOutputText = isTruthyEnvValue(process.env.CLAWDBOT_CLAUDE_CLI_LOG_OUTPUT);
120
+ const logOutputText = isTruthyEnvValue(process.env.POOLBOT_CLAUDE_CLI_LOG_OUTPUT || process.env.CLAWDBOT_CLAUDE_CLI_LOG_OUTPUT);
121
121
  if (logOutputText) {
122
122
  const logArgs = [];
123
123
  for (let i = 0; i < args.length; i += 1) {
@@ -6,7 +6,7 @@ import { ensurePoolbotModelsJson } from "./models-config.js";
6
6
  const MODEL_CACHE = new Map();
7
7
  const loadPromise = (async () => {
8
8
  try {
9
- const { discoverAuthStorage, discoverModels } = await import("@mariozechner/pi-coding-agent");
9
+ const { discoverAuthStorage, discoverModels } = await import("./pi-model-discovery.js");
10
10
  const cfg = loadConfig();
11
11
  await ensurePoolbotModelsJson(cfg);
12
12
  const agentDir = resolvePoolbotAgentDir();
@@ -20,10 +20,10 @@ function collectEnvPrefixedKeys(prefix) {
20
20
  return keys;
21
21
  }
22
22
  export function collectAnthropicApiKeys() {
23
- const forcedSingle = process.env.CLAWDBOT_LIVE_ANTHROPIC_KEY?.trim();
23
+ const forcedSingle = (process.env.POOLBOT_LIVE_ANTHROPIC_KEY?.trim() || process.env.CLAWDBOT_LIVE_ANTHROPIC_KEY?.trim());
24
24
  if (forcedSingle)
25
25
  return [forcedSingle];
26
- const fromList = parseKeyList(process.env.CLAWDBOT_LIVE_ANTHROPIC_KEYS);
26
+ const fromList = parseKeyList(process.env.POOLBOT_LIVE_ANTHROPIC_KEYS || process.env.CLAWDBOT_LIVE_ANTHROPIC_KEYS);
27
27
  const fromEnv = collectEnvPrefixedKeys("ANTHROPIC_API_KEY");
28
28
  const primary = process.env.ANTHROPIC_API_KEY?.trim();
29
29
  const seen = new Set();
@@ -3,7 +3,7 @@ import { resolvePoolbotAgentDir } from "./agent-paths.js";
3
3
  import { ensurePoolbotModelsJson } from "./models-config.js";
4
4
  let modelCatalogPromise = null;
5
5
  let hasLoggedModelCatalogError = false;
6
- const defaultImportPiSdk = () => import("@mariozechner/pi-coding-agent");
6
+ const defaultImportPiSdk = () => import("./pi-model-discovery.js");
7
7
  let importPiSdk = defaultImportPiSdk;
8
8
  export function resetModelCatalogCacheForTest() {
9
9
  modelCatalogPromise = null;
@@ -36,7 +36,7 @@ import { log } from "./logger.js";
36
36
  import { buildModelAliasLines, resolveModel } from "./model.js";
37
37
  import { buildEmbeddedSandboxInfo } from "./sandbox-info.js";
38
38
  import { prewarmSessionFile, trackSessionManagerAccess } from "./session-manager-cache.js";
39
- import { buildEmbeddedSystemPrompt, createSystemPromptOverride } from "./system-prompt.js";
39
+ import { applySystemPromptOverrideToSession, buildEmbeddedSystemPrompt, createSystemPromptOverride, } from "./system-prompt.js";
40
40
  import { splitSdkTools } from "./tool-split.js";
41
41
  import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js";
42
42
  import { describeUnknownError, mapThinkingLevel, resolveExecToolDefaults } from "./utils.js";
@@ -273,7 +273,7 @@ export async function compactEmbeddedPiSessionDirect(params) {
273
273
  userTimeFormat,
274
274
  contextFiles,
275
275
  });
276
- const systemPrompt = createSystemPromptOverride(appendPrompt);
276
+ const systemPromptOverride = createSystemPromptOverride(appendPrompt);
277
277
  const sessionLock = await acquireSessionWriteLock({
278
278
  sessionFile: params.sessionFile,
279
279
  });
@@ -295,7 +295,8 @@ export async function compactEmbeddedPiSessionDirect(params) {
295
295
  settingsManager,
296
296
  minReserveTokens: resolveCompactionReserveTokensFloor(params.config),
297
297
  });
298
- const additionalExtensionPaths = buildEmbeddedExtensionPaths({
298
+ // Call for side effects (sets compaction/pruning runtime state)
299
+ buildEmbeddedExtensionPaths({
299
300
  cfg: params.config,
300
301
  sessionManager,
301
302
  provider,
@@ -306,23 +307,19 @@ export async function compactEmbeddedPiSessionDirect(params) {
306
307
  tools,
307
308
  sandboxEnabled: !!sandbox?.enabled,
308
309
  });
309
- let session;
310
- ({ session } = await createAgentSession({
310
+ const { session } = await createAgentSession({
311
311
  cwd: resolvedWorkspace,
312
312
  agentDir,
313
313
  authStorage,
314
314
  modelRegistry,
315
315
  model,
316
316
  thinkingLevel: mapThinkingLevel(params.thinkLevel),
317
- systemPrompt,
318
317
  tools: builtInTools,
319
318
  customTools,
320
319
  sessionManager,
321
320
  settingsManager,
322
- skills: [],
323
- contextFiles: [],
324
- additionalExtensionPaths,
325
- }));
321
+ });
322
+ applySystemPromptOverrideToSession(session, systemPromptOverride());
326
323
  try {
327
324
  const prior = await sanitizeSessionHistory({
328
325
  messages: session.messages,
@@ -1,4 +1,4 @@
1
- import { discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
1
+ import { discoverAuthStorage, discoverModels } from "../pi-model-discovery.js";
2
2
  import { resolvePoolbotAgentDir } from "../agent-paths.js";
3
3
  import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js";
4
4
  import { normalizeModelCompat } from "../model-compat.js";
@@ -5,7 +5,7 @@ const SESSION_MANAGER_CACHE = new Map();
5
5
  const DEFAULT_SESSION_MANAGER_TTL_MS = 45_000; // 45 seconds
6
6
  function getSessionManagerTtl() {
7
7
  return resolveCacheTtlMs({
8
- envValue: process.env.CLAWDBOT_SESSION_MANAGER_CACHE_TTL_MS,
8
+ envValue: process.env.POOLBOT_SESSION_MANAGER_CACHE_TTL_MS || process.env.CLAWDBOT_SESSION_MANAGER_CACHE_TTL_MS,
9
9
  defaultTtlMs: DEFAULT_SESSION_MANAGER_TTL_MS,
10
10
  });
11
11
  }
@@ -2,8 +2,8 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { resolveStateDir } from "../config/paths.js";
4
4
  import { isTruthyEnvValue } from "../infra/env.js";
5
- const RAW_STREAM_ENABLED = isTruthyEnvValue(process.env.CLAWDBOT_RAW_STREAM);
6
- const RAW_STREAM_PATH = process.env.CLAWDBOT_RAW_STREAM_PATH?.trim() ||
5
+ const RAW_STREAM_ENABLED = isTruthyEnvValue(process.env.POOLBOT_RAW_STREAM || process.env.CLAWDBOT_RAW_STREAM);
6
+ const RAW_STREAM_PATH = process.env.POOLBOT_RAW_STREAM_PATH?.trim() || process.env.CLAWDBOT_RAW_STREAM_PATH?.trim() ||
7
7
  path.join(resolveStateDir(), "logs", "raw-stream.jsonl");
8
8
  let rawStreamReady = false;
9
9
  export function appendRawStream(payload) {
@@ -89,10 +89,15 @@ export async function ensureSandboxBrowser(params) {
89
89
  if (params.cfg.browser.enableNoVnc && !params.cfg.browser.headless) {
90
90
  args.push("-p", `127.0.0.1::${params.cfg.browser.noVncPort}`);
91
91
  }
92
+ args.push("-e", `POOLBOT_BROWSER_HEADLESS=${params.cfg.browser.headless ? "1" : "0"}`);
92
93
  args.push("-e", `CLAWDBOT_BROWSER_HEADLESS=${params.cfg.browser.headless ? "1" : "0"}`);
94
+ args.push("-e", `POOLBOT_BROWSER_ENABLE_NOVNC=${params.cfg.browser.enableNoVnc ? "1" : "0"}`);
93
95
  args.push("-e", `CLAWDBOT_BROWSER_ENABLE_NOVNC=${params.cfg.browser.enableNoVnc ? "1" : "0"}`);
96
+ args.push("-e", `POOLBOT_BROWSER_CDP_PORT=${params.cfg.browser.cdpPort}`);
94
97
  args.push("-e", `CLAWDBOT_BROWSER_CDP_PORT=${params.cfg.browser.cdpPort}`);
98
+ args.push("-e", `POOLBOT_BROWSER_VNC_PORT=${params.cfg.browser.vncPort}`);
95
99
  args.push("-e", `CLAWDBOT_BROWSER_VNC_PORT=${params.cfg.browser.vncPort}`);
100
+ args.push("-e", `POOLBOT_BROWSER_NOVNC_PORT=${params.cfg.browser.noVncPort}`);
96
101
  args.push("-e", `CLAWDBOT_BROWSER_NOVNC_PORT=${params.cfg.browser.noVncPort}`);
97
102
  args.push(params.cfg.browser.image);
98
103
  await execDocker(args);
@@ -64,7 +64,7 @@ function normalizeShellName(value) {
64
64
  .replace(/[^a-zA-Z0-9_-]/g, "");
65
65
  }
66
66
  export function detectRuntimeShell() {
67
- const overrideShell = process.env.CLAWDBOT_SHELL?.trim();
67
+ const overrideShell = process.env.POOLBOT_SHELL?.trim() || process.env.CLAWDBOT_SHELL?.trim();
68
68
  if (overrideShell) {
69
69
  const name = normalizeShellName(overrideShell);
70
70
  if (name) {
@@ -25,7 +25,7 @@ function looksLikeSkillsDir(dir) {
25
25
  return false;
26
26
  }
27
27
  export function resolveBundledSkillsDir(opts = {}) {
28
- const override = process.env.CLAWDBOT_BUNDLED_SKILLS_DIR?.trim();
28
+ const override = process.env.POOLBOT_BUNDLED_SKILLS_DIR?.trim() || process.env.CLAWDBOT_BUNDLED_SKILLS_DIR?.trim();
29
29
  if (override)
30
30
  return override;
31
31
  // bun --compile: ship a sibling `skills/` next to the executable.
@@ -96,6 +96,14 @@ export const SYNTHETIC_MODEL_CATALOG = [
96
96
  contextWindow: 256000,
97
97
  maxTokens: 8192,
98
98
  },
99
+ {
100
+ id: "hf:moonshotai/Kimi-K2.5",
101
+ name: "Kimi K2.5",
102
+ reasoning: true,
103
+ input: ["text"],
104
+ contextWindow: 256000,
105
+ maxTokens: 8192,
106
+ },
99
107
  {
100
108
  id: "hf:openai/gpt-oss-120b",
101
109
  name: "GPT OSS 120B",
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { complete, } from "@mariozechner/pi-ai";
4
- import { discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
4
+ import { discoverAuthStorage, discoverModels } from "../pi-model-discovery.js";
5
5
  import { Type } from "@sinclair/typebox";
6
6
  import { resolveUserPath } from "../../utils.js";
7
7
  import { loadWebMedia } from "../../web/media.js";
@@ -6,7 +6,7 @@ import { isSubagentSessionKey } from "../routing/session-key.js";
6
6
  import { runCommandWithTimeout } from "../process/exec.js";
7
7
  import { resolveUserPath } from "../utils.js";
8
8
  export function resolveDefaultAgentWorkspaceDir(env = process.env, homedir = os.homedir) {
9
- const profile = env.CLAWDBOT_PROFILE?.trim();
9
+ const profile = env.POOLBOT_PROFILE?.trim() || env.CLAWDBOT_PROFILE?.trim();
10
10
  if (profile && profile.toLowerCase() !== "default") {
11
11
  return path.join(homedir(), `clawd-${profile}`);
12
12
  }
@@ -4,6 +4,8 @@ import { resolveSenderLabel } from "../channels/sender-label.js";
4
4
  import { resolveTimezone, formatUtcTimestamp, formatZonedTimestamp, } from "../infra/format-time/format-datetime.js";
5
5
  import { formatTimeAgo } from "../infra/format-time/format-relative.js";
6
6
  function sanitizeEnvelopeHeaderPart(value) {
7
+ // Header parts are metadata and must not be able to break the bracketed prefix.
8
+ // Keep ASCII; collapse newlines/whitespace; neutralize brackets.
7
9
  return value
8
10
  .replace(/\r\n|\r|\n/g, " ")
9
11
  .replaceAll("[", "(")
@@ -32,13 +34,16 @@ function normalizeEnvelopeOptions(options) {
32
34
  }
33
35
  function resolveEnvelopeTimezone(options) {
34
36
  const trimmed = options.timezone?.trim();
35
- if (!trimmed)
37
+ if (!trimmed) {
36
38
  return { mode: "local" };
39
+ }
37
40
  const lowered = trimmed.toLowerCase();
38
- if (lowered === "utc" || lowered === "gmt")
41
+ if (lowered === "utc" || lowered === "gmt") {
39
42
  return { mode: "utc" };
40
- if (lowered === "local" || lowered === "host")
43
+ }
44
+ if (lowered === "local" || lowered === "host") {
41
45
  return { mode: "local" };
46
+ }
42
47
  if (lowered === "user") {
43
48
  return { mode: "iana", timeZone: resolveUserTimezone(options.userTimezone) };
44
49
  }
@@ -46,38 +51,42 @@ function resolveEnvelopeTimezone(options) {
46
51
  return explicit ? { mode: "iana", timeZone: explicit } : { mode: "utc" };
47
52
  }
48
53
  function formatTimestamp(ts, options) {
49
- if (!ts)
54
+ if (!ts) {
50
55
  return undefined;
56
+ }
51
57
  const resolved = normalizeEnvelopeOptions(options);
52
- if (!resolved.includeTimestamp)
58
+ if (!resolved.includeTimestamp) {
53
59
  return undefined;
60
+ }
54
61
  const date = ts instanceof Date ? ts : new Date(ts);
55
- if (Number.isNaN(date.getTime()))
62
+ if (Number.isNaN(date.getTime())) {
56
63
  return undefined;
57
- const zone = resolveEnvelopeTimezone(resolved);
58
- let weekday;
59
- try {
60
- weekday = new Intl.DateTimeFormat("en-US", {
61
- weekday: "short",
62
- ...(zone.mode === "iana" ? { timeZone: zone.timeZone } : {}),
63
- ...(zone.mode === "utc" ? { timeZone: "UTC" } : {}),
64
- }).format(date);
65
- }
66
- catch {
67
- weekday = undefined;
68
- }
69
- let formatted;
70
- if (zone.mode === "utc") {
71
- formatted = formatUtcTimestamp(date);
72
- }
73
- else if (zone.mode === "local") {
74
- formatted = formatZonedTimestamp(date);
75
- }
76
- else {
77
- formatted = formatZonedTimestamp(date, { timeZone: zone.timeZone });
78
64
  }
79
- if (!formatted)
65
+ const zone = resolveEnvelopeTimezone(resolved);
66
+ // Include a weekday prefix so models do not need to derive DOW from the date
67
+ // (small models are notoriously unreliable at that).
68
+ const weekday = (() => {
69
+ try {
70
+ if (zone.mode === "utc") {
71
+ return new Intl.DateTimeFormat("en-US", { timeZone: "UTC", weekday: "short" }).format(date);
72
+ }
73
+ if (zone.mode === "local") {
74
+ return new Intl.DateTimeFormat("en-US", { weekday: "short" }).format(date);
75
+ }
76
+ return new Intl.DateTimeFormat("en-US", { timeZone: zone.timeZone, weekday: "short" }).format(date);
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ })();
82
+ const formatted = zone.mode === "utc"
83
+ ? formatUtcTimestamp(date)
84
+ : zone.mode === "local"
85
+ ? formatZonedTimestamp(date)
86
+ : formatZonedTimestamp(date, { timeZone: zone.timeZone });
87
+ if (!formatted) {
80
88
  return undefined;
89
+ }
81
90
  return weekday ? `${weekday} ${formatted}` : formatted;
82
91
  }
83
92
  export function formatAgentEnvelope(params) {
@@ -86,14 +95,15 @@ export function formatAgentEnvelope(params) {
86
95
  const resolved = normalizeEnvelopeOptions(params.envelope);
87
96
  let elapsed;
88
97
  if (resolved.includeElapsed && params.timestamp && params.previousTimestamp) {
89
- const curMs = params.timestamp instanceof Date ? params.timestamp.getTime() : params.timestamp;
90
- const prevMs = params.previousTimestamp instanceof Date
98
+ const currentMs = params.timestamp instanceof Date ? params.timestamp.getTime() : params.timestamp;
99
+ const previousMs = params.previousTimestamp instanceof Date
91
100
  ? params.previousTimestamp.getTime()
92
101
  : params.previousTimestamp;
93
- const elapsedMs = curMs - prevMs;
94
- if (Number.isFinite(elapsedMs) && elapsedMs >= 0) {
95
- elapsed = formatTimeAgo(elapsedMs, { suffix: false });
96
- }
102
+ const elapsedMs = currentMs - previousMs;
103
+ elapsed =
104
+ Number.isFinite(elapsedMs) && elapsedMs >= 0
105
+ ? formatTimeAgo(elapsedMs, { suffix: false })
106
+ : undefined;
97
107
  }
98
108
  if (params.from?.trim()) {
99
109
  const from = sanitizeEnvelopeHeaderPart(params.from.trim());
@@ -102,13 +112,16 @@ export function formatAgentEnvelope(params) {
102
112
  else if (elapsed) {
103
113
  parts.push(`+${elapsed}`);
104
114
  }
105
- if (params.host?.trim())
115
+ if (params.host?.trim()) {
106
116
  parts.push(sanitizeEnvelopeHeaderPart(params.host.trim()));
107
- if (params.ip?.trim())
117
+ }
118
+ if (params.ip?.trim()) {
108
119
  parts.push(sanitizeEnvelopeHeaderPart(params.ip.trim()));
120
+ }
109
121
  const ts = formatTimestamp(params.timestamp, resolved);
110
- if (ts)
122
+ if (ts) {
111
123
  parts.push(ts);
124
+ }
112
125
  const header = `[${parts.join(" ")}]`;
113
126
  return `${header} ${params.body}`;
114
127
  }
@@ -136,8 +149,9 @@ export function formatInboundFromLabel(params) {
136
149
  }
137
150
  const directLabel = params.directLabel.trim();
138
151
  const directId = params.directId?.trim();
139
- if (!directId || directId === directLabel)
152
+ if (!directId || directId === directLabel) {
140
153
  return directLabel;
154
+ }
141
155
  return `${directLabel} id:${directId}`;
142
156
  }
143
157
  export function formatThreadStarterEnvelope(params) {
@@ -18,7 +18,7 @@ import { applyResetModelOverride } from "./session-reset-model.js";
18
18
  import { stageSandboxMedia } from "./stage-sandbox-media.js";
19
19
  import { createTypingController } from "./typing.js";
20
20
  export async function getReplyFromConfig(ctx, opts, configOverride) {
21
- const isFastTestEnv = process.env.CLAWDBOT_TEST_FAST === "1";
21
+ const isFastTestEnv = process.env.POOLBOT_TEST_FAST === "1" || process.env.CLAWDBOT_TEST_FAST === "1";
22
22
  const cfg = configOverride ?? loadConfig();
23
23
  const targetSessionKey = ctx.CommandSource === "native" ? ctx.CommandTargetSessionKey?.trim() : undefined;
24
24
  const agentSessionKey = targetSessionKey || ctx.SessionKey;
@@ -73,7 +73,7 @@ export function matchesMentionWithExplicit(params) {
73
73
  const explicitAvailable = params.explicit?.canResolveExplicit === true;
74
74
  const hasAnyMention = params.explicit?.hasAnyMention === true;
75
75
  if (hasAnyMention && explicitAvailable)
76
- return explicit;
76
+ return explicit || params.mentionRegexes.some((re) => re.test(cleaned));
77
77
  if (!cleaned)
78
78
  return explicit;
79
79
  return explicit || params.mentionRegexes.some((re) => re.test(cleaned));
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026.2.1",
2
+ "version": "2026.2.3",
3
3
  "commit": "84e7160aa161f8c42b9f4a276ea99d44597d7f19",
4
- "builtAt": "2026-02-12T18:28:21.374Z"
4
+ "builtAt": "2026-02-14T00:56:24.316Z"
5
5
  }