From bb759287495fabc1f3fa7e0fbecff13ab4d41cb2 Mon Sep 17 00:00:00 2001 From: Johnny Eric Amancio Date: Thu, 16 Jul 2026 18:16:10 +0200 Subject: [PATCH] fix(vscode): group context controls in task header and use distinct icons (#12287) * fix(vscode): group context controls in task header and use distinct icons * chore: update kilo-vscode visual regression baselines --------- Co-authored-by: kilo-maintainer[bot] --- .changeset/context-icons-task-header.md | 6 + ...-header-with-memory-200-chromium-linux.png | 3 + ...task-header-with-memory-chromium-linux.png | 4 +- .../task-header-with-todos-chromium-linux.png | 4 +- packages/kilo-ui/src/components/icon.tsx | 4 + .../src/components/chat/TaskHeader.tsx | 179 +++++++++--------- .../src/components/settings/Settings.tsx | 2 +- .../webview-ui/src/stories/chat.stories.tsx | 55 +++--- .../webview-ui/src/styles/task-header.css | 76 ++++++-- 9 files changed, 200 insertions(+), 133 deletions(-) create mode 100644 .changeset/context-icons-task-header.md create mode 100644 packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-200-chromium-linux.png diff --git a/.changeset/context-icons-task-header.md b/.changeset/context-icons-task-header.md new file mode 100644 index 0000000000..5db8c182ff --- /dev/null +++ b/.changeset/context-icons-task-header.md @@ -0,0 +1,6 @@ +--- +"@kilocode/kilo-ui": patch +"kilo-code": patch +--- + +Use distinct icons for context, project memory, and code indexing, and group context controls to preserve task titles in narrow VS Code sidebars. diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-200-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-200-chromium-linux.png new file mode 100644 index 0000000000..f7283e81eb --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-200-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a89d1a9a31f7de1780d772b7caf71d96f0b4b895df954c77dcd508a7febe7c9 +size 1950 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-chromium-linux.png index 60adb8adf7..ca5db9f648 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-memory-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a864b6a5c0e88bc00292f8a38685acdf2ecdd9eb5d880a663ba830152b7280b -size 3523 +oid sha256:431a0c12cb844b5d4e535cc4c7bf5546fd9e66a178b8023b00978d07c291a531 +size 3919 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png index 3c28f10cc0..5fda873115 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/task-header-with-todos-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08f1498ef61670dfec83a2de45f1b9d7008c6c9987705a39175eb990182ee5c2 -size 6156 +oid sha256:f68544cdf994abca3004e652911aa8edd77cf2bb3f91678e5dc6210022dff2f9 +size 6188 diff --git a/packages/kilo-ui/src/components/icon.tsx b/packages/kilo-ui/src/components/icon.tsx index 34e71420cc..8509d5a223 100644 --- a/packages/kilo-ui/src/components/icon.tsx +++ b/packages/kilo-ui/src/components/icon.tsx @@ -3,6 +3,10 @@ import { splitProps } from "solid-js" const icons: Record = { memory: { + viewBox: "0 0 24 24", + path: ``, + }, + database: { viewBox: "0 0 24 24", path: ``, }, diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx index 5737bfbcd9..f7f0529fa6 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx @@ -122,13 +122,6 @@ export const TaskHeader: Component = (props) => { : []), ] }) - const activitySummary = createMemo(() => { - if (memory.error()) return memory.error()! - if (!memory.enabled()) return language.t("chat.memory.project.disabled") - const lines = activityLines() - if (lines.length === 0) return language.t("chat.memory.activity.idle") - return [language.t("chat.memory.status.active"), ...lines].join(" · ") - }) const activityItems = createMemo(() => activity() .flatMap((item) => { @@ -157,6 +150,8 @@ export const TaskHeader: Component = (props) => { ) const activityTooltip = () => ( <> +
{language.t("settings.context.title")}
+
{memoryStatus()}
{activitySummaryView()} 0}>
@@ -318,107 +313,117 @@ export const TaskHeader: Component = (props) => { - + } > -
-
{memoryStatus()}
- {activitySummaryView()} - +
+
{language.t("settings.context.title")}
+ +
+
+ + {language.t("settings.context.compaction.title")} +
+
- - } - > -
- - - - - -
-
- {language.t("chat.memory.verbose")} - memory.verbose(next ? "on" : "off")} - > - {language.t("chat.memory.verbose")} - -
+
+
+
+
+ + {language.t("settings.context.memory.title")} +
+
{memoryStatus()}
+ {activitySummaryView()} +
+ memory.enable()} + > + {language.t("chat.memory.enable")} + + } + > + + + + + + +
+ +
+ {language.t("chat.memory.verbose")} + memory.verbose(next ? "on" : "off")} + > + {language.t("chat.memory.verbose")} + +
+
+
- - - session.compact()} - aria-label={language.t("command.session.compact")} - /> - - = (props) => { - + {language.t("settings.indexing.title")} diff --git a/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx index d950a3e752..f97d6fe945 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx @@ -1037,31 +1037,40 @@ const mockMemory: MemoryContextValue = { forget: () => {}, } +const memoryHeader = (width: string) => { + const session = { + ...mockSessionValue({ id: SESSION_ID, status: "idle" }), + messages: () => [{ id: "msg-001" }] as any[], + contextUsage: () => ({ tokens: 34300, percentage: 17 }), + costBreakdown: () => [{ label: "Session", cost: 0.64 }], + currentSession: () => ({ + id: SESSION_ID, + title: "Integrate project memory", + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }), + } + return ( + + + +
+ +
+
+
+
+ ) +} + export const TaskHeaderWithMemory: Story = { name: "TaskHeader — with memory enabled", - render: () => { - const session = { - ...mockSessionValue({ id: SESSION_ID, status: "idle" }), - messages: () => [{ id: "msg-001" }] as any[], - currentSession: () => ({ - id: SESSION_ID, - title: "Integrate project memory", - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - }), - } - return ( - - - -
- -
-
-
-
- ) - }, + render: () => memoryHeader("380px"), +} + +export const TaskHeaderWithMemory200: Story = { + name: "TaskHeader — with memory enabled 200", + render: () => memoryHeader("200px"), } const usageTokens = { input: 25_900_000, output: 52_000, reasoning: 4_100, cache: { read: 10_500_000, write: 80_000 } } diff --git a/packages/kilo-vscode/webview-ui/src/styles/task-header.css b/packages/kilo-vscode/webview-ui/src/styles/task-header.css index 5d190a81ef..e6097cd989 100644 --- a/packages/kilo-vscode/webview-ui/src/styles/task-header.css +++ b/packages/kilo-vscode/webview-ui/src/styles/task-header.css @@ -50,6 +50,12 @@ white-space: nowrap; } +@media (max-width: 360px) { + [data-component="task-header"] { + padding-inline: 8px; + } +} + /* ============================================ Task Header Todos ============================================ */ @@ -467,7 +473,7 @@ font-variant-numeric: tabular-nums; } -.task-header-memory-trigger { +.task-header-context-trigger { all: unset; position: relative; display: inline-flex; @@ -478,18 +484,10 @@ border-radius: 3px; color: var(--vscode-foreground); cursor: pointer; - opacity: 0.4; - transition: opacity 0.15s ease; } -.task-header-memory-trigger--enabled { - color: var(--vscode-foreground); - opacity: 1; -} - -.task-header-memory-trigger:hover { +.task-header-context-trigger:hover { background: var(--vscode-toolbar-hoverBackground); - opacity: 1; } [data-slot="task-header-memory-dot"] { @@ -502,7 +500,7 @@ background: var(--vscode-testing-iconPassed, #73c991); } -.task-header-memory-popover { +.task-header-context-popover { width: min(280px, calc(100vw - 16px)); max-width: calc(100vw - 16px); white-space: normal; @@ -515,20 +513,62 @@ overflow-wrap: break-word; } -[data-slot="task-header-memory-menu"] { +[data-slot="task-header-context-tooltip-title"] { + margin-bottom: 4px; + color: var(--vscode-foreground); + font-weight: 600; +} + +[data-slot="task-header-context-tooltip-status"] { + margin-bottom: 2px; + color: var(--vscode-foreground); +} + +[data-slot="task-header-context-menu"] { display: flex; flex-direction: column; - gap: 8px; padding: 8px; } +[data-slot="task-header-context-title"] { + padding: 2px 4px 8px; + color: var(--vscode-foreground); + font-size: var(--kilo-font-size-12); + font-weight: 600; +} + +[data-slot="task-header-context-section"] { + display: flex; + flex-direction: column; + gap: 6px; + padding: 6px 0; +} + +[data-slot="task-header-context-section"] + [data-slot="task-header-context-section"] { + margin-top: 6px; + padding-top: 12px; + border-top: 1px solid var(--vscode-widget-border, var(--vscode-editorWidget-border)); +} + +[data-slot="task-header-context-section-title"] { + display: flex; + align-items: center; + gap: 4px; + padding: 0 4px; + color: var(--vscode-descriptionForeground); + font-size: var(--kilo-font-size-11); + font-weight: 600; +} + [data-slot="task-header-memory-status"] { + padding: 0 4px; color: var(--vscode-foreground); font-size: var(--kilo-font-size-11); } [data-slot="task-header-memory-activity"] { min-width: 0; + padding: 0 4px; color: var(--vscode-descriptionForeground); font-size: var(--kilo-font-size-11); white-space: normal; @@ -558,13 +598,13 @@ overflow-wrap: break-word; } -[data-slot="task-header-memory-actions"] { +[data-slot="task-header-context-actions"] { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; } -[data-slot="task-header-memory-action"] { +[data-slot="task-header-context-action"] { border: 0; border-radius: 3px; padding: 4px 6px; @@ -576,15 +616,15 @@ cursor: pointer; } -[data-slot="task-header-memory-action"]:last-child:nth-child(odd) { +[data-slot="task-header-context-action"]:last-child:nth-child(odd) { grid-column: 1 / -1; } -[data-slot="task-header-memory-action"]:hover:not(:disabled) { +[data-slot="task-header-context-action"]:hover:not(:disabled) { background: var(--vscode-list-hoverBackground); } -[data-slot="task-header-memory-action"]:disabled { +[data-slot="task-header-context-action"]:disabled { color: var(--vscode-disabledForeground); cursor: default; }