2026-03-18 23:30:25 +00:00
|
|
|
import * as bluebubblesSdk from "openclaw/plugin-sdk/bluebubbles";
|
2026-03-18 16:36:09 +00:00
|
|
|
import * as channelRuntimeSdk from "openclaw/plugin-sdk/channel-runtime";
|
2026-03-18 17:29:54 +00:00
|
|
|
import * as channelSendResultSdk from "openclaw/plugin-sdk/channel-send-result";
|
2026-03-16 00:19:21 -07:00
|
|
|
import * as coreSdk from "openclaw/plugin-sdk/core";
|
2026-03-16 09:51:28 +00:00
|
|
|
import type {
|
|
|
|
|
ChannelMessageActionContext as CoreChannelMessageActionContext,
|
|
|
|
|
OpenClawPluginApi as CoreOpenClawPluginApi,
|
|
|
|
|
PluginRuntime as CorePluginRuntime,
|
|
|
|
|
} from "openclaw/plugin-sdk/core";
|
2026-03-18 16:36:09 +00:00
|
|
|
import * as directoryRuntimeSdk from "openclaw/plugin-sdk/directory-runtime";
|
2026-03-03 22:07:03 -05:00
|
|
|
import * as discordSdk from "openclaw/plugin-sdk/discord";
|
|
|
|
|
import * as imessageSdk from "openclaw/plugin-sdk/imessage";
|
2026-03-17 09:24:14 -07:00
|
|
|
import * as lazyRuntimeSdk from "openclaw/plugin-sdk/lazy-runtime";
|
2026-03-16 12:46:04 +00:00
|
|
|
import * as ollamaSetupSdk from "openclaw/plugin-sdk/ollama-setup";
|
2026-03-18 11:17:50 -07:00
|
|
|
import * as providerModelsSdk from "openclaw/plugin-sdk/provider-models";
|
2026-03-16 12:04:32 +00:00
|
|
|
import * as providerSetupSdk from "openclaw/plugin-sdk/provider-setup";
|
2026-03-18 17:29:54 +00:00
|
|
|
import * as replyPayloadSdk from "openclaw/plugin-sdk/reply-payload";
|
2026-03-16 22:32:25 -07:00
|
|
|
import * as routingSdk from "openclaw/plugin-sdk/routing";
|
|
|
|
|
import * as runtimeSdk from "openclaw/plugin-sdk/runtime";
|
2026-03-16 12:04:32 +00:00
|
|
|
import * as sandboxSdk from "openclaw/plugin-sdk/sandbox";
|
2026-03-16 12:46:04 +00:00
|
|
|
import * as selfHostedProviderSetupSdk from "openclaw/plugin-sdk/self-hosted-provider-setup";
|
2026-03-16 20:17:03 -07:00
|
|
|
import * as setupSdk from "openclaw/plugin-sdk/setup";
|
2026-03-03 22:07:03 -05:00
|
|
|
import * as slackSdk from "openclaw/plugin-sdk/slack";
|
2026-03-05 23:07:13 -06:00
|
|
|
import * as telegramSdk from "openclaw/plugin-sdk/telegram";
|
2026-03-17 00:59:16 -07:00
|
|
|
import * as testingSdk from "openclaw/plugin-sdk/testing";
|
2026-03-03 22:07:03 -05:00
|
|
|
import * as whatsappSdk from "openclaw/plugin-sdk/whatsapp";
|
2026-03-18 11:13:19 -07:00
|
|
|
import * as whatsappActionRuntimeSdk from "openclaw/plugin-sdk/whatsapp-action-runtime";
|
|
|
|
|
import * as whatsappLoginQrSdk from "openclaw/plugin-sdk/whatsapp-login-qr";
|
2026-03-16 09:51:28 +00:00
|
|
|
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
|
|
|
import type { ChannelMessageActionContext } from "../channels/plugins/types.js";
|
|
|
|
|
import type { PluginRuntime } from "../plugins/runtime/types.js";
|
|
|
|
|
import type { OpenClawPluginApi } from "../plugins/types.js";
|
2026-03-16 10:05:40 +00:00
|
|
|
import type {
|
|
|
|
|
ChannelMessageActionContext as SharedChannelMessageActionContext,
|
|
|
|
|
OpenClawPluginApi as SharedOpenClawPluginApi,
|
|
|
|
|
PluginRuntime as SharedPluginRuntime,
|
|
|
|
|
} from "./channel-plugin-common.js";
|
2026-03-15 19:52:28 -07:00
|
|
|
import { pluginSdkSubpaths } from "./entrypoints.js";
|
2026-03-03 22:07:03 -05:00
|
|
|
|
2026-03-16 01:32:47 +00:00
|
|
|
const importPluginSdkSubpath = (specifier: string) => import(/* @vite-ignore */ specifier);
|
|
|
|
|
|
2026-03-16 02:23:21 +00:00
|
|
|
const bundledExtensionSubpathLoaders = pluginSdkSubpaths.map((id: string) => ({
|
2026-03-16 01:32:47 +00:00
|
|
|
id,
|
|
|
|
|
load: () => importPluginSdkSubpath(`openclaw/plugin-sdk/${id}`),
|
|
|
|
|
}));
|
2026-03-04 02:31:44 -05:00
|
|
|
|
2026-03-16 01:34:22 -07:00
|
|
|
const asExports = (mod: object) => mod as Record<string, unknown>;
|
2026-03-18 04:03:00 +00:00
|
|
|
const accountHelpersSdk = await import("openclaw/plugin-sdk/account-helpers");
|
2026-03-18 16:36:09 +00:00
|
|
|
const allowlistEditSdk = await import("openclaw/plugin-sdk/allowlist-config-edit");
|
2026-03-16 01:34:22 -07:00
|
|
|
|
2026-03-03 22:07:03 -05:00
|
|
|
describe("plugin-sdk subpath exports", () => {
|
2026-03-18 23:30:25 +00:00
|
|
|
it("keeps the curated public list free of bundled extension facades", () => {
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("compat");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("signal");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("line");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("msteams");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("googlechat");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("mattermost");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("matrix");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("nostr");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("voice-call");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("zalo");
|
|
|
|
|
expect(pluginSdkSubpaths).not.toContain("zalouser");
|
2026-03-04 01:19:17 -05:00
|
|
|
});
|
|
|
|
|
|
2026-03-16 22:32:25 -07:00
|
|
|
it("keeps core focused on generic shared exports", () => {
|
|
|
|
|
expect(typeof coreSdk.emptyPluginConfigSchema).toBe("function");
|
2026-03-17 00:14:01 -07:00
|
|
|
expect(typeof coreSdk.definePluginEntry).toBe("function");
|
2026-03-16 23:51:41 -07:00
|
|
|
expect(typeof coreSdk.defineChannelPluginEntry).toBe("function");
|
|
|
|
|
expect(typeof coreSdk.defineSetupPluginEntry).toBe("function");
|
2026-03-17 20:13:45 -07:00
|
|
|
expect(typeof coreSdk.createChannelPluginBase).toBe("function");
|
2026-03-17 23:02:30 -07:00
|
|
|
expect(typeof coreSdk.isSecretRef).toBe("function");
|
2026-03-17 19:48:47 -07:00
|
|
|
expect(typeof coreSdk.optionalStringEnum).toBe("function");
|
2026-03-16 22:32:25 -07:00
|
|
|
expect("runPassiveAccountLifecycle" in asExports(coreSdk)).toBe(false);
|
|
|
|
|
expect("createLoggerBackedRuntime" in asExports(coreSdk)).toBe(false);
|
2026-03-16 12:04:32 +00:00
|
|
|
expect("registerSandboxBackend" in asExports(coreSdk)).toBe(false);
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 22:32:25 -07:00
|
|
|
it("exports routing helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof routingSdk.buildAgentSessionKey).toBe("function");
|
|
|
|
|
expect(typeof routingSdk.resolveThreadSessionKeys).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 17:29:54 +00:00
|
|
|
it("exports reply payload helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof replyPayloadSdk.deliverTextOrMediaReply).toBe("function");
|
|
|
|
|
expect(typeof replyPayloadSdk.resolveOutboundMediaUrls).toBe("function");
|
|
|
|
|
expect(typeof replyPayloadSdk.sendPayloadWithChunkedTextAndMedia).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 04:03:00 +00:00
|
|
|
it("exports account helper builders from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof accountHelpersSdk.createAccountListHelpers).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 16:36:09 +00:00
|
|
|
it("exports allowlist edit helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof allowlistEditSdk.buildDmGroupAccountAllowlistAdapter).toBe("function");
|
|
|
|
|
expect(typeof allowlistEditSdk.createNestedAllowlistOverrideResolver).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 22:32:25 -07:00
|
|
|
it("exports runtime helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof runtimeSdk.createLoggerBackedRuntime).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 16:36:09 +00:00
|
|
|
it("exports directory runtime helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof directoryRuntimeSdk.listDirectoryEntriesFromSources).toBe("function");
|
|
|
|
|
expect(typeof directoryRuntimeSdk.listResolvedDirectoryEntriesFromSources).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("exports channel runtime helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof channelRuntimeSdk.createChannelDirectoryAdapter).toBe("function");
|
|
|
|
|
expect(typeof channelRuntimeSdk.createRuntimeOutboundDelegates).toBe("function");
|
2026-03-18 17:29:54 +00:00
|
|
|
expect(typeof channelRuntimeSdk.sendPayloadMediaSequenceOrFallback).toBe("function");
|
2026-03-18 16:36:09 +00:00
|
|
|
});
|
|
|
|
|
|
2026-03-18 17:29:54 +00:00
|
|
|
it("exports channel send-result helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof channelSendResultSdk.attachChannelToResult).toBe("function");
|
|
|
|
|
expect(typeof channelSendResultSdk.buildChannelSendResult).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 12:04:32 +00:00
|
|
|
it("exports provider setup helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof providerSetupSdk.buildVllmProvider).toBe("function");
|
|
|
|
|
expect(typeof providerSetupSdk.discoverOpenAICompatibleSelfHostedProvider).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 23:30:25 +00:00
|
|
|
it("keeps provider models focused on shared provider primitives", () => {
|
|
|
|
|
expect(typeof providerModelsSdk.applyOpenAIConfig).toBe("function");
|
|
|
|
|
expect(typeof providerModelsSdk.buildKilocodeModelDefinition).toBe("function");
|
|
|
|
|
expect(typeof providerModelsSdk.discoverHuggingfaceModels).toBe("function");
|
|
|
|
|
expect("buildMinimaxModelDefinition" in asExports(providerModelsSdk)).toBe(false);
|
|
|
|
|
expect("buildMoonshotProvider" in asExports(providerModelsSdk)).toBe(false);
|
|
|
|
|
expect("QIANFAN_BASE_URL" in asExports(providerModelsSdk)).toBe(false);
|
|
|
|
|
expect("resolveZaiBaseUrl" in asExports(providerModelsSdk)).toBe(false);
|
2026-03-18 11:17:50 -07:00
|
|
|
});
|
|
|
|
|
|
2026-03-16 20:17:03 -07:00
|
|
|
it("exports shared setup helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof setupSdk.DEFAULT_ACCOUNT_ID).toBe("string");
|
2026-03-18 03:58:15 +00:00
|
|
|
expect(typeof setupSdk.createAllowFromSection).toBe("function");
|
|
|
|
|
expect(typeof setupSdk.createDelegatedSetupWizardProxy).toBe("function");
|
2026-03-18 03:26:31 +00:00
|
|
|
expect(typeof setupSdk.createTopLevelChannelDmPolicy).toBe("function");
|
2026-03-16 20:17:03 -07:00
|
|
|
expect(typeof setupSdk.mergeAllowFromEntries).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-17 09:24:14 -07:00
|
|
|
it("exports shared lazy runtime helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof lazyRuntimeSdk.createLazyRuntimeSurface).toBe("function");
|
|
|
|
|
expect(typeof lazyRuntimeSdk.createLazyRuntimeModule).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 12:46:04 +00:00
|
|
|
it("exports narrow self-hosted provider setup helpers", () => {
|
|
|
|
|
expect(typeof selfHostedProviderSetupSdk.buildVllmProvider).toBe("function");
|
|
|
|
|
expect(typeof selfHostedProviderSetupSdk.buildSglangProvider).toBe("function");
|
|
|
|
|
expect(
|
|
|
|
|
typeof selfHostedProviderSetupSdk.configureOpenAICompatibleSelfHostedProviderNonInteractive,
|
|
|
|
|
).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("exports narrow Ollama setup helpers", () => {
|
|
|
|
|
expect(typeof ollamaSetupSdk.buildOllamaProvider).toBe("function");
|
|
|
|
|
expect(typeof ollamaSetupSdk.configureOllamaNonInteractive).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 12:04:32 +00:00
|
|
|
it("exports sandbox helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof sandboxSdk.registerSandboxBackend).toBe("function");
|
|
|
|
|
expect(typeof sandboxSdk.runPluginCommandWithTimeout).toBe("function");
|
2026-03-16 00:19:21 -07:00
|
|
|
});
|
|
|
|
|
|
2026-03-16 09:51:28 +00:00
|
|
|
it("exports shared core types used by bundled channels", () => {
|
|
|
|
|
expectTypeOf<CoreOpenClawPluginApi>().toMatchTypeOf<OpenClawPluginApi>();
|
|
|
|
|
expectTypeOf<CorePluginRuntime>().toMatchTypeOf<PluginRuntime>();
|
|
|
|
|
expectTypeOf<CoreChannelMessageActionContext>().toMatchTypeOf<ChannelMessageActionContext>();
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 00:19:56 -07:00
|
|
|
it("exports the public testing surface", () => {
|
2026-03-17 00:59:16 -07:00
|
|
|
expect(typeof testingSdk.removeAckReactionAfterReply).toBe("function");
|
|
|
|
|
expect(typeof testingSdk.shouldAckReaction).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-16 10:05:40 +00:00
|
|
|
it("keeps core shared types aligned with the channel prelude", () => {
|
|
|
|
|
expectTypeOf<CoreOpenClawPluginApi>().toMatchTypeOf<SharedOpenClawPluginApi>();
|
|
|
|
|
expectTypeOf<CorePluginRuntime>().toMatchTypeOf<SharedPluginRuntime>();
|
|
|
|
|
expectTypeOf<CoreChannelMessageActionContext>().toMatchTypeOf<SharedChannelMessageActionContext>();
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-03 22:07:03 -05:00
|
|
|
it("exports Discord helpers", () => {
|
2026-03-16 01:34:22 -07:00
|
|
|
expect(typeof discordSdk.buildChannelConfigSchema).toBe("function");
|
|
|
|
|
expect(typeof discordSdk.DiscordConfigSchema).toBe("object");
|
|
|
|
|
expect(typeof discordSdk.projectCredentialSnapshotFields).toBe("function");
|
|
|
|
|
expect("resolveDiscordAccount" in asExports(discordSdk)).toBe(false);
|
2026-03-03 22:07:03 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("exports Slack helpers", () => {
|
2026-03-16 01:34:22 -07:00
|
|
|
expect(typeof slackSdk.buildChannelConfigSchema).toBe("function");
|
|
|
|
|
expect(typeof slackSdk.SlackConfigSchema).toBe("object");
|
|
|
|
|
expect(typeof slackSdk.looksLikeSlackTargetId).toBe("function");
|
|
|
|
|
expect("resolveSlackAccount" in asExports(slackSdk)).toBe(false);
|
2026-03-03 22:07:03 -05:00
|
|
|
});
|
|
|
|
|
|
2026-03-05 23:07:13 -06:00
|
|
|
it("exports Telegram helpers", () => {
|
2026-03-16 01:34:22 -07:00
|
|
|
expect(typeof telegramSdk.buildChannelConfigSchema).toBe("function");
|
|
|
|
|
expect(typeof telegramSdk.TelegramConfigSchema).toBe("object");
|
|
|
|
|
expect(typeof telegramSdk.projectCredentialSnapshotFields).toBe("function");
|
|
|
|
|
expect("resolveTelegramAccount" in asExports(telegramSdk)).toBe(false);
|
2026-03-05 23:07:13 -06:00
|
|
|
});
|
|
|
|
|
|
2026-03-03 22:07:03 -05:00
|
|
|
it("exports iMessage helpers", () => {
|
2026-03-16 01:34:22 -07:00
|
|
|
expect(typeof imessageSdk.IMessageConfigSchema).toBe("object");
|
|
|
|
|
expect(typeof imessageSdk.resolveIMessageConfigAllowFrom).toBe("function");
|
|
|
|
|
expect(typeof imessageSdk.looksLikeIMessageTargetId).toBe("function");
|
|
|
|
|
expect("resolveIMessageAccount" in asExports(imessageSdk)).toBe(false);
|
2026-03-03 22:07:03 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("exports WhatsApp helpers", () => {
|
2026-03-14 02:44:55 -07:00
|
|
|
expect(typeof whatsappSdk.WhatsAppConfigSchema).toBe("object");
|
|
|
|
|
expect(typeof whatsappSdk.resolveWhatsAppOutboundTarget).toBe("function");
|
2026-03-15 08:50:23 -07:00
|
|
|
expect(typeof whatsappSdk.resolveWhatsAppMentionStripRegexes).toBe("function");
|
2026-03-03 22:07:03 -05:00
|
|
|
});
|
|
|
|
|
|
2026-03-18 11:13:19 -07:00
|
|
|
it("exports WhatsApp QR login helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof whatsappLoginQrSdk.startWebLoginWithQr).toBe("function");
|
|
|
|
|
expect(typeof whatsappLoginQrSdk.waitForWebLogin).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it("exports WhatsApp action runtime helpers from the dedicated subpath", () => {
|
|
|
|
|
expect(typeof whatsappActionRuntimeSdk.handleWhatsAppAction).toBe("function");
|
|
|
|
|
});
|
|
|
|
|
|
2026-03-18 23:30:25 +00:00
|
|
|
it("keeps the remaining bundled helper surface narrow", () => {
|
|
|
|
|
expect(typeof bluebubblesSdk.parseFiniteNumber).toBe("function");
|
2026-03-18 00:09:20 -07:00
|
|
|
});
|
|
|
|
|
|
2026-03-18 23:30:25 +00:00
|
|
|
it("resolves every curated public subpath", async () => {
|
2026-03-04 02:31:44 -05:00
|
|
|
for (const { id, load } of bundledExtensionSubpathLoaders) {
|
|
|
|
|
const mod = await load();
|
|
|
|
|
expect(typeof mod).toBe("object");
|
|
|
|
|
expect(mod, `subpath ${id} should resolve`).toBeTruthy();
|
|
|
|
|
}
|
|
|
|
|
});
|
2026-03-03 22:07:03 -05:00
|
|
|
});
|