Skip to content

Settings + Themes - #158

Merged
AviPeltz merged 11 commits into
mainfrom
theme
Nov 27, 2025
Merged

AviPeltz merged 11 commits into
mainfrom
theme

Conversation

@AviPeltz

@AviPeltz AviPeltz commented Nov 27, 2025 •

Copy link
Copy Markdown
Collaborator

Description

Related Issues

Type of Change

  • Bug fix
  • [x ] New feature
  • Documentation
  • [x ] Refactor
  • Other (please describe):

Testing

Screenshots (if applicable)

Additional Notes

  • just added it cause i wanted to standardize the color themes for start page and other ui features

Summary by CodeRabbit

  • New Features

    • Settings panel accessible from the top bar with a two‑pane settings UI and appearance section
    • Theme browser and selection UI (theme cards) plus built‑in light/dark/Monokai/One Dark themes and custom theme support
  • Enhancements

    • Full theming system with persisted preferences, preview, and flash‑free startup theming
    • Terminals adopt selected theme dynamically (background and colors)
  • Enhancements / Terminal

    • Stateful terminal escape filtering with buffered handling and flush-on-exit
  • Security

    • Stricter Content Security Policy applied to renderer HTML

✏️ Tip: You can customize this high-level summary in your review settings.

AviPeltz and others added 7 commits November 26, 2025 20:30
- Store now syncs theme-id (not just theme-type) to localStorage
- getDefaultTerminalTheme() looks up actual theme by ID from builtInThemes
- Monokai/One Dark users get correct terminal colors on first paint

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Store now caches theme.terminal JSON in localStorage
- getDefaultTerminalTheme() reads cached colors first
- Future-proofs custom themes without needing builtInThemes lookup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Tests cached terminal colors from localStorage
- Tests fallback to theme-id lookup
- Tests fallback to default dark theme
- Tests graceful handling of invalid JSON
- Mocks trpc-client to avoid electronTRPC dependency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 27, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a stateful TerminalEscapeFilter and wires it per-terminal session (with flush-on-exit), expands terminal escape patterns, and implements a full theming system (types, built-in themes, store, utilities, boot script) plus Settings UI and terminal theme wiring.

Changes

Cohort / File(s) Summary
Terminal escape filtering
apps/desktop/src/main/lib/terminal-escape-filter.ts, apps/desktop/src/main/lib/terminal-escape-filter.test.ts
Add exported TerminalEscapeFilter class with buffering, filter/flush/reset, heuristics for incomplete sequences; expand FILTER_PATTERNS (standardModeReport, unknownCSI_O, relaxed oscColorResponse); expose patterns and keep stateless filterTerminalQueryResponses as legacy. Tests added for chunked reassembly, buffering, flush/reset, and passthrough.
Terminal integration & history
apps/desktop/src/main/lib/terminal-manager.ts, apps/desktop/src/main/lib/terminal-history.ts
Per-session escapeFilter: TerminalEscapeFilter created and used (replace stateless filter call); filtered output written to scrollback/history; filter flushed on PTY exit. Minor import consolidation in history file.
Terminal theming & wiring
apps/desktop/src/renderer/.../Terminal/helpers.ts, .../helpers.test.ts, .../SetupTerminal/SetupTerminal.tsx, .../Terminal/Terminal.tsx
Add getDefaultTerminalTheme and getDefaultTerminalBg; extend createTerminalInstance to accept initial theme; add useTerminalTheme usage and dynamic xterm theme updates; tests for theming fallback and caching.
Theme types & built-ins
apps/desktop/src/shared/themes/types.ts, apps/desktop/src/shared/themes/built-in/*.ts, apps/desktop/src/shared/themes/built-in/index.ts, apps/desktop/src/shared/themes/index.ts
Add UIColors, TerminalColors, Theme, ThemeMetadata types; add built-in themes (dark, light, monokai, one-dark), builtInThemes array, DEFAULT_THEME_ID, getBuiltInTheme, and barrel exports.
Theme store & utilities
apps/desktop/src/renderer/stores/theme/store.ts, .../utils/css-variables.ts, .../utils/terminal-theme.ts, .../utils/index.ts, .../theme/index.ts
Implement Zustand theme store (persistence, applyTheme, terminalTheme conversion), utilities to apply CSS variables, update theme class, clear variables, and convert terminal colors to xterm ITheme. Expose hooks: useThemeStore, useTheme, useTerminalTheme, useSetTheme, useThemeId.
App state & stores index
apps/desktop/src/renderer/stores/app-state.ts, apps/desktop/src/renderer/stores/index.ts
Add AppView state with useAppStore, useCurrentView, useOpenSettings, useCloseSettings; re-export new stores from stores index.
Settings UI
apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx, .../SettingsSidebar.tsx, .../SettingsContent.tsx, .../AppearanceSettings.tsx, .../components/ThemeCard/*
New SettingsView two-pane layout with Sidebar, Content, AppearanceSettings and ThemeCard components; theme selection grid and selection handling; exports updated.
Top bar & settings button
apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/*, apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
Add SettingsButton component (opens settings) and insert into TopBar.
Main view routing & hotkeys
apps/desktop/src/renderer/screens/main/index.tsx
Use useCurrentView to conditionally render SettingsView vs WorkspaceView and guard workspace-only hotkeys (meta+s, meta+d, meta+shift+d).
HTML/CSS theme boot & CSP
apps/desktop/src/renderer/index.html, apps/desktop/src/renderer/globals.css, apps/desktop/src/resources/public/theme-boot.js
Remove hardcoded dark class, inject theme-boot.js to set theme pre-hydration, reorganize CSS variables into :root/.dark/:root.light, and tighten Content Security Policy.
Exports & barrels
apps/desktop/src/renderer/stores/theme/index.ts, apps/desktop/src/renderer/stores/index.ts, apps/desktop/src/shared/themes/index.ts
Add/restructure re-exports for theme hooks, utilities, and theme definitions.

Sequence Diagram(s)

sequenceDiagram
    participant PTY as PTY Process
    participant Session as TerminalSession
    participant Filter as TerminalEscapeFilter
    participant Scroll as Scrollback
    participant XTerm as XTerm

    PTY->>Session: data(chunk)
    Session->>Filter: filter(chunk)
    activate Filter
    Filter->>Filter: buffer & detect complete sequences
    alt complete sequences
        Filter-->>Session: filteredOutput
    else partial tail
        Filter-->>Session: filteredOutput (without incomplete tail)
    end
    deactivate Filter
    Session->>XTerm: emit original data (unfiltered)
    Session->>Scroll: write filteredOutput
    Note right of Session: on PTY exit
    Session->>Filter: flush()
    Filter-->>Session: remaining filtered data
    Session->>Scroll: write flushed data
Loading
sequenceDiagram
    participant App as Renderer
    participant Store as Theme Store
    participant Utils as Theme Utils
    participant DOM

    App->>Store: initialize (rehydrate)
    activate Store
    Store->>Store: read persisted activeThemeId & terminal cache
    Store->>Utils: applyUIColors(theme.ui)
    Utils->>DOM: set CSS variables
    Store->>Utils: updateThemeClass(type)
    Utils->>DOM: set root class (dark|light)
    Store->>Store: toXtermTheme(theme.terminal)
    deactivate Store
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas needing extra attention:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts — buffering heuristics, regex patterns, edge cases for split sequences and flush behavior.
  • apps/desktop/src/main/lib/terminal-manager.ts — session lifecycle, correct creation and flush of per-session filter.
  • apps/desktop/src/renderer/stores/theme/store.ts and css-variables.ts — persistence/rehydration ordering, DOM mutation timing to avoid flash.
  • createTerminalInstance signature changes — ensure all call sites updated and theme application order prevents visual flicker.

Possibly related PRs

Poem

🐰
I stitched the themes with whiskered care,
Buffered the echoes of bytes in the air.
Dark or light, the terminal gleams—
Settings open, and color streams.
Hop, click, apply — a rabbit's small cheer!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description follows the template structure with Type of Change selections (New feature, Refactor), but critical sections lack detail: Description, Related Issues, Testing, and Screenshots are all empty or minimally filled. Complete the Description section with specifics on theme functionality, add any related issue links, document testing steps, and provide screenshots showing the new Settings UI and theme selection.
Docstring Coverage ⚠️ Warning Docstring coverage is 55.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Settings + Themes' is concise and directly reflects the main changes: adding a Settings view with theme management UI and comprehensive theming infrastructure.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch theme

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.

❤️ Share

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: 3

Caution

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

⚠️ Outside diff range comments (2)
apps/desktop/src/renderer/screens/main/index.tsx (1)

19-59: Hotkey shortcuts must be centralized in a dedicated system per coding guidelines

The code embeds hotkeys directly in components, but the coding guideline requires defining keyboard shortcuts using apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions. This centralized system doesn't currently exist. Create shortcuts.ts to define all keyboard shortcuts in one place, then import and register them in components.

As a secondary improvement, once centralized, you can use the enabled option from react-hotkeys-hook v5.2.1 (which supports conditional registration via enabled: isWorkspaceView) instead of manual guards inside callbacks for cleaner separation of concerns.

apps/desktop/src/renderer/globals.css (1)

204-232: Scrollbar styling is hardcoded for dark mode.

The scrollbar colors use fixed rgb(63 63 70 / ...) values which are optimized for dark backgrounds. In light theme, these dark scrollbars may appear visually inconsistent. Consider using theme-aware variables or adding .light overrides.

+/* Light mode scrollbar styling */
+:root.light * {
+	scrollbar-color: rgb(200 200 200 / 0.5) transparent;
+}
+
+:root.light *::-webkit-scrollbar-thumb {
+	background-color: rgb(180 180 180 / 0.5);
+}
+
+:root.light *::-webkit-scrollbar-thumb:hover {
+	background-color: rgb(160 160 160 / 0.7);
+}
+
+:root.light *::-webkit-scrollbar-thumb:active {
+	background-color: rgb(140 140 140 / 0.8);
+}
🧹 Nitpick comments (4)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts (1)

39-54: Consider splitting test with multiple assertions.

This test has three assertions checking different properties. Per coding guidelines, tests should have one assert per test for clarity and easier debugging when failures occur. Based on learnings, tests should be readable and independent.

-	it("should return cached terminal colors from localStorage", () => {
+	it("should return cached background from localStorage", () => {
 		const cachedTerminal = {
 			background: "#272822",
 			foreground: "#f8f8f2",
 			cursor: "#f8f8f0",
 			red: "#f92672",
 			green: "#a6e22e",
 		};
 		localStorage.setItem("theme-terminal", JSON.stringify(cachedTerminal));
 
 		const theme = getDefaultTerminalTheme();
 
 		expect(theme.background).toBe("#272822");
-		expect(theme.foreground).toBe("#f8f8f2");
-		expect(theme.cursor).toBe("#f8f8f0");
 	});
+
+	it("should return cached foreground from localStorage", () => {
+		const cachedTerminal = {
+			background: "#272822",
+			foreground: "#f8f8f2",
+			cursor: "#f8f8f0",
+		};
+		localStorage.setItem("theme-terminal", JSON.stringify(cachedTerminal));
+
+		const theme = getDefaultTerminalTheme();
+
+		expect(theme.foreground).toBe("#f8f8f2");
+	});
+
+	it("should return cached cursor from localStorage", () => {
+		const cachedTerminal = {
+			background: "#272822",
+			foreground: "#f8f8f2",
+			cursor: "#f8f8f0",
+		};
+		localStorage.setItem("theme-terminal", JSON.stringify(cachedTerminal));
+
+		const theme = getDefaultTerminalTheme();
+
+		expect(theme.cursor).toBe("#f8f8f0");
+	});
apps/desktop/src/renderer/globals.css (1)

57-93: Missing --radius in light theme block.

The :root block defines --radius: 0.625rem (line 46), but :root.light doesn't include it. While this may be intentional (same radius for both themes), explicitly including it would maintain consistency and make the light theme self-contained.

 	--sidebar-border: oklch(0.922 0 0);
 	--sidebar-ring: oklch(0.708 0 0);
+	--radius: 0.625rem;
 }
apps/desktop/src/shared/themes/built-in/index.ts (1)

10-27: LGTM! Well-organized theme aggregation.

The aggregation pattern is clean and the getBuiltInTheme helper provides convenient lookup. The array size (4 themes) makes the find() approach perfectly acceptable.

One optional improvement for type safety:

-export const DEFAULT_THEME_ID = "dark";
+export const DEFAULT_THEME_ID = "dark" as const;

-export const builtInThemes: Theme[] = [
+export const builtInThemes: readonly Theme[] = [
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (1)

5-10: Theme bootstrap via localStorage looks solid; consider centralizing key constants

The helpers correctly prefer cached terminal colors, fall back to a theme-id lookup, and finally to a hard-coded safe default, with try/catch to tolerate missing/localStorage issues. This should minimize terminal theme flash on startup.

To avoid drift between this file and renderer/stores/theme/store.ts, consider exporting shared constants for "theme-id" / "theme-terminal" (and "theme-type" if relevant) from a small themes-storage util and reusing them here instead of literal strings.

Also applies to: 14-48

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e26dad and ceb9c01.

📒 Files selected for processing (33)
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts (3 hunks)
  • apps/desktop/src/main/lib/terminal-escape-filter.ts (2 hunks)
  • apps/desktop/src/main/lib/terminal-history.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal-manager.ts (3 hunks)
  • apps/desktop/src/renderer/globals.css (3 hunks)
  • apps/desktop/src/renderer/index.html (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx (4 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (4 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/index.tsx (4 hunks)
  • apps/desktop/src/renderer/stores/app-state.ts (1 hunks)
  • apps/desktop/src/renderer/stores/index.ts (1 hunks)
  • apps/desktop/src/renderer/stores/theme/index.ts (1 hunks)
  • apps/desktop/src/renderer/stores/theme/store.ts (1 hunks)
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts (1 hunks)
  • apps/desktop/src/renderer/stores/theme/utils/index.ts (1 hunks)
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts (1 hunks)
  • apps/desktop/src/resources/public/theme-boot.js (1 hunks)
  • apps/desktop/src/shared/themes/built-in/dark.ts (1 hunks)
  • apps/desktop/src/shared/themes/built-in/index.ts (1 hunks)
  • apps/desktop/src/shared/themes/built-in/light.ts (1 hunks)
  • apps/desktop/src/shared/themes/built-in/monokai.ts (1 hunks)
  • apps/desktop/src/shared/themes/built-in/one-dark.ts (1 hunks)
  • apps/desktop/src/shared/themes/index.ts (1 hunks)
  • apps/desktop/src/shared/themes/types.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/shared/themes/built-in/monokai.ts
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/renderer/stores/theme/utils/index.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/resources/public/theme-boot.js
  • apps/desktop/src/shared/themes/built-in/dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/shared/themes/built-in/one-dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/shared/themes/built-in/index.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/shared/themes/built-in/monokai.ts
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/renderer/stores/theme/utils/index.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/shared/themes/built-in/dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/shared/themes/built-in/one-dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/shared/themes/built-in/index.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/shared/themes/built-in/monokai.ts
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/renderer/stores/theme/utils/index.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/shared/themes/built-in/dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/shared/themes/built-in/one-dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/shared/themes/built-in/index.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
apps/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use one component per file; do not create multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Define keyboard shortcuts using the centralized system in apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/shared/themes/built-in/monokai.ts
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/renderer/stores/theme/utils/index.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/resources/public/theme-boot.js
  • apps/desktop/src/shared/themes/built-in/dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/shared/themes/built-in/one-dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/shared/themes/built-in/index.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
  • apps/desktop/src/shared/themes/built-in/monokai.ts
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/renderer/stores/theme/utils/index.ts
  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/shared/themes/built-in/dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx
  • apps/desktop/src/shared/themes/built-in/one-dark.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx
  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/shared/themes/built-in/index.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
apps/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
apps/desktop/**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.test.{ts,tsx,js,jsx}: Tests should have one assert per test
Tests should be readable
Tests should be fast
Tests should be independent
Tests should be repeatable

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
🧠 Learnings (16)
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/renderer/**/*.tsx : Define keyboard shortcuts using the centralized system in apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions

Applied to files:

  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : Implement Electron IPC handlers in dedicated files under apps/desktop/src/main/lib/ (e.g., workspace-ipcs.ts, terminal-ipcs.ts)

Applied to files:

  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/main/lib/terminal-history.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx
  • apps/desktop/src/renderer/stores/app-state.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/index.tsx
  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/index.ts
  • apps/desktop/src/renderer/stores/app-state.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to packages/ui/**/*.{tsx,ts} : Use TailwindCSS v4 and shadcn/ui for UI component styling and design

Applied to files:

  • apps/desktop/src/renderer/stores/theme/utils/css-variables.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.{tsx,ts} : Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Applied to files:

  • apps/desktop/src/renderer/stores/theme/index.ts
  • apps/desktop/src/renderer/stores/index.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be readable

Applied to files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be independent

Applied to files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be repeatable

Applied to files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.test.{ts,tsx} : Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be fast

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to @(apps/desktop/src/renderer|apps/desktop/src/shared)/**/*.{ts,tsx} : Never import Node.js modules in Electron renderer process or shared code; use IPC for communication between main and renderer processes

Applied to files:

  • apps/desktop/src/renderer/stores/index.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/lib/electron-router-dom.ts : Do not import Node.js modules in apps/desktop/src/lib/electron-router-dom.ts as it is shared between main and renderer processes

Applied to files:

  • apps/desktop/src/renderer/stores/index.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/**/*.{tsx,ts} : Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export

Applied to files:

  • apps/desktop/src/renderer/stores/index.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables from monorepo root .env file in apps/desktop/src/main/index.ts before any imports with override: true

Applied to files:

  • apps/desktop/src/renderer/stores/index.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Applied to files:

  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/renderer/stores/app-state.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx
🧬 Code graph analysis (16)
apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1)
  • SettingsSidebar (23-65)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)
  • SettingsContent (8-14)
apps/desktop/src/shared/themes/built-in/monokai.ts (3)
apps/desktop/src/shared/themes/built-in/index.ts (1)
  • monokaiTheme (30-30)
apps/desktop/src/shared/themes/index.ts (2)
  • monokaiTheme (10-10)
  • Theme (13-13)
apps/desktop/src/shared/themes/types.ts (1)
  • Theme (108-131)
apps/desktop/src/shared/themes/types.ts (1)
apps/desktop/src/shared/themes/index.ts (4)
  • UIColors (13-13)
  • TerminalColors (13-13)
  • Theme (13-13)
  • ThemeMetadata (13-13)
apps/desktop/src/renderer/screens/main/index.tsx (3)
apps/desktop/src/renderer/stores/app-state.ts (1)
  • useCurrentView (35-35)
apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx (1)
  • SettingsView (7-22)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/index.tsx (1)
  • WorkspaceView (14-88)
apps/desktop/src/shared/themes/built-in/dark.ts (3)
apps/desktop/src/shared/themes/built-in/index.ts (1)
  • darkTheme (30-30)
apps/desktop/src/shared/themes/index.ts (2)
  • darkTheme (7-7)
  • Theme (13-13)
apps/desktop/src/shared/themes/types.ts (1)
  • Theme (108-131)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx (1)
  • SettingsSection (5-5)
apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx (1)
  • AppearanceSettings (6-49)
apps/desktop/src/shared/themes/built-in/one-dark.ts (3)
apps/desktop/src/shared/themes/built-in/index.ts (1)
  • oneDarkTheme (30-30)
apps/desktop/src/shared/themes/index.ts (2)
  • oneDarkTheme (11-11)
  • Theme (13-13)
apps/desktop/src/shared/themes/types.ts (1)
  • Theme (108-131)
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (3)
apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx (1)
  • SettingsSection (5-5)
apps/desktop/src/renderer/stores/app-state.ts (1)
  • useCloseSettings (37-38)
packages/ui/src/lib/utils.ts (1)
  • cn (4-6)
apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (2)
apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts (1)
  • SettingsButton (1-1)
apps/desktop/src/renderer/stores/app-state.ts (1)
  • useOpenSettings (36-36)
apps/desktop/src/main/lib/terminal-escape-filter.test.ts (1)
apps/desktop/src/main/lib/terminal-escape-filter.ts (3)
  • filterTerminalQueryResponses (246-248)
  • filter (115-138)
  • TerminalEscapeFilter (108-236)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (2)
  • getDefaultTerminalTheme (19-40)
  • getDefaultTerminalBg (46-48)
apps/desktop/src/main/lib/terminal-manager.ts (1)
apps/desktop/src/main/lib/terminal-escape-filter.ts (1)
  • TerminalEscapeFilter (108-236)
apps/desktop/src/shared/themes/built-in/index.ts (4)
apps/desktop/src/shared/themes/types.ts (1)
  • Theme (108-131)
apps/desktop/src/shared/themes/built-in/dark.ts (1)
  • darkTheme (6-77)
apps/desktop/src/shared/themes/built-in/light.ts (1)
  • lightTheme (6-77)
apps/desktop/src/shared/themes/built-in/monokai.ts (1)
  • monokaiTheme (6-78)
apps/desktop/src/renderer/stores/theme/store.ts (7)
apps/desktop/src/shared/themes/index.ts (4)
  • Theme (13-13)
  • ThemeMetadata (13-13)
  • builtInThemes (5-5)
  • DEFAULT_THEME_ID (6-6)
apps/desktop/src/shared/themes/types.ts (2)
  • Theme (108-131)
  • ThemeMetadata (136-143)
apps/desktop/src/shared/themes/built-in/index.ts (2)
  • builtInThemes (10-15)
  • DEFAULT_THEME_ID (20-20)
apps/desktop/src/renderer/stores/theme/utils/css-variables.ts (2)
  • applyUIColors (46-55)
  • updateThemeClass (60-69)
apps/desktop/src/renderer/stores/theme/utils/index.ts (3)
  • applyUIColors (2-2)
  • updateThemeClass (4-4)
  • toXtermTheme (6-6)
apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts (1)
  • toXtermTheme (7-36)
apps/desktop/src/renderer/lib/electron-storage.ts (1)
  • electronStorage (20-20)
apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx (1)
apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (1)
  • SettingsButton (4-17)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx (2)
apps/desktop/src/renderer/stores/theme/store.ts (1)
  • useTerminalTheme (184-185)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (2)
  • createTerminalInstance (50-113)
  • getDefaultTerminalBg (46-48)
🔇 Additional comments (48)
apps/desktop/src/main/lib/terminal-history.ts (1)

1-1: LGTM - Clean import consolidation.

The consolidated import statement improves readability without any functional changes.

apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/index.ts (1)

1-1: LGTM - Correct barrel export pattern.

Follows the component structure guidelines properly.

apps/desktop/src/resources/public/theme-boot.js (1)

1-12: LGTM - Effective FOUC prevention.

The implementation correctly applies the saved theme before React hydration with proper error handling and a sensible fallback to dark mode.

apps/desktop/src/renderer/stores/index.ts (1)

7-10: LGTM - Clean store exports.

The new exports properly surface the app-state and theme store APIs through the centralized barrel.

apps/desktop/src/renderer/screens/main/components/TopBar/SettingsButton/SettingsButton.tsx (1)

1-17: LGTM - Well-structured component.

The component follows all guidelines correctly:

  • Proper file structure (SettingsButton/SettingsButton.tsx with barrel export)
  • Good accessibility with aria-label
  • Appropriate use of zustand store hook
  • Explicit button type
apps/desktop/src/renderer/stores/theme/utils/index.ts (1)

1-6: LGTM - Clean utility exports.

The barrel export properly centralizes theme utility access.

apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx (2)

2-2: LGTM - Clean component integration.

The SettingsButton is properly imported and integrated into the top bar.


24-24: LGTM - Logical placement.

The settings button is appropriately positioned with other top bar controls.

apps/desktop/src/renderer/screens/main/index.tsx (1)

61-69: View-based switching between SettingsView and WorkspaceView is clean and centralized

Using currentView from the app-state store to toggle between <SettingsView /> and <WorkspaceView /> keeps main-screen navigation centralized and predictable. This fits well with the new settings screen without adding extra local state.

apps/desktop/src/shared/themes/built-in/monokai.ts (1)

6-77: Monokai theme definition is consistent and complete

The monokaiTheme object cleanly matches the Theme/TerminalColors shape and covers all the standard + bright ANSI slots, so it should plug into the theme store and xterm theming without surprises.

apps/desktop/src/renderer/stores/theme/utils/terminal-theme.ts (1)

7-35: toXtermTheme is a straightforward, correct adapter

The function cleanly forwards every TerminalColors field to the corresponding ITheme key, so xterm will see exactly the configured palette with no transformations or omissions. This should be easy to keep in sync if either type evolves.

apps/desktop/src/shared/themes/built-in/dark.ts (1)

6-76: Dark theme aligns with the shared Theme model and looks ready as a default

The darkTheme object follows the shared Theme shape, uses OKLCH for UI colors, and provides a complete terminal ANSI palette, making it a solid choice for the default/built-in dark theme.

apps/desktop/src/shared/themes/built-in/one-dark.ts (1)

6-77: One Dark theme is well-structured and consistent with other built-ins

The oneDarkTheme definition mirrors the other built-in themes (metadata, UI tokens, full ANSI + bright terminal palette), so it should integrate smoothly with the theme store and selector UI.

apps/desktop/src/renderer/index.html (1)

5-19: Theme boot + stricter CSP look good; please verify dev/HMR and preload behavior

Loading theme-boot.js before the body plus tightening CSP to script-src 'self' and restricted connect-src greatly improves security and should reduce theme flash, but it can also break dev tooling or any non-local resources if they’re still in use (e.g., HMR over HTTP, external fonts/scripts). Please run through your dev and packaged builds to confirm everything still works as expected with this CSP and with theme-boot.js being a non-module script.

apps/desktop/src/renderer/stores/theme/index.ts (1)

1-7: Barrel exporting theme hooks keeps the public store API tidy

Re-exporting the theme hooks from ./store gives consumers a clean, stable import path and matches the pattern used by other stores.

apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx (1)

6-48: Theme selection flow is straightforward and integrates cleanly with the theme store

Composing allThemes from builtInThemes and customThemes, then wiring ThemeCard’s onSelect to setTheme(theme.id) gives you a simple, predictable theme picker that’s fully driven by the centralized theme store. The copy and layout are clear, and using the renderer/stores and shared/themes aliases aligns with the path-alias guidelines.

As per coding guidelines, this alias usage is spot on.

apps/desktop/src/shared/themes/built-in/light.ts (1)

1-77: LGTM! Well-structured light theme definition.

The theme follows the established Theme interface pattern, with consistent use of oklch for UI colors and hex for terminal colors. The metadata and color tokens align with the CSS fallback values in globals.css (lines 58-93).

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts (1)

56-103: Good test coverage for fallback scenarios.

The remaining tests properly validate the fallback chain: theme-id lookup → default dark theme → graceful JSON error handling. Each test has a single assertion and is independent. The getDefaultTerminalBg tests appropriately verify the wrapper function behavior.

apps/desktop/src/shared/themes/index.ts (1)

1-13: LGTM! Clean barrel export structure.

The centralized re-exports allow consumers to import all theme-related entities from a single location. Minor nit: the comment on line 1 says "Theme types" but the file exports both theme objects and types - consider updating to "Theme exports" or removing the comments since the exports are self-documenting.

apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsSidebar.tsx (1)

1-65: LGTM! Clean settings sidebar implementation.

The component follows good patterns: single responsibility, proper button types for accessibility, extensible SECTIONS array for future additions, and appropriate use of the cn utility for conditional styling. The back button correctly integrates with the app store via useCloseSettings.

apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsContent.tsx (1)

8-14: LGTM! Appropriate content routing pattern.

The conditional rendering is suitable for the current single-section setup. As more sections are added, consider refactoring to a switch statement or object lookup pattern for better maintainability.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx (2)

78-198: terminalTheme used but not in dependency array.

terminalTheme is passed to createTerminalInstance (line 85) but isn't included in the effect's dependency array (line 198). If terminalTheme changes before the initial mount effect runs, the terminal could be created with a stale theme. While the second effect (lines 201-208) handles runtime theme updates, the initial creation might use incorrect colors.

This may be intentional to prevent terminal recreation on theme change. Please verify if this is the desired behavior, or if terminalTheme should be added to the deps with appropriate handling:

-	}, [tabId, workspaceId, setActiveTab, workspaceCwd, tabTitle]);
+	}, [tabId, workspaceId, setActiveTab, workspaceCwd, tabTitle, terminalTheme]);

Note: Adding it would cause terminal recreation on theme change, which the second effect already handles more gracefully. The current pattern may be correct.


200-220: Good theme update pattern.

The separate effect for theme updates is a clean approach that avoids recreating the terminal instance. The null guards and comment about xterm v5 behavior are helpful. The background fallback via getDefaultTerminalBg() ensures consistent styling before hydration.

apps/desktop/src/main/lib/terminal-escape-filter.test.ts (6)

1-5: LGTM!

Import updated to include TerminalEscapeFilter alongside the existing filterTerminalQueryResponses. This aligns with the new stateful filter class being tested.


217-232: LGTM!

Good addition of edge case tests for short-form hex color responses. These tests cover 2-digit (f5/f5/f5), 3-digit (fff/fff/fff), and both BEL and ST terminators, ensuring the filter handles various real-world OSC color response formats.


234-244: LGTM!

Standard mode report tests provide good coverage for the ESC[n;m$y format with different parameter combinations.


366-459: LGTM!

Excellent test coverage for the stateful TerminalEscapeFilter. The chunked data tests verify critical behaviors:

  • Split sequence reassembly (DA1, CPR, OSC, standard mode reports)
  • Conservative buffering decisions (ESC alone and ESC[ alone pass through)
  • Color codes correctly pass through after completion despite initial buffering

The tests are readable, independent, and repeatable. Based on learnings, this aligns with the test guidelines.


461-486: LGTM!

Flush and reset tests verify proper session cleanup semantics. The flush behavior test at line 469 correctly expects the incomplete sequence to pass through (since incomplete sequences can't be definitively identified as query responses).


488-504: LGTM!

These tests ensure the stateful filter doesn't inadvertently delay or corrupt normal terminal output. The chunk boundary test at lines 495-502 verifies ANSI colors remain intact even when split across data events.

apps/desktop/src/shared/themes/types.ts (3)

1-69: LGTM!

Well-structured UIColors interface with comprehensive coverage of UI chrome colors. The JSDoc comments clearly document the purpose of each color category (core backgrounds, cards, popovers, actions, etc.).


71-103: LGTM!

TerminalColors interface correctly models the ANSI 16-color palette with appropriate optional fields for cursor accent and selection colors. This aligns with xterm.js theming requirements.


105-143: LGTM!

The Theme and ThemeMetadata interfaces are well-designed. The distinction between optional isBuiltIn/isCustom on Theme and required on ThemeMetadata makes sense—ThemeMetadata is specifically for list displays where these flags are always needed, while Theme objects may be constructed without these flags initially.

apps/desktop/src/renderer/stores/theme/utils/css-variables.ts (3)

6-41: LGTM!

The UI_COLOR_TO_CSS_VAR mapping is complete and correctly maps all UIColors properties to their corresponding CSS custom property names. The naming convention follows kebab-case for CSS variables.


46-55: LGTM!

The applyUIColors function correctly applies theme colors to CSS variables. The truthy check on line 51 appropriately skips undefined or empty values, preventing invalid CSS variable assignments.


60-79: LGTM!

updateThemeClass correctly manages the dark/light class toggle, ensuring only one is active at a time. clearThemeVariables provides a clean reset mechanism for reverting to stylesheet defaults.

apps/desktop/src/main/lib/terminal-manager.ts (4)

6-6: LGTM!

Import and type definition correctly updated to use the new stateful TerminalEscapeFilter class. Adding escapeFilter to TerminalSession interface ensures each session maintains its own buffer state for chunked data handling.

Also applies to: 22-22


139-139: LGTM!

Per-session TerminalEscapeFilter instance ensures buffer state isolation between terminal sessions.


142-150: LGTM!

The data handling design is correct:

  • Filtered data goes to scrollback/history storage (removes terminal query responses)
  • Raw data goes to xterm (preserves DA/DSR/OSC responses needed for terminal behavior)

The comments clearly document this intentional divergence in data paths.


152-161: LGTM!

Flush on exit ensures any buffered partial sequences are processed and written to storage before the session closes. The conditional check if (remaining) correctly skips empty flush results.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/SetupTerminal/SetupTerminal.tsx (6)

6-11: LGTM!

Imports correctly added for useTerminalTheme hook and getDefaultTerminalBg helper. This enables theme-aware terminal initialization and background styling.


52-52: LGTM!

Using useTerminalTheme() from the theme store aligns with the coding guidelines preference for zustand state management.


107-111: LGTM!

createTerminalInstance call correctly passes terminalTheme for theme-aware terminal initialization, preventing a flash of default colors on mount.


206-213: Intentional omission of terminalTheme from dependency array.

The exclusion of terminalTheme from this effect's dependencies is correct. Theme changes are handled by the dedicated effect at lines 216-223, which updates the existing terminal instance without recreation. Including it here would cause unnecessary terminal recreation on theme changes.


215-223: LGTM!

The dedicated effect for theme updates is the correct pattern. Using xterm.options.theme property setter (rather than recreating the terminal) is efficient and leverages xterm.js v5's built-in repaint mechanism.


225-234: LGTM!

Background color styling with inline style and getDefaultTerminalBg() fallback prevents flash of unstyled content during initial render and theme loading. The wrapper structure correctly separates the background container from the terminal container.

apps/desktop/src/renderer/stores/app-state.ts (1)

1-38: Simple view store is clear and type-safe

The AppView union plus small Zustand store cleanly model workspace vs settings navigation, and the convenience hooks keep consumers terse. No issues from a correctness or style perspective.

apps/desktop/src/renderer/stores/theme/store.ts (1)

1-187: I'll verify the review comment by checking the path aliases configuration, locating the terminal helpers file, and confirming the zustand API compatibility.
<function_calls>


{
"command": "cat apps/desktop/tsconfig.json | grep -A 20 'paths'"
}


</function_calls>

Now let me find the terminal helpers file to check for key duplication:
<function_calls>


{
"command": "fd -e ts -e tsx 'terminal' apps/desktop/src/renderer --type f | head -20"
}


</function_calls>

Let me also search for the specific localStorage keys mentioned in the review:
<function_calls>


{
"command": "rg -n 'theme-id|theme-type|theme-terminal' apps/desktop/src/renderer --type ts --type tsx -C 2"
}


</function_calls>

Let me check the file structure to understand where electronStorage is located:
<function_calls>


{
"command": "find apps/desktop/src/renderer -name 'electron-storage*' -type f"
}


</function_calls>

Now I'll search the web for zustand persist middleware API documentation to verify the onRehydrateStorage callback pattern:
<function_calls>


{
"query": "zustand persist middleware onRehydrateStorage callback API documentation 2024 2025"
}


</function_calls>

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (1)

50-60: All call sites properly updated; theming is safe and consistent across the codebase.

The review comment's concern has been verified as addressed:

  • SetupTerminal.tsx (line 107): Passes terminalTheme from useTerminalTheme() hook
  • Terminal.tsx (line 82): Passes terminalTheme from useTerminalTheme() hook

Both callers pass the same hook value, which has type ITheme | null and can be null initially. The function correctly handles this with the fallback logic initialTheme ?? getDefaultTerminalTheme(), ensuring no un-themed terminals are created. The type system and runtime behavior are aligned—all terminals will either use the provided theme or fall back to the default, preventing any flash or inconsistency.

Comment on lines +1 to +22
import { useState } from "react";
import { SettingsContent } from "./SettingsContent";
import { SettingsSidebar } from "./SettingsSidebar";

export type SettingsSection = "appearance";

export function SettingsView() {
const [activeSection, setActiveSection] =
useState<SettingsSection>("appearance");

return (
<div className="flex flex-1 bg-tertiary">
<SettingsSidebar
activeSection={activeSection}
onSectionChange={setActiveSection}
/>
<div className="flex-1 m-3 bg-background rounded overflow-hidden">
<SettingsContent activeSection={activeSection} />
</div>
</div>
);
}

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.

🛠️ Refactor suggestion | 🟠 Major

Refactor to follow component structure guidelines.

The component implementation should be in SettingsView.tsx with index.ts serving as a barrel export.

As per coding guidelines: "Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export"

Suggested structure:

Create SettingsView/SettingsView.tsx:

import { useState } from "react";
import { SettingsContent } from "./SettingsContent";
import { SettingsSidebar } from "./SettingsSidebar";

export type SettingsSection = "appearance";

export function SettingsView() {
	const [activeSection, setActiveSection] =
		useState<SettingsSection>("appearance");

	return (
		<div className="flex flex-1 bg-tertiary">
			<SettingsSidebar
				activeSection={activeSection}
				onSectionChange={setActiveSection}
			/>
			<div className="flex-1 m-3 bg-background rounded overflow-hidden">
				<SettingsContent activeSection={activeSection} />
			</div>
		</div>
	);
}

Update SettingsView/index.ts:

export { SettingsView } from "./SettingsView";
export type { SettingsSection } from "./SettingsView";
🤖 Prompt for AI Agents
In apps/desktop/src/renderer/screens/main/components/SettingsView/index.tsx
(lines 1-22) the component is implemented directly in the index file instead of
following the ComponentName/ComponentName.tsx + index.ts barrel pattern; move
the component implementation into a new file
apps/desktop/src/renderer/screens/main/components/SettingsView/SettingsView.tsx
containing the current component code, create
apps/desktop/src/renderer/screens/main/components/SettingsView/index.ts that
re-exports the component and its type (export { SettingsView } from
"./SettingsView"; export type { SettingsSection } from "./SettingsView";), and
update any imports elsewhere to import from the folder path (the barrel) if
needed.

@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

♻️ Duplicate comments (1)
apps/desktop/src/main/lib/terminal-escape-filter.ts (1)

199-206: CSI completeness check still examines tail's last character instead of first final byte.

This bug was flagged in a previous review. The current logic checks csiBody[csiBody.length - 1], which means a CSI sequence like \x1b[31mHello\n is incorrectly marked incomplete because the last character is \n. The fix should search for the first CSI final byte ([a-zA-Z~]) in the body:

     if (secondChar === "[") {
       const csiBody = str.slice(2);
       if (csiBody.length === 0) return true;
-      // CSI ends with a letter
-      const lastChar = csiBody[csiBody.length - 1];
-      return !/[a-zA-Z~]/.test(lastChar);
+      // CSI is complete once we see the first final byte (letter or ~)
+      const finalIndex = csiBody.search(/[a-zA-Z~]/);
+      return finalIndex === -1;
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ceb9c01 and 85d8019.

📒 Files selected for processing (2)
  • apps/desktop/src/main/lib/terminal-escape-filter.ts (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (5)
apps/desktop/src/main/lib/terminal-escape-filter.ts (5)

61-66: LGTM!

The standardModeReport pattern correctly matches the non-private mode report variant (ESC [ Ps ; Pm $ y), complementing the existing decPrivateModeReport for private modes.


68-80: LGTM!

Good enhancement to handle varying color precision levels (8-bit, 12-bit, 16-bit) that different terminals may report.


87-91: LGTM!

Pragmatic addition to handle real-world terminal quirks. The pattern is specific enough to avoid false positives.


223-238: LGTM on flush/reset API.

The flush() and reset() methods provide proper lifecycle management for the filter state. flush() correctly applies the filter to any remaining buffered data before returning.


241-251: LGTM!

Clear deprecation notice with guidance to use the new TerminalEscapeFilter class. Maintaining the stateless function provides backward compatibility.

@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

🧹 Nitpick comments (2)
apps/desktop/src/main/lib/terminal-escape-filter.test.ts (1)

408-419: Multiple assertions in single test.

This test has two separate expect statements checking different behaviors (buffering vs. completion). Per coding guidelines, tests should have one assert per test.

Consider splitting into two tests:

-		it("should buffer digit CSI but pass through color codes when complete", () => {
+		it("should buffer incomplete digit CSI at chunk boundary", () => {
 			const filter = new TerminalEscapeFilter();
-			// Color sequence is buffered initially (could be CPR/mode report)
 			const chunk1 = `text${ESC}[32`;
-			const chunk2 = `mgreen`;
 			const result1 = filter.filter(chunk1);
-			const result2 = filter.filter(chunk2);
-			// First chunk buffered, second chunk completes sequence
-			// Color code doesn't match filter patterns, so passes through
 			expect(result1).toBe("text");
+		});
+
+		it("should pass through color codes when completed in next chunk", () => {
+			const filter = new TerminalEscapeFilter();
+			filter.filter(`text${ESC}[32`); // Buffer it
+			const chunk2 = `mgreen`;
+			const result2 = filter.filter(chunk2);
 			expect(result2).toBe(`${ESC}[32mgreen`);
 		});

Based on learnings, tests should be readable.

apps/desktop/src/main/lib/terminal-escape-filter.ts (1)

88-92: Document the source of this pattern.

The unknownCSI_O pattern filters ESC[O sequences, but without additional context, it's unclear when this appears and whether it might inadvertently filter legitimate terminal output. Consider adding a comment explaining which terminal(s) emit this sequence and under what circumstances.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 85d8019 and 5c235d9.

📒 Files selected for processing (2)
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts (3 hunks)
  • apps/desktop/src/main/lib/terminal-escape-filter.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate tests with their corresponding components (e.g., Component.test.tsx next to Component.tsx)

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
  • apps/desktop/src/main/lib/terminal-escape-filter.ts
apps/desktop/**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.test.{ts,tsx,js,jsx}: Tests should have one assert per test
Tests should be readable
Tests should be fast
Tests should be independent
Tests should be repeatable

Files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
🧠 Learnings (2)
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.test.{ts,tsx,js,jsx} : Tests should be readable

Applied to files:

  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts
📚 Learning: 2025-11-24T21:32:46.559Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-24T21:32:46.559Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : Implement Electron IPC handlers in dedicated files under apps/desktop/src/main/lib/ (e.g., workspace-ipcs.ts, terminal-ipcs.ts)

Applied to files:

  • apps/desktop/src/main/lib/terminal-escape-filter.ts
🧬 Code graph analysis (1)
apps/desktop/src/main/lib/terminal-escape-filter.test.ts (1)
apps/desktop/src/main/lib/terminal-escape-filter.ts (3)
  • filterTerminalQueryResponses (250-252)
  • filter (115-141)
  • TerminalEscapeFilter (108-240)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
apps/desktop/src/main/lib/terminal-escape-filter.test.ts (6)

2-5: LGTM!

The import correctly adds the new TerminalEscapeFilter class alongside the existing filterTerminalQueryResponses function.


218-232: LGTM!

These tests correctly verify the expanded OSC color response pattern now supports 2-4 digit hex values per channel.


234-244: LGTM!

The tests appropriately cover the new standard mode report pattern (ESC[Ps;Pm$y).


478-494: LGTM!

Flush behavior tests correctly verify that incomplete buffered sequences are returned (filtered) and that flushing with no buffer returns empty string.


496-503: LGTM!

Reset behavior test correctly verifies that the buffer is cleared after calling reset().


505-522: LGTM!

These tests correctly verify that normal text and ANSI color codes are not buffered or delayed, ensuring the filter doesn't introduce false positives.

apps/desktop/src/main/lib/terminal-escape-filter.ts (7)

61-66: LGTM!

The new standard mode report pattern correctly matches non-private mode status responses (ESC[Ps;Pm$y), complementing the existing private mode report pattern.


68-80: LGTM!

The expanded OSC color response pattern now correctly supports 2-4 hex digits per channel, accommodating different terminal implementations.


115-141: LGTM!

The filter method correctly implements stateful filtering with a conservative buffering strategy: only sequences that look like query responses AND are incomplete are buffered.


143-189: LGTM!

The looksLikeQueryResponse method implements a conservative heuristic that correctly identifies potential query response sequences while minimizing false buffering through early rejection of ambiguous patterns.


199-207: LGTM! Critical issue resolved.

The CSI completeness check now correctly scans for the first final byte in the CSI body, resolving the critical issue where colored output (like ESC[31mHello) was incorrectly buffered. This fix ensures normal SGR sequences pass through immediately while still handling truly split query responses.


224-239: LGTM!

The flush() and reset() methods correctly handle buffer cleanup. flush() appropriately filters any remaining buffered data before returning it.


242-252: LGTM!

The deprecation notice and updated documentation clearly communicate the function's limitations and provide a clear migration path to the new TerminalEscapeFilter class.

Comment on lines +209 to +219
// OSC sequence: ESC ]
if (secondChar === "]") {
// OSC ends with BEL or ST (ESC \)
return !str.includes(BEL) && !str.includes(`${ESC}\\`);
}

// DCS sequence: ESC P
if (secondChar === "P") {
// DCS ends with ST (ESC \)
return !str.includes(`${ESC}\\`);
}

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.

⚠️ Potential issue | 🟡 Minor

ST split across chunks may pass through unfiltered OSC/DCS sequences.

If a String Terminator (ESC \) is split such that ESC arrives at the end of one chunk and \ arrives in the next, the incomplete OSC/DCS sequence will not be buffered (because a solo trailing ESC is rejected by looksLikeQueryResponse), causing the incomplete sequence to pass through unfiltered.

For example:

  • Chunk 1: text ESC]10;rgb:ff/ff/ff ESC
  • The trailing ESC alone won't match looksLikeQueryResponse, so the incomplete OSC ESC]10;rgb:ff/ff/ff passes through

This is an edge case (terminals typically don't split ST), but for robustness, consider detecting when the combined string ends with a partial OSC/DCS sequence (even if the final ESC is not part of a recognizable pattern).

🤖 Prompt for AI Agents
In apps/desktop/src/main/lib/terminal-escape-filter.ts around lines 209 to 219,
OSC/DCS handling currently only checks for BEL or a complete ST (`ESC\`) inside
the chunk, which lets a trailing lone ESC (split ST) slip through; modify the
checks so that when secondChar is ']' or 'P' you also detect a chunk that ends
with a lone ESC (i.e., str.endsWith(ESC)) and treat that as incomplete (return
false / buffer it) — ensure you still allow a complete ST (`ESC\`) to pass.

@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

🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx (1)

11-21: Consider memoizing the accentColors array.

The accentColors array is recreated on every render. While the performance impact is minimal for a Settings UI, memoizing it follows React best practices.

Apply this diff to optimize:

+import { useMemo } from "react";
 import { cn } from "@superset/ui/utils";
 import { HiCheck } from "react-icons/hi2";
 import type { Theme } from "shared/themes";
 export function ThemeCard({ theme, isSelected, onSelect }: ThemeCardProps) {
 	const bgColor = theme.terminal.background;
 	const fgColor = theme.terminal.foreground;
-	const accentColors = [
+	const accentColors = useMemo(() => [
 		theme.terminal.red,
 		theme.terminal.green,
 		theme.terminal.yellow,
 		theme.terminal.blue,
 		theme.terminal.magenta,
 		theme.terminal.cyan,
-	];
+	], [theme.terminal]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c235d9 and 000470c.

📒 Files selected for processing (4)
  • apps/desktop/src/renderer/index.html (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/index.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src/renderer/index.html
  • apps/desktop/src/renderer/screens/main/components/SettingsView/AppearanceSettings.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Biome formatting, linting, and import organization at the root level for all code files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type; use type-safe approaches instead, unless necessary
Ensure TypeScript type checking passes across all packages using bun run typecheck

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
apps/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

apps/**/*.{tsx,ts}: Structure React applications with one folder per component following the pattern: ComponentName/ComponentName.tsx with index.ts barrel export
Co-locate component dependencies (hooks, utils, constants, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
apps/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use one component per file; do not create multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Define keyboard shortcuts using the centralized system in apps/desktop/src/renderer/lib/shortcuts.ts with Arc Browser-inspired shortcut definitions

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (4)
apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx (4)

1-3: LGTM!

Imports are properly structured and use the workspace alias as per coding guidelines.


5-9: LGTM!

Interface is properly typed without using any, following TypeScript best practices.


34-76: LGTM!

The theme preview section effectively demonstrates the terminal color scheme. Inline styles are appropriate here for dynamic theming.


78-91: LGTM!

The theme info section correctly handles optional author metadata and provides clear visual feedback for selection state.

Comment on lines +23 to +33
return (
<button
type="button"
onClick={onSelect}
className={cn(
"relative flex flex-col rounded-lg border-2 overflow-hidden transition-all text-left",
isSelected
? "border-primary ring-2 ring-primary/20"
: "border-border hover:border-muted-foreground/50",
)}
>

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.

⚠️ Potential issue | 🟠 Major

Add accessibility attributes for screen reader users.

The button lacks an accessible name and does not communicate its selected state to assistive technologies. Screen reader users cannot identify which theme the button represents or whether it is currently selected.

Apply this diff to add accessibility attributes:

 		<button
 			type="button"
 			onClick={onSelect}
+			aria-label={`${theme.name} theme${theme.author ? ` by ${theme.author}` : ""}`}
+			aria-pressed={isSelected}
 			className={cn(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<button
type="button"
onClick={onSelect}
className={cn(
"relative flex flex-col rounded-lg border-2 overflow-hidden transition-all text-left",
isSelected
? "border-primary ring-2 ring-primary/20"
: "border-border hover:border-muted-foreground/50",
)}
>
return (
<button
type="button"
onClick={onSelect}
aria-label={`${theme.name} theme${theme.author ? ` by ${theme.author}` : ""}`}
aria-pressed={isSelected}
className={cn(
"relative flex flex-col rounded-lg border-2 overflow-hidden transition-all text-left",
isSelected
? "border-primary ring-2 ring-primary/20"
: "border-border hover:border-muted-foreground/50",
)}
>
🤖 Prompt for AI Agents
In
apps/desktop/src/renderer/screens/main/components/SettingsView/components/ThemeCard/ThemeCard.tsx
around lines 23–33, the button is missing an accessible name and does not expose
its selected state to assistive tech; update the button to include an accessible
name (e.g., aria-label={name} or aria-labelledby pointing to the theme title)
and expose selection with an appropriate ARIA attribute (e.g.,
aria-pressed={isSelected} for a toggle-like button or aria-checked/role="radio"
if it’s part of a radio group), and ensure the value comes from the component
props so screen readers know which theme it is and whether it is selected.

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