Skip to content

feat(desktop): auto-update tab title from terminal#495

Merged
Kitenite merged 5 commits intomainfrom
auto-update-title
Dec 24, 2025
Merged

feat(desktop): auto-update tab title from terminal#495
Kitenite merged 5 commits intomainfrom
auto-update-title

Conversation

@Kitenite
Copy link
Copy Markdown
Collaborator

@Kitenite Kitenite commented Dec 24, 2025

Summary

  • Listen for terminal title changes via OSC escape sequences (0, 1, 2)
  • Automatically update the tab title when programs set the terminal title
  • Update workspace name if it hasn't been customized (still using default branch name)

This allows shells and programs (vim, htop, ssh, etc.) that set the terminal title via escape sequences to have that reflected in the UI.

Test plan

  • Open a terminal and run a command that sets the title (e.g., echo -e "\033]0;My Custom Title\007")
  • Verify the tab title updates to "My Custom Title"
  • Verify the workspace name updates if it was still using the default branch name
  • Rename the workspace manually, then run the echo command again
  • Verify the workspace name does NOT change (respects user customization)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Terminal tab titles now automatically update to reflect the current state and active commands in real-time with smooth performance.
  • Bug Fixes

    • Fixed memory leak where terminal event listeners were not properly disposed when closing or unmounting terminal components, preventing resource waste.

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

Listen for terminal title changes (OSC 0, 1, 2 escape sequences) and
automatically update the tab title. Also updates the workspace name
if it hasn't been customized (still using the default branch name).

This allows shells and programs (vim, htop, ssh, etc.) that set the
terminal title to have that reflected in the UI.

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

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

coderabbitai Bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Adds an xterm onTitleChange event listener to the Terminal component that propagates terminal title updates to the parent tab through a debounced setter. The listener is registered during terminal initialization and properly disposed on unmount to prevent memory leaks.

Changes

Cohort / File(s) Summary
Terminal title propagation
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
Registers onTitleChange handler on xterm instance to update parent tab title via debouncedSetTabAutoTitleRef; ensures listener disposal on unmount; minor import reordering

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant xterm
    participant Terminal Component
    participant Tab Store

    User->>xterm: Change terminal title
    xterm->>Terminal Component: Emit onTitleChange event
    Terminal Component->>Terminal Component: Debounce the update
    Terminal Component->>Tab Store: Call debouncedSetTabAutoTitleRef(title)
    Tab Store->>Tab Store: Update tab auto title
    
    Note over Terminal Component: On unmount
    Terminal Component->>Terminal Component: Dispose title listener
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 A whisker-twitch of title flow,
From xterm's heart, the updates glow,
Debounced soft through tab's window,
No leaks remain when we must go! 🌙

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: auto-updating the tab title from terminal output via OSC escape sequences.
Description check ✅ Passed The description is substantially complete but lacks some template sections; Related Issues and Testing sections are missing or incomplete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 auto-update-title

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dac746a and 08f1d68.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
🧰 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/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
**/*.{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/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.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/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.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/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
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/Terminal.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/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.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/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.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/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
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/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx
🧠 Learnings (1)
📚 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 **/*.{tsx,css} : Use React + TailwindCSS v4 + shadcn/ui for UI development

Applied to files:

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

391-391: Proper cleanup prevents memory leaks.

The disposal of titleDisposable correctly mirrors the cleanup pattern for other xterm event listeners and prevents memory leaks on unmount.


340-344: LGTM! Clean implementation of terminal title propagation.

The onTitleChange listener correctly propagates terminal title updates (from OSC escape sequences) to the parent tab using the existing debounced setter infrastructure. The guards ensure updates only occur when both title and parent tab exist, and the pattern matches the existing command buffer title handling.


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 and others added 4 commits December 23, 2025 22:15
Added useSetWorkspaceAutoName hook that invalidates workspace queries
after successfully updating the workspace name. This ensures the
WorkspaceItem in the top bar reflects the updated name.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove the branch-name check that was preventing subsequent auto-updates.
Now the workspace name always reflects the terminal title. Only skip
update if the name hasn't actually changed.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…itle

The tab and workspace name systems work differently:
- Tab name: Zustand store (immediate local updates)
- Workspace name: Database mutation (requires query invalidation)

Keeping only tab title updates from terminal OSC sequences is simpler
and more appropriate - tab shows "what's running", workspace shows
"what this is for" (branch name).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Kitenite Kitenite changed the title feat(desktop): auto-update tab and workspace titles from terminal feat(desktop): auto-update tab title from terminal Dec 24, 2025
@Kitenite Kitenite merged commit e80c3df into main Dec 24, 2025
4 of 5 checks passed
@Kitenite Kitenite deleted the auto-update-title branch December 24, 2025 06:42
@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

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