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

@legionworks/facet

v1.10.5

Published

<p align="center"> <strong>◆ facet</strong> </p>

Readme


Problem

An agent can emit a diagram or chart and see something that looks fine in the transcript. That is not evidence that the artifact rendered. A page can also produce a screenshot or page-shim report that says it rendered correctly; the page controls both claims.

Facet stores the source bytes without interpreting them, then asks independent validation layers what they observed. The verdict is bound to the exact revision SHA. Artifact code can influence the page, but it cannot rewrite the protocol observation after the fact.

What it does

  • Publishes markdown, mermaid, svg, chart, static html, and declared-mode tsx artifacts.
  • Stores immutable revisions and keeps a ring of up to 50 per artifact.
  • Records a stored Tier 0 verdict in every publish response; Tier 1 isolated browser validation and Tier 2 display-only inspection are explicit follow-up work.
  • Compares lexical expectations with protocol, isolated-world, and page-shim observations.
  • Serves a sandboxed, loopback gallery with revision-bound evidence and SSE updates.
  • Retains Tier 1 WebP captures of the whole artifact, console output, and protocol observations under an owner-only evidence directory. Interactive TSX declares animated WebP eligibility; static artifacts become eligible only when live CSS or Web Animations are detected.
  • Defaults the gallery theme to system; users can choose dark or light and the tab keeps that choice.
  • File-mode export returns local artifact and required sidecar paths with byte counts; --include-bytes opts into base64 in the envelope.
  • Keeps the service byte-dumb: renderers and parsers stay outside src/service/**.

Current gallery captures use the Mermaid fixture in resolved dark and the chart fixture in resolved light. They are 3840×2160 PNG display assets; Tier 1 evidence is WebP for the whole artifact.

Install

Facet is distributed as @legionworks/facet. Bun is the required runtime (version 1.4.0 or newer); install it first using the official Bun installation instructions. npm and pnpm distribute Facet, but do not provide Bun. npm alone is not enough.

Recommended:

bun add -g @legionworks/facet

Other distribution channels:

npm i -g @legionworks/facet
pnpm add -g @legionworks/facet

For a zero-install invocation:

bunx @legionworks/facet <verb>

The first visual read-back requires the pinned browser. If it is missing, facet doctor prints the install command. See the CLI reference for the command contract and MCP reference for structured-tool-only hosts.

Quickstart from an installed binary

This walkthrough uses the globally installed facet command, not a source checkout. It creates disposable runtime and export directories.

export FACET_HOME="$(mktemp -d)"
facet status --start
facet doctor
bunx --bun puppeteer browsers install [email protected]
SOURCE='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 80"><rect width="240" height="80" rx="8" fill="#202638"/><text x="20" y="48" fill="white">Facet quickstart</text></svg>'
SOURCE_FILE="$(mktemp)"
printf '%s' "$SOURCE" > "$SOURCE_FILE"
ARTIFACT_ID="$(facet create --project-id demo --slug quickstart --title 'Quickstart' | bun -e 'const x=JSON.parse(await Bun.stdin.text()); if(!x.ok) throw new Error(x.error.code); console.log(x.data.artifact.id)')"
PUBLISH="$(facet publish --artifact-id "$ARTIFACT_ID" --type svg --file "$SOURCE_FILE")"
printf '%s\n' "$PUBLISH" | bun -e 'const x=JSON.parse(await Bun.stdin.text()); if(!x.ok || !x.data.verdict) throw new Error("publish failed"); console.log(JSON.stringify(x.data.verdict))'
REVISION_SHA="$(printf '%s\n' "$PUBLISH" | bun -e 'const x=JSON.parse(await Bun.stdin.text()); console.log(x.data.revision.sha256)')"
facet read-back --artifact-id "$ARTIFACT_ID" --revision-sha "$REVISION_SHA" --tier visual
EXPORT_DIR="$(mktemp -d)"
facet export "$ARTIFACT_ID" --format source --out "$EXPORT_DIR/artifact.svg"

doctor checks the local runtime and browser setup and prints the browser install command if the pinned shell is missing. Install it before visual read-back. Inspect data.verdict in the publish envelope: an ok command envelope only confirms transport, and the stored verdict can still have status: "error".

Verdict language

The gallery and CLI use the same wire enum, glyph, hue, and treatment.

| enum (wire, verbatim) | glyph | hue | treatment | | ---------------------------- | ----- | --------- | ----------------------------------- | | ok | ✓ | #c3e88d | outline — proof, not celebration | | error | ✗ | #ff757f | outline | | partial:layout_unverified | ◐ | #ffc777 | outline; screenshot required | | partial:opaque_content | ◐ | #ffc777 | outline; screenshot required | | partial:external_resources | ◐ | #ffc777 | outline; screenshot required | | partial:unstable | ◐ | #ffc777 | outline; screenshot required | | partial:empty_render | ◐ | #ffc777 | empty TSX root; screenshot required | | tampered | ⊘ | #ff757f | filled alarm badge | | timeout | ◌ | #737aa2 | dim outline | | shim_only | ◇ | #737aa2 | dim outline | | probe_only | ◈ | #737aa2 | dim outline |

partial:external_resources means an artifact references external HTTPS images the no-egress verifier could not load. An ok verdict can still carry Verdict.screenshotError.code: "screenshot_unavailable" when whole-artifact capture cannot be produced; it records the limit without changing the validation result. insecure:unvalidated means level 3 intentionally skipped validation. A missing verdict is UNVERIFIED with no tier.

Why not just screenshot it?

| Approach | What it can establish | Trust boundary | | --------------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | Page-shim claim | Counts reported by JavaScript in the artifact page | Untrusted; a forged report becomes shim_only when the other channels are absent and tampered when it diverges | | Tier 1 protocol observation | DOM and renderer observations from the verifier, compared with an isolated-world probe and the page shim | Independent of the artifact's own claim; disagreement is tampered | | Tier 2 display-only view | What a human sees in the user's browser | No validation verdict; useful for inspection, not proof |

A screenshot is evidence of pixels. It is not evidence that the page's own report was honest.

What's in the box

  • CLI contract — create, publish, list, read-back, status, open, promote, instantiate, pin, and export (source/render with a mandatory sidecar).
  • Artifact types — Markdown, Mermaid, SVG, Vega-Lite chart specs, static HTML, and static or interactive TSX. Chart data must be inline; external data.url forms are rejected. HTML is script-free, has no <style> block or style= attribute, and styles from a vendored Tailwind/daisyUI vocabulary (reference).
  • Gallery — an offline-built shell with a direct-frame render API, a restrictive per-artifact CSP, zoom controls, and revision SSE.
  • Validation — a 5 MiB source cap, up to 64 Mermaid blocks and 10,000 Mermaid nodes, and a 1 MiB SVG cap with 16 roots. Tier 1 uses pinned chrome-headless-shell 151.0.7922.77; v9 evidence-format metadata is documented in the Export reference.
  • Templates — eleven checked-in starting points in templates/, documented in templates/README.md.

From source

For contributors working in a checkout, requires Bun 1.4.0 or newer. Bun 1.4.0 fixes oven-sh/bun#37230, the fd-reuse bug that affected CDP-pipe browser runs.

bun install

export FACET_HOME="$(mktemp -d)"
SOURCE='# Facet quickstart'
bun ./src/cli/main.ts status --start
ARTIFACT_ID="$(bun ./src/cli/main.ts create --project-id demo --slug chart --title "Chart" | bun -e 'const x=JSON.parse(await Bun.stdin.text()); if(!x.ok) throw new Error(x.error.code); console.log(x.data.artifact.id)')"
PUBLISH="$(printf '%s' "$SOURCE" | bun ./src/cli/main.ts publish --artifact-id "$ARTIFACT_ID" --type markdown)"
printf '%s\n' "$PUBLISH" | bun -e 'const x=JSON.parse(await Bun.stdin.text()); if(!x.ok || !x.data.verdict) throw new Error("publish failed"); console.log(JSON.stringify(x.data.verdict))'
REVISION_SHA="$(printf '%s\n' "$PUBLISH" | bun -e 'const x=JSON.parse(await Bun.stdin.text()); console.log(x.data.revision.sha256)')"
bun ./src/cli/main.ts read-back --artifact-id "$ARTIFACT_ID" --tier 0
bun ./src/cli/main.ts read-back --artifact-id "$ARTIFACT_ID" --revision-sha "$REVISION_SHA" --tier visual
EXPORT_DIR="$(mktemp -d)"
bun ./src/cli/main.ts export "$ARTIFACT_ID" --format source --out "$EXPORT_DIR/artifact.md"

This checkout invocation needs no global link. It uses disposable runtime and export directories. The read-back without --revision-sha uses the latest revision; pass the SHA returned by publish when reproducibility matters. Tier 0 is browser-free; visual read-back is explicit Tier 1 escalation. Each verb writes one JSON envelope to stdout; ok confirms command transport, so inspect data.verdict in the publish envelope, including a stored status: "error".

Facet's insecure mode is an explicit, boot-only opt-in (FACET_INSECURE=1|2|3) and is never the default. It weakens or skips validation by level, marks every affected verdict, and speaks loudly at startup, in envelopes, in the CLI, and in the gallery. FACET_INSECURE_AUTO=1 permits startup probe fallback but never selects level 3. Restart after changing either environment variable.

MCP

On harnesses with shell access, the CLI is the integration; the MCP adapter is for structured-tool-only environments. The npm package includes six CLI-backed tools: facet_create, facet_publish, facet_read_back, facet_status, facet_export, and facet_open_url. It requires Bun 1.4.0. Register it with bun add -g @legionworks/facet followed by the bare facet-mcp command; npx -p @legionworks/facet facet-mcp is the no-install alternative. See the MCP reference for OpenCode, Claude Code, and Codex registration.

Documentation

Status

Facet is a young, single-maintainer project. It targets local and single-operator workflows: the service binds to loopback, has no user-account authentication by design, and still protects routes with install/operator bearer capabilities. Interfaces may shift before 1.0. Bun 1.4.0 includes the verified fd-reuse fix for CDP-pipe browser runs. Current TSX compiler and runtime evidence lives in TSX measurements.

License

MIT OR Apache-2.0, at your option. See LICENSE-MIT or LICENSE-APACHE.