@poolzin/pool-bot 2026.2.21 → 2026.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-catalog.js +40 -9
  14. package/dist/agents/model-forward-compat.js +60 -23
  15. package/dist/agents/model-selection.js +134 -41
  16. package/dist/agents/pi-auth-json.js +2 -2
  17. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  18. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  19. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  20. package/dist/agents/pi-embedded-helpers.js +2 -2
  21. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  22. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  23. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  24. package/dist/agents/pi-embedded-runner/google.js +109 -19
  25. package/dist/agents/pi-embedded-runner/history.js +35 -17
  26. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
  27. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  28. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  29. package/dist/agents/pi-embedded-runner/run.js +193 -25
  30. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  31. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  32. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  33. package/dist/agents/pi-embedded-runner.js +1 -1
  34. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  35. package/dist/agents/pi-embedded-subscribe.js +37 -0
  36. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  37. package/dist/agents/pi-model-discovery.js +9 -2
  38. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  39. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  40. package/dist/agents/pi-tools.js +113 -94
  41. package/dist/agents/pi-tools.read.js +337 -38
  42. package/dist/agents/poolbot-tools.js +14 -5
  43. package/dist/agents/sandbox/docker.js +10 -5
  44. package/dist/agents/sandbox/registry.js +96 -46
  45. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  46. package/dist/agents/sandbox-paths.js +43 -10
  47. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  48. package/dist/agents/session-tool-result-guard.js +39 -39
  49. package/dist/agents/session-transcript-repair.js +36 -33
  50. package/dist/agents/session-write-lock.js +62 -44
  51. package/dist/agents/skills/frontmatter.js +49 -88
  52. package/dist/agents/skills/workspace.js +335 -28
  53. package/dist/agents/subagent-announce.js +508 -174
  54. package/dist/agents/subagent-registry.js +45 -4
  55. package/dist/agents/subagent-spawn.js +16 -33
  56. package/dist/agents/system-prompt-report.js +27 -10
  57. package/dist/agents/system-prompt.js +26 -32
  58. package/dist/agents/tool-call-id.js +69 -17
  59. package/dist/agents/tool-display-common.js +1 -1
  60. package/dist/agents/tool-images.js +64 -31
  61. package/dist/agents/tools/canvas-tool.js +17 -11
  62. package/dist/agents/tools/common.js +37 -19
  63. package/dist/agents/tools/cron-tool.js +40 -38
  64. package/dist/agents/tools/gateway.js +70 -2
  65. package/dist/agents/tools/message-tool.js +181 -40
  66. package/dist/agents/tools/nodes-tool.js +128 -36
  67. package/dist/agents/tools/nodes-utils.js +12 -38
  68. package/dist/agents/tools/session-status-tool.js +24 -71
  69. package/dist/agents/tools/sessions-helpers.js +38 -210
  70. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  71. package/dist/agents/tools/telegram-actions.js +58 -7
  72. package/dist/agents/tools/web-fetch-utils.js +112 -7
  73. package/dist/agents/tools/web-fetch.js +279 -175
  74. package/dist/agents/tools/web-shared.js +71 -8
  75. package/dist/agents/usage.js +25 -16
  76. package/dist/auto-reply/commands-registry.data.js +85 -11
  77. package/dist/auto-reply/dispatch.js +40 -21
  78. package/dist/auto-reply/reply/abort.js +102 -33
  79. package/dist/auto-reply/reply/commands-core.js +82 -33
  80. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  81. package/dist/auto-reply/reply/commands-info.js +41 -12
  82. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  83. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  84. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  85. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  86. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  87. package/dist/auto-reply/reply/mentions.js +18 -11
  88. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  89. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  90. package/dist/auto-reply/reply/session.js +102 -21
  91. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  92. package/dist/auto-reply/status.js +73 -50
  93. package/dist/browser/extension-relay.js +3 -3
  94. package/dist/browser/http-auth.js +1 -1
  95. package/dist/browser/paths.js +2 -2
  96. package/dist/build-info.json +3 -3
  97. package/dist/channels/allowlist-match.js +20 -0
  98. package/dist/channels/allowlists/resolve-utils.js +65 -2
  99. package/dist/channels/chat-type.js +8 -4
  100. package/dist/channels/dock.js +127 -35
  101. package/dist/channels/draft-stream-loop.js +6 -2
  102. package/dist/channels/plugins/actions/telegram.js +42 -18
  103. package/dist/channels/plugins/allowlist-match.js +1 -1
  104. package/dist/channels/plugins/group-mentions.js +51 -41
  105. package/dist/channels/plugins/message-action-names.js +2 -0
  106. package/dist/channels/plugins/message-actions.js +24 -5
  107. package/dist/channels/plugins/normalize/discord.js +26 -4
  108. package/dist/channels/plugins/normalize/signal.js +35 -22
  109. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  110. package/dist/channels/plugins/outbound/imessage.js +15 -14
  111. package/dist/channels/registry.js +20 -7
  112. package/dist/cli/acp-cli.js +7 -5
  113. package/dist/cli/browser-cli-extension.js +25 -12
  114. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  115. package/dist/cli/browser-cli-state.js +101 -145
  116. package/dist/cli/command-options.js +28 -0
  117. package/dist/cli/completion-cli.js +6 -6
  118. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  119. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  120. package/dist/cli/cron-cli/shared.js +7 -1
  121. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  122. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  123. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  124. package/dist/cli/daemon-cli.js +1 -0
  125. package/dist/cli/devices-cli.js +33 -20
  126. package/dist/cli/gateway-cli/register.js +37 -105
  127. package/dist/cli/gateway-cli/run.js +49 -11
  128. package/dist/cli/nodes-camera.js +59 -4
  129. package/dist/cli/nodes-cli/register.camera.js +27 -24
  130. package/dist/cli/nodes-cli/rpc.js +21 -38
  131. package/dist/cli/qr-cli.js +2 -2
  132. package/dist/cli/skills-cli.format.js +2 -2
  133. package/dist/cli/update-cli/progress.js +2 -2
  134. package/dist/cli/update-cli/restart-helper.js +28 -7
  135. package/dist/cli/update-cli/shared.js +7 -7
  136. package/dist/cli/update-cli/status.js +1 -1
  137. package/dist/cli/update-cli/update-command.js +14 -8
  138. package/dist/cli/update-cli/wizard.js +2 -2
  139. package/dist/cli/update-cli.js +21 -1027
  140. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  141. package/dist/commands/channels/add-mutators.js +3 -35
  142. package/dist/commands/channels/add.js +39 -51
  143. package/dist/commands/config-validation.js +1 -1
  144. package/dist/commands/configure.gateway-auth.js +52 -15
  145. package/dist/commands/configure.gateway.js +84 -40
  146. package/dist/commands/doctor-completion.js +3 -3
  147. package/dist/commands/doctor-config-flow.js +536 -16
  148. package/dist/commands/doctor-gateway-services.js +103 -79
  149. package/dist/commands/doctor-memory-search.js +9 -9
  150. package/dist/commands/doctor-platform-notes.js +57 -30
  151. package/dist/commands/doctor-prompter.js +26 -15
  152. package/dist/commands/doctor-session-locks.js +1 -1
  153. package/dist/commands/doctor.js +21 -9
  154. package/dist/commands/model-picker.js +120 -95
  155. package/dist/commands/models/set.js +2 -21
  156. package/dist/commands/models/shared.js +65 -37
  157. package/dist/commands/onboard-helpers.js +81 -39
  158. package/dist/commands/openai-codex-oauth.js +1 -1
  159. package/dist/commands/sessions.js +52 -53
  160. package/dist/commands/status.summary.js +52 -34
  161. package/dist/commands/test-wizard-helpers.js +2 -2
  162. package/dist/config/defaults.js +79 -42
  163. package/dist/config/group-policy.js +50 -18
  164. package/dist/config/includes.js +37 -10
  165. package/dist/config/schema.help.js +5 -4
  166. package/dist/config/schema.hints.js +2 -2
  167. package/dist/config/schema.labels.js +1 -0
  168. package/dist/config/sessions/group.js +12 -11
  169. package/dist/config/sessions/paths.js +137 -11
  170. package/dist/config/sessions/store.js +185 -65
  171. package/dist/config/sessions/types.js +15 -1
  172. package/dist/config/sessions.js +1 -0
  173. package/dist/config/telegram-custom-commands.js +3 -2
  174. package/dist/config/types.js +2 -0
  175. package/dist/config/zod-schema.agent-defaults.js +6 -27
  176. package/dist/config/zod-schema.agent-runtime.js +171 -79
  177. package/dist/config/zod-schema.providers-core.js +138 -65
  178. package/dist/config/zod-schema.session.js +49 -22
  179. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  180. package/dist/cron/isolated-agent/run.js +224 -57
  181. package/dist/cron/normalize.js +48 -45
  182. package/dist/cron/run-log.js +14 -0
  183. package/dist/cron/service/jobs.js +190 -28
  184. package/dist/cron/service/normalize.js +29 -11
  185. package/dist/cron/service/store.js +30 -44
  186. package/dist/cron/service/timer.js +182 -96
  187. package/dist/cron/service.js +3 -0
  188. package/dist/cron/stagger.js +37 -0
  189. package/dist/daemon/inspect.js +132 -92
  190. package/dist/daemon/runtime-paths.js +25 -4
  191. package/dist/daemon/service-audit.js +47 -16
  192. package/dist/discord/accounts.js +23 -20
  193. package/dist/discord/monitor/agent-components.js +1115 -219
  194. package/dist/discord/monitor/allow-list.js +114 -34
  195. package/dist/discord/monitor/listeners.js +204 -97
  196. package/dist/discord/monitor/message-handler.js +21 -10
  197. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  198. package/dist/discord/monitor/message-handler.process.js +384 -123
  199. package/dist/discord/monitor/message-utils.js +86 -23
  200. package/dist/discord/monitor/native-command.js +77 -57
  201. package/dist/discord/monitor/provider.js +122 -117
  202. package/dist/discord/monitor/reply-context.js +20 -16
  203. package/dist/discord/monitor/reply-delivery.js +40 -8
  204. package/dist/discord/monitor/rest-fetch.js +22 -0
  205. package/dist/discord/monitor/threading.js +117 -24
  206. package/dist/discord/send.js +2 -1
  207. package/dist/discord/send.outbound.js +124 -11
  208. package/dist/discord/send.shared.js +112 -72
  209. package/dist/discord/voice-message.js +3 -3
  210. package/dist/gateway/auth.js +119 -44
  211. package/dist/gateway/call.js +76 -34
  212. package/dist/gateway/channel-health-monitor.js +57 -50
  213. package/dist/gateway/client.js +63 -29
  214. package/dist/gateway/control-ui-contract.js +1 -1
  215. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  216. package/dist/gateway/net.js +109 -1
  217. package/dist/gateway/protocol/index.js +5 -8
  218. package/dist/gateway/protocol/schema/agent.js +19 -1
  219. package/dist/gateway/protocol/schema/channels.js +21 -0
  220. package/dist/gateway/protocol/schema/cron.js +43 -30
  221. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  222. package/dist/gateway/protocol/schema/sessions.js +5 -1
  223. package/dist/gateway/protocol/schema.js +0 -1
  224. package/dist/gateway/server/presence-events.js +12 -0
  225. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  226. package/dist/gateway/server/ws-connection.js +58 -21
  227. package/dist/gateway/server-broadcast.js +18 -13
  228. package/dist/gateway/server-cron.js +177 -10
  229. package/dist/gateway/server-methods/agent-job.js +131 -38
  230. package/dist/gateway/server-methods/send.js +60 -14
  231. package/dist/gateway/server-methods/sessions.js +160 -96
  232. package/dist/gateway/server-methods/system.js +5 -7
  233. package/dist/gateway/server-methods-list.js +8 -0
  234. package/dist/gateway/server-methods.js +24 -8
  235. package/dist/gateway/server-node-events.js +278 -68
  236. package/dist/gateway/session-utils.fs.js +316 -75
  237. package/dist/gateway/session-utils.js +224 -70
  238. package/dist/gateway/sessions-patch.js +63 -20
  239. package/dist/gateway/test-temp-config.js +1 -1
  240. package/dist/gateway/tools-invoke-http.js +118 -70
  241. package/dist/gateway/ws-log.js +135 -107
  242. package/dist/hooks/frontmatter.js +36 -82
  243. package/dist/hooks/install.js +149 -139
  244. package/dist/hooks/internal-hooks.js +29 -4
  245. package/dist/hooks/plugin-hooks.js +2 -1
  246. package/dist/imessage/monitor/deliver.js +10 -4
  247. package/dist/imessage/monitor/monitor-provider.js +138 -375
  248. package/dist/imessage/monitor/runtime.js +4 -8
  249. package/dist/imessage/send.js +65 -19
  250. package/dist/infra/exec-approvals-allowlist.js +7 -0
  251. package/dist/infra/exec-approvals.js +35 -920
  252. package/dist/infra/exec-safe-bin-trust.js +64 -0
  253. package/dist/infra/heartbeat-runner.js +207 -134
  254. package/dist/infra/heartbeat-wake.js +183 -22
  255. package/dist/infra/install-source-utils.js +47 -0
  256. package/dist/infra/net/ssrf.js +170 -36
  257. package/dist/infra/outbound/deliver.js +224 -58
  258. package/dist/infra/outbound/message-action-spec.js +12 -5
  259. package/dist/infra/outbound/outbound-session.js +27 -25
  260. package/dist/infra/poolbot-root.js +32 -22
  261. package/dist/infra/ports.js +14 -11
  262. package/dist/infra/skills-remote.js +48 -37
  263. package/dist/infra/system-events.js +25 -11
  264. package/dist/infra/system-presence.js +26 -33
  265. package/dist/infra/tmp-poolbot-dir.js +81 -2
  266. package/dist/infra/wsl.js +37 -1
  267. package/dist/line/bot-message-context.js +163 -191
  268. package/dist/logging/subsystem.js +59 -22
  269. package/dist/markdown/ir.js +124 -50
  270. package/dist/media/store.js +1 -1
  271. package/dist/media-understanding/runner.entries.js +42 -25
  272. package/dist/media-understanding/runner.js +53 -488
  273. package/dist/memory/embeddings-gemini.js +53 -38
  274. package/dist/memory/manager-embedding-ops.js +48 -69
  275. package/dist/pairing/pairing-store.js +178 -119
  276. package/dist/plugin-sdk/index.js +34 -6
  277. package/dist/plugins/hooks.js +135 -14
  278. package/dist/plugins/install.js +190 -152
  279. package/dist/polls.js +11 -0
  280. package/dist/routing/resolve-route.js +190 -56
  281. package/dist/routing/session-key.js +38 -22
  282. package/dist/runtime.js +35 -9
  283. package/dist/security/audit-channel.js +1 -1
  284. package/dist/sessions/session-key-utils.js +29 -11
  285. package/dist/shared/frontmatter.js +5 -5
  286. package/dist/shared/node-list-types.js +1 -0
  287. package/dist/shared/string-normalization.js +15 -0
  288. package/dist/signal/monitor/event-handler.js +68 -36
  289. package/dist/signal/send.js +29 -37
  290. package/dist/slack/monitor/allow-list.js +10 -11
  291. package/dist/slack/monitor/commands.js +14 -3
  292. package/dist/slack/monitor/events/interactions.js +4 -4
  293. package/dist/slack/monitor/media.js +224 -16
  294. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  295. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  296. package/dist/slack/monitor/slash.js +357 -144
  297. package/dist/slack/streaming.js +77 -0
  298. package/dist/telegram/accounts.js +40 -13
  299. package/dist/telegram/allowed-updates.js +3 -0
  300. package/dist/telegram/bot/delivery.js +129 -66
  301. package/dist/telegram/bot/helpers.js +136 -122
  302. package/dist/telegram/bot-handlers.js +600 -339
  303. package/dist/telegram/bot-message-context.js +115 -73
  304. package/dist/telegram/bot-message-dispatch.js +235 -104
  305. package/dist/telegram/bot-native-command-menu.js +3 -1
  306. package/dist/telegram/bot-native-commands.js +213 -193
  307. package/dist/telegram/bot.js +24 -132
  308. package/dist/telegram/draft-stream.js +84 -75
  309. package/dist/telegram/format.js +150 -6
  310. package/dist/telegram/send.js +415 -255
  311. package/dist/telegram/targets.js +21 -2
  312. package/dist/telegram/update-offset-store.js +19 -3
  313. package/dist/terminal/restore.js +5 -2
  314. package/dist/test-utils/fetch-mock.js +5 -0
  315. package/dist/version.js +18 -5
  316. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  317. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  318. package/dist/web/inbound/media.js +34 -8
  319. package/dist/web/inbound/monitor.js +34 -17
  320. package/dist/web/inbound/send-api.js +18 -17
  321. package/dist/web/outbound.js +12 -5
  322. package/dist/wizard/clack-prompter.js +40 -7
  323. package/extensions/bluebubbles/package.json +1 -1
  324. package/extensions/copilot-proxy/package.json +1 -1
  325. package/extensions/diagnostics-otel/package.json +1 -1
  326. package/extensions/discord/package.json +1 -1
  327. package/extensions/feishu/package.json +1 -1
  328. package/extensions/google-antigravity-auth/package.json +1 -1
  329. package/extensions/google-gemini-cli-auth/package.json +1 -1
  330. package/extensions/googlechat/package.json +1 -1
  331. package/extensions/imessage/package.json +1 -1
  332. package/extensions/irc/package.json +1 -1
  333. package/extensions/line/package.json +1 -1
  334. package/extensions/llm-task/package.json +1 -1
  335. package/extensions/lobster/package.json +1 -1
  336. package/extensions/matrix/CHANGELOG.md +5 -0
  337. package/extensions/matrix/package.json +1 -1
  338. package/extensions/mattermost/package.json +1 -1
  339. package/extensions/memory-core/package.json +1 -1
  340. package/extensions/memory-lancedb/package.json +1 -1
  341. package/extensions/minimax-portal-auth/package.json +1 -1
  342. package/extensions/msteams/CHANGELOG.md +5 -0
  343. package/extensions/msteams/package.json +1 -1
  344. package/extensions/nextcloud-talk/package.json +1 -1
  345. package/extensions/nostr/CHANGELOG.md +5 -0
  346. package/extensions/nostr/package.json +1 -1
  347. package/extensions/open-prose/package.json +1 -1
  348. package/extensions/openai-codex-auth/package.json +1 -1
  349. package/extensions/signal/package.json +1 -1
  350. package/extensions/slack/package.json +1 -1
  351. package/extensions/telegram/package.json +1 -1
  352. package/extensions/tlon/package.json +1 -1
  353. package/extensions/twitch/CHANGELOG.md +5 -0
  354. package/extensions/twitch/package.json +1 -1
  355. package/extensions/voice-call/CHANGELOG.md +5 -0
  356. package/extensions/voice-call/package.json +1 -1
  357. package/extensions/whatsapp/package.json +1 -1
  358. package/extensions/zalo/CHANGELOG.md +5 -0
  359. package/extensions/zalo/package.json +1 -1
  360. package/extensions/zalouser/CHANGELOG.md +5 -0
  361. package/extensions/zalouser/package.json +1 -1
  362. package/package.json +1 -1
  363. package/skills/apple-reminders/SKILL.md +100 -49
  364. package/skills/coding-agent/SKILL.md +34 -28
  365. package/skills/github/SKILL.md +131 -16
  366. package/skills/imsg/SKILL.md +112 -15
  367. package/skills/openhue/SKILL.md +101 -19
  368. package/skills/tmux/SKILL.md +111 -79
  369. package/skills/weather/SKILL.md +88 -25
@@ -10,7 +10,7 @@
10
10
  function getHooksForName(registry, hookName) {
11
11
  return registry.typedHooks
12
12
  .filter((h) => h.hookName === hookName)
13
- .sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
13
+ .toSorted((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
14
14
  }
15
15
  /**
16
16
  * Create a hook runner for a specific registry.
@@ -18,14 +18,26 @@ function getHooksForName(registry, hookName) {
18
18
  export function createHookRunner(registry, options = {}) {
19
19
  const logger = options.logger;
20
20
  const catchErrors = options.catchErrors ?? true;
21
+ const mergeBeforeModelResolve = (acc, next) => ({
22
+ // Keep the first defined override so higher-priority hooks win.
23
+ modelOverride: acc?.modelOverride ?? next.modelOverride,
24
+ providerOverride: acc?.providerOverride ?? next.providerOverride,
25
+ });
26
+ const mergeBeforePromptBuild = (acc, next) => ({
27
+ systemPrompt: next.systemPrompt ?? acc?.systemPrompt,
28
+ prependContext: acc?.prependContext && next.prependContext
29
+ ? `${acc.prependContext}\n\n${next.prependContext}`
30
+ : (next.prependContext ?? acc?.prependContext),
31
+ });
21
32
  /**
22
33
  * Run a hook that doesn't return a value (fire-and-forget style).
23
34
  * All handlers are executed in parallel for performance.
24
35
  */
25
36
  async function runVoidHook(hookName, event, ctx) {
26
37
  const hooks = getHooksForName(registry, hookName);
27
- if (hooks.length === 0)
38
+ if (hooks.length === 0) {
28
39
  return;
40
+ }
29
41
  logger?.debug?.(`[hooks] running ${hookName} (${hooks.length} handlers)`);
30
42
  const promises = hooks.map(async (hook) => {
31
43
  try {
@@ -37,7 +49,7 @@ export function createHookRunner(registry, options = {}) {
37
49
  logger?.error(msg);
38
50
  }
39
51
  else {
40
- throw new Error(msg);
52
+ throw new Error(msg, { cause: err });
41
53
  }
42
54
  }
43
55
  });
@@ -49,8 +61,9 @@ export function createHookRunner(registry, options = {}) {
49
61
  */
50
62
  async function runModifyingHook(hookName, event, ctx, mergeResults) {
51
63
  const hooks = getHooksForName(registry, hookName);
52
- if (hooks.length === 0)
64
+ if (hooks.length === 0) {
53
65
  return undefined;
66
+ }
54
67
  logger?.debug?.(`[hooks] running ${hookName} (${hooks.length} handlers, sequential)`);
55
68
  let result;
56
69
  for (const hook of hooks) {
@@ -71,7 +84,7 @@ export function createHookRunner(registry, options = {}) {
71
84
  logger?.error(msg);
72
85
  }
73
86
  else {
74
- throw new Error(msg);
87
+ throw new Error(msg, { cause: err });
75
88
  }
76
89
  }
77
90
  }
@@ -80,17 +93,28 @@ export function createHookRunner(registry, options = {}) {
80
93
  // =========================================================================
81
94
  // Agent Hooks
82
95
  // =========================================================================
96
+ /**
97
+ * Run before_model_resolve hook.
98
+ * Allows plugins to override provider/model before model resolution.
99
+ */
100
+ async function runBeforeModelResolve(event, ctx) {
101
+ return runModifyingHook("before_model_resolve", event, ctx, mergeBeforeModelResolve);
102
+ }
103
+ /**
104
+ * Run before_prompt_build hook.
105
+ * Allows plugins to inject context and system prompt before prompt submission.
106
+ */
107
+ async function runBeforePromptBuild(event, ctx) {
108
+ return runModifyingHook("before_prompt_build", event, ctx, mergeBeforePromptBuild);
109
+ }
83
110
  /**
84
111
  * Run before_agent_start hook.
85
- * Allows plugins to inject context into the system prompt.
86
- * Runs sequentially, merging systemPrompt and prependContext from all handlers.
112
+ * Legacy compatibility hook that combines model resolve + prompt build phases.
87
113
  */
88
114
  async function runBeforeAgentStart(event, ctx) {
89
115
  return runModifyingHook("before_agent_start", event, ctx, (acc, next) => ({
90
- systemPrompt: next.systemPrompt ?? acc?.systemPrompt,
91
- prependContext: acc?.prependContext && next.prependContext
92
- ? `${acc.prependContext}\n\n${next.prependContext}`
93
- : (next.prependContext ?? acc?.prependContext),
116
+ ...mergeBeforePromptBuild(acc, next),
117
+ ...mergeBeforeModelResolve(acc, next),
94
118
  }));
95
119
  }
96
120
  /**
@@ -101,6 +125,22 @@ export function createHookRunner(registry, options = {}) {
101
125
  async function runAgentEnd(event, ctx) {
102
126
  return runVoidHook("agent_end", event, ctx);
103
127
  }
128
+ /**
129
+ * Run llm_input hook.
130
+ * Allows plugins to observe the exact input payload sent to the LLM.
131
+ * Runs in parallel (fire-and-forget).
132
+ */
133
+ async function runLlmInput(event, ctx) {
134
+ return runVoidHook("llm_input", event, ctx);
135
+ }
136
+ /**
137
+ * Run llm_output hook.
138
+ * Allows plugins to observe the exact output payload returned by the LLM.
139
+ * Runs in parallel (fire-and-forget).
140
+ */
141
+ async function runLlmOutput(event, ctx) {
142
+ return runVoidHook("llm_output", event, ctx);
143
+ }
104
144
  /**
105
145
  * Run before_compaction hook.
106
146
  */
@@ -113,6 +153,14 @@ export function createHookRunner(registry, options = {}) {
113
153
  async function runAfterCompaction(event, ctx) {
114
154
  return runVoidHook("after_compaction", event, ctx);
115
155
  }
156
+ /**
157
+ * Run before_reset hook.
158
+ * Fired when /new or /reset clears a session, before messages are lost.
159
+ * Runs in parallel (fire-and-forget).
160
+ */
161
+ async function runBeforeReset(event, ctx) {
162
+ return runVoidHook("before_reset", event, ctx);
163
+ }
116
164
  // =========================================================================
117
165
  // Message Hooks
118
166
  // =========================================================================
@@ -175,13 +223,16 @@ export function createHookRunner(registry, options = {}) {
175
223
  */
176
224
  function runToolResultPersist(event, ctx) {
177
225
  const hooks = getHooksForName(registry, "tool_result_persist");
178
- if (hooks.length === 0)
226
+ if (hooks.length === 0) {
179
227
  return undefined;
228
+ }
180
229
  let current = event.message;
181
230
  for (const hook of hooks) {
182
231
  try {
232
+ // oxlint-disable-next-line typescript/no-explicit-any
183
233
  const out = hook.handler({ ...event, message: current }, ctx);
184
234
  // Guard against accidental async handlers (this hook is sync-only).
235
+ // oxlint-disable-next-line typescript/no-explicit-any
185
236
  if (out && typeof out.then === "function") {
186
237
  const msg = `[hooks] tool_result_persist handler from ${hook.pluginId} returned a Promise; ` +
187
238
  `this hook is synchronous and the result was ignored.`;
@@ -192,8 +243,9 @@ export function createHookRunner(registry, options = {}) {
192
243
  throw new Error(msg);
193
244
  }
194
245
  const next = out?.message;
195
- if (next)
246
+ if (next) {
196
247
  current = next;
248
+ }
197
249
  }
198
250
  catch (err) {
199
251
  const msg = `[hooks] tool_result_persist handler from ${hook.pluginId} failed: ${String(err)}`;
@@ -201,13 +253,75 @@ export function createHookRunner(registry, options = {}) {
201
253
  logger?.error(msg);
202
254
  }
203
255
  else {
204
- throw new Error(msg);
256
+ throw new Error(msg, { cause: err });
205
257
  }
206
258
  }
207
259
  }
208
260
  return { message: current };
209
261
  }
210
262
  // =========================================================================
263
+ // Message Write Hooks
264
+ // =========================================================================
265
+ /**
266
+ * Run before_message_write hook.
267
+ *
268
+ * This hook is intentionally synchronous: it runs on the hot path where
269
+ * session transcripts are appended synchronously.
270
+ *
271
+ * Handlers are executed sequentially in priority order (higher first).
272
+ * If any handler returns { block: true }, the message is NOT written
273
+ * to the session JSONL and we return immediately.
274
+ * If a handler returns { message }, the modified message replaces the
275
+ * original for subsequent handlers and the final write.
276
+ */
277
+ function runBeforeMessageWrite(event, ctx) {
278
+ const hooks = getHooksForName(registry, "before_message_write");
279
+ if (hooks.length === 0) {
280
+ return undefined;
281
+ }
282
+ let current = event.message;
283
+ for (const hook of hooks) {
284
+ try {
285
+ // oxlint-disable-next-line typescript/no-explicit-any
286
+ const out = hook.handler({ ...event, message: current }, ctx);
287
+ // Guard against accidental async handlers (this hook is sync-only).
288
+ // oxlint-disable-next-line typescript/no-explicit-any
289
+ if (out && typeof out.then === "function") {
290
+ const msg = `[hooks] before_message_write handler from ${hook.pluginId} returned a Promise; ` +
291
+ `this hook is synchronous and the result was ignored.`;
292
+ if (catchErrors) {
293
+ logger?.warn?.(msg);
294
+ continue;
295
+ }
296
+ throw new Error(msg);
297
+ }
298
+ const result = out;
299
+ // If any handler blocks, return immediately.
300
+ if (result?.block) {
301
+ return { block: true };
302
+ }
303
+ // If handler provided a modified message, use it for subsequent handlers.
304
+ if (result?.message) {
305
+ current = result.message;
306
+ }
307
+ }
308
+ catch (err) {
309
+ const msg = `[hooks] before_message_write handler from ${hook.pluginId} failed: ${String(err)}`;
310
+ if (catchErrors) {
311
+ logger?.error(msg);
312
+ }
313
+ else {
314
+ throw new Error(msg, { cause: err });
315
+ }
316
+ }
317
+ }
318
+ // If message was modified by any handler, return it.
319
+ if (current !== event.message) {
320
+ return { message: current };
321
+ }
322
+ return undefined;
323
+ }
324
+ // =========================================================================
211
325
  // Session Hooks
212
326
  // =========================================================================
213
327
  /**
@@ -258,10 +372,15 @@ export function createHookRunner(registry, options = {}) {
258
372
  }
259
373
  return {
260
374
  // Agent hooks
375
+ runBeforeModelResolve,
376
+ runBeforePromptBuild,
261
377
  runBeforeAgentStart,
378
+ runLlmInput,
379
+ runLlmOutput,
262
380
  runAgentEnd,
263
381
  runBeforeCompaction,
264
382
  runAfterCompaction,
383
+ runBeforeReset,
265
384
  // Message hooks
266
385
  runMessageReceived,
267
386
  runMessageSending,
@@ -270,6 +389,8 @@ export function createHookRunner(registry, options = {}) {
270
389
  runBeforeToolCall,
271
390
  runAfterToolCall,
272
391
  runToolResultPersist,
392
+ // Message write hooks
393
+ runBeforeMessageWrite,
273
394
  // Session hooks
274
395
  runSessionStart,
275
396
  runSessionEnd,