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

@ohmaseclaro/fleetwatch

v0.1.10

Published

Watch every Claude Code, Cowork, and Cursor session from your phone — multi-provider agent observability with live updates over LAN or ngrok.

Readme

fleetwatch

Watch every Claude Code, Cowork, and Cursor session from your phone — live.

npm version license: MIT node >= 20

A single command turns your laptop into a live dashboard for every AI coding agent running on it. Pair your phone via QR code (or open from anywhere via free ngrok tunnel) and watch sessions stream in real time — message-by-message, tool-call-by-tool-call, screenshot-by-screenshot.

npx @ohmaseclaro/fleetwatch

That's the entire setup. No accounts, no signup, no config. Auto-discovers Claude Code, Cowork, and Cursor data wherever you've installed them.


What you see

  fleetwatch  v0.1.2
  ─────────────────────────────────────────

  Open this on your phone (works anywhere — via ngrok):

     https://given-relapsing-plop.ngrok-free.dev/?token=HWRfx3wlwTrlS8ALSsA2nEuP9Gfv1M8l

  Or scan the QR code below:

 ▄▄▄▄▄▄▄ ▄   ▄▄   ▄▄▄  ▄  ▄▄▄▄ ▄▄▄▄▄▄▄
 █ ▄▄▄ █   █▀ ▄  ▀██▀ ▄▄▄█▀▄ ▀ █ ▄▄▄ █
 █ ███ █ █ ████▀▀▄ ▄▀   ▄▀▀███ █ ███ █
 █▄▄▄▄▄█ █▀█ ▄▀█▀▄▀▄▀▄▀▄ ▄▀▄ ▄ █▄▄▄▄▄█
 ▄   ▄ ▄▄█▄▀▀▀█▀█ █▀▀▀█▄██   █▄▄▄▄▄  ▄
 ▄  █▄▄▄▄▀ █▄  ▄ ███ ▀█▀▄▄ ▄█▀ ▀▄▀▀▀▀
 ██▀▀▀█▄▀▀█ ▀ █ ▄ █▀▄▄██▀▄   █▄██▀▄██▄
 ▀█▀▀▄▄▄▄▄ ▀█▄  ██ █   ▄█████▀▄▄▄██▄█
 █▄█▄▄▄▄██▀ ▀▀▄▀▀ █ █ ▀▄ █▄▀█▄█▄▀▀▄█▄▀
 ▀▄█ ▀▀▄▀▀█  ▀▄▄▄▄ ▄▀▄▀ ▄ ▀ █▄██▀██▄▀
   ▄██▄▄▀▀  ▄█▄▀█ █ ▄▀█▄█▄ ▀█▀▄▄█▀ █▀
 █▀▀█ █▄▄  █▄ █ ██ ▄ ▄▄██ ▀▄█▄▀ ██▄▄▄
 █ █  ▀▄██ ▄▄ ▀▄▄ █▄█▀█ ▄▀  ▄▄▄██▀▄███
 ▀▀▀█▀▀▄▀ ▀▄▀▀▄▄██   ▄▄███▀ ██▀▀▄▀▀▀
 ▄▄▄██▀▄██▀▄▀▄ ██▀█ ▄██▀ ▄   ▄███▄ █ █
 ▄▄▄▄▄▄▄ █▀█▄▄ ▀█ ▄▀   ▄█▄█  █ ▄ █  ▀
 █ ▄▄▄ █ ▄  ▄▀▄█▀▄▀▀▀████    █▄▄▄███▄▄
 █ ███ █  ▄▀ ▀▀██ ▄█▀ ▀ ▄ █▀▀▄██▀  ▀▀▀
 █▄▄▄▄▄█ ▄▄▀█ ███ █▀▀█████ ▀█ ▀ ▄▀ ██▄
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

  Host:    YA-MN9RV4054G
  Port:    7878
  Tunnel:  https://given-relapsing-plop.ngrok-free.dev   (token via ngrok.yml (~/Library/Application Support/ngrok/ngrok.yml))
  Auth:    pairing token only (set PASSWORD to add a password)
  Cowork:  off (toggle in Settings)

  Press Ctrl+C to stop.

Scan the QR or paste the URL into your phone's browser. You'll see every session sorted by most-recent activity, with live status (running / waiting / errored / idle), source icons (Claude / Cowork / Cursor), and message-level streaming as the agents work.


Features

  • Three providers, auto-discovered
    • Claude Code (~/.claude/projects/*.jsonl)
    • Cowork (~/Library/Application Support/Claude/local-agent-mode-sessions/)
    • Cursor IDE (~/Library/Application Support/Cursor/User/globalStorage/state.vscdb)
  • Filterable tabs — All / Claude / Cowork / Cursor, each with a brand icon
  • Live streaming — WebSocket; events arrive on your phone within milliseconds of being written
  • Image attachments — screenshots from the screenshot tool, user-pasted images render inline with a tap-to-zoom lightbox
  • Session info modal — tap (i) on any session to see the full transcript path, project, git branch, session ID, file size, with copy-to-clipboard
  • Auto ngrok tunnel — works on any network when you have a free authtoken; auto-picks it up from existing ~/.../ngrok.yml if you've run ngrok config add-authtoken … before
  • Optional password gate — set PASSWORD=… in .env to require a password before any device can connect (bcrypt-hashed in memory, never on disk)
  • JWT auth — 30-day tokens issued on login; WebSocket and attachment endpoints all authed
  • Read-only by design — never writes to source data; opens DBs read-only; never follows symlinks during discovery; respects file inodes for safe rotation
  • Robust file discovery — env var → known paths → bounded filesystem search, with mandatory verify predicates so VSCode's state.vscdb never gets mistaken for Cursor's

Install

Run without installing (recommended)

npx @ohmaseclaro/fleetwatch

⚠ If you're hacking on the fleetwatch source itself, run npm start or node dist/server/index.js from the repo — running npx from inside the repo will collide with the in-repo package.json and fail with command not found.

Install globally

npm install -g @ohmaseclaro/fleetwatch
fleetwatch

After global install, the fleetwatch command is on your PATH.


ngrok setup (optional — for access from anywhere)

By default fleetwatch only works on the same Wi-Fi as your laptop. To reach it from cellular, coffee shops, anywhere — start ngrok automatically:

  1. Sign up free (no credit card): https://dashboard.ngrok.com/signup

  2. Copy your authtoken: https://dashboard.ngrok.com/get-started/your-authtoken

  3. Run with the token:

    fleetwatch --ngrok-authtoken <your-token>

    The token is persisted to ~/.config/fleetwatch/config.json so future runs Just Work.

Already ran ngrok config add-authtoken … for another project? Fleetwatch finds it automatically — zero extra config.


Password protection (recommended with ngrok)

Once you put a tunnel on the public internet, anyone with the URL can connect. Add a password:

echo 'PASSWORD=correct horse battery staple' >> .env
fleetwatch

Or use the Password protection section of the Settings screen in the UI (visible only from the desktop, not the phone). Devices must enter the password before connecting; bcrypt hash lives in memory only.

After successful login the client gets a 30-day JWT and the pairing token is no longer used — the QR URL can leak without compromising the daemon.


Configuration

All env vars are optional. Defaults work out of the box.

| Env var | Description | |---|---| | NGROK_AUTHTOKEN | ngrok free-tier authtoken. Enables the public tunnel. | | NGROK_DISABLED=1 | Skip the ngrok tunnel even if a token is available. | | CURSOR_DISABLED=1 | Skip the Cursor provider entirely. | | PASSWORD | Optional password — required to connect when set. Bcrypt-hashed in memory only. | | JWT_SECRET | JWT signing secret (auto-generated and persisted if not set). | | CLAUDE_PROJECTS_DIR | Override Claude Code projects dir. | | COWORK_DIR | Override Cowork sessions dir. | | CLAUDE_HISTORY_FILE | Override history.jsonl path. | | CURSOR_DB_PATH | Override Cursor state.vscdb path. | | PORT | Override default port (7878). | | HOST | Override default bind address (0.0.0.0). |

.env files are read from ./.env then ~/.config/fleetwatch/.env. Shell env always wins.

CLI flags

fleetwatch [options]

  --port, -p <port>       Port to listen on (default 7878)
  --host <host>           Bind address (default 0.0.0.0)
  --quiet, -q             Suppress QR / banner output
  --ngrok-authtoken <t>   ngrok authtoken (persisted to config)
  --no-ngrok              Disable ngrok for THIS run only (ephemeral)
  --ngrok                 Force-enable ngrok, overriding stored config
  --reset-ngrok           Clear the persisted "ngrok disabled" flag
  --no-cursor             Skip the Cursor IDE provider
  --help, -h              Show help

Providers

Each "provider" surfaces sessions from one source. Discovery is robust — every provider tries the default path, then OS-specific alternatives, then a bounded filesystem search, with a verify() predicate that confirms the candidate is actually that provider's data.

| Provider | Discovers | Format | |---|---|---| | Claude Code | ~/.claude/projects/*.jsonl (plus $CLAUDE_PROJECTS_DIR, XDG dirs, fallback search) | Append-only JSONL | | Cowork | ~/Library/Application Support/Claude/local-agent-mode-sessions/ | Append-only JSONL (same schema as Claude Code) | | Cursor | ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb (plus Linux/Windows paths) | SQLite, read-only |

Adding a new provider

Aider? Continue? GitHub Copilot Chat? Custom internal agents? Extending fleetwatch with a new source is intentionally small: declare a ProviderInfo, declare a DiscoverySpec, implement onStart / backfillSession.

Full guide: docs/ADD_A_PROVIDER.md


Security

  • All HTTP and WebSocket endpoints require auth (pairing token OR JWT).
  • Image attachments served from content-addressed (sha256) URLs — no enumeration possible.
  • Daemon is read-only:
    • JSONL files opened with append-only tailing (rotation-safe via inode)
    • SQLite opened with readonly: true + fileMustExist: true
    • Never follows symlinks during discovery
  • No telemetry. No external network calls except ngrok (when enabled).
  • All state lives in ~/.config/fleetwatch/ — a single JSON file.

Development

git clone https://github.com/ohmaseclaro/fleetwatch
cd fleetwatch
npm install

# In one terminal: Vite HMR for the PWA
npm run dev:web

# In another: daemon in watch mode
npm run dev:server

Production build:

npm run build
npm start                                    # serves built bundle on :7878

Releasing

scripts/release.sh handles everything:

./scripts/release.sh patch        # 0.1.2 → 0.1.3
./scripts/release.sh minor        # 0.1.2 → 0.2.0
./scripts/release.sh major        # 0.1.2 → 1.0.0
./scripts/release.sh patch --otp=123456   # if 2FA is enforced

The script:

  • verifies clean tree + on main/master
  • runs typecheck + build
  • bumps the version
  • creates a vX.Y.Z commit + tag
  • publishes to npm (token from .env via project .npmrc)
  • pushes to GitHub

First-time setup: docs/PUBLISHING.md.


License

MIT © Augusto Claro