mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-18 09:11:39 +00:00
fix(cli): reduce plugin listing startup memory (#103132)
This commit is contained in:
committed by
GitHub
parent
ecad886cd1
commit
a1ce77d2a9
@@ -163,6 +163,11 @@ describe("ensureConfigReady", () => {
|
||||
commandPath: ["agent"],
|
||||
expectedDoctorCalls: 0,
|
||||
},
|
||||
{
|
||||
name: "skips doctor flow for plugin listing without legacy state",
|
||||
commandPath: ["plugins", "list"],
|
||||
expectedDoctorCalls: 0,
|
||||
},
|
||||
{
|
||||
name: "runs doctor flow for commands that may mutate state without legacy state",
|
||||
commandPath: ["message"],
|
||||
@@ -250,6 +255,43 @@ describe("ensureConfigReady", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves plugin listing migrations when the legacy plugin install index exists", async () => {
|
||||
const root = useTempOpenClawHome();
|
||||
writeStateMarker(root, "plugins/installs.json");
|
||||
const migratedSnapshot = {
|
||||
...makeSnapshot(),
|
||||
config: { plugins: { entries: { legacy: { enabled: true } } } },
|
||||
runtimeConfig: { plugins: { entries: { legacy: { enabled: true } } } },
|
||||
sourceConfig: { plugins: { entries: { legacy: { enabled: true } } } },
|
||||
};
|
||||
loadAndMaybeMigrateDoctorConfigMock.mockResolvedValue({
|
||||
snapshot: migratedSnapshot,
|
||||
baseConfig: {},
|
||||
});
|
||||
|
||||
await runEnsureConfigReady(["plugins", "list"]);
|
||||
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledOnce();
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledWith({
|
||||
migrateState: true,
|
||||
migrateLegacyConfig: false,
|
||||
invalidConfigNote: false,
|
||||
});
|
||||
expect(setRuntimeConfigSnapshotMock).toHaveBeenCalledWith(
|
||||
migratedSnapshot.runtimeConfig,
|
||||
migratedSnapshot.sourceConfig,
|
||||
);
|
||||
});
|
||||
|
||||
it("preserves plugin listing migrations when the shared state database exists", async () => {
|
||||
const root = useTempOpenClawHome();
|
||||
writeStateMarker(root, "state/openclaw.sqlite");
|
||||
|
||||
await runEnsureConfigReady(["plugins", "list"]);
|
||||
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("runs doctor flow before agent commands when default exec approvals must move to a custom state dir", async () => {
|
||||
const root = useTempOpenClawHome();
|
||||
const stateDir = path.join(root, "custom-state");
|
||||
@@ -301,7 +343,10 @@ describe("ensureConfigReady", () => {
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("runs doctor flow for read-only commands with configured custom session stores", async () => {
|
||||
it.each([
|
||||
{ name: "status", commandPath: ["status"] },
|
||||
{ name: "plugin listing", commandPath: ["plugins", "list"] },
|
||||
])("runs doctor flow for $name with configured custom session stores", async ({ commandPath }) => {
|
||||
const root = useTempOpenClawHome();
|
||||
const customStore = path.join(root, "sessions", "sessions.json");
|
||||
const snapshot = {
|
||||
@@ -315,7 +360,7 @@ describe("ensureConfigReady", () => {
|
||||
baseConfig: {},
|
||||
});
|
||||
|
||||
await runEnsureConfigReady(["status"]);
|
||||
await runEnsureConfigReady(commandPath);
|
||||
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).toHaveBeenCalledOnce();
|
||||
});
|
||||
@@ -337,6 +382,24 @@ describe("ensureConfigReady", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("pins plugin listing config without loading state migration runtime", async () => {
|
||||
const snapshot = {
|
||||
...makeSnapshot(),
|
||||
config: { plugins: { entries: { alpha: { enabled: true } } } },
|
||||
runtimeConfig: { plugins: { entries: { alpha: { enabled: true } } } },
|
||||
sourceConfig: { plugins: { entries: { alpha: { enabled: true } } } },
|
||||
};
|
||||
readConfigFileSnapshotMock.mockResolvedValue(snapshot);
|
||||
|
||||
await runEnsureConfigReady(["plugins", "list"]);
|
||||
|
||||
expect(loadAndMaybeMigrateDoctorConfigMock).not.toHaveBeenCalled();
|
||||
expect(setRuntimeConfigSnapshotMock).toHaveBeenCalledWith(
|
||||
snapshot.runtimeConfig,
|
||||
snapshot.sourceConfig,
|
||||
);
|
||||
});
|
||||
|
||||
it("retries the cached config snapshot after a read rejection", async () => {
|
||||
const originalVitest = process.env.VITEST;
|
||||
process.env.VITEST = "false";
|
||||
|
||||
@@ -142,6 +142,7 @@ function hasLegacyStateMigrationInputs(): boolean {
|
||||
path.join(stateDir, "agents"),
|
||||
path.join(stateDir, "plugins", "installs.json"),
|
||||
path.join(stateDir, "sessions"),
|
||||
path.join(stateDir, "state", "openclaw.sqlite"),
|
||||
].some(fileOrDirExists) ||
|
||||
sqliteSidecarPaths.some(
|
||||
(sourcePath) => fileOrDirExists(sourcePath) || hasPendingSqliteSidecarArchive(sourcePath),
|
||||
@@ -154,9 +155,12 @@ function hasLegacyStateMigrationInputs(): boolean {
|
||||
function shouldRunStateMigrationOnlyWithLegacyInputs(commandPath: string[]): boolean {
|
||||
const commandName = commandPath[0];
|
||||
const subcommandName = commandPath[1];
|
||||
// Metadata-only plugin listing still migrates known legacy inputs, but an empty
|
||||
// state must not cold-load doctor and bundled channel runtime graphs.
|
||||
return (
|
||||
commandName === "agent" ||
|
||||
commandName === "status" ||
|
||||
(commandName === "plugins" && subcommandName === "list") ||
|
||||
(commandName === "tasks" &&
|
||||
(subcommandName === undefined || ALLOWED_INVALID_TASK_SUBCOMMANDS.has(subcommandName)))
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user