mirror of https://github.com/openclaw/openclaw.git
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js";
|
|
import { resolveUserPath } from "../utils.js";
|
|
|
|
function isSourceCheckoutRoot(packageRoot: string): boolean {
|
|
return (
|
|
fs.existsSync(path.join(packageRoot, ".git")) &&
|
|
fs.existsSync(path.join(packageRoot, "src")) &&
|
|
fs.existsSync(path.join(packageRoot, "extensions"))
|
|
);
|
|
}
|
|
|
|
export function resolveBundledPluginsDir(env: NodeJS.ProcessEnv = process.env): string | undefined {
|
|
const override = env.OPENCLAW_BUNDLED_PLUGINS_DIR?.trim();
|
|
if (override) {
|
|
return resolveUserPath(override, env);
|
|
}
|
|
|
|
const preferSourceCheckout = Boolean(env.VITEST);
|
|
|
|
try {
|
|
const packageRoots = [
|
|
resolveOpenClawPackageRootSync({ cwd: process.cwd() }),
|
|
resolveOpenClawPackageRootSync({ moduleUrl: import.meta.url }),
|
|
].filter(
|
|
(entry, index, all): entry is string => Boolean(entry) && all.indexOf(entry) === index,
|
|
);
|
|
for (const packageRoot of packageRoots) {
|
|
const sourceExtensionsDir = path.join(packageRoot, "extensions");
|
|
if (
|
|
(preferSourceCheckout || isSourceCheckoutRoot(packageRoot)) &&
|
|
fs.existsSync(sourceExtensionsDir)
|
|
) {
|
|
return sourceExtensionsDir;
|
|
}
|
|
// Local source checkouts stage a runtime-complete bundled plugin tree under
|
|
// dist-runtime/. Prefer that over source extensions only when the paired
|
|
// dist/ tree exists; otherwise wrappers can drift ahead of the last build.
|
|
const runtimeExtensionsDir = path.join(packageRoot, "dist-runtime", "extensions");
|
|
const builtExtensionsDir = path.join(packageRoot, "dist", "extensions");
|
|
if (fs.existsSync(runtimeExtensionsDir) && fs.existsSync(builtExtensionsDir)) {
|
|
return runtimeExtensionsDir;
|
|
}
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
// bun --compile: ship a sibling `extensions/` next to the executable.
|
|
try {
|
|
const execDir = path.dirname(process.execPath);
|
|
const sibling = path.join(execDir, "extensions");
|
|
if (fs.existsSync(sibling)) {
|
|
return sibling;
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
// npm/dev: walk up from this module to find `extensions/` at the package root.
|
|
try {
|
|
let cursor = path.dirname(fileURLToPath(import.meta.url));
|
|
for (let i = 0; i < 6; i += 1) {
|
|
const candidate = path.join(cursor, "extensions");
|
|
if (fs.existsSync(candidate)) {
|
|
return candidate;
|
|
}
|
|
const parent = path.dirname(cursor);
|
|
if (parent === cursor) {
|
|
break;
|
|
}
|
|
cursor = parent;
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
return undefined;
|
|
}
|