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

@bounded-sh/observe

v0.1.2

Published

Bounded observe shim for Node: intercepts fetch + http/https egress, attributes actors, reports metadata-only events to the Bounded observe ingest. Never breaks the app.

Readme

@bounded-sh/observe — Bounded observe shim for Node

CP1 origin for the observe/enforce project (SPEC-OBSERVE-ENFORCE-CUSTODY.md §3.1a). Intercepts your service's egressglobalThis.fetch (undici) and http/https.request — and reports metadata-only event batches to the Bounded observe ingest. Dependency-free at runtime. Never breaks the app: every shim code path is wrapped; original behavior is always preserved; observe is always fail-open (Bounded down ⇒ nothing changes for your app, T9).

Install

npm install @bounded-sh/observe
const { init, middleware, runAs } = require("@bounded-sh/observe");

init({
  ingestBase: "https://observe-ingest.buildwithtarobase.workers.dev",
  token: process.env.BOUNDED_SENSOR_TOKEN, // obs1.<keyId>.<sig>
  org: "your-org",
});

That's the whole install: call init() once, as early as possible (before other modules grab references to fetch). ESM: import { init } from "@bounded-sh/observe".

Actor context — who did it

Attribution rides the report only; nothing is ever added to your outbound requests (any X-Bounded-* header is actively stripped from egress and used purely as attribution fallback).

// Per-request (Express or Hono): maps your session to an actor for the whole
// request's async chain.
app.use(middleware());                       // default: req.session.user / req.user
app.use(middleware((req) => ({ actor: req.session.user.id, kind: "human" })));

// Explicit scope (bots, jobs, agents):
await runAs({ actor: "agent:support-1", kind: "agent", onBehalfOf: customerId }, async () => {
  await stripe.refunds.create({ charge, amount }); // reported as agent:support-1
});

Actor ids should be opaque internal ids, never emails (L9 — the ingest scrubber redacts email-shaped values as suspected PII). Unattributed calls are still captured (they roll up under the unattributed pseudo-actor).

What's captured vs. NOT (PII posture)

Captured (metadata only, per event): destination host, templated path (UUIDs / numeric ids / hashes / vendor ids become {id} before anything leaves your process), method, status, duration, byte counts, actor context.

Manifest-recognized routes (built-in v0 registry: Stripe refunds/charges/payment_intents; OpenAI + Anthropic spend) additionally recognize safe fields only: amounts in cents, opaque ids (ch_…, cus_…), model names, token counts. As of envelope v2 these ride the wire under rec.fields (a bounded, one-level object of primitive SAFE values) — rec{rail, action, registryVersion, fields} — and drive deterministic action stories on the dashboard. They also remain available locally via the onEvent hook. Server-side, ingest re-checks rec.fields KEYS against the L2 denylist and scrubs the VALUES (L4), so a leaked email/PAN never lands raw.

NOT captured, ever:

  • request/response bodies (unrecognized routes: top-level field names/types only, on the first sighting of a shape);
  • query-string values (names only, on shape samples);
  • headers (only scanned to strip X-Bounded-*);
  • prompts/completions/messages of LLM calls (not in any safe-field list);
  • PII-named fields — hard denylist (L2): email, card*, *_name, password, *token (auth-shaped; token counts are fine), address, ssn, dob, … are compiled into the shim and re-checked at extraction time. Even a malicious/buggy manifest listing customer_email cannot capture it, and even the names of PII-shaped fields are dropped from shape samples.

Fail-safe: no/invalid manifest ⇒ metadata-only mode. Server side, ingest re-filters (L3) and value-scrubs (L4) independently — the shim never sends org/sensor (server-stamped from your sensor key), scrubbed, or any unknown field.

Honest counts: if the shim ever drops events (bounded memory, backpressure), the drop count is reported on the next successful event (dropped) and surfaces downstream as completeness flags.

Event classes (SPEC §3.2)

| class | when | notes | |---------|------------------------------------------|-------| | action | recognized route, 2xx | rec{rail, action, registryVersion, fields} (v2 rec.fields = SAFE values) | | error | recognized route, non-2xx / network fail | rec{…, fields}; status 0 = never completed | | shape | unrecognized route, first sighting | deduped in-memory, rate-capped, names/types only | | counter | manifest counters matchers + hot unrecognized GETs (> 60 calls/min, exact from call #1) | one event per (route, minute): exact count, summed dur/bytes, class-representative status |

Kill switch

BOUNDED_OBSERVE_DISABLED=1

  • at process start: nothing is patched at all;
  • at runtime: observation stops within one flush tick (≤2s). Clearing the env resumes it.

Reporting behavior

Async batches (≤500 events or 2s), fire-and-forget with a 5s send timeout, single in-flight send, one retry for transient failures, bounded queue (default 5000 events) with drop-and-count on overflow. shutdown() performs a final drain (call it on SIGTERM to flush the tail). Hot-path overhead is microseconds (measured in test/perf.test.ts; U2 target <1ms p99).

Supported environments

  • Node 18 / 20 / 22 server apps (fetch + http/https interception).
  • Vercel / Next.js Node runtime: supported (call init() in instrumentation.ts or the server entry).
  • Edge runtimes (Cloudflare Workers, Vercel Edge, Deno Deploy): the root entry cannot load there (it needs node:async_hooks, node:crypto, and http/https patching) — use the @bounded-sh/observe/edge subpath instead (below).

Edge emitter (@bounded-sh/observe/edge)

For code that already sits at a chokepoint (a Worker proxy, an API gateway) and wants to REPORT events rather than intercept egress. No queue, no timers, no patching — one fire-and-forget envelope-v2 POST per call:

import { emitEvent } from "@bounded-sh/observe/edge";

emitEvent(
  { ingestUrl: env.BOUNDED_INGEST_URL, sensorToken: env.BOUNDED_SENSOR_TOKEN },
  {
    class: "action",
    actor: { id: tenantId, kind: "service", grade: "attested" },
    dest: { host: "api.anthropic.com", pathTemplate: "/v1/messages", method: "POST" },
    status: 200, dur_ms: 0, bytes: { i: 0, o: 0 },
    rec: { rail: "llm-gateway", action: "acme.tenant.aiRun", registryVersion: "acme-proxy",
           fields: { actualCents, "usage.input_tokens": inTok, "usage.output_tokens": outTok } },
  },
  ctx, // optional Workers ExecutionContext — the POST rides ctx.waitUntil
);

Posture: NO-OP unless both ingestUrl and sensorToken are present (delete the secret = kill switch); postEvent never rejects; the POST is bounded by timeoutMs (default 2000 ms); org/sensor are never sent — the ingest stamps both server-authoritatively from the sensor key.

Notes: http/https path records duration to response headers and takes bytes.o from Content-Length (0 when chunked); response-field recognition (LLM token counts) is fetch-path only.

Config quick reference

init({
  ingestBase, token,            // required
  org,                          // manifest polling scope
  sessionMapper,                // default mapper for middleware()
  aliasHosts,                   // {"127.0.0.1:4242": "api.stripe.com"} — dev/demo
  flushIntervalMs: 2000, sendTimeoutMs: 5000, maxQueueEvents: 5000,
  counterPromoteThreshold: 60,  // unrecognized-GET calls/min -> counter class
  shapesPerMinute: 30,          // new-shape rate cap
  manifest,                     // override (tests); invalid -> built-in (fail-safe)
  disableManifestPoll, manifestPollMs,
  debug, onEvent,               // debug hook: (wireEvent, recognizedFields)
});

Manifest (living capture policy, §3.1g)

The shim polls <ingestBase>/v1/manifest?org=… every 60s (T1: capture policy changes reach every interceptor without re-install). The endpoint doesn't exist yet — 404/invalid keeps the built-in manifest. Signed-manifest verification is a marked TODO in src/manifest.ts; until it lands, the built-in registry is the trust anchor.

Development

  • npm run build · npm test (76 tests: interception, templating, recognizers, counters, ALS context, header stripping, kill switch, L1/L2 PII behavior, envelope contract vs the real observe-shared validator, perf, and an integration run of the sample app in ~/bounded/observe-sample-app).
  • npm run test:live — LIVE prod verification: mints a dev sensor key (needs /tmp/observe-admin-secret.txt or $OBSERVE_ADMIN_SECRET), runs the sample app against prod ingest, asserts exact rollup deltas via the consumer's /internal/rollup/acme-demo.
  • Wire contract: src/envelope.ts mirrors the versioned envelope (v2) from packages/cdk/cloudflare/observe-shared; test/envelope-contract.test.ts fails on any drift (types + constants + runtime validation), including that every emitted v2 event (with rec.fields) passes the real ingest validator with ZERO stripped fields.