@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
@@ -18,14 +18,17 @@ function resolveBundledPluginSources(params) {
18
18
  const discovery = discoverPoolBotPlugins({ workspaceDir: params.workspaceDir });
19
19
  const bundled = new Map();
20
20
  for (const candidate of discovery.candidates) {
21
- if (candidate.origin !== "bundled")
21
+ if (candidate.origin !== "bundled") {
22
22
  continue;
23
+ }
23
24
  const manifest = loadPluginManifest(candidate.rootDir);
24
- if (!manifest.ok)
25
+ if (!manifest.ok) {
25
26
  continue;
27
+ }
26
28
  const pluginId = manifest.manifest.id;
27
- if (bundled.has(pluginId))
29
+ if (bundled.has(pluginId)) {
28
30
  continue;
31
+ }
29
32
  const npmSpec = candidate.packagePoolbot?.install?.npmSpec?.trim() ||
30
33
  candidate.packageName?.trim() ||
31
34
  undefined;
@@ -38,8 +41,9 @@ function resolveBundledPluginSources(params) {
38
41
  return bundled;
39
42
  }
40
43
  function pathsEqual(left, right) {
41
- if (!left || !right)
44
+ if (!left || !right) {
42
45
  return false;
46
+ }
43
47
  return resolveUserPath(left) === resolveUserPath(right);
44
48
  }
45
49
  function buildLoadPathHelpers(existing) {
@@ -49,16 +53,18 @@ function buildLoadPathHelpers(existing) {
49
53
  let changed = false;
50
54
  const addPath = (value) => {
51
55
  const normalized = resolveUserPath(value);
52
- if (resolved.has(normalized))
56
+ if (resolved.has(normalized)) {
53
57
  return;
58
+ }
54
59
  paths.push(value);
55
60
  resolved.add(normalized);
56
61
  changed = true;
57
62
  };
58
63
  const removePath = (value) => {
59
64
  const normalized = resolveUserPath(value);
60
- if (!resolved.has(normalized))
65
+ if (!resolved.has(normalized)) {
61
66
  return;
67
+ }
62
68
  paths = paths.filter((entry) => resolveUserPath(entry) !== normalized);
63
69
  resolved = resolveSet();
64
70
  changed = true;
@@ -74,6 +80,24 @@ function buildLoadPathHelpers(existing) {
74
80
  },
75
81
  };
76
82
  }
83
+ function createPluginUpdateIntegrityDriftHandler(params) {
84
+ return async (drift) => {
85
+ const payload = {
86
+ pluginId: params.pluginId,
87
+ spec: drift.spec,
88
+ expectedIntegrity: drift.expectedIntegrity,
89
+ actualIntegrity: drift.actualIntegrity,
90
+ resolvedSpec: drift.resolution.resolvedSpec,
91
+ resolvedVersion: drift.resolution.version,
92
+ dryRun: params.dryRun,
93
+ };
94
+ if (params.onIntegrityDrift) {
95
+ return await params.onIntegrityDrift(payload);
96
+ }
97
+ params.logger.warn?.(`Integrity drift for "${params.pluginId}" (${payload.resolvedSpec ?? payload.spec}): expected ${payload.expectedIntegrity}, got ${payload.actualIntegrity}`);
98
+ return true;
99
+ };
100
+ }
77
101
  export async function updateNpmInstalledPlugins(params) {
78
102
  const logger = params.logger ?? {};
79
103
  const installs = params.config.plugins?.installs ?? {};
@@ -115,7 +139,18 @@ export async function updateNpmInstalledPlugins(params) {
115
139
  });
116
140
  continue;
117
141
  }
118
- const installPath = record.installPath ?? resolvePluginInstallDir(pluginId);
142
+ let installPath;
143
+ try {
144
+ installPath = record.installPath ?? resolvePluginInstallDir(pluginId);
145
+ }
146
+ catch (err) {
147
+ outcomes.push({
148
+ pluginId,
149
+ status: "error",
150
+ message: `Invalid install path for "${pluginId}": ${String(err)}`,
151
+ });
152
+ continue;
153
+ }
119
154
  const currentVersion = await readInstalledPackageVersion(installPath);
120
155
  if (params.dryRun) {
121
156
  let probe;
@@ -125,6 +160,13 @@ export async function updateNpmInstalledPlugins(params) {
125
160
  mode: "update",
126
161
  dryRun: true,
127
162
  expectedPluginId: pluginId,
163
+ expectedIntegrity: record.integrity,
164
+ onIntegrityDrift: createPluginUpdateIntegrityDriftHandler({
165
+ pluginId,
166
+ dryRun: true,
167
+ logger,
168
+ onIntegrityDrift: params.onIntegrityDrift,
169
+ }),
128
170
  logger,
129
171
  });
130
172
  }
@@ -172,6 +214,13 @@ export async function updateNpmInstalledPlugins(params) {
172
214
  spec: record.spec,
173
215
  mode: "update",
174
216
  expectedPluginId: pluginId,
217
+ expectedIntegrity: record.integrity,
218
+ onIntegrityDrift: createPluginUpdateIntegrityDriftHandler({
219
+ pluginId,
220
+ dryRun: false,
221
+ logger,
222
+ onIntegrityDrift: params.onIntegrityDrift,
223
+ }),
175
224
  logger,
176
225
  });
177
226
  }
@@ -198,6 +247,12 @@ export async function updateNpmInstalledPlugins(params) {
198
247
  spec: record.spec,
199
248
  installPath: result.targetDir,
200
249
  version: nextVersion,
250
+ resolvedName: result.npmResolution?.name,
251
+ resolvedVersion: result.npmResolution?.version,
252
+ resolvedSpec: result.npmResolution?.resolvedSpec,
253
+ integrity: result.npmResolution?.integrity,
254
+ shasum: result.npmResolution?.shasum,
255
+ resolvedAt: result.npmResolution?.resolvedAt,
201
256
  });
202
257
  changed = true;
203
258
  const currentLabel = currentVersion ?? "unknown";
@@ -241,12 +296,14 @@ export async function syncPluginsForUpdateChannel(params) {
241
296
  if (params.channel === "dev") {
242
297
  for (const [pluginId, record] of Object.entries(installs)) {
243
298
  const bundledInfo = bundled.get(pluginId);
244
- if (!bundledInfo)
299
+ if (!bundledInfo) {
245
300
  continue;
301
+ }
246
302
  loadHelpers.addPath(bundledInfo.localPath);
247
303
  const alreadyBundled = record.source === "path" && pathsEqual(record.sourcePath, bundledInfo.localPath);
248
- if (alreadyBundled)
304
+ if (alreadyBundled) {
249
305
  continue;
306
+ }
250
307
  next = recordPluginInstall(next, {
251
308
  pluginId,
252
309
  source: "path",
@@ -262,16 +319,19 @@ export async function syncPluginsForUpdateChannel(params) {
262
319
  else {
263
320
  for (const [pluginId, record] of Object.entries(installs)) {
264
321
  const bundledInfo = bundled.get(pluginId);
265
- if (!bundledInfo)
322
+ if (!bundledInfo) {
266
323
  continue;
324
+ }
267
325
  if (record.source === "npm") {
268
326
  loadHelpers.removePath(bundledInfo.localPath);
269
327
  continue;
270
328
  }
271
- if (record.source !== "path")
329
+ if (record.source !== "path") {
272
330
  continue;
273
- if (!pathsEqual(record.sourcePath, bundledInfo.localPath))
331
+ }
332
+ if (!pathsEqual(record.sourcePath, bundledInfo.localPath)) {
274
333
  continue;
334
+ }
275
335
  const spec = record.spec ?? bundledInfo.npmSpec;
276
336
  if (!spec) {
277
337
  summary.warnings.push(`Missing npm spec for ${pluginId}; keeping local path.`);
@@ -300,6 +360,12 @@ export async function syncPluginsForUpdateChannel(params) {
300
360
  spec,
301
361
  installPath: result.targetDir,
302
362
  version: result.version,
363
+ resolvedName: result.npmResolution?.name,
364
+ resolvedVersion: result.npmResolution?.version,
365
+ resolvedSpec: result.npmResolution?.resolvedSpec,
366
+ integrity: result.npmResolution?.integrity,
367
+ shasum: result.npmResolution?.shasum,
368
+ resolvedAt: result.npmResolution?.resolvedAt,
303
369
  sourcePath: undefined,
304
370
  });
305
371
  summary.switchedToNpm.push(pluginId);
@@ -5,19 +5,24 @@ export function resolveCommandStdio(params) {
5
5
  return [stdin, "pipe", "pipe"];
6
6
  }
7
7
  export function formatSpawnError(err) {
8
- if (!(err instanceof Error))
8
+ if (!(err instanceof Error)) {
9
9
  return String(err);
10
+ }
10
11
  const details = err;
11
12
  const parts = [];
12
13
  const message = err.message?.trim();
13
- if (message)
14
+ if (message) {
14
15
  parts.push(message);
15
- if (details.code && !message?.includes(details.code))
16
+ }
17
+ if (details.code && !message?.includes(details.code)) {
16
18
  parts.push(details.code);
17
- if (details.syscall)
19
+ }
20
+ if (details.syscall) {
18
21
  parts.push(`syscall=${details.syscall}`);
19
- if (typeof details.errno === "number")
22
+ }
23
+ if (typeof details.errno === "number") {
20
24
  parts.push(`errno=${details.errno}`);
25
+ }
21
26
  return parts.join(" ");
22
27
  }
23
28
  function shouldRetry(err, codes) {
@@ -33,15 +38,17 @@ async function spawnAndWaitForSpawn(spawnImpl, argv, options) {
33
38
  child.removeListener("spawn", onSpawn);
34
39
  };
35
40
  const finishResolve = () => {
36
- if (settled)
41
+ if (settled) {
37
42
  return;
43
+ }
38
44
  settled = true;
39
45
  cleanup();
40
46
  resolve(child);
41
47
  };
42
48
  const onError = (err) => {
43
- if (settled)
49
+ if (settled) {
44
50
  return;
51
+ }
45
52
  settled = true;
46
53
  cleanup();
47
54
  reject(err);
@@ -4,6 +4,8 @@ const DEFAULT_MAX_TOKENS = 8192;
4
4
  // We keep this list intentionally broad; if a model isn't available Copilot will
5
5
  // return an error and users can remove it from their config.
6
6
  const DEFAULT_MODEL_IDS = [
7
+ "claude-sonnet-4.6",
8
+ "claude-sonnet-4.5",
7
9
  "gpt-4o",
8
10
  "gpt-4.1",
9
11
  "gpt-4.1-mini",
@@ -17,8 +19,9 @@ export function getDefaultCopilotModelIds() {
17
19
  }
18
20
  export function buildCopilotModelDefinition(modelId) {
19
21
  const id = modelId.trim();
20
- if (!id)
22
+ if (!id) {
21
23
  throw new Error("Model id required");
24
+ }
22
25
  return {
23
26
  id,
24
27
  name: id,
@@ -39,25 +39,30 @@ function parseCopilotTokenResponse(value) {
39
39
  export const DEFAULT_COPILOT_API_BASE_URL = "https://api.individual.githubcopilot.com";
40
40
  export function deriveCopilotApiBaseUrlFromToken(token) {
41
41
  const trimmed = token.trim();
42
- if (!trimmed)
42
+ if (!trimmed) {
43
43
  return null;
44
+ }
44
45
  // The token returned from the Copilot token endpoint is a semicolon-delimited
45
46
  // set of key/value pairs. One of them is `proxy-ep=...`.
46
47
  const match = trimmed.match(/(?:^|;)\s*proxy-ep=([^;\s]+)/i);
47
48
  const proxyEp = match?.[1]?.trim();
48
- if (!proxyEp)
49
+ if (!proxyEp) {
49
50
  return null;
51
+ }
50
52
  // pi-ai expects converting proxy.* -> api.*
51
53
  // (see upstream getGitHubCopilotBaseUrl).
52
54
  const host = proxyEp.replace(/^https?:\/\//, "").replace(/^proxy\./i, "api.");
53
- if (!host)
55
+ if (!host) {
54
56
  return null;
57
+ }
55
58
  return `https://${host}`;
56
59
  }
57
60
  export async function resolveCopilotApiToken(params) {
58
61
  const env = params.env ?? process.env;
59
- const cachePath = resolveCopilotTokenCachePath(env);
60
- const cached = loadJsonFile(cachePath);
62
+ const cachePath = params.cachePath?.trim() || resolveCopilotTokenCachePath(env);
63
+ const loadJsonFileFn = params.loadJsonFileImpl ?? loadJsonFile;
64
+ const saveJsonFileFn = params.saveJsonFileImpl ?? saveJsonFile;
65
+ const cached = loadJsonFileFn(cachePath);
61
66
  if (cached && typeof cached.token === "string" && typeof cached.expiresAt === "number") {
62
67
  if (isTokenUsable(cached)) {
63
68
  return {
@@ -85,7 +90,7 @@ export async function resolveCopilotApiToken(params) {
85
90
  expiresAt: json.expiresAt,
86
91
  updatedAt: Date.now(),
87
92
  };
88
- saveJsonFile(cachePath, payload);
93
+ saveJsonFileFn(cachePath, payload);
89
94
  return {
90
95
  token: payload.token,
91
96
  expiresAt: payload.expiresAt,
@@ -3,7 +3,8 @@ const QWEN_OAUTH_BASE_URL = "https://chat.qwen.ai";
3
3
  const QWEN_OAUTH_TOKEN_ENDPOINT = `${QWEN_OAUTH_BASE_URL}/api/v1/oauth2/token`;
4
4
  const QWEN_OAUTH_CLIENT_ID = "f0304373b74a44d2b584a3fb70ca9e56";
5
5
  export async function refreshQwenPortalCredentials(credentials) {
6
- if (!credentials.refresh?.trim()) {
6
+ const refreshToken = credentials.refresh?.trim();
7
+ if (!refreshToken) {
7
8
  throw new Error("Qwen OAuth refresh token missing; re-authenticate.");
8
9
  }
9
10
  const response = await fetch(QWEN_OAUTH_TOKEN_ENDPOINT, {
@@ -14,7 +15,7 @@ export async function refreshQwenPortalCredentials(credentials) {
14
15
  },
15
16
  body: new URLSearchParams({
16
17
  grant_type: "refresh_token",
17
- refresh_token: credentials.refresh,
18
+ refresh_token: refreshToken,
18
19
  client_id: QWEN_OAUTH_CLIENT_ID,
19
20
  }),
20
21
  });
@@ -26,13 +27,20 @@ export async function refreshQwenPortalCredentials(credentials) {
26
27
  throw new Error(`Qwen OAuth refresh failed: ${text || response.statusText}`);
27
28
  }
28
29
  const payload = (await response.json());
29
- if (!payload.access_token || !payload.expires_in) {
30
+ const accessToken = payload.access_token?.trim();
31
+ const newRefreshToken = payload.refresh_token?.trim();
32
+ const expiresIn = payload.expires_in;
33
+ if (!accessToken) {
30
34
  throw new Error("Qwen OAuth refresh response missing access token.");
31
35
  }
36
+ if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
37
+ throw new Error("Qwen OAuth refresh response missing or invalid expires_in.");
38
+ }
32
39
  return {
33
40
  ...credentials,
34
- access: payload.access_token,
35
- refresh: payload.refresh_token || credentials.refresh,
36
- expires: Date.now() + payload.expires_in * 1000,
41
+ access: accessToken,
42
+ // RFC 6749 section 6: new refresh token is optional; if present, replace old.
43
+ refresh: newRefreshToken || refreshToken,
44
+ expires: Date.now() + expiresIn * 1000,
37
45
  };
38
46
  }
@@ -0,0 +1,30 @@
1
+ export const DEFAULT_ACCOUNT_ID = "default";
2
+ const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
3
+ const INVALID_CHARS_RE = /[^a-z0-9_-]+/g;
4
+ const LEADING_DASH_RE = /^-+/;
5
+ const TRAILING_DASH_RE = /-+$/;
6
+ function canonicalizeAccountId(value) {
7
+ if (VALID_ID_RE.test(value)) {
8
+ return value.toLowerCase();
9
+ }
10
+ return value
11
+ .toLowerCase()
12
+ .replace(INVALID_CHARS_RE, "-")
13
+ .replace(LEADING_DASH_RE, "")
14
+ .replace(TRAILING_DASH_RE, "")
15
+ .slice(0, 64);
16
+ }
17
+ export function normalizeAccountId(value) {
18
+ const trimmed = (value ?? "").trim();
19
+ if (!trimmed) {
20
+ return DEFAULT_ACCOUNT_ID;
21
+ }
22
+ return canonicalizeAccountId(trimmed) || DEFAULT_ACCOUNT_ID;
23
+ }
24
+ export function normalizeOptionalAccountId(value) {
25
+ const trimmed = (value ?? "").trim();
26
+ if (!trimmed) {
27
+ return undefined;
28
+ }
29
+ return canonicalizeAccountId(trimmed) || undefined;
30
+ }
@@ -3,7 +3,7 @@ import { normalizeChatType } from "../channels/chat-type.js";
3
3
  import { shouldLogVerbose } from "../globals.js";
4
4
  import { logDebug } from "../logger.js";
5
5
  import { listBindings } from "./bindings.js";
6
- import { buildAgentMainSessionKey, buildAgentPeerSessionKey, DEFAULT_ACCOUNT_ID, DEFAULT_MAIN_KEY, normalizeAgentId, sanitizeAgentId, } from "./session-key.js";
6
+ import { buildAgentMainSessionKey, buildAgentPeerSessionKey, DEFAULT_ACCOUNT_ID, DEFAULT_MAIN_KEY, normalizeAccountId as normalizeAccountIdShared, normalizeAgentId, sanitizeAgentId, } from "./session-key.js";
7
7
  export { DEFAULT_ACCOUNT_ID, DEFAULT_AGENT_ID } from "./session-key.js";
8
8
  function normalizeToken(value) {
9
9
  return (value ?? "").trim().toLowerCase();
@@ -17,10 +17,6 @@ function normalizeId(value) {
17
17
  }
18
18
  return "";
19
19
  }
20
- function normalizeAccountId(value) {
21
- const trimmed = (value ?? "").trim();
22
- return trimmed ? trimmed : DEFAULT_ACCOUNT_ID;
23
- }
24
20
  function matchesAccountId(match, actual) {
25
21
  const trimmed = (match ?? "").trim();
26
22
  if (!trimmed) {
@@ -29,7 +25,7 @@ function matchesAccountId(match, actual) {
29
25
  if (trimmed === "*") {
30
26
  return true;
31
27
  }
32
- return trimmed === actual;
28
+ return normalizeAccountIdShared(trimmed) === actual;
33
29
  }
34
30
  export function buildAgentSessionKey(params) {
35
31
  const channel = normalizeToken(params.channel) || "unknown";
@@ -164,7 +160,7 @@ function matchesBindingScope(match, scope) {
164
160
  }
165
161
  export function resolveAgentRoute(input) {
166
162
  const channel = normalizeToken(input.channel);
167
- const accountId = normalizeAccountId(input.accountId);
163
+ const accountId = normalizeAccountIdShared(input.accountId);
168
164
  const peer = input.peer ? { kind: input.peer.kind, id: normalizeId(input.peer.id) } : null;
169
165
  const guildId = normalizeId(input.guildId);
170
166
  const teamId = normalizeId(input.teamId);
@@ -1,8 +1,9 @@
1
1
  import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
2
+ import { normalizeAccountId } from "./account-id.js";
2
3
  export { getSubagentDepth, isCronSessionKey, isAcpSessionKey, isSubagentSessionKey, parseAgentSessionKey, } from "../sessions/session-key-utils.js";
4
+ export { DEFAULT_ACCOUNT_ID, normalizeAccountId, normalizeOptionalAccountId, } from "./account-id.js";
3
5
  export const DEFAULT_AGENT_ID = "main";
4
6
  export const DEFAULT_MAIN_KEY = "main";
5
- export const DEFAULT_ACCOUNT_ID = "default";
6
7
  // Pre-compiled regex
7
8
  const VALID_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
8
9
  const INVALID_CHARS_RE = /[^a-z0-9_-]+/g;
@@ -82,21 +83,6 @@ export function sanitizeAgentId(value) {
82
83
  .replace(TRAILING_DASH_RE, "")
83
84
  .slice(0, 64) || DEFAULT_AGENT_ID);
84
85
  }
85
- export function normalizeAccountId(value) {
86
- const trimmed = (value ?? "").trim();
87
- if (!trimmed) {
88
- return DEFAULT_ACCOUNT_ID;
89
- }
90
- if (VALID_ID_RE.test(trimmed)) {
91
- return trimmed.toLowerCase();
92
- }
93
- return (trimmed
94
- .toLowerCase()
95
- .replace(INVALID_CHARS_RE, "-")
96
- .replace(LEADING_DASH_RE, "")
97
- .replace(TRAILING_DASH_RE, "")
98
- .slice(0, 64) || DEFAULT_ACCOUNT_ID);
99
- }
100
86
  export function buildAgentMainSessionKey(params) {
101
87
  const agentId = normalizeAgentId(params.agentId);
102
88
  const mainKey = normalizeMainKey(params.mainKey);
@@ -3,11 +3,44 @@ import { isNumericTelegramUserId, normalizeTelegramAllowFromEntry, } from "../ch
3
3
  import { formatCliCommand } from "../cli/command-format.js";
4
4
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "../config/commands.js";
5
5
  import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
6
+ import { normalizeStringEntries } from "../shared/string-normalization.js";
7
+ import { resolveDmAllowState } from "./dm-policy-shared.js";
6
8
  function normalizeAllowFromList(list) {
7
- if (!Array.isArray(list)) {
8
- return [];
9
+ return normalizeStringEntries(Array.isArray(list) ? list : undefined);
10
+ }
11
+ const DISCORD_ALLOWLIST_ID_PREFIXES = ["discord:", "user:", "pk:"];
12
+ function isDiscordNameBasedAllowEntry(raw) {
13
+ const text = String(raw).trim();
14
+ if (!text || text === "*") {
15
+ return false;
16
+ }
17
+ const maybeId = text.replace(/^<@!?/, "").replace(/>$/, "");
18
+ if (/^\d+$/.test(maybeId)) {
19
+ return false;
20
+ }
21
+ const prefixed = DISCORD_ALLOWLIST_ID_PREFIXES.find((prefix) => text.startsWith(prefix));
22
+ if (prefixed) {
23
+ const candidate = text.slice(prefixed.length);
24
+ if (candidate) {
25
+ return false;
26
+ }
27
+ }
28
+ return true;
29
+ }
30
+ function addDiscordNameBasedEntries(params) {
31
+ if (!Array.isArray(params.values)) {
32
+ return;
33
+ }
34
+ for (const value of params.values) {
35
+ if (!isDiscordNameBasedAllowEntry(value)) {
36
+ continue;
37
+ }
38
+ const text = String(value).trim();
39
+ if (!text) {
40
+ continue;
41
+ }
42
+ params.target.add(`${params.source}:${text}`);
9
43
  }
10
- return list.map((v) => String(v).trim()).filter(Boolean);
11
44
  }
12
45
  function classifyChannelWarningSeverity(message) {
13
46
  const s = message.toLowerCase();
@@ -40,22 +73,12 @@ export async function collectChannelSecurityFindings(params) {
40
73
  };
41
74
  const warnDmPolicy = async (input) => {
42
75
  const policyPath = input.policyPath ?? `${input.allowFromPath}policy`;
43
- const configAllowFrom = normalizeAllowFromList(input.allowFrom);
44
- const hasWildcard = configAllowFrom.includes("*");
76
+ const { hasWildcard, isMultiUserDm } = await resolveDmAllowState({
77
+ provider: input.provider,
78
+ allowFrom: input.allowFrom,
79
+ normalizeEntry: input.normalizeEntry,
80
+ });
45
81
  const dmScope = params.cfg.session?.dmScope ?? "main";
46
- const storeAllowFrom = await readChannelAllowFromStore(input.provider).catch(() => []);
47
- const normalizeEntry = input.normalizeEntry ?? ((value) => value);
48
- const normalizedCfg = configAllowFrom
49
- .filter((value) => value !== "*")
50
- .map((value) => normalizeEntry(value))
51
- .map((value) => value.trim())
52
- .filter(Boolean);
53
- const normalizedStore = storeAllowFrom
54
- .map((value) => normalizeEntry(value))
55
- .map((value) => value.trim())
56
- .filter(Boolean);
57
- const allowCount = Array.from(new Set([...normalizedCfg, ...normalizedStore])).length;
58
- const isMultiUserDm = hasWildcard || allowCount > 1;
59
82
  if (input.dmPolicy === "open") {
60
83
  const allowFromKey = `${input.allowFromPath}allowFrom`;
61
84
  findings.push({
@@ -119,6 +142,64 @@ export async function collectChannelSecurityFindings(params) {
119
142
  if (plugin.id === "discord") {
120
143
  const discordCfg = account?.config ??
121
144
  {};
145
+ const storeAllowFrom = await readChannelAllowFromStore("discord").catch(() => []);
146
+ const discordNameBasedAllowEntries = new Set();
147
+ addDiscordNameBasedEntries({
148
+ target: discordNameBasedAllowEntries,
149
+ values: discordCfg.allowFrom,
150
+ source: "channels.discord.allowFrom",
151
+ });
152
+ addDiscordNameBasedEntries({
153
+ target: discordNameBasedAllowEntries,
154
+ values: discordCfg.dm?.allowFrom,
155
+ source: "channels.discord.dm.allowFrom",
156
+ });
157
+ addDiscordNameBasedEntries({
158
+ target: discordNameBasedAllowEntries,
159
+ values: storeAllowFrom,
160
+ source: "~/.poolbot/credentials/discord-allowFrom.json",
161
+ });
162
+ const discordGuildEntries = discordCfg.guilds ?? {};
163
+ for (const [guildKey, guildValue] of Object.entries(discordGuildEntries)) {
164
+ if (!guildValue || typeof guildValue !== "object") {
165
+ continue;
166
+ }
167
+ const guild = guildValue;
168
+ addDiscordNameBasedEntries({
169
+ target: discordNameBasedAllowEntries,
170
+ values: guild.users,
171
+ source: `channels.discord.guilds.${guildKey}.users`,
172
+ });
173
+ const channels = guild.channels;
174
+ if (!channels || typeof channels !== "object") {
175
+ continue;
176
+ }
177
+ for (const [channelKey, channelValue] of Object.entries(channels)) {
178
+ if (!channelValue || typeof channelValue !== "object") {
179
+ continue;
180
+ }
181
+ const channel = channelValue;
182
+ addDiscordNameBasedEntries({
183
+ target: discordNameBasedAllowEntries,
184
+ values: channel.users,
185
+ source: `channels.discord.guilds.${guildKey}.channels.${channelKey}.users`,
186
+ });
187
+ }
188
+ }
189
+ if (discordNameBasedAllowEntries.size > 0) {
190
+ const examples = Array.from(discordNameBasedAllowEntries).slice(0, 5);
191
+ const more = discordNameBasedAllowEntries.size > examples.length
192
+ ? ` (+${discordNameBasedAllowEntries.size - examples.length} more)`
193
+ : "";
194
+ findings.push({
195
+ checkId: "channels.discord.allowFrom.name_based_entries",
196
+ severity: "warn",
197
+ title: "Discord allowlist contains name or tag entries",
198
+ detail: "Discord name/tag allowlist matching uses normalized slugs and can collide across users. " +
199
+ `Found: ${examples.join(", ")}${more}.`,
200
+ remediation: "Prefer stable Discord IDs (or <@id>/user:<id>/pk:<id>) in channels.discord.allowFrom and channels.discord.guilds.*.users.",
201
+ });
202
+ }
122
203
  const nativeEnabled = resolveNativeCommandsEnabled({
123
204
  providerId: "discord",
124
205
  providerSetting: coerceNativeSetting(discordCfg.commands?.native),
@@ -133,7 +214,7 @@ export async function collectChannelSecurityFindings(params) {
133
214
  if (slashEnabled) {
134
215
  const defaultGroupPolicy = params.cfg.channels?.defaults?.groupPolicy;
135
216
  const groupPolicy = discordCfg.groupPolicy ?? defaultGroupPolicy ?? "allowlist";
136
- const guildEntries = discordCfg.guilds ?? {};
217
+ const guildEntries = discordGuildEntries;
137
218
  const guildsConfigured = Object.keys(guildEntries).length > 0;
138
219
  const hasAnyUserAllowlist = Object.values(guildEntries).some((guild) => {
139
220
  if (!guild || typeof guild !== "object") {
@@ -157,7 +238,6 @@ export async function collectChannelSecurityFindings(params) {
157
238
  });
158
239
  const dmAllowFromRaw = discordCfg.dm?.allowFrom;
159
240
  const dmAllowFrom = Array.isArray(dmAllowFromRaw) ? dmAllowFromRaw : [];
160
- const storeAllowFrom = await readChannelAllowFromStore("discord").catch(() => []);
161
241
  const ownerAllowFromConfigured = normalizeAllowFromList([...dmAllowFrom, ...storeAllowFrom]).length > 0;
162
242
  const useAccessGroups = params.cfg.commands?.useAccessGroups !== false;
163
243
  if (!useAccessGroups &&