fix plugins not loading

This commit is contained in:
KingKDot
2026-05-31 13:06:00 -05:00
parent 732ad67898
commit db188c544d
2 changed files with 81 additions and 5 deletions
@@ -0,0 +1,40 @@
import { afterEach, describe, expect, test } from "bun:test";
import { mkdtemp, mkdir, rm, writeFile } from "fs/promises";
import { tmpdir } from "os";
import { join } from "path";
import { loadPluginBundle } from "./plugin-state-bundle";
let tempRoots: string[] = [];
async function createTempRoot(): Promise<string> {
const root = await mkdtemp(join(tmpdir(), "overlord-plugin-bundle-test-"));
tempRoots.push(root);
return root;
}
afterEach(async () => {
await Promise.all(tempRoots.map((root) => rm(root, { recursive: true, force: true })));
tempRoots = [];
});
describe("loadPluginBundle", () => {
test("matches plugin binaries when clients report a pretty Windows OS name", async () => {
const root = await createTempRoot();
const pluginDir = join(root, "sample-c");
await mkdir(pluginDir, { recursive: true });
await writeFile(
join(pluginDir, "manifest.json"),
JSON.stringify({
id: "sample-c",
name: "sample-c",
binaries: { "windows-amd64": "sample-c-windows-amd64.dll" },
}),
);
await writeFile(join(pluginDir, "sample-c-windows-amd64.dll"), "test-binary");
const bundle = await loadPluginBundle(root, "sample-c", async () => {}, "Windows 11 Pro 24H2", "amd64");
expect(bundle.binaryPath).toBe(join(pluginDir, "sample-c-windows-amd64.dll"));
expect(bundle.size).toBe("test-binary".length);
});
});
@@ -262,8 +262,9 @@ export async function loadPluginBundle(
let binaryPath: string | null = null;
if (manifest.binaries && clientOS && clientArch) {
const key = `${clientOS}-${clientArch}`;
const filename = manifest.binaries[key];
const filename = getPluginBinaryCandidateKeys(clientOS, clientArch)
.map((key) => manifest.binaries?.[key])
.find((name): name is string => typeof name === "string" && name.length > 0);
if (filename) {
const candidate = path.join(dir, filename);
try {
@@ -274,7 +275,9 @@ export async function loadPluginBundle(
}
if (!binaryPath) {
const platformKey = clientOS && clientArch ? `${clientOS}-${clientArch}` : "unknown";
const platformKey = clientOS && clientArch ? formatPluginPlatformKey(clientOS, clientArch) : "unknown";
const normalizedOS = normalizePluginOS(clientOS);
const normalizedArch = normalizePluginArch(clientArch);
const files = await fs.readdir(dir);
const archRegex = /-(linux|darwin|windows|freebsd)-(amd64|arm64|arm|386)\.(so|dll|dylib)$/i;
@@ -282,8 +285,8 @@ export async function loadPluginBundle(
const m = f.match(archRegex);
if (m) {
return (
m[1].toLowerCase() === (clientOS || "").toLowerCase() &&
m[2].toLowerCase() === (clientArch || "").toLowerCase()
m[1].toLowerCase() === normalizedOS &&
m[2].toLowerCase() === normalizedArch
);
}
const fl = f.toLowerCase();
@@ -301,6 +304,39 @@ export async function loadPluginBundle(
return { manifest, binaryPath, size: stat.size };
}
function getPluginBinaryCandidateKeys(clientOS?: string, clientArch?: string): string[] {
if (!clientOS || !clientArch) return [];
const rawKey = `${clientOS}-${clientArch}`.toLowerCase();
const normalizedKey = formatPluginPlatformKey(clientOS, clientArch);
return Array.from(
new Set([normalizedKey, rawKey].filter((key) => !key.startsWith("unknown-") && !key.endsWith("-unknown"))),
);
}
function formatPluginPlatformKey(clientOS?: string, clientArch?: string): string {
return `${normalizePluginOS(clientOS)}-${normalizePluginArch(clientArch)}`;
}
function normalizePluginOS(value?: string): string {
const os = (value || "").trim().toLowerCase();
if (!os) return "unknown";
if (os.includes("windows") || os === "win32") return "windows";
if (os.includes("mac os") || os.includes("macos") || os.includes("os x") || os === "darwin") return "darwin";
if (os.includes("linux")) return "linux";
if (os.includes("freebsd")) return "freebsd";
return os;
}
function normalizePluginArch(value?: string): string {
const arch = (value || "").trim().toLowerCase();
if (!arch) return "unknown";
if (arch === "x64" || arch === "x86_64") return "amd64";
if (arch === "ia32" || arch === "i386" || arch === "x86") return "386";
if (arch === "aarch64") return "arm64";
if (arch === "armv7" || arch === "armv6") return "arm";
return arch;
}
export type PluginPull = {
id: string;
clientId: string;