






















@@ -28,6 +28,7 @@ const extensionsDir = path.join(rootDir, "extensions");
2828const ROOT_HELP_RENDER_TIMEOUT_MS = 120_000;
2929const BROWSER_HELP_RENDER_TIMEOUT_MS = 120_000;
3030const COMMAND_HELP_RENDER_TIMEOUT_MS = 120_000;
31+const PRECOMPUTED_SUBCOMMAND_HELP_COMMANDS = ["doctor", "gateway", "models", "plugins"] as const;
3132const CORE_CHANNEL_ORDER = [
3233"telegram",
3334"whatsapp",
@@ -50,6 +51,8 @@ type BundledChannelCatalog = {
5051signature: string;
5152};
525354+type PrecomputedSubcommandHelpCommand = (typeof PRECOMPUTED_SUBCOMMAND_HELP_COMMANDS)[number];
55+type PrecomputedSubcommandHelpText = Record<PrecomputedSubcommandHelpCommand, string>;
5356type RootHelpRenderContext = Pick<RootHelpRenderOptions, "config" | "env">;
54575558function resolveRootHelpBundleIdentity(
@@ -143,6 +146,30 @@ function resolveNodesHelpSourceSignature(sourceRootDir: string = rootDir): strin
143146return hash.digest("hex");
144147}
145148149+function resolveSubcommandHelpSourceSignature(sourceRootDir: string = rootDir): string {
150+const hash = createHash("sha1");
151+updateHashFromFiles(
152+hash,
153+[
154+path.join(sourceRootDir, "src/cli/program/help.ts"),
155+path.join(sourceRootDir, "src/cli/program/context.ts"),
156+path.join(sourceRootDir, "src/cli/banner.ts"),
157+path.join(sourceRootDir, "src/cli/help-format.ts"),
158+path.join(sourceRootDir, "src/cli/daemon-cli/register-service-commands.ts"),
159+path.join(sourceRootDir, "src/cli/program/register.maintenance.ts"),
160+path.join(sourceRootDir, "src/cli/gateway-cli.ts"),
161+path.join(sourceRootDir, "src/cli/gateway-cli/register.ts"),
162+path.join(sourceRootDir, "src/cli/gateway-cli/run-command.ts"),
163+path.join(sourceRootDir, "src/cli/models-cli.ts"),
164+path.join(sourceRootDir, "src/cli/plugins-cli.ts"),
165+path.join(sourceRootDir, "src/terminal/links.ts"),
166+path.join(sourceRootDir, "src/terminal/theme.ts"),
167+],
168+sourceRootDir,
169+);
170+return hash.digest("hex");
171+}
172+146173export function readBundledChannelCatalog(
147174extensionsDirOverride: string = extensionsDir,
148175): BundledChannelCatalog {
@@ -362,7 +389,7 @@ function renderSourceBrowserHelpText(
362389}
363390364391function renderSourceCommandHelpText(
365-command: "nodes" | "secrets",
392+command: "nodes" | "secrets" | PrecomputedSubcommandHelpCommand,
366393renderContext: RootHelpRenderContext = createIsolatedRootHelpRenderContext(),
367394): string {
368395const result = spawnSync(
@@ -403,6 +430,16 @@ function renderSourceNodesHelpText(
403430return renderSourceCommandHelpText("nodes", renderContext);
404431}
405432433+function renderSourceSubcommandHelpTextRecord(
434+renderContext: RootHelpRenderContext = createIsolatedRootHelpRenderContext(),
435+): PrecomputedSubcommandHelpText {
436+const entries = PRECOMPUTED_SUBCOMMAND_HELP_COMMANDS.map((commandName) => [
437+commandName,
438+renderSourceCommandHelpText(commandName, renderContext),
439+]);
440+return Object.fromEntries(entries) as PrecomputedSubcommandHelpText;
441+}
442+406443export async function writeCliStartupMetadata(options?: {
407444distDir?: string;
408445outputPath?: string;
@@ -413,6 +450,7 @@ export async function writeCliStartupMetadata(options?: {
413450renderSourceBrowserHelpText?: typeof renderSourceBrowserHelpText;
414451renderSourceSecretsHelpText?: typeof renderSourceSecretsHelpText;
415452renderSourceNodesHelpText?: typeof renderSourceNodesHelpText;
453+renderSourceSubcommandHelpTextRecord?: typeof renderSourceSubcommandHelpTextRecord;
416454}): Promise<void> {
417455const resolvedDistDir = options?.distDir ?? distDir;
418456const resolvedOutputPath = options?.outputPath ?? outputPath;
@@ -423,6 +461,7 @@ export async function writeCliStartupMetadata(options?: {
423461const browserHelpSourceSignature = resolveBrowserHelpSourceSignature(resolvedSourceRootDir);
424462const secretsHelpSourceSignature = resolveSecretsHelpSourceSignature(resolvedSourceRootDir);
425463const nodesHelpSourceSignature = resolveNodesHelpSourceSignature(resolvedSourceRootDir);
464+const subcommandHelpSourceSignature = resolveSubcommandHelpSourceSignature(resolvedSourceRootDir);
426465const bundledPluginsDir = path.join(resolvedDistDir, "extensions");
427466const renderContext = createIsolatedRootHelpRenderContext(
428467existsSync(bundledPluginsDir) ? bundledPluginsDir : resolvedExtensionsDir,
@@ -435,24 +474,28 @@ export async function writeCliStartupMetadata(options?: {
435474browserHelpSourceSignature?: unknown;
436475secretsHelpSourceSignature?: unknown;
437476nodesHelpSourceSignature?: unknown;
477+subcommandHelpSourceSignature?: unknown;
438478channelCatalogSignature?: unknown;
439479browserHelpText?: unknown;
440480secretsHelpText?: unknown;
441481nodesHelpText?: unknown;
482+subcommandHelpText?: unknown;
442483};
443484if (
444485bundleIdentity &&
445486existing.rootHelpBundleSignature === bundleIdentity.signature &&
446487existing.browserHelpSourceSignature === browserHelpSourceSignature &&
447488existing.secretsHelpSourceSignature === secretsHelpSourceSignature &&
448489existing.nodesHelpSourceSignature === nodesHelpSourceSignature &&
490+existing.subcommandHelpSourceSignature === subcommandHelpSourceSignature &&
449491existing.channelCatalogSignature === channelCatalog.signature &&
450492typeof existing.browserHelpText === "string" &&
451493existing.browserHelpText.length > 0 &&
452494typeof existing.secretsHelpText === "string" &&
453495existing.secretsHelpText.length > 0 &&
454496typeof existing.nodesHelpText === "string" &&
455-existing.nodesHelpText.length > 0
497+existing.nodesHelpText.length > 0 &&
498+hasAllPrecomputedSubcommandHelpText(existing.subcommandHelpText)
456499) {
457500return;
458501}
@@ -478,6 +521,9 @@ export async function writeCliStartupMetadata(options?: {
478521const nodesHelpText = (options?.renderSourceNodesHelpText ?? renderSourceNodesHelpText)(
479522renderContext,
480523);
524+const subcommandHelpText = (
525+options?.renderSourceSubcommandHelpTextRecord ?? renderSourceSubcommandHelpTextRecord
526+)(renderContext);
481527482528mkdirSync(resolvedDistDir, { recursive: true });
483529writeFileSync(
@@ -491,9 +537,11 @@ export async function writeCliStartupMetadata(options?: {
491537 browserHelpSourceSignature,
492538 secretsHelpSourceSignature,
493539 nodesHelpSourceSignature,
540+ subcommandHelpSourceSignature,
494541 browserHelpText,
495542 secretsHelpText,
496543 nodesHelpText,
544+ subcommandHelpText,
497545 rootHelpText,
498546 },
499547 null,
@@ -503,6 +551,16 @@ export async function writeCliStartupMetadata(options?: {
503551);
504552}
505553554+function hasAllPrecomputedSubcommandHelpText(value: unknown): boolean {
555+if (typeof value !== "object" || value === null) {
556+return false;
557+}
558+const record = value as Partial<Record<PrecomputedSubcommandHelpCommand, unknown>>;
559+return PRECOMPUTED_SUBCOMMAND_HELP_COMMANDS.every(
560+(commandName) => typeof record[commandName] === "string" && record[commandName].length > 0,
561+);
562+}
563+506564if (process.argv[1] && path.resolve(process.argv[1]) === scriptPath) {
507565await writeCliStartupMetadata();
508566process.exit(0);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。