


























@@ -309,12 +309,22 @@ describe("loadPluginRegistrySnapshotWithMetadata", () => {
309309);
310310});
311311312-it("treats persisted registry as stale when a diagnostic source path no longer exists", () => {
312+it("treats persisted registry as stale when a plugin diagnostic source path no longer exists", () => {
313313const tempRoot = makeTempDir();
314314const stateDir = path.join(tempRoot, "state");
315-const env = { ...createHermeticEnv(tempRoot), OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1" };
315+const env = {
316+ ...createHermeticEnv(tempRoot),
317+OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1",
318+OPENCLAW_STATE_DIR: stateDir,
319+};
316320const config = {};
317321const ghostDir = path.join(tempRoot, "extensions", "lossless-claw");
322+const npmPluginDir = writeManagedNpmPlugin({
323+ stateDir,
324+packageName: "@martian-engineering/lossless-claw",
325+pluginId: "lossless-claw",
326+version: "0.9.4",
327+});
318328const staleIndex: InstalledPluginIndex = {
319329 ...loadInstalledPluginIndex({ config, env, stateDir, installRecords: {} }),
320330diagnostics: [
@@ -335,8 +345,42 @@ describe("loadPluginRegistrySnapshotWithMetadata", () => {
335345expect(result.snapshot.diagnostics).not.toContainEqual(
336346expect.objectContaining({ source: ghostDir }),
337347);
348+expect(result.snapshot.plugins).toContainEqual(
349+expect.objectContaining({
350+pluginId: "lossless-claw",
351+origin: "global",
352+source: fs.realpathSync(path.join(npmPluginDir, "dist", "index.js")),
353+}),
354+);
338355expect(result.diagnostics).toContainEqual(
339356expect.objectContaining({ code: "persisted-registry-stale-source" }),
340357);
341358});
359+360+it("keeps persisted registry when a non-plugin diagnostic source path still does not exist", () => {
361+const tempRoot = makeTempDir();
362+const stateDir = path.join(tempRoot, "state");
363+const env = { ...createHermeticEnv(tempRoot), OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1" };
364+const config = {};
365+const missingConfiguredPath = path.join(tempRoot, "missing-configured-plugin");
366+const index: InstalledPluginIndex = {
367+ ...loadInstalledPluginIndex({ config, env, stateDir, installRecords: {} }),
368+diagnostics: [
369+{
370+level: "error",
371+message: `plugin path not found: ${missingConfiguredPath}`,
372+source: missingConfiguredPath,
373+},
374+],
375+};
376+writePersistedInstalledPluginIndexSync(index, { stateDir });
377+378+const result = loadPluginRegistrySnapshotWithMetadata({ config, env, stateDir });
379+380+expect(result.source).toBe("persisted");
381+expect(result.snapshot.diagnostics).toContainEqual(
382+expect.objectContaining({ source: missingConfiguredPath }),
383+);
384+expect(result.diagnostics).toStrictEqual([]);
385+});
342386});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。