feat: TUI customizations with brand colors and enhanced buddy system#141
feat: TUI customizations with brand colors and enhanced buddy system#141Icarus603 wants to merge 1 commit into
Conversation
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThe 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~28 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (6)
src/components/FullscreenLayout.tsx (1)
374-387: Remove unusedpadCollapsedvariable and update stale comments.The
paddingTopchange to always0leaves behind:
- Dead code:
padCollapsed(line 387) is now defined but never used- 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 == nullAlso 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 betweenrehatchand auto-hatch.The
rehatchblock (lines 106-145) and the auto-hatch block (lines 203-240) share nearly identical logic: generating a seed, rolling stats, looking up names/personalities, creatingStoredCompanion, 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
valexceeds 100,filledwould 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_GREENwhile removals stay red.darkDaltonizedThemestill 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-24treats#FEC84Aas a raw value, sodark-ansianddark-daltonizedskip 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 thanstartsWith('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
📒 Files selected for processing (14)
build.tspackages/color-diff-napi/src/index.tssrc/commands/buddy/buddy.tssrc/commands/buddy/index.tssrc/components/FullscreenLayout.tsxsrc/components/HighlightedCode.tsxsrc/components/Spinner/GlimmerMessage.tsxsrc/components/Spinner/SpinnerAnimationRow.tsxsrc/components/Spinner/SpinnerGlyph.tsxsrc/components/ThemePicker.tsxsrc/keybindings/defaultBindings.tssrc/keybindings/schema.tssrc/utils/markdown.tssrc/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
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/components/ThemePicker.tsx (1)
155-161:⚠️ Potential issue | 🟠 MajorThemePicker status can still misreport highlighting state.
Lines 157-161 can show “enabled”/theme even when persisted
settings.syntaxHighlightingDisabledstill disables highlighting insrc/components/StructuredDiff.tsxandsrc/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 unusedstalledIntensityprop from SpinnerGlyph and GlimmerMessage.
stalledIntensityis declared in the Props type but never destructured or used in either component. TheuseStalledAnimationhook 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
stalledIntensitydestructuring 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
briefLabelClaudenow usesrgb(...). 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
📒 Files selected for processing (14)
build.tspackages/color-diff-napi/src/index.tssrc/commands/buddy/buddy.tssrc/commands/buddy/index.tssrc/components/FullscreenLayout.tsxsrc/components/HighlightedCode.tsxsrc/components/Spinner/GlimmerMessage.tsxsrc/components/Spinner/SpinnerAnimationRow.tsxsrc/components/Spinner/SpinnerGlyph.tsxsrc/components/ThemePicker.tsxsrc/keybindings/defaultBindings.tssrc/keybindings/schema.tssrc/utils/markdown.tssrc/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
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>
Summary
This PR introduces comprehensive TUI customizations with a cohesive brand color palette and an enhanced
/buddycompanion system.Theme Colors
rgb(88,190,255))BRAND_COLOR,BRAND_COLOR_LIGHT,BRAND_RED,BRAND_GREENconstantsrgb(131,210,238))userMessageBackgroundto#0f0f0ffor better contrastSyntax Highlighting
UI Behavior
#FEC84A) in dark themesKeybindings
theme:toggleSyntaxHighlightingaction and Ctrl+T bindingBuddy System Enhancements
/buddy pet- Trigger heart animation + companion reaction/buddy rehatch- Re-roll a new companion with full stats display/buddy mute//buddy unmute- Show/hide companion/buddycall (no explicit hatch needed)Files Changed
build.ts- Add BUDDY to default build featurespackages/color-diff-napi/src/index.ts- Royal Gold Dark theme, brand diff colorssrc/utils/theme.ts- Brand color constants, theme updatessrc/utils/markdown.ts- Inline code color for dark themessrc/components/Spinner/*.tsx- Remove stalled warningsrc/components/ThemePicker.tsx- Remove syntax toggle UIsrc/components/FullscreenLayout.tsx- Remove top paddingsrc/components/HighlightedCode.tsx- Remove syntax toggle checksrc/keybindings/defaultBindings.ts- Remove Ctrl+T bindingsrc/keybindings/schema.ts- Remove toggle actionsrc/commands/buddy/buddy.ts- Enhanced buddy commands with statssrc/commands/buddy/index.ts- Updated command hintsTest Plan
/buddyauto-hatches on first use/buddy pettriggers heart animation/buddy rehatchcreates new companion with stats🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
/buddy rehatchsubcommand to generate a new companion./buddymute controls fromoff/ontomute/unmute.Updates
Bug Fixes