From 1f547ade8b97a6b6289a283c68b8e82cd3677e19 Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Fri, 28 Aug 2026 11:02:07 +0200 Subject: [PATCH] refactor(vscode): remove duplicate and unused UI code --- .../tests/unit/agent-manager-arch.test.ts | 2 +- .../kilo-vscode/tests/unit/plan-exit.test.ts | 3 +- .../tests/unit/revert-checkpoints.test.ts | 6 +- .../tests/unit/review-comments.test.ts | 17 ++ .../webview-ui/agent-manager/DiffPanel.tsx | 27 +-- .../agent-manager/ProjectActions.tsx | 103 ++++----- .../agent-manager/WorktreeSectionActions.tsx | 63 +----- .../diff-viewer/FullScreenDiffView.tsx | 27 +-- .../diff-viewer/review-annotations.ts | 15 ++ .../webview-ui/documents/DocumentPanel.tsx | 24 +- .../src/components/chat/MessageList.tsx | 3 - .../src/components/chat/VscodeSessionTurn.tsx | 210 ------------------ .../webview-ui/src/context/session.tsx | 3 +- .../src/stories/composite.stories.tsx | 29 ++- 14 files changed, 123 insertions(+), 409 deletions(-) delete mode 100644 packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx diff --git a/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts b/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts index e8d570ce4f..d21b301b1b 100644 --- a/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts +++ b/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts @@ -360,7 +360,7 @@ describe("Agent Manager Model Picker", () => { describe("Agent Manager Worktree Actions", () => { it("opens the configuration dialog from the primary plus action", () => { - const source = fs.readFileSync(path.join(ROOT, "webview-ui/agent-manager/WorktreeSectionActions.tsx"), "utf-8") + const source = fs.readFileSync(path.join(ROOT, "webview-ui/agent-manager/ProjectActions.tsx"), "utf-8") const start = source.indexOf('
') const end = source.indexOf("
", start) const actions = source.slice(start, end) diff --git a/packages/kilo-vscode/tests/unit/plan-exit.test.ts b/packages/kilo-vscode/tests/unit/plan-exit.test.ts index 11042c38fa..2371eca0d1 100644 --- a/packages/kilo-vscode/tests/unit/plan-exit.test.ts +++ b/packages/kilo-vscode/tests/unit/plan-exit.test.ts @@ -47,7 +47,7 @@ describe("planDisplayPath", () => { describe("plan_exit renderer uses openFile not openDiff (source)", () => { const ROOT = path.resolve(import.meta.dir, "../..") const FILE = path.join(ROOT, "webview-ui/src/components/chat/AssistantMessage.tsx") - const TURN_FILE = path.join(ROOT, "webview-ui/src/components/chat/VscodeSessionTurn.tsx") + const TURN_FILE = path.join(ROOT, "webview-ui/src/components/chat/TranscriptRow.tsx") const src = fs.readFileSync(FILE, "utf-8") const turnSrc = fs.readFileSync(TURN_FILE, "utf-8") @@ -76,6 +76,7 @@ describe("plan_exit renderer uses openFile not openDiff (source)", () => { expect(src).not.toContain("Object.values(data.store.part ?? {}).flat()") expect(src).not.toContain("[...props.parts, ...all()]") expect(src).not.toContain("turnParts") + expect(turnSrc).toContain("parts={row().parts as unknown as SDKPart[]}") expect(turnSrc).not.toContain("assistantMessages().flatMap") expect(turnSrc).not.toContain("turnParts={assistantParts()}") }) diff --git a/packages/kilo-vscode/tests/unit/revert-checkpoints.test.ts b/packages/kilo-vscode/tests/unit/revert-checkpoints.test.ts index c28477b20f..c2a03894cd 100644 --- a/packages/kilo-vscode/tests/unit/revert-checkpoints.test.ts +++ b/packages/kilo-vscode/tests/unit/revert-checkpoints.test.ts @@ -3,7 +3,7 @@ import fs from "node:fs" import path from "node:path" const ROOT = path.resolve(import.meta.dir, "../..") -const TURN_FILE = path.join(ROOT, "webview-ui/src/components/chat/VscodeSessionTurn.tsx") +const TURN_FILE = path.join(ROOT, "webview-ui/src/components/chat/TranscriptRow.tsx") const PROVIDER_FILE = path.join(ROOT, "src/KiloProvider.ts") const BANNER_FILE = path.join(ROOT, "webview-ui/src/components/chat/RevertBanner.tsx") const SESSION_FILE = path.join(ROOT, "webview-ui/src/types/messages/sessions.ts") @@ -32,12 +32,12 @@ function exported(name: string) { describe("message revert checkpoints", () => { it("keeps revert actions available after a session is already reverted", () => { - expect(src).toMatch(/onRevert=\{\s*assistantMessages\(\)\.length > 0\s*\? \(\) =>/) + expect(src).toMatch(/onRevert=\{\s*row\(\)\.answered\s*\? \(\) =>/) expect(src).not.toMatch(/onRevert=\{[\s\S]*?&& !session\.revert\(\)[\s\S]*?\? \(\) =>/) }) it("only marks revert disabled while the agent is busy", () => { - expect(src).toMatch(/data-revert-disabled=\{\s*assistantMessages\(\)\.length > 0 && session\.status\(\) !== "idle"/) + expect(src).toMatch(/data-revert-disabled=\{\s*row\(\)\.answered && session\.status\(\) !== "idle"/) expect(src).not.toMatch(/data-revert-disabled=\{[\s\S]*?!session\.revert\(\)/) }) }) diff --git a/packages/kilo-vscode/tests/unit/review-comments.test.ts b/packages/kilo-vscode/tests/unit/review-comments.test.ts index 7e40570bf5..9d0d6fff48 100644 --- a/packages/kilo-vscode/tests/unit/review-comments.test.ts +++ b/packages/kilo-vscode/tests/unit/review-comments.test.ts @@ -12,6 +12,7 @@ import { buildFileAnnotations, clearReviewComposer, createReviewComposer, + labels, reviewAnnotationSpeechKey, reviewComposerDraft, reviewComposerEdit, @@ -441,3 +442,19 @@ describe("getFilename", () => { expect(getFilename("src/components/Button.tsx")).toBe("Button.tsx") }) }) + +it("shares review action labels and translates line numbers", () => { + const value = labels((key, params) => (params ? `${key}:${params.line}` : key)) + expect(value).toMatchObject({ + placeholder: "agentManager.review.commentPlaceholder", + cancel: "common.cancel", + comment: "agentManager.review.commentAction", + send: "prompt.action.send", + save: "common.save", + sendToChat: "agentManager.review.sendToChat", + edit: "common.edit", + delete: "common.delete", + }) + expect(value.commentOnLine(3)).toBe("agentManager.review.commentOnLine:3") + expect(value.editCommentOnLine(7)).toBe("agentManager.review.editCommentOnLine:7") +}) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx index 5c6ceb30bb..49cb6875c7 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/DiffPanel.tsx @@ -48,7 +48,7 @@ import { reviewDraftSpeechKey, reviewEditSpeechKey, sendReviewComments, - type AnnotationLabels, + labels, type AnnotationMeta, type ReviewComposer, type ReviewDraft, @@ -130,18 +130,6 @@ export const DiffPanel: Component = (props) => { const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent) const sendAllKeybind = () => isMac ? t("agentManager.review.sendAllShortcut.mac") : t("agentManager.review.sendAllShortcut.other") - const labels = (): AnnotationLabels => ({ - commentOnLine: (line) => t("agentManager.review.commentOnLine", { line }), - editCommentOnLine: (line) => t("agentManager.review.editCommentOnLine", { line }), - placeholder: t("agentManager.review.commentPlaceholder"), - cancel: t("common.cancel"), - comment: t("agentManager.review.commentAction"), - send: t("prompt.action.send"), - save: t("common.save"), - sendToChat: t("agentManager.review.sendToChat"), - edit: t("common.edit"), - delete: t("common.delete"), - }) const localComposer = createReviewComposer() const composer = () => props.composer ?? localComposer const [manualOpen, setManualOpen] = createSignal>({}) @@ -437,7 +425,7 @@ export const DiffPanel: Component = (props) => { updateComment, deleteComment, cancelDraft, - labels: labels(), + labels: labels(t), activeTerminalId: props.activeTerminalId, speech: reviewSpeech, }) @@ -465,16 +453,7 @@ export const DiffPanel: Component = (props) => { const sendAllToChat = () => { const all = comments() if (all.length === 0) return - window.dispatchEvent( - new MessageEvent("message", { - data: { - type: props.activeTerminalId ? "appendReviewCommentsToTerminal" : "appendReviewComments", - comments: all, - autoSend: true, - targetTerminalId: props.activeTerminalId, - }, - }), - ) + sendReviewComments(all, props.activeTerminalId) preserveScroll(() => setComments([])) props.onSendAll?.() } diff --git a/packages/kilo-vscode/webview-ui/agent-manager/ProjectActions.tsx b/packages/kilo-vscode/webview-ui/agent-manager/ProjectActions.tsx index 210e77c1af..7081971921 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/ProjectActions.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/ProjectActions.tsx @@ -8,7 +8,7 @@ import { TooltipKeybind } from "@kilocode/kilo-ui/tooltip" import type { LanguageContextValue } from "../src/context/language" import { parseBindingTokens } from "./keybind-tokens" -interface Props { +export interface WorktreeCreateProps { branch: string bindings: Record loaded: boolean @@ -16,59 +16,62 @@ interface Props { onCreate: () => void onNew: () => void onSection: () => void - onSettings: () => void } -export const ProjectActions: Component = (props) => ( -
-
- = (props) => ( +
+ + + + + - - - - - - - - - - + + + + - - - - {props.t("agentManager.worktree.newSection")} - - - - -
+ + + {parseBindingTokens(props.bindings.quickWorktree ?? "").map((token) => ( + {token} + ))} + + + + + + {props.t("agentManager.worktree.newSection")} + + + + +
+) + +export const ProjectActions: Component void }> = (props) => ( +
+ current: Accessor - bindings: Record - branch: string git: boolean - loaded: boolean - t: LanguageContextValue["t"] onRef: (ref: SidebarSearchMenuRef) => void onSelect: (item: SidebarSearchItem) => void - onCreate: () => void - onNew: () => void - onSection: () => void onShortcuts: () => void onSettings: () => void onHistory: () => void @@ -47,54 +37,7 @@ export const WorktreeSectionActions: Component = (p onSelect={props.onSelect} /> -
- - - - - - - - - - - - - - - {props.t("agentManager.worktree.newSection")} - - - - -
+ = (props) => const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent) const sendAllKeybind = () => isMac ? t("agentManager.review.sendAllShortcut.mac") : t("agentManager.review.sendAllShortcut.other") - const labels = (): AnnotationLabels => ({ - commentOnLine: (line) => t("agentManager.review.commentOnLine", { line }), - editCommentOnLine: (line) => t("agentManager.review.editCommentOnLine", { line }), - placeholder: t("agentManager.review.commentPlaceholder"), - cancel: t("common.cancel"), - comment: t("agentManager.review.commentAction"), - send: t("prompt.action.send"), - save: t("common.save"), - sendToChat: t("agentManager.review.sendToChat"), - edit: t("common.edit"), - delete: t("common.delete"), - }) const localComposer = createReviewComposer() const composer = () => props.composer ?? localComposer const [manualOpen, setManualOpen] = createSignal>({}) @@ -437,7 +425,7 @@ export const FullScreenDiffView: Component = (props) => updateComment, deleteComment, cancelDraft, - labels: labels(), + labels: labels(t), activeTerminalId: props.activeTerminalId, speech: reviewSpeech, }) @@ -458,16 +446,7 @@ export const FullScreenDiffView: Component = (props) => const sendAllToChat = () => { const all = comments() if (all.length === 0) return - window.dispatchEvent( - new MessageEvent("message", { - data: { - type: props.activeTerminalId ? "appendReviewCommentsToTerminal" : "appendReviewComments", - comments: all, - autoSend: true, - targetTerminalId: props.activeTerminalId, - }, - }), - ) + sendReviewComments(all, props.activeTerminalId) preserveScroll(() => setComments([])) props.onSendAll?.() } diff --git a/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts b/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts index 27df2ab35c..e5b3e90de9 100644 --- a/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts +++ b/packages/kilo-vscode/webview-ui/diff-viewer/review-annotations.ts @@ -16,6 +16,21 @@ export interface AnnotationLabels { delete: string } +export function labels(t: (key: string, params?: Record) => string): AnnotationLabels { + return { + commentOnLine: (line) => t("agentManager.review.commentOnLine", { line }), + editCommentOnLine: (line) => t("agentManager.review.editCommentOnLine", { line }), + placeholder: t("agentManager.review.commentPlaceholder"), + cancel: t("common.cancel"), + comment: t("agentManager.review.commentAction"), + send: t("prompt.action.send"), + save: t("common.save"), + sendToChat: t("agentManager.review.sendToChat"), + edit: t("common.edit"), + delete: t("common.delete"), + } +} + // A draft is the active unsaved inline comment composer opened from the gutter. // It becomes a normal comment only after the user submits the textarea. export interface AnnotationMeta { diff --git a/packages/kilo-vscode/webview-ui/documents/DocumentPanel.tsx b/packages/kilo-vscode/webview-ui/documents/DocumentPanel.tsx index c3dfcf0a17..771e744b43 100644 --- a/packages/kilo-vscode/webview-ui/documents/DocumentPanel.tsx +++ b/packages/kilo-vscode/webview-ui/documents/DocumentPanel.tsx @@ -18,12 +18,12 @@ import { buildReviewAnnotation, createReviewComposer, sendReviewComments, - type AnnotationLabels, + labels, type AnnotationMeta, type ReviewComposer, type ReviewDraft, } from "../diff-viewer/review-annotations" -import { lineCount } from "../diff-viewer/review-comments" +import { getFilename, lineCount } from "../diff-viewer/review-comments" import { useLanguage } from "../src/context/language" export interface DocumentPanelProps { @@ -43,10 +43,6 @@ export interface DocumentPanelProps { visible: Accessor } -function pathName(file: string): string { - return file.slice(file.lastIndexOf("/") + 1) -} - function virtualDiff(file: string, content: string): WorktreeFileDiff { return { file, @@ -98,18 +94,6 @@ export const DocumentPanel: Component = (props) => { const file = () => selected()?.file ?? "" const content = () => data()?.content ?? "" const diff = () => virtualDiff(file(), content()) - const labels = (): AnnotationLabels => ({ - commentOnLine: (line) => t("agentManager.review.commentOnLine", { line }), - editCommentOnLine: (line) => t("agentManager.review.editCommentOnLine", { line }), - placeholder: t("agentManager.review.commentPlaceholder"), - cancel: t("common.cancel"), - comment: t("agentManager.review.commentAction"), - send: t("prompt.action.send"), - save: t("common.save"), - sendToChat: t("agentManager.review.sendToChat"), - edit: t("common.edit"), - delete: t("common.delete"), - }) const updateComments = (next: ReviewComment[]) => props.onCommentsChange(next) const comments = () => props.comments.filter((item) => item.file === file()) @@ -176,7 +160,7 @@ export const DocumentPanel: Component = (props) => { updateComment, deleteComment, cancelDraft, - labels: labels(), + labels: labels(t), activeTerminalId: props.activeTerminalId, }) const gutter = (range: SelectedLineRange) => { @@ -293,7 +277,7 @@ export const DocumentPanel: Component = (props) => { } diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx index 0e6a779897..234a7d6c76 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx @@ -3,9 +3,6 @@ /** * MessageList component * Scrollable turn-based message list with virtualization. - * Each user message is rendered as a VscodeSessionTurn — a custom component that - * renders all assistant parts as a flat, verbose list with no context grouping, - * and fully expands sub-agent (task tool) parts inline. * Shows recent sessions in the empty state for quick resumption. */ diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx deleted file mode 100644 index 96362f1bd5..0000000000 --- a/packages/kilo-vscode/webview-ui/src/components/chat/VscodeSessionTurn.tsx +++ /dev/null @@ -1,210 +0,0 @@ -/** - * VscodeSessionTurn component - * Custom replacement for the upstream SessionTurn, designed for the VS Code sidebar. - * - * Key differences from upstream SessionTurn: - * - No "Gathered context" grouping — each tool call is rendered individually - * - Sub-agents are fully expanded inline via TaskToolExpanded - * - No per-turn auto-scroll (MessageList handles it) - * - Simpler flat structure without overflow containers - */ - -import { Component, createMemo, For, Show, createEffect } from "solid-js" -import { UserMessageDisplay } from "@kilocode/kilo-ui/message-part" -import { DiffChanges } from "@kilocode/kilo-ui/diff-changes" -import { Icon } from "@kilocode/kilo-ui/icon" -import { useData } from "@kilocode/kilo-ui/context/data" -import { useI18n } from "@kilocode/kilo-ui/context/i18n" -import { AssistantMessage } from "./AssistantMessage" -import type { - AssistantMessage as SDKAssistantMessage, - Message as SDKMessage, - Part as SDKPart, - SnapshotFileDiff, -} from "@kilocode/sdk/v2" -import { ErrorDisplay } from "./ErrorDisplay" -import { useServer } from "../../context/server" -import { useSession } from "../../context/session" -import { useLanguage } from "../../context/language" -import { useVSCode } from "../../context/vscode" -import { useFeedback } from "../../context/feedback" -import { visibleError } from "../../context/session-errors" -import type { ErrorDisplayProps } from "./ErrorDisplay" -import type { Message as WebMessage } from "../../types/messages" - -export interface VscodeTurn { - id: string - user: WebMessage - assistant: WebMessage[] - partial?: boolean -} - -interface VscodeSessionTurnProps { - turn: VscodeTurn - queued?: boolean - onForkMessage?: (sessionId: string, messageId: string) => void -} - -export const VscodeSessionTurn: Component = (props) => { - const data = useData() - const i18n = useI18n() - const server = useServer() - const session = useSession() - const language = useLanguage() - const vscode = useVSCode() - const feedback = useFeedback() - - const emptyParts: SDKPart[] = [] - const emptyDiffs: SnapshotFileDiff[] = [] - - createEffect(() => { - const turn = props.turn - const ids = turn.partial ? turn.assistant.map((m) => m.id) : [turn.user.id, ...turn.assistant.map((m) => m.id)] - session.hydrateParts(ids) - }) - - const message = createMemo(() => props.turn.user as SDKMessage & { role: "user" }) - - const parts = createMemo(() => { - const msg = message() - return (data.store.part?.[msg.id] ?? emptyParts) as SDKPart[] - }) - - const assistantMessages = createMemo(() => props.turn.assistant as SDKAssistantMessage[]) - - const interrupted = createMemo(() => assistantMessages().some((m) => m.error?.name === "MessageAbortedError")) - - const error = createMemo(() => visibleError(assistantMessages(), session.isErrorHidden)) - - // Diffs from message summary - const diffs = createMemo(() => { - const rawDiffs = (message() as unknown as { summary?: { diffs?: unknown[] } } | undefined)?.summary?.diffs - if (!rawDiffs?.length) return emptyDiffs - const seen = new Set() - return (rawDiffs as SnapshotFileDiff[]) - .reduceRight((result, diff) => { - const file = diff.file ?? "" - if (seen.has(file)) return result - seen.add(file) - result.push(diff) - return result - }, []) - .reverse() - }) - - const openChanges = () => vscode.postMessage({ type: "openChanges", turnId: message().id }) - - // Copy part ID — the last text part from the last assistant message. - // Synthetic parts (e.g. "Initializing snapshot…" from the slow-repo guard) - // are transient status lines, not assistant output: they must never win - // this lookup, otherwise the copy button renders beside the spinner - // instead of the real response. - const showAssistantCopyPartID = createMemo(() => { - const msgs = assistantMessages() - for (let i = msgs.length - 1; i >= 0; i--) { - const msg = msgs[i] - if (!msg) continue - const msgParts = (data.store.part?.[msg.id] ?? emptyParts) as SDKPart[] - for (let j = msgParts.length - 1; j >= 0; j--) { - const part = msgParts[j] - if (!part || part.type !== "text") continue - if ((part as SDKPart & { synthetic?: boolean }).synthetic) continue - if ((part as SDKPart & { text: string }).text?.trim()) return part.id - } - } - return undefined - }) - - return ( - - {(msg) => ( -
- {/* User message */} - -
0 && session.status() !== "idle" ? "" : undefined} - title={ - assistantMessages().length > 0 && session.status() !== "idle" - ? language.t("revert.disabled.agentBusy") - : undefined - } - > - [0]["message"]} - parts={parts() as unknown as Parameters[0]["parts"]} - interrupted={interrupted()} - queued={props.queued} - onFork={props.onForkMessage ? () => props.onForkMessage?.(msg().sessionID, msg().id) : undefined} - onRevert={ - assistantMessages().length > 0 - ? () => { - if (session.status() !== "idle") return - session.revertSession(msg().id) - } - : undefined - } - /> -
-
- - {/* Assistant parts — flat list, no context grouping */} - 0}> -
- - {(amsg) => ( - - feedback.rate({ - messageID: amsg.id, - sessionID: amsg.sessionID, - parentMessageID: amsg.parentID, - providerID: amsg.providerID, - modelID: amsg.modelID, - variant: (amsg as SDKAssistantMessage & { variant?: string }).variant, - next, - }), - }} - /> - )} - -
-
- - {/* Diff summary — shown after completion. Click opens the changes view. */} - 0 && server.gitInstalled()}> -
- -
-
- - {/* Error handling */} - - {(err) => } - -
- )} -
- ) -} diff --git a/packages/kilo-vscode/webview-ui/src/context/session.tsx b/packages/kilo-vscode/webview-ui/src/context/session.tsx index 74849e4c60..87c099e6f8 100644 --- a/packages/kilo-vscode/webview-ui/src/context/session.tsx +++ b/packages/kilo-vscode/webview-ui/src/context/session.tsx @@ -166,7 +166,6 @@ interface SessionContextValue { isErrorHidden: (messageID: string) => boolean // Move stashed parts into the reactive store for the given message IDs. - // Called by VscodeSessionTurn when the virtualizer renders a turn. hydrateParts: (messageIDs: string[]) => void // Todos for current session @@ -363,7 +362,7 @@ export const SessionProvider: ParentComponent = (props) => { const [pages, setPages] = createStore>({}) // Parts stash: holds parts from messagesLoaded outside the reactive store - // until a VscodeSessionTurn is rendered by the virtualizer and calls + // until a TranscriptRowView is rendered by the virtualizer and calls // hydrateParts(). This avoids writing parts for off-screen messages into // the store, which would trigger expensive DOM work for invisible content. const stash = new PartStash() diff --git a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx index ce66c7495a..345a43ba69 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx @@ -11,7 +11,10 @@ import type { Meta, StoryObj } from "storybook-solidjs-vite" import type { AssistantMessage as SDKAssistantMessage, ReasoningPart, TextPart, ToolPart } from "@kilocode/sdk/v2" import { StoryProviders, defaultMockData, mockSessionValue } from "./StoryProviders" import { AssistantMessage } from "../components/chat/AssistantMessage" -import { VscodeSessionTurn } from "../components/chat/VscodeSessionTurn" +import { For } from "solid-js" +import { TranscriptRowView } from "../components/chat/TranscriptRow" +import { messageTurns } from "../context/session-queue" +import { transcriptRows } from "../context/transcript-rows" import { ChatView } from "../components/chat/ChatView" import { Part } from "@kilocode/kilo-ui/message-part" import { registerVscodeToolOverrides } from "../components/chat/VscodeToolOverrides" @@ -1380,20 +1383,28 @@ export const DiffSummaryCollapsed: Story = { { id: USER_MSG_ID, sessionID: SESSION_ID, - role: "user", + role: "user" as const, + createdAt: new Date(now - 10000).toISOString(), time: { created: now - 10000 }, summary: { diffs: mockDiffs }, }, - { ...baseAssistantMessage, parentID: USER_MSG_ID }, + { ...baseAssistantMessage, parentID: USER_MSG_ID, createdAt: new Date(now - 9000).toISOString() }, ], }, part: { [USER_MSG_ID]: [ - { id: "part-user-text", sessionID: SESSION_ID, messageID: USER_MSG_ID, type: "text", text: "Fix the bug" }, + { + id: "part-user-text", + sessionID: SESSION_ID, + messageID: USER_MSG_ID, + type: "text" as const, + text: "Fix the bug", + }, ], [ASST_MSG_ID]: [textPart], }, } + const parts = new Map(Object.entries(data.part)) const session = { ...mockSessionValue({ id: SESSION_ID, status: "idle" }), messages: () => data.message[SESSION_ID], @@ -1419,13 +1430,9 @@ export const DiffSummaryCollapsed: Story = {
- + parts.get(id) ?? [])}> + {(row) => } +