File size: 2,803 Bytes
eb3f11e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | // Commander subclass that preserves the exact failing command for parse-error guidance.
import { Command, CommanderError, type ErrorOptions } from "commander";
import { applyResolvedCommandOutputMode, isJsonOutputModeActive } from "../json-output-mode.js";
import {
getCommanderErrorCommandNames,
getCommanderErrorCommandPath,
getCommanderSubcommandFact,
hasCommanderOptionToken,
setCommanderErrorCommand,
} from "./commander-parse-facts.js";
import { createCliParseError } from "./error-output.js";
import { isCommandJsonOutputMode } from "./json-mode.js";
// Commander 15 declares this help hook only in its runtime class, not its types.
// Declaring it here lets the subclass override and delegate through `super`
// instead of re-binding a captured prototype method.
declare module "commander" {
interface Command {
_outputHelpIfRequested(args: string[]): void;
}
}
export class OpenClawCommand extends Command {
override createCommand(name?: string): Command {
return new OpenClawCommand(name);
}
override error(message: string, errorOptions?: ErrorOptions): never {
const restoreErrorCommand = setCommanderErrorCommand(this);
try {
return super.error(message, errorOptions);
} catch (error) {
if (
error instanceof CommanderError &&
error.exitCode !== 0 &&
(isJsonOutputModeActive(process.argv) || isCommandJsonOutputMode(this, process.argv))
) {
if (
!isCommandJsonOutputMode(this, process.argv) &&
!hasCommanderOptionToken(this, process.argv, new Set(["--json"]), "flag")
) {
applyResolvedCommandOutputMode(false);
throw error;
}
applyResolvedCommandOutputMode(true);
throw createCliParseError(
message,
{
argv: process.argv,
commandPath: getCommanderErrorCommandPath(this),
commandNames: getCommanderErrorCommandNames(this),
},
{ humanOutputWritten: true },
);
}
throw error;
} finally {
restoreErrorCommand();
}
}
// Commander 15 checks this internal hook before dispatching actions.
// Defer only marked lazy placeholders so their real command tree can decide.
override _outputHelpIfRequested(args: string[]): void {
const subcommandFact = getCommanderSubcommandFact(this, args);
if (subcommandFact?.kind === "defer") {
return;
}
if (subcommandFact?.kind === "unknown") {
this.error(`error: unknown command '${subcommandFact.name}'`, {
code: "commander.unknownCommand",
});
}
// oxlint-disable-next-line eslint/no-underscore-dangle -- Commander 15.0.0 owns this hook name; package.json pins that exact version.
super._outputHelpIfRequested(args);
}
}
|