@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,233 @@
1
+ import { defaultRuntime } from "../../runtime.js";
2
+ import { getFlagValue, getPositiveIntFlagValue, getVerboseFlag, hasFlag } from "../argv.js";
3
+ const routeHealth = {
4
+ match: (path) => path[0] === "health",
5
+ loadPlugins: true,
6
+ run: async (argv) => {
7
+ const json = hasFlag(argv, "--json");
8
+ const verbose = getVerboseFlag(argv, { includeDebug: true });
9
+ const timeoutMs = getPositiveIntFlagValue(argv, "--timeout");
10
+ if (timeoutMs === null) {
11
+ return false;
12
+ }
13
+ const { healthCommand } = await import("../../commands/health.js");
14
+ await healthCommand({ json, timeoutMs, verbose }, defaultRuntime);
15
+ return true;
16
+ },
17
+ };
18
+ const routeStatus = {
19
+ match: (path) => path[0] === "status",
20
+ loadPlugins: true,
21
+ run: async (argv) => {
22
+ const json = hasFlag(argv, "--json");
23
+ const deep = hasFlag(argv, "--deep");
24
+ const all = hasFlag(argv, "--all");
25
+ const usage = hasFlag(argv, "--usage");
26
+ const verbose = getVerboseFlag(argv, { includeDebug: true });
27
+ const timeoutMs = getPositiveIntFlagValue(argv, "--timeout");
28
+ if (timeoutMs === null) {
29
+ return false;
30
+ }
31
+ const { statusCommand } = await import("../../commands/status.js");
32
+ await statusCommand({ json, deep, all, usage, timeoutMs, verbose }, defaultRuntime);
33
+ return true;
34
+ },
35
+ };
36
+ const routeSessions = {
37
+ match: (path) => path[0] === "sessions",
38
+ run: async (argv) => {
39
+ const json = hasFlag(argv, "--json");
40
+ const store = getFlagValue(argv, "--store");
41
+ if (store === null) {
42
+ return false;
43
+ }
44
+ const active = getFlagValue(argv, "--active");
45
+ if (active === null) {
46
+ return false;
47
+ }
48
+ const { sessionsCommand } = await import("../../commands/sessions.js");
49
+ await sessionsCommand({ json, store, active }, defaultRuntime);
50
+ return true;
51
+ },
52
+ };
53
+ const routeAgentsList = {
54
+ match: (path) => path[0] === "agents" && path[1] === "list",
55
+ run: async (argv) => {
56
+ const json = hasFlag(argv, "--json");
57
+ const bindings = hasFlag(argv, "--bindings");
58
+ const { agentsListCommand } = await import("../../commands/agents.js");
59
+ await agentsListCommand({ json, bindings }, defaultRuntime);
60
+ return true;
61
+ },
62
+ };
63
+ const routeMemoryStatus = {
64
+ match: (path) => path[0] === "memory" && path[1] === "status",
65
+ run: async (argv) => {
66
+ const agent = getFlagValue(argv, "--agent");
67
+ if (agent === null) {
68
+ return false;
69
+ }
70
+ const json = hasFlag(argv, "--json");
71
+ const deep = hasFlag(argv, "--deep");
72
+ const index = hasFlag(argv, "--index");
73
+ const verbose = hasFlag(argv, "--verbose");
74
+ const { runMemoryStatus } = await import("../memory-cli.js");
75
+ await runMemoryStatus({ agent, json, deep, index, verbose });
76
+ return true;
77
+ },
78
+ };
79
+ function getCommandPositionals(argv) {
80
+ const out = [];
81
+ const args = argv.slice(2);
82
+ for (const arg of args) {
83
+ if (!arg || arg === "--") {
84
+ break;
85
+ }
86
+ if (arg.startsWith("-")) {
87
+ continue;
88
+ }
89
+ out.push(arg);
90
+ }
91
+ return out;
92
+ }
93
+ function getFlagValues(argv, name) {
94
+ const values = [];
95
+ const args = argv.slice(2);
96
+ for (let i = 0; i < args.length; i += 1) {
97
+ const arg = args[i];
98
+ if (!arg || arg === "--") {
99
+ break;
100
+ }
101
+ if (arg === name) {
102
+ const next = args[i + 1];
103
+ if (!next || next === "--" || next.startsWith("-")) {
104
+ return null;
105
+ }
106
+ values.push(next);
107
+ i += 1;
108
+ continue;
109
+ }
110
+ if (arg.startsWith(`${name}=`)) {
111
+ const value = arg.slice(name.length + 1).trim();
112
+ if (!value) {
113
+ return null;
114
+ }
115
+ values.push(value);
116
+ }
117
+ }
118
+ return values;
119
+ }
120
+ const routeConfigGet = {
121
+ match: (path) => path[0] === "config" && path[1] === "get",
122
+ run: async (argv) => {
123
+ const positionals = getCommandPositionals(argv);
124
+ const pathArg = positionals[2];
125
+ if (!pathArg) {
126
+ return false;
127
+ }
128
+ const json = hasFlag(argv, "--json");
129
+ const { runConfigGet } = await import("../config-cli.js");
130
+ await runConfigGet({ path: pathArg, json });
131
+ return true;
132
+ },
133
+ };
134
+ const routeConfigUnset = {
135
+ match: (path) => path[0] === "config" && path[1] === "unset",
136
+ run: async (argv) => {
137
+ const positionals = getCommandPositionals(argv);
138
+ const pathArg = positionals[2];
139
+ if (!pathArg) {
140
+ return false;
141
+ }
142
+ const { runConfigUnset } = await import("../config-cli.js");
143
+ await runConfigUnset({ path: pathArg });
144
+ return true;
145
+ },
146
+ };
147
+ const routeModelsList = {
148
+ match: (path) => path[0] === "models" && path[1] === "list",
149
+ run: async (argv) => {
150
+ const provider = getFlagValue(argv, "--provider");
151
+ if (provider === null) {
152
+ return false;
153
+ }
154
+ const all = hasFlag(argv, "--all");
155
+ const local = hasFlag(argv, "--local");
156
+ const json = hasFlag(argv, "--json");
157
+ const plain = hasFlag(argv, "--plain");
158
+ const { modelsListCommand } = await import("../../commands/models.js");
159
+ await modelsListCommand({ all, local, provider, json, plain }, defaultRuntime);
160
+ return true;
161
+ },
162
+ };
163
+ const routeModelsStatus = {
164
+ match: (path) => path[0] === "models" && path[1] === "status",
165
+ run: async (argv) => {
166
+ const probeProvider = getFlagValue(argv, "--probe-provider");
167
+ if (probeProvider === null) {
168
+ return false;
169
+ }
170
+ const probeTimeout = getFlagValue(argv, "--probe-timeout");
171
+ if (probeTimeout === null) {
172
+ return false;
173
+ }
174
+ const probeConcurrency = getFlagValue(argv, "--probe-concurrency");
175
+ if (probeConcurrency === null) {
176
+ return false;
177
+ }
178
+ const probeMaxTokens = getFlagValue(argv, "--probe-max-tokens");
179
+ if (probeMaxTokens === null) {
180
+ return false;
181
+ }
182
+ const agent = getFlagValue(argv, "--agent");
183
+ if (agent === null) {
184
+ return false;
185
+ }
186
+ const probeProfileValues = getFlagValues(argv, "--probe-profile");
187
+ if (probeProfileValues === null) {
188
+ return false;
189
+ }
190
+ const probeProfile = probeProfileValues.length === 0
191
+ ? undefined
192
+ : probeProfileValues.length === 1
193
+ ? probeProfileValues[0]
194
+ : probeProfileValues;
195
+ const json = hasFlag(argv, "--json");
196
+ const plain = hasFlag(argv, "--plain");
197
+ const check = hasFlag(argv, "--check");
198
+ const probe = hasFlag(argv, "--probe");
199
+ const { modelsStatusCommand } = await import("../../commands/models.js");
200
+ await modelsStatusCommand({
201
+ json,
202
+ plain,
203
+ check,
204
+ probe,
205
+ probeProvider,
206
+ probeProfile,
207
+ probeTimeout,
208
+ probeConcurrency,
209
+ probeMaxTokens,
210
+ agent,
211
+ }, defaultRuntime);
212
+ return true;
213
+ },
214
+ };
215
+ const routes = [
216
+ routeHealth,
217
+ routeStatus,
218
+ routeSessions,
219
+ routeAgentsList,
220
+ routeMemoryStatus,
221
+ routeConfigGet,
222
+ routeConfigUnset,
223
+ routeModelsList,
224
+ routeModelsStatus,
225
+ ];
226
+ export function findRoutedCommand(path) {
227
+ for (const route of routes) {
228
+ if (route.match(path)) {
229
+ return route;
230
+ }
231
+ }
232
+ return null;
233
+ }
@@ -0,0 +1,132 @@
1
+ import qrcode from "qrcode-terminal";
2
+ import { loadConfig } from "../config/config.js";
3
+ import { resolvePairingSetupFromConfig, encodePairingSetupCode } from "../pairing/setup-code.js";
4
+ import { runCommandWithTimeout } from "../process/exec.js";
5
+ import { defaultRuntime } from "../runtime.js";
6
+ import { theme } from "../terminal/theme.js";
7
+ function renderQrAscii(data) {
8
+ return new Promise((resolve) => {
9
+ qrcode.generate(data, { small: true }, (output) => {
10
+ resolve(output);
11
+ });
12
+ });
13
+ }
14
+ function readDevicePairPublicUrlFromConfig(cfg) {
15
+ const value = cfg.plugins?.entries?.["device-pair"]?.config?.["publicUrl"];
16
+ if (typeof value !== "string") {
17
+ return undefined;
18
+ }
19
+ const trimmed = value.trim();
20
+ return trimmed.length > 0 ? trimmed : undefined;
21
+ }
22
+ export function registerQrCli(program) {
23
+ program
24
+ .command("qr")
25
+ .description("Generate an iOS pairing QR code and setup code")
26
+ .option("--remote", "Use gateway.remote.url and gateway.remote token/password (ignores device-pair publicUrl)", false)
27
+ .option("--url <url>", "Override gateway URL used in the setup payload")
28
+ .option("--public-url <url>", "Override gateway public URL used in the setup payload")
29
+ .option("--token <token>", "Override gateway token for setup payload")
30
+ .option("--password <password>", "Override gateway password for setup payload")
31
+ .option("--setup-code-only", "Print only the setup code", false)
32
+ .option("--no-ascii", "Skip ASCII QR rendering")
33
+ .option("--json", "Output JSON", false)
34
+ .action(async (opts) => {
35
+ try {
36
+ if (opts.token && opts.password) {
37
+ throw new Error("Use either --token or --password, not both.");
38
+ }
39
+ const loaded = loadConfig();
40
+ const cfg = {
41
+ ...loaded,
42
+ gateway: {
43
+ ...loaded.gateway,
44
+ auth: {
45
+ ...loaded.gateway?.auth,
46
+ },
47
+ },
48
+ };
49
+ const token = typeof opts.token === "string" ? opts.token.trim() : "";
50
+ const password = typeof opts.password === "string" ? opts.password.trim() : "";
51
+ const wantsRemote = opts.remote === true;
52
+ if (token) {
53
+ cfg.gateway.auth.mode = "token";
54
+ cfg.gateway.auth.token = token;
55
+ }
56
+ if (password) {
57
+ cfg.gateway.auth.mode = "password";
58
+ cfg.gateway.auth.password = password;
59
+ }
60
+ if (wantsRemote && !token && !password) {
61
+ const remoteToken = typeof cfg.gateway?.remote?.token === "string" ? cfg.gateway.remote.token.trim() : "";
62
+ const remotePassword = typeof cfg.gateway?.remote?.password === "string"
63
+ ? cfg.gateway.remote.password.trim()
64
+ : "";
65
+ if (remoteToken) {
66
+ cfg.gateway.auth.mode = "token";
67
+ cfg.gateway.auth.token = remoteToken;
68
+ cfg.gateway.auth.password = undefined;
69
+ }
70
+ else if (remotePassword) {
71
+ cfg.gateway.auth.mode = "password";
72
+ cfg.gateway.auth.password = remotePassword;
73
+ cfg.gateway.auth.token = undefined;
74
+ }
75
+ }
76
+ if (wantsRemote && !opts.url && !opts.publicUrl) {
77
+ const tailscaleMode = cfg.gateway?.tailscale?.mode ?? "off";
78
+ const remoteUrl = cfg.gateway?.remote?.url;
79
+ const hasRemoteUrl = typeof remoteUrl === "string" && remoteUrl.trim().length > 0;
80
+ const hasTailscaleServe = tailscaleMode === "serve" || tailscaleMode === "funnel";
81
+ if (!hasRemoteUrl && !hasTailscaleServe) {
82
+ throw new Error("qr --remote requires gateway.remote.url (or gateway.tailscale.mode=serve/funnel).");
83
+ }
84
+ }
85
+ const explicitUrl = typeof opts.url === "string" && opts.url.trim()
86
+ ? opts.url.trim()
87
+ : typeof opts.publicUrl === "string" && opts.publicUrl.trim()
88
+ ? opts.publicUrl.trim()
89
+ : undefined;
90
+ const publicUrl = explicitUrl ?? (wantsRemote ? undefined : readDevicePairPublicUrlFromConfig(cfg));
91
+ const resolved = await resolvePairingSetupFromConfig(cfg, {
92
+ publicUrl,
93
+ preferRemoteUrl: wantsRemote,
94
+ runCommandWithTimeout: async (argv, runOpts) => await runCommandWithTimeout(argv, {
95
+ timeoutMs: runOpts.timeoutMs,
96
+ }),
97
+ });
98
+ if (!resolved.ok) {
99
+ throw new Error(resolved.error);
100
+ }
101
+ const setupCode = encodePairingSetupCode(resolved.payload);
102
+ if (opts.setupCodeOnly) {
103
+ defaultRuntime.log(setupCode);
104
+ return;
105
+ }
106
+ if (opts.json) {
107
+ defaultRuntime.log(JSON.stringify({
108
+ setupCode,
109
+ gatewayUrl: resolved.payload.url,
110
+ auth: resolved.authLabel,
111
+ urlSource: resolved.urlSource,
112
+ }, null, 2));
113
+ return;
114
+ }
115
+ const lines = [
116
+ theme.heading("Pairing QR"),
117
+ "Scan this with the OpenClaw iOS app (Onboarding -> Scan QR).",
118
+ "",
119
+ ];
120
+ if (opts.ascii !== false) {
121
+ const qrAscii = await renderQrAscii(setupCode);
122
+ lines.push(qrAscii.trimEnd(), "");
123
+ }
124
+ lines.push(`${theme.muted("Setup code:")} ${setupCode}`, `${theme.muted("Gateway:")} ${resolved.payload.url}`, `${theme.muted("Auth:")} ${resolved.authLabel}`, `${theme.muted("Source:")} ${resolved.urlSource}`, "", "Approve after scan with:", ` ${theme.command("openclaw devices list")}`, ` ${theme.command("openclaw devices approve <requestId>")}`);
125
+ defaultRuntime.log(lines.join("\n"));
126
+ }
127
+ catch (err) {
128
+ defaultRuntime.error(String(err));
129
+ defaultRuntime.exit(1);
130
+ }
131
+ });
132
+ }
@@ -0,0 +1,17 @@
1
+ export function createEmptyRequirements() {
2
+ return {
3
+ bins: [],
4
+ anyBins: [],
5
+ env: [],
6
+ config: [],
7
+ os: [],
8
+ };
9
+ }
10
+ export function createEmptyInstallChecks() {
11
+ return {
12
+ requirements: createEmptyRequirements(),
13
+ missing: createEmptyRequirements(),
14
+ configChecks: [],
15
+ install: [],
16
+ };
17
+ }
@@ -0,0 +1,4 @@
1
+ import { hasHelpOrVersion } from "./argv.js";
2
+ export function shouldSkipRespawnForArgv(argv) {
3
+ return hasHelpOrVersion(argv);
4
+ }
@@ -0,0 +1,18 @@
1
+ export function parsePort(raw) {
2
+ if (raw === undefined || raw === null) {
3
+ return null;
4
+ }
5
+ const value = typeof raw === "string"
6
+ ? raw
7
+ : typeof raw === "number" || typeof raw === "bigint"
8
+ ? raw.toString()
9
+ : null;
10
+ if (value === null) {
11
+ return null;
12
+ }
13
+ const parsed = Number.parseInt(value, 10);
14
+ if (!Number.isFinite(parsed) || parsed <= 0) {
15
+ return null;
16
+ }
17
+ return parsed;
18
+ }
@@ -0,0 +1,241 @@
1
+ import { renderTable } from "../terminal/table.js";
2
+ import { theme } from "../terminal/theme.js";
3
+ import { shortenHomePath } from "../utils.js";
4
+ import { formatCliCommand } from "./command-format.js";
5
+ function appendClawHubHint(output, json) {
6
+ if (json) {
7
+ return output;
8
+ }
9
+ return `${output}\n\nTip: use \`npx clawhub\` to search, install, and sync skills.`;
10
+ }
11
+ function formatSkillStatus(skill) {
12
+ if (skill.eligible) {
13
+ return theme.success("✓ ready");
14
+ }
15
+ if (skill.disabled) {
16
+ return theme.warn("⏸ disabled");
17
+ }
18
+ if (skill.blockedByAllowlist) {
19
+ return theme.warn("🚫 blocked");
20
+ }
21
+ return theme.error("✗ missing");
22
+ }
23
+ function formatSkillName(skill) {
24
+ const emoji = skill.emoji ?? "📦";
25
+ return `${emoji} ${theme.command(skill.name)}`;
26
+ }
27
+ function formatSkillMissingSummary(skill) {
28
+ const missing = [];
29
+ if (skill.missing.bins.length > 0) {
30
+ missing.push(`bins: ${skill.missing.bins.join(", ")}`);
31
+ }
32
+ if (skill.missing.anyBins.length > 0) {
33
+ missing.push(`anyBins: ${skill.missing.anyBins.join(", ")}`);
34
+ }
35
+ if (skill.missing.env.length > 0) {
36
+ missing.push(`env: ${skill.missing.env.join(", ")}`);
37
+ }
38
+ if (skill.missing.config.length > 0) {
39
+ missing.push(`config: ${skill.missing.config.join(", ")}`);
40
+ }
41
+ if (skill.missing.os.length > 0) {
42
+ missing.push(`os: ${skill.missing.os.join(", ")}`);
43
+ }
44
+ return missing.join("; ");
45
+ }
46
+ export function formatSkillsList(report, opts) {
47
+ const skills = opts.eligible ? report.skills.filter((s) => s.eligible) : report.skills;
48
+ if (opts.json) {
49
+ const jsonReport = {
50
+ workspaceDir: report.workspaceDir,
51
+ managedSkillsDir: report.managedSkillsDir,
52
+ skills: skills.map((s) => ({
53
+ name: s.name,
54
+ description: s.description,
55
+ emoji: s.emoji,
56
+ eligible: s.eligible,
57
+ disabled: s.disabled,
58
+ blockedByAllowlist: s.blockedByAllowlist,
59
+ source: s.source,
60
+ bundled: s.bundled,
61
+ primaryEnv: s.primaryEnv,
62
+ homepage: s.homepage,
63
+ missing: s.missing,
64
+ })),
65
+ };
66
+ return JSON.stringify(jsonReport, null, 2);
67
+ }
68
+ if (skills.length === 0) {
69
+ const message = opts.eligible
70
+ ? `No eligible skills found. Run \`${formatCliCommand("openclaw skills list")}\` to see all skills.`
71
+ : "No skills found.";
72
+ return appendClawHubHint(message, opts.json);
73
+ }
74
+ const eligible = skills.filter((s) => s.eligible);
75
+ const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
76
+ const rows = skills.map((skill) => {
77
+ const missing = formatSkillMissingSummary(skill);
78
+ return {
79
+ Status: formatSkillStatus(skill),
80
+ Skill: formatSkillName(skill),
81
+ Description: theme.muted(skill.description),
82
+ Source: skill.source ?? "",
83
+ Missing: missing ? theme.warn(missing) : "",
84
+ };
85
+ });
86
+ const columns = [
87
+ { key: "Status", header: "Status", minWidth: 10 },
88
+ { key: "Skill", header: "Skill", minWidth: 18, flex: true },
89
+ { key: "Description", header: "Description", minWidth: 24, flex: true },
90
+ { key: "Source", header: "Source", minWidth: 10 },
91
+ ];
92
+ if (opts.verbose) {
93
+ columns.push({ key: "Missing", header: "Missing", minWidth: 18, flex: true });
94
+ }
95
+ const lines = [];
96
+ lines.push(`${theme.heading("Skills")} ${theme.muted(`(${eligible.length}/${skills.length} ready)`)}`);
97
+ lines.push(renderTable({
98
+ width: tableWidth,
99
+ columns,
100
+ rows,
101
+ }).trimEnd());
102
+ return appendClawHubHint(lines.join("\n"), opts.json);
103
+ }
104
+ export function formatSkillInfo(report, skillName, opts) {
105
+ const skill = report.skills.find((s) => s.name === skillName || s.skillKey === skillName);
106
+ if (!skill) {
107
+ if (opts.json) {
108
+ return JSON.stringify({ error: "not found", skill: skillName }, null, 2);
109
+ }
110
+ return appendClawHubHint(`Skill "${skillName}" not found. Run \`${formatCliCommand("openclaw skills list")}\` to see available skills.`, opts.json);
111
+ }
112
+ if (opts.json) {
113
+ return JSON.stringify(skill, null, 2);
114
+ }
115
+ const lines = [];
116
+ const emoji = skill.emoji ?? "📦";
117
+ const status = skill.eligible
118
+ ? theme.success("✓ Ready")
119
+ : skill.disabled
120
+ ? theme.warn("⏸ Disabled")
121
+ : skill.blockedByAllowlist
122
+ ? theme.warn("🚫 Blocked by allowlist")
123
+ : theme.error("✗ Missing requirements");
124
+ lines.push(`${emoji} ${theme.heading(skill.name)} ${status}`);
125
+ lines.push("");
126
+ lines.push(skill.description);
127
+ lines.push("");
128
+ lines.push(theme.heading("Details:"));
129
+ lines.push(`${theme.muted(" Source:")} ${skill.source}`);
130
+ lines.push(`${theme.muted(" Path:")} ${shortenHomePath(skill.filePath)}`);
131
+ if (skill.homepage) {
132
+ lines.push(`${theme.muted(" Homepage:")} ${skill.homepage}`);
133
+ }
134
+ if (skill.primaryEnv) {
135
+ lines.push(`${theme.muted(" Primary env:")} ${skill.primaryEnv}`);
136
+ }
137
+ const hasRequirements = skill.requirements.bins.length > 0 ||
138
+ skill.requirements.anyBins.length > 0 ||
139
+ skill.requirements.env.length > 0 ||
140
+ skill.requirements.config.length > 0 ||
141
+ skill.requirements.os.length > 0;
142
+ if (hasRequirements) {
143
+ lines.push("");
144
+ lines.push(theme.heading("Requirements:"));
145
+ if (skill.requirements.bins.length > 0) {
146
+ const binsStatus = skill.requirements.bins.map((bin) => {
147
+ const missing = skill.missing.bins.includes(bin);
148
+ return missing ? theme.error(`✗ ${bin}`) : theme.success(`✓ ${bin}`);
149
+ });
150
+ lines.push(`${theme.muted(" Binaries:")} ${binsStatus.join(", ")}`);
151
+ }
152
+ if (skill.requirements.anyBins.length > 0) {
153
+ const anyBinsMissing = skill.missing.anyBins.length > 0;
154
+ const anyBinsStatus = skill.requirements.anyBins.map((bin) => {
155
+ const missing = anyBinsMissing;
156
+ return missing ? theme.error(`✗ ${bin}`) : theme.success(`✓ ${bin}`);
157
+ });
158
+ lines.push(`${theme.muted(" Any binaries:")} ${anyBinsStatus.join(", ")}`);
159
+ }
160
+ if (skill.requirements.env.length > 0) {
161
+ const envStatus = skill.requirements.env.map((env) => {
162
+ const missing = skill.missing.env.includes(env);
163
+ return missing ? theme.error(`✗ ${env}`) : theme.success(`✓ ${env}`);
164
+ });
165
+ lines.push(`${theme.muted(" Environment:")} ${envStatus.join(", ")}`);
166
+ }
167
+ if (skill.requirements.config.length > 0) {
168
+ const configStatus = skill.requirements.config.map((cfg) => {
169
+ const missing = skill.missing.config.includes(cfg);
170
+ return missing ? theme.error(`✗ ${cfg}`) : theme.success(`✓ ${cfg}`);
171
+ });
172
+ lines.push(`${theme.muted(" Config:")} ${configStatus.join(", ")}`);
173
+ }
174
+ if (skill.requirements.os.length > 0) {
175
+ const osStatus = skill.requirements.os.map((osName) => {
176
+ const missing = skill.missing.os.includes(osName);
177
+ return missing ? theme.error(`✗ ${osName}`) : theme.success(`✓ ${osName}`);
178
+ });
179
+ lines.push(`${theme.muted(" OS:")} ${osStatus.join(", ")}`);
180
+ }
181
+ }
182
+ if (skill.install.length > 0 && !skill.eligible) {
183
+ lines.push("");
184
+ lines.push(theme.heading("Install options:"));
185
+ for (const inst of skill.install) {
186
+ lines.push(` ${theme.warn("→")} ${inst.label}`);
187
+ }
188
+ }
189
+ return appendClawHubHint(lines.join("\n"), opts.json);
190
+ }
191
+ export function formatSkillsCheck(report, opts) {
192
+ const eligible = report.skills.filter((s) => s.eligible);
193
+ const disabled = report.skills.filter((s) => s.disabled);
194
+ const blocked = report.skills.filter((s) => s.blockedByAllowlist && !s.disabled);
195
+ const missingReqs = report.skills.filter((s) => !s.eligible && !s.disabled && !s.blockedByAllowlist);
196
+ if (opts.json) {
197
+ return JSON.stringify({
198
+ summary: {
199
+ total: report.skills.length,
200
+ eligible: eligible.length,
201
+ disabled: disabled.length,
202
+ blocked: blocked.length,
203
+ missingRequirements: missingReqs.length,
204
+ },
205
+ eligible: eligible.map((s) => s.name),
206
+ disabled: disabled.map((s) => s.name),
207
+ blocked: blocked.map((s) => s.name),
208
+ missingRequirements: missingReqs.map((s) => ({
209
+ name: s.name,
210
+ missing: s.missing,
211
+ install: s.install,
212
+ })),
213
+ }, null, 2);
214
+ }
215
+ const lines = [];
216
+ lines.push(theme.heading("Skills Status Check"));
217
+ lines.push("");
218
+ lines.push(`${theme.muted("Total:")} ${report.skills.length}`);
219
+ lines.push(`${theme.success("✓")} ${theme.muted("Eligible:")} ${eligible.length}`);
220
+ lines.push(`${theme.warn("⏸")} ${theme.muted("Disabled:")} ${disabled.length}`);
221
+ lines.push(`${theme.warn("🚫")} ${theme.muted("Blocked by allowlist:")} ${blocked.length}`);
222
+ lines.push(`${theme.error("✗")} ${theme.muted("Missing requirements:")} ${missingReqs.length}`);
223
+ if (eligible.length > 0) {
224
+ lines.push("");
225
+ lines.push(theme.heading("Ready to use:"));
226
+ for (const skill of eligible) {
227
+ const emoji = skill.emoji ?? "📦";
228
+ lines.push(` ${emoji} ${skill.name}`);
229
+ }
230
+ }
231
+ if (missingReqs.length > 0) {
232
+ lines.push("");
233
+ lines.push(theme.heading("Missing requirements:"));
234
+ for (const skill of missingReqs) {
235
+ const emoji = skill.emoji ?? "📦";
236
+ const missing = formatSkillMissingSummary(skill);
237
+ lines.push(` ${emoji} ${skill.name} ${theme.muted(`(${missing})`)}`);
238
+ }
239
+ }
240
+ return appendClawHubHint(lines.join("\n"), opts.json);
241
+ }