Skip to content

stepahin/cmux-claude-tabname

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

cmux-claude-tabname

Make cmux tabs show each Claude Code session's conversation name instead of the default Claude Code [N] stamp.

A tiny watcher that runs inside a cmux terminal and clears cmux's numbered tab stamp the moment it appears — the same effect as right-clicking a tab and choosing Remove Custom Tab Name, but automatic and for every tab.

┌ before ──────────────┐      ┌ after ───────────────┐
│ Claude Code [37]      │      │ hook cmux tab name    │
│ Claude Code [38]      │  →   │ cc update problem     │
│ Claude Code [41]      │      │ yo!                   │
└──────────────────────┘      └──────────────────────┘

Why this exists

When Claude Code runs inside cmux, the cmux Claude wrapper injects a SessionStart hook (cmux hooks claude session-start) that stamps the tab with a custom name Claude Code [N] (N = the surface ref number). It re-applies on every SessionStart — i.e. on startup, /clear, auto-compact, and resume — so manually clearing it doesn't stick.

Interestingly, Codex tabs don't have this problem: cmux shows the Codex session name as the tab title natively. Only Claude Code gets the numbered stamp, so this is really an inconsistency between the two integrations.

There is no cmux setting to disable just the stamp (only automation.claudeCodeIntegration: false, which also kills session-restore, Feed approvals, and notifications — too heavy). So this watcher clears the stamp after the fact.

Upstream feature request: manaflow-ai/cmux#5705 ("Rename tab to Claude's current conversation name").

Install

~/Dev/cmux-claude-tabname/install.sh

This symlinks bin/cmux-claude-tabname into ~/.local/bin (already on PATH).

Usage

Run it inside a cmux terminal and keep that tab open (e.g. a dedicated tab next to your other long-running processes):

cmux-claude-tabname
  • Polls every 5s and clears any tab whose title ends exactly with [N] Claude Code, across all workspaces. Codex tabs and already-named tabs are never touched.
  • Prints HH:MM:SS cleared surface:N (workspace:M) when it clears something, so you can see it's alive.
  • Change the interval: CMUX_TABWATCH_INTERVAL=3 cmux-claude-tabname.
  • Stop with Ctrl-C.
  • Running it a second time just exits ("already running") — a single-instance lock prevents duplicate watchers. Nothing breaks either way.

Restart it after a reboot or a cmux update (those restart cmux, which ends the tab the watcher lived in).

Why it must run inside cmux (and not via launchd)

cmux's control socket defaults to access mode cmuxOnly — only processes that cmux itself spawned may use it. A terminal you open inside cmux is a cmux descendant, so the watcher launched there is allowed. The same script run from a launchd LaunchAgent is rejected (Failed to write to socket (Broken pipe)) because launchd is not a cmux descendant.

Running it inside cmux therefore needs no security change. (If you ever did want a real background daemon, you'd have to switch Settings ▸ Automation to automation or password mode — not recommended just for this.)

How it works

# every INTERVAL seconds:
cmux workspace list                       # all workspaces
  → cmux list-pane-surfaces --workspace W # tabs in each
    → keep titles ending in "[N] Claude Code"
      → cmux tab-action --action clear-name --workspace W --tab surface:N

--workspace is required: clear-name --tab surface:N alone only resolves surfaces in the focused workspace.

Notes / things that don't work (so you don't retry them)

  • Claude Code hooks are too racy for this. They do fire under cmux (--settings merges with ~/.claude/settings.json), but cmux applies the stamp asynchronously, after the hook returns; a SessionStart clear runs too early, and a backgrounded (sleep N; …) & gets killed when the hook returns. Hooks also can't fix "resume then sit idle" (no hook fires). A polling watcher wins because it reacts after the stamp settles.
  • launchd / nohup / disown / closing the host tab all detach the process from cmux's process tree → socket access is refused. Keep it inside cmux.

Files

bin/cmux-claude-tabname   the watcher (zsh)
install.sh                symlink into ~/.local/bin
README.md                 this file

About

Make cmux tabs show each Claude Code session's conversation name instead of the default 'Claude Code [N]' stamp.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages