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

@prufs/trail-hooks

v0.1.0

Published

Signed, hash-chained Prufs audit trail for agentic coding sessions. Metadata only, never file contents or prompts.

Readme

@prufs/trail-hooks

Signed, hash-chained audit trails for agentic coding sessions. One command per hook, one receipt per session.

Agentic coding tools edit files and run commands on your behalf. When an examiner or an auditor asks what the agent did, most teams have nothing to show. This package gives Claude Code (and Cursor, see below) a tamper-evident record of each session: what tools ran, how often, against which files, signed with your own Ed25519 key and anchored at api.prufs.ai with a verifiable receipt.

Privacy stance, first

The trail is metadata only. Events carry:

  • tool name (Edit, Write, Bash, NotebookEdit)
  • a redacted file path (basename by default; full path or a truncated hash if you choose)
  • timestamps, counts, and the session id
  • exit codes for Bash, when the hook payload exposes one

Events never carry file contents, never prompts, never conversation text, and never command strings. For a Bash step the trail records that Bash ran and whether it failed. It does not record what the command was. This is enforced at the capture site in the code, stated in comments there, and covered by tests that feed secrets through the hooks and assert they never reach disk.

If the trail is not configured, every command exits 0 silently. If anything fails at runtime, the error goes to ~/.prufs/trail-hooks.log and the coding session continues untouched. A hook must never break your session.

Quickstart

npm install -g @prufs/trail-hooks
prufs-trail init

init writes ~/.prufs/trail-hooks.json, generates an Ed25519 keypair at ~/.prufs/trail-hooks.pem (owner-read-only), and prints your signer id plus the exact curl to register the public key with your Prufs org. Registration needs an org admin key; day-to-day flushes need only an ingest key:

export PRUFS_API_KEY=<your org ingest key>

Then merge the ready-made hooks block into your ~/.claude/settings.json (or a project's .claude/settings.json). The block ships in this package at hooks/claude-code.json:

  • SessionStart runs prufs-trail event session_started
  • PostToolUse (matcher Edit|Write|NotebookEdit|Bash) runs prufs-trail event tool_use
  • Stop runs prufs-trail event session_ended && prufs-trail flush

That is the whole integration. Events buffer locally per session in ~/.prufs/trail-sessions/. On flush they are coalesced (repeated edits to one file become one event with a count, so a session always fits the 100-event batch cap), signed into a hash chain with genesis prev_hash "0", and shipped as one batch. The receipt lands in ~/.prufs/trail-receipts/<session_id>.json.

Claude Code fires Stop at the end of every turn, so a multi-turn session produces one genesis batch and then continuation batches. Each continuation chains from the stored session head and the server verifies the link, so the whole session still reads as one continuous chain that opens with session_started and closes with session_ended.

Verifying a receipt

prufs-trail verify <session_id>

This recomputes every content hash and Ed25519 signature locally with @prufs/sdk (the same verifyEvent the server trusts) and checks the chain links, including across batches. With PRUFS_API_KEY set it also fetches each server receipt from GET /v1/event-receipts/:id and confirms the stored head matches your local head. A receipt with verification_status: verified_ed25519_hash_chain means the server checked the same math before storing.

Anyone with your public key can verify the chain independently. The signing contract is @prufs/sdk 0.2.2: content_hash is the SHA-256 of the canonical JSON (sorted keys) of the six unsigned fields, and the signature is Ed25519 over utf8(content_hash + prev_hash).

Cursor

Cursor has a native hooks system (~/.cursor/hooks.json or <project>/.cursor/hooks.json) with sessionStart, afterFileEdit, beforeShellExecution, and stop events that pipe JSON to a command, the same shape of integration as Claude Code. The payload field names differ (conversation_id rather than session_id, hook_event_name casing, per-edit diffs in afterFileEdit), so the Claude Code adapter does not read them yet. A hooks/cursor.json adapter is the next milestone; until then Cursor users can call prufs-trail event from a small wrapper script that maps conversation_id to session_id and strips the edits array before piping.

Why

The Federal Reserve's SR 26-2 flagged the gap between what firms claim about generative AI controls and the evidence they can produce. Agentic coding sits squarely in that gap: the work is real, the record usually is not. A signed, hash-chained trail with server receipts is evidence you can hand over, and because it is metadata only, handing it over discloses nothing about your code.

Commands

| Command | What it does | |---|---| | prufs-trail init | Write config, generate the signing key, print signer id and registration curl | | prufs-trail event <type> | Hook entry point; buffers one metadata event from stdin | | prufs-trail flush [session_id] | Sign, chain, and ship buffered events; store the receipt. Without an argument, flushes every session that has ended. With one, forces a flush | | prufs-trail verify <session_id> | Recompute the chain locally; fetch server receipts when credentials exist |

Configuration

~/.prufs/trail-hooks.json:

{
  "apiBase": "https://api.prufs.ai",
  "apiKeyEnv": "PRUFS_API_KEY",
  "signingKeyPath": "~/.prufs/trail-hooks.pem",
  "redaction": "basename",
  "projectId": null
}

redaction is basename (default), full, or hash. projectId null means the project id is the basename of the session's working directory. Set PRUFS_TRAIL_HOME to relocate all state away from ~/.prufs.

License

Apache-2.0.