diff --git a/docs/tools/plugin.md b/docs/tools/plugin.md index e989c7fd4fd..797e632a820 100644 --- a/docs/tools/plugin.md +++ b/docs/tools/plugin.md @@ -46,8 +46,7 @@ Looking for third-party listings? See [Community plugins](/plugins/community). - Memory (LanceDB) — bundled long-term memory plugin (auto-recall/capture; set `plugins.slots.memory = "memory-lancedb"`) - [Voice Call](/plugins/voice-call) — `@openclaw/voice-call` - [Zalo Personal](/plugins/zalouser) — `@openclaw/zalouser` -- [Matrix-js](/channels/matrix-js) — `@openclaw/matrix-js` -- [Matrix (legacy)](/channels/matrix) — `@openclaw/matrix` +- [Matrix](/channels/matrix) — `@openclaw/matrix` - [Nostr](/channels/nostr) — `@openclaw/nostr` - [Zalo](/channels/zalo) — `@openclaw/zalo` - [Microsoft Teams](/channels/msteams) — `@openclaw/msteams` @@ -107,6 +106,57 @@ Notes: - Uses core media-understanding audio configuration (`tools.media.audio`) and provider fallback order. - Returns `{ text: undefined }` when no transcription output is produced (for example skipped/unsupported input). +## Plugin SDK import paths + +Use SDK subpaths instead of the monolithic `openclaw/plugin-sdk` import when +authoring plugins: + +- `openclaw/plugin-sdk/core` for generic plugin APIs, provider auth types, and shared helpers. +- `openclaw/plugin-sdk/compat` for bundled/internal plugin code that needs broader shared runtime helpers than `core`. +- `openclaw/plugin-sdk/telegram` for Telegram channel plugins. +- `openclaw/plugin-sdk/discord` for Discord channel plugins. +- `openclaw/plugin-sdk/slack` for Slack channel plugins. +- `openclaw/plugin-sdk/signal` for Signal channel plugins. +- `openclaw/plugin-sdk/imessage` for iMessage channel plugins. +- `openclaw/plugin-sdk/whatsapp` for WhatsApp channel plugins. +- `openclaw/plugin-sdk/line` for LINE channel plugins. +- `openclaw/plugin-sdk/msteams` for the bundled Microsoft Teams plugin surface. +- Bundled extension-specific subpaths are also available: + `openclaw/plugin-sdk/acpx`, `openclaw/plugin-sdk/bluebubbles`, + `openclaw/plugin-sdk/copilot-proxy`, `openclaw/plugin-sdk/device-pair`, + `openclaw/plugin-sdk/diagnostics-otel`, `openclaw/plugin-sdk/diffs`, + `openclaw/plugin-sdk/feishu`, + `openclaw/plugin-sdk/google-gemini-cli-auth`, `openclaw/plugin-sdk/googlechat`, + `openclaw/plugin-sdk/irc`, `openclaw/plugin-sdk/llm-task`, + `openclaw/plugin-sdk/lobster`, `openclaw/plugin-sdk/matrix`, + `openclaw/plugin-sdk/matrix-js`, + `openclaw/plugin-sdk/mattermost`, `openclaw/plugin-sdk/memory-core`, + `openclaw/plugin-sdk/memory-lancedb`, + `openclaw/plugin-sdk/minimax-portal-auth`, + `openclaw/plugin-sdk/nextcloud-talk`, `openclaw/plugin-sdk/nostr`, + `openclaw/plugin-sdk/open-prose`, `openclaw/plugin-sdk/phone-control`, + `openclaw/plugin-sdk/qwen-portal-auth`, `openclaw/plugin-sdk/synology-chat`, + `openclaw/plugin-sdk/talk-voice`, `openclaw/plugin-sdk/test-utils`, + `openclaw/plugin-sdk/thread-ownership`, `openclaw/plugin-sdk/tlon`, + `openclaw/plugin-sdk/twitch`, `openclaw/plugin-sdk/voice-call`, + `openclaw/plugin-sdk/zalo`, and `openclaw/plugin-sdk/zalouser`. + +Compatibility note: + +- `openclaw/plugin-sdk` remains supported for existing external plugins. +- New and migrated bundled plugins should use channel or extension-specific + subpaths; use `core` for generic surfaces and `compat` only when broader + shared helpers are required. + +Performance note: + +- Plugin discovery and manifest metadata use short in-process caches to reduce + bursty startup/reload work. +- Set `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1` or + `OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` to disable these caches. +- Tune cache windows with `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS` and + `OPENCLAW_PLUGIN_MANIFEST_CACHE_MS`. + ## Discovery & precedence OpenClaw scans, in order: @@ -125,13 +175,21 @@ OpenClaw scans, in order: - `~/.openclaw/extensions/*.ts` - `~/.openclaw/extensions/*/index.ts` -4. Bundled extensions (shipped with OpenClaw, **disabled by default**) +4. Bundled extensions (shipped with OpenClaw, mostly disabled by default) - `/extensions/*` -Bundled plugins must be enabled explicitly via `plugins.entries..enabled` -or `openclaw plugins enable `. Installed plugins are enabled by default, -but can be disabled the same way. +Most bundled plugins must be enabled explicitly via +`plugins.entries..enabled` or `openclaw plugins enable `. + +Default-on bundled plugin exceptions: + +- `device-pair` +- `phone-control` +- `talk-voice` +- active memory slot plugin (default slot: `memory-core`) + +Installed plugins are enabled by default, but can be disabled the same way. Hardening notes: diff --git a/extensions/matrix-js/index.ts b/extensions/matrix-js/index.ts index 59fcc309505..23d8b53c1e1 100644 --- a/extensions/matrix-js/index.ts +++ b/extensions/matrix-js/index.ts @@ -1,5 +1,8 @@ -import type { GatewayRequestHandlerOptions, OpenClawPluginApi } from "openclaw/plugin-sdk"; -import { emptyPluginConfigSchema } from "openclaw/plugin-sdk"; +import type { + GatewayRequestHandlerOptions, + OpenClawPluginApi, +} from "openclaw/plugin-sdk/matrix-js"; +import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/matrix-js"; import { matrixPlugin } from "./src/channel.js"; import { registerMatrixJsCli } from "./src/cli.js"; import { diff --git a/extensions/matrix-js/src/actions.ts b/extensions/matrix-js/src/actions.ts index 2e94a03d743..f18226bd0a2 100644 --- a/extensions/matrix-js/src/actions.ts +++ b/extensions/matrix-js/src/actions.ts @@ -6,7 +6,7 @@ import { type ChannelMessageActionContext, type ChannelMessageActionName, type ChannelToolSend, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { resolveMatrixAccount } from "./matrix/accounts.js"; import { handleMatrixAction } from "./tool-actions.js"; import type { CoreConfig } from "./types.js"; diff --git a/extensions/matrix-js/src/channel.directory.test.ts b/extensions/matrix-js/src/channel.directory.test.ts index 5064cf1b2f9..18b02e5c0f7 100644 --- a/extensions/matrix-js/src/channel.directory.test.ts +++ b/extensions/matrix-js/src/channel.directory.test.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk"; +import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/matrix-js"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { matrixPlugin } from "./channel.js"; import { migrateMatrixLegacyCredentialsToDefaultAccount } from "./config-migration.js"; diff --git a/extensions/matrix-js/src/channel.ts b/extensions/matrix-js/src/channel.ts index 79cd1a2a530..a625f2cfc49 100644 --- a/extensions/matrix-js/src/channel.ts +++ b/extensions/matrix-js/src/channel.ts @@ -12,7 +12,7 @@ import { setAccountEnabledInConfigSection, type ChannelSetupInput, type ChannelPlugin, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { matrixMessageActions } from "./actions.js"; import { migrateMatrixLegacyCredentialsToDefaultAccount } from "./config-migration.js"; import { MatrixConfigSchema } from "./config-schema.js"; diff --git a/extensions/matrix-js/src/cli.test.ts b/extensions/matrix-js/src/cli.test.ts index 963c55b25b2..36c3efbf6af 100644 --- a/extensions/matrix-js/src/cli.test.ts +++ b/extensions/matrix-js/src/cli.test.ts @@ -1,5 +1,5 @@ import { Command } from "commander"; -import { formatZonedTimestamp } from "openclaw/plugin-sdk"; +import { formatZonedTimestamp } from "openclaw/plugin-sdk/matrix-js"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const bootstrapMatrixVerificationMock = vi.fn(); diff --git a/extensions/matrix-js/src/cli.ts b/extensions/matrix-js/src/cli.ts index 2877f900d24..8d7fbca4ae8 100644 --- a/extensions/matrix-js/src/cli.ts +++ b/extensions/matrix-js/src/cli.ts @@ -3,7 +3,7 @@ import { formatZonedTimestamp, normalizeAccountId, type ChannelSetupInput, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { matrixPlugin } from "./channel.js"; import { updateMatrixOwnProfile } from "./matrix/actions/profile.js"; import { diff --git a/extensions/matrix-js/src/config-migration.ts b/extensions/matrix-js/src/config-migration.ts index 3af3eb349a3..a5989024e83 100644 --- a/extensions/matrix-js/src/config-migration.ts +++ b/extensions/matrix-js/src/config-migration.ts @@ -1,4 +1,4 @@ -import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk"; +import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/matrix-js"; import type { CoreConfig, MatrixAccountConfig, MatrixConfig } from "./types.js"; type LegacyAccountField = diff --git a/extensions/matrix-js/src/config-schema.ts b/extensions/matrix-js/src/config-schema.ts index 32d2538de56..1876847b939 100644 --- a/extensions/matrix-js/src/config-schema.ts +++ b/extensions/matrix-js/src/config-schema.ts @@ -1,4 +1,4 @@ -import { MarkdownConfigSchema, ToolPolicySchema } from "openclaw/plugin-sdk"; +import { MarkdownConfigSchema, ToolPolicySchema } from "openclaw/plugin-sdk/matrix-js"; import { z } from "zod"; const allowFromEntry = z.union([z.string(), z.number()]); diff --git a/extensions/matrix-js/src/directory-live.ts b/extensions/matrix-js/src/directory-live.ts index e7c8fd45920..0fefdc45f2c 100644 --- a/extensions/matrix-js/src/directory-live.ts +++ b/extensions/matrix-js/src/directory-live.ts @@ -1,4 +1,4 @@ -import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk"; +import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/matrix-js"; import { resolveMatrixAuth } from "./matrix/client.js"; type MatrixUserResult = { diff --git a/extensions/matrix-js/src/group-mentions.ts b/extensions/matrix-js/src/group-mentions.ts index b324b4197a7..f6d3540f5d0 100644 --- a/extensions/matrix-js/src/group-mentions.ts +++ b/extensions/matrix-js/src/group-mentions.ts @@ -1,4 +1,4 @@ -import type { ChannelGroupContext, GroupToolPolicyConfig } from "openclaw/plugin-sdk"; +import type { ChannelGroupContext, GroupToolPolicyConfig } from "openclaw/plugin-sdk/matrix-js"; import { resolveMatrixAccountConfig } from "./matrix/accounts.js"; import { resolveMatrixRoomConfig } from "./matrix/monitor/rooms.js"; import type { CoreConfig } from "./types.js"; diff --git a/extensions/matrix-js/src/matrix/client/shared.test.ts b/extensions/matrix-js/src/matrix/client/shared.test.ts index 80f4bb5179c..72b708f3c93 100644 --- a/extensions/matrix-js/src/matrix/client/shared.test.ts +++ b/extensions/matrix-js/src/matrix/client/shared.test.ts @@ -55,22 +55,22 @@ describe("resolveSharedMatrixClient", () => { it("keeps account clients isolated when resolves are interleaved", async () => { const mainAuth = authFor("main"); - const poeAuth = authFor("poe"); + const poeAuth = authFor("ops"); const mainClient = createMockClient("main"); - const poeClient = createMockClient("poe"); + const poeClient = createMockClient("ops"); resolveMatrixAuthMock.mockImplementation(async ({ accountId }: { accountId?: string }) => - accountId === "poe" ? poeAuth : mainAuth, + accountId === "ops" ? poeAuth : mainAuth, ); createMatrixClientMock.mockImplementation(async ({ accountId }: { accountId?: string }) => { - if (accountId === "poe") { + if (accountId === "ops") { return poeClient; } return mainClient; }); const firstMain = await resolveSharedMatrixClient({ accountId: "main", startClient: false }); - const firstPoe = await resolveSharedMatrixClient({ accountId: "poe", startClient: false }); + const firstPoe = await resolveSharedMatrixClient({ accountId: "ops", startClient: false }); const secondMain = await resolveSharedMatrixClient({ accountId: "main" }); expect(firstMain).toBe(mainClient); @@ -83,22 +83,22 @@ describe("resolveSharedMatrixClient", () => { it("stops only the targeted account client", async () => { const mainAuth = authFor("main"); - const poeAuth = authFor("poe"); + const poeAuth = authFor("ops"); const mainClient = createMockClient("main"); - const poeClient = createMockClient("poe"); + const poeClient = createMockClient("ops"); resolveMatrixAuthMock.mockImplementation(async ({ accountId }: { accountId?: string }) => - accountId === "poe" ? poeAuth : mainAuth, + accountId === "ops" ? poeAuth : mainAuth, ); createMatrixClientMock.mockImplementation(async ({ accountId }: { accountId?: string }) => { - if (accountId === "poe") { + if (accountId === "ops") { return poeClient; } return mainClient; }); await resolveSharedMatrixClient({ accountId: "main", startClient: false }); - await resolveSharedMatrixClient({ accountId: "poe", startClient: false }); + await resolveSharedMatrixClient({ accountId: "ops", startClient: false }); stopSharedClientForAccount(mainAuth, "main"); diff --git a/extensions/matrix-js/src/matrix/config-update.ts b/extensions/matrix-js/src/matrix/config-update.ts index 4866b3ea3e0..1082eda5a6b 100644 --- a/extensions/matrix-js/src/matrix/config-update.ts +++ b/extensions/matrix-js/src/matrix/config-update.ts @@ -1,4 +1,4 @@ -import { normalizeAccountId } from "openclaw/plugin-sdk"; +import { normalizeAccountId } from "openclaw/plugin-sdk/matrix-js"; import type { CoreConfig, MatrixConfig } from "../types.js"; export type MatrixAccountPatch = { diff --git a/extensions/matrix-js/src/matrix/credentials.ts b/extensions/matrix-js/src/matrix/credentials.ts index 70a6d3c819b..b7c848457f2 100644 --- a/extensions/matrix-js/src/matrix/credentials.ts +++ b/extensions/matrix-js/src/matrix/credentials.ts @@ -1,8 +1,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { writeJsonFileAtomically } from "openclaw/plugin-sdk"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id"; +import { writeJsonFileAtomically } from "openclaw/plugin-sdk/matrix-js"; import { getMatrixRuntime } from "../runtime.js"; export type MatrixStoredCredentials = { diff --git a/extensions/matrix-js/src/matrix/deps.ts b/extensions/matrix-js/src/matrix/deps.ts index c8218fc200c..6585c7420d2 100644 --- a/extensions/matrix-js/src/matrix/deps.ts +++ b/extensions/matrix-js/src/matrix/deps.ts @@ -3,7 +3,7 @@ import fs from "node:fs"; import { createRequire } from "node:module"; import path from "node:path"; import { fileURLToPath } from "node:url"; -import type { RuntimeEnv } from "openclaw/plugin-sdk"; +import type { RuntimeEnv } from "openclaw/plugin-sdk/matrix-js"; const REQUIRED_MATRIX_PACKAGES = ["matrix-js-sdk", "@matrix-org/matrix-sdk-crypto-nodejs"]; diff --git a/extensions/matrix-js/src/matrix/monitor/allowlist.ts b/extensions/matrix-js/src/matrix/monitor/allowlist.ts index 754f3ee24f7..eabb263baca 100644 --- a/extensions/matrix-js/src/matrix/monitor/allowlist.ts +++ b/extensions/matrix-js/src/matrix/monitor/allowlist.ts @@ -1,4 +1,4 @@ -import type { AllowlistMatch } from "openclaw/plugin-sdk"; +import type { AllowlistMatch } from "openclaw/plugin-sdk/matrix-js"; function normalizeAllowList(list?: Array) { return (list ?? []).map((entry) => String(entry).trim()).filter(Boolean); diff --git a/extensions/matrix-js/src/matrix/monitor/auto-join.test.ts b/extensions/matrix-js/src/matrix/monitor/auto-join.test.ts index 8af091ba394..367bb9de9c1 100644 --- a/extensions/matrix-js/src/matrix/monitor/auto-join.test.ts +++ b/extensions/matrix-js/src/matrix/monitor/auto-join.test.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime } from "openclaw/plugin-sdk"; +import type { PluginRuntime } from "openclaw/plugin-sdk/matrix-js"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { setMatrixRuntime } from "../../runtime.js"; import type { CoreConfig } from "../../types.js"; @@ -53,7 +53,7 @@ describe("registerMatrixAutoJoin", () => { runtime: { log: vi.fn(), error: vi.fn(), - } as unknown as import("openclaw/plugin-sdk").RuntimeEnv, + } as unknown as import("openclaw/plugin-sdk/matrix-js").RuntimeEnv, }); const inviteHandler = getInviteHandler(); @@ -84,7 +84,7 @@ describe("registerMatrixAutoJoin", () => { runtime: { log: vi.fn(), error: vi.fn(), - } as unknown as import("openclaw/plugin-sdk").RuntimeEnv, + } as unknown as import("openclaw/plugin-sdk/matrix-js").RuntimeEnv, }); const inviteHandler = getInviteHandler(); @@ -115,7 +115,7 @@ describe("registerMatrixAutoJoin", () => { runtime: { log: vi.fn(), error: vi.fn(), - } as unknown as import("openclaw/plugin-sdk").RuntimeEnv, + } as unknown as import("openclaw/plugin-sdk/matrix-js").RuntimeEnv, }); const inviteHandler = getInviteHandler(); diff --git a/extensions/matrix-js/src/matrix/monitor/auto-join.ts b/extensions/matrix-js/src/matrix/monitor/auto-join.ts index 8077df1f322..6174d08d51f 100644 --- a/extensions/matrix-js/src/matrix/monitor/auto-join.ts +++ b/extensions/matrix-js/src/matrix/monitor/auto-join.ts @@ -1,4 +1,4 @@ -import type { RuntimeEnv } from "openclaw/plugin-sdk"; +import type { RuntimeEnv } from "openclaw/plugin-sdk/matrix-js"; import { getMatrixRuntime } from "../../runtime.js"; import type { CoreConfig } from "../../types.js"; import type { MatrixClient } from "../sdk.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/events.ts b/extensions/matrix-js/src/matrix/monitor/events.ts index 443798f8081..5147deb1ec3 100644 --- a/extensions/matrix-js/src/matrix/monitor/events.ts +++ b/extensions/matrix-js/src/matrix/monitor/events.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk"; +import type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/matrix-js"; import type { MatrixAuth } from "../client.js"; import type { MatrixClient } from "../sdk.js"; import type { MatrixRawEvent } from "./types.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/handler.test.ts b/extensions/matrix-js/src/matrix/monitor/handler.test.ts index 5d8e5d60243..7eb1e3712ab 100644 --- a/extensions/matrix-js/src/matrix/monitor/handler.test.ts +++ b/extensions/matrix-js/src/matrix/monitor/handler.test.ts @@ -33,7 +33,7 @@ describe("matrix monitor handler pairing account scope", () => { }, } as never, cfg: {} as never, - accountId: "poe", + accountId: "ops", runtime: {} as never, logger: { info: () => {}, @@ -107,7 +107,7 @@ describe("matrix monitor handler pairing account scope", () => { }, } as never, cfg: {} as never, - accountId: "poe", + accountId: "ops", runtime: {} as never, logger: { info: () => {}, @@ -177,7 +177,7 @@ describe("matrix monitor handler pairing account scope", () => { }, } as never, cfg: {} as never, - accountId: "poe", + accountId: "ops", runtime: {} as never, logger: { info: () => {}, @@ -217,23 +217,23 @@ describe("matrix monitor handler pairing account scope", () => { expect(readAllowFromStore).toHaveBeenCalledWith({ channel: "matrix-js", env: process.env, - accountId: "poe", + accountId: "ops", }); expect(upsertPairingRequest).toHaveBeenCalledWith({ channel: "matrix-js", id: "@user:example.org", - accountId: "poe", + accountId: "ops", meta: { name: "sender" }, }); }); it("passes accountId into route resolution for inbound dm messages", async () => { const resolveAgentRoute = vi.fn(() => ({ - agentId: "poe", + agentId: "ops", channel: "matrix-js", - accountId: "poe", - sessionKey: "agent:poe:main", - mainSessionKey: "agent:poe:main", + accountId: "ops", + sessionKey: "agent:ops:main", + mainSessionKey: "agent:ops:main", matchedBy: "binding.account", })); @@ -259,7 +259,7 @@ describe("matrix monitor handler pairing account scope", () => { }, } as never, cfg: {} as never, - accountId: "poe", + accountId: "ops", runtime: { error: () => {}, } as never, @@ -301,7 +301,7 @@ describe("matrix monitor handler pairing account scope", () => { expect(resolveAgentRoute).toHaveBeenCalledWith( expect.objectContaining({ channel: "matrix-js", - accountId: "poe", + accountId: "ops", }), ); }); diff --git a/extensions/matrix-js/src/matrix/monitor/handler.ts b/extensions/matrix-js/src/matrix/monitor/handler.ts index c4c1393abdf..38313f3399e 100644 --- a/extensions/matrix-js/src/matrix/monitor/handler.ts +++ b/extensions/matrix-js/src/matrix/monitor/handler.ts @@ -9,7 +9,7 @@ import { type ReplyPayload, type RuntimeEnv, type RuntimeLogger, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import type { CoreConfig, MatrixRoomConfig, ReplyToMode } from "../../types.js"; import { formatPollAsText, diff --git a/extensions/matrix-js/src/matrix/monitor/index.ts b/extensions/matrix-js/src/matrix/monitor/index.ts index 08de908707f..a9b1372f9c3 100644 --- a/extensions/matrix-js/src/matrix/monitor/index.ts +++ b/extensions/matrix-js/src/matrix/monitor/index.ts @@ -7,7 +7,7 @@ import { summarizeMapping, warnMissingProviderGroupPolicyFallbackOnce, type RuntimeEnv, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { resolveMatrixTargets } from "../../resolve-targets.js"; import { getMatrixRuntime } from "../../runtime.js"; import type { CoreConfig, ReplyToMode } from "../../types.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/location.ts b/extensions/matrix-js/src/matrix/monitor/location.ts index 7380ec215b4..582c4b4facf 100644 --- a/extensions/matrix-js/src/matrix/monitor/location.ts +++ b/extensions/matrix-js/src/matrix/monitor/location.ts @@ -2,7 +2,7 @@ import { formatLocationText, toLocationContext, type NormalizedLocation, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import type { LocationMessageEventContent } from "../sdk.js"; import { EventType } from "./types.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/media.test.ts b/extensions/matrix-js/src/matrix/monitor/media.test.ts index dcf7af8ad69..7127b1fc67c 100644 --- a/extensions/matrix-js/src/matrix/monitor/media.test.ts +++ b/extensions/matrix-js/src/matrix/monitor/media.test.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime } from "openclaw/plugin-sdk"; +import type { PluginRuntime } from "openclaw/plugin-sdk/matrix-js"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { setMatrixRuntime } from "../../runtime.js"; import { downloadMatrixMedia } from "./media.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/replies.test.ts b/extensions/matrix-js/src/matrix/monitor/replies.test.ts index b2f78fcf197..326eafdf1c1 100644 --- a/extensions/matrix-js/src/matrix/monitor/replies.test.ts +++ b/extensions/matrix-js/src/matrix/monitor/replies.test.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk"; +import type { PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/matrix-js"; import { beforeEach, describe, expect, it, vi } from "vitest"; import type { MatrixClient } from "../sdk.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/replies.ts b/extensions/matrix-js/src/matrix/monitor/replies.ts index cdbd98322e2..fb4f4d24ac4 100644 --- a/extensions/matrix-js/src/matrix/monitor/replies.ts +++ b/extensions/matrix-js/src/matrix/monitor/replies.ts @@ -1,4 +1,4 @@ -import type { MarkdownTableMode, ReplyPayload, RuntimeEnv } from "openclaw/plugin-sdk"; +import type { MarkdownTableMode, ReplyPayload, RuntimeEnv } from "openclaw/plugin-sdk/matrix-js"; import { getMatrixRuntime } from "../../runtime.js"; import type { MatrixClient } from "../sdk.js"; import { sendMessageMatrix } from "../send.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/rooms.ts b/extensions/matrix-js/src/matrix/monitor/rooms.ts index 2200ad0c1e4..b52c10ef3f2 100644 --- a/extensions/matrix-js/src/matrix/monitor/rooms.ts +++ b/extensions/matrix-js/src/matrix/monitor/rooms.ts @@ -1,4 +1,4 @@ -import { buildChannelKeyCandidates, resolveChannelEntryMatch } from "openclaw/plugin-sdk"; +import { buildChannelKeyCandidates, resolveChannelEntryMatch } from "openclaw/plugin-sdk/matrix-js"; import type { MatrixRoomConfig } from "../../types.js"; export type MatrixRoomConfigResolved = { diff --git a/extensions/matrix-js/src/matrix/poll-types.ts b/extensions/matrix-js/src/matrix/poll-types.ts index aa55a83d681..c3bebd38875 100644 --- a/extensions/matrix-js/src/matrix/poll-types.ts +++ b/extensions/matrix-js/src/matrix/poll-types.ts @@ -7,7 +7,7 @@ * - m.poll.end - Closes a poll */ -import type { PollInput } from "openclaw/plugin-sdk"; +import type { PollInput } from "openclaw/plugin-sdk/matrix-js"; export const M_POLL_START = "m.poll.start" as const; export const M_POLL_RESPONSE = "m.poll.response" as const; diff --git a/extensions/matrix-js/src/matrix/probe.ts b/extensions/matrix-js/src/matrix/probe.ts index fbd05ee1068..91261f95118 100644 --- a/extensions/matrix-js/src/matrix/probe.ts +++ b/extensions/matrix-js/src/matrix/probe.ts @@ -1,4 +1,4 @@ -import type { BaseProbeResult } from "openclaw/plugin-sdk"; +import type { BaseProbeResult } from "openclaw/plugin-sdk/matrix-js"; import { createMatrixClient, isBunRuntime } from "./client.js"; export type MatrixProbe = BaseProbeResult & { diff --git a/extensions/matrix-js/src/matrix/sdk/logger.ts b/extensions/matrix-js/src/matrix/sdk/logger.ts index f8e45b59879..61831a37815 100644 --- a/extensions/matrix-js/src/matrix/sdk/logger.ts +++ b/extensions/matrix-js/src/matrix/sdk/logger.ts @@ -1,5 +1,5 @@ import { format } from "node:util"; -import type { RuntimeLogger } from "openclaw/plugin-sdk"; +import type { RuntimeLogger } from "openclaw/plugin-sdk/matrix-js"; import { getMatrixRuntime } from "../../runtime.js"; export type Logger = { diff --git a/extensions/matrix-js/src/matrix/send.test.ts b/extensions/matrix-js/src/matrix/send.test.ts index e4c5918921c..d68cb35b088 100644 --- a/extensions/matrix-js/src/matrix/send.test.ts +++ b/extensions/matrix-js/src/matrix/send.test.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime } from "openclaw/plugin-sdk"; +import type { PluginRuntime } from "openclaw/plugin-sdk/matrix-js"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; import { setMatrixRuntime } from "../runtime.js"; diff --git a/extensions/matrix-js/src/matrix/send.ts b/extensions/matrix-js/src/matrix/send.ts index 768d336ed07..230c26915b1 100644 --- a/extensions/matrix-js/src/matrix/send.ts +++ b/extensions/matrix-js/src/matrix/send.ts @@ -1,4 +1,4 @@ -import type { PollInput } from "openclaw/plugin-sdk"; +import type { PollInput } from "openclaw/plugin-sdk/matrix-js"; import { getMatrixRuntime } from "../runtime.js"; import { buildPollStartContent, M_POLL_START } from "./poll-types.js"; import type { MatrixClient } from "./sdk.js"; diff --git a/extensions/matrix-js/src/onboarding.test.ts b/extensions/matrix-js/src/onboarding.test.ts index 559ba431fcc..01319f86dc1 100644 --- a/extensions/matrix-js/src/onboarding.test.ts +++ b/extensions/matrix-js/src/onboarding.test.ts @@ -1,4 +1,4 @@ -import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk"; +import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/matrix-js"; import { afterEach, describe, expect, it, vi } from "vitest"; import { matrixOnboardingAdapter } from "./onboarding.js"; import { setMatrixRuntime } from "./runtime.js"; diff --git a/extensions/matrix-js/src/onboarding.ts b/extensions/matrix-js/src/onboarding.ts index 49ad0c4b9bd..5684d6c764e 100644 --- a/extensions/matrix-js/src/onboarding.ts +++ b/extensions/matrix-js/src/onboarding.ts @@ -1,4 +1,5 @@ -import type { DmPolicy } from "openclaw/plugin-sdk"; +import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id"; +import type { DmPolicy } from "openclaw/plugin-sdk/matrix-js"; import { addWildcardAllowFrom, formatDocsLink, @@ -10,8 +11,7 @@ import { type ChannelOnboardingAdapter, type ChannelOnboardingDmPolicy, type WizardPrompter, -} from "openclaw/plugin-sdk"; -import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id"; +} from "openclaw/plugin-sdk/matrix-js"; import { migrateMatrixLegacyCredentialsToDefaultAccount } from "./config-migration.js"; import { listMatrixDirectoryGroupsLive } from "./directory-live.js"; import { diff --git a/extensions/matrix-js/src/outbound.ts b/extensions/matrix-js/src/outbound.ts index f100126f325..ce2f6642f32 100644 --- a/extensions/matrix-js/src/outbound.ts +++ b/extensions/matrix-js/src/outbound.ts @@ -1,4 +1,4 @@ -import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk"; +import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/matrix-js"; import { sendMessageMatrix, sendPollMatrix } from "./matrix/send.js"; import { getMatrixRuntime } from "./runtime.js"; diff --git a/extensions/matrix-js/src/resolve-targets.test.ts b/extensions/matrix-js/src/resolve-targets.test.ts index 4890df69aea..cdf94d78b3e 100644 --- a/extensions/matrix-js/src/resolve-targets.test.ts +++ b/extensions/matrix-js/src/resolve-targets.test.ts @@ -1,4 +1,4 @@ -import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk"; +import type { ChannelDirectoryEntry } from "openclaw/plugin-sdk/matrix-js"; import { describe, expect, it, vi, beforeEach } from "vitest"; import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js"; import { resolveMatrixTargets } from "./resolve-targets.js"; diff --git a/extensions/matrix-js/src/resolve-targets.ts b/extensions/matrix-js/src/resolve-targets.ts index c4c95ee30b2..a6dc93059a6 100644 --- a/extensions/matrix-js/src/resolve-targets.ts +++ b/extensions/matrix-js/src/resolve-targets.ts @@ -3,7 +3,7 @@ import type { ChannelResolveKind, ChannelResolveResult, RuntimeEnv, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js"; function findExactDirectoryMatches( diff --git a/extensions/matrix-js/src/runtime.ts b/extensions/matrix-js/src/runtime.ts index 62eff71ad17..d595c7a1805 100644 --- a/extensions/matrix-js/src/runtime.ts +++ b/extensions/matrix-js/src/runtime.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime } from "openclaw/plugin-sdk"; +import type { PluginRuntime } from "openclaw/plugin-sdk/matrix-js"; let runtime: PluginRuntime | null = null; diff --git a/extensions/matrix-js/src/tool-actions.ts b/extensions/matrix-js/src/tool-actions.ts index 9a305b0ca3d..88b584cee4e 100644 --- a/extensions/matrix-js/src/tool-actions.ts +++ b/extensions/matrix-js/src/tool-actions.ts @@ -5,7 +5,7 @@ import { readNumberParam, readReactionParams, readStringParam, -} from "openclaw/plugin-sdk"; +} from "openclaw/plugin-sdk/matrix-js"; import { bootstrapMatrixVerification, acceptMatrixVerification, diff --git a/extensions/matrix-js/src/types.ts b/extensions/matrix-js/src/types.ts index 03b2b06358b..8b755d86d2e 100644 --- a/extensions/matrix-js/src/types.ts +++ b/extensions/matrix-js/src/types.ts @@ -1,4 +1,4 @@ -import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk"; +import type { DmPolicy, GroupPolicy } from "openclaw/plugin-sdk/matrix-js"; export type { DmPolicy, GroupPolicy }; export type ReplyToMode = "off" | "first" | "all"; diff --git a/package.json b/package.json index 65fb40d3988..ad9847f0dec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openclaw", - "version": "2026.3.2", + "version": "2026.3.3", "description": "Multi-channel AI gateway with extensible messaging integrations", "keywords": [], "homepage": "https://github.com/openclaw/openclaw#readme", @@ -40,6 +40,174 @@ "types": "./dist/plugin-sdk/index.d.ts", "default": "./dist/plugin-sdk/index.js" }, + "./plugin-sdk/core": { + "types": "./dist/plugin-sdk/core.d.ts", + "default": "./dist/plugin-sdk/core.js" + }, + "./plugin-sdk/compat": { + "types": "./dist/plugin-sdk/compat.d.ts", + "default": "./dist/plugin-sdk/compat.js" + }, + "./plugin-sdk/telegram": { + "types": "./dist/plugin-sdk/telegram.d.ts", + "default": "./dist/plugin-sdk/telegram.js" + }, + "./plugin-sdk/discord": { + "types": "./dist/plugin-sdk/discord.d.ts", + "default": "./dist/plugin-sdk/discord.js" + }, + "./plugin-sdk/slack": { + "types": "./dist/plugin-sdk/slack.d.ts", + "default": "./dist/plugin-sdk/slack.js" + }, + "./plugin-sdk/signal": { + "types": "./dist/plugin-sdk/signal.d.ts", + "default": "./dist/plugin-sdk/signal.js" + }, + "./plugin-sdk/imessage": { + "types": "./dist/plugin-sdk/imessage.d.ts", + "default": "./dist/plugin-sdk/imessage.js" + }, + "./plugin-sdk/whatsapp": { + "types": "./dist/plugin-sdk/whatsapp.d.ts", + "default": "./dist/plugin-sdk/whatsapp.js" + }, + "./plugin-sdk/line": { + "types": "./dist/plugin-sdk/line.d.ts", + "default": "./dist/plugin-sdk/line.js" + }, + "./plugin-sdk/msteams": { + "types": "./dist/plugin-sdk/msteams.d.ts", + "default": "./dist/plugin-sdk/msteams.js" + }, + "./plugin-sdk/acpx": { + "types": "./dist/plugin-sdk/acpx.d.ts", + "default": "./dist/plugin-sdk/acpx.js" + }, + "./plugin-sdk/bluebubbles": { + "types": "./dist/plugin-sdk/bluebubbles.d.ts", + "default": "./dist/plugin-sdk/bluebubbles.js" + }, + "./plugin-sdk/copilot-proxy": { + "types": "./dist/plugin-sdk/copilot-proxy.d.ts", + "default": "./dist/plugin-sdk/copilot-proxy.js" + }, + "./plugin-sdk/device-pair": { + "types": "./dist/plugin-sdk/device-pair.d.ts", + "default": "./dist/plugin-sdk/device-pair.js" + }, + "./plugin-sdk/diagnostics-otel": { + "types": "./dist/plugin-sdk/diagnostics-otel.d.ts", + "default": "./dist/plugin-sdk/diagnostics-otel.js" + }, + "./plugin-sdk/diffs": { + "types": "./dist/plugin-sdk/diffs.d.ts", + "default": "./dist/plugin-sdk/diffs.js" + }, + "./plugin-sdk/feishu": { + "types": "./dist/plugin-sdk/feishu.d.ts", + "default": "./dist/plugin-sdk/feishu.js" + }, + "./plugin-sdk/google-gemini-cli-auth": { + "types": "./dist/plugin-sdk/google-gemini-cli-auth.d.ts", + "default": "./dist/plugin-sdk/google-gemini-cli-auth.js" + }, + "./plugin-sdk/googlechat": { + "types": "./dist/plugin-sdk/googlechat.d.ts", + "default": "./dist/plugin-sdk/googlechat.js" + }, + "./plugin-sdk/irc": { + "types": "./dist/plugin-sdk/irc.d.ts", + "default": "./dist/plugin-sdk/irc.js" + }, + "./plugin-sdk/llm-task": { + "types": "./dist/plugin-sdk/llm-task.d.ts", + "default": "./dist/plugin-sdk/llm-task.js" + }, + "./plugin-sdk/lobster": { + "types": "./dist/plugin-sdk/lobster.d.ts", + "default": "./dist/plugin-sdk/lobster.js" + }, + "./plugin-sdk/matrix": { + "types": "./dist/plugin-sdk/matrix.d.ts", + "default": "./dist/plugin-sdk/matrix.js" + }, + "./plugin-sdk/matrix-js": { + "types": "./dist/plugin-sdk/matrix-js.d.ts", + "default": "./dist/plugin-sdk/matrix-js.js" + }, + "./plugin-sdk/mattermost": { + "types": "./dist/plugin-sdk/mattermost.d.ts", + "default": "./dist/plugin-sdk/mattermost.js" + }, + "./plugin-sdk/memory-core": { + "types": "./dist/plugin-sdk/memory-core.d.ts", + "default": "./dist/plugin-sdk/memory-core.js" + }, + "./plugin-sdk/memory-lancedb": { + "types": "./dist/plugin-sdk/memory-lancedb.d.ts", + "default": "./dist/plugin-sdk/memory-lancedb.js" + }, + "./plugin-sdk/minimax-portal-auth": { + "types": "./dist/plugin-sdk/minimax-portal-auth.d.ts", + "default": "./dist/plugin-sdk/minimax-portal-auth.js" + }, + "./plugin-sdk/nextcloud-talk": { + "types": "./dist/plugin-sdk/nextcloud-talk.d.ts", + "default": "./dist/plugin-sdk/nextcloud-talk.js" + }, + "./plugin-sdk/nostr": { + "types": "./dist/plugin-sdk/nostr.d.ts", + "default": "./dist/plugin-sdk/nostr.js" + }, + "./plugin-sdk/open-prose": { + "types": "./dist/plugin-sdk/open-prose.d.ts", + "default": "./dist/plugin-sdk/open-prose.js" + }, + "./plugin-sdk/phone-control": { + "types": "./dist/plugin-sdk/phone-control.d.ts", + "default": "./dist/plugin-sdk/phone-control.js" + }, + "./plugin-sdk/qwen-portal-auth": { + "types": "./dist/plugin-sdk/qwen-portal-auth.d.ts", + "default": "./dist/plugin-sdk/qwen-portal-auth.js" + }, + "./plugin-sdk/synology-chat": { + "types": "./dist/plugin-sdk/synology-chat.d.ts", + "default": "./dist/plugin-sdk/synology-chat.js" + }, + "./plugin-sdk/talk-voice": { + "types": "./dist/plugin-sdk/talk-voice.d.ts", + "default": "./dist/plugin-sdk/talk-voice.js" + }, + "./plugin-sdk/test-utils": { + "types": "./dist/plugin-sdk/test-utils.d.ts", + "default": "./dist/plugin-sdk/test-utils.js" + }, + "./plugin-sdk/thread-ownership": { + "types": "./dist/plugin-sdk/thread-ownership.d.ts", + "default": "./dist/plugin-sdk/thread-ownership.js" + }, + "./plugin-sdk/tlon": { + "types": "./dist/plugin-sdk/tlon.d.ts", + "default": "./dist/plugin-sdk/tlon.js" + }, + "./plugin-sdk/twitch": { + "types": "./dist/plugin-sdk/twitch.d.ts", + "default": "./dist/plugin-sdk/twitch.js" + }, + "./plugin-sdk/voice-call": { + "types": "./dist/plugin-sdk/voice-call.d.ts", + "default": "./dist/plugin-sdk/voice-call.js" + }, + "./plugin-sdk/zalo": { + "types": "./dist/plugin-sdk/zalo.d.ts", + "default": "./dist/plugin-sdk/zalo.js" + }, + "./plugin-sdk/zalouser": { + "types": "./dist/plugin-sdk/zalouser.d.ts", + "default": "./dist/plugin-sdk/zalouser.js" + }, "./plugin-sdk/account-id": { "types": "./dist/plugin-sdk/account-id.d.ts", "default": "./dist/plugin-sdk/account-id.js" @@ -59,11 +227,11 @@ "android:run": "cd apps/android && ./gradlew :app:installDebug && adb shell am start -n ai.openclaw.android/.MainActivity", "android:test": "cd apps/android && ./gradlew :app:testDebugUnitTest", "android:test:integration": "OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_ANDROID_NODE=1 vitest run --config vitest.live.config.ts src/gateway/android-node.capabilities.live.test.ts", - "build": "pnpm canvas:a2ui:bundle && tsdown && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts", + "build": "pnpm canvas:a2ui:bundle && tsdown && node scripts/copy-plugin-sdk-root-alias.mjs && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/copy-export-html-templates.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-startup-metadata.ts && node --import tsx scripts/write-cli-compat.ts", "build:plugin-sdk:dts": "tsc -p tsconfig.plugin-sdk.dts.json", - "build:strict-smoke": "pnpm canvas:a2ui:bundle && tsdown && pnpm build:plugin-sdk:dts", + "build:strict-smoke": "pnpm canvas:a2ui:bundle && tsdown && node scripts/copy-plugin-sdk-root-alias.mjs && pnpm build:plugin-sdk:dts", "canvas:a2ui:bundle": "bash scripts/bundle-a2ui.sh", - "check": "pnpm format:check && pnpm tsgo && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope && pnpm check:host-env-policy:swift", + "check": "pnpm format:check && pnpm tsgo && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:plugins:no-monolithic-plugin-sdk-entry-imports && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope && pnpm check:host-env-policy:swift", "check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-links", "check:host-env-policy:swift": "node scripts/generate-host-env-security-policy-swift.mjs --check", "check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500", @@ -107,6 +275,7 @@ "lint:docs": "pnpm dlx markdownlint-cli2", "lint:docs:fix": "pnpm dlx markdownlint-cli2 --fix", "lint:fix": "oxlint --type-aware --fix && pnpm format", + "lint:plugins:no-monolithic-plugin-sdk-entry-imports": "node --import tsx scripts/check-no-monolithic-plugin-sdk-entry-imports.ts", "lint:plugins:no-register-http-handler": "node scripts/check-no-register-http-handler.mjs", "lint:swift": "swiftlint lint --config .swiftlint.yml && (cd apps/ios && swiftlint lint --config .swiftlint.yml)", "lint:tmp:channel-agnostic-boundaries": "node scripts/check-channel-agnostic-boundaries.mjs", @@ -173,7 +342,6 @@ "@grammyjs/runner": "^2.0.3", "@grammyjs/transformer-throttler": "^1.2.1", "@homebridge/ciao": "^1.3.5", - "@larksuiteoapi/node-sdk": "^1.59.0", "@line/bot-sdk": "^10.6.0", "@lydell/node-pty": "1.2.0-beta.3", "@mariozechner/pi-agent-core": "0.55.3", @@ -197,7 +365,6 @@ "express": "^5.2.1", "file-type": "^21.3.0", "gaxios": "7.1.3", - "google-auth-library": "10.6.1", "grammy": "^1.41.0", "https-proxy-agent": "^7.0.6", "ipaddr.js": "^2.3.0", @@ -249,9 +416,6 @@ "@napi-rs/canvas": "^0.1.89", "node-llama-cpp": "3.16.2" }, - "optionalDependencies": { - "@discordjs/opus": "^0.10.0" - }, "engines": { "node": ">=22.12.0" }, @@ -260,7 +424,7 @@ "minimumReleaseAge": 2880, "overrides": { "hono": "4.11.10", - "fast-xml-parser": "5.3.6", + "fast-xml-parser": "5.3.8", "request": "npm:@cypress/request@3.0.10", "request-promise": "npm:@cypress/request-promise@5.0.0", "form-data": "2.5.4", diff --git a/scripts/check-plugin-sdk-exports.mjs b/scripts/check-plugin-sdk-exports.mjs index 51f58b8aa6b..31520f8d8d5 100755 --- a/scripts/check-plugin-sdk-exports.mjs +++ b/scripts/check-plugin-sdk-exports.mjs @@ -41,6 +41,55 @@ const exportedNames = exportMatch[1] const exportSet = new Set(exportedNames); +const requiredSubpathEntries = [ + "core", + "compat", + "telegram", + "discord", + "slack", + "signal", + "imessage", + "whatsapp", + "line", + "msteams", + "acpx", + "bluebubbles", + "copilot-proxy", + "device-pair", + "diagnostics-otel", + "diffs", + "feishu", + "google-gemini-cli-auth", + "googlechat", + "irc", + "llm-task", + "lobster", + "matrix", + "matrix-js", + "mattermost", + "memory-core", + "memory-lancedb", + "minimax-portal-auth", + "nextcloud-talk", + "nostr", + "open-prose", + "phone-control", + "qwen-portal-auth", + "synology-chat", + "talk-voice", + "test-utils", + "thread-ownership", + "tlon", + "twitch", + "voice-call", + "zalo", + "zalouser", + "account-id", + "keyed-async-queue", +]; + +const requiredRuntimeShimEntries = ["root-alias.cjs"]; + // Critical functions that channel extension plugins import from openclaw/plugin-sdk. // If any of these are missing, plugins will fail at runtime with: // TypeError: (0 , _pluginSdk.) is not a function @@ -76,10 +125,33 @@ for (const name of requiredExports) { } } +for (const entry of requiredSubpathEntries) { + const jsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.js`); + const dtsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.d.ts`); + if (!existsSync(jsPath)) { + console.error(`MISSING SUBPATH JS: dist/plugin-sdk/${entry}.js`); + missing += 1; + } + if (!existsSync(dtsPath)) { + console.error(`MISSING SUBPATH DTS: dist/plugin-sdk/${entry}.d.ts`); + missing += 1; + } +} + +for (const entry of requiredRuntimeShimEntries) { + const shimPath = resolve(__dirname, "..", "dist", "plugin-sdk", entry); + if (!existsSync(shimPath)) { + console.error(`MISSING RUNTIME SHIM: dist/plugin-sdk/${entry}`); + missing += 1; + } +} + if (missing > 0) { - console.error(`\nERROR: ${missing} required export(s) missing from dist/plugin-sdk/index.js.`); + console.error( + `\nERROR: ${missing} required plugin-sdk artifact(s) missing (named exports or subpath files).`, + ); console.error("This will break channel extension plugins at runtime."); - console.error("Check src/plugin-sdk/index.ts and rebuild."); + console.error("Check src/plugin-sdk/index.ts, subpath entries, and rebuild."); process.exit(1); } diff --git a/scripts/release-check.ts b/scripts/release-check.ts index 03ceff6b94e..a1b4a28d1f6 100755 --- a/scripts/release-check.ts +++ b/scripts/release-check.ts @@ -14,6 +14,95 @@ const requiredPathGroups = [ ["dist/entry.js", "dist/entry.mjs"], "dist/plugin-sdk/index.js", "dist/plugin-sdk/index.d.ts", + "dist/plugin-sdk/core.js", + "dist/plugin-sdk/core.d.ts", + "dist/plugin-sdk/root-alias.cjs", + "dist/plugin-sdk/compat.js", + "dist/plugin-sdk/compat.d.ts", + "dist/plugin-sdk/telegram.js", + "dist/plugin-sdk/telegram.d.ts", + "dist/plugin-sdk/discord.js", + "dist/plugin-sdk/discord.d.ts", + "dist/plugin-sdk/slack.js", + "dist/plugin-sdk/slack.d.ts", + "dist/plugin-sdk/signal.js", + "dist/plugin-sdk/signal.d.ts", + "dist/plugin-sdk/imessage.js", + "dist/plugin-sdk/imessage.d.ts", + "dist/plugin-sdk/whatsapp.js", + "dist/plugin-sdk/whatsapp.d.ts", + "dist/plugin-sdk/line.js", + "dist/plugin-sdk/line.d.ts", + "dist/plugin-sdk/msteams.js", + "dist/plugin-sdk/msteams.d.ts", + "dist/plugin-sdk/acpx.js", + "dist/plugin-sdk/acpx.d.ts", + "dist/plugin-sdk/bluebubbles.js", + "dist/plugin-sdk/bluebubbles.d.ts", + "dist/plugin-sdk/copilot-proxy.js", + "dist/plugin-sdk/copilot-proxy.d.ts", + "dist/plugin-sdk/device-pair.js", + "dist/plugin-sdk/device-pair.d.ts", + "dist/plugin-sdk/diagnostics-otel.js", + "dist/plugin-sdk/diagnostics-otel.d.ts", + "dist/plugin-sdk/diffs.js", + "dist/plugin-sdk/diffs.d.ts", + "dist/plugin-sdk/feishu.js", + "dist/plugin-sdk/feishu.d.ts", + "dist/plugin-sdk/google-gemini-cli-auth.js", + "dist/plugin-sdk/google-gemini-cli-auth.d.ts", + "dist/plugin-sdk/googlechat.js", + "dist/plugin-sdk/googlechat.d.ts", + "dist/plugin-sdk/irc.js", + "dist/plugin-sdk/irc.d.ts", + "dist/plugin-sdk/llm-task.js", + "dist/plugin-sdk/llm-task.d.ts", + "dist/plugin-sdk/lobster.js", + "dist/plugin-sdk/lobster.d.ts", + "dist/plugin-sdk/matrix.js", + "dist/plugin-sdk/matrix.d.ts", + "dist/plugin-sdk/matrix-js.js", + "dist/plugin-sdk/matrix-js.d.ts", + "dist/plugin-sdk/mattermost.js", + "dist/plugin-sdk/mattermost.d.ts", + "dist/plugin-sdk/memory-core.js", + "dist/plugin-sdk/memory-core.d.ts", + "dist/plugin-sdk/memory-lancedb.js", + "dist/plugin-sdk/memory-lancedb.d.ts", + "dist/plugin-sdk/minimax-portal-auth.js", + "dist/plugin-sdk/minimax-portal-auth.d.ts", + "dist/plugin-sdk/nextcloud-talk.js", + "dist/plugin-sdk/nextcloud-talk.d.ts", + "dist/plugin-sdk/nostr.js", + "dist/plugin-sdk/nostr.d.ts", + "dist/plugin-sdk/open-prose.js", + "dist/plugin-sdk/open-prose.d.ts", + "dist/plugin-sdk/phone-control.js", + "dist/plugin-sdk/phone-control.d.ts", + "dist/plugin-sdk/qwen-portal-auth.js", + "dist/plugin-sdk/qwen-portal-auth.d.ts", + "dist/plugin-sdk/synology-chat.js", + "dist/plugin-sdk/synology-chat.d.ts", + "dist/plugin-sdk/talk-voice.js", + "dist/plugin-sdk/talk-voice.d.ts", + "dist/plugin-sdk/test-utils.js", + "dist/plugin-sdk/test-utils.d.ts", + "dist/plugin-sdk/thread-ownership.js", + "dist/plugin-sdk/thread-ownership.d.ts", + "dist/plugin-sdk/tlon.js", + "dist/plugin-sdk/tlon.d.ts", + "dist/plugin-sdk/twitch.js", + "dist/plugin-sdk/twitch.d.ts", + "dist/plugin-sdk/voice-call.js", + "dist/plugin-sdk/voice-call.d.ts", + "dist/plugin-sdk/zalo.js", + "dist/plugin-sdk/zalo.d.ts", + "dist/plugin-sdk/zalouser.js", + "dist/plugin-sdk/zalouser.d.ts", + "dist/plugin-sdk/account-id.js", + "dist/plugin-sdk/account-id.d.ts", + "dist/plugin-sdk/keyed-async-queue.js", + "dist/plugin-sdk/keyed-async-queue.d.ts", "dist/build-info.json", ]; const forbiddenPrefixes = ["dist/OpenClaw.app/"]; diff --git a/scripts/write-plugin-sdk-entry-dts.ts b/scripts/write-plugin-sdk-entry-dts.ts index 674f89ed13a..7a12baaf8ac 100644 --- a/scripts/write-plugin-sdk-entry-dts.ts +++ b/scripts/write-plugin-sdk-entry-dts.ts @@ -6,7 +6,53 @@ import path from "node:path"; // // Our package export map points subpath `types` at `dist/plugin-sdk/.d.ts`, so we // generate stable entry d.ts files that re-export the real declarations. -const entrypoints = ["index", "account-id"] as const; +const entrypoints = [ + "index", + "core", + "compat", + "telegram", + "discord", + "slack", + "signal", + "imessage", + "whatsapp", + "line", + "msteams", + "acpx", + "bluebubbles", + "copilot-proxy", + "device-pair", + "diagnostics-otel", + "diffs", + "feishu", + "google-gemini-cli-auth", + "googlechat", + "irc", + "llm-task", + "lobster", + "matrix", + "matrix-js", + "mattermost", + "memory-core", + "memory-lancedb", + "minimax-portal-auth", + "nextcloud-talk", + "nostr", + "open-prose", + "phone-control", + "qwen-portal-auth", + "synology-chat", + "talk-voice", + "test-utils", + "thread-ownership", + "tlon", + "twitch", + "voice-call", + "zalo", + "zalouser", + "account-id", + "keyed-async-queue", +] as const; for (const entry of entrypoints) { const out = path.join(process.cwd(), `dist/plugin-sdk/${entry}.d.ts`); fs.mkdirSync(path.dirname(out), { recursive: true }); diff --git a/src/plugin-sdk/matrix-js.ts b/src/plugin-sdk/matrix-js.ts new file mode 100644 index 00000000000..be55ca4a366 --- /dev/null +++ b/src/plugin-sdk/matrix-js.ts @@ -0,0 +1,11 @@ +// Matrix-js plugin-sdk surface. +// Reuse root plugin-sdk exports on branches that don't yet expose matrix-specific subpaths. + +export * from "./index.js"; + +export type { ChannelSetupInput } from "../channels/plugins/types.js"; +export type { GatewayRequestHandlerOptions } from "../gateway/server-methods/types.js"; +export { migrateBaseNameToDefaultAccount } from "../channels/plugins/setup-helpers.js"; +export { promptAccountId } from "../channels/plugins/onboarding/helpers.js"; +export { writeJsonFileAtomically } from "./json-store.js"; +export { formatZonedTimestamp } from "../infra/format-time/format-datetime.js"; diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index c0ac9751a3d..c9f690f3366 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -22,6 +22,7 @@ import { isPathInside, safeStatSync } from "./path-safety.js"; import { createPluginRegistry, type PluginRecord, type PluginRegistry } from "./registry.js"; import { setActivePluginRegistry } from "./runtime.js"; import { createPluginRuntime } from "./runtime/index.js"; +import type { PluginRuntime } from "./runtime/types.js"; import { validateJsonSchemaValue } from "./schema-validator.js"; import type { OpenClawPluginDefinition, @@ -85,10 +86,111 @@ const resolvePluginSdkAliasFile = (params: { }; const resolvePluginSdkAlias = (): string | null => - resolvePluginSdkAliasFile({ srcFile: "index.ts", distFile: "index.js" }); + resolvePluginSdkAliasFile({ srcFile: "root-alias.cjs", distFile: "root-alias.cjs" }); -const resolvePluginSdkAccountIdAlias = (): string | null => { - return resolvePluginSdkAliasFile({ srcFile: "account-id.ts", distFile: "account-id.js" }); +const pluginSdkScopedAliasEntries = [ + { subpath: "core", srcFile: "core.ts", distFile: "core.js" }, + { subpath: "compat", srcFile: "compat.ts", distFile: "compat.js" }, + { subpath: "telegram", srcFile: "telegram.ts", distFile: "telegram.js" }, + { subpath: "discord", srcFile: "discord.ts", distFile: "discord.js" }, + { subpath: "slack", srcFile: "slack.ts", distFile: "slack.js" }, + { subpath: "signal", srcFile: "signal.ts", distFile: "signal.js" }, + { subpath: "imessage", srcFile: "imessage.ts", distFile: "imessage.js" }, + { subpath: "whatsapp", srcFile: "whatsapp.ts", distFile: "whatsapp.js" }, + { subpath: "line", srcFile: "line.ts", distFile: "line.js" }, + { subpath: "msteams", srcFile: "msteams.ts", distFile: "msteams.js" }, + { subpath: "acpx", srcFile: "acpx.ts", distFile: "acpx.js" }, + { subpath: "bluebubbles", srcFile: "bluebubbles.ts", distFile: "bluebubbles.js" }, + { + subpath: "copilot-proxy", + srcFile: "copilot-proxy.ts", + distFile: "copilot-proxy.js", + }, + { subpath: "device-pair", srcFile: "device-pair.ts", distFile: "device-pair.js" }, + { + subpath: "diagnostics-otel", + srcFile: "diagnostics-otel.ts", + distFile: "diagnostics-otel.js", + }, + { subpath: "diffs", srcFile: "diffs.ts", distFile: "diffs.js" }, + { subpath: "feishu", srcFile: "feishu.ts", distFile: "feishu.js" }, + { + subpath: "google-gemini-cli-auth", + srcFile: "google-gemini-cli-auth.ts", + distFile: "google-gemini-cli-auth.js", + }, + { subpath: "googlechat", srcFile: "googlechat.ts", distFile: "googlechat.js" }, + { subpath: "irc", srcFile: "irc.ts", distFile: "irc.js" }, + { subpath: "llm-task", srcFile: "llm-task.ts", distFile: "llm-task.js" }, + { subpath: "lobster", srcFile: "lobster.ts", distFile: "lobster.js" }, + { subpath: "matrix", srcFile: "matrix.ts", distFile: "matrix.js" }, + { subpath: "matrix-js", srcFile: "matrix-js.ts", distFile: "matrix-js.js" }, + { subpath: "mattermost", srcFile: "mattermost.ts", distFile: "mattermost.js" }, + { subpath: "memory-core", srcFile: "memory-core.ts", distFile: "memory-core.js" }, + { + subpath: "memory-lancedb", + srcFile: "memory-lancedb.ts", + distFile: "memory-lancedb.js", + }, + { + subpath: "minimax-portal-auth", + srcFile: "minimax-portal-auth.ts", + distFile: "minimax-portal-auth.js", + }, + { + subpath: "nextcloud-talk", + srcFile: "nextcloud-talk.ts", + distFile: "nextcloud-talk.js", + }, + { subpath: "nostr", srcFile: "nostr.ts", distFile: "nostr.js" }, + { subpath: "open-prose", srcFile: "open-prose.ts", distFile: "open-prose.js" }, + { + subpath: "phone-control", + srcFile: "phone-control.ts", + distFile: "phone-control.js", + }, + { + subpath: "qwen-portal-auth", + srcFile: "qwen-portal-auth.ts", + distFile: "qwen-portal-auth.js", + }, + { + subpath: "synology-chat", + srcFile: "synology-chat.ts", + distFile: "synology-chat.js", + }, + { subpath: "talk-voice", srcFile: "talk-voice.ts", distFile: "talk-voice.js" }, + { subpath: "test-utils", srcFile: "test-utils.ts", distFile: "test-utils.js" }, + { + subpath: "thread-ownership", + srcFile: "thread-ownership.ts", + distFile: "thread-ownership.js", + }, + { subpath: "tlon", srcFile: "tlon.ts", distFile: "tlon.js" }, + { subpath: "twitch", srcFile: "twitch.ts", distFile: "twitch.js" }, + { subpath: "voice-call", srcFile: "voice-call.ts", distFile: "voice-call.js" }, + { subpath: "zalo", srcFile: "zalo.ts", distFile: "zalo.js" }, + { subpath: "zalouser", srcFile: "zalouser.ts", distFile: "zalouser.js" }, + { subpath: "account-id", srcFile: "account-id.ts", distFile: "account-id.js" }, + { + subpath: "keyed-async-queue", + srcFile: "keyed-async-queue.ts", + distFile: "keyed-async-queue.js", + }, +] as const; + +const resolvePluginSdkScopedAliasMap = (): Record => { + const aliasMap: Record = {}; + for (const entry of pluginSdkScopedAliasEntries) { + const resolved = resolvePluginSdkAliasFile({ + srcFile: entry.srcFile, + distFile: entry.distFile, + }); + if (resolved) { + aliasMap[`openclaw/plugin-sdk/${entry.subpath}`] = resolved; + } + } + return aliasMap; }; export const __testing = { @@ -393,7 +495,39 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi // Clear previously registered plugin commands before reloading clearPluginCommands(); - const runtime = createPluginRuntime(); + // Lazily initialize the runtime so startup paths that discover/skip plugins do + // not eagerly load every channel runtime dependency. + let resolvedRuntime: PluginRuntime | null = null; + const resolveRuntime = (): PluginRuntime => { + resolvedRuntime ??= createPluginRuntime(); + return resolvedRuntime; + }; + const runtime = new Proxy({} as PluginRuntime, { + get(_target, prop, receiver) { + return Reflect.get(resolveRuntime(), prop, receiver); + }, + set(_target, prop, value, receiver) { + return Reflect.set(resolveRuntime(), prop, value, receiver); + }, + has(_target, prop) { + return Reflect.has(resolveRuntime(), prop); + }, + ownKeys() { + return Reflect.ownKeys(resolveRuntime() as object); + }, + getOwnPropertyDescriptor(_target, prop) { + return Reflect.getOwnPropertyDescriptor(resolveRuntime() as object, prop); + }, + defineProperty(_target, prop, attributes) { + return Reflect.defineProperty(resolveRuntime() as object, prop, attributes); + }, + deleteProperty(_target, prop) { + return Reflect.deleteProperty(resolveRuntime() as object, prop); + }, + getPrototypeOf() { + return Reflect.getPrototypeOf(resolveRuntime() as object); + }, + }); const { registry, createApi } = createPluginRegistry({ logger, runtime, @@ -403,6 +537,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi const discovery = discoverOpenClawPlugins({ workspaceDir: options.workspaceDir, extraPaths: normalized.loadPaths, + cache: options.cache, }); const manifestRegistry = loadPluginManifestRegistry({ config: cfg, @@ -434,18 +569,16 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi return jitiLoader; } const pluginSdkAlias = resolvePluginSdkAlias(); - const pluginSdkAccountIdAlias = resolvePluginSdkAccountIdAlias(); + const aliasMap = { + ...(pluginSdkAlias ? { "openclaw/plugin-sdk": pluginSdkAlias } : {}), + ...resolvePluginSdkScopedAliasMap(), + }; jitiLoader = createJiti(import.meta.url, { interopDefault: true, extensions: [".ts", ".tsx", ".mts", ".cts", ".mtsx", ".ctsx", ".js", ".mjs", ".cjs", ".json"], - ...(pluginSdkAlias || pluginSdkAccountIdAlias + ...(Object.keys(aliasMap).length > 0 ? { - alias: { - ...(pluginSdkAlias ? { "openclaw/plugin-sdk": pluginSdkAlias } : {}), - ...(pluginSdkAccountIdAlias - ? { "openclaw/plugin-sdk/account-id": pluginSdkAccountIdAlias } - : {}), - }, + alias: aliasMap, } : {}), }); @@ -528,6 +661,25 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi continue; } + // Fast-path bundled memory plugins that are guaranteed disabled by slot policy. + // This avoids opening/importing heavy memory plugin modules that will never register. + if (candidate.origin === "bundled" && manifestRecord.kind === "memory") { + const earlyMemoryDecision = resolveMemorySlotDecision({ + id: record.id, + kind: "memory", + slot: memorySlot, + selectedId: selectedMemoryPluginId, + }); + if (!earlyMemoryDecision.enabled) { + record.enabled = false; + record.status = "disabled"; + record.error = earlyMemoryDecision.reason; + registry.plugins.push(record); + seenIds.set(pluginId, candidate.origin); + continue; + } + } + if (!manifestRecord.configSchema) { pushPluginLoadError("missing config schema"); continue; diff --git a/tsconfig.plugin-sdk.dts.json b/tsconfig.plugin-sdk.dts.json index ba48a3d1eeb..ae0bb67b001 100644 --- a/tsconfig.plugin-sdk.dts.json +++ b/tsconfig.plugin-sdk.dts.json @@ -12,8 +12,50 @@ }, "include": [ "src/plugin-sdk/index.ts", + "src/plugin-sdk/core.ts", + "src/plugin-sdk/compat.ts", + "src/plugin-sdk/telegram.ts", + "src/plugin-sdk/discord.ts", + "src/plugin-sdk/slack.ts", + "src/plugin-sdk/signal.ts", + "src/plugin-sdk/imessage.ts", + "src/plugin-sdk/whatsapp.ts", + "src/plugin-sdk/line.ts", + "src/plugin-sdk/msteams.ts", "src/plugin-sdk/account-id.ts", "src/plugin-sdk/keyed-async-queue.ts", + "src/plugin-sdk/acpx.ts", + "src/plugin-sdk/bluebubbles.ts", + "src/plugin-sdk/copilot-proxy.ts", + "src/plugin-sdk/device-pair.ts", + "src/plugin-sdk/diagnostics-otel.ts", + "src/plugin-sdk/diffs.ts", + "src/plugin-sdk/feishu.ts", + "src/plugin-sdk/google-gemini-cli-auth.ts", + "src/plugin-sdk/googlechat.ts", + "src/plugin-sdk/irc.ts", + "src/plugin-sdk/llm-task.ts", + "src/plugin-sdk/lobster.ts", + "src/plugin-sdk/matrix.ts", + "src/plugin-sdk/matrix-js.ts", + "src/plugin-sdk/mattermost.ts", + "src/plugin-sdk/memory-core.ts", + "src/plugin-sdk/memory-lancedb.ts", + "src/plugin-sdk/minimax-portal-auth.ts", + "src/plugin-sdk/nextcloud-talk.ts", + "src/plugin-sdk/nostr.ts", + "src/plugin-sdk/open-prose.ts", + "src/plugin-sdk/phone-control.ts", + "src/plugin-sdk/qwen-portal-auth.ts", + "src/plugin-sdk/synology-chat.ts", + "src/plugin-sdk/talk-voice.ts", + "src/plugin-sdk/test-utils.ts", + "src/plugin-sdk/thread-ownership.ts", + "src/plugin-sdk/tlon.ts", + "src/plugin-sdk/twitch.ts", + "src/plugin-sdk/voice-call.ts", + "src/plugin-sdk/zalo.ts", + "src/plugin-sdk/zalouser.ts", "src/types/**/*.d.ts" ], "exclude": ["node_modules", "dist", "src/**/*.test.ts"] diff --git a/tsdown.config.ts b/tsdown.config.ts index b4c9d97b48d..623a6d0ff47 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -4,6 +4,54 @@ const env = { NODE_ENV: "production", }; +const pluginSdkEntrypoints = [ + "index", + "core", + "compat", + "telegram", + "discord", + "slack", + "signal", + "imessage", + "whatsapp", + "line", + "msteams", + "acpx", + "bluebubbles", + "copilot-proxy", + "device-pair", + "diagnostics-otel", + "diffs", + "feishu", + "google-gemini-cli-auth", + "googlechat", + "irc", + "llm-task", + "lobster", + "matrix", + "matrix-js", + "mattermost", + "memory-core", + "memory-lancedb", + "minimax-portal-auth", + "nextcloud-talk", + "nostr", + "open-prose", + "phone-control", + "qwen-portal-auth", + "synology-chat", + "talk-voice", + "test-utils", + "thread-ownership", + "tlon", + "twitch", + "voice-call", + "zalo", + "zalouser", + "account-id", + "keyed-async-queue", +] as const; + export default defineConfig([ { entry: "src/index.ts", @@ -31,19 +79,30 @@ export default defineConfig([ platform: "node", }, { - entry: "src/plugin-sdk/index.ts", - outDir: "dist/plugin-sdk", + // Keep sync lazy-runtime channel modules as concrete dist files. + entry: { + "channels/plugins/agent-tools/whatsapp-login": + "src/channels/plugins/agent-tools/whatsapp-login.ts", + "channels/plugins/actions/discord": "src/channels/plugins/actions/discord.ts", + "channels/plugins/actions/signal": "src/channels/plugins/actions/signal.ts", + "channels/plugins/actions/telegram": "src/channels/plugins/actions/telegram.ts", + "telegram/audit": "src/telegram/audit.ts", + "telegram/token": "src/telegram/token.ts", + "line/accounts": "src/line/accounts.ts", + "line/send": "src/line/send.ts", + "line/template-messages": "src/line/template-messages.ts", + }, env, fixedExtension: false, platform: "node", }, - { - entry: "src/plugin-sdk/account-id.ts", + ...pluginSdkEntrypoints.map((entry) => ({ + entry: `src/plugin-sdk/${entry}.ts`, outDir: "dist/plugin-sdk", env, fixedExtension: false, - platform: "node", - }, + platform: "node" as const, + })), { entry: "src/extensionAPI.ts", env, diff --git a/vitest.config.ts b/vitest.config.ts index 51eda12f55b..26bcf574955 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -8,19 +8,61 @@ const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true"; const isWindows = process.platform === "win32"; const localWorkers = Math.max(4, Math.min(16, os.cpus().length)); const ciWorkers = isWindows ? 2 : 3; +const pluginSdkSubpaths = [ + "account-id", + "core", + "compat", + "telegram", + "discord", + "slack", + "signal", + "imessage", + "whatsapp", + "line", + "msteams", + "acpx", + "bluebubbles", + "copilot-proxy", + "device-pair", + "diagnostics-otel", + "diffs", + "feishu", + "google-gemini-cli-auth", + "googlechat", + "irc", + "llm-task", + "lobster", + "matrix", + "matrix-js", + "mattermost", + "memory-core", + "memory-lancedb", + "minimax-portal-auth", + "nextcloud-talk", + "nostr", + "open-prose", + "phone-control", + "qwen-portal-auth", + "synology-chat", + "talk-voice", + "test-utils", + "thread-ownership", + "tlon", + "twitch", + "voice-call", + "zalo", + "zalouser", + "keyed-async-queue", +] as const; export default defineConfig({ resolve: { // Keep this ordered: the base `openclaw/plugin-sdk` alias is a prefix match. alias: [ - { - find: "openclaw/plugin-sdk/account-id", - replacement: path.join(repoRoot, "src", "plugin-sdk", "account-id.ts"), - }, - { - find: "openclaw/plugin-sdk/keyed-async-queue", - replacement: path.join(repoRoot, "src", "plugin-sdk", "keyed-async-queue.ts"), - }, + ...pluginSdkSubpaths.map((subpath) => ({ + find: `openclaw/plugin-sdk/${subpath}`, + replacement: path.join(repoRoot, "src", "plugin-sdk", `${subpath}.ts`), + })), { find: "openclaw/plugin-sdk", replacement: path.join(repoRoot, "src", "plugin-sdk", "index.ts"),