@poolzin/pool-bot 2026.2.17 → 2026.2.18

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 (469) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/agent-scope.js +4 -0
  3. package/dist/agents/announce-idempotency.js +14 -0
  4. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
  5. package/dist/agents/bash-tools.exec-runtime.js +438 -0
  6. package/dist/agents/bash-tools.shared.js +6 -0
  7. package/dist/agents/cli-runner/reliability.js +61 -0
  8. package/dist/agents/cli-watchdog-defaults.js +11 -0
  9. package/dist/agents/command-poll-backoff.js +63 -0
  10. package/dist/agents/current-time.js +16 -0
  11. package/dist/agents/model-alias-lines.js +18 -0
  12. package/dist/agents/model-auth-label.js +61 -0
  13. package/dist/agents/models-config.e2e-harness.js +115 -0
  14. package/dist/agents/ollama-stream.js +11 -3
  15. package/dist/agents/openclaw-tools.js +135 -0
  16. package/dist/agents/pi-auth-json.js +118 -0
  17. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
  18. package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
  19. package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
  20. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
  21. package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
  22. package/dist/agents/pi-tools.js +2 -0
  23. package/dist/agents/queued-file-writer.js +22 -0
  24. package/dist/agents/sandbox/docker.js +133 -40
  25. package/dist/agents/sandbox/fs-bridge.js +146 -0
  26. package/dist/agents/sandbox/fs-paths.js +205 -0
  27. package/dist/agents/sandbox/hash.js +4 -0
  28. package/dist/agents/sandbox-paths.js +3 -0
  29. package/dist/agents/session-dirs.js +20 -0
  30. package/dist/agents/skills/filter.js +24 -0
  31. package/dist/agents/skills/tools-dir.js +9 -0
  32. package/dist/agents/skills-install-download.js +290 -0
  33. package/dist/agents/skills-install-output.js +30 -0
  34. package/dist/agents/skills-install.download-test-utils.js +36 -0
  35. package/dist/agents/skills.e2e-test-helpers.js +13 -0
  36. package/dist/agents/subagent-announce-queue.js +59 -15
  37. package/dist/agents/subagent-depth.js +137 -0
  38. package/dist/agents/subagent-registry.js +448 -96
  39. package/dist/agents/subagent-spawn.js +262 -0
  40. package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
  41. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
  42. package/dist/agents/tool-display-common.js +782 -0
  43. package/dist/agents/tools/image-tool.js +1 -1
  44. package/dist/agents/tools/sessions-access.js +178 -0
  45. package/dist/agents/tools/sessions-resolution.js +206 -0
  46. package/dist/agents/tools/subagents-tool.js +616 -0
  47. package/dist/agents/workspace-dir.js +18 -0
  48. package/dist/agents/workspace-dirs.js +14 -0
  49. package/dist/agents/workspace.js +70 -0
  50. package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
  51. package/dist/auto-reply/reply/commands-export-session.js +163 -0
  52. package/dist/auto-reply/reply/commands-mesh.js +245 -0
  53. package/dist/auto-reply/reply/commands-setunset.js +28 -0
  54. package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
  55. package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
  56. package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
  57. package/dist/auto-reply/reply/directive-handling.params.js +1 -0
  58. package/dist/auto-reply/reply/directive-parsing.js +36 -0
  59. package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
  60. package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
  61. package/dist/auto-reply/reply/reply-delivery.js +92 -0
  62. package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
  63. package/dist/auto-reply/reply/session-run-accounting.js +33 -0
  64. package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
  65. package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
  66. package/dist/browser/bridge-auth-registry.js +26 -0
  67. package/dist/browser/client-actions-url.js +10 -0
  68. package/dist/browser/control-auth.js +73 -0
  69. package/dist/browser/csrf.js +64 -0
  70. package/dist/browser/http-auth.js +52 -0
  71. package/dist/browser/paths.js +37 -0
  72. package/dist/browser/proxy-files.js +32 -0
  73. package/dist/browser/pw-ai-state.js +7 -0
  74. package/dist/browser/resolved-config-refresh.js +42 -0
  75. package/dist/browser/routes/path-output.js +1 -0
  76. package/dist/browser/server-context.chrome-test-harness.js +20 -0
  77. package/dist/browser/server-middleware.js +31 -0
  78. package/dist/browser/test-port.js +16 -0
  79. package/dist/build-info.json +3 -3
  80. package/dist/canvas-host/file-resolver.js +43 -0
  81. package/dist/channels/account-summary.js +19 -0
  82. package/dist/channels/draft-stream-loop.js +77 -0
  83. package/dist/channels/plugins/account-helpers.js +26 -0
  84. package/dist/channels/telegram/allow-from.js +10 -0
  85. package/dist/cli/browser-cli-resize.js +22 -0
  86. package/dist/cli/browser-cli-shared.js +8 -0
  87. package/dist/cli/clawbot-cli.js +5 -0
  88. package/dist/cli/completion-cli.js +566 -0
  89. package/dist/cli/config-cli.js +63 -5
  90. package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
  91. package/dist/cli/daemon-cli/register-service-commands.js +60 -0
  92. package/dist/cli/daemon-cli-compat.js +80 -0
  93. package/dist/cli/nodes-cli/pairing-render.js +26 -0
  94. package/dist/cli/program/action-reparse.js +17 -0
  95. package/dist/cli/program/command-registry.js +17 -0
  96. package/dist/cli/program/program-context.js +8 -0
  97. package/dist/cli/program/register.subclis.js +7 -0
  98. package/dist/cli/program/routes.js +233 -0
  99. package/dist/cli/qr-cli.js +132 -0
  100. package/dist/cli/requirements-test-fixtures.js +17 -0
  101. package/dist/cli/respawn-policy.js +4 -0
  102. package/dist/cli/shared/parse-port.js +18 -0
  103. package/dist/cli/skills-cli.format.js +241 -0
  104. package/dist/cli/update-cli/progress.js +121 -0
  105. package/dist/cli/update-cli/restart-helper.js +108 -0
  106. package/dist/cli/update-cli/shared.js +196 -0
  107. package/dist/cli/update-cli/status.js +97 -0
  108. package/dist/cli/update-cli/suppress-deprecations.js +17 -0
  109. package/dist/cli/update-cli/update-command.js +506 -0
  110. package/dist/cli/update-cli/wizard.js +130 -0
  111. package/dist/cli/update-cli.js +3 -9
  112. package/dist/cli/windows-argv.js +69 -0
  113. package/dist/commands/auth-choice-legacy.js +20 -0
  114. package/dist/commands/auth-choice.apply-helpers.js +8 -0
  115. package/dist/commands/channel-test-helpers.js +19 -0
  116. package/dist/commands/cleanup-plan.js +10 -0
  117. package/dist/commands/cleanup-utils.js +7 -0
  118. package/dist/commands/config-validation.js +15 -0
  119. package/dist/commands/doctor-completion.js +112 -0
  120. package/dist/commands/doctor-memory-search.js +119 -0
  121. package/dist/commands/doctor-session-locks.js +73 -0
  122. package/dist/commands/doctor.e2e-harness.js +364 -0
  123. package/dist/commands/gateway-presence.js +19 -0
  124. package/dist/commands/model-default.js +35 -0
  125. package/dist/commands/models/fallbacks-shared.js +102 -0
  126. package/dist/commands/models/shared.js +24 -0
  127. package/dist/commands/onboard-auth.config-gateways.js +64 -0
  128. package/dist/commands/onboard-auth.config-litellm.js +45 -0
  129. package/dist/commands/onboard-auth.config-shared.js +116 -0
  130. package/dist/commands/onboard-config.js +16 -0
  131. package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
  132. package/dist/commands/onboard-provider-auth-flags.js +136 -0
  133. package/dist/commands/openai-codex-oauth.js +40 -0
  134. package/dist/commands/test-runtime-config-helpers.js +21 -0
  135. package/dist/commands/test-wizard-helpers.js +68 -0
  136. package/dist/commands/vllm-setup.js +66 -0
  137. package/dist/compat/legacy-names.js +2 -0
  138. package/dist/config/backup-rotation.js +19 -0
  139. package/dist/config/env-preserve.js +122 -0
  140. package/dist/config/includes-scan.js +78 -0
  141. package/dist/config/plugins-allowlist.js +13 -0
  142. package/dist/config/schema.help.js +256 -0
  143. package/dist/config/schema.hints.js +189 -0
  144. package/dist/config/schema.irc.js +20 -0
  145. package/dist/config/schema.labels.js +317 -0
  146. package/dist/config/sessions/delivery-info.js +40 -0
  147. package/dist/config/types.irc.js +1 -0
  148. package/dist/config/zod-schema.agent-model.js +10 -0
  149. package/dist/config/zod-schema.allowdeny.js +35 -0
  150. package/dist/config/zod-schema.sensitive.js +4 -0
  151. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  152. package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
  153. package/dist/cron/isolated-agent/subagent-followup.js +127 -0
  154. package/dist/cron/isolated-agent.mocks.js +12 -0
  155. package/dist/cron/isolated-agent.test-setup.js +22 -0
  156. package/dist/cron/legacy-delivery.js +43 -0
  157. package/dist/cron/webhook-url.js +22 -0
  158. package/dist/daemon/arg-split.js +40 -0
  159. package/dist/daemon/exec-file.js +23 -0
  160. package/dist/daemon/output.js +6 -0
  161. package/dist/daemon/runtime-format.js +31 -0
  162. package/dist/daemon/schtasks-exec.js +4 -0
  163. package/dist/daemon/service-audit.js +22 -0
  164. package/dist/discord/client.js +41 -0
  165. package/dist/discord/components-registry.js +57 -0
  166. package/dist/discord/components.js +816 -0
  167. package/dist/discord/guilds.js +12 -0
  168. package/dist/discord/monitor/gateway-plugin.js +48 -0
  169. package/dist/discord/monitor/presence.js +30 -0
  170. package/dist/discord/send.components.js +115 -0
  171. package/dist/discord/send.shared.js +4 -0
  172. package/dist/discord/ui.js +26 -0
  173. package/dist/discord/voice-message.js +254 -0
  174. package/dist/gateway/agent-event-assistant-text.js +5 -0
  175. package/dist/gateway/agent-prompt.js +33 -0
  176. package/dist/gateway/auth-rate-limit.js +136 -0
  177. package/dist/gateway/channel-health-monitor.js +114 -0
  178. package/dist/gateway/control-ui-contract.js +1 -0
  179. package/dist/gateway/control-ui-csp.js +15 -0
  180. package/dist/gateway/gateway-config-prompts.shared.js +25 -0
  181. package/dist/gateway/http-auth-helpers.js +18 -0
  182. package/dist/gateway/http-common.js +18 -0
  183. package/dist/gateway/http-endpoint-helpers.js +27 -0
  184. package/dist/gateway/node-invoke-sanitize.js +11 -0
  185. package/dist/gateway/node-invoke-system-run-approval.js +205 -0
  186. package/dist/gateway/probe-auth.js +21 -0
  187. package/dist/gateway/protocol/index.js +7 -2
  188. package/dist/gateway/protocol/schema/mesh.js +54 -0
  189. package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
  190. package/dist/gateway/protocol/schema.js +1 -0
  191. package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
  192. package/dist/gateway/server-channels.js +11 -0
  193. package/dist/gateway/server-methods/attachment-normalize.js +16 -0
  194. package/dist/gateway/server-methods/base-hash.js +8 -0
  195. package/dist/gateway/server-methods/mesh.js +700 -0
  196. package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
  197. package/dist/gateway/server-methods/restart-request.js +13 -0
  198. package/dist/gateway/server-methods/validation.js +8 -0
  199. package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
  200. package/dist/gateway/server.e2e-registry-helpers.js +1 -0
  201. package/dist/gateway/server.e2e-ws-harness.js +20 -0
  202. package/dist/gateway/test-helpers.js +2 -0
  203. package/dist/gateway/test-helpers.server.js +3 -1
  204. package/dist/gateway/test-http-response.js +12 -0
  205. package/dist/gateway/test-openai-responses-model.js +20 -0
  206. package/dist/gateway/test-temp-config.js +30 -0
  207. package/dist/gateway/test-with-server.js +32 -0
  208. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
  209. package/dist/imessage/monitor/abort-handler.js +23 -0
  210. package/dist/imessage/monitor/inbound-processing.js +346 -0
  211. package/dist/imessage/monitor/parse-notification.js +64 -0
  212. package/dist/imessage/target-parsing-helpers.js +92 -0
  213. package/dist/infra/archive.js +244 -20
  214. package/dist/infra/detect-package-manager.js +26 -0
  215. package/dist/infra/exec-approvals-allowlist.js +257 -0
  216. package/dist/infra/exec-approvals-analysis.js +770 -0
  217. package/dist/infra/exec-approvals.js +13 -0
  218. package/dist/infra/file-lock.js +1 -0
  219. package/dist/infra/gemini-auth.js +39 -0
  220. package/dist/infra/heartbeat-active-hours.js +85 -0
  221. package/dist/infra/heartbeat-events-filter.js +50 -0
  222. package/dist/infra/heartbeat-runner.test-utils.js +39 -0
  223. package/dist/infra/http-body.js +265 -0
  224. package/dist/infra/install-package-dir.js +50 -0
  225. package/dist/infra/install-safe-path.js +49 -0
  226. package/dist/infra/json-files.js +49 -0
  227. package/dist/infra/jsonl-socket.js +52 -0
  228. package/dist/infra/map-size.js +14 -0
  229. package/dist/infra/net/hostname.js +7 -0
  230. package/dist/infra/npm-registry-spec.js +39 -0
  231. package/dist/infra/openclaw-root.js +109 -0
  232. package/dist/infra/outbound/delivery-queue.js +214 -0
  233. package/dist/infra/outbound/identity.js +23 -0
  234. package/dist/infra/outbound/message-action-params.js +307 -0
  235. package/dist/infra/outbound/tool-payload.js +21 -0
  236. package/dist/infra/package-json.js +23 -0
  237. package/dist/infra/pairing-files.js +19 -0
  238. package/dist/infra/pairing-token.js +9 -0
  239. package/dist/infra/path-prepend.js +51 -0
  240. package/dist/infra/process-respawn.js +49 -0
  241. package/dist/infra/runtime-status.js +16 -0
  242. package/dist/infra/session-cost-usage.types.js +1 -0
  243. package/dist/infra/session-maintenance-warning.js +89 -0
  244. package/dist/infra/system-run-command.js +78 -0
  245. package/dist/infra/tmp-openclaw-dir.js +81 -0
  246. package/dist/infra/tmp-poolbot-dir.js +2 -0
  247. package/dist/infra/update-channels.js +19 -0
  248. package/dist/line/actions.js +45 -0
  249. package/dist/line/channel-access-token.js +9 -0
  250. package/dist/line/flex-templates/basic-cards.js +332 -0
  251. package/dist/line/flex-templates/common.js +18 -0
  252. package/dist/line/flex-templates/media-control-cards.js +453 -0
  253. package/dist/line/flex-templates/message.js +10 -0
  254. package/dist/line/flex-templates/schedule-cards.js +399 -0
  255. package/dist/line/flex-templates/types.js +1 -0
  256. package/dist/line/webhook-node.js +100 -0
  257. package/dist/line/webhook-utils.js +11 -0
  258. package/dist/logging/timestamps.js +14 -0
  259. package/dist/markdown/whatsapp.js +62 -0
  260. package/dist/media/base64.js +34 -0
  261. package/dist/media/local-roots.js +32 -0
  262. package/dist/media/outbound-attachment.js +10 -0
  263. package/dist/media/read-response-with-limit.js +41 -0
  264. package/dist/media/sniff-mime-from-base64.js +19 -0
  265. package/dist/media-understanding/audio-preflight.js +67 -0
  266. package/dist/media-understanding/fs.js +13 -0
  267. package/dist/media-understanding/output-extract.js +26 -0
  268. package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
  269. package/dist/media-understanding/providers/google/inline-data.js +64 -0
  270. package/dist/media-understanding/providers/shared.js +7 -0
  271. package/dist/media-understanding/runner.entries.js +459 -0
  272. package/dist/memory/batch-error-utils.js +11 -0
  273. package/dist/memory/batch-http.js +27 -0
  274. package/dist/memory/batch-output.js +29 -0
  275. package/dist/memory/batch-runner.js +22 -0
  276. package/dist/memory/batch-upload.js +23 -0
  277. package/dist/memory/batch-utils.js +26 -0
  278. package/dist/memory/embeddings-debug.js +11 -0
  279. package/dist/memory/embeddings-remote-client.js +22 -0
  280. package/dist/memory/embeddings-remote-fetch.js +14 -0
  281. package/dist/memory/manager-embedding-ops.js +616 -0
  282. package/dist/memory/manager-sync-ops.js +953 -0
  283. package/dist/memory/qmd-manager.js +1061 -0
  284. package/dist/memory/qmd-query-parser.js +107 -0
  285. package/dist/memory/qmd-scope.js +93 -0
  286. package/dist/memory/search-manager.js +0 -1
  287. package/dist/memory/sync-index.js +21 -0
  288. package/dist/memory/sync-progress.js +22 -0
  289. package/dist/memory/sync-stale.js +30 -0
  290. package/dist/memory/test-embeddings-mock.js +16 -0
  291. package/dist/memory/test-manager-helpers.js +14 -0
  292. package/dist/memory/test-runtime-mocks.js +11 -0
  293. package/dist/node-host/invoke-browser.js +177 -0
  294. package/dist/node-host/invoke.js +685 -0
  295. package/dist/pairing/setup-code.js +285 -0
  296. package/dist/plugin-sdk/account-id.js +1 -0
  297. package/dist/plugin-sdk/agent-media-payload.js +13 -0
  298. package/dist/plugin-sdk/allow-from.js +47 -0
  299. package/dist/plugin-sdk/command-auth.js +23 -0
  300. package/dist/plugin-sdk/config-paths.js +9 -0
  301. package/dist/plugin-sdk/file-lock.js +116 -0
  302. package/dist/plugin-sdk/json-store.js +31 -0
  303. package/dist/plugin-sdk/onboarding.js +28 -0
  304. package/dist/plugin-sdk/provider-auth-result.js +29 -0
  305. package/dist/plugin-sdk/slack-message-actions.js +133 -0
  306. package/dist/plugin-sdk/status-helpers.js +35 -0
  307. package/dist/plugin-sdk/text-chunking.js +31 -0
  308. package/dist/plugin-sdk/tool-send.js +12 -0
  309. package/dist/plugin-sdk/webhook-path.js +27 -0
  310. package/dist/plugin-sdk/webhook-targets.js +34 -0
  311. package/dist/plugins/hooks.test-helpers.js +21 -0
  312. package/dist/plugins/uninstall.js +171 -0
  313. package/dist/process/supervisor/adapters/child.js +143 -0
  314. package/dist/process/supervisor/adapters/env.js +13 -0
  315. package/dist/process/supervisor/adapters/pty.js +148 -0
  316. package/dist/process/supervisor/index.js +10 -0
  317. package/dist/process/supervisor/registry.js +117 -0
  318. package/dist/process/supervisor/supervisor.js +244 -0
  319. package/dist/process/supervisor/types.js +1 -0
  320. package/dist/providers/google-shared.test-helpers.js +75 -0
  321. package/dist/security/audit-channel.js +419 -0
  322. package/dist/security/audit-tool-policy.js +1 -0
  323. package/dist/security/scan-paths.js +12 -0
  324. package/dist/sessions/input-provenance.js +55 -0
  325. package/dist/sessions/session-key-utils.js +7 -0
  326. package/dist/shared/chat-content.js +31 -0
  327. package/dist/shared/chat-envelope.js +45 -0
  328. package/dist/shared/config-eval.js +117 -0
  329. package/dist/shared/device-auth.js +16 -0
  330. package/dist/shared/entry-metadata.js +9 -0
  331. package/dist/shared/entry-status.js +25 -0
  332. package/dist/shared/frontmatter.js +98 -0
  333. package/dist/shared/model-param-b.js +19 -0
  334. package/dist/shared/net/ipv4.js +17 -0
  335. package/dist/shared/node-match.js +53 -0
  336. package/dist/shared/requirements.js +128 -0
  337. package/dist/shared/subagents-format.js +84 -0
  338. package/dist/shared/usage-aggregates.js +28 -0
  339. package/dist/signal/monitor/mentions.js +45 -0
  340. package/dist/signal/rpc-context.js +19 -0
  341. package/dist/slack/blocks-fallback.js +76 -0
  342. package/dist/slack/blocks-input.js +40 -0
  343. package/dist/slack/draft-stream.js +106 -0
  344. package/dist/slack/message-actions.js +51 -0
  345. package/dist/slack/modal-metadata.js +32 -0
  346. package/dist/slack/monitor/events/interactions.js +462 -0
  347. package/dist/slack/monitor/room-context.js +17 -0
  348. package/dist/slack/stream-mode.js +41 -0
  349. package/dist/telegram/bot-native-command-menu.js +64 -0
  350. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  351. package/dist/telegram/button-types.js +1 -0
  352. package/dist/telegram/group-access.js +65 -0
  353. package/dist/telegram/outbound-params.js +21 -0
  354. package/dist/telegram/poll-vote-cache.js +21 -0
  355. package/dist/terminal/health-style.js +36 -0
  356. package/dist/test-utils/chunk-test-helpers.js +21 -0
  357. package/dist/test-utils/env.js +72 -0
  358. package/dist/test-utils/exec-assertions.js +12 -0
  359. package/dist/test-utils/imessage-test-plugin.js +54 -0
  360. package/dist/test-utils/mock-http-response.js +17 -0
  361. package/dist/test-utils/vitest-mock-fn.js +1 -0
  362. package/dist/tts/tts-core.js +550 -0
  363. package/dist/utils/chunk-items.js +10 -0
  364. package/dist/utils/reaction-level.js +52 -0
  365. package/dist/utils/safe-json.js +22 -0
  366. package/dist/utils/with-timeout.js +14 -0
  367. package/dist/web/media.js +17 -5
  368. package/dist/whatsapp/resolve-outbound-target.js +42 -0
  369. package/dist/wizard/onboarding.completion.js +74 -0
  370. package/extensions/bluebubbles/src/account-resolve.ts +29 -0
  371. package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
  372. package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
  373. package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
  374. package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
  375. package/extensions/bluebubbles/src/multipart.ts +32 -0
  376. package/extensions/bluebubbles/src/send-helpers.ts +53 -0
  377. package/extensions/bluebubbles/src/test-harness.ts +50 -0
  378. package/extensions/bluebubbles/src/test-mocks.ts +11 -0
  379. package/extensions/device-pair/index.ts +554 -0
  380. package/extensions/discord/src/channel.js +366 -0
  381. package/extensions/discord/src/runtime.js +10 -0
  382. package/extensions/feishu/index.ts +63 -0
  383. package/extensions/feishu/src/accounts.ts +114 -0
  384. package/extensions/feishu/src/bitable.ts +739 -0
  385. package/extensions/feishu/src/bot.ts +965 -0
  386. package/extensions/feishu/src/channel.ts +351 -0
  387. package/extensions/feishu/src/client.ts +118 -0
  388. package/extensions/feishu/src/config-schema.ts +206 -0
  389. package/extensions/feishu/src/dedup.ts +33 -0
  390. package/extensions/feishu/src/directory.ts +177 -0
  391. package/extensions/feishu/src/doc-schema.ts +47 -0
  392. package/extensions/feishu/src/docx.ts +536 -0
  393. package/extensions/feishu/src/drive-schema.ts +46 -0
  394. package/extensions/feishu/src/drive.ts +227 -0
  395. package/extensions/feishu/src/dynamic-agent.ts +131 -0
  396. package/extensions/feishu/src/media.ts +449 -0
  397. package/extensions/feishu/src/mention.ts +126 -0
  398. package/extensions/feishu/src/monitor.ts +330 -0
  399. package/extensions/feishu/src/onboarding.ts +359 -0
  400. package/extensions/feishu/src/outbound.ts +55 -0
  401. package/extensions/feishu/src/perm-schema.ts +52 -0
  402. package/extensions/feishu/src/perm.ts +173 -0
  403. package/extensions/feishu/src/policy.ts +84 -0
  404. package/extensions/feishu/src/probe.ts +44 -0
  405. package/extensions/feishu/src/reactions.ts +160 -0
  406. package/extensions/feishu/src/reply-dispatcher.ts +239 -0
  407. package/extensions/feishu/src/runtime.ts +14 -0
  408. package/extensions/feishu/src/send-result.ts +29 -0
  409. package/extensions/feishu/src/send.ts +335 -0
  410. package/extensions/feishu/src/streaming-card.ts +223 -0
  411. package/extensions/feishu/src/targets.ts +78 -0
  412. package/extensions/feishu/src/tools-config.ts +21 -0
  413. package/extensions/feishu/src/types.ts +81 -0
  414. package/extensions/feishu/src/typing.ts +80 -0
  415. package/extensions/feishu/src/wiki-schema.ts +55 -0
  416. package/extensions/feishu/src/wiki.ts +232 -0
  417. package/extensions/imessage/src/channel.js +253 -0
  418. package/extensions/imessage/src/runtime.js +10 -0
  419. package/extensions/irc/index.ts +17 -0
  420. package/extensions/irc/src/accounts.ts +268 -0
  421. package/extensions/irc/src/channel.ts +367 -0
  422. package/extensions/irc/src/client.ts +439 -0
  423. package/extensions/irc/src/config-schema.ts +97 -0
  424. package/extensions/irc/src/connect-options.ts +30 -0
  425. package/extensions/irc/src/control-chars.ts +22 -0
  426. package/extensions/irc/src/inbound.ts +334 -0
  427. package/extensions/irc/src/monitor.ts +147 -0
  428. package/extensions/irc/src/normalize.ts +117 -0
  429. package/extensions/irc/src/onboarding.ts +479 -0
  430. package/extensions/irc/src/policy.ts +157 -0
  431. package/extensions/irc/src/probe.ts +53 -0
  432. package/extensions/irc/src/protocol.ts +169 -0
  433. package/extensions/irc/src/runtime.ts +14 -0
  434. package/extensions/irc/src/send.ts +88 -0
  435. package/extensions/irc/src/types.ts +93 -0
  436. package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
  437. package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
  438. package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
  439. package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
  440. package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
  441. package/extensions/minimax-portal-auth/index.ts +161 -0
  442. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  443. package/extensions/msteams/src/file-lock.ts +1 -0
  444. package/extensions/msteams/src/graph.ts +92 -0
  445. package/extensions/msteams/src/mentions.ts +114 -0
  446. package/extensions/msteams/src/test-runtime.ts +16 -0
  447. package/extensions/openai-codex-auth/index.ts +177 -0
  448. package/extensions/phone-control/index.ts +421 -0
  449. package/extensions/shared/resolve-target-test-helpers.ts +66 -0
  450. package/extensions/signal/src/channel.js +273 -0
  451. package/extensions/signal/src/runtime.js +10 -0
  452. package/extensions/slack/src/channel.js +489 -0
  453. package/extensions/slack/src/runtime.js +10 -0
  454. package/extensions/talk-voice/index.ts +150 -0
  455. package/extensions/telegram/src/channel.js +424 -0
  456. package/extensions/telegram/src/runtime.js +10 -0
  457. package/extensions/thread-ownership/index.ts +133 -0
  458. package/extensions/tlon/src/account-fields.ts +25 -0
  459. package/extensions/tlon/src/urbit/base-url.ts +57 -0
  460. package/extensions/tlon/src/urbit/channel-client.ts +157 -0
  461. package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
  462. package/extensions/tlon/src/urbit/context.ts +47 -0
  463. package/extensions/tlon/src/urbit/errors.ts +51 -0
  464. package/extensions/tlon/src/urbit/fetch.ts +39 -0
  465. package/extensions/twitch/src/test-fixtures.ts +30 -0
  466. package/extensions/voice-call/src/allowlist.ts +19 -0
  467. package/extensions/whatsapp/src/channel.js +429 -0
  468. package/extensions/whatsapp/src/runtime.js +10 -0
  469. package/package.json +1 -1
@@ -0,0 +1,117 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export function isTruthy(value) {
4
+ if (value === undefined || value === null) {
5
+ return false;
6
+ }
7
+ if (typeof value === "boolean") {
8
+ return value;
9
+ }
10
+ if (typeof value === "number") {
11
+ return value !== 0;
12
+ }
13
+ if (typeof value === "string") {
14
+ return value.trim().length > 0;
15
+ }
16
+ return true;
17
+ }
18
+ export function resolveConfigPath(config, pathStr) {
19
+ const parts = pathStr.split(".").filter(Boolean);
20
+ let current = config;
21
+ for (const part of parts) {
22
+ if (typeof current !== "object" || current === null) {
23
+ return undefined;
24
+ }
25
+ current = current[part];
26
+ }
27
+ return current;
28
+ }
29
+ export function isConfigPathTruthyWithDefaults(config, pathStr, defaults) {
30
+ const value = resolveConfigPath(config, pathStr);
31
+ if (value === undefined && pathStr in defaults) {
32
+ return defaults[pathStr] ?? false;
33
+ }
34
+ return isTruthy(value);
35
+ }
36
+ export function evaluateRuntimeRequires(params) {
37
+ const requires = params.requires;
38
+ if (!requires) {
39
+ return true;
40
+ }
41
+ const requiredBins = requires.bins ?? [];
42
+ if (requiredBins.length > 0) {
43
+ for (const bin of requiredBins) {
44
+ if (params.hasBin(bin)) {
45
+ continue;
46
+ }
47
+ if (params.hasRemoteBin?.(bin)) {
48
+ continue;
49
+ }
50
+ return false;
51
+ }
52
+ }
53
+ const requiredAnyBins = requires.anyBins ?? [];
54
+ if (requiredAnyBins.length > 0) {
55
+ const anyFound = requiredAnyBins.some((bin) => params.hasBin(bin));
56
+ if (!anyFound && !params.hasAnyRemoteBin?.(requiredAnyBins)) {
57
+ return false;
58
+ }
59
+ }
60
+ const requiredEnv = requires.env ?? [];
61
+ if (requiredEnv.length > 0) {
62
+ for (const envName of requiredEnv) {
63
+ if (!params.hasEnv(envName)) {
64
+ return false;
65
+ }
66
+ }
67
+ }
68
+ const requiredConfig = requires.config ?? [];
69
+ if (requiredConfig.length > 0) {
70
+ for (const configPath of requiredConfig) {
71
+ if (!params.isConfigPathTruthy(configPath)) {
72
+ return false;
73
+ }
74
+ }
75
+ }
76
+ return true;
77
+ }
78
+ export function resolveRuntimePlatform() {
79
+ return process.platform;
80
+ }
81
+ function windowsPathExtensions() {
82
+ const raw = process.env.PATHEXT;
83
+ const list = raw !== undefined ? raw.split(";").map((v) => v.trim()) : [".EXE", ".CMD", ".BAT", ".COM"];
84
+ return ["", ...list.filter(Boolean)];
85
+ }
86
+ let cachedHasBinaryPath;
87
+ let cachedHasBinaryPathExt;
88
+ const hasBinaryCache = new Map();
89
+ export function hasBinary(bin) {
90
+ const pathEnv = process.env.PATH ?? "";
91
+ const pathExt = process.platform === "win32" ? (process.env.PATHEXT ?? "") : "";
92
+ if (cachedHasBinaryPath !== pathEnv || cachedHasBinaryPathExt !== pathExt) {
93
+ cachedHasBinaryPath = pathEnv;
94
+ cachedHasBinaryPathExt = pathExt;
95
+ hasBinaryCache.clear();
96
+ }
97
+ if (hasBinaryCache.has(bin)) {
98
+ return hasBinaryCache.get(bin);
99
+ }
100
+ const parts = pathEnv.split(path.delimiter).filter(Boolean);
101
+ const extensions = process.platform === "win32" ? windowsPathExtensions() : [""];
102
+ for (const part of parts) {
103
+ for (const ext of extensions) {
104
+ const candidate = path.join(part, bin + ext);
105
+ try {
106
+ fs.accessSync(candidate, fs.constants.X_OK);
107
+ hasBinaryCache.set(bin, true);
108
+ return true;
109
+ }
110
+ catch {
111
+ // keep scanning
112
+ }
113
+ }
114
+ }
115
+ hasBinaryCache.set(bin, false);
116
+ return false;
117
+ }
@@ -0,0 +1,16 @@
1
+ export function normalizeDeviceAuthRole(role) {
2
+ return role.trim();
3
+ }
4
+ export function normalizeDeviceAuthScopes(scopes) {
5
+ if (!Array.isArray(scopes)) {
6
+ return [];
7
+ }
8
+ const out = new Set();
9
+ for (const scope of scopes) {
10
+ const trimmed = scope.trim();
11
+ if (trimmed) {
12
+ out.add(trimmed);
13
+ }
14
+ }
15
+ return [...out].toSorted();
16
+ }
@@ -0,0 +1,9 @@
1
+ export function resolveEmojiAndHomepage(params) {
2
+ const emoji = params.metadata?.emoji ?? params.frontmatter?.emoji;
3
+ const homepageRaw = params.metadata?.homepage ??
4
+ params.frontmatter?.homepage ??
5
+ params.frontmatter?.website ??
6
+ params.frontmatter?.url;
7
+ const homepage = homepageRaw?.trim() ? homepageRaw.trim() : undefined;
8
+ return { ...(emoji ? { emoji } : {}), ...(homepage ? { homepage } : {}) };
9
+ }
@@ -0,0 +1,25 @@
1
+ import { resolveEmojiAndHomepage } from "./entry-metadata.js";
2
+ import { evaluateRequirementsFromMetadataWithRemote, } from "./requirements.js";
3
+ export function evaluateEntryMetadataRequirements(params) {
4
+ const { emoji, homepage } = resolveEmojiAndHomepage({
5
+ metadata: params.metadata,
6
+ frontmatter: params.frontmatter,
7
+ });
8
+ const { required, missing, eligible, configChecks } = evaluateRequirementsFromMetadataWithRemote({
9
+ always: params.always,
10
+ metadata: params.metadata ?? undefined,
11
+ hasLocalBin: params.hasLocalBin,
12
+ localPlatform: params.localPlatform,
13
+ remote: params.remote,
14
+ isEnvSatisfied: params.isEnvSatisfied,
15
+ isConfigSatisfied: params.isConfigSatisfied,
16
+ });
17
+ return {
18
+ ...(emoji ? { emoji } : {}),
19
+ ...(homepage ? { homepage } : {}),
20
+ required,
21
+ missing,
22
+ requirementsSatisfied: eligible,
23
+ configChecks,
24
+ };
25
+ }
@@ -0,0 +1,98 @@
1
+ import JSON5 from "json5";
2
+ import { LEGACY_MANIFEST_KEYS, MANIFEST_KEY } from "../compat/legacy-names.js";
3
+ import { parseBooleanValue } from "../utils/boolean.js";
4
+ export function normalizeStringList(input) {
5
+ if (!input) {
6
+ return [];
7
+ }
8
+ if (Array.isArray(input)) {
9
+ return input.map((value) => String(value).trim()).filter(Boolean);
10
+ }
11
+ if (typeof input === "string") {
12
+ return input
13
+ .split(",")
14
+ .map((value) => value.trim())
15
+ .filter(Boolean);
16
+ }
17
+ return [];
18
+ }
19
+ export function getFrontmatterString(frontmatter, key) {
20
+ const raw = frontmatter[key];
21
+ return typeof raw === "string" ? raw : undefined;
22
+ }
23
+ export function parseFrontmatterBool(value, fallback) {
24
+ const parsed = parseBooleanValue(value);
25
+ return parsed === undefined ? fallback : parsed;
26
+ }
27
+ export function resolveOpenClawManifestBlock(params) {
28
+ const raw = getFrontmatterString(params.frontmatter, params.key ?? "metadata");
29
+ if (!raw) {
30
+ return undefined;
31
+ }
32
+ try {
33
+ const parsed = JSON5.parse(raw);
34
+ if (!parsed || typeof parsed !== "object") {
35
+ return undefined;
36
+ }
37
+ const manifestKeys = [MANIFEST_KEY, ...LEGACY_MANIFEST_KEYS];
38
+ for (const key of manifestKeys) {
39
+ const candidate = parsed[key];
40
+ if (candidate && typeof candidate === "object") {
41
+ return candidate;
42
+ }
43
+ }
44
+ return undefined;
45
+ }
46
+ catch {
47
+ return undefined;
48
+ }
49
+ }
50
+ export function resolveOpenClawManifestRequires(metadataObj) {
51
+ const requiresRaw = typeof metadataObj.requires === "object" && metadataObj.requires !== null
52
+ ? metadataObj.requires
53
+ : undefined;
54
+ if (!requiresRaw) {
55
+ return undefined;
56
+ }
57
+ return {
58
+ bins: normalizeStringList(requiresRaw.bins),
59
+ anyBins: normalizeStringList(requiresRaw.anyBins),
60
+ env: normalizeStringList(requiresRaw.env),
61
+ config: normalizeStringList(requiresRaw.config),
62
+ };
63
+ }
64
+ export function resolveOpenClawManifestInstall(metadataObj, parseInstallSpec) {
65
+ const installRaw = Array.isArray(metadataObj.install) ? metadataObj.install : [];
66
+ return installRaw
67
+ .map((entry) => parseInstallSpec(entry))
68
+ .filter((entry) => Boolean(entry));
69
+ }
70
+ export function resolveOpenClawManifestOs(metadataObj) {
71
+ return normalizeStringList(metadataObj.os);
72
+ }
73
+ export function parseOpenClawManifestInstallBase(input, allowedKinds) {
74
+ if (!input || typeof input !== "object") {
75
+ return undefined;
76
+ }
77
+ const raw = input;
78
+ const kindRaw = typeof raw.kind === "string" ? raw.kind : typeof raw.type === "string" ? raw.type : "";
79
+ const kind = kindRaw.trim().toLowerCase();
80
+ if (!allowedKinds.includes(kind)) {
81
+ return undefined;
82
+ }
83
+ const spec = {
84
+ raw,
85
+ kind,
86
+ };
87
+ if (typeof raw.id === "string") {
88
+ spec.id = raw.id;
89
+ }
90
+ if (typeof raw.label === "string") {
91
+ spec.label = raw.label;
92
+ }
93
+ const bins = normalizeStringList(raw.bins);
94
+ if (bins.length > 0) {
95
+ spec.bins = bins;
96
+ }
97
+ return spec;
98
+ }
@@ -0,0 +1,19 @@
1
+ export function inferParamBFromIdOrName(text) {
2
+ const raw = text.toLowerCase();
3
+ const matches = raw.matchAll(/(?:^|[^a-z0-9])[a-z]?(\d+(?:\.\d+)?)b(?:[^a-z0-9]|$)/g);
4
+ let best = null;
5
+ for (const match of matches) {
6
+ const numRaw = match[1];
7
+ if (!numRaw) {
8
+ continue;
9
+ }
10
+ const value = Number(numRaw);
11
+ if (!Number.isFinite(value) || value <= 0) {
12
+ continue;
13
+ }
14
+ if (best === null || value > best) {
15
+ best = value;
16
+ }
17
+ }
18
+ return best;
19
+ }
@@ -0,0 +1,17 @@
1
+ export function validateIPv4AddressInput(value) {
2
+ if (!value) {
3
+ return "IP address is required for custom bind mode";
4
+ }
5
+ const trimmed = value.trim();
6
+ const parts = trimmed.split(".");
7
+ if (parts.length !== 4) {
8
+ return "Invalid IPv4 address (e.g., 192.168.1.100)";
9
+ }
10
+ if (parts.every((part) => {
11
+ const n = parseInt(part, 10);
12
+ return !Number.isNaN(n) && n >= 0 && n <= 255 && part === String(n);
13
+ })) {
14
+ return undefined;
15
+ }
16
+ return "Invalid IPv4 address (each octet must be 0-255)";
17
+ }
@@ -0,0 +1,53 @@
1
+ export function normalizeNodeKey(value) {
2
+ return value
3
+ .toLowerCase()
4
+ .replace(/[^a-z0-9]+/g, "-")
5
+ .replace(/^-+/, "")
6
+ .replace(/-+$/, "");
7
+ }
8
+ function listKnownNodes(nodes) {
9
+ return nodes
10
+ .map((n) => n.displayName || n.remoteIp || n.nodeId)
11
+ .filter(Boolean)
12
+ .join(", ");
13
+ }
14
+ export function resolveNodeMatches(nodes, query) {
15
+ const q = query.trim();
16
+ if (!q) {
17
+ return [];
18
+ }
19
+ const qNorm = normalizeNodeKey(q);
20
+ return nodes.filter((n) => {
21
+ if (n.nodeId === q) {
22
+ return true;
23
+ }
24
+ if (typeof n.remoteIp === "string" && n.remoteIp === q) {
25
+ return true;
26
+ }
27
+ const name = typeof n.displayName === "string" ? n.displayName : "";
28
+ if (name && normalizeNodeKey(name) === qNorm) {
29
+ return true;
30
+ }
31
+ if (q.length >= 6 && n.nodeId.startsWith(q)) {
32
+ return true;
33
+ }
34
+ return false;
35
+ });
36
+ }
37
+ export function resolveNodeIdFromCandidates(nodes, query) {
38
+ const q = query.trim();
39
+ if (!q) {
40
+ throw new Error("node required");
41
+ }
42
+ const matches = resolveNodeMatches(nodes, q);
43
+ if (matches.length === 1) {
44
+ return matches[0]?.nodeId ?? "";
45
+ }
46
+ if (matches.length === 0) {
47
+ const known = listKnownNodes(nodes);
48
+ throw new Error(`unknown node: ${q}${known ? ` (known: ${known})` : ""}`);
49
+ }
50
+ throw new Error(`ambiguous node: ${q} (matches: ${matches
51
+ .map((n) => n.displayName || n.remoteIp || n.nodeId)
52
+ .join(", ")})`);
53
+ }
@@ -0,0 +1,128 @@
1
+ export function resolveMissingBins(params) {
2
+ const remote = params.hasRemoteBin;
3
+ return params.required.filter((bin) => {
4
+ if (params.hasLocalBin(bin)) {
5
+ return false;
6
+ }
7
+ if (remote?.(bin)) {
8
+ return false;
9
+ }
10
+ return true;
11
+ });
12
+ }
13
+ export function resolveMissingAnyBins(params) {
14
+ if (params.required.length === 0) {
15
+ return [];
16
+ }
17
+ if (params.required.some((bin) => params.hasLocalBin(bin))) {
18
+ return [];
19
+ }
20
+ if (params.hasRemoteAnyBin?.(params.required)) {
21
+ return [];
22
+ }
23
+ return params.required;
24
+ }
25
+ export function resolveMissingOs(params) {
26
+ if (params.required.length === 0) {
27
+ return [];
28
+ }
29
+ if (params.required.includes(params.localPlatform)) {
30
+ return [];
31
+ }
32
+ if (params.remotePlatforms?.some((platform) => params.required.includes(platform))) {
33
+ return [];
34
+ }
35
+ return params.required;
36
+ }
37
+ export function resolveMissingEnv(params) {
38
+ const missing = [];
39
+ for (const envName of params.required) {
40
+ if (params.isSatisfied(envName)) {
41
+ continue;
42
+ }
43
+ missing.push(envName);
44
+ }
45
+ return missing;
46
+ }
47
+ export function buildConfigChecks(params) {
48
+ return params.required.map((pathStr) => {
49
+ const satisfied = params.isSatisfied(pathStr);
50
+ return { path: pathStr, satisfied };
51
+ });
52
+ }
53
+ export function evaluateRequirements(params) {
54
+ const missingBins = resolveMissingBins({
55
+ required: params.required.bins,
56
+ hasLocalBin: params.hasLocalBin,
57
+ hasRemoteBin: params.hasRemoteBin,
58
+ });
59
+ const missingAnyBins = resolveMissingAnyBins({
60
+ required: params.required.anyBins,
61
+ hasLocalBin: params.hasLocalBin,
62
+ hasRemoteAnyBin: params.hasRemoteAnyBin,
63
+ });
64
+ const missingOs = resolveMissingOs({
65
+ required: params.required.os,
66
+ localPlatform: params.localPlatform,
67
+ remotePlatforms: params.remotePlatforms,
68
+ });
69
+ const missingEnv = resolveMissingEnv({
70
+ required: params.required.env,
71
+ isSatisfied: params.isEnvSatisfied,
72
+ });
73
+ const configChecks = buildConfigChecks({
74
+ required: params.required.config,
75
+ isSatisfied: params.isConfigSatisfied,
76
+ });
77
+ const missingConfig = configChecks.filter((check) => !check.satisfied).map((check) => check.path);
78
+ const missing = params.always
79
+ ? { bins: [], anyBins: [], env: [], config: [], os: [] }
80
+ : {
81
+ bins: missingBins,
82
+ anyBins: missingAnyBins,
83
+ env: missingEnv,
84
+ config: missingConfig,
85
+ os: missingOs,
86
+ };
87
+ const eligible = params.always ||
88
+ (missing.bins.length === 0 &&
89
+ missing.anyBins.length === 0 &&
90
+ missing.env.length === 0 &&
91
+ missing.config.length === 0 &&
92
+ missing.os.length === 0);
93
+ return { missing, eligible, configChecks };
94
+ }
95
+ export function evaluateRequirementsFromMetadata(params) {
96
+ const required = {
97
+ bins: params.metadata?.requires?.bins ?? [],
98
+ anyBins: params.metadata?.requires?.anyBins ?? [],
99
+ env: params.metadata?.requires?.env ?? [],
100
+ config: params.metadata?.requires?.config ?? [],
101
+ os: params.metadata?.os ?? [],
102
+ };
103
+ const result = evaluateRequirements({
104
+ always: params.always,
105
+ required,
106
+ hasLocalBin: params.hasLocalBin,
107
+ hasRemoteBin: params.hasRemoteBin,
108
+ hasRemoteAnyBin: params.hasRemoteAnyBin,
109
+ localPlatform: params.localPlatform,
110
+ remotePlatforms: params.remotePlatforms,
111
+ isEnvSatisfied: params.isEnvSatisfied,
112
+ isConfigSatisfied: params.isConfigSatisfied,
113
+ });
114
+ return { required, ...result };
115
+ }
116
+ export function evaluateRequirementsFromMetadataWithRemote(params) {
117
+ return evaluateRequirementsFromMetadata({
118
+ always: params.always,
119
+ metadata: params.metadata,
120
+ hasLocalBin: params.hasLocalBin,
121
+ hasRemoteBin: params.remote?.hasBin,
122
+ hasRemoteAnyBin: params.remote?.hasAnyBin,
123
+ localPlatform: params.localPlatform,
124
+ remotePlatforms: params.remote?.platforms,
125
+ isEnvSatisfied: params.isEnvSatisfied,
126
+ isConfigSatisfied: params.isConfigSatisfied,
127
+ });
128
+ }
@@ -0,0 +1,84 @@
1
+ export function formatDurationCompact(valueMs) {
2
+ if (!valueMs || !Number.isFinite(valueMs) || valueMs <= 0) {
3
+ return "n/a";
4
+ }
5
+ const minutes = Math.max(1, Math.round(valueMs / 60_000));
6
+ if (minutes < 60) {
7
+ return `${minutes}m`;
8
+ }
9
+ const hours = Math.floor(minutes / 60);
10
+ const minutesRemainder = minutes % 60;
11
+ if (hours < 24) {
12
+ return minutesRemainder > 0 ? `${hours}h${minutesRemainder}m` : `${hours}h`;
13
+ }
14
+ const days = Math.floor(hours / 24);
15
+ const hoursRemainder = hours % 24;
16
+ return hoursRemainder > 0 ? `${days}d${hoursRemainder}h` : `${days}d`;
17
+ }
18
+ export function formatTokenShort(value) {
19
+ if (!value || !Number.isFinite(value) || value <= 0) {
20
+ return undefined;
21
+ }
22
+ const n = Math.floor(value);
23
+ if (n < 1_000) {
24
+ return `${n}`;
25
+ }
26
+ if (n < 10_000) {
27
+ return `${(n / 1_000).toFixed(1).replace(/\\.0$/, "")}k`;
28
+ }
29
+ if (n < 1_000_000) {
30
+ return `${Math.round(n / 1_000)}k`;
31
+ }
32
+ return `${(n / 1_000_000).toFixed(1).replace(/\\.0$/, "")}m`;
33
+ }
34
+ export function truncateLine(value, maxLength) {
35
+ if (value.length <= maxLength) {
36
+ return value;
37
+ }
38
+ return `${value.slice(0, maxLength).trimEnd()}...`;
39
+ }
40
+ export function resolveTotalTokens(entry) {
41
+ if (!entry || typeof entry !== "object") {
42
+ return undefined;
43
+ }
44
+ if (typeof entry.totalTokens === "number" && Number.isFinite(entry.totalTokens)) {
45
+ return entry.totalTokens;
46
+ }
47
+ const input = typeof entry.inputTokens === "number" ? entry.inputTokens : 0;
48
+ const output = typeof entry.outputTokens === "number" ? entry.outputTokens : 0;
49
+ const total = input + output;
50
+ return total > 0 ? total : undefined;
51
+ }
52
+ export function resolveIoTokens(entry) {
53
+ if (!entry || typeof entry !== "object") {
54
+ return undefined;
55
+ }
56
+ const input = typeof entry.inputTokens === "number" && Number.isFinite(entry.inputTokens)
57
+ ? entry.inputTokens
58
+ : 0;
59
+ const output = typeof entry.outputTokens === "number" && Number.isFinite(entry.outputTokens)
60
+ ? entry.outputTokens
61
+ : 0;
62
+ const total = input + output;
63
+ if (total <= 0) {
64
+ return undefined;
65
+ }
66
+ return { input, output, total };
67
+ }
68
+ export function formatTokenUsageDisplay(entry) {
69
+ const io = resolveIoTokens(entry);
70
+ const promptCache = resolveTotalTokens(entry);
71
+ const parts = [];
72
+ if (io) {
73
+ const input = formatTokenShort(io.input) ?? "0";
74
+ const output = formatTokenShort(io.output) ?? "0";
75
+ parts.push(`tokens ${formatTokenShort(io.total)} (in ${input} / out ${output})`);
76
+ }
77
+ else if (typeof promptCache === "number" && promptCache > 0) {
78
+ parts.push(`tokens ${formatTokenShort(promptCache)} prompt/cache`);
79
+ }
80
+ if (typeof promptCache === "number" && io && promptCache > io.total) {
81
+ parts.push(`prompt/cache ${formatTokenShort(promptCache)}`);
82
+ }
83
+ return parts.join(", ");
84
+ }
@@ -0,0 +1,28 @@
1
+ export function buildUsageAggregateTail(params) {
2
+ return {
3
+ byChannel: Array.from(params.byChannelMap.entries())
4
+ .map(([channel, totals]) => ({ channel, totals }))
5
+ .toSorted((a, b) => b.totals.totalCost - a.totals.totalCost),
6
+ latency: params.latencyTotals.count > 0
7
+ ? {
8
+ count: params.latencyTotals.count,
9
+ avgMs: params.latencyTotals.sum / params.latencyTotals.count,
10
+ minMs: params.latencyTotals.min === Number.POSITIVE_INFINITY ? 0 : params.latencyTotals.min,
11
+ maxMs: params.latencyTotals.max,
12
+ p95Ms: params.latencyTotals.p95Max,
13
+ }
14
+ : undefined,
15
+ dailyLatency: Array.from(params.dailyLatencyMap.values())
16
+ .map((entry) => ({
17
+ date: entry.date,
18
+ count: entry.count,
19
+ avgMs: entry.count ? entry.sum / entry.count : 0,
20
+ minMs: entry.min === Number.POSITIVE_INFINITY ? 0 : entry.min,
21
+ maxMs: entry.max,
22
+ p95Ms: entry.p95Max,
23
+ }))
24
+ .toSorted((a, b) => a.date.localeCompare(b.date)),
25
+ modelDaily: Array.from(params.modelDailyMap.values()).toSorted((a, b) => a.date.localeCompare(b.date) || b.cost - a.cost),
26
+ daily: Array.from(params.dailyMap.values()).toSorted((a, b) => a.date.localeCompare(b.date)),
27
+ };
28
+ }
@@ -0,0 +1,45 @@
1
+ const OBJECT_REPLACEMENT = "\uFFFC";
2
+ function isValidMention(mention) {
3
+ if (!mention) {
4
+ return false;
5
+ }
6
+ if (!(mention.uuid || mention.number)) {
7
+ return false;
8
+ }
9
+ if (typeof mention.start !== "number" || Number.isNaN(mention.start)) {
10
+ return false;
11
+ }
12
+ if (typeof mention.length !== "number" || Number.isNaN(mention.length)) {
13
+ return false;
14
+ }
15
+ return mention.length > 0;
16
+ }
17
+ function clampBounds(start, length, textLength) {
18
+ const safeStart = Math.max(0, Math.trunc(start));
19
+ const safeLength = Math.max(0, Math.trunc(length));
20
+ const safeEnd = Math.min(textLength, safeStart + safeLength);
21
+ return { start: safeStart, end: safeEnd };
22
+ }
23
+ export function renderSignalMentions(message, mentions) {
24
+ if (!message || !mentions?.length) {
25
+ return message;
26
+ }
27
+ let normalized = message;
28
+ const candidates = mentions.filter(isValidMention).toSorted((a, b) => b.start - a.start);
29
+ for (const mention of candidates) {
30
+ const identifier = mention.uuid ?? mention.number;
31
+ if (!identifier) {
32
+ continue;
33
+ }
34
+ const { start, end } = clampBounds(mention.start, mention.length, normalized.length);
35
+ if (start >= end) {
36
+ continue;
37
+ }
38
+ const slice = normalized.slice(start, end);
39
+ if (!slice.includes(OBJECT_REPLACEMENT)) {
40
+ continue;
41
+ }
42
+ normalized = normalized.slice(0, start) + `@${identifier}` + normalized.slice(end);
43
+ }
44
+ return normalized;
45
+ }
@@ -0,0 +1,19 @@
1
+ import { loadConfig } from "../config/config.js";
2
+ import { resolveSignalAccount } from "./accounts.js";
3
+ export function resolveSignalRpcContext(opts, accountInfo) {
4
+ const hasBaseUrl = Boolean(opts.baseUrl?.trim());
5
+ const hasAccount = Boolean(opts.account?.trim());
6
+ const resolvedAccount = accountInfo ||
7
+ (!hasBaseUrl || !hasAccount
8
+ ? resolveSignalAccount({
9
+ cfg: loadConfig(),
10
+ accountId: opts.accountId,
11
+ })
12
+ : undefined);
13
+ const baseUrl = opts.baseUrl?.trim() || resolvedAccount?.baseUrl;
14
+ if (!baseUrl) {
15
+ throw new Error("Signal base URL is required");
16
+ }
17
+ const account = opts.account?.trim() || resolvedAccount?.config.account?.trim();
18
+ return { baseUrl, account };
19
+ }