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

@mash/mdreview

v0.2.0

Published

Full-document Markdown review tool — difit-style review loop for a whole Markdown file, returns human comments to an AI agent.

Downloads

213

Readme

mdreview

A full-document Markdown review tool. It opens a browser UI showing your whole Markdown file, lets a human comment on any heading, paragraph, or line range, and returns those comments to an AI agent as structured text — a difit-style review loop for a complete document instead of a git diff.

npx @mash/mdreview README.md

This opens a browser tab. Select text in the rendered document, add comments, then click Finish Review (or just close the tab). The collected comments are printed to stdout in an AI-friendly format.

Features

  • Full-document review with pretty Markdown rendering and stable data-line / data-end-line source anchors on every block.
  • Rich rendering: GFM task lists, footnotes, strikethrough; KaTeX math ($…$ / $$…$$, rendered in the browser); Mermaid diagrams (lazy, strict); local images served from a jailed /asset/ route; lazy in-browser code highlighting (fast first paint, no blocking on highlight.js).
  • Precise comments: select any text → comment, with an exact text-span anchor (selected text + surrounding context + occurrence) on top of the line range, so an AI can apply changes accurately.
  • Suggestions: attach a proposed replacement string to a comment.
  • Discussion: resolve/reopen comments and add replies.
  • Preload existing findings with --comment file.json (e.g. AI-generated review notes the human then responds to).
  • Keyboard-driven: j/k navigate comments, c comment the selection, r resolve, Enter jump, Esc cancel.
  • Source / Split views toggle between rendered Markdown and raw source.
  • Multi-user review over Tailscale: --tailscale lets several reviewers on the same tailnet open one review and see each other's comments live; the owner ends it with Finish All. See below.
  • Local & private: by default (single-user) binds to 127.0.0.1 and closing the tab finishes after a grace period; a random per-session token guards the URL and every API call; file content never leaves the machine.

Why

AI writes a lot of Markdown — plans, design docs, READMEs, PRDs. Reviewing it means commenting on the whole document, not a diff. difit nails the review-loop ergonomics (local server, browser comments, comments returned to the agent on close) but targets git patches. mdreview keeps that loop and points it at a full Markdown file.

How it works

mdreview CLI ─reads file, renders with markdown-it (data-line anchors)
   → HTTP(S) server (default 127.0.0.1; tailnet IP in multi-user), token-guarded, SSR-first page
   → browser: select text → comment → autosave + heartbeat
   → finish: Finish Review (single-user, or tab close after grace) /
            owner Finish All (multi-user) / Ctrl-C
   → structured comments on stdout → consumed by an AI agent / Skill
  • Server-side first render: the document HTML is rendered on the server and inlined in the page shell so it's readable before the interaction JS loads.
  • Viewport-first, token-boundary slicing: only the first window of the document (~160 source lines) is inlined into #doc for a fast first paint; the rest ships inert in a <template> and the browser appends it right after paint. Splitting happens at top-level token-group boundaries, so fenced code, tables, lists, and blockquotes are never cut mid-block.
  • Source anchors: every block carries data-line / data-end-line (1-based, inclusive) from markdown-it token maps, so a selection resolves to a stable source line range that an AI can edit.
  • Heading paths: each comment's line is resolved to its heading path (Architecture > CLI server) server-side at finalize time.
  • Finish paths are mode-aware: in single-user (loopback) — or multi-user before any reviewer has joined — the browser sends a heartbeat and closing the tab finalizes from the last autosaved comments after the grace window. Once a real reviewer joins, tab close no longer ends the session; the owner finalizes with Finish All (or Ctrl-C).

Output

Default stdout:

# Review comments for docs/plan.md

## Comment 1
Target: docs/plan.md:L12-L20
Heading: Architecture > CLI server

Selected text:
The CLI starts a local server...

Comment:
This explanation is too vague. Add the data flow.

Options

| Option | Meaning | Default | |---|---|---| | --port <n> | Local server port | 0 (random free port) | | --comment <path> | Preload comments from a JSON file (repeatable; invalid entries dropped) | — | | --allow-remote-images | Relax page CSP to allow remote http(s) images in the reviewed Markdown | off | | --tailscale | Bind to this machine's tailnet IPv4 (enables multi-user mode); serves HTTPS via a Tailscale TLS cert when obtainable, else falls back to HTTP | off | | -h, --help | Show help | — |

The browser auto-opens by default. Set MDREVIEW_NO_OPEN=1 to suppress it (the owner/reviewer URLs are still printed to stderr) — handy for tests and automation. MDREVIEW_GRACE=<sec> overrides the default 5s heartbeat grace (advanced/testing).

Multi-user review (tailscale)

By default mdreview is single-user on 127.0.0.1. Passing --tailscale enables multi-user mode: several reviewers on the same tailnet open the same review, each leaves comments, and everyone sees each other's comments live (via polling/SSE).

  • Owner vs reviewer: the person who started the CLI is the owner and connects via a URL carrying a separate secret owner token. Reviewers get a token-only reviewer URL to share (the owner token is never in it). The CLI prints both URLs to stderr; the owner can also copy the invite link from the page UI.
  • Ending the review: the owner clicks Finish All to finalize the whole session — everyone's comments are merged and printed. A reviewer's own Finish only marks that reviewer done; it does not end the session. Ctrl-C also finalizes. In single-user (loopback) — or multi-user before any reviewer has joined — closing the tab finishes after the grace window. If nobody ever opens the page, the server auto-closes after ~120s.
  • HTTPS via Tailscale: with --tailscale, mdreview obtains a TLS cert for this machine's MagicDNS name (tailscale cert) and serves https://<machine>.<tailnet>.ts.net:<port>/, so the page is a secure context (clipboard, etc.). If a cert can't be obtained it falls back to plain HTTP. Binding is on the tailnet IP; only the URL host is the MagicDNS name.
  • Identity: each reviewer's display name is resolved server-side via tailscale whois on the peer IP (shown as verified), falling back to the host OS username for the local owner, else a short client id — there is no name prompt. Comments are bucketed by a per-client id (never by the client-supplied name), so one reviewer can't overwrite another's comments.

Security

  • Single-user binds to 127.0.0.1; multi-user (--tailscale) binds to the tailnet IP.
  • Every session generates a random token, required on the page URL and all API calls. In multi-user mode the owner token and reviewer token are separate bearer secrets. The file content never leaves your machine.
  • In multi-user mode the /asset/ route is restricted to an allowlist of paths the render actually referenced, and refuses dotfiles / .env / *.pem / .git. Raw HTML in the Markdown is sanitized; responses set Referrer-Policy: no-referrer; per-client and subscriber caps apply; peer connections are logged to stderr.

Development

npm install              # also vendors browser bundles via scripts/vendor.mjs (prepare)
npm run build            # vendor + tsc -> dist/
npm test                 # unit + e2e (node:test)
npm run dev -- file.md   # run from source via tsx

scripts/vendor.mjs copies the browser bundles (highlight.js, Mermaid, KaTeX) from node_modules into web/vendor/ — they load lazily in the UI and are gitignored (regenerated on install/build). The rendering strategy (markdown-it source maps, viewport-first token slicing, lazy code highlighting, CSS) is adapted from the local markdown-fast work.

Skill

skill/SKILL.md packages this as an agent skill so an AI can run the review loop and apply the returned comments. See that file for the agent workflow.