diff --git a/packages/kilo-ui/src/stories/message-part.stories.tsx b/packages/kilo-ui/src/stories/message-part.stories.tsx
index e67fe32b441..8c256487b12 100644
--- a/packages/kilo-ui/src/stories/message-part.stories.tsx
+++ b/packages/kilo-ui/src/stories/message-part.stories.tsx
@@ -163,6 +163,39 @@ const errorToolPart: ToolPart = {
},
}
+// Completed edit tool with full filediff metadata — exercises canOpenDiff()
+// so the "Open in Diff Viewer" icon button renders in the trigger.
+const editCompletedPart: ToolPart = {
+ id: "part-tool-edit-done",
+ sessionID: SESSION_ID,
+ messageID: ASST_MSG_ID,
+ type: "tool",
+ callID: "call-edit-done",
+ tool: "edit",
+ state: {
+ status: "completed",
+ input: {
+ filePath: "src/counter.tsx",
+ oldString: "const [count, setCount] = createSignal(0)",
+ newString: "const [count, setCount] = createSignal(1)",
+ },
+ output: "File edited successfully",
+ title: "Edit file",
+ metadata: {
+ filediff: {
+ file: "src/counter.tsx",
+ before:
+ "import { createSignal } from 'solid-js'\n\nexport function Counter() {\n const [count, setCount] = createSignal(0)\n return \n}\n",
+ after:
+ "import { createSignal } from 'solid-js'\n\nexport function Counter() {\n const [count, setCount] = createSignal(1)\n return \n}\n",
+ additions: 1,
+ deletions: 1,
+ },
+ },
+ time: { start: now - 4000, end: now - 3500 },
+ },
+}
+
// --- Reasoning part ---
const reasoningPart: ReasoningPart = {
@@ -208,10 +241,12 @@ const mockDataReasoning = createMockData([reasoningPart, textPart])
const mockDataBash = createMockData([bashCompleted])
// Three context-group tools — exercises ContextToolGroupHeader collapse path
const mockDataContextGroup = createMockData([completedToolPart, grepCompleted, globCompleted, textPart])
+// Completed edit tool with filediff — exercises the "Open in Diff Viewer" button path
+const mockDataEdit = createMockData([editCompletedPart])
-function AllProviders(props: { children: any; data?: MockData }) {
+function AllProviders(props: { children: any; data?: MockData; onOpenDiff?: () => void }) {
return (
-
+
@@ -354,6 +389,25 @@ export const WithContextGroup: Story = {
),
}
+// --- Completed edit tool with filediff → "Open in Diff Viewer" icon visible ---
+//
+// CSS :hover cannot be triggered reliably from Storybook `play` functions,
+// so the action slot is force-revealed via a scoped style override. This
+// captures the layout with the icon present so the visual regression
+// suite catches any regression in:
+// - the `:has()` parent-grow rule on basic-tool-tool-info
+// - the `margin-left: auto` pushing the action to the right
+// - the icon-button ghost variant in the tool-trigger row
+export const WithEditToolOpenDiffAction: Story = {
+ name: "WithEditTool (open-diff action visible)",
+ render: () => (
+ {}}>
+
+
+
+ ),
+}
+
// --- All 5 tool hint error types in a single screenshot ---
const hintErrors: ToolPart[] = [