When working across multiple Claude Code sessions, it's easy to lose track of which ones are waiting for your response.
There's no ambient signal — you have to check each session manually.
I created a keyboard-driven terminal UI to track and manage Claude Code sessions awaiting your response.
pip install textualOr use uv:
uv run main.pypython main.pyThis launches an interactive TUI that displays:
- All active Claude Code sessions sorted by most recent activity
- Project name, session title, time elapsed, and last message preview
- A scrollable list with keyboard navigation
| Key | Action |
|---|---|
j / k or ↑ / ↓ |
Navigate list |
Space |
Toggle preview pane (shows last ~5 message exchanges) |
o / Enter |
Open session in Claude Code |
d |
Dismiss session (hide from list) |
r |
Refresh / re-scan conversation files |
q / Ctrl+C |
Quit |
- Scans
~/.claude/projects/for.jsonlsession files - Parses Claude Code session metadata (ID, title, messages, timestamps)
- Displays active sessions in reverse chronological order
- Sessions can be marked as dismissed by pressing
d - Dismissed session IDs are stored in
~/.claude/session.log - Dismissed sessions are hidden from the TUI
- Can also be dismissed from within Claude Code via
/clearcommand with proper hook setup
~/.claude/projects/
├── {project-name}/
│ └── {sessionId}.jsonl # Session messages (line-delimited JSON)
├── -/
│ └── {sessionId}.jsonl # Default context sessions
└── (etc.)
To automatically dismiss sessions when using /clear in Claude Code, add a SessionEnd hook to ~/.claude/settings.json:
{
"hooks": {
"SessionEnd": [
{
"matcher": "clear",
"hooks": [
{
"type": "command",
"command": "python -c \"import sys,json; print(json.load(sys.stdin)['session_id'])\" >> ~/.claude/session.log"
}
]
}
]
}
}The hook fires on /clear, reads the session ID from stdin (passed by Claude Code as JSON), and appends it to ~/.claude/session.log. The TUI reads that file on startup and on refresh to exclude dismissed sessions.
agent-dashboard/
├── pyproject.toml # Project configuration
├── spec.md # Specification
├── README.md # This file
├── main.py # Entry point
└── src/
├── __init__.py
├── parser.py # Session discovery and JSONL parsing
├── dismiss.py # Dismissal log management
└── ui.py # Textual TUI application
The parser handles multiple message content formats:
- String content: Plain text messages
- Structured content: Lists of objects with type/text fields (used for text, thinking, images, etc.)
- Replying from within the TUI
- Searching/filtering sessions
- Starred or pinned sessions
- Custom session ordering
- Archiving vs. deletion distinction