Skip to content

feat(desktop): make terminal colors optional with xterm defaults fallback#478

Merged
AviPeltz merged 1 commit intomainfrom
feat/optional-terminal-colors
Dec 23, 2025
Merged

feat(desktop): make terminal colors optional with xterm defaults fallback#478
AviPeltz merged 1 commit intomainfrom
feat/optional-terminal-colors

Conversation

@AviPeltz
Copy link
Copy Markdown
Collaborator

@AviPeltz AviPeltz commented Dec 23, 2025

Summary

Makes terminal colors optional in theme definitions, with automatic fallback to xterm.js defaults based on theme type (light/dark).

Changes

  • Add DEFAULT_TERMINAL_COLORS_DARK and DEFAULT_TERMINAL_COLORS_LIGHT constants with standard xterm.js ANSI colors
  • Add getDefaultTerminalColors(type) and getTerminalColors(theme) helper functions
  • Make terminal property optional in Theme interface
  • Update light theme to use standard xterm default ANSI colors
  • Update theme store and terminal helpers to use the fallback system

Benefits

  • Themes can now omit terminal colors and will automatically use appropriate xterm defaults
  • Reduces boilerplate when creating new themes
  • Uses standard xterm.js ANSI colors for better compatibility

Summary by CodeRabbit

  • New Features

    • Added default terminal color palettes with automatic fallback and made terminal colors selectable/appliable across the UI.
  • Style

    • Updated light theme terminal palette to xterm-standard colors (foreground, cursor, selection, ANSI colors).
    • Theme UI (settings, previews, editor prompt) now uses the unified terminal color set for consistent appearance.
  • Bug Fixes

    • Persisted and applied computed terminal colors so terminal/editor appearance remains consistent across sessions.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 23, 2025

Walkthrough

Terminal color handling was refactored: Theme.terminal is now optional and terminal palettes are derived via getTerminalColors()/getDefaultTerminalColors() with built-in light/dark defaults; code was updated to use the derived terminal colors across theme store, editor conversion, and UI components.

Changes

Cohort / File(s) Summary
Terminal Color Types & Utilities
apps/desktop/src/shared/themes/types.ts, apps/desktop/src/shared/themes/index.ts
Added DEFAULT_TERMINAL_COLORS_DARK, DEFAULT_TERMINAL_COLORS_LIGHT, getDefaultTerminalColors(), getTerminalColors(); made Theme.terminal optional; re-exported new symbols from index.ts.
Built-in Light Theme Palette
apps/desktop/src/shared/themes/built-in/light.ts
Replaced light theme terminal color values (foreground, cursor, selectionBackground, ANSI standard and bright sets) with xterm-default-like hex values.
Renderer: Terminal helpers & UI
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts, apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
Replaced direct theme.terminal.* accesses with getTerminalColors(theme) and use the derived terminal object for UI color lists, inline styles, and prompt coloring.
Theme Store & Persistence
apps/desktop/src/renderer/stores/theme/store.ts
Persist terminal theme using JSON.stringify(getTerminalColors(theme)); derive terminalTheme via toXtermTheme(getTerminalColors(theme)) instead of theme.terminal.
Editor/Monaco Theme Integration
apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
Use getTerminalColors(theme) for terminal color derivation when creating editor colors and token rules; updated imports accordingly.

Sequence Diagram(s)

(omitted — changes are refactors of data derivation and constants, not new multi-component control flow)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: making terminal colors optional with xterm defaults fallback, which is the core feature of this PR.
Description check ✅ Passed The PR description provides a clear summary, lists all key changes, and explains the benefits, though it doesn't follow the template structure with explicit sections.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ 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 feat/optional-terminal-colors

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 322311f and 3589ff7.

📒 Files selected for processing (7)
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/shared/themes/types.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid using any type in TypeScript - maintain type safety unless absolutely necessary

Files:

  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix

Files:

  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
apps/desktop/**/*.{ts,tsx}

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

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
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.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)

Files:

  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Files:

  • apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
**/{components,features}/**/[!.]*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

Use React + TailwindCSS v4 + shadcn/ui for UI development

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/ThemeCard.tsx
🧬 Code graph analysis (1)
apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts (2)
apps/desktop/src/shared/themes/index.ts (1)
  • getTerminalColors (18-18)
apps/desktop/src/shared/themes/types.ts (1)
  • getTerminalColors (83-85)
⏰ 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 (6)
apps/desktop/src/renderer/stores/theme/utils/monaco-theme.ts (1)

2-3: LGTM! Clean adoption of the centralized terminal color derivation.

The refactoring correctly uses getTerminalColors(theme) to derive terminal colors with automatic fallback, while separately destructuring ui from the theme. This aligns well with the broader refactoring pattern across the codebase.

Also applies to: 12-16

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

50-76: LGTM! Terminal colors updated to standard xterm defaults.

The light theme now uses standard xterm.js ANSI color values, which aligns with DEFAULT_TERMINAL_COLORS_LIGHT. This provides better compatibility and consistency with terminal emulator standards.

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

11-22: LGTM! Correctly adopts centralized terminal color derivation.

The component now derives terminal colors via getTerminalColors(theme), ensuring consistent fallback behavior when themes omit terminal colors. The refactored color references are clean and maintain the same visual behavior.

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

14-19: LGTM! Clean barrel exports for the new terminal color utilities.

The new exports make getTerminalColors, getDefaultTerminalColors, and the default color constants available to consumers of the shared/themes module.

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

7-36: LGTM! Well-structured default terminal color constants.

The xterm.js default ANSI color values are correctly defined. Using as const could provide stricter typing, but the current approach with explicit TerminalColors type annotation works well for the use case.


204-205: LGTM! Optional terminal property with clear documentation.

Making terminal optional with documented fallback behavior aligns with the PR objective of reducing boilerplate when creating themes.


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.

@AviPeltz AviPeltz force-pushed the feat/optional-terminal-colors branch from c18f9e6 to 322311f Compare December 23, 2025 00:11
…back

- Add DEFAULT_TERMINAL_COLORS_DARK and DEFAULT_TERMINAL_COLORS_LIGHT constants
- Add getDefaultTerminalColors() and getTerminalColors() helper functions
- Make terminal property optional in Theme interface
- Update light theme to use standard xterm default ANSI colors
- Update theme store and terminal helpers to use fallback system

Themes can now omit terminal colors and will automatically use xterm
defaults based on the theme type (light/dark).
@AviPeltz AviPeltz force-pushed the feat/optional-terminal-colors branch from 322311f to 3589ff7 Compare December 23, 2025 00:13
Copy link
Copy Markdown
Contributor

@charliecreates charliecreates Bot left a comment

Choose a reason for hiding this comment

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

The main risks are around mutability and robustness: getTerminalColors() can return shared default objects that are easy to accidentally mutate, and the localStorage cached terminal colors aren’t normalized against defaults, which can cause odd rendering if the cache is partial/legacy/corrupted. There’s also duplicated ANSI palette data between dark/light defaults that would be safer and easier to maintain if composed from a shared constant. Addressing these will make the new fallback system more resilient long-term.

Additional notes (3)
  • Maintainability | apps/desktop/src/shared/themes/types.ts:10-67
    DEFAULT_TERMINAL_COLORS_DARK and DEFAULT_TERMINAL_COLORS_LIGHT define identical ANSI palettes (standard + bright). That duplication increases the chance of divergence or mistakes when updating values.

Also, these are described as “xterm defaults”; the ANSI 16-color palette being identical for light/dark makes sense, but then only the base fields (background, foreground, etc.) differ—those could be layered on top of a single shared palette constant.

  • Readability | ...omponents/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts:16-16
    getDefaultTerminalTheme() still parses theme-terminal from localStorage and passes it to toXtermTheme(...). If theme-terminal was written by an older app version (or is corrupted), the JSON may be structurally valid but missing required terminal fields, resulting in an incomplete ITheme and potentially weird rendering (e.g., missing ANSI colors).

You already introduced getTerminalColors(theme) for theme objects, but the cached path has no equivalent normalization step.

  • Compatibility | apps/desktop/src/shared/themes/built-in/light.ts:50-75
    selectionBackground changed from a semi-transparent black (rgba(0, 0, 0, 0.15)) to an opaque #add6ff. That aligns with xterm defaults, but it can materially impact readability/contrast depending on your UI background and terminal font rendering.

If this project expects theme terminal selection to blend with UI styling, you may want to ensure this value is intentionally accepted (and ideally tested/validated visually).

Summary of changes

What changed

Terminal theming now supports defaults

  • Introduced DEFAULT_TERMINAL_COLORS_DARK / DEFAULT_TERMINAL_COLORS_LIGHT in shared/themes/types.ts.
  • Added helpers getDefaultTerminalColors(type) and getTerminalColors(theme) to centralize fallback logic when theme.terminal is absent.
  • Made Theme.terminal optional (terminal?: TerminalColors).

App now uses the fallback helper everywhere

  • Updated terminal startup flash-prevention logic in Terminal/helpers.ts to use getTerminalColors(theme) for built-ins.
  • Updated theme store persistence and application (renderer/stores/theme/store.ts) to cache and apply terminal colors via getTerminalColors(theme).

Light theme terminal palette updated

  • Changed lightTheme.terminal ANSI palette and some base values (foreground, cursor, selectionBackground) to xterm defaults.

Public exports

  • Re-exported default constants + helper functions from shared/themes/index.ts.

Comment on lines +83 to +85
export function getTerminalColors(theme: Theme): TerminalColors {
return theme.terminal ?? getDefaultTerminalColors(theme.type);
}
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.

getTerminalColors() returns the theme’s terminal object as-is, otherwise returns a shared default object. That makes the returned value potentially mutable shared state (especially for the defaults), and it’s easy for downstream code (or xterm integration) to accidentally mutate it and affect all consumers.

Even if the current code path doesn’t mutate, this is a sharp edge that’s hard to debug later.

Suggestion

Consider returning a defensive copy to avoid accidental mutation of the shared defaults (and to keep behavior consistent whether the source is theme.terminal or defaults).

For example:

  • return { ...(theme.terminal ?? getDefaultTerminalColors(theme.type)) };

If you want to be extra safe against nested mutation (not needed here since it’s flat), a shallow copy is sufficient.

Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this change.

@charliecreates charliecreates Bot removed the request for review from CharlieHelps December 23, 2025 00:14
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

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

50-76: Consider removing the terminal property to reduce duplication.

The lightTheme.terminal colors now exactly match DEFAULT_TERMINAL_COLORS_LIGHT defined in types.ts. Since the Theme interface makes terminal optional with automatic fallback to defaults, you could remove this property to eliminate duplication and reduce maintenance burden.

🔎 Proposed refactor to use fallback defaults
 	},
-
-	terminal: {
-		background: "#ffffff",
-		foreground: "#000000",
-		cursor: "#000000",
-		cursorAccent: "#ffffff",
-		selectionBackground: "#add6ff",
-
-		// Standard ANSI colors (xterm defaults)
-		black: "#2e3436",
-		red: "#cc0000",
-		green: "#4e9a06",
-		yellow: "#c4a000",
-		blue: "#3465a4",
-		magenta: "#75507b",
-		cyan: "#06989a",
-		white: "#d3d7cf",
-
-		// Bright ANSI colors (xterm defaults)
-		brightBlack: "#555753",
-		brightRed: "#ef2929",
-		brightGreen: "#8ae234",
-		brightYellow: "#fce94f",
-		brightBlue: "#729fcf",
-		brightMagenta: "#ad7fa8",
-		brightCyan: "#34e2e2",
-		brightWhite: "#eeeeec",
-	},
 };

This would allow the fallback system to provide the identical colors via getTerminalColors(lightTheme), eliminating the need to maintain two copies of the same values.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c18f9e6 and 322311f.

📒 Files selected for processing (5)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/renderer/stores/theme/store.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/shared/themes/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/renderer/stores/theme/store.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid using any type in TypeScript - maintain type safety unless absolutely necessary

Files:

  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix

Files:

  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
apps/desktop/**/*.{ts,tsx}

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

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
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.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/shared/themes/types.ts
  • apps/desktop/src/shared/themes/built-in/light.ts
  • apps/desktop/src/shared/themes/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
🧠 Learnings (3)
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx} : Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.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 (7)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (2)

13-17: LGTM! Clean integration with centralized terminal color helpers.

The import and usage of getTerminalColors from shared/themes properly centralizes terminal color derivation with fallback logic. This maintains type safety while reducing direct access to theme.terminal.


38-38: Fallback logic correctly handles all theme types.

The refactoring safely replaces direct theme.terminal access with getTerminalColors(theme), which properly encapsulates fallback behavior:

  • All 5 built-in themes define terminal colors explicitly
  • Custom themes without terminal colors fall back via the nullish coalescing operator to getDefaultTerminalColors(theme.type)
  • Theme store hydration is protected by a 4-layer fallback chain in getDefaultTerminalTheme(): cached colors → lookup by theme ID → DEFAULT_THEME_ID → hardcoded xterm defaults
  • toXtermTheme() correctly maps TerminalColors to xterm's ITheme format with proper optional property handling

The refactoring improves maintainability by centralizing color resolution logic.

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

14-19: LGTM! Proper barrel export pattern.

The re-exports make the new terminal color utilities available through the index, maintaining clean module boundaries.

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

72-85: LGTM! Clean helper functions with appropriate fallback logic.

The helper functions correctly implement the fallback system:

  • getDefaultTerminalColors selects the appropriate default palette based on theme type
  • getTerminalColors uses nullish coalescing to fall back to defaults when theme.terminal is undefined

This maintains type safety while providing sensible defaults.


204-205: Well-documented optional property with clear fallback behavior.

Making terminal optional in the Theme interface is a good design choice that reduces boilerplate for theme authors. The inline documentation clearly explains the fallback behavior.


10-36: ANSI color values are correct and match xterm.js defaults.

The hex values in DEFAULT_TERMINAL_COLORS_DARK and DEFAULT_TERMINAL_COLORS_LIGHT are verified as the official xterm.js default ANSI color palette. No changes needed.

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

52-55: Clarify the light theme color design rationale or reference a specific design standard.

The light theme colors cannot be verified against "xterm.js defaults" because xterm.js does not specify official default colors for light mode—the ITheme properties are customizable and theme-specific. Either document which design standard these colors should align with (e.g., a specific light theme specification or accessibility standard), or verify the color choices match the project's documented design requirements.

@AviPeltz AviPeltz merged commit 0b5c259 into main Dec 23, 2025
5 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

Service Status
Neon Database (Neon) ⚠️

Thank you for your contribution! 🎉


Preview resources have been processed for cleanup

@Kitenite Kitenite deleted the feat/optional-terminal-colors branch December 25, 2025 18:31
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