From session-tab-namer
Auto-names the terminal tab for every Claude Code session based on the task's intent — for example "build:embabel-multi-agent", "research:jwt-rotation", or "debug:pytest-flaky". Use this skill whenever a new Claude Code session starts, whenever the user states or changes their objective, whenever the user asks to rename/relabel the tab, and proactively early in any session that still has a fallback name like "claude:a3f2c1". A well-named tab makes it easy to track, identify, and resume working sessions across many open terminals (cmux, iTerm2, Terminal.app, tmux, WezTerm).
How this skill is triggered — by the user, by Claude, or both
Slash command
/session-tab-namer:session-tab-namerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Keep every Claude Code session's terminal tab labeled by *what the session is actually for*, so the user can glance at a row of tabs and know which one is their multi-agent build, which is a research dive, which is a quick bug-chase.
Keep every Claude Code session's terminal tab labeled by what the session is actually for, so the user can glance at a row of tabs and know which one is their multi-agent build, which is a research dive, which is a quick bug-chase.
Every mainstream terminal emulator (Terminal.app, iTerm2, cmux, tmux, Alacritty, WezTerm, kitty, GNOME Terminal) honors the OSC 0 escape sequence for setting window/tab titles:
printf '\033]0;YOUR TITLE HERE\007' > /dev/tty
\033]0; — OSC "set icon name + window title"\007 — BEL, the string terminator> /dev/tty — writes directly to the controlling terminal, bypassing anything that might capture stdoutYou run this from the Bash tool. That's the whole mechanism — no terminal-specific APIs, no per-emulator branching.
Important: do not print the escape sequence into normal tool stdout. Claude Code captures Bash output for the model's context, so it won't reach the terminal's window manager and the tab will not actually rename. The > /dev/tty redirect is load-bearing.
On session start — a SessionStart hook (shipped in scripts/session_start_hook.sh) gives every new tab an immediate fallback name like claude:a3f2c1, using the first 6 characters of the Claude Code session ID. That guarantees the tab always has some name from the instant the session opens, before the user has even typed anything.
Once the objective is clear — replace the fallback with a semantic name as soon as the user states what they want to do. Don't wait to be asked. The value of this skill is that naming happens automatically. If the first user message is "help me set up a multi-agent flow in embabel", rename the tab before or alongside starting the work.
On explicit request — "rename the tab", "relabel this session", "call this one X", "change the tab to Y" → rename immediately, no debate.
When the objective shifts meaningfully — if what began as research:jwt-libraries clearly turned into build:jwt-rotation-service, rename. Don't churn the name on every micro-pivot; rename when the headline changes.
<prefix>:<short-kebab-description>
Prefix — pick the single short word that best captures the session's dominant activity. There is no fixed list. Words that come up naturally: research, build, debug, plan, review, refactor, ops, write, test, explore, deploy, spike. Pick whatever fits; the goal is a label the user recognizes at a glance, not taxonomic purity. If two prefixes fit, choose the one describing the outcome the user wants, not the activity they're currently doing (e.g. prefer build: over research: when the research is in service of a build).
Description — 2–4 words, lowercase, kebab-case, concrete enough to disambiguate from other tabs the user might have open. Prefer proper nouns (project names, ticket IDs, library names) over generic phrases.
Length — aim for ~30 characters total. Most terminals truncate tab titles aggressively; the first 15–20 characters are what the user actually sees.
| Objective stated by user | Good tab name | Why |
|---|---|---|
| "help me set up a multi-agent flow in embabel" | build:embabel-multi-agent | Project + what's being built |
| "figure out how JWT rotation works in practice" | research:jwt-rotation | Research prefix, concrete topic |
| "this pytest suite is flaking, help me find why" | debug:pytest-flaky | Debug prefix, specific symptom |
| "write the Q2 PRD for the payments service" | write:payments-q2-prd | Project + artifact |
| "review the auth middleware PR" | review:auth-middleware-pr | Review prefix, object |
| (no objective yet, fresh session) | claude:a3f2c1 | Fallback from hook, session-id based |
build:stuff — too generic, indistinguishable from other tabsBUILD:Embabel_Multi_Agent_System — caps and underscores waste visual spacebuilding-a-multi-agent-system-in-embabel-for-the-payments-project — truncates to garbagesession-12 — not semantic; the hook's fallback is already betterSingle Bash call — renames the tab AND persists the name so other tools can read it:
TAB_NAME="build:embabel-multi-agent" && printf '\033]0;%s\007' "$TAB_NAME" > /dev/tty && sid="" && [[ -n "${CLAUDE_TAB_SESSION_FILE:-}" && -s "$CLAUDE_TAB_SESSION_FILE" ]] && sid=$(<"$CLAUDE_TAB_SESSION_FILE") ; [[ -n "${sid:-}" ]] && mkdir -p ~/.claude/session-names && printf '%s' "$TAB_NAME" > ~/.claude/session-names/"$sid"
Replace build:embabel-multi-agent with the actual name. Both the rename and persist MUST happen in a single Bash call — never split them. No confirmation needed — renaming is free and reversible, and the user is expecting it. After renaming, briefly tell the user in one line what the tab is now called, e.g.:
Named this tab
build:embabel-multi-agent— just ask if you'd like it changed.
set-option -g allow-rename on and set-option -g set-titles on in .tmux.conf. Don't silently fail./dev/tty may not exist. The rename command will fail harmlessly with a non-zero exit; don't retry, just skip.build:xyz (not the fallback pattern claude:xxxxxx), don't rename on your own initiative. Only rename on explicit request or genuine objective shift.The hook in scripts/session_start_hook.sh is what gives every new session a fallback name before the user says anything. It needs to be registered in ~/.claude/settings.json under hooks.SessionStart.
On first use of this skill on a new machine, check whether the hook is installed:
grep -q 'session_start_hook.sh' ~/.claude/settings.json 2>/dev/null && echo installed || echo missing
If missing, ask the user:
I can install a
SessionStarthook that gives every new Claude Code tab a fallback name likeclaude:a3f2c1the instant it opens, before you've even said what the session is for. The installer edits~/.claude/settings.jsonwithjqand keeps a timestamped backup. Want me to wire it up?
On approval, run:
bash scripts/install.sh
This is a one-time install per machine. The installer is idempotent — running it twice won't duplicate the hook entry.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub mathewtbenjamin/session-tab-namer --plugin session-tab-namer