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,37 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import * as os from "node:os";
3
+ import * as path from "node:path";
4
+ import { writeBase64ToFile } from "./nodes-camera.js";
5
+ function asRecord(value) {
6
+ return typeof value === "object" && value !== null
7
+ ? value
8
+ : {};
9
+ }
10
+ function asString(value) {
11
+ return typeof value === "string" ? value : undefined;
12
+ }
13
+ export function parseScreenRecordPayload(value) {
14
+ const obj = asRecord(value);
15
+ const format = asString(obj.format);
16
+ const base64 = asString(obj.base64);
17
+ if (!format || !base64) {
18
+ throw new Error("invalid screen.record payload");
19
+ }
20
+ return {
21
+ format,
22
+ base64,
23
+ durationMs: typeof obj.durationMs === "number" ? obj.durationMs : undefined,
24
+ fps: typeof obj.fps === "number" ? obj.fps : undefined,
25
+ screenIndex: typeof obj.screenIndex === "number" ? obj.screenIndex : undefined,
26
+ hasAudio: typeof obj.hasAudio === "boolean" ? obj.hasAudio : undefined,
27
+ };
28
+ }
29
+ export function screenRecordTempPath(opts) {
30
+ const tmpDir = opts.tmpDir ?? os.tmpdir();
31
+ const id = opts.id ?? randomUUID();
32
+ const ext = opts.ext.startsWith(".") ? opts.ext : `.${opts.ext}`;
33
+ return path.join(tmpDir, `clawdbot-screen-record-${id}${ext}`);
34
+ }
35
+ export async function writeScreenRecordToFile(filePath, base64) {
36
+ return writeBase64ToFile(filePath, base64);
37
+ }
@@ -0,0 +1,20 @@
1
+ export function parseDurationMs(raw, opts) {
2
+ const trimmed = String(raw ?? "")
3
+ .trim()
4
+ .toLowerCase();
5
+ if (!trimmed)
6
+ throw new Error("invalid duration (empty)");
7
+ const m = /^(\d+(?:\.\d+)?)(ms|s|m|h)?$/.exec(trimmed);
8
+ if (!m)
9
+ throw new Error(`invalid duration: ${raw}`);
10
+ const value = Number(m[1]);
11
+ if (!Number.isFinite(value) || value < 0) {
12
+ throw new Error(`invalid duration: ${raw}`);
13
+ }
14
+ const unit = (m[2] ?? opts?.defaultUnit ?? "ms");
15
+ const multiplier = unit === "ms" ? 1 : unit === "s" ? 1000 : unit === "m" ? 60_000 : 3_600_000;
16
+ const ms = Math.round(value * multiplier);
17
+ if (!Number.isFinite(ms))
18
+ throw new Error(`invalid duration: ${raw}`);
19
+ return ms;
20
+ }
@@ -0,0 +1,97 @@
1
+ import { execFileSync } from "node:child_process";
2
+ function sleep(ms) {
3
+ return new Promise((resolve) => setTimeout(resolve, ms));
4
+ }
5
+ export function parseLsofOutput(output) {
6
+ const lines = output.split(/\r?\n/).filter(Boolean);
7
+ const results = [];
8
+ let current = {};
9
+ for (const line of lines) {
10
+ if (line.startsWith("p")) {
11
+ if (current.pid)
12
+ results.push(current);
13
+ current = { pid: Number.parseInt(line.slice(1), 10) };
14
+ }
15
+ else if (line.startsWith("c")) {
16
+ current.command = line.slice(1);
17
+ }
18
+ }
19
+ if (current.pid)
20
+ results.push(current);
21
+ return results;
22
+ }
23
+ export function listPortListeners(port) {
24
+ try {
25
+ const out = execFileSync("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-FpFc"], { encoding: "utf-8" });
26
+ return parseLsofOutput(out);
27
+ }
28
+ catch (err) {
29
+ const status = err.status;
30
+ const code = err.code;
31
+ if (code === "ENOENT") {
32
+ throw new Error("lsof not found; required for --force");
33
+ }
34
+ if (status === 1)
35
+ return []; // no listeners
36
+ throw err instanceof Error ? err : new Error(String(err));
37
+ }
38
+ }
39
+ export function forceFreePort(port) {
40
+ const listeners = listPortListeners(port);
41
+ for (const proc of listeners) {
42
+ try {
43
+ process.kill(proc.pid, "SIGTERM");
44
+ }
45
+ catch (err) {
46
+ throw new Error(`failed to kill pid ${proc.pid}${proc.command ? ` (${proc.command})` : ""}: ${String(err)}`);
47
+ }
48
+ }
49
+ return listeners;
50
+ }
51
+ function killPids(listeners, signal) {
52
+ for (const proc of listeners) {
53
+ try {
54
+ process.kill(proc.pid, signal);
55
+ }
56
+ catch (err) {
57
+ throw new Error(`failed to kill pid ${proc.pid}${proc.command ? ` (${proc.command})` : ""}: ${String(err)}`);
58
+ }
59
+ }
60
+ }
61
+ export async function forceFreePortAndWait(port, opts = {}) {
62
+ const timeoutMs = Math.max(opts.timeoutMs ?? 1500, 0);
63
+ const intervalMs = Math.max(opts.intervalMs ?? 100, 1);
64
+ const sigtermTimeoutMs = Math.min(Math.max(opts.sigtermTimeoutMs ?? 600, 0), timeoutMs);
65
+ const killed = forceFreePort(port);
66
+ if (killed.length === 0) {
67
+ return { killed, waitedMs: 0, escalatedToSigkill: false };
68
+ }
69
+ let waitedMs = 0;
70
+ const triesSigterm = intervalMs > 0 ? Math.ceil(sigtermTimeoutMs / intervalMs) : 0;
71
+ for (let i = 0; i < triesSigterm; i++) {
72
+ if (listPortListeners(port).length === 0) {
73
+ return { killed, waitedMs, escalatedToSigkill: false };
74
+ }
75
+ await sleep(intervalMs);
76
+ waitedMs += intervalMs;
77
+ }
78
+ if (listPortListeners(port).length === 0) {
79
+ return { killed, waitedMs, escalatedToSigkill: false };
80
+ }
81
+ const remaining = listPortListeners(port);
82
+ killPids(remaining, "SIGKILL");
83
+ const remainingBudget = Math.max(timeoutMs - waitedMs, 0);
84
+ const triesSigkill = intervalMs > 0 ? Math.ceil(remainingBudget / intervalMs) : 0;
85
+ for (let i = 0; i < triesSigkill; i++) {
86
+ if (listPortListeners(port).length === 0) {
87
+ return { killed, waitedMs, escalatedToSigkill: true };
88
+ }
89
+ await sleep(intervalMs);
90
+ waitedMs += intervalMs;
91
+ }
92
+ const still = listPortListeners(port);
93
+ if (still.length === 0) {
94
+ return { killed, waitedMs, escalatedToSigkill: true };
95
+ }
96
+ throw new Error(`port ${port} still has listeners after --force: ${still.map((p) => p.pid).join(", ")}`);
97
+ }
@@ -0,0 +1,406 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { agentCommand } from "../commands/agent.js";
4
+ import { configureCommand } from "../commands/configure.js";
5
+ import { doctorCommand } from "../commands/doctor.js";
6
+ import { healthCommand } from "../commands/health.js";
7
+ import { onboardCommand } from "../commands/onboard.js";
8
+ import { sendCommand } from "../commands/send.js";
9
+ import { sessionsCommand } from "../commands/sessions.js";
10
+ import { setupCommand } from "../commands/setup.js";
11
+ import { statusCommand } from "../commands/status.js";
12
+ import { updateCommand } from "../commands/update.js";
13
+ import { readConfigFileSnapshot } from "../config/config.js";
14
+ import { danger, setVerbose } from "../globals.js";
15
+ import { loginWeb, logoutWeb } from "../provider-web.js";
16
+ import { defaultRuntime } from "../runtime.js";
17
+ import { VERSION } from "../version.js";
18
+ import { registerBrowserCli } from "./browser-cli.js";
19
+ import { registerCanvasCli } from "./canvas-cli.js";
20
+ import { registerCronCli } from "./cron-cli.js";
21
+ import { createDefaultDeps } from "./deps.js";
22
+ import { registerDnsCli } from "./dns-cli.js";
23
+ import { registerGatewayCli } from "./gateway-cli.js";
24
+ import { registerHooksCli } from "./hooks-cli.js";
25
+ import { registerModelsCli } from "./models-cli.js";
26
+ import { registerNodesCli } from "./nodes-cli.js";
27
+ import { forceFreePort } from "./ports.js";
28
+ import { registerTuiCli } from "./tui-cli.js";
29
+ export { forceFreePort };
30
+ export function buildProgram() {
31
+ const program = new Command();
32
+ const PROGRAM_VERSION = VERSION;
33
+ const TAGLINE = "Send, receive, and auto-reply on WhatsApp (web) and Telegram (bot).";
34
+ program.name("clawdbot").description("").version(PROGRAM_VERSION);
35
+ const formatIntroLine = (version, rich = true) => {
36
+ const base = `📡 clawdbot ${version} — ${TAGLINE}`;
37
+ return rich && chalk.level > 0
38
+ ? `${chalk.bold.cyan("📡 clawdbot")} ${chalk.white(version)} ${chalk.gray("—")} ${chalk.green(TAGLINE)}`
39
+ : base;
40
+ };
41
+ program.configureHelp({
42
+ optionTerm: (option) => chalk.yellow(option.flags),
43
+ subcommandTerm: (cmd) => chalk.green(cmd.name()),
44
+ });
45
+ program.configureOutput({
46
+ writeOut: (str) => {
47
+ const colored = str
48
+ .replace(/^Usage:/gm, chalk.bold.cyan("Usage:"))
49
+ .replace(/^Options:/gm, chalk.bold.cyan("Options:"))
50
+ .replace(/^Commands:/gm, chalk.bold.cyan("Commands:"));
51
+ process.stdout.write(colored);
52
+ },
53
+ writeErr: (str) => process.stderr.write(str),
54
+ outputError: (str, write) => write(chalk.red(str)),
55
+ });
56
+ if (process.argv.includes("-V") ||
57
+ process.argv.includes("--version") ||
58
+ process.argv.includes("-v")) {
59
+ console.log(PROGRAM_VERSION);
60
+ process.exit(0);
61
+ }
62
+ program.addHelpText("beforeAll", `\n${formatIntroLine(PROGRAM_VERSION)}\n`);
63
+ program.hook("preAction", async (_thisCommand, actionCommand) => {
64
+ if (actionCommand.name() === "doctor")
65
+ return;
66
+ const snapshot = await readConfigFileSnapshot();
67
+ if (snapshot.legacyIssues.length === 0)
68
+ return;
69
+ const issues = snapshot.legacyIssues
70
+ .map((issue) => `- ${issue.path}: ${issue.message}`)
71
+ .join("\n");
72
+ defaultRuntime.error(danger(`Legacy config entries detected. Run "clawdbot doctor" (or ask your agent) to migrate.\n${issues}`));
73
+ process.exit(1);
74
+ });
75
+ const examples = [
76
+ [
77
+ "clawdbot login --verbose",
78
+ "Link personal WhatsApp Web and show QR + connection logs.",
79
+ ],
80
+ [
81
+ 'clawdbot send --to +15555550123 --message "Hi" --json',
82
+ "Send via your web session and print JSON result.",
83
+ ],
84
+ ["clawdbot gateway --port 18789", "Run the WebSocket Gateway locally."],
85
+ [
86
+ "clawdbot gateway --force",
87
+ "Kill anything bound to the default gateway port, then start it.",
88
+ ],
89
+ ["clawdbot gateway ...", "Gateway control via WebSocket."],
90
+ [
91
+ 'clawdbot agent --to +15555550123 --message "Run summary" --deliver',
92
+ "Talk directly to the agent using the Gateway; optionally send the WhatsApp reply.",
93
+ ],
94
+ [
95
+ 'clawdbot send --provider telegram --to @mychat --message "Hi"',
96
+ "Send via your Telegram bot.",
97
+ ],
98
+ ];
99
+ const fmtExamples = examples
100
+ .map(([cmd, desc]) => ` ${chalk.green(cmd)}\n ${chalk.gray(desc)}`)
101
+ .join("\n");
102
+ program.addHelpText("afterAll", `\n${chalk.bold.cyan("Examples:")}\n${fmtExamples}\n`);
103
+ program
104
+ .command("setup")
105
+ .description("Initialize ~/.clawdbot/clawdbot.json and the agent workspace")
106
+ .option("--workspace <dir>", "Agent workspace directory (default: ~/clawd; stored as agent.workspace)")
107
+ .option("--wizard", "Run the interactive onboarding wizard", false)
108
+ .option("--non-interactive", "Run the wizard without prompts", false)
109
+ .option("--mode <mode>", "Wizard mode: local|remote")
110
+ .option("--remote-url <url>", "Remote Gateway WebSocket URL")
111
+ .option("--remote-token <token>", "Remote Gateway token (optional)")
112
+ .action(async (opts) => {
113
+ try {
114
+ if (opts.wizard) {
115
+ await onboardCommand({
116
+ workspace: opts.workspace,
117
+ nonInteractive: Boolean(opts.nonInteractive),
118
+ mode: opts.mode,
119
+ remoteUrl: opts.remoteUrl,
120
+ remoteToken: opts.remoteToken,
121
+ }, defaultRuntime);
122
+ return;
123
+ }
124
+ await setupCommand({ workspace: opts.workspace }, defaultRuntime);
125
+ }
126
+ catch (err) {
127
+ defaultRuntime.error(String(err));
128
+ defaultRuntime.exit(1);
129
+ }
130
+ });
131
+ program
132
+ .command("onboard")
133
+ .description("Interactive wizard to set up the gateway, workspace, and skills")
134
+ .option("--workspace <dir>", "Agent workspace directory (default: ~/clawd)")
135
+ .option("--non-interactive", "Run without prompts", false)
136
+ .option("--mode <mode>", "Wizard mode: local|remote")
137
+ .option("--auth-choice <choice>", "Auth: oauth|apiKey|minimax|skip")
138
+ .option("--anthropic-api-key <key>", "Anthropic API key")
139
+ .option("--gateway-port <port>", "Gateway port")
140
+ .option("--gateway-bind <mode>", "Gateway bind: loopback|lan|tailnet|auto")
141
+ .option("--gateway-auth <mode>", "Gateway auth: off|token|password")
142
+ .option("--gateway-token <token>", "Gateway token (token auth)")
143
+ .option("--gateway-password <password>", "Gateway password (password auth)")
144
+ .option("--remote-url <url>", "Remote Gateway WebSocket URL")
145
+ .option("--remote-token <token>", "Remote Gateway token (optional)")
146
+ .option("--tailscale <mode>", "Tailscale: off|serve|funnel")
147
+ .option("--tailscale-reset-on-exit", "Reset tailscale serve/funnel on exit")
148
+ .option("--install-daemon", "Install gateway daemon")
149
+ .option("--skip-skills", "Skip skills setup")
150
+ .option("--skip-health", "Skip health check")
151
+ .option("--node-manager <name>", "Node manager for skills: npm|pnpm|bun")
152
+ .option("--json", "Output JSON summary", false)
153
+ .action(async (opts) => {
154
+ try {
155
+ await onboardCommand({
156
+ workspace: opts.workspace,
157
+ nonInteractive: Boolean(opts.nonInteractive),
158
+ mode: opts.mode,
159
+ authChoice: opts.authChoice,
160
+ anthropicApiKey: opts.anthropicApiKey,
161
+ gatewayPort: typeof opts.gatewayPort === "string"
162
+ ? Number.parseInt(opts.gatewayPort, 10)
163
+ : undefined,
164
+ gatewayBind: opts.gatewayBind,
165
+ gatewayAuth: opts.gatewayAuth,
166
+ gatewayToken: opts.gatewayToken,
167
+ gatewayPassword: opts.gatewayPassword,
168
+ remoteUrl: opts.remoteUrl,
169
+ remoteToken: opts.remoteToken,
170
+ tailscale: opts.tailscale,
171
+ tailscaleResetOnExit: Boolean(opts.tailscaleResetOnExit),
172
+ installDaemon: Boolean(opts.installDaemon),
173
+ skipSkills: Boolean(opts.skipSkills),
174
+ skipHealth: Boolean(opts.skipHealth),
175
+ nodeManager: opts.nodeManager,
176
+ json: Boolean(opts.json),
177
+ }, defaultRuntime);
178
+ }
179
+ catch (err) {
180
+ defaultRuntime.error(String(err));
181
+ defaultRuntime.exit(1);
182
+ }
183
+ });
184
+ program
185
+ .command("configure")
186
+ .alias("config")
187
+ .description("Interactive wizard to update models, providers, skills, and gateway")
188
+ .action(async () => {
189
+ try {
190
+ await configureCommand(defaultRuntime);
191
+ }
192
+ catch (err) {
193
+ defaultRuntime.error(String(err));
194
+ defaultRuntime.exit(1);
195
+ }
196
+ });
197
+ program
198
+ .command("doctor")
199
+ .description("Health checks + quick fixes for the gateway and providers")
200
+ .action(async () => {
201
+ try {
202
+ await doctorCommand(defaultRuntime);
203
+ }
204
+ catch (err) {
205
+ defaultRuntime.error(String(err));
206
+ defaultRuntime.exit(1);
207
+ }
208
+ });
209
+ program
210
+ .command("update")
211
+ .description("Audit and modernize the local configuration")
212
+ .action(async () => {
213
+ try {
214
+ await updateCommand(defaultRuntime);
215
+ }
216
+ catch (err) {
217
+ defaultRuntime.error(String(err));
218
+ defaultRuntime.exit(1);
219
+ }
220
+ });
221
+ program
222
+ .command("login")
223
+ .description("Link your personal WhatsApp via QR (web provider)")
224
+ .option("--verbose", "Verbose connection logs", false)
225
+ .option("--provider <provider>", "Provider alias (default: whatsapp)")
226
+ .action(async (opts) => {
227
+ setVerbose(Boolean(opts.verbose));
228
+ try {
229
+ const provider = opts.provider ?? "whatsapp";
230
+ await loginWeb(Boolean(opts.verbose), provider);
231
+ }
232
+ catch (err) {
233
+ defaultRuntime.error(danger(`Web login failed: ${String(err)}`));
234
+ defaultRuntime.exit(1);
235
+ }
236
+ });
237
+ program
238
+ .command("logout")
239
+ .description("Clear cached WhatsApp Web credentials")
240
+ .option("--provider <provider>", "Provider alias (default: whatsapp)")
241
+ .action(async (opts) => {
242
+ try {
243
+ void opts.provider; // placeholder for future multi-provider; currently web only.
244
+ await logoutWeb(defaultRuntime);
245
+ }
246
+ catch (err) {
247
+ defaultRuntime.error(danger(`Logout failed: ${String(err)}`));
248
+ defaultRuntime.exit(1);
249
+ }
250
+ });
251
+ program
252
+ .command("send")
253
+ .description("Send a message (WhatsApp Web, Telegram bot, Discord, Slack, Signal, iMessage)")
254
+ .requiredOption("-t, --to <number>", "Recipient: E.164 for WhatsApp/Signal, Telegram chat id/@username, Discord channel/user, or iMessage handle/chat_id")
255
+ .requiredOption("-m, --message <text>", "Message body")
256
+ .option("--media <path-or-url>", "Attach media (image/audio/video/document). Accepts local paths or URLs.")
257
+ .option("--gif-playback", "Treat video media as GIF playback (WhatsApp only).", false)
258
+ .option("--provider <provider>", "Delivery provider: whatsapp|telegram|discord|slack|signal|imessage (default: whatsapp)")
259
+ .option("--dry-run", "Print payload and skip sending", false)
260
+ .option("--json", "Output result as JSON", false)
261
+ .option("--verbose", "Verbose logging", false)
262
+ .addHelpText("after", `
263
+ Examples:
264
+ clawdbot send --to +15555550123 --message "Hi"
265
+ clawdbot send --to +15555550123 --message "Hi" --media photo.jpg
266
+ clawdbot send --to +15555550123 --message "Hi" --dry-run # print payload only
267
+ clawdbot send --to +15555550123 --message "Hi" --json # machine-readable result`)
268
+ .action(async (opts) => {
269
+ setVerbose(Boolean(opts.verbose));
270
+ const deps = createDefaultDeps();
271
+ try {
272
+ await sendCommand(opts, deps, defaultRuntime);
273
+ }
274
+ catch (err) {
275
+ defaultRuntime.error(String(err));
276
+ defaultRuntime.exit(1);
277
+ }
278
+ });
279
+ program
280
+ .command("agent")
281
+ .description("Talk directly to the configured agent (no chat send; optional delivery)")
282
+ .requiredOption("-m, --message <text>", "Message body for the agent")
283
+ .option("-t, --to <number>", "Recipient number in E.164 used to derive the session key")
284
+ .option("--session-id <id>", "Use an explicit session id")
285
+ .option("--thinking <level>", "Thinking level: off | minimal | low | medium | high")
286
+ .option("--verbose <on|off>", "Persist agent verbose level for the session")
287
+ .option("--provider <provider>", "Delivery provider: whatsapp|telegram|discord|slack|signal|imessage (default: whatsapp)")
288
+ .option("--deliver", "Send the agent's reply back to the selected provider (requires --to)", false)
289
+ .option("--json", "Output result as JSON", false)
290
+ .option("--timeout <seconds>", "Override agent command timeout (seconds, default 600 or config value)")
291
+ .addHelpText("after", `
292
+ Examples:
293
+ clawdbot agent --to +15555550123 --message "status update"
294
+ clawdbot agent --session-id 1234 --message "Summarize inbox" --thinking medium
295
+ clawdbot agent --to +15555550123 --message "Trace logs" --verbose on --json
296
+ clawdbot agent --to +15555550123 --message "Summon reply" --deliver
297
+ `)
298
+ .action(async (opts) => {
299
+ const verboseLevel = typeof opts.verbose === "string" ? opts.verbose.toLowerCase() : "";
300
+ setVerbose(verboseLevel === "on");
301
+ // Build default deps (keeps parity with other commands; future-proofing).
302
+ void createDefaultDeps();
303
+ try {
304
+ await agentCommand(opts, defaultRuntime);
305
+ }
306
+ catch (err) {
307
+ defaultRuntime.error(String(err));
308
+ defaultRuntime.exit(1);
309
+ }
310
+ });
311
+ registerCanvasCli(program);
312
+ registerGatewayCli(program);
313
+ registerModelsCli(program);
314
+ registerNodesCli(program);
315
+ registerTuiCli(program);
316
+ registerCronCli(program);
317
+ registerDnsCli(program);
318
+ registerHooksCli(program);
319
+ program
320
+ .command("status")
321
+ .description("Show web session health and recent session recipients")
322
+ .option("--json", "Output JSON instead of text", false)
323
+ .option("--deep", "Probe providers (WhatsApp Web + Telegram + Discord + Slack + Signal)", false)
324
+ .option("--timeout <ms>", "Probe timeout in milliseconds", "10000")
325
+ .option("--verbose", "Verbose logging", false)
326
+ .addHelpText("after", `
327
+ Examples:
328
+ clawdbot status # show linked account + session store summary
329
+ clawdbot status --json # machine-readable output
330
+ clawdbot status --deep # run provider probes (WA + Telegram + Discord + Slack + Signal)
331
+ clawdbot status --deep --timeout 5000 # tighten probe timeout`)
332
+ .action(async (opts) => {
333
+ setVerbose(Boolean(opts.verbose));
334
+ const timeout = opts.timeout
335
+ ? Number.parseInt(String(opts.timeout), 10)
336
+ : undefined;
337
+ if (timeout !== undefined && (Number.isNaN(timeout) || timeout <= 0)) {
338
+ defaultRuntime.error("--timeout must be a positive integer (milliseconds)");
339
+ defaultRuntime.exit(1);
340
+ return;
341
+ }
342
+ try {
343
+ await statusCommand({
344
+ json: Boolean(opts.json),
345
+ deep: Boolean(opts.deep),
346
+ timeoutMs: timeout,
347
+ }, defaultRuntime);
348
+ }
349
+ catch (err) {
350
+ defaultRuntime.error(String(err));
351
+ defaultRuntime.exit(1);
352
+ }
353
+ });
354
+ program
355
+ .command("health")
356
+ .description("Fetch health from the running gateway")
357
+ .option("--json", "Output JSON instead of text", false)
358
+ .option("--timeout <ms>", "Connection timeout in milliseconds", "10000")
359
+ .option("--verbose", "Verbose logging", false)
360
+ .action(async (opts) => {
361
+ setVerbose(Boolean(opts.verbose));
362
+ const timeout = opts.timeout
363
+ ? Number.parseInt(String(opts.timeout), 10)
364
+ : undefined;
365
+ if (timeout !== undefined && (Number.isNaN(timeout) || timeout <= 0)) {
366
+ defaultRuntime.error("--timeout must be a positive integer (milliseconds)");
367
+ defaultRuntime.exit(1);
368
+ return;
369
+ }
370
+ try {
371
+ await healthCommand({
372
+ json: Boolean(opts.json),
373
+ timeoutMs: timeout,
374
+ }, defaultRuntime);
375
+ }
376
+ catch (err) {
377
+ defaultRuntime.error(String(err));
378
+ defaultRuntime.exit(1);
379
+ }
380
+ });
381
+ program
382
+ .command("sessions")
383
+ .description("List stored conversation sessions")
384
+ .option("--json", "Output as JSON", false)
385
+ .option("--verbose", "Verbose logging", false)
386
+ .option("--store <path>", "Path to session store (default: resolved from config)")
387
+ .option("--active <minutes>", "Only show sessions updated within the past N minutes")
388
+ .addHelpText("after", `
389
+ Examples:
390
+ clawdbot sessions # list all sessions
391
+ clawdbot sessions --active 120 # only last 2 hours
392
+ clawdbot sessions --json # machine-readable output
393
+ clawdbot sessions --store ./tmp/sessions.json
394
+
395
+ Shows token usage per session when the agent reports it; set agent.contextTokens to see % of your model window.`)
396
+ .action(async (opts) => {
397
+ setVerbose(Boolean(opts.verbose));
398
+ await sessionsCommand({
399
+ json: Boolean(opts.json),
400
+ store: opts.store,
401
+ active: opts.active,
402
+ }, defaultRuntime);
403
+ });
404
+ registerBrowserCli(program);
405
+ return program;
406
+ }
@@ -0,0 +1,19 @@
1
+ import { stdin as input, stdout as output } from "node:process";
2
+ import readline from "node:readline/promises";
3
+ import { isVerbose, isYes } from "../globals.js";
4
+ export async function promptYesNo(question, defaultYes = false) {
5
+ // Simple Y/N prompt honoring global --yes and verbosity flags.
6
+ if (isVerbose() && isYes())
7
+ return true; // redundant guard when both flags set
8
+ if (isYes())
9
+ return true;
10
+ const rl = readline.createInterface({ input, output });
11
+ const suffix = defaultYes ? " [Y/n] " : " [y/N] ";
12
+ const answer = (await rl.question(`${question}${suffix}`))
13
+ .trim()
14
+ .toLowerCase();
15
+ rl.close();
16
+ if (!answer)
17
+ return defaultYes;
18
+ return answer.startsWith("y");
19
+ }
@@ -0,0 +1,35 @@
1
+ import { defaultRuntime } from "../runtime.js";
2
+ import { runTui } from "../tui/tui.js";
3
+ export function registerTuiCli(program) {
4
+ program
5
+ .command("tui")
6
+ .description("Open a terminal UI connected to the Gateway")
7
+ .option("--url <url>", "Gateway WebSocket URL (defaults to gateway.remote.url when configured)")
8
+ .option("--token <token>", "Gateway token (if required)")
9
+ .option("--password <password>", "Gateway password (if required)")
10
+ .option("--session <key>", 'Session key (default: "main", or "global" when scope is global)')
11
+ .option("--deliver", "Deliver assistant replies", false)
12
+ .option("--thinking <level>", "Thinking level override")
13
+ .option("--timeout-ms <ms>", "Agent timeout in ms", "30000")
14
+ .option("--history-limit <n>", "History entries to load", "200")
15
+ .action(async (opts) => {
16
+ try {
17
+ const timeoutMs = Number.parseInt(String(opts.timeoutMs ?? "30000"), 10);
18
+ const historyLimit = Number.parseInt(String(opts.historyLimit ?? "200"), 10);
19
+ await runTui({
20
+ url: opts.url,
21
+ token: opts.token,
22
+ password: opts.password,
23
+ session: opts.session,
24
+ deliver: Boolean(opts.deliver),
25
+ thinking: opts.thinking,
26
+ timeoutMs: Number.isNaN(timeoutMs) ? undefined : timeoutMs,
27
+ historyLimit: Number.isNaN(historyLimit) ? undefined : historyLimit,
28
+ });
29
+ }
30
+ catch (err) {
31
+ defaultRuntime.error(String(err));
32
+ defaultRuntime.exit(1);
33
+ }
34
+ });
35
+ }
@@ -0,0 +1,8 @@
1
+ export function waitForever() {
2
+ // Keep event loop alive via an unref'ed interval plus a pending promise.
3
+ const interval = setInterval(() => { }, 1_000_000);
4
+ interval.unref();
5
+ return new Promise(() => {
6
+ /* never resolve */
7
+ });
8
+ }