@poolzin/pool-bot 2026.2.25 → 2026.2.26

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 (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,63 +1,71 @@
1
+ import { resolveDiscordPreviewStreamMode, resolveSlackNativeStreaming, resolveSlackStreamingMode, resolveTelegramPreviewStreamMode, } from "./discord-preview-streaming.js";
1
2
  import { ensureRecord, getRecord, isRecord, mergeMissing, } from "./legacy.shared.js";
3
+ function migrateBindings(raw, changes, changeNote, mutator) {
4
+ const bindings = Array.isArray(raw.bindings) ? raw.bindings : null;
5
+ if (!bindings) {
6
+ return;
7
+ }
8
+ let touched = false;
9
+ for (const entry of bindings) {
10
+ if (!isRecord(entry)) {
11
+ continue;
12
+ }
13
+ const match = getRecord(entry.match);
14
+ if (!match) {
15
+ continue;
16
+ }
17
+ if (!mutator(match)) {
18
+ continue;
19
+ }
20
+ entry.match = match;
21
+ touched = true;
22
+ }
23
+ if (touched) {
24
+ raw.bindings = bindings;
25
+ changes.push(changeNote);
26
+ }
27
+ }
28
+ function ensureDefaultGroupEntry(section) {
29
+ const groups = isRecord(section.groups) ? section.groups : {};
30
+ const defaultKey = "*";
31
+ const entry = isRecord(groups[defaultKey]) ? groups[defaultKey] : {};
32
+ return { groups, entry };
33
+ }
2
34
  export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
3
35
  {
4
36
  id: "bindings.match.provider->bindings.match.channel",
5
37
  describe: "Move bindings[].match.provider to bindings[].match.channel",
6
38
  apply: (raw, changes) => {
7
- const bindings = Array.isArray(raw.bindings) ? raw.bindings : null;
8
- if (!bindings)
9
- return;
10
- let touched = false;
11
- for (const entry of bindings) {
12
- if (!isRecord(entry))
13
- continue;
14
- const match = getRecord(entry.match);
15
- if (!match)
16
- continue;
17
- if (typeof match.channel === "string" && match.channel.trim())
18
- continue;
39
+ migrateBindings(raw, changes, "Moved bindings[].match.provider bindings[].match.channel.", (match) => {
40
+ if (typeof match.channel === "string" && match.channel.trim()) {
41
+ return false;
42
+ }
19
43
  const provider = typeof match.provider === "string" ? match.provider.trim() : "";
20
- if (!provider)
21
- continue;
44
+ if (!provider) {
45
+ return false;
46
+ }
22
47
  match.channel = provider;
23
48
  delete match.provider;
24
- entry.match = match;
25
- touched = true;
26
- }
27
- if (touched) {
28
- raw.bindings = bindings;
29
- changes.push("Moved bindings[].match.provider → bindings[].match.channel.");
30
- }
49
+ return true;
50
+ });
31
51
  },
32
52
  },
33
53
  {
34
54
  id: "bindings.match.accountID->bindings.match.accountId",
35
55
  describe: "Move bindings[].match.accountID to bindings[].match.accountId",
36
56
  apply: (raw, changes) => {
37
- const bindings = Array.isArray(raw.bindings) ? raw.bindings : null;
38
- if (!bindings)
39
- return;
40
- let touched = false;
41
- for (const entry of bindings) {
42
- if (!isRecord(entry))
43
- continue;
44
- const match = getRecord(entry.match);
45
- if (!match)
46
- continue;
47
- if (match.accountId !== undefined)
48
- continue;
57
+ migrateBindings(raw, changes, "Moved bindings[].match.accountID bindings[].match.accountId.", (match) => {
58
+ if (match.accountId !== undefined) {
59
+ return false;
60
+ }
49
61
  const accountID = typeof match.accountID === "string" ? match.accountID.trim() : match.accountID;
50
- if (!accountID)
51
- continue;
62
+ if (!accountID) {
63
+ return false;
64
+ }
52
65
  match.accountId = accountID;
53
66
  delete match.accountID;
54
- entry.match = match;
55
- touched = true;
56
- }
57
- if (touched) {
58
- raw.bindings = bindings;
59
- changes.push("Moved bindings[].match.accountID → bindings[].match.accountId.");
60
- }
67
+ return true;
68
+ });
61
69
  },
62
70
  },
63
71
  {
@@ -65,26 +73,33 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
65
73
  describe: "Move session.sendPolicy.rules[].match.provider to match.channel",
66
74
  apply: (raw, changes) => {
67
75
  const session = getRecord(raw.session);
68
- if (!session)
76
+ if (!session) {
69
77
  return;
78
+ }
70
79
  const sendPolicy = getRecord(session.sendPolicy);
71
- if (!sendPolicy)
80
+ if (!sendPolicy) {
72
81
  return;
82
+ }
73
83
  const rules = Array.isArray(sendPolicy.rules) ? sendPolicy.rules : null;
74
- if (!rules)
84
+ if (!rules) {
75
85
  return;
86
+ }
76
87
  let touched = false;
77
88
  for (const rule of rules) {
78
- if (!isRecord(rule))
89
+ if (!isRecord(rule)) {
79
90
  continue;
91
+ }
80
92
  const match = getRecord(rule.match);
81
- if (!match)
93
+ if (!match) {
82
94
  continue;
83
- if (typeof match.channel === "string" && match.channel.trim())
95
+ }
96
+ if (typeof match.channel === "string" && match.channel.trim()) {
84
97
  continue;
98
+ }
85
99
  const provider = typeof match.provider === "string" ? match.provider.trim() : "";
86
- if (!provider)
100
+ if (!provider) {
87
101
  continue;
102
+ }
88
103
  match.channel = provider;
89
104
  delete match.provider;
90
105
  rule.match = match;
@@ -103,13 +118,16 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
103
118
  describe: "Move messages.queue.byProvider to messages.queue.byChannel",
104
119
  apply: (raw, changes) => {
105
120
  const messages = getRecord(raw.messages);
106
- if (!messages)
121
+ if (!messages) {
107
122
  return;
123
+ }
108
124
  const queue = getRecord(messages.queue);
109
- if (!queue)
125
+ if (!queue) {
110
126
  return;
111
- if (queue.byProvider === undefined)
127
+ }
128
+ if (queue.byProvider === undefined) {
112
129
  return;
130
+ }
113
131
  if (queue.byChannel === undefined) {
114
132
  queue.byChannel = queue.byProvider;
115
133
  changes.push("Moved messages.queue.byProvider → messages.queue.byChannel.");
@@ -136,13 +154,15 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
136
154
  "msteams",
137
155
  ];
138
156
  const legacyEntries = legacyKeys.filter((key) => isRecord(raw[key]));
139
- if (legacyEntries.length === 0)
157
+ if (legacyEntries.length === 0) {
140
158
  return;
159
+ }
141
160
  const channels = ensureRecord(raw, "channels");
142
161
  for (const key of legacyEntries) {
143
162
  const legacy = getRecord(raw[key]);
144
- if (!legacy)
163
+ if (!legacy) {
145
164
  continue;
165
+ }
146
166
  const channelEntry = ensureRecord(channels, key);
147
167
  const hadEntries = Object.keys(channelEntry).length > 0;
148
168
  mergeMissing(channelEntry, legacy);
@@ -153,16 +173,109 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
153
173
  raw.channels = channels;
154
174
  },
155
175
  },
176
+ {
177
+ id: "channels.streaming-keys->channels.streaming",
178
+ describe: "Normalize legacy streaming keys to channels.<provider>.streaming (Telegram/Discord/Slack)",
179
+ apply: (raw, changes) => {
180
+ const channels = getRecord(raw.channels);
181
+ if (!channels) {
182
+ return;
183
+ }
184
+ const migrateProviderEntry = (params) => {
185
+ const hasLegacyStreamMode = params.entry.streamMode !== undefined;
186
+ const legacyStreaming = params.entry.streaming;
187
+ const legacyNativeStreaming = params.entry.nativeStreaming;
188
+ if (params.provider === "telegram") {
189
+ if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") {
190
+ return;
191
+ }
192
+ const resolved = resolveTelegramPreviewStreamMode(params.entry);
193
+ params.entry.streaming = resolved;
194
+ if (hasLegacyStreamMode) {
195
+ delete params.entry.streamMode;
196
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
197
+ }
198
+ if (typeof legacyStreaming === "boolean") {
199
+ changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
200
+ }
201
+ return;
202
+ }
203
+ if (params.provider === "discord") {
204
+ if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") {
205
+ return;
206
+ }
207
+ const resolved = resolveDiscordPreviewStreamMode(params.entry);
208
+ params.entry.streaming = resolved;
209
+ if (hasLegacyStreamMode) {
210
+ delete params.entry.streamMode;
211
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
212
+ }
213
+ if (typeof legacyStreaming === "boolean") {
214
+ changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
215
+ }
216
+ return;
217
+ }
218
+ if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") {
219
+ return;
220
+ }
221
+ const resolvedStreaming = resolveSlackStreamingMode(params.entry);
222
+ const resolvedNativeStreaming = resolveSlackNativeStreaming(params.entry);
223
+ params.entry.streaming = resolvedStreaming;
224
+ params.entry.nativeStreaming = resolvedNativeStreaming;
225
+ if (hasLegacyStreamMode) {
226
+ delete params.entry.streamMode;
227
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolvedStreaming}).`);
228
+ }
229
+ if (typeof legacyStreaming === "boolean") {
230
+ changes.push(`Moved ${params.pathPrefix}.streaming (boolean) → ${params.pathPrefix}.nativeStreaming (${resolvedNativeStreaming}).`);
231
+ }
232
+ else if (typeof legacyNativeStreaming !== "boolean" && hasLegacyStreamMode) {
233
+ changes.push(`Set ${params.pathPrefix}.nativeStreaming → ${resolvedNativeStreaming}.`);
234
+ }
235
+ };
236
+ const migrateProvider = (provider) => {
237
+ const providerEntry = getRecord(channels[provider]);
238
+ if (!providerEntry) {
239
+ return;
240
+ }
241
+ migrateProviderEntry({
242
+ provider,
243
+ entry: providerEntry,
244
+ pathPrefix: `channels.${provider}`,
245
+ });
246
+ const accounts = getRecord(providerEntry.accounts);
247
+ if (!accounts) {
248
+ return;
249
+ }
250
+ for (const [accountId, accountValue] of Object.entries(accounts)) {
251
+ const account = getRecord(accountValue);
252
+ if (!account) {
253
+ continue;
254
+ }
255
+ migrateProviderEntry({
256
+ provider,
257
+ entry: account,
258
+ pathPrefix: `channels.${provider}.accounts.${accountId}`,
259
+ });
260
+ }
261
+ };
262
+ migrateProvider("telegram");
263
+ migrateProvider("discord");
264
+ migrateProvider("slack");
265
+ },
266
+ },
156
267
  {
157
268
  id: "routing.allowFrom->channels.whatsapp.allowFrom",
158
269
  describe: "Move routing.allowFrom to channels.whatsapp.allowFrom",
159
270
  apply: (raw, changes) => {
160
271
  const routing = raw.routing;
161
- if (!routing || typeof routing !== "object")
272
+ if (!routing || typeof routing !== "object") {
162
273
  return;
274
+ }
163
275
  const allowFrom = routing.allowFrom;
164
- if (allowFrom === undefined)
276
+ if (allowFrom === undefined) {
165
277
  return;
278
+ }
166
279
  const channels = getRecord(raw.channels);
167
280
  const whatsapp = channels ? getRecord(channels.whatsapp) : null;
168
281
  if (!whatsapp) {
@@ -193,31 +306,30 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
193
306
  describe: "Move routing.groupChat.requireMention to channels.whatsapp/telegram/imessage groups",
194
307
  apply: (raw, changes) => {
195
308
  const routing = raw.routing;
196
- if (!routing || typeof routing !== "object")
309
+ if (!routing || typeof routing !== "object") {
197
310
  return;
311
+ }
198
312
  const groupChat = routing.groupChat &&
199
313
  typeof routing.groupChat === "object"
200
314
  ? routing.groupChat
201
315
  : null;
202
- if (!groupChat)
316
+ if (!groupChat) {
203
317
  return;
318
+ }
204
319
  const requireMention = groupChat.requireMention;
205
- if (requireMention === undefined)
320
+ if (requireMention === undefined) {
206
321
  return;
322
+ }
207
323
  const channels = ensureRecord(raw, "channels");
208
324
  const applyTo = (key, options) => {
209
- if (options?.requireExisting && !isRecord(channels[key]))
325
+ if (options?.requireExisting && !isRecord(channels[key])) {
210
326
  return;
327
+ }
211
328
  const section = channels[key] && typeof channels[key] === "object"
212
329
  ? channels[key]
213
330
  : {};
214
- const groups = section.groups && typeof section.groups === "object"
215
- ? section.groups
216
- : {};
331
+ const { groups, entry } = ensureDefaultGroupEntry(section);
217
332
  const defaultKey = "*";
218
- const entry = groups[defaultKey] && typeof groups[defaultKey] === "object"
219
- ? groups[defaultKey]
220
- : {};
221
333
  if (entry.requireMention === undefined) {
222
334
  entry.requireMention = requireMention;
223
335
  groups[defaultKey] = entry;
@@ -247,19 +359,22 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
247
359
  describe: "Move gateway.token to gateway.auth.token",
248
360
  apply: (raw, changes) => {
249
361
  const gateway = raw.gateway;
250
- if (!gateway || typeof gateway !== "object")
362
+ if (!gateway || typeof gateway !== "object") {
251
363
  return;
364
+ }
252
365
  const token = gateway.token;
253
- if (token === undefined)
366
+ if (token === undefined) {
254
367
  return;
368
+ }
255
369
  const gatewayObj = gateway;
256
370
  const auth = gatewayObj.auth && typeof gatewayObj.auth === "object"
257
371
  ? gatewayObj.auth
258
372
  : {};
259
373
  if (auth.token === undefined) {
260
374
  auth.token = token;
261
- if (!auth.mode)
375
+ if (!auth.mode) {
262
376
  auth.mode = "token";
377
+ }
263
378
  changes.push("Moved gateway.token → gateway.auth.token.");
264
379
  }
265
380
  else {
@@ -278,19 +393,15 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
278
393
  apply: (raw, changes) => {
279
394
  const channels = ensureRecord(raw, "channels");
280
395
  const telegram = channels.telegram;
281
- if (!telegram || typeof telegram !== "object")
396
+ if (!telegram || typeof telegram !== "object") {
282
397
  return;
398
+ }
283
399
  const requireMention = telegram.requireMention;
284
- if (requireMention === undefined)
400
+ if (requireMention === undefined) {
285
401
  return;
286
- const groups = telegram.groups &&
287
- typeof telegram.groups === "object"
288
- ? telegram.groups
289
- : {};
402
+ }
403
+ const { groups, entry } = ensureDefaultGroupEntry(telegram);
290
404
  const defaultKey = "*";
291
- const entry = groups[defaultKey] && typeof groups[defaultKey] === "object"
292
- ? groups[defaultKey]
293
- : {};
294
405
  if (entry.requireMention === undefined) {
295
406
  entry.requireMention = requireMention;
296
407
  groups[defaultKey] = entry;
@@ -1,3 +1,4 @@
1
+ import { isBlockedObjectKey } from "./prototype-keys.js";
1
2
  export const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
2
3
  export const getRecord = (value) => isRecord(value) ? value : null;
3
4
  export const ensureRecord = (root, key) => {
@@ -10,8 +11,9 @@ export const ensureRecord = (root, key) => {
10
11
  };
11
12
  export const mergeMissing = (target, source) => {
12
13
  for (const [key, value] of Object.entries(source)) {
13
- if (value === undefined)
14
+ if (value === undefined || isBlockedObjectKey(key)) {
14
15
  continue;
16
+ }
15
17
  const existing = target[key];
16
18
  if (existing === undefined) {
17
19
  target[key] = value;
@@ -1,4 +1,5 @@
1
1
  import { isPlainObject } from "../utils.js";
2
+ import { isBlockedObjectKey } from "./prototype-keys.js";
2
3
  function isObjectWithStringId(value) {
3
4
  if (!isPlainObject(value)) {
4
5
  return false;
@@ -46,6 +47,9 @@ export function applyMergePatch(base, patch, options = {}) {
46
47
  }
47
48
  const result = isPlainObject(base) ? { ...base } : {};
48
49
  for (const [key, value] of Object.entries(patch)) {
50
+ if (isBlockedObjectKey(key)) {
51
+ continue;
52
+ }
49
53
  if (value === null) {
50
54
  delete result[key];
51
55
  continue;
@@ -0,0 +1,4 @@
1
+ const BLOCKED_OBJECT_KEYS = new Set(["__proto__", "prototype", "constructor"]);
2
+ export function isBlockedObjectKey(key) {
3
+ return BLOCKED_OBJECT_KEYS.has(key);
4
+ }
@@ -16,10 +16,14 @@ export const FIELD_HELP = {
16
16
  "discovery.mdns.mode": 'mDNS broadcast mode ("minimal" default, "full" includes cliPath/sshPort, "off" disables mDNS).',
17
17
  "gateway.auth.token": "Required by default for gateway access (unless using Tailscale Serve identity); required for non-loopback binds.",
18
18
  "gateway.auth.password": "Required for Tailscale funnel.",
19
+ "agents.defaults.sandbox.browser.network": "Docker network for sandbox browser containers (default: poolbot-sandbox-browser). Avoid bridge if you need stricter isolation.",
20
+ "agents.list[].sandbox.browser.network": "Per-agent override for sandbox browser Docker network.",
21
+ "agents.defaults.sandbox.browser.cdpSourceRange": "Optional CIDR allowlist for container-edge CDP ingress (for example 172.21.0.1/32).",
22
+ "agents.list[].sandbox.browser.cdpSourceRange": "Per-agent override for CDP source CIDR allowlist.",
19
23
  "gateway.controlUi.basePath": "Optional URL prefix where the Control UI is served (e.g. /poolbot).",
20
24
  "gateway.controlUi.root": "Optional filesystem root for Control UI assets (defaults to dist/control-ui).",
21
25
  "gateway.controlUi.allowedOrigins": "Allowed browser origins for Control UI/WebChat websocket connections (full origins only, e.g. https://control.example.com).",
22
- "gateway.controlUi.allowInsecureAuth": "Allow Control UI auth over insecure HTTP (token-only; not recommended).",
26
+ "gateway.controlUi.allowInsecureAuth": "Insecure-auth toggle; Control UI still enforces secure context + device identity unless dangerouslyDisableDeviceAuth is enabled.",
23
27
  "gateway.controlUi.dangerouslyDisableDeviceAuth": "DANGEROUS. Disable Control UI device identity checks (token/password only).",
24
28
  "gateway.http.endpoints.chatCompletions.enabled": "Enable the OpenAI-compatible `POST /v1/chat/completions` endpoint (default: false).",
25
29
  "gateway.reload.mode": 'Hot reload strategy for config changes ("hybrid" recommended).',
@@ -127,11 +131,19 @@ export const FIELD_HELP = {
127
131
  "agents.defaults.memorySearch.query.hybrid.vectorWeight": "Weight for vector similarity when merging results (0-1).",
128
132
  "agents.defaults.memorySearch.query.hybrid.textWeight": "Weight for BM25 text relevance when merging results (0-1).",
129
133
  "agents.defaults.memorySearch.query.hybrid.candidateMultiplier": "Multiplier for candidate pool size (default: 4).",
134
+ "agents.defaults.memorySearch.query.hybrid.mmr.enabled": "Enable MMR re-ranking to reduce near-duplicate memory hits (default: false).",
135
+ "agents.defaults.memorySearch.query.hybrid.mmr.lambda": "MMR relevance/diversity balance (0 = max diversity, 1 = max relevance, default: 0.7).",
136
+ "agents.defaults.memorySearch.query.hybrid.temporalDecay.enabled": "Enable exponential recency decay for hybrid scoring (default: false).",
137
+ "agents.defaults.memorySearch.query.hybrid.temporalDecay.halfLifeDays": "Half-life in days for temporal decay (default: 30).",
130
138
  "agents.defaults.memorySearch.cache.enabled": "Cache chunk embeddings in SQLite to speed up reindexing and frequent updates (default: true).",
131
139
  memory: "Memory backend configuration (global).",
132
140
  "memory.backend": 'Memory backend ("builtin" for Pool Bot embeddings, "qmd" for QMD sidecar).',
133
141
  "memory.citations": 'Default citation behavior ("auto", "on", or "off").',
134
142
  "memory.qmd.command": "Path to the qmd binary (default: resolves from PATH).",
143
+ "memory.qmd.mcporter": "Optional: route QMD searches through mcporter (MCP runtime) instead of spawning `qmd` per query. Intended to avoid per-search cold starts when QMD models are large.",
144
+ "memory.qmd.mcporter.enabled": "Enable mcporter-backed QMD searches (default: false).",
145
+ "memory.qmd.mcporter.serverName": "mcporter server name to call (default: qmd). Server should run `qmd mcp` with lifecycle keep-alive.",
146
+ "memory.qmd.mcporter.startDaemon": "Start `mcporter daemon start` automatically when enabled (default: true).",
135
147
  "memory.qmd.includeDefaultMemory": "Whether to automatically index MEMORY.md + memory/**/*.md (default: true).",
136
148
  "memory.qmd.paths": "Additional directories/files to index with QMD (path + optional glob pattern).",
137
149
  "memory.qmd.paths.path": "Absolute or ~-relative path to index via QMD.",
@@ -173,6 +185,12 @@ export const FIELD_HELP = {
173
185
  "plugins.installs.*.sourcePath": "Original archive/path used for install (if any).",
174
186
  "plugins.installs.*.installPath": "Resolved install directory (usually ~/.poolbot/extensions/<id>).",
175
187
  "plugins.installs.*.version": "Version recorded at install time (if available).",
188
+ "plugins.installs.*.resolvedName": "Resolved npm package name from the fetched artifact.",
189
+ "plugins.installs.*.resolvedVersion": "Resolved npm package version from the fetched artifact (useful for non-pinned specs).",
190
+ "plugins.installs.*.resolvedSpec": "Resolved exact npm spec (<name>@<version>) from the fetched artifact.",
191
+ "plugins.installs.*.integrity": "Resolved npm dist integrity hash for the fetched artifact (if reported by npm).",
192
+ "plugins.installs.*.shasum": "Resolved npm dist shasum for the fetched artifact (if reported by npm).",
193
+ "plugins.installs.*.resolvedAt": "ISO timestamp when npm package metadata was last resolved for this install record.",
176
194
  "plugins.installs.*.installedAt": "ISO timestamp of last install/update.",
177
195
  "agents.list.*.identity.avatar": "Agent avatar (workspace-relative path, http(s) URL, or data URI).",
178
196
  "agents.defaults.model.primary": "Primary model (provider/model).",
@@ -191,11 +209,15 @@ export const FIELD_HELP = {
191
209
  "commands.bashForegroundMs": "How long bash waits before backgrounding (default: 2000; 0 backgrounds immediately).",
192
210
  "commands.config": "Allow /config chat command to read/write config on disk (default: false).",
193
211
  "commands.debug": "Allow /debug chat command for runtime-only overrides (default: false).",
194
- "commands.restart": "Allow /restart and gateway restart tool actions (default: false).",
212
+ "commands.restart": "Allow /restart and gateway restart tool actions (default: true).",
195
213
  "commands.useAccessGroups": "Enforce access-group allowlists/policies for commands.",
196
214
  "commands.ownerAllowFrom": "Explicit owner allowlist for owner-only tools/commands. Use channel-native IDs (optionally prefixed like \"whatsapp:+15551234567\"). '*' is ignored.",
215
+ "commands.ownerDisplay": "Controls how owner IDs are rendered in the system prompt. Allowed values: raw, hash. Default: raw.",
216
+ "commands.ownerDisplaySecret": "Optional secret used to HMAC hash owner IDs when ownerDisplay=hash. Prefer env substitution.",
197
217
  "session.dmScope": 'DM session scoping: "main" keeps continuity; "per-peer", "per-channel-peer", or "per-account-channel-peer" isolates DM history (recommended for shared inboxes/multi-account).',
198
218
  "session.identityLinks": "Map canonical identities to provider-prefixed peer IDs for DM session linking (example: telegram:123456).",
219
+ "session.threadBindings.enabled": "Global master switch for thread-bound session routing features. Channel/provider keys (for example channels.discord.threadBindings.enabled) override this default. Default: true.",
220
+ "session.threadBindings.ttlHours": "Default auto-unfocus TTL in hours for thread-bound sessions across providers/channels. Set 0 to disable (default: 24). Provider keys (for example channels.discord.threadBindings.ttlHours) override this.",
199
221
  "channels.telegram.configWrites": "Allow Telegram to write config in response to channel events/commands (default: true).",
200
222
  "channels.slack.configWrites": "Allow Slack to write config in response to channel events/commands (default: true).",
201
223
  "channels.mattermost.configWrites": "Allow Mattermost to write config in response to channel events/commands (default: true).",
@@ -205,6 +227,7 @@ export const FIELD_HELP = {
205
227
  "channels.signal.configWrites": "Allow Signal to write config in response to channel events/commands (default: true).",
206
228
  "channels.imessage.configWrites": "Allow iMessage to write config in response to channel events/commands (default: true).",
207
229
  "channels.msteams.configWrites": "Allow Microsoft Teams to write config in response to channel events/commands (default: true).",
230
+ "channels.modelByChannel": "Map provider -> channel id -> model override (values are provider/model or aliases).",
208
231
  ...IRC_FIELD_HELP,
209
232
  "channels.discord.commands.native": 'Override native commands for Discord (bool or "auto").',
210
233
  "channels.discord.commands.nativeSkills": 'Override native skill commands for Discord (bool or "auto").',
@@ -212,18 +235,26 @@ export const FIELD_HELP = {
212
235
  "channels.telegram.commands.nativeSkills": 'Override native skill commands for Telegram (bool or "auto").',
213
236
  "channels.slack.commands.native": 'Override native commands for Slack (bool or "auto").',
214
237
  "channels.slack.commands.nativeSkills": 'Override native skill commands for Slack (bool or "auto").',
215
- "channels.slack.streamMode": "Live stream preview mode for Slack replies (replace | status_final | append).",
238
+ "channels.slack.streaming": 'Unified Slack stream preview mode: "off" | "partial" | "block" | "progress". Legacy boolean/streamMode keys are auto-mapped.',
239
+ "channels.slack.nativeStreaming": "Enable native Slack text streaming (chat.startStream/chat.appendStream/chat.stopStream) when channels.slack.streaming is partial (default: true).",
240
+ "channels.slack.streamMode": "Legacy Slack preview mode alias (replace | status_final | append); auto-migrated to channels.slack.streaming.",
216
241
  "session.agentToAgent.maxPingPongTurns": "Max reply-back turns between requester and target (0–5).",
217
242
  "channels.telegram.customCommands": "Additional Telegram bot menu commands (merged with native; conflicts ignored).",
218
243
  "messages.suppressToolErrors": "When true, suppress ⚠️ tool-error warnings from being shown to the user. The agent already sees errors in context and can retry. Default: false.",
219
244
  "messages.ackReaction": "Emoji reaction used to acknowledge inbound messages (empty disables).",
220
245
  "messages.ackReactionScope": 'When to send ack reactions ("group-mentions", "group-all", "direct", "all").',
246
+ "messages.statusReactions": "Lifecycle status reactions that update the emoji on the trigger message as the agent progresses (queued → thinking → tool → done/error).",
247
+ "messages.statusReactions.enabled": "Enable lifecycle status reactions for Telegram. When enabled, the ack reaction becomes the initial 'queued' state and progresses through thinking, tool, done/error automatically. Default: false.",
248
+ "messages.statusReactions.emojis": "Override default status reaction emojis. Keys: thinking, tool, coding, web, done, error, stallSoft, stallHard. Must be valid Telegram reaction emojis.",
249
+ "messages.statusReactions.timing": "Override default timing. Keys: debounceMs (700), stallSoftMs (25000), stallHardMs (60000), doneHoldMs (1500), errorHoldMs (2500).",
221
250
  "messages.inbound.debounceMs": "Debounce window (ms) for batching rapid inbound messages from the same sender (0 to disable).",
222
251
  "channels.telegram.dmPolicy": 'Direct message access control ("pairing" recommended). "open" requires channels.telegram.allowFrom=["*"].',
223
- "channels.telegram.streamMode": "Live stream preview mode for Telegram replies (off | partial | block). Separate from block streaming; uses sendMessage + editMessageText.",
224
- "channels.telegram.draftChunk.minChars": 'Minimum chars before emitting a Telegram stream preview update when channels.telegram.streamMode="block" (default: 200).',
225
- "channels.telegram.draftChunk.maxChars": 'Target max size for a Telegram stream preview chunk when channels.telegram.streamMode="block" (default: 800; clamped to channels.telegram.textChunkLimit).',
226
- "channels.telegram.draftChunk.breakPreference": "Preferred breakpoints for Telegram draft chunks (paragraph | newline | sentence). Default: paragraph.",
252
+ "channels.telegram.streaming": 'Unified Telegram stream preview mode: "off" | "partial" | "block" | "progress". "progress" maps to "partial" on Telegram. Legacy boolean/streamMode keys are auto-mapped.',
253
+ "channels.discord.streaming": 'Unified Discord stream preview mode: "off" | "partial" | "block" | "progress". "progress" maps to "partial" on Discord. Legacy boolean/streamMode keys are auto-mapped.',
254
+ "channels.discord.streamMode": "Legacy Discord preview mode alias (off | partial | block); auto-migrated to channels.discord.streaming.",
255
+ "channels.discord.draftChunk.minChars": 'Minimum chars before emitting a Discord stream preview update when channels.discord.streaming="block" (default: 200).',
256
+ "channels.discord.draftChunk.maxChars": 'Target max size for a Discord stream preview chunk when channels.discord.streaming="block" (default: 800; clamped to channels.discord.textChunkLimit).',
257
+ "channels.discord.draftChunk.breakPreference": "Preferred breakpoints for Discord draft chunks (paragraph | newline | sentence). Default: paragraph.",
227
258
  "channels.telegram.retry.attempts": "Max retry attempts for outbound Telegram API calls (default: 3).",
228
259
  "channels.telegram.retry.minDelayMs": "Minimum retry delay in ms for Telegram outbound calls.",
229
260
  "channels.telegram.retry.maxDelayMs": "Maximum retry delay cap in ms for Telegram outbound calls.",
@@ -243,7 +274,13 @@ export const FIELD_HELP = {
243
274
  "channels.discord.retry.maxDelayMs": "Maximum retry delay cap in ms for Discord outbound calls.",
244
275
  "channels.discord.retry.jitter": "Jitter factor (0-1) applied to Discord retry delays.",
245
276
  "channels.discord.maxLinesPerMessage": "Soft max line count per Discord message (default: 17).",
277
+ "channels.discord.threadBindings.enabled": "Enable Discord thread binding features (/focus, bound-thread routing/delivery, and thread-bound subagent sessions). Overrides session.threadBindings.enabled when set.",
278
+ "channels.discord.threadBindings.ttlHours": "Auto-unfocus TTL in hours for Discord thread-bound sessions (/focus and spawned thread sessions). Set 0 to disable (default: 24). Overrides session.threadBindings.ttlHours when set.",
279
+ "channels.discord.threadBindings.spawnSubagentSessions": "Allow subagent spawns with thread=true to auto-create and bind Discord threads (default: false; opt-in). Set true to enable thread-bound subagent spawns for this account/channel.",
246
280
  "channels.discord.ui.components.accentColor": "Accent color for Discord component containers (hex). Set per account via channels.discord.accounts.<id>.ui.components.accentColor.",
281
+ "channels.discord.voice.enabled": "Enable Discord voice channel conversations (default: true). Omit channels.discord.voice to keep voice support disabled for the account.",
282
+ "channels.discord.voice.autoJoin": "Voice channels to auto-join on startup (list of guildId/channelId entries).",
283
+ "channels.discord.voice.tts": "Optional TTS overrides for Discord voice playback (merged with messages.tts).",
247
284
  "channels.discord.intents.presence": "Enable the Guild Presences privileged intent. Must also be enabled in the Discord Developer Portal. Allows tracking user activities (e.g. Spotify). Default: false.",
248
285
  "channels.discord.intents.guildMembers": "Enable the Guild Members privileged intent. Must also be enabled in the Discord Developer Portal. Default: false.",
249
286
  "channels.discord.pluralkit.enabled": "Resolve PluralKit proxied messages and treat system members as distinct senders.",