CLI: unify routed config positional parsing
This commit is contained in:
@@ -102,6 +102,38 @@ describe("program routes", () => {
|
||||
expect(runConfigUnsetMock).toHaveBeenCalledWith({ path: "update.channel" });
|
||||
});
|
||||
|
||||
it("passes config get path when root value options appear after subcommand", async () => {
|
||||
const route = expectRoute(["config", "get"]);
|
||||
await expect(
|
||||
route?.run([
|
||||
"node",
|
||||
"openclaw",
|
||||
"config",
|
||||
"get",
|
||||
"--log-level",
|
||||
"debug",
|
||||
"update.channel",
|
||||
"--json",
|
||||
]),
|
||||
).resolves.toBe(true);
|
||||
expect(runConfigGetMock).toHaveBeenCalledWith({ path: "update.channel", json: true });
|
||||
});
|
||||
|
||||
it("passes config unset path when root value options appear after subcommand", async () => {
|
||||
const route = expectRoute(["config", "unset"]);
|
||||
await expect(
|
||||
route?.run(["node", "openclaw", "config", "unset", "--profile", "work", "update.channel"]),
|
||||
).resolves.toBe(true);
|
||||
expect(runConfigUnsetMock).toHaveBeenCalledWith({ path: "update.channel" });
|
||||
});
|
||||
|
||||
it("returns false for config get route when unknown option appears", async () => {
|
||||
await expectRunFalse(
|
||||
["config", "get"],
|
||||
["node", "openclaw", "config", "get", "--mystery", "value", "update.channel"],
|
||||
);
|
||||
});
|
||||
|
||||
it("returns false for memory status route when --agent value is missing", async () => {
|
||||
await expectRunFalse(["memory", "status"], ["node", "openclaw", "memory", "status", "--agent"]);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { consumeRootOptionToken, isValueToken } from "../../infra/cli-root-options.js";
|
||||
import { isValueToken } from "../../infra/cli-root-options.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { getFlagValue, getPositiveIntFlagValue, getVerboseFlag, hasFlag } from "../argv.js";
|
||||
import {
|
||||
getCommandPositionalsWithRootOptions,
|
||||
getFlagValue,
|
||||
getPositiveIntFlagValue,
|
||||
getVerboseFlag,
|
||||
hasFlag,
|
||||
} from "../argv.js";
|
||||
|
||||
export type RouteSpec = {
|
||||
match: (path: string[]) => boolean;
|
||||
@@ -100,31 +106,6 @@ const routeMemoryStatus: RouteSpec = {
|
||||
},
|
||||
};
|
||||
|
||||
function getCommandPositionals(argv: string[]): string[] {
|
||||
const out: string[] = [];
|
||||
const args = argv.slice(2);
|
||||
let commandStarted = false;
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
const arg = args[i];
|
||||
if (!arg || arg === "--") {
|
||||
break;
|
||||
}
|
||||
if (!commandStarted) {
|
||||
const consumed = consumeRootOptionToken(args, i);
|
||||
if (consumed > 0) {
|
||||
i += consumed - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (arg.startsWith("-")) {
|
||||
continue;
|
||||
}
|
||||
commandStarted = true;
|
||||
out.push(arg);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function getFlagValues(argv: string[], name: string): string[] | null {
|
||||
const values: string[] = [];
|
||||
const args = argv.slice(2);
|
||||
@@ -156,8 +137,14 @@ function getFlagValues(argv: string[], name: string): string[] | null {
|
||||
const routeConfigGet: RouteSpec = {
|
||||
match: (path) => path[0] === "config" && path[1] === "get",
|
||||
run: async (argv) => {
|
||||
const positionals = getCommandPositionals(argv);
|
||||
const pathArg = positionals[2];
|
||||
const positionals = getCommandPositionalsWithRootOptions(argv, {
|
||||
commandPath: ["config", "get"],
|
||||
booleanFlags: ["--json"],
|
||||
});
|
||||
if (!positionals || positionals.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
const pathArg = positionals[0];
|
||||
if (!pathArg) {
|
||||
return false;
|
||||
}
|
||||
@@ -171,8 +158,13 @@ const routeConfigGet: RouteSpec = {
|
||||
const routeConfigUnset: RouteSpec = {
|
||||
match: (path) => path[0] === "config" && path[1] === "unset",
|
||||
run: async (argv) => {
|
||||
const positionals = getCommandPositionals(argv);
|
||||
const pathArg = positionals[2];
|
||||
const positionals = getCommandPositionalsWithRootOptions(argv, {
|
||||
commandPath: ["config", "unset"],
|
||||
});
|
||||
if (!positionals || positionals.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
const pathArg = positionals[0];
|
||||
if (!pathArg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user