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,263 @@
1
+ import { complete, getEnvApiKey, getModel, } from "@mariozechner/pi-ai";
2
+ import { Type } from "@sinclair/typebox";
3
+ const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
4
+ const DEFAULT_TIMEOUT_MS = 12_000;
5
+ const DEFAULT_CONCURRENCY = 3;
6
+ const BASE_IMAGE_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+X3mIAAAAASUVORK5CYII=";
7
+ const TOOL_PING = {
8
+ name: "ping",
9
+ description: "Return OK.",
10
+ parameters: Type.Object({}),
11
+ };
12
+ function normalizeCreatedAtMs(value) {
13
+ if (typeof value !== "number" || !Number.isFinite(value))
14
+ return null;
15
+ if (value <= 0)
16
+ return null;
17
+ if (value > 1e12)
18
+ return Math.round(value);
19
+ return Math.round(value * 1000);
20
+ }
21
+ function inferParamBFromIdOrName(text) {
22
+ const raw = text.toLowerCase();
23
+ const matches = raw.matchAll(/(?:^|[^a-z0-9])[a-z]?(\d+(?:\.\d+)?)b(?:[^a-z0-9]|$)/g);
24
+ let best = null;
25
+ for (const match of matches) {
26
+ const numRaw = match[1];
27
+ if (!numRaw)
28
+ continue;
29
+ const value = Number(numRaw);
30
+ if (!Number.isFinite(value) || value <= 0)
31
+ continue;
32
+ if (best === null || value > best)
33
+ best = value;
34
+ }
35
+ return best;
36
+ }
37
+ function parseModality(modality) {
38
+ if (!modality)
39
+ return ["text"];
40
+ const normalized = modality.toLowerCase();
41
+ const parts = normalized.split(/[^a-z]+/).filter(Boolean);
42
+ const hasImage = parts.includes("image");
43
+ return hasImage ? ["text", "image"] : ["text"];
44
+ }
45
+ async function withTimeout(timeoutMs, fn) {
46
+ const controller = new AbortController();
47
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
48
+ try {
49
+ return await fn(controller.signal);
50
+ }
51
+ finally {
52
+ clearTimeout(timer);
53
+ }
54
+ }
55
+ async function fetchOpenRouterModels(fetchImpl) {
56
+ const res = await fetchImpl(OPENROUTER_MODELS_URL, {
57
+ headers: { Accept: "application/json" },
58
+ });
59
+ if (!res.ok) {
60
+ throw new Error(`OpenRouter /models failed: HTTP ${res.status}`);
61
+ }
62
+ const payload = (await res.json());
63
+ const entries = Array.isArray(payload.data) ? payload.data : [];
64
+ return entries
65
+ .map((entry) => {
66
+ if (!entry || typeof entry !== "object")
67
+ return null;
68
+ const obj = entry;
69
+ const id = typeof obj.id === "string" ? obj.id.trim() : "";
70
+ if (!id)
71
+ return null;
72
+ const name = typeof obj.name === "string" && obj.name.trim() ? obj.name.trim() : id;
73
+ const contextLength = typeof obj.context_length === "number" &&
74
+ Number.isFinite(obj.context_length)
75
+ ? obj.context_length
76
+ : null;
77
+ const maxCompletionTokens = typeof obj.max_completion_tokens === "number" &&
78
+ Number.isFinite(obj.max_completion_tokens)
79
+ ? obj.max_completion_tokens
80
+ : typeof obj.max_output_tokens === "number" &&
81
+ Number.isFinite(obj.max_output_tokens)
82
+ ? obj.max_output_tokens
83
+ : null;
84
+ const supportedParametersCount = Array.isArray(obj.supported_parameters)
85
+ ? obj.supported_parameters.length
86
+ : 0;
87
+ const modality = typeof obj.modality === "string" && obj.modality.trim()
88
+ ? obj.modality.trim()
89
+ : null;
90
+ const inferredParamB = inferParamBFromIdOrName(`${id} ${name}`);
91
+ const createdAtMs = normalizeCreatedAtMs(obj.created_at);
92
+ return {
93
+ id,
94
+ name,
95
+ contextLength,
96
+ maxCompletionTokens,
97
+ supportedParametersCount,
98
+ modality,
99
+ inferredParamB,
100
+ createdAtMs,
101
+ };
102
+ })
103
+ .filter((entry) => Boolean(entry));
104
+ }
105
+ async function probeTool(model, apiKey, timeoutMs) {
106
+ const context = {
107
+ messages: [
108
+ {
109
+ role: "user",
110
+ content: "Call the ping tool with {} and nothing else.",
111
+ timestamp: Date.now(),
112
+ },
113
+ ],
114
+ tools: [TOOL_PING],
115
+ };
116
+ const startedAt = Date.now();
117
+ try {
118
+ const message = await withTimeout(timeoutMs, (signal) => complete(model, context, {
119
+ apiKey,
120
+ maxTokens: 32,
121
+ temperature: 0,
122
+ toolChoice: "required",
123
+ signal,
124
+ }));
125
+ const hasToolCall = message.content.some((block) => block.type === "toolCall");
126
+ if (!hasToolCall) {
127
+ return {
128
+ ok: false,
129
+ latencyMs: Date.now() - startedAt,
130
+ error: "No tool call returned",
131
+ };
132
+ }
133
+ return { ok: true, latencyMs: Date.now() - startedAt };
134
+ }
135
+ catch (err) {
136
+ return {
137
+ ok: false,
138
+ latencyMs: Date.now() - startedAt,
139
+ error: err instanceof Error ? err.message : String(err),
140
+ };
141
+ }
142
+ }
143
+ async function probeImage(model, apiKey, timeoutMs) {
144
+ const context = {
145
+ messages: [
146
+ {
147
+ role: "user",
148
+ content: [
149
+ { type: "text", text: "Reply with OK." },
150
+ { type: "image", data: BASE_IMAGE_PNG, mimeType: "image/png" },
151
+ ],
152
+ timestamp: Date.now(),
153
+ },
154
+ ],
155
+ };
156
+ const startedAt = Date.now();
157
+ try {
158
+ await withTimeout(timeoutMs, (signal) => complete(model, context, {
159
+ apiKey,
160
+ maxTokens: 16,
161
+ temperature: 0,
162
+ signal,
163
+ }));
164
+ return { ok: true, latencyMs: Date.now() - startedAt };
165
+ }
166
+ catch (err) {
167
+ return {
168
+ ok: false,
169
+ latencyMs: Date.now() - startedAt,
170
+ error: err instanceof Error ? err.message : String(err),
171
+ };
172
+ }
173
+ }
174
+ function ensureImageInput(model) {
175
+ if (model.input.includes("image"))
176
+ return model;
177
+ return {
178
+ ...model,
179
+ input: Array.from(new Set([...model.input, "image"])),
180
+ };
181
+ }
182
+ async function mapWithConcurrency(items, concurrency, fn) {
183
+ const limit = Math.max(1, Math.floor(concurrency));
184
+ const results = Array.from({ length: items.length });
185
+ let nextIndex = 0;
186
+ const worker = async () => {
187
+ while (true) {
188
+ const current = nextIndex;
189
+ nextIndex += 1;
190
+ if (current >= items.length)
191
+ return;
192
+ results[current] = await fn(items[current], current);
193
+ }
194
+ };
195
+ await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
196
+ return results;
197
+ }
198
+ export async function scanOpenRouterModels(options = {}) {
199
+ const fetchImpl = options.fetchImpl ?? fetch;
200
+ const apiKey = options.apiKey?.trim() || getEnvApiKey("openrouter") || "";
201
+ if (!apiKey) {
202
+ throw new Error("Missing OpenRouter API key. Set OPENROUTER_API_KEY to run models scan.");
203
+ }
204
+ const timeoutMs = Math.max(1, Math.floor(options.timeoutMs ?? DEFAULT_TIMEOUT_MS));
205
+ const concurrency = Math.max(1, Math.floor(options.concurrency ?? DEFAULT_CONCURRENCY));
206
+ const minParamB = Math.max(0, Math.floor(options.minParamB ?? 0));
207
+ const maxAgeDays = Math.max(0, Math.floor(options.maxAgeDays ?? 0));
208
+ const providerFilter = options.providerFilter?.trim().toLowerCase() ?? "";
209
+ const catalog = await fetchOpenRouterModels(fetchImpl);
210
+ const now = Date.now();
211
+ const filtered = catalog.filter((entry) => {
212
+ if (!entry.id.endsWith(":free"))
213
+ return false;
214
+ if (providerFilter) {
215
+ const prefix = entry.id.split("/")[0]?.toLowerCase() ?? "";
216
+ if (prefix !== providerFilter)
217
+ return false;
218
+ }
219
+ if (minParamB > 0) {
220
+ const params = entry.inferredParamB ?? 0;
221
+ if (params < minParamB)
222
+ return false;
223
+ }
224
+ if (maxAgeDays > 0 && entry.createdAtMs) {
225
+ const ageMs = now - entry.createdAtMs;
226
+ const ageDays = ageMs / (24 * 60 * 60 * 1000);
227
+ if (ageDays > maxAgeDays)
228
+ return false;
229
+ }
230
+ return true;
231
+ });
232
+ const baseModel = getModel("openrouter", "openrouter/auto");
233
+ return mapWithConcurrency(filtered, concurrency, async (entry) => {
234
+ const model = {
235
+ ...baseModel,
236
+ id: entry.id,
237
+ name: entry.name || entry.id,
238
+ contextWindow: entry.contextLength ?? baseModel.contextWindow,
239
+ maxTokens: entry.maxCompletionTokens ?? baseModel.maxTokens,
240
+ input: parseModality(entry.modality),
241
+ reasoning: baseModel.reasoning,
242
+ };
243
+ const toolResult = await probeTool(model, apiKey, timeoutMs);
244
+ const imageResult = model.input.includes("image")
245
+ ? await probeImage(ensureImageInput(model), apiKey, timeoutMs)
246
+ : { ok: false, latencyMs: null, skipped: true };
247
+ return {
248
+ id: entry.id,
249
+ name: entry.name,
250
+ provider: "openrouter",
251
+ modelRef: `openrouter/${entry.id}`,
252
+ contextLength: entry.contextLength,
253
+ maxCompletionTokens: entry.maxCompletionTokens,
254
+ supportedParametersCount: entry.supportedParametersCount,
255
+ modality: entry.modality,
256
+ inferredParamB: entry.inferredParamB,
257
+ createdAtMs: entry.createdAtMs,
258
+ tool: toolResult,
259
+ image: imageResult,
260
+ };
261
+ });
262
+ }
263
+ export { OPENROUTER_MODELS_URL };
@@ -0,0 +1,116 @@
1
+ function normalizeAliasKey(value) {
2
+ return value.trim().toLowerCase();
3
+ }
4
+ export function modelKey(provider, model) {
5
+ return `${provider}/${model}`;
6
+ }
7
+ export function parseModelRef(raw, defaultProvider) {
8
+ const trimmed = raw.trim();
9
+ if (!trimmed)
10
+ return null;
11
+ const slash = trimmed.indexOf("/");
12
+ if (slash === -1) {
13
+ return { provider: defaultProvider, model: trimmed };
14
+ }
15
+ const provider = trimmed.slice(0, slash).trim();
16
+ const model = trimmed.slice(slash + 1).trim();
17
+ if (!provider || !model)
18
+ return null;
19
+ return { provider, model };
20
+ }
21
+ export function buildModelAliasIndex(params) {
22
+ const rawAliases = params.cfg.agent?.modelAliases ?? {};
23
+ const byAlias = new Map();
24
+ const byKey = new Map();
25
+ for (const [aliasRaw, targetRaw] of Object.entries(rawAliases)) {
26
+ const alias = aliasRaw.trim();
27
+ if (!alias)
28
+ continue;
29
+ const parsed = parseModelRef(String(targetRaw ?? ""), params.defaultProvider);
30
+ if (!parsed)
31
+ continue;
32
+ const aliasKey = normalizeAliasKey(alias);
33
+ byAlias.set(aliasKey, { alias, ref: parsed });
34
+ const key = modelKey(parsed.provider, parsed.model);
35
+ const existing = byKey.get(key) ?? [];
36
+ existing.push(alias);
37
+ byKey.set(key, existing);
38
+ }
39
+ return { byAlias, byKey };
40
+ }
41
+ export function resolveModelRefFromString(params) {
42
+ const trimmed = params.raw.trim();
43
+ if (!trimmed)
44
+ return null;
45
+ if (!trimmed.includes("/")) {
46
+ const aliasKey = normalizeAliasKey(trimmed);
47
+ const aliasMatch = params.aliasIndex?.byAlias.get(aliasKey);
48
+ if (aliasMatch) {
49
+ return { ref: aliasMatch.ref, alias: aliasMatch.alias };
50
+ }
51
+ }
52
+ const parsed = parseModelRef(trimmed, params.defaultProvider);
53
+ if (!parsed)
54
+ return null;
55
+ return { ref: parsed };
56
+ }
57
+ export function resolveConfiguredModelRef(params) {
58
+ const rawModel = params.cfg.agent?.model?.trim() || "";
59
+ if (rawModel) {
60
+ const trimmed = rawModel.trim();
61
+ const aliasIndex = buildModelAliasIndex({
62
+ cfg: params.cfg,
63
+ defaultProvider: params.defaultProvider,
64
+ });
65
+ const resolved = resolveModelRefFromString({
66
+ raw: trimmed,
67
+ defaultProvider: params.defaultProvider,
68
+ aliasIndex,
69
+ });
70
+ if (resolved)
71
+ return resolved.ref;
72
+ // TODO(steipete): drop this fallback once provider-less agent.model is fully deprecated.
73
+ return { provider: "anthropic", model: trimmed };
74
+ }
75
+ return { provider: params.defaultProvider, model: params.defaultModel };
76
+ }
77
+ export function buildAllowedModelSet(params) {
78
+ const rawAllowlist = params.cfg.agent?.allowedModels ?? [];
79
+ const allowAny = rawAllowlist.length === 0;
80
+ const catalogKeys = new Set(params.catalog.map((entry) => modelKey(entry.provider, entry.id)));
81
+ if (allowAny) {
82
+ return {
83
+ allowAny: true,
84
+ allowedCatalog: params.catalog,
85
+ allowedKeys: catalogKeys,
86
+ };
87
+ }
88
+ const allowedKeys = new Set();
89
+ for (const raw of rawAllowlist) {
90
+ const parsed = parseModelRef(String(raw), params.defaultProvider);
91
+ if (!parsed)
92
+ continue;
93
+ const key = modelKey(parsed.provider, parsed.model);
94
+ if (catalogKeys.has(key)) {
95
+ allowedKeys.add(key);
96
+ }
97
+ }
98
+ const allowedCatalog = params.catalog.filter((entry) => allowedKeys.has(modelKey(entry.provider, entry.id)));
99
+ if (allowedCatalog.length === 0) {
100
+ return {
101
+ allowAny: true,
102
+ allowedCatalog: params.catalog,
103
+ allowedKeys: catalogKeys,
104
+ };
105
+ }
106
+ return { allowAny: false, allowedCatalog, allowedKeys };
107
+ }
108
+ export function resolveThinkingDefault(params) {
109
+ const configured = params.cfg.agent?.thinkingDefault;
110
+ if (configured)
111
+ return configured;
112
+ const candidate = params.catalog?.find((entry) => entry.provider === params.provider && entry.id === params.model);
113
+ if (candidate?.reasoning)
114
+ return "low";
115
+ return "off";
116
+ }
@@ -0,0 +1,49 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { loadConfig } from "../config/config.js";
4
+ import { ensureClawdbotAgentEnv, resolveClawdbotAgentDir, } from "./agent-paths.js";
5
+ const DEFAULT_MODE = "merge";
6
+ function isRecord(value) {
7
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
8
+ }
9
+ async function readJson(pathname) {
10
+ try {
11
+ const raw = await fs.readFile(pathname, "utf8");
12
+ return JSON.parse(raw);
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ export async function ensureClawdbotModelsJson(config) {
19
+ const cfg = config ?? loadConfig();
20
+ const providers = cfg.models?.providers;
21
+ if (!providers || Object.keys(providers).length === 0) {
22
+ return { agentDir: resolveClawdbotAgentDir(), wrote: false };
23
+ }
24
+ const mode = cfg.models?.mode ?? DEFAULT_MODE;
25
+ const agentDir = ensureClawdbotAgentEnv();
26
+ const targetPath = path.join(agentDir, "models.json");
27
+ let mergedProviders = providers;
28
+ let existingRaw = "";
29
+ if (mode === "merge") {
30
+ const existing = await readJson(targetPath);
31
+ if (isRecord(existing) && isRecord(existing.providers)) {
32
+ const existingProviders = existing.providers;
33
+ mergedProviders = { ...existingProviders, ...providers };
34
+ }
35
+ }
36
+ const next = `${JSON.stringify({ providers: mergedProviders }, null, 2)}\n`;
37
+ try {
38
+ existingRaw = await fs.readFile(targetPath, "utf8");
39
+ }
40
+ catch {
41
+ existingRaw = "";
42
+ }
43
+ if (existingRaw === next) {
44
+ return { agentDir, wrote: false };
45
+ }
46
+ await fs.mkdir(agentDir, { recursive: true, mode: 0o700 });
47
+ await fs.writeFile(targetPath, next, { mode: 0o600 });
48
+ return { agentDir, wrote: true };
49
+ }
@@ -0,0 +1,74 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { sanitizeContentBlocksImages } from "./tool-images.js";
4
+ export async function ensureSessionHeader(params) {
5
+ const file = params.sessionFile;
6
+ try {
7
+ await fs.stat(file);
8
+ return;
9
+ }
10
+ catch {
11
+ // create
12
+ }
13
+ await fs.mkdir(path.dirname(file), { recursive: true });
14
+ const sessionVersion = 2;
15
+ const entry = {
16
+ type: "session",
17
+ version: sessionVersion,
18
+ id: params.sessionId,
19
+ timestamp: new Date().toISOString(),
20
+ cwd: params.cwd,
21
+ };
22
+ await fs.writeFile(file, `${JSON.stringify(entry)}\n`, "utf-8");
23
+ }
24
+ export async function sanitizeSessionMessagesImages(messages, label) {
25
+ // We sanitize historical session messages because Anthropic can reject a request
26
+ // if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX).
27
+ const out = [];
28
+ for (const msg of messages) {
29
+ if (!msg || typeof msg !== "object") {
30
+ out.push(msg);
31
+ continue;
32
+ }
33
+ const role = msg.role;
34
+ if (role === "toolResult") {
35
+ const toolMsg = msg;
36
+ const content = Array.isArray(toolMsg.content) ? toolMsg.content : [];
37
+ const nextContent = (await sanitizeContentBlocksImages(content, label));
38
+ out.push({ ...toolMsg, content: nextContent });
39
+ continue;
40
+ }
41
+ if (role === "user") {
42
+ const userMsg = msg;
43
+ const content = userMsg.content;
44
+ if (Array.isArray(content)) {
45
+ const nextContent = (await sanitizeContentBlocksImages(content, label));
46
+ out.push({ ...userMsg, content: nextContent });
47
+ continue;
48
+ }
49
+ }
50
+ out.push(msg);
51
+ }
52
+ return out;
53
+ }
54
+ export function buildBootstrapContextFiles(files) {
55
+ return files.map((file) => ({
56
+ path: file.name,
57
+ content: file.missing
58
+ ? `[MISSING] Expected at: ${file.path}`
59
+ : (file.content ?? ""),
60
+ }));
61
+ }
62
+ export function formatAssistantErrorText(msg) {
63
+ if (msg.stopReason !== "error")
64
+ return undefined;
65
+ const raw = (msg.errorMessage ?? "").trim();
66
+ if (!raw)
67
+ return "LLM request failed with an unknown error.";
68
+ const invalidRequest = raw.match(/"type":"invalid_request_error".*?"message":"([^"]+)"/);
69
+ if (invalidRequest?.[1]) {
70
+ return `LLM request rejected: ${invalidRequest[1]}`;
71
+ }
72
+ // Keep it short for WhatsApp.
73
+ return raw.length > 600 ? `${raw.slice(0, 600)}…` : raw;
74
+ }