Skip to content

Commit 786abe7

Browse files
Streamline OpenClaw onboarding (#98218)
* feat: streamline onboarding setup flow * fix: harden onboarding preflight installs * test: isolate gateway preflight safety env * fix: keep local gateway probes on loopback * fix: honor onboarding node manager installs * docs: align setup onboarding reference * fix: harden bare gateway probe fallback * fix: honor env gateway auth in bare TUI probe * test: isolate wizard TUI hatch mocks
1 parent 3f147ae commit 786abe7

55 files changed

Lines changed: 5254 additions & 964 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/cli/configure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ title: "Configure"
99

1010
Interactive prompt for targeted changes to an existing setup: credentials, devices, agent defaults, gateway, channels, plugins, skills, and health checks.
1111

12-
Use `openclaw onboard` for the full guided first-run journey, `openclaw setup` for the baseline config/workspace only, and `openclaw channels add` when you only need channel account setup.
12+
Use `openclaw onboard` or `openclaw setup` for the full guided first-run journey, `openclaw setup --baseline` for the baseline config/workspace only, and `openclaw channels add` when you only need channel account setup.
1313

1414
<Note>
1515
The **Model** section includes a multi-select for the `agents.defaults.models` allowlist (what shows up in `/model` and the model picker). Provider-scoped setup choices merge their selected models into the existing allowlist instead of replacing unrelated providers already in the config.

docs/cli/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ apply across the CLI.
1313

1414
Use the setup commands by intent:
1515

16-
- `openclaw setup` creates the baseline config and workspace without walking the full guided onboarding flow.
17-
- `openclaw onboard` is the full guided first-run path for gateway, model auth, workspace, channels, skills, and health.
16+
- `openclaw setup` and `openclaw onboard` run the full guided first-run path for gateway, model auth, workspace, channels, skills, and health.
17+
- `openclaw setup --baseline` creates the baseline config and workspace without walking the guided onboarding flow.
1818
- `openclaw configure` changes targeted parts of an existing setup, such as model auth, gateway, channels, plugins, or skills.
1919
- `openclaw channels add` configures channel accounts after the baseline exists; run it without flags for guided channel setup or with channel-specific flags for scripts.
2020

docs/cli/onboard.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ openclaw configure
247247
openclaw agents add <name>
248248
```
249249

250-
Use `openclaw setup` instead when you only need the baseline config/workspace. Use `openclaw configure` later for targeted changes and `openclaw channels add` for channel-only setup.
250+
Use `openclaw setup` as the same guided onboarding entry point. Use `openclaw setup --baseline` when you only need the baseline config/workspace, `openclaw configure` later for targeted changes, and `openclaw channels add` for channel-only setup.
251251

252252
<Note>
253253
`--json` does not imply non-interactive mode. Use `--non-interactive` for scripts.

docs/cli/setup.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
2-
summary: "CLI reference for `openclaw setup` (initialize config plus workspace, optionally run onboarding)"
2+
summary: "CLI reference for `openclaw setup` (alias for onboarding, with baseline setup available by flag)"
33
read_when:
4-
- You're doing first-run setup without full CLI onboarding
4+
- You're doing first-run setup with the CLI onboarding wizard
55
- You want to set the default workspace path
6-
- You need every flag and how setup decides between baseline and wizard mode
6+
- You need the baseline-only setup flag for scripts
77
title: "Setup"
88
---
99

1010
# `openclaw setup`
1111

12-
Initialize the baseline config and agent workspace. With any onboarding flag present, also runs the wizard.
12+
Run the full CLI onboarding flow. `openclaw setup` is an alias for `openclaw onboard`; use `--baseline` when you only need to initialize config/workspace folders without the wizard.
1313

1414
<Note>
1515
`openclaw setup` is for mutable config installs. In Nix mode (`OPENCLAW_NIX_MODE=1`) OpenClaw refuses setup writes because the config file is managed by Nix. Use the first-party [nix-openclaw Quick Start](https://github.com/openclaw/nix-openclaw#quick-start) or the equivalent source config for another Nix package.
@@ -20,7 +20,8 @@ Initialize the baseline config and agent workspace. With any onboarding flag pre
2020
| Flag | Description |
2121
| -------------------------- | --------------------------------------------------------------------------------------------------- |
2222
| `--workspace <dir>` | Agent workspace directory (default `~/.openclaw/workspace`; stored as `agents.defaults.workspace`). |
23-
| `--wizard` | Run interactive onboarding. |
23+
| `--baseline` | Create baseline config/workspace/session folders without onboarding. |
24+
| `--wizard` | Accepted for compatibility; setup runs onboarding by default. |
2425
| `--non-interactive` | Run onboarding without prompts. |
2526
| `--accept-risk` | Acknowledge full-system agent access risk; required with `--non-interactive`. |
2627
| `--mode <mode>` | Onboarding mode: `local` or `remote`. |
@@ -30,26 +31,24 @@ Initialize the baseline config and agent workspace. With any onboarding flag pre
3031
| `--remote-url <url>` | Remote Gateway WebSocket URL. |
3132
| `--remote-token <token>` | Remote Gateway token (optional). |
3233

33-
### Wizard auto-trigger
34+
### Baseline mode
3435

35-
`openclaw setup` runs the wizard when any of these flags are explicitly present, even without `--wizard`:
36-
37-
`--wizard`, `--non-interactive`, `--accept-risk`, `--mode`, `--import-from`, `--import-source`, `--import-secrets`, `--remote-url`, `--remote-token`.
36+
`openclaw setup --baseline` preserves the older baseline-only behavior: it creates the config, workspace, and session directories, then exits without running onboarding.
3837

3938
## Examples
4039

4140
```bash
4241
openclaw setup
42+
openclaw setup --baseline
4343
openclaw setup --workspace ~/.openclaw/workspace
44-
openclaw setup --wizard
45-
openclaw setup --wizard --import-from hermes --import-source ~/.hermes
44+
openclaw setup --import-from hermes --import-source ~/.hermes
4645
openclaw setup --non-interactive --accept-risk --mode remote --remote-url wss://gateway-host:18789 --remote-token <token>
4746
```
4847

4948
## Notes
5049

51-
- Plain `openclaw setup` initializes config and workspace without running the full onboarding flow.
52-
- After plain setup, run `openclaw onboard` for the full guided journey, `openclaw configure` for targeted changes, or `openclaw channels add` to add channel accounts.
50+
- Plain `openclaw setup` runs the same guided journey as `openclaw onboard`.
51+
- After baseline setup, run `openclaw setup` or `openclaw onboard` for the full guided journey, `openclaw configure` for targeted changes, or `openclaw channels add` to add channel accounts.
5352
- If Hermes state is detected, interactive onboarding can offer migration automatically. Import onboarding requires a fresh setup; use [Migrate](/cli/migrate) for dry-run plans, backups, and overwrite mode outside onboarding.
5453

5554
## Related

docs/docs_map.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
18871887
- Headings:
18881888
- H1: openclaw setup
18891889
- H2: Options
1890-
- H3: Wizard auto-trigger
1890+
- H3: Baseline mode
18911891
- H2: Examples
18921892
- H2: Notes
18931893
- H2: Related

docs/gateway/configuration-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ Metadata written by CLI guided setup flows (`onboard`, `configure`, `doctor`):
12601260
lastRunCommit: "abc1234",
12611261
lastRunCommand: "configure",
12621262
lastRunMode: "local",
1263+
securityAcknowledgedAt: "2026-01-01T00:00:00.000Z",
12631264
},
12641265
}
12651266
```

docs/start/wizard-cli-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ Typical fields in `~/.openclaw/openclaw.json`:
295295
- `wizard.lastRunCommit`
296296
- `wizard.lastRunCommand`
297297
- `wizard.lastRunMode`
298+
- `wizard.securityAcknowledgedAt`
298299

299300
`openclaw agents add` writes `agents.list[]` and optional `bindings`.
300301

scripts/lib/official-external-provider-catalog.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@
359359
"id": "codex",
360360
"label": "Codex"
361361
},
362+
"contracts": {
363+
"migrationProviders": ["codex"]
364+
},
362365
"providers": [
363366
{
364367
"id": "codex",

src/cli/program/register.onboard.ts

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
GatewayAuthChoice,
1111
GatewayBind,
1212
NodeManagerChoice,
13+
OnboardOptions,
1314
ResetScope,
1415
SecretInputMode,
1516
TailscaleMode,
@@ -90,30 +91,8 @@ function pickOnboardProviderAuthOptionValues(
9091
);
9192
}
9293

93-
export function registerOnboardCommand(program: Command): void {
94-
const command = program
95-
.command("onboard")
96-
.description("Guided setup for auth, models, Gateway, workspace, channels, and skills")
97-
.addHelpText(
98-
"after",
99-
() =>
100-
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.openclaw.ai/cli/onboard")}\n`,
101-
)
102-
.option("--workspace <dir>", "Agent workspace directory (default: ~/.openclaw/workspace)")
103-
.option(
104-
"--reset",
105-
"Reset config + credentials + sessions before running onboard (workspace only with --reset-scope full)",
106-
)
107-
.option("--reset-scope <scope>", "Reset scope: config|config+creds+sessions|full")
108-
.option("--non-interactive", "Run without prompts", false)
109-
.option("--modern", "Use the conversational setup/repair assistant", false)
110-
.option(
111-
"--accept-risk",
112-
"Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)",
113-
false,
114-
)
115-
.option("--flow <flow>", "Onboard flow: quickstart|advanced|manual|import")
116-
.option("--mode <mode>", "Onboard mode: local|remote")
94+
export function registerOnboardAuthOptions(command: Command): Command {
95+
command
11796
.option("--auth-choice <choice>", `Auth: ${AUTH_CHOICE_HELP}`)
11897
.option(
11998
"--token-provider <id>",
@@ -136,7 +115,7 @@ export function registerOnboardCommand(program: Command): void {
136115
command.option(providerFlag.cliOption, providerFlag.description);
137116
}
138117

139-
command
118+
return command
140119
.option("--custom-base-url <url>", "Custom provider base URL")
141120
.option("--custom-api-key <key>", "Custom provider API key (optional)")
142121
.option("--custom-model-id <id>", "Custom provider model ID")
@@ -146,7 +125,64 @@ export function registerOnboardCommand(program: Command): void {
146125
"Custom provider API compatibility: openai|openai-responses|anthropic (default: openai)",
147126
)
148127
.option("--custom-image-input", "Mark the custom provider model as image-capable")
149-
.option("--custom-text-input", "Mark the custom provider model as text-only")
128+
.option("--custom-text-input", "Mark the custom provider model as text-only");
129+
}
130+
131+
export function pickOnboardAuthOptionValues(
132+
opts: Record<string, unknown>,
133+
): Partial<OnboardOptions> {
134+
const customTextInput = opts.customTextInput === true;
135+
return {
136+
authChoice: opts.authChoice as AuthChoice | undefined,
137+
tokenProvider: opts.tokenProvider as string | undefined,
138+
token: opts.token as string | undefined,
139+
tokenProfileId: opts.tokenProfileId as string | undefined,
140+
tokenExpiresIn: opts.tokenExpiresIn as string | undefined,
141+
secretInputMode: opts.secretInputMode as SecretInputMode | undefined,
142+
...pickOnboardProviderAuthOptionValues(opts),
143+
cloudflareAiGatewayAccountId: opts.cloudflareAiGatewayAccountId as string | undefined,
144+
cloudflareAiGatewayGatewayId: opts.cloudflareAiGatewayGatewayId as string | undefined,
145+
customBaseUrl: opts.customBaseUrl as string | undefined,
146+
customApiKey: opts.customApiKey as string | undefined,
147+
customModelId: opts.customModelId as string | undefined,
148+
customProviderId: opts.customProviderId as string | undefined,
149+
customCompatibility: opts.customCompatibility as
150+
| "openai"
151+
| "openai-responses"
152+
| "anthropic"
153+
| undefined,
154+
customImageInput: customTextInput ? false : opts.customImageInput === true ? true : undefined,
155+
};
156+
}
157+
158+
export function registerOnboardCommand(program: Command): void {
159+
const command = program
160+
.command("onboard")
161+
.description("Guided setup for auth, models, Gateway, workspace, channels, and skills")
162+
.addHelpText(
163+
"after",
164+
() =>
165+
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.openclaw.ai/cli/onboard")}\n`,
166+
)
167+
.option("--workspace <dir>", "Agent workspace directory (default: ~/.openclaw/workspace)")
168+
.option(
169+
"--reset",
170+
"Reset config + credentials + sessions before running onboard (workspace only with --reset-scope full)",
171+
)
172+
.option("--reset-scope <scope>", "Reset scope: config|config+creds+sessions|full")
173+
.option("--non-interactive", "Run without prompts", false)
174+
.option("--modern", "Use the conversational setup/repair assistant", false)
175+
.option(
176+
"--accept-risk",
177+
"Acknowledge that agents are powerful and full system access is risky (required for --non-interactive)",
178+
false,
179+
)
180+
.option("--flow <flow>", "Onboard flow: quickstart|advanced|manual|import")
181+
.option("--mode <mode>", "Onboard mode: local|remote");
182+
183+
registerOnboardAuthOptions(command);
184+
185+
command
150186
.option("--gateway-port <port>", "Gateway port")
151187
.option("--gateway-bind <mode>", "Gateway bind: loopback|tailnet|lan|auto|custom")
152188
.option("--gateway-auth <mode>", "Gateway auth: token|password")
@@ -195,9 +231,6 @@ export function registerOnboardCommand(program: Command): void {
195231
installDaemon: Boolean(opts.installDaemon),
196232
});
197233
const gatewayPort = parsePort(opts.gatewayPort);
198-
const providerAuthOptionValues = pickOnboardProviderAuthOptionValues(
199-
opts as Record<string, unknown>,
200-
);
201234
const { setupWizardCommand } = await import("../../commands/onboard.js");
202235
await setupWizardCommand(
203236
{
@@ -206,30 +239,7 @@ export function registerOnboardCommand(program: Command): void {
206239
acceptRisk: Boolean(opts.acceptRisk),
207240
flow: opts.flow as "quickstart" | "advanced" | "manual" | "import" | undefined,
208241
mode: opts.mode as "local" | "remote" | undefined,
209-
authChoice: opts.authChoice as AuthChoice | undefined,
210-
tokenProvider: opts.tokenProvider as string | undefined,
211-
token: opts.token as string | undefined,
212-
tokenProfileId: opts.tokenProfileId as string | undefined,
213-
tokenExpiresIn: opts.tokenExpiresIn as string | undefined,
214-
secretInputMode: opts.secretInputMode as SecretInputMode | undefined,
215-
...providerAuthOptionValues,
216-
cloudflareAiGatewayAccountId: opts.cloudflareAiGatewayAccountId as string | undefined,
217-
cloudflareAiGatewayGatewayId: opts.cloudflareAiGatewayGatewayId as string | undefined,
218-
customBaseUrl: opts.customBaseUrl as string | undefined,
219-
customApiKey: opts.customApiKey as string | undefined,
220-
customModelId: opts.customModelId as string | undefined,
221-
customProviderId: opts.customProviderId as string | undefined,
222-
customCompatibility: opts.customCompatibility as
223-
| "openai"
224-
| "openai-responses"
225-
| "anthropic"
226-
| undefined,
227-
customImageInput:
228-
opts.customTextInput === true
229-
? false
230-
: opts.customImageInput === true
231-
? true
232-
: undefined,
242+
...pickOnboardAuthOptionValues(opts as Record<string, unknown>),
233243
gatewayPort: gatewayPort ?? undefined,
234244
gatewayBind: opts.gatewayBind as GatewayBind | undefined,
235245
gatewayAuth: opts.gatewayAuth as GatewayAuthChoice | undefined,

0 commit comments

Comments
 (0)