From 0a76db397e92c945fefabcf08ff89dcc97f6e6c3 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Thu, 15 Oct 2026 09:31:00 +0900 Subject: feat(tool-call-cards): distinct Phosphor icon per tool (phosphor-svelte, deep imports) --- src/features/chat/ui/ChatView.test.ts | 27 ++++++++++++++++++ src/features/chat/ui/ToolCard.svelte | 19 +++---------- src/features/chat/ui/tool-icons.ts | 52 +++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 src/features/chat/ui/tool-icons.ts (limited to 'src/features/chat/ui') diff --git a/src/features/chat/ui/ChatView.test.ts b/src/features/chat/ui/ChatView.test.ts index 4b28b48..77f832d 100644 --- a/src/features/chat/ui/ChatView.test.ts +++ b/src/features/chat/ui/ChatView.test.ts @@ -470,3 +470,30 @@ it("shows an argument-less call without `{}` — empty header summary, 'No argum expect(screen.getByText("No arguments")).toBeInTheDocument(); expect(container).not.toHaveTextContent("{}"); }); + +it("renders a per-tool Phosphor icon in the header", () => { + const chunks: RenderedChunk[] = [ + { + seq: 1, + role: "assistant", + provisional: false, + chunk: { + type: "tool-call", + toolCallId: "s", + toolName: "run_shell", + input: { command: "ls" }, + }, + }, + { + seq: 2, + role: "assistant", + provisional: false, + chunk: { type: "tool-call", toolCallId: "r", toolName: "read_file", input: { path: "a.ts" } }, + }, + ]; + const { container } = render(ChatView, { props: { chunks } }); + const icons = Array.from(container.querySelectorAll(".tool-header svg[aria-hidden='true']")); + expect(icons).toHaveLength(2); + // Different tools → different glyphs. + expect(icons[0]?.innerHTML).not.toBe(icons[1]?.innerHTML); +}); diff --git a/src/features/chat/ui/ToolCard.svelte b/src/features/chat/ui/ToolCard.svelte index c3da723..0a72bb5 100644 --- a/src/features/chat/ui/ToolCard.svelte +++ b/src/features/chat/ui/ToolCard.svelte @@ -2,9 +2,11 @@ import type { ToolEntry } from "../index"; import { viewToolEntry } from "../logic/tool-summary"; import LazyCollapse from "./LazyCollapse.svelte"; + import { TOOL_ICON_COMPONENTS } from "./tool-icons"; let { entry }: { entry: ToolEntry } = $props(); const card = $derived(viewToolEntry(entry)); + const ToolIcon = $derived(TOOL_ICON_COMPONENTS[card.icon]); let showAll = $state(false); @@ -25,21 +27,8 @@ aria-label="Succeeded">✓ {/if} - + +