mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
fix(plugins): serialize lifecycle mutations and preserve setup-required installs (#112763)
* fix(plugins): harden concurrent lifecycle mutations * fix(update): preserve post-core restart snapshot * fix(update): retain authoritative plugin records on resume * fix(update): reconcile plugin records after handoff
This commit is contained in:
committed by
GitHub
parent
67ef07863f
commit
a12e0f26ee
@@ -1766,13 +1766,13 @@ describe("plugins cli install", () => {
|
||||
expect(clawHubInstallCall().spec).toBe("clawhub:demo");
|
||||
});
|
||||
|
||||
it("does not persist incomplete config entries for config-gated bundled installs", async () => {
|
||||
it("preserves non-config policy for unconfigured bundled installs", async () => {
|
||||
const pluginId = "config-required-plugin";
|
||||
const cfg = {
|
||||
plugins: {
|
||||
entries: {
|
||||
[pluginId]: {
|
||||
config: {},
|
||||
hooks: { timeoutMs: 5_000 },
|
||||
},
|
||||
},
|
||||
load: {
|
||||
@@ -1801,7 +1801,10 @@ describe("plugins cli install", () => {
|
||||
const writtenConfig = writeConfigFile.mock.calls[
|
||||
writeConfigFile.mock.calls.length - 1
|
||||
]?.[0] as OpenClawConfig;
|
||||
expect(writtenConfig.plugins?.entries?.[pluginId]).toBeUndefined();
|
||||
expect(writtenConfig.plugins?.entries?.[pluginId]).toEqual({
|
||||
enabled: false,
|
||||
hooks: { timeoutMs: 5_000 },
|
||||
});
|
||||
expect(writtenConfig.plugins?.load?.paths).toEqual(["/existing/plugin"]);
|
||||
const record = persistedInstallRecord(pluginId);
|
||||
expect(record.source).toBe("path");
|
||||
@@ -1812,6 +1815,38 @@ describe("plugins cli install", () => {
|
||||
expect(runtimeLogsContain("requires configuration first")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects invalid authored config for config-gated bundled installs", async () => {
|
||||
const pluginId = "config-required-plugin";
|
||||
const cfg = {
|
||||
plugins: {
|
||||
entries: {
|
||||
[pluginId]: {
|
||||
config: {},
|
||||
hooks: { timeoutMs: 5_000 },
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
loadConfig.mockReturnValue(cfg);
|
||||
findBundledPluginSourceMock.mockReturnValue({
|
||||
pluginId,
|
||||
localPath: `/app/dist/extensions/${pluginId}`,
|
||||
configSchema: {
|
||||
type: "object",
|
||||
required: ["token"],
|
||||
properties: { token: { type: "string" } },
|
||||
},
|
||||
requiresConfig: true,
|
||||
});
|
||||
|
||||
await expect(runPluginsCommand(["plugins", "install", pluginId])).rejects.toThrow(
|
||||
"has invalid configured settings",
|
||||
);
|
||||
|
||||
expect(writeConfigFile).not.toHaveBeenCalled();
|
||||
expect(enablePluginInConfig).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("enables config-gated bundled installs when provider-backed config is explicit", async () => {
|
||||
const pluginId = "config-required-plugin";
|
||||
const cfg = {
|
||||
|
||||
Reference in New Issue
Block a user