openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
115 lines (114 loc) • 4.58 kB
JavaScript
//#region src/infra/cli-root-options.ts
/** CLI token that stops root option scanning and leaves following args positional. */
const FLAG_TERMINATOR = "--";
const ROOT_BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["--dev", "--no-color"]);
const ROOT_VALUE_FLAGS = /* @__PURE__ */ new Set([
"--profile",
"--log-level",
"--container"
]);
/** Returns whether a token can be consumed as a root option value. */
function isValueToken(arg) {
if (!arg || arg === "--") return false;
if (!arg.startsWith("-")) return true;
return /^-\d+(?:\.\d+)?$/.test(arg);
}
/** Returns how many argv tokens a supported root option consumes at the given index. */
function consumeRootOptionToken(args, index) {
const arg = args[index];
if (!arg) return 0;
if (ROOT_BOOLEAN_FLAGS.has(arg)) return 1;
if (arg.startsWith("--profile=") || arg.startsWith("--log-level=") || arg.startsWith("--container=")) return 1;
if (ROOT_VALUE_FLAGS.has(arg)) return isValueToken(args[index + 1]) ? 2 : 1;
return 0;
}
/** Locate the root command after supported root options without loading CLI catalogs. */
function findRootCommandIndex(argv) {
for (let index = 2; index < argv.length; index += 1) {
const arg = argv[index];
if (!arg || arg === "--") return null;
const consumed = consumeRootOptionToken(argv, index);
if (consumed > 0) {
index += consumed - 1;
continue;
}
if (!arg.startsWith("-")) return index;
}
return null;
}
/** Read positional command tokens while accepting root options at any pre-terminator position. */
function getRootOptionAwareCommandPath(argv, depth) {
const args = argv.slice(2);
const path = [];
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (!arg || arg === "--") break;
const consumed = consumeRootOptionToken(args, index);
if (consumed > 0) {
index += consumed - 1;
continue;
}
if (arg.startsWith("-")) continue;
path.push(arg);
if (path.length >= depth) break;
}
return path;
}
function consumeKnownOptionToken(args, index, booleanFlags, valueFlags, mode) {
const arg = args[index];
if (!arg || arg === "--" || !arg.startsWith("-")) return 0;
const equalsIndex = arg.indexOf("=");
const flag = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
if (booleanFlags.has(flag)) return equalsIndex === -1 ? 1 : 0;
if (!valueFlags.has(flag)) return 0;
if (equalsIndex !== -1) return mode === "command-path" || arg.slice(equalsIndex + 1).trim() ? 1 : 0;
if (mode === "command-path") return args[index + 1] !== void 0 ? 2 : 0;
return isValueToken(args[index + 1]) ? 2 : 0;
}
/** Parse command positionals while consuming known root and command options. */
function getCommandPositionalsWithRootOptions(argv, options) {
return parseCommandArgsWithRootOptions(argv, options, false);
}
/** Preserve the leaf's raw arguments after consuming its root and parent options. */
function getCommandArgsWithRootOptions(argv, options) {
return parseCommandArgsWithRootOptions(argv, options, true);
}
function parseCommandArgsWithRootOptions(argv, options, returnTail) {
const args = argv.slice(2);
const booleanFlags = new Set(options.booleanFlags ?? []);
const valueFlags = new Set(options.valueFlags ?? []);
const positionals = [];
let commandIndex = 0;
let literal = false;
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === void 0 || !arg && options.mode !== "command-path") break;
if (!literal && arg === "--") {
if (options.mode !== "command-path") break;
literal = true;
continue;
}
const rootConsumed = literal ? 0 : consumeRootOptionToken(args, index);
if (rootConsumed > 0) {
index += rootConsumed - 1;
continue;
}
if (!literal && arg.startsWith("-")) {
const optionConsumed = consumeKnownOptionToken(args, index, booleanFlags, valueFlags, options.mode);
if (optionConsumed === 0) return null;
index += optionConsumed - 1;
continue;
}
if (commandIndex < options.commandPath.length) {
if (arg !== options.commandPath[commandIndex]) return null;
commandIndex += 1;
if (returnTail && commandIndex === options.commandPath.length) return args.slice(index + 1);
continue;
}
positionals.push(arg);
if (positionals.length === options.maxPositionals) return positionals;
}
return commandIndex < options.commandPath.length ? null : positionals;
}
//#endregion
export { getCommandPositionalsWithRootOptions as a, getCommandArgsWithRootOptions as i, consumeRootOptionToken as n, getRootOptionAwareCommandPath as o, findRootCommandIndex as r, isValueToken as s, FLAG_TERMINATOR as t };