Skip to content

implement more font and xterm rendering improvements#324

Merged
Kitenite merged 17 commits intomainfrom
distant-wildfowl-f641df
Dec 12, 2025
Merged

implement more font and xterm rendering improvements#324
Kitenite merged 17 commits intomainfrom
distant-wildfowl-f641df

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Dec 11, 2025

Summary by CodeRabbit

  • New Features

    • GPU-accelerated terminal rendering with Canvas fallback, image support, and ligature handling.
    • New terminal session management with session lifecycle, recovery, history, and graceful fallback shell behavior.
    • Terminal environment builder to select shell, locale, and sanitized process env.
    • Batched terminal output to reduce IPC overhead.
  • New Dependencies

    • Added terminal rendering, ligature, shell and locale libraries.
  • Enhancements

    • Expanded terminal options (scrollback, cursor styles, fast-scroll controls, mac option mapping, screen-reader mode).
    • Terminal font handling prefers Nerd Font families.
  • Bug Fixes

    • Improved Zsh initialization for more reliable startup.

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

Kitenite and others added 2 commits December 10, 2025 19:11
Add Nerd Font families to terminal font stack to properly render
Powerlevel10k and similar Zsh themes that use special glyphs.

Closes #307

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 11, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
website Ready Ready Preview Comment Dec 12, 2025 2:41am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 11, 2025

Warning

Rate limit exceeded

@Kitenite has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 3fc5f69 and 90600f0.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • apps/desktop/package.json (3 hunks)
  • apps/desktop/src/main/lib/terminal-escape-filter.test.ts (2 hunks)
  • apps/desktop/src/main/lib/terminal-escape-filter.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal/env.test.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal/env.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal/manager.test.ts (4 hunks)
  • apps/desktop/src/main/lib/terminal/manager.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal/session.test.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal/session.ts (1 hunks)

Walkthrough

Reworks the desktop terminal subsystem: adds GPU-accelerated renderer with fallbacks and ligature/image addons, adds DataBatcher for batched IPC of terminal output, reorganizes terminal modules into a new terminal/ namespace with session/manager/types, updates terminal env and shell wrapper (ZDOTDIR ordering), and adds xterm-related dependencies.

Changes

Cohort / File(s) Change Summary
Renderer, addons & config
apps/desktop/package.json, apps/desktop/src/renderer/.../Terminal/helpers.ts, apps/desktop/src/renderer/.../Terminal/config.ts
Adds xterm addons to package.json; implements WebGL → Canvas renderer loading with context-loss fallback and disposal; loads Image and async Ligatures addons; expands createTerminalInstance to accept optional initialTheme; introduces private TERMINAL_FONT_FAMILY and extends exported TERMINAL_OPTIONS with scrollback, macOptionIsMeta, cursor styles, fastScroll settings, and screenReaderMode.
IPC batching utility
apps/desktop/src/main/lib/data-batcher.ts
New exported DataBatcher class: buffers writes, decodes UTF‑8 boundaries, flushes on 16ms timer or ≥200KB, exposes write/flush/dispose, invokes provided onFlush callback with decoded string.
Terminal module reshape (types/session/manager/index)
apps/desktop/src/main/lib/terminal/types.ts, apps/desktop/src/main/lib/terminal/session.ts, apps/desktop/src/main/lib/terminal/manager.ts, apps/desktop/src/main/lib/terminal/index.ts, apps/desktop/src/main/lib/terminal/manager.test.ts
New terminal/ namespace: adds rich session types, session lifecycle (createSession, spawnPty, history recovery, data handling, cleanup), TerminalManager class and singleton with createOrAttach/write/resize/signal/kill/etc., re-exports via terminal/index.ts, and adjusts test import paths.
Imports / call sites updated
apps/desktop/src/lib/trpc/routers/terminal/terminal.ts, apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts, apps/desktop/src/main/index.ts, apps/desktop/src/main/windows/main.ts
Swaps imports from old main/lib/terminal-manager to new main/lib/terminal (module path changes only; usage unchanged).
Terminal environment builder
apps/desktop/src/main/lib/terminal/env.ts
New module exporting FALLBACK_SHELL, SHELL_CRASH_THRESHOLD_MS, getDefaultShell(), and buildTerminalEnv(...) that composes sanitized env (detects locale, removes sensitive keys, sets terminal-related vars).
Agent shell wrapper tweak
apps/desktop/src/main/lib/agent-setup.ts
Reorders Zsh wrapper to set/export ZDOTDIR earlier (before sourcing user .zshrc) and adjusts wrapper generation ordering.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant PTY as PtyProcess
    participant Session as TerminalSession
    participant DB as DataBatcher
    participant Main as Main (IPC)
    participant Renderer as Renderer/XTerm

    PTY->>Session: data chunk (Buffer)
    Session->>DB: dataBatcher.write(Buffer)
    DB-->>DB: accumulate + handle UTF‑8 boundary
    par Flush conditions
        DB-->>DB: time-based flush (~16ms)
    and
        DB-->>DB: size-based flush (≥200KB)
    end
    DB->>Main: onFlush(decoded string)
    Main->>Renderer: IPC send terminal data
    Renderer->>Renderer: render frame (WebGL → Canvas fallback if needed)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • data-batcher.ts: UTF‑8 boundary edge cases, timer/flush race, dispose semantics.
    • session.ts / manager.ts: session lifecycle, fallback shell logic, crash-detection timing, and kill timeout/escalation.
    • Renderer lifecycle in helpers.ts: WebGL context-loss handling and proper addon/renderer disposal.
    • env.ts: correctness of locale detection and sanitization (removal of sensitive keys).

Possibly related PRs

Poem

🐰 I nibble bytes and stitch them tight,
WebGL leaps, then Canvas takes flight,
Fonts and ligatures line the row,
ZDOTDIR set — the shells now glow,
Hooray — the terminal hops in light 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, despite the template requiring sections for description, related issues, type of change, testing, and additional notes. Add a comprehensive description covering the changes: terminal manager refactoring, new session/environment modules, rendering improvements with GPU acceleration, and testing performed.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title references font and xterm rendering improvements, which aligns with changes to terminal configuration, rendering setup, and dependencies, but is vague about the specific improvements and omits the major terminal refactoring. Consider a more specific title that captures both the UI improvements (fonts, rendering) and the structural refactoring (terminal manager reorganization, session management).

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.

@Kitenite Kitenite changed the title distant wildfowl f641df fix nerd font Dec 11, 2025
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/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts (1)

6-18: Nice encapsulation of Nerd Font-aware font family

Centralizing the Nerd Font + monospace fallbacks into TERMINAL_FONT_FAMILY and wiring it into TERMINAL_OPTIONS.fontFamily keeps the config readable and makes future tweaks to the font stack straightforward. The resulting joined string is valid for ITerminalOptions["fontFamily"] and fits the renderer constraints (no Node imports).

If you later need this font stack elsewhere (e.g., other terminal-like views), consider exporting TERMINAL_FONT_FAMILY from this module instead of duplicating the list.

Also applies to: 23-23

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 127e1fc and 7cfad14.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
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/WorkspaceView/ContentView/TabsContent/Terminal/config.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/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

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

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
🧠 Learnings (2)
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/terminal-*.ts : Use node-pty for terminal session management in the desktop app

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
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/components/WorkspaceView/ContentView/TabsContent/Terminal/config.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

Add MesloLGM Nerd Font variants (recommended by Oh My Posh) and
CaskaydiaCove Nerd Font (popular with Starship) to terminal font stack.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 11, 2025

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

  • ✅ Neon database branch

Thank you for your contribution! 🎉

The zsh wrapper was resetting ZDOTDIR AFTER sourcing the user's .zshrc,
which caused Oh My Zsh to crash because it initializes paths based on
ZDOTDIR during .zshrc sourcing. Moving the ZDOTDIR reset to happen
BEFORE sourcing ensures Oh My Zsh sees the correct home directory.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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/main/lib/agent-setup.ts (1)

144-156: LGTM! The ZDOTDIR reset timing fix is correct.

The change ensures Oh My Zsh and similar frameworks see the correct ZDOTDIR during initialization by exporting it before sourcing the user's .zshrc. This fixes the issue where frameworks would look for configuration in the wrong directory.

Optional refinement: Distinguish between unset and set-to-HOME ZDOTDIR.

When ZDOTDIR was originally unset, the code sets SUPERSET_ORIG_ZDOTDIR to the home directory (line 219), then exports ZDOTDIR="$HOME" in the wrapper (line 150). This is not strictly equivalent to leaving ZDOTDIR unset, though most frameworks treat them identically. Edge cases might exist where scripts check [ -n "$ZDOTDIR" ] vs checking its value.

Consider using a separate flag to distinguish whether ZDOTDIR was originally set:

// In getShellEnv:
return {
  SUPERSET_ORIG_ZDOTDIR: process.env.ZDOTDIR || os.homedir(),
  SUPERSET_ZDOTDIR_WAS_SET: process.env.ZDOTDIR ? "1" : "0",
  ZDOTDIR: ZSH_DIR,
};

Then in the wrapper, conditionally export or unset:

 # Reset ZDOTDIR before sourcing user config so Oh My Zsh sees correct paths
-export ZDOTDIR="$_superset_home"
+if [ "$SUPERSET_ZDOTDIR_WAS_SET" = "1" ]; then
+  export ZDOTDIR="$_superset_home"
+else
+  unset ZDOTDIR
+fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c0d962 and 933c88b.

📒 Files selected for processing (1)
  • apps/desktop/src/main/lib/agent-setup.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
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/agent-setup.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/agent-setup.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/main/lib/agent-setup.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

xterm.js improvements:
- Add WebGL renderer with automatic Canvas fallback for GPU acceleration
- Add ImageAddon for inline image support (iTerm2 protocol)
- Add LigaturesAddon for font ligature support (async loaded)
- Improve terminal options: 10k scrollback, macOptionIsMeta, bar cursor

node-pty improvements:
- Add DataBatcher for IPC performance (~60fps batching like Hyper)
- Add enhanced env vars: TERM_PROGRAM, COLORTERM=truecolor, LANG

Based on vercel/hyper terminal implementation.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
apps/desktop/src/main/lib/data-batcher.ts (1)

15-19: Batch size threshold uses “chars” but constant is “bytes” — consider byte-based accounting.

BATCH_MAX_SIZE is documented as 200KB, but this.buffer.length is UTF-16 code units. If you want a true byte cap, consider Buffer.byteLength(this.buffer, "utf8") (or track bytes written separately).

Also applies to: 36-45

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

164-179: Environment defaults: LANG fallback may be surprising on some platforms; verify intent.

Setting LANG to "en_US.UTF-8" when missing is probably fine for UTF-8 safety, but please sanity-check on Windows/non-US locales (some tools behave differently when LANG is forced).


279-286: Dispose session.dataBatcher on “already-dead” cleanup paths (defensive timer cleanup).

Even if onExit usually runs, it’d be safer to session.dataBatcher.dispose() anywhere you delete/clear a session without going through onExit (e.g., cleanup() else-branch, killByWorkspaceId else-branch), to ensure any pending timer is cleared.

 } else {
 	// Clean up history for already-dead sessions
 	session.deleteHistoryOnExit = true;
+	session.dataBatcher.dispose();
 	await this.closeHistory(session);
 	this.sessions.delete(paneId);
 	results.push(Promise.resolve(true));
 }

Also applies to: 589-592, 522-528

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

60-97: Harden WebGL context-loss fallback (avoid keeping disposed renderer reference).

In onContextLoss, consider setting renderer = null before/after webglAddon.dispose() so dispose() doesn’t keep pointing at the disposed WebGL addon if Canvas creation fails.

 webglAddon.onContextLoss(() => {
 	console.warn("[Terminal] WebGL context lost, falling back to Canvas");
-	webglAddon.dispose();
+	renderer = null;
+	webglAddon.dispose();
 	try {
 		renderer = new CanvasAddon();
 		xterm.loadAddon(renderer);
 	} catch (canvasError) {
 		console.error("[Terminal] Canvas fallback failed:", canvasError);
 	}
 });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 933c88b and 5c2b65a.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • apps/desktop/package.json (1 hunks)
  • apps/desktop/src/main/lib/data-batcher.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal-manager.ts (7 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
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/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/data-batcher.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/main/lib/terminal-manager.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/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/data-batcher.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/data-batcher.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

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

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
apps/desktop/src/main/lib/terminal-*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use node-pty for terminal session management in the desktop app

Files:

  • apps/desktop/src/main/lib/terminal-manager.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/terminal-*.ts : Use node-pty for terminal session management in the desktop app
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/terminal-*.ts : Use node-pty for terminal session management in the desktop app

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/data-batcher.ts
  • apps/desktop/package.json
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/*{workspace,worktree}-*.ts : Use git worktree-based workspace management in the desktop app through workspace-manager.ts and worktree-manager.ts

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables from monorepo root .env file in src/main/index.ts with override: true

Applied to files:

  • apps/desktop/src/main/lib/terminal-manager.ts
🧬 Code graph analysis (1)
apps/desktop/src/main/lib/terminal-manager.ts (1)
apps/desktop/src/main/lib/data-batcher.ts (1)
  • DataBatcher (20-84)
🔇 Additional comments (4)
apps/desktop/package.json (1)

45-55: Verify xterm addon ↔ xterm core version compatibility (and lockfile update).

You added @xterm/addon-canvas and @xterm/addon-ligatures; please confirm these versions are intended/supported with @xterm/xterm@^5.5.0, and ensure the lockfile was updated accordingly.

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

223-228: DataBatcher changes event chunking — verify renderer-side assumptions (query suppression / protocol handling).

You now emit batched payloads instead of per-pty chunk. Please confirm anything consuming data:${paneId} (subscriptions/terminal parsing) doesn’t rely on chunk boundaries and still behaves correctly with ~16ms coalescing.

Also applies to: 257-264

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

143-157: Cleanup/lifecycle: verify xterm.dispose() is called somewhere; otherwise new addons can leak.

cleanup() now disposes the renderer, but not the xterm instance (nor the async ligatures addon). If callers don’t reliably call xterm.dispose(), consider doing it here (or document the ownership contract clearly).

Also applies to: 185-192


128-142: Addon load order looks sensible; ImageAddon addition is fine.

Comment thread apps/desktop/src/main/lib/data-batcher.ts
Comment on lines +6 to +22
// Font family with Nerd Font support for Oh My Posh, Powerlevel10k, Starship, and similar themes.
// Falls back to standard monospace fonts if Nerd Fonts aren't installed.
const TERMINAL_FONT_FAMILY = [
"MesloLGM Nerd Font", // Recommended by Oh My Posh (Medium line gap)
"MesloLGM NF",
"MesloLGS NF", // Recommended by Powerlevel10k (Small line gap)
"MesloLGS Nerd Font",
"Hack Nerd Font",
"FiraCode Nerd Font",
"JetBrainsMono Nerd Font",
"CaskaydiaCove Nerd Font", // Popular with Windows Terminal / Starship
"Menlo",
"Monaco",
'"Courier New"',
"monospace",
].join(", ");

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

Quote font names with spaces in fontFamily (CSS parsing bug).

Several entries contain spaces but aren’t quoted, so the font-family list may not resolve to the intended fonts.

 const TERMINAL_FONT_FAMILY = [
-	"MesloLGM Nerd Font", // Recommended by Oh My Posh (Medium line gap)
+	'"MesloLGM Nerd Font"', // Recommended by Oh My Posh (Medium line gap)
 	"MesloLGM NF",
-	"MesloLGS NF", // Recommended by Powerlevel10k (Small line gap)
-	"MesloLGS Nerd Font",
-	"Hack Nerd Font",
-	"FiraCode Nerd Font",
-	"JetBrainsMono Nerd Font",
-	"CaskaydiaCove Nerd Font", // Popular with Windows Terminal / Starship
+	"MesloLGS NF", // Recommended by Powerlevel10k (Small line gap)
+	'"MesloLGS Nerd Font"',
+	'"Hack Nerd Font"',
+	'"FiraCode Nerd Font"',
+	'"JetBrainsMono Nerd Font"',
+	'"CaskaydiaCove Nerd Font"', // Popular with Windows Terminal / Starship
 	"Menlo",
 	"Monaco",
 	'"Courier New"',
 	"monospace",
 ].join(", ");

Also applies to: 26-41

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

♻️ Duplicate comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts (1)

7-20: Font names with spaces need quotes for proper CSS parsing.

This was flagged in a previous review. Font names containing spaces (e.g., "MesloLGM Nerd Font", "Hack Nerd Font") must be wrapped in inner quotes to be correctly parsed as CSS font-family values. Without quotes, the browser may not resolve these fonts correctly.

Apply this diff:

 const TERMINAL_FONT_FAMILY = [
-	"MesloLGM Nerd Font",
+	'"MesloLGM Nerd Font"',
 	"MesloLGM NF",
 	"MesloLGS NF",
-	"MesloLGS Nerd Font",
-	"Hack Nerd Font",
-	"FiraCode Nerd Font",
-	"JetBrainsMono Nerd Font",
-	"CaskaydiaCove Nerd Font",
+	'"MesloLGS Nerd Font"',
+	'"Hack Nerd Font"',
+	'"FiraCode Nerd Font"',
+	'"JetBrainsMono Nerd Font"',
+	'"CaskaydiaCove Nerd Font"',
 	"Menlo",
 	"Monaco",
 	'"Courier New"',
 	"monospace",
 ].join(", ");
🧹 Nitpick comments (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (1)

119-129: Consider ImageAddon configuration for memory management in long-running sessions.

The ImageAddon is loaded with default settings. For long-running terminal sessions with heavy image output, consider configuring storageLimit (FIFO cache limit, default 128 MB), pixelLimit (per-image pixel limit, default 16777216), or sixelSizeLimit (SIXEL sequence size limit, default 25000000) to control memory usage and prevent excessive accumulation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c2b65a and aabd3ad.

📒 Files selected for processing (4)
  • apps/desktop/src/main/lib/agent-setup.ts (1 hunks)
  • apps/desktop/src/main/lib/terminal-manager.ts (7 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/main/lib/agent-setup.ts
🧰 Additional context used
📓 Path-based instructions (5)
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/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/terminal-manager.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}: 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/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Maintain type safety and avoid using any unless absolutely necessary in TypeScript code

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • 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 - only in src/main/

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
apps/desktop/src/main/lib/terminal-*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use node-pty for terminal session management in the desktop app

Files:

  • apps/desktop/src/main/lib/terminal-manager.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/terminal-*.ts : Use node-pty for terminal session management in the desktop app
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/terminal-*.ts : Use node-pty for terminal session management in the desktop app

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/config.ts
  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
📚 Learning: 2025-12-08T23:32:32.232Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-08T23:32:32.232Z
Learning: Applies to apps/desktop/src/main/lib/*{workspace,worktree}-*.ts : Use git worktree-based workspace management in the desktop app through workspace-manager.ts and worktree-manager.ts

Applied to files:

  • apps/desktop/src/main/lib/terminal-manager.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts
🔇 Additional comments (7)
apps/desktop/src/main/lib/terminal-manager.ts (3)

164-167: LGTM! Good terminal environment setup.

The new environment variables (TERM_PROGRAM, COLORTERM, LANG) properly identify the terminal capabilities. One minor note: process.env.npm_package_version is only available when running via npm scripts, so the fallback to "1.0.0" is appropriate for production builds.


219-223: DataBatcher integration looks correct.

The batcher is properly scoped per session with the callback emitting to the correct pane channel. This should effectively reduce IPC overhead by batching terminal output at ~60fps.


275-276: No action required. The DataBatcher.dispose() implementation properly flushes all remaining buffered data by calling flush(), which handles timeout cleanup, decoder finalization, and emission of all buffered content via the onFlush callback before state reset.

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

28-34: Good terminal option additions.

The new options enhance the terminal UX appropriately: scrollback: 10000 is a reasonable buffer size, macOptionIsMeta: true enables proper Meta key behavior for shell shortcuts, and the cursor/fast-scroll settings are sensible defaults.

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

55-89: Well-structured GPU renderer fallback logic.

The WebGL → Canvas → default renderer fallback chain is correctly implemented. The onContextLoss handler appropriately disposes the WebGL addon and attempts Canvas fallback. Empty catch blocks are acceptable here for graceful degradation.


131-139: Dynamic import for ligatures is a good pattern for optional features.

Loading ligatures asynchronously prevents blocking terminal initialization if the addon is unavailable or the font doesn't support ligatures. The error swallowing is intentional for this optional enhancement.


170-173: Cleanup properly disposes the renderer.

The cleanup function now correctly calls renderer.dispose() alongside the query suppression cleanup, ensuring GPU resources are released when the terminal instance is destroyed.

Move decoder.end() from flush() to dispose() so the StringDecoder
retains state for incomplete multi-byte UTF-8 sequences that may
span multiple PTY data chunks.

Before: decoder.end() was called every 16ms, corrupting emoji and
other multi-byte characters split across reads.

After: decoder maintains state across flushes, only finalized on
stream termination.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Kitenite Kitenite changed the title fix nerd font implement more font and xterm rendering improvements Dec 12, 2025
Security:
- Remove Electron's GOOGLE_API_KEY from terminal environment

Reliability:
- Add shell fallback mechanism: if shell crashes within 1s, retry with /bin/sh
- Use default-shell package for robust shell detection

Compatibility:
- Better locale detection: check LANG, LC_ALL, system locale, fallback to en_US.UTF-8

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Split the 760-line terminal-manager.ts into focused modules:

- terminal/types.ts - Session interfaces and type definitions
- terminal/env.ts - Environment setup, shell detection, locale
- terminal/session.ts - Session creation, data handling, history
- terminal/manager.ts - Main TerminalManager class (orchestration only)
- terminal/index.ts - Public exports

Benefits:
- Each file has a single responsibility
- Easier to test individual components
- Better code navigation and maintainability
- Clearer separation of concerns

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Terminal rendering looks odd

1 participant