Skip to content

feat(tui): add Mode 2031 theme detection with tri-state appearance mode#13233

Closed
kavhnr wants to merge 2 commits intoanomalyco:devfrom
kavhnr:feat/mode-2031-theme-detection
Closed

feat(tui): add Mode 2031 theme detection with tri-state appearance mode#13233
kavhnr wants to merge 2 commits intoanomalyco:devfrom
kavhnr:feat/mode-2031-theme-detection

Conversation

@kavhnr
Copy link
Contributor

@kavhnr kavhnr commented Feb 12, 2026

What does this PR do?

Closes #13232

OpenTUI v0.1.78 added Mode 2031 dark/light theme detection (opentui#657). OpenCode is already on v0.1.79 (#13036) which includes these APIs, but doesn't use them. This PR integrates renderer.themeMode / renderer.on("theme_mode", ...) into OpenCode's theme system.

Three changes:

  1. Tri-state appearance mode (auto/dark/light) — replaces the binary toggle. auto follows OS via Mode 2031, falling back to OSC 11 luminance on unsupported terminals. dark/light are manual overrides.
  2. Per-mode theme config"theme": { "light": "github", "dark": "catppuccin" } alongside existing "theme": "opencode" (backward compatible).
  3. Appearance selector in the theme dialog — ←/→ arrow keys cycle modes, clickable, reverts on cancel.

Mode 2031 is the same approach used by Neovim and Helix. Event-driven, zero overhead. Unsupported terminals silently ignore the sequences — no degradation.

Why Mode 2031 over the approaches in existing open PRs:

Approach PR Problem
Poll terminal bg every 5s #7182, #7162 Wastes CPU, delayed detection, races with palette queries
execSync("defaults read") / gsettings every 3s #9719 Platform-specific, breaks in SSH/containers/tmux, spawns child processes
Mode 2031 (this PR) Terminal-native, event-driven, zero overhead

Edge cases handled:

  • Unsupported terminals: detectedMode stays at initial OSC 11 value. No degradation.
  • Custom themes without variants: activeThemeMode() falls back to "dark". Existing custom themes work identically.
  • Cancel in dialog: both theme and mode revert to initial values.
  • Event cleanup: onCleanup(() => renderer.off("theme_mode", ...)) prevents leaks.

How did you verify your code works?

  • bun run typecheck passes (12/12 packages, zero errors)
  • Tested on Ghostty (Mode 2031 supported): toggling macOS appearance instantly switches theme variants
  • Tested on Terminal.app (Mode 2031 unsupported): falls back to existing behavior, manual mode selector works, no errors
  • Backward compatible: "theme": "opencode" works, "theme": { "light": "github", "dark": "catppuccin" } works
  • All 31 dual-variant built-in themes resolve correctly in both modes
  • aura and ayu (single-palette) unaffected by mode changes

Demo

mode-2031-theme-detection.mp4

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

Based on the search results, I found 3 related PRs that address similar appearance/theme functionality:

  1. #7182 - feat(tui): add appearance setting with dark/light/system modes

    • Related approach: Implements tri-state appearance modes (mentioned in the PR description as polling the terminal)
  2. #8239 - feat(desktop): Add command to /toggle-appearence

    • Related: Provides appearance toggling functionality
  3. #9719 - feat(tui): add system dark/light mode matching

    • Related approach: Implements system appearance detection (mentioned in the PR description as using platform-specific commands)

Note: The current PR (#13233) explicitly compares itself against these older approaches, explaining why Mode 2031 is superior (event-driven vs. polling/platform-specific). These appear to be alternative/prior attempts at the same feature rather than exact duplicates. If any of these are still open, they may need to be closed in favor of this Mode 2031 implementation.

@kavhnr kavhnr marked this pull request as ready for review February 12, 2026 00:39
@kavhnr kavhnr closed this Feb 13, 2026
@kavhnr kavhnr deleted the feat/mode-2031-theme-detection branch February 13, 2026 01:30
@mitchelljphayes
Copy link

@kavhnr any reason you closed this? I think this approach is more elegant than the polling approach explored by some other PRs?

@kavhnr
Copy link
Contributor Author

kavhnr commented Feb 14, 2026

@mitchelljphayes our org (I think anyone using foundry/gotham) flagged opencode as not approved from some weird behavior on our VMs, so I ended up removing opencode and this PR to finish the clean up. Plus, this didn’t seem like a priority and would likely be stale by the time it’s reviewed and I didn’t want to add noise to an already busy team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add support for OpenTUI's new themeMode detection (Mode 2031)

2 participants

Comments