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

@playcode/okf-lint

v2.2.0

Published

Readout - the document format agents hand back: routed diagrams, charts, KPI tiles and notebook pages from plain text, rendered self-contained and verified. Plus the OKF docs-profile linter (frontmatter, cross-links, indexes).

Readme

@playcode/okf-lint

Readout: the document format agents hand back. A compact plain-text language (```readout fences in markdown) that renders routed diagrams, real charts, KPI tiles and notebook pages as one self-contained interactive HTML file - written by agents, read by humans, verified faithful. This package also ships the OKF docs-profile linter the format grew out of. The former language name okf-d remains a permanent fence alias.

Rendered from examples/orders.diagram.md by okf diagram - no coordinates in the source, no hand-placed arrows, no Mermaid.

A linter for the docs/ knowledge base. It enforces a minimal OKF-style profile (markdown + YAML frontmatter + cross-links), generates per-folder index.md manifests, checks links, and reports staleness - so docs stay findable by both humans and agents.

Dependency-free at runtime (hand-rolled frontmatter/markdown parsing); run from source via tsx, no build step.

Usage

From the repo root:

pnpm okf check [--staged]   # validate frontmatter (+ links). --staged: only git-staged docs (the ratchet)
pnpm okf links              # dangling cross-links across the whole bundle
pnpm okf index [--check]    # regenerate index.md. --check fails on drift, --dry previews
pnpm okf diagram [--check]  # render *.diagram.md / *.diagram.json sources to sibling interactive .html
pnpm okf diagram --serve    # authoring loop: watch, rebuild on save, live-reload browser (port 4990)
pnpm okf diagram --verify   # prove the router + chart invariants in headless Chromium (hash-cached)
pnpm okf diagram --diff a b # what changed between two diagram sources (nodes, renames, edges)
pnpm okf stale [--days=N]   # docs older than N days by git last-commit date (default 365)
pnpm okf fix                # stamp missing type, add status to archive/ docs, regenerate indexes
pnpm okf precommit          # hook entry: regenerate+stage canvases, check staged docs

Add --json for machine output (use pnpm -s okf ... --json so pnpm's banner stays off stdout). Exit codes: 0 ok, 1 errors found, 2 usage.

The profile

Every concept doc carries frontmatter:

---
type: guide            # REQUIRED - routable kind (adr|daily|meeting|person|feature-plan|exec-plan|draft|bug|hypothesis|report|guide)
description: One line.  # REQUIRED - what the doc is (exempt under archive/)
status: active         # OPTIONAL - lifecycle: active|draft|superseded|archived
                       #            delivery (plans): in-progress|building|shipped-dev|shipped|complete
tags: [sky, storage]   # OPTIONAL
---

index.md (one per folder, generated) and README.md are reserved. Chronological logs (daily/, meetings/) and date-shard dirs are not indexed.

Rules

| Severity | Rules | |---|---| | error (blocks) | frontmatter-missing, type-missing, description-missing, value-yaml-unsafe, duplicate-frontmatter-key, description-multiline, index-stale (in index --check), diagram-invalid | | warning (informs) | link-dangling, type-unknown, status-invalid, filename-type-mismatch, archive-status-missing, adr-superseded-unmarked, multiple-h1, description-too-long, index-not-generated |

Severities live in src/config.ts (SEVERITY).

Finding docs with the structure

grep -rl '^type: adr' docs                 # every ADR
grep -rl '^tags:.*\bsky\b' docs            # by tag
grep '^\* ' docs/sky/index.md              # one-line summary of a folder's docs

Readout - the full reference

One compact *.diagram.md source renders to one self-contained interactive .html (dark + light themes, no external requests, no libraries). Two render modes from the same grammar:

  • canvas (default): an infinite pan/zoom board - architecture maps.
  • doc (render: doc in frontmatter): a notebook-grade PAGE - prose, tables, KPI tiles, charts and routed diagrams in one flowing document, with a scroll-spy table of contents and a print stylesheet.

| Dark | Light | |---|---| | | |

The same canvas source in both themes - the runtime owns colour, so a source never mentions one.

Doc mode, from examples/runbook.diagram.md: KPI tiles, prose, a table, a code fence and routed diagrams in one page, with a Contents rail and a print stylesheet.

The doctrine: sources carry semantics and structure only - no colors, no coordinates, no CSS, no hand-placed arrows. The packaged runtime owns theming, layout reflow, and arrow routing; okf diagram --verify proves the invariants (every edge drawn, no arrow through a card, no label over a card, chart text inside its card, no overlapping value labels) in headless Chromium.

File shape

---
type: diagram
description: One line - becomes the doc-mode subtitle.
render: doc            # omit for a canvas
---

# The H1 is the title

Doc mode: this prose flows into the page. Canvas mode: prose before the
first fence is the caption; prose after any fence is an error.

```readout
section: 1 - First section
nav: 1-First

row:
  api[teal]: API | :8080 - validates
  db[amber]: DB | rows of record

edges:
  api -> db : SQL
```

More prose (doc mode). It attaches to the NEXT section - use a continuation
block (`section: -`) to write commentary AFTER a diagram inside one section.

Sections

| Line | Meaning | |---|---| | section: <label> | required; the heading. id: overrides the slug, nav: the toolbar text | | section: - | continuation: no heading, no nav/ToC entry - lets prose and diagrams alternate inside one logical section (fixes "text after the picture") | | fold: true | doc mode: the section renders collapsed (<details>); deep links and print open it | | legend: teal=service, red=failure, flow=flow, fk=FK | one entry per role in use; in the rendered page each swatch is a click-to-filter for that role | | edges: | indented edge lines follow (see Edges) |

Containers

row rowT rowS rowW col colS stack grid2 cols ranks rankrow panel, plus cluster "Heading" (subtitle) <layout>:. Any container takes a gap override: rowT(110):. Two are special:

  • cols: / cols(2,1): - the doc-mode page grid. Children get equal (or weighted, one integer 1-12 per child) columns of the CONTENT width and FILL their cells - charts redraw themselves at the width the cell actually got. On phones the grid stacks. On a canvas it falls back to a top-aligned row.
  • ranks + rankrow - layered trees (FK graphs): rank by depth, point every arrow up with @tb.

Nodes

id[role flags]: Name | line | line     box (lines accept `code`, **bold**, [text](url))
inst id[role]: Name | line             saturated instance box
table id[role]: Name                   ER card; indented fields follow:
  fieldId: uid: UUID PK                  with id -> usable as an edge endpoint
  - name: string                         anonymous field
kpi id[role dir]: value | label | delta   stat tile, e.g.:
kpi k1[green up]: $22,667 | July gross | +37% on June
note: ...   warn: ...   info: ...      full-width bands (green / red / blue)
sub: ...                               small sub-label
spacer                                 flexible gap (with rowS)

Roles: purple teal amber green red blue yellow gray. Node flags:

| Flag | Meaning | |---|---| | wide | relax the width cap (box: long reference boxes; chart: full content width in doc mode) | | span | grid2 only: span both columns | | mark | emphasis ring - "this node is the point" | | ghost | de-emphasized context (the inverse of mark) | | up down flat | kpi only: the delta glyph. The ROLE carries good/bad - a red down is a warning, a green down is a win | | nudge=DX,DY | last-resort visual offset; survives reflow, arrows re-aim |

Edges

a -> b : label          plain arrow, optional label chip
a -teal-> b             role-colored arrow
a => b                  PRIMARY path - heavier stroke ( =teal=> for colored)
a -.-> b                thin FK arrow (child -> parent)
a <-> b    a <=> b      arrowheads both ends (plain / primary)
a -> a @r               self-loop (side via the @ hint)
a -green-> b @bt : PUT  side hints @<exit><enter>: l r t b, "." = auto

Arrows are routed, never drawn: orthogonal elbows with obstacle avoidance (straight -> L -> Z -> A*), ports spread along shared sides, parallel runs in separate lanes, labels on free spots. If an arrow looks wrong, fix the STRUCTURE first (escalation ladder in BEST-PRACTICES.md).

Charts

chart id[<type> <flags>]: Title | caption opens a chart; indented lines fill it:

chart c_rev[stackedBar values wide]: Monthly gross revenue | net of refunds, USD
  fmt: usd                  # usd | pct | int | compact
  y:   revenue              # value-axis label (donut: center caption)
  x:   Mar, Apr, May, Jun   # categories - one value per series per category
  s new[purple]:  4200, 5100, -, 3900     # "-" is a GAP (no data), never 0
  s renewals[teal]: 8100, 8400, 9200, 9600
  ref 16000[red]: break-even              # marker line on the value axis
  refx May[red]: core update              # vertical event marker on a category
  ann Jun: one whale = 43%                # short callout in a band above the plot
  hl: Jun                                 # emphasized categories, rest dim
  src: ClickHouse events, 2026-08-07      # "Source:" line under the plot
  scale: rev                              # same-name charts share one y-domain

Types and when to reach for them:

| Type | Use for | Notes | |---|---|---| | bar / groupedBar | comparison between series | single series = plain columns | | stackedBar | composition over time | values prints stack TOTALS | | hbar | rankings with long names | long labels middle-ellipsize + tooltip | | line | trends | value labels dodge collisions automatically | | area | cumulative totals | bands first, lines never buried | | donut | one moment's share | NO x: - each s line is one slice; >6 slices wants hbar | | waterfall | a bridge between two totals | exactly ONE series of DELTAS; negatives red, gray Total bar added | | combo | bars + a line over them | s margin[green line] = line; add y2 for a right axis (fmt2: + y2: label) | | heatmap | a series x categories matrix | heat: green sequential ramp, heat: red green diverging around 0 |

Chart flags: wide (more room; doc mode = full content width), values (numbers on marks - dropped when they cannot fit), facet (line/area/bar: one mini panel per series, all sharing the whole chart's domain), nudge=DX,DY.

| Dark | Light | |---|---| | | |

Worked examples of every type - examples/metrics.diagram.md. No chart library: the axis, the ramps and both themes are hand-rolled SVG. The arrow at the bottom points at a chart, because a chart is a card.

chart c_wf[waterfall values]: July to August bridge
  fmt: usd
  x: July, New subs, Renewals, Top-ups
  s delta[green]: 22667, -2375, -7673, -7390

chart c_margin[combo values]: Revenue vs margin
  fmt: usd
  fmt2: pct
  y2: margin
  x: May, Jun, Jul
  s gross[teal]: 19508, 17239, 22667
  s margin[green line y2]: 78.7, 71.2, 68.3

chart c_ret[heatmap values]: Cohort retention
  fmt: pct
  heat: green
  x: M0, M1, M2
  s May[gray]: 100, 65, 50
  s Jun[gray]: 100, 53, -

Every rendered chart carries a data toggle (its numbers as a table + copy-as-CSV) and styled hover tooltips (click to pin, Esc to release); clicking a mark opens the data with that series' row highlighted.

Doc mode - the notebook

render: doc turns the source into a flowing page:

  • Markdown between fences: paragraphs, ###/#### headings (auto-anchored, hover ¶ deep links), -/1. lists with nesting, > quotes, --- rules, fenced code blocks, inline code / bold / italic / [text](url).
  • Tables: pipe tables with the alignment row honored (---: right, :---: center); numeric columns right-align themselves; headers are sticky and click-to-sort (asc / desc / source order - view-state only).
  • KPI rows: cols: + kpi tiles is the standard report opener.
  • Images: ![alt](relative.png) - relative paths only; an external URL is a parse error (a committed page must not fetch the network). A missing file is a build WARNING.
  • Footnotes: A claim.[^1] ... [^1]: the fine print - rendered superscripts with a collected list + backlinks at the page end.
  • Sparklines: spark(4200 5100 4800) / sparkbar(1 2 3) inline in prose or table cells; spark(teal: ...) picks the role.
  • Navigation: a scroll-spy Contents rail (sections + h3s) replaces the pill toolbar; below 1280px it becomes a slide-over behind a floating button.
  • Print: the Print button (or Cmd+P) forces the light palette, hides chrome, opens all folds, and avoids page breaks inside cards - the PDF hand-off path.
  • Mobile: single column, charts redraw at the width they actually get, wide tables scroll inside their own box - the page never scrolls sideways.
  • Prose before a fence attaches to the FOLLOWING section; use section: - continuation blocks for diagram-then-commentary; trailing prose is the outro.

Interactions (rendered page)

| Gesture | Canvas | Doc | |---|---|---| | drag / wheel | pan / zoom | native scroll | | / | search cards (matches name, lines, id; dims the rest; Enter cycles + jumps) | - | | click a card | PIN its arrow spotlight; Esc or background click clears; shareable as #focus=<id> | text selection | | double-click a card | edit text in place (exploration only - the source is the truth) | same | | click a legend swatch | filter that role everywhere (boxes, edges, chart series) | same | | hover a card / mark | transient arrow spotlight / value tooltip (click pins) | same | | t / f / 1-9 | theme / fit / jump to section | - | | section buttons / ToC | fit that section + set #sec-<id> | scroll + set hash |

A canvas with 3+ sections opens fitted to its FIRST section, not the unreadable fit-all. The static render is always complete: filters, folds and search are view-state that print and PNG ignore.

Pipeline

  • okf diagram renders sources to sibling .html (+ PNG preview blocks under each canvas source's H1; doc sources get no PNG). --check is the drift gate; okf precommit regenerates and stages, and a broken source BLOCKS the commit.
  • okf diagram --serve [--port=N] - watch + rebuild + live reload. The reload snippet exists ONLY in served bytes; committed artifacts stay byte-identical (a test pins this).
  • okf diagram --verify - the invariant suite per diagram in headless Chromium. Unchanged artifacts are skipped via a content-hash cache in temp/okfd-verify-cache.json (OKF_VERIFY_ALL=1 re-verifies everything).
  • okf diagram --diff <a> <b> - added/removed/renamed nodes and added/removed edges between two sources.
  • okf diagram --to-dsl - convert *.diagram.json (the raw model, same renderer - useful for generated diagrams) to the DSL, round-trip guarded.
  • okf diagram --fmt - align box-line columns (whitespace only).

One source, several artifacts. The .html (and local .png) are generated siblings; exclude them in the editor (file_scan_exclusions) rather than reorganising the repo. The generated file leads with its MODEL, then a LIBRARY CODE BELOW - stop here banner ahead of the minified runtime - everything diagram-specific is in the first ~40 lines.

Editor support. editors/zed/ ships okf-d syntax highlighting for Zed (inside markdown fences and .okf-d files); Zed cannot preview HTML, which is what the PNG preview block is for.

Design rules the renderer encodes, chart-type guidance, the escalation ladder (reorder -> regroup -> spacer/gap -> @hints -> nudge), and the emphasis doctrine (mark/ghost/hl are authored SEMANTICS - "this is the finding" - while colors, sizes and coordinates stay banned): see BEST-PRACTICES.md.

Enforcement

.husky/pre-commit runs okf precommit on docs-touching commits (the hook path is installed by the repo-root prepare script, so a fresh pnpm install wires it up - no husky package needed). It regenerates and stages indexes and canvases, enforces type+description on touched docs (errors block), and warns on inbound links a rename/delete would break.

Known limit: the hook only sees staged files, so broken inbound links from untouched files on a rename are caught only by running pnpm okf links (there is no CI). Run it periodically.

Layout

src/cli.ts          commands + flags + exit codes
src/config.ts       paths, taxonomy, severities, the fs walker
src/frontmatter.ts  CRLF/BOM-safe parse/serialize, duplicate-key detection
src/markdown.ts     code stripping + link extraction
src/links.ts        link resolution + dangling rule
src/index-gen.ts    manifest generation + write-guard
src/rules/          frontmatter + convention rules
src/diagram/        types, dsl (parser - its header comment IS the grammar),
                    emit, validate, template (runtime), chart, build, verify,
                    serve, images, fmt
src/{git,doc,stale,fix,precommit,report}.ts
test/               vitest fixtures per area
pnpm test         # vitest
pnpm typecheck    # tsgo
pnpm lint         # oxlint + oxfmt