import fs from "node:fs"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { writePersistedInstalledPluginIndexSync } from "./installed-plugin-index-store.js"; import { loadInstalledPluginIndex, type InstalledPluginIndex } from "./installed-plugin-index.js"; import { loadPluginRegistrySnapshotWithMetadata } from "./plugin-registry-snapshot.js"; import { cleanupTrackedTempDirs, makeTrackedTempDir } from "./test-helpers/fs-fixtures.js"; const tempDirs: string[] = []; afterEach(() => { cleanupTrackedTempDirs(tempDirs); }); function makeTempDir() { return makeTrackedTempDir("openclaw-plugin-registry-snapshot", tempDirs); } function createHermeticEnv(rootDir: string): NodeJS.ProcessEnv { return { OPENCLAW_BUNDLED_PLUGINS_DIR: path.join(rootDir, "bundled"), OPENCLAW_VERSION: "2026.4.26", VITEST: "true", }; } function writeManifestlessClaudeBundle(rootDir: string) { fs.mkdirSync(path.join(rootDir, "skills"), { recursive: true }); fs.writeFileSync(path.join(rootDir, "skills", "SKILL.md"), "# Workspace skill\n", "utf8"); } function createManifestlessClaudeBundleIndex(params: { rootDir: string; env: NodeJS.ProcessEnv; }): InstalledPluginIndex { return loadInstalledPluginIndex({ config: { plugins: { load: { paths: [params.rootDir] }, }, }, env: params.env, }); } describe("loadPluginRegistrySnapshotWithMetadata", () => { it("keeps persisted manifestless Claude bundles on the fast path", () => { const tempRoot = makeTempDir(); const rootDir = path.join(tempRoot, "workspace"); const stateDir = path.join(tempRoot, "state"); const env = createHermeticEnv(tempRoot); const config = { plugins: { load: { paths: [rootDir] }, }, }; writeManifestlessClaudeBundle(rootDir); const index = createManifestlessClaudeBundleIndex({ rootDir, env }); writePersistedInstalledPluginIndexSync(index, { stateDir }); const result = loadPluginRegistrySnapshotWithMetadata({ config, env, stateDir, }); expect(result.source).toBe("persisted"); expect(result.diagnostics).toEqual([]); }); });