refactor(plugin-sdk): centralize entrypoint manifest
This commit is contained in:
parent
92e765cdee
commit
59940cb3ee
@ -292,6 +292,7 @@
|
|||||||
"moltbot:rpc": "node scripts/run-node.mjs agent --mode rpc --json",
|
"moltbot:rpc": "node scripts/run-node.mjs agent --mode rpc --json",
|
||||||
"openclaw": "node scripts/run-node.mjs",
|
"openclaw": "node scripts/run-node.mjs",
|
||||||
"openclaw:rpc": "node scripts/run-node.mjs agent --mode rpc --json",
|
"openclaw:rpc": "node scripts/run-node.mjs agent --mode rpc --json",
|
||||||
|
"plugin-sdk:sync-exports": "node scripts/sync-plugin-sdk-exports.mjs",
|
||||||
"plugins:sync": "node --import tsx scripts/sync-plugin-versions.ts",
|
"plugins:sync": "node --import tsx scripts/sync-plugin-versions.ts",
|
||||||
"prepack": "pnpm build && pnpm ui:build",
|
"prepack": "pnpm build && pnpm ui:build",
|
||||||
"prepare": "command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1 && git config core.hooksPath git-hooks || exit 0",
|
"prepare": "command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1 && git config core.hooksPath git-hooks || exit 0",
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
import { readFileSync, existsSync } from "node:fs";
|
import { readFileSync, existsSync } from "node:fs";
|
||||||
import { resolve, dirname } from "node:path";
|
import { resolve, dirname } from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { pluginSdkSubpaths } from "./lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
const distFile = resolve(__dirname, "..", "dist", "plugin-sdk", "index.js");
|
const distFile = resolve(__dirname, "..", "dist", "plugin-sdk", "index.js");
|
||||||
@ -41,51 +42,6 @@ const exportedNames = exportMatch[1]
|
|||||||
|
|
||||||
const exportSet = new Set(exportedNames);
|
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",
|
|
||||||
"googlechat",
|
|
||||||
"irc",
|
|
||||||
"llm-task",
|
|
||||||
"lobster",
|
|
||||||
"matrix",
|
|
||||||
"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"];
|
const requiredRuntimeShimEntries = ["root-alias.cjs"];
|
||||||
|
|
||||||
// Critical functions that channel extension plugins import from openclaw/plugin-sdk.
|
// Critical functions that channel extension plugins import from openclaw/plugin-sdk.
|
||||||
@ -123,7 +79,7 @@ for (const name of requiredExports) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const entry of requiredSubpathEntries) {
|
for (const entry of pluginSdkSubpaths) {
|
||||||
const jsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.js`);
|
const jsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.js`);
|
||||||
const dtsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.d.ts`);
|
const dtsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.d.ts`);
|
||||||
if (!existsSync(jsPath)) {
|
if (!existsSync(jsPath)) {
|
||||||
|
|||||||
78
scripts/lib/plugin-sdk-entries.mjs
Normal file
78
scripts/lib/plugin-sdk-entries.mjs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
export const pluginSdkEntrypoints = [
|
||||||
|
"index",
|
||||||
|
"core",
|
||||||
|
"compat",
|
||||||
|
"telegram",
|
||||||
|
"discord",
|
||||||
|
"slack",
|
||||||
|
"signal",
|
||||||
|
"imessage",
|
||||||
|
"whatsapp",
|
||||||
|
"line",
|
||||||
|
"msteams",
|
||||||
|
"acpx",
|
||||||
|
"bluebubbles",
|
||||||
|
"copilot-proxy",
|
||||||
|
"device-pair",
|
||||||
|
"diagnostics-otel",
|
||||||
|
"diffs",
|
||||||
|
"feishu",
|
||||||
|
"googlechat",
|
||||||
|
"irc",
|
||||||
|
"llm-task",
|
||||||
|
"lobster",
|
||||||
|
"matrix",
|
||||||
|
"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",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const pluginSdkSubpaths = pluginSdkEntrypoints.filter((entry) => entry !== "index");
|
||||||
|
|
||||||
|
export function buildPluginSdkEntrySources() {
|
||||||
|
return Object.fromEntries(
|
||||||
|
pluginSdkEntrypoints.map((entry) => [entry, `src/plugin-sdk/${entry}.ts`]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildPluginSdkSpecifiers() {
|
||||||
|
return pluginSdkEntrypoints.map((entry) =>
|
||||||
|
entry === "index" ? "openclaw/plugin-sdk" : `openclaw/plugin-sdk/${entry}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildPluginSdkPackageExports() {
|
||||||
|
return Object.fromEntries(
|
||||||
|
pluginSdkEntrypoints.map((entry) => [
|
||||||
|
entry === "index" ? "./plugin-sdk" : `./plugin-sdk/${entry}`,
|
||||||
|
{
|
||||||
|
types: `./dist/plugin-sdk/${entry}.d.ts`,
|
||||||
|
default: `./dist/plugin-sdk/${entry}.js`,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listPluginSdkDistArtifacts() {
|
||||||
|
return pluginSdkEntrypoints.flatMap((entry) => [
|
||||||
|
`dist/plugin-sdk/${entry}.js`,
|
||||||
|
`dist/plugin-sdk/${entry}.d.ts`,
|
||||||
|
]);
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ import {
|
|||||||
type BundledExtension,
|
type BundledExtension,
|
||||||
type ExtensionPackageJson as PackageJson,
|
type ExtensionPackageJson as PackageJson,
|
||||||
} from "./lib/bundled-extension-manifest.ts";
|
} from "./lib/bundled-extension-manifest.ts";
|
||||||
|
import { listPluginSdkDistArtifacts } from "./lib/plugin-sdk-entries.mjs";
|
||||||
import { sparkleBuildFloorsFromShortVersion, type SparkleBuildFloors } from "./sparkle-build.ts";
|
import { sparkleBuildFloorsFromShortVersion, type SparkleBuildFloors } from "./sparkle-build.ts";
|
||||||
|
|
||||||
export { collectBundledExtensionManifestErrors } from "./lib/bundled-extension-manifest.ts";
|
export { collectBundledExtensionManifestErrors } from "./lib/bundled-extension-manifest.ts";
|
||||||
@ -20,93 +21,8 @@ type PackResult = { files?: PackFile[]; filename?: string; unpackedSize?: number
|
|||||||
const requiredPathGroups = [
|
const requiredPathGroups = [
|
||||||
["dist/index.js", "dist/index.mjs"],
|
["dist/index.js", "dist/index.mjs"],
|
||||||
["dist/entry.js", "dist/entry.mjs"],
|
["dist/entry.js", "dist/entry.mjs"],
|
||||||
"dist/plugin-sdk/index.js",
|
...listPluginSdkDistArtifacts(),
|
||||||
"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/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/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/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",
|
"dist/build-info.json",
|
||||||
];
|
];
|
||||||
const forbiddenPrefixes = ["dist/OpenClaw.app/"];
|
const forbiddenPrefixes = ["dist/OpenClaw.app/"];
|
||||||
|
|||||||
34
scripts/sync-plugin-sdk-exports.mjs
Normal file
34
scripts/sync-plugin-sdk-exports.mjs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import fs from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
|
import { buildPluginSdkPackageExports } from "./lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
||||||
|
const currentExports = packageJson.exports ?? {};
|
||||||
|
const syncedPluginSdkExports = buildPluginSdkPackageExports();
|
||||||
|
|
||||||
|
const nextExports = {};
|
||||||
|
let insertedPluginSdkExports = false;
|
||||||
|
for (const [key, value] of Object.entries(currentExports)) {
|
||||||
|
if (key.startsWith("./plugin-sdk")) {
|
||||||
|
if (!insertedPluginSdkExports) {
|
||||||
|
Object.assign(nextExports, syncedPluginSdkExports);
|
||||||
|
insertedPluginSdkExports = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nextExports[key] = value;
|
||||||
|
if (key === "." && !insertedPluginSdkExports) {
|
||||||
|
Object.assign(nextExports, syncedPluginSdkExports);
|
||||||
|
insertedPluginSdkExports = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!insertedPluginSdkExports) {
|
||||||
|
Object.assign(nextExports, syncedPluginSdkExports);
|
||||||
|
}
|
||||||
|
|
||||||
|
packageJson.exports = nextExports;
|
||||||
|
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, "utf8");
|
||||||
@ -1,57 +1,13 @@
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import { pluginSdkEntrypoints } from "./lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
// `tsc` emits declarations under `dist/plugin-sdk/src/plugin-sdk/*` because the source lives
|
// `tsc` emits declarations under `dist/plugin-sdk/src/plugin-sdk/*` because the source lives
|
||||||
// at `src/plugin-sdk/*` and `rootDir` is `.` (repo root, to support cross-src/extensions refs).
|
// at `src/plugin-sdk/*` and `rootDir` is `.` (repo root, to support cross-src/extensions refs).
|
||||||
//
|
//
|
||||||
// Our package export map points subpath `types` at `dist/plugin-sdk/<entry>.d.ts`, so we
|
// Our package export map points subpath `types` at `dist/plugin-sdk/<entry>.d.ts`, so we
|
||||||
// generate stable entry d.ts files that re-export the real declarations.
|
// generate stable entry d.ts files that re-export the real declarations.
|
||||||
const entrypoints = [
|
for (const entry of pluginSdkEntrypoints) {
|
||||||
"index",
|
|
||||||
"core",
|
|
||||||
"compat",
|
|
||||||
"telegram",
|
|
||||||
"discord",
|
|
||||||
"slack",
|
|
||||||
"signal",
|
|
||||||
"imessage",
|
|
||||||
"whatsapp",
|
|
||||||
"line",
|
|
||||||
"msteams",
|
|
||||||
"acpx",
|
|
||||||
"bluebubbles",
|
|
||||||
"copilot-proxy",
|
|
||||||
"device-pair",
|
|
||||||
"diagnostics-otel",
|
|
||||||
"diffs",
|
|
||||||
"feishu",
|
|
||||||
"googlechat",
|
|
||||||
"irc",
|
|
||||||
"llm-task",
|
|
||||||
"lobster",
|
|
||||||
"matrix",
|
|
||||||
"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`);
|
const out = path.join(process.cwd(), `dist/plugin-sdk/${entry}.d.ts`);
|
||||||
fs.mkdirSync(path.dirname(out), { recursive: true });
|
fs.mkdirSync(path.dirname(out), { recursive: true });
|
||||||
// NodeNext: reference the runtime specifier with `.js`, TS will map it to `.d.ts`.
|
// NodeNext: reference the runtime specifier with `.js`, TS will map it to `.d.ts`.
|
||||||
|
|||||||
@ -4,68 +4,15 @@ import path from "node:path";
|
|||||||
import { pathToFileURL } from "node:url";
|
import { pathToFileURL } from "node:url";
|
||||||
import { build } from "tsdown";
|
import { build } from "tsdown";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
|
buildPluginSdkEntrySources,
|
||||||
|
buildPluginSdkPackageExports,
|
||||||
|
buildPluginSdkSpecifiers,
|
||||||
|
pluginSdkEntrypoints,
|
||||||
|
} from "../../scripts/lib/plugin-sdk-entries.mjs";
|
||||||
import * as sdk from "./index.js";
|
import * as sdk from "./index.js";
|
||||||
|
|
||||||
const pluginSdkEntrypoints = [
|
const pluginSdkSpecifiers = buildPluginSdkSpecifiers();
|
||||||
"index",
|
|
||||||
"core",
|
|
||||||
"compat",
|
|
||||||
"telegram",
|
|
||||||
"discord",
|
|
||||||
"slack",
|
|
||||||
"signal",
|
|
||||||
"imessage",
|
|
||||||
"whatsapp",
|
|
||||||
"line",
|
|
||||||
"msteams",
|
|
||||||
"acpx",
|
|
||||||
"bluebubbles",
|
|
||||||
"copilot-proxy",
|
|
||||||
"device-pair",
|
|
||||||
"diagnostics-otel",
|
|
||||||
"diffs",
|
|
||||||
"feishu",
|
|
||||||
"googlechat",
|
|
||||||
"irc",
|
|
||||||
"llm-task",
|
|
||||||
"lobster",
|
|
||||||
"matrix",
|
|
||||||
"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;
|
|
||||||
|
|
||||||
const pluginSdkSpecifiers = pluginSdkEntrypoints.map((entry) =>
|
|
||||||
entry === "index" ? "openclaw/plugin-sdk" : `openclaw/plugin-sdk/${entry}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
function buildPluginSdkPackageExports() {
|
|
||||||
return Object.fromEntries(
|
|
||||||
pluginSdkEntrypoints.map((entry) => [
|
|
||||||
entry === "index" ? "./plugin-sdk" : `./plugin-sdk/${entry}`,
|
|
||||||
{
|
|
||||||
default: `./dist/plugin-sdk/${entry}.js`,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("plugin-sdk exports", () => {
|
describe("plugin-sdk exports", () => {
|
||||||
it("does not expose runtime modules", () => {
|
it("does not expose runtime modules", () => {
|
||||||
@ -180,9 +127,7 @@ describe("plugin-sdk exports", () => {
|
|||||||
clean: true,
|
clean: true,
|
||||||
config: false,
|
config: false,
|
||||||
dts: false,
|
dts: false,
|
||||||
entry: Object.fromEntries(
|
entry: buildPluginSdkEntrySources(),
|
||||||
pluginSdkEntrypoints.map((entry) => [entry, `src/plugin-sdk/${entry}.ts`]),
|
|
||||||
),
|
|
||||||
env: { NODE_ENV: "production" },
|
env: { NODE_ENV: "production" },
|
||||||
fixedExtension: false,
|
fixedExtension: false,
|
||||||
logLevel: "error",
|
logLevel: "error",
|
||||||
@ -237,4 +182,16 @@ describe("plugin-sdk exports", () => {
|
|||||||
await fs.rm(fixtureDir, { recursive: true, force: true });
|
await fs.rm(fixtureDir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps package.json plugin-sdk exports synced with the manifest", async () => {
|
||||||
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
||||||
|
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")) as {
|
||||||
|
exports?: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
const currentPluginSdkExports = Object.fromEntries(
|
||||||
|
Object.entries(packageJson.exports ?? {}).filter(([key]) => key.startsWith("./plugin-sdk")),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(currentPluginSdkExports).toEqual(buildPluginSdkPackageExports());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,42 +9,14 @@ import * as slackSdk from "openclaw/plugin-sdk/slack";
|
|||||||
import * as telegramSdk from "openclaw/plugin-sdk/telegram";
|
import * as telegramSdk from "openclaw/plugin-sdk/telegram";
|
||||||
import * as whatsappSdk from "openclaw/plugin-sdk/whatsapp";
|
import * as whatsappSdk from "openclaw/plugin-sdk/whatsapp";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { pluginSdkSubpaths } from "../../scripts/lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
const bundledExtensionSubpathLoaders = [
|
const importPluginSdkSubpath = (specifier: string) => import(/* @vite-ignore */ specifier);
|
||||||
{ id: "acpx", load: () => import("openclaw/plugin-sdk/acpx") },
|
|
||||||
{ id: "bluebubbles", load: () => import("openclaw/plugin-sdk/bluebubbles") },
|
const bundledExtensionSubpathLoaders = pluginSdkSubpaths.map((id) => ({
|
||||||
{ id: "copilot-proxy", load: () => import("openclaw/plugin-sdk/copilot-proxy") },
|
id,
|
||||||
{ id: "device-pair", load: () => import("openclaw/plugin-sdk/device-pair") },
|
load: () => importPluginSdkSubpath(`openclaw/plugin-sdk/${id}`),
|
||||||
{ id: "diagnostics-otel", load: () => import("openclaw/plugin-sdk/diagnostics-otel") },
|
}));
|
||||||
{ id: "diffs", load: () => import("openclaw/plugin-sdk/diffs") },
|
|
||||||
{ id: "feishu", load: () => import("openclaw/plugin-sdk/feishu") },
|
|
||||||
{ id: "googlechat", load: () => import("openclaw/plugin-sdk/googlechat") },
|
|
||||||
{ id: "irc", load: () => import("openclaw/plugin-sdk/irc") },
|
|
||||||
{ id: "llm-task", load: () => import("openclaw/plugin-sdk/llm-task") },
|
|
||||||
{ id: "lobster", load: () => import("openclaw/plugin-sdk/lobster") },
|
|
||||||
{ id: "matrix", load: () => import("openclaw/plugin-sdk/matrix") },
|
|
||||||
{ id: "mattermost", load: () => import("openclaw/plugin-sdk/mattermost") },
|
|
||||||
{ id: "memory-core", load: () => import("openclaw/plugin-sdk/memory-core") },
|
|
||||||
{ id: "memory-lancedb", load: () => import("openclaw/plugin-sdk/memory-lancedb") },
|
|
||||||
{
|
|
||||||
id: "minimax-portal-auth",
|
|
||||||
load: () => import("openclaw/plugin-sdk/minimax-portal-auth"),
|
|
||||||
},
|
|
||||||
{ id: "nextcloud-talk", load: () => import("openclaw/plugin-sdk/nextcloud-talk") },
|
|
||||||
{ id: "nostr", load: () => import("openclaw/plugin-sdk/nostr") },
|
|
||||||
{ id: "open-prose", load: () => import("openclaw/plugin-sdk/open-prose") },
|
|
||||||
{ id: "phone-control", load: () => import("openclaw/plugin-sdk/phone-control") },
|
|
||||||
{ id: "qwen-portal-auth", load: () => import("openclaw/plugin-sdk/qwen-portal-auth") },
|
|
||||||
{ id: "synology-chat", load: () => import("openclaw/plugin-sdk/synology-chat") },
|
|
||||||
{ id: "talk-voice", load: () => import("openclaw/plugin-sdk/talk-voice") },
|
|
||||||
{ id: "test-utils", load: () => import("openclaw/plugin-sdk/test-utils") },
|
|
||||||
{ id: "thread-ownership", load: () => import("openclaw/plugin-sdk/thread-ownership") },
|
|
||||||
{ id: "tlon", load: () => import("openclaw/plugin-sdk/tlon") },
|
|
||||||
{ id: "twitch", load: () => import("openclaw/plugin-sdk/twitch") },
|
|
||||||
{ id: "voice-call", load: () => import("openclaw/plugin-sdk/voice-call") },
|
|
||||||
{ id: "zalo", load: () => import("openclaw/plugin-sdk/zalo") },
|
|
||||||
{ id: "zalouser", load: () => import("openclaw/plugin-sdk/zalouser") },
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
describe("plugin-sdk subpath exports", () => {
|
describe("plugin-sdk subpath exports", () => {
|
||||||
it("exports compat helpers", () => {
|
it("exports compat helpers", () => {
|
||||||
|
|||||||
@ -10,51 +10,6 @@
|
|||||||
"rootDir": ".",
|
"rootDir": ".",
|
||||||
"tsBuildInfoFile": "dist/plugin-sdk/.tsbuildinfo"
|
"tsBuildInfoFile": "dist/plugin-sdk/.tsbuildinfo"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/plugin-sdk/**/*.ts", "src/types/**/*.d.ts"],
|
||||||
"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/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/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"]
|
"exclude": ["node_modules", "dist", "src/**/*.test.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { defineConfig } from "tsdown";
|
import { defineConfig } from "tsdown";
|
||||||
|
import { buildPluginSdkEntrySources } from "./scripts/lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
const env = {
|
const env = {
|
||||||
NODE_ENV: "production",
|
NODE_ENV: "production",
|
||||||
@ -58,52 +59,6 @@ function nodeBuildConfig(config: Record<string, unknown>) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const pluginSdkEntrypoints = [
|
|
||||||
"index",
|
|
||||||
"core",
|
|
||||||
"compat",
|
|
||||||
"telegram",
|
|
||||||
"discord",
|
|
||||||
"slack",
|
|
||||||
"signal",
|
|
||||||
"imessage",
|
|
||||||
"whatsapp",
|
|
||||||
"line",
|
|
||||||
"msteams",
|
|
||||||
"acpx",
|
|
||||||
"bluebubbles",
|
|
||||||
"copilot-proxy",
|
|
||||||
"device-pair",
|
|
||||||
"diagnostics-otel",
|
|
||||||
"diffs",
|
|
||||||
"feishu",
|
|
||||||
"googlechat",
|
|
||||||
"irc",
|
|
||||||
"llm-task",
|
|
||||||
"lobster",
|
|
||||||
"matrix",
|
|
||||||
"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;
|
|
||||||
|
|
||||||
function listBundledPluginBuildEntries(): Record<string, string> {
|
function listBundledPluginBuildEntries(): Record<string, string> {
|
||||||
const extensionsRoot = path.join(process.cwd(), "extensions");
|
const extensionsRoot = path.join(process.cwd(), "extensions");
|
||||||
const entries: Record<string, string> = {};
|
const entries: Record<string, string> = {};
|
||||||
@ -189,7 +144,7 @@ export default defineConfig([
|
|||||||
nodeBuildConfig({
|
nodeBuildConfig({
|
||||||
// Bundle all plugin-sdk entries in a single build so the bundler can share
|
// Bundle all plugin-sdk entries in a single build so the bundler can share
|
||||||
// common chunks instead of duplicating them per entry (~712MB heap saved).
|
// common chunks instead of duplicating them per entry (~712MB heap saved).
|
||||||
entry: Object.fromEntries(pluginSdkEntrypoints.map((e) => [e, `src/plugin-sdk/${e}.ts`])),
|
entry: buildPluginSdkEntrySources(),
|
||||||
outDir: "dist/plugin-sdk",
|
outDir: "dist/plugin-sdk",
|
||||||
}),
|
}),
|
||||||
nodeBuildConfig({
|
nodeBuildConfig({
|
||||||
|
|||||||
@ -2,57 +2,13 @@ import os from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
import { defineConfig } from "vitest/config";
|
import { defineConfig } from "vitest/config";
|
||||||
|
import { pluginSdkSubpaths } from "./scripts/lib/plugin-sdk-entries.mjs";
|
||||||
|
|
||||||
const repoRoot = path.dirname(fileURLToPath(import.meta.url));
|
const repoRoot = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
||||||
const isWindows = process.platform === "win32";
|
const isWindows = process.platform === "win32";
|
||||||
const localWorkers = Math.max(4, Math.min(16, os.cpus().length));
|
const localWorkers = Math.max(4, Math.min(16, os.cpus().length));
|
||||||
const ciWorkers = isWindows ? 2 : 3;
|
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",
|
|
||||||
"googlechat",
|
|
||||||
"irc",
|
|
||||||
"llm-task",
|
|
||||||
"lobster",
|
|
||||||
"matrix",
|
|
||||||
"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({
|
export default defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
// Keep this ordered: the base `openclaw/plugin-sdk` alias is a prefix match.
|
// Keep this ordered: the base `openclaw/plugin-sdk` alias is a prefix match.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user