



















@@ -0,0 +1,85 @@
1+#!/usr/bin/env node
2+3+import fs from "node:fs/promises";
4+import path from "node:path";
5+import { fileURLToPath } from "node:url";
6+7+const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
8+const extensionsRoot = path.join(repoRoot, "extensions");
9+10+const WILDCARD_PLUGIN_SDK_REEXPORT_PATTERN =
11+/^\s*export\s+(?:type\s+)?\*\s+from\s+["']openclaw\/plugin-sdk\//u;
12+13+async function listExtensionApiFiles(rootDir = extensionsRoot) {
14+const entries = await fs.readdir(rootDir, { withFileTypes: true });
15+const files = [];
16+for (const entry of entries) {
17+if (!entry.isDirectory()) {
18+continue;
19+}
20+for (const fileName of ["api.ts", "runtime-api.ts"]) {
21+const filePath = path.join(rootDir, entry.name, fileName);
22+try {
23+const stat = await fs.stat(filePath);
24+if (stat.isFile()) {
25+files.push(filePath);
26+}
27+} catch (error) {
28+if (!error || typeof error !== "object" || !("code" in error) || error.code !== "ENOENT") {
29+throw error;
30+}
31+}
32+}
33+}
34+return files.toSorted((left, right) => left.localeCompare(right));
35+}
36+37+export function findPluginSdkWildcardReexports(source) {
38+return source
39+.split(/\r?\n/u)
40+.map((text, index) => ({ line: index + 1, text }))
41+.filter(({ text }) => WILDCARD_PLUGIN_SDK_REEXPORT_PATTERN.test(text));
42+}
43+44+export async function collectPluginSdkWildcardReexports(rootDir = repoRoot) {
45+const files = await listExtensionApiFiles(path.join(rootDir, "extensions"));
46+const violations = [];
47+for (const filePath of files) {
48+const source = await fs.readFile(filePath, "utf8");
49+for (const match of findPluginSdkWildcardReexports(source)) {
50+violations.push({
51+file: path.relative(rootDir, filePath).split(path.sep).join("/"),
52+line: match.line,
53+text: match.text.trim(),
54+});
55+}
56+}
57+return violations;
58+}
59+60+export async function main(argv = process.argv.slice(2), io = process) {
61+const json = argv.includes("--json");
62+const violations = await collectPluginSdkWildcardReexports();
63+64+if (json) {
65+io.stdout.write(`${JSON.stringify(violations, null, 2)}\n`);
66+return violations.length === 0 ? 0 : 1;
67+}
68+69+if (violations.length === 0) {
70+io.stdout.write("No plugin-sdk wildcard re-exports found in extension API barrels.\n");
71+return 0;
72+}
73+74+io.stderr.write("Found plugin-sdk wildcard re-exports in extension API barrels:\n");
75+for (const violation of violations) {
76+io.stderr.write(`- ${violation.file}:${violation.line} ${violation.text}\n`);
77+}
78+io.stderr.write("Use explicit named exports from the narrow SDK subpath instead.\n");
79+return 1;
80+}
81+82+if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
83+const exitCode = await main();
84+process.exit(exitCode);
85+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。