feat(tui): make carbon the default decode UI#3
Conversation
- Add carbon theme (true black + programmer green) and set as default - Ignore inherited opencode config themes; /theme choice persists under decode_theme - New DECODE block wordmark, single source for home and exit epilogue - Session top strip with brand, title, and token budget - Prompt: green caret prefix, hairline full border, right-docked agent badge - Sidebar: CONTEXT/MODIFIED FILES/TODOS/MCP/LSP headers with green stats and context meter - Left-aligned home with full-width prompt field
|
Warning Review limit reached
Next review available in: 49 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe TUI adds Carbon theme support, changes theme persistence, refreshes logo and branding output, restructures prompt and session layouts, adds session budget information, and updates sidebar context, file, LSP, MCP, and todo summaries. ChangesTUI refresh
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Session
participant AssistantMessage
participant ProviderModelData
participant SessionHeader
Session->>AssistantMessage: read latest assistant output usage
Session->>ProviderModelData: resolve model context limit
Session->>SessionHeader: render tokens, limit, and cost
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
packages/tui/src/context/theme.tsx (1)
258-264: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMiddle fallback in
values()memo appears redundant.
store.activeis already initialized fromkv.get("decode_theme", DEFAULT_THEME)(line 124–125). Whenstore.themes[store.active]is falsy, the middle fallback readskv.get("decode_theme")— which returns the same value asstore.active— sostore.themes[saved]will also be falsy. The successful path is always either the first check or the finalDEFAULT_THEMEfallback.This is safe defensive code, but consider simplifying to reduce cognitive overhead.
♻️ Optional simplification
const values = createMemo(() => { const active = store.themes[store.active] if (active) return resolveTheme(active, store.mode) - const saved = kv.get("decode_theme") - if (typeof saved === "string") { - const theme = store.themes[saved] - if (theme) return resolveTheme(theme, store.mode) - } - return resolveTheme(store.themes[DEFAULT_THEME], store.mode) })🤖 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 `@packages/tui/src/context/theme.tsx` around lines 258 - 264, Remove the redundant kv.get("decode_theme") lookup and its associated fallback branch from the values() memo, leaving the existing store.active theme resolution and final DEFAULT_THEME fallback unchanged.packages/tui/src/feature-plugins/sidebar/context.tsx (2)
37-40: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMove
BAR_WIDTHabove its usage for readability.
BAR_WIDTHis referenced in thebarmemo (Line 38) but declared after theViewfunction (Line 64). It's safe at runtime sinceViewonly executes after module evaluation completes, but placing the constant near the top of the file (or aboveView) would make the dependency clearer.♻️ Proposed fix
+const BAR_WIDTH = 24 + function View(props: { api: TuiPluginApi; session_id: string }) { ... } - -const BAR_WIDTH = 24Also applies to: 64-65
🤖 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 `@packages/tui/src/feature-plugins/sidebar/context.tsx` around lines 37 - 40, Move the BAR_WIDTH constant declaration above the bar createMemo and before the View function, preserving its existing value and all current progress-bar behavior.
42-61: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftDuplicated sidebar header/toggle pattern across five files.
The header box (flex row,
justifyContent="space-between", arrow toggle gated onlist().length > 2,onMouseDowntogglingopen) is repeated nearly verbatim in this file and infiles.tsx,lsp.tsx,mcp.tsx, andtodo.tsx. Consider extracting a sharedSidebarSectionHeadercomponent (label, count/status slot, toggle behavior) to avoid five copies drifting out of sync.🤖 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 `@packages/tui/src/feature-plugins/sidebar/context.tsx` around lines 42 - 61, The sidebar section header and toggle behavior is duplicated across the context sidebar and the corresponding files, lsp, mcp, and todo components. Extract a shared SidebarSectionHeader component that accepts the section label, count/status content, list-based toggle visibility, open state, and toggle handler, then replace each local header implementation with it while preserving existing styling and behavior.
🤖 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 `@packages/tui/src/component/prompt/index.tsx`:
- Around line 1412-1430: Use the disabled-aware cursor color consistently in the
prompt input component: update the effect near the existing cursor-color
assignment and the deferred callback inside the textarea ref to assign
props.disabled ? theme.backgroundElement : theme.primary. Keep the declarative
cursorColor prop aligned with this same value.
In `@packages/tui/src/routes/session/index.tsx`:
- Around line 1180-1210: Update the session header layout around the title
<text> and budget <Show> block so the left segment can shrink within the
available width and the title truncation adapts to terminal width instead of
always using 60 characters. Preserve the non-shrinking budget block and ensure
the session ID and budget remain readable without overlap on narrow terminals.
---
Nitpick comments:
In `@packages/tui/src/context/theme.tsx`:
- Around line 258-264: Remove the redundant kv.get("decode_theme") lookup and
its associated fallback branch from the values() memo, leaving the existing
store.active theme resolution and final DEFAULT_THEME fallback unchanged.
In `@packages/tui/src/feature-plugins/sidebar/context.tsx`:
- Around line 37-40: Move the BAR_WIDTH constant declaration above the bar
createMemo and before the View function, preserving its existing value and all
current progress-bar behavior.
- Around line 42-61: The sidebar section header and toggle behavior is
duplicated across the context sidebar and the corresponding files, lsp, mcp, and
todo components. Extract a shared SidebarSectionHeader component that accepts
the section label, count/status content, list-based toggle visibility, open
state, and toggle handler, then replace each local header implementation with it
while preserving existing styling and behavior.
🪄 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: 764202b9-6af2-442e-bdb3-e332b8c3c2c0
📒 Files selected for processing (15)
packages/tui/src/component/logo.tsxpackages/tui/src/component/prompt/index.tsxpackages/tui/src/context/theme.tsxpackages/tui/src/feature-plugins/sidebar/context.tsxpackages/tui/src/feature-plugins/sidebar/files.tsxpackages/tui/src/feature-plugins/sidebar/footer.tsxpackages/tui/src/feature-plugins/sidebar/lsp.tsxpackages/tui/src/feature-plugins/sidebar/mcp.tsxpackages/tui/src/feature-plugins/sidebar/todo.tsxpackages/tui/src/logo.tspackages/tui/src/routes/home.tsxpackages/tui/src/routes/session/index.tsxpackages/tui/src/theme/assets/carbon.jsonpackages/tui/src/theme/index.tspackages/tui/src/util/presentation.ts
- Disabled-aware cursor color in all three assignment paths - Width-aware session strip title truncation with shrinkable left segment - Remove redundant decode_theme fallback in values() memo - Move BAR_WIDTH above its usage
Summary
Makes the Carbon design the default decode identity — true-black background with programmer green (#00e676), applied as both a theme and structural UI changes. This is decode's out-of-the-box look; it cannot be hijacked by inherited opencode configs.
Theme
carbon.jsontheme asset (54 keys, dark + light) registered and set asDEFAULT_THEMEconfig.themefrom inherited opencode configs is ignored; explicit/themechoices persist under a newdecode_themeKV key (stale legacy state ignored)Structural UI
DECODEart (white DE + green CODE), single source insrc/logo.tsshared by home splash and exit epilogue❯caret prefix ($in shell mode), hairline full border, right-docked agent badge cell (agent-only on home)Testing
bun typecheckclean (packages/tui)bun test191 pass / 0 failSummary by CodeRabbit
New Features
Style