refactor: clean extension api boundaries

This commit is contained in:
Peter Steinberger
2026-03-17 09:33:17 -07:00
parent 4d8106eece
commit 4b125762f6
147 changed files with 699 additions and 364 deletions

View File

@@ -0,0 +1 @@
export { bluebubblesPlugin } from "./src/channel.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { bluebubblesPlugin } from "./src/channel.js";
import { setBlueBubblesRuntime } from "./src/runtime.js";
export { bluebubblesPlugin } from "./src/channel.js";
export { setBlueBubblesRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "bluebubbles",
name: "BlueBubbles",

13
extensions/discord/api.ts Normal file
View File

@@ -0,0 +1,13 @@
export * from "./runtime-api.js";
export * from "./src/account-inspect.js";
export * from "./src/accounts.js";
export * from "./src/actions/handle-action.guild-admin.js";
export * from "./src/actions/handle-action.js";
export * from "./src/components.js";
export * from "./src/normalize.js";
export * from "./src/pluralkit.js";
export * from "./src/session-key-normalization.js";
export * from "./src/status-issues.js";
export * from "./src/targets.js";
export type { DiscordSendComponents, DiscordSendEmbeds } from "./src/send.shared.js";
export type { DiscordSendResult } from "./src/send.types.js";

View File

@@ -3,6 +3,9 @@ import { discordPlugin } from "./src/channel.js";
import { setDiscordRuntime } from "./src/runtime.js";
import { registerDiscordSubagentHooks } from "./src/subagent-hooks.js";
export { discordPlugin } from "./src/channel.js";
export { setDiscordRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "discord",
name: "Discord",

View File

@@ -0,0 +1,14 @@
export * from "./src/audit.js";
export * from "./src/channel-actions.js";
export * from "./src/directory-live.js";
export * from "./src/monitor.js";
export * from "./src/monitor/gateway-plugin.js";
export * from "./src/monitor/gateway-registry.js";
export * from "./src/monitor/presence-cache.js";
export * from "./src/monitor/thread-bindings.js";
export * from "./src/monitor/thread-bindings.manager.js";
export * from "./src/monitor/timeouts.js";
export * from "./src/probe.js";
export * from "./src/resolve-channels.js";
export * from "./src/resolve-users.js";
export * from "./src/send.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { discordSetupPlugin } from "./src/channel.setup.js";
export { discordSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(discordSetupPlugin);

View File

@@ -55,7 +55,7 @@ import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
import { chunkItems } from "openclaw/plugin-sdk/text-runtime";
import { withTimeout } from "openclaw/plugin-sdk/text-runtime";
import { loadWebMedia } from "../../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import { resolveDiscordMaxLinesPerMessage } from "../accounts.js";
import { chunkDiscordTextWithMode } from "../chunk.js";
import {

View File

@@ -7,7 +7,7 @@ import {
import { ChannelType, Routes } from "discord-api-types/v10";
import { loadConfig, type OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { recordChannelActivity } from "openclaw/plugin-sdk/infra-runtime";
import { loadWebMedia } from "../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import { resolveDiscordAccount } from "./accounts.js";
import { registerDiscordComponentEntries } from "./components-registry.js";
import {

View File

@@ -1,5 +1,5 @@
import { Routes } from "discord-api-types/v10";
import { loadWebMediaRaw } from "../../whatsapp/src/media.js";
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
import { normalizeEmojiName, resolveDiscordRest } from "./send.shared.js";
import type { DiscordEmojiUpload, DiscordReactOpts, DiscordStickerUpload } from "./send.types.js";
import { DISCORD_MAX_EMOJI_BYTES, DISCORD_MAX_STICKER_BYTES } from "./send.types.js";

View File

@@ -14,7 +14,7 @@ import { unlinkIfExists } from "openclaw/plugin-sdk/media-runtime";
import type { PollInput } from "openclaw/plugin-sdk/media-runtime";
import { resolveChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
import { loadWebMediaRaw } from "../../whatsapp/src/media.js";
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
import { resolveDiscordAccount } from "./accounts.js";
import { rewriteDiscordKnownMentions } from "./mentions.js";
import {

View File

@@ -18,7 +18,7 @@ import {
type PollInput,
} from "openclaw/plugin-sdk/media-runtime";
import type { ChunkMode } from "openclaw/plugin-sdk/reply-runtime";
import { loadWebMedia } from "../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import { resolveDiscordAccount } from "./accounts.js";
import { chunkDiscordTextWithMode } from "./chunk.js";
import { createDiscordClient, resolveDiscordRest } from "./client.js";

View File

@@ -17,6 +17,7 @@ import {
type ChannelSetupDmPolicy,
type ChannelSetupWizard,
} from "openclaw/plugin-sdk/setup";
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { inspectDiscordAccount } from "./account-inspect.js";
import { listDiscordAccountIds, resolveDiscordAccount } from "./accounts.js";

View File

@@ -6,6 +6,7 @@ import {
type WizardPrompter,
} from "openclaw/plugin-sdk/setup";
import { type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { resolveDefaultDiscordAccountId, resolveDiscordAccount } from "./accounts.js";
import { normalizeDiscordSlug } from "./monitor/allow-list.js";
import {

View File

@@ -3,7 +3,12 @@ import {
createScopedAccountConfigAccessors,
createScopedChannelConfigBase,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { getChatChannelMeta, type ChannelPlugin } from "openclaw/plugin-sdk/core";
import {
buildChannelConfigSchema,
DiscordConfigSchema,
getChatChannelMeta,
type ChannelPlugin,
} from "openclaw/plugin-sdk/discord-core";
import { inspectDiscordAccount } from "./account-inspect.js";
import {
listDiscordAccountIds,
@@ -40,7 +45,6 @@ export const discordConfigBase = createScopedChannelConfigBase<ResolvedDiscordAc
});
export function createDiscordPluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedDiscordAccount>, "configSchema">["configSchema"];
setup: NonNullable<ChannelPlugin<ResolvedDiscordAccount>["setup"]>;
}): Pick<
ChannelPlugin<ResolvedDiscordAccount>,
@@ -72,7 +76,7 @@ export function createDiscordPluginBase(params: {
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
},
reload: { configPrefixes: ["channels.discord"] },
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(DiscordConfigSchema),
config: {
...discordConfigBase,
isConfigured: (account) => Boolean(account.token?.trim()),

4
extensions/feishu/api.ts Normal file
View File

@@ -0,0 +1,4 @@
export * from "./src/conversation-id.js";
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";
export * from "./src/thread-bindings.js";

View File

@@ -9,6 +9,8 @@ import { setFeishuRuntime } from "./src/runtime.js";
import { registerFeishuSubagentHooks } from "./src/subagent-hooks.js";
import { registerFeishuWikiTools } from "./src/wiki.js";
export { feishuPlugin } from "./src/channel.js";
export { setFeishuRuntime } from "./src/runtime.js";
export { monitorFeishuProvider } from "./src/monitor.js";
export {
sendMessageFeishu,

View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { googlechatPlugin } from "./src/channel.js";
import { setGoogleChatRuntime } from "./src/runtime.js";
export { googlechatPlugin } from "./src/channel.js";
export { setGoogleChatRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "googlechat",
name: "Google Chat",

View File

@@ -0,0 +1,4 @@
export * from "./runtime-api.js";
export * from "./src/accounts.js";
export * from "./src/target-parsing-helpers.js";
export * from "./src/targets.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { imessagePlugin } from "./src/channel.js";
import { setIMessageRuntime } from "./src/runtime.js";
export { imessagePlugin } from "./src/channel.js";
export { setIMessageRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "imessage",
name: "iMessage",

View File

@@ -0,0 +1,3 @@
export * from "./src/monitor.js";
export * from "./src/probe.js";
export * from "./src/send.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { imessageSetupPlugin } from "./src/channel.setup.js";
export { imessageSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(imessageSetupPlugin);

View File

@@ -14,6 +14,7 @@ import type {
ChannelSetupWizard,
ChannelSetupWizardTextInput,
} from "openclaw/plugin-sdk/setup";
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import {
listIMessageAccountIds,
resolveDefaultIMessageAccountId,

View File

@@ -1,5 +1,5 @@
import { detectBinary } from "openclaw/plugin-sdk/imessage";
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
import { detectBinary } from "openclaw/plugin-sdk/setup-tools";
import { listIMessageAccountIds, resolveIMessageAccount } from "./accounts.js";
import {
createIMessageCliPathTextInput,

View File

@@ -1,19 +1,19 @@
import {
formatTrimmedAllowFromEntries,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
} from "openclaw/plugin-sdk/channel-config-helpers";
import {
buildAccountScopedDmSecurityPolicy,
collectAllowlistProviderRestrictSendersWarnings,
} from "openclaw/plugin-sdk/channel-policy";
import {
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
deleteAccountFromConfigSection,
formatTrimmedAllowFromEntries,
getChatChannelMeta,
IMessageConfigSchema,
resolveIMessageConfigAllowFrom,
resolveIMessageConfigDefaultTo,
setAccountEnabledInConfigSection,
type ChannelPlugin,
} from "openclaw/plugin-sdk/core";
} from "openclaw/plugin-sdk/imessage-core";
import {
listIMessageAccountIds,
resolveDefaultIMessageAccountId,
@@ -33,7 +33,6 @@ export const imessageSetupWizard = createIMessageSetupWizardProxy(async () => ({
}));
export function createIMessagePluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedIMessageAccount>, "configSchema">["configSchema"];
setupWizard?: NonNullable<ChannelPlugin<ResolvedIMessageAccount>["setupWizard"]>;
setup: NonNullable<ChannelPlugin<ResolvedIMessageAccount>["setup"]>;
}): Pick<
@@ -61,7 +60,7 @@ export function createIMessagePluginBase(params: {
media: true,
},
reload: { configPrefixes: ["channels.imessage"] },
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(IMessageConfigSchema),
config: {
listAccountIds: (cfg) => listIMessageAccountIds(cfg),
resolveAccount: (cfg, accountId) => resolveIMessageAccount({ cfg, accountId }),

2
extensions/irc/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./src/accounts.js";
export * from "./src/setup-surface.js";

View File

@@ -3,6 +3,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { ircPlugin } from "./src/channel.js";
import { setIrcRuntime } from "./src/runtime.js";
export { ircPlugin } from "./src/channel.js";
export { setIrcRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "irc",
name: "IRC",

2
extensions/line/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -3,6 +3,9 @@ import { registerLineCardCommand } from "./src/card-command.js";
import { linePlugin } from "./src/channel.js";
import { setLineRuntime } from "./src/runtime.js";
export { linePlugin } from "./src/channel.js";
export { setLineRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "line",
name: "LINE",

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { lineSetupPlugin } from "./src/channel.setup.js";
export { lineSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(lineSetupPlugin);

2
extensions/matrix/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { matrixPlugin } from "./src/channel.js";
import { setMatrixRuntime } from "./src/runtime.js";
export { matrixPlugin } from "./src/channel.js";
export { setMatrixRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "matrix",
name: "Matrix",

View File

@@ -0,0 +1 @@
export { mattermostPlugin } from "./src/channel.js";

View File

@@ -3,6 +3,9 @@ import { mattermostPlugin } from "./src/channel.js";
import { registerSlashCommandRoute } from "./src/mattermost/slash-state.js";
import { setMattermostRuntime } from "./src/runtime.js";
export { mattermostPlugin } from "./src/channel.js";
export { setMattermostRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "mattermost",
name: "Mattermost",

View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { msteamsPlugin } from "./src/channel.js";
import { setMSTeamsRuntime } from "./src/runtime.js";
export { msteamsPlugin } from "./src/channel.js";
export { setMSTeamsRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "msteams",
name: "Microsoft Teams",

View File

@@ -0,0 +1 @@
export { nextcloudTalkPlugin } from "./src/channel.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { nextcloudTalkPlugin } from "./src/channel.js";
import { setNextcloudTalkRuntime } from "./src/runtime.js";
export { nextcloudTalkPlugin } from "./src/channel.js";
export { setNextcloudTalkRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "nextcloud-talk",
name: "Nextcloud Talk",

1
extensions/nostr/api.ts Normal file
View File

@@ -0,0 +1 @@
export * from "./src/setup-surface.js";

View File

@@ -5,6 +5,9 @@ import { createNostrProfileHttpHandler } from "./src/nostr-profile-http.js";
import { getNostrRuntime, setNostrRuntime } from "./src/runtime.js";
import { resolveNostrAccount } from "./src/types.js";
export { nostrPlugin } from "./src/channel.js";
export { setNostrRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "nostr",
name: "Nostr",

2
extensions/signal/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./runtime-api.js";
export * from "./src/accounts.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { signalPlugin } from "./src/channel.js";
import { setSignalRuntime } from "./src/runtime.js";
export { signalPlugin } from "./src/channel.js";
export { setSignalRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "signal",
name: "Signal",

View File

@@ -0,0 +1 @@
export * from "./src/index.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { signalSetupPlugin } from "./src/channel.setup.js";
export { signalSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(signalSetupPlugin);

View File

@@ -14,7 +14,7 @@ import type {
ChannelSetupWizard,
ChannelSetupWizardTextInput,
} from "openclaw/plugin-sdk/setup";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/signal";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import {
listSignalAccountIds,
resolveDefaultSignalAccountId,

View File

@@ -1,5 +1,5 @@
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
import { detectBinary, installSignalCli } from "openclaw/plugin-sdk/signal";
import { detectBinary, installSignalCli } from "openclaw/plugin-sdk/setup-tools";
import { listSignalAccountIds, resolveSignalAccount } from "./accounts.js";
import {
createSignalCliPathTextInput,

View File

@@ -4,13 +4,15 @@ import {
collectAllowlistProviderRestrictSendersWarnings,
} from "openclaw/plugin-sdk/channel-policy";
import {
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
deleteAccountFromConfigSection,
getChatChannelMeta,
normalizeE164,
setAccountEnabledInConfigSection,
SignalConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/core";
import { normalizeE164 } from "openclaw/plugin-sdk/setup";
} from "openclaw/plugin-sdk/signal-core";
import {
listSignalAccountIds,
resolveDefaultSignalAccountId,
@@ -42,7 +44,6 @@ export const signalConfigAccessors = createScopedAccountConfigAccessors({
});
export function createSignalPluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedSignalAccount>, "configSchema">["configSchema"];
setupWizard?: NonNullable<ChannelPlugin<ResolvedSignalAccount>["setupWizard"]>;
setup: NonNullable<ChannelPlugin<ResolvedSignalAccount>["setup"]>;
}): Pick<
@@ -73,7 +74,7 @@ export function createSignalPluginBase(params: {
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
},
reload: { configPrefixes: ["channels.signal"] },
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(SignalConfigSchema),
config: {
listAccountIds: (cfg) => listSignalAccountIds(cfg),
resolveAccount: (cfg, accountId) => resolveSignalAccount({ cfg, accountId }),

12
extensions/slack/api.ts Normal file
View File

@@ -0,0 +1,12 @@
export * from "./runtime-api.js";
export * from "./src/account-inspect.js";
export * from "./src/accounts.js";
export * from "./src/actions.js";
export * from "./src/blocks-input.js";
export * from "./src/blocks-render.js";
export * from "./src/http/index.js";
export * from "./src/interactive-replies.js";
export * from "./src/message-actions.js";
export * from "./src/sent-thread-cache.js";
export * from "./src/targets.js";
export * from "./src/threading-tool-context.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { slackPlugin } from "./src/channel.js";
import { setSlackRuntime } from "./src/runtime.js";
export { slackPlugin } from "./src/channel.js";
export { setSlackRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "slack",
name: "Slack",

View File

@@ -0,0 +1,4 @@
export * from "./src/directory-live.js";
export * from "./src/index.js";
export * from "./src/resolve-channels.js";
export * from "./src/resolve-users.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { slackSetupPlugin } from "./src/channel.setup.js";
export { slackSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(slackSetupPlugin);

View File

@@ -12,7 +12,7 @@ import {
} from "openclaw/plugin-sdk/reply-runtime";
import { isSilentReplyText } from "openclaw/plugin-sdk/reply-runtime";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { loadWebMedia } from "../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import type { SlackTokenSource } from "./accounts.js";
import { resolveSlackAccount } from "./accounts.js";
import { buildSlackBlocksFallbackText } from "./blocks-fallback.js";

View File

@@ -18,7 +18,7 @@ import {
type ChannelSetupWizard,
type ChannelSetupWizardAllowFromEntry,
} from "openclaw/plugin-sdk/setup";
import { formatDocsLink } from "openclaw/plugin-sdk/slack";
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { inspectSlackAccount } from "./account-inspect.js";
import { listSlackAccountIds, resolveSlackAccount, type ResolvedSlackAccount } from "./accounts.js";
import {

View File

@@ -11,7 +11,7 @@ import type {
ChannelSetupWizard,
ChannelSetupWizardAllowFromEntry,
} from "openclaw/plugin-sdk/setup";
import { formatDocsLink } from "openclaw/plugin-sdk/slack";
import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { resolveDefaultSlackAccountId, resolveSlackAccount } from "./accounts.js";
import { resolveSlackChannelAllowlist } from "./resolve-channels.js";
import { resolveSlackUserAllowlist } from "./resolve-users.js";

View File

@@ -3,13 +3,18 @@ import {
createScopedAccountConfigAccessors,
createScopedChannelConfigBase,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { getChatChannelMeta, type ChannelPlugin } from "openclaw/plugin-sdk/core";
import {
formatDocsLink,
hasConfiguredSecretInput,
patchChannelConfigForAccount,
type OpenClawConfig,
} from "openclaw/plugin-sdk/setup";
import {
buildChannelConfigSchema,
getChatChannelMeta,
SlackConfigSchema,
type ChannelPlugin,
type OpenClawConfig,
} from "openclaw/plugin-sdk/slack-core";
import { inspectSlackAccount } from "./account-inspect.js";
import {
listSlackAccountIds,
@@ -156,7 +161,6 @@ export const slackConfigBase = createScopedChannelConfigBase({
});
export function createSlackPluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedSlackAccount>, "configSchema">["configSchema"];
setupWizard: NonNullable<ChannelPlugin<ResolvedSlackAccount>["setupWizard"]>;
setup: NonNullable<ChannelPlugin<ResolvedSlackAccount>["setup"]>;
}): Pick<
@@ -201,7 +205,7 @@ export function createSlackPluginBase(params: {
blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
},
reload: { configPrefixes: ["channels.slack"] },
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(SlackConfigSchema),
config: {
...slackConfigBase,
isConfigured: (account) => isSlackPluginAccountConfigured(account),

View File

@@ -0,0 +1 @@
export * from "./src/setup-surface.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { synologyChatPlugin } from "./src/channel.js";
import { setSynologyRuntime } from "./src/runtime.js";
export { synologyChatPlugin } from "./src/channel.js";
export { setSynologyRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "synology-chat",
name: "Synology Chat",

View File

@@ -0,0 +1,18 @@
export * from "./runtime-api.js";
export * from "./src/account-inspect.js";
export * from "./src/accounts.js";
export * from "./src/allow-from.js";
export * from "./src/api-fetch.js";
export * from "./src/exec-approvals.js";
export * from "./src/inline-buttons.js";
export * from "./src/model-buttons.js";
export * from "./src/normalize.js";
export * from "./src/outbound-adapter.js";
export * from "./src/outbound-params.js";
export * from "./src/reaction-level.js";
export * from "./src/sticker-cache.js";
export * from "./src/status-issues.js";
export * from "./src/targets.js";
export * from "./src/update-offset-store.js";
export type { TelegramButtonStyle, TelegramInlineButtons } from "./src/button-types.js";
export type { StickerMetadata } from "./src/bot/types.js";

View File

@@ -3,6 +3,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { telegramPlugin } from "./src/channel.js";
import { setTelegramRuntime } from "./src/runtime.js";
export { telegramPlugin } from "./src/channel.js";
export { setTelegramRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "telegram",
name: "Telegram",

View File

@@ -0,0 +1,7 @@
export * from "./src/audit.js";
export * from "./src/channel-actions.js";
export * from "./src/monitor.js";
export * from "./src/probe.js";
export * from "./src/send.js";
export * from "./src/thread-bindings.js";
export * from "./src/token.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { telegramSetupPlugin } from "./src/channel.setup.js";
export { telegramSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(telegramSetupPlugin);

View File

@@ -20,7 +20,7 @@ export function getLoadWebMediaMock(): AnyMock {
return loadWebMedia;
}
vi.mock("../../whatsapp/src/media.js", () => ({
vi.mock("openclaw/plugin-sdk/web-media", () => ({
loadWebMedia,
}));

View File

@@ -17,7 +17,7 @@ import { chunkMarkdownTextWithMode, type ChunkMode } from "openclaw/plugin-sdk/r
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { danger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { loadWebMedia } from "../../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import type { TelegramInlineButtons } from "../button-types.js";
import { splitTelegramCaption } from "../caption.js";
import {

View File

@@ -44,7 +44,7 @@ type TelegramSendTestMocks = {
maybePersistResolvedTelegramTarget: MockFn;
};
vi.mock("../../whatsapp/src/media.js", () => ({
vi.mock("openclaw/plugin-sdk/web-media", () => ({
loadWebMedia,
}));

View File

@@ -19,7 +19,7 @@ import { normalizePollInput, type PollInput } from "openclaw/plugin-sdk/media-ru
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
import { redactSensitiveText } from "openclaw/plugin-sdk/text-runtime";
import { loadWebMedia } from "../../whatsapp/src/media.js";
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
import { type ResolvedTelegramAccount, resolveTelegramAccount } from "./accounts.js";
import { withTelegramApiErrorLogging } from "./api-logging.js";
import { buildTelegramThreadParams, buildTypingThreadParams } from "./bot/helpers.js";

View File

@@ -8,7 +8,7 @@ import {
type WizardPrompter,
} from "openclaw/plugin-sdk/setup";
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/telegram";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js";
import { fetchTelegramChatId } from "./api-fetch.js";

View File

@@ -1,14 +1,16 @@
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
import {
createScopedChannelConfigBase,
createScopedAccountConfigAccessors,
createScopedChannelConfigBase,
} from "openclaw/plugin-sdk/channel-config-helpers";
import {
buildChannelConfigSchema,
getChatChannelMeta,
normalizeAccountId,
type OpenClawConfig,
TelegramConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/core";
type OpenClawConfig,
} from "openclaw/plugin-sdk/telegram-core";
import { inspectTelegramAccount } from "./account-inspect.js";
import {
listTelegramAccountIds,
@@ -71,7 +73,6 @@ export const telegramConfigBase = createScopedChannelConfigBase<ResolvedTelegram
});
export function createTelegramPluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedTelegramAccount>, "configSchema">["configSchema"];
setupWizard: NonNullable<ChannelPlugin<ResolvedTelegramAccount>["setupWizard"]>;
setup: NonNullable<ChannelPlugin<ResolvedTelegramAccount>["setup"]>;
}): Pick<
@@ -95,7 +96,7 @@ export function createTelegramPluginBase(params: {
blockStreaming: true,
},
reload: { configPrefixes: ["channels.telegram"] },
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(TelegramConfigSchema),
config: {
...telegramConfigBase,
isConfigured: (account, cfg) => {

2
extensions/tlon/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -6,6 +6,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { tlonPlugin } from "./src/channel.js";
import { setTlonRuntime } from "./src/runtime.js";
export { tlonPlugin } from "./src/channel.js";
export { setTlonRuntime } from "./src/runtime.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const ALLOWED_TLON_COMMANDS = new Set([

1
extensions/twitch/api.ts Normal file
View File

@@ -0,0 +1 @@
export * from "./src/setup-surface.js";

View File

@@ -0,0 +1,2 @@
export * from "./runtime-api.js";
export * from "./src/accounts.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { whatsappPlugin } from "./src/channel.js";
import { setWhatsAppRuntime } from "./src/runtime.js";
export { whatsappPlugin } from "./src/channel.js";
export { setWhatsAppRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "whatsapp",
name: "WhatsApp",

View File

@@ -0,0 +1 @@
export * from "./src/login-qr.js";

View File

@@ -0,0 +1,9 @@
export * from "./src/active-listener.js";
export * from "./src/agent-tools-login.js";
export * from "./src/auth-store.js";
export * from "./src/auto-reply.js";
export * from "./src/inbound.js";
export * from "./src/login.js";
export * from "./src/media.js";
export * from "./src/send.js";
export * from "./src/session.js";

View File

@@ -1,4 +1,6 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { whatsappSetupPlugin } from "./src/channel.setup.js";
export { whatsappSetupPlugin } from "./src/channel.setup.js";
export default defineSetupPluginEntry(whatsappSetupPlugin);

View File

@@ -7,10 +7,6 @@ import {
readWebSelfId as readWebSelfIdImpl,
webAuthExists as webAuthExistsImpl,
} from "./auth-store.js";
import {
startWebLoginWithQr as startWebLoginWithQrImpl,
waitForWebLogin as waitForWebLoginImpl,
} from "./login-qr.js";
import { loginWeb as loginWebImpl } from "./login.js";
import { whatsappSetupWizard as whatsappSetupWizardImpl } from "./setup-surface.js";
@@ -26,6 +22,13 @@ type WaitForWebLogin = typeof import("./login-qr.js").waitForWebLogin;
type WhatsAppSetupWizard = typeof import("./setup-surface.js").whatsappSetupWizard;
type MonitorWebChannel = typeof import("openclaw/plugin-sdk/whatsapp").monitorWebChannel;
let loginQrPromise: Promise<typeof import("./login-qr.js")> | null = null;
function loadWhatsAppLoginQr() {
loginQrPromise ??= import("./login-qr.js");
return loginQrPromise;
}
export function getActiveWebListener(
...args: Parameters<GetActiveWebListener>
): ReturnType<GetActiveWebListener> {
@@ -56,14 +59,18 @@ export function loginWeb(...args: Parameters<LoginWeb>): ReturnType<LoginWeb> {
return loginWebImpl(...args);
}
export function startWebLoginWithQr(
export async function startWebLoginWithQr(
...args: Parameters<StartWebLoginWithQr>
): ReturnType<StartWebLoginWithQr> {
return startWebLoginWithQrImpl(...args);
const { startWebLoginWithQr } = await loadWhatsAppLoginQr();
return await startWebLoginWithQr(...args);
}
export function waitForWebLogin(...args: Parameters<WaitForWebLogin>): ReturnType<WaitForWebLogin> {
return waitForWebLoginImpl(...args);
export async function waitForWebLogin(
...args: Parameters<WaitForWebLogin>
): ReturnType<WaitForWebLogin> {
const { waitForWebLogin } = await loadWhatsAppLoginQr();
return await waitForWebLogin(...args);
}
export const whatsappSetupWizard: WhatsAppSetupWizard = { ...whatsappSetupWizardImpl };

View File

@@ -11,7 +11,7 @@ import {
type OpenClawConfig,
} from "openclaw/plugin-sdk/setup";
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/whatsapp";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js";
import { loginWeb } from "./login.js";
import { whatsappSetupAdapter } from "./setup-core.js";

View File

@@ -1,19 +1,22 @@
import {
formatWhatsAppConfigAllowFromEntries,
resolveWhatsAppConfigAllowFrom,
resolveWhatsAppConfigDefaultTo,
} from "openclaw/plugin-sdk/channel-config-helpers";
import {
buildAccountScopedDmSecurityPolicy,
collectAllowlistProviderGroupPolicyWarnings,
collectOpenGroupPolicyRouteAllowlistWarnings,
} from "openclaw/plugin-sdk/channel-policy";
import {
buildChannelConfigSchema,
DEFAULT_ACCOUNT_ID,
formatWhatsAppConfigAllowFromEntries,
getChatChannelMeta,
normalizeE164,
resolveWhatsAppConfigAllowFrom,
resolveWhatsAppConfigDefaultTo,
resolveWhatsAppGroupIntroHint,
resolveWhatsAppGroupRequireMention,
resolveWhatsAppGroupToolPolicy,
WhatsAppConfigSchema,
type ChannelPlugin,
} from "openclaw/plugin-sdk/core";
import { normalizeE164 } from "openclaw/plugin-sdk/setup";
} from "openclaw/plugin-sdk/whatsapp-core";
import {
listWhatsAppAccountIds,
resolveDefaultWhatsAppAccountId,
@@ -76,8 +79,6 @@ export function createWhatsAppSetupWizardProxy(
}
export function createWhatsAppPluginBase(params: {
configSchema: Pick<ChannelPlugin<ResolvedWhatsAppAccount>, "configSchema">["configSchema"];
groups: Pick<ChannelPlugin<ResolvedWhatsAppAccount>, "groups">["groups"];
setupWizard: NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["setupWizard"]>;
setup: NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["setup"]>;
isConfigured: NonNullable<ChannelPlugin<ResolvedWhatsAppAccount>["config"]>["isConfigured"];
@@ -113,7 +114,7 @@ export function createWhatsAppPluginBase(params: {
},
reload: { configPrefixes: ["web"], noopPrefixes: ["channels.whatsapp"] },
gatewayMethods: ["web.login.start", "web.login.wait"],
configSchema: params.configSchema,
configSchema: buildChannelConfigSchema(WhatsAppConfigSchema),
config: {
listAccountIds: (cfg) => listWhatsAppAccountIds(cfg),
resolveAccount: (cfg, accountId) => resolveWhatsAppAccount({ cfg, accountId }),
@@ -212,6 +213,10 @@ export function createWhatsAppPluginBase(params: {
},
},
setup: params.setup,
groups: params.groups,
groups: {
resolveRequireMention: resolveWhatsAppGroupRequireMention,
resolveToolPolicy: resolveWhatsAppGroupToolPolicy,
resolveGroupIntroHint: resolveWhatsAppGroupIntroHint,
},
};
}

2
extensions/zalo/api.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -2,6 +2,9 @@ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { zaloPlugin } from "./src/channel.js";
import { setZaloRuntime } from "./src/runtime.js";
export { zaloPlugin } from "./src/channel.js";
export { setZaloRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "zalo",
name: "Zalo",

View File

@@ -0,0 +1,2 @@
export * from "./src/setup-core.js";
export * from "./src/setup-surface.js";

View File

@@ -4,6 +4,9 @@ import { zalouserPlugin } from "./src/channel.js";
import { setZalouserRuntime } from "./src/runtime.js";
import { ZalouserToolSchema, executeZalouserTool } from "./src/tool.js";
export { zalouserPlugin } from "./src/channel.js";
export { setZalouserRuntime } from "./src/runtime.js";
export default defineChannelPluginEntry({
id: "zalouser",
name: "Zalo Personal",