clawdbot 2026.1.4-1

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 (550) hide show
  1. package/CHANGELOG.md +120 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +297 -0
  5. package/dist/agents/agent-paths.js +17 -0
  6. package/dist/agents/bash-process-registry.js +126 -0
  7. package/dist/agents/bash-tools.js +837 -0
  8. package/dist/agents/clawdbot-tools.js +30 -0
  9. package/dist/agents/clawdis-tools.js +27 -0
  10. package/dist/agents/context.js +34 -0
  11. package/dist/agents/defaults.js +6 -0
  12. package/dist/agents/model-auth.js +112 -0
  13. package/dist/agents/model-catalog.js +55 -0
  14. package/dist/agents/model-fallback.js +191 -0
  15. package/dist/agents/model-scan.js +263 -0
  16. package/dist/agents/model-selection.js +116 -0
  17. package/dist/agents/models-config.js +49 -0
  18. package/dist/agents/pi-embedded-helpers.js +74 -0
  19. package/dist/agents/pi-embedded-runner.js +407 -0
  20. package/dist/agents/pi-embedded-subscribe.js +568 -0
  21. package/dist/agents/pi-embedded-utils.js +20 -0
  22. package/dist/agents/pi-embedded.js +1 -0
  23. package/dist/agents/pi-oauth.js +88 -0
  24. package/dist/agents/pi-tools.js +433 -0
  25. package/dist/agents/sandbox-paths.js +68 -0
  26. package/dist/agents/sandbox.js +644 -0
  27. package/dist/agents/shell-utils.js +53 -0
  28. package/dist/agents/skills-install.js +244 -0
  29. package/dist/agents/skills-status.js +157 -0
  30. package/dist/agents/skills.js +470 -0
  31. package/dist/agents/steerable-agent-loop.js +338 -0
  32. package/dist/agents/steerable-provider-transport.js +48 -0
  33. package/dist/agents/system-prompt.js +104 -0
  34. package/dist/agents/tool-display.js +162 -0
  35. package/dist/agents/tool-images.js +138 -0
  36. package/dist/agents/tools/browser-tool.js +339 -0
  37. package/dist/agents/tools/canvas-tool.js +193 -0
  38. package/dist/agents/tools/common.js +88 -0
  39. package/dist/agents/tools/cron-tool.js +124 -0
  40. package/dist/agents/tools/discord-actions-guild.js +186 -0
  41. package/dist/agents/tools/discord-actions-messaging.js +285 -0
  42. package/dist/agents/tools/discord-actions-moderation.js +70 -0
  43. package/dist/agents/tools/discord-actions.js +56 -0
  44. package/dist/agents/tools/discord-schema.js +199 -0
  45. package/dist/agents/tools/discord-tool.js +16 -0
  46. package/dist/agents/tools/gateway-tool.js +46 -0
  47. package/dist/agents/tools/gateway.js +27 -0
  48. package/dist/agents/tools/image-tool.js +132 -0
  49. package/dist/agents/tools/nodes-tool.js +413 -0
  50. package/dist/agents/tools/nodes-utils.js +92 -0
  51. package/dist/agents/tools/sessions-helpers.js +88 -0
  52. package/dist/agents/tools/sessions-history-tool.js +53 -0
  53. package/dist/agents/tools/sessions-list-tool.js +143 -0
  54. package/dist/agents/tools/sessions-send-helpers.js +100 -0
  55. package/dist/agents/tools/sessions-send-tool.js +347 -0
  56. package/dist/agents/tools/slack-actions.js +129 -0
  57. package/dist/agents/tools/slack-schema.js +59 -0
  58. package/dist/agents/tools/slack-tool.js +16 -0
  59. package/dist/agents/usage.js +39 -0
  60. package/dist/agents/workspace.js +241 -0
  61. package/dist/auto-reply/chunk.js +76 -0
  62. package/dist/auto-reply/envelope.js +38 -0
  63. package/dist/auto-reply/group-activation.js +20 -0
  64. package/dist/auto-reply/heartbeat.js +57 -0
  65. package/dist/auto-reply/model.js +14 -0
  66. package/dist/auto-reply/reply/abort.js +14 -0
  67. package/dist/auto-reply/reply/agent-runner.js +371 -0
  68. package/dist/auto-reply/reply/block-streaming.js +34 -0
  69. package/dist/auto-reply/reply/body.js +29 -0
  70. package/dist/auto-reply/reply/commands.js +207 -0
  71. package/dist/auto-reply/reply/directive-handling.js +361 -0
  72. package/dist/auto-reply/reply/directives.js +47 -0
  73. package/dist/auto-reply/reply/followup-runner.js +149 -0
  74. package/dist/auto-reply/reply/groups.js +91 -0
  75. package/dist/auto-reply/reply/mentions.js +38 -0
  76. package/dist/auto-reply/reply/model-selection.js +114 -0
  77. package/dist/auto-reply/reply/queue.js +399 -0
  78. package/dist/auto-reply/reply/reply-tags.js +26 -0
  79. package/dist/auto-reply/reply/session-updates.js +87 -0
  80. package/dist/auto-reply/reply/session.js +160 -0
  81. package/dist/auto-reply/reply/typing.js +75 -0
  82. package/dist/auto-reply/reply.js +535 -0
  83. package/dist/auto-reply/send-policy.js +28 -0
  84. package/dist/auto-reply/status.js +158 -0
  85. package/dist/auto-reply/templating.js +9 -0
  86. package/dist/auto-reply/thinking.js +49 -0
  87. package/dist/auto-reply/tokens.js +2 -0
  88. package/dist/auto-reply/tool-meta.js +74 -0
  89. package/dist/auto-reply/transcription.js +57 -0
  90. package/dist/auto-reply/types.js +1 -0
  91. package/dist/browser/bridge-server.js +37 -0
  92. package/dist/browser/cdp.js +382 -0
  93. package/dist/browser/chrome.js +432 -0
  94. package/dist/browser/client-actions-core.js +67 -0
  95. package/dist/browser/client-actions-observe.js +24 -0
  96. package/dist/browser/client-actions-types.js +1 -0
  97. package/dist/browser/client-actions.js +3 -0
  98. package/dist/browser/client-fetch.js +43 -0
  99. package/dist/browser/client.js +105 -0
  100. package/dist/browser/config.js +140 -0
  101. package/dist/browser/constants.js +4 -0
  102. package/dist/browser/profiles-service.js +122 -0
  103. package/dist/browser/profiles.js +85 -0
  104. package/dist/browser/pw-ai.js +2 -0
  105. package/dist/browser/pw-session.js +144 -0
  106. package/dist/browser/pw-tools-core.js +363 -0
  107. package/dist/browser/routes/agent.js +535 -0
  108. package/dist/browser/routes/basic.js +155 -0
  109. package/dist/browser/routes/index.js +8 -0
  110. package/dist/browser/routes/tabs.js +105 -0
  111. package/dist/browser/routes/utils.js +62 -0
  112. package/dist/browser/screenshot.js +40 -0
  113. package/dist/browser/server-context.js +377 -0
  114. package/dist/browser/server.js +81 -0
  115. package/dist/browser/target-id.js +18 -0
  116. package/dist/browser/trash.js +21 -0
  117. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  118. package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
  119. package/dist/canvas-host/a2ui/index.html +246 -0
  120. package/dist/canvas-host/a2ui.js +187 -0
  121. package/dist/canvas-host/server.js +382 -0
  122. package/dist/cli/browser-cli-actions-input.js +459 -0
  123. package/dist/cli/browser-cli-actions-observe.js +56 -0
  124. package/dist/cli/browser-cli-examples.js +31 -0
  125. package/dist/cli/browser-cli-inspect.js +97 -0
  126. package/dist/cli/browser-cli-manage.js +286 -0
  127. package/dist/cli/browser-cli-shared.js +1 -0
  128. package/dist/cli/browser-cli.js +26 -0
  129. package/dist/cli/canvas-cli.js +416 -0
  130. package/dist/cli/cron-cli.js +454 -0
  131. package/dist/cli/deps.js +17 -0
  132. package/dist/cli/dns-cli.js +180 -0
  133. package/dist/cli/gateway-cli.js +489 -0
  134. package/dist/cli/gateway-rpc.js +20 -0
  135. package/dist/cli/hooks-cli.js +135 -0
  136. package/dist/cli/models-cli.js +248 -0
  137. package/dist/cli/nodes-camera.js +57 -0
  138. package/dist/cli/nodes-canvas.js +26 -0
  139. package/dist/cli/nodes-cli.js +946 -0
  140. package/dist/cli/nodes-screen.js +37 -0
  141. package/dist/cli/parse-duration.js +20 -0
  142. package/dist/cli/ports.js +97 -0
  143. package/dist/cli/program.js +406 -0
  144. package/dist/cli/prompt.js +19 -0
  145. package/dist/cli/tui-cli.js +35 -0
  146. package/dist/cli/wait.js +8 -0
  147. package/dist/commands/agent.js +645 -0
  148. package/dist/commands/antigravity-oauth.js +327 -0
  149. package/dist/commands/configure.js +480 -0
  150. package/dist/commands/doctor.js +484 -0
  151. package/dist/commands/health.js +108 -0
  152. package/dist/commands/models/aliases.js +64 -0
  153. package/dist/commands/models/fallbacks.js +99 -0
  154. package/dist/commands/models/image-fallbacks.js +99 -0
  155. package/dist/commands/models/list.js +323 -0
  156. package/dist/commands/models/scan.js +266 -0
  157. package/dist/commands/models/set-image.js +23 -0
  158. package/dist/commands/models/set.js +23 -0
  159. package/dist/commands/models/shared.js +72 -0
  160. package/dist/commands/models.js +7 -0
  161. package/dist/commands/onboard-auth.js +70 -0
  162. package/dist/commands/onboard-helpers.js +295 -0
  163. package/dist/commands/onboard-interactive.js +17 -0
  164. package/dist/commands/onboard-non-interactive.js +202 -0
  165. package/dist/commands/onboard-providers.js +634 -0
  166. package/dist/commands/onboard-remote.js +120 -0
  167. package/dist/commands/onboard-skills.js +148 -0
  168. package/dist/commands/onboard-types.js +1 -0
  169. package/dist/commands/onboard.js +12 -0
  170. package/dist/commands/send.js +124 -0
  171. package/dist/commands/sessions.js +212 -0
  172. package/dist/commands/setup.js +58 -0
  173. package/dist/commands/signal-install.js +135 -0
  174. package/dist/commands/status.js +207 -0
  175. package/dist/commands/update.js +16 -0
  176. package/dist/config/config.js +6 -0
  177. package/dist/config/defaults.js +61 -0
  178. package/dist/config/io.js +147 -0
  179. package/dist/config/legacy-migrate.js +13 -0
  180. package/dist/config/legacy.js +159 -0
  181. package/dist/config/paths.js +71 -0
  182. package/dist/config/schema.js +150 -0
  183. package/dist/config/sessions.js +282 -0
  184. package/dist/config/talk.js +31 -0
  185. package/dist/config/types.js +1 -0
  186. package/dist/config/validation.js +29 -0
  187. package/dist/config/zod-schema.js +831 -0
  188. package/dist/control-ui/assets/index-BFID3yAA.css +1 -0
  189. package/dist/control-ui/assets/index-CE_axlTS.js +2235 -0
  190. package/dist/control-ui/assets/index-CE_axlTS.js.map +1 -0
  191. package/dist/control-ui/index.html +15 -0
  192. package/dist/cron/isolated-agent.js +499 -0
  193. package/dist/cron/run-log.js +72 -0
  194. package/dist/cron/schedule.js +24 -0
  195. package/dist/cron/service.js +471 -0
  196. package/dist/cron/store.js +43 -0
  197. package/dist/cron/types.js +1 -0
  198. package/dist/daemon/constants.js +10 -0
  199. package/dist/daemon/launchd.js +276 -0
  200. package/dist/daemon/legacy.js +63 -0
  201. package/dist/daemon/program-args.js +76 -0
  202. package/dist/daemon/schtasks.js +257 -0
  203. package/dist/daemon/service.js +60 -0
  204. package/dist/daemon/systemd.js +266 -0
  205. package/dist/discord/index.js +2 -0
  206. package/dist/discord/monitor.js +1188 -0
  207. package/dist/discord/probe.js +54 -0
  208. package/dist/discord/send.js +577 -0
  209. package/dist/discord/token.js +8 -0
  210. package/dist/gateway/auth.js +121 -0
  211. package/dist/gateway/call.js +94 -0
  212. package/dist/gateway/chat-attachments.js +41 -0
  213. package/dist/gateway/client.js +180 -0
  214. package/dist/gateway/config-reload.js +274 -0
  215. package/dist/gateway/control-ui.js +184 -0
  216. package/dist/gateway/hooks-mapping.js +282 -0
  217. package/dist/gateway/hooks.js +168 -0
  218. package/dist/gateway/net.js +29 -0
  219. package/dist/gateway/protocol/index.js +61 -0
  220. package/dist/gateway/protocol/schema.js +560 -0
  221. package/dist/gateway/server-bridge-subscriptions.js +93 -0
  222. package/dist/gateway/server-bridge.js +1013 -0
  223. package/dist/gateway/server-browser.js +12 -0
  224. package/dist/gateway/server-chat.js +159 -0
  225. package/dist/gateway/server-constants.js +8 -0
  226. package/dist/gateway/server-discovery.js +62 -0
  227. package/dist/gateway/server-http.js +165 -0
  228. package/dist/gateway/server-methods/agent-job.js +125 -0
  229. package/dist/gateway/server-methods/agent.js +250 -0
  230. package/dist/gateway/server-methods/chat.js +200 -0
  231. package/dist/gateway/server-methods/config.js +50 -0
  232. package/dist/gateway/server-methods/connect.js +6 -0
  233. package/dist/gateway/server-methods/cron.js +83 -0
  234. package/dist/gateway/server-methods/health.js +28 -0
  235. package/dist/gateway/server-methods/models.js +16 -0
  236. package/dist/gateway/server-methods/nodes.js +294 -0
  237. package/dist/gateway/server-methods/providers.js +217 -0
  238. package/dist/gateway/server-methods/send.js +166 -0
  239. package/dist/gateway/server-methods/sessions.js +305 -0
  240. package/dist/gateway/server-methods/skills.js +83 -0
  241. package/dist/gateway/server-methods/system.js +118 -0
  242. package/dist/gateway/server-methods/talk.js +22 -0
  243. package/dist/gateway/server-methods/types.js +1 -0
  244. package/dist/gateway/server-methods/voicewake.js +30 -0
  245. package/dist/gateway/server-methods/web.js +58 -0
  246. package/dist/gateway/server-methods/wizard.js +100 -0
  247. package/dist/gateway/server-methods.js +53 -0
  248. package/dist/gateway/server-providers.js +644 -0
  249. package/dist/gateway/server-shared.js +1 -0
  250. package/dist/gateway/server-utils.js +35 -0
  251. package/dist/gateway/server.js +1437 -0
  252. package/dist/gateway/session-utils.js +216 -0
  253. package/dist/gateway/ws-log.js +349 -0
  254. package/dist/gateway/ws-logging.js +8 -0
  255. package/dist/globals.js +41 -0
  256. package/dist/hooks/gmail-ops.js +236 -0
  257. package/dist/hooks/gmail-setup-utils.js +278 -0
  258. package/dist/hooks/gmail-watcher.js +175 -0
  259. package/dist/hooks/gmail.js +177 -0
  260. package/dist/imessage/client.js +165 -0
  261. package/dist/imessage/index.js +3 -0
  262. package/dist/imessage/monitor.js +272 -0
  263. package/dist/imessage/probe.js +26 -0
  264. package/dist/imessage/send.js +83 -0
  265. package/dist/imessage/targets.js +176 -0
  266. package/dist/index.js +50 -0
  267. package/dist/infra/agent-events.js +46 -0
  268. package/dist/infra/binaries.js +9 -0
  269. package/dist/infra/bonjour-discovery.js +163 -0
  270. package/dist/infra/bonjour.js +200 -0
  271. package/dist/infra/bridge/server.js +562 -0
  272. package/dist/infra/canvas-host-url.js +54 -0
  273. package/dist/infra/env.js +8 -0
  274. package/dist/infra/errors.js +28 -0
  275. package/dist/infra/gateway-lock.js +8 -0
  276. package/dist/infra/heartbeat-events.js +21 -0
  277. package/dist/infra/heartbeat-runner.js +453 -0
  278. package/dist/infra/heartbeat-wake.js +61 -0
  279. package/dist/infra/is-main.js +37 -0
  280. package/dist/infra/machine-name.js +40 -0
  281. package/dist/infra/node-pairing.js +211 -0
  282. package/dist/infra/pam.js +42 -0
  283. package/dist/infra/path-env.js +92 -0
  284. package/dist/infra/ports.js +87 -0
  285. package/dist/infra/provider-summary.js +80 -0
  286. package/dist/infra/restart.js +29 -0
  287. package/dist/infra/retry.js +16 -0
  288. package/dist/infra/runtime-guard.js +59 -0
  289. package/dist/infra/system-events.js +44 -0
  290. package/dist/infra/system-presence.js +216 -0
  291. package/dist/infra/tailnet.js +46 -0
  292. package/dist/infra/tailscale.js +149 -0
  293. package/dist/infra/voicewake.js +77 -0
  294. package/dist/infra/widearea-dns.js +123 -0
  295. package/dist/infra/ws.js +13 -0
  296. package/dist/logger.js +52 -0
  297. package/dist/logging.js +490 -0
  298. package/dist/macos/gateway-daemon.js +141 -0
  299. package/dist/macos/relay.js +46 -0
  300. package/dist/media/constants.js +33 -0
  301. package/dist/media/host.js +42 -0
  302. package/dist/media/image-ops.js +121 -0
  303. package/dist/media/mime.js +115 -0
  304. package/dist/media/parse.js +81 -0
  305. package/dist/media/server.js +64 -0
  306. package/dist/media/store.js +139 -0
  307. package/dist/process/command-queue.js +97 -0
  308. package/dist/process/exec.js +75 -0
  309. package/dist/protocol.schema.json +2918 -0
  310. package/dist/provider-web.js +8 -0
  311. package/dist/providers/web/index.js +2 -0
  312. package/dist/runtime.js +8 -0
  313. package/dist/sessions/send-policy.js +68 -0
  314. package/dist/signal/client.js +134 -0
  315. package/dist/signal/daemon.js +69 -0
  316. package/dist/signal/index.js +3 -0
  317. package/dist/signal/monitor.js +336 -0
  318. package/dist/signal/probe.js +46 -0
  319. package/dist/signal/send.js +91 -0
  320. package/dist/slack/actions.js +97 -0
  321. package/dist/slack/index.js +5 -0
  322. package/dist/slack/monitor.js +1029 -0
  323. package/dist/slack/probe.js +47 -0
  324. package/dist/slack/send.js +131 -0
  325. package/dist/slack/token.js +10 -0
  326. package/dist/telegram/bot.js +394 -0
  327. package/dist/telegram/download.js +34 -0
  328. package/dist/telegram/index.js +4 -0
  329. package/dist/telegram/monitor.js +47 -0
  330. package/dist/telegram/probe.js +63 -0
  331. package/dist/telegram/proxy.js +9 -0
  332. package/dist/telegram/send.js +138 -0
  333. package/dist/telegram/token.js +30 -0
  334. package/dist/telegram/webhook-set.js +12 -0
  335. package/dist/telegram/webhook.js +56 -0
  336. package/dist/tui/commands.js +74 -0
  337. package/dist/tui/components/assistant-message.js +16 -0
  338. package/dist/tui/components/chat-log.js +92 -0
  339. package/dist/tui/components/custom-editor.js +53 -0
  340. package/dist/tui/components/selectors.js +8 -0
  341. package/dist/tui/components/tool-execution.js +111 -0
  342. package/dist/tui/components/user-message.js +17 -0
  343. package/dist/tui/gateway-chat.js +140 -0
  344. package/dist/tui/layout.js +41 -0
  345. package/dist/tui/message-list.js +57 -0
  346. package/dist/tui/theme/theme.js +80 -0
  347. package/dist/tui/theme.js +25 -0
  348. package/dist/tui/tui.js +708 -0
  349. package/dist/utils.js +133 -0
  350. package/dist/version.js +18 -0
  351. package/dist/web/active-listener.js +7 -0
  352. package/dist/web/auto-reply.js +1203 -0
  353. package/dist/web/inbound.js +481 -0
  354. package/dist/web/login-qr.js +204 -0
  355. package/dist/web/login.js +59 -0
  356. package/dist/web/media.js +148 -0
  357. package/dist/web/outbound.js +67 -0
  358. package/dist/web/qr-image.js +97 -0
  359. package/dist/web/reconnect.js +60 -0
  360. package/dist/web/reply-heartbeat-wake.js +61 -0
  361. package/dist/web/session.js +346 -0
  362. package/dist/wizard/clack-prompter.js +56 -0
  363. package/dist/wizard/onboarding.js +452 -0
  364. package/dist/wizard/prompts.js +6 -0
  365. package/dist/wizard/session.js +203 -0
  366. package/docs/AGENTS.default.md +116 -0
  367. package/docs/CNAME +1 -0
  368. package/docs/RELEASING.md +64 -0
  369. package/docs/_config.yml +51 -0
  370. package/docs/_layouts/default.html +145 -0
  371. package/docs/agent-send.md +21 -0
  372. package/docs/agent.md +104 -0
  373. package/docs/android/connect.md +131 -0
  374. package/docs/architecture.md +89 -0
  375. package/docs/assets/markdown.css +130 -0
  376. package/docs/assets/pixel-lobster.svg +60 -0
  377. package/docs/assets/terminal.css +497 -0
  378. package/docs/assets/theme.js +55 -0
  379. package/docs/audio.md +50 -0
  380. package/docs/background-process.md +74 -0
  381. package/docs/bash.md +32 -0
  382. package/docs/bonjour.md +159 -0
  383. package/docs/browser.md +289 -0
  384. package/docs/camera.md +152 -0
  385. package/docs/clawd.md +199 -0
  386. package/docs/clawdbot-mac.md +104 -0
  387. package/docs/configuration.md +1177 -0
  388. package/docs/control-api.md +49 -0
  389. package/docs/control-ui.md +83 -0
  390. package/docs/cron.md +374 -0
  391. package/docs/dashboard.md +17 -0
  392. package/docs/device-models.md +46 -0
  393. package/docs/discord.md +293 -0
  394. package/docs/discovery.md +112 -0
  395. package/docs/docker.md +251 -0
  396. package/docs/docs.json +86 -0
  397. package/docs/doctor.md +47 -0
  398. package/docs/elevated.md +31 -0
  399. package/docs/faq.md +640 -0
  400. package/docs/gateway/pairing.md +109 -0
  401. package/docs/gateway-lock.md +28 -0
  402. package/docs/gateway.md +174 -0
  403. package/docs/gmail-pubsub.md +191 -0
  404. package/docs/grammy.md +27 -0
  405. package/docs/group-messages.md +71 -0
  406. package/docs/groups.md +78 -0
  407. package/docs/health.md +28 -0
  408. package/docs/heartbeat.md +64 -0
  409. package/docs/images.md +52 -0
  410. package/docs/imessage.md +63 -0
  411. package/docs/index.md +182 -0
  412. package/docs/ios/connect.md +177 -0
  413. package/docs/ios/spec.md +236 -0
  414. package/docs/location-command.md +95 -0
  415. package/docs/logging.md +99 -0
  416. package/docs/lore.md +131 -0
  417. package/docs/mac/bun.md +133 -0
  418. package/docs/mac/canvas.md +161 -0
  419. package/docs/mac/child-process.md +72 -0
  420. package/docs/mac/dev-setup.md +81 -0
  421. package/docs/mac/health.md +28 -0
  422. package/docs/mac/icon.md +26 -0
  423. package/docs/mac/logging.md +51 -0
  424. package/docs/mac/menu-bar.md +69 -0
  425. package/docs/mac/peekaboo.md +170 -0
  426. package/docs/mac/permissions.md +40 -0
  427. package/docs/mac/release.md +76 -0
  428. package/docs/mac/remote.md +57 -0
  429. package/docs/mac/signing.md +41 -0
  430. package/docs/mac/skills.md +27 -0
  431. package/docs/mac/voice-overlay.md +52 -0
  432. package/docs/mac/voicewake.md +56 -0
  433. package/docs/mac/webchat.md +27 -0
  434. package/docs/mac/xpc.md +40 -0
  435. package/docs/models.md +90 -0
  436. package/docs/nix.md +49 -0
  437. package/docs/nodes.md +157 -0
  438. package/docs/onboarding-config-protocol.md +29 -0
  439. package/docs/onboarding.md +185 -0
  440. package/docs/presence.md +133 -0
  441. package/docs/queue.md +78 -0
  442. package/docs/refactor/browser-control-simplification.md +58 -0
  443. package/docs/refactor/canvas-a2ui.md +93 -0
  444. package/docs/refactor/cli-unification.md +64 -0
  445. package/docs/refactor/gateway-client.md +31 -0
  446. package/docs/refactor/gateway.md +99 -0
  447. package/docs/refactor/new-arch.md +171 -0
  448. package/docs/refactor/tui.md +26 -0
  449. package/docs/refactor/web-gateway-troubleshooting.md +37 -0
  450. package/docs/refactor/webagent-session.md +46 -0
  451. package/docs/remote-gateway-readme.md +148 -0
  452. package/docs/remote.md +66 -0
  453. package/docs/research/memory.md +227 -0
  454. package/docs/rpc.md +35 -0
  455. package/docs/security.md +168 -0
  456. package/docs/session-tool.md +119 -0
  457. package/docs/session.md +84 -0
  458. package/docs/sessions.md +8 -0
  459. package/docs/setup.md +118 -0
  460. package/docs/signal.md +113 -0
  461. package/docs/skills-config.md +58 -0
  462. package/docs/skills.md +149 -0
  463. package/docs/slack.md +158 -0
  464. package/docs/surface.md +20 -0
  465. package/docs/tailscale.md +71 -0
  466. package/docs/talk.md +79 -0
  467. package/docs/telegram.md +90 -0
  468. package/docs/templates/AGENTS.md +126 -0
  469. package/docs/templates/BOOTSTRAP.md +53 -0
  470. package/docs/templates/IDENTITY.md +17 -0
  471. package/docs/templates/SOUL.md +41 -0
  472. package/docs/templates/TOOLS.md +41 -0
  473. package/docs/templates/USER.md +22 -0
  474. package/docs/test.md +35 -0
  475. package/docs/thinking.md +46 -0
  476. package/docs/tools.md +248 -0
  477. package/docs/troubleshooting.md +227 -0
  478. package/docs/tui.md +69 -0
  479. package/docs/typebox.md +42 -0
  480. package/docs/voicewake.md +61 -0
  481. package/docs/web.md +115 -0
  482. package/docs/webchat.md +34 -0
  483. package/docs/webhook.md +132 -0
  484. package/docs/whatsapp-clawd.jpg +0 -0
  485. package/docs/whatsapp.md +142 -0
  486. package/docs/wizard.md +158 -0
  487. package/package.json +186 -0
  488. package/skills/apple-notes/SKILL.md +50 -0
  489. package/skills/apple-reminders/SKILL.md +67 -0
  490. package/skills/bear-notes/SKILL.md +79 -0
  491. package/skills/bird/SKILL.md +25 -0
  492. package/skills/blogwatcher/SKILL.md +46 -0
  493. package/skills/blucli/SKILL.md +27 -0
  494. package/skills/brave-search/SKILL.md +30 -0
  495. package/skills/brave-search/scripts/content.mjs +53 -0
  496. package/skills/brave-search/scripts/search.mjs +79 -0
  497. package/skills/camsnap/SKILL.md +25 -0
  498. package/skills/clawdhub/SKILL.md +53 -0
  499. package/skills/coding-agent/SKILL.md +275 -0
  500. package/skills/discord/SKILL.md +369 -0
  501. package/skills/eightctl/SKILL.md +29 -0
  502. package/skills/food-order/SKILL.md +41 -0
  503. package/skills/gemini/SKILL.md +23 -0
  504. package/skills/gifgrep/SKILL.md +47 -0
  505. package/skills/github/SKILL.md +47 -0
  506. package/skills/gog/SKILL.md +36 -0
  507. package/skills/goplaces/SKILL.md +30 -0
  508. package/skills/imsg/SKILL.md +25 -0
  509. package/skills/local-places/SERVER_README.md +101 -0
  510. package/skills/local-places/SKILL.md +91 -0
  511. package/skills/local-places/pyproject.toml +27 -0
  512. package/skills/local-places/src/local_places/__init__.py +2 -0
  513. package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  514. package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  515. package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  516. package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  517. package/skills/local-places/src/local_places/google_places.py +314 -0
  518. package/skills/local-places/src/local_places/main.py +65 -0
  519. package/skills/local-places/src/local_places/schemas.py +107 -0
  520. package/skills/mcporter/SKILL.md +38 -0
  521. package/skills/nano-banana-pro/SKILL.md +29 -0
  522. package/skills/nano-banana-pro/scripts/generate_image.py +167 -0
  523. package/skills/nano-pdf/SKILL.md +20 -0
  524. package/skills/notion/SKILL.md +156 -0
  525. package/skills/obsidian/SKILL.md +55 -0
  526. package/skills/openai-image-gen/SKILL.md +31 -0
  527. package/skills/openai-image-gen/scripts/gen.py +173 -0
  528. package/skills/openai-whisper/SKILL.md +19 -0
  529. package/skills/openai-whisper-api/SKILL.md +43 -0
  530. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  531. package/skills/openhue/SKILL.md +30 -0
  532. package/skills/oracle/SKILL.md +105 -0
  533. package/skills/ordercli/SKILL.md +47 -0
  534. package/skills/peekaboo/SKILL.md +153 -0
  535. package/skills/qmd/SKILL.md +26 -0
  536. package/skills/sag/SKILL.md +62 -0
  537. package/skills/slack/SKILL.md +143 -0
  538. package/skills/songsee/SKILL.md +29 -0
  539. package/skills/sonoscli/SKILL.md +26 -0
  540. package/skills/spotify-player/SKILL.md +34 -0
  541. package/skills/summarize/SKILL.md +49 -0
  542. package/skills/things-mac/SKILL.md +61 -0
  543. package/skills/tmux/SKILL.md +121 -0
  544. package/skills/tmux/scripts/find-sessions.sh +112 -0
  545. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  546. package/skills/trello/SKILL.md +84 -0
  547. package/skills/video-frames/SKILL.md +29 -0
  548. package/skills/video-frames/scripts/frame.sh +81 -0
  549. package/skills/wacli/SKILL.md +42 -0
  550. package/skills/weather/SKILL.md +49 -0
@@ -0,0 +1,452 @@
1
+ import path from "node:path";
2
+ import { loginAnthropic } from "@mariozechner/pi-ai";
3
+ import { isRemoteEnvironment, loginAntigravityVpsAware, } from "../commands/antigravity-oauth.js";
4
+ import { healthCommand } from "../commands/health.js";
5
+ import { applyMinimaxConfig, setAnthropicApiKey, writeOAuthCredentials, } from "../commands/onboard-auth.js";
6
+ import { applyWizardMetadata, DEFAULT_WORKSPACE, detectBrowserOpenSupport, ensureWorkspaceAndSessions, formatControlUiSshHint, handleReset, openUrl, printWizardHeader, probeGatewayReachable, randomToken, resolveControlUiLinks, summarizeExistingConfig, } from "../commands/onboard-helpers.js";
7
+ import { setupProviders } from "../commands/onboard-providers.js";
8
+ import { promptRemoteGatewayConfig } from "../commands/onboard-remote.js";
9
+ import { setupSkills } from "../commands/onboard-skills.js";
10
+ import { CONFIG_PATH_CLAWDBOT, readConfigFileSnapshot, resolveGatewayPort, writeConfigFile, } from "../config/config.js";
11
+ import { GATEWAY_LAUNCH_AGENT_LABEL } from "../daemon/constants.js";
12
+ import { resolveGatewayProgramArguments } from "../daemon/program-args.js";
13
+ import { resolveGatewayService } from "../daemon/service.js";
14
+ import { defaultRuntime } from "../runtime.js";
15
+ import { resolveUserPath, sleep } from "../utils.js";
16
+ export async function runOnboardingWizard(opts, runtime = defaultRuntime, prompter) {
17
+ printWizardHeader(runtime);
18
+ await prompter.intro("Clawdbot onboarding");
19
+ const snapshot = await readConfigFileSnapshot();
20
+ let baseConfig = snapshot.valid ? snapshot.config : {};
21
+ if (snapshot.exists) {
22
+ const title = snapshot.valid
23
+ ? "Existing config detected"
24
+ : "Invalid config";
25
+ await prompter.note(summarizeExistingConfig(baseConfig), title);
26
+ if (!snapshot.valid && snapshot.issues.length > 0) {
27
+ await prompter.note(snapshot.issues
28
+ .map((iss) => `- ${iss.path}: ${iss.message}`)
29
+ .join("\n"), "Config issues");
30
+ }
31
+ const action = (await prompter.select({
32
+ message: "Config handling",
33
+ options: [
34
+ { value: "keep", label: "Use existing values" },
35
+ { value: "modify", label: "Update values" },
36
+ { value: "reset", label: "Reset" },
37
+ ],
38
+ }));
39
+ if (action === "reset") {
40
+ const workspaceDefault = baseConfig.agent?.workspace ?? DEFAULT_WORKSPACE;
41
+ const resetScope = (await prompter.select({
42
+ message: "Reset scope",
43
+ options: [
44
+ { value: "config", label: "Config only" },
45
+ {
46
+ value: "config+creds+sessions",
47
+ label: "Config + creds + sessions",
48
+ },
49
+ {
50
+ value: "full",
51
+ label: "Full reset (config + creds + sessions + workspace)",
52
+ },
53
+ ],
54
+ }));
55
+ await handleReset(resetScope, resolveUserPath(workspaceDefault), runtime);
56
+ baseConfig = {};
57
+ }
58
+ else if (action === "keep" && !snapshot.valid) {
59
+ baseConfig = {};
60
+ }
61
+ }
62
+ const localPort = resolveGatewayPort(baseConfig);
63
+ const localUrl = `ws://127.0.0.1:${localPort}`;
64
+ const localProbe = await probeGatewayReachable({
65
+ url: localUrl,
66
+ token: process.env.CLAWDBOT_GATEWAY_TOKEN,
67
+ password: baseConfig.gateway?.auth?.password ??
68
+ process.env.CLAWDBOT_GATEWAY_PASSWORD,
69
+ });
70
+ const remoteUrl = baseConfig.gateway?.remote?.url?.trim() ?? "";
71
+ const remoteProbe = remoteUrl
72
+ ? await probeGatewayReachable({
73
+ url: remoteUrl,
74
+ token: baseConfig.gateway?.remote?.token,
75
+ })
76
+ : null;
77
+ const mode = opts.mode ??
78
+ (await prompter.select({
79
+ message: "Where will the Gateway run?",
80
+ options: [
81
+ {
82
+ value: "local",
83
+ label: "Local (this machine)",
84
+ hint: localProbe.ok
85
+ ? `Gateway reachable (${localUrl})`
86
+ : `No gateway detected (${localUrl})`,
87
+ },
88
+ {
89
+ value: "remote",
90
+ label: "Remote (info-only)",
91
+ hint: !remoteUrl
92
+ ? "No remote URL configured yet"
93
+ : remoteProbe?.ok
94
+ ? `Gateway reachable (${remoteUrl})`
95
+ : `Configured but unreachable (${remoteUrl})`,
96
+ },
97
+ ],
98
+ }));
99
+ if (mode === "remote") {
100
+ let nextConfig = await promptRemoteGatewayConfig(baseConfig, prompter);
101
+ nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode });
102
+ await writeConfigFile(nextConfig);
103
+ runtime.log(`Updated ${CONFIG_PATH_CLAWDBOT}`);
104
+ await prompter.outro("Remote gateway configured.");
105
+ return;
106
+ }
107
+ const workspaceInput = opts.workspace ??
108
+ (await prompter.text({
109
+ message: "Workspace directory",
110
+ initialValue: baseConfig.agent?.workspace ?? DEFAULT_WORKSPACE,
111
+ }));
112
+ const workspaceDir = resolveUserPath(workspaceInput.trim() || DEFAULT_WORKSPACE);
113
+ let nextConfig = {
114
+ ...baseConfig,
115
+ agent: {
116
+ ...baseConfig.agent,
117
+ workspace: workspaceDir,
118
+ },
119
+ gateway: {
120
+ ...baseConfig.gateway,
121
+ mode: "local",
122
+ },
123
+ };
124
+ const authChoice = (await prompter.select({
125
+ message: "Model/auth choice",
126
+ options: [
127
+ { value: "oauth", label: "Anthropic OAuth (Claude Pro/Max)" },
128
+ {
129
+ value: "antigravity",
130
+ label: "Google Antigravity (Claude Opus 4.5, Gemini 3, etc.)",
131
+ },
132
+ { value: "apiKey", label: "Anthropic API key" },
133
+ { value: "minimax", label: "Minimax M2.1 (LM Studio)" },
134
+ { value: "skip", label: "Skip for now" },
135
+ ],
136
+ }));
137
+ if (authChoice === "oauth") {
138
+ await prompter.note("Browser will open. Paste the code shown after login (code#state).", "Anthropic OAuth");
139
+ const spin = prompter.progress("Waiting for authorization…");
140
+ let oauthCreds = null;
141
+ try {
142
+ oauthCreds = await loginAnthropic(async (url) => {
143
+ await openUrl(url);
144
+ runtime.log(`Open: ${url}`);
145
+ }, async () => {
146
+ const code = await prompter.text({
147
+ message: "Paste authorization code (code#state)",
148
+ validate: (value) => (value?.trim() ? undefined : "Required"),
149
+ });
150
+ return String(code);
151
+ });
152
+ spin.stop("OAuth complete");
153
+ if (oauthCreds) {
154
+ await writeOAuthCredentials("anthropic", oauthCreds);
155
+ }
156
+ }
157
+ catch (err) {
158
+ spin.stop("OAuth failed");
159
+ runtime.error(String(err));
160
+ }
161
+ }
162
+ else if (authChoice === "antigravity") {
163
+ const isRemote = isRemoteEnvironment();
164
+ await prompter.note(isRemote
165
+ ? [
166
+ "You are running in a remote/VPS environment.",
167
+ "A URL will be shown for you to open in your LOCAL browser.",
168
+ "After signing in, copy the redirect URL and paste it back here.",
169
+ ].join("\n")
170
+ : [
171
+ "Browser will open for Google authentication.",
172
+ "Sign in with your Google account that has Antigravity access.",
173
+ "The callback will be captured automatically on localhost:51121.",
174
+ ].join("\n"), "Google Antigravity OAuth");
175
+ const spin = prompter.progress("Starting OAuth flow…");
176
+ let oauthCreds = null;
177
+ try {
178
+ oauthCreds = await loginAntigravityVpsAware(async (url) => {
179
+ if (isRemote) {
180
+ spin.stop("OAuth URL ready");
181
+ runtime.log(`\nOpen this URL in your LOCAL browser:\n\n${url}\n`);
182
+ }
183
+ else {
184
+ spin.update("Complete sign-in in browser…");
185
+ await openUrl(url);
186
+ runtime.log(`Open: ${url}`);
187
+ }
188
+ }, (msg) => spin.update(msg));
189
+ spin.stop("Antigravity OAuth complete");
190
+ if (oauthCreds) {
191
+ await writeOAuthCredentials("google-antigravity", oauthCreds);
192
+ nextConfig = {
193
+ ...nextConfig,
194
+ agent: {
195
+ ...nextConfig.agent,
196
+ model: "google-antigravity/claude-opus-4-5-thinking",
197
+ },
198
+ };
199
+ await prompter.note("Default model set to google-antigravity/claude-opus-4-5-thinking", "Model configured");
200
+ }
201
+ }
202
+ catch (err) {
203
+ spin.stop("Antigravity OAuth failed");
204
+ runtime.error(String(err));
205
+ }
206
+ }
207
+ else if (authChoice === "apiKey") {
208
+ const key = await prompter.text({
209
+ message: "Enter Anthropic API key",
210
+ validate: (value) => (value?.trim() ? undefined : "Required"),
211
+ });
212
+ await setAnthropicApiKey(String(key).trim());
213
+ }
214
+ else if (authChoice === "minimax") {
215
+ nextConfig = applyMinimaxConfig(nextConfig);
216
+ }
217
+ const portRaw = await prompter.text({
218
+ message: "Gateway port",
219
+ initialValue: String(localPort),
220
+ validate: (value) => Number.isFinite(Number(value)) ? undefined : "Invalid port",
221
+ });
222
+ const port = Number.parseInt(String(portRaw), 10);
223
+ let bind = (await prompter.select({
224
+ message: "Gateway bind",
225
+ options: [
226
+ { value: "loopback", label: "Loopback (127.0.0.1)" },
227
+ { value: "lan", label: "LAN" },
228
+ { value: "tailnet", label: "Tailnet" },
229
+ { value: "auto", label: "Auto" },
230
+ ],
231
+ }));
232
+ let authMode = (await prompter.select({
233
+ message: "Gateway auth",
234
+ options: [
235
+ {
236
+ value: "off",
237
+ label: "Off (loopback only)",
238
+ hint: "Recommended for single-machine setups",
239
+ },
240
+ {
241
+ value: "token",
242
+ label: "Token",
243
+ hint: "Use for multi-machine access or non-loopback binds",
244
+ },
245
+ { value: "password", label: "Password" },
246
+ ],
247
+ }));
248
+ const tailscaleMode = (await prompter.select({
249
+ message: "Tailscale exposure",
250
+ options: [
251
+ { value: "off", label: "Off", hint: "No Tailscale exposure" },
252
+ {
253
+ value: "serve",
254
+ label: "Serve",
255
+ hint: "Private HTTPS for your tailnet (devices on Tailscale)",
256
+ },
257
+ {
258
+ value: "funnel",
259
+ label: "Funnel",
260
+ hint: "Public HTTPS via Tailscale Funnel (internet)",
261
+ },
262
+ ],
263
+ }));
264
+ let tailscaleResetOnExit = false;
265
+ if (tailscaleMode !== "off") {
266
+ tailscaleResetOnExit = Boolean(await prompter.confirm({
267
+ message: "Reset Tailscale serve/funnel on exit?",
268
+ initialValue: false,
269
+ }));
270
+ }
271
+ if (tailscaleMode !== "off" && bind !== "loopback") {
272
+ await prompter.note("Tailscale requires bind=loopback. Adjusting bind to loopback.", "Note");
273
+ bind = "loopback";
274
+ }
275
+ if (authMode === "off" && bind !== "loopback") {
276
+ await prompter.note("Non-loopback bind requires auth. Switching to token auth.", "Note");
277
+ authMode = "token";
278
+ }
279
+ if (tailscaleMode === "funnel" && authMode !== "password") {
280
+ await prompter.note("Tailscale funnel requires password auth.", "Note");
281
+ authMode = "password";
282
+ }
283
+ let gatewayToken;
284
+ if (authMode === "token") {
285
+ const tokenInput = await prompter.text({
286
+ message: "Gateway token (blank to generate)",
287
+ placeholder: "Needed for multi-machine or non-loopback access",
288
+ initialValue: randomToken(),
289
+ });
290
+ gatewayToken = String(tokenInput).trim() || randomToken();
291
+ }
292
+ if (authMode === "password") {
293
+ const password = await prompter.text({
294
+ message: "Gateway password",
295
+ validate: (value) => (value?.trim() ? undefined : "Required"),
296
+ });
297
+ nextConfig = {
298
+ ...nextConfig,
299
+ gateway: {
300
+ ...nextConfig.gateway,
301
+ auth: {
302
+ ...nextConfig.gateway?.auth,
303
+ mode: "password",
304
+ password: String(password).trim(),
305
+ },
306
+ },
307
+ };
308
+ }
309
+ else if (authMode === "token") {
310
+ nextConfig = {
311
+ ...nextConfig,
312
+ gateway: {
313
+ ...nextConfig.gateway,
314
+ auth: {
315
+ ...nextConfig.gateway?.auth,
316
+ mode: "token",
317
+ token: gatewayToken,
318
+ },
319
+ },
320
+ };
321
+ }
322
+ nextConfig = {
323
+ ...nextConfig,
324
+ gateway: {
325
+ ...nextConfig.gateway,
326
+ port,
327
+ bind,
328
+ tailscale: {
329
+ ...nextConfig.gateway?.tailscale,
330
+ mode: tailscaleMode,
331
+ resetOnExit: tailscaleResetOnExit,
332
+ },
333
+ },
334
+ };
335
+ nextConfig = await setupProviders(nextConfig, runtime, prompter, {
336
+ allowSignalInstall: true,
337
+ });
338
+ await writeConfigFile(nextConfig);
339
+ runtime.log(`Updated ${CONFIG_PATH_CLAWDBOT}`);
340
+ await ensureWorkspaceAndSessions(workspaceDir, runtime);
341
+ nextConfig = await setupSkills(nextConfig, workspaceDir, runtime, prompter);
342
+ nextConfig = applyWizardMetadata(nextConfig, { command: "onboard", mode });
343
+ await writeConfigFile(nextConfig);
344
+ const installDaemon = await prompter.confirm({
345
+ message: "Install Gateway daemon (recommended)",
346
+ initialValue: true,
347
+ });
348
+ if (installDaemon) {
349
+ const service = resolveGatewayService();
350
+ const loaded = await service.isLoaded({ env: process.env });
351
+ if (loaded) {
352
+ const action = (await prompter.select({
353
+ message: "Gateway service already installed",
354
+ options: [
355
+ { value: "restart", label: "Restart" },
356
+ { value: "reinstall", label: "Reinstall" },
357
+ { value: "skip", label: "Skip" },
358
+ ],
359
+ }));
360
+ if (action === "restart") {
361
+ await service.restart({ stdout: process.stdout });
362
+ }
363
+ else if (action === "reinstall") {
364
+ await service.uninstall({ env: process.env, stdout: process.stdout });
365
+ }
366
+ }
367
+ if (!loaded ||
368
+ (loaded && (await service.isLoaded({ env: process.env })) === false)) {
369
+ const devMode = process.argv[1]?.includes(`${path.sep}src${path.sep}`) &&
370
+ process.argv[1]?.endsWith(".ts");
371
+ const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({ port, dev: devMode });
372
+ const environment = {
373
+ PATH: process.env.PATH,
374
+ CLAWDBOT_GATEWAY_TOKEN: gatewayToken,
375
+ CLAWDBOT_LAUNCHD_LABEL: process.platform === "darwin"
376
+ ? GATEWAY_LAUNCH_AGENT_LABEL
377
+ : undefined,
378
+ };
379
+ await service.install({
380
+ env: process.env,
381
+ stdout: process.stdout,
382
+ programArguments,
383
+ workingDirectory,
384
+ environment,
385
+ });
386
+ }
387
+ }
388
+ await sleep(1500);
389
+ try {
390
+ await healthCommand({ json: false, timeoutMs: 10_000 }, runtime);
391
+ }
392
+ catch (err) {
393
+ runtime.error(`Health check failed: ${String(err)}`);
394
+ }
395
+ await prompter.note([
396
+ "Add nodes for extra features:",
397
+ "- macOS app (system + notifications)",
398
+ "- iOS app (camera/canvas)",
399
+ "- Android app (camera/canvas)",
400
+ ].join("\n"), "Optional apps");
401
+ await prompter.note((() => {
402
+ const links = resolveControlUiLinks({
403
+ bind,
404
+ port,
405
+ basePath: baseConfig.gateway?.controlUi?.basePath,
406
+ });
407
+ const tokenParam = authMode === "token" && gatewayToken
408
+ ? `?token=${encodeURIComponent(gatewayToken)}`
409
+ : "";
410
+ const authedUrl = `${links.httpUrl}${tokenParam}`;
411
+ return [
412
+ `Web UI: ${links.httpUrl}`,
413
+ tokenParam ? `Web UI (with token): ${authedUrl}` : undefined,
414
+ `Gateway WS: ${links.wsUrl}`,
415
+ ]
416
+ .filter(Boolean)
417
+ .join("\n");
418
+ })(), "Control UI");
419
+ const browserSupport = await detectBrowserOpenSupport();
420
+ if (!browserSupport.ok) {
421
+ await prompter.note(formatControlUiSshHint({
422
+ port,
423
+ basePath: baseConfig.gateway?.controlUi?.basePath,
424
+ token: authMode === "token" ? gatewayToken : undefined,
425
+ }), "Open Control UI");
426
+ }
427
+ else {
428
+ const wantsOpen = await prompter.confirm({
429
+ message: "Open Control UI now?",
430
+ initialValue: true,
431
+ });
432
+ if (wantsOpen) {
433
+ const links = resolveControlUiLinks({
434
+ bind,
435
+ port,
436
+ basePath: baseConfig.gateway?.controlUi?.basePath,
437
+ });
438
+ const tokenParam = authMode === "token" && gatewayToken
439
+ ? `?token=${encodeURIComponent(gatewayToken)}`
440
+ : "";
441
+ const opened = await openUrl(`${links.httpUrl}${tokenParam}`);
442
+ if (!opened) {
443
+ await prompter.note(formatControlUiSshHint({
444
+ port,
445
+ basePath: baseConfig.gateway?.controlUi?.basePath,
446
+ token: authMode === "token" ? gatewayToken : undefined,
447
+ }), "Open Control UI");
448
+ }
449
+ }
450
+ }
451
+ await prompter.outro("Onboarding complete.");
452
+ }
@@ -0,0 +1,6 @@
1
+ export class WizardCancelledError extends Error {
2
+ constructor(message = "wizard cancelled") {
3
+ super(message);
4
+ this.name = "WizardCancelledError";
5
+ }
6
+ }
@@ -0,0 +1,203 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { WizardCancelledError, } from "./prompts.js";
3
+ function createDeferred() {
4
+ let resolve;
5
+ let reject;
6
+ const promise = new Promise((res, rej) => {
7
+ resolve = res;
8
+ reject = rej;
9
+ });
10
+ return { promise, resolve, reject };
11
+ }
12
+ class WizardSessionPrompter {
13
+ session;
14
+ constructor(session) {
15
+ this.session = session;
16
+ }
17
+ async intro(title) {
18
+ await this.prompt({
19
+ type: "note",
20
+ title,
21
+ message: "",
22
+ executor: "client",
23
+ });
24
+ }
25
+ async outro(message) {
26
+ await this.prompt({
27
+ type: "note",
28
+ title: "Done",
29
+ message,
30
+ executor: "client",
31
+ });
32
+ }
33
+ async note(message, title) {
34
+ await this.prompt({ type: "note", title, message, executor: "client" });
35
+ }
36
+ async select(params) {
37
+ const res = await this.prompt({
38
+ type: "select",
39
+ message: params.message,
40
+ options: params.options.map((opt) => ({
41
+ value: opt.value,
42
+ label: opt.label,
43
+ hint: opt.hint,
44
+ })),
45
+ initialValue: params.initialValue,
46
+ executor: "client",
47
+ });
48
+ return res;
49
+ }
50
+ async multiselect(params) {
51
+ const res = await this.prompt({
52
+ type: "multiselect",
53
+ message: params.message,
54
+ options: params.options.map((opt) => ({
55
+ value: opt.value,
56
+ label: opt.label,
57
+ hint: opt.hint,
58
+ })),
59
+ initialValue: params.initialValues,
60
+ executor: "client",
61
+ });
62
+ return (Array.isArray(res) ? res : []);
63
+ }
64
+ async text(params) {
65
+ const res = await this.prompt({
66
+ type: "text",
67
+ message: params.message,
68
+ initialValue: params.initialValue,
69
+ placeholder: params.placeholder,
70
+ executor: "client",
71
+ });
72
+ const value = res === null || res === undefined
73
+ ? ""
74
+ : typeof res === "string"
75
+ ? res
76
+ : typeof res === "number" ||
77
+ typeof res === "boolean" ||
78
+ typeof res === "bigint"
79
+ ? String(res)
80
+ : "";
81
+ const error = params.validate?.(value);
82
+ if (error) {
83
+ throw new Error(error);
84
+ }
85
+ return value;
86
+ }
87
+ async confirm(params) {
88
+ const res = await this.prompt({
89
+ type: "confirm",
90
+ message: params.message,
91
+ initialValue: params.initialValue,
92
+ executor: "client",
93
+ });
94
+ return Boolean(res);
95
+ }
96
+ progress(_label) {
97
+ return {
98
+ update: (_message) => { },
99
+ stop: (_message) => { },
100
+ };
101
+ }
102
+ async prompt(step) {
103
+ return await this.session.awaitAnswer({
104
+ ...step,
105
+ id: randomUUID(),
106
+ });
107
+ }
108
+ }
109
+ export class WizardSession {
110
+ runner;
111
+ currentStep = null;
112
+ stepDeferred = null;
113
+ answerDeferred = new Map();
114
+ status = "running";
115
+ error;
116
+ constructor(runner) {
117
+ this.runner = runner;
118
+ const prompter = new WizardSessionPrompter(this);
119
+ void this.run(prompter);
120
+ }
121
+ async next() {
122
+ if (this.currentStep) {
123
+ return { done: false, step: this.currentStep, status: this.status };
124
+ }
125
+ if (this.status !== "running") {
126
+ return { done: true, status: this.status, error: this.error };
127
+ }
128
+ if (!this.stepDeferred) {
129
+ this.stepDeferred = createDeferred();
130
+ }
131
+ const step = await this.stepDeferred.promise;
132
+ if (step) {
133
+ return { done: false, step, status: this.status };
134
+ }
135
+ return { done: true, status: this.status, error: this.error };
136
+ }
137
+ async answer(stepId, value) {
138
+ const deferred = this.answerDeferred.get(stepId);
139
+ if (!deferred) {
140
+ throw new Error("wizard: no pending step");
141
+ }
142
+ this.answerDeferred.delete(stepId);
143
+ this.currentStep = null;
144
+ deferred.resolve(value);
145
+ }
146
+ cancel() {
147
+ if (this.status !== "running")
148
+ return;
149
+ this.status = "cancelled";
150
+ this.error = "cancelled";
151
+ this.currentStep = null;
152
+ for (const [, deferred] of this.answerDeferred) {
153
+ deferred.reject(new WizardCancelledError());
154
+ }
155
+ this.answerDeferred.clear();
156
+ this.resolveStep(null);
157
+ }
158
+ pushStep(step) {
159
+ this.currentStep = step;
160
+ this.resolveStep(step);
161
+ }
162
+ async run(prompter) {
163
+ try {
164
+ await this.runner(prompter);
165
+ this.status = "done";
166
+ }
167
+ catch (err) {
168
+ if (err instanceof WizardCancelledError) {
169
+ this.status = "cancelled";
170
+ this.error = err.message;
171
+ }
172
+ else {
173
+ this.status = "error";
174
+ this.error = String(err);
175
+ }
176
+ }
177
+ finally {
178
+ this.resolveStep(null);
179
+ }
180
+ }
181
+ async awaitAnswer(step) {
182
+ if (this.status !== "running") {
183
+ throw new Error("wizard: session not running");
184
+ }
185
+ this.pushStep(step);
186
+ const deferred = createDeferred();
187
+ this.answerDeferred.set(step.id, deferred);
188
+ return await deferred.promise;
189
+ }
190
+ resolveStep(step) {
191
+ if (!this.stepDeferred)
192
+ return;
193
+ const deferred = this.stepDeferred;
194
+ this.stepDeferred = null;
195
+ deferred.resolve(step);
196
+ }
197
+ getStatus() {
198
+ return this.status;
199
+ }
200
+ getError() {
201
+ return this.error;
202
+ }
203
+ }