diff --git a/extensions/bluebubbles/src/setup-core.ts b/extensions/bluebubbles/src/setup-core.ts index bea84e6cd2f..83a079dbaab 100644 --- a/extensions/bluebubbles/src/setup-core.ts +++ b/extensions/bluebubbles/src/setup-core.ts @@ -1,9 +1,9 @@ -import { setTopLevelChannelDmPolicyWithAllowFrom } from "../../../src/channels/plugins/setup-flow-helpers.js"; import { applyAccountNameToChannelSection, migrateBaseNameToDefaultAccount, patchScopedAccountConfig, } from "../../../src/channels/plugins/setup-helpers.js"; +import { setTopLevelChannelDmPolicyWithAllowFrom } from "../../../src/channels/plugins/setup-wizard-helpers.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/bluebubbles/src/setup-surface.test.ts b/extensions/bluebubbles/src/setup-surface.test.ts index 5093c757b06..95130666e60 100644 --- a/extensions/bluebubbles/src/setup-surface.test.ts +++ b/extensions/bluebubbles/src/setup-surface.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; import type { WizardPrompter } from "../../../src/wizard/prompts.js"; import { resolveBlueBubblesAccount } from "./accounts.js"; @@ -27,8 +27,8 @@ async function createBlueBubblesConfigureAdapter() { }).config.allowFrom ?? [], }, setup: blueBubblesSetupAdapter, - } as Parameters[0]["plugin"]; - return buildChannelSetupFlowAdapterFromSetupWizard({ + } as Parameters[0]["plugin"]; + return buildChannelSetupWizardAdapterFromSetupWizard({ plugin, wizard: blueBubblesSetupWizard, }); diff --git a/extensions/bluebubbles/src/setup-surface.ts b/extensions/bluebubbles/src/setup-surface.ts index a331aec7d43..1a138b8e73d 100644 --- a/extensions/bluebubbles/src/setup-surface.ts +++ b/extensions/bluebubbles/src/setup-surface.ts @@ -1,8 +1,8 @@ import { mergeAllowFromEntries, resolveSetupAccountId, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/discord/src/setup-core.ts b/extensions/discord/src/setup-core.ts index f130888cc2b..3c9ab69059b 100644 --- a/extensions/discord/src/setup-core.ts +++ b/extensions/discord/src/setup-core.ts @@ -1,3 +1,7 @@ +import { + applyAccountNameToChannelSection, + migrateBaseNameToDefaultAccount, +} from "../../../src/channels/plugins/setup-helpers.js"; import { noteChannelLookupFailure, noteChannelLookupSummary, @@ -5,12 +9,8 @@ import { patchChannelConfigForAccount, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applyAccountNameToChannelSection, - migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/discord/src/setup-surface.ts b/extensions/discord/src/setup-surface.ts index 36382eae756..ce7c6e789e4 100644 --- a/extensions/discord/src/setup-surface.ts +++ b/extensions/discord/src/setup-surface.ts @@ -7,8 +7,8 @@ import { resolveSetupAccountId, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; diff --git a/extensions/feishu/src/setup-status.test.ts b/extensions/feishu/src/setup-status.test.ts index 94488a72bfa..e145bf8a753 100644 --- a/extensions/feishu/src/setup-status.test.ts +++ b/extensions/feishu/src/setup-status.test.ts @@ -1,9 +1,9 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/feishu"; import { describe, expect, it } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { feishuPlugin } from "./channel.js"; -const feishuConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const feishuConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: feishuPlugin, wizard: feishuPlugin.setupWizard!, }); diff --git a/extensions/feishu/src/setup-surface.test.ts b/extensions/feishu/src/setup-surface.test.ts index f46aef482ba..33ab8ad7989 100644 --- a/extensions/feishu/src/setup-surface.test.ts +++ b/extensions/feishu/src/setup-surface.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; vi.mock("./probe.js", () => ({ probeFeishu: vi.fn(async () => ({ ok: false, error: "mocked" })), @@ -56,7 +56,7 @@ async function getStatusWithEnvRefs(params: { appIdKey: string; appSecretKey: st }); } -const feishuConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const feishuConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: feishuPlugin, wizard: feishuPlugin.setupWizard!, }); diff --git a/extensions/feishu/src/setup-surface.ts b/extensions/feishu/src/setup-surface.ts index 1c0f966e01e..4f92b07a804 100644 --- a/extensions/feishu/src/setup-surface.ts +++ b/extensions/feishu/src/setup-surface.ts @@ -6,8 +6,8 @@ import { setTopLevelChannelDmPolicyWithAllowFrom, setTopLevelChannelGroupPolicy, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/googlechat/src/setup-surface.test.ts b/extensions/googlechat/src/setup-surface.test.ts index 4be1a1bbff0..e8855648c99 100644 --- a/extensions/googlechat/src/setup-surface.test.ts +++ b/extensions/googlechat/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig, WizardPrompter } from "openclaw/plugin-sdk/googlechat"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; import { googlechatPlugin } from "./channel.js"; @@ -26,7 +26,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const googlechatConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const googlechatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: googlechatPlugin, wizard: googlechatPlugin.setupWizard!, }); diff --git a/extensions/googlechat/src/setup-surface.ts b/extensions/googlechat/src/setup-surface.ts index 9b18d2fad4f..5561989543f 100644 --- a/extensions/googlechat/src/setup-surface.ts +++ b/extensions/googlechat/src/setup-surface.ts @@ -1,14 +1,14 @@ +import { + applySetupAccountConfigPatch, + migrateBaseNameToDefaultAccount, +} from "../../../src/channels/plugins/setup-helpers.js"; import { addWildcardAllowFrom, mergeAllowFromEntries, setTopLevelChannelDmPolicyWithAllowFrom, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applySetupAccountConfigPatch, - migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/imessage/src/setup-core.ts b/extensions/imessage/src/setup-core.ts index 0beb217f305..38f280852c0 100644 --- a/extensions/imessage/src/setup-core.ts +++ b/extensions/imessage/src/setup-core.ts @@ -1,14 +1,14 @@ +import { + applyAccountNameToChannelSection, + migrateBaseNameToDefaultAccount, +} from "../../../src/channels/plugins/setup-helpers.js"; import { parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applyAccountNameToChannelSection, - migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/imessage/src/setup-surface.ts b/extensions/imessage/src/setup-surface.ts index 722cdb172c4..0d0de246d7b 100644 --- a/extensions/imessage/src/setup-surface.ts +++ b/extensions/imessage/src/setup-surface.ts @@ -3,8 +3,8 @@ import { promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { detectBinary } from "../../../src/commands/onboard-helpers.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/irc/src/setup-core.ts b/extensions/irc/src/setup-core.ts index d1603dee476..c793098063b 100644 --- a/extensions/irc/src/setup-core.ts +++ b/extensions/irc/src/setup-core.ts @@ -1,11 +1,11 @@ -import { - setTopLevelChannelAllowFrom, - setTopLevelChannelDmPolicyWithAllowFrom, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; import { applyAccountNameToChannelSection, patchScopedAccountConfig, } from "../../../src/channels/plugins/setup-helpers.js"; +import { + setTopLevelChannelAllowFrom, + setTopLevelChannelDmPolicyWithAllowFrom, +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { ChannelSetupInput } from "../../../src/channels/plugins/types.core.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/irc/src/setup-surface.test.ts b/extensions/irc/src/setup-surface.test.ts index 92cca5f0f35..147432b6131 100644 --- a/extensions/irc/src/setup-surface.test.ts +++ b/extensions/irc/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/irc"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; import { ircPlugin } from "./channel.js"; import type { CoreConfig } from "./types.js"; @@ -27,7 +27,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const ircConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const ircConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: ircPlugin, wizard: ircPlugin.setupWizard!, }); diff --git a/extensions/irc/src/setup-surface.ts b/extensions/irc/src/setup-surface.ts index bde9f603593..1607a9bdd54 100644 --- a/extensions/irc/src/setup-surface.ts +++ b/extensions/irc/src/setup-surface.ts @@ -1,8 +1,8 @@ import { resolveSetupAccountId, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { DmPolicy } from "../../../src/config/types.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; diff --git a/extensions/line/src/setup-surface.test.ts b/extensions/line/src/setup-surface.test.ts index 01a3024fc3a..3fd98df4b2e 100644 --- a/extensions/line/src/setup-surface.test.ts +++ b/extensions/line/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/line"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { listLineAccountIds, resolveDefaultLineAccountId, @@ -30,7 +30,7 @@ function createPrompter(overrides: Partial = {}): WizardPrompter }; } -const lineConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const lineConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: { id: "line", meta: { label: "LINE" }, @@ -41,7 +41,7 @@ const lineConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ resolveLineAccount({ cfg, accountId: accountId ?? undefined }).config.allowFrom, }, setup: lineSetupAdapter, - } as Parameters[0]["plugin"], + } as Parameters[0]["plugin"], wizard: lineSetupWizard, }); diff --git a/extensions/line/src/setup-surface.ts b/extensions/line/src/setup-surface.ts index 705c89a44f9..9ea7dd4ce68 100644 --- a/extensions/line/src/setup-surface.ts +++ b/extensions/line/src/setup-surface.ts @@ -2,8 +2,8 @@ import { setSetupChannelEnabled, setTopLevelChannelDmPolicyWithAllowFrom, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { resolveLineAccount } from "../../../src/line/accounts.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; diff --git a/extensions/matrix/src/setup-surface.ts b/extensions/matrix/src/setup-surface.ts index 0dcff40fb38..0f79545358e 100644 --- a/extensions/matrix/src/setup-surface.ts +++ b/extensions/matrix/src/setup-surface.ts @@ -4,8 +4,8 @@ import { mergeAllowFromEntries, promptSingleChannelSecretInput, setTopLevelChannelGroupPolicy, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy } from "../../../src/config/types.js"; diff --git a/extensions/msteams/src/setup-surface.ts b/extensions/msteams/src/setup-surface.ts index 8336e0ae976..e3bc6169f6c 100644 --- a/extensions/msteams/src/setup-surface.ts +++ b/extensions/msteams/src/setup-surface.ts @@ -4,8 +4,8 @@ import { setTopLevelChannelDmPolicyWithAllowFrom, setTopLevelChannelGroupPolicy, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { DmPolicy, MSTeamsTeamConfig } from "../../../src/config/types.js"; diff --git a/extensions/nextcloud-talk/src/setup-core.ts b/extensions/nextcloud-talk/src/setup-core.ts index 61ef7e47a85..1d45a392fd1 100644 --- a/extensions/nextcloud-talk/src/setup-core.ts +++ b/extensions/nextcloud-talk/src/setup-core.ts @@ -1,14 +1,14 @@ +import { + applyAccountNameToChannelSection, + patchScopedAccountConfig, +} from "../../../src/channels/plugins/setup-helpers.js"; import { mergeAllowFromEntries, resolveSetupAccountId, setSetupChannelEnabled, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applyAccountNameToChannelSection, - patchScopedAccountConfig, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { ChannelSetupInput } from "../../../src/channels/plugins/types.core.js"; diff --git a/extensions/nextcloud-talk/src/setup-surface.ts b/extensions/nextcloud-talk/src/setup-surface.ts index 64c0fc5a7a1..da839359ff2 100644 --- a/extensions/nextcloud-talk/src/setup-surface.ts +++ b/extensions/nextcloud-talk/src/setup-surface.ts @@ -3,8 +3,8 @@ import { resolveSetupAccountId, setSetupChannelEnabled, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupInput } from "../../../src/channels/plugins/types.core.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/nostr/src/setup-surface.test.ts b/extensions/nostr/src/setup-surface.test.ts index 0bd1b3f29a3..0a46946f8f9 100644 --- a/extensions/nostr/src/setup-surface.test.ts +++ b/extensions/nostr/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/nostr"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { WizardPrompter } from "../../../src/wizard/prompts.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; import { nostrPlugin } from "./channel.js"; @@ -25,7 +25,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const nostrConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const nostrConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: nostrPlugin, wizard: nostrPlugin.setupWizard!, }); diff --git a/extensions/nostr/src/setup-surface.ts b/extensions/nostr/src/setup-surface.ts index 84c78743cb3..e284d7b68a6 100644 --- a/extensions/nostr/src/setup-surface.ts +++ b/extensions/nostr/src/setup-surface.ts @@ -4,8 +4,8 @@ import { setTopLevelChannelAllowFrom, setTopLevelChannelDmPolicyWithAllowFrom, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/ollama/index.ts b/extensions/ollama/index.ts index c0b325e5a64..0609c597dc4 100644 --- a/extensions/ollama/index.ts +++ b/extensions/ollama/index.ts @@ -96,7 +96,7 @@ const ollamaPlugin = { }, }, wizard: { - onboarding: { + setup: { choiceId: "ollama", choiceLabel: "Ollama", choiceHint: "Cloud and local open models", diff --git a/extensions/sglang/index.ts b/extensions/sglang/index.ts index 64143026592..5672034ad9c 100644 --- a/extensions/sglang/index.ts +++ b/extensions/sglang/index.ts @@ -59,7 +59,7 @@ const sglangPlugin = { }), }, wizard: { - onboarding: { + setup: { choiceId: "sglang", choiceLabel: "SGLang", choiceHint: "Fast self-hosted OpenAI-compatible server", diff --git a/extensions/signal/src/setup-core.ts b/extensions/signal/src/setup-core.ts index 1b5b00d8264..40cc99add6e 100644 --- a/extensions/signal/src/setup-core.ts +++ b/extensions/signal/src/setup-core.ts @@ -1,14 +1,14 @@ +import { + applyAccountNameToChannelSection, + migrateBaseNameToDefaultAccount, +} from "../../../src/channels/plugins/setup-helpers.js"; import { parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applyAccountNameToChannelSection, - migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import { formatCliCommand } from "../../../src/cli/command-format.js"; diff --git a/extensions/signal/src/setup-surface.ts b/extensions/signal/src/setup-surface.ts index 62cb02b78ab..d3bd8e0b6de 100644 --- a/extensions/signal/src/setup-surface.ts +++ b/extensions/signal/src/setup-surface.ts @@ -3,8 +3,8 @@ import { promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { formatCliCommand } from "../../../src/cli/command-format.js"; import { detectBinary } from "../../../src/commands/onboard-helpers.js"; diff --git a/extensions/slack/src/setup-core.ts b/extensions/slack/src/setup-core.ts index 0aff9fc50a8..6b32f206d2e 100644 --- a/extensions/slack/src/setup-core.ts +++ b/extensions/slack/src/setup-core.ts @@ -1,3 +1,7 @@ +import { + applyAccountNameToChannelSection, + migrateBaseNameToDefaultAccount, +} from "../../../src/channels/plugins/setup-helpers.js"; import { noteChannelLookupFailure, noteChannelLookupSummary, @@ -6,12 +10,8 @@ import { setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { - applyAccountNameToChannelSection, - migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard, ChannelSetupWizardAllowFromEntry, diff --git a/extensions/slack/src/setup-surface.ts b/extensions/slack/src/setup-surface.ts index 4088e0d0ceb..5769c4c6d77 100644 --- a/extensions/slack/src/setup-surface.ts +++ b/extensions/slack/src/setup-surface.ts @@ -8,8 +8,8 @@ import { setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard, ChannelSetupWizardAllowFromEntry, diff --git a/extensions/synology-chat/src/setup-surface.test.ts b/extensions/synology-chat/src/setup-surface.test.ts index d7a2a1056a0..6c1289a8a84 100644 --- a/extensions/synology-chat/src/setup-surface.test.ts +++ b/extensions/synology-chat/src/setup-surface.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { WizardPrompter } from "../../../src/wizard/prompts.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; @@ -26,7 +26,7 @@ function createPrompter(overrides: Partial = {}): WizardPrompter }; } -const synologyChatConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const synologyChatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: synologyChatPlugin, wizard: synologyChatSetupWizard, }); diff --git a/extensions/synology-chat/src/setup-surface.ts b/extensions/synology-chat/src/setup-surface.ts index 77ad0ded2c2..d998022365b 100644 --- a/extensions/synology-chat/src/setup-surface.ts +++ b/extensions/synology-chat/src/setup-surface.ts @@ -2,7 +2,7 @@ import { mergeAllowFromEntries, setSetupChannelEnabled, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/telegram/src/bot-access.ts b/extensions/telegram/src/bot-access.ts index 57b242afc3d..bee8392e686 100644 --- a/extensions/telegram/src/bot-access.ts +++ b/extensions/telegram/src/bot-access.ts @@ -33,7 +33,7 @@ function warnInvalidAllowFromEntries(entries: string[]) { JSON.stringify(entry), "- allowFrom/groupAllowFrom authorization expects numeric Telegram sender user IDs only.", 'To allow a Telegram group or supergroup, add its negative chat ID under "channels.telegram.groups" instead.', - 'If you had "@username" entries, re-run onboarding (it resolves @username to IDs) or replace them manually.', + 'If you had "@username" entries, re-run setup (it resolves @username to IDs) or replace them manually.', ].join(" "), ); } diff --git a/extensions/telegram/src/setup-core.ts b/extensions/telegram/src/setup-core.ts index 1a3d17e68fd..cb688b67012 100644 --- a/extensions/telegram/src/setup-core.ts +++ b/extensions/telegram/src/setup-core.ts @@ -1,11 +1,11 @@ -import { - patchChannelConfigForAccount, - splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; import { applyAccountNameToChannelSection, migrateBaseNameToDefaultAccount, } from "../../../src/channels/plugins/setup-helpers.js"; +import { + patchChannelConfigForAccount, + splitSetupEntries, +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import { formatCliCommand } from "../../../src/cli/command-format.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; @@ -73,7 +73,7 @@ export async function promptTelegramAllowFromForAccount(params: { cfg: OpenClawConfig; prompter: Parameters< NonNullable< - import("../../../src/channels/plugins/setup-flow-types.js").ChannelSetupDmPolicy["promptAllowFrom"] + import("../../../src/channels/plugins/setup-wizard-types.js").ChannelSetupDmPolicy["promptAllowFrom"] > >[0]["prompter"]; accountId?: string; @@ -88,7 +88,7 @@ export async function promptTelegramAllowFromForAccount(params: { ); } const { promptResolvedAllowFrom } = - await import("../../../src/channels/plugins/setup-flow-helpers.js"); + await import("../../../src/channels/plugins/setup-wizard-helpers.js"); const unique = await promptResolvedAllowFrom({ prompter: params.prompter, existing: resolved.config.allowFrom ?? [], diff --git a/extensions/telegram/src/setup-surface.ts b/extensions/telegram/src/setup-surface.ts index ba03f2bb251..d0f122af174 100644 --- a/extensions/telegram/src/setup-surface.ts +++ b/extensions/telegram/src/setup-surface.ts @@ -3,8 +3,8 @@ import { setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import { type ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import { type ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import { type ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js"; diff --git a/extensions/tlon/src/setup-surface.test.ts b/extensions/tlon/src/setup-surface.test.ts index 9d3f432b46c..d54db2c75a1 100644 --- a/extensions/tlon/src/setup-surface.test.ts +++ b/extensions/tlon/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig, RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/tlon"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; import { tlonPlugin } from "./channel.js"; @@ -26,7 +26,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const tlonConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const tlonConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: tlonPlugin, wizard: tlonPlugin.setupWizard!, }); diff --git a/extensions/twitch/src/setup-surface.ts b/extensions/twitch/src/setup-surface.ts index 7d4129d2ebd..3113bfd9e3b 100644 --- a/extensions/twitch/src/setup-surface.ts +++ b/extensions/twitch/src/setup-surface.ts @@ -2,7 +2,7 @@ * Twitch setup wizard surface for CLI setup. */ -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/vllm/index.ts b/extensions/vllm/index.ts index cb865de4dfd..571692c6585 100644 --- a/extensions/vllm/index.ts +++ b/extensions/vllm/index.ts @@ -59,7 +59,7 @@ const vllmPlugin = { }), }, wizard: { - onboarding: { + setup: { choiceId: "vllm", choiceLabel: "vLLM", choiceHint: "Local/self-hosted OpenAI-compatible server", diff --git a/extensions/whatsapp/src/setup-surface.test.ts b/extensions/whatsapp/src/setup-surface.test.ts index e28766058af..51295d30a1b 100644 --- a/extensions/whatsapp/src/setup-surface.test.ts +++ b/extensions/whatsapp/src/setup-surface.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; import type { RuntimeEnv } from "../../../src/runtime.js"; import type { WizardPrompter } from "../../../src/wizard/prompts.js"; @@ -83,7 +83,7 @@ function createRuntime(): RuntimeEnv { } as unknown as RuntimeEnv; } -const whatsappConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const whatsappConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: whatsappPlugin, wizard: whatsappPlugin.setupWizard!, }); diff --git a/extensions/whatsapp/src/setup-surface.ts b/extensions/whatsapp/src/setup-surface.ts index e9b5b8aeb0b..4210b5772af 100644 --- a/extensions/whatsapp/src/setup-surface.ts +++ b/extensions/whatsapp/src/setup-surface.ts @@ -3,8 +3,8 @@ import { loginWeb } from "../../../src/channel-web.js"; import { normalizeAllowFromEntries, splitSetupEntries, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import { setSetupChannelEnabled } from "../../../src/channels/plugins/setup-flow-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import { setSetupChannelEnabled } from "../../../src/channels/plugins/setup-wizard-helpers.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { formatCliCommand } from "../../../src/cli/command-format.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; diff --git a/extensions/zalo/src/setup-status.test.ts b/extensions/zalo/src/setup-status.test.ts index 65e5591cbae..d8ba9d53d03 100644 --- a/extensions/zalo/src/setup-status.test.ts +++ b/extensions/zalo/src/setup-status.test.ts @@ -1,9 +1,9 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/zalo"; import { describe, expect, it } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { zaloPlugin } from "./channel.js"; -const zaloConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const zaloConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: zaloPlugin, wizard: zaloPlugin.setupWizard!, }); diff --git a/extensions/zalo/src/setup-surface.test.ts b/extensions/zalo/src/setup-surface.test.ts index b5db1019c38..f00060b50c6 100644 --- a/extensions/zalo/src/setup-surface.test.ts +++ b/extensions/zalo/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig, RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/zalo"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; import { zaloPlugin } from "./channel.js"; @@ -18,7 +18,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const zaloConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const zaloConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: zaloPlugin, wizard: zaloPlugin.setupWizard!, }); diff --git a/extensions/zalo/src/setup-surface.ts b/extensions/zalo/src/setup-surface.ts index b3ad6549c13..6ae6a78be0f 100644 --- a/extensions/zalo/src/setup-surface.ts +++ b/extensions/zalo/src/setup-surface.ts @@ -4,8 +4,8 @@ import { promptSingleChannelSecretInput, runSingleChannelSecretStep, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { SecretInput } from "../../../src/config/types.secrets.js"; diff --git a/extensions/zalouser/src/setup-surface.test.ts b/extensions/zalouser/src/setup-surface.test.ts index bd96ff2efe0..fc95b90ab8d 100644 --- a/extensions/zalouser/src/setup-surface.test.ts +++ b/extensions/zalouser/src/setup-surface.test.ts @@ -1,6 +1,6 @@ import type { OpenClawConfig, WizardPrompter } from "openclaw/plugin-sdk/zalouser"; import { describe, expect, it, vi } from "vitest"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import { createRuntimeEnv } from "../../test-utils/runtime-env.js"; vi.mock("./zalo-js.js", async (importOriginal) => { @@ -50,7 +50,7 @@ function createPrompter(overrides: Partial): WizardPrompter { }; } -const zalouserConfigureAdapter = buildChannelSetupFlowAdapterFromSetupWizard({ +const zalouserConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin: zalouserPlugin, wizard: zalouserPlugin.setupWizard!, }); diff --git a/extensions/zalouser/src/setup-surface.ts b/extensions/zalouser/src/setup-surface.ts index c7406f50edd..74f940e5077 100644 --- a/extensions/zalouser/src/setup-surface.ts +++ b/extensions/zalouser/src/setup-surface.ts @@ -1,9 +1,9 @@ +import { patchScopedAccountConfig } from "../../../src/channels/plugins/setup-helpers.js"; import { mergeAllowFromEntries, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../../../src/channels/plugins/setup-flow-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-flow-types.js"; -import { patchScopedAccountConfig } from "../../../src/channels/plugins/setup-helpers.js"; +} from "../../../src/channels/plugins/setup-wizard-helpers.js"; +import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { formatResolvedUnresolvedNote } from "../../../src/plugin-sdk/resolution-notes.js"; diff --git a/src/agents/auth-profiles/order.ts b/src/agents/auth-profiles/order.ts index d653b7198cb..fba2e9ed35c 100644 --- a/src/agents/auth-profiles/order.ts +++ b/src/agents/auth-profiles/order.ts @@ -104,7 +104,7 @@ export function resolveAuthProfileOrder(params: { }).eligible; let filtered = baseOrder.filter(isValidProfile); - // Repair config/store profile-id drift from older onboarding flows: + // Repair config/store profile-id drift from older setup flows: // if configured profile ids no longer exist in auth-profiles.json, scan the // provider's stored credentials and use any valid entries. const allBaseProfilesMissing = baseOrder.every((profileId) => !store.profiles[profileId]); diff --git a/src/agents/model-auth.ts b/src/agents/model-auth.ts index 4a896d5b56b..9e94c51dad7 100644 --- a/src/agents/model-auth.ts +++ b/src/agents/model-auth.ts @@ -202,7 +202,7 @@ function resolveSyntheticLocalProviderAuth(params: { // Custom providers pointing at a local server (e.g. llama.cpp, vLLM, LocalAI) // typically don't require auth. Synthesize a local key so the auth resolver - // doesn't reject them when the user left the API key blank during onboarding. + // doesn't reject them when the user left the API key blank during setup. if (providerConfig.baseUrl && isLocalBaseUrl(providerConfig.baseUrl)) { return { apiKey: CUSTOM_LOCAL_AUTH_MARKER, diff --git a/src/agents/workspace.test.ts b/src/agents/workspace.test.ts index 14302629a1c..4493ef716a1 100644 --- a/src/agents/workspace.test.ts +++ b/src/agents/workspace.test.ts @@ -31,22 +31,22 @@ describe("resolveDefaultAgentWorkspaceDir", () => { const WORKSPACE_STATE_PATH_SEGMENTS = [".openclaw", "workspace-state.json"] as const; -async function readOnboardingState(dir: string): Promise<{ +async function readWorkspaceState(dir: string): Promise<{ version: number; bootstrapSeededAt?: string; - onboardingCompletedAt?: string; + setupCompletedAt?: string; }> { const raw = await fs.readFile(path.join(dir, ...WORKSPACE_STATE_PATH_SEGMENTS), "utf-8"); return JSON.parse(raw) as { version: number; bootstrapSeededAt?: string; - onboardingCompletedAt?: string; + setupCompletedAt?: string; }; } async function expectBootstrapSeeded(dir: string) { await expect(fs.access(path.join(dir, DEFAULT_BOOTSTRAP_FILENAME))).resolves.toBeUndefined(); - const state = await readOnboardingState(dir); + const state = await readWorkspaceState(dir); expect(state.bootstrapSeededAt).toMatch(/\d{4}-\d{2}-\d{2}T/); } @@ -55,8 +55,8 @@ async function expectCompletedWithoutBootstrap(dir: string) { await expect(fs.access(path.join(dir, DEFAULT_BOOTSTRAP_FILENAME))).rejects.toMatchObject({ code: "ENOENT", }); - const state = await readOnboardingState(dir); - expect(state.onboardingCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); + const state = await readWorkspaceState(dir); + expect(state.setupCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); } function expectSubagentAllowedBootstrapNames(files: WorkspaceBootstrapFile[]) { @@ -78,7 +78,7 @@ describe("ensureAgentWorkspace", () => { await ensureAgentWorkspace({ dir: tempDir, ensureBootstrapFiles: true }); await expectBootstrapSeeded(tempDir); - expect((await readOnboardingState(tempDir)).onboardingCompletedAt).toBeUndefined(); + expect((await readWorkspaceState(tempDir)).setupCompletedAt).toBeUndefined(); }); it("recovers partial initialization by creating BOOTSTRAP.md when marker is missing", async () => { @@ -104,8 +104,8 @@ describe("ensureAgentWorkspace", () => { code: "ENOENT", }); await expect(fs.access(path.join(tempDir, DEFAULT_TOOLS_FILENAME))).resolves.toBeUndefined(); - const state = await readOnboardingState(tempDir); - expect(state.onboardingCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); + const state = await readWorkspaceState(tempDir); + expect(state.setupCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); }); it("does not re-seed BOOTSTRAP.md for legacy completed workspaces without state marker", async () => { @@ -118,9 +118,9 @@ describe("ensureAgentWorkspace", () => { await expect(fs.access(path.join(tempDir, DEFAULT_BOOTSTRAP_FILENAME))).rejects.toMatchObject({ code: "ENOENT", }); - const state = await readOnboardingState(tempDir); + const state = await readWorkspaceState(tempDir); expect(state.bootstrapSeededAt).toBeUndefined(); - expect(state.onboardingCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); + expect(state.setupCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); }); it("treats memory-backed workspaces as existing even when template files are missing", async () => { @@ -135,8 +135,8 @@ describe("ensureAgentWorkspace", () => { await expect(fs.access(path.join(tempDir, DEFAULT_BOOTSTRAP_FILENAME))).rejects.toMatchObject({ code: "ENOENT", }); - const state = await readOnboardingState(tempDir); - expect(state.onboardingCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); + const state = await readWorkspaceState(tempDir); + expect(state.setupCompletedAt).toMatch(/\d{4}-\d{2}-\d{2}T/); const memoryContent = await fs.readFile(path.join(tempDir, "MEMORY.md"), "utf-8"); expect(memoryContent).toBe("# Long-term memory\nImportant stuff"); }); @@ -150,6 +150,28 @@ describe("ensureAgentWorkspace", () => { await expectCompletedWithoutBootstrap(tempDir); }); + + it("migrates legacy onboardingCompletedAt markers to setupCompletedAt", async () => { + const tempDir = await makeTempWorkspace("openclaw-workspace-"); + await fs.mkdir(path.join(tempDir, ".openclaw"), { recursive: true }); + await fs.writeFile( + path.join(tempDir, ...WORKSPACE_STATE_PATH_SEGMENTS), + JSON.stringify({ + version: 1, + onboardingCompletedAt: "2026-03-15T02:30:00.000Z", + }), + ); + + await ensureAgentWorkspace({ dir: tempDir, ensureBootstrapFiles: true }); + + const state = await readWorkspaceState(tempDir); + expect(state.setupCompletedAt).toBe("2026-03-15T02:30:00.000Z"); + const persisted = await fs.readFile( + path.join(tempDir, ...WORKSPACE_STATE_PATH_SEGMENTS), + "utf-8", + ); + expect(persisted).toContain('"setupCompletedAt": "2026-03-15T02:30:00.000Z"'); + }); }); describe("loadWorkspaceBootstrapFiles", () => { diff --git a/src/agents/workspace.ts b/src/agents/workspace.ts index c4f1044a8d9..09159b4b072 100644 --- a/src/agents/workspace.ts +++ b/src/agents/workspace.ts @@ -159,10 +159,10 @@ export type ExtraBootstrapLoadDiagnostic = { detail: string; }; -type WorkspaceOnboardingState = { +type WorkspaceSetupState = { version: typeof WORKSPACE_STATE_VERSION; bootstrapSeededAt?: string; - onboardingCompletedAt?: string; + setupCompletedAt?: string; }; /** Set of recognized bootstrap filenames for runtime validation */ @@ -207,35 +207,43 @@ function resolveWorkspaceStatePath(dir: string): string { return path.join(dir, WORKSPACE_STATE_DIRNAME, WORKSPACE_STATE_FILENAME); } -function parseWorkspaceOnboardingState(raw: string): WorkspaceOnboardingState | null { +function parseWorkspaceSetupState(raw: string): WorkspaceSetupState | null { try { const parsed = JSON.parse(raw) as { bootstrapSeededAt?: unknown; + setupCompletedAt?: unknown; onboardingCompletedAt?: unknown; }; if (!parsed || typeof parsed !== "object") { return null; } + const legacyCompletedAt = + typeof parsed.onboardingCompletedAt === "string" ? parsed.onboardingCompletedAt : undefined; return { version: WORKSPACE_STATE_VERSION, bootstrapSeededAt: typeof parsed.bootstrapSeededAt === "string" ? parsed.bootstrapSeededAt : undefined, - onboardingCompletedAt: - typeof parsed.onboardingCompletedAt === "string" ? parsed.onboardingCompletedAt : undefined, + setupCompletedAt: + typeof parsed.setupCompletedAt === "string" ? parsed.setupCompletedAt : legacyCompletedAt, }; } catch { return null; } } -async function readWorkspaceOnboardingState(statePath: string): Promise { +async function readWorkspaceSetupState(statePath: string): Promise { try { const raw = await fs.readFile(statePath, "utf-8"); - return ( - parseWorkspaceOnboardingState(raw) ?? { - version: WORKSPACE_STATE_VERSION, - } - ); + const parsed = parseWorkspaceSetupState(raw); + if ( + parsed && + raw.includes('"onboardingCompletedAt"') && + !raw.includes('"setupCompletedAt"') && + parsed.setupCompletedAt + ) { + await writeWorkspaceSetupState(statePath, parsed); + } + return parsed ?? { version: WORKSPACE_STATE_VERSION }; } catch (err) { const anyErr = err as { code?: string }; if (anyErr.code !== "ENOENT") { @@ -247,21 +255,19 @@ async function readWorkspaceOnboardingState(statePath: string): Promise { +async function readWorkspaceSetupStateForDir(dir: string): Promise { const statePath = resolveWorkspaceStatePath(resolveUserPath(dir)); - return await readWorkspaceOnboardingState(statePath); + return await readWorkspaceSetupState(statePath); } -export async function isWorkspaceOnboardingCompleted(dir: string): Promise { - const state = await readWorkspaceOnboardingStateForDir(dir); - return ( - typeof state.onboardingCompletedAt === "string" && state.onboardingCompletedAt.trim().length > 0 - ); +export async function isWorkspaceSetupCompleted(dir: string): Promise { + const state = await readWorkspaceSetupStateForDir(dir); + return typeof state.setupCompletedAt === "string" && state.setupCompletedAt.trim().length > 0; } -async function writeWorkspaceOnboardingState( +async function writeWorkspaceSetupState( statePath: string, - state: WorkspaceOnboardingState, + state: WorkspaceSetupState, ): Promise { await fs.mkdir(path.dirname(statePath), { recursive: true }); const payload = `${JSON.stringify(state, null, 2)}\n`; @@ -382,9 +388,9 @@ export async function ensureAgentWorkspace(params?: { await writeFileIfMissing(userPath, userTemplate); await writeFileIfMissing(heartbeatPath, heartbeatTemplate); - let state = await readWorkspaceOnboardingState(statePath); + let state = await readWorkspaceSetupState(statePath); let stateDirty = false; - const markState = (next: Partial) => { + const markState = (next: Partial) => { state = { ...state, ...next }; stateDirty = true; }; @@ -395,14 +401,14 @@ export async function ensureAgentWorkspace(params?: { markState({ bootstrapSeededAt: nowIso() }); } - if (!state.onboardingCompletedAt && state.bootstrapSeededAt && !bootstrapExists) { - markState({ onboardingCompletedAt: nowIso() }); + if (!state.setupCompletedAt && state.bootstrapSeededAt && !bootstrapExists) { + markState({ setupCompletedAt: nowIso() }); } - if (!state.bootstrapSeededAt && !state.onboardingCompletedAt && !bootstrapExists) { + if (!state.bootstrapSeededAt && !state.setupCompletedAt && !bootstrapExists) { // Legacy migration path: if USER/IDENTITY diverged from templates, or if user-content - // indicators exist, treat onboarding as complete and avoid recreating BOOTSTRAP for - // already-onboarded workspaces. + // indicators exist, treat setup as complete and avoid recreating BOOTSTRAP for + // already-configured workspaces. const [identityContent, userContent] = await Promise.all([ fs.readFile(identityPath, "utf-8"), fs.readFile(userPath, "utf-8"), @@ -423,10 +429,10 @@ export async function ensureAgentWorkspace(params?: { } return false; })(); - const legacyOnboardingCompleted = + const legacySetupCompleted = identityContent !== identityTemplate || userContent !== userTemplate || hasUserContent; - if (legacyOnboardingCompleted) { - markState({ onboardingCompletedAt: nowIso() }); + if (legacySetupCompleted) { + markState({ setupCompletedAt: nowIso() }); } else { const bootstrapTemplate = await loadTemplate(DEFAULT_BOOTSTRAP_FILENAME); const wroteBootstrap = await writeFileIfMissing(bootstrapPath, bootstrapTemplate); @@ -442,7 +448,7 @@ export async function ensureAgentWorkspace(params?: { } if (stateDirty) { - await writeWorkspaceOnboardingState(statePath, state); + await writeWorkspaceSetupState(statePath, state); } await ensureGitRepo(dir, isBrandNewWorkspace); diff --git a/src/channels/plugins/setup-group-access.ts b/src/channels/plugins/setup-group-access.ts index b9130f7de51..6e68a0a4842 100644 --- a/src/channels/plugins/setup-group-access.ts +++ b/src/channels/plugins/setup-group-access.ts @@ -1,5 +1,5 @@ import type { WizardPrompter } from "../../wizard/prompts.js"; -import { splitSetupEntries } from "./setup-flow-helpers.js"; +import { splitSetupEntries } from "./setup-wizard-helpers.js"; export type ChannelAccessPolicy = "allowlist" | "open" | "disabled"; diff --git a/src/channels/plugins/setup-flow-helpers.test.ts b/src/channels/plugins/setup-wizard-helpers.test.ts similarity index 97% rename from src/channels/plugins/setup-flow-helpers.test.ts rename to src/channels/plugins/setup-wizard-helpers.test.ts index d13ce6a3b6b..3c20f51242f 100644 --- a/src/channels/plugins/setup-flow-helpers.test.ts +++ b/src/channels/plugins/setup-wizard-helpers.test.ts @@ -1,12 +1,6 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; - -const promptAccountIdSdkMock = vi.hoisted(() => vi.fn(async () => "default")); -vi.mock("../../plugin-sdk/setup.js", () => ({ - promptAccountId: promptAccountIdSdkMock, -})); - import { applySingleTokenPromptResult, buildSingleChannelSecretPromptState, @@ -35,7 +29,7 @@ import { setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, splitSetupEntries, -} from "./setup-flow-helpers.js"; +} from "./setup-wizard-helpers.js"; function createPrompter(inputs: string[]) { return { @@ -166,11 +160,6 @@ async function runPromptLegacyAllowFrom(params: { } describe("promptResolvedAllowFrom", () => { - beforeEach(() => { - promptAccountIdSdkMock.mockReset(); - promptAccountIdSdkMock.mockResolvedValue("default"); - }); - it("re-prompts without token until all ids are parseable", async () => { const prompter = createPrompter(["@alice", "123"]); const resolveEntries = vi.fn(); @@ -1150,11 +1139,6 @@ describe("resolveSetupAccountId", () => { }); describe("resolveAccountIdForConfigure", () => { - beforeEach(() => { - promptAccountIdSdkMock.mockReset(); - promptAccountIdSdkMock.mockResolvedValue("default"); - }); - it("uses normalized override without prompting", async () => { const accountId = await resolveAccountIdForConfigure({ cfg: {}, @@ -1183,12 +1167,16 @@ describe("resolveAccountIdForConfigure", () => { }); it("prompts for account id when prompting is enabled and no override is provided", async () => { - promptAccountIdSdkMock.mockResolvedValueOnce("prompted-id"); + const prompter = { + select: vi.fn(async () => "prompted-id"), + text: vi.fn(async () => ""), + note: vi.fn(async () => undefined), + }; const accountId = await resolveAccountIdForConfigure({ cfg: {}, // oxlint-disable-next-line typescript/no-explicit-any - prompter: {} as any, + prompter: prompter as any, label: "Signal", shouldPromptAccountIds: true, listAccountIds: () => ["default", "prompted-id"], @@ -1196,12 +1184,12 @@ describe("resolveAccountIdForConfigure", () => { }); expect(accountId).toBe("prompted-id"); - expect(promptAccountIdSdkMock).toHaveBeenCalledWith( + expect(prompter.select).toHaveBeenCalledWith( expect.objectContaining({ - label: "Signal", - currentId: "fallback", - defaultAccountId: "fallback", + message: "Signal account", + initialValue: "fallback", }), ); + expect(prompter.text).not.toHaveBeenCalled(); }); }); diff --git a/src/channels/plugins/setup-flow-helpers.ts b/src/channels/plugins/setup-wizard-helpers.ts similarity index 95% rename from src/channels/plugins/setup-flow-helpers.ts rename to src/channels/plugins/setup-wizard-helpers.ts index b0519b8f35d..de513f64d27 100644 --- a/src/channels/plugins/setup-flow-helpers.ts +++ b/src/channels/plugins/setup-wizard-helpers.ts @@ -1,21 +1,49 @@ import { - promptSecretRefForOnboarding, + promptSecretRefForSetup, resolveSecretInputModeForEnvSelection, } from "../../commands/auth-choice.apply-helpers.js"; import type { OpenClawConfig } from "../../config/config.js"; import type { DmPolicy, GroupPolicy } from "../../config/types.js"; import type { SecretInput } from "../../config/types.secrets.js"; -import { promptAccountId as promptAccountIdSdk } from "../../plugin-sdk/setup.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; import type { WizardPrompter } from "../../wizard/prompts.js"; -import type { PromptAccountId, PromptAccountIdParams } from "./setup-flow-types.js"; import { moveSingleAccountChannelSectionToDefaultAccount, patchScopedAccountConfig, } from "./setup-helpers.js"; +import type { PromptAccountId, PromptAccountIdParams } from "./setup-wizard-types.js"; export const promptAccountId: PromptAccountId = async (params: PromptAccountIdParams) => { - return await promptAccountIdSdk(params); + const existingIds = params.listAccountIds(params.cfg); + const initial = params.currentId?.trim() || params.defaultAccountId || DEFAULT_ACCOUNT_ID; + const choice = await params.prompter.select({ + message: `${params.label} account`, + options: [ + ...existingIds.map((id) => ({ + value: id, + label: id === DEFAULT_ACCOUNT_ID ? "default (primary)" : id, + })), + { value: "__new__", label: "Add a new account" }, + ], + initialValue: initial, + }); + + if (choice !== "__new__") { + return normalizeAccountId(choice); + } + + const entered = await params.prompter.text({ + message: `New ${params.label} account id`, + validate: (value) => (value?.trim() ? undefined : "Required"), + }); + const normalized = normalizeAccountId(String(entered)); + if (String(entered).trim() !== normalized) { + await params.prompter.note( + `Normalized account id to "${normalized}".`, + `${params.label} account`, + ); + } + return normalized; }; export function addWildcardAllowFrom(allowFrom?: Array | null): string[] { @@ -617,7 +645,7 @@ export async function promptSingleChannelSecretInput(params: { } } - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: params.providerHint, config: params.cfg, prompter: params.prompter as WizardPrompter, diff --git a/src/channels/plugins/setup-flow-types.ts b/src/channels/plugins/setup-wizard-types.ts similarity index 98% rename from src/channels/plugins/setup-flow-types.ts rename to src/channels/plugins/setup-wizard-types.ts index 53766d72af6..7dec2ea87a4 100644 --- a/src/channels/plugins/setup-flow-types.ts +++ b/src/channels/plugins/setup-wizard-types.ts @@ -90,7 +90,7 @@ export type ChannelSetupDmPolicy = { }) => Promise; }; -export type ChannelSetupFlowAdapter = { +export type ChannelSetupWizardAdapter = { channel: ChannelId; getStatus: (ctx: ChannelSetupStatusContext) => Promise; configure: (ctx: ChannelSetupConfigureContext) => Promise; diff --git a/src/channels/plugins/setup-wizard.ts b/src/channels/plugins/setup-wizard.ts index 66e7765ffe4..2301cc8fe49 100644 --- a/src/channels/plugins/setup-wizard.ts +++ b/src/channels/plugins/setup-wizard.ts @@ -1,21 +1,21 @@ import type { OpenClawConfig } from "../../config/config.js"; import { DEFAULT_ACCOUNT_ID } from "../../routing/session-key.js"; import type { WizardPrompter } from "../../wizard/prompts.js"; +import { configureChannelAccessWithAllowlist } from "./setup-group-access-configure.js"; +import type { ChannelAccessPolicy } from "./setup-group-access.js"; import { promptResolvedAllowFrom, resolveAccountIdForConfigure, runSingleChannelSecretStep, splitSetupEntries, -} from "./setup-flow-helpers.js"; +} from "./setup-wizard-helpers.js"; import type { - ChannelSetupFlowAdapter, + ChannelSetupWizardAdapter, ChannelSetupConfigureContext, ChannelSetupDmPolicy, ChannelSetupStatus, ChannelSetupStatusContext, -} from "./setup-flow-types.js"; -import { configureChannelAccessWithAllowlist } from "./setup-group-access-configure.js"; -import type { ChannelAccessPolicy } from "./setup-group-access.js"; +} from "./setup-wizard-types.js"; import type { ChannelSetupInput } from "./types.core.js"; import type { ChannelPlugin } from "./types.js"; @@ -273,7 +273,7 @@ export type ChannelSetupWizard = { allowFrom?: ChannelSetupWizardAllowFrom; groupAccess?: ChannelSetupWizardGroupAccess; disable?: (cfg: OpenClawConfig) => OpenClawConfig; - onAccountRecorded?: ChannelSetupFlowAdapter["onAccountRecorded"]; + onAccountRecorded?: ChannelSetupWizardAdapter["onAccountRecorded"]; }; type ChannelSetupWizardPlugin = Pick; @@ -399,10 +399,10 @@ async function applyWizardTextInputValue(params: { }).cfg; } -export function buildChannelSetupFlowAdapterFromSetupWizard(params: { +export function buildChannelSetupWizardAdapterFromSetupWizard(params: { plugin: ChannelSetupWizardPlugin; wizard: ChannelSetupWizard; -}): ChannelSetupFlowAdapter { +}): ChannelSetupWizardAdapter { const { plugin, wizard } = params; return { channel: plugin.id, diff --git a/src/cli/program/command-registry.ts b/src/cli/program/command-registry.ts index 4b39b1d94a9..89d59bfb7ee 100644 --- a/src/cli/program/command-registry.ts +++ b/src/cli/program/command-registry.ts @@ -56,7 +56,7 @@ const coreEntries: CoreCliEntry[] = [ commands: [ { name: "onboard", - description: "Interactive onboarding wizard for gateway, workspace, and skills", + description: "Interactive setup wizard for gateway, workspace, and skills", hasSubcommands: false, }, ], diff --git a/src/cli/program/core-command-descriptors.ts b/src/cli/program/core-command-descriptors.ts index 6cad819a1dc..8756c7bf7d4 100644 --- a/src/cli/program/core-command-descriptors.ts +++ b/src/cli/program/core-command-descriptors.ts @@ -12,7 +12,7 @@ export const CORE_CLI_COMMAND_DESCRIPTORS = [ }, { name: "onboard", - description: "Interactive onboarding wizard for gateway, workspace, and skills", + description: "Interactive setup wizard for gateway, workspace, and skills", hasSubcommands: false, }, { diff --git a/src/cli/program/register.setup.ts b/src/cli/program/register.setup.ts index ec580a2344e..2839ad721e4 100644 --- a/src/cli/program/register.setup.ts +++ b/src/cli/program/register.setup.ts @@ -20,7 +20,7 @@ export function registerSetupCommand(program: Command) { "--workspace ", "Agent workspace directory (default: ~/.openclaw/workspace; stored as agents.defaults.workspace)", ) - .option("--wizard", "Run the interactive onboarding wizard", false) + .option("--wizard", "Run the interactive setup wizard", false) .option("--non-interactive", "Run the wizard without prompts", false) .option("--mode ", "Wizard mode: local|remote") .option("--remote-url ", "Remote Gateway WebSocket URL") diff --git a/src/commands/auth-choice.apply-helpers.test.ts b/src/commands/auth-choice.apply-helpers.test.ts index 7a1c30fd18f..e80f5e79b07 100644 --- a/src/commands/auth-choice.apply-helpers.test.ts +++ b/src/commands/auth-choice.apply-helpers.test.ts @@ -282,7 +282,7 @@ describe("ensureApiKeyFromEnvOrPrompt", () => { setCredential, }), ).rejects.toThrow( - 'Environment variable "MINIMAX_API_KEY" is required for --secret-input-mode ref in non-interactive onboarding.', + 'Environment variable "MINIMAX_API_KEY" is required for --secret-input-mode ref in non-interactive setup.', ); expect(setCredential).not.toHaveBeenCalled(); }); diff --git a/src/commands/auth-choice.apply-helpers.ts b/src/commands/auth-choice.apply-helpers.ts index 32c6ac82786..7029dd081c3 100644 --- a/src/commands/auth-choice.apply-helpers.ts +++ b/src/commands/auth-choice.apply-helpers.ts @@ -32,7 +32,7 @@ export type SecretInputModePromptCopy = { refHint?: string; }; -export type SecretRefOnboardingPromptCopy = { +export type SecretRefSetupPromptCopy = { sourceMessage?: string; envVarMessage?: string; envVarPlaceholder?: string; @@ -72,13 +72,13 @@ function resolveRefFallbackInput(params: { const fallbackEnvVar = params.preferredEnvVar ?? resolveDefaultProviderEnvVar(params.provider); if (!fallbackEnvVar) { throw new Error( - `No default environment variable mapping found for provider "${params.provider}". Set a provider-specific env var, or re-run onboarding in an interactive terminal to configure a ref.`, + `No default environment variable mapping found for provider "${params.provider}". Set a provider-specific env var, or re-run setup in an interactive terminal to configure a ref.`, ); } const value = process.env[fallbackEnvVar]?.trim(); if (!value) { throw new Error( - `Environment variable "${fallbackEnvVar}" is required for --secret-input-mode ref in non-interactive onboarding.`, + `Environment variable "${fallbackEnvVar}" is required for --secret-input-mode ref in non-interactive setup.`, ); } return { @@ -93,12 +93,12 @@ function resolveRefFallbackInput(params: { }; } -export async function promptSecretRefForOnboarding(params: { +export async function promptSecretRefForSetup(params: { provider: string; config: OpenClawConfig; prompter: WizardPrompter; preferredEnvVar?: string; - copy?: SecretRefOnboardingPromptCopy; + copy?: SecretRefSetupPromptCopy; }): Promise<{ ref: SecretRef; resolvedValue: string }> { const defaultEnvVar = params.preferredEnvVar ?? resolveDefaultProviderEnvVar(params.provider) ?? ""; @@ -506,7 +506,7 @@ export async function ensureApiKeyFromEnvOrPrompt(params: { await params.setCredential(fallback.ref, selectedMode); return fallback.resolvedValue; } - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: params.provider, config: params.config, prompter: params.prompter, diff --git a/src/commands/auth-choice.apply.anthropic.ts b/src/commands/auth-choice.apply.anthropic.ts index e9914c7fa78..a33864230cc 100644 --- a/src/commands/auth-choice.apply.anthropic.ts +++ b/src/commands/auth-choice.apply.anthropic.ts @@ -3,7 +3,7 @@ import { normalizeApiKeyInput, validateApiKeyInput } from "./auth-choice.api-key import { normalizeSecretInputModeInput, ensureApiKeyFromOptionEnvOrPrompt, - promptSecretRefForOnboarding, + promptSecretRefForSetup, resolveSecretInputModeForEnvSelection, } from "./auth-choice.apply-helpers.js"; import type { ApplyAuthChoiceParams, ApplyAuthChoiceResult } from "./auth-choice.apply.js"; @@ -42,7 +42,7 @@ export async function applyAuthChoiceAnthropic( let token = ""; let tokenRef: { source: "env" | "file" | "exec"; provider: string; id: string } | undefined; if (selectedMode === "ref") { - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: "anthropic-setup-token", config: params.config, prompter: params.prompter, diff --git a/src/commands/auth-choice.apply.openai.ts b/src/commands/auth-choice.apply.openai.ts index 57059307920..d554839f28b 100644 --- a/src/commands/auth-choice.apply.openai.ts +++ b/src/commands/auth-choice.apply.openai.ts @@ -90,7 +90,7 @@ export async function applyAuthChoiceOpenAI( }); } catch { // The helper already surfaces the error to the user. - // Keep onboarding flow alive and return unchanged config. + // Keep setup flow alive and return unchanged config. return { config: nextConfig, agentModelOverride }; } if (creds) { diff --git a/src/commands/onboarding/plugin-install.test.ts b/src/commands/channel-setup/plugin-install.test.ts similarity index 91% rename from src/commands/onboarding/plugin-install.test.ts rename to src/commands/channel-setup/plugin-install.test.ts index 953fccf5a68..8e11c866c16 100644 --- a/src/commands/onboarding/plugin-install.test.ts +++ b/src/commands/channel-setup/plugin-install.test.ts @@ -61,12 +61,12 @@ import { loadOpenClawPlugins } from "../../plugins/loader.js"; import { createEmptyPluginRegistry } from "../../plugins/registry.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js"; import type { WizardPrompter } from "../../wizard/prompts.js"; -import { makePrompter, makeRuntime } from "./__tests__/test-utils.js"; +import { makePrompter, makeRuntime } from "../setup/__tests__/test-utils.js"; import { - ensureOnboardingPluginInstalled, - loadOnboardingPluginRegistrySnapshotForChannel, - reloadOnboardingPluginRegistry, - reloadOnboardingPluginRegistryForChannel, + ensureChannelSetupPluginInstalled, + loadChannelSetupPluginRegistrySnapshotForChannel, + reloadChannelSetupPluginRegistry, + reloadChannelSetupPluginRegistryForChannel, } from "./plugin-install.js"; const baseEntry: ChannelPluginCatalogEntry = { @@ -106,7 +106,7 @@ async function runInitialValueForChannel(channel: "dev" | "beta") { const cfg: OpenClawConfig = { update: { channel } }; mockRepoLocalPathExists(); - await ensureOnboardingPluginInstalled({ + await ensureChannelSetupPluginInstalled({ cfg, entry: baseEntry, prompter, @@ -118,14 +118,14 @@ async function runInitialValueForChannel(channel: "dev" | "beta") { } function expectPluginLoadedFromLocalPath( - result: Awaited>, + result: Awaited>, ) { const expectedPath = path.resolve(process.cwd(), "extensions/zalo"); expect(result.installed).toBe(true); expect(result.cfg.plugins?.load?.paths).toContain(expectedPath); } -describe("ensureOnboardingPluginInstalled", () => { +describe("ensureChannelSetupPluginInstalled", () => { it("installs from npm and enables the plugin", async () => { const runtime = makeRuntime(); const prompter = makePrompter({ @@ -140,7 +140,7 @@ describe("ensureOnboardingPluginInstalled", () => { extensions: [], }); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg, entry: baseEntry, prompter, @@ -166,7 +166,7 @@ describe("ensureOnboardingPluginInstalled", () => { const cfg: OpenClawConfig = {}; mockRepoLocalPathExists(); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg, entry: baseEntry, prompter, @@ -185,7 +185,7 @@ describe("ensureOnboardingPluginInstalled", () => { const cfg: OpenClawConfig = {}; mockRepoLocalPathExists(); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg, entry: { ...baseEntry, @@ -228,7 +228,7 @@ describe("ensureOnboardingPluginInstalled", () => { ]), ); - await ensureOnboardingPluginInstalled({ + await ensureChannelSetupPluginInstalled({ cfg, entry: baseEntry, prompter, @@ -264,7 +264,7 @@ describe("ensureOnboardingPluginInstalled", () => { error: "nope", }); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg, entry: baseEntry, prompter, @@ -280,7 +280,7 @@ describe("ensureOnboardingPluginInstalled", () => { const runtime = makeRuntime(); const cfg: OpenClawConfig = {}; - reloadOnboardingPluginRegistry({ + reloadChannelSetupPluginRegistry({ cfg, runtime, workspaceDir: "/tmp/openclaw-workspace", @@ -300,11 +300,11 @@ describe("ensureOnboardingPluginInstalled", () => { ); }); - it("scopes channel reloads when onboarding starts from an empty registry", () => { + it("scopes channel reloads when setup starts from an empty registry", () => { const runtime = makeRuntime(); const cfg: OpenClawConfig = {}; - reloadOnboardingPluginRegistryForChannel({ + reloadChannelSetupPluginRegistryForChannel({ cfg, runtime, channel: "telegram", @@ -348,7 +348,7 @@ describe("ensureOnboardingPluginInstalled", () => { }); setActivePluginRegistry(registry); - reloadOnboardingPluginRegistryForChannel({ + reloadChannelSetupPluginRegistryForChannel({ cfg, runtime, channel: "telegram", @@ -366,7 +366,7 @@ describe("ensureOnboardingPluginInstalled", () => { const runtime = makeRuntime(); const cfg: OpenClawConfig = {}; - loadOnboardingPluginRegistrySnapshotForChannel({ + loadChannelSetupPluginRegistrySnapshotForChannel({ cfg, runtime, channel: "telegram", @@ -389,7 +389,7 @@ describe("ensureOnboardingPluginInstalled", () => { const runtime = makeRuntime(); const cfg: OpenClawConfig = {}; - loadOnboardingPluginRegistrySnapshotForChannel({ + loadChannelSetupPluginRegistrySnapshotForChannel({ cfg, runtime, channel: "msteams", diff --git a/src/commands/onboarding/plugin-install.ts b/src/commands/channel-setup/plugin-install.ts similarity index 94% rename from src/commands/onboarding/plugin-install.ts rename to src/commands/channel-setup/plugin-install.ts index 3a7f5623425..ff4e03c5128 100644 --- a/src/commands/onboarding/plugin-install.ts +++ b/src/commands/channel-setup/plugin-install.ts @@ -139,7 +139,7 @@ function resolveInstallDefaultChoice(params: { return localPath ? "local" : "npm"; } -export async function ensureOnboardingPluginInstalled(params: { +export async function ensureChannelSetupPluginInstalled(params: { cfg: OpenClawConfig; entry: ChannelPluginCatalogEntry; prompter: WizardPrompter; @@ -225,15 +225,15 @@ export async function ensureOnboardingPluginInstalled(params: { return { cfg: next, installed: false }; } -export function reloadOnboardingPluginRegistry(params: { +export function reloadChannelSetupPluginRegistry(params: { cfg: OpenClawConfig; runtime: RuntimeEnv; workspaceDir?: string; }): void { - loadOnboardingPluginRegistry(params); + loadChannelSetupPluginRegistry(params); } -function loadOnboardingPluginRegistry(params: { +function loadChannelSetupPluginRegistry(params: { cfg: OpenClawConfig; runtime: RuntimeEnv; workspaceDir?: string; @@ -255,7 +255,7 @@ function loadOnboardingPluginRegistry(params: { }); } -export function reloadOnboardingPluginRegistryForChannel(params: { +export function reloadChannelSetupPluginRegistryForChannel(params: { cfg: OpenClawConfig; runtime: RuntimeEnv; channel: string; @@ -264,24 +264,24 @@ export function reloadOnboardingPluginRegistryForChannel(params: { }): void { const activeRegistry = getActivePluginRegistry(); // On low-memory hosts, the empty-registry fallback should only recover the selected - // plugin instead of importing every bundled extension during onboarding. + // plugin instead of importing every bundled extension during setup. const onlyPluginIds = activeRegistry?.plugins.length ? undefined : [params.pluginId ?? params.channel]; - loadOnboardingPluginRegistry({ + loadChannelSetupPluginRegistry({ ...params, onlyPluginIds, }); } -export function loadOnboardingPluginRegistrySnapshotForChannel(params: { +export function loadChannelSetupPluginRegistrySnapshotForChannel(params: { cfg: OpenClawConfig; runtime: RuntimeEnv; channel: string; pluginId?: string; workspaceDir?: string; }): PluginRegistry { - return loadOnboardingPluginRegistry({ + return loadChannelSetupPluginRegistry({ ...params, onlyPluginIds: [params.pluginId ?? params.channel], activate: false, diff --git a/src/commands/channel-setup/registry.ts b/src/commands/channel-setup/registry.ts index 9bfd1cf188b..a2f72f63343 100644 --- a/src/commands/channel-setup/registry.ts +++ b/src/commands/channel-setup/registry.ts @@ -1,20 +1,20 @@ import { listChannelSetupPlugins } from "../../channels/plugins/setup-registry.js"; -import { buildChannelSetupFlowAdapterFromSetupWizard } from "../../channels/plugins/setup-wizard.js"; +import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../channels/plugins/setup-wizard.js"; import type { ChannelPlugin } from "../../channels/plugins/types.js"; import type { ChannelChoice } from "../onboard-types.js"; -import type { ChannelSetupFlowAdapter } from "./types.js"; +import type { ChannelSetupWizardAdapter } from "./types.js"; -const setupWizardAdapters = new WeakMap(); +const setupWizardAdapters = new WeakMap(); -export function resolveChannelSetupFlowAdapterForPlugin( +export function resolveChannelSetupWizardAdapterForPlugin( plugin?: ChannelPlugin, -): ChannelSetupFlowAdapter | undefined { +): ChannelSetupWizardAdapter | undefined { if (plugin?.setupWizard) { const cached = setupWizardAdapters.get(plugin); if (cached) { return cached; } - const adapter = buildChannelSetupFlowAdapterFromSetupWizard({ + const adapter = buildChannelSetupWizardAdapterFromSetupWizard({ plugin, wizard: plugin.setupWizard, }); @@ -24,10 +24,10 @@ export function resolveChannelSetupFlowAdapterForPlugin( return undefined; } -const CHANNEL_SETUP_FLOW_ADAPTERS = () => { - const adapters = new Map(); +const getChannelSetupWizardAdapterMap = () => { + const adapters = new Map(); for (const plugin of listChannelSetupPlugins()) { - const adapter = resolveChannelSetupFlowAdapterForPlugin(plugin); + const adapter = resolveChannelSetupWizardAdapterForPlugin(plugin); if (!adapter) { continue; } @@ -36,12 +36,12 @@ const CHANNEL_SETUP_FLOW_ADAPTERS = () => { return adapters; }; -export function getChannelSetupFlowAdapter( +export function getChannelSetupWizardAdapter( channel: ChannelChoice, -): ChannelSetupFlowAdapter | undefined { - return CHANNEL_SETUP_FLOW_ADAPTERS().get(channel); +): ChannelSetupWizardAdapter | undefined { + return getChannelSetupWizardAdapterMap().get(channel); } -export function listChannelSetupFlowAdapters(): ChannelSetupFlowAdapter[] { - return Array.from(CHANNEL_SETUP_FLOW_ADAPTERS().values()); +export function listChannelSetupWizardAdapters(): ChannelSetupWizardAdapter[] { + return Array.from(getChannelSetupWizardAdapterMap().values()); } diff --git a/src/commands/channel-setup/types.ts b/src/commands/channel-setup/types.ts index f610d0cb1f6..d1fb33c2c5b 100644 --- a/src/commands/channel-setup/types.ts +++ b/src/commands/channel-setup/types.ts @@ -1 +1 @@ -export * from "../../channels/plugins/setup-flow-types.js"; +export * from "../../channels/plugins/setup-wizard-types.js"; diff --git a/src/commands/channel-test-helpers.ts b/src/commands/channel-test-helpers.ts index 7a6d687a91c..410dbd5496b 100644 --- a/src/commands/channel-test-helpers.ts +++ b/src/commands/channel-test-helpers.ts @@ -6,22 +6,22 @@ import { telegramPlugin } from "../../extensions/telegram/src/channel.js"; import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; import { createTestRegistry } from "../test-utils/channel-plugins.js"; -import { getChannelSetupFlowAdapter } from "./channel-setup/registry.js"; -import type { ChannelSetupFlowAdapter } from "./channel-setup/types.js"; +import { getChannelSetupWizardAdapter } from "./channel-setup/registry.js"; +import type { ChannelSetupWizardAdapter } from "./channel-setup/types.js"; import type { ChannelChoice } from "./onboard-types.js"; -type ChannelSetupFlowAdapterPatch = Partial< +type ChannelSetupWizardAdapterPatch = Partial< Pick< - ChannelSetupFlowAdapter, + ChannelSetupWizardAdapter, "configure" | "configureInteractive" | "configureWhenConfigured" | "getStatus" > >; type PatchedSetupAdapterFields = { - configure?: ChannelSetupFlowAdapter["configure"]; - configureInteractive?: ChannelSetupFlowAdapter["configureInteractive"]; - configureWhenConfigured?: ChannelSetupFlowAdapter["configureWhenConfigured"]; - getStatus?: ChannelSetupFlowAdapter["getStatus"]; + configure?: ChannelSetupWizardAdapter["configure"]; + configureInteractive?: ChannelSetupWizardAdapter["configureInteractive"]; + configureWhenConfigured?: ChannelSetupWizardAdapter["configureWhenConfigured"]; + getStatus?: ChannelSetupWizardAdapter["getStatus"]; }; export function setDefaultChannelPluginRegistryForTests(): void { @@ -36,11 +36,11 @@ export function setDefaultChannelPluginRegistryForTests(): void { setActivePluginRegistry(createTestRegistry(channels)); } -export function patchChannelSetupFlowAdapter( +export function patchChannelSetupWizardAdapter( channel: ChannelChoice, - patch: ChannelSetupFlowAdapterPatch, + patch: ChannelSetupWizardAdapterPatch, ): () => void { - const adapter = getChannelSetupFlowAdapter(channel); + const adapter = getChannelSetupWizardAdapter(channel); if (!adapter) { throw new Error(`missing setup adapter for ${channel}`); } diff --git a/src/commands/channels.add.test.ts b/src/commands/channels.add.test.ts index fdb3e61f97d..ad5d323f427 100644 --- a/src/commands/channels.add.test.ts +++ b/src/commands/channels.add.test.ts @@ -2,12 +2,12 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import type { ChannelPluginCatalogEntry } from "../channels/plugins/catalog.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js"; +import { + ensureChannelSetupPluginInstalled, + loadChannelSetupPluginRegistrySnapshotForChannel, +} from "./channel-setup/plugin-install.js"; import { setDefaultChannelPluginRegistryForTests } from "./channel-test-helpers.js"; import { configMocks, offsetMocks } from "./channels.mock-harness.js"; -import { - ensureOnboardingPluginInstalled, - loadOnboardingPluginRegistrySnapshotForChannel, -} from "./onboarding/plugin-install.js"; import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js"; const catalogMocks = vi.hoisted(() => ({ @@ -34,12 +34,12 @@ vi.mock("../plugins/manifest-registry.js", async (importOriginal) => { }; }); -vi.mock("./onboarding/plugin-install.js", async (importOriginal) => { - const actual = await importOriginal(); +vi.mock("./channel-setup/plugin-install.js", async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, - ensureOnboardingPluginInstalled: vi.fn(async ({ cfg }) => ({ cfg, installed: true })), - loadOnboardingPluginRegistrySnapshotForChannel: vi.fn(() => createTestRegistry()), + ensureChannelSetupPluginInstalled: vi.fn(async ({ cfg }) => ({ cfg, installed: true })), + loadChannelSetupPluginRegistrySnapshotForChannel: vi.fn(() => createTestRegistry()), }; }); @@ -65,13 +65,15 @@ describe("channelsAddCommand", () => { plugins: [], diagnostics: [], }); - vi.mocked(ensureOnboardingPluginInstalled).mockClear(); - vi.mocked(ensureOnboardingPluginInstalled).mockImplementation(async ({ cfg }) => ({ + vi.mocked(ensureChannelSetupPluginInstalled).mockClear(); + vi.mocked(ensureChannelSetupPluginInstalled).mockImplementation(async ({ cfg }) => ({ cfg, installed: true, })); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockClear(); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockReturnValue(createTestRegistry()); + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockClear(); + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockReturnValue( + createTestRegistry(), + ); setDefaultChannelPluginRegistryForTests(); }); @@ -151,7 +153,7 @@ describe("channelsAddCommand", () => { })), }, }; - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockReturnValue( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockReturnValue( createTestRegistry([{ pluginId: "msteams", plugin: scopedMSTeamsPlugin, source: "test" }]), ); @@ -165,10 +167,10 @@ describe("channelsAddCommand", () => { { hasFlags: true }, ); - expect(ensureOnboardingPluginInstalled).toHaveBeenCalledWith( + expect(ensureChannelSetupPluginInstalled).toHaveBeenCalledWith( expect.objectContaining({ entry: catalogEntry }), ); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams", pluginId: "@openclaw/msteams-plugin", @@ -234,7 +236,7 @@ describe("channelsAddCommand", () => { })), }, }; - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockReturnValue( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockReturnValue( createTestRegistry([{ pluginId: "msteams", plugin: scopedMSTeamsPlugin, source: "test" }]), ); @@ -248,8 +250,8 @@ describe("channelsAddCommand", () => { { hasFlags: true }, ); - expect(ensureOnboardingPluginInstalled).not.toHaveBeenCalled(); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(ensureChannelSetupPluginInstalled).not.toHaveBeenCalled(); + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams", pluginId: "@openclaw/msteams-plugin", @@ -285,12 +287,12 @@ describe("channelsAddCommand", () => { }, }; catalogMocks.listChannelPluginCatalogEntries.mockReturnValue([catalogEntry]); - vi.mocked(ensureOnboardingPluginInstalled).mockImplementation(async ({ cfg }) => ({ + vi.mocked(ensureChannelSetupPluginInstalled).mockImplementation(async ({ cfg }) => ({ cfg, installed: true, pluginId: "@vendor/teams-runtime", })); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockReturnValue( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockReturnValue( createTestRegistry([ { pluginId: "@vendor/teams-runtime", @@ -328,7 +330,7 @@ describe("channelsAddCommand", () => { { hasFlags: true }, ); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams", pluginId: "@vendor/teams-runtime", diff --git a/src/commands/channels/add.ts b/src/commands/channels/add.ts index b4f8205ae3a..b2a092780a8 100644 --- a/src/commands/channels/add.ts +++ b/src/commands/channels/add.ts @@ -2,8 +2,8 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/ag import { listChannelPluginCatalogEntries } from "../../channels/plugins/catalog.js"; import { parseOptionalDelimitedEntries } from "../../channels/plugins/helpers.js"; import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js"; -import type { ChannelSetupPlugin } from "../../channels/plugins/setup-flow-types.js"; import { moveSingleAccountChannelSectionToDefaultAccount } from "../../channels/plugins/setup-helpers.js"; +import type { ChannelSetupPlugin } from "../../channels/plugins/setup-wizard-types.js"; import type { ChannelId, ChannelPlugin, ChannelSetupInput } from "../../channels/plugins/types.js"; import { writeConfigFile, type OpenClawConfig } from "../../config/config.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js"; @@ -188,9 +188,9 @@ export async function channelsAddCommand( if (existing) { return existing; } - const { loadOnboardingPluginRegistrySnapshotForChannel } = - await import("../onboarding/plugin-install.js"); - const snapshot = loadOnboardingPluginRegistrySnapshotForChannel({ + const { loadChannelSetupPluginRegistrySnapshotForChannel } = + await import("../channel-setup/plugin-install.js"); + const snapshot = loadChannelSetupPluginRegistrySnapshotForChannel({ cfg: nextConfig, runtime, channel: channelId, @@ -212,9 +212,10 @@ export async function channelsAddCommand( workspaceDir, }) ) { - const { ensureOnboardingPluginInstalled } = await import("../onboarding/plugin-install.js"); + const { ensureChannelSetupPluginInstalled } = + await import("../channel-setup/plugin-install.js"); const prompter = createClackPrompter(); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg: nextConfig, entry: catalogEntry, prompter, diff --git a/src/commands/configure.wizard.ts b/src/commands/configure.wizard.ts index 6e5f0203be0..78cd0716376 100644 --- a/src/commands/configure.wizard.ts +++ b/src/commands/configure.wizard.ts @@ -10,8 +10,8 @@ import { defaultRuntime } from "../runtime.js"; import { note } from "../terminal/note.js"; import { resolveUserPath } from "../utils.js"; import { createClackPrompter } from "../wizard/clack-prompter.js"; -import { resolveOnboardingSecretInputString } from "../wizard/onboarding.secret-input.js"; import { WizardCancelledError } from "../wizard/prompts.js"; +import { resolveSetupSecretInputString } from "../wizard/setup.secret-input.js"; import { removeChannelConfigWizard } from "./configure.channels.js"; import { maybeInstallDaemon } from "./configure.daemon.js"; import { promptAuthConfig } from "./configure.gateway-auth.js"; @@ -54,7 +54,7 @@ async function resolveGatewaySecretInputForWizard(params: { path: string; }): Promise { try { - return await resolveOnboardingSecretInputString({ + return await resolveSetupSecretInputString({ config: params.cfg, value: params.value, path: params.path, diff --git a/src/commands/doctor-completion.ts b/src/commands/doctor-completion.ts index 1e38c7701c7..edb2d98fb38 100644 --- a/src/commands/doctor-completion.ts +++ b/src/commands/doctor-completion.ts @@ -163,7 +163,7 @@ export async function doctorShellCompletion( } /** - * Ensure completion cache exists. Used during onboarding/update to fix + * Ensure completion cache exists. Used during setup/update to fix * cases where profile has completion but no cache. * This is a silent fix - no prompts. */ diff --git a/src/commands/doctor-config-analysis.ts b/src/commands/doctor-config-analysis.ts index 994bac5f863..acc333b5cba 100644 --- a/src/commands/doctor-config-analysis.ts +++ b/src/commands/doctor-config-analysis.ts @@ -126,7 +126,7 @@ export function noteOpencodeProviderOverrides(cfg: OpenClawConfig): void { }); lines.push( - "- Remove these entries to restore per-model API routing + costs (then re-run onboarding if needed).", + "- Remove these entries to restore per-model API routing + costs (then re-run setup if needed).", ); note(lines.join("\n"), "OpenCode"); } diff --git a/src/commands/model-picker.test.ts b/src/commands/model-picker.test.ts index ce8c4bfb9f6..a4eb89e066c 100644 --- a/src/commands/model-picker.test.ts +++ b/src/commands/model-picker.test.ts @@ -6,7 +6,7 @@ import { promptDefaultModel, promptModelAllowlist, } from "./model-picker.js"; -import { makePrompter } from "./onboarding/__tests__/test-utils.js"; +import { makePrompter } from "./setup/__tests__/test-utils.js"; const loadModelCatalog = vi.hoisted(() => vi.fn()); vi.mock("../agents/model-catalog.js", () => ({ @@ -76,7 +76,7 @@ beforeEach(() => { }); describe("promptDefaultModel", () => { - it("supports configuring vLLM during onboarding", async () => { + it("supports configuring vLLM during setup", async () => { loadModelCatalog.mockResolvedValue([ { provider: "anthropic", diff --git a/src/commands/ollama-setup.ts b/src/commands/ollama-setup.ts index 3308dfcf067..060724061bd 100644 --- a/src/commands/ollama-setup.ts +++ b/src/commands/ollama-setup.ts @@ -313,7 +313,7 @@ export async function promptAndConfigureOllama(params: { `Ollama could not be reached at ${baseUrl}.`, "Download it at https://ollama.com/download", "", - "Start Ollama and re-run onboarding.", + "Start Ollama and re-run setup.", ].join("\n"), "Ollama", ); @@ -486,7 +486,7 @@ export async function configureOllamaNonInteractive(params: { runtime.error( [ `No Ollama models are available at ${baseUrl}.`, - "Pull a model first, then re-run onboarding.", + "Pull a model first, then re-run setup.", ].join("\n"), ); runtime.exit(1); diff --git a/src/commands/onboard-auth.config-core.ts b/src/commands/onboard-auth.config-core.ts index 6fc132f57cb..0afd59c3910 100644 --- a/src/commands/onboard-auth.config-core.ts +++ b/src/commands/onboard-auth.config-core.ts @@ -338,7 +338,7 @@ export function applyVeniceProviderConfig(cfg: OpenClawConfig): OpenClawConfig { /** * Apply Venice provider configuration AND set Venice as the default model. - * Use this when Venice is the primary provider choice during onboarding. + * Use this when Venice is the primary provider choice during setup. */ export function applyVeniceConfig(cfg: OpenClawConfig): OpenClawConfig { const next = applyVeniceProviderConfig(cfg); @@ -368,7 +368,7 @@ export function applyTogetherProviderConfig(cfg: OpenClawConfig): OpenClawConfig /** * Apply Together provider configuration AND set Together as the default model. - * Use this when Together is the primary provider choice during onboarding. + * Use this when Together is the primary provider choice during setup. */ export function applyTogetherConfig(cfg: OpenClawConfig): OpenClawConfig { const next = applyTogetherProviderConfig(cfg); @@ -477,7 +477,7 @@ export function applyKilocodeProviderConfig(cfg: OpenClawConfig): OpenClawConfig /** * Apply Kilo Gateway provider configuration AND set Kilo Gateway as the default model. - * Use this when Kilo Gateway is the primary provider choice during onboarding. + * Use this when Kilo Gateway is the primary provider choice during setup. */ export function applyKilocodeConfig(cfg: OpenClawConfig): OpenClawConfig { const next = applyKilocodeProviderConfig(cfg); diff --git a/src/commands/onboard-auth.test.ts b/src/commands/onboard-auth.test.ts index 8742c2fe7fa..8c4b8e38bda 100644 --- a/src/commands/onboard-auth.test.ts +++ b/src/commands/onboard-auth.test.ts @@ -467,7 +467,7 @@ describe("applyZaiConfig", () => { it("adds zai provider with correct settings", () => { const cfg = applyZaiConfig({}); expect(cfg.models?.providers?.zai).toMatchObject({ - // Default: general (non-coding) endpoint. Coding Plan endpoint is detected during onboarding. + // Default: general (non-coding) endpoint. Coding Plan endpoint is detected during setup. baseUrl: ZAI_GLOBAL_BASE_URL, api: "openai-completions", }); diff --git a/src/commands/onboard-channels.e2e.test.ts b/src/commands/onboard-channels.e2e.test.ts index faf1e7cfb7e..7d64a4d120f 100644 --- a/src/commands/onboard-channels.e2e.test.ts +++ b/src/commands/onboard-channels.e2e.test.ts @@ -5,15 +5,15 @@ import { createEmptyPluginRegistry } from "../plugins/registry.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { - patchChannelSetupFlowAdapter, + ensureChannelSetupPluginInstalled, + loadChannelSetupPluginRegistrySnapshotForChannel, + reloadChannelSetupPluginRegistry, +} from "./channel-setup/plugin-install.js"; +import { + patchChannelSetupWizardAdapter, setDefaultChannelPluginRegistryForTests, } from "./channel-test-helpers.js"; import { setupChannels } from "./onboard-channels.js"; -import { - ensureOnboardingPluginInstalled, - loadOnboardingPluginRegistrySnapshotForChannel, - reloadOnboardingPluginRegistry, -} from "./onboarding/plugin-install.js"; import { createExitThrowingRuntime, createWizardPrompter } from "./test-wizard-helpers.js"; const catalogMocks = vi.hoisted(() => ({ @@ -96,8 +96,8 @@ function createTelegramCfg(botToken: string, enabled?: boolean): OpenClawConfig } as OpenClawConfig; } -function patchTelegramAdapter(overrides: Parameters[1]) { - return patchChannelSetupFlowAdapter("telegram", { +function patchTelegramAdapter(overrides: Parameters[1]) { + return patchChannelSetupWizardAdapter("telegram", { ...overrides, getStatus: overrides.getStatus ?? @@ -214,17 +214,17 @@ vi.mock("./onboard-helpers.js", () => ({ detectBinary: vi.fn(async () => false), })); -vi.mock("./onboarding/plugin-install.js", async (importOriginal) => { +vi.mock("./channel-setup/plugin-install.js", async (importOriginal) => { const actual = await importOriginal(); return { ...(actual as Record), - ensureOnboardingPluginInstalled: vi.fn(async ({ cfg }: { cfg: OpenClawConfig }) => ({ + ensureChannelSetupPluginInstalled: vi.fn(async ({ cfg }: { cfg: OpenClawConfig }) => ({ cfg, installed: true, })), - // Allow tests to simulate an empty plugin registry during onboarding. - loadOnboardingPluginRegistrySnapshotForChannel: vi.fn(() => createEmptyPluginRegistry()), - reloadOnboardingPluginRegistry: vi.fn(() => {}), + // Allow tests to simulate an empty plugin registry during setup. + loadChannelSetupPluginRegistrySnapshotForChannel: vi.fn(() => createEmptyPluginRegistry()), + reloadChannelSetupPluginRegistry: vi.fn(() => {}), }; }); @@ -237,13 +237,13 @@ describe("setupChannels", () => { plugins: [], diagnostics: [], }); - vi.mocked(ensureOnboardingPluginInstalled).mockClear(); - vi.mocked(ensureOnboardingPluginInstalled).mockImplementation(async ({ cfg }) => ({ + vi.mocked(ensureChannelSetupPluginInstalled).mockClear(); + vi.mocked(ensureChannelSetupPluginInstalled).mockImplementation(async ({ cfg }) => ({ cfg, installed: true, })); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockClear(); - vi.mocked(reloadOnboardingPluginRegistry).mockClear(); + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockClear(); + vi.mocked(reloadChannelSetupPluginRegistry).mockClear(); }); it("QuickStart uses single-select (no multiselect) and doesn't prompt for Telegram token when WhatsApp is chosen", async () => { const select = vi.fn(async () => "whatsapp"); @@ -311,8 +311,8 @@ describe("setupChannels", () => { ); }); expect(sawHardStop).toBe(false); - expect(loadOnboardingPluginRegistrySnapshotForChannel).not.toHaveBeenCalled(); - expect(reloadOnboardingPluginRegistry).not.toHaveBeenCalled(); + expect(loadChannelSetupPluginRegistrySnapshotForChannel).not.toHaveBeenCalled(); + expect(reloadChannelSetupPluginRegistry).not.toHaveBeenCalled(); }); it("shows explicit dmScope config command in channel primer", async () => { @@ -356,7 +356,7 @@ describe("setupChannels", () => { }, } satisfies ChannelPluginCatalogEntry, ]); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockImplementation( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockImplementation( ({ channel }: { channel: string }) => { const registry = createEmptyPluginRegistry(); if (channel === "msteams") { @@ -418,7 +418,7 @@ describe("setupChannels", () => { prompter, ); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams", pluginId: "@openclaw/msteams-plugin", @@ -454,7 +454,7 @@ describe("setupChannels", () => { ], diagnostics: [], }); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockImplementation( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockImplementation( ({ channel }: { channel: string }) => { const registry = createEmptyPluginRegistry(); if (channel === "msteams") { @@ -511,8 +511,8 @@ describe("setupChannels", () => { await runSetupChannels({} as OpenClawConfig, prompter); - expect(ensureOnboardingPluginInstalled).not.toHaveBeenCalled(); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(ensureChannelSetupPluginInstalled).not.toHaveBeenCalled(); + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams", pluginId: "@openclaw/msteams-plugin", @@ -556,7 +556,7 @@ describe("setupChannels", () => { }, }), ); - vi.mocked(loadOnboardingPluginRegistrySnapshotForChannel).mockImplementation( + vi.mocked(loadChannelSetupPluginRegistrySnapshotForChannel).mockImplementation( ({ channel }: { channel: string }) => { const registry = createEmptyPluginRegistry(); if (channel === "msteams") { @@ -653,7 +653,7 @@ describe("setupChannels", () => { { allowDisable: true }, ); - expect(loadOnboardingPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( + expect(loadChannelSetupPluginRegistrySnapshotForChannel).toHaveBeenCalledWith( expect.objectContaining({ channel: "msteams" }), ); expect(setAccountEnabled).toHaveBeenCalledWith( diff --git a/src/commands/onboard-channels.ts b/src/commands/onboard-channels.ts index 564e056b053..569e4cd4a44 100644 --- a/src/commands/onboard-channels.ts +++ b/src/commands/onboard-channels.ts @@ -1,11 +1,11 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js"; import { listChannelPluginCatalogEntries } from "../channels/plugins/catalog.js"; import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; -import type { ChannelSetupPlugin } from "../channels/plugins/setup-flow-types.js"; import { getChannelSetupPlugin, listChannelSetupPlugins, } from "../channels/plugins/setup-registry.js"; +import type { ChannelSetupPlugin } from "../channels/plugins/setup-wizard-types.js"; import { formatChannelPrimerLine, formatChannelSelectionLine, @@ -21,9 +21,13 @@ import type { RuntimeEnv } from "../runtime.js"; import { formatDocsLink } from "../terminal/links.js"; import type { WizardPrompter, WizardSelectOption } from "../wizard/prompts.js"; import { resolveChannelSetupEntries } from "./channel-setup/discovery.js"; -import { resolveChannelSetupFlowAdapterForPlugin } from "./channel-setup/registry.js"; +import { + ensureChannelSetupPluginInstalled, + loadChannelSetupPluginRegistrySnapshotForChannel, +} from "./channel-setup/plugin-install.js"; +import { resolveChannelSetupWizardAdapterForPlugin } from "./channel-setup/registry.js"; import type { - ChannelSetupFlowAdapter, + ChannelSetupWizardAdapter, ChannelSetupConfiguredResult, ChannelSetupDmPolicy, ChannelSetupResult, @@ -31,10 +35,6 @@ import type { SetupChannelsOptions, } from "./channel-setup/types.js"; import type { ChannelChoice } from "./onboard-types.js"; -import { - ensureOnboardingPluginInstalled, - loadOnboardingPluginRegistrySnapshotForChannel, -} from "./onboarding/plugin-install.js"; type ConfiguredChannelAction = "update" | "disable" | "delete" | "skip"; @@ -119,7 +119,7 @@ async function collectChannelStatus(params: { options?: SetupChannelsOptions; accountOverrides: Partial>; installedPlugins?: ChannelSetupPlugin[]; - resolveAdapter?: (channel: ChannelChoice) => ChannelSetupFlowAdapter | undefined; + resolveAdapter?: (channel: ChannelChoice) => ChannelSetupWizardAdapter | undefined; }): Promise { const installedPlugins = params.installedPlugins ?? listChannelSetupPlugins(); const workspaceDir = resolveAgentWorkspaceDir(params.cfg, resolveDefaultAgentId(params.cfg)); @@ -131,7 +131,7 @@ async function collectChannelStatus(params: { const resolveAdapter = params.resolveAdapter ?? ((channel: ChannelChoice) => - resolveChannelSetupFlowAdapterForPlugin( + resolveChannelSetupWizardAdapterForPlugin( installedPlugins.find((plugin) => plugin.id === channel), )); const statusEntries = await Promise.all( @@ -271,7 +271,7 @@ async function maybeConfigureDmPolicies(params: { selection: ChannelChoice[]; prompter: WizardPrompter; accountIdsByChannel?: Map; - resolveAdapter?: (channel: ChannelChoice) => ChannelSetupFlowAdapter | undefined; + resolveAdapter?: (channel: ChannelChoice) => ChannelSetupWizardAdapter | undefined; }): Promise { const { selection, prompter, accountIdsByChannel } = params; const resolve = params.resolveAdapter ?? (() => undefined); @@ -374,7 +374,7 @@ export async function setupChannels( if (existing) { return existing; } - const snapshot = loadOnboardingPluginRegistrySnapshotForChannel({ + const snapshot = loadChannelSetupPluginRegistrySnapshotForChannel({ cfg: next, runtime, channel, @@ -393,9 +393,9 @@ export async function setupChannels( const getVisibleSetupFlowAdapter = (channel: ChannelChoice) => { const scopedPlugin = scopedPluginsById.get(channel); if (scopedPlugin) { - return resolveChannelSetupFlowAdapterForPlugin(scopedPlugin); + return resolveChannelSetupWizardAdapterForPlugin(scopedPlugin); } - return resolveChannelSetupFlowAdapterForPlugin(getChannelSetupPlugin(channel)); + return resolveChannelSetupWizardAdapterForPlugin(getChannelSetupPlugin(channel)); }; const preloadConfiguredExternalPlugins = () => { // Keep setup memory bounded by snapshot-loading only configured external plugins. @@ -735,7 +735,7 @@ export async function setupChannels( const installedCatalogEntry = installedCatalogById.get(channel); if (catalogEntry) { const workspaceDir = resolveWorkspaceDir(); - const result = await ensureOnboardingPluginInstalled({ + const result = await ensureChannelSetupPluginInstalled({ cfg: next, entry: catalogEntry, prompter, diff --git a/src/commands/onboard-config.test.ts b/src/commands/onboard-config.test.ts index c5997345fe7..e10b6ef4011 100644 --- a/src/commands/onboard-config.test.ts +++ b/src/commands/onboard-config.test.ts @@ -1,19 +1,19 @@ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import { - applyOnboardingLocalWorkspaceConfig, + applyLocalSetupWorkspaceConfig, ONBOARDING_DEFAULT_DM_SCOPE, ONBOARDING_DEFAULT_TOOLS_PROFILE, } from "./onboard-config.js"; -describe("applyOnboardingLocalWorkspaceConfig", () => { +describe("applyLocalSetupWorkspaceConfig", () => { it("defaults local onboarding tool profile to coding", () => { expect(ONBOARDING_DEFAULT_TOOLS_PROFILE).toBe("coding"); }); it("sets secure dmScope default when unset", () => { const baseConfig: OpenClawConfig = {}; - const result = applyOnboardingLocalWorkspaceConfig(baseConfig, "/tmp/workspace"); + const result = applyLocalSetupWorkspaceConfig(baseConfig, "/tmp/workspace"); expect(result.session?.dmScope).toBe(ONBOARDING_DEFAULT_DM_SCOPE); expect(result.gateway?.mode).toBe("local"); @@ -27,7 +27,7 @@ describe("applyOnboardingLocalWorkspaceConfig", () => { dmScope: "main", }, }; - const result = applyOnboardingLocalWorkspaceConfig(baseConfig, "/tmp/workspace"); + const result = applyLocalSetupWorkspaceConfig(baseConfig, "/tmp/workspace"); expect(result.session?.dmScope).toBe("main"); }); @@ -38,7 +38,7 @@ describe("applyOnboardingLocalWorkspaceConfig", () => { dmScope: "per-account-channel-peer", }, }; - const result = applyOnboardingLocalWorkspaceConfig(baseConfig, "/tmp/workspace"); + const result = applyLocalSetupWorkspaceConfig(baseConfig, "/tmp/workspace"); expect(result.session?.dmScope).toBe("per-account-channel-peer"); }); @@ -49,7 +49,7 @@ describe("applyOnboardingLocalWorkspaceConfig", () => { profile: "full", }, }; - const result = applyOnboardingLocalWorkspaceConfig(baseConfig, "/tmp/workspace"); + const result = applyLocalSetupWorkspaceConfig(baseConfig, "/tmp/workspace"); expect(result.tools?.profile).toBe("full"); }); diff --git a/src/commands/onboard-config.ts b/src/commands/onboard-config.ts index 62b1006283e..73e0cd5ceca 100644 --- a/src/commands/onboard-config.ts +++ b/src/commands/onboard-config.ts @@ -5,7 +5,7 @@ import type { ToolProfileId } from "../config/types.tools.js"; export const ONBOARDING_DEFAULT_DM_SCOPE: DmScope = "per-channel-peer"; export const ONBOARDING_DEFAULT_TOOLS_PROFILE: ToolProfileId = "coding"; -export function applyOnboardingLocalWorkspaceConfig( +export function applyLocalSetupWorkspaceConfig( baseConfig: OpenClawConfig, workspaceDir: string, ): OpenClawConfig { diff --git a/src/commands/onboard-hooks.ts b/src/commands/onboard-hooks.ts index b2086161511..7286673ce29 100644 --- a/src/commands/onboard-hooks.ts +++ b/src/commands/onboard-hooks.ts @@ -24,7 +24,7 @@ export async function setupInternalHooks( const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)); const report = buildWorkspaceHookStatus(workspaceDir, { config: cfg }); - // Show every eligible hook so users can opt in during onboarding. + // Show every eligible hook so users can opt in during setup. const eligibleHooks = report.hooks.filter((h) => h.eligible); if (eligibleHooks.length === 0) { diff --git a/src/commands/onboard-interactive.test.ts b/src/commands/onboard-interactive.test.ts index 4dd8d9b4ddc..ba3a9227fe6 100644 --- a/src/commands/onboard-interactive.test.ts +++ b/src/commands/onboard-interactive.test.ts @@ -1,11 +1,11 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import type { RuntimeEnv } from "../runtime.js"; import { WizardCancelledError } from "../wizard/prompts.js"; -import { runInteractiveOnboarding } from "./onboard-interactive.js"; +import { runInteractiveSetup } from "./onboard-interactive.js"; const mocks = vi.hoisted(() => ({ createClackPrompter: vi.fn(() => ({ id: "prompter" })), - runOnboardingWizard: vi.fn(async () => {}), + runSetupWizard: vi.fn(async () => {}), restoreTerminalState: vi.fn(), })); @@ -13,8 +13,8 @@ vi.mock("../wizard/clack-prompter.js", () => ({ createClackPrompter: mocks.createClackPrompter, })); -vi.mock("../wizard/onboarding.js", () => ({ - runOnboardingWizard: mocks.runOnboardingWizard, +vi.mock("../wizard/setup.js", () => ({ + runSetupWizard: mocks.runSetupWizard, })); vi.mock("../terminal/restore.js", () => ({ @@ -29,7 +29,7 @@ function makeRuntime(): RuntimeEnv { }; } -describe("runInteractiveOnboarding", () => { +describe("runInteractiveSetup", () => { afterEach(() => { vi.clearAllMocks(); }); @@ -37,10 +37,10 @@ describe("runInteractiveOnboarding", () => { it("restores terminal state without resuming stdin on success", async () => { const runtime = makeRuntime(); - await runInteractiveOnboarding({} as never, runtime); + await runInteractiveSetup({} as never, runtime); - expect(mocks.runOnboardingWizard).toHaveBeenCalledOnce(); - expect(mocks.restoreTerminalState).toHaveBeenCalledWith("onboarding finish", { + expect(mocks.runSetupWizard).toHaveBeenCalledOnce(); + expect(mocks.restoreTerminalState).toHaveBeenCalledWith("setup finish", { resumeStdinIfPaused: false, }); }); @@ -54,12 +54,12 @@ describe("runInteractiveOnboarding", () => { throw exitError; }) as unknown as RuntimeEnv["exit"], }; - mocks.runOnboardingWizard.mockRejectedValueOnce(new WizardCancelledError("cancelled")); + mocks.runSetupWizard.mockRejectedValueOnce(new WizardCancelledError("cancelled")); - await expect(runInteractiveOnboarding({} as never, runtime)).rejects.toBe(exitError); + await expect(runInteractiveSetup({} as never, runtime)).rejects.toBe(exitError); expect(runtime.exit).toHaveBeenCalledWith(1); - expect(mocks.restoreTerminalState).toHaveBeenCalledWith("onboarding finish", { + expect(mocks.restoreTerminalState).toHaveBeenCalledWith("setup finish", { resumeStdinIfPaused: false, }); const restoreOrder = @@ -73,12 +73,12 @@ describe("runInteractiveOnboarding", () => { it("rethrows non-cancel errors after restoring terminal state", async () => { const runtime = makeRuntime(); const err = new Error("boom"); - mocks.runOnboardingWizard.mockRejectedValueOnce(err); + mocks.runSetupWizard.mockRejectedValueOnce(err); - await expect(runInteractiveOnboarding({} as never, runtime)).rejects.toThrow("boom"); + await expect(runInteractiveSetup({} as never, runtime)).rejects.toThrow("boom"); expect(runtime.exit).not.toHaveBeenCalled(); - expect(mocks.restoreTerminalState).toHaveBeenCalledWith("onboarding finish", { + expect(mocks.restoreTerminalState).toHaveBeenCalledWith("setup finish", { resumeStdinIfPaused: false, }); }); diff --git a/src/commands/onboard-interactive.ts b/src/commands/onboard-interactive.ts index 670c0fa02de..f271764e5de 100644 --- a/src/commands/onboard-interactive.ts +++ b/src/commands/onboard-interactive.ts @@ -2,18 +2,18 @@ import type { RuntimeEnv } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; import { restoreTerminalState } from "../terminal/restore.js"; import { createClackPrompter } from "../wizard/clack-prompter.js"; -import { runOnboardingWizard } from "../wizard/onboarding.js"; import { WizardCancelledError } from "../wizard/prompts.js"; +import { runSetupWizard } from "../wizard/setup.js"; import type { OnboardOptions } from "./onboard-types.js"; -export async function runInteractiveOnboarding( +export async function runInteractiveSetup( opts: OnboardOptions, runtime: RuntimeEnv = defaultRuntime, ) { const prompter = createClackPrompter(); let exitCode: number | null = null; try { - await runOnboardingWizard(opts, runtime, prompter); + await runSetupWizard(opts, runtime, prompter); } catch (err) { if (err instanceof WizardCancelledError) { // Best practice: cancellation is not a successful completion. @@ -23,7 +23,7 @@ export async function runInteractiveOnboarding( throw err; } finally { // Keep stdin paused so non-daemon runs can exit cleanly (e.g. Docker setup). - restoreTerminalState("onboarding finish", { resumeStdinIfPaused: false }); + restoreTerminalState("setup finish", { resumeStdinIfPaused: false }); if (exitCode !== null) { runtime.exit(exitCode); } diff --git a/src/commands/onboard-non-interactive.gateway.test.ts b/src/commands/onboard-non-interactive.gateway.test.ts index 83a81f340b3..3ea1bf159ca 100644 --- a/src/commands/onboard-non-interactive.gateway.test.ts +++ b/src/commands/onboard-non-interactive.gateway.test.ts @@ -90,7 +90,7 @@ vi.mock("../daemon/diagnostics.js", () => ({ readLastGatewayErrorLine: readLastGatewayErrorLineMock, })); -const { runNonInteractiveOnboarding } = await import("./onboard-non-interactive.js"); +const { runNonInteractiveSetup } = await import("./onboard-non-interactive.js"); const { resolveConfigPath: resolveStateConfigPath } = await import("../config/paths.js"); const { resolveConfigPath } = await import("../config/config.js"); const { callGateway } = await import("../gateway/call.js"); @@ -170,7 +170,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { const token = "tok_test_123"; const workspace = path.join(stateDir, "openclaw"); - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -208,7 +208,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { process.env.OPENCLAW_GATEWAY_TOKEN = envToken; try { - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -248,7 +248,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { process.env.OPENCLAW_GATEWAY_TOKEN = envToken; try { - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -292,7 +292,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { delete process.env.MISSING_GATEWAY_TOKEN_ENV; try { await expect( - runNonInteractiveOnboarding( + runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -322,7 +322,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { await withStateDir("state-remote-", async () => { const port = getPseudoPort(30_000); const token = "tok_remote_123"; - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "remote", @@ -359,7 +359,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { })); await expect( - runNonInteractiveOnboarding( + runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -386,7 +386,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { return { ok: true }; }); - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -438,7 +438,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { try { await expect( - runNonInteractiveOnboarding( + runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -509,7 +509,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { }; await expect( - runNonInteractiveOnboarding( + runNonInteractiveSetup( { nonInteractive: true, mode: "local", @@ -568,7 +568,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { const port = getPseudoPort(40_000); const workspace = path.join(stateDir, "openclaw"); - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { nonInteractive: true, mode: "local", diff --git a/src/commands/onboard-non-interactive.provider-auth.test.ts b/src/commands/onboard-non-interactive.provider-auth.test.ts index 5ee3077d1c5..10de2ecbcb6 100644 --- a/src/commands/onboard-non-interactive.provider-auth.test.ts +++ b/src/commands/onboard-non-interactive.provider-auth.test.ts @@ -33,7 +33,7 @@ vi.mock("./zai-endpoint-detect.js", () => ({ detectZaiEndpoint, })); -const { runNonInteractiveOnboarding } = await import("./onboard-non-interactive.js"); +const { runNonInteractiveSetup } = await import("./onboard-non-interactive.js"); const NON_INTERACTIVE_DEFAULT_OPTIONS = { nonInteractive: true, @@ -109,11 +109,11 @@ async function withOnboardEnv( } } -async function runNonInteractiveOnboardingWithDefaults( +async function runNonInteractiveSetupWithDefaults( runtime: NonInteractiveRuntime, options: Record, ): Promise { - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { ...NON_INTERACTIVE_DEFAULT_OPTIONS, ...options, @@ -126,7 +126,7 @@ async function runOnboardingAndReadConfig( env: OnboardEnv, options: Record, ): Promise { - await runNonInteractiveOnboardingWithDefaults(env.runtime, { + await runNonInteractiveSetupWithDefaults(env.runtime, { skipSkills: true, ...options, }); @@ -141,7 +141,7 @@ async function runCustomLocalNonInteractive( runtime: NonInteractiveRuntime, overrides: Record = {}, ): Promise { - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { authChoice: "custom-api-key", customBaseUrl: CUSTOM_LOCAL_BASE_URL, customModelId: CUSTOM_LOCAL_MODEL_ID, @@ -366,7 +366,7 @@ describe("onboard (non-interactive): provider auth", () => { const cleanToken = `sk-ant-oat01-${"a".repeat(80)}`; const token = `${cleanToken.slice(0, 30)}\r${cleanToken.slice(30)}`; - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { authChoice: "token", tokenProvider: "anthropic", token, @@ -466,7 +466,7 @@ describe("onboard (non-interactive): provider auth", () => { await withEnvAsync(envOverrides, async () => { let thrown: Error | undefined; try { - await runNonInteractiveOnboardingWithDefaults(runtime, options); + await runNonInteractiveSetupWithDefaults(runtime, options); } catch (error) { thrown = error as Error; } @@ -492,7 +492,7 @@ describe("onboard (non-interactive): provider auth", () => { OPENCODE_ZEN_API_KEY: "opencode-zen-env-key", // pragma: allowlist secret }, async () => { - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { authChoice: "opencode-zen", secretInputMode: "ref", // pragma: allowlist secret skipSkills: true, @@ -609,7 +609,7 @@ describe("onboard (non-interactive): provider auth", () => { }, ])("$name", async ({ prefix, options }) => { await withOnboardEnv(prefix, async ({ configPath, runtime }) => { - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { cloudflareAiGatewayAccountId: "cf-account-id", cloudflareAiGatewayGatewayId: "cf-gateway-id", cloudflareAiGatewayApiKey: "cf-gateway-test-key", // pragma: allowlist secret @@ -689,7 +689,7 @@ describe("onboard (non-interactive): provider auth", () => { it("configures a custom provider from non-interactive flags", async () => { await withOnboardEnv("openclaw-onboard-custom-provider-", async ({ configPath, runtime }) => { - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { authChoice: "custom-api-key", customBaseUrl: "https://llm.example.com/v1", customApiKey: "custom-test-key", // pragma: allowlist secret @@ -713,7 +713,7 @@ describe("onboard (non-interactive): provider auth", () => { await withOnboardEnv( "openclaw-onboard-custom-provider-infer-", async ({ configPath, runtime }) => { - await runNonInteractiveOnboardingWithDefaults(runtime, { + await runNonInteractiveSetupWithDefaults(runtime, { customBaseUrl: "https://models.custom.local/v1", customModelId: "local-large", customApiKey: "custom-test-key", // pragma: allowlist secret @@ -810,7 +810,7 @@ describe("onboard (non-interactive): provider auth", () => { "openclaw-onboard-custom-provider-invalid-compat-", async ({ runtime }) => { await expect( - runNonInteractiveOnboardingWithDefaults(runtime, { + runNonInteractiveSetupWithDefaults(runtime, { authChoice: "custom-api-key", customBaseUrl: "https://models.custom.local/v1", customModelId: "local-large", @@ -825,7 +825,7 @@ describe("onboard (non-interactive): provider auth", () => { it("fails custom provider auth when explicit provider id is invalid", async () => { await withOnboardEnv("openclaw-onboard-custom-provider-invalid-id-", async ({ runtime }) => { await expect( - runNonInteractiveOnboardingWithDefaults(runtime, { + runNonInteractiveSetupWithDefaults(runtime, { authChoice: "custom-api-key", customBaseUrl: "https://models.custom.local/v1", customModelId: "local-large", @@ -843,7 +843,7 @@ describe("onboard (non-interactive): provider auth", () => { "openclaw-onboard-custom-provider-missing-required-", async ({ runtime }) => { await expect( - runNonInteractiveOnboardingWithDefaults(runtime, { + runNonInteractiveSetupWithDefaults(runtime, { customApiKey: "custom-test-key", // pragma: allowlist secret skipSkills: true, }), diff --git a/src/commands/onboard-non-interactive.test-helpers.ts b/src/commands/onboard-non-interactive.test-helpers.ts index 6fb5aa24e33..acb2a6d48d5 100644 --- a/src/commands/onboard-non-interactive.test-helpers.ts +++ b/src/commands/onboard-non-interactive.test-helpers.ts @@ -28,19 +28,19 @@ export function createThrowingRuntime(): NonInteractiveRuntime { }; } -export async function runNonInteractiveOnboarding( +export async function runNonInteractiveSetup( options: Record, runtime: NonInteractiveRuntime, ): Promise { - const { runNonInteractiveOnboarding: run } = await import("./onboard-non-interactive.js"); + const { runNonInteractiveSetup: run } = await import("./onboard-non-interactive.js"); await run(options, runtime); } -export async function runNonInteractiveOnboardingWithDefaults( +export async function runNonInteractiveSetupWithDefaults( runtime: NonInteractiveRuntime, options: Record, ): Promise { - await runNonInteractiveOnboarding( + await runNonInteractiveSetup( { ...NON_INTERACTIVE_DEFAULT_OPTIONS, ...options, diff --git a/src/commands/onboard-non-interactive.ts b/src/commands/onboard-non-interactive.ts index ee2b3498180..7d9fbe7c1af 100644 --- a/src/commands/onboard-non-interactive.ts +++ b/src/commands/onboard-non-interactive.ts @@ -3,18 +3,18 @@ import type { OpenClawConfig } from "../config/config.js"; import { readConfigFileSnapshot } from "../config/config.js"; import type { RuntimeEnv } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; -import { runNonInteractiveOnboardingLocal } from "./onboard-non-interactive/local.js"; -import { runNonInteractiveOnboardingRemote } from "./onboard-non-interactive/remote.js"; +import { runNonInteractiveLocalSetup } from "./onboard-non-interactive/local.js"; +import { runNonInteractiveRemoteSetup } from "./onboard-non-interactive/remote.js"; import type { OnboardOptions } from "./onboard-types.js"; -export async function runNonInteractiveOnboarding( +export async function runNonInteractiveSetup( opts: OnboardOptions, runtime: RuntimeEnv = defaultRuntime, ) { const snapshot = await readConfigFileSnapshot(); if (snapshot.exists && !snapshot.valid) { runtime.error( - `Config invalid. Run \`${formatCliCommand("openclaw doctor")}\` to repair it, then re-run onboarding.`, + `Config invalid. Run \`${formatCliCommand("openclaw doctor")}\` to repair it, then re-run setup.`, ); runtime.exit(1); return; @@ -29,9 +29,9 @@ export async function runNonInteractiveOnboarding( } if (mode === "remote") { - await runNonInteractiveOnboardingRemote({ opts, runtime, baseConfig }); + await runNonInteractiveRemoteSetup({ opts, runtime, baseConfig }); return; } - await runNonInteractiveOnboardingLocal({ opts, runtime, baseConfig }); + await runNonInteractiveLocalSetup({ opts, runtime, baseConfig }); } diff --git a/src/commands/onboard-non-interactive/local.ts b/src/commands/onboard-non-interactive/local.ts index 5e26bf50d24..b5ab9b5cb7b 100644 --- a/src/commands/onboard-non-interactive/local.ts +++ b/src/commands/onboard-non-interactive/local.ts @@ -4,7 +4,7 @@ import { resolveGatewayPort, writeConfigFile } from "../../config/config.js"; import { logConfigUpdated } from "../../config/logging.js"; import type { RuntimeEnv } from "../../runtime.js"; import { DEFAULT_GATEWAY_DAEMON_RUNTIME } from "../daemon-runtime.js"; -import { applyOnboardingLocalWorkspaceConfig } from "../onboard-config.js"; +import { applyLocalSetupWorkspaceConfig } from "../onboard-config.js"; import { applyWizardMetadata, DEFAULT_WORKSPACE, @@ -67,7 +67,7 @@ async function collectGatewayHealthFailureDiagnostics(): Promise< : undefined; } -export async function runNonInteractiveOnboardingLocal(params: { +export async function runNonInteractiveLocalSetup(params: { opts: OnboardOptions; runtime: RuntimeEnv; baseConfig: OpenClawConfig; @@ -81,13 +81,13 @@ export async function runNonInteractiveOnboardingLocal(params: { defaultWorkspaceDir: DEFAULT_WORKSPACE, }); - let nextConfig: OpenClawConfig = applyOnboardingLocalWorkspaceConfig(baseConfig, workspaceDir); + let nextConfig: OpenClawConfig = applyLocalSetupWorkspaceConfig(baseConfig, workspaceDir); const inferredAuthChoice = inferAuthChoiceFromFlags(opts); if (!opts.authChoice && inferredAuthChoice.matches.length > 1) { runtime.error( [ - "Multiple API key flags were provided for non-interactive onboarding.", + "Multiple API key flags were provided for non-interactive setup.", "Use a single provider flag or pass --auth-choice explicitly.", `Flags: ${inferredAuthChoice.matches.map((match) => match.label).join(", ")}`, ].join("\n"), diff --git a/src/commands/onboard-non-interactive/remote.ts b/src/commands/onboard-non-interactive/remote.ts index fa38cb9c43f..f58488b89e5 100644 --- a/src/commands/onboard-non-interactive/remote.ts +++ b/src/commands/onboard-non-interactive/remote.ts @@ -6,7 +6,7 @@ import type { RuntimeEnv } from "../../runtime.js"; import { applyWizardMetadata } from "../onboard-helpers.js"; import type { OnboardOptions } from "../onboard-types.js"; -export async function runNonInteractiveOnboardingRemote(params: { +export async function runNonInteractiveRemoteSetup(params: { opts: OnboardOptions; runtime: RuntimeEnv; baseConfig: OpenClawConfig; diff --git a/src/commands/onboard-remote.ts b/src/commands/onboard-remote.ts index 665d3ad3d26..2f213df4853 100644 --- a/src/commands/onboard-remote.ts +++ b/src/commands/onboard-remote.ts @@ -6,7 +6,7 @@ import { discoverGatewayBeacons } from "../infra/bonjour-discovery.js"; import { resolveWideAreaDiscoveryDomain } from "../infra/widearea-dns.js"; import type { WizardPrompter } from "../wizard/prompts.js"; import { - promptSecretRefForOnboarding, + promptSecretRefForSetup, resolveSecretInputModeForEnvSelection, } from "./auth-choice.apply-helpers.js"; import { detectBinary } from "./onboard-helpers.js"; @@ -175,7 +175,7 @@ export async function promptRemoteGatewayConfig( }, }); if (selectedMode === "ref") { - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: "gateway-remote-token", config: cfg, prompter, @@ -207,7 +207,7 @@ export async function promptRemoteGatewayConfig( }, }); if (selectedMode === "ref") { - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: "gateway-remote-password", config: cfg, prompter, diff --git a/src/commands/onboard-types.ts b/src/commands/onboard-types.ts index f7a89a8b971..9d738298e52 100644 --- a/src/commands/onboard-types.ts +++ b/src/commands/onboard-types.ts @@ -98,7 +98,7 @@ export type OnboardOptions = { flow?: "quickstart" | "advanced" | "manual"; workspace?: string; nonInteractive?: boolean; - /** Required for non-interactive onboarding; skips the interactive risk prompt when true. */ + /** Required for non-interactive setup; skips the interactive risk prompt when true. */ acceptRisk?: boolean; reset?: boolean; resetScope?: ResetScope; @@ -111,7 +111,7 @@ export type OnboardOptions = { tokenProfileId?: string; /** Used when `authChoice=token` in non-interactive mode. */ tokenExpiresIn?: string; - /** API key persistence mode for onboarding flows (default: plaintext). */ + /** API key persistence mode for setup flows (default: plaintext). */ secretInputMode?: SecretInputMode; anthropicApiKey?: string; openaiApiKey?: string; diff --git a/src/commands/onboard.test.ts b/src/commands/onboard.test.ts index 5d1dc20634d..ca47a3e0980 100644 --- a/src/commands/onboard.test.ts +++ b/src/commands/onboard.test.ts @@ -3,18 +3,18 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import type { RuntimeEnv } from "../runtime.js"; const mocks = vi.hoisted(() => ({ - runInteractiveOnboarding: vi.fn(async () => {}), - runNonInteractiveOnboarding: vi.fn(async () => {}), + runInteractiveSetup: vi.fn(async () => {}), + runNonInteractiveSetup: vi.fn(async () => {}), readConfigFileSnapshot: vi.fn(async () => ({ exists: false, valid: false, config: {} })), handleReset: vi.fn(async () => {}), })); vi.mock("./onboard-interactive.js", () => ({ - runInteractiveOnboarding: mocks.runInteractiveOnboarding, + runInteractiveSetup: mocks.runInteractiveSetup, })); vi.mock("./onboard-non-interactive.js", () => ({ - runNonInteractiveOnboarding: mocks.runNonInteractiveOnboarding, + runNonInteractiveSetup: mocks.runNonInteractiveSetup, })); vi.mock("../config/config.js", () => ({ @@ -56,8 +56,8 @@ describe("onboardCommand", () => { 'Invalid --secret-input-mode. Use "plaintext" or "ref".', ); expect(runtime.exit).toHaveBeenCalledWith(1); - expect(mocks.runInteractiveOnboarding).not.toHaveBeenCalled(); - expect(mocks.runNonInteractiveOnboarding).not.toHaveBeenCalled(); + expect(mocks.runInteractiveSetup).not.toHaveBeenCalled(); + expect(mocks.runNonInteractiveSetup).not.toHaveBeenCalled(); }); it("logs ASCII-safe Windows guidance before onboarding", async () => { @@ -155,7 +155,7 @@ describe("onboardCommand", () => { ); expect(runtime.exit).toHaveBeenCalledWith(1); expect(mocks.handleReset).not.toHaveBeenCalled(); - expect(mocks.runInteractiveOnboarding).not.toHaveBeenCalled(); - expect(mocks.runNonInteractiveOnboarding).not.toHaveBeenCalled(); + expect(mocks.runInteractiveSetup).not.toHaveBeenCalled(); + expect(mocks.runNonInteractiveSetup).not.toHaveBeenCalled(); }); }); diff --git a/src/commands/onboard.ts b/src/commands/onboard.ts index 6762998f815..a2e32d4cef2 100644 --- a/src/commands/onboard.ts +++ b/src/commands/onboard.ts @@ -6,8 +6,8 @@ import { defaultRuntime } from "../runtime.js"; import { resolveUserPath } from "../utils.js"; import { isDeprecatedAuthChoice, normalizeLegacyOnboardAuthChoice } from "./auth-choice-legacy.js"; import { DEFAULT_WORKSPACE, handleReset } from "./onboard-helpers.js"; -import { runInteractiveOnboarding } from "./onboard-interactive.js"; -import { runNonInteractiveOnboarding } from "./onboard-non-interactive.js"; +import { runInteractiveSetup } from "./onboard-interactive.js"; +import { runNonInteractiveSetup } from "./onboard-non-interactive.js"; import type { OnboardOptions, ResetScope } from "./onboard-types.js"; const VALID_RESET_SCOPES = new Set(["config", "config+creds+sessions", "full"]); @@ -56,7 +56,7 @@ export async function onboardCommand(opts: OnboardOptions, runtime: RuntimeEnv = if (normalizedOpts.nonInteractive && normalizedOpts.acceptRisk !== true) { runtime.error( [ - "Non-interactive onboarding requires explicit risk acknowledgement.", + "Non-interactive setup requires explicit risk acknowledgement.", "Read: https://docs.openclaw.ai/security", `Re-run with: ${formatCliCommand("openclaw onboard --non-interactive --accept-risk ...")}`, ].join("\n"), @@ -86,11 +86,11 @@ export async function onboardCommand(opts: OnboardOptions, runtime: RuntimeEnv = } if (normalizedOpts.nonInteractive) { - await runNonInteractiveOnboarding(normalizedOpts, runtime); + await runNonInteractiveSetup(normalizedOpts, runtime); return; } - await runInteractiveOnboarding(normalizedOpts, runtime); + await runInteractiveSetup(normalizedOpts, runtime); } export type { OnboardOptions } from "./onboard-types.js"; diff --git a/src/commands/onboarding/__tests__/test-utils.ts b/src/commands/setup/__tests__/test-utils.ts similarity index 100% rename from src/commands/onboarding/__tests__/test-utils.ts rename to src/commands/setup/__tests__/test-utils.ts diff --git a/src/commands/status.scan.ts b/src/commands/status.scan.ts index 4ef90bf1da0..1cc556f2588 100644 --- a/src/commands/status.scan.ts +++ b/src/commands/status.scan.ts @@ -18,6 +18,7 @@ import { pickGatewaySelfPresence, resolveGatewayProbeAuthResolution, } from "./status.gateway-probe.js"; +import type { buildChannelsTable, collectChannelStatusIssues } from "./status.scan.runtime.js"; import { getStatusSummary } from "./status.summary.js"; import { getUpdateCheckResult } from "./status.update.js"; diff --git a/src/config/legacy.migrations.part-3.ts b/src/config/legacy.migrations.part-3.ts index 5035930dadb..be382e5bd8a 100644 --- a/src/config/legacy.migrations.part-3.ts +++ b/src/config/legacy.migrations.part-3.ts @@ -100,7 +100,7 @@ function mergeLegacyIntoDefaults(params: { export const LEGACY_CONFIG_MIGRATIONS_PART_3: LegacyConfigMigration[] = [ { // v2026.2.26 added a startup guard requiring gateway.controlUi.allowedOrigins (or the - // host-header fallback flag) for any non-loopback bind. The onboarding wizard was updated + // host-header fallback flag) for any non-loopback bind. The setup wizard was updated // to seed this for new installs, but existing bind=lan/bind=custom installs that upgrade // crash-loop immediately on next startup with no recovery path (issue #29385). // diff --git a/src/config/schema.help.ts b/src/config/schema.help.ts index e5d30070317..2b98bb76704 100644 --- a/src/config/schema.help.ts +++ b/src/config/schema.help.ts @@ -30,7 +30,7 @@ export const FIELD_HELP: Record = { "wizard.lastRunCommand": "Command invocation recorded for the latest wizard run to preserve execution context. Use this to reproduce onboarding steps when verifying setup regressions.", "wizard.lastRunMode": - 'Wizard execution mode recorded as "local" or "remote" for the most recent onboarding flow. Use this to understand whether setup targeted direct local runtime or remote gateway topology.', + 'Wizard execution mode recorded as "local" or "remote" for the most recent setup flow. Use this to understand whether setup targeted direct local runtime or remote gateway topology.', diagnostics: "Diagnostics controls for targeted tracing, telemetry export, and cache inspection during debugging. Keep baseline diagnostics minimal in production and enable deeper signals only when investigating issues.", "diagnostics.otel": diff --git a/src/gateway/server-methods/agents-mutate.test.ts b/src/gateway/server-methods/agents-mutate.test.ts index 1cd88825b8a..af16c82e6f5 100644 --- a/src/gateway/server-methods/agents-mutate.test.ts +++ b/src/gateway/server-methods/agents-mutate.test.ts @@ -172,7 +172,7 @@ function makeSymlinkStat(params?: { dev?: number; ino?: number }): import("node: } function mockWorkspaceStateRead(params: { - onboardingCompletedAt?: string; + setupCompletedAt?: string; errorCode?: string; rawContent?: string; }) { @@ -186,7 +186,7 @@ function mockWorkspaceStateRead(params: { return params.rawContent; } return JSON.stringify({ - onboardingCompletedAt: params.onboardingCompletedAt ?? "2026-02-15T14:00:00.000Z", + setupCompletedAt: params.setupCompletedAt ?? "2026-02-15T14:00:00.000Z", }); } throw createEnoentError(); @@ -513,7 +513,7 @@ describe("agents.files.list", () => { }); it("hides BOOTSTRAP.md when workspace onboarding is complete", async () => { - mockWorkspaceStateRead({ onboardingCompletedAt: "2026-02-15T14:00:00.000Z" }); + mockWorkspaceStateRead({ setupCompletedAt: "2026-02-15T14:00:00.000Z" }); const names = await listAgentFileNames(); expect(names).not.toContain("BOOTSTRAP.md"); diff --git a/src/gateway/server-methods/agents.ts b/src/gateway/server-methods/agents.ts index b9de9b797aa..73d640b2756 100644 --- a/src/gateway/server-methods/agents.ts +++ b/src/gateway/server-methods/agents.ts @@ -16,7 +16,7 @@ import { DEFAULT_TOOLS_FILENAME, DEFAULT_USER_FILENAME, ensureAgentWorkspace, - isWorkspaceOnboardingCompleted, + isWorkspaceSetupCompleted, } from "../../agents/workspace.js"; import { movePathToTrash } from "../../browser/trash.js"; import { @@ -653,7 +653,7 @@ export const agentsHandlers: GatewayRequestHandlers = { const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId); let hideBootstrap = false; try { - hideBootstrap = await isWorkspaceOnboardingCompleted(workspaceDir); + hideBootstrap = await isWorkspaceSetupCompleted(workspaceDir); } catch { // Fall back to showing BOOTSTRAP if workspace state cannot be read. } diff --git a/src/gateway/server.impl.ts b/src/gateway/server.impl.ts index 5453ff8fcee..0bd13ddc4b9 100644 --- a/src/gateway/server.impl.ts +++ b/src/gateway/server.impl.ts @@ -63,7 +63,7 @@ import { prepareSecretsRuntimeSnapshot, resolveCommandSecretsFromActiveRuntimeSnapshot, } from "../secrets/runtime.js"; -import { runOnboardingWizard } from "../wizard/onboarding.js"; +import { runSetupWizard } from "../wizard/setup.js"; import { createAuthRateLimiter, type AuthRateLimiter } from "./auth-rate-limit.js"; import { startChannelHealthMonitor } from "./channel-health-monitor.js"; import { startGatewayConfigReloader } from "./config-reload.js"; @@ -255,7 +255,7 @@ export type GatewayServerOptions = { */ allowCanvasHostInTests?: boolean; /** - * Test-only: override the onboarding wizard runner. + * Test-only: override the setup wizard runner. */ wizardRunner?: ( opts: import("../commands/onboard-types.js").OnboardOptions, @@ -561,7 +561,7 @@ export async function startGatewayServer( : { kind: "missing" }; } - const wizardRunner = opts.wizardRunner ?? runOnboardingWizard; + const wizardRunner = opts.wizardRunner ?? runSetupWizard; const { wizardSessions, findRunningWizard, purgeWizardSession } = createWizardSessionTracker(); const deps = createDefaultDeps(); diff --git a/src/hooks/bundled/session-memory/HOOK.md b/src/hooks/bundled/session-memory/HOOK.md index 6969fb2b8be..c963e17b76c 100644 --- a/src/hooks/bundled/session-memory/HOOK.md +++ b/src/hooks/bundled/session-memory/HOOK.md @@ -51,7 +51,7 @@ The LLM generates descriptive slugs based on your conversation: ## Requirements -- **Config**: `workspace.dir` must be set (automatically configured during onboarding) +- **Config**: `workspace.dir` must be set (automatically configured during setup) The hook uses your configured LLM provider to generate slugs, so it works with any provider (Anthropic, OpenAI, etc.). diff --git a/src/plugin-sdk/bluebubbles.ts b/src/plugin-sdk/bluebubbles.ts index 3c8fc8c194c..6375bdea76c 100644 --- a/src/plugin-sdk/bluebubbles.ts +++ b/src/plugin-sdk/bluebubbles.ts @@ -35,7 +35,7 @@ export { addWildcardAllowFrom, mergeAllowFromEntries, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { applyAccountNameToChannelSection, diff --git a/src/plugin-sdk/feishu.ts b/src/plugin-sdk/feishu.ts index 03c48b7e414..4a6d8dc6251 100644 --- a/src/plugin-sdk/feishu.ts +++ b/src/plugin-sdk/feishu.ts @@ -22,7 +22,7 @@ export { setTopLevelChannelDmPolicyWithAllowFrom, setTopLevelChannelGroupPolicy, splitSetupEntries, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export type { BaseProbeResult, diff --git a/src/plugin-sdk/googlechat.ts b/src/plugin-sdk/googlechat.ts index 130b3d2fc14..c02cf8fe20a 100644 --- a/src/plugin-sdk/googlechat.ts +++ b/src/plugin-sdk/googlechat.ts @@ -29,7 +29,7 @@ export { mergeAllowFromEntries, splitSetupEntries, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { applyAccountNameToChannelSection, diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index 6ad093eec91..35a060f4db6 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -232,7 +232,7 @@ export { export { promptSingleChannelSecretInput, type SingleChannelSecretInputPromptResult, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { buildOauthProviderAuthResult } from "./provider-auth-result.js"; export { formatResolvedUnresolvedNote } from "./resolution-notes.js"; export { buildChannelSendResult } from "./channel-send-result.js"; diff --git a/src/plugin-sdk/irc.ts b/src/plugin-sdk/irc.ts index 2b2a86badda..4192322d527 100644 --- a/src/plugin-sdk/irc.ts +++ b/src/plugin-sdk/irc.ts @@ -17,7 +17,7 @@ export { addWildcardAllowFrom, setTopLevelChannelAllowFrom, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { patchScopedAccountConfig } from "../channels/plugins/setup-helpers.js"; export type { BaseProbeResult } from "../channels/plugins/types.js"; diff --git a/src/plugin-sdk/matrix.ts b/src/plugin-sdk/matrix.ts index 58234ca86fe..164575e04e1 100644 --- a/src/plugin-sdk/matrix.ts +++ b/src/plugin-sdk/matrix.ts @@ -38,7 +38,7 @@ export { mergeAllowFromEntries, promptSingleChannelSecretInput, setTopLevelChannelGroupPolicy, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { applyAccountNameToChannelSection } from "../channels/plugins/setup-helpers.js"; export { createAccountListHelpers } from "../channels/plugins/account-helpers.js"; diff --git a/src/plugin-sdk/mattermost.ts b/src/plugin-sdk/mattermost.ts index 4787d5e8ac3..c8043045906 100644 --- a/src/plugin-sdk/mattermost.ts +++ b/src/plugin-sdk/mattermost.ts @@ -32,7 +32,7 @@ export { buildSingleChannelSecretPromptState, promptSingleChannelSecretInput, runSingleChannelSecretStep, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { applyAccountNameToChannelSection, applySetupAccountConfigPatch, diff --git a/src/plugin-sdk/msteams.ts b/src/plugin-sdk/msteams.ts index 96e296af04a..4a2d12a9ba0 100644 --- a/src/plugin-sdk/msteams.ts +++ b/src/plugin-sdk/msteams.ts @@ -39,7 +39,7 @@ export { setTopLevelChannelDmPolicyWithAllowFrom, setTopLevelChannelGroupPolicy, splitSetupEntries, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export type { BaseProbeResult, diff --git a/src/plugin-sdk/nextcloud-talk.ts b/src/plugin-sdk/nextcloud-talk.ts index 960ac32af0b..4ce53e1ec15 100644 --- a/src/plugin-sdk/nextcloud-talk.ts +++ b/src/plugin-sdk/nextcloud-talk.ts @@ -24,7 +24,7 @@ export { promptSingleChannelSecretInput, runSingleChannelSecretStep, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { applyAccountNameToChannelSection, patchScopedAccountConfig, diff --git a/src/plugin-sdk/setup.ts b/src/plugin-sdk/setup.ts deleted file mode 100644 index 0752243124f..00000000000 --- a/src/plugin-sdk/setup.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { OpenClawConfig } from "../config/config.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; -import type { WizardPrompter } from "../wizard/prompts.js"; - -export type PromptAccountIdParams = { - cfg: OpenClawConfig; - prompter: WizardPrompter; - label: string; - currentId?: string; - listAccountIds: (cfg: OpenClawConfig) => string[]; - defaultAccountId: string; -}; - -export async function promptAccountId(params: PromptAccountIdParams): Promise { - const existingIds = params.listAccountIds(params.cfg); - const initial = params.currentId?.trim() || params.defaultAccountId || DEFAULT_ACCOUNT_ID; - const choice = await params.prompter.select({ - message: `${params.label} account`, - options: [ - ...existingIds.map((id) => ({ - value: id, - label: id === DEFAULT_ACCOUNT_ID ? "default (primary)" : id, - })), - { value: "__new__", label: "Add a new account" }, - ], - initialValue: initial, - }); - - if (choice !== "__new__") { - return normalizeAccountId(choice); - } - - const entered = await params.prompter.text({ - message: `New ${params.label} account id`, - validate: (value) => (value?.trim() ? undefined : "Required"), - }); - const normalized = normalizeAccountId(String(entered)); - if (String(entered).trim() !== normalized) { - await params.prompter.note( - `Normalized account id to "${normalized}".`, - `${params.label} account`, - ); - } - return normalized; -} diff --git a/src/plugin-sdk/zalo.ts b/src/plugin-sdk/zalo.ts index 775f2817ca1..cb8b059dc2c 100644 --- a/src/plugin-sdk/zalo.ts +++ b/src/plugin-sdk/zalo.ts @@ -18,7 +18,7 @@ export { promptSingleChannelSecretInput, runSingleChannelSecretStep, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { applyAccountNameToChannelSection, diff --git a/src/plugin-sdk/zalouser.ts b/src/plugin-sdk/zalouser.ts index 9e4910b1c85..8f4866e949e 100644 --- a/src/plugin-sdk/zalouser.ts +++ b/src/plugin-sdk/zalouser.ts @@ -15,7 +15,7 @@ export { addWildcardAllowFrom, mergeAllowFromEntries, setTopLevelChannelDmPolicyWithAllowFrom, -} from "../channels/plugins/setup-flow-helpers.js"; +} from "../channels/plugins/setup-wizard-helpers.js"; export { applyAccountNameToChannelSection, applySetupAccountConfigPatch, diff --git a/src/plugins/provider-validation.test.ts b/src/plugins/provider-validation.test.ts index fc91a74576d..f0208aa1d2a 100644 --- a/src/plugins/provider-validation.test.ts +++ b/src/plugins/provider-validation.test.ts @@ -49,7 +49,7 @@ describe("normalizeRegisteredProvider", () => { { id: " ", label: "Missing", kind: "custom", run: async () => ({ profiles: [] }) }, ], wizard: { - onboarding: { + setup: { choiceId: " demo-choice ", methodId: " missing ", }, @@ -69,7 +69,7 @@ describe("normalizeRegisteredProvider", () => { envVars: ["DEMO_API_KEY"], auth: [{ id: "primary", label: "Primary" }], wizard: { - onboarding: { + setup: { choiceId: "demo-choice", }, modelPicker: { @@ -89,7 +89,7 @@ describe("normalizeRegisteredProvider", () => { { level: "warn", message: - 'provider "demo" onboarding method "missing" not found; falling back to available methods', + 'provider "demo" setup method "missing" not found; falling back to available methods', }, { level: "warn", @@ -107,7 +107,7 @@ describe("normalizeRegisteredProvider", () => { source: "/tmp/demo/index.ts", provider: makeProvider({ wizard: { - onboarding: { + setup: { choiceId: "demo", }, modelPicker: { @@ -120,7 +120,7 @@ describe("normalizeRegisteredProvider", () => { expect(provider?.wizard).toBeUndefined(); expect(diagnostics.map((diag) => diag.message)).toEqual([ - 'provider "demo" onboarding metadata ignored because it has no auth methods', + 'provider "demo" setup metadata ignored because it has no auth methods', 'provider "demo" model-picker metadata ignored because it has no auth methods', ]); }); diff --git a/src/plugins/provider-validation.ts b/src/plugins/provider-validation.ts index 5401144929c..172fefc1777 100644 --- a/src/plugins/provider-validation.ts +++ b/src/plugins/provider-validation.ts @@ -87,9 +87,9 @@ function normalizeProviderWizard(params: { const hasMethod = (methodId: string | undefined) => Boolean(methodId && params.auth.some((method) => method.id === methodId)); - const normalizeOnboarding = () => { - const onboarding = params.wizard?.onboarding; - if (!onboarding) { + const normalizeSetup = () => { + const setup = params.wizard?.setup; + if (!setup) { return undefined; } if (!hasAuthMethods) { @@ -97,38 +97,30 @@ function normalizeProviderWizard(params: { level: "warn", pluginId: params.pluginId, source: params.source, - message: `provider "${params.providerId}" onboarding metadata ignored because it has no auth methods`, + message: `provider "${params.providerId}" setup metadata ignored because it has no auth methods`, pushDiagnostic: params.pushDiagnostic, }); return undefined; } - const methodId = normalizeText(onboarding.methodId); + const methodId = normalizeText(setup.methodId); if (methodId && !hasMethod(methodId)) { pushProviderDiagnostic({ level: "warn", pluginId: params.pluginId, source: params.source, - message: `provider "${params.providerId}" onboarding method "${methodId}" not found; falling back to available methods`, + message: `provider "${params.providerId}" setup method "${methodId}" not found; falling back to available methods`, pushDiagnostic: params.pushDiagnostic, }); } return { - ...(normalizeText(onboarding.choiceId) - ? { choiceId: normalizeText(onboarding.choiceId) } - : {}), - ...(normalizeText(onboarding.choiceLabel) - ? { choiceLabel: normalizeText(onboarding.choiceLabel) } - : {}), - ...(normalizeText(onboarding.choiceHint) - ? { choiceHint: normalizeText(onboarding.choiceHint) } - : {}), - ...(normalizeText(onboarding.groupId) ? { groupId: normalizeText(onboarding.groupId) } : {}), - ...(normalizeText(onboarding.groupLabel) - ? { groupLabel: normalizeText(onboarding.groupLabel) } - : {}), - ...(normalizeText(onboarding.groupHint) - ? { groupHint: normalizeText(onboarding.groupHint) } + ...(normalizeText(setup.choiceId) ? { choiceId: normalizeText(setup.choiceId) } : {}), + ...(normalizeText(setup.choiceLabel) + ? { choiceLabel: normalizeText(setup.choiceLabel) } : {}), + ...(normalizeText(setup.choiceHint) ? { choiceHint: normalizeText(setup.choiceHint) } : {}), + ...(normalizeText(setup.groupId) ? { groupId: normalizeText(setup.groupId) } : {}), + ...(normalizeText(setup.groupLabel) ? { groupLabel: normalizeText(setup.groupLabel) } : {}), + ...(normalizeText(setup.groupHint) ? { groupHint: normalizeText(setup.groupHint) } : {}), ...(methodId && hasMethod(methodId) ? { methodId } : {}), }; }; @@ -165,13 +157,13 @@ function normalizeProviderWizard(params: { }; }; - const onboarding = normalizeOnboarding(); + const setup = normalizeSetup(); const modelPicker = normalizeModelPicker(); - if (!onboarding && !modelPicker) { + if (!setup && !modelPicker) { return undefined; } return { - ...(onboarding ? { onboarding } : {}), + ...(setup ? { setup } : {}), ...(modelPicker ? { modelPicker } : {}), }; } diff --git a/src/plugins/provider-wizard.test.ts b/src/plugins/provider-wizard.test.ts index c6e265231a0..f55d9292824 100644 --- a/src/plugins/provider-wizard.test.ts +++ b/src/plugins/provider-wizard.test.ts @@ -25,7 +25,7 @@ describe("provider wizard boundaries", () => { vi.clearAllMocks(); }); - it("uses explicit onboarding choice ids and bound method ids", () => { + it("uses explicit setup choice ids and bound method ids", () => { const provider = makeProvider({ id: "vllm", label: "vLLM", @@ -34,7 +34,7 @@ describe("provider wizard boundaries", () => { { id: "cloud", label: "Cloud", kind: "custom", run: vi.fn() }, ], wizard: { - onboarding: { + setup: { choiceId: "self-hosted-vllm", methodId: "local", choiceLabel: "vLLM local", diff --git a/src/plugins/provider-wizard.ts b/src/plugins/provider-wizard.ts index 4b02fcd3cf7..dcac7e36d40 100644 --- a/src/plugins/provider-wizard.ts +++ b/src/plugins/provider-wizard.ts @@ -8,7 +8,7 @@ import type { ProviderAuthMethod, ProviderPlugin, ProviderPluginWizardModelPicker, - ProviderPluginWizardOnboarding, + ProviderPluginWizardSetup, } from "./types.js"; export const PROVIDER_PLUGIN_CHOICE_PREFIX = "provider-plugin:"; @@ -32,9 +32,9 @@ function normalizeChoiceId(choiceId: string): string { return choiceId.trim(); } -function resolveWizardOnboardingChoiceId( +function resolveWizardSetupChoiceId( provider: ProviderPlugin, - wizard: ProviderPluginWizardOnboarding, + wizard: ProviderPluginWizardSetup, ): string { const explicit = wizard.choiceId?.trim(); if (explicit) { @@ -61,9 +61,9 @@ function resolveMethodById( return provider.auth.find((method) => method.id.trim().toLowerCase() === normalizedMethodId); } -function buildOnboardingOptionForMethod(params: { +function buildSetupOptionForMethod(params: { provider: ProviderPlugin; - wizard: ProviderPluginWizardOnboarding; + wizard: ProviderPluginWizardSetup; method: ProviderAuthMethod; value: string; }): ProviderWizardOption { @@ -93,18 +93,18 @@ export function resolveProviderWizardOptions(params: { const options: ProviderWizardOption[] = []; for (const provider of providers) { - const wizard = provider.wizard?.onboarding; - if (!wizard) { + const setup = provider.wizard?.setup; + if (!setup) { continue; } - const explicitMethod = resolveMethodById(provider, wizard.methodId); + const explicitMethod = resolveMethodById(provider, setup.methodId); if (explicitMethod) { options.push( - buildOnboardingOptionForMethod({ + buildSetupOptionForMethod({ provider, - wizard, + wizard: setup, method: explicitMethod, - value: resolveWizardOnboardingChoiceId(provider, wizard), + value: resolveWizardSetupChoiceId(provider, setup), }), ); continue; @@ -112,9 +112,9 @@ export function resolveProviderWizardOptions(params: { for (const method of provider.auth) { options.push( - buildOnboardingOptionForMethod({ + buildSetupOptionForMethod({ provider, - wizard, + wizard: setup, method, value: buildProviderPluginMethodChoice(provider.id, method.id), }), @@ -187,11 +187,11 @@ export function resolveProviderPluginChoice(params: { } for (const provider of params.providers) { - const onboarding = provider.wizard?.onboarding; - if (onboarding) { - const onboardingChoiceId = resolveWizardOnboardingChoiceId(provider, onboarding); - if (normalizeChoiceId(onboardingChoiceId) === choice) { - const method = resolveMethodById(provider, onboarding.methodId); + const setup = provider.wizard?.setup; + if (setup) { + const setupChoiceId = resolveWizardSetupChoiceId(provider, setup); + if (normalizeChoiceId(setupChoiceId) === choice) { + const method = resolveMethodById(provider, setup.methodId); if (method) { return { provider, method }; } diff --git a/src/plugins/types.ts b/src/plugins/types.ts index df7e00734d5..4e8d17cddc4 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -496,7 +496,7 @@ export type ProviderDiscoveryResult = ProviderCatalogResult; */ export type ProviderPluginDiscovery = ProviderPluginCatalog; -export type ProviderPluginWizardOnboarding = { +export type ProviderPluginWizardSetup = { choiceId?: string; choiceLabel?: string; choiceHint?: string; @@ -513,7 +513,7 @@ export type ProviderPluginWizardModelPicker = { }; export type ProviderPluginWizard = { - onboarding?: ProviderPluginWizardOnboarding; + setup?: ProviderPluginWizardSetup; modelPicker?: ProviderPluginWizardModelPicker; }; @@ -532,7 +532,7 @@ export type ProviderPlugin = { docsPath?: string; aliases?: string[]; /** - * Provider-related env vars shown in onboarding/search/help surfaces. + * Provider-related env vars shown in setup/search/help surfaces. * * Keep entries in preferred display order. This can include direct auth env * vars or setup inputs such as OAuth client id/secret vars. diff --git a/src/wizard/onboarding.completion.test.ts b/src/wizard/setup.completion.test.ts similarity index 78% rename from src/wizard/onboarding.completion.test.ts rename to src/wizard/setup.completion.test.ts index 031bad31919..4086d745c07 100644 --- a/src/wizard/onboarding.completion.test.ts +++ b/src/wizard/setup.completion.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { setupOnboardingShellCompletion } from "./onboarding.completion.js"; +import { setupWizardShellCompletion } from "./setup.completion.js"; function createPrompter(confirmValue = false) { return { @@ -9,7 +9,7 @@ function createPrompter(confirmValue = false) { } function createDeps() { - const deps: NonNullable[0]["deps"]> = { + const deps: NonNullable[0]["deps"]> = { resolveCliName: () => "openclaw", checkShellCompletionStatus: vi.fn(async (_binName: string) => ({ shell: "zsh" as const, @@ -24,12 +24,12 @@ function createDeps() { return deps; } -describe("setupOnboardingShellCompletion", () => { +describe("setupWizardShellCompletion", () => { it("QuickStart: installs without prompting", async () => { const prompter = createPrompter(); const deps = createDeps(); - await setupOnboardingShellCompletion({ flow: "quickstart", prompter, deps }); + await setupWizardShellCompletion({ flow: "quickstart", prompter, deps }); expect(prompter.confirm).not.toHaveBeenCalled(); expect(deps.ensureCompletionCacheExists).toHaveBeenCalledWith("openclaw"); @@ -41,7 +41,7 @@ describe("setupOnboardingShellCompletion", () => { const prompter = createPrompter(); const deps = createDeps(); - await setupOnboardingShellCompletion({ flow: "advanced", prompter, deps }); + await setupWizardShellCompletion({ flow: "advanced", prompter, deps }); expect(prompter.confirm).toHaveBeenCalledTimes(1); expect(deps.ensureCompletionCacheExists).not.toHaveBeenCalled(); diff --git a/src/wizard/onboarding.completion.ts b/src/wizard/setup.completion.ts similarity index 96% rename from src/wizard/onboarding.completion.ts rename to src/wizard/setup.completion.ts index f0888a9e6a2..be00151db36 100644 --- a/src/wizard/onboarding.completion.ts +++ b/src/wizard/setup.completion.ts @@ -8,8 +8,8 @@ import { ensureCompletionCacheExists, } from "../commands/doctor-completion.js"; import { pathExists } from "../utils.js"; -import type { WizardFlow } from "./onboarding.types.js"; import type { WizardPrompter } from "./prompts.js"; +import type { WizardFlow } from "./setup.types.js"; type CompletionDeps = { resolveCliName: () => string; @@ -41,7 +41,7 @@ function formatReloadHint(shell: ShellCompletionStatus["shell"], profileHint: st return `Restart your shell or run: source ${profileHint}`; } -export async function setupOnboardingShellCompletion(params: { +export async function setupWizardShellCompletion(params: { flow: WizardFlow; prompter: Pick; deps?: Partial; diff --git a/src/wizard/onboarding.finalize.test.ts b/src/wizard/setup.finalize.test.ts similarity index 95% rename from src/wizard/onboarding.finalize.test.ts rename to src/wizard/setup.finalize.test.ts index 0fa67d16a8f..269c96e347c 100644 --- a/src/wizard/onboarding.finalize.test.ts +++ b/src/wizard/setup.finalize.test.ts @@ -4,7 +4,7 @@ import type { RuntimeEnv } from "../runtime.js"; const runTui = vi.hoisted(() => vi.fn(async () => {})); const probeGatewayReachable = vi.hoisted(() => vi.fn(async () => ({ ok: true }))); -const setupOnboardingShellCompletion = vi.hoisted(() => vi.fn(async () => {})); +const setupWizardShellCompletion = vi.hoisted(() => vi.fn(async () => {})); const buildGatewayInstallPlan = vi.hoisted(() => vi.fn(async () => ({ programArguments: [], @@ -96,11 +96,11 @@ vi.mock("../tui/tui.js", () => ({ runTui, })); -vi.mock("./onboarding.completion.js", () => ({ - setupOnboardingShellCompletion, +vi.mock("./setup.completion.js", () => ({ + setupWizardShellCompletion, })); -import { finalizeOnboardingWizard } from "./onboarding.finalize.js"; +import { finalizeSetupWizard } from "./setup.finalize.js"; function createRuntime(): RuntimeEnv { return { @@ -117,11 +117,11 @@ function expectFirstOnboardingInstallPlanCallOmitsToken() { expect(firstArg && "token" in firstArg).toBe(false); } -describe("finalizeOnboardingWizard", () => { +describe("finalizeSetupWizard", () => { beforeEach(() => { runTui.mockClear(); probeGatewayReachable.mockClear(); - setupOnboardingShellCompletion.mockClear(); + setupWizardShellCompletion.mockClear(); buildGatewayInstallPlan.mockClear(); gatewayServiceInstall.mockClear(); gatewayServiceIsLoaded.mockReset(); @@ -150,7 +150,7 @@ describe("finalizeOnboardingWizard", () => { const runtime = createRuntime(); try { - await finalizeOnboardingWizard({ + await finalizeSetupWizard({ flow: "quickstart", opts: { acceptRisk: true, @@ -220,7 +220,7 @@ describe("finalizeOnboardingWizard", () => { }); const runtime = createRuntime(); - await finalizeOnboardingWizard({ + await finalizeSetupWizard({ flow: "advanced", opts: { acceptRisk: true, @@ -277,7 +277,7 @@ describe("finalizeOnboardingWizard", () => { progress: vi.fn(() => ({ update: progressUpdate, stop: progressStop })), }); - await finalizeOnboardingWizard({ + await finalizeSetupWizard({ flow: "advanced", opts: { acceptRisk: true, diff --git a/src/wizard/onboarding.finalize.ts b/src/wizard/setup.finalize.ts similarity index 98% rename from src/wizard/onboarding.finalize.ts rename to src/wizard/setup.finalize.ts index b218e160ed5..31940e8632d 100644 --- a/src/wizard/onboarding.finalize.ts +++ b/src/wizard/setup.finalize.ts @@ -30,10 +30,10 @@ import type { RuntimeEnv } from "../runtime.js"; import { restoreTerminalState } from "../terminal/restore.js"; import { runTui } from "../tui/tui.js"; import { resolveUserPath } from "../utils.js"; -import { setupOnboardingShellCompletion } from "./onboarding.completion.js"; -import { resolveOnboardingSecretInputString } from "./onboarding.secret-input.js"; -import type { GatewayWizardSettings, WizardFlow } from "./onboarding.types.js"; import type { WizardPrompter } from "./prompts.js"; +import { setupWizardShellCompletion } from "./setup.completion.js"; +import { resolveSetupSecretInputString } from "./setup.secret-input.js"; +import type { GatewayWizardSettings, WizardFlow } from "./setup.types.js"; type FinalizeOnboardingOptions = { flow: WizardFlow; @@ -46,7 +46,7 @@ type FinalizeOnboardingOptions = { runtime: RuntimeEnv; }; -export async function finalizeOnboardingWizard( +export async function finalizeSetupWizard( options: FinalizeOnboardingOptions, ): Promise<{ launchedTui: boolean }> { const { flow, opts, baseConfig, nextConfig, settings, prompter, runtime } = options; @@ -286,7 +286,7 @@ export async function finalizeOnboardingWizard( if (settings.authMode === "password") { try { resolvedGatewayPassword = - (await resolveOnboardingSecretInputString({ + (await resolveSetupSecretInputString({ config: nextConfig, value: nextConfig.gateway?.auth?.password, path: "gateway.auth.password", @@ -441,7 +441,7 @@ export async function finalizeOnboardingWizard( "Security", ); - await setupOnboardingShellCompletion({ flow, prompter }); + await setupWizardShellCompletion({ flow, prompter }); const shouldOpenControlUi = !opts.skipUi && diff --git a/src/wizard/onboarding.gateway-config.test.ts b/src/wizard/setup.gateway-config.test.ts similarity index 95% rename from src/wizard/onboarding.gateway-config.test.ts rename to src/wizard/setup.gateway-config.test.ts index 1345b8f4954..3df835e3283 100644 --- a/src/wizard/onboarding.gateway-config.test.ts +++ b/src/wizard/setup.gateway-config.test.ts @@ -22,9 +22,9 @@ vi.mock("../infra/tailscale.js", () => ({ getTailnetHostname: mocks.getTailnetHostname, })); -import { configureGatewayForOnboarding } from "./onboarding.gateway-config.js"; +import { configureGatewayForSetup } from "./setup.gateway-config.js"; -describe("configureGatewayForOnboarding", () => { +describe("configureGatewayForSetup", () => { function createPrompter(params: { selectQueue: string[]; textQueue: Array }) { const selectQueue = [...params.selectQueue]; const textQueue = [...params.textQueue]; @@ -78,7 +78,7 @@ describe("configureGatewayForOnboarding", () => { textQueue: params?.textQueue ?? ["18789", undefined], }); const runtime = createRuntime(); - return configureGatewayForOnboarding({ + return configureGatewayForSetup({ flow: params?.flow ?? "advanced", baseConfig: {}, nextConfig: params?.nextConfig ?? {}, @@ -153,7 +153,7 @@ describe("configureGatewayForOnboarding", () => { }); const runtime = createRuntime(); - const result = await configureGatewayForOnboarding({ + const result = await configureGatewayForSetup({ flow: "advanced", baseConfig: {}, nextConfig: {}, @@ -189,7 +189,7 @@ describe("configureGatewayForOnboarding", () => { }); const runtime = createRuntime(); - const result = await configureGatewayForOnboarding({ + const result = await configureGatewayForSetup({ flow: "advanced", baseConfig: {}, nextConfig: {}, @@ -231,7 +231,7 @@ describe("configureGatewayForOnboarding", () => { textQueue: [], }); - const result = await configureGatewayForOnboarding({ + const result = await configureGatewayForSetup({ flow: "quickstart", baseConfig: {}, nextConfig: { diff --git a/src/wizard/onboarding.gateway-config.ts b/src/wizard/setup.gateway-config.ts similarity index 96% rename from src/wizard/onboarding.gateway-config.ts rename to src/wizard/setup.gateway-config.ts index c6d9111c3e4..74420c1dac2 100644 --- a/src/wizard/onboarding.gateway-config.ts +++ b/src/wizard/setup.gateway-config.ts @@ -1,5 +1,5 @@ import { - promptSecretRefForOnboarding, + promptSecretRefForSetup, resolveSecretInputModeForEnvSelection, } from "../commands/auth-choice.apply-helpers.js"; import { @@ -25,13 +25,13 @@ import { DEFAULT_DANGEROUS_NODE_COMMANDS } from "../gateway/node-command-policy. import { findTailscaleBinary } from "../infra/tailscale.js"; import type { RuntimeEnv } from "../runtime.js"; import { validateIPv4AddressInput } from "../shared/net/ipv4.js"; -import { resolveOnboardingSecretInputString } from "./onboarding.secret-input.js"; +import type { WizardPrompter } from "./prompts.js"; +import { resolveSetupSecretInputString } from "./setup.secret-input.js"; import type { GatewayWizardSettings, QuickstartGatewayDefaults, WizardFlow, -} from "./onboarding.types.js"; -import type { WizardPrompter } from "./prompts.js"; +} from "./setup.types.js"; type ConfigureGatewayOptions = { flow: WizardFlow; @@ -49,7 +49,7 @@ type ConfigureGatewayResult = { settings: GatewayWizardSettings; }; -export async function configureGatewayForOnboarding( +export async function configureGatewayForSetup( opts: ConfigureGatewayOptions, ): Promise { const { flow, localPort, quickstartGateway, prompter } = opts; @@ -183,14 +183,14 @@ export async function configureGatewayForOnboarding( if (tokenMode === "ref") { if (flow === "quickstart" && quickstartTokenRef) { gatewayTokenInput = quickstartTokenRef; - gatewayToken = await resolveOnboardingSecretInputString({ + gatewayToken = await resolveSetupSecretInputString({ config: nextConfig, value: quickstartTokenRef, path: "gateway.auth.token", env: process.env, }); } else { - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: "gateway-auth-token", config: nextConfig, prompter, @@ -236,7 +236,7 @@ export async function configureGatewayForOnboarding( }, }); if (selectedMode === "ref") { - const resolved = await promptSecretRefForOnboarding({ + const resolved = await promptSecretRefForSetup({ provider: "gateway-auth-password", config: nextConfig, prompter, diff --git a/src/wizard/onboarding.secret-input.test.ts b/src/wizard/setup.secret-input.test.ts similarity index 79% rename from src/wizard/onboarding.secret-input.test.ts rename to src/wizard/setup.secret-input.test.ts index 4258d6df6cd..94abbfd55c8 100644 --- a/src/wizard/onboarding.secret-input.test.ts +++ b/src/wizard/setup.secret-input.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; -import { resolveOnboardingSecretInputString } from "./onboarding.secret-input.js"; +import { resolveSetupSecretInputString } from "./setup.secret-input.js"; function makeConfig(): OpenClawConfig { return { @@ -12,9 +12,9 @@ function makeConfig(): OpenClawConfig { } as OpenClawConfig; } -describe("resolveOnboardingSecretInputString", () => { +describe("resolveSetupSecretInputString", () => { it("resolves env-template SecretInput strings", async () => { - const resolved = await resolveOnboardingSecretInputString({ + const resolved = await resolveSetupSecretInputString({ config: makeConfig(), value: "${OPENCLAW_GATEWAY_PASSWORD}", path: "gateway.auth.password", @@ -27,7 +27,7 @@ describe("resolveOnboardingSecretInputString", () => { }); it("returns plaintext strings when value is not a SecretRef", async () => { - const resolved = await resolveOnboardingSecretInputString({ + const resolved = await resolveSetupSecretInputString({ config: makeConfig(), value: "plain-text", path: "gateway.auth.password", @@ -38,7 +38,7 @@ describe("resolveOnboardingSecretInputString", () => { it("throws with path context when env-template SecretRef cannot resolve", async () => { await expect( - resolveOnboardingSecretInputString({ + resolveSetupSecretInputString({ config: makeConfig(), value: "${OPENCLAW_GATEWAY_PASSWORD}", path: "gateway.auth.password", diff --git a/src/wizard/onboarding.secret-input.ts b/src/wizard/setup.secret-input.ts similarity index 94% rename from src/wizard/onboarding.secret-input.ts rename to src/wizard/setup.secret-input.ts index cbb071690fa..1ccfdde1644 100644 --- a/src/wizard/onboarding.secret-input.ts +++ b/src/wizard/setup.secret-input.ts @@ -11,7 +11,7 @@ function formatSecretResolutionError(error: unknown): string { return String(error); } -export async function resolveOnboardingSecretInputString(params: { +export async function resolveSetupSecretInputString(params: { config: OpenClawConfig; value: unknown; path: string; diff --git a/src/wizard/onboarding.test.ts b/src/wizard/setup.test.ts similarity index 94% rename from src/wizard/onboarding.test.ts rename to src/wizard/setup.test.ts index 14c3183c323..97ca8546664 100644 --- a/src/wizard/onboarding.test.ts +++ b/src/wizard/setup.test.ts @@ -5,8 +5,8 @@ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; import { createWizardPrompter as buildWizardPrompter } from "../../test/helpers/wizard-prompter.js"; import { DEFAULT_BOOTSTRAP_FILENAME } from "../agents/workspace.js"; import type { RuntimeEnv } from "../runtime.js"; -import { runOnboardingWizard } from "./onboarding.js"; import type { WizardPrompter, WizardSelectParams } from "./prompts.js"; +import { runSetupWizard } from "./setup.js"; const ensureAuthProfileStore = vi.hoisted(() => vi.fn(() => ({ profiles: {} }))); const promptAuthChoiceGrouped = vi.hoisted(() => vi.fn(async () => "skip")); @@ -16,7 +16,7 @@ const warnIfModelConfigLooksOff = vi.hoisted(() => vi.fn(async () => {})); const applyPrimaryModel = vi.hoisted(() => vi.fn((cfg) => cfg)); const promptDefaultModel = vi.hoisted(() => vi.fn(async () => ({ config: null, model: null }))); const promptCustomApiConfig = vi.hoisted(() => vi.fn(async (args) => ({ config: args.config }))); -const configureGatewayForOnboarding = vi.hoisted(() => +const configureGatewayForSetup = vi.hoisted(() => vi.fn(async (args) => ({ nextConfig: args.nextConfig, settings: { @@ -29,7 +29,7 @@ const configureGatewayForOnboarding = vi.hoisted(() => }, })), ); -const finalizeOnboardingWizard = vi.hoisted(() => +const finalizeSetupWizard = vi.hoisted(() => vi.fn(async (options) => { if (!options.nextConfig?.tools?.web?.search?.provider) { await options.prompter.note("Web search was skipped.", "Web search"); @@ -86,7 +86,7 @@ const ensureSystemdUserLingerInteractive = vi.hoisted(() => vi.fn(async () => {} const isSystemdUserServiceAvailable = vi.hoisted(() => vi.fn(async () => true)); const ensureControlUiAssetsBuilt = vi.hoisted(() => vi.fn(async () => ({ ok: true }))); const runTui = vi.hoisted(() => vi.fn(async (_options: unknown) => {})); -const setupOnboardingShellCompletion = vi.hoisted(() => vi.fn(async () => {})); +const setupWizardShellCompletion = vi.hoisted(() => vi.fn(async () => {})); const probeGatewayReachable = vi.hoisted(() => vi.fn(async () => ({ ok: true }))); vi.mock("../commands/onboard-channels.js", () => ({ @@ -184,16 +184,16 @@ vi.mock("../tui/tui.js", () => ({ runTui, })); -vi.mock("./onboarding.gateway-config.js", () => ({ - configureGatewayForOnboarding, +vi.mock("./setup.gateway-config.js", () => ({ + configureGatewayForSetup, })); -vi.mock("./onboarding.finalize.js", () => ({ - finalizeOnboardingWizard, +vi.mock("./setup.finalize.js", () => ({ + finalizeSetupWizard, })); -vi.mock("./onboarding.completion.js", () => ({ - setupOnboardingShellCompletion, +vi.mock("./setup.completion.js", () => ({ + setupWizardShellCompletion, })); function createRuntime(opts?: { throwsOnExit?: boolean }): RuntimeEnv { @@ -214,7 +214,7 @@ function createRuntime(opts?: { throwsOnExit?: boolean }): RuntimeEnv { }; } -describe("runOnboardingWizard", () => { +describe("runSetupWizard", () => { let suiteRoot = ""; let suiteCase = 0; @@ -255,7 +255,7 @@ describe("runOnboardingWizard", () => { const runtime = createRuntime({ throwsOnExit: true }); await expect( - runOnboardingWizard( + runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -284,7 +284,7 @@ describe("runOnboardingWizard", () => { const prompter = buildWizardPrompter({ select, multiselect }); const runtime = createRuntime({ throwsOnExit: true }); - await runOnboardingWizard( + await runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -328,7 +328,7 @@ describe("runOnboardingWizard", () => { const prompter = buildWizardPrompter({ select }); const runtime = createRuntime({ throwsOnExit: true }); - await runOnboardingWizard( + await runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -370,7 +370,7 @@ describe("runOnboardingWizard", () => { const prompter = buildWizardPrompter({ note }); const runtime = createRuntime(); - await runOnboardingWizard( + await runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -435,7 +435,7 @@ describe("runOnboardingWizard", () => { const runtime = createRuntime(); try { - await runOnboardingWizard( + await runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -468,11 +468,11 @@ describe("runOnboardingWizard", () => { }); it("passes secretInputMode through to local gateway config step", async () => { - configureGatewayForOnboarding.mockClear(); + configureGatewayForSetup.mockClear(); const prompter = buildWizardPrompter({}); const runtime = createRuntime(); - await runOnboardingWizard( + await runSetupWizard( { acceptRisk: true, flow: "quickstart", @@ -490,7 +490,7 @@ describe("runOnboardingWizard", () => { prompter, ); - expect(configureGatewayForOnboarding).toHaveBeenCalledWith( + expect(configureGatewayForSetup).toHaveBeenCalledWith( expect.objectContaining({ secretInputMode: "ref", // pragma: allowlist secret }), diff --git a/src/wizard/onboarding.ts b/src/wizard/setup.ts similarity index 94% rename from src/wizard/onboarding.ts rename to src/wizard/setup.ts index d2c35a022da..cf734720170 100644 --- a/src/wizard/onboarding.ts +++ b/src/wizard/setup.ts @@ -16,9 +16,9 @@ import { normalizeSecretInputString } from "../config/types.secrets.js"; import type { RuntimeEnv } from "../runtime.js"; import { defaultRuntime } from "../runtime.js"; import { resolveUserPath } from "../utils.js"; -import { resolveOnboardingSecretInputString } from "./onboarding.secret-input.js"; -import type { QuickstartGatewayDefaults, WizardFlow } from "./onboarding.types.js"; import { WizardCancelledError, type WizardPrompter } from "./prompts.js"; +import { resolveSetupSecretInputString } from "./setup.secret-input.js"; +import type { QuickstartGatewayDefaults, WizardFlow } from "./setup.types.js"; async function requireRiskAcknowledgement(params: { opts: OnboardOptions; @@ -70,7 +70,7 @@ async function requireRiskAcknowledgement(params: { } } -export async function runOnboardingWizard( +export async function runSetupWizard( opts: OnboardOptions, runtime: RuntimeEnv = defaultRuntime, prompter: WizardPrompter, @@ -96,7 +96,7 @@ export async function runOnboardingWizard( ); } await prompter.outro( - `Config invalid. Run \`${formatCliCommand("openclaw doctor")}\` to repair it, then re-run onboarding.`, + `Config invalid. Run \`${formatCliCommand("openclaw doctor")}\` to repair it, then re-run setup.`, ); runtime.exit(1); return; @@ -283,7 +283,7 @@ export async function runOnboardingWizard( const localUrl = `ws://127.0.0.1:${localPort}`; let localGatewayToken = process.env.OPENCLAW_GATEWAY_TOKEN ?? process.env.CLAWDBOT_GATEWAY_TOKEN; try { - const resolvedGatewayToken = await resolveOnboardingSecretInputString({ + const resolvedGatewayToken = await resolveSetupSecretInputString({ config: baseConfig, value: baseConfig.gateway?.auth?.token, path: "gateway.auth.token", @@ -304,7 +304,7 @@ export async function runOnboardingWizard( let localGatewayPassword = process.env.OPENCLAW_GATEWAY_PASSWORD ?? process.env.CLAWDBOT_GATEWAY_PASSWORD; try { - const resolvedGatewayPassword = await resolveOnboardingSecretInputString({ + const resolvedGatewayPassword = await resolveSetupSecretInputString({ config: baseConfig, value: baseConfig.gateway?.auth?.password, path: "gateway.auth.password", @@ -331,7 +331,7 @@ export async function runOnboardingWizard( const remoteUrl = baseConfig.gateway?.remote?.url?.trim() ?? ""; let remoteGatewayToken = normalizeSecretInputString(baseConfig.gateway?.remote?.token); try { - const resolvedRemoteGatewayToken = await resolveOnboardingSecretInputString({ + const resolvedRemoteGatewayToken = await resolveSetupSecretInputString({ config: baseConfig, value: baseConfig.gateway?.remote?.token, path: "gateway.remote.token", @@ -406,8 +406,8 @@ export async function runOnboardingWizard( const workspaceDir = resolveUserPath(workspaceInput.trim() || onboardHelpers.DEFAULT_WORKSPACE); - const { applyOnboardingLocalWorkspaceConfig } = await import("../commands/onboard-config.js"); - let nextConfig: OpenClawConfig = applyOnboardingLocalWorkspaceConfig(baseConfig, workspaceDir); + const { applyLocalSetupWorkspaceConfig } = await import("../commands/onboard-config.js"); + let nextConfig: OpenClawConfig = applyLocalSetupWorkspaceConfig(baseConfig, workspaceDir); const { ensureAuthProfileStore } = await import("../agents/auth-profiles.runtime.js"); const { promptAuthChoiceGrouped } = await import("../commands/auth-choice-prompt.js"); @@ -482,8 +482,8 @@ export async function runOnboardingWizard( await warnIfModelConfigLooksOff(nextConfig, prompter); - const { configureGatewayForOnboarding } = await import("./onboarding.gateway-config.js"); - const gateway = await configureGatewayForOnboarding({ + const { configureGatewayForSetup } = await import("./setup.gateway-config.js"); + const gateway = await configureGatewayForSetup({ flow, baseConfig, nextConfig, @@ -548,8 +548,8 @@ export async function runOnboardingWizard( nextConfig = onboardHelpers.applyWizardMetadata(nextConfig, { command: "onboard", mode }); await writeConfigFile(nextConfig); - const { finalizeOnboardingWizard } = await import("./onboarding.finalize.js"); - const { launchedTui } = await finalizeOnboardingWizard({ + const { finalizeSetupWizard } = await import("./setup.finalize.js"); + const { launchedTui } = await finalizeSetupWizard({ flow, opts, baseConfig, diff --git a/src/wizard/onboarding.types.ts b/src/wizard/setup.types.ts similarity index 100% rename from src/wizard/onboarding.types.ts rename to src/wizard/setup.types.ts