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

hdlinter

v0.2.1

Published

Cursor/VS Code extension and CLI for validating project document metadata headers.

Readme

hdlinter

Cursor/VS Code extension and CLI for validating Markdown planning headers.

The linter enforces this header shape at the top of every Markdown file:

- Status: Draft
- Owner: Project Manager
- Reviewers: Siem, Vansh
- Last updated: 2026-05-11
- Milestone: M1
- Depends on: [Execution Plan](docs/mvp-execution-plan.md) [2026-05-10]
- Supersedes: None

Rules

  • Required fields must appear in order.
  • Header fields are written as unordered list items so GitHub renders them as separate lines without raw <br> tags.
  • Status must be one of Draft, In Review, Approved, or Superseded.
  • Last updated must be a valid ISO date.
  • Depends on and Supersedes must be either None or Markdown links.
  • Header links must include the referenced document's Last updated date in brackets after the link.
  • Referenced files must exist when they point at local Markdown files.
  • Bare local .md paths in normal document body text must be clickable Markdown links. Inline code, fenced code blocks, images, URLs, and existing links are ignored.
  • Last updated must change when the body or stable metadata changes.
  • Last updated must not change when only volatile header data changes.
  • A dependency newer than the current document is flagged as possible drift.
  • A superseded document newer than the superseding document is flagged as suspicious.

State And Git

The extension writes hidden graph/hash state to .hdlinter/state.json. That file is the accepted document baseline, so projects that rely on freshness checks should commit it to git.

Content freshness is checked from a hash of:

  • the post-header body
  • stable header fields: Status, Owner, Reviewers, Milestone, dependency targets, and superseded targets

These are excluded from the freshness hash:

  • Last updated
  • dependency and supersedes date annotations such as [2026-05-11]
  • list-marker/header formatting changes

This means refreshing dependency dates does not force an unrelated date bump. It also means a date-only Last updated change is reported and autofixed back to the previous accepted date.

The state file is intentionally deterministic: it does not store an absolute workspace path or generated timestamp. hdlinter --write-state writes state only after a clean lint run. hdlinter --fix fixes documents first, then writes state only if errors are gone.

Configuration

hdlinter is opt-in per project. The extension only lints a Markdown workspace when hdlinter.conf.json exists somewhere above the opened folder. Without that marker, it stays silent.

Create hdlinter.conf.json in the project root:

{
  "ignore": ["docs/initial/**", "vendor/**/*.md"],
  "allowMissingHeaders": false
}
  • ignore skips workspace-relative Markdown paths matched by glob.
  • allowMissingHeaders lets freeform Markdown files exist without a metadata header. The CLI summary reports how many Markdown files were allowed through this path so a clean lint is not mistaken for full metadata coverage.
  • When missing headers are not allowed, Cursor exposes Quick Fixes to either insert a normalized header or add the file to ignore.
  • The config file may be empty. An empty marker means "use defaults."

Optional header schema (see Diagnostics reference):

  • schemaVersion, header.fields, statuses, fieldAliases, stripUnknownHeaderFields customize field order, validation, and migration aliases.
  • After schema changes, run hdlinter --fix (safe reorder + placeholders). Run hdlinter --fix-aggressive or use the editor quick fix Remove header fields not in schema to drop consecutive header lines whose names are not in the schema.
  • Any hdlinter.conf.json schema validation error blocks lint and state writes until resolved.

Cursor Setup

From this directory:

npm install
npm run compile

Then in Cursor:

  1. Open this folder.
  2. Press F5 to launch the extension development host.
  3. In the launched Cursor/VS Code window, open the target Markdown project.
  4. Diagnostics and Quick Fixes appear for Markdown files.

For regular use, package/install it as a VS Code-compatible extension later:

npm install -g @vscode/vsce
npm run package

Then install the generated .vsix in Cursor.

CLI

Run without installing:

npx hdlinter .

When the CLI cannot find hdlinter.conf.json above the current directory, it creates an empty marker at the nearest package.json or .git root. If neither exists, it creates the marker in the current directory. That first run opts the project in.

Lint a workspace and rebuild hidden graph state:

npx hdlinter ../aicompliance --write-state

Autofix a workspace (safe structural fixes, body .md path links, and placeholders; does not remove unknown header lines):

npx hdlinter ../aicompliance --fix

Same as --fix, plus strip consecutive header lines not declared in the configured schema:

npx hdlinter ../aicompliance --fix-aggressive

The CLI exits non-zero when errors are found. CLI output uses ANSI color when stdout/stderr are terminals. NO_COLOR disables color, and FORCE_COLOR=1 enables it for redirected output. The final summary includes configured ignored Markdown files and allowed headerless Markdown files when present.

Local Development

For quick local CLI testing from this repo:

npm install
npm run build
tmpdir="$(mktemp -d)"
printf "" > "$tmpdir/hdlinter.conf.json"
printf -- "- Status: Draft\n- Owner: Test\n- Reviewers: Test\n- Last updated: 2026-05-11\n- Milestone: M0\n- Depends on: None\n- Supersedes: None\n\n# Sample\n" > "$tmpdir/sample.md"
npm exec -- hdlinter "$tmpdir"

npm link works for local development, but publishing to npm is the intended path for normal npx hdlinter usage.

Future Work

See Future Work Plan for the detailed roadmap. The focus is configurability, granular diagnostics/autofixes, and stronger testing. Modularity is treated as an enabling constraint, not a broad refactor goal.