theme-manager
Theme Manager Skill
Specialized skill for updating and maintaining the GitArbor TUI theme system.
Reference Documentation
This skill includes comprehensive reference documentation:
- THEMES.md - User-facing documentation for all themes, usage guide, and theme switching instructions
- THEME_REFERENCE.md - Quick reference chart with theme comparisons and color palettes
- THEME_IMPLEMENTATION.md - Implementation history, technical details, and development summary
When to use this skill
Use this skill when:
- User wants to add a new theme to GitArbor
- User wants to modify an existing theme's colors
- User reports theme-related bugs or inconsistencies
- User asks about theme structure or design tokens
- User wants to update theme documentation
- User mentions specific color schemes (Catppuccin, One Dark, etc.)
- User wants to ensure all components use theme tokens correctly
What this skill does
This skill provides comprehensive guidance for:
- Adding new themes to the theme system
- Modifying existing theme colors
- Validating theme structure and completeness
- Ensuring components use theme tokens (no hardcoded colors)
- Updating theme documentation
- Testing theme changes across the application
- Maintaining theme consistency and quality
Theme System Architecture
Core Files
src/theme.ts- Theme definitions, management functions, and active theme proxyTHEMES.md- User-facing documentation for all themesTHEME_REFERENCE.md- Quick reference chart with color comparisonsTHEME_IMPLEMENTATION.md- Implementation history and technical details~/.gitarborrc- User's theme preference storage
Theme Structure
Every theme must implement the Theme interface:
interface Theme {
name: string // Display name
description: string // Brief description
colors: {
primary: string // Main accent color
primaryDark: string // Darker variant
border: string // Unfocused borders
borderFocused: string // Focused borders
background: {
primary: string // Main background
modal: string // Modal backgrounds
button: string // Button backgrounds
buttonHover: string // Button hover state
}
text: {
primary: string // Main text
secondary: string // Secondary text
muted: string // Muted/disabled
disabled: string // Disabled state
inverted: string // Text on bright bg
}
git: {
staged: string // Staged files (typically green)
modified: string // Modified files (typically yellow)
untracked: string // Untracked files (typically gray/cyan)
deleted: string // Deleted files (typically red)
added: string // Added lines in diff (typically green)
}
status: {
success: string // Success messages (typically green)
error: string // Error messages (typically red)
warning: string // Warning messages (typically yellow)
info: string // Info messages (typically cyan/blue)
}
}
spacing: {
none: number // 0
xs: number // 1
sm: number // 2
md: number // 3
lg: number // 4
xl: number // 5
}
borders: {
style: 'single' // Border style (currently only 'single')
}
}
Adding a New Theme: Step-by-Step
Step 1: Research the color scheme
- Find the official color scheme documentation/repository
- Identify all primary colors used in the scheme
- Note the background colors (for dark/light variants)
- Understand the scheme's design philosophy
Step 2: Create the theme object in src/theme.ts
Add after existing theme definitions, before the themes export:
/**
* Theme Name - Brief description
*/
const themeNameTheme: Theme = {
name: 'Theme Name',
description: 'Brief description of the theme',
colors: {
primary: '#XXXXXX', // Choose the main accent color
primaryDark: '#XXXXXX', // Darker variant (20-30% darker)
border: '#XXXXXX', // Subtle border color
borderFocused: '#XXXXXX', // Use primary or similar
background: {
primary: '#XXXXXX', // Main background
modal: '#XXXXXX', // Slightly different from primary
button: '#XXXXXX', // Button backgrounds
buttonHover: '#XXXXXX', // Lighter/darker on hover
},
text: {
primary: '#XXXXXX', // Main text color
secondary: '#XXXXXX', // Slightly muted
muted: '#XXXXXX', // More muted
disabled: '#XXXXXX', // Even more muted
inverted: '#XXXXXX', // Opposite of background
},
git: {
staged: '#XXXXXX', // Green variant from scheme
modified: '#XXXXXX', // Yellow/orange variant
untracked: '#XXXXXX', // Gray or cyan variant
deleted: '#XXXXXX', // Red variant
added: '#XXXXXX', // Same as staged typically
},
status: {
success: '#XXXXXX', // Same as git.staged typically
error: '#XXXXXX', // Same as git.deleted typically
warning: '#XXXXXX', // Same as git.modified typically
info: '#XXXXXX', // Cyan or blue variant
},
},
spacing: {
none: 0,
xs: 1,
sm: 2,
md: 3,
lg: 4,
xl: 5,
},
borders: {
style: 'single',
},
}
Step 3: Add to themes registry
In the themes export object, add your new theme:
export const themes: Record<string, Theme> = {
// ... existing themes
'theme-id': themeNameTheme,
}
Theme ID naming conventions:
- Use lowercase with hyphens
- Match the popular name (e.g.,
catppuccin-mocha,one-dark) - For variants, include variant name (e.g.,
gruvbox-dark,gruvbox-light)
Step 4: Update THEMES.md
Add to the appropriate section (Dark Themes or Light Themes):
### Dark Themes (or Light Themes)
X. **Theme Name**
- Brief description from official docs
- Primary color: Color name (#XXXXXX)
- Best for: Use case description
Add theme ID to the manual config section:
Available theme IDs:
- `theme-id`
Step 5: Update THEME_REFERENCE.md
Add a row to the theme comparison chart:
| **Theme Name** | Dark/Light | 🎨 Color | 🟢 Color | 🟡 Color | ⬛/⬜ BG | Best For |
Add a color palette section:
### Theme Name
Primary: #XXXXXX (Color name) Staged: #XXXXXX (Green variant) Modified: #XXXXXX (Yellow variant) Untracked: #XXXXXX (Gray/Cyan) Deleted: #XXXXXX (Red variant) Background: #XXXXXX (Background color)
Step 6: Test the theme
-
Run type checking:
bun --bun tsc --noEmit -
Start the application:
bun run start -
Open settings (
,key) → Switch to Themes tab (Tab key) -
Verify your new theme appears in the list
-
Select it and check the preview panel:
- All colors should be visible
- Colors should match your theme definition
- No colors should be missing or default
-
Apply the theme and verify:
- Status view colors (staged, modified, untracked)
- Diff view colors (added, deleted lines)
- Status messages (success, error, warning, info)
- Borders (focused vs unfocused)
- Text readability on background
Step 7: Commit changes
Include all modified files:
src/theme.tsTHEMES.mdTHEME_REFERENCE.md
Use a commit message like:
Add [Theme Name] theme
Adds [Theme Name] as a new [dark/light] theme option with [description].
Colors sourced from official [Theme Name] color scheme.
Modifying an Existing Theme
Step 1: Identify the theme
Find the theme object in src/theme.ts (e.g., nordTheme, monokaiTheme)
Step 2: Update colors
Modify the specific color values in the theme object:
const nordTheme: Theme = {
// ... existing fields
colors: {
// ... existing colors
primary: '#NEW_COLOR', // Update specific color
}
}
Step 3: Update documentation
If color changes are significant, update:
THEMES.md- Description or "Best for" sectionTHEME_REFERENCE.md- Color palette if primary colors changed
Step 4: Test changes
Follow testing steps from "Adding a New Theme" section
Step 5: Commit
Update [Theme Name] theme colors
Changes [specific color] from [old] to [new] to [reason].
Color Selection Guidelines
Contrast requirements
- Text on background: Minimum 4.5:1 contrast ratio (WCAG AA)
- Interactive elements: Minimum 3:1 contrast ratio
- Borders: Should be visible but not distracting
Git status colors (semantic meaning)
- Staged/Added: Green shades (#00FF00, #00AA00, #A6E22E, etc.)
- Represents "good", "added", "ready"
- Modified: Yellow/orange shades (#FFFF00, #CC8800, #E6DB74, etc.)
- Represents "changed", "pending", "attention needed"
- Untracked: Gray or cyan shades (#CCCCCC, #666666, #81A1C1, etc.)
- Represents "new", "not tracked yet"
- Deleted: Red shades (#FF0000, #CC0000, #F92672, etc.)
- Represents "removed", "error", "danger"
Background colors
- Dark themes: Use dark backgrounds (#000000 to #3B4261)
- Light themes: Use light backgrounds (#FFFFFF to #FDF6E3)
- Modals: Slightly different from primary (darker for dark, lighter for light)
- Buttons: Distinct from background, visible when focused
Primary accent color
- Should stand out against background
- Used for focused elements, highlights
- Common choices: Blue, orange, purple, pink, cyan
- Should match the theme's overall aesthetic
Common Patterns
Creating color variants
To create a darker variant of a color:
// If primary is #CC8844
// primaryDark is approximately 10-20% darker: #BB7733 or #AA6622
Use a color picker tool or HSL adjustment:
- Reduce L (lightness) by 10-15% for darker variant
- Increase L by 10-15% for lighter variant
Borrowing from existing schemes
Many popular themes have official color definitions:
- Nord: https://www.nordtheme.com/docs/colors-and-palettes
- Solarized: https://ethanschoonover.com/solarized/
- Gruvbox: https://github.com/morhetz/gruvbox
- Dracula: https://draculatheme.com/contribute
- Tokyo Night: https://github.com/enkia/tokyo-night-vscode-theme
- Catppuccin: https://github.com/catppuccin/catppuccin
- One Dark: https://github.com/atom/atom/tree/master/packages/one-dark-syntax
Light theme from dark theme
When creating a light variant:
- Invert background (dark → light)
- Invert text (light → dark)
- Adjust primary color if needed (some colors work for both)
- Keep git colors semantic (green=good, red=bad)
- Reduce saturation/brightness of accent colors
Validation Checklist
Before finalizing theme changes:
- Theme object implements full
Themeinterface - All color fields use hex format (#XXXXXX)
- Spacing values match standard (0, 1, 2, 3, 4, 5)
- Border style is 'single'
- Theme added to
themesexport object - Theme ID follows naming conventions (lowercase-with-hyphens)
-
THEMES.mdupdated with description -
THEME_REFERENCE.mdupdated with color palette - Type checking passes (
bun --bun tsc --noEmit) - Theme appears in settings modal
- Preview shows all colors correctly
- Theme applies without errors
- Git status colors are semantically correct
- Text is readable on background
- Borders are visible
- Status messages use appropriate colors
Ensuring Components Use Theme Tokens
The Rule
NEVER hardcode colors in components. Always use theme.colors.*
Incorrect (hardcoded):
<text fg="#FFFFFF">Text</text>
<box borderColor="#555555">...</box>
Correct (using theme):
import { theme } from '../theme'
<text fg={theme.colors.text.primary}>Text</text>
<box borderColor={theme.colors.border}>...</box>
Finding hardcoded colors
Search for hex colors in component files:
grep -r '#[0-9A-Fa-f]\{6\}' src/components/
Common theme token mappings
| Use Case | Theme Token |
|---|---|
| Main text | theme.colors.text.primary |
| Muted text | theme.colors.text.muted |
| Focused border | theme.colors.borderFocused |
| Unfocused border | theme.colors.border |
| Accent/highlight | theme.colors.primary |
| Success message | theme.colors.status.success |
| Error message | theme.colors.status.error |
| Staged file | theme.colors.git.staged |
| Modified file | theme.colors.git.modified |
Troubleshooting
Theme doesn't appear in settings
- Check that theme is added to
themesexport insrc/theme.ts - Verify theme ID doesn't have typos
- Restart the application
Colors don't match preview
- Ensure theme preference is saved in
~/.gitarborrc - Restart application after changing theme
- Check terminal supports true colors (24-bit color)
Type errors after adding theme
- Verify theme object matches
Themeinterface exactly - Check all required fields are present
- Run
bun --bun tsc --noEmitfor detailed errors
Theme looks different in terminal
- Terminal emulator may not support true colors
- Some terminals apply color transformations
- Test with different terminal emulator
Best Practices
- Research first: Study the official color scheme before creating a theme
- Test in context: Apply theme and use the app for a few minutes
- Check accessibility: Ensure text is readable and colors have sufficient contrast
- Be consistent: Follow existing theme patterns and conventions
- Document well: Add clear descriptions in THEMES.md
- Use semantic colors: Green=good, red=bad, yellow=warning
- Keep spacing standard: Don't change spacing values unless necessary
- Version control: Commit theme and docs together
- Name clearly: Use recognizable, searchable theme names
- Test edge cases: Check with very long file names, deep nesting, etc.
Examples
Example: Adding Catppuccin Mocha
-
Research: Visit https://github.com/catppuccin/catppuccin
-
Identify colors from Mocha palette:
- Background: #1E1E2E
- Primary text: #CDD6F4
- Accent (Mauve): #CBA6F7
- Green: #A6E3A1
- Yellow: #F9E2AF
- Red: #F38BA8
-
Create theme object:
const catppuccinMochaTheme: Theme = {
name: 'Catppuccin Mocha',
description: 'Soothing pastel theme for the high-spirited',
colors: {
primary: '#CBA6F7', // Mauve
primaryDark: '#B493E0', // Darker mauve
border: '#45475A', // Surface1
borderFocused: '#CBA6F7', // Mauve
background: {
primary: '#1E1E2E', // Base
modal: '#181825', // Mantle
button: '#313244', // Surface0
buttonHover: '#45475A', // Surface1
},
text: {
primary: '#CDD6F4', // Text
secondary: '#BAC2DE', // Subtext1
muted: '#A6ADC8', // Subtext0
disabled: '#585B70', // Surface2
inverted: '#1E1E2E', // Base
},
git: {
staged: '#A6E3A1', // Green
modified: '#F9E2AF', // Yellow
untracked: '#89DCEB', // Sky
deleted: '#F38BA8', // Red
added: '#A6E3A1', // Green
},
status: {
success: '#A6E3A1', // Green
error: '#F38BA8', // Red
warning: '#F9E2AF', // Yellow
info: '#89B4FA', // Blue
},
},
spacing: {
none: 0,
xs: 1,
sm: 2,
md: 3,
lg: 4,
xl: 5,
},
borders: {
style: 'single',
},
}
- Add to themes:
export const themes: Record<string, Theme> = {
// ... existing
'catppuccin-mocha': catppuccinMochaTheme,
}
-
Update THEMES.md, THEME_REFERENCE.md
-
Test and commit
Quick Reference Commands
# Type check
bun --bun tsc --noEmit
# Start app
bun run start
# Search for hardcoded colors in components
grep -r '#[0-9A-Fa-f]\{6\}' src/components/
# View current theme preference
cat ~/.gitarborrc
# Set theme manually
echo '{"theme":"theme-id"}' > ~/.gitarborrc
Resources
- Project theme docs:
THEMES.md - Color reference:
THEME_REFERENCE.md - Implementation notes:
THEME_IMPLEMENTATION.md - Theme source:
src/theme.ts - Settings UI:
src/components/SettingsModal.tsx
Notes for Agents
- Always run type checking after modifying
src/theme.ts - Test theme in the actual application, not just type checking
- When adding multiple themes, do one at a time to catch errors early
- Use the existing 10 themes as templates and references
- Preserve the comment style and structure in
src/theme.ts - Keep theme objects alphabetically ordered for easier maintenance
More from gitarbor/gitarbor-tui
skills-creator
Create and manage Agent Skills following the agentskills.io specification. Use when users want to create, validate, or modify skills for AI agents.
39unit-test
Create comprehensive unit tests using Bun's test runner. Use when the user asks to create or fix unit tests or create test files.
5opentui-dev
Build and modify terminal user interfaces using OpenTUI with React or Core API. Use when implementing terminal UIs, TUIs, CLI applications, interactive terminal components, keyboard navigation, terminal styling, or working on OpenTUI-based applications.
4opencode-agents
Create and configure custom OpenCode agents (primary and subagents) with specialized prompts, tools, permissions, and models. Use when the user wants to create, modify, or configure OpenCode agents, or mentions agent modes, tool permissions, or task delegation.
4nuxt-website
Build and maintain Vue 3/Nuxt 4 marketing websites. Use when working with website pages, components, layouts, SEO, Nuxt configuration, or when user mentions 'website', 'marketing site', 'landing page', 'docs site', Vue, or Nuxt.
4