fix: avoid CLI startup warmup leaks

This commit is contained in:
Peter Steinberger
2026-04-26 10:40:58 +01:00
parent 64af2feda0
commit 4bc5e183ef
6 changed files with 49 additions and 3 deletions

View File

@@ -1,6 +1,7 @@
{
"id": "browser",
"enabledByDefault": true,
"commandAliases": [{ "name": "browser" }],
"skills": ["./skills"],
"configSchema": {
"type": "object",

View File

@@ -201,6 +201,10 @@ describe("lookupContextTokens", () => {
const { shouldEagerWarmContextWindowCache } = await importContextModule();
expect(shouldEagerWarmContextWindowCache(["node", "openclaw", "chat"])).toBe(true);
expect(shouldEagerWarmContextWindowCache(["node", "openclaw", "chat", "--help"])).toBe(false);
expect(
shouldEagerWarmContextWindowCache(["node", "openclaw", "browser", "status", "--help"]),
).toBe(false);
expect(
shouldEagerWarmContextWindowCache([
"node",
@@ -215,6 +219,9 @@ describe("lookupContextTokens", () => {
false,
);
expect(shouldEagerWarmContextWindowCache(["node", "openclaw", "status", "--json"])).toBe(false);
expect(shouldEagerWarmContextWindowCache(["node", "openclaw", "sessions", "--json"])).toBe(
false,
);
expect(
shouldEagerWarmContextWindowCache(["node", "scripts/test-built-plugin-singleton.mjs"]),
).toBe(false);

View File

@@ -130,9 +130,22 @@ function getCommandPathFromArgv(argv: string[]): string[] {
return tokens;
}
function hasHelpOrVersionFlag(argv: string[]): boolean {
for (const arg of argv.slice(2)) {
if (arg === FLAG_TERMINATOR) {
return false;
}
if (arg === "-h" || arg === "--help" || arg === "-V" || arg === "--version") {
return true;
}
}
return false;
}
const SKIP_EAGER_WARMUP_PRIMARY_COMMANDS = new Set([
"agent",
"backup",
"browser",
"completion",
"config",
"directory",
@@ -142,8 +155,10 @@ const SKIP_EAGER_WARMUP_PRIMARY_COMMANDS = new Set([
"hooks",
"logs",
"models",
"pairing",
"plugins",
"secrets",
"sessions",
"status",
"update",
"webhooks",
@@ -160,6 +175,9 @@ export function shouldEagerWarmContextWindowCache(argv: string[] = process.argv)
if (!isLikelyOpenClawCliProcess(argv)) {
return false;
}
if (hasHelpOrVersionFlag(argv)) {
return false;
}
const [primary] = getCommandPathFromArgv(argv);
return Boolean(primary) && !SKIP_EAGER_WARMUP_PRIMARY_COMMANDS.has(primary);
}

View File

@@ -30,12 +30,13 @@ async function registerSubCliWithPluginCommands(
registerSubCli: () => Promise<void>,
pluginCliPosition: "before" | "after",
) {
const isHelpOrVersion = resolveCliArgvInvocation(process.argv).hasHelpOrVersion;
const { registerPluginCliCommandsFromValidatedConfig } = await import("../../plugins/cli.js");
if (pluginCliPosition === "before") {
if (pluginCliPosition === "before" && !isHelpOrVersion) {
await registerPluginCliCommandsFromValidatedConfig(program);
}
await registerSubCli();
if (pluginCliPosition === "after") {
if (pluginCliPosition === "after" && !isHelpOrVersion) {
await registerPluginCliCommandsFromValidatedConfig(program);
}
}

View File

@@ -2,7 +2,6 @@ import type { Command } from "commander";
import { defaultRuntime } from "../runtime.js";
import { formatDocsLink } from "../terminal/links.js";
import { theme } from "../terminal/theme.js";
import { runTui } from "../tui/tui.js";
import { parseTimeoutMs } from "./parse-timeout.js";
export function registerTuiCli(program: Command) {
@@ -43,6 +42,7 @@ export function registerTuiCli(program: Command) {
);
}
const historyLimit = Number.parseInt(String(opts.historyLimit ?? "200"), 10);
const { runTui } = await import("../tui/tui.js");
await runTui({
local: isLocal,
url: opts.url as string | undefined,

View File

@@ -42,6 +42,16 @@ describe("activation planner", () => {
hooks: [],
origin: "bundled",
},
{
id: "browser",
commandAliases: [{ name: "browser" }],
providers: [],
channels: [],
cliBackends: [],
skills: [],
hooks: [],
origin: "bundled",
},
{
id: "openai",
providers: ["openai"],
@@ -88,6 +98,15 @@ describe("activation planner", () => {
}),
).toEqual(["memory-core"]);
expect(
resolveManifestActivationPluginIds({
trigger: {
kind: "command",
command: "browser",
},
}),
).toEqual(["browser"]);
expect(
resolveManifestActivationPluginIds({
trigger: {