clawdbot 2026.1.4-1 → 2026.1.5-1

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 (116) hide show
  1. package/CHANGELOG.md +32 -6
  2. package/README.md +26 -1
  3. package/dist/agents/pi-embedded-runner.js +2 -0
  4. package/dist/agents/pi-embedded-subscribe.js +18 -3
  5. package/dist/agents/pi-tools.js +45 -6
  6. package/dist/agents/tools/browser-tool.js +38 -89
  7. package/dist/agents/tools/cron-tool.js +8 -8
  8. package/dist/agents/workspace.js +8 -1
  9. package/dist/auto-reply/command-detection.js +26 -0
  10. package/dist/auto-reply/reply/agent-runner.js +15 -8
  11. package/dist/auto-reply/reply/commands.js +36 -25
  12. package/dist/auto-reply/reply/directive-handling.js +4 -2
  13. package/dist/auto-reply/reply/directives.js +12 -0
  14. package/dist/auto-reply/reply/session-updates.js +2 -4
  15. package/dist/auto-reply/reply.js +26 -4
  16. package/dist/browser/config.js +22 -4
  17. package/dist/browser/profiles-service.js +3 -1
  18. package/dist/browser/profiles.js +14 -3
  19. package/dist/canvas-host/a2ui/.bundle.hash +2 -0
  20. package/dist/cli/gateway-cli.js +2 -2
  21. package/dist/cli/profile.js +81 -0
  22. package/dist/cli/program.js +10 -1
  23. package/dist/cli/run-main.js +33 -0
  24. package/dist/commands/configure.js +5 -0
  25. package/dist/commands/onboard-providers.js +1 -1
  26. package/dist/commands/setup.js +4 -1
  27. package/dist/config/defaults.js +56 -0
  28. package/dist/config/io.js +47 -6
  29. package/dist/config/paths.js +2 -2
  30. package/dist/config/port-defaults.js +32 -0
  31. package/dist/config/sessions.js +3 -2
  32. package/dist/config/validation.js +2 -2
  33. package/dist/config/zod-schema.js +16 -0
  34. package/dist/discord/monitor.js +75 -266
  35. package/dist/entry.js +16 -0
  36. package/dist/gateway/call.js +8 -1
  37. package/dist/gateway/server-methods/chat.js +1 -1
  38. package/dist/gateway/server.js +14 -3
  39. package/dist/index.js +2 -2
  40. package/dist/infra/control-ui-assets.js +118 -0
  41. package/dist/infra/dotenv.js +15 -0
  42. package/dist/infra/shell-env.js +79 -0
  43. package/dist/infra/system-events.js +50 -23
  44. package/dist/macos/relay.js +8 -2
  45. package/dist/telegram/bot.js +24 -1
  46. package/dist/utils.js +8 -2
  47. package/dist/web/auto-reply.js +18 -21
  48. package/dist/web/inbound.js +5 -1
  49. package/dist/web/qr-image.js +4 -4
  50. package/dist/web/session.js +2 -3
  51. package/docs/agent.md +0 -2
  52. package/docs/assets/markdown.css +4 -1
  53. package/docs/audio.md +0 -2
  54. package/docs/clawd.md +0 -2
  55. package/docs/configuration.md +62 -3
  56. package/docs/docs.json +9 -1
  57. package/docs/faq.md +32 -7
  58. package/docs/gateway.md +28 -0
  59. package/docs/images.md +0 -2
  60. package/docs/index.md +2 -4
  61. package/docs/mac/icon.md +1 -1
  62. package/docs/nix.md +57 -11
  63. package/docs/onboarding.md +0 -2
  64. package/docs/refactor/webagent-session.md +0 -2
  65. package/docs/research/memory.md +1 -1
  66. package/docs/skills.md +0 -2
  67. package/docs/templates/AGENTS.md +2 -2
  68. package/docs/tools.md +15 -0
  69. package/docs/whatsapp.md +2 -0
  70. package/package.json +9 -16
  71. package/dist/control-ui/assets/index-BFID3yAA.css +0 -1
  72. package/dist/control-ui/assets/index-CE_axlTS.js +0 -2235
  73. package/dist/control-ui/assets/index-CE_axlTS.js.map +0 -1
  74. package/dist/control-ui/index.html +0 -15
  75. package/dist/daemon/constants.js +0 -10
  76. package/dist/daemon/launchd.js +0 -276
  77. package/dist/daemon/legacy.js +0 -63
  78. package/dist/daemon/program-args.js +0 -76
  79. package/dist/daemon/schtasks.js +0 -257
  80. package/dist/daemon/service.js +0 -60
  81. package/dist/daemon/systemd.js +0 -266
  82. package/dist/imessage/client.js +0 -165
  83. package/dist/imessage/index.js +0 -3
  84. package/dist/imessage/monitor.js +0 -272
  85. package/dist/imessage/probe.js +0 -26
  86. package/dist/imessage/send.js +0 -83
  87. package/dist/imessage/targets.js +0 -176
  88. package/dist/signal/client.js +0 -134
  89. package/dist/signal/daemon.js +0 -69
  90. package/dist/signal/index.js +0 -3
  91. package/dist/signal/monitor.js +0 -336
  92. package/dist/signal/probe.js +0 -46
  93. package/dist/signal/send.js +0 -91
  94. package/dist/slack/actions.js +0 -97
  95. package/dist/slack/index.js +0 -5
  96. package/dist/slack/monitor.js +0 -1029
  97. package/dist/slack/probe.js +0 -47
  98. package/dist/slack/send.js +0 -131
  99. package/dist/slack/token.js +0 -10
  100. package/dist/tui/commands.js +0 -74
  101. package/dist/tui/components/assistant-message.js +0 -16
  102. package/dist/tui/components/chat-log.js +0 -92
  103. package/dist/tui/components/custom-editor.js +0 -53
  104. package/dist/tui/components/selectors.js +0 -8
  105. package/dist/tui/components/tool-execution.js +0 -111
  106. package/dist/tui/components/user-message.js +0 -17
  107. package/dist/tui/gateway-chat.js +0 -140
  108. package/dist/tui/layout.js +0 -41
  109. package/dist/tui/message-list.js +0 -57
  110. package/dist/tui/theme/theme.js +0 -80
  111. package/dist/tui/theme.js +0 -25
  112. package/dist/tui/tui.js +0 -708
  113. package/dist/wizard/clack-prompter.js +0 -56
  114. package/dist/wizard/onboarding.js +0 -452
  115. package/dist/wizard/prompts.js +0 -6
  116. package/dist/wizard/session.js +0 -203
@@ -1,5 +1,16 @@
1
1
  import { resolveTalkApiKey } from "./talk.js";
2
2
  let defaultWarnState = { warned: false };
3
+ const DEFAULT_MODEL_ALIASES = {
4
+ // Anthropic (pi-ai catalog uses "latest" ids without date suffix)
5
+ opus: "anthropic/claude-opus-4-5",
6
+ sonnet: "anthropic/claude-sonnet-4-5",
7
+ // OpenAI
8
+ gpt: "openai/gpt-5.2",
9
+ "gpt-mini": "openai/gpt-5-mini",
10
+ // Google Gemini (3.x are preview ids in the catalog)
11
+ gemini: "google/gemini-3-pro-preview",
12
+ "gemini-flash": "google/gemini-3-flash-preview",
13
+ };
3
14
  function escapeRegExp(text) {
4
15
  return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5
16
  }
@@ -56,6 +67,51 @@ export function applyTalkApiKey(config) {
56
67
  },
57
68
  };
58
69
  }
70
+ function normalizeAliasKey(value) {
71
+ return value.trim().toLowerCase();
72
+ }
73
+ export function applyModelAliasDefaults(cfg) {
74
+ const existingAgent = cfg.agent;
75
+ if (!existingAgent)
76
+ return cfg;
77
+ const existingAliases = existingAgent?.modelAliases ?? {};
78
+ const byNormalized = new Map();
79
+ for (const key of Object.keys(existingAliases)) {
80
+ const norm = normalizeAliasKey(key);
81
+ if (!norm)
82
+ continue;
83
+ if (!byNormalized.has(norm))
84
+ byNormalized.set(norm, key);
85
+ }
86
+ let mutated = false;
87
+ const nextAliases = { ...existingAliases };
88
+ for (const [canonicalKey, target] of Object.entries(DEFAULT_MODEL_ALIASES)) {
89
+ const norm = normalizeAliasKey(canonicalKey);
90
+ const existingKey = byNormalized.get(norm);
91
+ if (!existingKey) {
92
+ nextAliases[canonicalKey] = target;
93
+ byNormalized.set(norm, canonicalKey);
94
+ mutated = true;
95
+ continue;
96
+ }
97
+ const existingValue = String(existingAliases[existingKey] ?? "");
98
+ if (existingKey !== canonicalKey && existingValue === target) {
99
+ delete nextAliases[existingKey];
100
+ nextAliases[canonicalKey] = target;
101
+ byNormalized.set(norm, canonicalKey);
102
+ mutated = true;
103
+ }
104
+ }
105
+ if (!mutated)
106
+ return cfg;
107
+ return {
108
+ ...cfg,
109
+ agent: {
110
+ ...existingAgent,
111
+ modelAliases: nextAliases,
112
+ },
113
+ };
114
+ }
59
115
  export function resetSessionDefaultsWarningForTests() {
60
116
  defaultWarnState = { warned: false };
61
117
  }
package/dist/config/io.js CHANGED
@@ -2,11 +2,27 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import JSON5 from "json5";
5
- import { applyIdentityDefaults, applySessionDefaults, applyTalkApiKey, } from "./defaults.js";
5
+ import { loadShellEnvFallback, resolveShellEnvFallbackTimeoutMs, shouldEnableShellEnvFallback, } from "../infra/shell-env.js";
6
+ import { applyIdentityDefaults, applyModelAliasDefaults, applySessionDefaults, applyTalkApiKey, } from "./defaults.js";
6
7
  import { findLegacyConfigIssues } from "./legacy.js";
7
8
  import { CONFIG_PATH_CLAWDBOT, resolveConfigPath, resolveStateDir, } from "./paths.js";
8
9
  import { validateConfigObject } from "./validation.js";
9
10
  import { ClawdbotSchema } from "./zod-schema.js";
11
+ const SHELL_ENV_EXPECTED_KEYS = [
12
+ "OPENAI_API_KEY",
13
+ "ANTHROPIC_API_KEY",
14
+ "ANTHROPIC_OAUTH_TOKEN",
15
+ "GEMINI_API_KEY",
16
+ "ZAI_API_KEY",
17
+ "MINIMAX_API_KEY",
18
+ "ELEVENLABS_API_KEY",
19
+ "TELEGRAM_BOT_TOKEN",
20
+ "DISCORD_BOT_TOKEN",
21
+ "SLACK_BOT_TOKEN",
22
+ "SLACK_APP_TOKEN",
23
+ "CLAWDBOT_GATEWAY_TOKEN",
24
+ "CLAWDBOT_GATEWAY_PASSWORD",
25
+ ];
10
26
  function resolveConfigPathForDeps(deps) {
11
27
  if (deps.configPath)
12
28
  return deps.configPath;
@@ -35,8 +51,18 @@ export function createConfigIO(overrides = {}) {
35
51
  const configPath = resolveConfigPathForDeps(deps);
36
52
  function loadConfig() {
37
53
  try {
38
- if (!deps.fs.existsSync(configPath))
54
+ if (!deps.fs.existsSync(configPath)) {
55
+ if (shouldEnableShellEnvFallback(deps.env)) {
56
+ loadShellEnvFallback({
57
+ enabled: true,
58
+ env: deps.env,
59
+ expectedKeys: SHELL_ENV_EXPECTED_KEYS,
60
+ logger: deps.logger,
61
+ timeoutMs: resolveShellEnvFallbackTimeoutMs(deps.env),
62
+ });
63
+ }
39
64
  return {};
65
+ }
40
66
  const raw = deps.fs.readFileSync(configPath, "utf-8");
41
67
  const parsed = deps.json5.parse(raw);
42
68
  if (typeof parsed !== "object" || parsed === null)
@@ -49,7 +75,20 @@ export function createConfigIO(overrides = {}) {
49
75
  }
50
76
  return {};
51
77
  }
52
- return applySessionDefaults(applyIdentityDefaults(validated.data));
78
+ const cfg = applyModelAliasDefaults(applySessionDefaults(applyIdentityDefaults(validated.data)));
79
+ const enabled = shouldEnableShellEnvFallback(deps.env) ||
80
+ cfg.env?.shellEnv?.enabled === true;
81
+ if (enabled) {
82
+ loadShellEnvFallback({
83
+ enabled: true,
84
+ env: deps.env,
85
+ expectedKeys: SHELL_ENV_EXPECTED_KEYS,
86
+ logger: deps.logger,
87
+ timeoutMs: cfg.env?.shellEnv?.timeoutMs ??
88
+ resolveShellEnvFallbackTimeoutMs(deps.env),
89
+ });
90
+ }
91
+ return cfg;
53
92
  }
54
93
  catch (err) {
55
94
  deps.logger.error(`Failed to read config at ${configPath}`, err);
@@ -59,7 +98,7 @@ export function createConfigIO(overrides = {}) {
59
98
  async function readConfigFileSnapshot() {
60
99
  const exists = deps.fs.existsSync(configPath);
61
100
  if (!exists) {
62
- const config = applyTalkApiKey(applySessionDefaults({}));
101
+ const config = applyTalkApiKey(applyModelAliasDefaults(applySessionDefaults({})));
63
102
  const legacyIssues = [];
64
103
  return {
65
104
  path: configPath,
@@ -109,7 +148,7 @@ export function createConfigIO(overrides = {}) {
109
148
  raw,
110
149
  parsed: parsedRes.parsed,
111
150
  valid: true,
112
- config: applyTalkApiKey(applySessionDefaults(validated.config)),
151
+ config: applyTalkApiKey(applyModelAliasDefaults(applySessionDefaults(validated.config))),
113
152
  issues: [],
114
153
  legacyIssues,
115
154
  };
@@ -131,7 +170,9 @@ export function createConfigIO(overrides = {}) {
131
170
  await deps.fs.promises.mkdir(path.dirname(configPath), {
132
171
  recursive: true,
133
172
  });
134
- const json = JSON.stringify(cfg, null, 2).trimEnd().concat("\n");
173
+ const json = JSON.stringify(applyModelAliasDefaults(cfg), null, 2)
174
+ .trimEnd()
175
+ .concat("\n");
135
176
  await deps.fs.promises.writeFile(configPath, json, "utf-8");
136
177
  }
137
178
  return {
@@ -18,9 +18,9 @@ export const isNixMode = resolveIsNixMode();
18
18
  * Default: ~/.clawdbot
19
19
  */
20
20
  export function resolveStateDir(env = process.env, homedir = os.homedir) {
21
- const override = env.CLAWDBOT_STATE_DIR?.trim();
21
+ const override = env.CLAWDBOT_STATE_DIR?.trim() || env.CLAWDIS_STATE_DIR?.trim();
22
22
  if (override)
23
- return override;
23
+ return resolveUserPath(override);
24
24
  return path.join(homedir(), ".clawdbot");
25
25
  }
26
26
  export const STATE_DIR_CLAWDBOT = resolveStateDir();
@@ -0,0 +1,32 @@
1
+ function isValidPort(port) {
2
+ return Number.isFinite(port) && port > 0 && port <= 65535;
3
+ }
4
+ function clampPort(port, fallback) {
5
+ return isValidPort(port) ? port : fallback;
6
+ }
7
+ function derivePort(base, offset, fallback) {
8
+ return clampPort(base + offset, fallback);
9
+ }
10
+ export const DEFAULT_BRIDGE_PORT = 18790;
11
+ export const DEFAULT_BROWSER_CONTROL_PORT = 18791;
12
+ export const DEFAULT_CANVAS_HOST_PORT = 18793;
13
+ export const DEFAULT_BROWSER_CDP_PORT_RANGE_START = 18800;
14
+ export const DEFAULT_BROWSER_CDP_PORT_RANGE_END = 18899;
15
+ export function deriveDefaultBridgePort(gatewayPort) {
16
+ return derivePort(gatewayPort, 1, DEFAULT_BRIDGE_PORT);
17
+ }
18
+ export function deriveDefaultBrowserControlPort(gatewayPort) {
19
+ return derivePort(gatewayPort, 2, DEFAULT_BROWSER_CONTROL_PORT);
20
+ }
21
+ export function deriveDefaultCanvasHostPort(gatewayPort) {
22
+ return derivePort(gatewayPort, 4, DEFAULT_CANVAS_HOST_PORT);
23
+ }
24
+ export function deriveDefaultBrowserCdpPortRange(browserControlPort) {
25
+ const start = derivePort(browserControlPort, 9, DEFAULT_BROWSER_CDP_PORT_RANGE_START);
26
+ const end = clampPort(start +
27
+ (DEFAULT_BROWSER_CDP_PORT_RANGE_END -
28
+ DEFAULT_BROWSER_CDP_PORT_RANGE_START), DEFAULT_BROWSER_CDP_PORT_RANGE_END);
29
+ if (end < start)
30
+ return { start, end: start };
31
+ return { start, end };
32
+ }
@@ -4,6 +4,7 @@ import os from "node:os";
4
4
  import path from "node:path";
5
5
  import JSON5 from "json5";
6
6
  import { normalizeE164 } from "../utils.js";
7
+ import { resolveStateDir } from "./paths.js";
7
8
  const GROUP_SURFACES = new Set([
8
9
  "whatsapp",
9
10
  "telegram",
@@ -13,8 +14,8 @@ const GROUP_SURFACES = new Set([
13
14
  "webchat",
14
15
  "slack",
15
16
  ]);
16
- export function resolveSessionTranscriptsDir() {
17
- return path.join(os.homedir(), ".clawdbot", "sessions");
17
+ export function resolveSessionTranscriptsDir(env = process.env, homedir = os.homedir) {
18
+ return path.join(resolveStateDir(env, homedir), "sessions");
18
19
  }
19
20
  export function resolveDefaultSessionStorePath() {
20
21
  return path.join(resolveSessionTranscriptsDir(), "sessions.json");
@@ -1,4 +1,4 @@
1
- import { applyIdentityDefaults, applySessionDefaults } from "./defaults.js";
1
+ import { applyIdentityDefaults, applyModelAliasDefaults, applySessionDefaults, } from "./defaults.js";
2
2
  import { findLegacyConfigIssues } from "./legacy.js";
3
3
  import { ClawdbotSchema } from "./zod-schema.js";
4
4
  export function validateConfigObject(raw) {
@@ -24,6 +24,6 @@ export function validateConfigObject(raw) {
24
24
  }
25
25
  return {
26
26
  ok: true,
27
- config: applySessionDefaults(applyIdentityDefaults(validated.data)),
27
+ config: applyModelAliasDefaults(applySessionDefaults(applyIdentityDefaults(validated.data))),
28
28
  };
29
29
  }
@@ -256,6 +256,16 @@ const HooksGmailSchema = z
256
256
  })
257
257
  .optional();
258
258
  export const ClawdbotSchema = z.object({
259
+ env: z
260
+ .object({
261
+ shellEnv: z
262
+ .object({
263
+ enabled: z.boolean().optional(),
264
+ timeoutMs: z.number().int().nonnegative().optional(),
265
+ })
266
+ .optional(),
267
+ })
268
+ .optional(),
259
269
  identity: z
260
270
  .object({
261
271
  name: z.string().optional(),
@@ -346,6 +356,12 @@ export const ClawdbotSchema = z.object({
346
356
  modelFallbacks: z.array(z.string()).optional(),
347
357
  imageModelFallbacks: z.array(z.string()).optional(),
348
358
  contextTokens: z.number().int().positive().optional(),
359
+ tools: z
360
+ .object({
361
+ allow: z.array(z.string()).optional(),
362
+ deny: z.array(z.string()).optional(),
363
+ })
364
+ .optional(),
349
365
  thinkingDefault: z
350
366
  .union([
351
367
  z.literal("off"),