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

@generative-a11y/devtools

v0.1.1

Published

Development-only accessibility diagnostics and a redacted trace explorer for screen-reader announcements in AI runtimes.

Readme

@generative-a11y/devtools

Opt-in, development-only diagnostics for generative-a11y runtimes. The default headless store is framework-neutral, side-effect-free on import, and retains a bounded redacted trace: it stores categories, timing, outcomes, stable runtime IDs, queue/entity snapshots, and browser delivery metadata. It never retains assistant text, labels, error messages, tool data, stacks, or DOM content.

npm install --save-dev @generative-a11y/devtools
import { createDevtoolsStore } from "@generative-a11y/devtools";
import { THREAD_ADAPTER_METADATA } from "@generative-a11y/assistant-ui";

const store = createDevtoolsStore({ maxEntries: 250 });
const detach = store.attachRuntime({
  id: "support",
  runtime,
  source: {
    adapter: THREAD_ADAPTER_METADATA.name,
    fidelity: THREAD_ADAPTER_METADATA.fidelity,
    evidence: THREAD_ADAPTER_METADATA.observedRuntimeMethods,
  },
});
const unsubscribe = store.subscribe(renderDiagnostics);

store.pauseCapture(); // Does not pause or alter the runtime.
store.resumeCapture();
store.refreshSnapshots();
const trace = store.exportTrace(); // schema-versioned and redacted
store.clear();

unsubscribe();
detach();
store.dispose();

Store API

  • createDevtoolsStore({ maxEntries }) creates an isolated store. maxEntries defaults to 250, must be a positive safe integer, and bounds the retained ring buffer. droppedCount reports records evicted since the last clear().
  • attachRuntime({ id, runtime }) validates a non-empty ID, subscribes only to public diagnostics, captures an initial safe snapshot, and returns an idempotent detach function. Attaching the same ID replaces its subscription only after the replacement subscribes successfully.
  • subscribe(listener) observes store snapshot changes and returns an idempotent unsubscribe function. Listener failures do not alter capture.
  • getSnapshot() returns a cached, immutable, content-free view until captured state changes. refreshSnapshots() explicitly requests fresh runtime snapshots without changing the observed runtimes.
  • pauseCapture() and resumeCapture() change devtools capture only. They do not pause scheduling, delivery, or any host runtime behavior.
  • recordDelivery(input) adds validated, content-free DOM delivery evidence. It records nothing while capture is paused or after disposal, but malformed IDs and timestamps still throw so integration defects remain visible.
  • exportTrace() refreshes runtime snapshots and returns an immutable, schema-versioned, redacted trace. clear() removes retained records and resets droppedCount without detaching runtimes.
  • dispose() is idempotent. It detaches all runtimes, clears captured state, publishes one final empty snapshot to current subscribers, and then removes those subscribers. Later attachment or subscription attempts throw; other control methods are no-ops.

The store only subscribes through subscribeDiagnosticEvents() and does not monkey-patch dispatch, access browser globals, create UI, retain a core history, or alter accessibility policy. A captured DOM/API delivery remains evidence of an action, not proof that assistive technology spoke it.

Declared adapter evidence

Pass source when attaching a runtime driven by an adapter. This is an explicit, serializable declaration from the integration, not framework detection by devtools. It lets an inspector show the adapter name, documented public evidence and declared fidelity without filling gaps in the lifecycle trace. Workflow fidelity distinguishes runs, steps, hierarchy, tools, interactions, replay, reconnection, and unsupported custom events as exact, partial, or unavailable where applicable. The inspector also shows content-free run and step parentage, attempt boundaries, active or terminal state, and associated entity IDs from the core diagnostic snapshot. interruption and retries accept exact, action-wrapper, or unavailable. connection accepts those values plus inferred, because some integrations can only derive connection state from another documented public signal. The store freezes a copy of this metadata and includes it in its redacted export. Each captured record references an opaque runtimeSourceId. Source revisions remain immutable and exportable for as long as a retained record references them, even after a runtime detaches or the same runtime ID is reattached with different metadata. Unreferenced revisions are removed with ring-buffer eviction so repeated attachment cannot create unbounded source history.

Use an adapter package's exported metadata where it fits the integration. For custom adapters, provide only public signals that justify normalized events. Do not put user content, internal URLs, or private framework state in evidence. The store accepts at most 12 public evidence strings, each at most 120 characters, and rejects unsupported fidelity or optional-event values before it subscribes to a runtime.

Browser delivery correlation

The store intentionally does not import @generative-a11y/dom. Connect the announcer's public diagnostic callback yourself to capture a content-free delivery record alongside runtime decisions:

const announcer = createDOMAnnouncer({
  onDiagnostic(result) {
    store.recordDelivery({ runtimeId: "support", result });
  },
});

This exposes the browser-level method and status (aria-notify, fallback live region, unavailable, or disposed) and safe correlation IDs. It still cannot establish what a screen reader announced.

Explicit overlay

@generative-a11y/devtools/overlay is an optional browser-only mounting helper. It creates one open Shadow DOM host only when called and starts collapsed. The mounted workbench is built from package-local shadcn/Radix components, with its styles contained inside that Shadow DOM. It provides one searchable, filterable Accessibility Trace Explorer with a keyboard-managed trace list, selected causal evidence, plain-language policy and delivery context, collapsed raw metadata, capture pause/resume/clear/refresh actions, and explicit trace copy. These actions affect only devtools capture, never runtime policy, queueing, focus, or host UI.

Opening the overlay moves focus into the workbench; closing it restores the element focused before the launcher was activated. Streaming records never move focus. The overlay does not trap focus, create a live region, modify host layout, or install global shortcuts.

import { mountDevtoolsOverlay } from "@generative-a11y/devtools/overlay";

const overlay = mountDevtoolsOverlay({ store });
overlay.dispose();

Documentation

Related packages