mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
refactor: keep plugin sdk owner seams explicit
This commit is contained in:
@@ -47,6 +47,8 @@ export const reservedBundledPluginSdkEntrypoints = [
|
||||
"msteams",
|
||||
"nextcloud-talk",
|
||||
"nostr",
|
||||
"opencode",
|
||||
"telegram-command-ui",
|
||||
"thread-ownership",
|
||||
"tlon",
|
||||
"twitch",
|
||||
@@ -64,6 +66,32 @@ export const supportedBundledFacadeSdkEntrypoints = [
|
||||
"tts-runtime",
|
||||
] as const;
|
||||
|
||||
export const publicPluginOwnedSdkEntrypoints = [
|
||||
"browser-config",
|
||||
"image-generation-core",
|
||||
"memory-core-host-engine-embeddings",
|
||||
"memory-core-host-engine-foundation",
|
||||
"memory-core-host-engine-qmd",
|
||||
"memory-core-host-engine-storage",
|
||||
"memory-core-host-events",
|
||||
"memory-core-host-multimodal",
|
||||
"memory-core-host-query",
|
||||
"memory-core-host-runtime-cli",
|
||||
"memory-core-host-runtime-core",
|
||||
"memory-core-host-runtime-files",
|
||||
"memory-core-host-secret",
|
||||
"memory-core-host-status",
|
||||
"memory-host-core",
|
||||
"memory-host-events",
|
||||
"memory-host-files",
|
||||
"memory-host-markdown",
|
||||
"memory-host-search",
|
||||
"memory-host-status",
|
||||
"speech-core",
|
||||
"telegram-command-config",
|
||||
"video-generation-core",
|
||||
] as const;
|
||||
|
||||
/** Map every SDK entrypoint name to its source file path inside the repo. */
|
||||
export function buildPluginSdkEntrySources(entries: readonly string[] = pluginSdkEntrypoints) {
|
||||
return Object.fromEntries(entries.map((entry) => [entry, `src/plugin-sdk/${entry}.ts`]));
|
||||
|
||||
@@ -4,12 +4,14 @@ import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
pluginSdkEntrypoints,
|
||||
publicPluginOwnedSdkEntrypoints,
|
||||
reservedBundledPluginSdkEntrypoints,
|
||||
supportedBundledFacadeSdkEntrypoints,
|
||||
} from "../../plugin-sdk/entrypoints.js";
|
||||
|
||||
const ROOT_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
||||
const REPO_ROOT = resolve(ROOT_DIR, "..");
|
||||
const SDK_SUBPATH_DOC_FILE = "docs/plugins/sdk-subpaths.md";
|
||||
const PUBLIC_CONTRACT_REFERENCE_FILES = [
|
||||
"docs/plugins/architecture.md",
|
||||
"src/plugins/contracts/plugin-sdk-subpaths.test.ts",
|
||||
@@ -57,6 +59,48 @@ function collectPluginSdkSubpathReferences() {
|
||||
return references;
|
||||
}
|
||||
|
||||
function collectDocumentedSdkSubpaths(): Set<string> {
|
||||
const source = readFileSync(resolve(REPO_ROOT, SDK_SUBPATH_DOC_FILE), "utf8");
|
||||
return new Set(
|
||||
[...source.matchAll(/`plugin-sdk\/([a-z0-9][a-z0-9-]*)`/g)]
|
||||
.map((match) => match[1])
|
||||
.filter((subpath): subpath is string => Boolean(subpath)),
|
||||
);
|
||||
}
|
||||
|
||||
function collectBundledPluginIds(): string[] {
|
||||
return readdirSync(resolve(REPO_ROOT, "extensions"), { withFileTypes: true })
|
||||
.filter((entry) => entry.isDirectory())
|
||||
.map((entry) => entry.name)
|
||||
.toSorted((a, b) => b.length - a.length || a.localeCompare(b));
|
||||
}
|
||||
|
||||
function collectPluginOwnedSdkEntrypoints(): string[] {
|
||||
const pluginIds = collectBundledPluginIds();
|
||||
return pluginSdkEntrypoints
|
||||
.filter((entrypoint) =>
|
||||
pluginIds.some(
|
||||
(pluginId) => entrypoint === pluginId || entrypoint.startsWith(`${pluginId}-`),
|
||||
),
|
||||
)
|
||||
.toSorted();
|
||||
}
|
||||
|
||||
function collectClassificationOverlaps(classifications: Record<string, readonly string[]>) {
|
||||
const seen = new Map<string, string[]>();
|
||||
for (const [classification, entrypoints] of Object.entries(classifications)) {
|
||||
for (const entrypoint of entrypoints) {
|
||||
const current = seen.get(entrypoint) ?? [];
|
||||
current.push(classification);
|
||||
seen.set(entrypoint, current);
|
||||
}
|
||||
}
|
||||
return [...seen.entries()]
|
||||
.filter(([, matches]) => matches.length > 1)
|
||||
.map(([entrypoint, matches]) => `${entrypoint}: ${matches.toSorted().join(", ")}`)
|
||||
.toSorted();
|
||||
}
|
||||
|
||||
function collectBundledFacadeSdkEntrypoints(): string[] {
|
||||
const entrypoints: string[] = [];
|
||||
for (const entrypoint of pluginSdkEntrypoints) {
|
||||
@@ -224,6 +268,43 @@ describe("plugin-sdk package contract guardrails", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps plugin-owned SDK subpaths explicitly classified and documented", () => {
|
||||
const entrypoints = new Set(pluginSdkEntrypoints);
|
||||
const reserved = new Set<string>(reservedBundledPluginSdkEntrypoints);
|
||||
const supported = new Set<string>(supportedBundledFacadeSdkEntrypoints);
|
||||
const publicOwned = new Set<string>(publicPluginOwnedSdkEntrypoints);
|
||||
const documented = collectDocumentedSdkSubpaths();
|
||||
const pluginOwnedEntrypoints = collectPluginOwnedSdkEntrypoints();
|
||||
const classified = new Set([...reserved, ...supported, ...publicOwned]);
|
||||
|
||||
const unknownPublicOwned = [...publicOwned].filter(
|
||||
(entrypoint) => !entrypoints.has(entrypoint),
|
||||
);
|
||||
const classificationOverlaps = collectClassificationOverlaps({
|
||||
reserved: reservedBundledPluginSdkEntrypoints,
|
||||
supported: supportedBundledFacadeSdkEntrypoints,
|
||||
publicOwned: publicPluginOwnedSdkEntrypoints,
|
||||
});
|
||||
const unclassifiedPluginOwned = pluginOwnedEntrypoints.filter(
|
||||
(entrypoint) => !classified.has(entrypoint),
|
||||
);
|
||||
const undocumentedPluginOwned = pluginOwnedEntrypoints.filter(
|
||||
(entrypoint) => !documented.has(entrypoint),
|
||||
);
|
||||
|
||||
expect({
|
||||
unknownPublicOwned,
|
||||
classificationOverlaps,
|
||||
unclassifiedPluginOwned,
|
||||
undocumentedPluginOwned,
|
||||
}).toEqual({
|
||||
unknownPublicOwned: [],
|
||||
classificationOverlaps: [],
|
||||
unclassifiedPluginOwned: [],
|
||||
undocumentedPluginOwned: [],
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps curated public plugin-sdk references on exported built subpaths", () => {
|
||||
const entrypoints = new Set(pluginSdkEntrypoints);
|
||||
const exports = new Set(collectPluginSdkPackageExports());
|
||||
|
||||
Reference in New Issue
Block a user