From a200e8b1663c0e1690fc1bc29c9690d0c9ab809b Mon Sep 17 00:00:00 2001 From: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Date: Tue, 10 Mar 2026 14:43:53 -0700 Subject: [PATCH] ai-customizations: improve list visual scannability (#300551) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ai-customizations: improve list visual scannability (#299211) - Add type-specific icon to each list item (agent, skill, instructions, prompt, hook) - Format item names: convert dashes/underscores to spaces and apply title case - Truncate descriptions to first sentence (max 120 chars fallback) to reduce visual noise - Make item name font-weight 500 so titles pop against secondary text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: add type icon + name/description polish for MCP servers and plugins (#299211) - Export formatDisplayName and truncateToFirstSentence helpers from aiCustomizationListWidget - Add mcpServerIcon to McpServerItemRenderer (local + builtin items) - Add pluginIcon to PluginInstalledItemRenderer - Apply formatDisplayName (dash/underscore → spaces, title case) to names - Apply truncateToFirstSentence to descriptions - Set font-weight: 500 on mcp-server-name to match AI customization list style - Remove left-indent padding on mcp-server-item now that the icon fills that space Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: mute group count badges (#299211) Replace badge-background/foreground pill styling with plain descriptionForeground text (opacity 0.8) on both the group-header count and the sidebar section count. This lets the section label dominate visually. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: restore badge pill with reduced opacity (#299211) Keep badge-background/foreground colors but apply opacity: 0.6 so the pill is still visible but clearly secondary to the section label. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: use keybindingLabel tokens for count badges (#299211) Switch from badge-background (bright accent) to keybindingLabel-background/ foreground/border tokens, which are designed for subtle inline labels. No opacity hacks needed — the color itself is naturally muted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: use list.inactiveSelection tokens for count badges (#299211) Switch to list.inactiveSelectionBackground/Foreground — the semantically closest tokens for a secondary/muted count pill in a list/tree context. No opacity hacks needed and the name directly reflects the role. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: strip trailing .md from display names (#299211) formatDisplayName now strips a case-insensitive .md suffix before applying the title-case transform, so 'my-file.Md' no longer appears as a title. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: remove explicit font-weight from item titles (#299211) Drop the font-weight: 500 on item-name and mcp-server-name. The visual hierarchy is already established by the 13px full-foreground title vs the 11px muted descriptionForeground description below it, without needing an explicit weight bump. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: use star icon for built-in MCP server items (#299211) Built-in MCP items now show builtinIcon (star) instead of mcpServerIcon, consistent with the prompts built-in group. Icon is now set per-element in renderElement so the two item types can show different icons. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert "ai-customizations: use star icon for built-in MCP server items (#299211)" This reverts commit 6b08675a22a29dc8c36834232b46a0ace42a29a3. * ai-customizations: use star icon for Built-in MCP group header (#299211) Change the Built-in group header icon from extensionIcon to builtinIcon (starFull), consistent with the Built-in group in the prompts list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: remove unused extensionIcon import from mcpListWidget (#299211) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * prompts: add create-pr prompt with compile-check reminder Ensures the TypeScript compile check is run before opening a PR, catching unused import and type errors that tsgo would flag in CI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ai-customizations: fix IMatch highlight positions for formatted names (#299211) nameMatches are now computed against formatDisplayName(item.name) in filterItems so highlight positions align with the displayed string. The .md stripping in formatDisplayName changes string length, so matches against the raw name would produce incorrect highlight spans. Also removed the outdated '1:1 transformation' claim from the JSDoc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../aiCustomizationListWidget.ts | 62 +++++++++++++++++-- .../browser/aiCustomization/mcpListWidget.ts | 19 +++--- .../media/aiCustomizationManagement.css | 24 ++++--- .../aiCustomization/pluginListWidget.ts | 11 +++- 4 files changed, 94 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts index 2ae76f14240..96873795ec8 100644 --- a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationListWidget.ts @@ -115,6 +115,7 @@ class AICustomizationListDelegate implements IListVirtualDelegate { interface IAICustomizationItemTemplateData { readonly container: HTMLElement; readonly actionsContainer: HTMLElement; + readonly typeIcon: HTMLElement; readonly nameLabel: HighlightedLabel; readonly description: HighlightedLabel; readonly disposables: DisposableStore; @@ -194,6 +195,47 @@ class GroupHeaderRenderer implements IListRenderer c.toUpperCase()); +} + +/** + * Truncates a description string to the first sentence, with a maximum character fallback. + */ +export function truncateToFirstSentence(text: string, maxChars = 120): string { + const match = text.match(/^[^.!?]*[.!?]/); + if (match && match[0].length <= maxChars) { + return match[0]; + } + if (text.length > maxChars) { + return text.substring(0, maxChars).trimEnd() + '\u2026'; + } + return text; +} + /** * Renderer for AI customization list items. */ @@ -212,6 +254,7 @@ class AICustomizationItemRenderer implements IListRenderer { const uriLabel = this.labelService.getUriLabel(element.uri, { relative: false }); @@ -245,11 +293,12 @@ class AICustomizationItemRenderer implements IListRenderer { interface IMcpServerItemTemplateData { readonly container: HTMLElement; + readonly typeIcon: HTMLElement; readonly name: HTMLElement; readonly description: HTMLElement; readonly status: HTMLElement; @@ -113,13 +115,16 @@ class McpServerItemRenderer implements IListRenderer { interface IPluginInstalledItemTemplateData { readonly container: HTMLElement; + readonly typeIcon: HTMLElement; readonly name: HTMLElement; readonly description: HTMLElement; readonly status: HTMLElement; @@ -112,21 +114,24 @@ class PluginInstalledItemRenderer implements IListRenderer