@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,601 @@
1
+ import { u as resolveGatewayPort } from "./paths-CNST7z3O.mjs";
2
+ import { g as restoreTerminalState, h as writeRuntimeJson, m as defaultRuntime } from "./subsystem-yLe4Gjha.mjs";
3
+ import { y as resolveUserPath } from "./utils-Dc9DiBqf.mjs";
4
+ import { d as readConfigFileSnapshot, g as writeConfigFile } from "./io-CDQGJKjg.mjs";
5
+ import { s as isValidEnvSecretRefId } from "./types.secrets-CKipkqRX.mjs";
6
+ import { t as assertSupportedRuntime } from "./runtime-guard-CWHkkioa.mjs";
7
+ import { l as resolveDefaultSecretProviderAlias } from "./ref-contract-UXicez0Y.mjs";
8
+ import { t as formatCliCommand } from "./command-format-D1DrcTDP.mjs";
9
+ import { t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-D8rTbK9d.mjs";
10
+ import { a as ensureWorkspaceAndSessions, b as waitForGatewayReachable, c as handleReset, g as resolveControlUiLinks, m as randomToken, n as applyWizardMetadata, t as DEFAULT_WORKSPACE, u as normalizeGatewayTokenInput } from "./onboard-helpers-C5GCWoDO.mjs";
11
+ import { t as WizardCancelledError } from "./prompts-BqZHJHEi.mjs";
12
+ import { n as logConfigUpdated } from "./logging-CcQ-gmqC.mjs";
13
+ import { t as createClackPrompter } from "./clack-prompter-C0PG2vbx.mjs";
14
+ import { t as runSetupWizard } from "./setup-DHU6h2yc.mjs";
15
+ import { i as resolveManifestProviderOnboardAuthFlags } from "./provider-auth-choices-DFywK1Pz.mjs";
16
+ import { n as isDeprecatedAuthChoice, r as normalizeLegacyOnboardAuthChoice } from "./auth-choice-legacy-WiHuT2El.mjs";
17
+ import { r as applyLocalSetupWorkspaceConfig } from "./onboard-config-B4gx9Ky_.mjs";
18
+
19
+ //#region src/commands/onboard-core-auth-flags.ts
20
+ const CORE_ONBOARD_AUTH_FLAGS = [{
21
+ optionKey: "litellmApiKey",
22
+ authChoice: "litellm-api-key",
23
+ cliFlag: "--litellm-api-key",
24
+ cliOption: "--litellm-api-key <key>",
25
+ description: "LiteLLM API key"
26
+ }];
27
+
28
+ //#endregion
29
+ //#region src/commands/onboard-interactive.ts
30
+ async function runInteractiveSetup(opts, runtime = defaultRuntime) {
31
+ const prompter = createClackPrompter();
32
+ let exitCode = null;
33
+ try {
34
+ await runSetupWizard(opts, runtime, prompter);
35
+ } catch (err) {
36
+ if (err instanceof WizardCancelledError) {
37
+ exitCode = 1;
38
+ return;
39
+ }
40
+ throw err;
41
+ } finally {
42
+ restoreTerminalState("setup finish", { resumeStdinIfPaused: false });
43
+ if (exitCode !== null) runtime.exit(exitCode);
44
+ }
45
+ }
46
+
47
+ //#endregion
48
+ //#region src/commands/onboard-non-interactive/local/auth-choice-inference.ts
49
+ function hasStringValue(value) {
50
+ return typeof value === "string" ? value.trim().length > 0 : Boolean(value);
51
+ }
52
+ function inferAuthChoiceFromFlags(opts) {
53
+ const matches = [...CORE_ONBOARD_AUTH_FLAGS, ...resolveManifestProviderOnboardAuthFlags()].filter(({ optionKey }) => hasStringValue(opts[optionKey])).map((flag) => ({
54
+ optionKey: flag.optionKey,
55
+ authChoice: flag.authChoice,
56
+ label: flag.cliFlag
57
+ }));
58
+ if (hasStringValue(opts.customBaseUrl) || hasStringValue(opts.customModelId) || hasStringValue(opts.customApiKey)) matches.push({
59
+ optionKey: "customBaseUrl",
60
+ authChoice: "custom-api-key",
61
+ label: "--custom-base-url/--custom-model-id/--custom-api-key"
62
+ });
63
+ return {
64
+ choice: matches[0]?.authChoice,
65
+ matches
66
+ };
67
+ }
68
+
69
+ //#endregion
70
+ //#region src/commands/onboard-non-interactive/local/gateway-config.ts
71
+ function applyNonInteractiveGatewayConfig(params) {
72
+ const { opts, runtime } = params;
73
+ const hasGatewayPort = opts.gatewayPort !== void 0;
74
+ if (hasGatewayPort && (!Number.isFinite(opts.gatewayPort) || (opts.gatewayPort ?? 0) <= 0)) {
75
+ runtime.error("Invalid --gateway-port");
76
+ runtime.exit(1);
77
+ return null;
78
+ }
79
+ const port = hasGatewayPort ? opts.gatewayPort : params.defaultPort;
80
+ let bind = opts.gatewayBind ?? "loopback";
81
+ const authModeRaw = opts.gatewayAuth ?? "token";
82
+ if (authModeRaw !== "token" && authModeRaw !== "password") {
83
+ runtime.error("Invalid --gateway-auth (use token|password).");
84
+ runtime.exit(1);
85
+ return null;
86
+ }
87
+ let authMode = authModeRaw;
88
+ const tailscaleMode = opts.tailscale ?? "off";
89
+ const tailscaleResetOnExit = Boolean(opts.tailscaleResetOnExit);
90
+ if (tailscaleMode !== "off" && bind !== "loopback") bind = "loopback";
91
+ if (tailscaleMode === "funnel" && authMode !== "password") authMode = "password";
92
+ let nextConfig = params.nextConfig;
93
+ const explicitGatewayToken = normalizeGatewayTokenInput(opts.gatewayToken);
94
+ const envGatewayToken = normalizeGatewayTokenInput(process.env.OPENCLAW_GATEWAY_TOKEN);
95
+ let gatewayToken = explicitGatewayToken || envGatewayToken || void 0;
96
+ const gatewayTokenRefEnv = String(opts.gatewayTokenRefEnv ?? "").trim();
97
+ if (authMode === "token") if (gatewayTokenRefEnv) {
98
+ if (!isValidEnvSecretRefId(gatewayTokenRefEnv)) {
99
+ runtime.error("Invalid --gateway-token-ref-env (use env var name like OPENCLAW_GATEWAY_TOKEN).");
100
+ runtime.exit(1);
101
+ return null;
102
+ }
103
+ if (explicitGatewayToken) {
104
+ runtime.error("Use either --gateway-token or --gateway-token-ref-env, not both.");
105
+ runtime.exit(1);
106
+ return null;
107
+ }
108
+ const resolvedFromEnv = process.env[gatewayTokenRefEnv]?.trim();
109
+ if (!resolvedFromEnv) {
110
+ runtime.error(`Environment variable "${gatewayTokenRefEnv}" is missing or empty.`);
111
+ runtime.exit(1);
112
+ return null;
113
+ }
114
+ gatewayToken = resolvedFromEnv;
115
+ nextConfig = {
116
+ ...nextConfig,
117
+ gateway: {
118
+ ...nextConfig.gateway,
119
+ auth: {
120
+ ...nextConfig.gateway?.auth,
121
+ mode: "token",
122
+ token: {
123
+ source: "env",
124
+ provider: resolveDefaultSecretProviderAlias(nextConfig, "env", { preferFirstProviderForSource: true }),
125
+ id: gatewayTokenRefEnv
126
+ }
127
+ }
128
+ }
129
+ };
130
+ } else {
131
+ if (!gatewayToken) gatewayToken = randomToken();
132
+ nextConfig = {
133
+ ...nextConfig,
134
+ gateway: {
135
+ ...nextConfig.gateway,
136
+ auth: {
137
+ ...nextConfig.gateway?.auth,
138
+ mode: "token",
139
+ token: gatewayToken
140
+ }
141
+ }
142
+ };
143
+ }
144
+ if (authMode === "password") {
145
+ const password = opts.gatewayPassword?.trim();
146
+ if (!password) {
147
+ runtime.error("Missing --gateway-password for password auth.");
148
+ runtime.exit(1);
149
+ return null;
150
+ }
151
+ nextConfig = {
152
+ ...nextConfig,
153
+ gateway: {
154
+ ...nextConfig.gateway,
155
+ auth: {
156
+ ...nextConfig.gateway?.auth,
157
+ mode: "password",
158
+ password
159
+ }
160
+ }
161
+ };
162
+ }
163
+ nextConfig = {
164
+ ...nextConfig,
165
+ gateway: {
166
+ ...nextConfig.gateway,
167
+ port,
168
+ bind,
169
+ tailscale: {
170
+ ...nextConfig.gateway?.tailscale,
171
+ mode: tailscaleMode,
172
+ resetOnExit: tailscaleResetOnExit
173
+ }
174
+ }
175
+ };
176
+ return {
177
+ nextConfig,
178
+ port,
179
+ bind,
180
+ authMode,
181
+ tailscaleMode,
182
+ tailscaleResetOnExit,
183
+ gatewayToken
184
+ };
185
+ }
186
+
187
+ //#endregion
188
+ //#region src/commands/onboard-non-interactive/local/output.ts
189
+ function logNonInteractiveOnboardingJson(params) {
190
+ if (!params.opts.json) return;
191
+ writeRuntimeJson(params.runtime, {
192
+ ok: true,
193
+ mode: params.mode,
194
+ workspace: params.workspaceDir,
195
+ authChoice: params.authChoice,
196
+ gateway: params.gateway,
197
+ installDaemon: Boolean(params.installDaemon),
198
+ daemonInstall: params.daemonInstall,
199
+ daemonRuntime: params.daemonRuntime,
200
+ skipSkills: Boolean(params.skipSkills),
201
+ skipHealth: Boolean(params.skipHealth)
202
+ });
203
+ }
204
+ function formatGatewayRuntimeSummary(diagnostics) {
205
+ const service = diagnostics?.service;
206
+ if (!service?.runtimeStatus) return;
207
+ const parts = [service.runtimeStatus];
208
+ if (typeof service.pid === "number") parts.push(`pid ${service.pid}`);
209
+ if (service.state) parts.push(`state ${service.state}`);
210
+ if (typeof service.lastExitStatus === "number") parts.push(`last exit ${service.lastExitStatus}`);
211
+ if (service.lastExitReason) parts.push(`reason ${service.lastExitReason}`);
212
+ return parts.join(", ");
213
+ }
214
+ function logNonInteractiveOnboardingFailure(params) {
215
+ const hints = params.hints?.filter(Boolean) ?? [];
216
+ const gatewayRuntime = formatGatewayRuntimeSummary(params.diagnostics);
217
+ if (params.opts.json) {
218
+ writeRuntimeJson(params.runtime, {
219
+ ok: false,
220
+ mode: params.mode,
221
+ phase: params.phase,
222
+ message: params.message,
223
+ detail: params.detail,
224
+ gateway: params.gateway,
225
+ installDaemon: Boolean(params.installDaemon),
226
+ daemonInstall: params.daemonInstall,
227
+ daemonRuntime: params.daemonRuntime,
228
+ diagnostics: params.diagnostics,
229
+ hints: hints.length > 0 ? hints : void 0
230
+ });
231
+ return;
232
+ }
233
+ const lines = [
234
+ params.message,
235
+ params.detail ? `Last probe: ${params.detail}` : void 0,
236
+ params.diagnostics?.service ? `Service: ${params.diagnostics.service.label} (${params.diagnostics.service.loaded ? params.diagnostics.service.loadedText : "not loaded"})` : void 0,
237
+ gatewayRuntime ? `Runtime: ${gatewayRuntime}` : void 0,
238
+ params.diagnostics?.lastGatewayError ? `Last gateway error: ${params.diagnostics.lastGatewayError}` : void 0,
239
+ params.diagnostics?.inspectError ? `Diagnostics warning: ${params.diagnostics.inspectError}` : void 0,
240
+ hints.length > 0 ? hints.join("\n") : void 0
241
+ ].filter(Boolean).join("\n");
242
+ params.runtime.error(lines);
243
+ }
244
+
245
+ //#endregion
246
+ //#region src/commands/onboard-non-interactive/local/skills-config.ts
247
+ function applyNonInteractiveSkillsConfig(params) {
248
+ const { nextConfig, opts, runtime } = params;
249
+ if (opts.skipSkills) return nextConfig;
250
+ const nodeManager = opts.nodeManager ?? "npm";
251
+ if (![
252
+ "npm",
253
+ "pnpm",
254
+ "bun"
255
+ ].includes(nodeManager)) {
256
+ runtime.error("Invalid --node-manager (use npm, pnpm, or bun)");
257
+ runtime.exit(1);
258
+ return nextConfig;
259
+ }
260
+ return {
261
+ ...nextConfig,
262
+ skills: {
263
+ ...nextConfig.skills,
264
+ install: {
265
+ ...nextConfig.skills?.install,
266
+ nodeManager
267
+ }
268
+ }
269
+ };
270
+ }
271
+
272
+ //#endregion
273
+ //#region src/commands/onboard-non-interactive/local/workspace.ts
274
+ function resolveNonInteractiveWorkspaceDir(params) {
275
+ return resolveUserPath((params.opts.workspace ?? params.baseConfig.agents?.defaults?.workspace ?? params.defaultWorkspaceDir).trim());
276
+ }
277
+
278
+ //#endregion
279
+ //#region src/commands/onboard-non-interactive/local.ts
280
+ const INSTALL_DAEMON_HEALTH_DEADLINE_MS = 45e3;
281
+ const ATTACH_EXISTING_GATEWAY_HEALTH_DEADLINE_MS = 15e3;
282
+ async function collectGatewayHealthFailureDiagnostics() {
283
+ const diagnostics = {};
284
+ try {
285
+ const { resolveGatewayService } = await import("./service-BdQxMPOx.mjs");
286
+ const service = resolveGatewayService();
287
+ const env = process.env;
288
+ const [loaded, runtime] = await Promise.all([service.isLoaded({ env }).catch(() => false), service.readRuntime(env).catch(() => void 0)]);
289
+ diagnostics.service = {
290
+ label: service.label,
291
+ loaded,
292
+ loadedText: service.loadedText,
293
+ runtimeStatus: runtime?.status,
294
+ state: runtime?.state,
295
+ pid: runtime?.pid,
296
+ lastExitStatus: runtime?.lastExitStatus,
297
+ lastExitReason: runtime?.lastExitReason
298
+ };
299
+ } catch (err) {
300
+ diagnostics.inspectError = `service diagnostics failed: ${String(err)}`;
301
+ }
302
+ try {
303
+ const { readLastGatewayErrorLine } = await import("./diagnostics-CFvH6Rsr.mjs");
304
+ diagnostics.lastGatewayError = await readLastGatewayErrorLine(process.env) ?? void 0;
305
+ } catch (err) {
306
+ diagnostics.inspectError = diagnostics.inspectError ? `${diagnostics.inspectError}; log diagnostics failed: ${String(err)}` : `log diagnostics failed: ${String(err)}`;
307
+ }
308
+ return diagnostics.service || diagnostics.lastGatewayError || diagnostics.inspectError ? diagnostics : void 0;
309
+ }
310
+ async function runNonInteractiveLocalSetup(params) {
311
+ const { opts, runtime, baseConfig } = params;
312
+ const mode = "local";
313
+ const workspaceDir = resolveNonInteractiveWorkspaceDir({
314
+ opts,
315
+ baseConfig,
316
+ defaultWorkspaceDir: DEFAULT_WORKSPACE
317
+ });
318
+ let nextConfig = applyLocalSetupWorkspaceConfig(baseConfig, workspaceDir);
319
+ const inferredAuthChoice = inferAuthChoiceFromFlags(opts);
320
+ if (!opts.authChoice && inferredAuthChoice.matches.length > 1) {
321
+ runtime.error([
322
+ "Multiple API key flags were provided for non-interactive setup.",
323
+ "Use a single provider flag or pass --auth-choice explicitly.",
324
+ `Flags: ${inferredAuthChoice.matches.map((match) => match.label).join(", ")}`
325
+ ].join("\n"));
326
+ runtime.exit(1);
327
+ return;
328
+ }
329
+ const authChoice = opts.authChoice ?? inferredAuthChoice.choice ?? "skip";
330
+ if (authChoice !== "skip") {
331
+ const { applyNonInteractiveAuthChoice } = await import("./auth-choice-Dig4eYbk.mjs");
332
+ const nextConfigAfterAuth = await applyNonInteractiveAuthChoice({
333
+ nextConfig,
334
+ authChoice,
335
+ opts,
336
+ runtime,
337
+ baseConfig
338
+ });
339
+ if (!nextConfigAfterAuth) return;
340
+ nextConfig = nextConfigAfterAuth;
341
+ }
342
+ const gatewayBasePort = resolveGatewayPort(baseConfig);
343
+ const gatewayResult = applyNonInteractiveGatewayConfig({
344
+ nextConfig,
345
+ opts,
346
+ runtime,
347
+ defaultPort: gatewayBasePort
348
+ });
349
+ if (!gatewayResult) return;
350
+ nextConfig = gatewayResult.nextConfig;
351
+ nextConfig = applyNonInteractiveSkillsConfig({
352
+ nextConfig,
353
+ opts,
354
+ runtime
355
+ });
356
+ nextConfig = applyWizardMetadata(nextConfig, {
357
+ command: "onboard",
358
+ mode
359
+ });
360
+ await writeConfigFile(nextConfig);
361
+ logConfigUpdated(runtime);
362
+ await ensureWorkspaceAndSessions(workspaceDir, runtime, { skipBootstrap: Boolean(nextConfig.agents?.defaults?.skipBootstrap) });
363
+ const daemonRuntimeRaw = opts.daemonRuntime ?? DEFAULT_GATEWAY_DAEMON_RUNTIME;
364
+ let daemonInstallStatus;
365
+ if (opts.installDaemon) {
366
+ const { installGatewayDaemonNonInteractive } = await import("./daemon-install-C8HGWXLQ.mjs");
367
+ const daemonInstall = await installGatewayDaemonNonInteractive({
368
+ nextConfig,
369
+ opts,
370
+ runtime,
371
+ port: gatewayResult.port
372
+ });
373
+ daemonInstallStatus = daemonInstall.installed ? {
374
+ requested: true,
375
+ installed: true
376
+ } : {
377
+ requested: true,
378
+ installed: false,
379
+ skippedReason: daemonInstall.skippedReason
380
+ };
381
+ if (!daemonInstall.installed && !opts.skipHealth) {
382
+ logNonInteractiveOnboardingFailure({
383
+ opts,
384
+ runtime,
385
+ mode,
386
+ phase: "daemon-install",
387
+ message: daemonInstall.skippedReason === "systemd-user-unavailable" ? "Gateway service install is unavailable because systemd user services are not reachable in this Linux session." : "Gateway service install did not complete successfully.",
388
+ installDaemon: true,
389
+ daemonInstall: {
390
+ requested: true,
391
+ installed: false,
392
+ skippedReason: daemonInstall.skippedReason
393
+ },
394
+ daemonRuntime: daemonRuntimeRaw,
395
+ hints: daemonInstall.skippedReason === "systemd-user-unavailable" ? ["Fix: rerun without `--install-daemon` for one-shot setup, or enable a working user-systemd session and retry.", "If your auth profile uses env-backed refs, keep those env vars set in the shell that runs `openclaw gateway run` or `openclaw agent --local`."] : [`Run \`${formatCliCommand("openclaw gateway status --deep")}\` for more detail.`]
396
+ });
397
+ runtime.exit(1);
398
+ return;
399
+ }
400
+ }
401
+ if (!opts.skipHealth) {
402
+ const { healthCommand } = await import("./health-Co9G83gO.mjs");
403
+ const links = resolveControlUiLinks({
404
+ bind: gatewayResult.bind,
405
+ port: gatewayResult.port,
406
+ customBindHost: nextConfig.gateway?.customBindHost,
407
+ basePath: void 0
408
+ });
409
+ const probe = await waitForGatewayReachable({
410
+ url: links.wsUrl,
411
+ token: gatewayResult.gatewayToken,
412
+ deadlineMs: opts.installDaemon ? INSTALL_DAEMON_HEALTH_DEADLINE_MS : ATTACH_EXISTING_GATEWAY_HEALTH_DEADLINE_MS
413
+ });
414
+ if (!probe.ok) {
415
+ const diagnostics = opts.installDaemon ? await collectGatewayHealthFailureDiagnostics() : void 0;
416
+ logNonInteractiveOnboardingFailure({
417
+ opts,
418
+ runtime,
419
+ mode,
420
+ phase: "gateway-health",
421
+ message: `Gateway did not become reachable at ${links.wsUrl}.`,
422
+ detail: probe.detail,
423
+ gateway: {
424
+ wsUrl: links.wsUrl,
425
+ httpUrl: links.httpUrl
426
+ },
427
+ installDaemon: Boolean(opts.installDaemon),
428
+ daemonInstall: daemonInstallStatus,
429
+ daemonRuntime: opts.installDaemon ? daemonRuntimeRaw : void 0,
430
+ diagnostics,
431
+ hints: !opts.installDaemon ? [
432
+ "Non-interactive local setup only waits for an already-running gateway unless you pass --install-daemon.",
433
+ `Fix: start \`${formatCliCommand("openclaw gateway run")}\`, re-run with \`--install-daemon\`, or use \`--skip-health\`.`,
434
+ process.platform === "win32" ? "Native Windows managed gateway install tries Scheduled Tasks first and falls back to a per-user Startup-folder login item when task creation is denied." : void 0
435
+ ].filter((value) => Boolean(value)) : [`Run \`${formatCliCommand("openclaw gateway status --deep")}\` for more detail.`]
436
+ });
437
+ runtime.exit(1);
438
+ return;
439
+ }
440
+ await healthCommand({
441
+ json: false,
442
+ timeoutMs: 1e4
443
+ }, runtime);
444
+ }
445
+ logNonInteractiveOnboardingJson({
446
+ opts,
447
+ runtime,
448
+ mode,
449
+ workspaceDir,
450
+ authChoice,
451
+ gateway: {
452
+ port: gatewayResult.port,
453
+ bind: gatewayResult.bind,
454
+ authMode: gatewayResult.authMode,
455
+ tailscaleMode: gatewayResult.tailscaleMode
456
+ },
457
+ installDaemon: Boolean(opts.installDaemon),
458
+ daemonInstall: daemonInstallStatus,
459
+ daemonRuntime: opts.installDaemon ? daemonRuntimeRaw : void 0,
460
+ skipSkills: Boolean(opts.skipSkills),
461
+ skipHealth: Boolean(opts.skipHealth)
462
+ });
463
+ if (!opts.json) runtime.log(`Tip: run \`${formatCliCommand("openclaw configure --section web")}\` to store your Brave API key for web_search. Docs: https://docs.openclaw.ai/tools/web`);
464
+ }
465
+
466
+ //#endregion
467
+ //#region src/commands/onboard-non-interactive/remote.ts
468
+ async function runNonInteractiveRemoteSetup(params) {
469
+ const { opts, runtime, baseConfig } = params;
470
+ const mode = "remote";
471
+ const remoteUrl = opts.remoteUrl?.trim();
472
+ if (!remoteUrl) {
473
+ runtime.error("Missing --remote-url for remote mode.");
474
+ runtime.exit(1);
475
+ return;
476
+ }
477
+ let nextConfig = {
478
+ ...baseConfig,
479
+ gateway: {
480
+ ...baseConfig.gateway,
481
+ mode: "remote",
482
+ remote: {
483
+ url: remoteUrl,
484
+ token: opts.remoteToken?.trim() || void 0
485
+ }
486
+ }
487
+ };
488
+ nextConfig = applyWizardMetadata(nextConfig, {
489
+ command: "onboard",
490
+ mode
491
+ });
492
+ await writeConfigFile(nextConfig);
493
+ logConfigUpdated(runtime);
494
+ const payload = {
495
+ mode,
496
+ remoteUrl,
497
+ auth: opts.remoteToken ? "token" : "none"
498
+ };
499
+ if (opts.json) writeRuntimeJson(runtime, payload);
500
+ else {
501
+ runtime.log(`Remote gateway: ${remoteUrl}`);
502
+ runtime.log(`Auth: ${payload.auth}`);
503
+ runtime.log(`Tip: run \`${formatCliCommand("openclaw configure --section web")}\` to store your Brave API key for web_search. Docs: https://docs.openclaw.ai/tools/web`);
504
+ }
505
+ }
506
+
507
+ //#endregion
508
+ //#region src/commands/onboard-non-interactive.ts
509
+ async function runNonInteractiveSetup(opts, runtime = defaultRuntime) {
510
+ const snapshot = await readConfigFileSnapshot();
511
+ if (snapshot.exists && !snapshot.valid) {
512
+ runtime.error(`Config invalid. Run \`${formatCliCommand("openclaw doctor")}\` to repair it, then re-run setup.`);
513
+ runtime.exit(1);
514
+ return;
515
+ }
516
+ const baseConfig = snapshot.valid ? snapshot.exists ? snapshot.config : {} : {};
517
+ const mode = opts.mode ?? "local";
518
+ if (mode !== "local" && mode !== "remote") {
519
+ runtime.error(`Invalid --mode "${String(mode)}" (use local|remote).`);
520
+ runtime.exit(1);
521
+ return;
522
+ }
523
+ if (mode === "remote") {
524
+ await runNonInteractiveRemoteSetup({
525
+ opts,
526
+ runtime,
527
+ baseConfig
528
+ });
529
+ return;
530
+ }
531
+ await runNonInteractiveLocalSetup({
532
+ opts,
533
+ runtime,
534
+ baseConfig
535
+ });
536
+ }
537
+
538
+ //#endregion
539
+ //#region src/commands/onboard.ts
540
+ const VALID_RESET_SCOPES = new Set([
541
+ "config",
542
+ "config+creds+sessions",
543
+ "full"
544
+ ]);
545
+ async function setupWizardCommand(opts, runtime = defaultRuntime) {
546
+ assertSupportedRuntime(runtime);
547
+ const originalAuthChoice = opts.authChoice;
548
+ const normalizedAuthChoice = normalizeLegacyOnboardAuthChoice(originalAuthChoice);
549
+ if (opts.nonInteractive && isDeprecatedAuthChoice(originalAuthChoice)) {
550
+ runtime.error([`Auth choice "${String(originalAuthChoice)}" is deprecated.`, "Use \"--auth-choice token\" (Anthropic setup-token) or \"--auth-choice openai-codex\"."].join("\n"));
551
+ runtime.exit(1);
552
+ return;
553
+ }
554
+ if (originalAuthChoice === "claude-cli") runtime.log("Auth choice \"claude-cli\" is deprecated; using setup-token flow instead.");
555
+ if (originalAuthChoice === "codex-cli") runtime.log("Auth choice \"codex-cli\" is deprecated; using OpenAI Codex OAuth instead.");
556
+ const flow = opts.flow === "manual" ? "advanced" : opts.flow;
557
+ const normalizedOpts = normalizedAuthChoice === opts.authChoice && flow === opts.flow ? opts : {
558
+ ...opts,
559
+ authChoice: normalizedAuthChoice,
560
+ flow
561
+ };
562
+ if (normalizedOpts.secretInputMode && normalizedOpts.secretInputMode !== "plaintext" && normalizedOpts.secretInputMode !== "ref") {
563
+ runtime.error("Invalid --secret-input-mode. Use \"plaintext\" or \"ref\".");
564
+ runtime.exit(1);
565
+ return;
566
+ }
567
+ if (normalizedOpts.resetScope && !VALID_RESET_SCOPES.has(normalizedOpts.resetScope)) {
568
+ runtime.error("Invalid --reset-scope. Use \"config\", \"config+creds+sessions\", or \"full\".");
569
+ runtime.exit(1);
570
+ return;
571
+ }
572
+ if (normalizedOpts.nonInteractive && normalizedOpts.acceptRisk !== true) {
573
+ runtime.error([
574
+ "Non-interactive setup requires explicit risk acknowledgement.",
575
+ "Read: https://docs.openclaw.ai/security",
576
+ `Re-run with: ${formatCliCommand("openclaw onboard --non-interactive --accept-risk ...")}`
577
+ ].join("\n"));
578
+ runtime.exit(1);
579
+ return;
580
+ }
581
+ if (normalizedOpts.reset) {
582
+ const snapshot = await readConfigFileSnapshot();
583
+ const baseConfig = snapshot.valid ? snapshot.config : {};
584
+ const workspaceDefault = normalizedOpts.workspace ?? baseConfig.agents?.defaults?.workspace ?? DEFAULT_WORKSPACE;
585
+ await handleReset(normalizedOpts.resetScope ?? "config+creds+sessions", resolveUserPath(workspaceDefault), runtime);
586
+ }
587
+ if (process.platform === "win32") runtime.log([
588
+ "Windows detected - OpenClaw runs great on WSL2!",
589
+ "Native Windows might be trickier.",
590
+ "Quick setup: wsl --install (one command, one reboot)",
591
+ "Guide: https://docs.openclaw.ai/windows"
592
+ ].join("\n"));
593
+ if (normalizedOpts.nonInteractive) {
594
+ await runNonInteractiveSetup(normalizedOpts, runtime);
595
+ return;
596
+ }
597
+ await runInteractiveSetup(normalizedOpts, runtime);
598
+ }
599
+
600
+ //#endregion
601
+ export { CORE_ONBOARD_AUTH_FLAGS as n, setupWizardCommand as t };