diff --git a/extensions/discord/src/accounts.ts b/extensions/discord/src/accounts.ts index a623e97446f..6e9d58c97de 100644 --- a/extensions/discord/src/accounts.ts +++ b/extensions/discord/src/accounts.ts @@ -3,10 +3,12 @@ import type { DiscordAccountConfig, DiscordActionConfig, } from "openclaw/plugin-sdk/discord"; -import { createAccountActionGate } from "../../../src/channels/plugins/account-action-gate.js"; -import { createAccountListHelpers } from "../../../src/channels/plugins/account-helpers.js"; -import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; -import { normalizeAccountId } from "../../../src/routing/session-key.js"; +import { + createAccountActionGate, + createAccountListHelpers, + normalizeAccountId, + resolveAccountEntry, +} from "../../../src/plugin-sdk-internal/accounts.js"; import { resolveDiscordToken } from "./token.js"; export type ResolvedDiscordAccount = { diff --git a/extensions/discord/src/draft-chunking.ts b/extensions/discord/src/draft-chunking.ts index 1d56841577a..a6461412ae7 100644 --- a/extensions/discord/src/draft-chunking.ts +++ b/extensions/discord/src/draft-chunking.ts @@ -1,5 +1,5 @@ import { resolveTextChunkLimit } from "../../../src/auto-reply/chunk.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; +import { type OpenClawConfig } from "../../../src/config/config.js"; import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; import { normalizeAccountId } from "../../../src/routing/session-key.js"; import { DISCORD_TEXT_CHUNK_LIMIT } from "./outbound-adapter.js"; diff --git a/extensions/discord/src/setup-core.ts b/extensions/discord/src/setup-core.ts index 3c9ab69059b..6b644fe87c6 100644 --- a/extensions/discord/src/setup-core.ts +++ b/extensions/discord/src/setup-core.ts @@ -1,22 +1,23 @@ +import type { DiscordGuildEntry } from "../../../src/config/types.discord.js"; import { applyAccountNameToChannelSection, + DEFAULT_ACCOUNT_ID, + formatDocsLink, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import { + normalizeAccountId, noteChannelLookupFailure, noteChannelLookupSummary, parseMentionOrPrefixedId, patchChannelConfigForAccount, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import type { DiscordGuildEntry } from "../../../src/config/types.discord.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; + type OpenClawConfig, +} from "../../../src/plugin-sdk-internal/setup.js"; +import { + type ChannelSetupAdapter, + type ChannelSetupDmPolicy, + type ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { inspectDiscordAccount } from "./account-inspect.js"; import { listDiscordAccountIds, resolveDiscordAccount } from "./accounts.js"; diff --git a/extensions/discord/src/setup-surface.ts b/extensions/discord/src/setup-surface.ts index ce7c6e789e4..2a59cbb1ed0 100644 --- a/extensions/discord/src/setup-surface.ts +++ b/extensions/discord/src/setup-surface.ts @@ -1,19 +1,21 @@ import { + DEFAULT_ACCOUNT_ID, + formatDocsLink, noteChannelLookupFailure, noteChannelLookupSummary, + type OpenClawConfig, parseMentionOrPrefixedId, patchChannelConfigForAccount, promptLegacyChannelAllowFrom, resolveSetupAccountId, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import { + type ChannelSetupDmPolicy, + type ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { inspectDiscordAccount } from "./account-inspect.js"; import { listDiscordAccountIds, diff --git a/extensions/discord/src/token.ts b/extensions/discord/src/token.ts index 8f942c6920f..aff802f3ded 100644 --- a/extensions/discord/src/token.ts +++ b/extensions/discord/src/token.ts @@ -1,4 +1,4 @@ -import type { BaseTokenResolution } from "../../../src/channels/plugins/types.js"; +import type { BaseTokenResolution } from "../../../src/channels/plugins/types.core.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { normalizeResolvedSecretInputString } from "../../../src/config/types.secrets.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; diff --git a/extensions/imessage/src/accounts.ts b/extensions/imessage/src/accounts.ts index 1a6ca8bceb9..21c3c36d356 100644 --- a/extensions/imessage/src/accounts.ts +++ b/extensions/imessage/src/accounts.ts @@ -1,7 +1,10 @@ -import { normalizeAccountId, type IMessageAccountConfig } from "openclaw/plugin-sdk/imessage"; -import { createAccountListHelpers } from "../../../src/channels/plugins/account-helpers.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; +import type { IMessageAccountConfig } from "openclaw/plugin-sdk/imessage"; +import { + type OpenClawConfig, + createAccountListHelpers, + normalizeAccountId, + resolveAccountEntry, +} from "../../../src/plugin-sdk-internal/accounts.js"; export type ResolvedIMessageAccount = { accountId: string; diff --git a/extensions/imessage/src/probe.test.ts b/extensions/imessage/src/probe.test.ts index 5d676327c11..5eb406cace8 100644 --- a/extensions/imessage/src/probe.test.ts +++ b/extensions/imessage/src/probe.test.ts @@ -1,36 +1,29 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import * as onboardHelpers from "../../../src/commands/onboard-helpers.js"; +import * as execModule from "../../../src/process/exec.js"; +import * as clientModule from "./client.js"; import { probeIMessage } from "./probe.js"; -const detectBinaryMock = vi.hoisted(() => vi.fn()); -const runCommandWithTimeoutMock = vi.hoisted(() => vi.fn()); -const createIMessageRpcClientMock = vi.hoisted(() => vi.fn()); - -vi.mock("../../../src/commands/onboard-helpers.js", () => ({ - detectBinary: (...args: unknown[]) => detectBinaryMock(...args), -})); - -vi.mock("../../../src/process/exec.js", () => ({ - runCommandWithTimeout: (...args: unknown[]) => runCommandWithTimeoutMock(...args), -})); - -vi.mock("./client.js", () => ({ - createIMessageRpcClient: (...args: unknown[]) => createIMessageRpcClientMock(...args), -})); - beforeEach(() => { - detectBinaryMock.mockClear().mockResolvedValue(true); - runCommandWithTimeoutMock.mockClear().mockResolvedValue({ + vi.restoreAllMocks(); + vi.spyOn(onboardHelpers, "detectBinary").mockResolvedValue(true); + vi.spyOn(execModule, "runCommandWithTimeout").mockResolvedValue({ stdout: "", stderr: 'unknown command "rpc" for "imsg"', code: 1, signal: null, killed: false, }); - createIMessageRpcClientMock.mockClear(); }); describe("probeIMessage", () => { it("marks unknown rpc subcommand as fatal", async () => { + const createIMessageRpcClientMock = vi + .spyOn(clientModule, "createIMessageRpcClient") + .mockResolvedValue({ + request: vi.fn(), + stop: vi.fn(), + } as unknown as Awaited>); const result = await probeIMessage(1000, { cliPath: "imsg" }); expect(result.ok).toBe(false); expect(result.fatal).toBe(true); diff --git a/extensions/imessage/src/setup-core.ts b/extensions/imessage/src/setup-core.ts index 38f280852c0..ada78cc9add 100644 --- a/extensions/imessage/src/setup-core.ts +++ b/extensions/imessage/src/setup-core.ts @@ -1,20 +1,21 @@ import { applyAccountNameToChannelSection, + DEFAULT_ACCOUNT_ID, + formatDocsLink, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import { + normalizeAccountId, parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; + type OpenClawConfig, + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupAdapter, + ChannelSetupDmPolicy, + ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { listIMessageAccountIds, resolveDefaultIMessageAccountId, diff --git a/extensions/imessage/src/setup-surface.ts b/extensions/imessage/src/setup-surface.ts index 0d0de246d7b..b8487dff54d 100644 --- a/extensions/imessage/src/setup-surface.ts +++ b/extensions/imessage/src/setup-surface.ts @@ -1,16 +1,18 @@ import { + DEFAULT_ACCOUNT_ID, + detectBinary, + formatDocsLink, + type OpenClawConfig, parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupDmPolicy, + ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { listIMessageAccountIds, resolveDefaultIMessageAccountId, diff --git a/extensions/signal/src/accounts.ts b/extensions/signal/src/accounts.ts index 38316955edd..0bf9db0e79a 100644 --- a/extensions/signal/src/accounts.ts +++ b/extensions/signal/src/accounts.ts @@ -1,7 +1,10 @@ -import { normalizeAccountId, type SignalAccountConfig } from "openclaw/plugin-sdk/signal"; -import { createAccountListHelpers } from "../../../src/channels/plugins/account-helpers.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; +import type { SignalAccountConfig } from "openclaw/plugin-sdk/signal"; +import { + type OpenClawConfig, + createAccountListHelpers, + normalizeAccountId, + resolveAccountEntry, +} from "../../../src/plugin-sdk-internal/accounts.js"; export type ResolvedSignalAccount = { accountId: string; diff --git a/extensions/signal/src/probe.test.ts b/extensions/signal/src/probe.test.ts index 7250c1de744..30816129107 100644 --- a/extensions/signal/src/probe.test.ts +++ b/extensions/signal/src/probe.test.ts @@ -1,27 +1,20 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import * as clientModule from "./client.js"; import { classifySignalCliLogLine } from "./daemon.js"; import { probeSignal } from "./probe.js"; -const signalCheckMock = vi.fn(); -const signalRpcRequestMock = vi.fn(); - -vi.mock("./client.js", () => ({ - signalCheck: (...args: unknown[]) => signalCheckMock(...args), - signalRpcRequest: (...args: unknown[]) => signalRpcRequestMock(...args), -})); - describe("probeSignal", () => { beforeEach(() => { - vi.clearAllMocks(); + vi.restoreAllMocks(); }); it("extracts version from {version} result", async () => { - signalCheckMock.mockResolvedValueOnce({ + vi.spyOn(clientModule, "signalCheck").mockResolvedValueOnce({ ok: true, status: 200, error: null, }); - signalRpcRequestMock.mockResolvedValueOnce({ version: "0.13.22" }); + vi.spyOn(clientModule, "signalRpcRequest").mockResolvedValueOnce({ version: "0.13.22" }); const res = await probeSignal("http://127.0.0.1:8080", 1000); @@ -31,7 +24,7 @@ describe("probeSignal", () => { }); it("returns ok=false when /check fails", async () => { - signalCheckMock.mockResolvedValueOnce({ + vi.spyOn(clientModule, "signalCheck").mockResolvedValueOnce({ ok: false, status: 503, error: "HTTP 503", diff --git a/extensions/signal/src/setup-core.ts b/extensions/signal/src/setup-core.ts index 40cc99add6e..7e78fbf64a5 100644 --- a/extensions/signal/src/setup-core.ts +++ b/extensions/signal/src/setup-core.ts @@ -1,22 +1,23 @@ import { applyAccountNameToChannelSection, + DEFAULT_ACCOUNT_ID, + formatCliCommand, + formatDocsLink, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import { + normalizeAccountId, + normalizeE164, parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import { normalizeE164 } from "../../../src/utils.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; + type OpenClawConfig, + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupAdapter, + ChannelSetupDmPolicy, + ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { listSignalAccountIds, resolveDefaultSignalAccountId, diff --git a/extensions/signal/src/setup-surface.ts b/extensions/signal/src/setup-surface.ts index d3bd8e0b6de..5c40ba0788e 100644 --- a/extensions/signal/src/setup-surface.ts +++ b/extensions/signal/src/setup-surface.ts @@ -1,18 +1,20 @@ import { + DEFAULT_ACCOUNT_ID, + detectBinary, + formatCliCommand, + formatDocsLink, + installSignalCli, + type OpenClawConfig, parseSetupEntriesAllowingWildcard, promptParsedAllowFromForScopedChannel, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} 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"; -import { installSignalCli } from "../../../src/commands/signal-install.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupDmPolicy, + ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { listSignalAccountIds, resolveDefaultSignalAccountId, diff --git a/extensions/slack/src/accounts.ts b/extensions/slack/src/accounts.ts index 294bbf8956b..51faf8a4a6b 100644 --- a/extensions/slack/src/accounts.ts +++ b/extensions/slack/src/accounts.ts @@ -1,9 +1,12 @@ -import { normalizeChatType } from "../../../src/channels/chat-type.js"; -import { createAccountListHelpers } from "../../../src/channels/plugins/account-helpers.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import type { SlackAccountConfig } from "../../../src/config/types.js"; -import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; +import type { SlackAccountConfig } from "openclaw/plugin-sdk/slack"; +import { + type OpenClawConfig, + createAccountListHelpers, + DEFAULT_ACCOUNT_ID, + normalizeAccountId, + normalizeChatType, + resolveAccountEntry, +} from "../../../src/plugin-sdk-internal/accounts.js"; import type { SlackAccountSurfaceFields } from "./account-surface-fields.js"; import { resolveSlackAppToken, resolveSlackBotToken, resolveSlackUserToken } from "./token.js"; diff --git a/extensions/slack/src/setup-core.ts b/extensions/slack/src/setup-core.ts index 6b32f206d2e..9b8ad30d240 100644 --- a/extensions/slack/src/setup-core.ts +++ b/extensions/slack/src/setup-core.ts @@ -1,8 +1,11 @@ import { applyAccountNameToChannelSection, + DEFAULT_ACCOUNT_ID, + formatDocsLink, + hasConfiguredSecretInput, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import { + normalizeAccountId, + type OpenClawConfig, noteChannelLookupFailure, noteChannelLookupSummary, parseMentionOrPrefixedId, @@ -10,17 +13,13 @@ import { setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-wizard-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; -import type { - ChannelSetupWizard, - ChannelSetupWizardAllowFromEntry, -} 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"; -import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; +} from "../../../src/plugin-sdk-internal/setup.js"; +import { + type ChannelSetupAdapter, + type ChannelSetupDmPolicy, + type ChannelSetupWizard, + type ChannelSetupWizardAllowFromEntry, +} from "../../../src/plugin-sdk-internal/setup.js"; import { inspectSlackAccount } from "./account-inspect.js"; import { listSlackAccountIds, resolveSlackAccount, type ResolvedSlackAccount } from "./accounts.js"; diff --git a/extensions/slack/src/setup-surface.ts b/extensions/slack/src/setup-surface.ts index 5769c4c6d77..6493a17ac79 100644 --- a/extensions/slack/src/setup-surface.ts +++ b/extensions/slack/src/setup-surface.ts @@ -1,6 +1,11 @@ import { + DEFAULT_ACCOUNT_ID, + formatDocsLink, + hasConfiguredSecretInput, noteChannelLookupFailure, noteChannelLookupSummary, + normalizeAccountId, + type OpenClawConfig, parseMentionOrPrefixedId, patchChannelConfigForAccount, promptLegacyChannelAllowFrom, @@ -8,17 +13,13 @@ import { setAccountGroupPolicyForChannel, setLegacyChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, -} from "../../../src/channels/plugins/setup-wizard-helpers.js"; -import type { ChannelSetupDmPolicy } from "../../../src/channels/plugins/setup-wizard-types.js"; + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; import type { + ChannelSetupDmPolicy, ChannelSetupWizard, ChannelSetupWizardAllowFromEntry, -} from "../../../src/channels/plugins/setup-wizard.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; -import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; +} from "../../../src/plugin-sdk-internal/setup.js"; import { inspectSlackAccount } from "./account-inspect.js"; import { listSlackAccountIds, diff --git a/extensions/telegram/src/accounts.test.ts b/extensions/telegram/src/accounts.test.ts index 28af65a5d8a..839e2f64008 100644 --- a/extensions/telegram/src/accounts.test.ts +++ b/extensions/telegram/src/accounts.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../src/config/config.js"; +import * as subsystemModule from "../../../src/logging/subsystem.js"; import { withEnv } from "../../../src/test-utils/env.js"; import { listTelegramAccountIds, @@ -29,15 +30,16 @@ function resolveAccountWithEnv( return withEnv(env, () => resolveTelegramAccount({ cfg, ...(accountId ? { accountId } : {}) })); } -vi.mock("../../../src/logging/subsystem.js", () => ({ - createSubsystemLogger: () => { +beforeEach(() => { + vi.restoreAllMocks(); + vi.spyOn(subsystemModule, "createSubsystemLogger").mockImplementation(() => { const logger = { warn: warnMock, child: () => logger, }; - return logger; - }, -})); + return logger as ReturnType; + }); +}); describe("resolveTelegramAccount", () => { afterEach(() => { diff --git a/extensions/telegram/src/accounts.ts b/extensions/telegram/src/accounts.ts index cff6853a5b1..ab94be5845c 100644 --- a/extensions/telegram/src/accounts.ts +++ b/extensions/telegram/src/accounts.ts @@ -21,7 +21,14 @@ import { } from "../../../src/routing/session-key.js"; import { resolveTelegramToken } from "./token.js"; -const log = createSubsystemLogger("telegram/accounts"); +let log: ReturnType | null = null; + +function getLog() { + if (!log) { + log = createSubsystemLogger("telegram/accounts"); + } + return log; +} function formatDebugArg(value: unknown): string { if (typeof value === "string") { @@ -36,7 +43,7 @@ function formatDebugArg(value: unknown): string { const debugAccounts = (...args: unknown[]) => { if (isTruthyEnvValue(process.env.OPENCLAW_DEBUG_TELEGRAM_ACCOUNTS)) { const parts = args.map((arg) => formatDebugArg(arg)); - log.warn(parts.join(" ").trim()); + getLog().warn(parts.join(" ").trim()); } }; @@ -92,7 +99,7 @@ export function resolveDefaultTelegramAccountId(cfg: OpenClawConfig): string { } if (ids.length > 1 && !emittedMissingDefaultWarn) { emittedMissingDefaultWarn = true; - log.warn( + getLog().warn( `channels.telegram: accounts.default is missing; falling back to "${ids[0]}". ` + `${formatSetExplicitDefaultInstruction("telegram")} to avoid routing surprises in multi-account setups.`, ); diff --git a/extensions/telegram/src/draft-chunking.ts b/extensions/telegram/src/draft-chunking.ts index 951fbb41951..76edc1b1811 100644 --- a/extensions/telegram/src/draft-chunking.ts +++ b/extensions/telegram/src/draft-chunking.ts @@ -1,5 +1,5 @@ import { resolveTextChunkLimit } from "../../../src/auto-reply/chunk.js"; -import type { OpenClawConfig } from "../../../src/config/config.js"; +import { type OpenClawConfig } from "../../../src/config/config.js"; import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; import { normalizeAccountId } from "../../../src/routing/session-key.js"; import { TELEGRAM_TEXT_CHUNK_LIMIT } from "./outbound-adapter.js"; diff --git a/extensions/telegram/src/probe.ts b/extensions/telegram/src/probe.ts index 8a12161470a..dfa7707f144 100644 --- a/extensions/telegram/src/probe.ts +++ b/extensions/telegram/src/probe.ts @@ -1,5 +1,5 @@ +import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/telegram"; import type { BaseProbeResult } from "../../../src/channels/plugins/types.js"; -import type { TelegramNetworkConfig } from "../../../src/config/types.telegram.js"; import { fetchWithTimeout } from "../../../src/utils/fetch-timeout.js"; import { resolveTelegramFetch } from "./fetch.js"; import { makeProxyFetch } from "./proxy.js"; diff --git a/extensions/telegram/src/setup-core.ts b/extensions/telegram/src/setup-core.ts index dedf2ca8527..6ef275ee8b2 100644 --- a/extensions/telegram/src/setup-core.ts +++ b/extensions/telegram/src/setup-core.ts @@ -1,16 +1,20 @@ import { applyAccountNameToChannelSection, + DEFAULT_ACCOUNT_ID, + formatCliCommand, + formatDocsLink, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import { + normalizeAccountId, patchChannelConfigForAccount, + promptResolvedAllowFrom, 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"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; + type OpenClawConfig, + type WizardPrompter, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupAdapter, + ChannelSetupDmPolicy, +} from "../../../src/plugin-sdk-internal/setup.js"; import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js"; import { fetchTelegramChatId } from "./api-fetch.js"; @@ -71,11 +75,7 @@ export async function resolveTelegramAllowFromEntries(params: { export async function promptTelegramAllowFromForAccount(params: { cfg: OpenClawConfig; - prompter: Parameters< - NonNullable< - import("../../../src/channels/plugins/setup-wizard-types.js").ChannelSetupDmPolicy["promptAllowFrom"] - > - >[0]["prompter"]; + prompter: WizardPrompter; accountId?: string; }) { const accountId = params.accountId ?? resolveDefaultTelegramAccountId(params.cfg); @@ -87,8 +87,6 @@ export async function promptTelegramAllowFromForAccount(params: { "Telegram", ); } - const { promptResolvedAllowFrom } = - await import("../../../src/channels/plugins/setup-wizard-helpers.runtime.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 d0f122af174..7d95f40728b 100644 --- a/extensions/telegram/src/setup-surface.ts +++ b/extensions/telegram/src/setup-surface.ts @@ -1,14 +1,16 @@ import { + DEFAULT_ACCOUNT_ID, + hasConfiguredSecretInput, + type OpenClawConfig, patchChannelConfigForAccount, setChannelDmPolicyWithAllowFrom, setSetupChannelEnabled, splitSetupEntries, -} 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"; -import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js"; +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { + ChannelSetupDmPolicy, + ChannelSetupWizard, +} from "../../../src/plugin-sdk-internal/setup.js"; import { inspectTelegramAccount } from "./account-inspect.js"; import { listTelegramAccountIds, resolveTelegramAccount } from "./accounts.js"; import { diff --git a/extensions/telegram/src/token.ts b/extensions/telegram/src/token.ts index 827b4899e21..e0009d6b76a 100644 --- a/extensions/telegram/src/token.ts +++ b/extensions/telegram/src/token.ts @@ -1,7 +1,7 @@ -import type { BaseTokenResolution } from "../../../src/channels/plugins/types.js"; +import type { TelegramAccountConfig } from "openclaw/plugin-sdk/telegram"; +import type { BaseTokenResolution } from "../../../src/channels/plugins/types.core.js"; import type { OpenClawConfig } from "../../../src/config/config.js"; import { normalizeResolvedSecretInputString } from "../../../src/config/types.secrets.js"; -import type { TelegramAccountConfig } from "../../../src/config/types.telegram.js"; import { tryReadSecretFileSync } from "../../../src/infra/secret-file.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; diff --git a/extensions/whatsapp/src/accounts.ts b/extensions/whatsapp/src/accounts.ts index 53e73128894..c607840dcd3 100644 --- a/extensions/whatsapp/src/accounts.ts +++ b/extensions/whatsapp/src/accounts.ts @@ -1,16 +1,15 @@ import fs from "node:fs"; import path from "node:path"; -import type { - DmPolicy, - GroupPolicy, - OpenClawConfig, - WhatsAppAccountConfig, -} from "openclaw/plugin-sdk/whatsapp"; -import { createAccountListHelpers } from "../../../src/channels/plugins/account-helpers.js"; +import type { DmPolicy, GroupPolicy, WhatsAppAccountConfig } from "openclaw/plugin-sdk/whatsapp"; import { resolveOAuthDir } from "../../../src/config/paths.js"; -import { resolveAccountEntry } from "../../../src/routing/account-lookup.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { resolveUserPath } from "../../../src/utils.js"; +import { + type OpenClawConfig, + createAccountListHelpers, + DEFAULT_ACCOUNT_ID, + normalizeAccountId, + resolveAccountEntry, + resolveUserPath, +} from "../../../src/plugin-sdk-internal/accounts.js"; import { hasWebCredsSync } from "./auth-store.js"; export type ResolvedWhatsAppAccount = { diff --git a/extensions/whatsapp/src/setup-core.ts b/extensions/whatsapp/src/setup-core.ts index 2b243743076..a4471eb8188 100644 --- a/extensions/whatsapp/src/setup-core.ts +++ b/extensions/whatsapp/src/setup-core.ts @@ -1,9 +1,9 @@ import { applyAccountNameToChannelSection, + type ChannelSetupAdapter, migrateBaseNameToDefaultAccount, -} from "../../../src/channels/plugins/setup-helpers.js"; -import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js"; -import { normalizeAccountId } from "../../../src/routing/session-key.js"; + normalizeAccountId, +} from "../../../src/plugin-sdk-internal/setup.js"; const channel = "whatsapp" as const; diff --git a/extensions/whatsapp/src/setup-surface.ts b/extensions/whatsapp/src/setup-surface.ts index 4210b5772af..21e1803263c 100644 --- a/extensions/whatsapp/src/setup-surface.ts +++ b/extensions/whatsapp/src/setup-surface.ts @@ -1,23 +1,48 @@ import path from "node:path"; -import { loginWeb } from "../../../src/channel-web.js"; import { + DEFAULT_ACCOUNT_ID, + type DmPolicy, + formatCliCommand, + formatDocsLink, + normalizeAccountId, normalizeAllowFromEntries, + normalizeE164, + pathExists, splitSetupEntries, -} 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"; -import { mergeWhatsAppConfig } from "../../../src/config/merge-config.js"; -import type { DmPolicy } from "../../../src/config/types.js"; -import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js"; -import { formatDocsLink } from "../../../src/terminal/links.js"; -import { normalizeE164, pathExists } from "../../../src/utils.js"; + setSetupChannelEnabled, + type OpenClawConfig, +} from "../../../src/plugin-sdk-internal/setup.js"; +import type { ChannelSetupWizard } from "../../../src/plugin-sdk-internal/setup.js"; import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js"; +import { loginWeb } from "./login.js"; import { whatsappSetupAdapter } from "./setup-core.js"; const channel = "whatsapp" as const; +function mergeWhatsAppConfig( + cfg: OpenClawConfig, + patch: Partial["whatsapp"]>, + options?: { unsetOnUndefined?: string[] }, +): OpenClawConfig { + const base = { ...(cfg.channels?.whatsapp ?? {}) } as Record; + for (const [key, value] of Object.entries(patch)) { + if (value === undefined) { + if (options?.unsetOnUndefined?.includes(key)) { + delete base[key]; + } + continue; + } + base[key] = value; + } + return { + ...cfg, + channels: { + ...cfg.channels, + whatsapp: base, + }, + }; +} + function setWhatsAppDmPolicy(cfg: OpenClawConfig, dmPolicy: DmPolicy): OpenClawConfig { return mergeWhatsAppConfig(cfg, { dmPolicy }); } diff --git a/src/plugin-sdk-internal/accounts.ts b/src/plugin-sdk-internal/accounts.ts new file mode 100644 index 00000000000..853d41c5f42 --- /dev/null +++ b/src/plugin-sdk-internal/accounts.ts @@ -0,0 +1,8 @@ +export type { OpenClawConfig } from "../config/config.js"; + +export { createAccountActionGate } from "../channels/plugins/account-action-gate.js"; +export { createAccountListHelpers } from "../channels/plugins/account-helpers.js"; +export { normalizeChatType } from "../channels/chat-type.js"; +export { resolveAccountEntry } from "../routing/account-lookup.js"; +export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; +export { normalizeE164, pathExists, resolveUserPath } from "../utils.js"; diff --git a/src/plugin-sdk-internal/setup.ts b/src/plugin-sdk-internal/setup.ts new file mode 100644 index 00000000000..6caf9253e14 --- /dev/null +++ b/src/plugin-sdk-internal/setup.ts @@ -0,0 +1,37 @@ +export type { OpenClawConfig } from "../config/config.js"; +export type { WizardPrompter } from "../wizard/prompts.js"; +export type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js"; +export type { ChannelSetupDmPolicy } from "../channels/plugins/setup-wizard-types.js"; +export type { + ChannelSetupWizard, + ChannelSetupWizardAllowFromEntry, +} from "../channels/plugins/setup-wizard.js"; + +export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; +export { + applyAccountNameToChannelSection, + migrateBaseNameToDefaultAccount, +} from "../channels/plugins/setup-helpers.js"; +export { + normalizeAllowFromEntries, + noteChannelLookupFailure, + noteChannelLookupSummary, + parseMentionOrPrefixedId, + parseSetupEntriesAllowingWildcard, + patchChannelConfigForAccount, + promptLegacyChannelAllowFrom, + promptParsedAllowFromForScopedChannel, + promptResolvedAllowFrom, + resolveSetupAccountId, + setAccountGroupPolicyForChannel, + setChannelDmPolicyWithAllowFrom, + setLegacyChannelDmPolicyWithAllowFrom, + setSetupChannelEnabled, + splitSetupEntries, +} from "../channels/plugins/setup-wizard-helpers.js"; +export { detectBinary } from "../commands/onboard-helpers.js"; +export { installSignalCli } from "../commands/signal-install.js"; +export { formatCliCommand } from "../cli/command-format.js"; +export { formatDocsLink } from "../terminal/links.js"; +export { hasConfiguredSecretInput } from "../config/types.secrets.js"; +export { normalizeE164, pathExists } from "../utils.js"; diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index e43be3bfadd..721e9da25e6 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -1,4 +1,5 @@ export { createAccountListHelpers } from "../channels/plugins/account-helpers.js"; +export { createAccountActionGate } from "../channels/plugins/account-action-gate.js"; export { CHANNEL_MESSAGE_ACTION_NAMES } from "../channels/plugins/message-action-names.js"; export { BLUEBUBBLES_ACTIONS, @@ -61,6 +62,27 @@ export type { BaseTokenResolution, } from "../channels/plugins/types.js"; export type { ChannelConfigSchema, ChannelPlugin } from "../channels/plugins/types.plugin.js"; +export type { + ChannelSetupConfigureContext, + ChannelSetupDmPolicy, + ChannelSetupInteractiveContext, + ChannelSetupPlugin, + ChannelSetupResult, + ChannelSetupStatus, + ChannelSetupStatusContext, + ChannelSetupWizardAdapter, +} from "../channels/plugins/setup-wizard-types.js"; +export type { + ChannelSetupWizard, + ChannelSetupWizardAllowFromEntry, + ChannelSetupWizardCredential, + ChannelSetupWizardCredentialState, + ChannelSetupWizardFinalize, + ChannelSetupWizardGroupAccess, + ChannelSetupWizardPrepare, + ChannelSetupWizardStatus, + ChannelSetupWizardTextInput, +} from "../channels/plugins/setup-wizard.js"; export type { AcpRuntimeCapabilities, AcpRuntimeControl, @@ -222,6 +244,21 @@ export { createDefaultChannelRuntimeState, } from "./status-helpers.js"; export { + normalizeAllowFromEntries, + noteChannelLookupFailure, + noteChannelLookupSummary, + parseMentionOrPrefixedId, + parseSetupEntriesAllowingWildcard, + patchChannelConfigForAccount, + promptLegacyChannelAllowFrom, + promptParsedAllowFromForScopedChannel, + promptResolvedAllowFrom, + resolveSetupAccountId, + setAccountGroupPolicyForChannel, + setChannelDmPolicyWithAllowFrom, + setLegacyChannelDmPolicyWithAllowFrom, + setSetupChannelEnabled, + splitSetupEntries, promptSingleChannelSecretInput, type SingleChannelSecretInputPromptResult, } from "../channels/plugins/setup-wizard-helpers.js"; @@ -356,6 +393,7 @@ export { listConfiguredAccountIds, resolveAccountWithDefaultFallback, } from "./account-resolution.js"; +export { resolveAccountEntry } from "../routing/account-lookup.js"; export { issuePairingChallenge } from "../pairing/pairing-challenge.js"; export { handleSlackMessageAction } from "./slack-message-actions.js"; export { extractToolSend } from "./tool-send.js"; @@ -385,7 +423,10 @@ export { resolveRuntimeEnv, resolveRuntimeEnvWithUnavailableExit, } from "./runtime.js"; +export { detectBinary } from "../commands/onboard-helpers.js"; +export { installSignalCli } from "../commands/signal-install.js"; export { chunkTextForOutbound } from "./text-chunking.js"; +export { resolveTextChunkLimit } from "../auto-reply/chunk.js"; export { readBooleanParam } from "./boolean-param.js"; export { readJsonFileWithFallback, writeJsonFileAtomically } from "./json-store.js"; export { generatePkceVerifierChallenge, toFormUrlEncoded } from "./oauth-utils.js"; @@ -420,6 +461,7 @@ export type { TailscaleStatusCommandRunner, } from "../shared/tailscale-status.js"; export type { ChatType } from "../channels/chat-type.js"; +export { normalizeChatType } from "../channels/chat-type.js"; /** @deprecated Use ChatType instead */ export type { RoutePeerKind } from "../routing/resolve-route.js"; export { resolveAckReaction } from "../agents/identity.js"; @@ -453,6 +495,7 @@ export type { PersistentDedupeOptions, } from "./persistent-dedupe.js"; export { formatErrorMessage } from "../infra/errors.js"; +export { resolveFetch } from "../infra/fetch.js"; export { formatUtcTimestamp, formatZonedTimestamp, @@ -619,6 +662,7 @@ export { readStringParam, } from "../agents/tools/common.js"; export { formatDocsLink } from "../terminal/links.js"; +export { formatCliCommand } from "../cli/command-format.js"; export { DM_GROUP_ACCESS_REASON, readStoreAllowFromForDmPolicy, @@ -630,7 +674,23 @@ export { } from "../security/dm-policy-shared.js"; export type { DmGroupAccessReasonCode } from "../security/dm-policy-shared.js"; export type { HookEntry } from "../hooks/types.js"; -export { clamp, escapeRegExp, normalizeE164, safeParseJson, sleep } from "../utils.js"; +export { + clamp, + escapeRegExp, + isRecord, + normalizeE164, + pathExists, + resolveUserPath, + safeParseJson, + sleep, +} from "../utils.js"; +export { fetchWithTimeout } from "../utils/fetch-timeout.js"; +export { + DEFAULT_SECRET_FILE_MAX_BYTES, + loadSecretFileSync, + readSecretFileSync, + tryReadSecretFileSync, +} from "../infra/secret-file.js"; export { stripAnsi } from "../terminal/ansi.js"; export { missingTargetError } from "../infra/outbound/target-errors.js"; export { registerLogTransport } from "../logging/logger.js"; @@ -656,6 +716,8 @@ export type { DiagnosticWebhookProcessedEvent, DiagnosticWebhookReceivedEvent, } from "../infra/diagnostic-events.js"; +export { loadConfig } from "../config/config.js"; +export { runCommandWithTimeout } from "../process/exec.js"; export { detectMime, extensionForMime, getFileExtension } from "../media/mime.js"; export { extractOriginalFilename } from "../media/store.js"; export { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js"; diff --git a/src/plugin-sdk/telegram.ts b/src/plugin-sdk/telegram.ts index 2eed87097f0..3e1275c1425 100644 --- a/src/plugin-sdk/telegram.ts +++ b/src/plugin-sdk/telegram.ts @@ -4,24 +4,25 @@ export type { ChannelMessageActionAdapter, } from "../channels/plugins/types.js"; export type { OpenClawConfig } from "../config/config.js"; -export type { TelegramAccountConfig, TelegramActionConfig } from "../config/types.js"; +export type { PluginRuntime } from "../plugins/runtime/types.js"; +export type { OpenClawPluginApi } from "../plugins/types.js"; export type { - ChannelMessageActionContext, - ChannelPlugin, - OpenClawPluginApi, - PluginRuntime, -} from "./channel-plugin-common.js"; + TelegramAccountConfig, + TelegramActionConfig, + TelegramNetworkConfig, +} from "../config/types.js"; + +export { emptyPluginConfigSchema } from "../plugins/config-schema.js"; +export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; + export { - DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, applyAccountNameToChannelSection, buildChannelConfigSchema, deleteAccountFromConfigSection, - emptyPluginConfigSchema, formatPairingApproveHint, getChatChannelMeta, migrateBaseNameToDefaultAccount, - normalizeAccountId, setAccountEnabledInConfigSection, } from "./channel-plugin-common.js";