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

@berlysia/shiori

v0.0.1

Published

Annotation tracking and governance CLI tool for recovering structured annotations from source code

Readme

shiori

Annotation tracking and governance tool.

Purpose

shiori is a governance layer that recovers structured annotations — lint violations hidden by disable comments and other tracked exceptions — from source code, manages them in a registry, and verifies them in CI.

When developers use stylelint-disable-next-line or eslint-disable-next-line, those violations disappear from lint results entirely. This tool brings them back under organizational control by:

  • Scanning source code for shiori: annotations (in lint disable comments and standalone)
  • Requiring each annotation to carry a tracking reference (e.g. shiori: SUP-1234)
  • Supporting annotation classification via kind field in the registry: waive, design, compat, risk, migrate (and custom kinds)
  • Verifying references against a JSON registry with reason, ownership, and expiration
  • Generating human-readable (Markdown) and machine-readable (JSON) reports

Annotation Syntax

Annotations use the shiori: prefix. The first token is the tracking reference (positional ref); additional fields use key=value syntax.

shiori: <ref> [expires=<date>] [reason=<text>]
shiori:<ref>                    // compact form

Fields

| Field | Required | Description | | --------- | -------- | ----------------------------------------------------------------- | | ref | Yes | Tracking reference (positional, e.g. SUP-1234, JIRA:PROJ-123) | | expires | No | Expiration date (YYYY-MM-DD or YYYY-MM) | | reason | No | Free-text description |

Note: The kind field (annotation classification: waive, design, compat, risk, migrate, etc.) is managed in the registry, not in source comments. See ADR 004.

See ADR 007 for the positional ref syntax rationale.

Why Not a Lint Plugin?

  • disable comments make violations invisible to lint results. A plugin cannot reliably observe or report suppressed violations.
  • Plugins can enforce comment formatting (e.g., requiring an ID), but registry reconciliation, expiry detection, and inventory audits are organizational concerns that bloat a plugin.
  • This tool operates as an external CLI that handles extraction, reconciliation, and reporting — complementary to (not replacing) lint rules.

Architecture: Provider Design

Annotation extraction is abstracted behind an AnnotationProvider interface, making the tool independent of any specific lint tool's internals.

┌─────────────┐     ┌──────────────────────┐     ┌─────────────────────┐
│ Source Files │────▶│  AnnotationProvider   │────▶│ ShioriAnnotation[]  │
└─────────────┘     │  (pluggable)          │     └─────────────────────┘
                    └──────────────────────┘
                              │
                    ┌─────────┼─────────┐
                    ▼         ▼         ▼
             CommentProvider  (future)  (future)
             (shiori: prefix)  ESLint   Remote
                              native    registry
                              suppress.

Current: CommentProvider — line-based text scanning for shiori: annotations in stylelint-disable-*, eslint-disable-*, and standalone comments.

Future providers (not yet implemented):

  • ESLint native suppressions (eslint-suppressions.json)
  • External JSON suppressions
  • Remote registry APIs

Usage

Comment Convention

Each tracked comment must include a shiori: annotation with a tracking reference. Place the annotation after the -- separator in lint disable comments, or as a standalone comment.

Lint disable comments (ESLint / stylelint):

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- shiori: SUP-5678 expires=2026-12-31
const data: any = fetchLegacyAPI();

// eslint-disable-next-line no-console -- shiori: NOTE-1
console.log('debug output');

// eslint-disable-next-line no-var -- shiori: MIG-1 expires=2026-12-31
var legacy = true;
/* stylelint-disable-next-line plugin/baseline -- shiori: SUP-1234 expires=2026-06-01 */
.foo {
  display: flex;
}

Standalone annotations (no lint directive):

// shiori: ADR:0007
// shiori:SUP-1234

Registry Format

A JSON file keyed by annotation ref:

{
  "SUP-1234": {
    "reason": "vendor prefix fallback for older browsers",
    "target": ["iOS Safari < 17.4", "old Android WebView"],
    "expires": "2026-06-01",
    "ticket": "CSS-1234",
    "owner": "team-frontend",
    "kind": "compat"
  }
}

Commands

scan — Extract annotations from source

shiori scan \
  --patterns "src/**/*.{css,scss,ts,tsx}" \
  --output scan-result.json

Options:

  • --patterns, -p — Glob patterns (comma-separated). Default: **/*.{css,scss,pcss,js,ts,tsx,jsx}
  • --ignore, -i — Exclude patterns. Default: **/node_modules/**,**/dist/**,**/.git/**
  • --output, -o — Output file (default: stdout)
  • --cwd — Working directory (default: process.cwd())
  • --provider — Annotation provider. Default: comment

verify — Reconcile scan results with registry

shiori verify \
  --scan scan-result.json \
  --registry registry.json \
  --fail-on missing-in-registry,expired \
  --warn-on unused-in-source

Detects:

  • missing-in-registry — ref in source but not in registry
  • unused-in-source — ref in registry but not in source
  • expired — Registry entry past its expires date
  • syntax-error — Annotation with shiori: marker but invalid syntax

Options:

  • --scan, -s — Path to scan result JSON (required)
  • --registry, -r — Path to registry JSON (required)
  • --fail-on — Issue types that cause exit code 1 (comma-separated)
  • --warn-on — Issue types reported as warnings (comma-separated)
  • --format, -f — Output format: json (default) or markdown
  • --output, -o — Output file (default: stdout)

init-registry — Generate registry template

shiori init-registry \
  --scan scan-result.json \
  --output registry.json

# Merge with existing registry (preserves existing entries)
shiori init-registry \
  --scan scan-result.json \
  --output registry.json \
  --merge existing-registry.json

draft — List draft annotations

shiori draft \
  --scan scan-result.json \
  --output drafts.json

Lists annotations that have a shiori: marker but no ref (intentional drafts awaiting a tracking reference).

Options:

  • --scan, -s — Path to scan result JSON (required)
  • --output, -o — Output file (default: stdout)

candidates — List candidate annotations

shiori candidates \
  --scan scan-result.json \
  --format markdown \
  --output candidates.md

Lists lint disable comments and other patterns detected as potential shiori management candidates (no shiori: marker).

Options:

  • --scan, -s — Path to scan result JSON (required)
  • --format, -f — Output format: json (default) or markdown
  • --output, -o — Output file (default: stdout)

show — Show information about a specific ref

shiori show \
  --ref JIRA:PROJ-123 \
  --scan scan-result.json \
  --registry registry.json

Looks up a ref and displays its registry entry, source locations, and resolved URL (if namespace is configured). Exit code 0 if found, 1 if not found.

Options:

  • --ref — The ref to look up (required)
  • --scan, -s — Path to scan result JSON (required)
  • --registry, -r — Path to registry file (required)
  • --config, -c — Path to directory containing .shiorirc.json (default: cwd)

CI Integration

GitHub Actions

name: Annotation Registry Check
on: [pull_request]

jobs:
  shiori:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci

      - name: Scan annotations
        run: npx shiori scan --output scan-result.json

      - name: Verify against registry
        run: |
          npx shiori verify \
            --scan scan-result.json \
            --registry registry.json \
            --fail-on missing-in-registry,expired \
            --warn-on unused-in-source

      - name: Generate report
        if: always()
        run: |
          npx shiori verify \
            --scan scan-result.json \
            --registry registry.json \
            --format markdown \
            --output report.md \
            --warn-on missing-in-registry,unused-in-source,expired,syntax-error

Development

pnpm install
pnpm build
pnpm test
pnpm typecheck
pnpm lint

License

ISC