refactor(plugins): decouple bundled plugin runtime loading

This commit is contained in:
Peter Steinberger
2026-03-29 09:08:06 +01:00
parent 1738d540f4
commit 8e0ab35b0e
582 changed files with 8057 additions and 22869 deletions

View File

@@ -1,5 +1,10 @@
import fs from "node:fs";
import path from "node:path";
import {
BUNDLED_PLUGIN_ROOT_DIR,
bundledDistPluginFile,
bundledPluginFile,
} from "./bundled-plugin-paths.mjs";
import { shouldBuildBundledCluster } from "./optional-bundled-clusters.mjs";
const TOP_LEVEL_PUBLIC_SURFACE_EXTENSIONS = new Set([".ts", ".js", ".mts", ".cts", ".mjs", ".cjs"]);
@@ -68,7 +73,7 @@ function collectTopLevelPublicSurfaceEntries(pluginDir) {
export function collectBundledPluginBuildEntries(params = {}) {
const cwd = params.cwd ?? process.cwd();
const env = params.env ?? process.env;
const extensionsRoot = path.join(cwd, "extensions");
const extensionsRoot = path.join(cwd, BUNDLED_PLUGIN_ROOT_DIR);
const entries = [];
for (const dirent of fs.readdirSync(extensionsRoot, { withFileTypes: true })) {
@@ -109,8 +114,8 @@ export function listBundledPluginBuildEntries(params = {}) {
collectBundledPluginBuildEntries(params).flatMap(({ id, sourceEntries }) =>
sourceEntries.map((entry) => {
const normalizedEntry = entry.replace(/^\.\//, "");
const entryKey = `extensions/${id}/${normalizedEntry.replace(/\.[^.]+$/u, "")}`;
return [entryKey, path.join("extensions", id, normalizedEntry)];
const entryKey = bundledPluginFile(id, normalizedEntry.replace(/\.[^.]+$/u, ""));
return [entryKey, path.join(BUNDLED_PLUGIN_ROOT_DIR, id, normalizedEntry)];
}),
),
);
@@ -121,13 +126,13 @@ export function listBundledPluginPackArtifacts(params = {}) {
const artifacts = new Set();
for (const { id, hasPackageJson, sourceEntries } of entries) {
artifacts.add(`dist/extensions/${id}/openclaw.plugin.json`);
artifacts.add(bundledDistPluginFile(id, "openclaw.plugin.json"));
if (hasPackageJson) {
artifacts.add(`dist/extensions/${id}/package.json`);
artifacts.add(bundledDistPluginFile(id, "package.json"));
}
for (const entry of sourceEntries) {
const normalizedEntry = entry.replace(/^\.\//, "").replace(/\.[^.]+$/u, "");
artifacts.add(`dist/extensions/${id}/${normalizedEntry}.js`);
artifacts.add(bundledDistPluginFile(id, `${normalizedEntry}.js`));
}
}

View File

@@ -0,0 +1,25 @@
export const BUNDLED_PLUGIN_ROOT_DIR = "extensions";
export const BUNDLED_PLUGIN_PATH_PREFIX = `${BUNDLED_PLUGIN_ROOT_DIR}/`;
export const BUNDLED_PLUGIN_TEST_GLOB = `${BUNDLED_PLUGIN_ROOT_DIR}/**/*.test.ts`;
export const BUNDLED_PLUGIN_E2E_TEST_GLOB = `${BUNDLED_PLUGIN_ROOT_DIR}/**/*.e2e.test.ts`;
export const BUNDLED_PLUGIN_LIVE_TEST_GLOB = `${BUNDLED_PLUGIN_ROOT_DIR}/**/*.live.test.ts`;
export function bundledPluginRoot(pluginId) {
return `${BUNDLED_PLUGIN_PATH_PREFIX}${pluginId}`;
}
export function bundledPluginFile(pluginId, relativePath) {
return `${bundledPluginRoot(pluginId)}/${relativePath}`;
}
export function bundledDistPluginRoot(pluginId) {
return `dist/${bundledPluginRoot(pluginId)}`;
}
export function bundledDistPluginFile(pluginId, relativePath) {
return `${bundledDistPluginRoot(pluginId)}/${relativePath}`;
}
export function bundledPluginCallsite(pluginId, relativePath, line) {
return `${bundledPluginFile(pluginId, relativePath)}:${line}`;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
import fs from "node:fs";
import path from "node:path";
import { BUNDLED_PLUGIN_PATH_PREFIX } from "../bundled-plugin-paths.mjs";
import { pluginSdkEntrypoints } from "../plugin-sdk-entries.mjs";
import type { ConsumerScope, PublicEntrypoint, TopologyScope, UsageBucket } from "./types.js";
@@ -19,7 +20,7 @@ function isTestFile(relPath: string): boolean {
}
function classifyScope(relPath: string): ConsumerScope {
if (relPath.startsWith("extensions/")) {
if (relPath.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
return "extension";
}
if (relPath.startsWith("packages/")) {
@@ -74,7 +75,7 @@ function extractOwner(relPath: string): string | null {
}
function extractExtensionId(relPath: string): string | null {
if (!relPath.startsWith("extensions/")) {
if (!relPath.startsWith(BUNDLED_PLUGIN_PATH_PREFIX)) {
return null;
}
const parts = relPath.split("/");