claude-session-hud
v0.5.0
Published
Live macOS desktop widget (Übersicht) for Claude Code sessions - status, current activity, click-to-focus the VS Code window, and idle notifications.
Maintainers
Readme
claude-session-hud
A live macOS desktop widget for Claude Code sessions. It shows every running session across all your projects - status, the step it's currently on, and time since last activity - and lets you click a session to focus its VS Code window. It also pings you when a session goes idle waiting on you.
Built on Übersicht and Claude Code hooks.
What you get
- Live session list - name/title, project, and
busy/idle/waiting/needs-youstate, refreshing every 2s. - Context-window usage - per session,
<model> · <used> / 1M · <state>, colored green/amber/red as it fills. - Usage-limit bars - a full-height right-side rail of
5H/W/Fbars (5-hour, weekly, and weekly-Fable limits) polled from/usage, each showing its percent on top. The poll is adaptive: it runs more often when sessions are actively burning usage, rarely when idle. - Current activity - "→ Bash: git status", "→ Editing settings.json", "⏸ awaiting permission".
- Click to focus - clicking a row focuses the session's host app. The host is detected from the session's process tree, so it works beyond VS Code (see Supported hosts).
- Idle notifications - a desktop notification when a session has been waiting on you for more than 60s.
- Notification hook - desktop notifications for Claude Code's own notification events.
Requirements
- macOS (uses Übersicht,
launchd, AppleScript - not portable to Linux/Windows) - Homebrew
- Claude Code
- VS Code (only for the click-to-focus feature)
The installer will brew install jq, terminal-notifier, and the ubersicht cask if missing.
Install
npx claude-session-hud installThen grant Übersicht two permissions (the installer opens the panes for you):
- Screen Recording - so the widget can draw on the desktop
- Accessibility - so clicking a session can focus its VS Code window
Quit and reopen Übersicht (menu-bar icon → Quit) to apply the grants.
Commands
npx claude-session-hud install # install everything
npx claude-session-hud status # show what's installed
npx claude-session-hud uninstall # remove everything it installed
# install flags
npx claude-session-hud install --skip-deps # skip Homebrew checks
npx claude-session-hud install --no-activate # write files only, don't load launchd / open ÜbersichtWhat it installs
| Path | What |
|------|------|
| ~/.claude/hooks/*.sh | 6 hook/render scripts |
| ~/Library/Application Support/Übersicht/widgets/claude-sessions.jsx | the widget |
| ~/Library/LaunchAgents/com.claudecode.idlewatch.plist | idle-watch agent (polls every 20s) |
| ~/Library/LaunchAgents/com.claudecode.usagepoll.plist | usage-poll agent (adaptive; caches /usage to ~/.claude/session-hud/) |
| ~/.claude/settings.json | adds hooks (backed up first; your other hooks are left untouched) |
uninstall reverses all of it and restores nothing else.
How it works (and the caveat)
Claude Code maintains an internal registry at ~/.claude/sessions/ (one file per
running session, with status, name, cwd, pid) and writes an ai-title
into each session transcript. The widget reads those directly for status and
title. Activity ("what step") comes from Claude Code hooks this tool adds to
settings.json.
Best-effort caveat: the registry and transcript formats are Claude Code internals with no stable contract. A future Claude Code update could change a field name and break the status/title parts of the widget. The hook-driven parts (activity, notifications) are on documented APIs and are durable.
The usage-limit bars come from Claude Code's /usage, which has no local
cache or API - so the usage-poll agent reads it by spawning claude -p "/usage"
and parsing its text output (best-effort; may need updating if the wording
changes). Each poll creates and immediately deletes a throwaway transcript, so
it does not clutter your session history. Polling is adaptive: it fires more
often while sessions are actively growing their transcripts (i.e. burning usage)
and backs off to ~45-minute checks when idle. touch ~/.claude/session-hud/poll-trigger
to force a refresh (e.g. from a hook).
Supported hosts
Click-to-focus detects the host app from the session's process tree and does the best it can per host:
| Host | Focus precision | |------|-----------------| | VS Code | window (raises the window whose workspace is the deepest ancestor of the session's cwd) | | VS Code forks - Cursor, Windsurf, VSCodium, Insiders | window, best-effort (their System Events process names are unverified; falls back to activating the app if that guess is wrong) | | Terminal.app | tab (selects the exact tab by tty) | | iTerm2, JetBrains, Warp, Ghostty, other | app-level (activates the correct app) |
Every host at least gets "activate the correct app"; VS Code and Terminal.app get precise window/tab focus. The correct app is always brought forward first, so a missing Accessibility/Automation grant only downgrades precision, never focuses the wrong app.
Limitations
- VS Code focus is window-level, not tab-level. Sessions sharing a folder share a window. (Focusing a specific terminal tab inside VS Code isn't reachable from outside it - see issue #1.)
- tmux / screen / ssh sessions: the host app can't be resolved from the process tree (the shell is parented under a daemon, not an
.app), so click-to-focus is a no-op for these. Not currently supported. - VS Code fork window-precision is written but unverified (no forks were available to test); it degrades to app-level activation if the process-name guess is wrong.
needs-youis driven by permission-prompt notifications; if you run with permission prompts suppressed,waiting(from the registry) is the reliable "blocked on you" signal.
License
MIT
