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

@dosu/sessiondb

v0.3.0

Published

The sessiondb SDK: redact, normalize and store coding-agent sessions in the sessionstorage layout, and read them back. The server is a thin HTTP wrapper around this package.

Readme

@dosu/sessiondb

The sessiondb SDK: coding-agent sessions as a durable, redacted, content-addressed archive in a bucket you own, written in the sessionstorage layout.

bun add @dosu/sessiondb    # or npm install

One client, two backends:

import { connect } from "@dosu/sessiondb";

// Serverless: redact and normalize here, write the bucket with this machine's credential.
const db = connect({ store: "s3://acme-sessions/archive", owner: "alice" });

// Or through a sessiondb server, which runs the same pipeline against its own bucket.
const db = connect({ server: "https://sessiondb.acme.internal", token: process.env.SESSIONDB_TOKEN });

The calls are the same either way:

const result = await db.ingest({
  agent: "claude-code",
  session_id: "8f1c…",
  transcript: await Bun.file("~/.claude/projects/-repo-app/8f1c….jsonl").text(),
  project: "github.com/acme/widget",
});
// { status: "stored", content_hash: "…", records_total: 41, bytes_total: 48213, … }

// As the session goes on, send what the log gained since, from where the last answer ended.
await db.ingest({ agent: "claude-code", session_id: "8f1c…", transcript: tail, offset: result.bytes_total });

const metadata = await db.getSession("claude-code", "8f1c…");
const trace = await db.getTrace("claude-code", "8f1c…");
const page = await db.listSessions();
const feed = await db.changes({ after: cursor });
await db.tombstone("claude-code", "8f1c…");

And so is what they throw: SessionRejected (a transcript that cannot be stored, with the code the server would report), OffsetMismatch (a chunk that does not start where the log ends; expected says where), StoreError (the bucket, or the server, is unreachable). The HTTP backend adds ServerError for the responses that are not one of those.

Which backend

| | connect({ store, owner }) | connect({ server, token }) | |---|---|---| | Where redaction runs | On this machine, before any write | On the server, before any write | | What this machine holds | A bucket credential, scoped to owners/<owner>/ by bucket policy | A token for one owner | | Who sees the transcript unredacted | Only this machine | This machine, the network path, the server | | Owner isolation enforced by | The bucket's own policy | The server's token list |

One person with their own bucket wants the first. A team wants the second: redaction is enforced where a laptop cannot skip it, and one line in SESSIONDB_TOKENS is a person.

Stores

store is a Store or its URL: s3://bucket/prefix (AWS; S3_ENDPOINT for MinIO, Backblaze, Wasabi…), r2://bucket/prefix (Cloudflare; R2_ACCOUNT_ID), or file:///path. Credentials come from the usual AWS_* / R2_* variables or credentials in the options. openStore(url) is the same resolution on its own.

Runtimes

Bun runs the package from its TypeScript source (the bun export condition); Node 20+ loads the bundled dist/. Everything works on both except the S3/R2 store, which is over Bun.S3Client and throws a StoreError saying so under Node; a Node program that wants a bucket talks to a sessiondb server for now.

The HTTP backend takes timeoutMs (default 120 s per request, 0 to disable), userAgent (so the server's logs name the program, dosu-cli/0.68.5), and fetch for tests.

Lower down

storeSession, getSession, getTrace, listSessions, readChanges and tombstone are the pipeline over a Store without the client; normalizeTranscript, redactRaw, redactRecords and parseTrajectory are its pieces. spec/testdata/goldens/ pins what they produce.