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

herdr-convo

v0.1.1

Published

Normalized, incremental conversation turns from OpenCode, Codex, Claude Code and Pi sessions

Readme

herdr-convo

npm license node

Read another coding agent's conversation as normalized turns.

Herdr knows which agent occupies a pane and whether it is working or finished. It does not read what that agent said. herdr-convo does, and presents Claude Code, Codex, OpenCode and Pi through one shape — so an orchestrator can follow another agent without knowing which agent is on the other side, and without scraping a terminal.

herdr-convo latest w1:p2 --text       # what that agent last said
herdr-convo read w1:p2 --cursor "$C"  # only what happened since

Install

Node 24 or newer, no runtime dependencies.

npm install -g herdr-convo            # the command
herdr plugin install arvemy/herdr-convo   # Herdr pane actions
npx skills add arvemy/herdr-convo     # agent skill

Or npx herdr-convo … to run it without installing.

Usage

herdr-convo read <target>     [--cursor C] [--limit N] [--text]
herdr-convo latest <target>   [--text]
herdr-convo locate <target>
herdr-convo inspect <ref>

A target is a Herdr agent name or pane id, and defaults to the invoking pane inside a plugin action. Without a Herdr server, address a session directly with --agent claude --session <id>.

Output is JSON unless --text is given. Errors are JSON on stderr with a code — handle cursor_stale, session_not_found, no_agent_session, herdr_unavailable and unsupported_agent.

cursor=$(herdr-convo read w1:p2 | jq -r .cursor)
while sleep 5; do
  new=$(herdr-convo read w1:p2 --cursor "$cursor")
  echo "$new" | jq -r '.turns[] | "\(.role): \(.text)"'
  cursor=$(echo "$new" | jq -r .cursor)
done

What a turn is

One user message, or one assistant response with everything it did to produce it. Reasoning, tool calls, results and patches are counted, never inlined, so reading a conversation does not drag a session's logs into your context.

{
  "turn_id": "claude:5df48142-…:a71c",
  "role": "assistant",
  "text": "There are 2 files.",
  "agent": "claude",
  "session_id": "5df48142-…",
  "omitted": { "reasoning": 1, "tool_calls": 1, "patches": 0 },
  "refs": ["eyJhIjoiY2xhdWRl…"],
  "complete": true
}

Nothing is thrown away: every omitted block leaves a ref, and inspect <ref> returns that one block without reading the rest of the session.

Two invariants, because getting either wrong fails silently. A cursor never advances past a turn still being written — an in-progress answer is re-sent whole once it finishes, never in halves. And only what a person typed becomes a user turn: every harness writes its own context as user messages (slash commands, environment blocks, skill prompts, compaction summaries), and each adapter filters them on the strongest signal its format carries.

Providers

| Agent | Source | Position | | --- | --- | --- | | Claude Code | ~/.claude/projects/<cwd-slug>/<session>.jsonl | byte offset | | Codex | ~/.codex/sessions/YYYY/MM/DD/rollout-*-<session>.jsonl | byte offset | | Pi | ~/.pi/agent/sessions/<cwd-slug>/<time>_<session>.jsonl | byte offset | | OpenCode | ~/.local/share/opencode/opencode.db | part and message ids |

Sessions are read where the agent writes them. Nothing is copied or cached, and reads are read-only.

Development

git clone https://github.com/arvemy/herdr-convo && cd herdr-convo
npm install
npm run check        # typecheck and the full suite
npm link             # herdr-convo on PATH
herdr plugin link .  # plugin follows the working tree, unlike `install`

From a checkout, TypeScript runs directly. The published package ships compiled JavaScript, because Node refuses to strip types under node_modules.

Every provider goes through the same conformance cases in test/conformance.ts, so a new adapter is a classification table, a fixture directory and one runConformance call. Fixtures are synthetic; HERDR_CONVO_REQUIRE_REAL_SESSIONS=1 additionally asserts against real sessions on your machine.

docs/conversation-layer.md is the contract: turn model, cursor and ref semantics, per-provider turn-end signals, error codes, and the bounds that are stated rather than papered over.

License

Apache 2.0 — see LICENSE.