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

@easytocloud/sessionscope

v0.3.11

Published

Tail Claude Code JSONL sessions and stream SessionScope records over SSE.

Readme

@easytocloud/sessionscope

Tails Claude Code's JSONL session logs and streams SessionScope records over SSE using @easytocloud/sessionscope-core to parse each session — so the three views (Dialog / Graph / Timeline) in @easytocloud/sessionscope-web light up against a real ~/.claude session instead of mock data.

src/server.js   startServer({dir, port, capture, serveDir}) — chokidar tail +
                incremental read + SSE broadcast + capture matching
src/tee.js      startTee({port, capture, upstream}) — optional
                ANTHROPIC_BASE_URL tee that writes the capture log
bin/sessionscope.js      CLI: parses flags, calls startServer()
bin/tee.js                CLI: parses flags, calls startTee()

Both startServer and startTee are exported so a future @easytocloud/sessionscope-vscode extension can start them in-process inside a webview host, instead of shelling out to the CLI.

Run

npx @easytocloud/sessionscope                      # watches ~/.claude/projects, SSE on :4317
sessionscope --dir ~/.claude/projects --port 4317
sessionscope --serve ../web/dist                    # override with a custom-built UI

The published package already bundles a built @easytocloud/sessionscope-web UI, served at / by default — no --serve flag needed. Pass --serve <dir> to override it with a UI built from source instead. Open http://localhost:4317/raw for the built-in raw feed (no build step, always available). No real data yet? npm run fixture at the repo root, then sessionscope --dir ./fixtures.

Captured payloads (the drawer's Reconstructed ↔ Captured diff)

The JSONL faithfully reconstructs the message body but not the request envelope (tools schemas, cache_control placement, max_tokens, anthropic-beta). Feed those from a proxy capture:

# terminal 1 — tee sits in front of the real API, logs request bodies by request-id
sessionscope-tee --capture ./capture.ndjson
export ANTHROPIC_BASE_URL=http://localhost:4318

# terminal 2 — server reads the same capture log
sessionscope --capture ./capture.ndjson

The tee keys each body by the response request-id header, which is exactly the requestId Claude Code records in the JSONL — so the matcher lines them up per node. Already have your own BASE_URL interceptor? Just emit NDJSON of { "requestId": "<response request-id>", "body": { ...request... } } to the capture file and skip the tee.

Transparent capture (zero manual steps)

Skip the manual export/restore dance entirely. Run once per project:

sessionscope-tee-install

This installs SessionStart/SessionEnd hooks into .claude/settings.local.json. From then on, just run claude normally in any terminal — the first session in the project transparently starts a shared sessionscope-tee daemon and points ANTHROPIC_BASE_URL at it; opening more terminals joins the same daemon instead of starting another one; closing the last session stops the daemon and restores ANTHROPIC_BASE_URL to whatever it was before (including removing it entirely if it wasn't set). Subagents are captured automatically too — they run in-process in the same claude invocation and inherit the same env, so there's nothing extra to wire up.

Capture lands at .claude/sessionscope-tee/capture.ndjson (git-ignored automatically); point the viewer at it:

sessionscope --capture .claude/sessionscope-tee/capture.ndjson

If a session crashes without a clean exit, the next SessionStart detects the dead daemon and recovers automatically. For a manual reset (force-stop the daemon, restore settings) run sessionscope-tee-install --teardown.

Known limitation: background/remote agent dispatch does not reliably inherit ANTHROPIC_BASE_URL from the gateway environment, so traffic from those won't be captured by this mechanism.

Endpoints

| route | returns | |---|---| | GET /events[?session=<id>] | SSE: reset, then a record per node, plus meta | | GET /snapshot[?session=<id>] | full current record set as JSON | | GET /sessions | known session files, newest first, + the active one, each with a title | | GET /record?session=<id>&uuid=<u>&blockIndex=<n> | full (untruncated) text for one content block | | GET / | bundled web UI, or --serve <dir> override if set, else the raw feed | | GET /raw | status page + live raw feed (always available) |

Default active session = most-recently-modified *.jsonl under --dir. Pin one with ?session=<uuid>.

Every SessionScope node ships firstLine()-truncated previews only — the full text of a prompt, tool input, or tool result is fetched on demand via /record, keyed by the {uuid, blockIndex} ref the parser attaches to each message/tool node. /sessions titles prefer Claude Code's own ai-title record, falling back to the first real user prompt.