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,38 @@
1
+ export function stripStructuralPrefixes(text) {
2
+ // Ignore wrapper labels, timestamps, and sender prefixes so directive-only
3
+ // detection still works in group batches that include history/context.
4
+ const marker = "[Current message - respond to this]";
5
+ const afterMarker = text.includes(marker)
6
+ ? text.slice(text.indexOf(marker) + marker.length)
7
+ : text;
8
+ return afterMarker
9
+ .replace(/\[[^\]]+\]\s*/g, "")
10
+ .replace(/^[ \t]*[A-Za-z0-9+()\-_. ]+:\s*/gm, "")
11
+ .replace(/\s+/g, " ")
12
+ .trim();
13
+ }
14
+ export function stripMentions(text, ctx, cfg) {
15
+ let result = text;
16
+ const patterns = cfg?.routing?.groupChat?.mentionPatterns ?? [];
17
+ for (const p of patterns) {
18
+ try {
19
+ const re = new RegExp(p, "gi");
20
+ result = result.replace(re, " ");
21
+ }
22
+ catch {
23
+ // ignore invalid regex
24
+ }
25
+ }
26
+ const selfE164 = (ctx.To ?? "").replace(/^whatsapp:/, "");
27
+ if (selfE164) {
28
+ const esc = selfE164.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29
+ result = result
30
+ .replace(new RegExp(esc, "gi"), " ")
31
+ .replace(new RegExp(`@${esc}`, "gi"), " ");
32
+ }
33
+ // Generic mention patterns like @123456789 or plain digits
34
+ result = result.replace(/@[0-9+]{5,}/g, " ");
35
+ // Discord-style mentions (<@123> or <@!123>)
36
+ result = result.replace(/<@!?\d+>/g, " ");
37
+ return result.replace(/\s+/g, " ").trim();
38
+ }
@@ -0,0 +1,114 @@
1
+ import { lookupContextTokens } from "../../agents/context.js";
2
+ import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js";
3
+ import { loadModelCatalog } from "../../agents/model-catalog.js";
4
+ import { buildAllowedModelSet, modelKey, resolveModelRefFromString, resolveThinkingDefault, } from "../../agents/model-selection.js";
5
+ import { saveSessionStore } from "../../config/sessions.js";
6
+ export async function createModelSelectionState(params) {
7
+ const { cfg, agentCfg, sessionEntry, sessionStore, sessionKey, storePath, defaultProvider, } = params;
8
+ let provider = params.provider;
9
+ let model = params.model;
10
+ const hasAllowlist = (agentCfg?.allowedModels?.length ?? 0) > 0;
11
+ const hasStoredOverride = Boolean(sessionEntry?.modelOverride || sessionEntry?.providerOverride);
12
+ const needsModelCatalog = params.hasModelDirective || hasAllowlist || hasStoredOverride;
13
+ let allowedModelKeys = new Set();
14
+ let allowedModelCatalog = [];
15
+ let modelCatalog = null;
16
+ let resetModelOverride = false;
17
+ if (needsModelCatalog) {
18
+ modelCatalog = await loadModelCatalog({ config: cfg });
19
+ const allowed = buildAllowedModelSet({
20
+ cfg,
21
+ catalog: modelCatalog,
22
+ defaultProvider,
23
+ });
24
+ allowedModelCatalog = allowed.allowedCatalog;
25
+ allowedModelKeys = allowed.allowedKeys;
26
+ }
27
+ if (sessionEntry && sessionStore && sessionKey && hasStoredOverride) {
28
+ const overrideProvider = sessionEntry.providerOverride?.trim() || defaultProvider;
29
+ const overrideModel = sessionEntry.modelOverride?.trim();
30
+ if (overrideModel) {
31
+ const key = modelKey(overrideProvider, overrideModel);
32
+ if (allowedModelKeys.size > 0 && !allowedModelKeys.has(key)) {
33
+ delete sessionEntry.providerOverride;
34
+ delete sessionEntry.modelOverride;
35
+ sessionEntry.updatedAt = Date.now();
36
+ sessionStore[sessionKey] = sessionEntry;
37
+ if (storePath) {
38
+ await saveSessionStore(storePath, sessionStore);
39
+ }
40
+ resetModelOverride = true;
41
+ }
42
+ }
43
+ }
44
+ const storedProviderOverride = sessionEntry?.providerOverride?.trim();
45
+ const storedModelOverride = sessionEntry?.modelOverride?.trim();
46
+ if (storedModelOverride) {
47
+ const candidateProvider = storedProviderOverride || defaultProvider;
48
+ const key = modelKey(candidateProvider, storedModelOverride);
49
+ if (allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
50
+ provider = candidateProvider;
51
+ model = storedModelOverride;
52
+ }
53
+ }
54
+ let defaultThinkingLevel;
55
+ const resolveDefaultThinkingLevel = async () => {
56
+ if (defaultThinkingLevel)
57
+ return defaultThinkingLevel;
58
+ let catalogForThinking = modelCatalog ?? allowedModelCatalog;
59
+ if (!catalogForThinking || catalogForThinking.length === 0) {
60
+ modelCatalog = await loadModelCatalog({ config: cfg });
61
+ catalogForThinking = modelCatalog;
62
+ }
63
+ defaultThinkingLevel = resolveThinkingDefault({
64
+ cfg,
65
+ provider,
66
+ model,
67
+ catalog: catalogForThinking,
68
+ });
69
+ return defaultThinkingLevel;
70
+ };
71
+ return {
72
+ provider,
73
+ model,
74
+ allowedModelKeys,
75
+ allowedModelCatalog,
76
+ resetModelOverride,
77
+ resolveDefaultThinkingLevel,
78
+ needsModelCatalog,
79
+ };
80
+ }
81
+ export function resolveModelDirectiveSelection(params) {
82
+ const { raw, defaultProvider, defaultModel, aliasIndex, allowedModelKeys } = params;
83
+ const resolved = resolveModelRefFromString({
84
+ raw,
85
+ defaultProvider,
86
+ aliasIndex,
87
+ });
88
+ if (!resolved) {
89
+ return {
90
+ error: `Unrecognized model "${raw}". Use /model to list available models.`,
91
+ };
92
+ }
93
+ const key = modelKey(resolved.ref.provider, resolved.ref.model);
94
+ if (allowedModelKeys.size > 0 && !allowedModelKeys.has(key)) {
95
+ return {
96
+ error: `Model "${resolved.ref.provider}/${resolved.ref.model}" is not allowed. Use /model to list available models.`,
97
+ };
98
+ }
99
+ const isDefault = resolved.ref.provider === defaultProvider &&
100
+ resolved.ref.model === defaultModel;
101
+ return {
102
+ selection: {
103
+ provider: resolved.ref.provider,
104
+ model: resolved.ref.model,
105
+ isDefault,
106
+ alias: resolved.alias,
107
+ },
108
+ };
109
+ }
110
+ export function resolveContextTokens(params) {
111
+ return (params.agentCfg?.contextTokens ??
112
+ lookupContextTokens(params.model) ??
113
+ DEFAULT_CONTEXT_TOKENS);
114
+ }
@@ -0,0 +1,399 @@
1
+ import { parseDurationMs } from "../../cli/parse-duration.js";
2
+ import { defaultRuntime } from "../../runtime.js";
3
+ const DEFAULT_QUEUE_DEBOUNCE_MS = 1000;
4
+ const DEFAULT_QUEUE_CAP = 20;
5
+ const DEFAULT_QUEUE_DROP = "summarize";
6
+ const FOLLOWUP_QUEUES = new Map();
7
+ function normalizeQueueMode(raw) {
8
+ if (!raw)
9
+ return undefined;
10
+ const cleaned = raw.trim().toLowerCase();
11
+ if (cleaned === "queue" || cleaned === "queued")
12
+ return "steer";
13
+ if (cleaned === "interrupt" ||
14
+ cleaned === "interrupts" ||
15
+ cleaned === "abort")
16
+ return "interrupt";
17
+ if (cleaned === "steer" || cleaned === "steering")
18
+ return "steer";
19
+ if (cleaned === "followup" ||
20
+ cleaned === "follow-ups" ||
21
+ cleaned === "followups")
22
+ return "followup";
23
+ if (cleaned === "collect" || cleaned === "coalesce")
24
+ return "collect";
25
+ if (cleaned === "steer+backlog" ||
26
+ cleaned === "steer-backlog" ||
27
+ cleaned === "steer_backlog")
28
+ return "steer-backlog";
29
+ return undefined;
30
+ }
31
+ function normalizeQueueDropPolicy(raw) {
32
+ if (!raw)
33
+ return undefined;
34
+ const cleaned = raw.trim().toLowerCase();
35
+ if (cleaned === "old" || cleaned === "oldest")
36
+ return "old";
37
+ if (cleaned === "new" || cleaned === "newest")
38
+ return "new";
39
+ if (cleaned === "summarize" || cleaned === "summary")
40
+ return "summarize";
41
+ return undefined;
42
+ }
43
+ function parseQueueDebounce(raw) {
44
+ if (!raw)
45
+ return undefined;
46
+ try {
47
+ const parsed = parseDurationMs(raw.trim(), { defaultUnit: "ms" });
48
+ if (!parsed || parsed < 0)
49
+ return undefined;
50
+ return Math.round(parsed);
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ }
56
+ function parseQueueCap(raw) {
57
+ if (!raw)
58
+ return undefined;
59
+ const num = Number(raw);
60
+ if (!Number.isFinite(num))
61
+ return undefined;
62
+ const cap = Math.floor(num);
63
+ if (cap < 1)
64
+ return undefined;
65
+ return cap;
66
+ }
67
+ function parseQueueDirectiveArgs(raw) {
68
+ let i = 0;
69
+ const len = raw.length;
70
+ while (i < len && /\s/.test(raw[i]))
71
+ i += 1;
72
+ if (raw[i] === ":") {
73
+ i += 1;
74
+ while (i < len && /\s/.test(raw[i]))
75
+ i += 1;
76
+ }
77
+ let consumed = i;
78
+ let queueMode;
79
+ let queueReset = false;
80
+ let rawMode;
81
+ let debounceMs;
82
+ let cap;
83
+ let dropPolicy;
84
+ let rawDebounce;
85
+ let rawCap;
86
+ let rawDrop;
87
+ let hasOptions = false;
88
+ const takeToken = () => {
89
+ if (i >= len)
90
+ return null;
91
+ const start = i;
92
+ while (i < len && !/\s/.test(raw[i]))
93
+ i += 1;
94
+ if (start === i)
95
+ return null;
96
+ const token = raw.slice(start, i);
97
+ while (i < len && /\s/.test(raw[i]))
98
+ i += 1;
99
+ return token;
100
+ };
101
+ while (i < len) {
102
+ const token = takeToken();
103
+ if (!token)
104
+ break;
105
+ const lowered = token.trim().toLowerCase();
106
+ if (lowered === "default" || lowered === "reset" || lowered === "clear") {
107
+ queueReset = true;
108
+ consumed = i;
109
+ break;
110
+ }
111
+ if (lowered.startsWith("debounce:") || lowered.startsWith("debounce=")) {
112
+ rawDebounce = token.split(/[:=]/)[1] ?? "";
113
+ debounceMs = parseQueueDebounce(rawDebounce);
114
+ hasOptions = true;
115
+ consumed = i;
116
+ continue;
117
+ }
118
+ if (lowered.startsWith("cap:") || lowered.startsWith("cap=")) {
119
+ rawCap = token.split(/[:=]/)[1] ?? "";
120
+ cap = parseQueueCap(rawCap);
121
+ hasOptions = true;
122
+ consumed = i;
123
+ continue;
124
+ }
125
+ if (lowered.startsWith("drop:") || lowered.startsWith("drop=")) {
126
+ rawDrop = token.split(/[:=]/)[1] ?? "";
127
+ dropPolicy = normalizeQueueDropPolicy(rawDrop);
128
+ hasOptions = true;
129
+ consumed = i;
130
+ continue;
131
+ }
132
+ const mode = normalizeQueueMode(token);
133
+ if (mode) {
134
+ queueMode = mode;
135
+ rawMode = token;
136
+ consumed = i;
137
+ continue;
138
+ }
139
+ // Stop at first unrecognized token.
140
+ break;
141
+ }
142
+ return {
143
+ consumed,
144
+ queueMode,
145
+ queueReset,
146
+ rawMode,
147
+ debounceMs,
148
+ cap,
149
+ dropPolicy,
150
+ rawDebounce,
151
+ rawCap,
152
+ rawDrop,
153
+ hasOptions,
154
+ };
155
+ }
156
+ export function extractQueueDirective(body) {
157
+ if (!body)
158
+ return {
159
+ cleaned: "",
160
+ hasDirective: false,
161
+ queueReset: false,
162
+ hasOptions: false,
163
+ };
164
+ const re = /(?:^|\s)\/queue(?=$|\s|:)/i;
165
+ const match = re.exec(body);
166
+ if (!match) {
167
+ return {
168
+ cleaned: body.trim(),
169
+ hasDirective: false,
170
+ queueReset: false,
171
+ hasOptions: false,
172
+ };
173
+ }
174
+ const start = match.index + match[0].indexOf("/queue");
175
+ const argsStart = start + "/queue".length;
176
+ const args = body.slice(argsStart);
177
+ const parsed = parseQueueDirectiveArgs(args);
178
+ const cleanedRaw = body.slice(0, start) + body.slice(argsStart + parsed.consumed);
179
+ const cleaned = cleanedRaw.replace(/\s+/g, " ").trim();
180
+ return {
181
+ cleaned,
182
+ queueMode: parsed.queueMode,
183
+ queueReset: parsed.queueReset,
184
+ rawMode: parsed.rawMode,
185
+ debounceMs: parsed.debounceMs,
186
+ cap: parsed.cap,
187
+ dropPolicy: parsed.dropPolicy,
188
+ rawDebounce: parsed.rawDebounce,
189
+ rawCap: parsed.rawCap,
190
+ rawDrop: parsed.rawDrop,
191
+ hasDirective: true,
192
+ hasOptions: parsed.hasOptions,
193
+ };
194
+ }
195
+ function elideText(text, limit = 140) {
196
+ if (text.length <= limit)
197
+ return text;
198
+ return `${text.slice(0, Math.max(0, limit - 1)).trimEnd()}…`;
199
+ }
200
+ function buildQueueSummaryLine(run) {
201
+ const base = run.summaryLine?.trim() || run.prompt.trim();
202
+ const cleaned = base.replace(/\s+/g, " ").trim();
203
+ return elideText(cleaned, 160);
204
+ }
205
+ function getFollowupQueue(key, settings) {
206
+ const existing = FOLLOWUP_QUEUES.get(key);
207
+ if (existing) {
208
+ existing.mode = settings.mode;
209
+ existing.debounceMs =
210
+ typeof settings.debounceMs === "number"
211
+ ? Math.max(0, settings.debounceMs)
212
+ : existing.debounceMs;
213
+ existing.cap =
214
+ typeof settings.cap === "number" && settings.cap > 0
215
+ ? Math.floor(settings.cap)
216
+ : existing.cap;
217
+ existing.dropPolicy = settings.dropPolicy ?? existing.dropPolicy;
218
+ return existing;
219
+ }
220
+ const created = {
221
+ items: [],
222
+ draining: false,
223
+ lastEnqueuedAt: 0,
224
+ mode: settings.mode,
225
+ debounceMs: typeof settings.debounceMs === "number"
226
+ ? Math.max(0, settings.debounceMs)
227
+ : DEFAULT_QUEUE_DEBOUNCE_MS,
228
+ cap: typeof settings.cap === "number" && settings.cap > 0
229
+ ? Math.floor(settings.cap)
230
+ : DEFAULT_QUEUE_CAP,
231
+ dropPolicy: settings.dropPolicy ?? DEFAULT_QUEUE_DROP,
232
+ droppedCount: 0,
233
+ summaryLines: [],
234
+ };
235
+ FOLLOWUP_QUEUES.set(key, created);
236
+ return created;
237
+ }
238
+ export function enqueueFollowupRun(key, run, settings) {
239
+ const queue = getFollowupQueue(key, settings);
240
+ queue.lastEnqueuedAt = Date.now();
241
+ queue.lastRun = run.run;
242
+ const cap = queue.cap;
243
+ if (cap > 0 && queue.items.length >= cap) {
244
+ if (queue.dropPolicy === "new") {
245
+ return false;
246
+ }
247
+ const dropCount = queue.items.length - cap + 1;
248
+ const dropped = queue.items.splice(0, dropCount);
249
+ if (queue.dropPolicy === "summarize") {
250
+ for (const item of dropped) {
251
+ queue.droppedCount += 1;
252
+ queue.summaryLines.push(buildQueueSummaryLine(item));
253
+ }
254
+ while (queue.summaryLines.length > cap)
255
+ queue.summaryLines.shift();
256
+ }
257
+ }
258
+ queue.items.push(run);
259
+ return true;
260
+ }
261
+ async function waitForQueueDebounce(queue) {
262
+ const debounceMs = Math.max(0, queue.debounceMs);
263
+ if (debounceMs <= 0)
264
+ return;
265
+ while (true) {
266
+ const since = Date.now() - queue.lastEnqueuedAt;
267
+ if (since >= debounceMs)
268
+ return;
269
+ await new Promise((resolve) => setTimeout(resolve, debounceMs - since));
270
+ }
271
+ }
272
+ function buildSummaryPrompt(queue) {
273
+ if (queue.dropPolicy !== "summarize" || queue.droppedCount <= 0) {
274
+ return undefined;
275
+ }
276
+ const lines = [
277
+ `[Queue overflow] Dropped ${queue.droppedCount} message${queue.droppedCount === 1 ? "" : "s"} due to cap.`,
278
+ ];
279
+ if (queue.summaryLines.length > 0) {
280
+ lines.push("Summary:");
281
+ for (const line of queue.summaryLines) {
282
+ lines.push(`- ${line}`);
283
+ }
284
+ }
285
+ queue.droppedCount = 0;
286
+ queue.summaryLines = [];
287
+ return lines.join("\n");
288
+ }
289
+ function buildCollectPrompt(items, summary) {
290
+ const blocks = ["[Queued messages while agent was busy]"];
291
+ if (summary) {
292
+ blocks.push(summary);
293
+ }
294
+ items.forEach((item, idx) => {
295
+ blocks.push(`---\nQueued #${idx + 1}\n${item.prompt}`.trim());
296
+ });
297
+ return blocks.join("\n\n");
298
+ }
299
+ export function scheduleFollowupDrain(key, runFollowup) {
300
+ const queue = FOLLOWUP_QUEUES.get(key);
301
+ if (!queue || queue.draining)
302
+ return;
303
+ queue.draining = true;
304
+ void (async () => {
305
+ try {
306
+ while (queue.items.length > 0 || queue.droppedCount > 0) {
307
+ await waitForQueueDebounce(queue);
308
+ if (queue.mode === "collect") {
309
+ const items = queue.items.splice(0, queue.items.length);
310
+ const summary = buildSummaryPrompt(queue);
311
+ const run = items.at(-1)?.run ?? queue.lastRun;
312
+ if (!run)
313
+ break;
314
+ const prompt = buildCollectPrompt(items, summary);
315
+ await runFollowup({
316
+ prompt,
317
+ run,
318
+ enqueuedAt: Date.now(),
319
+ });
320
+ continue;
321
+ }
322
+ const summaryPrompt = buildSummaryPrompt(queue);
323
+ if (summaryPrompt) {
324
+ const run = queue.lastRun;
325
+ if (!run)
326
+ break;
327
+ await runFollowup({
328
+ prompt: summaryPrompt,
329
+ run,
330
+ enqueuedAt: Date.now(),
331
+ });
332
+ continue;
333
+ }
334
+ const next = queue.items.shift();
335
+ if (!next)
336
+ break;
337
+ await runFollowup(next);
338
+ }
339
+ }
340
+ catch (err) {
341
+ defaultRuntime.error?.(`followup queue drain failed for ${key}: ${String(err)}`);
342
+ }
343
+ finally {
344
+ queue.draining = false;
345
+ if (queue.items.length === 0 && queue.droppedCount === 0) {
346
+ FOLLOWUP_QUEUES.delete(key);
347
+ }
348
+ else {
349
+ scheduleFollowupDrain(key, runFollowup);
350
+ }
351
+ }
352
+ })();
353
+ }
354
+ function defaultQueueModeForSurface(surface) {
355
+ const normalized = surface?.trim().toLowerCase();
356
+ if (normalized === "discord")
357
+ return "collect";
358
+ if (normalized === "webchat")
359
+ return "collect";
360
+ if (normalized === "whatsapp")
361
+ return "collect";
362
+ if (normalized === "telegram")
363
+ return "collect";
364
+ if (normalized === "imessage")
365
+ return "collect";
366
+ if (normalized === "signal")
367
+ return "collect";
368
+ return "collect";
369
+ }
370
+ export function resolveQueueSettings(params) {
371
+ const surfaceKey = params.surface?.trim().toLowerCase();
372
+ const queueCfg = params.cfg.routing?.queue;
373
+ const surfaceModeRaw = surfaceKey && queueCfg?.bySurface
374
+ ? queueCfg.bySurface[surfaceKey]
375
+ : undefined;
376
+ const resolvedMode = params.inlineMode ??
377
+ normalizeQueueMode(params.sessionEntry?.queueMode) ??
378
+ normalizeQueueMode(surfaceModeRaw) ??
379
+ normalizeQueueMode(queueCfg?.mode) ??
380
+ defaultQueueModeForSurface(surfaceKey);
381
+ const debounceRaw = params.inlineOptions?.debounceMs ??
382
+ params.sessionEntry?.queueDebounceMs ??
383
+ queueCfg?.debounceMs ??
384
+ DEFAULT_QUEUE_DEBOUNCE_MS;
385
+ const capRaw = params.inlineOptions?.cap ??
386
+ params.sessionEntry?.queueCap ??
387
+ queueCfg?.cap ??
388
+ DEFAULT_QUEUE_CAP;
389
+ const dropRaw = params.inlineOptions?.dropPolicy ??
390
+ params.sessionEntry?.queueDrop ??
391
+ normalizeQueueDropPolicy(queueCfg?.drop) ??
392
+ DEFAULT_QUEUE_DROP;
393
+ return {
394
+ mode: resolvedMode,
395
+ debounceMs: typeof debounceRaw === "number" ? Math.max(0, debounceRaw) : undefined,
396
+ cap: typeof capRaw === "number" ? Math.max(1, Math.floor(capRaw)) : undefined,
397
+ dropPolicy: dropRaw,
398
+ };
399
+ }
@@ -0,0 +1,26 @@
1
+ export function extractReplyToTag(text, currentMessageId) {
2
+ if (!text)
3
+ return { cleaned: "", hasTag: false };
4
+ let cleaned = text;
5
+ let replyToId;
6
+ let hasTag = false;
7
+ const currentMatch = cleaned.match(/\[\[reply_to_current\]\]/i);
8
+ if (currentMatch) {
9
+ cleaned = cleaned.replace(/\[\[reply_to_current\]\]/gi, " ");
10
+ hasTag = true;
11
+ if (currentMessageId?.trim()) {
12
+ replyToId = currentMessageId.trim();
13
+ }
14
+ }
15
+ const idMatch = cleaned.match(/\[\[reply_to:([^\]\n]+)\]\]/i);
16
+ if (idMatch?.[1]) {
17
+ cleaned = cleaned.replace(/\[\[reply_to:[^\]\n]+\]\]/gi, " ");
18
+ replyToId = idMatch[1].trim();
19
+ hasTag = true;
20
+ }
21
+ cleaned = cleaned
22
+ .replace(/[ \t]+/g, " ")
23
+ .replace(/[ \t]*\n[ \t]*/g, "\n")
24
+ .trim();
25
+ return { cleaned, replyToId, hasTag };
26
+ }
@@ -0,0 +1,87 @@
1
+ import crypto from "node:crypto";
2
+ import { buildWorkspaceSkillSnapshot } from "../../agents/skills.js";
3
+ import { saveSessionStore } from "../../config/sessions.js";
4
+ import { buildProviderSummary } from "../../infra/provider-summary.js";
5
+ import { drainSystemEvents } from "../../infra/system-events.js";
6
+ export async function prependSystemEvents(params) {
7
+ if (!params.isMainSession)
8
+ return params.prefixedBodyBase;
9
+ const compactSystemEvent = (line) => {
10
+ const trimmed = line.trim();
11
+ if (!trimmed)
12
+ return null;
13
+ const lower = trimmed.toLowerCase();
14
+ if (lower.includes("reason periodic"))
15
+ return null;
16
+ if (lower.includes("heartbeat"))
17
+ return null;
18
+ if (trimmed.startsWith("Node:")) {
19
+ return trimmed.replace(/ · last input [^·]+/i, "").trim();
20
+ }
21
+ return trimmed;
22
+ };
23
+ const systemLines = [];
24
+ const queued = drainSystemEvents();
25
+ systemLines.push(...queued.map(compactSystemEvent).filter((v) => Boolean(v)));
26
+ if (params.isNewSession) {
27
+ const summary = await buildProviderSummary(params.cfg);
28
+ if (summary.length > 0)
29
+ systemLines.unshift(...summary);
30
+ }
31
+ if (systemLines.length === 0)
32
+ return params.prefixedBodyBase;
33
+ const block = systemLines.map((l) => `System: ${l}`).join("\n");
34
+ return `${block}\n\n${params.prefixedBodyBase}`;
35
+ }
36
+ export async function ensureSkillSnapshot(params) {
37
+ const { sessionEntry, sessionStore, sessionKey, storePath, sessionId, isFirstTurnInSession, workspaceDir, cfg, } = params;
38
+ let nextEntry = sessionEntry;
39
+ let systemSent = sessionEntry?.systemSent ?? false;
40
+ if (isFirstTurnInSession && sessionStore && sessionKey) {
41
+ const current = nextEntry ??
42
+ sessionStore[sessionKey] ?? {
43
+ sessionId: sessionId ?? crypto.randomUUID(),
44
+ updatedAt: Date.now(),
45
+ };
46
+ const skillSnapshot = isFirstTurnInSession || !current.skillsSnapshot
47
+ ? buildWorkspaceSkillSnapshot(workspaceDir, { config: cfg })
48
+ : current.skillsSnapshot;
49
+ nextEntry = {
50
+ ...current,
51
+ sessionId: sessionId ?? current.sessionId ?? crypto.randomUUID(),
52
+ updatedAt: Date.now(),
53
+ systemSent: true,
54
+ skillsSnapshot: skillSnapshot,
55
+ };
56
+ sessionStore[sessionKey] = nextEntry;
57
+ if (storePath) {
58
+ await saveSessionStore(storePath, sessionStore);
59
+ }
60
+ systemSent = true;
61
+ }
62
+ const skillsSnapshot = nextEntry?.skillsSnapshot ??
63
+ (isFirstTurnInSession
64
+ ? undefined
65
+ : buildWorkspaceSkillSnapshot(workspaceDir, { config: cfg }));
66
+ if (skillsSnapshot &&
67
+ sessionStore &&
68
+ sessionKey &&
69
+ !isFirstTurnInSession &&
70
+ !nextEntry?.skillsSnapshot) {
71
+ const current = nextEntry ?? {
72
+ sessionId: sessionId ?? crypto.randomUUID(),
73
+ updatedAt: Date.now(),
74
+ };
75
+ nextEntry = {
76
+ ...current,
77
+ sessionId: sessionId ?? current.sessionId ?? crypto.randomUUID(),
78
+ updatedAt: Date.now(),
79
+ skillsSnapshot,
80
+ };
81
+ sessionStore[sessionKey] = nextEntry;
82
+ if (storePath) {
83
+ await saveSessionStore(storePath, sessionStore);
84
+ }
85
+ }
86
+ return { sessionEntry: nextEntry, skillsSnapshot, systemSent };
87
+ }