diff --git a/src/cli/interactiveSetup.ts b/src/cli/interactiveSetup.ts index 9e73025e69..6a4af58753 100644 --- a/src/cli/interactiveSetup.ts +++ b/src/cli/interactiveSetup.ts @@ -275,8 +275,15 @@ const readyAgentClients = ( const readyProviders = (result: SetupResult): readonly string[] => result.doctor.availableProviders.map(displayProviderId); +/** Product spellings that title case would distort. Lookup ids stay lowercase. */ +const PROVIDER_DISPLAY_NAMES: Readonly> = { + ida: "IDA", + jadx: "JADX", +}; + const displayProviderId = (id: string): string => - id.length === 0 ? id : `${id[0]?.toUpperCase() ?? ""}${id.slice(1)}`; + PROVIDER_DISPLAY_NAMES[id] ?? + (id.length === 0 ? id : `${id[0]?.toUpperCase() ?? ""}${id.slice(1)}`); const humanList = (values: readonly string[]): string => { if (values.length < 2) return values[0] ?? ""; diff --git a/tests/boundary/cli/cliSetup.test.ts b/tests/boundary/cli/cliSetup.test.ts index 7574b4e26d..cd4ee046d1 100644 --- a/tests/boundary/cli/cliSetup.test.ts +++ b/tests/boundary/cli/cliSetup.test.ts @@ -493,6 +493,38 @@ describe("interactive setup completion", () => { ); }, ); + + it("prints IDA and JADX with their product spellings", async () => { + const { stderr } = await execute( + process.execPath, + [ + "--input-type=module", + "--eval", + [ + 'import { renderInteractiveSetupResult } from "./dist/cli/interactiveSetup.js";', + "renderInteractiveSetupResult({", + ' status: "ready",', + " plannedActions: [],", + " appliedActions: [],", + " clients: {},", + " doctor: {", + " healthy: true,", + ' availableProviders: ["hopper", "ghidra", "ida", "jadx", "kuna"],', + " checks: [],", + " },", + "}, {});", + ].join("\n"), + ], + { cwd: process.cwd(), env: { ...process.env, NO_COLOR: "1" } }, + ); + + expect(stderr).toContain( + "Deep analysis: Hopper, Ghidra, IDA, JADX, and Kuna", + ); + expect(stderr).not.toContain("Ida"); + expect(stderr).not.toContain("Jadx"); + }); + it("prints retained cleanup resources without relying on paths in remediation", async () => { const resources = ["/fixture/owned backup", "/fixture/临时目录"]; const result: SetupResult = {