claude-terminal-status
A small Claude Code plugin that mirrors the current Claude session state into your terminal window title — so a glance at the tab strip tells you whether Claude is still working, done, or waiting for your input.
| State | Emoji | When |
|---|
idle | ✅ | Claude finished responding and is waiting for your next prompt |
working | 🧑🏽💻 | Claude is processing — turn in flight, tool calls running |
waiting | ⚠️ | Claude needs a decision from you (permission prompt, input pause) |
The title is set via standard ANSI OSC 0 escape sequences (\033]0;TITLE\007), so it works in any modern terminal: iTerm2, Terminal.app, Ghostty, Alacritty, Kitty, WezTerm, tmux (with set -g set-titles on), and most Linux terminal emulators.
Installation
Add the marketplace, then install the plugin:
/plugin marketplace add https://github.com/McGo/claude-terminal-status-plugin
/plugin install claude-terminal-status@claude-terminal-status-plugin
(Run those inside an active Claude Code session — they are slash commands, not shell commands.)
For local development from a checkout:
claude --plugin-dir /path/to/claude-terminal-status-plugin
Once installed, the hooks register automatically. Open a new Claude Code session and the tab title should flip to 🧑🏽💻 Claude while Claude is working and back to ✅ Claude once it stops.
How it works
The plugin wires six lifecycle hooks to a single shell script (bin/set-title.sh) that writes an OSC 0 sequence to /dev/tty:
| Hook event | State invoked |
|---|
SessionStart | working |
UserPromptSubmit | working |
PreToolUse | working |
Stop | idle |
Notification | waiting |
SessionEnd | clear |
The script writes directly to /dev/tty so the escape sequence reaches the terminal emulator regardless of how the hook harness routes stdout. If no controlling terminal is available (CI, nested subprocesses), the script silently exits without error.
Configuration
Two optional environment variables shape the title text:
| Variable | Default | Effect |
|---|
CLAUDE_TITLE_LABEL | Claude | Static label after the emoji |
CLAUDE_PROJECT_DIR | (unset) | When set, appends · <basename> so multiple sessions are distinct |
CLAUDE_PROJECT_DIR is already populated by Claude Code itself — so out of the box you'll see titles like 🧑🏽💻 Claude · my-project.
To override the label globally, add this to your shell rc:
export CLAUDE_TITLE_LABEL="Code"
Customizing the emoji set
Edit bin/set-title.sh and adjust the case block. The script reads the state name as $1, so you can also extend it with new states by adding the matching event in hooks/hooks.json.
Compatibility notes
- tmux: add
set -g set-titles on and a set-titles-string containing #T to your .tmux.conf for the title to surface on the status line.
- macOS Terminal.app: uses OSC 0 — works out of the box.
- VS Code integrated terminal: updates the tab title, not the window title.
- Terminal multiplexers / screen: must have title forwarding enabled.
Known limitation
Claude Code itself writes the tab title while a session is active — animating ·· while working and * when input is needed. Our hook fires and writes the emoji correctly, but Claude's built-in title updater overwrites it within a frame, so on most setups you only see our title flash briefly before Claude takes it back.
As of Claude Code 2.1.x there is no documented way to opt out of the built-in title animation. Track the upstream side via /feedback inside Claude Code asking for a disableTerminalTitle setting or a PreTitleUpdate hook. Until then this plugin is mostly useful as a standalone OSC 0 title setter (see Manual testing below) and as a reference for the hook plumbing.
How the script gets to the terminal: Claude Code spawns hook subprocesses without a controlling terminal, so a naïve > /dev/tty write fails silently. The script walks the parent process chain to find the nearest ancestor with a real tty (the claude process or its login shell) and writes the OSC sequence there directly.
Manual testing
The script is callable directly without the plugin installed — useful for debugging:
./bin/set-title.sh working
./bin/set-title.sh idle
./bin/set-title.sh clear