Fix tree selector: proper selectedBg theme color, correct filter logic

- Add selectedBg theme color for active line highlight
- Fix filter modes:
  - no-tools: default minus tool results (still hides label/custom)
  - user-only: just user messages
  - labeled-only: just labeled entries
  - all: everything
- Update theme.md with new color tokens (50 total)
This commit is contained in:
Mario Zechner 2025-12-30 01:45:24 +01:00
parent e7d438b59d
commit ae351257b6
5 changed files with 45 additions and 17 deletions

View file

@ -21,12 +21,16 @@ Every theme must define all color tokens. There are no optional colors.
| `dim` | Very dimmed text | Less important info, placeholders | | `dim` | Very dimmed text | Less important info, placeholders |
| `text` | Default text color | Main content (usually `""`) | | `text` | Default text color | Main content (usually `""`) |
### Backgrounds & Content Text (7 colors) ### Backgrounds & Content Text (11 colors)
| Token | Purpose | | Token | Purpose |
|-------|---------| |-------|---------|
| `selectedBg` | Selected/active line background (e.g., tree selector) |
| `userMessageBg` | User message background | | `userMessageBg` | User message background |
| `userMessageText` | User message text color | | `userMessageText` | User message text color |
| `customMessageBg` | Hook custom message background |
| `customMessageText` | Hook custom message text color |
| `customMessageLabel` | Hook custom message label/type text |
| `toolPendingBg` | Tool execution box (pending state) | | `toolPendingBg` | Tool execution box (pending state) |
| `toolSuccessBg` | Tool execution box (success state) | | `toolSuccessBg` | Tool execution box (success state) |
| `toolErrorBg` | Tool execution box (error state) | | `toolErrorBg` | Tool execution box (error state) |
@ -95,7 +99,7 @@ These create a visual hierarchy: off → minimal → low → medium → high →
|-------|---------| |-------|---------|
| `bashMode` | Editor border color when in bash mode (! prefix) | | `bashMode` | Editor border color when in bash mode (! prefix) |
**Total: 46 color tokens** (all required) **Total: 50 color tokens** (all required)
## Theme Format ## Theme Format

View file

@ -262,18 +262,30 @@ class TreeList implements Component {
// Apply filter mode // Apply filter mode
let passesFilter = true; let passesFilter = true;
if (this.filterMode === "user-only") { switch (this.filterMode) {
passesFilter = case "user-only":
(entry.type === "message" && entry.message.role === "user") || // Just user messages
(entry.type === "custom_message" && entry.display); passesFilter = entry.type === "message" && entry.message.role === "user";
} else if (this.filterMode === "no-tools") { break;
// Hide tool results case "no-tools":
passesFilter = !(entry.type === "message" && entry.message.role === "toolResult"); // Default minus tool results (still hide label/custom entries)
} else if (this.filterMode === "labeled-only") { passesFilter =
passesFilter = flatNode.node.label !== undefined; entry.type !== "label" &&
} else if (this.filterMode !== "all") { entry.type !== "custom" &&
// Default mode: hide label and custom entries !(entry.type === "message" && entry.message.role === "toolResult");
passesFilter = entry.type !== "label" && entry.type !== "custom"; break;
case "labeled-only":
// Just labeled entries
passesFilter = flatNode.node.label !== undefined;
break;
case "all":
// Show everything
passesFilter = true;
break;
default:
// Default mode: hide label and custom entries
passesFilter = entry.type !== "label" && entry.type !== "custom";
break;
} }
if (!passesFilter) return false; if (!passesFilter) return false;
@ -464,7 +476,7 @@ class TreeList implements Component {
let line = cursor + theme.fg("dim", prefix) + pathMarker + label + content; let line = cursor + theme.fg("dim", prefix) + pathMarker + label + content;
if (isSelected) { if (isSelected) {
line = theme.inverse(line); line = theme.bg("selectedBg", line);
} }
lines.push(truncateToWidth(line, width)); lines.push(truncateToWidth(line, width));
} }

View file

@ -11,6 +11,7 @@
"dimGray": "#666666", "dimGray": "#666666",
"darkGray": "#505050", "darkGray": "#505050",
"accent": "#8abeb7", "accent": "#8abeb7",
"selectedBg": "#3a3a4a",
"userMsgBg": "#343541", "userMsgBg": "#343541",
"toolPendingBg": "#282832", "toolPendingBg": "#282832",
"toolSuccessBg": "#283228", "toolSuccessBg": "#283228",
@ -29,6 +30,7 @@
"dim": "dimGray", "dim": "dimGray",
"text": "", "text": "",
"selectedBg": "selectedBg",
"userMessageBg": "userMsgBg", "userMessageBg": "userMsgBg",
"userMessageText": "", "userMessageText": "",
"customMessageBg": "customMsgBg", "customMessageBg": "customMsgBg",

View file

@ -10,6 +10,7 @@
"mediumGray": "#6c6c6c", "mediumGray": "#6c6c6c",
"dimGray": "#8a8a8a", "dimGray": "#8a8a8a",
"lightGray": "#b0b0b0", "lightGray": "#b0b0b0",
"selectedBg": "#d0d0e0",
"userMsgBg": "#e8e8e8", "userMsgBg": "#e8e8e8",
"toolPendingBg": "#e8e8f0", "toolPendingBg": "#e8e8f0",
"toolSuccessBg": "#e8f0e8", "toolSuccessBg": "#e8f0e8",
@ -28,6 +29,7 @@
"dim": "dimGray", "dim": "dimGray",
"text": "", "text": "",
"selectedBg": "selectedBg",
"userMessageBg": "userMsgBg", "userMessageBg": "userMsgBg",
"userMessageText": "", "userMessageText": "",
"customMessageBg": "customMsgBg", "customMessageBg": "customMsgBg",

View file

@ -34,7 +34,8 @@ const ThemeJsonSchema = Type.Object({
muted: ColorValueSchema, muted: ColorValueSchema,
dim: ColorValueSchema, dim: ColorValueSchema,
text: ColorValueSchema, text: ColorValueSchema,
// Backgrounds & Content Text (10 colors) // Backgrounds & Content Text (11 colors)
selectedBg: ColorValueSchema,
userMessageBg: ColorValueSchema, userMessageBg: ColorValueSchema,
userMessageText: ColorValueSchema, userMessageText: ColorValueSchema,
customMessageBg: ColorValueSchema, customMessageBg: ColorValueSchema,
@ -132,7 +133,13 @@ export type ThemeColor =
| "thinkingXhigh" | "thinkingXhigh"
| "bashMode"; | "bashMode";
export type ThemeBg = "userMessageBg" | "customMessageBg" | "toolPendingBg" | "toolSuccessBg" | "toolErrorBg"; export type ThemeBg =
| "selectedBg"
| "userMessageBg"
| "customMessageBg"
| "toolPendingBg"
| "toolSuccessBg"
| "toolErrorBg";
type ColorMode = "truecolor" | "256color"; type ColorMode = "truecolor" | "256color";
@ -488,6 +495,7 @@ function createTheme(themeJson: ThemeJson, mode?: ColorMode): Theme {
const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>; const fgColors: Record<ThemeColor, string | number> = {} as Record<ThemeColor, string | number>;
const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>; const bgColors: Record<ThemeBg, string | number> = {} as Record<ThemeBg, string | number>;
const bgColorKeys: Set<string> = new Set([ const bgColorKeys: Set<string> = new Set([
"selectedBg",
"userMessageBg", "userMessageBg",
"customMessageBg", "customMessageBg",
"toolPendingBg", "toolPendingBg",