feat: map VS Code chat theme colors
This commit is contained in:
@@ -12,6 +12,37 @@ export type VSCodeThemeColorToken =
|
|||||||
| 'editor.selectionForeground'
|
| 'editor.selectionForeground'
|
||||||
| 'editor.lineHighlightBackground'
|
| 'editor.lineHighlightBackground'
|
||||||
| 'editorCursor.foreground'
|
| 'editorCursor.foreground'
|
||||||
|
// Chat
|
||||||
|
| 'interactive-session.foreground'
|
||||||
|
| 'chat.list.background'
|
||||||
|
| 'chat.requestBorder'
|
||||||
|
| 'chat.requestBackground'
|
||||||
|
| 'chat.requestBubbleBackground'
|
||||||
|
| 'chat.requestBubbleHoverBackground'
|
||||||
|
| 'chat.avatarBackground'
|
||||||
|
| 'chat.avatarForeground'
|
||||||
|
| 'chat.slashCommandBackground'
|
||||||
|
| 'chat.slashCommandForeground'
|
||||||
|
| 'chat.editedFileForeground'
|
||||||
|
| 'chat.requestCodeBorder'
|
||||||
|
| 'chat.linesAddedForeground'
|
||||||
|
| 'chat.linesRemovedForeground'
|
||||||
|
| 'chat.thinkingShimmer'
|
||||||
|
| 'chat.inputWorkingBorderColor1'
|
||||||
|
| 'chat.inputWorkingBorderColor2'
|
||||||
|
| 'chat.inputWorkingBorderColor3'
|
||||||
|
| 'textBlockQuote.background'
|
||||||
|
| 'textBlockQuote.border'
|
||||||
|
| 'toolbar.hoverBackground'
|
||||||
|
| 'toolbar.activeBackground'
|
||||||
|
| 'toolbar.hoverOutline'
|
||||||
|
| 'icon.foreground'
|
||||||
|
| 'inputOption.activeForeground'
|
||||||
|
| 'inputOption.activeBorder'
|
||||||
|
| 'inputOption.activeBackground'
|
||||||
|
| 'notificationsWarningIcon.foreground'
|
||||||
|
| 'problemsWarningIcon.foreground'
|
||||||
|
| 'problemsInfoIcon.foreground'
|
||||||
// UI borders and focus
|
// UI borders and focus
|
||||||
| 'focusBorder'
|
| 'focusBorder'
|
||||||
| 'contrastBorder'
|
| 'contrastBorder'
|
||||||
@@ -80,6 +111,7 @@ export type VSCodeThemeColorToken =
|
|||||||
// Preformatted text (code)
|
// Preformatted text (code)
|
||||||
| 'textPreformat.foreground'
|
| 'textPreformat.foreground'
|
||||||
| 'textPreformat.background'
|
| 'textPreformat.background'
|
||||||
|
| 'textPreformat.border'
|
||||||
// Editor widgets
|
// Editor widgets
|
||||||
| 'editorWidget.background'
|
| 'editorWidget.background'
|
||||||
| 'editorWidget.foreground'
|
| 'editorWidget.foreground'
|
||||||
@@ -113,6 +145,37 @@ const VARIABLE_MAP: Record<VSCodeThemeColorToken, string> = {
|
|||||||
'editor.selectionForeground': '--vscode-editor-selectionForeground',
|
'editor.selectionForeground': '--vscode-editor-selectionForeground',
|
||||||
'editor.lineHighlightBackground': '--vscode-editor-lineHighlightBackground',
|
'editor.lineHighlightBackground': '--vscode-editor-lineHighlightBackground',
|
||||||
'editorCursor.foreground': '--vscode-editorCursor-foreground',
|
'editorCursor.foreground': '--vscode-editorCursor-foreground',
|
||||||
|
// Chat
|
||||||
|
'interactive-session.foreground': '--vscode-interactive-session-foreground',
|
||||||
|
'chat.list.background': '--vscode-chat-list-background',
|
||||||
|
'chat.requestBorder': '--vscode-chat-requestBorder',
|
||||||
|
'chat.requestBackground': '--vscode-chat-requestBackground',
|
||||||
|
'chat.requestBubbleBackground': '--vscode-chat-requestBubbleBackground',
|
||||||
|
'chat.requestBubbleHoverBackground': '--vscode-chat-requestBubbleHoverBackground',
|
||||||
|
'chat.avatarBackground': '--vscode-chat-avatarBackground',
|
||||||
|
'chat.avatarForeground': '--vscode-chat-avatarForeground',
|
||||||
|
'chat.slashCommandBackground': '--vscode-chat-slashCommandBackground',
|
||||||
|
'chat.slashCommandForeground': '--vscode-chat-slashCommandForeground',
|
||||||
|
'chat.editedFileForeground': '--vscode-chat-editedFileForeground',
|
||||||
|
'chat.requestCodeBorder': '--vscode-chat-requestCodeBorder',
|
||||||
|
'chat.linesAddedForeground': '--vscode-chat-linesAddedForeground',
|
||||||
|
'chat.linesRemovedForeground': '--vscode-chat-linesRemovedForeground',
|
||||||
|
'chat.thinkingShimmer': '--vscode-chat-thinkingShimmer',
|
||||||
|
'chat.inputWorkingBorderColor1': '--vscode-chat-inputWorkingBorderColor1',
|
||||||
|
'chat.inputWorkingBorderColor2': '--vscode-chat-inputWorkingBorderColor2',
|
||||||
|
'chat.inputWorkingBorderColor3': '--vscode-chat-inputWorkingBorderColor3',
|
||||||
|
'textBlockQuote.background': '--vscode-textBlockQuote-background',
|
||||||
|
'textBlockQuote.border': '--vscode-textBlockQuote-border',
|
||||||
|
'toolbar.hoverBackground': '--vscode-toolbar-hoverBackground',
|
||||||
|
'toolbar.activeBackground': '--vscode-toolbar-activeBackground',
|
||||||
|
'toolbar.hoverOutline': '--vscode-toolbar-hoverOutline',
|
||||||
|
'icon.foreground': '--vscode-icon-foreground',
|
||||||
|
'inputOption.activeForeground': '--vscode-inputOption-activeForeground',
|
||||||
|
'inputOption.activeBorder': '--vscode-inputOption-activeBorder',
|
||||||
|
'inputOption.activeBackground': '--vscode-inputOption-activeBackground',
|
||||||
|
'notificationsWarningIcon.foreground': '--vscode-notificationsWarningIcon-foreground',
|
||||||
|
'problemsWarningIcon.foreground': '--vscode-problemsWarningIcon-foreground',
|
||||||
|
'problemsInfoIcon.foreground': '--vscode-problemsInfoIcon-foreground',
|
||||||
// UI borders and focus
|
// UI borders and focus
|
||||||
focusBorder: '--vscode-focusBorder',
|
focusBorder: '--vscode-focusBorder',
|
||||||
contrastBorder: '--vscode-contrastBorder',
|
contrastBorder: '--vscode-contrastBorder',
|
||||||
@@ -181,6 +244,7 @@ const VARIABLE_MAP: Record<VSCodeThemeColorToken, string> = {
|
|||||||
// Preformat
|
// Preformat
|
||||||
'textPreformat.foreground': '--vscode-textPreformat-foreground',
|
'textPreformat.foreground': '--vscode-textPreformat-foreground',
|
||||||
'textPreformat.background': '--vscode-textPreformat-background',
|
'textPreformat.background': '--vscode-textPreformat-background',
|
||||||
|
'textPreformat.border': '--vscode-textPreformat-border',
|
||||||
// Editor widgets
|
// Editor widgets
|
||||||
'editorWidget.background': '--vscode-editorWidget-background',
|
'editorWidget.background': '--vscode-editorWidget-background',
|
||||||
'editorWidget.foreground': '--vscode-editorWidget-foreground',
|
'editorWidget.foreground': '--vscode-editorWidget-foreground',
|
||||||
@@ -291,18 +355,18 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
// SURFACE COLORS - Layered backgrounds
|
// SURFACE COLORS - Layered backgrounds
|
||||||
// ===========================================
|
// ===========================================
|
||||||
|
|
||||||
// Main app background: sidebar is the outermost container
|
// Main chat background: match VS Code's chat list first, then fall back to shell surfaces.
|
||||||
const background = read('sideBar.background', base.colors.surface.background);
|
const background = read('chat.list.background', read('sideBar.background', base.colors.surface.background));
|
||||||
|
|
||||||
// Main foreground text color
|
// Main foreground text color
|
||||||
const foreground = read('foreground', read('editor.foreground', base.colors.surface.foreground));
|
const foreground = read('interactive-session.foreground', read('foreground', read('editor.foreground', base.colors.surface.foreground)));
|
||||||
|
|
||||||
// Elevated surfaces: panels, cards, dialogs - use editorWidget or panel
|
// Elevated surfaces: panels, cards, dialogs - use editorWidget or panel
|
||||||
const elevated = read('editorWidget.background', read('panel.background', read('editor.background', base.colors.surface.elevated)));
|
const elevated = read('editorWidget.background', read('panel.background', read('editor.background', base.colors.surface.elevated)));
|
||||||
const elevatedForeground = read('editorWidget.foreground', read('panel.foreground', foreground));
|
const elevatedForeground = read('editorWidget.foreground', read('panel.foreground', foreground));
|
||||||
|
|
||||||
// Muted background: used for inactive/deemphasized areas - use list inactive selection
|
// Muted background: used for inactive/deemphasized areas - use list inactive selection
|
||||||
const muted = read('list.inactiveSelectionBackground', read('editor.lineHighlightBackground', base.colors.surface.muted));
|
const muted = read('chat.requestBackground', read('list.inactiveSelectionBackground', read('editor.lineHighlightBackground', base.colors.surface.muted)));
|
||||||
|
|
||||||
// Muted foreground: secondary text - description foreground is perfect semantic match
|
// Muted foreground: secondary text - description foreground is perfect semantic match
|
||||||
const mutedForeground = read('descriptionForeground', read('input.placeholderForeground', base.colors.surface.mutedForeground));
|
const mutedForeground = read('descriptionForeground', read('input.placeholderForeground', base.colors.surface.mutedForeground));
|
||||||
@@ -328,7 +392,8 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
|
|
||||||
// Border: Use widget.border (most generic), then input.border, panel.border
|
// Border: Use widget.border (most generic), then input.border, panel.border
|
||||||
// DO NOT reduce opacity - these are already properly set by VS Code themes
|
// DO NOT reduce opacity - these are already properly set by VS Code themes
|
||||||
const border = read('widget.border', '') ||
|
const border = read('chat.requestBorder', '') ||
|
||||||
|
read('widget.border', '') ||
|
||||||
read('input.border', '') ||
|
read('input.border', '') ||
|
||||||
read('panel.border', '') ||
|
read('panel.border', '') ||
|
||||||
read('sideBar.border', '') ||
|
read('sideBar.border', '') ||
|
||||||
@@ -338,15 +403,15 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
const effectiveBorder = border || applyAlpha(foreground, isDark ? 0.25 : 0.2);
|
const effectiveBorder = border || applyAlpha(foreground, isDark ? 0.25 : 0.2);
|
||||||
|
|
||||||
// Hover/active backgrounds
|
// Hover/active backgrounds
|
||||||
const hoverBg = read('list.hoverBackground', base.colors.interactive.hover);
|
const hoverBg = read('toolbar.hoverBackground', read('chat.requestBubbleHoverBackground', read('list.hoverBackground', base.colors.interactive.hover)));
|
||||||
const activeBg = read('list.activeSelectionBackground', hoverBg);
|
const activeBg = read('toolbar.activeBackground', read('inputOption.activeBackground', read('list.activeSelectionBackground', hoverBg)));
|
||||||
|
|
||||||
// Selection
|
// Selection
|
||||||
const selection = read('editor.selectionBackground', base.colors.interactive.selection);
|
const selection = read('editor.selectionBackground', base.colors.interactive.selection);
|
||||||
const selectionForeground = read('editor.selectionForeground', read('list.activeSelectionForeground', foreground));
|
const selectionForeground = read('editor.selectionForeground', read('list.activeSelectionForeground', foreground));
|
||||||
|
|
||||||
// Focus
|
// Focus
|
||||||
const focus = read('focusBorder', accent);
|
const focus = read('focusBorder', read('inputOption.activeBorder', accent));
|
||||||
const focusRing = applyAlpha(focus, isDark ? 0.45 : 0.35);
|
const focusRing = applyAlpha(focus, isDark ? 0.45 : 0.35);
|
||||||
|
|
||||||
// Cursor
|
// Cursor
|
||||||
@@ -359,13 +424,13 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
const errorColor = read('editorError.foreground', read('testing.iconFailed', base.colors.status.error));
|
const errorColor = read('editorError.foreground', read('testing.iconFailed', base.colors.status.error));
|
||||||
const errorBg = read('editorError.background', applyAlpha(errorColor, isDark ? 0.16 : 0.12));
|
const errorBg = read('editorError.background', applyAlpha(errorColor, isDark ? 0.16 : 0.12));
|
||||||
|
|
||||||
const warningColor = read('editorWarning.foreground', base.colors.status.warning);
|
const warningColor = read('problemsWarningIcon.foreground', read('notificationsWarningIcon.foreground', read('editorWarning.foreground', base.colors.status.warning)));
|
||||||
const warningBg = read('editorWarning.background', applyAlpha(warningColor, isDark ? 0.16 : 0.12));
|
const warningBg = read('editorWarning.background', applyAlpha(warningColor, isDark ? 0.16 : 0.12));
|
||||||
|
|
||||||
const successColor = read('testing.iconPassed', read('gitDecoration.addedResourceForeground', base.colors.status.success));
|
const successColor = read('testing.iconPassed', read('gitDecoration.addedResourceForeground', base.colors.status.success));
|
||||||
const successBg = applyAlpha(successColor, isDark ? 0.16 : 0.12);
|
const successBg = applyAlpha(successColor, isDark ? 0.16 : 0.12);
|
||||||
|
|
||||||
const infoColor = read('editorInfo.foreground', base.colors.status.info);
|
const infoColor = read('problemsInfoIcon.foreground', read('editorInfo.foreground', base.colors.status.info));
|
||||||
const infoBg = read('editorInfo.background', applyAlpha(infoColor, isDark ? 0.16 : 0.12));
|
const infoBg = read('editorInfo.background', applyAlpha(infoColor, isDark ? 0.16 : 0.12));
|
||||||
|
|
||||||
// ===========================================
|
// ===========================================
|
||||||
@@ -385,15 +450,15 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
// ===========================================
|
// ===========================================
|
||||||
|
|
||||||
// Tools border should be visible! Use border directly without extra opacity reduction
|
// Tools border should be visible! Use border directly without extra opacity reduction
|
||||||
const toolsBorder = effectiveBorder;
|
const toolsBorder = read('chat.requestBorder', effectiveBorder);
|
||||||
const toolsBackground = applyAlpha(muted, 0.5);
|
const toolsBackground = read('editor.background', applyAlpha(muted, 0.5));
|
||||||
const toolsHeaderHover = applyAlpha(hoverBg, 0.5);
|
const toolsHeaderHover = read('toolbar.hoverBackground', applyAlpha(hoverBg, 0.5));
|
||||||
|
|
||||||
// Diff colors from VS Code diff editor
|
// Diff colors from VS Code diff editor
|
||||||
const diffAddedBg = read('diffEditor.insertedLineBackground', read('diffEditor.insertedTextBackground', successBg));
|
const diffAddedBg = read('diffEditor.insertedLineBackground', read('diffEditor.insertedTextBackground', successBg));
|
||||||
const diffRemovedBg = read('diffEditor.removedLineBackground', read('diffEditor.removedTextBackground', errorBg));
|
const diffRemovedBg = read('diffEditor.removedLineBackground', read('diffEditor.removedTextBackground', errorBg));
|
||||||
const diffAddedColor = read('gitDecoration.addedResourceForeground', successColor);
|
const diffAddedColor = read('chat.linesAddedForeground', read('gitDecoration.addedResourceForeground', successColor));
|
||||||
const diffRemovedColor = read('gitDecoration.deletedResourceForeground', errorColor);
|
const diffRemovedColor = read('chat.linesRemovedForeground', read('gitDecoration.deletedResourceForeground', errorColor));
|
||||||
const diffModifiedColor = read('gitDecoration.modifiedResourceForeground', infoColor);
|
const diffModifiedColor = read('gitDecoration.modifiedResourceForeground', infoColor);
|
||||||
|
|
||||||
// ===========================================
|
// ===========================================
|
||||||
@@ -408,7 +473,7 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
// ===========================================
|
// ===========================================
|
||||||
|
|
||||||
// User messages: same as chat input (subtle surface)
|
// User messages: same as chat input (subtle surface)
|
||||||
const userMessageBg = subtle;
|
const userMessageBg = read('chat.requestBubbleBackground', read('chat.requestBackground', subtle));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
@@ -444,10 +509,10 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
},
|
},
|
||||||
interactive: {
|
interactive: {
|
||||||
border: effectiveBorder,
|
border: effectiveBorder,
|
||||||
borderHover: effectiveBorder,
|
borderHover: read('toolbar.hoverOutline', effectiveBorder),
|
||||||
borderFocus: focus,
|
borderFocus: focus,
|
||||||
selection,
|
selection,
|
||||||
selectionForeground,
|
selectionForeground: read('inputOption.activeForeground', selectionForeground),
|
||||||
focus,
|
focus,
|
||||||
focusRing,
|
focusRing,
|
||||||
cursor,
|
cursor,
|
||||||
@@ -492,7 +557,7 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
background: toolsBackground,
|
background: toolsBackground,
|
||||||
border: toolsBorder,
|
border: toolsBorder,
|
||||||
headerHover: toolsHeaderHover,
|
headerHover: toolsHeaderHover,
|
||||||
icon: mutedForeground,
|
icon: read('icon.foreground', mutedForeground),
|
||||||
title: foreground,
|
title: foreground,
|
||||||
description: applyAlpha(mutedForeground, 0.8),
|
description: applyAlpha(mutedForeground, 0.8),
|
||||||
edit: {
|
edit: {
|
||||||
@@ -507,12 +572,21 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
},
|
},
|
||||||
// Explicit chat section
|
// Explicit chat section
|
||||||
chat: {
|
chat: {
|
||||||
|
background,
|
||||||
userMessage: foreground,
|
userMessage: foreground,
|
||||||
userMessageBackground: userMessageBg,
|
userMessageBackground: userMessageBg,
|
||||||
assistantMessage: foreground,
|
assistantMessage: foreground,
|
||||||
assistantMessageBackground: background,
|
assistantMessageBackground: background,
|
||||||
timestamp: mutedForeground,
|
timestamp: mutedForeground,
|
||||||
divider: effectiveBorder,
|
divider: effectiveBorder,
|
||||||
|
typing: read('chat.thinkingShimmer', mutedForeground),
|
||||||
|
avatarBackground: read('chat.avatarBackground', background),
|
||||||
|
avatarForeground: read('chat.avatarForeground', foreground),
|
||||||
|
slashCommandBackground: read('chat.slashCommandBackground', accent),
|
||||||
|
slashCommandForeground: read('chat.slashCommandForeground', accentForeground),
|
||||||
|
inputWorkingBorderColor1: read('chat.inputWorkingBorderColor1', accent),
|
||||||
|
inputWorkingBorderColor2: read('chat.inputWorkingBorderColor2', accentHover),
|
||||||
|
inputWorkingBorderColor3: read('chat.inputWorkingBorderColor3', accentMuted),
|
||||||
},
|
},
|
||||||
// Badges
|
// Badges
|
||||||
badges: {
|
badges: {
|
||||||
@@ -531,10 +605,12 @@ export const buildVSCodeThemeFromPalette = (palette: VSCodeThemePalette): Theme
|
|||||||
heading4: foreground,
|
heading4: foreground,
|
||||||
link: accentMuted,
|
link: accentMuted,
|
||||||
linkHover: read('textLink.activeForeground', accentHover),
|
linkHover: read('textLink.activeForeground', accentHover),
|
||||||
inlineCode: syntaxString,
|
inlineCode: read('textPreformat.foreground', syntaxString),
|
||||||
inlineCodeBackground: subtle,
|
inlineCodeBackground: subtle,
|
||||||
blockquote: mutedForeground,
|
inlineCodeBorder: read('textPreformat.border', read('chat.requestCodeBorder', effectiveBorder)),
|
||||||
blockquoteBorder: effectiveBorder,
|
blockquote: foreground,
|
||||||
|
blockquoteBackground: read('textBlockQuote.background', 'transparent'),
|
||||||
|
blockquoteBorder: read('textBlockQuote.border', effectiveBorder),
|
||||||
listMarker: applyAlpha(accent, 0.6),
|
listMarker: applyAlpha(accent, 0.6),
|
||||||
},
|
},
|
||||||
// Scrollbar
|
// Scrollbar
|
||||||
|
|||||||
Reference in New Issue
Block a user