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

@latten/sdk

v0.1.2

Published

Latten SDK — observe-only TypeScript instrumentation for AI apps. Track LLM calls, data touches, external APIs, cost, reach, and PII exposure; Codex can install it via @latten/installer.

Downloads

446

Readme

@latten/sdk

See what your AI reaches, what it costs, and where PII goes — one line, zero dependencies.

Wrap the calls where your app reaches an LLM, your data, or another service, and their cost, reach, and PII exposure become visible in the Latten console. Observe-only by design: it never blocks or throws into your app, ships with zero runtime dependencies, and PII is counted locally — never copied off your machine.

Install

npm install @latten/sdk

Get a token: the fastest path is to let your coding agent do it — add @latten/installer as an MCP server and say "instrument this app with Latten." It mints a token with no login and wires the SDK in a reviewable PR. Prefer to do it by hand? Grab a LATTEN_TOKEN from latten.io and set it in your environment.

Usage

import { init, withActor, track } from '@latten/sdk'

// LATTEN_TOKEN is the only env var your app carries. The endpoint defaults to
// the hosted console; LATTEN_URL (or `endpoint`) overrides for sandbox/self-host.
init()

await withActor({ kind: 'person', id: userId }, async () => {
  await withActor({ kind: 'agent', id: 'support-agent' }, async () => {
    const rows = await track(
      { kind: 'data_domain', id: 'billing' },
      () => db.query('select ...'),
      { dataAction: 'read' },
    )
  })
})

Zero-config: instrument a client once

Don't want to wrap every call? Instrument the provider client once and every call it makes is tracked automatically — token usage read off each response:

import Anthropic from '@anthropic-ai/sdk'
import { instrumentAnthropic } from '@latten/sdk'

const anthropic = instrumentAnthropic(new Anthropic())
// …use `anthropic` exactly as before; every non-streaming call is now tracked.

instrumentOpenAI(new OpenAI()) does the same for chat.completions.create. Streaming calls pass through untouched — use trackStream() for streamed cost.

  • withActor builds the authority_chain (who's acting, on behalf of whom).
  • track(target, fn, opts) records a crossing around a call and returns its result unchanged.
  • PII is scanned locally; only types+counts are sent, never values.
  • No withActor frame ⇒ the source is reported as unattributed (the BOLA finding).

Install with Codex

If you use Codex, prefer the MCP installer first. Add @latten/installer as a Codex MCP server, then ask Codex to instrument the repo with Latten. Codex calls provision when no token exists, reads the embedded guide, scans TypeScript crossings, adds this SDK in a reviewable PR, verifies real traffic, and returns the receipt plus claim URL.

Docs: https://latten.io/codex

Downloaded packages do not create a Latten graph by themselves. The graph starts when your agent connects the installer, calls provision, and verifies real crossings. The first receipt is free and observe-only; claim the graph when you want team history, recommendations, agent-applied fix PRs, and verification.

LLM calls meter themselves

Wrap an LLM call with track and the SDK reads the usage straight off the response — model, input tokens, cached input tokens, output tokens, and reasoning tokens — normalized across Anthropic, OpenAI (both API shapes), and Gemini. You never plumb token fields by hand, and the console prices cached reads at their real ~0.1× rate instead of overstating a well-cached path:

// latten: crossing
const msg = await track(
  { kind: 'external_api', id: 'anthropic' },
  () => anthropic.messages.create({ model, max_tokens, messages }),
)

Explicit opts always win over auto-extraction. For unwrappable call shapes, use usageFrom(response) to extract and pass the fields to recordCrossing.

API

  • init(options?) — zero-config in prod (token from LATTEN_TOKEN, endpoint defaults to the hosted console / LATTEN_URL); options override: endpoint, token, scanner, maxQueue, flushIntervalMs, onDrop.
  • withActor(actor, fn) — push an actor frame onto the authority chain for the duration of fn.
  • track(target, fn, opts?) — wrap an async call as a crossing; returns fn()'s result.
  • recordCrossing(input) — the explicit primitive (no wrapping).
  • usageFrom(response) — normalize an LLM response's usage (model, inputTokens, cachedInputTokens, outputTokens, reasoningTokens); null for unknown shapes, never a guess.
  • flush() / shutdown() — drain the buffer / drain and stop.

Events are delivered on a non-blocking buffered queue with idempotent retry; the buffer is bounded and reports drops via onDrop.


You moved fast with AI. Latten helps you stay in control of it — latten.io