Files
reverse-engineering-anything/src/cli/cliLoader.ts
T
gensokyo-devandgensokyo-dev b990eb496d perf(cli): load only the registrar a one-shot command needs
Every rea process imported and registered all 52 command registrars
(about 1,900 modules) before running any command. A one-shot command
now loads only the registrar that defines its top-level command.

- src/cli/cliCommandRegistrations.ts holds every registrar in one table,
  grouped by tool family, with its module loader and its call. The
  complete createCli registers the table with static imports, and the
  types check that each entry matches its module.
- src/cli/cliShell.ts owns what does not depend on which commands are
  registered: identity, globals, argument policy, completions and the
  registration builtins. The full and lazy paths share it.
- scripts/record-cli-commands.mjs records, after tsc, which registrar
  defines each top-level command, from the same compiled table. The
  bundle keeps the record as an external dist module.
- cli/cliLoader.ts selects the recorded registrar when a known top-level
  command runs. It loads the complete CLI for help, --schema, --llms,
  completions, builtins, unknown names ("did you mean"), or a missing
  record.
- Process-owned CLI resources register their closers when their module
  loads (cli/cliResources.ts), so the shell no longer imports
  JavaScript-analysis and guidance owners just to close them.

Measured on one pinned core (median of 5 warm runs, base main vs this
change):
- guidance: 1.95 s / 253 MB → 0.42 s / 101 MB
- list-cutter-sessions: 1.97 s → 0.49 s
- inspect-go-binary: 1.95 s → 0.95 s
- setup --dry-run: 2.40 s → 1.88 s
- analyze: 2.39 s → 1.78 s
- --help: 1.99 s → 2.04 s (complete CLI, as before)

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-11-14 20:25:11 +08:00

99 lines
3.3 KiB
TypeScript

import {
cliCompletionShell,
splitIncurBuiltinArguments,
} from "../cliBuiltinArguments.js";
import { RECORDED_CLI_COMMAND_REGISTRATIONS } from "../recordedCliCommandRegistrations.js";
import {
CLI_COMMAND_REGISTRATIONS,
type CliCommandRegistrationId,
} from "./cliCommandRegistrations.js";
import type { CliResultOutput } from "./cliResultOutput.js";
import type { CliInstance } from "./types.js";
/** Global switches that change only how a command's result is written. */
const COMMAND_OUTPUT_FLAGS: ReadonlySet<string> = new Set([
"--json",
"--full-output",
"--token-count",
"--timings",
"--no-timings",
]);
const isRegistrationId = (id: string): id is CliCommandRegistrationId =>
Object.hasOwn(CLI_COMMAND_REGISTRATIONS, id);
/**
* The registrar that defines the command these arguments run, or undefined
* when the complete CLI must answer. Help, schemas, `--llms`, completions,
* Incur builtins, unknown names ("did you mean"), and a missing or unusable
* recording all describe or search every command.
*/
export const selectCliRegistration = (
arguments_: readonly string[],
environment: Readonly<NodeJS.ProcessEnv>,
recorded: Readonly<Record<string, string>> | undefined,
): CliCommandRegistrationId | undefined => {
if (recorded === undefined || cliCompletionShell(environment) !== undefined)
return undefined;
const { command, flags } = splitIncurBuiltinArguments(arguments_);
for (const flag of flags)
if (!COMMAND_OUTPUT_FLAGS.has(flag) && !flag.startsWith("--timings="))
return undefined;
const name = command[0];
if (name === undefined || !Object.hasOwn(recorded, name)) return undefined;
const id = recorded[name]!;
return isRegistrationId(id) ? id : undefined;
};
/** The command runtime one invocation loaded, before its CLI is built. */
export interface CliRuntime {
createCli(resultOutput: CliResultOutput | undefined): CliInstance;
/** Closes the process-owned resources of this runtime's commands. */
closeCliResources(): Promise<void>;
}
/**
* Load the command runtime for one invocation. A recorded top-level command
* loads only its registrar's module graph; anything else loads the complete
* CLI.
*/
export const loadCliRuntime = async (
arguments_: readonly string[],
environment: NodeJS.ProcessEnv,
): Promise<CliRuntime> => {
const id = selectCliRegistration(
arguments_,
environment,
RECORDED_CLI_COMMAND_REGISTRATIONS,
);
if (id === undefined) {
const { createCli, closeCliResources } = await import("../cli.js");
return {
createCli: (resultOutput) => createCli(environment, resultOutput),
closeCliResources,
};
}
const registration = CLI_COMMAND_REGISTRATIONS[id];
const [module, { createCliShell }, { closeCliResources }, analysis] =
await Promise.all([
registration.load(),
import("./cliShell.js"),
import("./cliResources.js"),
registration.analysis
? import("../composition/directAnalysis.js")
: undefined,
]);
return {
createCli: (resultOutput) =>
createCliShell({
selectedEnvironment: environment,
resultOutput,
registrations: [{ registration, module }],
...(analysis === undefined
? {}
: { createAnalysis: analysis.createDirectAnalysis }),
}),
closeCliResources,
};
};