mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
plugin-sdk: add channel subpaths and migrate bundled plugins
This commit is contained in:
50
scripts/check-no-monolithic-plugin-sdk-entry-imports.ts
Normal file
50
scripts/check-no-monolithic-plugin-sdk-entry-imports.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { discoverOpenClawPlugins } from "../src/plugins/discovery.js";
|
||||
|
||||
const ROOT_IMPORT_PATTERNS = [
|
||||
/\b(?:import|export)\b[\s\S]*?\bfrom\s+["']openclaw\/plugin-sdk["']/,
|
||||
/\bimport\s+["']openclaw\/plugin-sdk["']/,
|
||||
/\bimport\s*\(\s*["']openclaw\/plugin-sdk["']\s*\)/,
|
||||
/\brequire\s*\(\s*["']openclaw\/plugin-sdk["']\s*\)/,
|
||||
];
|
||||
|
||||
function hasMonolithicRootImport(content: string): boolean {
|
||||
return ROOT_IMPORT_PATTERNS.some((pattern) => pattern.test(content));
|
||||
}
|
||||
|
||||
function main() {
|
||||
const discovery = discoverOpenClawPlugins({});
|
||||
const bundledEntryFiles = [
|
||||
...new Set(discovery.candidates.filter((c) => c.origin === "bundled").map((c) => c.source)),
|
||||
];
|
||||
|
||||
const offenders: string[] = [];
|
||||
for (const entryFile of bundledEntryFiles) {
|
||||
let content = "";
|
||||
try {
|
||||
content = fs.readFileSync(entryFile, "utf8");
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
if (hasMonolithicRootImport(content)) {
|
||||
offenders.push(entryFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (offenders.length > 0) {
|
||||
console.error("Bundled plugin entrypoints must not import monolithic openclaw/plugin-sdk.");
|
||||
for (const file of offenders.toSorted()) {
|
||||
const relative = path.relative(process.cwd(), file) || file;
|
||||
console.error(`- ${relative}`);
|
||||
}
|
||||
console.error("Use openclaw/plugin-sdk/<channel> for channel plugins or /core for others.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`OK: bundled entrypoints use scoped plugin-sdk subpaths (${bundledEntryFiles.length} checked).`,
|
||||
);
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -41,6 +41,18 @@ const exportedNames = exportMatch[1]
|
||||
|
||||
const exportSet = new Set(exportedNames);
|
||||
|
||||
const requiredSubpathEntries = [
|
||||
"core",
|
||||
"telegram",
|
||||
"discord",
|
||||
"slack",
|
||||
"signal",
|
||||
"imessage",
|
||||
"whatsapp",
|
||||
"line",
|
||||
"account-id",
|
||||
];
|
||||
|
||||
// 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.<name>) is not a function
|
||||
@@ -76,10 +88,25 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,22 @@ 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/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/build-info.json",
|
||||
];
|
||||
const forbiddenPrefixes = ["dist/OpenClaw.app/"];
|
||||
|
||||
@@ -6,7 +6,18 @@ import path from "node:path";
|
||||
//
|
||||
// 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.
|
||||
const entrypoints = ["index", "core", "telegram", "account-id"] as const;
|
||||
const entrypoints = [
|
||||
"index",
|
||||
"core",
|
||||
"telegram",
|
||||
"discord",
|
||||
"slack",
|
||||
"signal",
|
||||
"imessage",
|
||||
"whatsapp",
|
||||
"line",
|
||||
"account-id",
|
||||
] 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 });
|
||||
|
||||
Reference in New Issue
Block a user