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

@webcontextinterface/annotator

v1.3.0

Published

WCI annotator — derive data-wci-* annotations from unannotated HTML using accessibility semantics

Readme

@webcontextinterface/annotator

Derive data-wci-* annotations from HTML that nobody annotated.

npx @webcontextinterface/cli annotate legacy-page.html --out annotated.html
import { inferView, applyInferredAnnotations } from '@webcontextinterface/annotator';

const view = inferView(document);              // agent-facing view, DOM untouched
const result = applyInferredAnnotations(document); // or write attributes in place

Why

WCI is inert on a page nobody annotated, which is currently most of the web — the adoption problem in one sentence. This closes the gap from the agent's side by reconstructing the annotation layer from signals the page already carries: accessible names, ARIA roles, label[for] associations, form structure, and native element semantics.

Adoption becomes an optimisation rather than a precondition. An agent works on an unannotated site immediately; operators annotate to improve results they can already observe.

What it derives

| Field | From | |-------|------| | role | Native tag, ARIA role, landmark elements, aria-live | | desc | aria-labelaria-labelledbylabel[for] → wrapping label → text → placeholder | | action | Element type — fill, select, check, upload, click, navigate | | state | value, checked, disabled, aria-expanded, aria-selected | | options | <option> values, or a radio group's shared name | | scope | Nearest enclosing derived landmark | | priority | Submit buttons and required fields rank first; nav and secondary actions last |

Password values are never captured. aria-hidden, [hidden], and inline display:none are honoured through the whole subtree, so controls no user can reach are not offered to an agent.

Confidence

Every node carries a 0–1 confidence and the evidence behind it:

const { nodes, meanConfidence } = inferAnnotations(document);
// { id: 'email', desc: 'Billing email', confidence: 1, evidence: ['label[for]'], … }

An aria-label on a native button scores high; a <div onclick> with no accessible name scores low. Filter with minConfidence when precision matters more than coverage.

What it cannot do

Inference reaches "Place Order". An operator writes "Submit order — charges the saved card and cannot be undone". On the 50-scenario WCI benchmark, derived descriptions average 13.5 characters against 26.9 for curated ones.

It also cannot derive wci.txt policy. An operator's stated limits — denied scopes, auth requirements, actions needing human confirmation — are not inferable from markup by design, which is exactly why the AX layer must be authored.

Treat output as a starting point a developer edits, not a finished annotation.

MIT © WCI