clawdbot 2026.1.4-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 (550) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +297 -0
  5. package/dist/agents/agent-paths.js +17 -0
  6. package/dist/agents/bash-process-registry.js +126 -0
  7. package/dist/agents/bash-tools.js +837 -0
  8. package/dist/agents/clawdbot-tools.js +30 -0
  9. package/dist/agents/clawdis-tools.js +27 -0
  10. package/dist/agents/context.js +34 -0
  11. package/dist/agents/defaults.js +6 -0
  12. package/dist/agents/model-auth.js +112 -0
  13. package/dist/agents/model-catalog.js +55 -0
  14. package/dist/agents/model-fallback.js +191 -0
  15. package/dist/agents/model-scan.js +263 -0
  16. package/dist/agents/model-selection.js +116 -0
  17. package/dist/agents/models-config.js +49 -0
  18. package/dist/agents/pi-embedded-helpers.js +74 -0
  19. package/dist/agents/pi-embedded-runner.js +407 -0
  20. package/dist/agents/pi-embedded-subscribe.js +568 -0
  21. package/dist/agents/pi-embedded-utils.js +20 -0
  22. package/dist/agents/pi-embedded.js +1 -0
  23. package/dist/agents/pi-oauth.js +88 -0
  24. package/dist/agents/pi-tools.js +433 -0
  25. package/dist/agents/sandbox-paths.js +68 -0
  26. package/dist/agents/sandbox.js +644 -0
  27. package/dist/agents/shell-utils.js +53 -0
  28. package/dist/agents/skills-install.js +244 -0
  29. package/dist/agents/skills-status.js +157 -0
  30. package/dist/agents/skills.js +470 -0
  31. package/dist/agents/steerable-agent-loop.js +338 -0
  32. package/dist/agents/steerable-provider-transport.js +48 -0
  33. package/dist/agents/system-prompt.js +104 -0
  34. package/dist/agents/tool-display.js +162 -0
  35. package/dist/agents/tool-images.js +138 -0
  36. package/dist/agents/tools/browser-tool.js +339 -0
  37. package/dist/agents/tools/canvas-tool.js +193 -0
  38. package/dist/agents/tools/common.js +88 -0
  39. package/dist/agents/tools/cron-tool.js +124 -0
  40. package/dist/agents/tools/discord-actions-guild.js +186 -0
  41. package/dist/agents/tools/discord-actions-messaging.js +285 -0
  42. package/dist/agents/tools/discord-actions-moderation.js +70 -0
  43. package/dist/agents/tools/discord-actions.js +56 -0
  44. package/dist/agents/tools/discord-schema.js +199 -0
  45. package/dist/agents/tools/discord-tool.js +16 -0
  46. package/dist/agents/tools/gateway-tool.js +46 -0
  47. package/dist/agents/tools/gateway.js +27 -0
  48. package/dist/agents/tools/image-tool.js +132 -0
  49. package/dist/agents/tools/nodes-tool.js +413 -0
  50. package/dist/agents/tools/nodes-utils.js +92 -0
  51. package/dist/agents/tools/sessions-helpers.js +88 -0
  52. package/dist/agents/tools/sessions-history-tool.js +53 -0
  53. package/dist/agents/tools/sessions-list-tool.js +143 -0
  54. package/dist/agents/tools/sessions-send-helpers.js +100 -0
  55. package/dist/agents/tools/sessions-send-tool.js +347 -0
  56. package/dist/agents/tools/slack-actions.js +129 -0
  57. package/dist/agents/tools/slack-schema.js +59 -0
  58. package/dist/agents/tools/slack-tool.js +16 -0
  59. package/dist/agents/usage.js +39 -0
  60. package/dist/agents/workspace.js +241 -0
  61. package/dist/auto-reply/chunk.js +76 -0
  62. package/dist/auto-reply/envelope.js +38 -0
  63. package/dist/auto-reply/group-activation.js +20 -0
  64. package/dist/auto-reply/heartbeat.js +57 -0
  65. package/dist/auto-reply/model.js +14 -0
  66. package/dist/auto-reply/reply/abort.js +14 -0
  67. package/dist/auto-reply/reply/agent-runner.js +371 -0
  68. package/dist/auto-reply/reply/block-streaming.js +34 -0
  69. package/dist/auto-reply/reply/body.js +29 -0
  70. package/dist/auto-reply/reply/commands.js +207 -0
  71. package/dist/auto-reply/reply/directive-handling.js +361 -0
  72. package/dist/auto-reply/reply/directives.js +47 -0
  73. package/dist/auto-reply/reply/followup-runner.js +149 -0
  74. package/dist/auto-reply/reply/groups.js +91 -0
  75. package/dist/auto-reply/reply/mentions.js +38 -0
  76. package/dist/auto-reply/reply/model-selection.js +114 -0
  77. package/dist/auto-reply/reply/queue.js +399 -0
  78. package/dist/auto-reply/reply/reply-tags.js +26 -0
  79. package/dist/auto-reply/reply/session-updates.js +87 -0
  80. package/dist/auto-reply/reply/session.js +160 -0
  81. package/dist/auto-reply/reply/typing.js +75 -0
  82. package/dist/auto-reply/reply.js +535 -0
  83. package/dist/auto-reply/send-policy.js +28 -0
  84. package/dist/auto-reply/status.js +158 -0
  85. package/dist/auto-reply/templating.js +9 -0
  86. package/dist/auto-reply/thinking.js +49 -0
  87. package/dist/auto-reply/tokens.js +2 -0
  88. package/dist/auto-reply/tool-meta.js +74 -0
  89. package/dist/auto-reply/transcription.js +57 -0
  90. package/dist/auto-reply/types.js +1 -0
  91. package/dist/browser/bridge-server.js +37 -0
  92. package/dist/browser/cdp.js +382 -0
  93. package/dist/browser/chrome.js +432 -0
  94. package/dist/browser/client-actions-core.js +67 -0
  95. package/dist/browser/client-actions-observe.js +24 -0
  96. package/dist/browser/client-actions-types.js +1 -0
  97. package/dist/browser/client-actions.js +3 -0
  98. package/dist/browser/client-fetch.js +43 -0
  99. package/dist/browser/client.js +105 -0
  100. package/dist/browser/config.js +140 -0
  101. package/dist/browser/constants.js +4 -0
  102. package/dist/browser/profiles-service.js +122 -0
  103. package/dist/browser/profiles.js +85 -0
  104. package/dist/browser/pw-ai.js +2 -0
  105. package/dist/browser/pw-session.js +144 -0
  106. package/dist/browser/pw-tools-core.js +363 -0
  107. package/dist/browser/routes/agent.js +535 -0
  108. package/dist/browser/routes/basic.js +155 -0
  109. package/dist/browser/routes/index.js +8 -0
  110. package/dist/browser/routes/tabs.js +105 -0
  111. package/dist/browser/routes/utils.js +62 -0
  112. package/dist/browser/screenshot.js +40 -0
  113. package/dist/browser/server-context.js +377 -0
  114. package/dist/browser/server.js +81 -0
  115. package/dist/browser/target-id.js +18 -0
  116. package/dist/browser/trash.js +21 -0
  117. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  118. package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
  119. package/dist/canvas-host/a2ui/index.html +246 -0
  120. package/dist/canvas-host/a2ui.js +187 -0
  121. package/dist/canvas-host/server.js +382 -0
  122. package/dist/cli/browser-cli-actions-input.js +459 -0
  123. package/dist/cli/browser-cli-actions-observe.js +56 -0
  124. package/dist/cli/browser-cli-examples.js +31 -0
  125. package/dist/cli/browser-cli-inspect.js +97 -0
  126. package/dist/cli/browser-cli-manage.js +286 -0
  127. package/dist/cli/browser-cli-shared.js +1 -0
  128. package/dist/cli/browser-cli.js +26 -0
  129. package/dist/cli/canvas-cli.js +416 -0
  130. package/dist/cli/cron-cli.js +454 -0
  131. package/dist/cli/deps.js +17 -0
  132. package/dist/cli/dns-cli.js +180 -0
  133. package/dist/cli/gateway-cli.js +489 -0
  134. package/dist/cli/gateway-rpc.js +20 -0
  135. package/dist/cli/hooks-cli.js +135 -0
  136. package/dist/cli/models-cli.js +248 -0
  137. package/dist/cli/nodes-camera.js +57 -0
  138. package/dist/cli/nodes-canvas.js +26 -0
  139. package/dist/cli/nodes-cli.js +946 -0
  140. package/dist/cli/nodes-screen.js +37 -0
  141. package/dist/cli/parse-duration.js +20 -0
  142. package/dist/cli/ports.js +97 -0
  143. package/dist/cli/program.js +406 -0
  144. package/dist/cli/prompt.js +19 -0
  145. package/dist/cli/tui-cli.js +35 -0
  146. package/dist/cli/wait.js +8 -0
  147. package/dist/commands/agent.js +645 -0
  148. package/dist/commands/antigravity-oauth.js +327 -0
  149. package/dist/commands/configure.js +480 -0
  150. package/dist/commands/doctor.js +484 -0
  151. package/dist/commands/health.js +108 -0
  152. package/dist/commands/models/aliases.js +64 -0
  153. package/dist/commands/models/fallbacks.js +99 -0
  154. package/dist/commands/models/image-fallbacks.js +99 -0
  155. package/dist/commands/models/list.js +323 -0
  156. package/dist/commands/models/scan.js +266 -0
  157. package/dist/commands/models/set-image.js +23 -0
  158. package/dist/commands/models/set.js +23 -0
  159. package/dist/commands/models/shared.js +72 -0
  160. package/dist/commands/models.js +7 -0
  161. package/dist/commands/onboard-auth.js +70 -0
  162. package/dist/commands/onboard-helpers.js +295 -0
  163. package/dist/commands/onboard-interactive.js +17 -0
  164. package/dist/commands/onboard-non-interactive.js +202 -0
  165. package/dist/commands/onboard-providers.js +634 -0
  166. package/dist/commands/onboard-remote.js +120 -0
  167. package/dist/commands/onboard-skills.js +148 -0
  168. package/dist/commands/onboard-types.js +1 -0
  169. package/dist/commands/onboard.js +12 -0
  170. package/dist/commands/send.js +124 -0
  171. package/dist/commands/sessions.js +212 -0
  172. package/dist/commands/setup.js +58 -0
  173. package/dist/commands/signal-install.js +135 -0
  174. package/dist/commands/status.js +207 -0
  175. package/dist/commands/update.js +16 -0
  176. package/dist/config/config.js +6 -0
  177. package/dist/config/defaults.js +61 -0
  178. package/dist/config/io.js +147 -0
  179. package/dist/config/legacy-migrate.js +13 -0
  180. package/dist/config/legacy.js +159 -0
  181. package/dist/config/paths.js +71 -0
  182. package/dist/config/schema.js +150 -0
  183. package/dist/config/sessions.js +282 -0
  184. package/dist/config/talk.js +31 -0
  185. package/dist/config/types.js +1 -0
  186. package/dist/config/validation.js +29 -0
  187. package/dist/config/zod-schema.js +831 -0
  188. package/dist/control-ui/assets/index-BFID3yAA.css +1 -0
  189. package/dist/control-ui/assets/index-CE_axlTS.js +2235 -0
  190. package/dist/control-ui/assets/index-CE_axlTS.js.map +1 -0
  191. package/dist/control-ui/index.html +15 -0
  192. package/dist/cron/isolated-agent.js +499 -0
  193. package/dist/cron/run-log.js +72 -0
  194. package/dist/cron/schedule.js +24 -0
  195. package/dist/cron/service.js +471 -0
  196. package/dist/cron/store.js +43 -0
  197. package/dist/cron/types.js +1 -0
  198. package/dist/daemon/constants.js +10 -0
  199. package/dist/daemon/launchd.js +276 -0
  200. package/dist/daemon/legacy.js +63 -0
  201. package/dist/daemon/program-args.js +76 -0
  202. package/dist/daemon/schtasks.js +257 -0
  203. package/dist/daemon/service.js +60 -0
  204. package/dist/daemon/systemd.js +266 -0
  205. package/dist/discord/index.js +2 -0
  206. package/dist/discord/monitor.js +1188 -0
  207. package/dist/discord/probe.js +54 -0
  208. package/dist/discord/send.js +577 -0
  209. package/dist/discord/token.js +8 -0
  210. package/dist/gateway/auth.js +121 -0
  211. package/dist/gateway/call.js +94 -0
  212. package/dist/gateway/chat-attachments.js +41 -0
  213. package/dist/gateway/client.js +180 -0
  214. package/dist/gateway/config-reload.js +274 -0
  215. package/dist/gateway/control-ui.js +184 -0
  216. package/dist/gateway/hooks-mapping.js +282 -0
  217. package/dist/gateway/hooks.js +168 -0
  218. package/dist/gateway/net.js +29 -0
  219. package/dist/gateway/protocol/index.js +61 -0
  220. package/dist/gateway/protocol/schema.js +560 -0
  221. package/dist/gateway/server-bridge-subscriptions.js +93 -0
  222. package/dist/gateway/server-bridge.js +1013 -0
  223. package/dist/gateway/server-browser.js +12 -0
  224. package/dist/gateway/server-chat.js +159 -0
  225. package/dist/gateway/server-constants.js +8 -0
  226. package/dist/gateway/server-discovery.js +62 -0
  227. package/dist/gateway/server-http.js +165 -0
  228. package/dist/gateway/server-methods/agent-job.js +125 -0
  229. package/dist/gateway/server-methods/agent.js +250 -0
  230. package/dist/gateway/server-methods/chat.js +200 -0
  231. package/dist/gateway/server-methods/config.js +50 -0
  232. package/dist/gateway/server-methods/connect.js +6 -0
  233. package/dist/gateway/server-methods/cron.js +83 -0
  234. package/dist/gateway/server-methods/health.js +28 -0
  235. package/dist/gateway/server-methods/models.js +16 -0
  236. package/dist/gateway/server-methods/nodes.js +294 -0
  237. package/dist/gateway/server-methods/providers.js +217 -0
  238. package/dist/gateway/server-methods/send.js +166 -0
  239. package/dist/gateway/server-methods/sessions.js +305 -0
  240. package/dist/gateway/server-methods/skills.js +83 -0
  241. package/dist/gateway/server-methods/system.js +118 -0
  242. package/dist/gateway/server-methods/talk.js +22 -0
  243. package/dist/gateway/server-methods/types.js +1 -0
  244. package/dist/gateway/server-methods/voicewake.js +30 -0
  245. package/dist/gateway/server-methods/web.js +58 -0
  246. package/dist/gateway/server-methods/wizard.js +100 -0
  247. package/dist/gateway/server-methods.js +53 -0
  248. package/dist/gateway/server-providers.js +644 -0
  249. package/dist/gateway/server-shared.js +1 -0
  250. package/dist/gateway/server-utils.js +35 -0
  251. package/dist/gateway/server.js +1437 -0
  252. package/dist/gateway/session-utils.js +216 -0
  253. package/dist/gateway/ws-log.js +349 -0
  254. package/dist/gateway/ws-logging.js +8 -0
  255. package/dist/globals.js +41 -0
  256. package/dist/hooks/gmail-ops.js +236 -0
  257. package/dist/hooks/gmail-setup-utils.js +278 -0
  258. package/dist/hooks/gmail-watcher.js +175 -0
  259. package/dist/hooks/gmail.js +177 -0
  260. package/dist/imessage/client.js +165 -0
  261. package/dist/imessage/index.js +3 -0
  262. package/dist/imessage/monitor.js +272 -0
  263. package/dist/imessage/probe.js +26 -0
  264. package/dist/imessage/send.js +83 -0
  265. package/dist/imessage/targets.js +176 -0
  266. package/dist/index.js +50 -0
  267. package/dist/infra/agent-events.js +46 -0
  268. package/dist/infra/binaries.js +9 -0
  269. package/dist/infra/bonjour-discovery.js +163 -0
  270. package/dist/infra/bonjour.js +200 -0
  271. package/dist/infra/bridge/server.js +562 -0
  272. package/dist/infra/canvas-host-url.js +54 -0
  273. package/dist/infra/env.js +8 -0
  274. package/dist/infra/errors.js +28 -0
  275. package/dist/infra/gateway-lock.js +8 -0
  276. package/dist/infra/heartbeat-events.js +21 -0
  277. package/dist/infra/heartbeat-runner.js +453 -0
  278. package/dist/infra/heartbeat-wake.js +61 -0
  279. package/dist/infra/is-main.js +37 -0
  280. package/dist/infra/machine-name.js +40 -0
  281. package/dist/infra/node-pairing.js +211 -0
  282. package/dist/infra/pam.js +42 -0
  283. package/dist/infra/path-env.js +92 -0
  284. package/dist/infra/ports.js +87 -0
  285. package/dist/infra/provider-summary.js +80 -0
  286. package/dist/infra/restart.js +29 -0
  287. package/dist/infra/retry.js +16 -0
  288. package/dist/infra/runtime-guard.js +59 -0
  289. package/dist/infra/system-events.js +44 -0
  290. package/dist/infra/system-presence.js +216 -0
  291. package/dist/infra/tailnet.js +46 -0
  292. package/dist/infra/tailscale.js +149 -0
  293. package/dist/infra/voicewake.js +77 -0
  294. package/dist/infra/widearea-dns.js +123 -0
  295. package/dist/infra/ws.js +13 -0
  296. package/dist/logger.js +52 -0
  297. package/dist/logging.js +490 -0
  298. package/dist/macos/gateway-daemon.js +141 -0
  299. package/dist/macos/relay.js +46 -0
  300. package/dist/media/constants.js +33 -0
  301. package/dist/media/host.js +42 -0
  302. package/dist/media/image-ops.js +121 -0
  303. package/dist/media/mime.js +115 -0
  304. package/dist/media/parse.js +81 -0
  305. package/dist/media/server.js +64 -0
  306. package/dist/media/store.js +139 -0
  307. package/dist/process/command-queue.js +97 -0
  308. package/dist/process/exec.js +75 -0
  309. package/dist/protocol.schema.json +2918 -0
  310. package/dist/provider-web.js +8 -0
  311. package/dist/providers/web/index.js +2 -0
  312. package/dist/runtime.js +8 -0
  313. package/dist/sessions/send-policy.js +68 -0
  314. package/dist/signal/client.js +134 -0
  315. package/dist/signal/daemon.js +69 -0
  316. package/dist/signal/index.js +3 -0
  317. package/dist/signal/monitor.js +336 -0
  318. package/dist/signal/probe.js +46 -0
  319. package/dist/signal/send.js +91 -0
  320. package/dist/slack/actions.js +97 -0
  321. package/dist/slack/index.js +5 -0
  322. package/dist/slack/monitor.js +1029 -0
  323. package/dist/slack/probe.js +47 -0
  324. package/dist/slack/send.js +131 -0
  325. package/dist/slack/token.js +10 -0
  326. package/dist/telegram/bot.js +394 -0
  327. package/dist/telegram/download.js +34 -0
  328. package/dist/telegram/index.js +4 -0
  329. package/dist/telegram/monitor.js +47 -0
  330. package/dist/telegram/probe.js +63 -0
  331. package/dist/telegram/proxy.js +9 -0
  332. package/dist/telegram/send.js +138 -0
  333. package/dist/telegram/token.js +30 -0
  334. package/dist/telegram/webhook-set.js +12 -0
  335. package/dist/telegram/webhook.js +56 -0
  336. package/dist/tui/commands.js +74 -0
  337. package/dist/tui/components/assistant-message.js +16 -0
  338. package/dist/tui/components/chat-log.js +92 -0
  339. package/dist/tui/components/custom-editor.js +53 -0
  340. package/dist/tui/components/selectors.js +8 -0
  341. package/dist/tui/components/tool-execution.js +111 -0
  342. package/dist/tui/components/user-message.js +17 -0
  343. package/dist/tui/gateway-chat.js +140 -0
  344. package/dist/tui/layout.js +41 -0
  345. package/dist/tui/message-list.js +57 -0
  346. package/dist/tui/theme/theme.js +80 -0
  347. package/dist/tui/theme.js +25 -0
  348. package/dist/tui/tui.js +708 -0
  349. package/dist/utils.js +133 -0
  350. package/dist/version.js +18 -0
  351. package/dist/web/active-listener.js +7 -0
  352. package/dist/web/auto-reply.js +1203 -0
  353. package/dist/web/inbound.js +481 -0
  354. package/dist/web/login-qr.js +204 -0
  355. package/dist/web/login.js +59 -0
  356. package/dist/web/media.js +148 -0
  357. package/dist/web/outbound.js +67 -0
  358. package/dist/web/qr-image.js +97 -0
  359. package/dist/web/reconnect.js +60 -0
  360. package/dist/web/reply-heartbeat-wake.js +61 -0
  361. package/dist/web/session.js +346 -0
  362. package/dist/wizard/clack-prompter.js +56 -0
  363. package/dist/wizard/onboarding.js +452 -0
  364. package/dist/wizard/prompts.js +6 -0
  365. package/dist/wizard/session.js +203 -0
  366. package/docs/AGENTS.default.md +116 -0
  367. package/docs/CNAME +1 -0
  368. package/docs/RELEASING.md +64 -0
  369. package/docs/_config.yml +51 -0
  370. package/docs/_layouts/default.html +145 -0
  371. package/docs/agent-send.md +21 -0
  372. package/docs/agent.md +104 -0
  373. package/docs/android/connect.md +131 -0
  374. package/docs/architecture.md +89 -0
  375. package/docs/assets/markdown.css +130 -0
  376. package/docs/assets/pixel-lobster.svg +60 -0
  377. package/docs/assets/terminal.css +497 -0
  378. package/docs/assets/theme.js +55 -0
  379. package/docs/audio.md +50 -0
  380. package/docs/background-process.md +74 -0
  381. package/docs/bash.md +32 -0
  382. package/docs/bonjour.md +159 -0
  383. package/docs/browser.md +289 -0
  384. package/docs/camera.md +152 -0
  385. package/docs/clawd.md +199 -0
  386. package/docs/clawdbot-mac.md +104 -0
  387. package/docs/configuration.md +1177 -0
  388. package/docs/control-api.md +49 -0
  389. package/docs/control-ui.md +83 -0
  390. package/docs/cron.md +374 -0
  391. package/docs/dashboard.md +17 -0
  392. package/docs/device-models.md +46 -0
  393. package/docs/discord.md +293 -0
  394. package/docs/discovery.md +112 -0
  395. package/docs/docker.md +251 -0
  396. package/docs/docs.json +86 -0
  397. package/docs/doctor.md +47 -0
  398. package/docs/elevated.md +31 -0
  399. package/docs/faq.md +640 -0
  400. package/docs/gateway/pairing.md +109 -0
  401. package/docs/gateway-lock.md +28 -0
  402. package/docs/gateway.md +174 -0
  403. package/docs/gmail-pubsub.md +191 -0
  404. package/docs/grammy.md +27 -0
  405. package/docs/group-messages.md +71 -0
  406. package/docs/groups.md +78 -0
  407. package/docs/health.md +28 -0
  408. package/docs/heartbeat.md +64 -0
  409. package/docs/images.md +52 -0
  410. package/docs/imessage.md +63 -0
  411. package/docs/index.md +182 -0
  412. package/docs/ios/connect.md +177 -0
  413. package/docs/ios/spec.md +236 -0
  414. package/docs/location-command.md +95 -0
  415. package/docs/logging.md +99 -0
  416. package/docs/lore.md +131 -0
  417. package/docs/mac/bun.md +133 -0
  418. package/docs/mac/canvas.md +161 -0
  419. package/docs/mac/child-process.md +72 -0
  420. package/docs/mac/dev-setup.md +81 -0
  421. package/docs/mac/health.md +28 -0
  422. package/docs/mac/icon.md +26 -0
  423. package/docs/mac/logging.md +51 -0
  424. package/docs/mac/menu-bar.md +69 -0
  425. package/docs/mac/peekaboo.md +170 -0
  426. package/docs/mac/permissions.md +40 -0
  427. package/docs/mac/release.md +76 -0
  428. package/docs/mac/remote.md +57 -0
  429. package/docs/mac/signing.md +41 -0
  430. package/docs/mac/skills.md +27 -0
  431. package/docs/mac/voice-overlay.md +52 -0
  432. package/docs/mac/voicewake.md +56 -0
  433. package/docs/mac/webchat.md +27 -0
  434. package/docs/mac/xpc.md +40 -0
  435. package/docs/models.md +90 -0
  436. package/docs/nix.md +49 -0
  437. package/docs/nodes.md +157 -0
  438. package/docs/onboarding-config-protocol.md +29 -0
  439. package/docs/onboarding.md +185 -0
  440. package/docs/presence.md +133 -0
  441. package/docs/queue.md +78 -0
  442. package/docs/refactor/browser-control-simplification.md +58 -0
  443. package/docs/refactor/canvas-a2ui.md +93 -0
  444. package/docs/refactor/cli-unification.md +64 -0
  445. package/docs/refactor/gateway-client.md +31 -0
  446. package/docs/refactor/gateway.md +99 -0
  447. package/docs/refactor/new-arch.md +171 -0
  448. package/docs/refactor/tui.md +26 -0
  449. package/docs/refactor/web-gateway-troubleshooting.md +37 -0
  450. package/docs/refactor/webagent-session.md +46 -0
  451. package/docs/remote-gateway-readme.md +148 -0
  452. package/docs/remote.md +66 -0
  453. package/docs/research/memory.md +227 -0
  454. package/docs/rpc.md +35 -0
  455. package/docs/security.md +168 -0
  456. package/docs/session-tool.md +119 -0
  457. package/docs/session.md +84 -0
  458. package/docs/sessions.md +8 -0
  459. package/docs/setup.md +118 -0
  460. package/docs/signal.md +113 -0
  461. package/docs/skills-config.md +58 -0
  462. package/docs/skills.md +149 -0
  463. package/docs/slack.md +158 -0
  464. package/docs/surface.md +20 -0
  465. package/docs/tailscale.md +71 -0
  466. package/docs/talk.md +79 -0
  467. package/docs/telegram.md +90 -0
  468. package/docs/templates/AGENTS.md +126 -0
  469. package/docs/templates/BOOTSTRAP.md +53 -0
  470. package/docs/templates/IDENTITY.md +17 -0
  471. package/docs/templates/SOUL.md +41 -0
  472. package/docs/templates/TOOLS.md +41 -0
  473. package/docs/templates/USER.md +22 -0
  474. package/docs/test.md +35 -0
  475. package/docs/thinking.md +46 -0
  476. package/docs/tools.md +248 -0
  477. package/docs/troubleshooting.md +227 -0
  478. package/docs/tui.md +69 -0
  479. package/docs/typebox.md +42 -0
  480. package/docs/voicewake.md +61 -0
  481. package/docs/web.md +115 -0
  482. package/docs/webchat.md +34 -0
  483. package/docs/webhook.md +132 -0
  484. package/docs/whatsapp-clawd.jpg +0 -0
  485. package/docs/whatsapp.md +142 -0
  486. package/docs/wizard.md +158 -0
  487. package/package.json +186 -0
  488. package/skills/apple-notes/SKILL.md +50 -0
  489. package/skills/apple-reminders/SKILL.md +67 -0
  490. package/skills/bear-notes/SKILL.md +79 -0
  491. package/skills/bird/SKILL.md +25 -0
  492. package/skills/blogwatcher/SKILL.md +46 -0
  493. package/skills/blucli/SKILL.md +27 -0
  494. package/skills/brave-search/SKILL.md +30 -0
  495. package/skills/brave-search/scripts/content.mjs +53 -0
  496. package/skills/brave-search/scripts/search.mjs +79 -0
  497. package/skills/camsnap/SKILL.md +25 -0
  498. package/skills/clawdhub/SKILL.md +53 -0
  499. package/skills/coding-agent/SKILL.md +275 -0
  500. package/skills/discord/SKILL.md +369 -0
  501. package/skills/eightctl/SKILL.md +29 -0
  502. package/skills/food-order/SKILL.md +41 -0
  503. package/skills/gemini/SKILL.md +23 -0
  504. package/skills/gifgrep/SKILL.md +47 -0
  505. package/skills/github/SKILL.md +47 -0
  506. package/skills/gog/SKILL.md +36 -0
  507. package/skills/goplaces/SKILL.md +30 -0
  508. package/skills/imsg/SKILL.md +25 -0
  509. package/skills/local-places/SERVER_README.md +101 -0
  510. package/skills/local-places/SKILL.md +91 -0
  511. package/skills/local-places/pyproject.toml +27 -0
  512. package/skills/local-places/src/local_places/__init__.py +2 -0
  513. package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  514. package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  515. package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  516. package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  517. package/skills/local-places/src/local_places/google_places.py +314 -0
  518. package/skills/local-places/src/local_places/main.py +65 -0
  519. package/skills/local-places/src/local_places/schemas.py +107 -0
  520. package/skills/mcporter/SKILL.md +38 -0
  521. package/skills/nano-banana-pro/SKILL.md +29 -0
  522. package/skills/nano-banana-pro/scripts/generate_image.py +167 -0
  523. package/skills/nano-pdf/SKILL.md +20 -0
  524. package/skills/notion/SKILL.md +156 -0
  525. package/skills/obsidian/SKILL.md +55 -0
  526. package/skills/openai-image-gen/SKILL.md +31 -0
  527. package/skills/openai-image-gen/scripts/gen.py +173 -0
  528. package/skills/openai-whisper/SKILL.md +19 -0
  529. package/skills/openai-whisper-api/SKILL.md +43 -0
  530. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  531. package/skills/openhue/SKILL.md +30 -0
  532. package/skills/oracle/SKILL.md +105 -0
  533. package/skills/ordercli/SKILL.md +47 -0
  534. package/skills/peekaboo/SKILL.md +153 -0
  535. package/skills/qmd/SKILL.md +26 -0
  536. package/skills/sag/SKILL.md +62 -0
  537. package/skills/slack/SKILL.md +143 -0
  538. package/skills/songsee/SKILL.md +29 -0
  539. package/skills/sonoscli/SKILL.md +26 -0
  540. package/skills/spotify-player/SKILL.md +34 -0
  541. package/skills/summarize/SKILL.md +49 -0
  542. package/skills/things-mac/SKILL.md +61 -0
  543. package/skills/tmux/SKILL.md +121 -0
  544. package/skills/tmux/scripts/find-sessions.sh +112 -0
  545. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  546. package/skills/trello/SKILL.md +84 -0
  547. package/skills/video-frames/SKILL.md +29 -0
  548. package/skills/video-frames/scripts/frame.sh +81 -0
  549. package/skills/wacli/SKILL.md +42 -0
  550. package/skills/weather/SKILL.md +49 -0
@@ -0,0 +1,1177 @@
1
+ ---
2
+ summary: "All configuration options for ~/.clawdbot/clawdbot.json with examples"
3
+ read_when:
4
+ - Adding or modifying config fields
5
+ ---
6
+ <!-- {% raw %} -->
7
+ # Configuration 🔧
8
+
9
+ CLAWDBOT reads an optional **JSON5** config from `~/.clawdbot/clawdbot.json` (comments + trailing commas allowed).
10
+
11
+ If the file is missing, CLAWDBOT uses safe-ish defaults (embedded Pi agent + per-sender sessions + workspace `~/clawd`). You usually only need a config to:
12
+ - restrict who can trigger the bot (`whatsapp.allowFrom`, `telegram.allowFrom`, etc.)
13
+ - control group mention behavior (`whatsapp.groups`, `telegram.groups`, `discord.guilds`, `routing.groupChat`)
14
+ - customize message prefixes (`messages`)
15
+ - set the agent's workspace (`agent.workspace`)
16
+ - tune the embedded agent (`agent`) and session behavior (`session`)
17
+ - set the agent's identity (`identity`)
18
+
19
+ ## Schema + UI hints
20
+
21
+ The Gateway exposes a JSON Schema representation of the config via `config.schema` for UI editors.
22
+ The Control UI renders a form from this schema, with a **Raw JSON** editor as an escape hatch.
23
+
24
+ Hints (labels, grouping, sensitive fields) ship alongside the schema so clients can render
25
+ better forms without hard-coding config knowledge.
26
+
27
+ ## Minimal config (recommended starting point)
28
+
29
+ ```json5
30
+ {
31
+ agent: { workspace: "~/clawd" },
32
+ whatsapp: { allowFrom: ["+15555550123"] }
33
+ }
34
+ ```
35
+
36
+ Build the default image once with:
37
+ ```bash
38
+ scripts/sandbox-setup.sh
39
+ ```
40
+
41
+ ## Self-chat mode (recommended for group control)
42
+
43
+ To prevent the bot from responding to WhatsApp @-mentions in groups (only respond to specific text triggers):
44
+
45
+ ```json5
46
+ {
47
+ agent: { workspace: "~/clawd" },
48
+ whatsapp: {
49
+ // Allowlist is DMs only; including your own number enables self-chat mode.
50
+ allowFrom: ["+15555550123"],
51
+ groups: { "*": { requireMention: true } }
52
+ },
53
+ routing: {
54
+ groupChat: {
55
+ mentionPatterns: ["@clawd", "reisponde"]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ## Common options
62
+
63
+ ### `identity`
64
+
65
+ Optional agent identity used for defaults and UX. This is written by the macOS onboarding assistant.
66
+
67
+ If set, CLAWDBOT derives defaults (only when you haven’t set them explicitly):
68
+ - `messages.responsePrefix` from `identity.emoji`
69
+ - `routing.groupChat.mentionPatterns` from `identity.name` (so “@Samantha” works in groups)
70
+
71
+ ```json5
72
+ {
73
+ identity: { name: "Samantha", theme: "helpful sloth", emoji: "🦥" }
74
+ }
75
+ ```
76
+
77
+ ### `wizard`
78
+
79
+ Metadata written by CLI wizards (`onboard`, `configure`, `doctor`, `update`).
80
+
81
+ ```json5
82
+ {
83
+ wizard: {
84
+ lastRunAt: "2026-01-01T00:00:00.000Z",
85
+ lastRunVersion: "2026.1.4",
86
+ lastRunCommit: "abc1234",
87
+ lastRunCommand: "configure",
88
+ lastRunMode: "local"
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### `logging`
94
+
95
+ - Default log file: `/tmp/clawdbot/clawdbot-YYYY-MM-DD.log`
96
+ - If you want a stable path, set `logging.file` to `/tmp/clawdbot/clawdbot.log`.
97
+ - Console output can be tuned separately via:
98
+ - `logging.consoleLevel` (defaults to `info`, bumps to `debug` when `--verbose`)
99
+ - `logging.consoleStyle` (`pretty` | `compact` | `json`)
100
+
101
+ ```json5
102
+ {
103
+ logging: {
104
+ level: "info",
105
+ file: "/tmp/clawdbot/clawdbot.log",
106
+ consoleLevel: "info",
107
+ consoleStyle: "pretty"
108
+ }
109
+ }
110
+ ```
111
+
112
+ ### `whatsapp.allowFrom`
113
+
114
+ Allowlist of E.164 phone numbers that may trigger WhatsApp auto-replies (DMs only).
115
+ If empty, the default allowlist is your own WhatsApp number (self-chat mode).
116
+
117
+ ```json5
118
+ {
119
+ whatsapp: {
120
+ allowFrom: ["+15555550123", "+447700900123"],
121
+ textChunkLimit: 4000 // optional outbound chunk size (chars)
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### `routing.groupChat`
127
+
128
+ Group messages default to **require mention** (either metadata mention or regex patterns). Applies to WhatsApp, Telegram, Discord, and iMessage group chats.
129
+
130
+ **Mention types:**
131
+ - **Metadata mentions**: Native platform @-mentions (e.g., WhatsApp tap-to-mention). Ignored in WhatsApp self-chat mode (see `whatsapp.allowFrom`).
132
+ - **Text patterns**: Regex patterns defined in `mentionPatterns`. Always checked regardless of self-chat mode.
133
+
134
+ ```json5
135
+ {
136
+ routing: {
137
+ groupChat: {
138
+ mentionPatterns: ["@clawd", "clawdbot", "clawd"],
139
+ historyLimit: 50
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ Mention gating defaults live per provider (`whatsapp.groups`, `telegram.groups`, `imessage.groups`, `discord.guilds`).
146
+
147
+ To respond **only** to specific text triggers (ignoring native @-mentions):
148
+ ```json5
149
+ {
150
+ whatsapp: {
151
+ // Include your own number to enable self-chat mode (ignore native @-mentions).
152
+ allowFrom: ["+15555550123"],
153
+ groups: { "*": { requireMention: true } }
154
+ },
155
+ routing: {
156
+ groupChat: {
157
+ // Only these text patterns will trigger responses
158
+ mentionPatterns: ["reisponde", "@clawd"]
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### `routing.queue`
165
+
166
+ Controls how inbound messages behave when an agent run is already active.
167
+
168
+ ```json5
169
+ {
170
+ routing: {
171
+ queue: {
172
+ mode: "collect", // steer | followup | collect | steer-backlog (steer+backlog ok) | interrupt (queue=steer legacy)
173
+ debounceMs: 1000,
174
+ cap: 20,
175
+ drop: "summarize", // old | new | summarize
176
+ bySurface: {
177
+ whatsapp: "collect",
178
+ telegram: "collect",
179
+ discord: "collect",
180
+ imessage: "collect",
181
+ webchat: "collect"
182
+ }
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ ### `web` (WhatsApp web provider)
189
+
190
+ WhatsApp runs through the gateway’s web provider. It starts automatically when a linked session exists.
191
+ Set `web.enabled: false` to keep it off by default.
192
+
193
+ ```json5
194
+ {
195
+ web: {
196
+ enabled: true,
197
+ heartbeatSeconds: 60,
198
+ reconnect: {
199
+ initialMs: 2000,
200
+ maxMs: 120000,
201
+ factor: 1.4,
202
+ jitter: 0.2,
203
+ maxAttempts: 0
204
+ }
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### `telegram` (bot transport)
210
+
211
+ Clawdbot starts Telegram only when a `telegram` config section exists. The bot token is resolved from `TELEGRAM_BOT_TOKEN` or `telegram.botToken`.
212
+ Set `telegram.enabled: false` to disable automatic startup.
213
+
214
+ ```json5
215
+ {
216
+ telegram: {
217
+ enabled: true,
218
+ botToken: "your-bot-token",
219
+ requireMention: true,
220
+ allowFrom: ["123456789"],
221
+ mediaMaxMb: 5,
222
+ proxy: "socks5://localhost:9050",
223
+ webhookUrl: "https://example.com/telegram-webhook",
224
+ webhookSecret: "secret",
225
+ webhookPath: "/telegram-webhook"
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### `discord` (bot transport)
231
+
232
+ Configure the Discord bot by setting the bot token and optional gating:
233
+
234
+ ```json5
235
+ {
236
+ discord: {
237
+ enabled: true,
238
+ token: "your-bot-token",
239
+ mediaMaxMb: 8, // clamp inbound media size
240
+ actions: { // tool action gates (false disables)
241
+ reactions: true,
242
+ stickers: true,
243
+ polls: true,
244
+ permissions: true,
245
+ messages: true,
246
+ threads: true,
247
+ pins: true,
248
+ search: true,
249
+ memberInfo: true,
250
+ roleInfo: true,
251
+ roles: false,
252
+ channelInfo: true,
253
+ voiceStatus: true,
254
+ events: true,
255
+ moderation: false
256
+ },
257
+ replyToMode: "off", // off | first | all
258
+ slashCommand: { // user-installed app slash commands
259
+ enabled: true,
260
+ name: "clawd",
261
+ sessionPrefix: "discord:slash",
262
+ ephemeral: true
263
+ },
264
+ dm: {
265
+ enabled: true, // disable all DMs when false
266
+ allowFrom: ["1234567890", "steipete"], // optional DM allowlist (ids or names)
267
+ groupEnabled: false, // enable group DMs
268
+ groupChannels: ["clawd-dm"] // optional group DM allowlist
269
+ },
270
+ guilds: {
271
+ "123456789012345678": { // guild id (preferred) or slug
272
+ slug: "friends-of-clawd",
273
+ requireMention: false, // per-guild default
274
+ reactionNotifications: "own", // off | own | all | allowlist
275
+ users: ["987654321098765432"], // optional per-guild user allowlist
276
+ channels: {
277
+ general: { allow: true },
278
+ help: { allow: true, requireMention: true }
279
+ }
280
+ }
281
+ },
282
+ historyLimit: 20 // include last N guild messages as context
283
+ }
284
+ }
285
+ ```
286
+
287
+ Clawdbot starts Discord only when a `discord` config section exists. The token is resolved from `DISCORD_BOT_TOKEN` or `discord.token` (unless `discord.enabled` is `false`). Use `user:<id>` (DM) or `channel:<id>` (guild channel) when specifying delivery targets for cron/CLI commands.
288
+ Guild slugs are lowercase with spaces replaced by `-`; channel keys use the slugged channel name (no leading `#`). Prefer guild ids as keys to avoid rename ambiguity.
289
+ Reaction notification modes:
290
+ - `off`: no reaction events.
291
+ - `own`: reactions on the bot's own messages (default).
292
+ - `all`: all reactions on all messages.
293
+ - `allowlist`: reactions from `guilds.<id>.users` on all messages (empty list disables).
294
+
295
+ ### `slack` (socket mode)
296
+
297
+ Slack runs in Socket Mode and requires both a bot token and app token:
298
+
299
+ ```json5
300
+ {
301
+ slack: {
302
+ enabled: true,
303
+ botToken: "xoxb-...",
304
+ appToken: "xapp-...",
305
+ dm: {
306
+ enabled: true,
307
+ allowFrom: ["U123", "U456", "*"],
308
+ groupEnabled: false,
309
+ groupChannels: ["G123"]
310
+ },
311
+ channels: {
312
+ C123: { allow: true, requireMention: true },
313
+ "#general": { allow: true, requireMention: false }
314
+ },
315
+ reactionNotifications: "own", // off | own | all | allowlist
316
+ reactionAllowlist: ["U123"],
317
+ actions: {
318
+ reactions: true,
319
+ messages: true,
320
+ pins: true,
321
+ memberInfo: true,
322
+ emojiList: true
323
+ },
324
+ slashCommand: {
325
+ enabled: true,
326
+ name: "clawd",
327
+ sessionPrefix: "slack:slash",
328
+ ephemeral: true
329
+ },
330
+ textChunkLimit: 4000,
331
+ mediaMaxMb: 20
332
+ }
333
+ }
334
+ ```
335
+
336
+ Clawdbot starts Slack when the provider is enabled and both tokens are set (via config or `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). Use `user:<id>` (DM) or `channel:<id>` when specifying delivery targets for cron/CLI commands.
337
+
338
+ Reaction notification modes:
339
+ - `off`: no reaction events.
340
+ - `own`: reactions on the bot's own messages (default).
341
+ - `all`: all reactions on all messages.
342
+ - `allowlist`: reactions from `slack.reactionAllowlist` on all messages (empty list disables).
343
+
344
+ Slack action groups (gate `slack` tool actions):
345
+ | Action group | Default | Notes |
346
+ | --- | --- | --- |
347
+ | reactions | enabled | React + list reactions |
348
+ | messages | enabled | Read/send/edit/delete |
349
+ | pins | enabled | Pin/unpin/list |
350
+ | memberInfo | enabled | Member info |
351
+ | emojiList | enabled | Custom emoji list |
352
+ ### `imessage` (imsg CLI)
353
+
354
+ Clawdbot spawns `imsg rpc` (JSON-RPC over stdio). No daemon or port required.
355
+
356
+ ```json5
357
+ {
358
+ imessage: {
359
+ enabled: true,
360
+ cliPath: "imsg",
361
+ dbPath: "~/Library/Messages/chat.db",
362
+ allowFrom: ["+15555550123", "user@example.com", "chat_id:123"],
363
+ includeAttachments: false,
364
+ mediaMaxMb: 16,
365
+ service: "auto",
366
+ region: "US"
367
+ }
368
+ }
369
+ ```
370
+
371
+ Notes:
372
+ - Requires Full Disk Access to the Messages DB.
373
+ - The first send will prompt for Messages automation permission.
374
+ - Prefer `chat_id:<id>` targets. Use `imsg chats --limit 20` to list chats.
375
+
376
+ ### `agent.workspace`
377
+
378
+ Sets the **single global workspace directory** used by the agent for file operations.
379
+
380
+ Default: `~/clawd`.
381
+
382
+ ```json5
383
+ {
384
+ agent: { workspace: "~/clawd" }
385
+ }
386
+ ```
387
+
388
+ If `agent.sandbox` is enabled, non-main sessions can override this with their
389
+ own per-session workspaces under `agent.sandbox.workspaceRoot`.
390
+
391
+ ### `messages`
392
+
393
+ Controls inbound/outbound prefixes and timestamps.
394
+
395
+ ```json5
396
+ {
397
+ messages: {
398
+ messagePrefix: "[clawdbot]",
399
+ responsePrefix: "🦞",
400
+ timestampPrefix: "Europe/London"
401
+ }
402
+ }
403
+ ```
404
+
405
+ ### `talk`
406
+
407
+ Defaults for Talk mode (macOS/iOS/Android). Voice IDs fall back to `ELEVENLABS_VOICE_ID` or `SAG_VOICE_ID` when unset.
408
+ `apiKey` falls back to `ELEVENLABS_API_KEY` (or the gateway’s shell profile) when unset.
409
+ `voiceAliases` lets Talk directives use friendly names (e.g. `"voice":"Clawd"`).
410
+
411
+ ```json5
412
+ {
413
+ talk: {
414
+ voiceId: "elevenlabs_voice_id",
415
+ voiceAliases: {
416
+ Clawd: "EXAVITQu4vr4xnSDxMaL",
417
+ Roger: "CwhRBWXzGAHq8TQ4Fs17"
418
+ },
419
+ modelId: "eleven_v3",
420
+ outputFormat: "mp3_44100_128",
421
+ apiKey: "elevenlabs_api_key",
422
+ interruptOnSpeech: true
423
+ }
424
+ }
425
+ ```
426
+
427
+ ### `agent`
428
+
429
+ Controls the embedded agent runtime (model/thinking/verbose/timeouts).
430
+ `allowedModels` lets `/model` list/filter and enforce a per-session allowlist
431
+ (omit to show the full catalog).
432
+ `modelAliases` adds short names for `/model` (alias -> provider/model).
433
+ `modelFallbacks` lists ordered fallback models to try when the default fails.
434
+ `imageModel` selects an image-capable model for the `image` tool.
435
+ `imageModelFallbacks` lists ordered fallback image models for the `image` tool.
436
+
437
+ ```json5
438
+ {
439
+ agent: {
440
+ model: "anthropic/claude-opus-4-5",
441
+ allowedModels: [
442
+ "anthropic/claude-opus-4-5",
443
+ "anthropic/claude-sonnet-4-1"
444
+ ],
445
+ modelAliases: {
446
+ Opus: "anthropic/claude-opus-4-5",
447
+ Sonnet: "anthropic/claude-sonnet-4-1"
448
+ },
449
+ modelFallbacks: [
450
+ "openrouter/deepseek/deepseek-r1:free",
451
+ "openrouter/meta-llama/llama-3.3-70b-instruct:free"
452
+ ],
453
+ imageModel: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
454
+ imageModelFallbacks: [
455
+ "openrouter/google/gemini-2.0-flash-vision:free"
456
+ ],
457
+ thinkingDefault: "low",
458
+ verboseDefault: "off",
459
+ elevatedDefault: "on",
460
+ timeoutSeconds: 600,
461
+ mediaMaxMb: 5,
462
+ heartbeat: {
463
+ every: "30m",
464
+ target: "last"
465
+ },
466
+ maxConcurrent: 3,
467
+ bash: {
468
+ backgroundMs: 10000,
469
+ timeoutSec: 1800,
470
+ cleanupMs: 1800000
471
+ },
472
+ contextTokens: 200000
473
+ }
474
+ }
475
+ ```
476
+
477
+ Block streaming:
478
+ - `agent.blockStreamingDefault`: `"on"`/`"off"` (default on).
479
+ - `agent.blockStreamingBreak`: `"text_end"` or `"message_end"` (default: text_end).
480
+ - `agent.blockStreamingChunk`: soft chunking for streamed blocks. Defaults to
481
+ 800–1200 chars, prefers paragraph breaks (`\n\n`), then newlines, then sentences.
482
+ Example:
483
+ ```json5
484
+ {
485
+ agent: {
486
+ blockStreamingChunk: { minChars: 800, maxChars: 1200 }
487
+ }
488
+ }
489
+ ```
490
+
491
+ `agent.model` should be set as `provider/model` (e.g. `anthropic/claude-opus-4-5`).
492
+ If `modelAliases` is configured, you may also use the alias key (e.g. `Opus`).
493
+ If you omit the provider, CLAWDBOT currently assumes `anthropic` as a temporary
494
+ deprecation fallback.
495
+ Z.AI models are available as `zai/<model>` (e.g. `zai/glm-4.7`) and require
496
+ `ZAI_API_KEY` (or legacy `Z_AI_API_KEY`) in the environment.
497
+
498
+ `agent.heartbeat` configures periodic heartbeat runs:
499
+ - `every`: duration string (`ms`, `s`, `m`, `h`); default unit minutes. Omit or set
500
+ `0m` to disable.
501
+ - `model`: optional override model for heartbeat runs (`provider/model`).
502
+ - `target`: optional delivery channel (`last`, `whatsapp`, `telegram`, `discord`, `imessage`, `none`). Default: `last`.
503
+ - `to`: optional recipient override (E.164 for WhatsApp, chat id for Telegram).
504
+ - `prompt`: optional override for the heartbeat body (default: `HEARTBEAT`).
505
+
506
+ `agent.bash` configures background bash defaults:
507
+ - `backgroundMs`: time before auto-background (ms, default 10000)
508
+ - `timeoutSec`: auto-kill after this runtime (seconds, default 1800)
509
+ - `cleanupMs`: how long to keep finished sessions in memory (ms, default 1800000)
510
+
511
+ `agent.elevated` controls elevated (host) bash access:
512
+ - `enabled`: allow elevated mode (default true)
513
+ - `allowFrom`: per-surface allowlists (empty = disabled)
514
+ - `whatsapp`: E.164 numbers
515
+ - `telegram`: chat ids or usernames
516
+ - `discord`: user ids or usernames (falls back to `discord.dm.allowFrom` if omitted)
517
+ - `signal`: E.164 numbers
518
+ - `imessage`: handles/chat ids
519
+ - `webchat`: session ids or usernames
520
+
521
+ Example:
522
+ ```json5
523
+ {
524
+ agent: {
525
+ elevated: {
526
+ enabled: true,
527
+ allowFrom: {
528
+ whatsapp: ["+15555550123"],
529
+ discord: ["steipete", "1234567890123"]
530
+ }
531
+ }
532
+ }
533
+ }
534
+ ```
535
+
536
+ `agent.maxConcurrent` sets the maximum number of embedded agent runs that can
537
+ execute in parallel across sessions. Each session is still serialized (one run
538
+ per session key at a time). Default: 1.
539
+
540
+ ### `agent.sandbox`
541
+
542
+ Optional per-session **Docker sandboxing** for the embedded agent. Intended for
543
+ non-main sessions so they cannot access your host system.
544
+
545
+ Defaults (if enabled):
546
+ - one container per session
547
+ - Debian bookworm-slim based image
548
+ - workspace per session under `~/.clawdbot/sandboxes`
549
+ - auto-prune: idle > 24h OR age > 7d
550
+ - tools: allow only `bash`, `process`, `read`, `write`, `edit` (deny wins)
551
+ - optional sandboxed browser (Chromium + CDP, noVNC observer)
552
+ - hardening knobs: `network`, `user`, `pidsLimit`, `memory`, `cpus`, `ulimits`, `seccompProfile`, `apparmorProfile`
553
+
554
+ ```json5
555
+ {
556
+ agent: {
557
+ sandbox: {
558
+ mode: "non-main", // off | non-main | all
559
+ perSession: true,
560
+ workspaceRoot: "~/.clawdbot/sandboxes",
561
+ docker: {
562
+ image: "clawdbot-sandbox:bookworm-slim",
563
+ containerPrefix: "clawdbot-sbx-",
564
+ workdir: "/workspace",
565
+ readOnlyRoot: true,
566
+ tmpfs: ["/tmp", "/var/tmp", "/run"],
567
+ network: "none",
568
+ user: "1000:1000",
569
+ capDrop: ["ALL"],
570
+ env: { LANG: "C.UTF-8" },
571
+ setupCommand: "apt-get update && apt-get install -y git curl jq",
572
+ pidsLimit: 256,
573
+ memory: "1g",
574
+ memorySwap: "2g",
575
+ cpus: 1,
576
+ ulimits: {
577
+ nofile: { soft: 1024, hard: 2048 },
578
+ nproc: 256
579
+ },
580
+ seccompProfile: "/path/to/seccomp.json",
581
+ apparmorProfile: "clawdbot-sandbox",
582
+ dns: ["1.1.1.1", "8.8.8.8"],
583
+ extraHosts: ["internal.service:10.0.0.5"]
584
+ },
585
+ browser: {
586
+ enabled: false,
587
+ image: "clawdbot-sandbox-browser:bookworm-slim",
588
+ containerPrefix: "clawdbot-sbx-browser-",
589
+ cdpPort: 9222,
590
+ vncPort: 5900,
591
+ noVncPort: 6080,
592
+ headless: false,
593
+ enableNoVnc: true
594
+ },
595
+ tools: {
596
+ allow: ["bash", "process", "read", "write", "edit"],
597
+ deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"]
598
+ },
599
+ prune: {
600
+ idleHours: 24, // 0 disables idle pruning
601
+ maxAgeDays: 7 // 0 disables max-age pruning
602
+ }
603
+ }
604
+ }
605
+ }
606
+ ```
607
+
608
+ Build the default sandbox image once with:
609
+ ```bash
610
+ scripts/sandbox-setup.sh
611
+ ```
612
+
613
+ Note: sandbox containers default to `network: "none"`; set `agent.sandbox.docker.network`
614
+ to `"bridge"` (or your custom network) if the agent needs outbound access.
615
+
616
+ Build the optional browser image with:
617
+ ```bash
618
+ scripts/sandbox-browser-setup.sh
619
+ ```
620
+
621
+ When `agent.sandbox.browser.enabled=true`, the browser tool uses a sandboxed
622
+ Chromium instance (CDP). If noVNC is enabled (default when headless=false),
623
+ the noVNC URL is injected into the system prompt so the agent can reference it.
624
+ This does not require `browser.enabled` in the main config; the sandbox control
625
+ URL is injected per session.
626
+
627
+ ### `models` (custom providers + base URLs)
628
+
629
+ Clawdbot uses the **pi-coding-agent** model catalog. You can add custom providers
630
+ (LiteLLM, local OpenAI-compatible servers, Anthropic proxies, etc.) by writing
631
+ `~/.clawdbot/agent/models.json` or by defining the same schema inside your
632
+ Clawdbot config under `models.providers`.
633
+
634
+ When `models.providers` is present, Clawdbot writes/merges a `models.json` into
635
+ `~/.clawdbot/agent/` on startup:
636
+ - default behavior: **merge** (keeps existing providers, overrides on name)
637
+ - set `models.mode: "replace"` to overwrite the file contents
638
+
639
+ Select the model via `agent.model` (provider/model).
640
+
641
+ ```json5
642
+ {
643
+ agent: { model: "custom-proxy/llama-3.1-8b" },
644
+ models: {
645
+ mode: "merge",
646
+ providers: {
647
+ "custom-proxy": {
648
+ baseUrl: "http://localhost:4000/v1",
649
+ apiKey: "LITELLM_KEY",
650
+ api: "openai-completions",
651
+ models: [
652
+ {
653
+ id: "llama-3.1-8b",
654
+ name: "Llama 3.1 8B",
655
+ reasoning: false,
656
+ input: ["text"],
657
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
658
+ contextWindow: 128000,
659
+ maxTokens: 32000
660
+ }
661
+ ]
662
+ }
663
+ }
664
+ }
665
+ }
666
+ ```
667
+
668
+ ### Local models (LM Studio) — recommended setup
669
+
670
+ Best current local setup (what we’re running): **MiniMax M2.1** on a beefy Mac Studio
671
+ via **LM Studio** using the **Responses API**.
672
+
673
+ ```json5
674
+ {
675
+ agent: {
676
+ model: "Minimax",
677
+ allowedModels: [
678
+ "anthropic/claude-opus-4-5",
679
+ "lmstudio/minimax-m2.1-gs32"
680
+ ],
681
+ modelAliases: {
682
+ Opus: "anthropic/claude-opus-4-5",
683
+ Minimax: "lmstudio/minimax-m2.1-gs32"
684
+ }
685
+ },
686
+ models: {
687
+ mode: "merge",
688
+ providers: {
689
+ lmstudio: {
690
+ baseUrl: "http://127.0.0.1:1234/v1",
691
+ apiKey: "lmstudio",
692
+ api: "openai-responses",
693
+ models: [
694
+ {
695
+ id: "minimax-m2.1-gs32",
696
+ name: "MiniMax M2.1 GS32",
697
+ reasoning: false,
698
+ input: ["text"],
699
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
700
+ contextWindow: 196608,
701
+ maxTokens: 8192
702
+ }
703
+ ]
704
+ }
705
+ }
706
+ }
707
+ }
708
+ ```
709
+
710
+ Notes:
711
+ - LM Studio must have the model loaded and the local server enabled (default URL above).
712
+ - Responses API enables clean reasoning/output separation; WhatsApp sees only final text.
713
+ - Adjust `contextWindow`/`maxTokens` if your LM Studio context length differs.
714
+
715
+ Notes:
716
+ - Supported APIs: `openai-completions`, `openai-responses`, `anthropic-messages`,
717
+ `google-generative-ai`
718
+ - Use `authHeader: true` + `headers` for custom auth needs.
719
+ - Override the agent config root with `CLAWDBOT_AGENT_DIR` (or `PI_CODING_AGENT_DIR`)
720
+ if you want `models.json` stored elsewhere.
721
+
722
+ ### `session`
723
+
724
+ Controls session scoping, idle expiry, reset triggers, and where the session store is written.
725
+
726
+ ```json5
727
+ {
728
+ session: {
729
+ scope: "per-sender",
730
+ idleMinutes: 60,
731
+ resetTriggers: ["/new", "/reset"],
732
+ store: "~/.clawdbot/sessions/sessions.json",
733
+ // mainKey is ignored; primary key is fixed to "main"
734
+ agentToAgent: {
735
+ // Max ping-pong reply turns between requester/target (0–5).
736
+ maxPingPongTurns: 5
737
+ },
738
+ sendPolicy: {
739
+ rules: [
740
+ { action: "deny", match: { surface: "discord", chatType: "group" } }
741
+ ],
742
+ default: "allow"
743
+ }
744
+ }
745
+ }
746
+ ```
747
+
748
+ Fields:
749
+ - `agentToAgent.maxPingPongTurns`: max reply-back turns between requester/target (0–5, default 5).
750
+ - `sendPolicy.default`: `allow` or `deny` fallback when no rule matches.
751
+ - `sendPolicy.rules[]`: match by `surface` (provider), `chatType` (`direct|group|room`), or `keyPrefix` (e.g. `cron:`). First deny wins; otherwise allow.
752
+
753
+ ### `skills` (skills config)
754
+
755
+ Controls bundled allowlist, install preferences, extra skill folders, and per-skill
756
+ overrides. Applies to **bundled** skills and `~/.clawdbot/skills` (workspace skills
757
+ still win on name conflicts).
758
+
759
+ Fields:
760
+ - `allowBundled`: optional allowlist for **bundled** skills only. If set, only those
761
+ bundled skills are eligible (managed/workspace skills unaffected).
762
+ - `load.extraDirs`: additional skill directories to scan (lowest precedence).
763
+ - `install.preferBrew`: prefer brew installers when available (default: true).
764
+ - `install.nodeManager`: node installer preference (`npm` | `pnpm` | `yarn`, default: npm).
765
+ - `entries.<skillKey>`: per-skill config overrides.
766
+
767
+ Per-skill fields:
768
+ - `enabled`: set `false` to disable a skill even if it’s bundled/installed.
769
+ - `env`: environment variables injected for the agent run (only if not already set).
770
+ - `apiKey`: optional convenience for skills that declare a primary env var (e.g. `nano-banana-pro` → `GEMINI_API_KEY`).
771
+
772
+ Example:
773
+
774
+ ```json5
775
+ {
776
+ skills: {
777
+ allowBundled: ["brave-search", "gemini"],
778
+ load: {
779
+ extraDirs: [
780
+ "~/Projects/agent-scripts/skills",
781
+ "~/Projects/oss/some-skill-pack/skills"
782
+ ]
783
+ },
784
+ install: {
785
+ preferBrew: true,
786
+ nodeManager: "npm"
787
+ },
788
+ entries: {
789
+ "nano-banana-pro": {
790
+ apiKey: "GEMINI_KEY_HERE",
791
+ env: {
792
+ GEMINI_API_KEY: "GEMINI_KEY_HERE"
793
+ }
794
+ },
795
+ peekaboo: { enabled: true },
796
+ sag: { enabled: false }
797
+ }
798
+ }
799
+ }
800
+ ```
801
+
802
+ ### `browser` (clawd-managed Chrome)
803
+
804
+ Clawdbot can start a **dedicated, isolated** Chrome/Chromium instance for clawd and expose a small loopback control server.
805
+ Profiles can point at a **remote** Chrome via `profiles.<name>.cdpUrl`. Remote
806
+ profiles are attach-only (start/stop/reset are disabled).
807
+
808
+ `browser.cdpUrl` remains for legacy single-profile configs and as the base
809
+ scheme/host for profiles that only set `cdpPort`.
810
+
811
+ Defaults:
812
+ - enabled: `true`
813
+ - control URL: `http://127.0.0.1:18791` (CDP uses `18792`)
814
+ - CDP URL: `http://127.0.0.1:18792` (control URL + 1, legacy single-profile)
815
+ - profile color: `#FF4500` (lobster-orange)
816
+ - Note: the control server is started by the running gateway (Clawdbot.app menubar, or `clawdbot gateway`).
817
+
818
+ ```json5
819
+ {
820
+ browser: {
821
+ enabled: true,
822
+ controlUrl: "http://127.0.0.1:18791",
823
+ // cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override
824
+ defaultProfile: "clawd",
825
+ profiles: {
826
+ clawd: { cdpPort: 18800, color: "#FF4500" },
827
+ work: { cdpPort: 18801, color: "#0066CC" },
828
+ remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" }
829
+ },
830
+ color: "#FF4500",
831
+ // Advanced:
832
+ // headless: false,
833
+ // noSandbox: false,
834
+ // executablePath: "/usr/bin/chromium",
835
+ // attachOnly: false, // set true when tunneling a remote CDP to localhost
836
+ }
837
+ }
838
+ ```
839
+
840
+ ### `ui` (Appearance)
841
+
842
+ Optional accent color used by the native apps for UI chrome (e.g. Talk Mode bubble tint).
843
+
844
+ If unset, clients fall back to a muted light-blue.
845
+
846
+ ```json5
847
+ {
848
+ ui: {
849
+ seamColor: "#FF4500" // hex (RRGGBB or #RRGGBB)
850
+ }
851
+ }
852
+ ```
853
+
854
+ ### `gateway` (Gateway server mode + bind)
855
+
856
+ Use `gateway.mode` to explicitly declare whether this machine should run the Gateway.
857
+
858
+ Defaults:
859
+ - mode: **unset** (treated as “do not auto-start”)
860
+ - bind: `loopback`
861
+ - port: `18789` (single port for WS + HTTP)
862
+
863
+ ```json5
864
+ {
865
+ gateway: {
866
+ mode: "local", // or "remote"
867
+ port: 18789, // WS + HTTP multiplex
868
+ bind: "loopback",
869
+ // controlUi: { enabled: true, basePath: "/clawdbot" }
870
+ // auth: { mode: "token", token: "your-token" } // token is for multi-machine CLI access
871
+ // tailscale: { mode: "off" | "serve" | "funnel" }
872
+ }
873
+ }
874
+ ```
875
+
876
+ Control UI base path:
877
+ - `gateway.controlUi.basePath` sets the URL prefix where the Control UI is served.
878
+ - Examples: `"/ui"`, `"/clawdbot"`, `"/apps/clawdbot"`.
879
+ - Default: root (`/`) (unchanged).
880
+
881
+ Notes:
882
+ - `clawdbot gateway` refuses to start unless `gateway.mode` is set to `local` (or you pass the override flag).
883
+ - `gateway.port` controls the single multiplexed port used for WebSocket + HTTP (control UI, hooks, A2UI).
884
+ - Precedence: `--port` > `CLAWDBOT_GATEWAY_PORT` > `gateway.port` > default `18789`.
885
+
886
+ Auth and Tailscale:
887
+ - `gateway.auth.mode` sets the handshake requirements (`token` or `password`).
888
+ - `gateway.auth.token` stores the shared token for token auth (used by the CLI on the same machine).
889
+ - When `gateway.auth.mode` is set, only that method is accepted (plus optional Tailscale headers).
890
+ - `gateway.auth.password` can be set here, or via `CLAWDBOT_GATEWAY_PASSWORD` (recommended).
891
+ - `gateway.auth.allowTailscale` controls whether Tailscale identity headers can satisfy auth.
892
+ - `gateway.tailscale.mode: "serve"` uses Tailscale Serve (tailnet only, loopback bind).
893
+ - `gateway.tailscale.mode: "funnel"` exposes the dashboard publicly; requires auth.
894
+ - `gateway.tailscale.resetOnExit` resets Serve/Funnel config on shutdown.
895
+
896
+ Remote client defaults (CLI):
897
+ - `gateway.remote.url` sets the default Gateway WebSocket URL for CLI calls when `gateway.mode = "remote"`.
898
+ - `gateway.remote.token` supplies the token for remote calls (leave unset for no auth).
899
+ - `gateway.remote.password` supplies the password for remote calls (leave unset for no auth).
900
+
901
+ macOS app behavior:
902
+ - Clawdbot.app watches `~/.clawdbot/clawdbot.json` and switches modes live when `gateway.mode` or `gateway.remote.url` changes.
903
+ - If `gateway.mode` is unset but `gateway.remote.url` is set, the macOS app treats it as remote mode.
904
+ - When you change connection mode in the macOS app, it writes `gateway.mode` (and `gateway.remote.url` in remote mode) back to the config file.
905
+
906
+ ```json5
907
+ {
908
+ gateway: {
909
+ mode: "remote",
910
+ remote: {
911
+ url: "ws://gateway.tailnet:18789",
912
+ token: "your-token",
913
+ password: "your-password"
914
+ }
915
+ }
916
+ }
917
+ ```
918
+
919
+ ### `gateway.reload` (Config hot reload)
920
+
921
+ The Gateway watches `~/.clawdbot/clawdbot.json` (or `CLAWDBOT_CONFIG_PATH`) and applies changes automatically.
922
+
923
+ Modes:
924
+ - `hybrid` (default): hot-apply safe changes; restart the Gateway for critical changes.
925
+ - `hot`: only apply hot-safe changes; log when a restart is required.
926
+ - `restart`: restart the Gateway on any config change.
927
+ - `off`: disable hot reload.
928
+
929
+ ```json5
930
+ {
931
+ gateway: {
932
+ reload: {
933
+ mode: "hybrid",
934
+ debounceMs: 300
935
+ }
936
+ }
937
+ }
938
+ ```
939
+
940
+ #### Hot reload matrix (files + impact)
941
+
942
+ Files watched:
943
+ - `~/.clawdbot/clawdbot.json` (or `CLAWDBOT_CONFIG_PATH`)
944
+
945
+ Hot-applied (no full gateway restart):
946
+ - `hooks` (webhook auth/path/mappings) + `hooks.gmail` (Gmail watcher restarted)
947
+ - `browser` (browser control server restart)
948
+ - `cron` (cron service restart + concurrency update)
949
+ - `agent.heartbeat` (heartbeat runner restart)
950
+ - `web` (WhatsApp web provider restart)
951
+ - `telegram`, `discord`, `signal`, `imessage` (provider restarts)
952
+ - `agent`, `models`, `routing`, `messages`, `session`, `whatsapp`, `logging`, `skills`, `ui`, `talk`, `identity`, `wizard` (dynamic reads)
953
+
954
+ Requires full Gateway restart:
955
+ - `gateway` (port/bind/auth/control UI/tailscale)
956
+ - `bridge`
957
+ - `discovery`
958
+ - `canvasHost`
959
+ - Any unknown/unsupported config path (defaults to restart for safety)
960
+
961
+ ### Multi-instance isolation
962
+
963
+ To run multiple gateways on one host, isolate per-instance state + config and use unique ports:
964
+ - `CLAWDBOT_CONFIG_PATH` (per-instance config)
965
+ - `CLAWDBOT_STATE_DIR` (sessions/creds/logs)
966
+ - `agent.workspace` (memories)
967
+ - `gateway.port` (unique per instance)
968
+
969
+ Example:
970
+ ```bash
971
+ CLAWDBOT_CONFIG_PATH=~/.clawdbot/a.json \
972
+ CLAWDBOT_STATE_DIR=~/.clawdbot-a \
973
+ clawdbot gateway --port 19001
974
+ ```
975
+
976
+ ### `hooks` (Gateway webhooks)
977
+
978
+ Enable a simple HTTP webhook surface on the Gateway HTTP server.
979
+
980
+ Defaults:
981
+ - enabled: `false`
982
+ - path: `/hooks`
983
+ - maxBodyBytes: `262144` (256 KB)
984
+
985
+ ```json5
986
+ {
987
+ hooks: {
988
+ enabled: true,
989
+ token: "shared-secret",
990
+ path: "/hooks",
991
+ presets: ["gmail"],
992
+ transformsDir: "~/.clawdbot/hooks",
993
+ mappings: [
994
+ {
995
+ match: { path: "gmail" },
996
+ action: "agent",
997
+ wakeMode: "now",
998
+ name: "Gmail",
999
+ sessionKey: "hook:gmail:{{messages[0].id}}",
1000
+ messageTemplate:
1001
+ "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}",
1002
+ },
1003
+ ],
1004
+ }
1005
+ }
1006
+ ```
1007
+
1008
+ Requests must include the hook token:
1009
+ - `Authorization: Bearer <token>` **or**
1010
+ - `x-clawdbot-token: <token>` **or**
1011
+ - `?token=<token>`
1012
+
1013
+ Endpoints:
1014
+ - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }`
1015
+ - `POST /hooks/agent` → `{ message, name?, sessionKey?, wakeMode?, deliver?, channel?, to?, thinking?, timeoutSeconds? }`
1016
+ - `POST /hooks/<name>` → resolved via `hooks.mappings`
1017
+
1018
+ `/hooks/agent` always posts a summary into the main session (and can optionally trigger an immediate heartbeat via `wakeMode: "now"`).
1019
+
1020
+ Mapping notes:
1021
+ - `match.path` matches the sub-path after `/hooks` (e.g. `/hooks/gmail` → `gmail`).
1022
+ - `match.source` matches a payload field (e.g. `{ source: "gmail" }`) so you can use a generic `/hooks/ingest` path.
1023
+ - Templates like `{{messages[0].subject}}` read from the payload.
1024
+ - `transform` can point to a JS/TS module that returns a hook action.
1025
+
1026
+ Gmail helper config (used by `clawdbot hooks gmail setup` / `run`):
1027
+
1028
+ ```json5
1029
+ {
1030
+ hooks: {
1031
+ gmail: {
1032
+ account: "clawdbot@gmail.com",
1033
+ topic: "projects/<project-id>/topics/gog-gmail-watch",
1034
+ subscription: "gog-gmail-watch-push",
1035
+ pushToken: "shared-push-token",
1036
+ hookUrl: "http://127.0.0.1:18789/hooks/gmail",
1037
+ includeBody: true,
1038
+ maxBytes: 20000,
1039
+ renewEveryMinutes: 720,
1040
+ serve: { bind: "127.0.0.1", port: 8788, path: "/" },
1041
+ tailscale: { mode: "funnel", path: "/gmail-pubsub" },
1042
+ }
1043
+ }
1044
+ }
1045
+ ```
1046
+
1047
+ Gateway auto-start:
1048
+ - If `hooks.enabled=true` and `hooks.gmail.account` is set, the Gateway starts
1049
+ `gog gmail watch serve` on boot and auto-renews the watch.
1050
+ - Set `CLAWDBOT_SKIP_GMAIL_WATCHER=1` to disable the auto-start (for manual runs).
1051
+ - Avoid running a separate `gog gmail watch serve` alongside the Gateway; it will
1052
+ fail with `listen tcp 127.0.0.1:8788: bind: address already in use`.
1053
+
1054
+ Note: when `tailscale.mode` is on, Clawdbot defaults `serve.path` to `/` so
1055
+ Tailscale can proxy `/gmail-pubsub` correctly (it strips the set-path prefix).
1056
+
1057
+ ### `canvasHost` (LAN/tailnet Canvas file server + live reload)
1058
+
1059
+ The Gateway serves a directory of HTML/CSS/JS over HTTP so iOS/Android nodes can simply `canvas.navigate` to it.
1060
+
1061
+ Default root: `~/clawd/canvas`
1062
+ Default port: `18793` (chosen to avoid the clawd browser CDP port `18792`)
1063
+ The server listens on the **bridge bind host** (LAN or Tailnet) so nodes can reach it.
1064
+
1065
+ The server:
1066
+ - serves files under `canvasHost.root`
1067
+ - injects a tiny live-reload client into served HTML
1068
+ - watches the directory and broadcasts reloads over a WebSocket endpoint at `/__clawdbot/ws`
1069
+ - auto-creates a starter `index.html` when the directory is empty (so you see something immediately)
1070
+ - also serves A2UI at `/__clawdbot__/a2ui/` and is advertised to nodes as `canvasHostUrl`
1071
+ (always used by nodes for Canvas/A2UI)
1072
+
1073
+ Disable live reload (and file watching) if the directory is large or you hit `EMFILE`:
1074
+ - config: `canvasHost: { liveReload: false }`
1075
+
1076
+ ```json5
1077
+ {
1078
+ canvasHost: {
1079
+ root: "~/clawd/canvas",
1080
+ port: 18793,
1081
+ liveReload: true
1082
+ }
1083
+ }
1084
+ ```
1085
+
1086
+ Changes to `canvasHost.*` require a gateway restart (config reload will restart).
1087
+
1088
+ Disable with:
1089
+ - config: `canvasHost: { enabled: false }`
1090
+ - env: `CLAWDBOT_SKIP_CANVAS_HOST=1`
1091
+
1092
+ ### `bridge` (node bridge server)
1093
+
1094
+ The Gateway can expose a simple TCP bridge for nodes (iOS/Android), typically on port `18790`.
1095
+
1096
+ Defaults:
1097
+ - enabled: `true`
1098
+ - port: `18790`
1099
+ - bind: `lan` (binds to `0.0.0.0`)
1100
+
1101
+ Bind modes:
1102
+ - `lan`: `0.0.0.0` (reachable on any interface, including LAN/Wi‑Fi and Tailscale)
1103
+ - `tailnet`: bind only to the machine’s Tailscale IP (recommended for Vienna ⇄ London)
1104
+ - `loopback`: `127.0.0.1` (local only)
1105
+ - `auto`: prefer tailnet IP if present, else `lan`
1106
+
1107
+ ```json5
1108
+ {
1109
+ bridge: {
1110
+ enabled: true,
1111
+ port: 18790,
1112
+ bind: "tailnet"
1113
+ }
1114
+ }
1115
+ ```
1116
+
1117
+ ### `discovery.wideArea` (Wide-Area Bonjour / unicast DNS‑SD)
1118
+
1119
+ When enabled, the Gateway writes a unicast DNS-SD zone for `_clawdbot-bridge._tcp` under `~/.clawdbot/dns/` using the standard discovery domain `clawdbot.internal.`
1120
+
1121
+ To make iOS/Android discover across networks (Vienna ⇄ London), pair this with:
1122
+ - a DNS server on the gateway host serving `clawdbot.internal.` (CoreDNS is recommended)
1123
+ - Tailscale **split DNS** so clients resolve `clawdbot.internal` via that server
1124
+
1125
+ One-time setup helper (gateway host):
1126
+
1127
+ ```bash
1128
+ clawdbot dns setup --apply
1129
+ ```
1130
+
1131
+ ```json5
1132
+ {
1133
+ discovery: { wideArea: { enabled: true } }
1134
+ }
1135
+ ```
1136
+
1137
+ ## Template variables
1138
+
1139
+ Template placeholders are expanded in `routing.transcribeAudio.command` (and any future templated command fields).
1140
+
1141
+ | Variable | Description |
1142
+ |----------|-------------|
1143
+ | `{{Body}}` | Full inbound message body |
1144
+ | `{{BodyStripped}}` | Body with group mentions stripped (best default for agents) |
1145
+ | `{{From}}` | Sender identifier (E.164 for WhatsApp; may differ per surface) |
1146
+ | `{{To}}` | Destination identifier |
1147
+ | `{{MessageSid}}` | Provider message id (when available) |
1148
+ | `{{SessionId}}` | Current session UUID |
1149
+ | `{{IsNewSession}}` | `"true"` when a new session was created |
1150
+ | `{{MediaUrl}}` | Inbound media pseudo-URL (if present) |
1151
+ | `{{MediaPath}}` | Local media path (if downloaded) |
1152
+ | `{{MediaType}}` | Media type (image/audio/document/…) |
1153
+ | `{{Transcript}}` | Audio transcript (when enabled) |
1154
+ | `{{ChatType}}` | `"direct"` or `"group"` |
1155
+ | `{{GroupSubject}}` | Group subject (best effort) |
1156
+ | `{{GroupMembers}}` | Group members preview (best effort) |
1157
+ | `{{SenderName}}` | Sender display name (best effort) |
1158
+ | `{{SenderE164}}` | Sender phone number (best effort) |
1159
+ | `{{Surface}}` | Surface hint (whatsapp|telegram|discord|imessage|webchat|…) |
1160
+
1161
+ ## Cron (Gateway scheduler)
1162
+
1163
+ Cron is a Gateway-owned scheduler for wakeups and scheduled jobs. See [Cron + wakeups](./cron.md) for the full RFC and CLI examples.
1164
+
1165
+ ```json5
1166
+ {
1167
+ cron: {
1168
+ enabled: true,
1169
+ maxConcurrentRuns: 2
1170
+ }
1171
+ }
1172
+ ```
1173
+
1174
+ ---
1175
+
1176
+ *Next: [Agent Runtime](./agent.md)* 🦞
1177
+ <!-- {% endraw %} -->