@poolzin/pool-bot 2026.2.24 → 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 (646) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/event-mapper.js +87 -22
  4. package/dist/acp/meta.js +12 -6
  5. package/dist/acp/secret-file.js +22 -0
  6. package/dist/agents/agent-paths.js +8 -9
  7. package/dist/agents/agent-scope.js +17 -5
  8. package/dist/agents/auth-profiles/oauth.js +148 -64
  9. package/dist/agents/auth-profiles/session-override.js +13 -7
  10. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  11. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  12. package/dist/agents/bash-tools.exec-host-gateway.js +240 -0
  13. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  14. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  15. package/dist/agents/bash-tools.exec-types.js +1 -0
  16. package/dist/agents/bash-tools.process.js +224 -218
  17. package/dist/agents/bedrock-discovery.js +3 -1
  18. package/dist/agents/byteplus-models.js +97 -0
  19. package/dist/agents/chutes-oauth.js +1 -0
  20. package/dist/agents/cli-runner/helpers.js +4 -0
  21. package/dist/agents/compaction.js +41 -14
  22. package/dist/agents/content-blocks.js +16 -0
  23. package/dist/agents/doubao-models.js +121 -0
  24. package/dist/agents/failover-error.js +2 -0
  25. package/dist/agents/huggingface-models.js +5 -3
  26. package/dist/agents/live-model-filter.js +5 -0
  27. package/dist/agents/minimax-vlm.js +10 -8
  28. package/dist/agents/model-auth.js +6 -0
  29. package/dist/agents/model-catalog.js +3 -1
  30. package/dist/agents/model-fallback.js +96 -101
  31. package/dist/agents/model-selection.js +7 -1
  32. package/dist/agents/models-config.providers.js +364 -165
  33. package/dist/agents/ollama-stream.js +117 -4
  34. package/dist/agents/opencode-zen-models.js +22 -11
  35. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  36. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  37. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  38. package/dist/agents/pi-embedded-helpers.js +1 -1
  39. package/dist/agents/pi-embedded-payloads.js +1 -0
  40. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  41. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  42. package/dist/agents/pi-embedded-runner/google.js +20 -8
  43. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  44. package/dist/agents/pi-embedded-runner/run.js +71 -12
  45. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  46. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  47. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  48. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  49. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  50. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  51. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  52. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  53. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  54. package/dist/agents/pi-embedded-subscribe.js +9 -4
  55. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  56. package/dist/agents/pi-embedded-utils.js +3 -0
  57. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  58. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  59. package/dist/agents/pi-settings.js +40 -0
  60. package/dist/agents/pi-tools.policy.js +2 -1
  61. package/dist/agents/provider/config-loader.js +1 -1
  62. package/dist/agents/sandbox/browser.js +170 -33
  63. package/dist/agents/sandbox/config-hash.js +14 -27
  64. package/dist/agents/sandbox/config.js +21 -2
  65. package/dist/agents/sandbox/constants.js +2 -0
  66. package/dist/agents/sandbox/docker.js +16 -2
  67. package/dist/agents/sandbox/novnc-auth.js +62 -0
  68. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  69. package/dist/agents/sandbox/shared.js +10 -6
  70. package/dist/agents/sandbox-paths.js +24 -11
  71. package/dist/agents/schema/clean-for-gemini.js +132 -85
  72. package/dist/agents/session-slug.js +10 -5
  73. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  74. package/dist/agents/session-tool-result-guard.js +3 -1
  75. package/dist/agents/session-transcript-repair.js +40 -6
  76. package/dist/agents/skills/bundled-dir.js +19 -5
  77. package/dist/agents/skills/env-overrides.js +124 -43
  78. package/dist/agents/skills/frontmatter.js +6 -6
  79. package/dist/agents/skills/plugin-skills.js +14 -7
  80. package/dist/agents/skills/workspace.js +1 -0
  81. package/dist/agents/skills.test-helpers.js +13 -0
  82. package/dist/agents/stable-stringify.js +12 -0
  83. package/dist/agents/subagent-announce.js +251 -49
  84. package/dist/agents/subagent-lifecycle-events.js +19 -0
  85. package/dist/agents/subagent-registry-cleanup.js +31 -0
  86. package/dist/agents/subagent-registry-completion.js +68 -0
  87. package/dist/agents/subagent-registry-queries.js +117 -0
  88. package/dist/agents/subagent-registry-state.js +46 -0
  89. package/dist/agents/subagent-registry.js +252 -221
  90. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  91. package/dist/agents/subagent-registry.store.js +1 -0
  92. package/dist/agents/subagent-registry.types.js +1 -0
  93. package/dist/agents/subagent-spawn.js +195 -7
  94. package/dist/agents/system-prompt.js +22 -6
  95. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  96. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  97. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  98. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  99. package/dist/agents/timeout.js +18 -6
  100. package/dist/agents/tool-call-id.js +1 -1
  101. package/dist/agents/tool-display-common.js +162 -29
  102. package/dist/agents/tool-images.js +82 -9
  103. package/dist/agents/tool-policy-shared.js +108 -0
  104. package/dist/agents/tool-policy.js +51 -26
  105. package/dist/agents/tools/browser-tool.js +160 -54
  106. package/dist/agents/tools/canvas-tool.js +27 -1
  107. package/dist/agents/tools/common.js +45 -0
  108. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  109. package/dist/agents/tools/discord-actions-guild.js +4 -1
  110. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  111. package/dist/agents/tools/gateway-tool.js +3 -1
  112. package/dist/agents/tools/image-tool.js +214 -99
  113. package/dist/agents/tools/nodes-utils.js +1 -10
  114. package/dist/agents/tools/sessions-history-tool.js +140 -108
  115. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  116. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  117. package/dist/agents/tools/subagents-tool.js +2 -1
  118. package/dist/agents/tools/whatsapp-actions.js +10 -2
  119. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  120. package/dist/agents/transcript-policy.js +22 -8
  121. package/dist/agents/venice-models.js +11 -3
  122. package/dist/agents/workspace.js +222 -46
  123. package/dist/auto-reply/commands-registry.data.js +51 -0
  124. package/dist/auto-reply/commands-registry.js +19 -21
  125. package/dist/auto-reply/fallback-state.js +114 -0
  126. package/dist/auto-reply/group-activation.js +10 -5
  127. package/dist/auto-reply/inbound-debounce.js +10 -5
  128. package/dist/auto-reply/model-runtime.js +68 -0
  129. package/dist/auto-reply/reply/abort.js +1 -1
  130. package/dist/auto-reply/reply/agent-runner-execution.js +40 -5
  131. package/dist/auto-reply/reply/agent-runner.js +165 -39
  132. package/dist/auto-reply/reply/bash-command.js +41 -39
  133. package/dist/auto-reply/reply/command-gates.js +25 -0
  134. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  135. package/dist/auto-reply/reply/commands-bash.js +6 -5
  136. package/dist/auto-reply/reply/commands-config.js +30 -28
  137. package/dist/auto-reply/reply/commands-core.js +2 -1
  138. package/dist/auto-reply/reply/commands-info.js +1 -0
  139. package/dist/auto-reply/reply/commands-models.js +65 -14
  140. package/dist/auto-reply/reply/commands-session.js +237 -82
  141. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  142. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  143. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  144. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  145. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  146. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  147. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  148. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  149. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  150. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  151. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  152. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  153. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  154. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  155. package/dist/auto-reply/reply/commands-tts.js +10 -5
  156. package/dist/auto-reply/reply/config-value.js +10 -5
  157. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  158. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  159. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  160. package/dist/auto-reply/reply/followup-runner.js +1 -0
  161. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  162. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  163. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  164. package/dist/auto-reply/reply/get-reply.js +71 -12
  165. package/dist/auto-reply/reply/model-selection.js +80 -39
  166. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  167. package/dist/auto-reply/reply/queue/state.js +13 -12
  168. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  169. package/dist/auto-reply/reply/reply-reference.js +9 -8
  170. package/dist/auto-reply/reply/route-reply.js +15 -8
  171. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  172. package/dist/auto-reply/reply/session.js +22 -6
  173. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  174. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  175. package/dist/auto-reply/reply/typing.js +46 -21
  176. package/dist/auto-reply/send-policy.js +14 -7
  177. package/dist/auto-reply/status.js +140 -16
  178. package/dist/auto-reply/templating.js +10 -5
  179. package/dist/auto-reply/thinking.js +7 -16
  180. package/dist/auto-reply/tokens.js +21 -5
  181. package/dist/browser/bridge-server.js +36 -20
  182. package/dist/browser/cdp.helpers.js +7 -14
  183. package/dist/browser/cdp.js +35 -15
  184. package/dist/browser/chrome.profile-decoration.js +7 -4
  185. package/dist/browser/config.js +30 -0
  186. package/dist/browser/extension-relay-auth.js +55 -0
  187. package/dist/browser/extension-relay.js +74 -29
  188. package/dist/browser/navigation-guard.js +39 -0
  189. package/dist/browser/paths.js +77 -0
  190. package/dist/browser/profiles.js +13 -8
  191. package/dist/browser/pw-ai-module.js +10 -5
  192. package/dist/browser/pw-session.js +76 -39
  193. package/dist/browser/pw-tools-core.interactions.js +14 -7
  194. package/dist/browser/pw-tools-core.state.js +12 -6
  195. package/dist/browser/routes/agent.act.js +431 -424
  196. package/dist/browser/routes/agent.shared.js +47 -3
  197. package/dist/browser/routes/agent.snapshot.js +122 -116
  198. package/dist/browser/routes/agent.storage.js +303 -297
  199. package/dist/browser/routes/tabs.js +154 -100
  200. package/dist/browser/server-context.js +7 -0
  201. package/dist/browser/server-lifecycle.js +37 -0
  202. package/dist/build-info.json +3 -3
  203. package/dist/channels/allow-from.js +26 -0
  204. package/dist/channels/allowlists/resolve-utils.js +43 -19
  205. package/dist/channels/channel-config.js +14 -7
  206. package/dist/channels/draft-stream-loop.js +7 -0
  207. package/dist/channels/model-overrides.js +82 -0
  208. package/dist/channels/plugins/account-action-gate.js +13 -0
  209. package/dist/channels/plugins/message-actions.js +10 -0
  210. package/dist/channels/plugins/normalize/imessage.js +14 -7
  211. package/dist/channels/plugins/normalize/slack.js +10 -5
  212. package/dist/channels/plugins/normalize/telegram.js +14 -7
  213. package/dist/channels/plugins/outbound/discord.js +80 -8
  214. package/dist/channels/plugins/outbound/signal.js +11 -11
  215. package/dist/channels/plugins/setup-helpers.js +10 -5
  216. package/dist/channels/sender-label.js +14 -7
  217. package/dist/channels/session.js +4 -2
  218. package/dist/channels/status-reactions.js +297 -0
  219. package/dist/channels/telegram/api.js +18 -0
  220. package/dist/cli/argv.js +84 -21
  221. package/dist/cli/banner.js +3 -2
  222. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  223. package/dist/cli/cli-name.js +11 -11
  224. package/dist/cli/cli-utils.js +13 -3
  225. package/dist/cli/command-format.js +1 -1
  226. package/dist/cli/config-cli.js +1 -1
  227. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  228. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  229. package/dist/cli/daemon-cli/restart-health.js +126 -0
  230. package/dist/cli/daemon-cli/status.gather.js +9 -13
  231. package/dist/cli/daemon-cli/status.print.js +2 -10
  232. package/dist/cli/deps.js +27 -22
  233. package/dist/cli/exec-approvals-cli.js +92 -124
  234. package/dist/cli/gateway-cli/run-loop.js +23 -5
  235. package/dist/cli/memory-cli.js +158 -61
  236. package/dist/cli/node-cli/register.js +14 -5
  237. package/dist/cli/nodes-cli/register.push.js +63 -0
  238. package/dist/cli/nodes-media-utils.js +26 -0
  239. package/dist/cli/outbound-send-deps.js +2 -9
  240. package/dist/cli/outbound-send-mapping.js +11 -0
  241. package/dist/cli/pairing-cli.js +40 -14
  242. package/dist/cli/plugins-cli.js +250 -73
  243. package/dist/cli/ports.js +11 -10
  244. package/dist/cli/program/build-program.js +3 -1
  245. package/dist/cli/program/command-registry.js +214 -136
  246. package/dist/cli/program/command-tree.js +16 -0
  247. package/dist/cli/program/help.js +43 -12
  248. package/dist/cli/program/preaction.js +13 -9
  249. package/dist/cli/program/register.configure.js +3 -18
  250. package/dist/cli/program/register.maintenance.js +2 -2
  251. package/dist/cli/program/register.onboard.js +2 -0
  252. package/dist/cli/program/register.status-health-sessions.js +16 -17
  253. package/dist/cli/program/register.subclis.js +93 -52
  254. package/dist/cli/route.js +12 -8
  255. package/dist/cli/system-cli.js +36 -46
  256. package/dist/cli/test-runtime-capture.js +24 -0
  257. package/dist/cli/update-cli/shared.js +22 -9
  258. package/dist/cli/update-cli/update-command.js +89 -14
  259. package/dist/cli/update-cli/wizard.js +6 -12
  260. package/dist/commands/agent/run-context.js +18 -5
  261. package/dist/commands/agent/session-store.js +17 -4
  262. package/dist/commands/agent.js +185 -89
  263. package/dist/commands/agents.bindings.js +14 -7
  264. package/dist/commands/agents.commands.add.js +13 -9
  265. package/dist/commands/agents.commands.identity.js +12 -6
  266. package/dist/commands/agents.commands.list.js +11 -6
  267. package/dist/commands/agents.config.js +8 -10
  268. package/dist/commands/agents.providers.js +12 -6
  269. package/dist/commands/auth-choice-options.js +103 -75
  270. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  271. package/dist/commands/auth-choice.apply.js +4 -0
  272. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  273. package/dist/commands/auth-choice.apply.openai.js +3 -1
  274. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  275. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  276. package/dist/commands/channels/remove.js +13 -6
  277. package/dist/commands/channels/shared.js +4 -14
  278. package/dist/commands/channels.mock-harness.js +23 -0
  279. package/dist/commands/configure.commands.js +14 -0
  280. package/dist/commands/configure.gateway.js +2 -4
  281. package/dist/commands/configure.js +1 -1
  282. package/dist/commands/configure.shared.js +11 -0
  283. package/dist/commands/daemon-install-helpers.js +2 -2
  284. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  285. package/dist/commands/dashboard.js +12 -10
  286. package/dist/commands/docs.js +14 -8
  287. package/dist/commands/doctor-config-flow.js +11 -9
  288. package/dist/commands/doctor-legacy-config.js +281 -0
  289. package/dist/commands/doctor-state-integrity.js +99 -23
  290. package/dist/commands/doctor-update.js +12 -9
  291. package/dist/commands/models/list.list-command.js +7 -5
  292. package/dist/commands/models/set-image.js +2 -21
  293. package/dist/commands/node-daemon-install-helpers.js +10 -8
  294. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  295. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  296. package/dist/commands/onboard-auth.credentials.js +90 -13
  297. package/dist/commands/onboard-auth.js +1 -1
  298. package/dist/commands/onboard-auth.models.js +6 -5
  299. package/dist/commands/onboard-hooks.js +1 -1
  300. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  301. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  302. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  303. package/dist/commands/onboard-remote.js +14 -7
  304. package/dist/commands/onboard.js +11 -13
  305. package/dist/commands/sandbox-display.js +6 -5
  306. package/dist/commands/sessions.test-helpers.js +61 -0
  307. package/dist/commands/status-all/diagnosis.js +14 -10
  308. package/dist/commands/status-all/format.js +1 -0
  309. package/dist/commands/status.gateway-probe.js +1 -16
  310. package/dist/commands/systemd-linger.js +12 -6
  311. package/dist/config/agent-limits.js +2 -0
  312. package/dist/config/commands.js +32 -15
  313. package/dist/config/config-paths.js +9 -11
  314. package/dist/config/config.js +1 -1
  315. package/dist/config/defaults.js +22 -2
  316. package/dist/config/discord-preview-streaming.js +104 -0
  317. package/dist/config/env-substitution.js +62 -34
  318. package/dist/config/env-vars.js +45 -7
  319. package/dist/config/includes.js +4 -0
  320. package/dist/config/io.js +656 -171
  321. package/dist/config/legacy.migrations.part-1.js +189 -78
  322. package/dist/config/legacy.shared.js +3 -1
  323. package/dist/config/merge-patch.js +54 -4
  324. package/dist/config/prototype-keys.js +4 -0
  325. package/dist/config/redact-snapshot.js +404 -76
  326. package/dist/config/schema.help.js +44 -7
  327. package/dist/config/schema.js +58 -570
  328. package/dist/config/schema.labels.js +38 -6
  329. package/dist/config/sessions/delivery-info.js +10 -3
  330. package/dist/config/sessions/main-session.js +10 -5
  331. package/dist/config/sessions/session-file.js +33 -0
  332. package/dist/config/sessions/session-key.js +10 -5
  333. package/dist/config/sessions/store.js +1 -1
  334. package/dist/config/sessions.js +1 -0
  335. package/dist/config/validation.js +140 -85
  336. package/dist/config/zod-schema.agent-runtime.js +11 -0
  337. package/dist/config/zod-schema.hooks.js +40 -11
  338. package/dist/config/zod-schema.installs.js +20 -0
  339. package/dist/config/zod-schema.js +156 -20
  340. package/dist/config/zod-schema.providers-core.js +78 -4
  341. package/dist/config/zod-schema.providers.js +6 -1
  342. package/dist/config/zod-schema.session.js +41 -2
  343. package/dist/cron/run-log.js +3 -0
  344. package/dist/cron/schedule.js +21 -10
  345. package/dist/cron/service/ops.js +35 -21
  346. package/dist/cron/service/timer.js +116 -16
  347. package/dist/cron/stagger.js +3 -1
  348. package/dist/daemon/cmd-argv.js +21 -0
  349. package/dist/daemon/cmd-set.js +58 -0
  350. package/dist/daemon/service-types.js +1 -0
  351. package/dist/discord/api.js +12 -6
  352. package/dist/discord/draft-chunking.js +22 -0
  353. package/dist/discord/draft-stream.js +124 -0
  354. package/dist/discord/monitor/agent-components.js +1 -1
  355. package/dist/discord/monitor/commands.js +5 -0
  356. package/dist/discord/monitor/exec-approvals.js +357 -162
  357. package/dist/discord/monitor/gateway-plugin.js +2 -1
  358. package/dist/discord/monitor/listeners.js +37 -27
  359. package/dist/discord/monitor/message-handler.js +4 -1
  360. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  361. package/dist/discord/monitor/message-handler.process.js +246 -217
  362. package/dist/discord/monitor/message-utils.js +143 -6
  363. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  364. package/dist/discord/monitor/model-picker.js +651 -0
  365. package/dist/discord/monitor/native-command.js +573 -16
  366. package/dist/discord/monitor/provider.allowlist.js +223 -0
  367. package/dist/discord/monitor/provider.js +275 -347
  368. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  369. package/dist/discord/monitor/reply-delivery.js +123 -16
  370. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  371. package/dist/discord/monitor/thread-bindings.js +4 -0
  372. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  373. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  374. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  375. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  376. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  377. package/dist/discord/resolve-users.js +33 -21
  378. package/dist/discord/send.channels.js +15 -0
  379. package/dist/discord/send.js +3 -2
  380. package/dist/discord/send.outbound.js +82 -26
  381. package/dist/discord/send.permissions.js +83 -30
  382. package/dist/discord/send.reactions.js +8 -4
  383. package/dist/discord/token.js +10 -5
  384. package/dist/discord/voice/command.js +263 -0
  385. package/dist/discord/voice/manager.js +531 -0
  386. package/dist/gateway/auth.js +72 -13
  387. package/dist/gateway/call.js +152 -83
  388. package/dist/gateway/canvas-capability.js +75 -0
  389. package/dist/gateway/client.js +28 -4
  390. package/dist/gateway/config-reload.js +3 -4
  391. package/dist/gateway/control-plane-audit.js +28 -0
  392. package/dist/gateway/control-plane-rate-limit.js +53 -0
  393. package/dist/gateway/control-ui.js +219 -96
  394. package/dist/gateway/events.js +1 -0
  395. package/dist/gateway/hooks-mapping.js +88 -38
  396. package/dist/gateway/hooks.js +109 -54
  397. package/dist/gateway/http-auth-helpers.js +3 -2
  398. package/dist/gateway/http-common.js +22 -0
  399. package/dist/gateway/http-endpoint-helpers.js +1 -0
  400. package/dist/gateway/method-scopes.js +169 -0
  401. package/dist/gateway/net.js +74 -9
  402. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  403. package/dist/gateway/node-registry.js +10 -5
  404. package/dist/gateway/openai-http.js +1 -0
  405. package/dist/gateway/openresponses-http.js +121 -110
  406. package/dist/gateway/origin-check.js +1 -18
  407. package/dist/gateway/probe-auth.js +2 -0
  408. package/dist/gateway/protocol/index.js +4 -2
  409. package/dist/gateway/protocol/schema/cron.js +1 -0
  410. package/dist/gateway/protocol/schema/devices.js +1 -0
  411. package/dist/gateway/protocol/schema/protocol-schemas.js +4 -1
  412. package/dist/gateway/protocol/schema/push.js +18 -0
  413. package/dist/gateway/protocol/schema/sessions.js +6 -0
  414. package/dist/gateway/protocol/schema.js +1 -0
  415. package/dist/gateway/role-policy.js +17 -0
  416. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  417. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  418. package/dist/gateway/server-chat.js +83 -25
  419. package/dist/gateway/server-constants.js +10 -9
  420. package/dist/gateway/server-cron.js +1 -0
  421. package/dist/gateway/server-http.js +247 -54
  422. package/dist/gateway/server-maintenance.js +20 -5
  423. package/dist/gateway/server-methods/agent.js +162 -24
  424. package/dist/gateway/server-methods/chat.js +465 -130
  425. package/dist/gateway/server-methods/config.js +193 -152
  426. package/dist/gateway/server-methods/devices.js +17 -3
  427. package/dist/gateway/server-methods/models.js +11 -1
  428. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  429. package/dist/gateway/server-methods/nodes.js +251 -69
  430. package/dist/gateway/server-methods/push.js +53 -0
  431. package/dist/gateway/server-methods/sessions.js +64 -8
  432. package/dist/gateway/server-methods/usage.js +162 -75
  433. package/dist/gateway/server-node-events.js +29 -0
  434. package/dist/gateway/server-reload-handlers.js +2 -3
  435. package/dist/gateway/server-runtime-config.js +39 -13
  436. package/dist/gateway/server-runtime-state.js +2 -0
  437. package/dist/gateway/server-startup-memory.js +17 -11
  438. package/dist/gateway/server-ws-runtime.js +1 -0
  439. package/dist/gateway/server.impl.js +296 -139
  440. package/dist/gateway/session-preview.test-helpers.js +11 -0
  441. package/dist/gateway/session-utils.fs.js +32 -34
  442. package/dist/gateway/sessions-resolve.js +17 -5
  443. package/dist/gateway/startup-auth.js +126 -0
  444. package/dist/gateway/test-helpers.agent-results.js +15 -0
  445. package/dist/gateway/test-helpers.mocks.js +37 -14
  446. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  447. package/dist/gateway/test-helpers.server.js +161 -77
  448. package/dist/gateway/tools-invoke-http.js +21 -10
  449. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  450. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  451. package/dist/hooks/bundled/session-memory/handler.js +170 -38
  452. package/dist/hooks/frontmatter.js +6 -6
  453. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  454. package/dist/hooks/gmail-watcher.js +11 -6
  455. package/dist/hooks/internal-hooks.js +11 -1
  456. package/dist/hooks/llm-slug-generator.js +4 -1
  457. package/dist/hooks/workspace.js +47 -17
  458. package/dist/imessage/accounts.js +9 -20
  459. package/dist/imessage/monitor/inbound-processing.js +2 -1
  460. package/dist/infra/archive-path.js +49 -0
  461. package/dist/infra/archive.js +174 -73
  462. package/dist/infra/control-ui-assets.js +14 -6
  463. package/dist/infra/device-pairing.js +204 -144
  464. package/dist/infra/env.js +10 -5
  465. package/dist/infra/exec-approvals-allowlist.js +141 -70
  466. package/dist/infra/exec-approvals-analysis.js +78 -20
  467. package/dist/infra/exec-approvals.js +5 -17
  468. package/dist/infra/exec-safe-bin-policy.js +277 -0
  469. package/dist/infra/fixed-window-rate-limit.js +33 -0
  470. package/dist/infra/fs-safe.js +71 -39
  471. package/dist/infra/gateway-lock.js +6 -2
  472. package/dist/infra/git-root.js +61 -0
  473. package/dist/infra/heartbeat-active-hours.js +2 -2
  474. package/dist/infra/heartbeat-reason.js +40 -0
  475. package/dist/infra/heartbeat-runner.js +72 -32
  476. package/dist/infra/heartbeat-wake.js +6 -12
  477. package/dist/infra/host-env-security-policy.json +19 -0
  478. package/dist/infra/host-env-security.js +66 -0
  479. package/dist/infra/install-source-utils.js +91 -7
  480. package/dist/infra/net/ssrf.js +131 -38
  481. package/dist/infra/node-pairing.js +50 -105
  482. package/dist/infra/npm-integrity.js +45 -0
  483. package/dist/infra/npm-pack-install.js +40 -0
  484. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  485. package/dist/infra/outbound/channel-adapters.js +20 -7
  486. package/dist/infra/outbound/channel-selection.js +12 -6
  487. package/dist/infra/outbound/envelope.js +1 -1
  488. package/dist/infra/outbound/format.js +12 -6
  489. package/dist/infra/outbound/message-action-runner.js +107 -327
  490. package/dist/infra/outbound/message.js +59 -36
  491. package/dist/infra/outbound/outbound-policy.js +52 -25
  492. package/dist/infra/outbound/outbound-send-service.js +58 -71
  493. package/dist/infra/outbound/payloads.js +14 -7
  494. package/dist/infra/outbound/session-binding-service.js +123 -0
  495. package/dist/infra/pairing-files.js +10 -0
  496. package/dist/infra/path-guards.js +25 -0
  497. package/dist/infra/plain-object.js +9 -0
  498. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  499. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  500. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  501. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  502. package/dist/infra/push-apns.js +365 -0
  503. package/dist/infra/restart-sentinel.js +16 -1
  504. package/dist/infra/restart.js +229 -26
  505. package/dist/infra/retry-policy.js +4 -2
  506. package/dist/infra/retry.js +9 -5
  507. package/dist/infra/scp-host.js +54 -0
  508. package/dist/infra/session-cost-usage.js +107 -59
  509. package/dist/infra/session-maintenance-warning.js +3 -1
  510. package/dist/infra/shell-env.js +98 -34
  511. package/dist/infra/ssh-config.js +12 -6
  512. package/dist/infra/system-run-command.js +49 -4
  513. package/dist/infra/update-channels.js +10 -5
  514. package/dist/infra/update-startup.js +86 -9
  515. package/dist/line/accounts.js +5 -7
  516. package/dist/line/bot-access.js +8 -20
  517. package/dist/line/bot-handlers.js +3 -1
  518. package/dist/link-understanding/detect.js +15 -7
  519. package/dist/media/constants.js +15 -6
  520. package/dist/media/image-ops.js +7 -0
  521. package/dist/media/inbound-path-policy.js +114 -0
  522. package/dist/media/input-files.js +16 -0
  523. package/dist/media/local-roots.js +3 -2
  524. package/dist/media-understanding/apply.js +4 -1
  525. package/dist/media-understanding/concurrency.js +8 -20
  526. package/dist/memory/backend-config.js +45 -6
  527. package/dist/memory/embeddings.js +10 -4
  528. package/dist/memory/fs-utils.js +23 -0
  529. package/dist/memory/manager-search.js +12 -6
  530. package/dist/memory/manager-sync-ops.js +12 -2
  531. package/dist/memory/qmd-manager.js +466 -53
  532. package/dist/memory/query-expansion.js +167 -3
  533. package/dist/memory/status-format.js +10 -5
  534. package/dist/memory/sync-memory-files.js +1 -1
  535. package/dist/memory/test-manager.js +8 -0
  536. package/dist/node-host/invoke-system-run.js +281 -0
  537. package/dist/node-host/invoke.js +55 -337
  538. package/dist/pairing/pairing-store.js +22 -0
  539. package/dist/plugin-sdk/allow-from.js +1 -1
  540. package/dist/plugin-sdk/command-auth.js +3 -1
  541. package/dist/plugin-sdk/index.js +6 -3
  542. package/dist/plugin-sdk/temp-path.js +47 -0
  543. package/dist/plugin-sdk/webhook-targets.js +32 -0
  544. package/dist/plugins/bundled-dir.js +9 -6
  545. package/dist/plugins/discovery.js +217 -23
  546. package/dist/plugins/hook-runner-global.js +16 -0
  547. package/dist/plugins/hooks.js +50 -0
  548. package/dist/plugins/install.js +28 -16
  549. package/dist/plugins/loader.js +192 -26
  550. package/dist/plugins/logger.js +8 -0
  551. package/dist/plugins/manifest-registry.js +3 -0
  552. package/dist/plugins/path-safety.js +34 -0
  553. package/dist/plugins/registry.js +5 -2
  554. package/dist/plugins/runtime/index.js +271 -206
  555. package/dist/plugins/runtime.js +3 -17
  556. package/dist/plugins/update.js +78 -12
  557. package/dist/process/spawn-utils.js +14 -7
  558. package/dist/providers/github-copilot-models.js +4 -1
  559. package/dist/providers/github-copilot-token.js +11 -6
  560. package/dist/providers/qwen-portal-oauth.js +14 -6
  561. package/dist/routing/account-id.js +30 -0
  562. package/dist/routing/resolve-route.js +3 -7
  563. package/dist/routing/session-key.js +2 -16
  564. package/dist/security/audit-channel.js +100 -20
  565. package/dist/security/audit-extra.async.js +505 -179
  566. package/dist/security/audit-extra.js +12 -2
  567. package/dist/security/audit-extra.sync.js +421 -35
  568. package/dist/security/audit-fs.js +31 -13
  569. package/dist/security/audit.js +180 -370
  570. package/dist/security/dm-policy-shared.js +68 -0
  571. package/dist/security/external-content.js +46 -14
  572. package/dist/security/fix.js +49 -85
  573. package/dist/security/scan-paths.js +20 -0
  574. package/dist/security/secret-equal.js +3 -7
  575. package/dist/security/windows-acl.js +30 -15
  576. package/dist/shared/entry-status.js +6 -0
  577. package/dist/shared/frontmatter.js +5 -5
  578. package/dist/shared/node-list-parse.js +13 -0
  579. package/dist/shared/node-match.js +11 -4
  580. package/dist/shared/operator-scope-compat.js +42 -0
  581. package/dist/shared/text-chunking.js +29 -0
  582. package/dist/signal/accounts.js +7 -20
  583. package/dist/signal/monitor/event-handler.js +3 -1
  584. package/dist/slack/accounts.js +6 -19
  585. package/dist/slack/actions.js +11 -3
  586. package/dist/slack/blocks.test-helpers.js +31 -0
  587. package/dist/slack/monitor/auth.js +1 -1
  588. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  589. package/dist/slack/monitor/mrkdwn.js +8 -0
  590. package/dist/slack/monitor/replies.js +15 -7
  591. package/dist/slack/monitor/slash.js +22 -13
  592. package/dist/slack/resolve-channels.js +10 -5
  593. package/dist/slack/send.js +102 -12
  594. package/dist/slack/stream-mode.js +10 -0
  595. package/dist/slack/streaming.js +4 -2
  596. package/dist/telegram/accounts.js +19 -14
  597. package/dist/telegram/bot/helpers.js +3 -5
  598. package/dist/telegram/bot-access.js +35 -36
  599. package/dist/telegram/bot-handlers.js +120 -148
  600. package/dist/telegram/bot-message-context.js +68 -9
  601. package/dist/telegram/bot-message-dispatch.js +477 -210
  602. package/dist/telegram/bot-native-commands.js +16 -0
  603. package/dist/telegram/draft-stream.js +44 -8
  604. package/dist/telegram/inline-buttons.js +5 -15
  605. package/dist/telegram/monitor.js +11 -7
  606. package/dist/telegram/network-config.js +19 -7
  607. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  608. package/dist/telegram/send.js +3 -2
  609. package/dist/telegram/sent-message-cache.js +5 -6
  610. package/dist/telegram/status-reaction-variants.js +208 -0
  611. package/dist/telegram/sticker-cache.js +11 -9
  612. package/dist/terminal/prompt-select-styled.js +9 -0
  613. package/dist/terminal/theme.js +12 -12
  614. package/dist/test-utils/command-runner.js +6 -0
  615. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  616. package/dist/test-utils/model-auth-mock.js +12 -0
  617. package/dist/test-utils/provider-usage-fetch.js +14 -0
  618. package/dist/test-utils/temp-home.js +33 -0
  619. package/dist/tts/tts.js +80 -567
  620. package/dist/tui/components/chat-log.js +50 -8
  621. package/dist/tui/theme/theme.js +10 -12
  622. package/dist/tui/tui-command-handlers.js +36 -27
  623. package/dist/tui/tui-event-handlers.js +122 -32
  624. package/dist/tui/tui-local-shell.js +16 -6
  625. package/dist/tui/tui.js +236 -48
  626. package/dist/utils/account-id.js +2 -4
  627. package/dist/utils/boolean.js +10 -5
  628. package/dist/utils/directive-tags.js +11 -0
  629. package/dist/utils/mask-api-key.js +10 -0
  630. package/dist/utils/queue-helpers.js +67 -12
  631. package/dist/utils/run-with-concurrency.js +39 -0
  632. package/dist/web/auto-reply/deliver-reply.js +8 -4
  633. package/dist/web/auto-reply/mentions.js +10 -5
  634. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  635. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  636. package/dist/web/inbound/access-control.js +5 -2
  637. package/dist/web/login-qr.js +12 -6
  638. package/dist/web/media.js +126 -15
  639. package/docs/tools/slash-commands.md +5 -1
  640. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  641. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  642. package/extensions/feishu/src/external-keys.ts +19 -0
  643. package/extensions/lobster/src/windows-spawn.ts +193 -0
  644. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  645. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  646. package/package.json +1 -1
@@ -113,7 +113,7 @@ export const FIELD_LABELS = {
113
113
  "gateway.controlUi.basePath": "Control UI Base Path",
114
114
  "gateway.controlUi.root": "Control UI Assets Root",
115
115
  "gateway.controlUi.allowedOrigins": "Control UI Allowed Origins",
116
- "gateway.controlUi.allowInsecureAuth": "Allow Insecure Control UI Auth",
116
+ "gateway.controlUi.allowInsecureAuth": "Insecure Control UI Auth Toggle",
117
117
  "gateway.controlUi.dangerouslyDisableDeviceAuth": "Dangerously Disable Control UI Device Auth",
118
118
  "gateway.http.endpoints.chatCompletions.enabled": "OpenAI Chat Completions Endpoint",
119
119
  "gateway.reload.mode": "Config Reload Mode",
@@ -163,6 +163,10 @@ export const FIELD_LABELS = {
163
163
  "agents.defaults.memorySearch.query.hybrid.vectorWeight": "Memory Search Vector Weight",
164
164
  "agents.defaults.memorySearch.query.hybrid.textWeight": "Memory Search Text Weight",
165
165
  "agents.defaults.memorySearch.query.hybrid.candidateMultiplier": "Memory Search Hybrid Candidate Multiplier",
166
+ "agents.defaults.memorySearch.query.hybrid.mmr.enabled": "Memory Search MMR Re-ranking",
167
+ "agents.defaults.memorySearch.query.hybrid.mmr.lambda": "Memory Search MMR Lambda",
168
+ "agents.defaults.memorySearch.query.hybrid.temporalDecay.enabled": "Memory Search Temporal Decay",
169
+ "agents.defaults.memorySearch.query.hybrid.temporalDecay.halfLifeDays": "Memory Search Temporal Decay Half-life (Days)",
166
170
  "agents.defaults.memorySearch.cache.enabled": "Memory Search Embedding Cache",
167
171
  "agents.defaults.memorySearch.cache.maxEntries": "Memory Search Embedding Cache Max Entries",
168
172
  memory: "Memory",
@@ -216,19 +220,31 @@ export const FIELD_LABELS = {
216
220
  "commands.restart": "Allow Restart",
217
221
  "commands.useAccessGroups": "Use Access Groups",
218
222
  "commands.ownerAllowFrom": "Command Owners",
223
+ "commands.ownerDisplay": "Owner ID Display",
224
+ "commands.ownerDisplaySecret": "Owner ID Hash Secret",
219
225
  "ui.seamColor": "Accent Color",
220
226
  "ui.assistant.name": "Assistant Name",
221
227
  "ui.assistant.avatar": "Assistant Avatar",
222
228
  "browser.evaluateEnabled": "Browser Evaluate Enabled",
223
229
  "browser.snapshotDefaults": "Browser Snapshot Defaults",
224
230
  "browser.snapshotDefaults.mode": "Browser Snapshot Mode",
231
+ "browser.ssrfPolicy": "Browser SSRF Policy",
232
+ "browser.ssrfPolicy.allowPrivateNetwork": "Browser Allow Private Network",
233
+ "browser.ssrfPolicy.allowedHostnames": "Browser Allowed Hostnames",
234
+ "browser.ssrfPolicy.hostnameAllowlist": "Browser Hostname Allowlist",
225
235
  "browser.remoteCdpTimeoutMs": "Remote CDP Timeout (ms)",
226
236
  "browser.remoteCdpHandshakeTimeoutMs": "Remote CDP Handshake Timeout (ms)",
227
237
  "session.dmScope": "DM Session Scope",
238
+ "session.threadBindings.enabled": "Thread Binding Enabled",
239
+ "session.threadBindings.ttlHours": "Thread Binding TTL (hours)",
228
240
  "session.agentToAgent.maxPingPongTurns": "Agent-to-Agent Ping-Pong Turns",
229
241
  "messages.suppressToolErrors": "Suppress Tool Error Warnings",
230
242
  "messages.ackReaction": "Ack Reaction Emoji",
231
243
  "messages.ackReactionScope": "Ack Reaction Scope",
244
+ "messages.statusReactions": "Status Reactions",
245
+ "messages.statusReactions.enabled": "Enable Status Reactions",
246
+ "messages.statusReactions.emojis": "Status Reaction Emojis",
247
+ "messages.statusReactions.timing": "Status Reaction Timing",
232
248
  "messages.inbound.debounceMs": "Inbound Message Debounce (ms)",
233
249
  "talk.apiKey": "Talk API Key",
234
250
  "channels.whatsapp": "WhatsApp",
@@ -241,13 +257,11 @@ export const FIELD_LABELS = {
241
257
  "channels.imessage": "iMessage",
242
258
  "channels.bluebubbles": "BlueBubbles",
243
259
  "channels.msteams": "MS Teams",
260
+ "channels.modelByChannel": "Channel Model Overrides",
244
261
  ...IRC_FIELD_LABELS,
245
262
  "channels.telegram.botToken": "Telegram Bot Token",
246
263
  "channels.telegram.dmPolicy": "Telegram DM Policy",
247
- "channels.telegram.streamMode": "Telegram Stream Mode",
248
- "channels.telegram.draftChunk.minChars": "Telegram Draft Chunk Min Chars",
249
- "channels.telegram.draftChunk.maxChars": "Telegram Draft Chunk Max Chars",
250
- "channels.telegram.draftChunk.breakPreference": "Telegram Draft Chunk Break Preference",
264
+ "channels.telegram.streaming": "Telegram Streaming Mode",
251
265
  "channels.telegram.retry.attempts": "Telegram Retry Attempts",
252
266
  "channels.telegram.retry.minDelayMs": "Telegram Retry Min Delay (ms)",
253
267
  "channels.telegram.retry.maxDelayMs": "Telegram Retry Max Delay (ms)",
@@ -263,14 +277,24 @@ export const FIELD_LABELS = {
263
277
  "channels.bluebubbles.dmPolicy": "BlueBubbles DM Policy",
264
278
  "channels.discord.dmPolicy": "Discord DM Policy",
265
279
  "channels.discord.dm.policy": "Discord DM Policy",
280
+ "channels.discord.streaming": "Discord Streaming Mode",
281
+ "channels.discord.streamMode": "Discord Stream Mode (Legacy)",
282
+ "channels.discord.draftChunk.minChars": "Discord Draft Chunk Min Chars",
283
+ "channels.discord.draftChunk.maxChars": "Discord Draft Chunk Max Chars",
284
+ "channels.discord.draftChunk.breakPreference": "Discord Draft Chunk Break Preference",
266
285
  "channels.discord.retry.attempts": "Discord Retry Attempts",
267
286
  "channels.discord.retry.minDelayMs": "Discord Retry Min Delay (ms)",
268
287
  "channels.discord.retry.maxDelayMs": "Discord Retry Max Delay (ms)",
269
288
  "channels.discord.retry.jitter": "Discord Retry Jitter",
270
289
  "channels.discord.maxLinesPerMessage": "Discord Max Lines Per Message",
290
+ "channels.discord.threadBindings.enabled": "Discord Thread Binding Enabled",
291
+ "channels.discord.threadBindings.ttlHours": "Discord Thread Binding TTL (hours)",
292
+ "channels.discord.threadBindings.spawnSubagentSessions": "Discord Thread-Bound Subagent Spawn",
271
293
  "channels.discord.ui.components.accentColor": "Discord Component Accent Color",
272
294
  "channels.discord.intents.presence": "Discord Presence Intent",
273
295
  "channels.discord.intents.guildMembers": "Discord Guild Members Intent",
296
+ "channels.discord.voice.enabled": "Discord Voice Enabled",
297
+ "channels.discord.voice.autoJoin": "Discord Voice Auto-Join",
274
298
  "channels.discord.pluralkit.enabled": "Discord PluralKit Enabled",
275
299
  "channels.discord.pluralkit.token": "Discord PluralKit Token",
276
300
  "channels.discord.activity": "Discord Presence Activity",
@@ -285,7 +309,9 @@ export const FIELD_LABELS = {
285
309
  "channels.slack.appToken": "Slack App Token",
286
310
  "channels.slack.userToken": "Slack User Token",
287
311
  "channels.slack.userTokenReadOnly": "Slack User Token Read Only",
288
- "channels.slack.streamMode": "Slack Stream Mode",
312
+ "channels.slack.streaming": "Slack Streaming Mode",
313
+ "channels.slack.nativeStreaming": "Slack Native Streaming",
314
+ "channels.slack.streamMode": "Slack Stream Mode (Legacy)",
289
315
  "channels.slack.thread.historyScope": "Slack Thread History Scope",
290
316
  "channels.slack.thread.inheritParent": "Slack Thread Parent Inheritance",
291
317
  "channels.slack.thread.initialHistoryLimit": "Slack Thread Initial History Limit",
@@ -314,5 +340,11 @@ export const FIELD_LABELS = {
314
340
  "plugins.installs.*.sourcePath": "Plugin Install Source Path",
315
341
  "plugins.installs.*.installPath": "Plugin Install Path",
316
342
  "plugins.installs.*.version": "Plugin Install Version",
343
+ "plugins.installs.*.resolvedName": "Plugin Resolved Package Name",
344
+ "plugins.installs.*.resolvedVersion": "Plugin Resolved Package Version",
345
+ "plugins.installs.*.resolvedSpec": "Plugin Resolved Package Spec",
346
+ "plugins.installs.*.integrity": "Plugin Resolved Integrity",
347
+ "plugins.installs.*.shasum": "Plugin Resolved Shasum",
348
+ "plugins.installs.*.resolvedAt": "Plugin Resolution Time",
317
349
  "plugins.installs.*.installedAt": "Plugin Install Time",
318
350
  };
@@ -5,9 +5,9 @@ import { loadSessionStore } from "./store.js";
5
5
  * Extract deliveryContext and threadId from a sessionKey.
6
6
  * Supports both :thread: (most channels) and :topic: (Telegram).
7
7
  */
8
- export function extractDeliveryInfo(sessionKey) {
8
+ export function parseSessionThreadInfo(sessionKey) {
9
9
  if (!sessionKey) {
10
- return { deliveryContext: undefined, threadId: undefined };
10
+ return { baseSessionKey: undefined, threadId: undefined };
11
11
  }
12
12
  const topicIndex = sessionKey.lastIndexOf(":topic:");
13
13
  const threadIndex = sessionKey.lastIndexOf(":thread:");
@@ -16,13 +16,20 @@ export function extractDeliveryInfo(sessionKey) {
16
16
  const baseSessionKey = markerIndex === -1 ? sessionKey : sessionKey.slice(0, markerIndex);
17
17
  const threadIdRaw = markerIndex === -1 ? undefined : sessionKey.slice(markerIndex + marker.length);
18
18
  const threadId = threadIdRaw?.trim() || undefined;
19
+ return { baseSessionKey, threadId };
20
+ }
21
+ export function extractDeliveryInfo(sessionKey) {
22
+ const { baseSessionKey, threadId } = parseSessionThreadInfo(sessionKey);
23
+ if (!sessionKey || !baseSessionKey) {
24
+ return { deliveryContext: undefined, threadId };
25
+ }
19
26
  let deliveryContext;
20
27
  try {
21
28
  const cfg = loadConfig();
22
29
  const storePath = resolveStorePath(cfg.session?.store);
23
30
  const store = loadSessionStore(storePath);
24
31
  let entry = store[sessionKey];
25
- if (!entry?.deliveryContext && markerIndex !== -1 && baseSessionKey) {
32
+ if (!entry?.deliveryContext && baseSessionKey !== sessionKey) {
26
33
  entry = store[baseSessionKey];
27
34
  }
28
35
  if (entry?.deliveryContext) {
@@ -1,8 +1,9 @@
1
1
  import { buildAgentMainSessionKey, DEFAULT_AGENT_ID, normalizeAgentId, normalizeMainKey, resolveAgentIdFromSessionKey, } from "../../routing/session-key.js";
2
2
  import { loadConfig } from "../config.js";
3
3
  export function resolveMainSessionKey(cfg) {
4
- if (cfg?.session?.scope === "global")
4
+ if (cfg?.session?.scope === "global") {
5
5
  return "global";
6
+ }
6
7
  const agents = cfg?.agents?.list ?? [];
7
8
  const defaultAgentId = agents.find((agent) => agent?.default)?.id ?? agents[0]?.id ?? DEFAULT_AGENT_ID;
8
9
  const agentId = normalizeAgentId(defaultAgentId);
@@ -19,14 +20,16 @@ export function resolveAgentMainSessionKey(params) {
19
20
  }
20
21
  export function resolveExplicitAgentSessionKey(params) {
21
22
  const agentId = params.agentId?.trim();
22
- if (!agentId)
23
+ if (!agentId) {
23
24
  return undefined;
25
+ }
24
26
  return resolveAgentMainSessionKey({ cfg: params.cfg, agentId });
25
27
  }
26
28
  export function canonicalizeMainSessionAlias(params) {
27
29
  const raw = params.sessionKey.trim();
28
- if (!raw)
30
+ if (!raw) {
29
31
  return raw;
32
+ }
30
33
  const agentId = normalizeAgentId(params.agentId);
31
34
  const mainKey = normalizeMainKey(params.cfg?.session?.mainKey);
32
35
  const agentMainSessionKey = buildAgentMainSessionKey({ agentId, mainKey });
@@ -35,9 +38,11 @@ export function canonicalizeMainSessionAlias(params) {
35
38
  mainKey: "main",
36
39
  });
37
40
  const isMainAlias = raw === "main" || raw === mainKey || raw === agentMainSessionKey || raw === agentMainAliasKey;
38
- if (params.cfg?.session?.scope === "global" && isMainAlias)
41
+ if (params.cfg?.session?.scope === "global" && isMainAlias) {
39
42
  return "global";
40
- if (isMainAlias)
43
+ }
44
+ if (isMainAlias) {
41
45
  return agentMainSessionKey;
46
+ }
42
47
  return raw;
43
48
  }
@@ -0,0 +1,33 @@
1
+ import { resolveSessionFilePath } from "./paths.js";
2
+ import { updateSessionStore } from "./store.js";
3
+ export async function resolveAndPersistSessionFile(params) {
4
+ const { sessionId, sessionKey, sessionStore, storePath } = params;
5
+ const baseEntry = params.sessionEntry ??
6
+ sessionStore[sessionKey] ?? { sessionId, updatedAt: Date.now() };
7
+ const fallbackSessionFile = params.fallbackSessionFile?.trim();
8
+ const entryForResolve = !baseEntry.sessionFile && fallbackSessionFile
9
+ ? { ...baseEntry, sessionFile: fallbackSessionFile }
10
+ : baseEntry;
11
+ const sessionFile = resolveSessionFilePath(sessionId, entryForResolve, {
12
+ agentId: params.agentId,
13
+ sessionsDir: params.sessionsDir,
14
+ });
15
+ const persistedEntry = {
16
+ ...baseEntry,
17
+ sessionId,
18
+ updatedAt: Date.now(),
19
+ sessionFile,
20
+ };
21
+ if (baseEntry.sessionId !== sessionId || baseEntry.sessionFile !== sessionFile) {
22
+ sessionStore[sessionKey] = persistedEntry;
23
+ await updateSessionStore(storePath, (store) => {
24
+ store[sessionKey] = {
25
+ ...store[sessionKey],
26
+ ...persistedEntry,
27
+ };
28
+ }, params.activeSessionKey ? { activeSessionKey: params.activeSessionKey } : undefined);
29
+ return { sessionFile, sessionEntry: persistedEntry };
30
+ }
31
+ sessionStore[sessionKey] = persistedEntry;
32
+ return { sessionFile, sessionEntry: persistedEntry };
33
+ }
@@ -3,11 +3,13 @@ import { normalizeE164 } from "../../utils.js";
3
3
  import { resolveGroupSessionKey } from "./group.js";
4
4
  // Decide which session bucket to use (per-sender vs global).
5
5
  export function deriveSessionKey(scope, ctx) {
6
- if (scope === "global")
6
+ if (scope === "global") {
7
7
  return "global";
8
+ }
8
9
  const resolvedGroup = resolveGroupSessionKey(ctx);
9
- if (resolvedGroup)
10
+ if (resolvedGroup) {
10
11
  return resolvedGroup.key;
12
+ }
11
13
  const from = ctx.From ? normalizeE164(ctx.From) : "";
12
14
  return from || "unknown";
13
15
  }
@@ -17,18 +19,21 @@ export function deriveSessionKey(scope, ctx) {
17
19
  */
18
20
  export function resolveSessionKey(scope, ctx, mainKey) {
19
21
  const explicit = ctx.SessionKey?.trim();
20
- if (explicit)
22
+ if (explicit) {
21
23
  return explicit.toLowerCase();
24
+ }
22
25
  const raw = deriveSessionKey(scope, ctx);
23
- if (scope === "global")
26
+ if (scope === "global") {
24
27
  return raw;
28
+ }
25
29
  const canonicalMainKey = normalizeMainKey(mainKey);
26
30
  const canonical = buildAgentMainSessionKey({
27
31
  agentId: DEFAULT_AGENT_ID,
28
32
  mainKey: canonicalMainKey,
29
33
  });
30
34
  const isGroup = raw.includes(":group:") || raw.includes(":channel:");
31
- if (!isGroup)
35
+ if (!isGroup) {
32
36
  return canonical;
37
+ }
33
38
  return `agent:${DEFAULT_AGENT_ID}:${raw}`;
34
39
  }
@@ -472,7 +472,7 @@ async function saveSessionStoreUnlocked(storePath, store, opts) {
472
472
  // Final attempt failed — skip this save. The write lock ensures
473
473
  // the next save will retry with fresh data. Log for diagnostics.
474
474
  if (i === 4) {
475
- console.warn(`[session-store] rename failed after 5 attempts: ${storePath}`);
475
+ log.warn(`rename failed after 5 attempts: ${storePath}`);
476
476
  }
477
477
  }
478
478
  }
@@ -7,4 +7,5 @@ export * from "./sessions/session-key.js";
7
7
  export * from "./sessions/store.js";
8
8
  export * from "./sessions/types.js";
9
9
  export * from "./sessions/transcript.js";
10
+ export * from "./sessions/session-file.js";
10
11
  export * from "./sessions/delivery-info.js";
@@ -4,6 +4,7 @@ import { CHANNEL_IDS, normalizeChatChannelId } from "../channels/registry.js";
4
4
  import { normalizePluginsConfig, resolveEnableState, resolveMemorySlotDecision, } from "../plugins/config-state.js";
5
5
  import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
6
6
  import { validateJsonSchemaValue } from "../plugins/schema-validator.js";
7
+ import { isRecord } from "../utils.js";
7
8
  import { findDuplicateAgentDirs, formatDuplicateAgentDirError } from "./agent-dirs.js";
8
9
  import { applyAgentDefaults, applyModelDefaults, applySessionDefaults } from "./defaults.js";
9
10
  import { findLegacyConfigIssues } from "./legacy.js";
@@ -16,28 +17,35 @@ function isWorkspaceAvatarPath(value, workspaceDir) {
16
17
  const workspaceRoot = path.resolve(workspaceDir);
17
18
  const resolved = path.resolve(workspaceRoot, value);
18
19
  const relative = path.relative(workspaceRoot, resolved);
19
- if (relative === "")
20
+ if (relative === "") {
20
21
  return true;
21
- if (relative.startsWith(".."))
22
+ }
23
+ if (relative.startsWith("..")) {
22
24
  return false;
25
+ }
23
26
  return !path.isAbsolute(relative);
24
27
  }
25
28
  function validateIdentityAvatar(config) {
26
29
  const agents = config.agents?.list;
27
- if (!Array.isArray(agents) || agents.length === 0)
30
+ if (!Array.isArray(agents) || agents.length === 0) {
28
31
  return [];
32
+ }
29
33
  const issues = [];
30
34
  for (const [index, entry] of agents.entries()) {
31
- if (!entry || typeof entry !== "object")
35
+ if (!entry || typeof entry !== "object") {
32
36
  continue;
37
+ }
33
38
  const avatarRaw = entry.identity?.avatar;
34
- if (typeof avatarRaw !== "string")
39
+ if (typeof avatarRaw !== "string") {
35
40
  continue;
41
+ }
36
42
  const avatar = avatarRaw.trim();
37
- if (!avatar)
43
+ if (!avatar) {
38
44
  continue;
39
- if (AVATAR_DATA_RE.test(avatar) || AVATAR_HTTP_RE.test(avatar))
45
+ }
46
+ if (AVATAR_DATA_RE.test(avatar) || AVATAR_HTTP_RE.test(avatar)) {
40
47
  continue;
48
+ }
41
49
  if (avatar.startsWith("~")) {
42
50
  issues.push({
43
51
  path: `agents.list.${index}.identity.avatar`,
@@ -63,7 +71,11 @@ function validateIdentityAvatar(config) {
63
71
  }
64
72
  return issues;
65
73
  }
66
- export function validateConfigObject(raw) {
74
+ /**
75
+ * Validates config without applying runtime defaults.
76
+ * Use this when you need the raw validated config (e.g., for writing back to file).
77
+ */
78
+ export function validateConfigObjectRaw(raw) {
67
79
  const legacyIssues = findLegacyConfigIssues(raw);
68
80
  if (legacyIssues.length > 0) {
69
81
  return {
@@ -102,42 +114,136 @@ export function validateConfigObject(raw) {
102
114
  }
103
115
  return {
104
116
  ok: true,
105
- config: applyModelDefaults(applyAgentDefaults(applySessionDefaults(validated.data))),
117
+ config: validated.data,
106
118
  };
107
119
  }
108
- function isRecord(value) {
109
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
120
+ export function validateConfigObject(raw) {
121
+ const result = validateConfigObjectRaw(raw);
122
+ if (!result.ok) {
123
+ return result;
124
+ }
125
+ return {
126
+ ok: true,
127
+ config: applyModelDefaults(applyAgentDefaults(applySessionDefaults(result.config))),
128
+ };
110
129
  }
111
130
  export function validateConfigObjectWithPlugins(raw) {
112
- const base = validateConfigObject(raw);
131
+ return validateConfigObjectWithPluginsBase(raw, { applyDefaults: true });
132
+ }
133
+ export function validateConfigObjectRawWithPlugins(raw) {
134
+ return validateConfigObjectWithPluginsBase(raw, { applyDefaults: false });
135
+ }
136
+ function validateConfigObjectWithPluginsBase(raw, opts) {
137
+ const base = opts.applyDefaults ? validateConfigObject(raw) : validateConfigObjectRaw(raw);
113
138
  if (!base.ok) {
114
139
  return { ok: false, issues: base.issues, warnings: [] };
115
140
  }
116
141
  const config = base.config;
117
142
  const issues = [];
118
143
  const warnings = [];
119
- const pluginsConfig = config.plugins;
120
- const normalizedPlugins = normalizePluginsConfig(pluginsConfig);
121
- const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
122
- const registry = loadPluginManifestRegistry({
123
- config,
124
- workspaceDir: workspaceDir ?? undefined,
125
- });
126
- const knownIds = new Set(registry.plugins.map((record) => record.id));
127
- for (const diag of registry.diagnostics) {
128
- let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
129
- if (!diag.pluginId && diag.message.includes("plugin path not found")) {
130
- path = "plugins.load.paths";
144
+ const hasExplicitPluginsConfig = isRecord(raw) && Object.prototype.hasOwnProperty.call(raw, "plugins");
145
+ let registryInfo = null;
146
+ const ensureRegistry = () => {
147
+ if (registryInfo) {
148
+ return registryInfo;
149
+ }
150
+ const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
151
+ const registry = loadPluginManifestRegistry({
152
+ config,
153
+ workspaceDir: workspaceDir ?? undefined,
154
+ });
155
+ const knownIds = new Set(registry.plugins.map((record) => record.id));
156
+ const normalizedPlugins = normalizePluginsConfig(config.plugins);
157
+ for (const diag of registry.diagnostics) {
158
+ let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
159
+ if (!diag.pluginId && diag.message.includes("plugin path not found")) {
160
+ path = "plugins.load.paths";
161
+ }
162
+ const pluginLabel = diag.pluginId ? `plugin ${diag.pluginId}` : "plugin";
163
+ const message = `${pluginLabel}: ${diag.message}`;
164
+ if (diag.level === "error") {
165
+ issues.push({ path, message });
166
+ }
167
+ else {
168
+ warnings.push({ path, message });
169
+ }
170
+ }
171
+ registryInfo = { registry, knownIds, normalizedPlugins };
172
+ return registryInfo;
173
+ };
174
+ const allowedChannels = new Set(["defaults", ...CHANNEL_IDS]);
175
+ if (config.channels && isRecord(config.channels)) {
176
+ for (const key of Object.keys(config.channels)) {
177
+ const trimmed = key.trim();
178
+ if (!trimmed) {
179
+ continue;
180
+ }
181
+ if (!allowedChannels.has(trimmed)) {
182
+ const { registry } = ensureRegistry();
183
+ for (const record of registry.plugins) {
184
+ for (const channelId of record.channels) {
185
+ allowedChannels.add(channelId);
186
+ }
187
+ }
188
+ }
189
+ if (!allowedChannels.has(trimmed)) {
190
+ issues.push({
191
+ path: `channels.${trimmed}`,
192
+ message: `unknown channel id: ${trimmed}`,
193
+ });
194
+ }
195
+ }
196
+ }
197
+ const heartbeatChannelIds = new Set();
198
+ for (const channelId of CHANNEL_IDS) {
199
+ heartbeatChannelIds.add(channelId.toLowerCase());
200
+ }
201
+ const validateHeartbeatTarget = (target, path) => {
202
+ if (typeof target !== "string") {
203
+ return;
204
+ }
205
+ const trimmed = target.trim();
206
+ if (!trimmed) {
207
+ issues.push({ path, message: "heartbeat target must not be empty" });
208
+ return;
209
+ }
210
+ const normalized = trimmed.toLowerCase();
211
+ if (normalized === "last" || normalized === "none") {
212
+ return;
213
+ }
214
+ if (normalizeChatChannelId(trimmed)) {
215
+ return;
131
216
  }
132
- const pluginLabel = diag.pluginId ? `plugin ${diag.pluginId}` : "plugin";
133
- const message = `${pluginLabel}: ${diag.message}`;
134
- if (diag.level === "error") {
135
- issues.push({ path, message });
217
+ if (!heartbeatChannelIds.has(normalized)) {
218
+ const { registry } = ensureRegistry();
219
+ for (const record of registry.plugins) {
220
+ for (const channelId of record.channels) {
221
+ const pluginChannel = channelId.trim();
222
+ if (pluginChannel) {
223
+ heartbeatChannelIds.add(pluginChannel.toLowerCase());
224
+ }
225
+ }
226
+ }
136
227
  }
137
- else {
138
- warnings.push({ path, message });
228
+ if (heartbeatChannelIds.has(normalized)) {
229
+ return;
230
+ }
231
+ issues.push({ path, message: `unknown heartbeat target: ${target}` });
232
+ };
233
+ validateHeartbeatTarget(config.agents?.defaults?.heartbeat?.target, "agents.defaults.heartbeat.target");
234
+ if (Array.isArray(config.agents?.list)) {
235
+ for (const [index, entry] of config.agents.list.entries()) {
236
+ validateHeartbeatTarget(entry?.heartbeat?.target, `agents.list.${index}.heartbeat.target`);
139
237
  }
140
238
  }
239
+ if (!hasExplicitPluginsConfig) {
240
+ if (issues.length > 0) {
241
+ return { ok: false, issues, warnings };
242
+ }
243
+ return { ok: true, config, warnings };
244
+ }
245
+ const { registry, knownIds, normalizedPlugins } = ensureRegistry();
246
+ const pluginsConfig = config.plugins;
141
247
  const entries = pluginsConfig?.entries;
142
248
  if (entries && isRecord(entries)) {
143
249
  for (const pluginId of Object.keys(entries)) {
@@ -151,8 +257,9 @@ export function validateConfigObjectWithPlugins(raw) {
151
257
  }
152
258
  const allow = pluginsConfig?.allow ?? [];
153
259
  for (const pluginId of allow) {
154
- if (typeof pluginId !== "string" || !pluginId.trim())
260
+ if (typeof pluginId !== "string" || !pluginId.trim()) {
155
261
  continue;
262
+ }
156
263
  if (!knownIds.has(pluginId)) {
157
264
  issues.push({
158
265
  path: "plugins.allow",
@@ -162,8 +269,9 @@ export function validateConfigObjectWithPlugins(raw) {
162
269
  }
163
270
  const deny = pluginsConfig?.deny ?? [];
164
271
  for (const pluginId of deny) {
165
- if (typeof pluginId !== "string" || !pluginId.trim())
272
+ if (typeof pluginId !== "string" || !pluginId.trim()) {
166
273
  continue;
274
+ }
167
275
  if (!knownIds.has(pluginId)) {
168
276
  issues.push({
169
277
  path: "plugins.deny",
@@ -178,59 +286,6 @@ export function validateConfigObjectWithPlugins(raw) {
178
286
  message: `plugin not found: ${memorySlot}`,
179
287
  });
180
288
  }
181
- const allowedChannels = new Set(["defaults", ...CHANNEL_IDS]);
182
- for (const record of registry.plugins) {
183
- for (const channelId of record.channels) {
184
- allowedChannels.add(channelId);
185
- }
186
- }
187
- if (config.channels && isRecord(config.channels)) {
188
- for (const key of Object.keys(config.channels)) {
189
- const trimmed = key.trim();
190
- if (!trimmed)
191
- continue;
192
- if (!allowedChannels.has(trimmed)) {
193
- issues.push({
194
- path: `channels.${trimmed}`,
195
- message: `unknown channel id: ${trimmed}`,
196
- });
197
- }
198
- }
199
- }
200
- const heartbeatChannelIds = new Set();
201
- for (const channelId of CHANNEL_IDS) {
202
- heartbeatChannelIds.add(channelId.toLowerCase());
203
- }
204
- for (const record of registry.plugins) {
205
- for (const channelId of record.channels) {
206
- const trimmed = channelId.trim();
207
- if (trimmed)
208
- heartbeatChannelIds.add(trimmed.toLowerCase());
209
- }
210
- }
211
- const validateHeartbeatTarget = (target, path) => {
212
- if (typeof target !== "string")
213
- return;
214
- const trimmed = target.trim();
215
- if (!trimmed) {
216
- issues.push({ path, message: "heartbeat target must not be empty" });
217
- return;
218
- }
219
- const normalized = trimmed.toLowerCase();
220
- if (normalized === "last" || normalized === "none")
221
- return;
222
- if (normalizeChatChannelId(trimmed))
223
- return;
224
- if (heartbeatChannelIds.has(normalized))
225
- return;
226
- issues.push({ path, message: `unknown heartbeat target: ${target}` });
227
- };
228
- validateHeartbeatTarget(config.agents?.defaults?.heartbeat?.target, "agents.defaults.heartbeat.target");
229
- if (Array.isArray(config.agents?.list)) {
230
- for (const [index, entry] of config.agents.list.entries()) {
231
- validateHeartbeatTarget(entry?.heartbeat?.target, `agents.list.${index}.heartbeat.target`);
232
- }
233
- }
234
289
  let selectedMemoryPluginId = null;
235
290
  const seenPlugins = new Set();
236
291
  for (const record of registry.plugins) {
@@ -168,7 +168,9 @@ export const SandboxBrowserSchema = z
168
168
  enabled: z.boolean().optional(),
169
169
  image: z.string().optional(),
170
170
  containerPrefix: z.string().optional(),
171
+ network: z.string().optional(),
171
172
  cdpPort: z.number().int().positive().optional(),
173
+ cdpSourceRange: z.string().optional(),
172
174
  vncPort: z.number().int().positive().optional(),
173
175
  noVncPort: z.number().int().positive().optional(),
174
176
  headless: z.boolean().optional(),
@@ -177,6 +179,15 @@ export const SandboxBrowserSchema = z
177
179
  autoStart: z.boolean().optional(),
178
180
  autoStartTimeoutMs: z.number().int().positive().optional(),
179
181
  binds: z.array(z.string()).optional(),
182
+ })
183
+ .superRefine((data, ctx) => {
184
+ if (data.network?.trim().toLowerCase() === "host") {
185
+ ctx.addIssue({
186
+ code: z.ZodIssueCode.custom,
187
+ path: ["network"],
188
+ message: 'Sandbox security: browser network mode "host" is blocked. Use "bridge" or a custom bridge network instead.',
189
+ });
190
+ }
180
191
  })
181
192
  .strict()
182
193
  .optional();