@poolzin/pool-bot 2026.2.21 → 2026.2.22

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 (369) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/diagnostics-otel/package.json +1 -1
  326. package/extensions/discord/package.json +1 -1
  327. package/extensions/feishu/package.json +1 -1
  328. package/extensions/google-antigravity-auth/package.json +1 -1
  329. package/extensions/google-gemini-cli-auth/package.json +1 -1
  330. package/extensions/googlechat/package.json +1 -1
  331. package/extensions/imessage/package.json +1 -1
  332. package/extensions/irc/package.json +1 -1
  333. package/extensions/line/package.json +1 -1
  334. package/extensions/llm-task/package.json +1 -1
  335. package/extensions/lobster/package.json +1 -1
  336. package/extensions/matrix/CHANGELOG.md +5 -0
  337. package/extensions/matrix/package.json +1 -1
  338. package/extensions/mattermost/package.json +1 -1
  339. package/extensions/memory-core/package.json +1 -1
  340. package/extensions/memory-lancedb/package.json +1 -1
  341. package/extensions/minimax-portal-auth/package.json +1 -1
  342. package/extensions/msteams/CHANGELOG.md +5 -0
  343. package/extensions/msteams/package.json +1 -1
  344. package/extensions/nextcloud-talk/package.json +1 -1
  345. package/extensions/nostr/CHANGELOG.md +5 -0
  346. package/extensions/nostr/package.json +1 -1
  347. package/extensions/open-prose/package.json +1 -1
  348. package/extensions/openai-codex-auth/package.json +1 -1
  349. package/extensions/signal/package.json +1 -1
  350. package/extensions/slack/package.json +1 -1
  351. package/extensions/telegram/package.json +1 -1
  352. package/extensions/tlon/package.json +1 -1
  353. package/extensions/twitch/CHANGELOG.md +5 -0
  354. package/extensions/twitch/package.json +1 -1
  355. package/extensions/voice-call/CHANGELOG.md +5 -0
  356. package/extensions/voice-call/package.json +1 -1
  357. package/extensions/whatsapp/package.json +1 -1
  358. package/extensions/zalo/CHANGELOG.md +5 -0
  359. package/extensions/zalo/package.json +1 -1
  360. package/extensions/zalouser/CHANGELOG.md +5 -0
  361. package/extensions/zalouser/package.json +1 -1
  362. package/package.json +1 -1
  363. package/skills/apple-reminders/SKILL.md +100 -49
  364. package/skills/coding-agent/SKILL.md +34 -28
  365. package/skills/github/SKILL.md +131 -16
  366. package/skills/imsg/SKILL.md +112 -15
  367. package/skills/openhue/SKILL.md +101 -19
  368. package/skills/tmux/SKILL.md +111 -79
  369. package/skills/weather/SKILL.md +88 -25
@@ -1,19 +1,21 @@
1
1
  import { resolveHumanDelayConfig } from "../../agents/identity.js";
2
2
  import { hasControlCommand } from "../../auto-reply/command-detection.js";
3
+ import { dispatchInboundMessage } from "../../auto-reply/dispatch.js";
3
4
  import { formatInboundEnvelope, formatInboundFromLabel, resolveEnvelopeFormatOptions, } from "../../auto-reply/envelope.js";
4
5
  import { createInboundDebouncer, resolveInboundDebounceMs, } from "../../auto-reply/inbound-debounce.js";
5
- import { dispatchInboundMessage } from "../../auto-reply/dispatch.js";
6
6
  import { buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled, } from "../../auto-reply/reply/history.js";
7
- import { buildMentionRegexes, matchesMentionPatterns } from "../../auto-reply/reply/mentions.js";
8
7
  import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
8
+ import { buildMentionRegexes, matchesMentionPatterns } from "../../auto-reply/reply/mentions.js";
9
9
  import { createReplyDispatcherWithTyping } from "../../auto-reply/reply/reply-dispatcher.js";
10
+ import { resolveControlCommandGate } from "../../channels/command-gating.js";
10
11
  import { logInboundDrop, logTypingFailure } from "../../channels/logging.js";
11
12
  import { resolveMentionGatingWithBypass } from "../../channels/mention-gating.js";
12
- import { createReplyPrefixContext } from "../../channels/reply-prefix.js";
13
+ import { normalizeSignalMessagingTarget } from "../../channels/plugins/normalize/signal.js";
14
+ import { createReplyPrefixOptions } from "../../channels/reply-prefix.js";
13
15
  import { recordInboundSession } from "../../channels/session.js";
14
16
  import { createTypingCallbacks } from "../../channels/typing.js";
15
- import { readSessionUpdatedAt, resolveStorePath } from "../../config/sessions.js";
16
17
  import { resolveChannelGroupRequireMention } from "../../config/group-policy.js";
18
+ import { readSessionUpdatedAt, resolveStorePath } from "../../config/sessions.js";
17
19
  import { danger, logVerbose, shouldLogVerbose } from "../../globals.js";
18
20
  import { enqueueSystemEvent } from "../../infra/system-events.js";
19
21
  import { mediaKindFromMime } from "../../media/constants.js";
@@ -21,9 +23,9 @@ import { buildPairingReply } from "../../pairing/pairing-messages.js";
21
23
  import { readChannelAllowFromStore, upsertChannelPairingRequest, } from "../../pairing/pairing-store.js";
22
24
  import { resolveAgentRoute } from "../../routing/resolve-route.js";
23
25
  import { normalizeE164 } from "../../utils.js";
24
- import { resolveControlCommandGate } from "../../channels/command-gating.js";
25
26
  import { formatSignalPairingIdLine, formatSignalSenderDisplay, formatSignalSenderId, isSignalSenderAllowed, resolveSignalPeerId, resolveSignalRecipient, resolveSignalSender, } from "../identity.js";
26
27
  import { sendMessageSignal, sendReadReceiptSignal, sendTypingSignal } from "../send.js";
28
+ import { renderSignalMentions } from "./mentions.js";
27
29
  export function createSignalEventHandler(deps) {
28
30
  const inboundDebounceMs = resolveInboundDebounceMs({ cfg: deps.cfg, channel: "signal" });
29
31
  async function handleSignalInboundMessage(entry) {
@@ -40,7 +42,7 @@ export function createSignalEventHandler(deps) {
40
42
  channel: "signal",
41
43
  accountId: deps.accountId,
42
44
  peer: {
43
- kind: entry.isGroup ? "group" : "dm",
45
+ kind: entry.isGroup ? "group" : "direct",
44
46
  id: entry.isGroup ? (entry.groupId ?? "unknown") : entry.senderPeerId,
45
47
  },
46
48
  });
@@ -81,7 +83,10 @@ export function createSignalEventHandler(deps) {
81
83
  }),
82
84
  });
83
85
  }
84
- const signalTo = entry.isGroup ? `group:${entry.groupId}` : `signal:${entry.senderRecipient}`;
86
+ const signalToRaw = entry.isGroup
87
+ ? `group:${entry.groupId}`
88
+ : `signal:${entry.senderRecipient}`;
89
+ const signalTo = normalizeSignalMessagingTarget(signalToRaw) ?? signalToRaw;
85
90
  const inboundHistory = entry.isGroup && historyKey && deps.historyLimit > 0
86
91
  ? (deps.groupHistories.get(historyKey) ?? []).map((historyEntry) => ({
87
92
  sender: historyEntry.sender,
@@ -138,11 +143,17 @@ export function createSignalEventHandler(deps) {
138
143
  const preview = body.slice(0, 200).replace(/\\n/g, "\\\\n");
139
144
  logVerbose(`signal inbound: from=${ctxPayload.From} len=${body.length} preview="${preview}"`);
140
145
  }
141
- const prefixContext = createReplyPrefixContext({ cfg: deps.cfg, agentId: route.agentId });
146
+ const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
147
+ cfg: deps.cfg,
148
+ agentId: route.agentId,
149
+ channel: "signal",
150
+ accountId: route.accountId,
151
+ });
142
152
  const typingCallbacks = createTypingCallbacks({
143
153
  start: async () => {
144
- if (!ctxPayload.To)
154
+ if (!ctxPayload.To) {
145
155
  return;
156
+ }
146
157
  await sendTypingSignal(ctxPayload.To, {
147
158
  baseUrl: deps.baseUrl,
148
159
  account: deps.account,
@@ -159,8 +170,7 @@ export function createSignalEventHandler(deps) {
159
170
  },
160
171
  });
161
172
  const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({
162
- responsePrefix: prefixContext.responsePrefix,
163
- responsePrefixContextProvider: prefixContext.responsePrefixContextProvider,
173
+ ...prefixOptions,
164
174
  humanDelay: resolveHumanDelayConfig(deps.cfg, route.agentId),
165
175
  deliver: async (payload) => {
166
176
  await deps.deliverReplies({
@@ -186,9 +196,7 @@ export function createSignalEventHandler(deps) {
186
196
  replyOptions: {
187
197
  ...replyOptions,
188
198
  disableBlockStreaming: typeof deps.blockStreaming === "boolean" ? !deps.blockStreaming : undefined,
189
- onModelSelected: (ctx) => {
190
- prefixContext.onModelSelected(ctx);
191
- },
199
+ onModelSelected,
192
200
  },
193
201
  });
194
202
  markDispatchIdle();
@@ -214,21 +222,25 @@ export function createSignalEventHandler(deps) {
214
222
  debounceMs: inboundDebounceMs,
215
223
  buildKey: (entry) => {
216
224
  const conversationId = entry.isGroup ? (entry.groupId ?? "unknown") : entry.senderPeerId;
217
- if (!conversationId || !entry.senderPeerId)
225
+ if (!conversationId || !entry.senderPeerId) {
218
226
  return null;
227
+ }
219
228
  return `signal:${deps.accountId}:${conversationId}:${entry.senderPeerId}`;
220
229
  },
221
230
  shouldDebounce: (entry) => {
222
- if (!entry.bodyText.trim())
231
+ if (!entry.bodyText.trim()) {
223
232
  return false;
224
- if (entry.mediaPath || entry.mediaType)
233
+ }
234
+ if (entry.mediaPath || entry.mediaType) {
225
235
  return false;
236
+ }
226
237
  return !hasControlCommand(entry.bodyText, deps.cfg);
227
238
  },
228
239
  onFlush: async (entries) => {
229
240
  const last = entries.at(-1);
230
- if (!last)
241
+ if (!last) {
231
242
  return;
243
+ }
232
244
  if (entries.length === 1) {
233
245
  await handleSignalInboundMessage(last);
234
246
  return;
@@ -237,8 +249,9 @@ export function createSignalEventHandler(deps) {
237
249
  .map((entry) => entry.bodyText)
238
250
  .filter(Boolean)
239
251
  .join("\\n");
240
- if (!combinedText.trim())
252
+ if (!combinedText.trim()) {
241
253
  return;
254
+ }
242
255
  await handleSignalInboundMessage({
243
256
  ...last,
244
257
  bodyText: combinedText,
@@ -251,8 +264,9 @@ export function createSignalEventHandler(deps) {
251
264
  },
252
265
  });
253
266
  return async (event) => {
254
- if (event.event !== "receive" || !event.data)
267
+ if (event.event !== "receive" || !event.data) {
255
268
  return;
269
+ }
256
270
  let payload = null;
257
271
  try {
258
272
  payload = JSON.parse(event.data);
@@ -265,16 +279,20 @@ export function createSignalEventHandler(deps) {
265
279
  deps.runtime.error?.(`receive exception: ${payload.exception.message}`);
266
280
  }
267
281
  const envelope = payload?.envelope;
268
- if (!envelope)
282
+ if (!envelope) {
269
283
  return;
270
- if (envelope.syncMessage)
284
+ }
285
+ if (envelope.syncMessage) {
271
286
  return;
287
+ }
272
288
  const sender = resolveSignalSender(envelope);
273
- if (!sender)
289
+ if (!sender) {
274
290
  return;
291
+ }
275
292
  if (deps.account && sender.kind === "phone") {
276
- if (sender.e164 === normalizeE164(deps.account))
293
+ if (sender.e164 === normalizeE164(deps.account)) {
277
294
  return;
295
+ }
278
296
  }
279
297
  const dataMessage = envelope.dataMessage ?? envelope.editMessage?.dataMessage;
280
298
  const reaction = deps.isSignalReactionMessage(envelope.reactionMessage)
@@ -282,12 +300,17 @@ export function createSignalEventHandler(deps) {
282
300
  : deps.isSignalReactionMessage(dataMessage?.reaction)
283
301
  ? dataMessage?.reaction
284
302
  : null;
285
- const messageText = (dataMessage?.message ?? "").trim();
303
+ // Replace (object replacement character) with @uuid or @phone from mentions
304
+ // Signal encodes mentions as the object replacement character; hydrate them from metadata first.
305
+ const rawMessage = dataMessage?.message ?? "";
306
+ const normalizedMessage = renderSignalMentions(rawMessage, dataMessage?.mentions);
307
+ const messageText = normalizedMessage.trim();
286
308
  const quoteText = dataMessage?.quote?.text?.trim() ?? "";
287
309
  const hasBodyContent = Boolean(messageText || quoteText) || Boolean(!reaction && dataMessage?.attachments?.length);
288
310
  if (reaction && !hasBodyContent) {
289
- if (reaction.isRemove)
290
- return; // Ignore reaction removals
311
+ if (reaction.isRemove) {
312
+ return;
313
+ } // Ignore reaction removals
291
314
  const emojiLabel = reaction.emoji?.trim() || "emoji";
292
315
  const senderDisplay = formatSignalSenderDisplay(sender);
293
316
  const senderName = envelope.sourceName ?? senderDisplay;
@@ -300,8 +323,9 @@ export function createSignalEventHandler(deps) {
300
323
  sender,
301
324
  allowlist: deps.reactionAllowlist,
302
325
  });
303
- if (!shouldNotify)
326
+ if (!shouldNotify) {
304
327
  return;
328
+ }
305
329
  const groupId = reaction.groupInfo?.groupId ?? undefined;
306
330
  const groupName = reaction.groupInfo?.groupName ?? undefined;
307
331
  const isGroup = Boolean(groupId);
@@ -311,7 +335,7 @@ export function createSignalEventHandler(deps) {
311
335
  channel: "signal",
312
336
  accountId: deps.accountId,
313
337
  peer: {
314
- kind: isGroup ? "group" : "dm",
338
+ kind: isGroup ? "group" : "direct",
315
339
  id: isGroup ? (groupId ?? "unknown") : senderPeerId,
316
340
  },
317
341
  });
@@ -341,14 +365,16 @@ export function createSignalEventHandler(deps) {
341
365
  enqueueSystemEvent(text, { sessionKey: route.sessionKey, contextKey });
342
366
  return;
343
367
  }
344
- if (!dataMessage)
368
+ if (!dataMessage) {
345
369
  return;
370
+ }
346
371
  const senderDisplay = formatSignalSenderDisplay(sender);
347
372
  const senderRecipient = resolveSignalRecipient(sender);
348
373
  const senderPeerId = resolveSignalPeerId(sender);
349
374
  const senderAllowId = formatSignalSenderId(sender);
350
- if (!senderRecipient)
375
+ if (!senderRecipient) {
351
376
  return;
377
+ }
352
378
  const senderIdLine = formatSignalPairingIdLine(sender);
353
379
  const groupId = dataMessage.groupInfo?.groupId ?? undefined;
354
380
  const groupName = dataMessage.groupInfo?.groupName ?? undefined;
@@ -358,8 +384,9 @@ export function createSignalEventHandler(deps) {
358
384
  const effectiveGroupAllow = [...deps.groupAllowFrom, ...storeAllowFrom];
359
385
  const dmAllowed = deps.dmPolicy === "open" ? true : isSignalSenderAllowed(sender, effectiveDmAllow);
360
386
  if (!isGroup) {
361
- if (deps.dmPolicy === "disabled")
387
+ if (deps.dmPolicy === "disabled") {
362
388
  return;
389
+ }
363
390
  if (!dmAllowed) {
364
391
  if (deps.dmPolicy === "pairing") {
365
392
  const senderId = senderAllowId;
@@ -435,7 +462,7 @@ export function createSignalEventHandler(deps) {
435
462
  channel: "signal",
436
463
  accountId: deps.accountId,
437
464
  peer: {
438
- kind: isGroup ? "group" : "dm",
465
+ kind: isGroup ? "group" : "direct",
439
466
  id: isGroup ? (groupId ?? "unknown") : senderPeerId,
440
467
  },
441
468
  });
@@ -473,6 +500,8 @@ export function createSignalEventHandler(deps) {
473
500
  if (!dataMessage.attachments?.length) {
474
501
  return "";
475
502
  }
503
+ // When we're skipping a message we intentionally avoid downloading attachments.
504
+ // Still record a useful placeholder for pending-history context.
476
505
  if (deps.ignoreAttachments) {
477
506
  return "<media:attachment>";
478
507
  }
@@ -519,13 +548,16 @@ export function createSignalEventHandler(deps) {
519
548
  }
520
549
  }
521
550
  const kind = mediaKindFromMime(mediaType ?? undefined);
522
- if (kind)
551
+ if (kind) {
523
552
  placeholder = `<media:${kind}>`;
524
- else if (dataMessage.attachments?.length)
553
+ }
554
+ else if (dataMessage.attachments?.length) {
525
555
  placeholder = "<media:attachment>";
556
+ }
526
557
  const bodyText = messageText || placeholder || dataMessage.quote?.text?.trim() || "";
527
- if (!bodyText)
558
+ if (!bodyText) {
528
559
  return;
560
+ }
529
561
  const receiptTimestamp = typeof envelope.timestamp === "number"
530
562
  ? envelope.timestamp
531
563
  : typeof dataMessage.timestamp === "number"
@@ -1,15 +1,16 @@
1
1
  import { loadConfig } from "../config/config.js";
2
2
  import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
3
3
  import { mediaKindFromMime } from "../media/constants.js";
4
- import { saveMediaBuffer } from "../media/store.js";
5
- import { loadWebMedia } from "../web/media.js";
4
+ import { resolveOutboundAttachmentFromUrl } from "../media/outbound-attachment.js";
6
5
  import { resolveSignalAccount } from "./accounts.js";
7
6
  import { signalRpcRequest } from "./client.js";
8
7
  import { markdownToSignalText } from "./format.js";
8
+ import { resolveSignalRpcContext } from "./rpc-context.js";
9
9
  function parseTarget(raw) {
10
10
  let value = raw.trim();
11
- if (!value)
11
+ if (!value) {
12
12
  throw new Error("Signal recipient is required");
13
+ }
13
14
  const lower = value.toLowerCase();
14
15
  if (lower.startsWith("signal:")) {
15
16
  value = value.slice("signal:".length).trim();
@@ -31,44 +32,25 @@ function parseTarget(raw) {
31
32
  }
32
33
  function buildTargetParams(target, allow) {
33
34
  if (target.type === "recipient") {
34
- if (!allow.recipient)
35
+ if (!allow.recipient) {
35
36
  return null;
37
+ }
36
38
  return { recipient: [target.recipient] };
37
39
  }
38
40
  if (target.type === "group") {
39
- if (!allow.group)
41
+ if (!allow.group) {
40
42
  return null;
43
+ }
41
44
  return { groupId: target.groupId };
42
45
  }
43
46
  if (target.type === "username") {
44
- if (!allow.username)
47
+ if (!allow.username) {
45
48
  return null;
49
+ }
46
50
  return { username: [target.username] };
47
51
  }
48
52
  return null;
49
53
  }
50
- function resolveSignalRpcContext(opts, accountInfo) {
51
- const hasBaseUrl = Boolean(opts.baseUrl?.trim());
52
- const hasAccount = Boolean(opts.account?.trim());
53
- const resolvedAccount = accountInfo ||
54
- (!hasBaseUrl || !hasAccount
55
- ? resolveSignalAccount({
56
- cfg: loadConfig(),
57
- accountId: opts.accountId,
58
- })
59
- : undefined);
60
- const baseUrl = opts.baseUrl?.trim() || resolvedAccount?.baseUrl;
61
- if (!baseUrl) {
62
- throw new Error("Signal base URL is required");
63
- }
64
- const account = opts.account?.trim() || resolvedAccount?.config.account?.trim();
65
- return { baseUrl, account };
66
- }
67
- async function resolveAttachment(mediaUrl, maxBytes) {
68
- const media = await loadWebMedia(mediaUrl, maxBytes);
69
- const saved = await saveMediaBuffer(media.buffer, media.contentType ?? undefined, "outbound", maxBytes);
70
- return { path: saved.path, contentType: saved.contentType };
71
- }
72
54
  export async function sendMessageSignal(to, text, opts = {}) {
73
55
  const cfg = loadConfig();
74
56
  const accountInfo = resolveSignalAccount({
@@ -82,8 +64,9 @@ export async function sendMessageSignal(to, text, opts = {}) {
82
64
  let textStyles = [];
83
65
  const textMode = opts.textMode ?? "markdown";
84
66
  const maxBytes = (() => {
85
- if (typeof opts.maxBytes === "number")
67
+ if (typeof opts.maxBytes === "number") {
86
68
  return opts.maxBytes;
69
+ }
87
70
  if (typeof accountInfo.config.mediaMaxMb === "number") {
88
71
  return accountInfo.config.mediaMaxMb * 1024 * 1024;
89
72
  }
@@ -94,7 +77,9 @@ export async function sendMessageSignal(to, text, opts = {}) {
94
77
  })();
95
78
  let attachments;
96
79
  if (opts.mediaUrl?.trim()) {
97
- const resolved = await resolveAttachment(opts.mediaUrl.trim(), maxBytes);
80
+ const resolved = await resolveOutboundAttachmentFromUrl(opts.mediaUrl.trim(), maxBytes, {
81
+ localRoots: opts.mediaLocalRoots,
82
+ });
98
83
  attachments = [resolved.path];
99
84
  const kind = mediaKindFromMime(resolved.contentType ?? undefined);
100
85
  if (!message && kind) {
@@ -125,8 +110,9 @@ export async function sendMessageSignal(to, text, opts = {}) {
125
110
  if (textStyles.length > 0) {
126
111
  params["text-style"] = textStyles.map((style) => `${style.start}:${style.length}:${style.style}`);
127
112
  }
128
- if (account)
113
+ if (account) {
129
114
  params.account = account;
115
+ }
130
116
  if (attachments && attachments.length > 0) {
131
117
  params.attachments = attachments;
132
118
  }
@@ -155,13 +141,16 @@ export async function sendTypingSignal(to, opts = {}) {
155
141
  recipient: true,
156
142
  group: true,
157
143
  });
158
- if (!targetParams)
144
+ if (!targetParams) {
159
145
  return false;
146
+ }
160
147
  const params = { ...targetParams };
161
- if (account)
148
+ if (account) {
162
149
  params.account = account;
163
- if (opts.stop)
150
+ }
151
+ if (opts.stop) {
164
152
  params.stop = true;
153
+ }
165
154
  await signalRpcRequest("sendTyping", params, {
166
155
  baseUrl,
167
156
  timeoutMs: opts.timeoutMs,
@@ -169,21 +158,24 @@ export async function sendTypingSignal(to, opts = {}) {
169
158
  return true;
170
159
  }
171
160
  export async function sendReadReceiptSignal(to, targetTimestamp, opts = {}) {
172
- if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0)
161
+ if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) {
173
162
  return false;
163
+ }
174
164
  const { baseUrl, account } = resolveSignalRpcContext(opts);
175
165
  const targetParams = buildTargetParams(parseTarget(to), {
176
166
  recipient: true,
177
167
  });
178
- if (!targetParams)
168
+ if (!targetParams) {
179
169
  return false;
170
+ }
180
171
  const params = {
181
172
  ...targetParams,
182
173
  targetTimestamp,
183
174
  type: opts.type ?? "read",
184
175
  };
185
- if (account)
176
+ if (account) {
186
177
  params.account = account;
178
+ }
187
179
  await signalRpcRequest("sendReceipt", params, {
188
180
  baseUrl,
189
181
  timeoutMs: opts.timeoutMs,
@@ -1,21 +1,18 @@
1
+ import { normalizeHyphenSlug, normalizeStringEntries, normalizeStringEntriesLower, } from "../../shared/string-normalization.js";
1
2
  export function normalizeSlackSlug(raw) {
2
- const trimmed = raw?.trim().toLowerCase() ?? "";
3
- if (!trimmed)
4
- return "";
5
- const dashed = trimmed.replace(/\s+/g, "-");
6
- const cleaned = dashed.replace(/[^a-z0-9#@._+-]+/g, "-");
7
- return cleaned.replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, "");
3
+ return normalizeHyphenSlug(raw);
8
4
  }
9
5
  export function normalizeAllowList(list) {
10
- return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean);
6
+ return normalizeStringEntries(list);
11
7
  }
12
8
  export function normalizeAllowListLower(list) {
13
- return normalizeAllowList(list).map((entry) => entry.toLowerCase());
9
+ return normalizeStringEntriesLower(list);
14
10
  }
15
11
  export function resolveSlackAllowListMatch(params) {
16
12
  const allowList = params.allowList;
17
- if (allowList.length === 0)
13
+ if (allowList.length === 0) {
18
14
  return { allowed: false };
15
+ }
19
16
  if (allowList.includes("*")) {
20
17
  return { allowed: true, matchKey: "*", matchSource: "wildcard" };
21
18
  }
@@ -31,8 +28,9 @@ export function resolveSlackAllowListMatch(params) {
31
28
  { value: slug, source: "slug" },
32
29
  ];
33
30
  for (const candidate of candidates) {
34
- if (!candidate.value)
31
+ if (!candidate.value) {
35
32
  continue;
33
+ }
36
34
  if (allowList.includes(candidate.value)) {
37
35
  return {
38
36
  allowed: true,
@@ -48,8 +46,9 @@ export function allowListMatches(params) {
48
46
  }
49
47
  export function resolveSlackUserAllowed(params) {
50
48
  const allowList = normalizeAllowListLower(params.allowList);
51
- if (allowList.length === 0)
49
+ if (allowList.length === 0) {
52
50
  return true;
51
+ }
53
52
  return allowListMatches({
54
53
  allowList,
55
54
  id: params.userId,
@@ -1,9 +1,19 @@
1
+ /**
2
+ * Strip Slack mentions (<@U123>, <@U123|name>) so command detection works on
3
+ * normalized text. Use in both prepare and debounce gate for consistency.
4
+ */
5
+ export function stripSlackMentionsForCommandDetection(text) {
6
+ return (text ?? "")
7
+ .replace(/<@[^>]+>/g, " ")
8
+ .replace(/\s+/g, " ")
9
+ .trim();
10
+ }
1
11
  export function normalizeSlackSlashCommandName(raw) {
2
12
  return raw.replace(/^\/+/, "");
3
13
  }
4
14
  export function resolveSlackSlashCommandConfig(raw) {
5
- const normalizedName = normalizeSlackSlashCommandName(raw?.name?.trim() || "clawd");
6
- const name = normalizedName || "clawd";
15
+ const normalizedName = normalizeSlackSlashCommandName(raw?.name?.trim() || "poolbot");
16
+ const name = normalizedName || "poolbot";
7
17
  return {
8
18
  enabled: raw?.enabled === true,
9
19
  name,
@@ -12,6 +22,7 @@ export function resolveSlackSlashCommandConfig(raw) {
12
22
  };
13
23
  }
14
24
  export function buildSlackSlashCommandMatcher(name) {
15
- const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
25
+ const normalized = normalizeSlackSlashCommandName(name);
26
+ const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
16
27
  return new RegExp(`^/?${escaped}$`);
17
28
  }
@@ -1,7 +1,7 @@
1
1
  import { enqueueSystemEvent } from "../../../infra/system-events.js";
2
2
  import { parseSlackModalPrivateMetadata } from "../../modal-metadata.js";
3
- // Prefix for OpenClaw-generated action IDs to scope our handler
4
- const POOLBOT_ACTION_PREFIX = "openclaw:";
3
+ // Prefix for Pool Bot-generated action IDs to scope our handler
4
+ const POOLBOT_ACTION_PREFIX = "poolbot:";
5
5
  function readOptionValues(options) {
6
6
  if (!Array.isArray(options)) {
7
7
  return undefined;
@@ -255,7 +255,7 @@ export function registerSlackInteractionEvents(params) {
255
255
  if (typeof ctx.app.action !== "function") {
256
256
  return;
257
257
  }
258
- // Handle Block Kit button clicks from OpenClaw-generated messages
258
+ // Handle Block Kit button clicks from Pool Bot-generated messages
259
259
  // Only matches action_ids that start with our prefix to avoid interfering
260
260
  // with other Slack integrations or future features
261
261
  ctx.app.action(new RegExp(`^${POOLBOT_ACTION_PREFIX}`), async (args) => {
@@ -378,7 +378,7 @@ export function registerSlackInteractionEvents(params) {
378
378
  if (typeof ctx.app.view !== "function") {
379
379
  return;
380
380
  }
381
- // Handle OpenClaw modal submissions with callback_ids scoped by our prefix.
381
+ // Handle Pool Bot modal submissions with callback_ids scoped by our prefix.
382
382
  ctx.app.view(new RegExp(`^${POOLBOT_ACTION_PREFIX}`), async ({ ack, body }) => {
383
383
  await ack();
384
384
  const typedBody = body;