@poolzin/pool-bot 2026.2.17 → 2026.2.18

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 (469) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/agents/agent-scope.js +4 -0
  3. package/dist/agents/announce-idempotency.js +14 -0
  4. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
  5. package/dist/agents/bash-tools.exec-runtime.js +438 -0
  6. package/dist/agents/bash-tools.shared.js +6 -0
  7. package/dist/agents/cli-runner/reliability.js +61 -0
  8. package/dist/agents/cli-watchdog-defaults.js +11 -0
  9. package/dist/agents/command-poll-backoff.js +63 -0
  10. package/dist/agents/current-time.js +16 -0
  11. package/dist/agents/model-alias-lines.js +18 -0
  12. package/dist/agents/model-auth-label.js +61 -0
  13. package/dist/agents/models-config.e2e-harness.js +115 -0
  14. package/dist/agents/ollama-stream.js +11 -3
  15. package/dist/agents/openclaw-tools.js +135 -0
  16. package/dist/agents/pi-auth-json.js +118 -0
  17. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
  18. package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
  19. package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
  20. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
  21. package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
  22. package/dist/agents/pi-tools.js +2 -0
  23. package/dist/agents/queued-file-writer.js +22 -0
  24. package/dist/agents/sandbox/docker.js +133 -40
  25. package/dist/agents/sandbox/fs-bridge.js +146 -0
  26. package/dist/agents/sandbox/fs-paths.js +205 -0
  27. package/dist/agents/sandbox/hash.js +4 -0
  28. package/dist/agents/sandbox-paths.js +3 -0
  29. package/dist/agents/session-dirs.js +20 -0
  30. package/dist/agents/skills/filter.js +24 -0
  31. package/dist/agents/skills/tools-dir.js +9 -0
  32. package/dist/agents/skills-install-download.js +290 -0
  33. package/dist/agents/skills-install-output.js +30 -0
  34. package/dist/agents/skills-install.download-test-utils.js +36 -0
  35. package/dist/agents/skills.e2e-test-helpers.js +13 -0
  36. package/dist/agents/subagent-announce-queue.js +59 -15
  37. package/dist/agents/subagent-depth.js +137 -0
  38. package/dist/agents/subagent-registry.js +448 -96
  39. package/dist/agents/subagent-spawn.js +262 -0
  40. package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
  41. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
  42. package/dist/agents/tool-display-common.js +782 -0
  43. package/dist/agents/tools/image-tool.js +1 -1
  44. package/dist/agents/tools/sessions-access.js +178 -0
  45. package/dist/agents/tools/sessions-resolution.js +206 -0
  46. package/dist/agents/tools/subagents-tool.js +616 -0
  47. package/dist/agents/workspace-dir.js +18 -0
  48. package/dist/agents/workspace-dirs.js +14 -0
  49. package/dist/agents/workspace.js +70 -0
  50. package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
  51. package/dist/auto-reply/reply/commands-export-session.js +163 -0
  52. package/dist/auto-reply/reply/commands-mesh.js +245 -0
  53. package/dist/auto-reply/reply/commands-setunset.js +28 -0
  54. package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
  55. package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
  56. package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
  57. package/dist/auto-reply/reply/directive-handling.params.js +1 -0
  58. package/dist/auto-reply/reply/directive-parsing.js +36 -0
  59. package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
  60. package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
  61. package/dist/auto-reply/reply/reply-delivery.js +92 -0
  62. package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
  63. package/dist/auto-reply/reply/session-run-accounting.js +33 -0
  64. package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
  65. package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
  66. package/dist/browser/bridge-auth-registry.js +26 -0
  67. package/dist/browser/client-actions-url.js +10 -0
  68. package/dist/browser/control-auth.js +73 -0
  69. package/dist/browser/csrf.js +64 -0
  70. package/dist/browser/http-auth.js +52 -0
  71. package/dist/browser/paths.js +37 -0
  72. package/dist/browser/proxy-files.js +32 -0
  73. package/dist/browser/pw-ai-state.js +7 -0
  74. package/dist/browser/resolved-config-refresh.js +42 -0
  75. package/dist/browser/routes/path-output.js +1 -0
  76. package/dist/browser/server-context.chrome-test-harness.js +20 -0
  77. package/dist/browser/server-middleware.js +31 -0
  78. package/dist/browser/test-port.js +16 -0
  79. package/dist/build-info.json +3 -3
  80. package/dist/canvas-host/file-resolver.js +43 -0
  81. package/dist/channels/account-summary.js +19 -0
  82. package/dist/channels/draft-stream-loop.js +77 -0
  83. package/dist/channels/plugins/account-helpers.js +26 -0
  84. package/dist/channels/telegram/allow-from.js +10 -0
  85. package/dist/cli/browser-cli-resize.js +22 -0
  86. package/dist/cli/browser-cli-shared.js +8 -0
  87. package/dist/cli/clawbot-cli.js +5 -0
  88. package/dist/cli/completion-cli.js +566 -0
  89. package/dist/cli/config-cli.js +63 -5
  90. package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
  91. package/dist/cli/daemon-cli/register-service-commands.js +60 -0
  92. package/dist/cli/daemon-cli-compat.js +80 -0
  93. package/dist/cli/nodes-cli/pairing-render.js +26 -0
  94. package/dist/cli/program/action-reparse.js +17 -0
  95. package/dist/cli/program/command-registry.js +17 -0
  96. package/dist/cli/program/program-context.js +8 -0
  97. package/dist/cli/program/register.subclis.js +7 -0
  98. package/dist/cli/program/routes.js +233 -0
  99. package/dist/cli/qr-cli.js +132 -0
  100. package/dist/cli/requirements-test-fixtures.js +17 -0
  101. package/dist/cli/respawn-policy.js +4 -0
  102. package/dist/cli/shared/parse-port.js +18 -0
  103. package/dist/cli/skills-cli.format.js +241 -0
  104. package/dist/cli/update-cli/progress.js +121 -0
  105. package/dist/cli/update-cli/restart-helper.js +108 -0
  106. package/dist/cli/update-cli/shared.js +196 -0
  107. package/dist/cli/update-cli/status.js +97 -0
  108. package/dist/cli/update-cli/suppress-deprecations.js +17 -0
  109. package/dist/cli/update-cli/update-command.js +506 -0
  110. package/dist/cli/update-cli/wizard.js +130 -0
  111. package/dist/cli/update-cli.js +3 -9
  112. package/dist/cli/windows-argv.js +69 -0
  113. package/dist/commands/auth-choice-legacy.js +20 -0
  114. package/dist/commands/auth-choice.apply-helpers.js +8 -0
  115. package/dist/commands/channel-test-helpers.js +19 -0
  116. package/dist/commands/cleanup-plan.js +10 -0
  117. package/dist/commands/cleanup-utils.js +7 -0
  118. package/dist/commands/config-validation.js +15 -0
  119. package/dist/commands/doctor-completion.js +112 -0
  120. package/dist/commands/doctor-memory-search.js +119 -0
  121. package/dist/commands/doctor-session-locks.js +73 -0
  122. package/dist/commands/doctor.e2e-harness.js +364 -0
  123. package/dist/commands/gateway-presence.js +19 -0
  124. package/dist/commands/model-default.js +35 -0
  125. package/dist/commands/models/fallbacks-shared.js +102 -0
  126. package/dist/commands/models/shared.js +24 -0
  127. package/dist/commands/onboard-auth.config-gateways.js +64 -0
  128. package/dist/commands/onboard-auth.config-litellm.js +45 -0
  129. package/dist/commands/onboard-auth.config-shared.js +116 -0
  130. package/dist/commands/onboard-config.js +16 -0
  131. package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
  132. package/dist/commands/onboard-provider-auth-flags.js +136 -0
  133. package/dist/commands/openai-codex-oauth.js +40 -0
  134. package/dist/commands/test-runtime-config-helpers.js +21 -0
  135. package/dist/commands/test-wizard-helpers.js +68 -0
  136. package/dist/commands/vllm-setup.js +66 -0
  137. package/dist/compat/legacy-names.js +2 -0
  138. package/dist/config/backup-rotation.js +19 -0
  139. package/dist/config/env-preserve.js +122 -0
  140. package/dist/config/includes-scan.js +78 -0
  141. package/dist/config/plugins-allowlist.js +13 -0
  142. package/dist/config/schema.help.js +256 -0
  143. package/dist/config/schema.hints.js +189 -0
  144. package/dist/config/schema.irc.js +20 -0
  145. package/dist/config/schema.labels.js +317 -0
  146. package/dist/config/sessions/delivery-info.js +40 -0
  147. package/dist/config/types.irc.js +1 -0
  148. package/dist/config/zod-schema.agent-model.js +10 -0
  149. package/dist/config/zod-schema.allowdeny.js +35 -0
  150. package/dist/config/zod-schema.sensitive.js +4 -0
  151. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  152. package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
  153. package/dist/cron/isolated-agent/subagent-followup.js +127 -0
  154. package/dist/cron/isolated-agent.mocks.js +12 -0
  155. package/dist/cron/isolated-agent.test-setup.js +22 -0
  156. package/dist/cron/legacy-delivery.js +43 -0
  157. package/dist/cron/webhook-url.js +22 -0
  158. package/dist/daemon/arg-split.js +40 -0
  159. package/dist/daemon/exec-file.js +23 -0
  160. package/dist/daemon/output.js +6 -0
  161. package/dist/daemon/runtime-format.js +31 -0
  162. package/dist/daemon/schtasks-exec.js +4 -0
  163. package/dist/daemon/service-audit.js +22 -0
  164. package/dist/discord/client.js +41 -0
  165. package/dist/discord/components-registry.js +57 -0
  166. package/dist/discord/components.js +816 -0
  167. package/dist/discord/guilds.js +12 -0
  168. package/dist/discord/monitor/gateway-plugin.js +48 -0
  169. package/dist/discord/monitor/presence.js +30 -0
  170. package/dist/discord/send.components.js +115 -0
  171. package/dist/discord/send.shared.js +4 -0
  172. package/dist/discord/ui.js +26 -0
  173. package/dist/discord/voice-message.js +254 -0
  174. package/dist/gateway/agent-event-assistant-text.js +5 -0
  175. package/dist/gateway/agent-prompt.js +33 -0
  176. package/dist/gateway/auth-rate-limit.js +136 -0
  177. package/dist/gateway/channel-health-monitor.js +114 -0
  178. package/dist/gateway/control-ui-contract.js +1 -0
  179. package/dist/gateway/control-ui-csp.js +15 -0
  180. package/dist/gateway/gateway-config-prompts.shared.js +25 -0
  181. package/dist/gateway/http-auth-helpers.js +18 -0
  182. package/dist/gateway/http-common.js +18 -0
  183. package/dist/gateway/http-endpoint-helpers.js +27 -0
  184. package/dist/gateway/node-invoke-sanitize.js +11 -0
  185. package/dist/gateway/node-invoke-system-run-approval.js +205 -0
  186. package/dist/gateway/probe-auth.js +21 -0
  187. package/dist/gateway/protocol/index.js +7 -2
  188. package/dist/gateway/protocol/schema/mesh.js +54 -0
  189. package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
  190. package/dist/gateway/protocol/schema.js +1 -0
  191. package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
  192. package/dist/gateway/server-channels.js +11 -0
  193. package/dist/gateway/server-methods/attachment-normalize.js +16 -0
  194. package/dist/gateway/server-methods/base-hash.js +8 -0
  195. package/dist/gateway/server-methods/mesh.js +700 -0
  196. package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
  197. package/dist/gateway/server-methods/restart-request.js +13 -0
  198. package/dist/gateway/server-methods/validation.js +8 -0
  199. package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
  200. package/dist/gateway/server.e2e-registry-helpers.js +1 -0
  201. package/dist/gateway/server.e2e-ws-harness.js +20 -0
  202. package/dist/gateway/test-helpers.js +2 -0
  203. package/dist/gateway/test-helpers.server.js +3 -1
  204. package/dist/gateway/test-http-response.js +12 -0
  205. package/dist/gateway/test-openai-responses-model.js +20 -0
  206. package/dist/gateway/test-temp-config.js +30 -0
  207. package/dist/gateway/test-with-server.js +32 -0
  208. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
  209. package/dist/imessage/monitor/abort-handler.js +23 -0
  210. package/dist/imessage/monitor/inbound-processing.js +346 -0
  211. package/dist/imessage/monitor/parse-notification.js +64 -0
  212. package/dist/imessage/target-parsing-helpers.js +92 -0
  213. package/dist/infra/archive.js +244 -20
  214. package/dist/infra/detect-package-manager.js +26 -0
  215. package/dist/infra/exec-approvals-allowlist.js +257 -0
  216. package/dist/infra/exec-approvals-analysis.js +770 -0
  217. package/dist/infra/exec-approvals.js +13 -0
  218. package/dist/infra/file-lock.js +1 -0
  219. package/dist/infra/gemini-auth.js +39 -0
  220. package/dist/infra/heartbeat-active-hours.js +85 -0
  221. package/dist/infra/heartbeat-events-filter.js +50 -0
  222. package/dist/infra/heartbeat-runner.test-utils.js +39 -0
  223. package/dist/infra/http-body.js +265 -0
  224. package/dist/infra/install-package-dir.js +50 -0
  225. package/dist/infra/install-safe-path.js +49 -0
  226. package/dist/infra/json-files.js +49 -0
  227. package/dist/infra/jsonl-socket.js +52 -0
  228. package/dist/infra/map-size.js +14 -0
  229. package/dist/infra/net/hostname.js +7 -0
  230. package/dist/infra/npm-registry-spec.js +39 -0
  231. package/dist/infra/openclaw-root.js +109 -0
  232. package/dist/infra/outbound/delivery-queue.js +214 -0
  233. package/dist/infra/outbound/identity.js +23 -0
  234. package/dist/infra/outbound/message-action-params.js +307 -0
  235. package/dist/infra/outbound/tool-payload.js +21 -0
  236. package/dist/infra/package-json.js +23 -0
  237. package/dist/infra/pairing-files.js +19 -0
  238. package/dist/infra/pairing-token.js +9 -0
  239. package/dist/infra/path-prepend.js +51 -0
  240. package/dist/infra/process-respawn.js +49 -0
  241. package/dist/infra/runtime-status.js +16 -0
  242. package/dist/infra/session-cost-usage.types.js +1 -0
  243. package/dist/infra/session-maintenance-warning.js +89 -0
  244. package/dist/infra/system-run-command.js +78 -0
  245. package/dist/infra/tmp-openclaw-dir.js +81 -0
  246. package/dist/infra/tmp-poolbot-dir.js +2 -0
  247. package/dist/infra/update-channels.js +19 -0
  248. package/dist/line/actions.js +45 -0
  249. package/dist/line/channel-access-token.js +9 -0
  250. package/dist/line/flex-templates/basic-cards.js +332 -0
  251. package/dist/line/flex-templates/common.js +18 -0
  252. package/dist/line/flex-templates/media-control-cards.js +453 -0
  253. package/dist/line/flex-templates/message.js +10 -0
  254. package/dist/line/flex-templates/schedule-cards.js +399 -0
  255. package/dist/line/flex-templates/types.js +1 -0
  256. package/dist/line/webhook-node.js +100 -0
  257. package/dist/line/webhook-utils.js +11 -0
  258. package/dist/logging/timestamps.js +14 -0
  259. package/dist/markdown/whatsapp.js +62 -0
  260. package/dist/media/base64.js +34 -0
  261. package/dist/media/local-roots.js +32 -0
  262. package/dist/media/outbound-attachment.js +10 -0
  263. package/dist/media/read-response-with-limit.js +41 -0
  264. package/dist/media/sniff-mime-from-base64.js +19 -0
  265. package/dist/media-understanding/audio-preflight.js +67 -0
  266. package/dist/media-understanding/fs.js +13 -0
  267. package/dist/media-understanding/output-extract.js +26 -0
  268. package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
  269. package/dist/media-understanding/providers/google/inline-data.js +64 -0
  270. package/dist/media-understanding/providers/shared.js +7 -0
  271. package/dist/media-understanding/runner.entries.js +459 -0
  272. package/dist/memory/batch-error-utils.js +11 -0
  273. package/dist/memory/batch-http.js +27 -0
  274. package/dist/memory/batch-output.js +29 -0
  275. package/dist/memory/batch-runner.js +22 -0
  276. package/dist/memory/batch-upload.js +23 -0
  277. package/dist/memory/batch-utils.js +26 -0
  278. package/dist/memory/embeddings-debug.js +11 -0
  279. package/dist/memory/embeddings-remote-client.js +22 -0
  280. package/dist/memory/embeddings-remote-fetch.js +14 -0
  281. package/dist/memory/manager-embedding-ops.js +616 -0
  282. package/dist/memory/manager-sync-ops.js +953 -0
  283. package/dist/memory/qmd-manager.js +1061 -0
  284. package/dist/memory/qmd-query-parser.js +107 -0
  285. package/dist/memory/qmd-scope.js +93 -0
  286. package/dist/memory/search-manager.js +0 -1
  287. package/dist/memory/sync-index.js +21 -0
  288. package/dist/memory/sync-progress.js +22 -0
  289. package/dist/memory/sync-stale.js +30 -0
  290. package/dist/memory/test-embeddings-mock.js +16 -0
  291. package/dist/memory/test-manager-helpers.js +14 -0
  292. package/dist/memory/test-runtime-mocks.js +11 -0
  293. package/dist/node-host/invoke-browser.js +177 -0
  294. package/dist/node-host/invoke.js +685 -0
  295. package/dist/pairing/setup-code.js +285 -0
  296. package/dist/plugin-sdk/account-id.js +1 -0
  297. package/dist/plugin-sdk/agent-media-payload.js +13 -0
  298. package/dist/plugin-sdk/allow-from.js +47 -0
  299. package/dist/plugin-sdk/command-auth.js +23 -0
  300. package/dist/plugin-sdk/config-paths.js +9 -0
  301. package/dist/plugin-sdk/file-lock.js +116 -0
  302. package/dist/plugin-sdk/json-store.js +31 -0
  303. package/dist/plugin-sdk/onboarding.js +28 -0
  304. package/dist/plugin-sdk/provider-auth-result.js +29 -0
  305. package/dist/plugin-sdk/slack-message-actions.js +133 -0
  306. package/dist/plugin-sdk/status-helpers.js +35 -0
  307. package/dist/plugin-sdk/text-chunking.js +31 -0
  308. package/dist/plugin-sdk/tool-send.js +12 -0
  309. package/dist/plugin-sdk/webhook-path.js +27 -0
  310. package/dist/plugin-sdk/webhook-targets.js +34 -0
  311. package/dist/plugins/hooks.test-helpers.js +21 -0
  312. package/dist/plugins/uninstall.js +171 -0
  313. package/dist/process/supervisor/adapters/child.js +143 -0
  314. package/dist/process/supervisor/adapters/env.js +13 -0
  315. package/dist/process/supervisor/adapters/pty.js +148 -0
  316. package/dist/process/supervisor/index.js +10 -0
  317. package/dist/process/supervisor/registry.js +117 -0
  318. package/dist/process/supervisor/supervisor.js +244 -0
  319. package/dist/process/supervisor/types.js +1 -0
  320. package/dist/providers/google-shared.test-helpers.js +75 -0
  321. package/dist/security/audit-channel.js +419 -0
  322. package/dist/security/audit-tool-policy.js +1 -0
  323. package/dist/security/scan-paths.js +12 -0
  324. package/dist/sessions/input-provenance.js +55 -0
  325. package/dist/sessions/session-key-utils.js +7 -0
  326. package/dist/shared/chat-content.js +31 -0
  327. package/dist/shared/chat-envelope.js +45 -0
  328. package/dist/shared/config-eval.js +117 -0
  329. package/dist/shared/device-auth.js +16 -0
  330. package/dist/shared/entry-metadata.js +9 -0
  331. package/dist/shared/entry-status.js +25 -0
  332. package/dist/shared/frontmatter.js +98 -0
  333. package/dist/shared/model-param-b.js +19 -0
  334. package/dist/shared/net/ipv4.js +17 -0
  335. package/dist/shared/node-match.js +53 -0
  336. package/dist/shared/requirements.js +128 -0
  337. package/dist/shared/subagents-format.js +84 -0
  338. package/dist/shared/usage-aggregates.js +28 -0
  339. package/dist/signal/monitor/mentions.js +45 -0
  340. package/dist/signal/rpc-context.js +19 -0
  341. package/dist/slack/blocks-fallback.js +76 -0
  342. package/dist/slack/blocks-input.js +40 -0
  343. package/dist/slack/draft-stream.js +106 -0
  344. package/dist/slack/message-actions.js +51 -0
  345. package/dist/slack/modal-metadata.js +32 -0
  346. package/dist/slack/monitor/events/interactions.js +462 -0
  347. package/dist/slack/monitor/room-context.js +17 -0
  348. package/dist/slack/stream-mode.js +41 -0
  349. package/dist/telegram/bot-native-command-menu.js +64 -0
  350. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  351. package/dist/telegram/button-types.js +1 -0
  352. package/dist/telegram/group-access.js +65 -0
  353. package/dist/telegram/outbound-params.js +21 -0
  354. package/dist/telegram/poll-vote-cache.js +21 -0
  355. package/dist/terminal/health-style.js +36 -0
  356. package/dist/test-utils/chunk-test-helpers.js +21 -0
  357. package/dist/test-utils/env.js +72 -0
  358. package/dist/test-utils/exec-assertions.js +12 -0
  359. package/dist/test-utils/imessage-test-plugin.js +54 -0
  360. package/dist/test-utils/mock-http-response.js +17 -0
  361. package/dist/test-utils/vitest-mock-fn.js +1 -0
  362. package/dist/tts/tts-core.js +550 -0
  363. package/dist/utils/chunk-items.js +10 -0
  364. package/dist/utils/reaction-level.js +52 -0
  365. package/dist/utils/safe-json.js +22 -0
  366. package/dist/utils/with-timeout.js +14 -0
  367. package/dist/web/media.js +17 -5
  368. package/dist/whatsapp/resolve-outbound-target.js +42 -0
  369. package/dist/wizard/onboarding.completion.js +74 -0
  370. package/extensions/bluebubbles/src/account-resolve.ts +29 -0
  371. package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
  372. package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
  373. package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
  374. package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
  375. package/extensions/bluebubbles/src/multipart.ts +32 -0
  376. package/extensions/bluebubbles/src/send-helpers.ts +53 -0
  377. package/extensions/bluebubbles/src/test-harness.ts +50 -0
  378. package/extensions/bluebubbles/src/test-mocks.ts +11 -0
  379. package/extensions/device-pair/index.ts +554 -0
  380. package/extensions/discord/src/channel.js +366 -0
  381. package/extensions/discord/src/runtime.js +10 -0
  382. package/extensions/feishu/index.ts +63 -0
  383. package/extensions/feishu/src/accounts.ts +114 -0
  384. package/extensions/feishu/src/bitable.ts +739 -0
  385. package/extensions/feishu/src/bot.ts +965 -0
  386. package/extensions/feishu/src/channel.ts +351 -0
  387. package/extensions/feishu/src/client.ts +118 -0
  388. package/extensions/feishu/src/config-schema.ts +206 -0
  389. package/extensions/feishu/src/dedup.ts +33 -0
  390. package/extensions/feishu/src/directory.ts +177 -0
  391. package/extensions/feishu/src/doc-schema.ts +47 -0
  392. package/extensions/feishu/src/docx.ts +536 -0
  393. package/extensions/feishu/src/drive-schema.ts +46 -0
  394. package/extensions/feishu/src/drive.ts +227 -0
  395. package/extensions/feishu/src/dynamic-agent.ts +131 -0
  396. package/extensions/feishu/src/media.ts +449 -0
  397. package/extensions/feishu/src/mention.ts +126 -0
  398. package/extensions/feishu/src/monitor.ts +330 -0
  399. package/extensions/feishu/src/onboarding.ts +359 -0
  400. package/extensions/feishu/src/outbound.ts +55 -0
  401. package/extensions/feishu/src/perm-schema.ts +52 -0
  402. package/extensions/feishu/src/perm.ts +173 -0
  403. package/extensions/feishu/src/policy.ts +84 -0
  404. package/extensions/feishu/src/probe.ts +44 -0
  405. package/extensions/feishu/src/reactions.ts +160 -0
  406. package/extensions/feishu/src/reply-dispatcher.ts +239 -0
  407. package/extensions/feishu/src/runtime.ts +14 -0
  408. package/extensions/feishu/src/send-result.ts +29 -0
  409. package/extensions/feishu/src/send.ts +335 -0
  410. package/extensions/feishu/src/streaming-card.ts +223 -0
  411. package/extensions/feishu/src/targets.ts +78 -0
  412. package/extensions/feishu/src/tools-config.ts +21 -0
  413. package/extensions/feishu/src/types.ts +81 -0
  414. package/extensions/feishu/src/typing.ts +80 -0
  415. package/extensions/feishu/src/wiki-schema.ts +55 -0
  416. package/extensions/feishu/src/wiki.ts +232 -0
  417. package/extensions/imessage/src/channel.js +253 -0
  418. package/extensions/imessage/src/runtime.js +10 -0
  419. package/extensions/irc/index.ts +17 -0
  420. package/extensions/irc/src/accounts.ts +268 -0
  421. package/extensions/irc/src/channel.ts +367 -0
  422. package/extensions/irc/src/client.ts +439 -0
  423. package/extensions/irc/src/config-schema.ts +97 -0
  424. package/extensions/irc/src/connect-options.ts +30 -0
  425. package/extensions/irc/src/control-chars.ts +22 -0
  426. package/extensions/irc/src/inbound.ts +334 -0
  427. package/extensions/irc/src/monitor.ts +147 -0
  428. package/extensions/irc/src/normalize.ts +117 -0
  429. package/extensions/irc/src/onboarding.ts +479 -0
  430. package/extensions/irc/src/policy.ts +157 -0
  431. package/extensions/irc/src/probe.ts +53 -0
  432. package/extensions/irc/src/protocol.ts +169 -0
  433. package/extensions/irc/src/runtime.ts +14 -0
  434. package/extensions/irc/src/send.ts +88 -0
  435. package/extensions/irc/src/types.ts +93 -0
  436. package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
  437. package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
  438. package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
  439. package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
  440. package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
  441. package/extensions/minimax-portal-auth/index.ts +161 -0
  442. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  443. package/extensions/msteams/src/file-lock.ts +1 -0
  444. package/extensions/msteams/src/graph.ts +92 -0
  445. package/extensions/msteams/src/mentions.ts +114 -0
  446. package/extensions/msteams/src/test-runtime.ts +16 -0
  447. package/extensions/openai-codex-auth/index.ts +177 -0
  448. package/extensions/phone-control/index.ts +421 -0
  449. package/extensions/shared/resolve-target-test-helpers.ts +66 -0
  450. package/extensions/signal/src/channel.js +273 -0
  451. package/extensions/signal/src/runtime.js +10 -0
  452. package/extensions/slack/src/channel.js +489 -0
  453. package/extensions/slack/src/runtime.js +10 -0
  454. package/extensions/talk-voice/index.ts +150 -0
  455. package/extensions/telegram/src/channel.js +424 -0
  456. package/extensions/telegram/src/runtime.js +10 -0
  457. package/extensions/thread-ownership/index.ts +133 -0
  458. package/extensions/tlon/src/account-fields.ts +25 -0
  459. package/extensions/tlon/src/urbit/base-url.ts +57 -0
  460. package/extensions/tlon/src/urbit/channel-client.ts +157 -0
  461. package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
  462. package/extensions/tlon/src/urbit/context.ts +47 -0
  463. package/extensions/tlon/src/urbit/errors.ts +51 -0
  464. package/extensions/tlon/src/urbit/fetch.ts +39 -0
  465. package/extensions/twitch/src/test-fixtures.ts +30 -0
  466. package/extensions/voice-call/src/allowlist.ts +19 -0
  467. package/extensions/whatsapp/src/channel.js +429 -0
  468. package/extensions/whatsapp/src/runtime.js +10 -0
  469. package/package.json +1 -1
@@ -0,0 +1,107 @@
1
+ import { createSubsystemLogger } from "../logging/subsystem.js";
2
+ const log = createSubsystemLogger("memory");
3
+ export function parseQmdQueryJson(stdout, stderr) {
4
+ const trimmedStdout = stdout.trim();
5
+ const trimmedStderr = stderr.trim();
6
+ const stdoutIsMarker = trimmedStdout.length > 0 && isQmdNoResultsOutput(trimmedStdout);
7
+ const stderrIsMarker = trimmedStderr.length > 0 && isQmdNoResultsOutput(trimmedStderr);
8
+ if (stdoutIsMarker || (!trimmedStdout && stderrIsMarker)) {
9
+ return [];
10
+ }
11
+ if (!trimmedStdout) {
12
+ const context = trimmedStderr ? ` (stderr: ${summarizeQmdStderr(trimmedStderr)})` : "";
13
+ const message = `stdout empty${context}`;
14
+ log.warn(`qmd query returned invalid JSON: ${message}`);
15
+ throw new Error(`qmd query returned invalid JSON: ${message}`);
16
+ }
17
+ try {
18
+ const parsed = parseQmdQueryResultArray(trimmedStdout);
19
+ if (parsed !== null) {
20
+ return parsed;
21
+ }
22
+ const noisyPayload = extractFirstJsonArray(trimmedStdout);
23
+ if (!noisyPayload) {
24
+ throw new Error("qmd query JSON response was not an array");
25
+ }
26
+ const fallback = parseQmdQueryResultArray(noisyPayload);
27
+ if (fallback !== null) {
28
+ return fallback;
29
+ }
30
+ throw new Error("qmd query JSON response was not an array");
31
+ }
32
+ catch (err) {
33
+ const message = err instanceof Error ? err.message : String(err);
34
+ log.warn(`qmd query returned invalid JSON: ${message}`);
35
+ throw new Error(`qmd query returned invalid JSON: ${message}`, { cause: err });
36
+ }
37
+ }
38
+ function isQmdNoResultsOutput(raw) {
39
+ const lines = raw
40
+ .split(/\r?\n/)
41
+ .map((line) => line.trim().toLowerCase().replace(/\s+/g, " "))
42
+ .filter((line) => line.length > 0);
43
+ return lines.some((line) => isQmdNoResultsLine(line));
44
+ }
45
+ function isQmdNoResultsLine(line) {
46
+ if (line === "no results found" || line === "no results found.") {
47
+ return true;
48
+ }
49
+ return /^(?:\[[^\]]+\]\s*)?(?:(?:warn(?:ing)?|info|error|qmd)\s*:\s*)+no results found\.?$/.test(line);
50
+ }
51
+ function summarizeQmdStderr(raw) {
52
+ return raw.length <= 120 ? raw : `${raw.slice(0, 117)}...`;
53
+ }
54
+ function parseQmdQueryResultArray(raw) {
55
+ try {
56
+ const parsed = JSON.parse(raw);
57
+ if (!Array.isArray(parsed)) {
58
+ return null;
59
+ }
60
+ return parsed;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ function extractFirstJsonArray(raw) {
67
+ const start = raw.indexOf("[");
68
+ if (start < 0) {
69
+ return null;
70
+ }
71
+ let depth = 0;
72
+ let inString = false;
73
+ let escaped = false;
74
+ for (let i = start; i < raw.length; i += 1) {
75
+ const char = raw[i];
76
+ if (char === undefined) {
77
+ break;
78
+ }
79
+ if (inString) {
80
+ if (escaped) {
81
+ escaped = false;
82
+ continue;
83
+ }
84
+ if (char === "\\") {
85
+ escaped = true;
86
+ }
87
+ else if (char === '"') {
88
+ inString = false;
89
+ }
90
+ continue;
91
+ }
92
+ if (char === '"') {
93
+ inString = true;
94
+ continue;
95
+ }
96
+ if (char === "[") {
97
+ depth += 1;
98
+ }
99
+ else if (char === "]") {
100
+ depth -= 1;
101
+ if (depth === 0) {
102
+ return raw.slice(start, i + 1);
103
+ }
104
+ }
105
+ }
106
+ return null;
107
+ }
@@ -0,0 +1,93 @@
1
+ import { parseAgentSessionKey } from "../sessions/session-key-utils.js";
2
+ export function isQmdScopeAllowed(scope, sessionKey) {
3
+ if (!scope) {
4
+ return true;
5
+ }
6
+ const parsed = parseQmdSessionScope(sessionKey);
7
+ const channel = parsed.channel;
8
+ const chatType = parsed.chatType;
9
+ const normalizedKey = parsed.normalizedKey ?? "";
10
+ const rawKey = sessionKey?.trim().toLowerCase() ?? "";
11
+ for (const rule of scope.rules ?? []) {
12
+ if (!rule) {
13
+ continue;
14
+ }
15
+ const match = rule.match ?? {};
16
+ if (match.channel && match.channel !== channel) {
17
+ continue;
18
+ }
19
+ if (match.chatType && match.chatType !== chatType) {
20
+ continue;
21
+ }
22
+ const normalizedPrefix = match.keyPrefix?.trim().toLowerCase() || undefined;
23
+ const rawPrefix = match.keyPrefix?.trim().toLowerCase() || undefined;
24
+ if (rawPrefix && !rawKey.startsWith(rawPrefix)) {
25
+ continue;
26
+ }
27
+ if (normalizedPrefix) {
28
+ // Backward compat: older configs used `keyPrefix: "agent:<id>:..."` to match raw keys.
29
+ const isLegacyRaw = normalizedPrefix.startsWith("agent:");
30
+ if (isLegacyRaw) {
31
+ if (!rawKey.startsWith(normalizedPrefix)) {
32
+ continue;
33
+ }
34
+ }
35
+ else if (!normalizedKey.startsWith(normalizedPrefix)) {
36
+ continue;
37
+ }
38
+ }
39
+ return rule.action === "allow";
40
+ }
41
+ const fallback = scope.default ?? "allow";
42
+ return fallback === "allow";
43
+ }
44
+ export function deriveQmdScopeChannel(key) {
45
+ return parseQmdSessionScope(key).channel;
46
+ }
47
+ export function deriveQmdScopeChatType(key) {
48
+ return parseQmdSessionScope(key).chatType;
49
+ }
50
+ function parseQmdSessionScope(key) {
51
+ const normalized = normalizeQmdSessionKey(key);
52
+ if (!normalized) {
53
+ return {};
54
+ }
55
+ const parts = normalized.split(":").filter(Boolean);
56
+ let chatType;
57
+ if (parts.length >= 2 &&
58
+ (parts[1] === "group" || parts[1] === "channel" || parts[1] === "direct" || parts[1] === "dm")) {
59
+ if (parts.includes("group")) {
60
+ chatType = "group";
61
+ }
62
+ else if (parts.includes("channel")) {
63
+ chatType = "channel";
64
+ }
65
+ return {
66
+ normalizedKey: normalized,
67
+ channel: parts[0]?.toLowerCase(),
68
+ chatType: chatType ?? "direct",
69
+ };
70
+ }
71
+ if (normalized.includes(":group:")) {
72
+ return { normalizedKey: normalized, chatType: "group" };
73
+ }
74
+ if (normalized.includes(":channel:")) {
75
+ return { normalizedKey: normalized, chatType: "channel" };
76
+ }
77
+ return { normalizedKey: normalized, chatType: "direct" };
78
+ }
79
+ function normalizeQmdSessionKey(key) {
80
+ if (!key) {
81
+ return undefined;
82
+ }
83
+ const trimmed = key.trim();
84
+ if (!trimmed) {
85
+ return undefined;
86
+ }
87
+ const parsed = parseAgentSessionKey(trimmed);
88
+ const normalized = (parsed?.rest ?? trimmed).toLowerCase();
89
+ if (normalized.startsWith("subagent:")) {
90
+ return undefined;
91
+ }
92
+ return normalized;
93
+ }
@@ -11,7 +11,6 @@ export async function getMemorySearchManager(params) {
11
11
  return { manager: cached };
12
12
  }
13
13
  try {
14
- // @ts-expect-error qmd-manager is an optional module that may not exist at build time
15
14
  const { QmdMemoryManager } = await import("./qmd-manager.js");
16
15
  const primary = await QmdMemoryManager.create({
17
16
  cfg: params.cfg,
@@ -0,0 +1,21 @@
1
+ function tickProgress(progress) {
2
+ if (!progress) {
3
+ return;
4
+ }
5
+ progress.completed += 1;
6
+ progress.report({
7
+ completed: progress.completed,
8
+ total: progress.total,
9
+ });
10
+ }
11
+ export async function indexFileEntryIfChanged(params) {
12
+ const record = params.db
13
+ .prepare(`SELECT hash FROM files WHERE path = ? AND source = ?`)
14
+ .get(params.entry.path, params.source);
15
+ if (!params.needsFullReindex && record?.hash === params.entry.hash) {
16
+ tickProgress(params.progress);
17
+ return;
18
+ }
19
+ await params.indexFile(params.entry);
20
+ tickProgress(params.progress);
21
+ }
@@ -0,0 +1,22 @@
1
+ export function bumpSyncProgressTotal(progress, delta, label) {
2
+ if (!progress) {
3
+ return;
4
+ }
5
+ progress.total += delta;
6
+ progress.report({
7
+ completed: progress.completed,
8
+ total: progress.total,
9
+ label,
10
+ });
11
+ }
12
+ export function bumpSyncProgressCompleted(progress, delta = 1, label) {
13
+ if (!progress) {
14
+ return;
15
+ }
16
+ progress.completed += delta;
17
+ progress.report({
18
+ completed: progress.completed,
19
+ total: progress.total,
20
+ label,
21
+ });
22
+ }
@@ -0,0 +1,30 @@
1
+ export function deleteStaleIndexedPaths(params) {
2
+ const staleRows = params.db
3
+ .prepare(`SELECT path FROM files WHERE source = ?`)
4
+ .all(params.source);
5
+ for (const stale of staleRows) {
6
+ if (params.activePaths.has(stale.path)) {
7
+ continue;
8
+ }
9
+ params.db
10
+ .prepare(`DELETE FROM files WHERE path = ? AND source = ?`)
11
+ .run(stale.path, params.source);
12
+ try {
13
+ params.db
14
+ .prepare(`DELETE FROM ${params.vectorTable} WHERE id IN (SELECT id FROM chunks WHERE path = ? AND source = ?)`)
15
+ .run(stale.path, params.source);
16
+ }
17
+ catch { }
18
+ params.db
19
+ .prepare(`DELETE FROM chunks WHERE path = ? AND source = ?`)
20
+ .run(stale.path, params.source);
21
+ if (params.ftsEnabled && params.ftsAvailable) {
22
+ try {
23
+ params.db
24
+ .prepare(`DELETE FROM ${params.ftsTable} WHERE path = ? AND source = ? AND model = ?`)
25
+ .run(stale.path, params.source, params.model);
26
+ }
27
+ catch { }
28
+ }
29
+ }
30
+ }
@@ -0,0 +1,16 @@
1
+ export function createOpenAIEmbeddingProviderMock(params) {
2
+ return {
3
+ requestedProvider: "openai",
4
+ provider: {
5
+ id: "openai",
6
+ model: "text-embedding-3-small",
7
+ embedQuery: params.embedQuery,
8
+ embedBatch: params.embedBatch,
9
+ },
10
+ openAi: {
11
+ baseUrl: "https://api.openai.com/v1",
12
+ headers: { Authorization: "Bearer test", "Content-Type": "application/json" },
13
+ model: "text-embedding-3-small",
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,14 @@
1
+ import { getMemorySearchManager } from "./index.js";
2
+ export async function getRequiredMemoryIndexManager(params) {
3
+ const result = await getMemorySearchManager({
4
+ cfg: params.cfg,
5
+ agentId: params.agentId ?? "main",
6
+ });
7
+ if (!result.manager) {
8
+ throw new Error("manager missing");
9
+ }
10
+ if (!("sync" in result.manager) || typeof result.manager.sync !== "function") {
11
+ throw new Error("manager does not support sync");
12
+ }
13
+ return result.manager;
14
+ }
@@ -0,0 +1,11 @@
1
+ import { vi } from "vitest";
2
+ // Unit tests: avoid importing the real chokidar implementation (native fsevents, etc.).
3
+ vi.mock("chokidar", () => ({
4
+ default: {
5
+ watch: () => ({ on: () => { }, close: async () => { } }),
6
+ },
7
+ watch: () => ({ on: () => { }, close: async () => { } }),
8
+ }));
9
+ vi.mock("./sqlite-vec.js", () => ({
10
+ loadSqliteVecExtension: async () => ({ ok: false, error: "sqlite-vec disabled in tests" }),
11
+ }));
@@ -0,0 +1,177 @@
1
+ import fsPromises from "node:fs/promises";
2
+ import { resolveBrowserConfig } from "../browser/config.js";
3
+ import { createBrowserControlContext, startBrowserControlServiceFromConfig, } from "../browser/control-service.js";
4
+ import { createBrowserRouteDispatcher } from "../browser/routes/dispatcher.js";
5
+ import { loadConfig } from "../config/config.js";
6
+ import { detectMime } from "../media/mime.js";
7
+ import { withTimeout } from "./with-timeout.js";
8
+ const BROWSER_PROXY_MAX_FILE_BYTES = 10 * 1024 * 1024;
9
+ function normalizeProfileAllowlist(raw) {
10
+ return Array.isArray(raw) ? raw.map((entry) => entry.trim()).filter(Boolean) : [];
11
+ }
12
+ function resolveBrowserProxyConfig() {
13
+ const cfg = loadConfig();
14
+ const proxy = cfg.nodeHost?.browserProxy;
15
+ const allowProfiles = normalizeProfileAllowlist(proxy?.allowProfiles);
16
+ const enabled = proxy?.enabled !== false;
17
+ return { enabled, allowProfiles };
18
+ }
19
+ let browserControlReady = null;
20
+ async function ensureBrowserControlService() {
21
+ if (browserControlReady) {
22
+ return browserControlReady;
23
+ }
24
+ browserControlReady = (async () => {
25
+ const cfg = loadConfig();
26
+ const resolved = resolveBrowserConfig(cfg.browser, cfg);
27
+ if (!resolved.enabled) {
28
+ throw new Error("browser control disabled");
29
+ }
30
+ const started = await startBrowserControlServiceFromConfig();
31
+ if (!started) {
32
+ throw new Error("browser control disabled");
33
+ }
34
+ })();
35
+ return browserControlReady;
36
+ }
37
+ function isProfileAllowed(params) {
38
+ const { allowProfiles, profile } = params;
39
+ if (!allowProfiles.length) {
40
+ return true;
41
+ }
42
+ if (!profile) {
43
+ return false;
44
+ }
45
+ return allowProfiles.includes(profile.trim());
46
+ }
47
+ function collectBrowserProxyPaths(payload) {
48
+ const paths = new Set();
49
+ const obj = typeof payload === "object" && payload !== null ? payload : null;
50
+ if (!obj) {
51
+ return [];
52
+ }
53
+ if (typeof obj.path === "string" && obj.path.trim()) {
54
+ paths.add(obj.path.trim());
55
+ }
56
+ if (typeof obj.imagePath === "string" && obj.imagePath.trim()) {
57
+ paths.add(obj.imagePath.trim());
58
+ }
59
+ const download = obj.download;
60
+ if (download && typeof download === "object") {
61
+ const dlPath = download.path;
62
+ if (typeof dlPath === "string" && dlPath.trim()) {
63
+ paths.add(dlPath.trim());
64
+ }
65
+ }
66
+ return [...paths];
67
+ }
68
+ async function readBrowserProxyFile(filePath) {
69
+ const stat = await fsPromises.stat(filePath).catch(() => null);
70
+ if (!stat || !stat.isFile()) {
71
+ return null;
72
+ }
73
+ if (stat.size > BROWSER_PROXY_MAX_FILE_BYTES) {
74
+ throw new Error(`browser proxy file exceeds ${Math.round(BROWSER_PROXY_MAX_FILE_BYTES / (1024 * 1024))}MB`);
75
+ }
76
+ const buffer = await fsPromises.readFile(filePath);
77
+ const mimeType = await detectMime({ buffer, filePath });
78
+ return { path: filePath, base64: buffer.toString("base64"), mimeType };
79
+ }
80
+ function decodeParams(raw) {
81
+ if (!raw) {
82
+ throw new Error("INVALID_REQUEST: paramsJSON required");
83
+ }
84
+ return JSON.parse(raw);
85
+ }
86
+ export async function runBrowserProxyCommand(paramsJSON) {
87
+ const params = decodeParams(paramsJSON);
88
+ const pathValue = typeof params.path === "string" ? params.path.trim() : "";
89
+ if (!pathValue) {
90
+ throw new Error("INVALID_REQUEST: path required");
91
+ }
92
+ const proxyConfig = resolveBrowserProxyConfig();
93
+ if (!proxyConfig.enabled) {
94
+ throw new Error("UNAVAILABLE: node browser proxy disabled");
95
+ }
96
+ await ensureBrowserControlService();
97
+ const cfg = loadConfig();
98
+ const resolved = resolveBrowserConfig(cfg.browser, cfg);
99
+ const requestedProfile = typeof params.profile === "string" ? params.profile.trim() : "";
100
+ const allowedProfiles = proxyConfig.allowProfiles;
101
+ if (allowedProfiles.length > 0) {
102
+ if (pathValue !== "/profiles") {
103
+ const profileToCheck = requestedProfile || resolved.defaultProfile;
104
+ if (!isProfileAllowed({ allowProfiles: allowedProfiles, profile: profileToCheck })) {
105
+ throw new Error("INVALID_REQUEST: browser profile not allowed");
106
+ }
107
+ }
108
+ else if (requestedProfile) {
109
+ if (!isProfileAllowed({ allowProfiles: allowedProfiles, profile: requestedProfile })) {
110
+ throw new Error("INVALID_REQUEST: browser profile not allowed");
111
+ }
112
+ }
113
+ }
114
+ const method = typeof params.method === "string" ? params.method.toUpperCase() : "GET";
115
+ const path = pathValue.startsWith("/") ? pathValue : `/${pathValue}`;
116
+ const body = params.body;
117
+ const query = {};
118
+ if (requestedProfile) {
119
+ query.profile = requestedProfile;
120
+ }
121
+ const rawQuery = params.query ?? {};
122
+ for (const [key, value] of Object.entries(rawQuery)) {
123
+ if (value === undefined || value === null) {
124
+ continue;
125
+ }
126
+ query[key] = typeof value === "string" ? value : String(value);
127
+ }
128
+ const dispatcher = createBrowserRouteDispatcher(createBrowserControlContext());
129
+ const response = await withTimeout((signal) => dispatcher.dispatch({
130
+ method: method === "DELETE" ? "DELETE" : method === "POST" ? "POST" : "GET",
131
+ path,
132
+ query,
133
+ body,
134
+ signal,
135
+ }), params.timeoutMs, "browser proxy request");
136
+ if (response.status >= 400) {
137
+ const message = response.body && typeof response.body === "object" && "error" in response.body
138
+ ? String(response.body.error)
139
+ : `HTTP ${response.status}`;
140
+ throw new Error(message);
141
+ }
142
+ const result = response.body;
143
+ if (allowedProfiles.length > 0 && path === "/profiles") {
144
+ const obj = typeof result === "object" && result !== null ? result : {};
145
+ const profiles = Array.isArray(obj.profiles) ? obj.profiles : [];
146
+ obj.profiles = profiles.filter((entry) => {
147
+ if (!entry || typeof entry !== "object") {
148
+ return false;
149
+ }
150
+ const name = entry.name;
151
+ return typeof name === "string" && allowedProfiles.includes(name);
152
+ });
153
+ }
154
+ let files;
155
+ const paths = collectBrowserProxyPaths(result);
156
+ if (paths.length > 0) {
157
+ const loaded = await Promise.all(paths.map(async (p) => {
158
+ try {
159
+ const file = await readBrowserProxyFile(p);
160
+ if (!file) {
161
+ throw new Error("file not found");
162
+ }
163
+ return file;
164
+ }
165
+ catch (err) {
166
+ throw new Error(`browser proxy file read failed for ${p}: ${String(err)}`, {
167
+ cause: err,
168
+ });
169
+ }
170
+ }));
171
+ if (loaded.length > 0) {
172
+ files = loaded;
173
+ }
174
+ }
175
+ const payload = files ? { result, files } : { result };
176
+ return JSON.stringify(payload);
177
+ }