Skip to content

feat: TUI customizations with brand colors and enhanced buddy system#141

Closed
Icarus603 wants to merge 1 commit into
claude-code-best:mainfrom
Icarus603:main
Closed

feat: TUI customizations with brand colors and enhanced buddy system#141
Icarus603 wants to merge 1 commit into
claude-code-best:mainfrom
Icarus603:main

Conversation

@Icarus603
Copy link
Copy Markdown

@Icarus603 Icarus603 commented Apr 5, 2026

Summary

This PR introduces comprehensive TUI customizations with a cohesive brand color palette and an enhanced /buddy companion system.

Theme Colors

  • Replace Claude orange brand color with blue (rgb(88,190,255))
  • Add BRAND_COLOR, BRAND_COLOR_LIGHT, BRAND_RED, BRAND_GREEN constants
  • Update all 6 theme variants (light, dark, ansi, daltonized) with consistent palette
  • Change permission/suggestion/remember colors to cyan-blue (rgb(131,210,238))
  • Set dark theme userMessageBackground to #0f0f0f for better contrast
  • Update diff colors: burgundy red and forest green

Syntax Highlighting

  • Add new Royal Gold Dark theme with gold/blue palette (lower saturation)
  • Replace Monokai Extended as default dark syntax theme

UI Behavior

  • Remove spinner stalled-to-red warning for cleaner UX
  • Remove syntax highlighting toggle (Ctrl+T) from ThemePicker
  • Remove top padding from FullscreenLayout
  • Set inline code color to amber gold (#FEC84A) in dark themes

Keybindings

  • Remove theme:toggleSyntaxHighlighting action and Ctrl+T binding

Buddy System Enhancements

  • Add /buddy pet - Trigger heart animation + companion reaction
  • Add /buddy rehatch - Re-roll a new companion with full stats display
  • Add /buddy mute / /buddy unmute - Show/hide companion
  • Add 20-character stat bars (████████░░) for DEBUGGING, PATIENCE, CHAOS, WISDOM, SNARK
  • Auto-hatch on first /buddy call (no explicit hatch needed)
  • Display sprite, rarity, eye, hat, personality in text format
  • Enable BUDDY feature in production builds by default

Files Changed

  • build.ts - Add BUDDY to default build features
  • packages/color-diff-napi/src/index.ts - Royal Gold Dark theme, brand diff colors
  • src/utils/theme.ts - Brand color constants, theme updates
  • src/utils/markdown.ts - Inline code color for dark themes
  • src/components/Spinner/*.tsx - Remove stalled warning
  • src/components/ThemePicker.tsx - Remove syntax toggle UI
  • src/components/FullscreenLayout.tsx - Remove top padding
  • src/components/HighlightedCode.tsx - Remove syntax toggle check
  • src/keybindings/defaultBindings.ts - Remove Ctrl+T binding
  • src/keybindings/schema.ts - Remove toggle action
  • src/commands/buddy/buddy.ts - Enhanced buddy commands with stats
  • src/commands/buddy/index.ts - Updated command hints

Test Plan

  • Verify theme colors render correctly in light/dark modes
  • Verify syntax highlighting uses Royal Gold Dark for dark themes
  • Verify spinner no longer turns red when stalled
  • Verify /buddy auto-hatches on first use
  • Verify /buddy pet triggers heart animation
  • Verify /buddy rehatch creates new companion with stats
  • Verify 20-char stat bars display correctly

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added /buddy rehatch subcommand to generate a new companion.
    • Updated /buddy mute controls from off/on to mute/unmute.
  • Updates

    • Refined companion display with improved stat visualization.
    • Updated dark theme color defaults and syntax highlighting colors.
    • Enhanced color consistency throughout the app.
  • Bug Fixes

    • Simplified spinner animation rendering by removing stalled intensity handling.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 5, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

The pull request extends the buddy command system with rehatch and mute/unmute functionality, removes stalled loading state handling from spinner components, introduces brand color constants across the theme system, and updates various UI components for consistency with new color and state management approaches.

Changes

Cohort / File(s) Summary
Buddy Command System
build.ts, src/commands/buddy/buddy.ts, src/commands/buddy/index.ts
Added BUDDY feature flag to default build features; replaced mute toggle from off/on to mute/unmute; introduced /buddy rehatch subcommand to generate new companions with stat bars; changed default behavior to render companion as text details instead of React CompanionCard; updated command metadata for new subcommands.
Spinner/Loading State Cleanup
src/components/Spinner/GlimmerMessage.tsx, src/components/Spinner/SpinnerAnimationRow.tsx, src/components/Spinner/SpinnerGlyph.tsx
Removed stalled intensity rendering paths that applied theme-dependent color transitions; deleted useTheme, color interpolation utilities, and conditional stalled-state rendering branches; spinner now always renders using messageColor regardless of stalledIntensity.
Theme & Color System
src/utils/theme.ts, packages/color-diff-napi/src/index.ts, src/utils/markdown.ts
Introduced shared brand color constants (BRAND_COLOR, BRAND_RED, BRAND_GREEN); updated all theme palettes to use brand colors for consistency; changed dark-mode default syntax theme from Monokai to Royal Gold Dark; updated diff color palettes to use brand red/green; applied theme-aware codespan colors in markdown rendering.
UI Component Updates
src/components/HighlightedCode.tsx, src/components/FullscreenLayout.tsx, src/components/ThemePicker.tsx
Simplified syntax highlighting fallback logic; removed conditional padding in fullscreen scroll behavior; refactored syntax highlighting toggle to read from settings instead of app state; removed shortcut display integration in theme picker.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Possibly related PRs

Suggested reviewers

  • KonghaYao

Poem

🐰 Brand new colors paint the way,
Companions hatch and find their say,
Stalled states fade to simple sight,
Spinners spin in true delight,
Rehatch, mute, unmute with glee,
The buddy system now runs free! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main changes: TUI customizations with brand color updates and an enhanced buddy system with new features.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (6)
src/components/FullscreenLayout.tsx (1)

374-387: Remove unused padCollapsed variable and update stale comments.

The paddingTop change to always 0 leaves behind:

  1. Dead code: padCollapsed (line 387) is now defined but never used
  2. Stale comments: Lines 374-383 still describe the old padCollapsed-based padding behavior
♻️ Proposed cleanup
-    // Three sticky states: null (at bottom), {text,scrollTo} (scrolled up,
-    // header shows), 'clicked' (just clicked header — hide it so the
-    // content ❯ takes row 0). padCollapsed covers the latter two: once
-    // scrolled away from bottom, padding drops to 0 and stays there until
-    // repin. headerVisible is only the middle state. After click:
-    // scrollBox_y=0 (header gone) + padding=0 → viewportTop=0 → ❯ at
-    // row 0. On next scroll the onChange fires with a fresh {text} and
-    // header comes back (viewportTop 0→1, a single 1-row shift —
-    // acceptable since user explicitly scrolled).
+    // Two sticky header states: null (at bottom or hidden via hideSticky),
+    // {text,scrollTo} (scrolled up, header shows). 'clicked' hides the
+    // header so content ❯ takes row 0. On next scroll the onChange fires
+    // with a fresh {text} and header comes back.
     const sticky = hideSticky ? null : stickyPrompt
     const headerPrompt =
       sticky != null && sticky !== 'clicked' && overlay == null ? sticky : null
-    const padCollapsed = sticky != null && overlay == null

Also applies to: 401-401

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/FullscreenLayout.tsx` around lines 374 - 387, Remove the
now-unused padCollapsed variable and update the surrounding comment block to
reflect the current behavior that paddingTop is always 0; specifically delete
the declaration "const padCollapsed = sticky != null && overlay == null", remove
any other references to padCollapsed (including the duplicate at the later
location), and rewrite the comment above the sticky/header logic to describe the
simplified states and headerPrompt calculation (using hideSticky, stickyPrompt,
sticky and overlay) without mentioning padding collapse. Ensure headerPrompt
remains computed as "sticky != null && sticky !== 'clicked' && overlay == null ?
sticky : null" and no other code expects padCollapsed.
src/commands/buddy/buddy.ts (2)

106-145: Duplicated hatching logic between rehatch and auto-hatch.

The rehatch block (lines 106-145) and the auto-hatch block (lines 203-240) share nearly identical logic: generating a seed, rolling stats, looking up names/personalities, creating StoredCompanion, saving config, and building the output lines. Consider extracting a shared helper to reduce duplication.

♻️ Suggested extraction
function hatchCompanion(): { stored: StoredCompanion; output: string[] } {
  const seed = generateSeed()
  const r = rollWithSeed(seed)
  const name = SPECIES_NAMES[r.bones.species] ?? 'Buddy'
  const personality = SPECIES_PERSONALITY[r.bones.species] ?? 'Mysterious and code-savvy.'

  const stored: StoredCompanion = {
    name,
    personality,
    seed,
    hatchedAt: Date.now(),
  }

  saveGlobalConfig(cfg => ({ ...cfg, companion: stored }))

  const stars = RARITY_STARS[r.bones.rarity]
  const sprite = renderSprite(r.bones, 0)
  const shiny = r.bones.shiny ? '  ✨ Shiny!' : ''

  const output = [
    ...sprite,
    '',
    `  ${name} the ${speciesLabel(r.bones.species)}${shiny}`,
    `  Rarity: ${stars} (${r.bones.rarity})`,
    `  Eye: ${r.bones.eye}  Hat: ${r.bones.hat}`,
    '',
    `  "${personality}"`,
    '',
    '  Stats:',
    renderStats(r.bones.stats),
  ]

  return { stored, output }
}

Then use it in both places with different header/footer messages.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/buddy/buddy.ts` around lines 106 - 145, Extract the duplicated
companion hatching logic from the rehatch block and the auto-hatch block into a
single helper (e.g., hatchCompanion) that returns the StoredCompanion and the
rendered output lines; move seed generation, rollWithSeed, name/personality
lookup, StoredCompanion creation, saveGlobalConfig call, and sprite/stats
rendering into that helper (refer to symbols generateSeed, rollWithSeed,
SPECIES_NAMES, SPECIES_PERSONALITY, StoredCompanion, saveGlobalConfig,
RARITY_STARS, renderSprite, speciesLabel, renderStats). Replace the duplicated
code in both the rehatch handling and the auto-hatch handling to call
hatchCompanion(), then prepend/append the context-specific header/footer lines
(e.g., "🎉 A new companion appeared!" or auto-hatch message and "Your old
companion has been replaced!" only where appropriate) and pass the joined output
to onDone as before.

68-82: Consider clamping the filled value to prevent unexpected bar lengths.

If val exceeds 100, filled would exceed 20, causing the '░'.repeat(20 - filled) to produce an empty string (since negative repeat returns ""). While stats are presumably 0-100, a defensive clamp would ensure consistent 20-character bars.

🛡️ Optional defensive fix
 function renderStats(stats: Record<string, number>): string {
   const lines = [
     'DEBUGGING',
     'PATIENCE',
     'CHAOS',
     'WISDOM',
     'SNARK',
   ].map(name => {
     const val = stats[name] ?? 0
-    const filled = Math.round(val / 5)
+    const filled = Math.min(20, Math.max(0, Math.round(val / 5)))
     const bar = '█'.repeat(filled) + '░'.repeat(20 - filled)
     return `  ${name.padEnd(10)} ${bar} ${val}`
   })
   return lines.join('\n')
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/buddy/buddy.ts` around lines 68 - 82, In renderStats, guard
against values outside 0–100 by clamping the computed filled count so the
progress bar always stays 20 chars; instead of using filled = Math.round(val /
5) directly, compute filled = Math.max(0, Math.min(20, Math.round(val / 5))) (or
equivalent) before building bar to ensure '█'.repeat(filled) and '░'.repeat(20 -
filled) never receive negative lengths; update the logic in the renderStats
function accordingly.
src/utils/theme.ts (1)

390-395: Keep the light daltonized diff palette off the brand green/red split.

This variant explicitly avoids green elsewhere for deuteranopia, but the add path here ends on BRAND_GREEN while removals stay red. darkDaltonizedTheme still keeps additions blue, so the two daltonized variants now diverge on the one surface users scan hardest.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/theme.ts` around lines 390 - 395, The daltonized light theme
currently mixes brand green/red for word-level diffs (diffAddedWord =
BRAND_GREEN, diffRemovedWord = BRAND_RED) which breaks consistency with
darkDaltonizedTheme; change the light daltonized variant to avoid the brand
green by using the same non-green addition color used by the daltonized dark
theme (make diffAddedWord match the daltonized addition blue) and ensure
diffRemovedWord uses the corresponding daltonized removal color so both
daltonized themes present the same addition/removal colors rather than a
green/red split.
src/utils/markdown.ts (1)

90-92: Route inline-code color through the theme instead of hardcoding it here.

src/components/design-system/color.ts:7-24 treats #FEC84A as a raw value, so dark-ansi and dark-daltonized skip their palette lookup entirely here. That makes the renderer own variant-specific contrast instead of the theme. Please move this to a theme token, or at least branch on the concrete theme names rather than startsWith('dark').

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/markdown.ts` around lines 90 - 92, The inline-code color is
hardcoded as '#FEC84A' in the return that calls color(...)(token.text); change
this to resolve via the theme token instead of startsWith('dark') — either map
concrete theme names (e.g., 'dark-ansi', 'dark-daltonized') to the appropriate
token or use an explicit theme token key (e.g., 'inlineCode' or reuse
'permission') and pass that token name to color(themeToken, theme) so color(...)
looks up the palette from the theme; update the branch that currently uses
theme?.startsWith('dark') to use the concrete theme names or the theme token
lookup and keep the call as color(themeToken, theme)(token.text).
packages/color-diff-napi/src/index.ts (1)

388-393: Don't reintroduce green/red in the light daltonized diff renderer.

This branch now uses the regular brand-green add palette, while the dark daltonized branch above keeps additions blue. That means the accessibility variant renders the same semantic split differently by brightness mode and relies on green/red again in the light renderer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/color-diff-napi/src/index.ts` around lines 388 - 393, The light
"daltonized" renderer is mistakenly using the regular green brand tokens
(addLine, addWord, addDecoration set to BRAND_DIFF_GREEN_*) and raw red rgb(...)
values for deletions, which reintroduces green/red; replace those with the
daltonized palette used by the dark daltonized branch so additions use the
daltonized blue tokens (swap out BRAND_DIFF_GREEN_LIGHT_LINE/WORD/DECORATION for
the daltonized-addition equivalents used in the dark-daltonized code) and
replace the raw rgb(...) deleteLine/deleteWord/deleteDecoration values with the
corresponding daltonized-deletion tokens so both light and dark daltonized
renderers share the same semantic colors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/HighlightedCode.tsx`:
- Around line 37-43: HighlightedCode currently constructs a ColorFile regardless
of the persisted syntax-highlighting setting, causing inconsistency with
StructuredDiff; update the useMemo block in HighlightedCode to read the
persisted flag (e.g., settings.syntaxHighlightingDisabled or similar) and
early-return null or a plain text renderer when highlighting is disabled, or
alternatively ensure the component calls expectColorFile only when highlighting
is enabled; modify the useMemo that creates ColorFile (function/component names:
HighlightedCode, useMemo, expectColorFile, ColorFile, code, filePath) so the
persisted setting is consulted and the component's behavior matches
StructuredDiff and the persisted types.

In `@src/components/Spinner/SpinnerGlyph.tsx`:
- Around line 2-4: Update the import block in SpinnerGlyph.tsx to use the
project path alias (src/*) instead of relative paths and add missing semicolons:
replace imports for Box and Text (currently from '../../ink.js'), Theme (from
'../../utils/theme.js') and getDefaultCharacters (from './utils.js') to the
appropriate src/* aliased module paths and terminate each import statement with
a semicolon so the file follows the repo TSX conventions and line/semicolon
rules.

In `@src/components/ThemePicker.tsx`:
- Around line 155-161: ThemePicker currently reports highlighting as enabled
(via colorModuleUnavailableReason/syntaxTheme) while the persisted flag
settings.syntaxHighlightingDisabled (used by StructuredDiff) can still disable
it; either surface that persisted flag in ThemePicker state/footer or
migrate/remove the persisted flag. Fix by reading
settings.syntaxHighlightingDisabled inside ThemePicker and, if true, display a
disabled message (e.g. "Syntax highlighting disabled (persisted)") and disable
theme-selection UI, or perform a migration: clear/convert
settings.syntaxHighlightingDisabled during this PR and update persistence logic
in src/utils/settings/types.ts so ThemePicker and StructuredDiff remain
consistent; update references to colorModuleUnavailableReason and syntaxTheme in
ThemePicker to incorporate the persisted flag check.

In `@src/utils/theme.ts`:
- Around line 493-494: The Theme constant now uses hex strings for
userMessageBackground and userMessageBackgroundHover which themeColorToAnsi()
can't parse; update either the Theme entries (userMessageBackground,
userMessageBackgroundHover) to use "rgb(r,g,b)" format or extend
themeColorToAnsi() to accept "#RRGGBB" by adding a branch that matches
/^#([0-9a-fA-F]{6})$/ and converts the hex pairs to numeric r,g,b values before
proceeding with the existing RGB→ANSI conversion; reference Theme,
userMessageBackground, userMessageBackgroundHover, and themeColorToAnsi() when
making the change.

---

Nitpick comments:
In `@packages/color-diff-napi/src/index.ts`:
- Around line 388-393: The light "daltonized" renderer is mistakenly using the
regular green brand tokens (addLine, addWord, addDecoration set to
BRAND_DIFF_GREEN_*) and raw red rgb(...) values for deletions, which
reintroduces green/red; replace those with the daltonized palette used by the
dark daltonized branch so additions use the daltonized blue tokens (swap out
BRAND_DIFF_GREEN_LIGHT_LINE/WORD/DECORATION for the daltonized-addition
equivalents used in the dark-daltonized code) and replace the raw rgb(...)
deleteLine/deleteWord/deleteDecoration values with the corresponding
daltonized-deletion tokens so both light and dark daltonized renderers share the
same semantic colors.

In `@src/commands/buddy/buddy.ts`:
- Around line 106-145: Extract the duplicated companion hatching logic from the
rehatch block and the auto-hatch block into a single helper (e.g.,
hatchCompanion) that returns the StoredCompanion and the rendered output lines;
move seed generation, rollWithSeed, name/personality lookup, StoredCompanion
creation, saveGlobalConfig call, and sprite/stats rendering into that helper
(refer to symbols generateSeed, rollWithSeed, SPECIES_NAMES,
SPECIES_PERSONALITY, StoredCompanion, saveGlobalConfig, RARITY_STARS,
renderSprite, speciesLabel, renderStats). Replace the duplicated code in both
the rehatch handling and the auto-hatch handling to call hatchCompanion(), then
prepend/append the context-specific header/footer lines (e.g., "🎉 A new
companion appeared!" or auto-hatch message and "Your old companion has been
replaced!" only where appropriate) and pass the joined output to onDone as
before.
- Around line 68-82: In renderStats, guard against values outside 0–100 by
clamping the computed filled count so the progress bar always stays 20 chars;
instead of using filled = Math.round(val / 5) directly, compute filled =
Math.max(0, Math.min(20, Math.round(val / 5))) (or equivalent) before building
bar to ensure '█'.repeat(filled) and '░'.repeat(20 - filled) never receive
negative lengths; update the logic in the renderStats function accordingly.

In `@src/components/FullscreenLayout.tsx`:
- Around line 374-387: Remove the now-unused padCollapsed variable and update
the surrounding comment block to reflect the current behavior that paddingTop is
always 0; specifically delete the declaration "const padCollapsed = sticky !=
null && overlay == null", remove any other references to padCollapsed (including
the duplicate at the later location), and rewrite the comment above the
sticky/header logic to describe the simplified states and headerPrompt
calculation (using hideSticky, stickyPrompt, sticky and overlay) without
mentioning padding collapse. Ensure headerPrompt remains computed as "sticky !=
null && sticky !== 'clicked' && overlay == null ? sticky : null" and no other
code expects padCollapsed.

In `@src/utils/markdown.ts`:
- Around line 90-92: The inline-code color is hardcoded as '#FEC84A' in the
return that calls color(...)(token.text); change this to resolve via the theme
token instead of startsWith('dark') — either map concrete theme names (e.g.,
'dark-ansi', 'dark-daltonized') to the appropriate token or use an explicit
theme token key (e.g., 'inlineCode' or reuse 'permission') and pass that token
name to color(themeToken, theme) so color(...) looks up the palette from the
theme; update the branch that currently uses theme?.startsWith('dark') to use
the concrete theme names or the theme token lookup and keep the call as
color(themeToken, theme)(token.text).

In `@src/utils/theme.ts`:
- Around line 390-395: The daltonized light theme currently mixes brand
green/red for word-level diffs (diffAddedWord = BRAND_GREEN, diffRemovedWord =
BRAND_RED) which breaks consistency with darkDaltonizedTheme; change the light
daltonized variant to avoid the brand green by using the same non-green addition
color used by the daltonized dark theme (make diffAddedWord match the daltonized
addition blue) and ensure diffRemovedWord uses the corresponding daltonized
removal color so both daltonized themes present the same addition/removal colors
rather than a green/red split.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 470c92b1-a249-4260-badf-fa68a5597996

📥 Commits

Reviewing files that changed from the base of the PR and between 2b84333 and 3214e58.

📒 Files selected for processing (14)
  • build.ts
  • packages/color-diff-napi/src/index.ts
  • src/commands/buddy/buddy.ts
  • src/commands/buddy/index.ts
  • src/components/FullscreenLayout.tsx
  • src/components/HighlightedCode.tsx
  • src/components/Spinner/GlimmerMessage.tsx
  • src/components/Spinner/SpinnerAnimationRow.tsx
  • src/components/Spinner/SpinnerGlyph.tsx
  • src/components/ThemePicker.tsx
  • src/keybindings/defaultBindings.ts
  • src/keybindings/schema.ts
  • src/utils/markdown.ts
  • src/utils/theme.ts
💤 Files with no reviewable changes (4)
  • src/keybindings/defaultBindings.ts
  • src/keybindings/schema.ts
  • src/components/Spinner/SpinnerAnimationRow.tsx
  • src/components/Spinner/GlimmerMessage.tsx

Comment thread src/components/HighlightedCode.tsx Outdated
Comment thread src/components/Spinner/SpinnerGlyph.tsx Outdated
Comment thread src/components/ThemePicker.tsx Outdated
Comment thread src/utils/theme.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/components/ThemePicker.tsx (1)

155-161: ⚠️ Potential issue | 🟠 Major

ThemePicker status can still misreport highlighting state.

Lines 157-161 can show “enabled”/theme even when persisted settings.syntaxHighlightingDisabled still disables highlighting in src/components/StructuredDiff.tsx and src/components/Markdown.tsx. This keeps UI state inconsistent and removes any way to fix it from this screen. Please either read that persisted flag here or migrate/clear it with this PR path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/ThemePicker.tsx` around lines 155 - 161, ThemePicker currently
reports syntax highlighting as enabled based only on
colorModuleUnavailableReason/syntaxTheme, which can conflict with the persisted
flag settings.syntaxHighlightingDisabled used by StructuredDiff and Markdown;
update ThemePicker to read the persisted flag (e.g., from the same
settings/store used by StructuredDiff/Markdown) and use it to override the
displayed status (or, if you prefer migration, detect the legacy persisted flag
and clear/migrate it on load so ThemePicker and StructuredDiff/Markdown are
consistent). Locate ThemePicker (symbols: colorModuleUnavailableReason,
syntaxTheme) and either read settings.syntaxHighlightingDisabled before choosing
the message or perform a one-time migration that updates/clears
settings.syntaxHighlightingDisabled and then reflect that migrated state in the
displayed text.
🧹 Nitpick comments (2)
src/components/Spinner/SpinnerGlyph.tsx (1)

16-22: Remove unused stalledIntensity prop from SpinnerGlyph and GlimmerMessage.

stalledIntensity is declared in the Props type but never destructured or used in either component. The useStalledAnimation hook computes this value in SpinnerAnimationRow, but it is never passed downstream to these components.

Proposed fix for SpinnerGlyph.tsx
 type Props = {
   frame: number
   messageColor: keyof Theme
-  stalledIntensity?: number
   reducedMotion?: boolean
   time?: number
 }
Proposed fix for GlimmerMessage.tsx
 type Props = {
   message: string
   mode: SpinnerMode
   messageColor: keyof Theme
   glimmerIndex: number
   flashOpacity: number
   shimmerColor: keyof Theme
-  stalledIntensity?: number
 }

Also consider removing the stalledIntensity destructuring from SpinnerAnimationRow (line 126) since the value is never used after being computed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Spinner/SpinnerGlyph.tsx` around lines 16 - 22, Remove the
unused stalledIntensity prop throughout the spinner components: delete
stalledIntensity from the Props type in SpinnerGlyph (and GlimmerMessage if it
declares the same type), remove any stalledIntensity destructuring in the
SpinnerGlyph and GlimmerMessage components, and remove stalledIntensity from the
destructuring in SpinnerAnimationRow (where useStalledAnimation computes it).
Ensure no other references to stalledIntensity remain so the type and components
only accept and use frame, messageColor, reducedMotion, and time.
src/utils/theme.ts (1)

261-263: Keep the ANSI theme entries ANSI-only.

These two variants are documented as 16-color fallbacks, but briefLabelClaude now uses rgb(...). That makes this label depend on RGB quantization instead of the fixed ANSI palette these themes are supposed to guarantee.

♻️ Example adjustment
   briefLabelYou: 'ansi:blue',
-  briefLabelClaude: BRAND_COLOR,
+  briefLabelClaude: 'ansi:cyan',
   rainbow_red: 'ansi:red',

   briefLabelYou: 'ansi:blueBright',
-  briefLabelClaude: BRAND_COLOR,
+  briefLabelClaude: 'ansi:cyanBright',
   rainbow_red: 'ansi:red',

Also applies to: 342-344

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/theme.ts` around lines 261 - 263, The theme entries intended to be
ANSI-only include briefLabelYou, briefLabelClaude and rainbow_red, but
briefLabelClaude currently uses an rgb(...) value which breaks the ANSI-only
guarantee; update briefLabelClaude to use an ANSI palette token (e.g.,
'ansi:blue' or the ANSI variant of BRAND_COLOR) instead of rgb(...), and apply
the same fix to the duplicate entries around briefLabelYou/briefLabelClaude at
the later block (the entries at lines corresponding to the second occurrence),
ensuring all these keys use only 'ansi:...' values or the predefined ANSI
constant rather than rgb() notation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/ThemePicker.tsx`:
- Line 158: The ternary string in ThemePicker.tsx is exceeding the 120-char .tsx
line limit; refactor the long message expression (the ternary branch that
includes process.env.CLAUDE_CODE_SYNTAX_HIGHLIGHT) by breaking it into smaller
pieces: either build the message in a const above (e.g., const unavailableMsg =
... ) or split the template string across concatenated segments so each line
stays under 120 chars; ensure the refactor preserves the same text and includes
a trailing semicolon per Biome rules.

---

Duplicate comments:
In `@src/components/ThemePicker.tsx`:
- Around line 155-161: ThemePicker currently reports syntax highlighting as
enabled based only on colorModuleUnavailableReason/syntaxTheme, which can
conflict with the persisted flag settings.syntaxHighlightingDisabled used by
StructuredDiff and Markdown; update ThemePicker to read the persisted flag
(e.g., from the same settings/store used by StructuredDiff/Markdown) and use it
to override the displayed status (or, if you prefer migration, detect the legacy
persisted flag and clear/migrate it on load so ThemePicker and
StructuredDiff/Markdown are consistent). Locate ThemePicker (symbols:
colorModuleUnavailableReason, syntaxTheme) and either read
settings.syntaxHighlightingDisabled before choosing the message or perform a
one-time migration that updates/clears settings.syntaxHighlightingDisabled and
then reflect that migrated state in the displayed text.

---

Nitpick comments:
In `@src/components/Spinner/SpinnerGlyph.tsx`:
- Around line 16-22: Remove the unused stalledIntensity prop throughout the
spinner components: delete stalledIntensity from the Props type in SpinnerGlyph
(and GlimmerMessage if it declares the same type), remove any stalledIntensity
destructuring in the SpinnerGlyph and GlimmerMessage components, and remove
stalledIntensity from the destructuring in SpinnerAnimationRow (where
useStalledAnimation computes it). Ensure no other references to stalledIntensity
remain so the type and components only accept and use frame, messageColor,
reducedMotion, and time.

In `@src/utils/theme.ts`:
- Around line 261-263: The theme entries intended to be ANSI-only include
briefLabelYou, briefLabelClaude and rainbow_red, but briefLabelClaude currently
uses an rgb(...) value which breaks the ANSI-only guarantee; update
briefLabelClaude to use an ANSI palette token (e.g., 'ansi:blue' or the ANSI
variant of BRAND_COLOR) instead of rgb(...), and apply the same fix to the
duplicate entries around briefLabelYou/briefLabelClaude at the later block (the
entries at lines corresponding to the second occurrence), ensuring all these
keys use only 'ansi:...' values or the predefined ANSI constant rather than
rgb() notation.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8210fc2b-5a67-42ca-a47c-cdd2070a6587

📥 Commits

Reviewing files that changed from the base of the PR and between 3214e58 and 42a5888.

📒 Files selected for processing (14)
  • build.ts
  • packages/color-diff-napi/src/index.ts
  • src/commands/buddy/buddy.ts
  • src/commands/buddy/index.ts
  • src/components/FullscreenLayout.tsx
  • src/components/HighlightedCode.tsx
  • src/components/Spinner/GlimmerMessage.tsx
  • src/components/Spinner/SpinnerAnimationRow.tsx
  • src/components/Spinner/SpinnerGlyph.tsx
  • src/components/ThemePicker.tsx
  • src/keybindings/defaultBindings.ts
  • src/keybindings/schema.ts
  • src/utils/markdown.ts
  • src/utils/theme.ts
💤 Files with no reviewable changes (4)
  • src/keybindings/defaultBindings.ts
  • src/keybindings/schema.ts
  • src/components/Spinner/SpinnerAnimationRow.tsx
  • src/components/Spinner/GlimmerMessage.tsx
✅ Files skipped from review due to trivial changes (4)
  • build.ts
  • src/commands/buddy/index.ts
  • src/components/FullscreenLayout.tsx
  • src/utils/markdown.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/HighlightedCode.tsx
  • src/commands/buddy/buddy.ts

Comment thread packages/color-diff-napi/src/index.ts
Comment thread src/components/ThemePicker.tsx Outdated
Theme Colors:
- Change brand color from orange to blue (rgb(88,190,255))
- Add BRAND_COLOR, BRAND_COLOR_LIGHT, BRAND_RED, BRAND_GREEN constants
- Update all 6 theme variants with consistent brand palette
- Change permission/suggestion/remember to cyan-blue (rgb(131,210,238))
- Set dark theme userMessageBackground to rgb(15,15,15)
- Update diff colors to burgundy red and forest green

Syntax Highlighting:
- Add Royal Gold Dark theme (gold/blue palette, lower saturation)
- Replace Monokai Extended as default dark syntax theme
- Keep Ctrl+T toggle functionality in ThemePicker
- Support syntaxHighlightingDisabled setting in HighlightedCode

UI Behavior:
- Remove spinner stalled-to-red warning
- Remove top padding from FullscreenLayout
- Set inline code color to amber gold (#FEC84A) in dark themes

Buddy System:
- Add /buddy pet, rehatch, mute, unmute commands
- Add 20-char stat bars (████████░░) for companion stats
- Auto-hatch on first /buddy call
- Enable BUDDY feature in production builds

Files changed:
- build.ts, packages/color-diff-napi/src/index.ts
- src/utils/theme.ts, src/utils/markdown.ts
- src/components/Spinner/*.tsx
- src/components/FullscreenLayout.tsx, HighlightedCode.tsx, ThemePicker.tsx
- src/commands/buddy/buddy.ts, index.ts
- src/keybindings/defaultBindings.ts, schema.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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