Skip to content

Implement System Theme Support in OpenTUI #3731

@shuv1337

Description

@shuv1337

Implement System Theme Support in OpenTUI

Problem/Context

The OpenTUI version of OpenCode currently lacks the system theme functionality that exists in the Go TUI version. The Go implementation (packages/tui/internal/theme/system.go) provides dynamic theme adaptation based on the terminal's background color, automatically generating appropriate grayscale colors and using ANSI colors for compatibility.

Currently, OpenTUI only supports static JSON-based themes defined in packages/opencode/src/cli/cmd/tui/context/theme.tsx, with no runtime detection or adaptation capabilities.

Acceptance Criteria

  • System theme option appears in theme picker alongside existing static themes
  • System theme automatically detects terminal background color (dark/light)
  • Dynamic color generation creates appropriate grayscale palette based on terminal background
  • ANSI colors are used for primary/accent colors for terminal compatibility
  • Theme updates at runtime if terminal background changes
  • Graceful fallback to default theme if detection fails
  • KV persistence works correctly with dynamic system theme
  • All UI surfaces (dialogs, markdown, diffs, syntax) render correctly with system theme

Implementation Details

Current Architecture Analysis

Go TUI Implementation (packages/tui/internal/theme/system.go):

  • SystemTheme struct with NewSystemTheme(terminalBg color.Color, isDark bool)
  • Dynamic grayscale generation using generateGrayScale() method
  • Luminance calculation: 0.299*bgR + 0.587*bgG + 0.114*bgB
  • Adaptive color mapping for dark/light terminals
  • ANSI color usage for primary colors (cyan, magenta, etc.)
  • Runtime updates via UpdateSystemTheme() function

OpenTUI Current State (packages/opencode/src/cli/cmd/tui/context/theme.tsx):

  • Static theme resolution via resolveTheme(themeJson) function
  • Fixed color mapping from JSON definitions to RGBA values
  • No runtime detection or dynamic generation capabilities

Required Components

1. Terminal Background Detection

// packages/opencode/src/cli/cmd/tui/context/theme.tsx
function detectTerminalBackground(): { bg: RGBA; isDark: boolean } {
  // Implementation needed:
  // - Use Node.js process APIs or ANSI escape sequences
  // - Query terminal background color
  // - Determine if terminal is dark or light mode
  // - Handle cross-platform differences
}

2. Dynamic Theme Generation

// packages/opencode/src/cli/cmd/tui/context/theme.tsx
function createSystemTheme(bgColor: RGBA, isDark: boolean): Theme {
  // Implementation needed:
  // - Port grayscale generation logic from Go version
  // - Generate 12-step grayscale palette
  // - Map to Theme interface properties
  // - Use ANSI colors for primary/accent colors
}

3. Theme Integration

// packages/opencode/src/cli/cmd/tui/context/theme.tsx
export const THEMES: Record<string, Theme> = {
  // ... existing themes
  system: createSystemTheme(...detectTerminalBackground()),
}

4. Runtime Updates

  • Implement theme update mechanism when terminal colors change
  • Add event listeners for terminal color changes
  • Update theme registry dynamically

Technical Approach

  1. Detection Strategy: Use ANSI escape sequences or Node.js TTY APIs to detect terminal background
  2. Color Generation: Port the Go implementation's luminance-based grayscale generation
  3. ANSI Mapping: Use standard ANSI 16 colors for primary/accent colors
  4. Fallback Strategy: Default to opencode theme if detection fails
  5. Performance: Cache detection results and only update when necessary

Reference Implementation

The Go implementation in packages/tui/internal/theme/system.go provides a complete reference for:

  • Color detection and luminance calculation
  • Grayscale palette generation algorithm
  • ANSI color mapping strategy
  • Dark/light mode adaptation logic

Files to Modify

  • packages/opencode/src/cli/cmd/tui/context/theme.tsx - Add system theme detection and generation
  • packages/opencode/src/cli/cmd/tui/component/dialog-theme-list.tsx - Ensure system theme appears in picker
  • packages/opencode/src/cli/cmd/tui/context/kv.tsx - Verify KV persistence works with dynamic theme

Testing Strategy

  • Unit tests for color detection functions
  • Integration tests for theme generation
  • Manual testing across different terminal environments
  • Regression testing for existing static themes

Tasks

  • Research terminal color detection methods for Node.js
  • Implement terminal background detection function
  • Port grayscale generation logic from Go implementation
  • Create system theme generation function
  • Add system theme to THEMES registry
  • Update theme picker to include system option
  • Implement runtime theme updates
  • Add error handling and fallback logic
  • Write unit tests for new functionality
  • Test across different terminal environments
  • Update documentation

Additional Context

This feature was previously available in the Go TUI version and users expect similar functionality in OpenTUI. The implementation should maintain feature parity while adapting to the TypeScript/OpenTUI architecture.

The existing Go implementation provides a solid foundation and reference for the required algorithms and color generation logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions