From a965d28e040949dba215bbb0d4a40ef47d63cc36 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 13 Jul 2026 06:47:02 -0700 Subject: [PATCH] refactor(cli): trim internal command exports (#106426) --- scripts/deadcode-exports.baseline.mjs | 22 ------------------- .../program/command-descriptor-utils.test.ts | 15 ------------- src/cli/program/command-descriptor-utils.ts | 10 +++------ .../program/command-group-descriptors.test.ts | 13 ----------- src/cli/program/command-group-descriptors.ts | 2 +- src/cli/program/command-registry-core.ts | 3 --- src/cli/program/command-registry.test.ts | 4 ++-- src/cli/program/command-registry.ts | 14 ++---------- src/cli/program/command-tree.test.ts | 19 +--------------- src/cli/program/command-tree.ts | 2 +- src/cli/program/register.subclis.ts | 10 +-------- .../program/root-command-descriptions.test.ts | 3 ++- src/cli/update-cli/update-command.test.ts | 14 +++++++----- src/cli/update-cli/update-command.ts | 21 +----------------- 14 files changed, 22 insertions(+), 130 deletions(-) diff --git a/scripts/deadcode-exports.baseline.mjs b/scripts/deadcode-exports.baseline.mjs index e79f8226b4b5..1c0022010046 100644 --- a/scripts/deadcode-exports.baseline.mjs +++ b/scripts/deadcode-exports.baseline.mjs @@ -1331,15 +1331,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/cli/ports.ts: PortProcess", "src/cli/ports.ts: probePortFree", "src/cli/precomputed-help.ts: resolvePrecomputedSubcommandHelpCommand", - "src/cli/program/command-descriptor-utils.ts: getCommandDescriptorNames", - "src/cli/program/command-descriptor-utils.ts: getCommandsWithSubcommands", - "src/cli/program/command-descriptor-utils.ts: getParentDefaultHelpCommands", - "src/cli/program/command-group-descriptors.ts: resolveCommandGroupEntries", - "src/cli/program/command-registry.ts: getCoreCliCommandNames", - "src/cli/program/command-registry.ts: getCoreCliCommandsWithSubcommands", - "src/cli/program/command-registry.ts: registerCoreCliCommands", - "src/cli/program/command-tree.ts: removeCommand", - "src/cli/program/register.subclis.ts: getSubCliEntries", "src/cli/startup-metadata.ts: testing", "src/cli/tagline.ts: DEFAULT_TAGLINE", "src/cli/update-cli/progress.ts: inferUpdateFailureHints", @@ -1350,19 +1341,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/cli/update-cli/update-command-service.ts: recoverInstalledLaunchAgentAfterUpdate", "src/cli/update-cli/update-command-service.ts: recoverLaunchAgentAndRecheckGatewayHealth", "src/cli/update-cli/update-command-service.ts: shouldUseLegacyProcessRestartAfterUpdate", - "src/cli/update-cli/update-command.ts: buildInvalidConfigPostCoreUpdateResult", - "src/cli/update-cli/update-command.ts: collectMissingPluginInstallPayloads", - "src/cli/update-cli/update-command.ts: formatPostUpdateGatewayRecoveryInstructions", - "src/cli/update-cli/update-command.ts: recoverInstalledLaunchAgentAfterUpdate", - "src/cli/update-cli/update-command.ts: recoverLaunchAgentAndRecheckGatewayHealth", - "src/cli/update-cli/update-command.ts: resolvePostCoreUpdateChildStdio", - "src/cli/update-cli/update-command.ts: resolvePostInstallDoctorEnv", - "src/cli/update-cli/update-command.ts: resolvePostSyncPluginUpdateSkipIds", - "src/cli/update-cli/update-command.ts: resolvePostUpdateServiceStateReadEnv", - "src/cli/update-cli/update-command.ts: resolveUpdatedGatewayRestartPort", - "src/cli/update-cli/update-command.ts: shouldPrepareUpdatedInstallRestart", - "src/cli/update-cli/update-command.ts: shouldUseLegacyProcessRestartAfterUpdate", - "src/cli/update-cli/update-command.ts: updatePluginsAfterCoreUpdate", "src/commands/audit.ts: testApi", "src/commands/auth-choice-options.ts: buildAuthChoiceOptions", "src/commands/auth-choice.model-check.ts: DefaultModelAuthStatus", diff --git a/src/cli/program/command-descriptor-utils.test.ts b/src/cli/program/command-descriptor-utils.test.ts index 2b0483e2dcf4..7594b8578a6c 100644 --- a/src/cli/program/command-descriptor-utils.test.ts +++ b/src/cli/program/command-descriptor-utils.test.ts @@ -5,9 +5,6 @@ import { addCommandDescriptorsToProgram, collectUniqueCommandDescriptors, defineCommandDescriptorCatalog, - getCommandDescriptorNames, - getCommandsWithSubcommands, - getParentDefaultHelpCommands, } from "./command-descriptor-utils.js"; describe("command-descriptor-utils", () => { @@ -17,18 +14,6 @@ describe("command-descriptor-utils", () => { { name: "gamma", description: "Gamma", hasSubcommands: true, parentDefaultHelp: true }, ] as const; - it("returns descriptor names in order", () => { - expect(getCommandDescriptorNames(descriptors)).toEqual(["alpha", "beta", "gamma"]); - }); - - it("returns commands with subcommands", () => { - expect(getCommandsWithSubcommands(descriptors)).toEqual(["beta", "gamma"]); - }); - - it("returns commands with parent default help", () => { - expect(getParentDefaultHelpCommands(descriptors)).toEqual(["gamma"]); - }); - it("collects unique descriptors across groups in order", () => { expect( collectUniqueCommandDescriptors([ diff --git a/src/cli/program/command-descriptor-utils.ts b/src/cli/program/command-descriptor-utils.ts index e872e2de3f55..5d1cf6b37dab 100644 --- a/src/cli/program/command-descriptor-utils.ts +++ b/src/cli/program/command-descriptor-utils.ts @@ -37,23 +37,19 @@ export function sanitizeCommandDescriptorDescription(description: string): strin } /** Return descriptor names in registration order. */ -export function getCommandDescriptorNames(descriptors: readonly CommandDescriptorLike[]): string[] { +function getCommandDescriptorNames(descriptors: readonly CommandDescriptorLike[]): string[] { return descriptors.map((descriptor) => descriptor.name); } /** Return descriptor names that should remain parent commands with subcommands. */ -export function getCommandsWithSubcommands( - descriptors: readonly NamedCommandDescriptor[], -): string[] { +function getCommandsWithSubcommands(descriptors: readonly NamedCommandDescriptor[]): string[] { return descriptors .filter((descriptor) => descriptor.hasSubcommands) .map((descriptor) => descriptor.name); } /** Return descriptors whose parent command should show help by default. */ -export function getParentDefaultHelpCommands( - descriptors: readonly NamedCommandDescriptor[], -): string[] { +function getParentDefaultHelpCommands(descriptors: readonly NamedCommandDescriptor[]): string[] { return descriptors .filter((descriptor) => descriptor.parentDefaultHelp) .map((descriptor) => descriptor.name); diff --git a/src/cli/program/command-group-descriptors.test.ts b/src/cli/program/command-group-descriptors.test.ts index f2b0c3056085..a218c4b7eb66 100644 --- a/src/cli/program/command-group-descriptors.test.ts +++ b/src/cli/program/command-group-descriptors.test.ts @@ -6,7 +6,6 @@ import { buildCommandGroupEntries, defineImportedCommandGroupSpec, defineImportedProgramCommandGroupSpecs, - resolveCommandGroupEntries, } from "./command-group-descriptors.js"; const descriptors = [ @@ -23,18 +22,6 @@ const descriptors = [ ] as const; describe("command-group-descriptors", () => { - it("resolves placeholders by descriptor name", () => { - const register = vi.fn(); - expect( - resolveCommandGroupEntries(descriptors, [{ commandNames: ["alpha"], register }]), - ).toEqual([ - { - placeholders: [descriptors[0]], - register, - }, - ]); - }); - it("builds command-group entries with a register mapper", () => { const register = vi.fn(); const mappedRegister = vi.fn(); diff --git a/src/cli/program/command-group-descriptors.ts b/src/cli/program/command-group-descriptors.ts index 33599e121ca4..461d6f10da35 100644 --- a/src/cli/program/command-group-descriptors.ts +++ b/src/cli/program/command-group-descriptors.ts @@ -33,7 +33,7 @@ function buildDescriptorIndex( } /** Resolve named command-group specs into descriptor-backed entries. */ -export function resolveCommandGroupEntries( +function resolveCommandGroupEntries( descriptors: readonly TDescriptor[], specs: readonly CommandGroupDescriptorSpec[], ): ResolvedCommandGroupEntry[] { diff --git a/src/cli/program/command-registry-core.ts b/src/cli/program/command-registry-core.ts index 4c2db15e746c..7c502d63d3e5 100644 --- a/src/cli/program/command-registry-core.ts +++ b/src/cli/program/command-registry-core.ts @@ -12,7 +12,6 @@ import type { ProgramContext } from "./context.js"; import { getCoreCliCommandDescriptors, getCoreCliCommandNames as getCoreDescriptorNames, - getCoreCliCommandsWithSubcommands, } from "./core-command-descriptors.js"; import { registerCommandGroupByName, @@ -20,8 +19,6 @@ import { type CommandGroupEntry, } from "./register-command-groups.js"; -export { getCoreCliCommandsWithSubcommands }; - type CommandRegisterParams = { program: Command; ctx: ProgramContext; diff --git a/src/cli/program/command-registry.test.ts b/src/cli/program/command-registry.test.ts index a248a48f5f6c..eb91c8495735 100644 --- a/src/cli/program/command-registry.test.ts +++ b/src/cli/program/command-registry.test.ts @@ -52,10 +52,10 @@ vi.mock("./register.crestodian.js", () => ({ import { getCoreCliCommandNames, - getCoreCliCommandsWithSubcommands, registerCoreCliByName, registerCoreCliCommands, -} from "./command-registry.js"; +} from "./command-registry-core.js"; +import { getCoreCliCommandsWithSubcommands } from "./core-command-descriptors.js"; const testProgramContext: ProgramContext = { programVersion: "0.0.0-test", diff --git a/src/cli/program/command-registry.ts b/src/cli/program/command-registry.ts index 6fea4c3eb017..ed7f0d959694 100644 --- a/src/cli/program/command-registry.ts +++ b/src/cli/program/command-registry.ts @@ -1,20 +1,10 @@ // Program command registry facade: exports core descriptors and registers core plus sub-CLIs. import type { Command } from "commander"; -import { - getCoreCliCommandNames, - getCoreCliCommandsWithSubcommands, - registerCoreCliByName, - registerCoreCliCommands, -} from "./command-registry-core.js"; +import { registerCoreCliCommands } from "./command-registry-core.js"; import type { ProgramContext } from "./context.js"; import { registerSubCliCommands } from "./register.subclis.js"; -export { - getCoreCliCommandNames, - getCoreCliCommandsWithSubcommands, - registerCoreCliByName, - registerCoreCliCommands, -}; +export { registerCoreCliByName } from "./command-registry-core.js"; /** Register all root-program commands for the current argv shape. */ export function registerProgramCommands( diff --git a/src/cli/program/command-tree.test.ts b/src/cli/program/command-tree.test.ts index 94b947cde42f..22db0235f6bd 100644 --- a/src/cli/program/command-tree.test.ts +++ b/src/cli/program/command-tree.test.ts @@ -1,26 +1,9 @@ // Command tree tests cover CLI command hierarchy construction and lookup. import { Command } from "commander"; import { describe, expect, it } from "vitest"; -import { removeCommand, removeCommandByName } from "./command-tree.js"; +import { removeCommandByName } from "./command-tree.js"; describe("command-tree", () => { - it("removes a command instance when present", () => { - const program = new Command(); - const alpha = program.command("alpha"); - program.command("beta"); - - expect(removeCommand(program, alpha)).toBe(true); - expect(program.commands.map((command) => command.name())).toEqual(["beta"]); - }); - - it("returns false when command instance is already absent", () => { - const program = new Command(); - program.command("alpha"); - const detached = new Command("beta"); - - expect(removeCommand(program, detached)).toBe(false); - }); - it("removes by command name", () => { const program = new Command(); program.command("alpha"); diff --git a/src/cli/program/command-tree.ts b/src/cli/program/command-tree.ts index 3b2142413c12..d55e45fe8cbf 100644 --- a/src/cli/program/command-tree.ts +++ b/src/cli/program/command-tree.ts @@ -2,7 +2,7 @@ import type { Command } from "commander"; /** Remove an exact Command instance from a parent program. */ -export function removeCommand(program: Command, command: Command): boolean { +function removeCommand(program: Command, command: Command): boolean { const commands = program.commands as Command[]; const index = commands.indexOf(command); if (index < 0) { diff --git a/src/cli/program/register.subclis.ts b/src/cli/program/register.subclis.ts index a671a0da5d5c..d730344801f5 100644 --- a/src/cli/program/register.subclis.ts +++ b/src/cli/program/register.subclis.ts @@ -20,10 +20,7 @@ import { registerSubCliCommands as registerSubCliCommandsCore, type SubCliRegistrationContext, } from "./register.subclis-core.js"; -import { - getSubCliEntries as getSubCliEntryDescriptors, - type SubCliDescriptor, -} from "./subcli-descriptors.js"; +import { getSubCliEntries as getSubCliEntryDescriptors } from "./subcli-descriptors.js"; type SubCliRegistrar = ( program: Command, @@ -54,11 +51,6 @@ function resolveSubCliCommandGroups( ); } -/** Return visible sub-CLI descriptors after private QA filtering. */ -export function getSubCliEntries(): ReadonlyArray { - return getSubCliEntryDescriptors(); -} - /** Register one sub-CLI by name, including lazy command groups. */ export async function registerSubCliByName( program: Command, diff --git a/src/cli/program/root-command-descriptions.test.ts b/src/cli/program/root-command-descriptions.test.ts index 3e7c8b9979df..edfc0c8053c7 100644 --- a/src/cli/program/root-command-descriptions.test.ts +++ b/src/cli/program/root-command-descriptions.test.ts @@ -5,7 +5,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { getCoreCliCommandNames, registerCoreCliByName } from "./command-registry-core.js"; import { createProgramContext } from "./context.js"; import { getCoreCliCommandDescriptors } from "./core-command-descriptors.js"; -import { getSubCliEntries, registerSubCliByName } from "./register.subclis.js"; +import { registerSubCliByName } from "./register.subclis.js"; +import { getSubCliEntries } from "./subcli-descriptors.js"; describe("root command descriptions", () => { beforeEach(() => { diff --git a/src/cli/update-cli/update-command.test.ts b/src/cli/update-cli/update-command.test.ts index d64b40c9fc18..f1e4b8f7c452 100644 --- a/src/cli/update-cli/update-command.test.ts +++ b/src/cli/update-cli/update-command.test.ts @@ -12,18 +12,20 @@ import type { UpdateRunResult } from "../../infra/update-runner.js"; import { buildInvalidConfigPostCoreUpdateResult, collectMissingPluginInstallPayloads, + resolvePostSyncPluginUpdateSkipIds, + updatePluginsAfterCoreUpdate, +} from "./update-command-plugins.js"; +import { resolvePostCoreUpdateChildStdio } from "./update-command-post-core.js"; +import { formatPostUpdateGatewayRecoveryInstructions, recoverInstalledLaunchAgentAfterUpdate, recoverLaunchAgentAndRecheckGatewayHealth, - resolvePostCoreUpdateChildStdio, - resolvePostUpdateServiceStateReadEnv, resolvePostInstallDoctorEnv, - resolvePostSyncPluginUpdateSkipIds, - shouldPrepareUpdatedInstallRestart, + resolvePostUpdateServiceStateReadEnv, resolveUpdatedGatewayRestartPort, + shouldPrepareUpdatedInstallRestart, shouldUseLegacyProcessRestartAfterUpdate, - updatePluginsAfterCoreUpdate, -} from "./update-command.js"; +} from "./update-command-service.js"; describe("resolveGatewayInstallEntrypointCandidates", () => { it("prefers index.js before legacy entry.js", () => { diff --git a/src/cli/update-cli/update-command.ts b/src/cli/update-cli/update-command.ts index 1a7f72a545b2..5bbe0fa876c7 100644 --- a/src/cli/update-cli/update-command.ts +++ b/src/cli/update-cli/update-command.ts @@ -140,26 +140,7 @@ import { type UpdateCommandRecoveryState, } from "./update-command-service.js"; -export { - buildInvalidConfigPostCoreUpdateResult, - collectMissingPluginInstallPayloads, - resolvePostSyncPluginUpdateSkipIds, - updatePluginsAfterCoreUpdate, -} from "./update-command-plugins.js"; -export { - formatPostUpdateGatewayRecoveryInstructions, - recoverInstalledLaunchAgentAfterUpdate, - recoverLaunchAgentAndRecheckGatewayHealth, - resolvePostInstallDoctorEnv, - resolvePostUpdateServiceStateReadEnv, - resolveUpdatedGatewayRestartPort, - shouldPrepareUpdatedInstallRestart, - shouldUseLegacyProcessRestartAfterUpdate, -} from "./update-command-service.js"; -export { - resolvePostCoreUpdateChildStdio, - updateFinalizeCommand, -} from "./update-command-post-core.js"; +export { updateFinalizeCommand } from "./update-command-post-core.js"; const CLI_NAME = resolveCliName(); const DEFAULT_UPDATE_STEP_TIMEOUT_MS = 30 * 60_000;