npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@johnrobinsn/claude-watch

v0.7.1

Published

TUI dashboard for monitoring Claude Code sessions with tmux integration

Readme

claude-watch

A terminal UI dashboard for monitoring multiple Claude Code sessions running in tmux. See at a glance which sessions need attention, which are idle, and which are actively working—then jump to any session with a single keystroke.

Requires tmux. claude-watch is designed to run inside tmux and leverages tmux for session management, navigation, and state detection.

https://github.com/user-attachments/assets/74d77eee-191e-4224-aa87-9985efd1ace7

Features

  • Real-time monitoring of all Claude Code sessions across tmux
  • Color-coded status indicators:
    • 🔴 Red — Waiting for permission or user input
    • 🟡 Yellow — Idle at prompt
    • 🟢 Green — Actively working
  • tmux session list — Also shows non-Claude tmux sessions for easy navigation
  • Quick navigation — Press Enter to jump directly to any session
  • Fullscreen TUI — Uses alternate screen buffer, restores terminal on exit
  • Automatic session management — Automatically creates and switches to a dedicated watch session
  • Automatic cleanup — Removes stale sessions when Claude processes exit

Installation

From npm (recommended)

npm install -g @johnrobinsn/claude-watch

From source

git clone https://github.com/johnrobinsn/claude-watch.git
cd claude-watch
npm install
npm run build
npm link  # Makes 'claude-watch' available globally

Usage

From any tmux session, simply run:

claude-watch

On first run, claude-watch will prompt to install hooks in ~/.claude/settings.json. After that, it will:

  1. Create a watch tmux session if it doesn't exist
  2. Switch you to the watch session
  3. Start the dashboard
  4. Add a prefix + w keybinding to quickly return to the dashboard

Note: Requires tmux. If you run claude-watch outside of tmux, it will print an error and exit.

Keyboard shortcuts

| Key | Action | |-----|--------| | j / | Move selection down | | k / | Move selection up | | Enter | Jump to selected session | | h | Toggle help dialog | | q | Quit dashboard |

Quick access

From any tmux session, press prefix + w to jump to the dashboard.

How It Works

Architecture

┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  Claude Code    │────▶│  Hook Scripts    │────▶│  JSON Files     │
│  (running)      │     │  (on events)     │     │  (sessions/)    │
└─────────────────┘     └──────────────────┘     └────────┬────────┘
                                                          │
┌─────────────────┐     ┌──────────────────┐              │
│  tmux panes     │────▶│  Pane Polling    │──────────────┤
│  (capture)      │     │  (every 2s)      │              │
└─────────────────┘     └──────────────────┘              │
                                                          ▼
                                               ┌─────────────────┐
                                               │  claude-watch   │
                                               │  TUI (polling)  │
                                               └─────────────────┘

Claude Code Hooks

claude-watch uses Claude Code hooks to track session state changes:

| Hook | Purpose | |------|---------| | SessionStart | Register new session with PID and working directory | | UserPromptSubmit | Mark session as busy ("Thinking...") | | PreToolUse | Update status with current tool name | | PostToolUse | Clear tool-specific status | | Stop | Mark session as idle when turn ends | | Notification | Handle idle prompts, permission requests, elicitations | | SessionEnd | Remove session from tracking |

Tmux Pane Polling

NOTE: This heuristic exists because Claude Code does not currently provide a hook for when the user interrupts Claude with the Escape key. If a UserInterrupt hook is added to Claude Code in the future, this polling mechanism should be revisited.

Hooks don't fire when the user presses Escape to interrupt Claude mid-response. To handle this, claude-watch polls tmux panes every 2 seconds:

  • If "Esc to interrupt" is visible → Claude is working (busy)
  • If "Esc to interrupt" is NOT visible → Claude is idle

This bidirectional sync ensures the dashboard accurately reflects the true state even when hooks don't fire.

Data Storage

Session state is stored as individual JSON files in ~/.claude-watch/sessions/, one file per session. This approach eliminates native compilation requirements and allows atomic updates via temp file + rename.

{
  "v": 1,
  "id": "session-uuid",
  "pid": 12345,
  "cwd": "/path/to/project",
  "tmux_target": "main:1.0",
  "window_name": "vim",
  "state": "busy",
  "current_action": "Running: Bash",
  "prompt_text": null,
  "last_update": 1706745600000
}

Development

Prerequisites

  • Node.js >= 18
  • npm
  • tmux (for full functionality)

Running locally

# Clone the repository
git clone https://github.com/johnrobinsn/claude-watch.git
cd claude-watch

# Install dependencies
npm install

# Build TypeScript
npm run build

# Run directly
node dist/cli.js

# Or link for global access
npm link
claude-watch

Development workflow

# Watch mode (rebuild on changes)
npm run build -- --watch

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Check test coverage
npm run coverage

# Lint code
npm run lint

# Format code
npm run format

Project structure

claude-watch/
├── src/
│   ├── cli.ts              # CLI entry point
│   ├── app.tsx             # Main React/Ink app
│   ├── components/         # UI components
│   │   ├── Header.tsx
│   │   ├── HelpDialog.tsx
│   │   ├── SessionEntry.tsx
│   │   ├── SessionList.tsx
│   │   └── StatusBar.tsx
│   ├── db/                 # Session storage (JSON files)
│   │   ├── sessions-json.ts
│   │   └── index.ts
│   ├── hooks/              # Claude Code hook handler
│   │   └── claude-watch-hook.ts
│   ├── setup/              # Setup wizard
│   │   ├── hooks.ts
│   │   └── index.ts
│   ├── tmux/               # tmux integration
│   │   ├── detect.ts
│   │   ├── navigate.ts
│   │   └── pane.ts
│   └── utils/
│       ├── paths.ts
│       ├── pid.ts
│       └── version.ts
└── tests/                  # Test files (mirrors src/)

Upgrading

From npm

npm update -g @johnrobinsn/claude-watch
claude-watch  # Will prompt to update hooks if needed

From source

cd claude-watch
git pull
npm install
npm run build
claude-watch  # Will prompt to update hooks if needed

Uninstall

Remove hooks from Claude Code settings:

claude-watch --cleanup

This will remove claude-watch hooks from ~/.claude/settings.json.

To fully uninstall the package:

# Remove hooks first
claude-watch --cleanup

# Uninstall the npm package
npm uninstall -g @johnrobinsn/claude-watch

# Remove data directory (optional)
rm -rf ~/.claude-watch

Troubleshooting

Sessions not appearing

  1. Run claude-watch and accept the prompt to install hooks (if shown)
  2. Restart any running Claude Code sessions (hooks are loaded at startup)
  3. Check that ~/.claude/settings.json contains the claude-watch hooks

Status not updating

  1. Check that hooks are installed: cat ~/.claude/settings.json | grep claude-watch
  2. Ensure sessions directory exists: ls ~/.claude-watch/sessions/
  3. Restart Claude Code sessions to pick up new hooks

"No sessions" when Claude is running

The Claude session may have started before hooks were installed. Restart Claude Code to pick up the new hooks.

tmux binding not working

The prefix + w binding is added dynamically when claude-watch starts. If it's not working:

  1. Ensure claude-watch has been started at least once in this tmux server
  2. Check binding exists: tmux list-keys | grep "switch-client -t watch"

Requirements

  • Node.js >= 18
  • tmux (required)
  • Claude Code with hooks support

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Run tests (npm test)
  4. Commit your changes (git commit -m 'Add amazing feature')
  5. Push to the branch (git push origin feature/amazing-feature)
  6. Open a Pull Request