@heretek-ai/openclaw 2026.3.30 → 2026.3.32

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 (60) hide show
  1. package/dist/.buildstamp +1 -1
  2. package/dist/build-info.json +3 -3
  3. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  4. package/dist/chunks/command-registry-BeAmVjny.mjs +214 -0
  5. package/dist/chunks/command-registry-BnmWhMEa.mjs +214 -0
  6. package/dist/chunks/command-registry-CCc0vZoH.mjs +14 -0
  7. package/dist/chunks/command-registry-CLOY087q.mjs +14 -0
  8. package/dist/chunks/command-registry-CjAG33h3.mjs +14 -0
  9. package/dist/chunks/command-registry-DPx6M6gw.mjs +214 -0
  10. package/dist/chunks/completion-cli-BDWbmV-o.mjs +448 -0
  11. package/dist/chunks/completion-cli-CBrKGQfJ.mjs +17 -0
  12. package/dist/chunks/completion-cli-CpJ8IzQO.mjs +448 -0
  13. package/dist/chunks/completion-cli-CwouPhbG.mjs +17 -0
  14. package/dist/chunks/completion-cli-DuMZk0lN.mjs +448 -0
  15. package/dist/chunks/completion-cli-DxUdlYt0.mjs +17 -0
  16. package/dist/chunks/doctor-completion-1UqU9aiy.mjs +92 -0
  17. package/dist/chunks/doctor-completion-B_LLsQm-.mjs +92 -0
  18. package/dist/chunks/doctor-completion-CCuL-Cen.mjs +92 -0
  19. package/dist/chunks/gateway-cli-Bc4J6-zj.mjs +43508 -0
  20. package/dist/chunks/gateway-cli-CqAlS2xh.mjs +43508 -0
  21. package/dist/chunks/gateway-cli-CxfnMGx8.mjs +43508 -0
  22. package/dist/chunks/onboard-CRZ2jxOE.mjs +601 -0
  23. package/dist/chunks/onboard-CyzbNCBF.mjs +601 -0
  24. package/dist/chunks/onboard-Y9qZW5yw.mjs +601 -0
  25. package/dist/chunks/program-B27s-BhZ.mjs +163 -0
  26. package/dist/chunks/program-B3JSAo3Q.mjs +163 -0
  27. package/dist/chunks/program-DVTI5ouc.mjs +163 -0
  28. package/dist/chunks/prompt-select-styled-AhC9B2Sr.mjs +5035 -0
  29. package/dist/chunks/prompt-select-styled-DWTJpQCH.mjs +5035 -0
  30. package/dist/chunks/prompt-select-styled-PxJbW1Dj.mjs +5035 -0
  31. package/dist/chunks/register.maintenance-DkQKQI29.mjs +685 -0
  32. package/dist/chunks/register.maintenance-DrxPWWzR.mjs +685 -0
  33. package/dist/chunks/register.maintenance-ofEvddjM.mjs +685 -0
  34. package/dist/chunks/register.onboard-3m3OGP7x.mjs +168 -0
  35. package/dist/chunks/register.onboard-BpL-OvP9.mjs +168 -0
  36. package/dist/chunks/register.onboard-CvtQ4Z6V.mjs +168 -0
  37. package/dist/chunks/register.setup-Dz3jKcQw.mjs +188 -0
  38. package/dist/chunks/register.setup-NRV53Eo_.mjs +188 -0
  39. package/dist/chunks/register.setup-xf9cH3sc.mjs +188 -0
  40. package/dist/chunks/register.subclis-B6xOze_R.mjs +319 -0
  41. package/dist/chunks/register.subclis-B_qUKZPW.mjs +13 -0
  42. package/dist/chunks/register.subclis-BvClctGE.mjs +319 -0
  43. package/dist/chunks/register.subclis-CXtcQnsP.mjs +13 -0
  44. package/dist/chunks/register.subclis-Dd7Q2x2W.mjs +13 -0
  45. package/dist/chunks/register.subclis-Dj9qGYdr.mjs +319 -0
  46. package/dist/chunks/run-main-BYaCWOd9.mjs +437 -0
  47. package/dist/chunks/run-main-CpZzBbaq.mjs +437 -0
  48. package/dist/chunks/run-main-nT8E6iSo.mjs +437 -0
  49. package/dist/chunks/setup-BufxzaUK.mjs +399 -0
  50. package/dist/chunks/setup-DHU6h2yc.mjs +399 -0
  51. package/dist/chunks/setup-Ddj3KzQ7.mjs +399 -0
  52. package/dist/chunks/setup.finalize-Cc2mg8-p.mjs +544 -0
  53. package/dist/chunks/setup.finalize-DVacBRaT.mjs +544 -0
  54. package/dist/chunks/setup.finalize-ZR-Hv0hQ.mjs +544 -0
  55. package/dist/chunks/update-cli-DK2TX2U4.mjs +1632 -0
  56. package/dist/chunks/update-cli-DWGkI141.mjs +1632 -0
  57. package/dist/chunks/update-cli-JcUKNsam.mjs +1632 -0
  58. package/dist/entry.mjs +1 -1
  59. package/dist/index.mjs +1 -1
  60. package/package.json +134 -134
@@ -0,0 +1,544 @@
1
+ import "./redact-CtGOTRBK.mjs";
2
+ import "./errors-CbvpN2RP.mjs";
3
+ import "./logger-vRSRu9wD.mjs";
4
+ import "./paths-CNST7z3O.mjs";
5
+ import "./node-startup-env-Vn3Qa5f_.mjs";
6
+ import "./tmp-openclaw-dir-BeWwpCKM.mjs";
7
+ import "./theme-w86ra_7m.mjs";
8
+ import "./globals-DZFR3wyP.mjs";
9
+ import { g as restoreTerminalState } from "./subsystem-yLe4Gjha.mjs";
10
+ import "./ansi-BJ9IOlIp.mjs";
11
+ import "./boolean-Bwxxidw8.mjs";
12
+ import "./env-9fhyzTaG.mjs";
13
+ import { h as pathExists, y as resolveUserPath } from "./utils-Dc9DiBqf.mjs";
14
+ import "./links-BNNF54ea.mjs";
15
+ import "./paths-B5L5nZjW.mjs";
16
+ import "./auth-profiles-ByaVWjmJ.mjs";
17
+ import "./agent-scope-CnAwGoC2.mjs";
18
+ import "./boundary-path-DnlNnNbU.mjs";
19
+ import "./boundary-file-read-BB4JbZzx.mjs";
20
+ import "./logger-DWOgrQoS.mjs";
21
+ import "./exec-DX0zVVG7.mjs";
22
+ import "./openclaw-root-CSfnLaqO.mjs";
23
+ import { r as DEFAULT_BOOTSTRAP_FILENAME } from "./workspace-CoFl73GV.mjs";
24
+ import "./model-selection-BJk_hQeE.mjs";
25
+ import "./io-CDQGJKjg.mjs";
26
+ import "./shell-env-CP5vTYhw.mjs";
27
+ import "./safe-text-Bsdm3bQS.mjs";
28
+ import "./version-Ckv-IbvB.mjs";
29
+ import "./env-substitution-DGlYO8jV.mjs";
30
+ import "./scan-paths-ahOy4FCQ.mjs";
31
+ import "./includes-DcO1JxKG.mjs";
32
+ import "./zod-schema.providers-core-CjdAU1TY.mjs";
33
+ import "./legacy-web-search-B1O8hiGy.mjs";
34
+ import "./schema-validator-BOH34EXk.mjs";
35
+ import "./registry-DBJv0dvl.mjs";
36
+ import "./config-state-kmbzTT63.mjs";
37
+ import "./min-host-version-EA11e8I5.mjs";
38
+ import "./manifest-registry-dO1qi1iI.mjs";
39
+ import "./runtime-guard-CWHkkioa.mjs";
40
+ import "./avatar-policy-uRVtZ7lJ.mjs";
41
+ import "./ip-BtMd9ssR.mjs";
42
+ import "./zod-schema.agent-runtime-BtGT59eP.mjs";
43
+ import "./zod-schema.core-CMT7g7UX.mjs";
44
+ import "./zod-schema.channels-BAG3dUtC.mjs";
45
+ import "./zod-schema.providers-whatsapp-qnpQepaf.mjs";
46
+ import "./config-Bhjk4Vel.mjs";
47
+ import "./process-scoped-map-BmLEe6nP.mjs";
48
+ import "./file-lock-hqfE8fCo.mjs";
49
+ import "./file-lock-CjVc7LJY.mjs";
50
+ import "./audit-fs-kb-rv_ZT.mjs";
51
+ import "./shared-VxKfp8Uy.mjs";
52
+ import "./resolve-DI6cKS4v.mjs";
53
+ import "./chutes-oauth-BLrDl-qw.mjs";
54
+ import "./json-file-ZNWqd95a.mjs";
55
+ import "./profiles-CqdEUxnl.mjs";
56
+ import "./redact-identifier-DTBisVz0.mjs";
57
+ import { n as resolveCliName } from "./cli-name-lEyorNIN.mjs";
58
+ import { t as formatCliCommand } from "./command-format-D1DrcTDP.mjs";
59
+ import "./daemon-install-plan.shared-MtLyPLVq.mjs";
60
+ import "./runtime-paths-qezFSLu3.mjs";
61
+ import { n as buildGatewayInstallPlan, r as gatewayInstallErrorHint, t as resolveGatewayInstallToken } from "./gateway-install-token-3hijf3Zd.mjs";
62
+ import { n as GATEWAY_DAEMON_RUNTIME_OPTIONS, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-D8rTbK9d.mjs";
63
+ import "./prompt-hGCcgj-D.mjs";
64
+ import "./tailscale-DZJRdd6v.mjs";
65
+ import "./secret-equal-DcNDdUBf.mjs";
66
+ import "./tailnet-Bc7IPWjH.mjs";
67
+ import "./net-OJiOmwY1.mjs";
68
+ import "./auth-C5eSR-m1.mjs";
69
+ import "./credentials-DTsHVnAc.mjs";
70
+ import "./message-channel-DCt8BIP7.mjs";
71
+ import "./store-B0V1qm_-.mjs";
72
+ import "./runtime-a4e8n7tq.mjs";
73
+ import "./registry-9YpVWxKb.mjs";
74
+ import "./plugins-D8oapapr.mjs";
75
+ import "./sessions-CYgBPqrc.mjs";
76
+ import "./paths-CGxgQvpf.mjs";
77
+ import "./types-DoAKcnWC.mjs";
78
+ import "./session-write-lock-DE8KASyZ.mjs";
79
+ import "./json-files-BcpXnc9i.mjs";
80
+ import "./delivery-info-CGNfeMd6.mjs";
81
+ import "./method-scopes-hu-4urbi.mjs";
82
+ import "./call-CcXWxOVG.mjs";
83
+ import "./ws-Dv5Afaxu.mjs";
84
+ import "./control-ui-shared-Dhzx9It_.mjs";
85
+ import { b as waitForGatewayReachable, d as openUrl, g as resolveControlUiLinks, i as detectBrowserOpenSupport, o as formatControlUiSshHint, p as probeGatewayReachable } from "./onboard-helpers-C5GCWoDO.mjs";
86
+ import "./wsl-BW8_A9_i.mjs";
87
+ import "./prompt-style-Dua6SIJh.mjs";
88
+ import "./ports-lsof-D1pMGdtZ.mjs";
89
+ import "./restart-stale-pids-DpJ5KhNO.mjs";
90
+ import "./runtime-parse-Dv1L_ID-.mjs";
91
+ import "./launchd-CFtZl6rs.mjs";
92
+ import { n as resolveGatewayService, t as describeGatewayServiceRestart } from "./service-eLNsotU2.mjs";
93
+ import "./kill-tree-C7sbsfc4.mjs";
94
+ import "./ports-0KspCIU9.mjs";
95
+ import "./ports-probe-CW8QePv6.mjs";
96
+ import { i as isSystemdUserServiceAvailable } from "./systemd-B1Tl3zeB.mjs";
97
+ import "./commands-CibL1v-k.mjs";
98
+ import "./progress-BxDdsPK3.mjs";
99
+ import "./tokens-CIQuw4-h.mjs";
100
+ import "./heartbeat-B3sryw3e.mjs";
101
+ import "./registry-CFSnIRx_.mjs";
102
+ import "./internal-hooks-VOrTrqjW.mjs";
103
+ import "./provider-runtime-CRmI76OF.mjs";
104
+ import "./providers.runtime-CtdkYDy2.mjs";
105
+ import "./accounts-DCMTPA3m.mjs";
106
+ import "./loader-CYgWRKc6.mjs";
107
+ import "./config-presence-DzY-U322.mjs";
108
+ import "./types-BaXbwBIP.mjs";
109
+ import "./hook-runner-global-z_Icpwvo.mjs";
110
+ import "./session-binding-service-Bmkk4TGJ.mjs";
111
+ import "./conversation-binding-elBCYjlA.mjs";
112
+ import "./sdk-alias-C5qDxQv2.mjs";
113
+ import "./anthropic-vertex-provider-Davkw2Ua.mjs";
114
+ import "./provider-env-vars-BvHq384O.mjs";
115
+ import "./model-auth-markers-D9P0hXHx.mjs";
116
+ import "./model-auth-env-D5wfS1i-.mjs";
117
+ import "./model-auth-DtPujlPX.mjs";
118
+ import "./helpers-DxddeIS7.mjs";
119
+ import "./thinking-DvqE1iCX.mjs";
120
+ import "./provider-catalog-BDbid2d6.mjs";
121
+ import "./models-config.providers-4zEBpqdF.mjs";
122
+ import "./models-config.providers.discovery-BjIw3Rrd.mjs";
123
+ import "./web-search-providers.runtime-C9cFlSM-.mjs";
124
+ import "./image-generation-provider-6Bn9TpiN.mjs";
125
+ import "./web-search-providers-D1Ywb8m5.mjs";
126
+ import "./tool-display-BAeitKtC.mjs";
127
+ import "./resolve-configured-secret-input-string-BG1RVESA.mjs";
128
+ import "./bindings-B0u6nL3P.mjs";
129
+ import "./strip-inbound-meta-B47L4pVc.mjs";
130
+ import "./commands-registry.data-CmXNmvUH.mjs";
131
+ import "./commands-registry-D9AHOLEZ.mjs";
132
+ import { t as listConfiguredWebSearchProviders } from "./runtime-XqqgCXDc.mjs";
133
+ import "./read-only-account-inspect-CoN81Eok.mjs";
134
+ import "./note-CaQ2HD-A.mjs";
135
+ import { r as installCompletion } from "./completion-cli-BDWbmV-o.mjs";
136
+ import "./register.subclis-B6xOze_R.mjs";
137
+ import "./command-registry-DPx6M6gw.mjs";
138
+ import "./program-context-9v4H9od4.mjs";
139
+ import "./heartbeat-summary-CUbo9b9F.mjs";
140
+ import { r as healthCommand } from "./health-C4WG9Yfr.mjs";
141
+ import { t as ensureControlUiAssetsBuilt } from "./control-ui-assets-CW49D85b.mjs";
142
+ import { t as resolveSetupSecretInputString } from "./setup.secret-input-DPX4L6ht.mjs";
143
+ import { t as formatHealthCheckFailure } from "./health-format-DnRUP-NJ.mjs";
144
+ import { r as ensureCompletionCacheExists, t as checkShellCompletionStatus } from "./doctor-completion-B_LLsQm-.mjs";
145
+ import { t as runTui } from "./tui-CCssIqEB.mjs";
146
+ import path from "node:path";
147
+ import os from "node:os";
148
+ import fs from "node:fs/promises";
149
+
150
+ //#region src/wizard/setup.completion.ts
151
+ async function resolveProfileHint(shell) {
152
+ const home = process.env.HOME || os.homedir();
153
+ if (shell === "zsh") return "~/.zshrc";
154
+ if (shell === "bash") return await pathExists(path.join(home, ".bashrc")) ? "~/.bashrc" : "~/.bash_profile";
155
+ if (shell === "fish") return "~/.config/fish/config.fish";
156
+ return "$PROFILE";
157
+ }
158
+ function formatReloadHint(shell, profileHint) {
159
+ if (shell === "powershell") return "Restart your shell (or reload your PowerShell profile).";
160
+ return `Restart your shell or run: source ${profileHint}`;
161
+ }
162
+ async function setupWizardShellCompletion(params) {
163
+ const deps = {
164
+ resolveCliName,
165
+ checkShellCompletionStatus,
166
+ ensureCompletionCacheExists,
167
+ installCompletion,
168
+ ...params.deps
169
+ };
170
+ const cliName = deps.resolveCliName();
171
+ const completionStatus = await deps.checkShellCompletionStatus(cliName);
172
+ if (completionStatus.usesSlowPattern) {
173
+ if (await deps.ensureCompletionCacheExists(cliName)) await deps.installCompletion(completionStatus.shell, true, cliName);
174
+ return;
175
+ }
176
+ if (completionStatus.profileInstalled && !completionStatus.cacheExists) {
177
+ await deps.ensureCompletionCacheExists(cliName);
178
+ return;
179
+ }
180
+ if (!completionStatus.profileInstalled) {
181
+ if (!(params.flow === "quickstart" ? true : await params.prompter.confirm({
182
+ message: `Enable ${completionStatus.shell} shell completion for ${cliName}?`,
183
+ initialValue: true
184
+ }))) return;
185
+ if (!await deps.ensureCompletionCacheExists(cliName)) {
186
+ await params.prompter.note(`Failed to generate completion cache. Run \`${cliName} completion --install\` later.`, "Shell completion");
187
+ return;
188
+ }
189
+ await deps.installCompletion(completionStatus.shell, true, cliName);
190
+ const profileHint = await resolveProfileHint(completionStatus.shell);
191
+ await params.prompter.note(`Shell completion installed. ${formatReloadHint(completionStatus.shell, profileHint)}`, "Shell completion");
192
+ }
193
+ }
194
+
195
+ //#endregion
196
+ //#region src/wizard/setup.finalize.ts
197
+ async function finalizeSetupWizard(options) {
198
+ const { flow, opts, baseConfig, nextConfig, settings, prompter, runtime } = options;
199
+ const withWizardProgress = async (label, options$1, work) => {
200
+ const progress = prompter.progress(label);
201
+ try {
202
+ return await work(progress);
203
+ } finally {
204
+ progress.stop(typeof options$1.doneMessage === "function" ? options$1.doneMessage() : options$1.doneMessage);
205
+ }
206
+ };
207
+ const systemdAvailable = process.platform === "linux" ? await isSystemdUserServiceAvailable() : true;
208
+ if (process.platform === "linux" && !systemdAvailable) await prompter.note("Systemd user services are unavailable. Skipping lingering checks and service install.", "Systemd");
209
+ if (process.platform === "linux" && systemdAvailable) {
210
+ const { ensureSystemdUserLingerInteractive } = await import("./systemd-linger-Cxd_lIj7.mjs");
211
+ await ensureSystemdUserLingerInteractive({
212
+ runtime,
213
+ prompter: {
214
+ confirm: prompter.confirm,
215
+ note: prompter.note
216
+ },
217
+ reason: "Linux installs use a systemd user service by default. Without lingering, systemd stops the user session on logout/idle and kills the Gateway.",
218
+ requireConfirm: false
219
+ });
220
+ }
221
+ const explicitInstallDaemon = typeof opts.installDaemon === "boolean" ? opts.installDaemon : void 0;
222
+ let installDaemon;
223
+ if (explicitInstallDaemon !== void 0) installDaemon = explicitInstallDaemon;
224
+ else if (process.platform === "linux" && !systemdAvailable) installDaemon = false;
225
+ else if (flow === "quickstart") installDaemon = true;
226
+ else installDaemon = await prompter.confirm({
227
+ message: "Install Gateway service (recommended)",
228
+ initialValue: true
229
+ });
230
+ if (process.platform === "linux" && !systemdAvailable && installDaemon) {
231
+ await prompter.note("Systemd user services are unavailable; skipping service install. Use your container supervisor or `docker compose up -d`.", "Gateway service");
232
+ installDaemon = false;
233
+ }
234
+ if (installDaemon) {
235
+ const daemonRuntime = flow === "quickstart" ? DEFAULT_GATEWAY_DAEMON_RUNTIME : await prompter.select({
236
+ message: "Gateway service runtime",
237
+ options: GATEWAY_DAEMON_RUNTIME_OPTIONS,
238
+ initialValue: opts.daemonRuntime ?? DEFAULT_GATEWAY_DAEMON_RUNTIME
239
+ });
240
+ if (flow === "quickstart") await prompter.note("QuickStart uses Node for the Gateway service (stable + supported).", "Gateway service runtime");
241
+ const service = resolveGatewayService();
242
+ const loaded = await service.isLoaded({ env: process.env });
243
+ let restartWasScheduled = false;
244
+ if (loaded) {
245
+ const action = await prompter.select({
246
+ message: "Gateway service already installed",
247
+ options: [
248
+ {
249
+ value: "restart",
250
+ label: "Restart"
251
+ },
252
+ {
253
+ value: "reinstall",
254
+ label: "Reinstall"
255
+ },
256
+ {
257
+ value: "skip",
258
+ label: "Skip"
259
+ }
260
+ ]
261
+ });
262
+ if (action === "restart") {
263
+ let restartDoneMessage = "Gateway service restarted.";
264
+ await withWizardProgress("Gateway service", { doneMessage: () => restartDoneMessage }, async (progress) => {
265
+ progress.update("Restarting Gateway service…");
266
+ const restartStatus = describeGatewayServiceRestart("Gateway", await service.restart({
267
+ env: process.env,
268
+ stdout: process.stdout
269
+ }));
270
+ restartDoneMessage = restartStatus.progressMessage;
271
+ restartWasScheduled = restartStatus.scheduled;
272
+ });
273
+ } else if (action === "reinstall") await withWizardProgress("Gateway service", { doneMessage: "Gateway service uninstalled." }, async (progress) => {
274
+ progress.update("Uninstalling Gateway service…");
275
+ await service.uninstall({
276
+ env: process.env,
277
+ stdout: process.stdout
278
+ });
279
+ });
280
+ }
281
+ if (!loaded || !restartWasScheduled && loaded && !await service.isLoaded({ env: process.env })) {
282
+ const progress = prompter.progress("Gateway service");
283
+ let installError = null;
284
+ try {
285
+ progress.update("Preparing Gateway service…");
286
+ const tokenResolution = await resolveGatewayInstallToken({
287
+ config: nextConfig,
288
+ env: process.env
289
+ });
290
+ for (const warning of tokenResolution.warnings) await prompter.note(warning, "Gateway service");
291
+ if (tokenResolution.unavailableReason) installError = [
292
+ "Gateway install blocked:",
293
+ tokenResolution.unavailableReason,
294
+ "Fix gateway auth config/token input and rerun setup."
295
+ ].join(" ");
296
+ else {
297
+ const { programArguments, workingDirectory, environment } = await buildGatewayInstallPlan({
298
+ env: process.env,
299
+ port: settings.port,
300
+ runtime: daemonRuntime,
301
+ warn: (message, title) => prompter.note(message, title),
302
+ config: nextConfig
303
+ });
304
+ progress.update("Installing Gateway service…");
305
+ await service.install({
306
+ env: process.env,
307
+ stdout: process.stdout,
308
+ programArguments,
309
+ workingDirectory,
310
+ environment
311
+ });
312
+ }
313
+ } catch (err) {
314
+ installError = err instanceof Error ? err.message : String(err);
315
+ } finally {
316
+ progress.stop(installError ? "Gateway service install failed." : "Gateway service installed.");
317
+ }
318
+ if (installError) {
319
+ await prompter.note(`Gateway service install failed: ${installError}`, "Gateway");
320
+ await prompter.note(gatewayInstallErrorHint(), "Gateway");
321
+ }
322
+ }
323
+ }
324
+ if (!opts.skipHealth) {
325
+ await waitForGatewayReachable({
326
+ url: resolveControlUiLinks({
327
+ bind: nextConfig.gateway?.bind ?? "loopback",
328
+ port: settings.port,
329
+ customBindHost: nextConfig.gateway?.customBindHost,
330
+ basePath: void 0
331
+ }).wsUrl,
332
+ token: settings.gatewayToken,
333
+ deadlineMs: 15e3
334
+ });
335
+ try {
336
+ await healthCommand({
337
+ json: false,
338
+ timeoutMs: 1e4
339
+ }, runtime);
340
+ } catch (err) {
341
+ runtime.error(formatHealthCheckFailure(err));
342
+ await prompter.note([
343
+ "Docs:",
344
+ "https://docs.openclaw.ai/gateway/health",
345
+ "https://docs.openclaw.ai/gateway/troubleshooting"
346
+ ].join("\n"), "Health check help");
347
+ }
348
+ }
349
+ const controlUiEnabled = nextConfig.gateway?.controlUi?.enabled ?? baseConfig.gateway?.controlUi?.enabled ?? true;
350
+ if (!opts.skipUi && controlUiEnabled) {
351
+ const controlUiAssets = await ensureControlUiAssetsBuilt(runtime);
352
+ if (!controlUiAssets.ok && controlUiAssets.message) runtime.error(controlUiAssets.message);
353
+ }
354
+ await prompter.note([
355
+ "Add nodes for extra features:",
356
+ "- macOS app (system + notifications)",
357
+ "- iOS app (camera/canvas)",
358
+ "- Android app (camera/canvas)"
359
+ ].join("\n"), "Optional apps");
360
+ const controlUiBasePath = nextConfig.gateway?.controlUi?.basePath ?? baseConfig.gateway?.controlUi?.basePath;
361
+ const links = resolveControlUiLinks({
362
+ bind: settings.bind,
363
+ port: settings.port,
364
+ customBindHost: settings.customBindHost,
365
+ basePath: controlUiBasePath
366
+ });
367
+ const authedUrl = settings.authMode === "token" && settings.gatewayToken ? `${links.httpUrl}#token=${encodeURIComponent(settings.gatewayToken)}` : links.httpUrl;
368
+ let resolvedGatewayPassword = "";
369
+ if (settings.authMode === "password") try {
370
+ resolvedGatewayPassword = await resolveSetupSecretInputString({
371
+ config: nextConfig,
372
+ value: nextConfig.gateway?.auth?.password,
373
+ path: "gateway.auth.password",
374
+ env: process.env
375
+ }) ?? "";
376
+ } catch (error) {
377
+ await prompter.note(["Could not resolve gateway.auth.password SecretRef for setup auth.", error instanceof Error ? error.message : String(error)].join("\n"), "Gateway auth");
378
+ }
379
+ const gatewayProbe = await probeGatewayReachable({
380
+ url: links.wsUrl,
381
+ token: settings.authMode === "token" ? settings.gatewayToken : void 0,
382
+ password: settings.authMode === "password" ? resolvedGatewayPassword : ""
383
+ });
384
+ const gatewayStatusLine = gatewayProbe.ok ? "Gateway: reachable" : `Gateway: not detected${gatewayProbe.detail ? ` (${gatewayProbe.detail})` : ""}`;
385
+ const bootstrapPath = path.join(resolveUserPath(options.workspaceDir), DEFAULT_BOOTSTRAP_FILENAME);
386
+ const hasBootstrap = await fs.access(bootstrapPath).then(() => true).catch(() => false);
387
+ await prompter.note([
388
+ `Web UI: ${links.httpUrl}`,
389
+ settings.authMode === "token" && settings.gatewayToken ? `Web UI (with token): ${authedUrl}` : void 0,
390
+ `Gateway WS: ${links.wsUrl}`,
391
+ gatewayStatusLine,
392
+ "Docs: https://docs.openclaw.ai/web/control-ui"
393
+ ].filter(Boolean).join("\n"), "Control UI");
394
+ let controlUiOpened = false;
395
+ let controlUiOpenHint;
396
+ let hatchChoice = null;
397
+ let launchedTui = false;
398
+ if (!opts.skipUi && gatewayProbe.ok) {
399
+ if (hasBootstrap) await prompter.note([
400
+ "This is the defining action that makes your agent you.",
401
+ "Please take your time.",
402
+ "The more you tell it, the better the experience will be.",
403
+ "We will send: \"Wake up, my friend!\""
404
+ ].join("\n"), "Start TUI (best option!)");
405
+ await prompter.note([
406
+ "Gateway token: shared auth for the Gateway + Control UI.",
407
+ "Stored in: ~/.Heretek-AI/openclaw.json (gateway.auth.token) or OPENCLAW_GATEWAY_TOKEN.",
408
+ `View token: ${formatCliCommand("openclaw config get gateway.auth.token")}`,
409
+ `Generate token: ${formatCliCommand("openclaw doctor --generate-gateway-token")}`,
410
+ "Web UI keeps dashboard URL tokens in memory for the current tab and strips them from the URL after load.",
411
+ `Open the dashboard anytime: ${formatCliCommand("openclaw dashboard --no-open")}`,
412
+ "If prompted: paste the token into Control UI settings (or use the tokenized dashboard URL)."
413
+ ].join("\n"), "Token");
414
+ hatchChoice = await prompter.select({
415
+ message: "How do you want to hatch your bot?",
416
+ options: [
417
+ {
418
+ value: "tui",
419
+ label: "Hatch in TUI (recommended)"
420
+ },
421
+ {
422
+ value: "web",
423
+ label: "Open the Web UI"
424
+ },
425
+ {
426
+ value: "later",
427
+ label: "Do this later"
428
+ }
429
+ ],
430
+ initialValue: "tui"
431
+ });
432
+ if (hatchChoice === "tui") {
433
+ restoreTerminalState("pre-setup tui", { resumeStdinIfPaused: true });
434
+ await runTui({
435
+ url: links.wsUrl,
436
+ token: settings.authMode === "token" ? settings.gatewayToken : void 0,
437
+ password: settings.authMode === "password" ? resolvedGatewayPassword : "",
438
+ deliver: false,
439
+ message: hasBootstrap ? "Wake up, my friend!" : void 0
440
+ });
441
+ launchedTui = true;
442
+ } else if (hatchChoice === "web") {
443
+ if ((await detectBrowserOpenSupport()).ok) {
444
+ controlUiOpened = await openUrl(authedUrl);
445
+ if (!controlUiOpened) controlUiOpenHint = formatControlUiSshHint({
446
+ port: settings.port,
447
+ basePath: controlUiBasePath,
448
+ token: settings.authMode === "token" ? settings.gatewayToken : void 0
449
+ });
450
+ } else controlUiOpenHint = formatControlUiSshHint({
451
+ port: settings.port,
452
+ basePath: controlUiBasePath,
453
+ token: settings.authMode === "token" ? settings.gatewayToken : void 0
454
+ });
455
+ await prompter.note([
456
+ `Dashboard link (with token): ${authedUrl}`,
457
+ controlUiOpened ? "Opened in your browser. Keep that tab to control OpenClaw." : "Copy/paste this URL in a browser on this machine to control OpenClaw.",
458
+ controlUiOpenHint
459
+ ].filter(Boolean).join("\n"), "Dashboard ready");
460
+ } else await prompter.note(`When you're ready: ${formatCliCommand("openclaw dashboard --no-open")}`, "Later");
461
+ } else if (opts.skipUi) await prompter.note("Skipping Control UI/TUI prompts.", "Control UI");
462
+ await prompter.note(["Back up your agent workspace.", "Docs: https://docs.openclaw.ai/concepts/agent-workspace"].join("\n"), "Workspace backup");
463
+ await prompter.note("Running agents on your computer is risky — harden your setup: https://docs.openclaw.ai/security", "Security");
464
+ await setupWizardShellCompletion({
465
+ flow,
466
+ prompter
467
+ });
468
+ if (!opts.skipUi && settings.authMode === "token" && Boolean(settings.gatewayToken) && hatchChoice === null) {
469
+ if ((await detectBrowserOpenSupport()).ok) {
470
+ controlUiOpened = await openUrl(authedUrl);
471
+ if (!controlUiOpened) controlUiOpenHint = formatControlUiSshHint({
472
+ port: settings.port,
473
+ basePath: controlUiBasePath,
474
+ token: settings.gatewayToken
475
+ });
476
+ } else controlUiOpenHint = formatControlUiSshHint({
477
+ port: settings.port,
478
+ basePath: controlUiBasePath,
479
+ token: settings.gatewayToken
480
+ });
481
+ await prompter.note([
482
+ `Dashboard link (with token): ${authedUrl}`,
483
+ controlUiOpened ? "Opened in your browser. Keep that tab to control OpenClaw." : "Copy/paste this URL in a browser on this machine to control OpenClaw.",
484
+ controlUiOpenHint
485
+ ].filter(Boolean).join("\n"), "Dashboard ready");
486
+ }
487
+ const webSearchProvider = nextConfig.tools?.web?.search?.provider;
488
+ const webSearchEnabled = nextConfig.tools?.web?.search?.enabled;
489
+ const configuredSearchProviders = listConfiguredWebSearchProviders({ config: nextConfig });
490
+ if (webSearchProvider) {
491
+ const { resolveExistingKey, hasExistingKey, hasKeyInEnv } = await import("./onboard-search-BUF1Kic8.mjs");
492
+ const entry = configuredSearchProviders.find((e) => e.id === webSearchProvider);
493
+ const label = entry?.label ?? webSearchProvider;
494
+ const storedKey = entry ? resolveExistingKey(nextConfig, webSearchProvider) : void 0;
495
+ const keyConfigured = entry ? hasExistingKey(nextConfig, webSearchProvider) : false;
496
+ const envAvailable = entry ? hasKeyInEnv(entry) : false;
497
+ const hasKey = keyConfigured || envAvailable;
498
+ const keySource = storedKey ? "API key: stored in config." : keyConfigured ? "API key: configured via secret reference." : envAvailable ? `API key: provided via ${entry?.envVars.join(" / ")} env var.` : void 0;
499
+ if (!entry) await prompter.note([
500
+ `Web search provider ${label} is selected but unavailable under the current plugin policy.`,
501
+ "web_search will not work until the provider is re-enabled or a different provider is selected.",
502
+ ` ${formatCliCommand("openclaw configure --section web")}`,
503
+ "",
504
+ "Docs: https://docs.openclaw.ai/tools/web"
505
+ ].join("\n"), "Web search");
506
+ else if (webSearchEnabled !== false && hasKey) await prompter.note([
507
+ "Web search is enabled, so your agent can look things up online when needed.",
508
+ "",
509
+ `Provider: ${label}`,
510
+ ...keySource ? [keySource] : [],
511
+ "Docs: https://docs.openclaw.ai/tools/web"
512
+ ].join("\n"), "Web search");
513
+ else if (!hasKey) await prompter.note([
514
+ `Provider ${label} is selected but no API key was found.`,
515
+ "web_search will not work until a key is added.",
516
+ ` ${formatCliCommand("openclaw configure --section web")}`,
517
+ "",
518
+ `Get your key at: ${entry?.signupUrl ?? "https://docs.openclaw.ai/tools/web"}`,
519
+ "Docs: https://docs.openclaw.ai/tools/web"
520
+ ].join("\n"), "Web search");
521
+ else await prompter.note([
522
+ `Web search (${label}) is configured but disabled.`,
523
+ `Re-enable: ${formatCliCommand("openclaw configure --section web")}`,
524
+ "",
525
+ "Docs: https://docs.openclaw.ai/tools/web"
526
+ ].join("\n"), "Web search");
527
+ } else {
528
+ const { hasExistingKey, hasKeyInEnv } = await import("./onboard-search-BUF1Kic8.mjs");
529
+ const legacyDetected = configuredSearchProviders.find((e) => hasExistingKey(nextConfig, e.id) || hasKeyInEnv(e));
530
+ if (legacyDetected) await prompter.note([`Web search is available via ${legacyDetected.label} (auto-detected).`, "Docs: https://docs.openclaw.ai/tools/web"].join("\n"), "Web search");
531
+ else await prompter.note([
532
+ "Web search was skipped. You can enable it later:",
533
+ ` ${formatCliCommand("openclaw configure --section web")}`,
534
+ "",
535
+ "Docs: https://docs.openclaw.ai/tools/web"
536
+ ].join("\n"), "Web search");
537
+ }
538
+ await prompter.note("What now: https://openclaw.ai/showcase (\"What People Are Building\").", "What now");
539
+ await prompter.outro(controlUiOpened ? "Onboarding complete. Dashboard opened; keep that tab to control OpenClaw." : "Onboarding complete. Use the dashboard link above to control OpenClaw.");
540
+ return { launchedTui };
541
+ }
542
+
543
+ //#endregion
544
+ export { finalizeSetupWizard };