@poolzin/pool-bot 2026.2.1 → 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.
Files changed (38) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/README-header.png +0 -0
  3. package/dist/agents/context.js +1 -1
  4. package/dist/agents/model-catalog.js +1 -1
  5. package/dist/agents/pi-embedded-runner/compact.js +7 -10
  6. package/dist/agents/pi-embedded-runner/model.js +1 -1
  7. package/dist/agents/tools/image-tool.js +1 -1
  8. package/dist/auto-reply/envelope.js +52 -38
  9. package/dist/auto-reply/reply/mentions.js +1 -1
  10. package/dist/build-info.json +2 -2
  11. package/dist/canvas-host/a2ui/index.html +28 -28
  12. package/dist/commands/auth-choice.apply.oauth.js +1 -1
  13. package/dist/commands/models/list.registry.js +1 -1
  14. package/dist/compat/legacy-names.js +2 -0
  15. package/dist/config/paths.js +1 -1
  16. package/dist/control-ui/assets/{index-CIRDm-Lu.css → index-CSfXd2LO.css} +1 -1
  17. package/dist/control-ui/assets/{index-CmNMuoem.js → index-HRr1grwl.js} +446 -413
  18. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -0
  19. package/dist/control-ui/index.html +4 -4
  20. package/dist/cron/isolated-agent/run.js +1 -0
  21. package/dist/gateway/test-helpers.mocks.js +11 -7
  22. package/dist/infra/format-time/format-datetime.js +1 -1
  23. package/dist/media/store.js +2 -0
  24. package/dist/media-understanding/providers/image.js +1 -1
  25. package/dist/telegram/bot-message-dispatch.js +6 -2
  26. package/dist/wizard/clack-prompter.js +9 -6
  27. package/extensions/googlechat/node_modules/.bin/poolbot +21 -0
  28. package/extensions/googlechat/package.json +2 -2
  29. package/extensions/line/node_modules/.bin/poolbot +21 -0
  30. package/extensions/line/package.json +1 -1
  31. package/extensions/matrix/node_modules/.bin/poolbot +21 -0
  32. package/extensions/matrix/package.json +1 -1
  33. package/extensions/memory-core/node_modules/.bin/poolbot +21 -0
  34. package/extensions/memory-core/package.json +4 -1
  35. package/extensions/twitch/node_modules/.bin/poolbot +21 -0
  36. package/extensions/twitch/package.json +1 -1
  37. package/package.json +183 -24
  38. 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
@@ -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();
@@ -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";
@@ -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";
@@ -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) {
@@ -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.2",
3
3
  "commit": "84e7160aa161f8c42b9f4a276ea99d44597d7f19",
4
- "builtAt": "2026-02-12T18:28:21.374Z"
4
+ "builtAt": "2026-02-12T23:46:09.256Z"
5
5
  }
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Moltbot Canvas</title>
6
+ <title>Poolbot Canvas</title>
7
7
  <script>
8
8
  (() => {
9
9
  try {
@@ -81,7 +81,7 @@
81
81
  backface-visibility: hidden;
82
82
  opacity: 0.45;
83
83
  pointer-events: none;
84
- animation: moltbot-grid-drift 140s ease-in-out infinite alternate;
84
+ animation: poolbot-grid-drift 140s ease-in-out infinite alternate;
85
85
  }
86
86
  :root[data-platform="android"] body::before {
87
87
  opacity: 0.8;
@@ -101,7 +101,7 @@
101
101
  backface-visibility: hidden;
102
102
  transform: translate3d(0, 0, 0);
103
103
  pointer-events: none;
104
- animation: moltbot-glow-drift 110s ease-in-out infinite alternate;
104
+ animation: poolbot-glow-drift 110s ease-in-out infinite alternate;
105
105
  }
106
106
  :root[data-platform="android"] body::after {
107
107
  opacity: 0.85;
@@ -116,7 +116,7 @@
116
116
  opacity: 0.7;
117
117
  }
118
118
  }
119
- @keyframes moltbot-grid-drift {
119
+ @keyframes poolbot-grid-drift {
120
120
  0% {
121
121
  transform: translate3d(-12px, 8px, 0) rotate(-7deg);
122
122
  opacity: 0.4;
@@ -130,7 +130,7 @@
130
130
  opacity: 0.42;
131
131
  }
132
132
  }
133
- @keyframes moltbot-glow-drift {
133
+ @keyframes poolbot-glow-drift {
134
134
  0% {
135
135
  transform: translate3d(-18px, 12px, 0) scale(1.02);
136
136
  opacity: 0.4;
@@ -153,14 +153,14 @@
153
153
  touch-action: none;
154
154
  z-index: 1;
155
155
  }
156
- :root[data-platform="android"] #moltbot-canvas {
156
+ :root[data-platform="android"] #poolbot-canvas {
157
157
  background:
158
158
  radial-gradient(1100px 800px at 20% 15%, rgba(42, 113, 255, 0.78), rgba(0, 0, 0, 0) 58%),
159
159
  radial-gradient(900px 650px at 82% 28%, rgba(255, 0, 138, 0.66), rgba(0, 0, 0, 0) 62%),
160
160
  radial-gradient(1000px 900px at 60% 88%, rgba(0, 209, 255, 0.58), rgba(0, 0, 0, 0) 62%),
161
161
  #141c33;
162
162
  }
163
- #moltbot-status {
163
+ #poolbot-status {
164
164
  position: fixed;
165
165
  inset: 0;
166
166
  display: none;
@@ -172,7 +172,7 @@
172
172
  pointer-events: none;
173
173
  z-index: 3;
174
174
  }
175
- #moltbot-status .card {
175
+ #poolbot-status .card {
176
176
  width: min(560px, 88vw);
177
177
  text-align: left;
178
178
  padding: 14px 16px 12px;
@@ -185,7 +185,7 @@
185
185
  -webkit-backdrop-filter: blur(18px) saturate(140%);
186
186
  backdrop-filter: blur(18px) saturate(140%);
187
187
  }
188
- #moltbot-status .title {
188
+ #poolbot-status .title {
189
189
  font:
190
190
  600 12px/1.2 -apple-system,
191
191
  BlinkMacSystemFont,
@@ -196,7 +196,7 @@
196
196
  text-transform: uppercase;
197
197
  color: rgba(255, 255, 255, 0.7);
198
198
  }
199
- #moltbot-status .subtitle {
199
+ #poolbot-status .subtitle {
200
200
  margin-top: 8px;
201
201
  font:
202
202
  500 13px/1.45 -apple-system,
@@ -208,39 +208,39 @@
208
208
  white-space: pre-wrap;
209
209
  overflow-wrap: anywhere;
210
210
  }
211
- moltbot-a2ui-host {
211
+ poolbot-a2ui-host {
212
212
  display: block;
213
213
  height: 100%;
214
214
  position: fixed;
215
215
  inset: 0;
216
216
  z-index: 4;
217
- --moltbot-a2ui-inset-top: 28px;
218
- --moltbot-a2ui-inset-right: 0px;
219
- --moltbot-a2ui-inset-bottom: 0px;
220
- --moltbot-a2ui-inset-left: 0px;
221
- --moltbot-a2ui-scroll-pad-bottom: 0px;
222
- --moltbot-a2ui-status-top: calc(50% - 18px);
223
- --moltbot-a2ui-empty-top: 18px;
217
+ --poolbot-a2ui-inset-top: 28px;
218
+ --poolbot-a2ui-inset-right: 0px;
219
+ --poolbot-a2ui-inset-bottom: 0px;
220
+ --poolbot-a2ui-inset-left: 0px;
221
+ --poolbot-a2ui-scroll-pad-bottom: 0px;
222
+ --poolbot-a2ui-status-top: calc(50% - 18px);
223
+ --poolbot-a2ui-empty-top: 18px;
224
224
  }
225
225
  </style>
226
226
  </head>
227
227
  <body>
228
- <canvas id="moltbot-canvas"></canvas>
229
- <div id="moltbot-status">
228
+ <canvas id="poolbot-canvas"></canvas>
229
+ <div id="poolbot-status">
230
230
  <div class="card">
231
- <div class="title" id="moltbot-status-title">Ready</div>
232
- <div class="subtitle" id="moltbot-status-subtitle">Waiting for agent</div>
231
+ <div class="title" id="poolbot-status-title">Ready</div>
232
+ <div class="subtitle" id="poolbot-status-subtitle">Waiting for agent</div>
233
233
  </div>
234
234
  </div>
235
- <moltbot-a2ui-host></moltbot-a2ui-host>
235
+ <poolbot-a2ui-host></poolbot-a2ui-host>
236
236
  <script src="a2ui.bundle.js"></script>
237
237
  <script>
238
238
  (() => {
239
- const canvas = document.getElementById("moltbot-canvas");
239
+ const canvas = document.getElementById("poolbot-canvas");
240
240
  const ctx = canvas.getContext("2d");
241
- const statusEl = document.getElementById("moltbot-status");
242
- const titleEl = document.getElementById("moltbot-status-title");
243
- const subtitleEl = document.getElementById("moltbot-status-subtitle");
241
+ const statusEl = document.getElementById("poolbot-status");
242
+ const titleEl = document.getElementById("poolbot-status-title");
243
+ const subtitleEl = document.getElementById("poolbot-status-subtitle");
244
244
  const debugStatusEnabledByQuery = (() => {
245
245
  try {
246
246
  const params = new URLSearchParams(window.location.search);
@@ -278,7 +278,7 @@
278
278
  statusEl.style.display = "none";
279
279
  }
280
280
 
281
- window.__moltbot = {
281
+ window.__poolbot = {
282
282
  canvas,
283
283
  ctx,
284
284
  setDebugStatusEnabled,
@@ -53,7 +53,7 @@ export async function applyAuthChoiceOAuth(params) {
53
53
  onProgress: (msg) => spin.update(msg),
54
54
  });
55
55
  spin.stop("Chutes OAuth complete");
56
- const email = creds.email?.trim() || "default";
56
+ const email = typeof creds.email === "string" && creds.email.trim() ? creds.email.trim() : "default";
57
57
  const profileId = `chutes:${email}`;
58
58
  await writeOAuthCredentials("chutes", creds, params.agentDir);
59
59
  nextConfig = applyAuthProfileConfig(nextConfig, {
@@ -1,4 +1,4 @@
1
- import { discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
1
+ import { discoverAuthStorage, discoverModels } from "../../agents/pi-model-discovery.js";
2
2
  import { resolvePoolbotAgentDir } from "../../agents/agent-paths.js";
3
3
  import { listProfilesForProvider } from "../../agents/auth-profiles.js";
4
4
  import { getCustomProviderApiKey, resolveAwsSdkEnvVarName, resolveEnvApiKey, } from "../../agents/model-auth.js";
@@ -3,3 +3,5 @@ export const LEGACY_MANIFEST_KEY = LEGACY_PROJECT_NAME;
3
3
  export const LEGACY_PLUGIN_MANIFEST_FILENAME = `${LEGACY_PROJECT_NAME}.plugin.json`;
4
4
  export const LEGACY_CANVAS_HANDLER_NAME = `${LEGACY_PROJECT_NAME}CanvasA2UIAction`;
5
5
  export const LEGACY_MACOS_APP_SOURCES_DIR = "apps/macos/Sources/Pool-Bot";
6
+ // Alias used by conformance tests; points to the actual macOS app sources directory
7
+ export const MACOS_APP_SOURCES_DIR = "apps/macos/Sources/Clawdbot";
@@ -20,7 +20,7 @@ const LEGACY_CONFIG_FILENAMES = ["clawdbot.json", "moltbot.json", "moldbot.json"
20
20
  function resolveDefaultHomeDir() {
21
21
  return resolveRequiredHomeDir(process.env, os.homedir);
22
22
  }
23
- /** Build a homedir thunk that respects MOLTBOT_HOME for the given env. */
23
+ /** Build a homedir thunk that respects CLAWDBOT_HOME for the given env. */
24
24
  function envHomedir(env) {
25
25
  return () => resolveRequiredHomeDir(env, os.homedir);
26
26
  }