Skip to content

feat(tui): new theme + Catppuccin syntax highlighter - #88

Merged
elkaix merged 2 commits into
mainfrom
feat/tui-codex-theme
Jun 8, 2026
Merged

feat(tui): new theme + Catppuccin syntax highlighter#88
elkaix merged 2 commits into
mainfrom
feat/tui-codex-theme

Conversation

@elkaix

@elkaix elkaix commented Jun 8, 2026

Copy link
Copy Markdown
Member

Refreshes the TUI theme and adopts a Catppuccin code-syntax highlighter, with the brand accent preserved.

What changed

Accent (brand periwinkle/indigo)

  • accent#B3B9F4 (dark) / #0B114E (light); border_accent + the selection tint reharmonized into the same family.
  • Selection background is now sourced from a single constant (_SELECTED_BG_*) feeding both the selected_bg token and the prompt-toolkit completion/dialog styles — no more parallel literals.

Catppuccin syntax highlighter

  • Code blocks use Catppuccin Mocha (dark UI) / Latte (light UI), adaptive by active theme.
  • Hand-built as Pygments styles (official palette, canonical token mapping, no italic/underline, bold-only) — no new dependency.
  • Rendered foreground-only on the calm code-block panel (background_color="default"), keeping the no-background-on-markdown invariant.
  • pythinker-ansi and stock Pygments styles remain opt-ins; the config default is now catppuccin-adaptive.

Markdown (terminal-native ANSI, mode-independent)

  • Inline code & links → cyan, blockquotes → green, ordered-list markers → bright_blue (terminal-native ANSI, so they adapt per terminal).
  • Headings/strong/emphasis keep their existing colors (intentional — only the four enumerated elements change).
  • Fixes the vendored markdown renderer that previously stripped blockquote color (in two places) and rendered list markers unstyled, so those colors never reached the screen.

User messages

  • Rendered on a neutral grey block (#333333 / #E0E0E0), removing the prior blue "blur" tint.

Cleanup

  • Shimmer ramp constants derive from the activity_verb* tokens (kill drift); dead _SPINNER_SILVER and unused tool_success_bg token removed.

Verification

  • Full suite green (4540 passed; 1661 ui/ui_and_conv re-verified on the main base).
  • pyright: 0 errors · ruff: clean.
  • All new behavior covered by TDD; WCAG contrast verified for the new accent family.

Notes

  • Semantic-alias tokens (tool_diff_addedsuccess, activity_labeltool_title, …), the fixed brand-logo palette, and the wired-but-empty *_message_text tokens were intentionally kept (documented) — merging/removing them would reduce semantic clarity.
  • Fidelity caveat: Pygments tokenizes differently from syntect/two-face-based highlighters, so it's "Catppuccin palette through Pygments," not byte-identical rendering.

Summary by CodeRabbit

  • New Features

    • Catppuccin code syntax themes with automatic dark/light theme adaptation.
  • Style

    • Updated markdown rendering for links, inline code, blockquotes, and list markers.
    • Changed user-message background to neutral grey.
    • Refined selection tint and brand accent colors.

@elkaix
elkaix force-pushed the feat/tui-codex-theme branch from d858908 to e690065 Compare June 8, 2026 18:32
@elkaix elkaix changed the title feat(tui): codex-aligned theme + Catppuccin syntax highlighter feat(tui): new theme + Catppuccin syntax highlighter Jun 8, 2026
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.58333% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pythinker_code/utils/rich/syntax.py 85.29% 2 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

Refresh the TUI theme and adopt a Catppuccin code-syntax highlighter:

- Accent reharmonized to the brand periwinkle/indigo (#B3B9F4 dark / #0B114E
  light); border_accent and the selection tint follow the accent family (the
  selection bg is now sourced from a single constant feeding both the token and
  the prompt-toolkit styles).
- Code blocks use Catppuccin Mocha (dark UI) / Latte (light UI), adaptive,
  hand-built as Pygments styles and rendered foreground-only on the calm
  code-block panel (transparent bg). 'pythinker-ansi' and stock Pygments styles
  remain opt-ins; the config default is now 'catppuccin-adaptive'.
- Markdown uses terminal-native ANSI for inline code and links (cyan),
  blockquotes (green) and ordered-list markers (bright blue), mode-independent.
  Also fixes the vendored renderer that stripped blockquote colour and left list
  markers unstyled.
- User-sent messages render on a neutral grey block (#333333 / #E0E0E0),
  removing the prior blue tint.

Shimmer ramp constants now derive from the activity tokens and the unused
tool_success_bg token is removed.
@elkaix
elkaix force-pushed the feat/tui-codex-theme branch from e690065 to cde81bd Compare June 8, 2026 18:41
The CI `check` job failed pyright on tests/ui_and_conv/test_tui_theme_tokens.py:
type the `expected` dict keys as ThemeName so the loop var is accepted by
get_tui_tokens, and route markdown_rich_style(...).color.name through a
_color_name helper that asserts the optional Color is present.

Also add the missing `## Unreleased` CHANGELOG bullet for the new TUI theme
+ Catppuccin highlighter, fixing the `changelog` job.
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR replaces the ANSI code-theme default with Catppuccin adaptive (switching dark/light with UI theme), unifies selection backgrounds via shared constants, harmonizes markdown to terminal-native ANSI colors (cyan/green/bright_blue), and restructures UI tokens accordingly. All rendering paths and tests are updated to reflect the new theme system.

Changes

Catppuccin theme migration and markdown color harmonization

Layer / File(s) Summary
Catppuccin syntax theme infrastructure
src/pythinker_code/utils/rich/syntax.py
Adds Catppuccin Mocha/Latte palettes, defines CatppuccinMochaStyle/CatppuccinLatteStyle Pygments classes, extends resolve_code_theme to recognize adaptive/mocha/latte sentinels with lazy-loaded theme switching, updates available_code_themes() to list them, and changes module default from ANSI to Catppuccin adaptive.
Theme token system and selection background unification
src/pythinker_code/ui/theme.py
Introduces _SELECTED_BG_DARK/_SELECTED_BG_LIGHT shared constants; updates prompt/completion/dialog styles to use them; extends MarkdownColors with ordered_marker and unordered_marker fields; rewrites _build_markdown_colors() to map enumerated elements to terminal-native ANSI color names (cyan, green, bright_blue) and ties unordered bullets to tokens.muted; reharmonizes all dark/light TuiTokens defaults for accent, border, selected_bg, and message backgrounds.
Markdown rendering implementation
src/pythinker_code/utils/rich/markdown.py, src/pythinker_code/ui/shell/components/markdown.py
Preserves BlockQuote color in rendering; applies Rich styles to ListItem bullet and number markers via markdown.item.bullet/markdown.item.number; removes forced color stripping in MarkdownContext; branches BorderedCodeBlock rendering based on stock vs. adaptive/ANSI theme to control syntax background handling; updates markdown style overrides to use theme's ordered/unordered marker accents.
Code block, shimmer, and brand updates
src/pythinker_code/ui/shell/motion.py, src/pythinker_code/ui/shell/__init__.py
Sources dark shimmer colors from theme activity_verb* tokens instead of hardcoded hex; clarifies robot logo palette comments as transferred from animated SVG and theme-independent.
Configuration defaults and documentation
src/pythinker_code/config.py, CHANGELOG.md
Changes TUIConfig.code_theme default from pythinker-ansi to catppuccin-adaptive with updated field description explaining Catppuccin dark/light pinning and stock style options; updates CHANGELOG with refreshed theme colors and rendering changes.
Test infrastructure and SGR capture
tests/ui_and_conv/test_md_color_contract.py
Updates _sgr_fg to extract exact SGR escape via Rich Console rendering and regex instead of manual hex conversion; adds contract test for blockquote and ordered-list marker ANSI colors.
Code theme opt-in test coverage
tests/ui_and_conv/test_code_theme_opt_in.py
Adds three tests: defaults to Catppuccin adaptive with case-insensitive normalization, adaptive resolves based on active UI theme (dark/light), and Catppuccin rendering applies foreground color without solid background or italic SGR.
Shell accent and token validation
tests/ui_and_conv/test_shell_design_system.py, tests/ui_and_conv/test_shell_panel.py, tests/ui_and_conv/test_tui_theme_tokens.py
Updates shell accent hex expectations for dark/light modes; validates brand_panel active border uses accent color; verifies selected_bg and user_message_bg token values and neutral grey tolerance; asserts markdown colors resolve to terminal-native ANSI names (cyan/green/bright_blue) for code/link/quote/ordered-marker and tokens.muted for unordered bullets.
Configuration snapshot
tests/core/test_config.py
Updates default configuration dump snapshot to reflect catppuccin-adaptive as the new tui.code_theme default.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

The PR involves dense logic across multiple theme system layers (syntax theme definitions, token restructuring, markdown color mappings, rendering branching logic), heterogeneous changes to shell components and utilities, and comprehensive test coverage updates that require understanding the new ANSI-color-based approach and adaptive theme switching.

Possibly related PRs

  • Pythoughts-labs/pythinker-code#62: Introduces the active code theme state plumbing and available_code_themes() that this PR builds upon to deliver Catppuccin theme resolution and adaptive switching.

Suggested labels

enhancement

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.00% which is insufficient. The required threshold is 70.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title follows conventional commits format with feat type and (tui) scope, clearly summarizing the main changes: new theme and Catppuccin syntax highlighter.
Description check ✅ Passed Description covers all required sections: related issue links (implied by context), detailed changes, verification, and follows repository standards with comprehensive context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tui-codex-theme

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/ui_and_conv/test_code_theme_opt_in.py (1)

1-7: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the module docstring to reflect the new default theme.

The docstring still says the default is pythinker-ansi, but this file now validates catppuccin-adaptive as default, which is misleading for future maintainers.

Suggested edit
-Default (``pythinker-ansi``) keeps today's terminal-adaptive, transparent look.
+Default (``catppuccin-adaptive``) follows active UI theme (Mocha/Latte) while
+preserving transparent syntax backgrounds in fenced code blocks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/ui_and_conv/test_code_theme_opt_in.py` around lines 1 - 7, The module
docstring in tests/ui_and_conv/test_code_theme_opt_in.py incorrectly states the
default theme as "pythinker-ansi"; update that top-level docstring to say the
current default is "catppuccin-adaptive" (and adjust the explanatory text
accordingly) so it matches the test's expectations and avoids future confusion
about the default code_theme.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/ui_and_conv/test_tui_theme_tokens.py`:
- Around line 93-102: The test imports private theme dicts
(_PROMPT_STYLE_DARK/_PROMPT_STYLE_LIGHT) which couples it to implementation;
instead remove those imports and assert the selection background via the public
API: use get_tui_tokens("dark"/"light") to get selected_bg and call the public
style-rendering function that returns the prompt style mapping for the theme
(the same mapping that would contain "slash-completion-menu.row.current") and
assert that mapping["slash-completion-menu.row.current"] ==
f"bg:{get_tui_tokens('dark' or 'light').selected_bg}"; replace references to
_PROMPT_STYLE_DARK/_PROMPT_STYLE_LIGHT with this public-style call and keep the
existing key "slash-completion-menu.row.current".

---

Outside diff comments:
In `@tests/ui_and_conv/test_code_theme_opt_in.py`:
- Around line 1-7: The module docstring in
tests/ui_and_conv/test_code_theme_opt_in.py incorrectly states the default theme
as "pythinker-ansi"; update that top-level docstring to say the current default
is "catppuccin-adaptive" (and adjust the explanatory text accordingly) so it
matches the test's expectations and avoids future confusion about the default
code_theme.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f0bd414e-4b09-4d41-a792-16500f62f7f9

📥 Commits

Reviewing files that changed from the base of the PR and between f811f87 and 7fe3421.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • src/pythinker_code/config.py
  • src/pythinker_code/ui/shell/__init__.py
  • src/pythinker_code/ui/shell/components/markdown.py
  • src/pythinker_code/ui/shell/motion.py
  • src/pythinker_code/ui/theme.py
  • src/pythinker_code/utils/rich/markdown.py
  • src/pythinker_code/utils/rich/syntax.py
  • tests/core/test_config.py
  • tests/ui_and_conv/test_code_theme_opt_in.py
  • tests/ui_and_conv/test_md_color_contract.py
  • tests/ui_and_conv/test_shell_design_system.py
  • tests/ui_and_conv/test_shell_panel.py
  • tests/ui_and_conv/test_tui_theme_tokens.py

Comment thread tests/ui_and_conv/test_tui_theme_tokens.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant