diff --git a/packages/app/src/components/provider-icons.test.ts b/packages/app/src/components/provider-icons.test.ts index 025ff14bef..6b9314c99f 100644 --- a/packages/app/src/components/provider-icons.test.ts +++ b/packages/app/src/components/provider-icons.test.ts @@ -1,5 +1,7 @@ // @vitest-environment jsdom import { act, cleanup, renderHook } from "@testing-library/react"; +import { TERMINAL_PROFILE_ICON_NAMES } from "@getpaseo/protocol/provider-icon-names"; +import { ACP_PROVIDER_ICON_SVGS } from "@/assets/acp-provider-icons"; import { Bot } from "lucide-react-native"; import { SvgXml } from "react-native-svg"; import { afterEach, describe, expect, it } from "vitest"; @@ -84,3 +86,32 @@ it("updates collection consumers when their host snapshot arrives", () => { act(() => replaceProviderSnapshotIcons(serverId, [{ provider, iconSvg: svg }])); expect(renderIcon(result.current(provider))).toMatchObject({ props: { xml: svg } }); }); + +it("renders the shipped Antigravity SVG for a terminal profile icon", () => { + const { result } = renderHook(() => useProviderIcon("agy")); + expect(result.current).not.toBe(Bot); + expect(renderIcon(result.current)).toMatchObject({ + type: SvgXml, + props: { xml: ACP_PROVIDER_ICON_SVGS.agy, width: 18, height: 18, color: "#123456" }, + }); +}); + +it.each(TERMINAL_PROFILE_ICON_NAMES)( + "renders terminal icon %s through collection consumers", + (name) => { + const { result } = renderHook(() => useProviderIcons()); + expect(renderIcon(result.current(name))).toMatchObject({ + type: SvgXml, + props: { xml: ACP_PROVIDER_ICON_SVGS[name as keyof typeof ACP_PROVIDER_ICON_SVGS] }, + }); + }, +); + +it("preserves catalog icons and the unknown icon fallback", () => { + const catalog = renderHook(() => useProviderIcon("cursor")); + expect(renderIcon(catalog.result.current)).toMatchObject({ + type: SvgXml, + props: { xml: ACP_PROVIDER_ICON_SVGS.cursor }, + }); + expect(renderHook(() => useProviderIcon("definitely-not-a-real-icon")).result.current).toBe(Bot); +}); diff --git a/packages/app/src/components/provider-icons.ts b/packages/app/src/components/provider-icons.ts index fec4003705..883b4820f7 100644 --- a/packages/app/src/components/provider-icons.ts +++ b/packages/app/src/components/provider-icons.ts @@ -3,6 +3,7 @@ import { providerSnapshotIcons } from "@/data/provider-icons"; import { Bot, PackagePlus } from "lucide-react-native"; import { createElement, useCallback, type ComponentType } from "react"; import { SvgXml } from "react-native-svg"; +import { TERMINAL_PROFILE_ICON_NAMES } from "@getpaseo/protocol/provider-icon-names"; import { ClaudeIcon } from "@/components/icons/claude-icon"; import { CodexIcon } from "@/components/icons/codex-icon"; import { CopilotIcon } from "@/components/icons/copilot-icon"; @@ -10,6 +11,7 @@ import { MiniMaxIcon } from "@/components/icons/minimax-icon"; import { OpenCodeIcon } from "@/components/icons/opencode-icon"; import { OmpIcon } from "@/components/icons/omp-icon"; import { PiIcon } from "@/components/icons/pi-icon"; +import { ACP_PROVIDER_ICON_SVGS } from "@/assets/acp-provider-icons"; import { ACP_PROVIDER_CATALOG } from "@/data/acp-provider-catalog"; import { resolveProviderIconName } from "@/components/provider-icon-name"; @@ -31,10 +33,17 @@ const BUILTIN_PROVIDER_ICONS: Record = { pi: PiIcon as unknown as ProviderIconComponent, }; -const CATALOG_ICON_SVGS = new Map( +const CATALOG_ICON_SVGS = new Map( ACP_PROVIDER_CATALOG.flatMap((entry) => (entry.iconSvg ? [[entry.id, entry.iconSvg]] : [])), ); +for (const name of TERMINAL_PROFILE_ICON_NAMES) { + const iconSvg = (ACP_PROVIDER_ICON_SVGS as Record)[name]; + if (iconSvg) { + CATALOG_ICON_SVGS.set(name, iconSvg); + } +} + const catalogIconComponents = new Map(); const snapshotIconComponents = new Map();