























@@ -801,6 +801,26 @@ describe("uninstallPlugin", () => {
801801});
802802await expect(fs.access(managedDir)).rejects.toThrow();
803803});
804+805+it("deletes tracked installs from a recorded managed extensions root", async () => {
806+const currentExtensionsDir = path.join(tempDir, "current", "extensions");
807+const recordedExtensionsDir = path.join(tempDir, "recorded", "extensions");
808+const installPath = resolvePluginInstallDir("my-plugin", recordedExtensionsDir);
809+await fs.mkdir(installPath, { recursive: true });
810+await fs.writeFile(path.join(installPath, "index.js"), "// plugin");
811+812+const result = await uninstallPlugin({
813+config: createSingleNpmInstallConfig(installPath),
814+pluginId: "my-plugin",
815+deleteFiles: true,
816+extensionsDir: currentExtensionsDir,
817+});
818+819+expectSuccessfulUninstallActions(result, {
820+directory: true,
821+});
822+await expect(fs.access(installPath)).rejects.toThrow();
823+});
804824});
805825806826describe("resolveUninstallDirectoryTarget", () => {
@@ -851,4 +871,27 @@ describe("resolveUninstallDirectoryTarget", () => {
851871}),
852872).toBe(installPath);
853873});
874+875+it("uses configured installPath when it is under the recorded managed extensions root", () => {
876+const currentExtensionsDir = path.join(os.tmpdir(), "openclaw-uninstall-current", "extensions");
877+const recordedExtensionsDir = path.join(
878+os.tmpdir(),
879+"openclaw-uninstall-recorded",
880+"extensions",
881+);
882+const installPath = resolvePluginInstallDir("my-plugin", recordedExtensionsDir);
883+884+expect(
885+resolveUninstallDirectoryTarget({
886+pluginId: "my-plugin",
887+hasInstall: true,
888+installRecord: {
889+source: "npm",
890+spec: "my-plugin@1.0.0",
891+ installPath,
892+},
893+extensionsDir: currentExtensionsDir,
894+}),
895+).toBe(installPath);
896+});
854897});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。