From f0b05869fc4a8f486daae3cca424d4604602bca9 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 20:54:47 +0000 Subject: [PATCH] refactor: share onboarding account id resolution prelude --- .../src/onboarding.secret-input.test.ts | 8 ++++++ extensions/bluebubbles/src/onboarding.ts | 25 +++++++----------- extensions/googlechat/src/onboarding.ts | 24 +++++++---------- extensions/irc/src/onboarding.ts | 23 +++++++--------- .../mattermost/src/onboarding-helpers.ts | 2 +- extensions/mattermost/src/onboarding.ts | 25 ++++++++---------- extensions/nextcloud-talk/src/onboarding.ts | 26 +++++++------------ extensions/tlon/src/onboarding.ts | 25 +++++++----------- extensions/zalo/src/onboarding.ts | 23 +++++++--------- extensions/zalouser/src/onboarding.ts | 24 +++++++---------- src/plugin-sdk/bluebubbles.ts | 1 + src/plugin-sdk/googlechat.ts | 1 + src/plugin-sdk/irc.ts | 6 ++++- src/plugin-sdk/mattermost.ts | 1 + src/plugin-sdk/nextcloud-talk.ts | 1 + src/plugin-sdk/tlon.ts | 5 +++- src/plugin-sdk/zalo.ts | 1 + src/plugin-sdk/zalouser.ts | 1 + 18 files changed, 105 insertions(+), 117 deletions(-) diff --git a/extensions/bluebubbles/src/onboarding.secret-input.test.ts b/extensions/bluebubbles/src/onboarding.secret-input.test.ts index a96e30ab20a..af59594f377 100644 --- a/extensions/bluebubbles/src/onboarding.secret-input.test.ts +++ b/extensions/bluebubbles/src/onboarding.secret-input.test.ts @@ -23,6 +23,10 @@ vi.mock("openclaw/plugin-sdk/bluebubbles", () => ({ ); }, mergeAllowFromEntries: (_existing: unknown, entries: string[]) => entries, + createAccountListHelpers: () => ({ + listAccountIds: () => ["default"], + resolveDefaultAccountId: () => "default", + }), normalizeSecretInputString: (value: unknown) => { if (typeof value !== "string") { return undefined; @@ -33,6 +37,10 @@ vi.mock("openclaw/plugin-sdk/bluebubbles", () => ({ normalizeAccountId: (value?: string | null) => value && value.trim().length > 0 ? value : "default", promptAccountId: vi.fn(), + resolveAccountIdForConfigure: async (params: { + accountOverride?: string; + defaultAccountId: string; + }) => params.accountOverride?.trim() || params.defaultAccountId, })); describe("bluebubbles onboarding SecretInput", () => { diff --git a/extensions/bluebubbles/src/onboarding.ts b/extensions/bluebubbles/src/onboarding.ts index bd6bb0913b8..aa011607e0a 100644 --- a/extensions/bluebubbles/src/onboarding.ts +++ b/extensions/bluebubbles/src/onboarding.ts @@ -11,7 +11,7 @@ import { formatDocsLink, mergeAllowFromEntries, normalizeAccountId, - promptAccountId, + resolveAccountIdForConfigure, } from "openclaw/plugin-sdk/bluebubbles"; import { listBlueBubblesAccountIds, @@ -160,21 +160,16 @@ export const blueBubblesOnboardingAdapter: ChannelOnboardingAdapter = { }; }, configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => { - const blueBubblesOverride = accountOverrides.bluebubbles?.trim(); const defaultAccountId = resolveDefaultBlueBubblesAccountId(cfg); - let accountId = blueBubblesOverride - ? normalizeAccountId(blueBubblesOverride) - : defaultAccountId; - if (shouldPromptAccountIds && !blueBubblesOverride) { - accountId = await promptAccountId({ - cfg, - prompter, - label: "BlueBubbles", - currentId: accountId, - listAccountIds: listBlueBubblesAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "BlueBubbles", + accountOverride: accountOverrides.bluebubbles, + shouldPromptAccountIds, + listAccountIds: listBlueBubblesAccountIds, + defaultAccountId, + }); let next = cfg; const resolvedAccount = resolveBlueBubblesAccount({ cfg: next, accountId }); diff --git a/extensions/googlechat/src/onboarding.ts b/extensions/googlechat/src/onboarding.ts index 9c0aac823b9..20040db5631 100644 --- a/extensions/googlechat/src/onboarding.ts +++ b/extensions/googlechat/src/onboarding.ts @@ -3,12 +3,11 @@ import { addWildcardAllowFrom, formatDocsLink, mergeAllowFromEntries, - promptAccountId, + resolveAccountIdForConfigure, type ChannelOnboardingAdapter, type ChannelOnboardingDmPolicy, type WizardPrompter, DEFAULT_ACCOUNT_ID, - normalizeAccountId, migrateBaseNameToDefaultAccount, } from "openclaw/plugin-sdk/googlechat"; import { @@ -241,19 +240,16 @@ export const googlechatOnboardingAdapter: ChannelOnboardingAdapter = { }; }, configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => { - const override = accountOverrides["googlechat"]?.trim(); const defaultAccountId = resolveDefaultGoogleChatAccountId(cfg); - let accountId = override ? normalizeAccountId(override) : defaultAccountId; - if (shouldPromptAccountIds && !override) { - accountId = await promptAccountId({ - cfg, - prompter, - label: "Google Chat", - currentId: accountId, - listAccountIds: listGoogleChatAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Google Chat", + accountOverride: accountOverrides["googlechat"], + shouldPromptAccountIds, + listAccountIds: listGoogleChatAccountIds, + defaultAccountId, + }); let next = cfg; await noteGoogleChatSetup(prompter); diff --git a/extensions/irc/src/onboarding.ts b/extensions/irc/src/onboarding.ts index 4a3ea982bd5..99e8561175f 100644 --- a/extensions/irc/src/onboarding.ts +++ b/extensions/irc/src/onboarding.ts @@ -2,8 +2,8 @@ import { addWildcardAllowFrom, DEFAULT_ACCOUNT_ID, formatDocsLink, - promptAccountId, promptChannelAccessConfig, + resolveAccountIdForConfigure, type ChannelOnboardingAdapter, type ChannelOnboardingDmPolicy, type DmPolicy, @@ -308,19 +308,16 @@ export const ircOnboardingAdapter: ChannelOnboardingAdapter = { forceAllowFrom, }) => { let next = cfg as CoreConfig; - const ircOverride = accountOverrides.irc?.trim(); const defaultAccountId = resolveDefaultIrcAccountId(next); - let accountId = ircOverride || defaultAccountId; - if (shouldPromptAccountIds && !ircOverride) { - accountId = await promptAccountId({ - cfg: next, - prompter, - label: "IRC", - currentId: accountId, - listAccountIds: listIrcAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg: next, + prompter, + label: "IRC", + accountOverride: accountOverrides.irc, + shouldPromptAccountIds, + listAccountIds: listIrcAccountIds, + defaultAccountId, + }); const resolved = resolveIrcAccount({ cfg: next, accountId }); const isDefaultAccount = accountId === DEFAULT_ACCOUNT_ID; diff --git a/extensions/mattermost/src/onboarding-helpers.ts b/extensions/mattermost/src/onboarding-helpers.ts index b125b0371e5..e78abf5ebec 100644 --- a/extensions/mattermost/src/onboarding-helpers.ts +++ b/extensions/mattermost/src/onboarding-helpers.ts @@ -1 +1 @@ -export { promptAccountId } from "openclaw/plugin-sdk/mattermost"; +export { promptAccountId, resolveAccountIdForConfigure } from "openclaw/plugin-sdk/mattermost"; diff --git a/extensions/mattermost/src/onboarding.ts b/extensions/mattermost/src/onboarding.ts index 5204f512d23..86b47e12047 100644 --- a/extensions/mattermost/src/onboarding.ts +++ b/extensions/mattermost/src/onboarding.ts @@ -1,4 +1,4 @@ -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id"; +import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id"; import { hasConfiguredSecretInput, promptSingleChannelSecretInput, @@ -12,7 +12,7 @@ import { resolveDefaultMattermostAccountId, resolveMattermostAccount, } from "./mattermost/accounts.js"; -import { promptAccountId } from "./onboarding-helpers.js"; +import { resolveAccountIdForConfigure } from "./onboarding-helpers.js"; const channel = "mattermost" as const; @@ -65,19 +65,16 @@ export const mattermostOnboardingAdapter: ChannelOnboardingAdapter = { }; }, configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => { - const override = accountOverrides.mattermost?.trim(); const defaultAccountId = resolveDefaultMattermostAccountId(cfg); - let accountId = override ? normalizeAccountId(override) : defaultAccountId; - if (shouldPromptAccountIds && !override) { - accountId = await promptAccountId({ - cfg, - prompter, - label: "Mattermost", - currentId: accountId, - listAccountIds: listMattermostAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Mattermost", + accountOverride: accountOverrides.mattermost, + shouldPromptAccountIds, + listAccountIds: listMattermostAccountIds, + defaultAccountId, + }); let next = cfg; const resolvedAccount = resolveMattermostAccount({ diff --git a/extensions/nextcloud-talk/src/onboarding.ts b/extensions/nextcloud-talk/src/onboarding.ts index 71d904c7a0e..13ae49a41a7 100644 --- a/extensions/nextcloud-talk/src/onboarding.ts +++ b/extensions/nextcloud-talk/src/onboarding.ts @@ -4,7 +4,7 @@ import { hasConfiguredSecretInput, mergeAllowFromEntries, promptSingleChannelSecretInput, - promptAccountId, + resolveAccountIdForConfigure, DEFAULT_ACCOUNT_ID, normalizeAccountId, type SecretInput, @@ -202,22 +202,16 @@ export const nextcloudTalkOnboardingAdapter: ChannelOnboardingAdapter = { shouldPromptAccountIds, forceAllowFrom, }) => { - const nextcloudTalkOverride = accountOverrides["nextcloud-talk"]?.trim(); const defaultAccountId = resolveDefaultNextcloudTalkAccountId(cfg as CoreConfig); - let accountId = nextcloudTalkOverride - ? normalizeAccountId(nextcloudTalkOverride) - : defaultAccountId; - - if (shouldPromptAccountIds && !nextcloudTalkOverride) { - accountId = await promptAccountId({ - cfg: cfg as CoreConfig, - prompter, - label: "Nextcloud Talk", - currentId: accountId, - listAccountIds: listNextcloudTalkAccountIds as (cfg: OpenClawConfig) => string[], - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Nextcloud Talk", + accountOverride: accountOverrides["nextcloud-talk"], + shouldPromptAccountIds, + listAccountIds: listNextcloudTalkAccountIds as (cfg: OpenClawConfig) => string[], + defaultAccountId, + }); let next = cfg as CoreConfig; const resolvedAccount = resolveNextcloudTalkAccount({ diff --git a/extensions/tlon/src/onboarding.ts b/extensions/tlon/src/onboarding.ts index 39256e34362..6558dab0257 100644 --- a/extensions/tlon/src/onboarding.ts +++ b/extensions/tlon/src/onboarding.ts @@ -1,9 +1,8 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/tlon"; import { formatDocsLink, - promptAccountId, + resolveAccountIdForConfigure, DEFAULT_ACCOUNT_ID, - normalizeAccountId, type ChannelOnboardingAdapter, type WizardPrompter, } from "openclaw/plugin-sdk/tlon"; @@ -113,20 +112,16 @@ export const tlonOnboardingAdapter: ChannelOnboardingAdapter = { }; }, configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => { - const override = accountOverrides[channel]?.trim(); const defaultAccountId = DEFAULT_ACCOUNT_ID; - let accountId = override ? normalizeAccountId(override) : defaultAccountId; - - if (shouldPromptAccountIds && !override) { - accountId = await promptAccountId({ - cfg, - prompter, - label: "Tlon", - currentId: accountId, - listAccountIds: listTlonAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Tlon", + accountOverride: accountOverrides[channel], + shouldPromptAccountIds, + listAccountIds: listTlonAccountIds, + defaultAccountId, + }); const resolved = resolveTlonAccount(cfg, accountId); await noteTlonHelp(prompter); diff --git a/extensions/zalo/src/onboarding.ts b/extensions/zalo/src/onboarding.ts index b8c3b0ef011..17388982a9f 100644 --- a/extensions/zalo/src/onboarding.ts +++ b/extensions/zalo/src/onboarding.ts @@ -11,8 +11,8 @@ import { hasConfiguredSecretInput, mergeAllowFromEntries, normalizeAccountId, - promptAccountId, promptSingleChannelSecretInput, + resolveAccountIdForConfigure, } from "openclaw/plugin-sdk/zalo"; import { listZaloAccountIds, resolveDefaultZaloAccountId, resolveZaloAccount } from "./accounts.js"; @@ -240,19 +240,16 @@ export const zaloOnboardingAdapter: ChannelOnboardingAdapter = { shouldPromptAccountIds, forceAllowFrom, }) => { - const zaloOverride = accountOverrides.zalo?.trim(); const defaultZaloAccountId = resolveDefaultZaloAccountId(cfg); - let zaloAccountId = zaloOverride ? normalizeAccountId(zaloOverride) : defaultZaloAccountId; - if (shouldPromptAccountIds && !zaloOverride) { - zaloAccountId = await promptAccountId({ - cfg: cfg, - prompter, - label: "Zalo", - currentId: zaloAccountId, - listAccountIds: listZaloAccountIds, - defaultAccountId: defaultZaloAccountId, - }); - } + const zaloAccountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Zalo", + accountOverride: accountOverrides.zalo, + shouldPromptAccountIds, + listAccountIds: listZaloAccountIds, + defaultAccountId: defaultZaloAccountId, + }); let next = cfg; const resolvedAccount = resolveZaloAccount({ diff --git a/extensions/zalouser/src/onboarding.ts b/extensions/zalouser/src/onboarding.ts index 195f3dfe1a6..21ec359e5ad 100644 --- a/extensions/zalouser/src/onboarding.ts +++ b/extensions/zalouser/src/onboarding.ts @@ -10,8 +10,8 @@ import { formatResolvedUnresolvedNote, mergeAllowFromEntries, normalizeAccountId, - promptAccountId, promptChannelAccessConfig, + resolveAccountIdForConfigure, } from "openclaw/plugin-sdk/zalouser"; import { listZalouserAccountIds, @@ -226,20 +226,16 @@ export const zalouserOnboardingAdapter: ChannelOnboardingAdapter = { shouldPromptAccountIds, forceAllowFrom, }) => { - const zalouserOverride = accountOverrides.zalouser?.trim(); const defaultAccountId = resolveDefaultZalouserAccountId(cfg); - let accountId = zalouserOverride ? normalizeAccountId(zalouserOverride) : defaultAccountId; - - if (shouldPromptAccountIds && !zalouserOverride) { - accountId = await promptAccountId({ - cfg, - prompter, - label: "Zalo Personal", - currentId: accountId, - listAccountIds: listZalouserAccountIds, - defaultAccountId, - }); - } + const accountId = await resolveAccountIdForConfigure({ + cfg, + prompter, + label: "Zalo Personal", + accountOverride: accountOverrides.zalouser, + shouldPromptAccountIds, + listAccountIds: listZalouserAccountIds, + defaultAccountId, + }); let next = cfg; const account = resolveZalouserAccountSync({ cfg: next, accountId }); diff --git a/src/plugin-sdk/bluebubbles.ts b/src/plugin-sdk/bluebubbles.ts index bbe87260f86..22d7441051a 100644 --- a/src/plugin-sdk/bluebubbles.ts +++ b/src/plugin-sdk/bluebubbles.ts @@ -39,6 +39,7 @@ export { addWildcardAllowFrom, mergeAllowFromEntries, promptAccountId, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { diff --git a/src/plugin-sdk/googlechat.ts b/src/plugin-sdk/googlechat.ts index 7bdc7fb63f8..65a6d0456c0 100644 --- a/src/plugin-sdk/googlechat.ts +++ b/src/plugin-sdk/googlechat.ts @@ -31,6 +31,7 @@ export { addWildcardAllowFrom, mergeAllowFromEntries, promptAccountId, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { diff --git a/src/plugin-sdk/irc.ts b/src/plugin-sdk/irc.ts index 31321801522..128a11fc38e 100644 --- a/src/plugin-sdk/irc.ts +++ b/src/plugin-sdk/irc.ts @@ -15,7 +15,11 @@ export type { ChannelOnboardingDmPolicy, } from "../channels/plugins/onboarding-types.js"; export { promptChannelAccessConfig } from "../channels/plugins/onboarding/channel-access.js"; -export { addWildcardAllowFrom, promptAccountId } from "../channels/plugins/onboarding/helpers.js"; +export { + addWildcardAllowFrom, + promptAccountId, + resolveAccountIdForConfigure, +} from "../channels/plugins/onboarding/helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export type { BaseProbeResult } from "../channels/plugins/types.js"; export type { ChannelPlugin } from "../channels/plugins/types.plugin.js"; diff --git a/src/plugin-sdk/mattermost.ts b/src/plugin-sdk/mattermost.ts index 88ecfa70571..6f074a7cc20 100644 --- a/src/plugin-sdk/mattermost.ts +++ b/src/plugin-sdk/mattermost.ts @@ -32,6 +32,7 @@ export type { ChannelOnboardingAdapter } from "../channels/plugins/onboarding-ty export { promptAccountId, promptSingleChannelSecretInput, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { applyAccountNameToChannelSection, diff --git a/src/plugin-sdk/nextcloud-talk.ts b/src/plugin-sdk/nextcloud-talk.ts index a7b86724a4f..d224ca38da7 100644 --- a/src/plugin-sdk/nextcloud-talk.ts +++ b/src/plugin-sdk/nextcloud-talk.ts @@ -26,6 +26,7 @@ export { mergeAllowFromEntries, promptAccountId, promptSingleChannelSecretInput, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { applyAccountNameToChannelSection } from "../channels/plugins/setup-helpers.js"; export { createAccountListHelpers } from "../channels/plugins/account-helpers.js"; diff --git a/src/plugin-sdk/tlon.ts b/src/plugin-sdk/tlon.ts index fe41eba5687..6858bde8bff 100644 --- a/src/plugin-sdk/tlon.ts +++ b/src/plugin-sdk/tlon.ts @@ -4,7 +4,10 @@ export type { ReplyPayload } from "../auto-reply/types.js"; export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js"; export type { ChannelOnboardingAdapter } from "../channels/plugins/onboarding-types.js"; -export { promptAccountId } from "../channels/plugins/onboarding/helpers.js"; +export { + promptAccountId, + resolveAccountIdForConfigure, +} from "../channels/plugins/onboarding/helpers.js"; export { applyAccountNameToChannelSection } from "../channels/plugins/setup-helpers.js"; export type { ChannelAccountSnapshot, diff --git a/src/plugin-sdk/zalo.ts b/src/plugin-sdk/zalo.ts index 5732a4e138c..3036c216390 100644 --- a/src/plugin-sdk/zalo.ts +++ b/src/plugin-sdk/zalo.ts @@ -20,6 +20,7 @@ export { mergeAllowFromEntries, promptAccountId, promptSingleChannelSecretInput, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { PAIRING_APPROVED_MESSAGE } from "../channels/plugins/pairing-message.js"; export { diff --git a/src/plugin-sdk/zalouser.ts b/src/plugin-sdk/zalouser.ts index e5c076f8ca2..31a580460d6 100644 --- a/src/plugin-sdk/zalouser.ts +++ b/src/plugin-sdk/zalouser.ts @@ -20,6 +20,7 @@ export { addWildcardAllowFrom, mergeAllowFromEntries, promptAccountId, + resolveAccountIdForConfigure, } from "../channels/plugins/onboarding/helpers.js"; export { applyAccountNameToChannelSection,