@poolzin/pool-bot 2026.2.11 → 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 (535) hide show
  1. package/CHANGELOG.md +34 -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/usage.js +22 -0
  5. package/dist/agents/auth-profiles.js +1 -1
  6. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
  7. package/dist/agents/bash-tools.exec-runtime.js +438 -0
  8. package/dist/agents/bash-tools.shared.js +6 -0
  9. package/dist/agents/cli-runner/reliability.js +61 -0
  10. package/dist/agents/cli-watchdog-defaults.js +11 -0
  11. package/dist/agents/command-poll-backoff.js +63 -0
  12. package/dist/agents/current-time.js +16 -0
  13. package/dist/agents/glob-pattern.js +42 -0
  14. package/dist/agents/memory-search.js +33 -0
  15. package/dist/agents/model-alias-lines.js +18 -0
  16. package/dist/agents/model-auth-label.js +61 -0
  17. package/dist/agents/model-fallback.js +59 -8
  18. package/dist/agents/models-config.e2e-harness.js +115 -0
  19. package/dist/agents/ollama-stream.js +11 -3
  20. package/dist/agents/openclaw-tools.js +135 -0
  21. package/dist/agents/pi-auth-json.js +118 -0
  22. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
  23. package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
  24. package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
  25. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
  26. package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
  27. package/dist/agents/pi-tools.before-tool-call.js +145 -4
  28. package/dist/agents/pi-tools.js +29 -9
  29. package/dist/agents/pi-tools.policy.js +85 -92
  30. package/dist/agents/pi-tools.schema.js +54 -27
  31. package/dist/agents/queued-file-writer.js +22 -0
  32. package/dist/agents/sandbox/docker.js +133 -40
  33. package/dist/agents/sandbox/fs-bridge.js +146 -0
  34. package/dist/agents/sandbox/fs-paths.js +205 -0
  35. package/dist/agents/sandbox/hash.js +4 -0
  36. package/dist/agents/sandbox/validate-sandbox-security.js +157 -0
  37. package/dist/agents/sandbox-paths.js +3 -0
  38. package/dist/agents/sandbox-tool-policy.js +26 -0
  39. package/dist/agents/sanitize-for-prompt.js +18 -0
  40. package/dist/agents/session-dirs.js +20 -0
  41. package/dist/agents/session-write-lock.js +203 -39
  42. package/dist/agents/skills/filter.js +24 -0
  43. package/dist/agents/skills/tools-dir.js +9 -0
  44. package/dist/agents/skills-install-download.js +290 -0
  45. package/dist/agents/skills-install-output.js +30 -0
  46. package/dist/agents/skills-install.download-test-utils.js +36 -0
  47. package/dist/agents/skills.e2e-test-helpers.js +13 -0
  48. package/dist/agents/subagent-announce-queue.js +59 -15
  49. package/dist/agents/subagent-depth.js +137 -0
  50. package/dist/agents/subagent-registry.js +448 -96
  51. package/dist/agents/subagent-spawn.js +262 -0
  52. package/dist/agents/system-prompt.js +52 -10
  53. package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
  54. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
  55. package/dist/agents/tool-display-common.js +782 -0
  56. package/dist/agents/tool-loop-detection.js +466 -0
  57. package/dist/agents/tool-policy.js +6 -0
  58. package/dist/agents/tools/image-tool.js +1 -1
  59. package/dist/agents/tools/sessions-access.js +178 -0
  60. package/dist/agents/tools/sessions-resolution.js +206 -0
  61. package/dist/agents/tools/subagents-tool.js +616 -0
  62. package/dist/agents/workspace-dir.js +18 -0
  63. package/dist/agents/workspace-dirs.js +14 -0
  64. package/dist/agents/workspace.js +70 -0
  65. package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
  66. package/dist/auto-reply/reply/commands-export-session.js +163 -0
  67. package/dist/auto-reply/reply/commands-mesh.js +245 -0
  68. package/dist/auto-reply/reply/commands-setunset.js +28 -0
  69. package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
  70. package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
  71. package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
  72. package/dist/auto-reply/reply/directive-handling.params.js +1 -0
  73. package/dist/auto-reply/reply/directive-parsing.js +36 -0
  74. package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
  75. package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
  76. package/dist/auto-reply/reply/post-compaction-audit.js +96 -0
  77. package/dist/auto-reply/reply/post-compaction-context.js +98 -0
  78. package/dist/auto-reply/reply/reply-delivery.js +92 -0
  79. package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
  80. package/dist/auto-reply/reply/session-run-accounting.js +33 -0
  81. package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
  82. package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
  83. package/dist/browser/bridge-auth-registry.js +26 -0
  84. package/dist/browser/client-actions-url.js +10 -0
  85. package/dist/browser/control-auth.js +73 -0
  86. package/dist/browser/csrf.js +64 -0
  87. package/dist/browser/http-auth.js +52 -0
  88. package/dist/browser/paths.js +37 -0
  89. package/dist/browser/proxy-files.js +32 -0
  90. package/dist/browser/pw-ai-state.js +7 -0
  91. package/dist/browser/resolved-config-refresh.js +42 -0
  92. package/dist/browser/routes/path-output.js +1 -0
  93. package/dist/browser/server-context.chrome-test-harness.js +20 -0
  94. package/dist/browser/server-middleware.js +31 -0
  95. package/dist/browser/test-port.js +16 -0
  96. package/dist/build-info.json +3 -3
  97. package/dist/canvas-host/file-resolver.js +43 -0
  98. package/dist/channels/account-summary.js +19 -0
  99. package/dist/channels/draft-stream-loop.js +77 -0
  100. package/dist/channels/plugins/account-helpers.js +26 -0
  101. package/dist/channels/telegram/allow-from.js +10 -0
  102. package/dist/cli/browser-cli-resize.js +22 -0
  103. package/dist/cli/browser-cli-shared.js +8 -0
  104. package/dist/cli/clawbot-cli.js +5 -0
  105. package/dist/cli/completion-cli.js +566 -0
  106. package/dist/cli/config-cli.js +63 -5
  107. package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
  108. package/dist/cli/daemon-cli/register-service-commands.js +60 -0
  109. package/dist/cli/daemon-cli-compat.js +80 -0
  110. package/dist/cli/nodes-cli/pairing-render.js +26 -0
  111. package/dist/cli/program/action-reparse.js +17 -0
  112. package/dist/cli/program/command-registry.js +17 -0
  113. package/dist/cli/program/program-context.js +8 -0
  114. package/dist/cli/program/register.subclis.js +7 -0
  115. package/dist/cli/program/routes.js +233 -0
  116. package/dist/cli/qr-cli.js +132 -0
  117. package/dist/cli/requirements-test-fixtures.js +17 -0
  118. package/dist/cli/respawn-policy.js +4 -0
  119. package/dist/cli/shared/parse-port.js +18 -0
  120. package/dist/cli/skills-cli.format.js +241 -0
  121. package/dist/cli/update-cli/progress.js +121 -0
  122. package/dist/cli/update-cli/restart-helper.js +108 -0
  123. package/dist/cli/update-cli/shared.js +196 -0
  124. package/dist/cli/update-cli/status.js +97 -0
  125. package/dist/cli/update-cli/suppress-deprecations.js +17 -0
  126. package/dist/cli/update-cli/update-command.js +506 -0
  127. package/dist/cli/update-cli/wizard.js +130 -0
  128. package/dist/cli/update-cli.js +3 -9
  129. package/dist/cli/windows-argv.js +69 -0
  130. package/dist/commands/auth-choice-legacy.js +20 -0
  131. package/dist/commands/auth-choice.apply-helpers.js +8 -0
  132. package/dist/commands/channel-test-helpers.js +19 -0
  133. package/dist/commands/cleanup-plan.js +10 -0
  134. package/dist/commands/cleanup-utils.js +7 -0
  135. package/dist/commands/config-validation.js +15 -0
  136. package/dist/commands/doctor-completion.js +112 -0
  137. package/dist/commands/doctor-memory-search.js +119 -0
  138. package/dist/commands/doctor-session-locks.js +73 -0
  139. package/dist/commands/doctor.e2e-harness.js +364 -0
  140. package/dist/commands/gateway-presence.js +19 -0
  141. package/dist/commands/model-default.js +35 -0
  142. package/dist/commands/models/fallbacks-shared.js +102 -0
  143. package/dist/commands/models/shared.js +24 -0
  144. package/dist/commands/onboard-auth.config-gateways.js +64 -0
  145. package/dist/commands/onboard-auth.config-litellm.js +45 -0
  146. package/dist/commands/onboard-auth.config-shared.js +116 -0
  147. package/dist/commands/onboard-config.js +16 -0
  148. package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
  149. package/dist/commands/onboard-provider-auth-flags.js +136 -0
  150. package/dist/commands/openai-codex-oauth.js +40 -0
  151. package/dist/commands/test-runtime-config-helpers.js +21 -0
  152. package/dist/commands/test-wizard-helpers.js +68 -0
  153. package/dist/commands/vllm-setup.js +66 -0
  154. package/dist/compat/legacy-names.js +2 -0
  155. package/dist/config/backup-rotation.js +19 -0
  156. package/dist/config/env-preserve.js +122 -0
  157. package/dist/config/includes-scan.js +78 -0
  158. package/dist/config/plugins-allowlist.js +13 -0
  159. package/dist/config/schema.help.js +256 -0
  160. package/dist/config/schema.hints.js +189 -0
  161. package/dist/config/schema.irc.js +20 -0
  162. package/dist/config/schema.labels.js +317 -0
  163. package/dist/config/sessions/delivery-info.js +40 -0
  164. package/dist/config/types.irc.js +1 -0
  165. package/dist/config/zod-schema.agent-defaults.js +14 -0
  166. package/dist/config/zod-schema.agent-model.js +10 -0
  167. package/dist/config/zod-schema.agent-runtime.js +14 -0
  168. package/dist/config/zod-schema.allowdeny.js +35 -0
  169. package/dist/config/zod-schema.sensitive.js +4 -0
  170. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  171. package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
  172. package/dist/cron/isolated-agent/subagent-followup.js +127 -0
  173. package/dist/cron/isolated-agent.mocks.js +12 -0
  174. package/dist/cron/isolated-agent.test-setup.js +22 -0
  175. package/dist/cron/legacy-delivery.js +43 -0
  176. package/dist/cron/webhook-url.js +22 -0
  177. package/dist/daemon/arg-split.js +40 -0
  178. package/dist/daemon/exec-file.js +23 -0
  179. package/dist/daemon/output.js +6 -0
  180. package/dist/daemon/runtime-format.js +31 -0
  181. package/dist/daemon/schtasks-exec.js +4 -0
  182. package/dist/daemon/service-audit.js +22 -0
  183. package/dist/discord/client.js +41 -0
  184. package/dist/discord/components-registry.js +57 -0
  185. package/dist/discord/components.js +816 -0
  186. package/dist/discord/guilds.js +12 -0
  187. package/dist/discord/monitor/gateway-plugin.js +48 -0
  188. package/dist/discord/monitor/presence.js +30 -0
  189. package/dist/discord/send.components.js +115 -0
  190. package/dist/discord/send.shared.js +4 -0
  191. package/dist/discord/ui.js +26 -0
  192. package/dist/discord/voice-message.js +254 -0
  193. package/dist/gateway/agent-event-assistant-text.js +5 -0
  194. package/dist/gateway/agent-prompt.js +33 -0
  195. package/dist/gateway/auth-rate-limit.js +136 -0
  196. package/dist/gateway/channel-health-monitor.js +114 -0
  197. package/dist/gateway/control-ui-contract.js +1 -0
  198. package/dist/gateway/control-ui-csp.js +15 -0
  199. package/dist/gateway/gateway-config-prompts.shared.js +25 -0
  200. package/dist/gateway/http-auth-helpers.js +18 -0
  201. package/dist/gateway/http-common.js +18 -0
  202. package/dist/gateway/http-endpoint-helpers.js +27 -0
  203. package/dist/gateway/node-invoke-sanitize.js +11 -0
  204. package/dist/gateway/node-invoke-system-run-approval.js +205 -0
  205. package/dist/gateway/probe-auth.js +21 -0
  206. package/dist/gateway/protocol/index.js +7 -2
  207. package/dist/gateway/protocol/schema/mesh.js +54 -0
  208. package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
  209. package/dist/gateway/protocol/schema.js +1 -0
  210. package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
  211. package/dist/gateway/server-channels.js +11 -0
  212. package/dist/gateway/server-methods/attachment-normalize.js +16 -0
  213. package/dist/gateway/server-methods/base-hash.js +8 -0
  214. package/dist/gateway/server-methods/mesh.js +700 -0
  215. package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
  216. package/dist/gateway/server-methods/restart-request.js +13 -0
  217. package/dist/gateway/server-methods/validation.js +8 -0
  218. package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
  219. package/dist/gateway/server.e2e-registry-helpers.js +1 -0
  220. package/dist/gateway/server.e2e-ws-harness.js +20 -0
  221. package/dist/gateway/test-helpers.js +2 -0
  222. package/dist/gateway/test-helpers.server.js +3 -1
  223. package/dist/gateway/test-http-response.js +12 -0
  224. package/dist/gateway/test-openai-responses-model.js +20 -0
  225. package/dist/gateway/test-temp-config.js +30 -0
  226. package/dist/gateway/test-with-server.js +32 -0
  227. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
  228. package/dist/imessage/monitor/abort-handler.js +23 -0
  229. package/dist/imessage/monitor/inbound-processing.js +346 -0
  230. package/dist/imessage/monitor/parse-notification.js +64 -0
  231. package/dist/imessage/target-parsing-helpers.js +92 -0
  232. package/dist/infra/archive.js +244 -20
  233. package/dist/infra/detect-package-manager.js +26 -0
  234. package/dist/infra/exec-approvals-allowlist.js +257 -0
  235. package/dist/infra/exec-approvals-analysis.js +770 -0
  236. package/dist/infra/exec-approvals.js +13 -0
  237. package/dist/infra/file-lock.js +1 -0
  238. package/dist/infra/gemini-auth.js +39 -0
  239. package/dist/infra/heartbeat-active-hours.js +85 -0
  240. package/dist/infra/heartbeat-events-filter.js +50 -0
  241. package/dist/infra/heartbeat-runner.test-utils.js +39 -0
  242. package/dist/infra/http-body.js +265 -0
  243. package/dist/infra/install-package-dir.js +50 -0
  244. package/dist/infra/install-safe-path.js +49 -0
  245. package/dist/infra/json-files.js +49 -0
  246. package/dist/infra/jsonl-socket.js +52 -0
  247. package/dist/infra/map-size.js +14 -0
  248. package/dist/infra/net/hostname.js +7 -0
  249. package/dist/infra/npm-registry-spec.js +39 -0
  250. package/dist/infra/openclaw-root.js +109 -0
  251. package/dist/infra/outbound/delivery-queue.js +214 -0
  252. package/dist/infra/outbound/identity.js +23 -0
  253. package/dist/infra/outbound/message-action-params.js +307 -0
  254. package/dist/infra/outbound/tool-payload.js +21 -0
  255. package/dist/infra/package-json.js +23 -0
  256. package/dist/infra/pairing-files.js +19 -0
  257. package/dist/infra/pairing-token.js +9 -0
  258. package/dist/infra/path-prepend.js +51 -0
  259. package/dist/infra/path-safety.js +16 -0
  260. package/dist/infra/process-respawn.js +49 -0
  261. package/dist/infra/runtime-status.js +16 -0
  262. package/dist/infra/session-cost-usage.types.js +1 -0
  263. package/dist/infra/session-maintenance-warning.js +89 -0
  264. package/dist/infra/system-run-command.js +78 -0
  265. package/dist/infra/tmp-openclaw-dir.js +81 -0
  266. package/dist/infra/tmp-poolbot-dir.js +2 -0
  267. package/dist/infra/update-channels.js +19 -0
  268. package/dist/line/actions.js +45 -0
  269. package/dist/line/channel-access-token.js +9 -0
  270. package/dist/line/flex-templates/basic-cards.js +332 -0
  271. package/dist/line/flex-templates/common.js +18 -0
  272. package/dist/line/flex-templates/media-control-cards.js +453 -0
  273. package/dist/line/flex-templates/message.js +10 -0
  274. package/dist/line/flex-templates/schedule-cards.js +399 -0
  275. package/dist/line/flex-templates/types.js +1 -0
  276. package/dist/line/webhook-node.js +100 -0
  277. package/dist/line/webhook-utils.js +11 -0
  278. package/dist/logging/diagnostic-session-state.js +73 -0
  279. package/dist/logging/diagnostic.js +22 -0
  280. package/dist/logging/timestamps.js +14 -0
  281. package/dist/markdown/whatsapp.js +62 -0
  282. package/dist/media/base64.js +34 -0
  283. package/dist/media/local-roots.js +32 -0
  284. package/dist/media/outbound-attachment.js +10 -0
  285. package/dist/media/read-response-with-limit.js +41 -0
  286. package/dist/media/sniff-mime-from-base64.js +19 -0
  287. package/dist/media-understanding/audio-preflight.js +67 -0
  288. package/dist/media-understanding/fs.js +13 -0
  289. package/dist/media-understanding/output-extract.js +26 -0
  290. package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
  291. package/dist/media-understanding/providers/google/inline-data.js +64 -0
  292. package/dist/media-understanding/providers/shared.js +7 -0
  293. package/dist/media-understanding/runner.entries.js +459 -0
  294. package/dist/memory/batch-error-utils.js +11 -0
  295. package/dist/memory/batch-http.js +27 -0
  296. package/dist/memory/batch-output.js +29 -0
  297. package/dist/memory/batch-runner.js +22 -0
  298. package/dist/memory/batch-upload.js +23 -0
  299. package/dist/memory/batch-utils.js +26 -0
  300. package/dist/memory/embeddings-debug.js +11 -0
  301. package/dist/memory/embeddings-remote-client.js +22 -0
  302. package/dist/memory/embeddings-remote-fetch.js +14 -0
  303. package/dist/memory/embeddings.js +36 -9
  304. package/dist/memory/hybrid.js +24 -5
  305. package/dist/memory/manager-embedding-ops.js +616 -0
  306. package/dist/memory/manager-sync-ops.js +953 -0
  307. package/dist/memory/manager.js +76 -28
  308. package/dist/memory/mmr.js +164 -0
  309. package/dist/memory/qmd-manager.js +1061 -0
  310. package/dist/memory/qmd-query-parser.js +107 -0
  311. package/dist/memory/qmd-scope.js +93 -0
  312. package/dist/memory/query-expansion.js +331 -0
  313. package/dist/memory/search-manager.js +0 -1
  314. package/dist/memory/sync-index.js +21 -0
  315. package/dist/memory/sync-progress.js +22 -0
  316. package/dist/memory/sync-stale.js +30 -0
  317. package/dist/memory/temporal-decay.js +119 -0
  318. package/dist/memory/test-embeddings-mock.js +16 -0
  319. package/dist/memory/test-manager-helpers.js +14 -0
  320. package/dist/memory/test-runtime-mocks.js +11 -0
  321. package/dist/node-host/invoke-browser.js +177 -0
  322. package/dist/node-host/invoke.js +685 -0
  323. package/dist/pairing/setup-code.js +285 -0
  324. package/dist/plugin-sdk/account-id.js +1 -0
  325. package/dist/plugin-sdk/agent-media-payload.js +13 -0
  326. package/dist/plugin-sdk/allow-from.js +47 -0
  327. package/dist/plugin-sdk/command-auth.js +23 -0
  328. package/dist/plugin-sdk/config-paths.js +9 -0
  329. package/dist/plugin-sdk/file-lock.js +116 -0
  330. package/dist/plugin-sdk/json-store.js +31 -0
  331. package/dist/plugin-sdk/onboarding.js +28 -0
  332. package/dist/plugin-sdk/provider-auth-result.js +29 -0
  333. package/dist/plugin-sdk/slack-message-actions.js +133 -0
  334. package/dist/plugin-sdk/status-helpers.js +35 -0
  335. package/dist/plugin-sdk/text-chunking.js +31 -0
  336. package/dist/plugin-sdk/tool-send.js +12 -0
  337. package/dist/plugin-sdk/webhook-path.js +27 -0
  338. package/dist/plugin-sdk/webhook-targets.js +34 -0
  339. package/dist/plugins/hooks.test-helpers.js +21 -0
  340. package/dist/plugins/uninstall.js +171 -0
  341. package/dist/process/kill-tree.js +98 -0
  342. package/dist/process/supervisor/adapters/child.js +143 -0
  343. package/dist/process/supervisor/adapters/env.js +13 -0
  344. package/dist/process/supervisor/adapters/pty.js +148 -0
  345. package/dist/process/supervisor/index.js +10 -0
  346. package/dist/process/supervisor/registry.js +117 -0
  347. package/dist/process/supervisor/supervisor.js +244 -0
  348. package/dist/process/supervisor/types.js +1 -0
  349. package/dist/providers/google-shared.test-helpers.js +75 -0
  350. package/dist/security/audit-channel.js +419 -0
  351. package/dist/security/audit-tool-policy.js +1 -0
  352. package/dist/security/scan-paths.js +12 -0
  353. package/dist/sessions/input-provenance.js +55 -0
  354. package/dist/sessions/session-key-utils.js +7 -0
  355. package/dist/shared/chat-content.js +31 -0
  356. package/dist/shared/chat-envelope.js +45 -0
  357. package/dist/shared/config-eval.js +117 -0
  358. package/dist/shared/device-auth.js +16 -0
  359. package/dist/shared/entry-metadata.js +9 -0
  360. package/dist/shared/entry-status.js +25 -0
  361. package/dist/shared/frontmatter.js +98 -0
  362. package/dist/shared/model-param-b.js +19 -0
  363. package/dist/shared/net/ipv4.js +17 -0
  364. package/dist/shared/node-match.js +53 -0
  365. package/dist/shared/pid-alive.js +12 -0
  366. package/dist/shared/process-scoped-map.js +10 -0
  367. package/dist/shared/requirements.js +128 -0
  368. package/dist/shared/subagents-format.js +84 -0
  369. package/dist/shared/usage-aggregates.js +28 -0
  370. package/dist/signal/monitor/mentions.js +45 -0
  371. package/dist/signal/rpc-context.js +19 -0
  372. package/dist/slack/blocks-fallback.js +76 -0
  373. package/dist/slack/blocks-input.js +40 -0
  374. package/dist/slack/draft-stream.js +106 -0
  375. package/dist/slack/message-actions.js +51 -0
  376. package/dist/slack/modal-metadata.js +32 -0
  377. package/dist/slack/monitor/events/interactions.js +462 -0
  378. package/dist/slack/monitor/room-context.js +17 -0
  379. package/dist/slack/stream-mode.js +41 -0
  380. package/dist/telegram/bot-native-command-menu.js +64 -0
  381. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  382. package/dist/telegram/button-types.js +1 -0
  383. package/dist/telegram/group-access.js +65 -0
  384. package/dist/telegram/outbound-params.js +21 -0
  385. package/dist/telegram/poll-vote-cache.js +21 -0
  386. package/dist/terminal/health-style.js +36 -0
  387. package/dist/test-utils/chunk-test-helpers.js +21 -0
  388. package/dist/test-utils/env.js +72 -0
  389. package/dist/test-utils/exec-assertions.js +12 -0
  390. package/dist/test-utils/imessage-test-plugin.js +54 -0
  391. package/dist/test-utils/mock-http-response.js +17 -0
  392. package/dist/test-utils/vitest-mock-fn.js +1 -0
  393. package/dist/tts/tts-core.js +550 -0
  394. package/dist/utils/chunk-items.js +10 -0
  395. package/dist/utils/reaction-level.js +52 -0
  396. package/dist/utils/safe-json.js +22 -0
  397. package/dist/utils/with-timeout.js +14 -0
  398. package/dist/web/media.js +17 -5
  399. package/dist/whatsapp/resolve-outbound-target.js +42 -0
  400. package/dist/wizard/onboarding.completion.js +74 -0
  401. package/extensions/bluebubbles/package.json +1 -1
  402. package/extensions/bluebubbles/src/account-resolve.ts +29 -0
  403. package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
  404. package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
  405. package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
  406. package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
  407. package/extensions/bluebubbles/src/multipart.ts +32 -0
  408. package/extensions/bluebubbles/src/send-helpers.ts +53 -0
  409. package/extensions/bluebubbles/src/test-harness.ts +50 -0
  410. package/extensions/bluebubbles/src/test-mocks.ts +11 -0
  411. package/extensions/copilot-proxy/package.json +1 -1
  412. package/extensions/device-pair/index.ts +554 -0
  413. package/extensions/diagnostics-otel/package.json +1 -1
  414. package/extensions/discord/package.json +1 -1
  415. package/extensions/discord/src/channel.js +366 -0
  416. package/extensions/discord/src/runtime.js +10 -0
  417. package/extensions/feishu/index.ts +63 -0
  418. package/extensions/feishu/src/accounts.ts +114 -0
  419. package/extensions/feishu/src/bitable.ts +739 -0
  420. package/extensions/feishu/src/bot.ts +965 -0
  421. package/extensions/feishu/src/channel.ts +351 -0
  422. package/extensions/feishu/src/client.ts +118 -0
  423. package/extensions/feishu/src/config-schema.ts +206 -0
  424. package/extensions/feishu/src/dedup.ts +33 -0
  425. package/extensions/feishu/src/directory.ts +177 -0
  426. package/extensions/feishu/src/doc-schema.ts +47 -0
  427. package/extensions/feishu/src/docx.ts +536 -0
  428. package/extensions/feishu/src/drive-schema.ts +46 -0
  429. package/extensions/feishu/src/drive.ts +227 -0
  430. package/extensions/feishu/src/dynamic-agent.ts +131 -0
  431. package/extensions/feishu/src/media.ts +449 -0
  432. package/extensions/feishu/src/mention.ts +126 -0
  433. package/extensions/feishu/src/monitor.ts +330 -0
  434. package/extensions/feishu/src/onboarding.ts +359 -0
  435. package/extensions/feishu/src/outbound.ts +55 -0
  436. package/extensions/feishu/src/perm-schema.ts +52 -0
  437. package/extensions/feishu/src/perm.ts +173 -0
  438. package/extensions/feishu/src/policy.ts +84 -0
  439. package/extensions/feishu/src/probe.ts +44 -0
  440. package/extensions/feishu/src/reactions.ts +160 -0
  441. package/extensions/feishu/src/reply-dispatcher.ts +239 -0
  442. package/extensions/feishu/src/runtime.ts +14 -0
  443. package/extensions/feishu/src/send-result.ts +29 -0
  444. package/extensions/feishu/src/send.ts +335 -0
  445. package/extensions/feishu/src/streaming-card.ts +223 -0
  446. package/extensions/feishu/src/targets.ts +78 -0
  447. package/extensions/feishu/src/tools-config.ts +21 -0
  448. package/extensions/feishu/src/types.ts +81 -0
  449. package/extensions/feishu/src/typing.ts +80 -0
  450. package/extensions/feishu/src/wiki-schema.ts +55 -0
  451. package/extensions/feishu/src/wiki.ts +232 -0
  452. package/extensions/google-antigravity-auth/package.json +1 -1
  453. package/extensions/google-gemini-cli-auth/package.json +1 -1
  454. package/extensions/googlechat/package.json +1 -1
  455. package/extensions/imessage/package.json +1 -1
  456. package/extensions/imessage/src/channel.js +253 -0
  457. package/extensions/imessage/src/runtime.js +10 -0
  458. package/extensions/irc/index.ts +17 -0
  459. package/extensions/irc/src/accounts.ts +268 -0
  460. package/extensions/irc/src/channel.ts +367 -0
  461. package/extensions/irc/src/client.ts +439 -0
  462. package/extensions/irc/src/config-schema.ts +97 -0
  463. package/extensions/irc/src/connect-options.ts +30 -0
  464. package/extensions/irc/src/control-chars.ts +22 -0
  465. package/extensions/irc/src/inbound.ts +334 -0
  466. package/extensions/irc/src/monitor.ts +147 -0
  467. package/extensions/irc/src/normalize.ts +117 -0
  468. package/extensions/irc/src/onboarding.ts +479 -0
  469. package/extensions/irc/src/policy.ts +157 -0
  470. package/extensions/irc/src/probe.ts +53 -0
  471. package/extensions/irc/src/protocol.ts +169 -0
  472. package/extensions/irc/src/runtime.ts +14 -0
  473. package/extensions/irc/src/send.ts +88 -0
  474. package/extensions/irc/src/types.ts +93 -0
  475. package/extensions/line/package.json +1 -1
  476. package/extensions/llm-task/package.json +1 -1
  477. package/extensions/lobster/package.json +1 -1
  478. package/extensions/matrix/CHANGELOG.md +5 -0
  479. package/extensions/matrix/package.json +1 -1
  480. package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
  481. package/extensions/mattermost/package.json +1 -1
  482. package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
  483. package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
  484. package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
  485. package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
  486. package/extensions/memory-core/package.json +1 -1
  487. package/extensions/memory-lancedb/package.json +1 -1
  488. package/extensions/minimax-portal-auth/index.ts +161 -0
  489. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  490. package/extensions/msteams/CHANGELOG.md +5 -0
  491. package/extensions/msteams/package.json +1 -1
  492. package/extensions/msteams/src/file-lock.ts +1 -0
  493. package/extensions/msteams/src/graph.ts +92 -0
  494. package/extensions/msteams/src/mentions.ts +114 -0
  495. package/extensions/msteams/src/test-runtime.ts +16 -0
  496. package/extensions/nextcloud-talk/package.json +1 -1
  497. package/extensions/nostr/CHANGELOG.md +5 -0
  498. package/extensions/nostr/package.json +1 -1
  499. package/extensions/open-prose/package.json +1 -1
  500. package/extensions/openai-codex-auth/index.ts +177 -0
  501. package/extensions/phone-control/index.ts +421 -0
  502. package/extensions/shared/resolve-target-test-helpers.ts +66 -0
  503. package/extensions/signal/package.json +1 -1
  504. package/extensions/signal/src/channel.js +273 -0
  505. package/extensions/signal/src/runtime.js +10 -0
  506. package/extensions/slack/package.json +1 -1
  507. package/extensions/slack/src/channel.js +489 -0
  508. package/extensions/slack/src/runtime.js +10 -0
  509. package/extensions/talk-voice/index.ts +150 -0
  510. package/extensions/telegram/package.json +1 -1
  511. package/extensions/telegram/src/channel.js +424 -0
  512. package/extensions/telegram/src/runtime.js +10 -0
  513. package/extensions/thread-ownership/index.ts +133 -0
  514. package/extensions/tlon/package.json +1 -1
  515. package/extensions/tlon/src/account-fields.ts +25 -0
  516. package/extensions/tlon/src/urbit/base-url.ts +57 -0
  517. package/extensions/tlon/src/urbit/channel-client.ts +157 -0
  518. package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
  519. package/extensions/tlon/src/urbit/context.ts +47 -0
  520. package/extensions/tlon/src/urbit/errors.ts +51 -0
  521. package/extensions/tlon/src/urbit/fetch.ts +39 -0
  522. package/extensions/twitch/CHANGELOG.md +5 -0
  523. package/extensions/twitch/package.json +1 -1
  524. package/extensions/twitch/src/test-fixtures.ts +30 -0
  525. package/extensions/voice-call/CHANGELOG.md +5 -0
  526. package/extensions/voice-call/package.json +1 -1
  527. package/extensions/voice-call/src/allowlist.ts +19 -0
  528. package/extensions/whatsapp/package.json +1 -1
  529. package/extensions/whatsapp/src/channel.js +429 -0
  530. package/extensions/whatsapp/src/runtime.js +10 -0
  531. package/extensions/zalo/CHANGELOG.md +5 -0
  532. package/extensions/zalo/package.json +1 -1
  533. package/extensions/zalouser/CHANGELOG.md +5 -0
  534. package/extensions/zalouser/package.json +1 -1
  535. package/package.json +1 -1
@@ -0,0 +1,116 @@
1
+ function extractAgentDefaultModelFallbacks(model) {
2
+ if (!model || typeof model !== "object") {
3
+ return undefined;
4
+ }
5
+ if (!("fallbacks" in model)) {
6
+ return undefined;
7
+ }
8
+ const fallbacks = model.fallbacks;
9
+ return Array.isArray(fallbacks) ? fallbacks.map((v) => String(v)) : undefined;
10
+ }
11
+ export function applyOnboardAuthAgentModelsAndProviders(cfg, params) {
12
+ return {
13
+ ...cfg,
14
+ agents: {
15
+ ...cfg.agents,
16
+ defaults: {
17
+ ...cfg.agents?.defaults,
18
+ models: params.agentModels,
19
+ },
20
+ },
21
+ models: {
22
+ mode: cfg.models?.mode ?? "merge",
23
+ providers: params.providers,
24
+ },
25
+ };
26
+ }
27
+ export function applyAgentDefaultModelPrimary(cfg, primary) {
28
+ const existingFallbacks = extractAgentDefaultModelFallbacks(cfg.agents?.defaults?.model);
29
+ return {
30
+ ...cfg,
31
+ agents: {
32
+ ...cfg.agents,
33
+ defaults: {
34
+ ...cfg.agents?.defaults,
35
+ model: {
36
+ ...(existingFallbacks ? { fallbacks: existingFallbacks } : undefined),
37
+ primary,
38
+ },
39
+ },
40
+ },
41
+ };
42
+ }
43
+ export function applyProviderConfigWithDefaultModels(cfg, params) {
44
+ const providers = { ...cfg.models?.providers };
45
+ const existingProvider = providers[params.providerId];
46
+ const existingModels = Array.isArray(existingProvider?.models)
47
+ ? existingProvider.models
48
+ : [];
49
+ const defaultModels = params.defaultModels;
50
+ const defaultModelId = params.defaultModelId ?? defaultModels[0]?.id;
51
+ const hasDefaultModel = defaultModelId
52
+ ? existingModels.some((model) => model.id === defaultModelId)
53
+ : true;
54
+ const mergedModels = existingModels.length > 0
55
+ ? hasDefaultModel || defaultModels.length === 0
56
+ ? existingModels
57
+ : [...existingModels, ...defaultModels]
58
+ : defaultModels;
59
+ providers[params.providerId] = buildProviderConfig({
60
+ existingProvider,
61
+ api: params.api,
62
+ baseUrl: params.baseUrl,
63
+ mergedModels,
64
+ fallbackModels: defaultModels,
65
+ });
66
+ return applyOnboardAuthAgentModelsAndProviders(cfg, {
67
+ agentModels: params.agentModels,
68
+ providers,
69
+ });
70
+ }
71
+ export function applyProviderConfigWithDefaultModel(cfg, params) {
72
+ return applyProviderConfigWithDefaultModels(cfg, {
73
+ agentModels: params.agentModels,
74
+ providerId: params.providerId,
75
+ api: params.api,
76
+ baseUrl: params.baseUrl,
77
+ defaultModels: [params.defaultModel],
78
+ defaultModelId: params.defaultModelId ?? params.defaultModel.id,
79
+ });
80
+ }
81
+ export function applyProviderConfigWithModelCatalog(cfg, params) {
82
+ const providers = { ...cfg.models?.providers };
83
+ const existingProvider = providers[params.providerId];
84
+ const existingModels = Array.isArray(existingProvider?.models)
85
+ ? existingProvider.models
86
+ : [];
87
+ const catalogModels = params.catalogModels;
88
+ const mergedModels = existingModels.length > 0
89
+ ? [
90
+ ...existingModels,
91
+ ...catalogModels.filter((model) => !existingModels.some((existing) => existing.id === model.id)),
92
+ ]
93
+ : catalogModels;
94
+ providers[params.providerId] = buildProviderConfig({
95
+ existingProvider,
96
+ api: params.api,
97
+ baseUrl: params.baseUrl,
98
+ mergedModels,
99
+ fallbackModels: catalogModels,
100
+ });
101
+ return applyOnboardAuthAgentModelsAndProviders(cfg, {
102
+ agentModels: params.agentModels,
103
+ providers,
104
+ });
105
+ }
106
+ function buildProviderConfig(params) {
107
+ const { apiKey: existingApiKey, ...existingProviderRest } = (params.existingProvider ?? {});
108
+ const normalizedApiKey = typeof existingApiKey === "string" ? existingApiKey.trim() : undefined;
109
+ return {
110
+ ...existingProviderRest,
111
+ baseUrl: params.baseUrl,
112
+ api: params.api,
113
+ ...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
114
+ models: params.mergedModels.length > 0 ? params.mergedModels : params.fallbackModels,
115
+ };
116
+ }
@@ -0,0 +1,16 @@
1
+ export function applyOnboardingLocalWorkspaceConfig(baseConfig, workspaceDir) {
2
+ return {
3
+ ...baseConfig,
4
+ agents: {
5
+ ...baseConfig.agents,
6
+ defaults: {
7
+ ...baseConfig.agents?.defaults,
8
+ workspace: workspaceDir,
9
+ },
10
+ },
11
+ gateway: {
12
+ ...baseConfig.gateway,
13
+ mode: "local",
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,31 @@
1
+ import fs from "node:fs/promises";
2
+ const NON_INTERACTIVE_DEFAULT_OPTIONS = {
3
+ nonInteractive: true,
4
+ skipHealth: true,
5
+ skipChannels: true,
6
+ json: true,
7
+ };
8
+ export function createThrowingRuntime() {
9
+ return {
10
+ log: () => { },
11
+ error: (...args) => {
12
+ throw new Error(args.map(String).join(" "));
13
+ },
14
+ exit: (code) => {
15
+ throw new Error(`exit:${code}`);
16
+ },
17
+ };
18
+ }
19
+ export async function runNonInteractiveOnboarding(options, runtime) {
20
+ const { runNonInteractiveOnboarding: run } = await import("./onboard-non-interactive.js");
21
+ await run(options, runtime);
22
+ }
23
+ export async function runNonInteractiveOnboardingWithDefaults(runtime, options) {
24
+ await runNonInteractiveOnboarding({
25
+ ...NON_INTERACTIVE_DEFAULT_OPTIONS,
26
+ ...options,
27
+ }, runtime);
28
+ }
29
+ export async function readJsonFile(filePath) {
30
+ return JSON.parse(await fs.readFile(filePath, "utf8"));
31
+ }
@@ -0,0 +1,136 @@
1
+ // Shared source for provider API-key flags used by CLI registration + non-interactive inference.
2
+ export const ONBOARD_PROVIDER_AUTH_FLAGS = [
3
+ {
4
+ optionKey: "anthropicApiKey",
5
+ authChoice: "apiKey",
6
+ cliFlag: "--anthropic-api-key",
7
+ cliOption: "--anthropic-api-key <key>",
8
+ description: "Anthropic API key",
9
+ },
10
+ {
11
+ optionKey: "openaiApiKey",
12
+ authChoice: "openai-api-key",
13
+ cliFlag: "--openai-api-key",
14
+ cliOption: "--openai-api-key <key>",
15
+ description: "OpenAI API key",
16
+ },
17
+ {
18
+ optionKey: "openrouterApiKey",
19
+ authChoice: "openrouter-api-key",
20
+ cliFlag: "--openrouter-api-key",
21
+ cliOption: "--openrouter-api-key <key>",
22
+ description: "OpenRouter API key",
23
+ },
24
+ {
25
+ optionKey: "aiGatewayApiKey",
26
+ authChoice: "ai-gateway-api-key",
27
+ cliFlag: "--ai-gateway-api-key",
28
+ cliOption: "--ai-gateway-api-key <key>",
29
+ description: "Vercel AI Gateway API key",
30
+ },
31
+ {
32
+ optionKey: "cloudflareAiGatewayApiKey",
33
+ authChoice: "cloudflare-ai-gateway-api-key",
34
+ cliFlag: "--cloudflare-ai-gateway-api-key",
35
+ cliOption: "--cloudflare-ai-gateway-api-key <key>",
36
+ description: "Cloudflare AI Gateway API key",
37
+ },
38
+ {
39
+ optionKey: "moonshotApiKey",
40
+ authChoice: "moonshot-api-key",
41
+ cliFlag: "--moonshot-api-key",
42
+ cliOption: "--moonshot-api-key <key>",
43
+ description: "Moonshot API key",
44
+ },
45
+ {
46
+ optionKey: "kimiCodeApiKey",
47
+ authChoice: "kimi-code-api-key",
48
+ cliFlag: "--kimi-code-api-key",
49
+ cliOption: "--kimi-code-api-key <key>",
50
+ description: "Kimi Coding API key",
51
+ },
52
+ {
53
+ optionKey: "geminiApiKey",
54
+ authChoice: "gemini-api-key",
55
+ cliFlag: "--gemini-api-key",
56
+ cliOption: "--gemini-api-key <key>",
57
+ description: "Gemini API key",
58
+ },
59
+ {
60
+ optionKey: "zaiApiKey",
61
+ authChoice: "zai-api-key",
62
+ cliFlag: "--zai-api-key",
63
+ cliOption: "--zai-api-key <key>",
64
+ description: "Z.AI API key",
65
+ },
66
+ {
67
+ optionKey: "xiaomiApiKey",
68
+ authChoice: "xiaomi-api-key",
69
+ cliFlag: "--xiaomi-api-key",
70
+ cliOption: "--xiaomi-api-key <key>",
71
+ description: "Xiaomi API key",
72
+ },
73
+ {
74
+ optionKey: "minimaxApiKey",
75
+ authChoice: "minimax-api",
76
+ cliFlag: "--minimax-api-key",
77
+ cliOption: "--minimax-api-key <key>",
78
+ description: "MiniMax API key",
79
+ },
80
+ {
81
+ optionKey: "syntheticApiKey",
82
+ authChoice: "synthetic-api-key",
83
+ cliFlag: "--synthetic-api-key",
84
+ cliOption: "--synthetic-api-key <key>",
85
+ description: "Synthetic API key",
86
+ },
87
+ {
88
+ optionKey: "veniceApiKey",
89
+ authChoice: "venice-api-key",
90
+ cliFlag: "--venice-api-key",
91
+ cliOption: "--venice-api-key <key>",
92
+ description: "Venice API key",
93
+ },
94
+ {
95
+ optionKey: "togetherApiKey",
96
+ authChoice: "together-api-key",
97
+ cliFlag: "--together-api-key",
98
+ cliOption: "--together-api-key <key>",
99
+ description: "Together AI API key",
100
+ },
101
+ {
102
+ optionKey: "huggingfaceApiKey",
103
+ authChoice: "huggingface-api-key",
104
+ cliFlag: "--huggingface-api-key",
105
+ cliOption: "--huggingface-api-key <key>",
106
+ description: "Hugging Face API key (HF token)",
107
+ },
108
+ {
109
+ optionKey: "opencodeZenApiKey",
110
+ authChoice: "opencode-zen",
111
+ cliFlag: "--opencode-zen-api-key",
112
+ cliOption: "--opencode-zen-api-key <key>",
113
+ description: "OpenCode Zen API key",
114
+ },
115
+ {
116
+ optionKey: "xaiApiKey",
117
+ authChoice: "xai-api-key",
118
+ cliFlag: "--xai-api-key",
119
+ cliOption: "--xai-api-key <key>",
120
+ description: "xAI API key",
121
+ },
122
+ {
123
+ optionKey: "litellmApiKey",
124
+ authChoice: "litellm-api-key",
125
+ cliFlag: "--litellm-api-key",
126
+ cliOption: "--litellm-api-key <key>",
127
+ description: "LiteLLM API key",
128
+ },
129
+ {
130
+ optionKey: "qianfanApiKey",
131
+ authChoice: "qianfan-api-key",
132
+ cliFlag: "--qianfan-api-key",
133
+ cliOption: "--qianfan-api-key <key>",
134
+ description: "QIANFAN API key",
135
+ },
136
+ ];
@@ -0,0 +1,40 @@
1
+ import { loginOpenAICodex } from "@mariozechner/pi-ai";
2
+ import { createVpsAwareOAuthHandlers } from "./oauth-flow.js";
3
+ export async function loginOpenAICodexOAuth(params) {
4
+ const { prompter, runtime, isRemote, openUrl, localBrowserMessage } = params;
5
+ await prompter.note(isRemote
6
+ ? [
7
+ "You are running in a remote/VPS environment.",
8
+ "A URL will be shown for you to open in your LOCAL browser.",
9
+ "After signing in, paste the redirect URL back here.",
10
+ ].join("\n")
11
+ : [
12
+ "Browser will open for OpenAI authentication.",
13
+ "If the callback doesn't auto-complete, paste the redirect URL.",
14
+ "OpenAI OAuth uses localhost:1455 for the callback.",
15
+ ].join("\n"), "OpenAI Codex OAuth");
16
+ const spin = prompter.progress("Starting OAuth flow…");
17
+ try {
18
+ const { onAuth, onPrompt } = createVpsAwareOAuthHandlers({
19
+ isRemote,
20
+ prompter,
21
+ runtime,
22
+ spin,
23
+ openUrl,
24
+ localBrowserMessage: localBrowserMessage ?? "Complete sign-in in browser…",
25
+ });
26
+ const creds = await loginOpenAICodex({
27
+ onAuth,
28
+ onPrompt,
29
+ onProgress: (msg) => spin.update(msg),
30
+ });
31
+ spin.stop("OpenAI OAuth complete");
32
+ return creds ?? null;
33
+ }
34
+ catch (err) {
35
+ spin.stop("OpenAI OAuth failed");
36
+ runtime.error(String(err));
37
+ await prompter.note("Trouble with OAuth? See https://docs.openclaw.ai/start/faq", "OAuth help");
38
+ throw err;
39
+ }
40
+ }
@@ -0,0 +1,21 @@
1
+ import { vi } from "vitest";
2
+ export const baseConfigSnapshot = {
3
+ path: "/tmp/poolbot.json",
4
+ exists: true,
5
+ raw: "{}",
6
+ parsed: {},
7
+ valid: true,
8
+ config: {},
9
+ issues: [],
10
+ legacyIssues: [],
11
+ };
12
+ export function createTestRuntime() {
13
+ const log = vi.fn();
14
+ const error = vi.fn();
15
+ const exit = vi.fn((_) => undefined);
16
+ return {
17
+ log,
18
+ error,
19
+ exit,
20
+ };
21
+ }
@@ -0,0 +1,68 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { vi } from "vitest";
4
+ import { makeTempWorkspace } from "../test-helpers/workspace.js";
5
+ import { captureEnv } from "../test-utils/env.js";
6
+ export const noopAsync = async () => { };
7
+ export const noop = () => { };
8
+ export function createExitThrowingRuntime() {
9
+ return {
10
+ log: vi.fn(),
11
+ error: vi.fn(),
12
+ exit: vi.fn((code) => {
13
+ throw new Error(`exit:${code}`);
14
+ }),
15
+ };
16
+ }
17
+ export function createWizardPrompter(overrides, options) {
18
+ return {
19
+ intro: vi.fn(noopAsync),
20
+ outro: vi.fn(noopAsync),
21
+ note: vi.fn(noopAsync),
22
+ select: vi.fn(async () => (options?.defaultSelect ?? "")),
23
+ multiselect: vi.fn(async () => []),
24
+ text: vi.fn(async () => ""),
25
+ confirm: vi.fn(async () => false),
26
+ progress: vi.fn(() => ({ update: noop, stop: noop })),
27
+ ...overrides,
28
+ };
29
+ }
30
+ export async function setupAuthTestEnv(prefix = "openclaw-auth-", options) {
31
+ const stateDir = await makeTempWorkspace(prefix);
32
+ const agentDir = path.join(stateDir, options?.agentSubdir ?? "agent");
33
+ process.env.POOLBOT_STATE_DIR = stateDir;
34
+ process.env.POOLBOT_AGENT_DIR = agentDir;
35
+ process.env.PI_CODING_AGENT_DIR = agentDir;
36
+ await fs.mkdir(agentDir, { recursive: true });
37
+ return { stateDir, agentDir };
38
+ }
39
+ export function createAuthTestLifecycle(envKeys) {
40
+ const envSnapshot = captureEnv(envKeys);
41
+ let stateDir = null;
42
+ return {
43
+ setStateDir(nextStateDir) {
44
+ stateDir = nextStateDir;
45
+ },
46
+ async cleanup() {
47
+ if (stateDir) {
48
+ await fs.rm(stateDir, { recursive: true, force: true });
49
+ stateDir = null;
50
+ }
51
+ envSnapshot.restore();
52
+ },
53
+ };
54
+ }
55
+ export function requireOpenClawAgentDir() {
56
+ const agentDir = process.env.POOLBOT_AGENT_DIR;
57
+ if (!agentDir) {
58
+ throw new Error("POOLBOT_AGENT_DIR not set");
59
+ }
60
+ return agentDir;
61
+ }
62
+ export function authProfilePathForAgent(agentDir) {
63
+ return path.join(agentDir, "auth-profiles.json");
64
+ }
65
+ export async function readAuthProfilesForAgent(agentDir) {
66
+ const raw = await fs.readFile(authProfilePathForAgent(agentDir), "utf8");
67
+ return JSON.parse(raw);
68
+ }
@@ -0,0 +1,66 @@
1
+ import { upsertAuthProfileWithLock } from "../agents/auth-profiles.js";
2
+ export const VLLM_DEFAULT_BASE_URL = "http://127.0.0.1:8000/v1";
3
+ export const VLLM_DEFAULT_CONTEXT_WINDOW = 128000;
4
+ export const VLLM_DEFAULT_MAX_TOKENS = 8192;
5
+ export const VLLM_DEFAULT_COST = {
6
+ input: 0,
7
+ output: 0,
8
+ cacheRead: 0,
9
+ cacheWrite: 0,
10
+ };
11
+ export async function promptAndConfigureVllm(params) {
12
+ const baseUrlRaw = await params.prompter.text({
13
+ message: "vLLM base URL",
14
+ initialValue: VLLM_DEFAULT_BASE_URL,
15
+ placeholder: VLLM_DEFAULT_BASE_URL,
16
+ validate: (value) => (value?.trim() ? undefined : "Required"),
17
+ });
18
+ const apiKeyRaw = await params.prompter.text({
19
+ message: "vLLM API key",
20
+ placeholder: "sk-... (or any non-empty string)",
21
+ validate: (value) => (value?.trim() ? undefined : "Required"),
22
+ });
23
+ const modelIdRaw = await params.prompter.text({
24
+ message: "vLLM model",
25
+ placeholder: "meta-llama/Meta-Llama-3-8B-Instruct",
26
+ validate: (value) => (value?.trim() ? undefined : "Required"),
27
+ });
28
+ const baseUrl = String(baseUrlRaw ?? "")
29
+ .trim()
30
+ .replace(/\/+$/, "");
31
+ const apiKey = String(apiKeyRaw ?? "").trim();
32
+ const modelId = String(modelIdRaw ?? "").trim();
33
+ const modelRef = `vllm/${modelId}`;
34
+ await upsertAuthProfileWithLock({
35
+ profileId: "vllm:default",
36
+ credential: { type: "api_key", provider: "vllm", key: apiKey },
37
+ agentDir: params.agentDir,
38
+ });
39
+ const nextConfig = {
40
+ ...params.cfg,
41
+ models: {
42
+ ...params.cfg.models,
43
+ mode: params.cfg.models?.mode ?? "merge",
44
+ providers: {
45
+ ...params.cfg.models?.providers,
46
+ vllm: {
47
+ baseUrl,
48
+ api: "openai-completions",
49
+ apiKey: "VLLM_API_KEY",
50
+ models: [
51
+ {
52
+ id: modelId,
53
+ name: modelId,
54
+ reasoning: false,
55
+ input: ["text"],
56
+ cost: VLLM_DEFAULT_COST,
57
+ contextWindow: VLLM_DEFAULT_CONTEXT_WINDOW,
58
+ maxTokens: VLLM_DEFAULT_MAX_TOKENS,
59
+ },
60
+ ],
61
+ },
62
+ },
63
+ },
64
+ };
65
+ return { config: nextConfig, modelId, modelRef };
66
+ }
@@ -1,5 +1,7 @@
1
1
  export const LEGACY_PROJECT_NAME = "poolbot";
2
2
  export const LEGACY_MANIFEST_KEY = LEGACY_PROJECT_NAME;
3
+ export const MANIFEST_KEY = LEGACY_PROJECT_NAME;
4
+ export const LEGACY_MANIFEST_KEYS = [LEGACY_MANIFEST_KEY];
3
5
  export const LEGACY_PLUGIN_MANIFEST_FILENAME = `${LEGACY_PROJECT_NAME}.plugin.json`;
4
6
  export const LEGACY_CANVAS_HANDLER_NAME = `${LEGACY_PROJECT_NAME}CanvasA2UIAction`;
5
7
  export const LEGACY_MACOS_APP_SOURCES_DIR = "apps/macos/Sources/Pool-Bot";
@@ -0,0 +1,19 @@
1
+ export const CONFIG_BACKUP_COUNT = 5;
2
+ export async function rotateConfigBackups(configPath, ioFs) {
3
+ if (CONFIG_BACKUP_COUNT <= 1) {
4
+ return;
5
+ }
6
+ const backupBase = `${configPath}.bak`;
7
+ const maxIndex = CONFIG_BACKUP_COUNT - 1;
8
+ await ioFs.unlink(`${backupBase}.${maxIndex}`).catch(() => {
9
+ // best-effort
10
+ });
11
+ for (let index = maxIndex - 1; index >= 1; index -= 1) {
12
+ await ioFs.rename(`${backupBase}.${index}`, `${backupBase}.${index + 1}`).catch(() => {
13
+ // best-effort
14
+ });
15
+ }
16
+ await ioFs.rename(backupBase, `${backupBase}.1`).catch(() => {
17
+ // best-effort
18
+ });
19
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Preserves `${VAR}` environment variable references during config write-back.
3
+ *
4
+ * When config is read, `${VAR}` references are resolved to their values.
5
+ * When writing back, callers pass the resolved config. This module detects
6
+ * values that match what a `${VAR}` reference would resolve to and restores
7
+ * the original reference, so env var references survive config round-trips.
8
+ *
9
+ * A value is restored only if:
10
+ * 1. The pre-substitution value contained a `${VAR}` pattern
11
+ * 2. Resolving that pattern with current env vars produces the incoming value
12
+ *
13
+ * If a caller intentionally set a new value (different from what the env var
14
+ * resolves to), the new value is kept as-is.
15
+ */
16
+ const ENV_VAR_PATTERN = /\$\{[A-Z_][A-Z0-9_]*\}/;
17
+ function isPlainObject(value) {
18
+ return (typeof value === "object" &&
19
+ value !== null &&
20
+ !Array.isArray(value) &&
21
+ Object.prototype.toString.call(value) === "[object Object]");
22
+ }
23
+ /**
24
+ * Check if a string contains any `${VAR}` env var references.
25
+ */
26
+ function hasEnvVarRef(value) {
27
+ return ENV_VAR_PATTERN.test(value);
28
+ }
29
+ /**
30
+ * Resolve `${VAR}` references in a single string using the given env.
31
+ * Returns null if any referenced var is missing (instead of throwing).
32
+ *
33
+ * Mirrors the substitution semantics of `substituteString` in env-substitution.ts:
34
+ * - `${VAR}` → env value (returns null if missing)
35
+ * - `$${VAR}` → literal `${VAR}` (escape sequence)
36
+ */
37
+ function tryResolveString(template, env) {
38
+ const ENV_VAR_NAME = /^[A-Z_][A-Z0-9_]*$/;
39
+ const chunks = [];
40
+ for (let i = 0; i < template.length; i++) {
41
+ if (template[i] === "$") {
42
+ // Escaped: $${VAR} -> literal ${VAR}
43
+ if (template[i + 1] === "$" && template[i + 2] === "{") {
44
+ const start = i + 3;
45
+ const end = template.indexOf("}", start);
46
+ if (end !== -1) {
47
+ const name = template.slice(start, end);
48
+ if (ENV_VAR_NAME.test(name)) {
49
+ chunks.push(`\${${name}}`);
50
+ i = end;
51
+ continue;
52
+ }
53
+ }
54
+ }
55
+ // Substitution: ${VAR} -> env value
56
+ if (template[i + 1] === "{") {
57
+ const start = i + 2;
58
+ const end = template.indexOf("}", start);
59
+ if (end !== -1) {
60
+ const name = template.slice(start, end);
61
+ if (ENV_VAR_NAME.test(name)) {
62
+ const val = env[name];
63
+ if (val === undefined || val === "") {
64
+ return null;
65
+ }
66
+ chunks.push(val);
67
+ i = end;
68
+ continue;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ chunks.push(template[i]);
74
+ }
75
+ return chunks.join("");
76
+ }
77
+ /**
78
+ * Deep-walk the incoming config and restore `${VAR}` references from the
79
+ * pre-substitution parsed config wherever the resolved value matches.
80
+ *
81
+ * @param incoming - The resolved config about to be written
82
+ * @param parsed - The pre-substitution parsed config (from the current file on disk)
83
+ * @param env - Environment variables for verification
84
+ * @returns A new config object with env var references restored where appropriate
85
+ */
86
+ export function restoreEnvVarRefs(incoming, parsed, env = process.env) {
87
+ // If parsed has no env var refs at this level, return incoming as-is
88
+ if (parsed === null || parsed === undefined) {
89
+ return incoming;
90
+ }
91
+ // String leaf: check if parsed was a ${VAR} template that resolves to incoming
92
+ if (typeof incoming === "string" && typeof parsed === "string") {
93
+ if (hasEnvVarRef(parsed)) {
94
+ const resolved = tryResolveString(parsed, env);
95
+ if (resolved === incoming) {
96
+ // The incoming value matches what the env var resolves to — restore the reference
97
+ return parsed;
98
+ }
99
+ }
100
+ return incoming;
101
+ }
102
+ // Arrays: walk element by element
103
+ if (Array.isArray(incoming) && Array.isArray(parsed)) {
104
+ return incoming.map((item, i) => i < parsed.length ? restoreEnvVarRefs(item, parsed[i], env) : item);
105
+ }
106
+ // Objects: walk key by key
107
+ if (isPlainObject(incoming) && isPlainObject(parsed)) {
108
+ const result = {};
109
+ for (const [key, value] of Object.entries(incoming)) {
110
+ if (key in parsed) {
111
+ result[key] = restoreEnvVarRefs(value, parsed[key], env);
112
+ }
113
+ else {
114
+ // New key added by caller — keep as-is
115
+ result[key] = value;
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ // Mismatched types or primitives — keep incoming
121
+ return incoming;
122
+ }