From 76bdb025d63a8b6f0890c28fd40ab99d2e0152ee Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 19 Jun 2026 04:37:25 +0800 Subject: [PATCH] refactor(cli): remove stale path policy helpers --- src/cli/argv.test.ts | 3 +- src/cli/argv.ts | 4 - src/cli/command-path-matches.test.ts | 15 --- src/cli/command-path-matches.ts | 8 -- src/cli/command-startup-policy.test.ts | 156 ++++++++++++------------- src/cli/command-startup-policy.ts | 38 ------ 6 files changed, 74 insertions(+), 150 deletions(-) diff --git a/src/cli/argv.test.ts b/src/cli/argv.test.ts index abd42a34eb75..4a8d9fd29eb9 100644 --- a/src/cli/argv.test.ts +++ b/src/cli/argv.test.ts @@ -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", () => { diff --git a/src/cli/argv.ts b/src/cli/argv.ts index 3e737feaedd4..50d00ed0ff03 100644 --- a/src/cli/argv.ts +++ b/src/cli/argv.ts @@ -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 }); } diff --git a/src/cli/command-path-matches.test.ts b/src/cli/command-path-matches.test.ts index 060d858a91f8..238e17f54ccb 100644 --- a/src/cli/command-path-matches.test.ts +++ b/src/cli/command-path-matches.test.ts @@ -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); - }); }); diff --git a/src/cli/command-path-matches.ts b/src/cli/command-path-matches.ts index 3eb94045f985..f585e9abf129 100644 --- a/src/cli/command-path-matches.ts +++ b/src/cli/command-path-matches.ts @@ -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)); -} diff --git a/src/cli/command-startup-policy.test.ts b/src/cli/command-startup-policy.test.ts index 011a582e3870..20e807ed3654 100644 --- a/src/cli/command-startup-policy.test.ts +++ b/src/cli/command-startup-policy.test.ts @@ -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({ diff --git a/src/cli/command-startup-policy.ts b/src/cli/command-startup-policy.ts index 650e5e568a6f..a3ae31978c01 100644 --- a/src/cli/command-startup-policy.ts +++ b/src/cli/command-startup-policy.ts @@ -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[];