refactor(cli): remove stale path policy helpers

This commit is contained in:
Vincent Koc
2026-06-19 04:37:25 +08:00
parent d2e36a176d
commit 76bdb025d6
6 changed files with 74 additions and 150 deletions
+1 -2
View File
@@ -3,7 +3,6 @@ import { describe, expect, it } from "vitest";
import {
buildParseArgv,
getFlagValue,
getCommandPath,
getCommandPositionalsWithRootOptions,
getCommandPathWithRootOptions,
getPrimaryCommand,
@@ -442,7 +441,7 @@ describe("argv helpers", () => {
expected: ["status"],
},
])("extracts command path: $name", ({ argv, expected }) => {
expect(getCommandPath(argv, 2)).toEqual(expected);
expect(getCommandPathWithRootOptions(argv, 2)).toEqual(expected);
});
it("extracts command path while skipping known root option values", () => {
-4
View File
@@ -438,10 +438,6 @@ export function getPositiveIntFlagValue(argv: string[], name: string): number |
return parsePositiveInt(raw);
}
export function getCommandPath(argv: string[], depth = 2): string[] {
return getCommandPathInternal(argv, depth, { skipRootOptions: false });
}
export function getCommandPathWithRootOptions(argv: string[], depth = 2): string[] {
return getCommandPathInternal(argv, depth, { skipRootOptions: true });
}
-15
View File
@@ -1,7 +1,6 @@
// Command path match tests cover CLI command path matching and normalization.
import { describe, expect, it } from "vitest";
import {
matchesAnyCommandPath,
matchesCommandPath,
matchesCommandPathRule,
} from "./command-path-matches.js";
@@ -38,18 +37,4 @@ describe("command-path-matches", () => {
).toBe(true);
});
it("matches any command path from a rule set", () => {
expect(
matchesAnyCommandPath(
["config", "schema"],
[["backup"], { pattern: ["config", "schema"], exact: true }],
),
).toBe(true);
expect(
matchesAnyCommandPath(
["message", "send"],
[["status"], { pattern: ["config", "schema"], exact: true }],
),
).toBe(false);
});
});
-8
View File
@@ -43,11 +43,3 @@ export function matchesCommandPathRule(commandPath: string[], rule: CommandPathM
exact: normalizedRule.exact,
});
}
/** Returns whether any configured command-path rule matches the parsed command path. */
export function matchesAnyCommandPath(
commandPath: string[],
rules: readonly CommandPathMatchRule[],
): boolean {
return rules.some((rule) => matchesCommandPathRule(commandPath, rule));
}
+73 -83
View File
@@ -3,12 +3,21 @@ import { describe, expect, it } from "vitest";
import {
resolveCliStartupPolicy,
shouldBypassConfigGuardForCommandPath,
shouldEnsureCliPathForCommandPath,
shouldHideCliBannerForCommandPath,
shouldLoadPluginsForCommandPath,
shouldSkipRouteConfigGuardForCommandPath,
} from "./command-startup-policy.js";
function resolvePolicy(params: {
argv?: string[];
commandPath: string[];
jsonOutputMode?: boolean;
env?: NodeJS.ProcessEnv;
routeMode?: boolean;
}) {
return resolveCliStartupPolicy({
jsonOutputMode: false,
...params,
});
}
describe("command-startup-policy", () => {
it("matches config guard bypass commands", () => {
expect(shouldBypassConfigGuardForCommandPath(["backup", "create"])).toBe(true);
@@ -21,161 +30,152 @@ describe("command-startup-policy", () => {
it("matches route-first config guard skip policy", () => {
expect(
shouldSkipRouteConfigGuardForCommandPath({
resolvePolicy({
commandPath: ["status"],
suppressDoctorStdout: true,
}),
jsonOutputMode: true,
routeMode: true,
}).skipConfigGuard,
).toBe(false);
expect(
shouldSkipRouteConfigGuardForCommandPath({
resolvePolicy({
commandPath: ["gateway", "status"],
suppressDoctorStdout: false,
}),
routeMode: true,
}).skipConfigGuard,
).toBe(true);
expect(
shouldSkipRouteConfigGuardForCommandPath({
resolvePolicy({
commandPath: ["status"],
suppressDoctorStdout: false,
}),
routeMode: true,
}).skipConfigGuard,
).toBe(false);
});
it("matches plugin preload policy", () => {
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["status"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["status"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["health"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["channels", "status"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["channels", "list"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["channels", "add"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["channels", "logs"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["message", "send"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["message", "send"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
argv: ["node", "openclaw", "agent", "--json"],
commandPath: ["agent"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
argv: ["node", "openclaw", "agent", "--json", "--local"],
commandPath: ["agent"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(true);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
argv: ["node", "openclaw", "agent"],
commandPath: ["agent"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(true);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "list"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "list"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "bind"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "bindings"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "unbind"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "set-identity"],
jsonOutputMode: false,
}),
}).loadPlugins,
).toBe(false);
expect(
shouldLoadPluginsForCommandPath({
resolvePolicy({
commandPath: ["agents", "delete"],
jsonOutputMode: true,
}),
}).loadPlugins,
).toBe(false);
});
it("matches banner suppression policy", () => {
expect(shouldHideCliBannerForCommandPath(["update", "status"])).toBe(true);
expect(shouldHideCliBannerForCommandPath(["completion"])).toBe(true);
expect(resolvePolicy({ commandPath: ["update", "status"], env: {} }).hideBanner).toBe(true);
expect(resolvePolicy({ commandPath: ["completion"], env: {} }).hideBanner).toBe(true);
expect(
shouldHideCliBannerForCommandPath(["status"], {
...process.env,
OPENCLAW_HIDE_BANNER: "1",
}),
resolvePolicy({
commandPath: ["status"],
env: {
...process.env,
OPENCLAW_HIDE_BANNER: "1",
},
}).hideBanner,
).toBe(true);
expect(shouldHideCliBannerForCommandPath(["status"], {})).toBe(false);
expect(resolvePolicy({ commandPath: ["status"], env: {} }).hideBanner).toBe(false);
});
it("uses process env banner suppression when startup env is omitted", () => {
@@ -205,16 +205,6 @@ describe("command-startup-policy", () => {
}
});
it("matches CLI PATH bootstrap policy", () => {
expect(shouldEnsureCliPathForCommandPath(["status"])).toBe(false);
expect(shouldEnsureCliPathForCommandPath(["sessions"])).toBe(false);
expect(shouldEnsureCliPathForCommandPath(["config", "get"])).toBe(false);
expect(shouldEnsureCliPathForCommandPath(["models", "status"])).toBe(false);
expect(shouldEnsureCliPathForCommandPath(["tools", "effective"])).toBe(false);
expect(shouldEnsureCliPathForCommandPath(["message", "send"])).toBe(true);
expect(shouldEnsureCliPathForCommandPath([])).toBe(true);
});
it("aggregates startup policy for commander and route-first callers", () => {
expect(
resolveCliStartupPolicy({
-38
View File
@@ -7,30 +7,6 @@ export function shouldBypassConfigGuardForCommandPath(commandPath: string[]): bo
return resolveCliCommandPathPolicy(commandPath).bypassConfigGuard;
}
export function shouldSkipRouteConfigGuardForCommandPath(params: {
commandPath: string[];
suppressDoctorStdout: boolean;
}): boolean {
const routeConfigGuard = resolveCliCommandPathPolicy(params.commandPath).routeConfigGuard;
return (
routeConfigGuard === "always" ||
(routeConfigGuard === "when-suppressed" && params.suppressDoctorStdout)
);
}
export function shouldLoadPluginsForCommandPath(params: {
argv?: string[];
commandPath: string[];
jsonOutputMode: boolean;
}): boolean {
return shouldLoadPlugins({
loadPlugins: resolveCliCommandPathPolicy(params.commandPath).loadPlugins,
argv: params.argv,
commandPath: params.commandPath,
jsonOutputMode: params.jsonOutputMode,
});
}
function shouldLoadPlugins(params: {
argv?: string[];
commandPath: string[];
@@ -49,20 +25,6 @@ function shouldLoadPlugins(params: {
return loadPlugins === "always" || (loadPlugins === "text-only" && !params.jsonOutputMode);
}
export function shouldHideCliBannerForCommandPath(
commandPath: string[],
env: NodeJS.ProcessEnv = process.env,
): boolean {
return (
isTruthyEnvValue(env.OPENCLAW_HIDE_BANNER) ||
resolveCliCommandPathPolicy(commandPath).hideBanner
);
}
export function shouldEnsureCliPathForCommandPath(commandPath: string[]): boolean {
return commandPath.length === 0 || resolveCliCommandPathPolicy(commandPath).ensureCliPath;
}
export function resolveCliStartupPolicy(params: {
argv?: string[];
commandPath: string[];