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

linelore

v0.6.0

Published

The lore of a line of code — trace a single line's full history through edits and renames.

Readme

linelore

The lore of a line of code.

git blame tells you who last touched a line. It shows you a single frame. linelore shows you the whole reel — every commit that shaped one line, back to its birth, following it across edits and file renames.

$ linelore src/auth.ts:42

the lore of src/auth.ts:42
  4 changes · 1y ago → 3d ago

● 3f9a1c2e0  3d ago  Ada Lovelace
  harden token check against clock skew
      - if (exp < now) return false;
      + if (exp < now - SKEW_TOLERANCE) return false;

● a71d4b8c9  4mo ago  Ada Lovelace
  extract SKEW_TOLERANCE constant
      - if (exp < now - 30) return false;
      + if (exp < now - SKEW_TOLERANCE) return false;

✱ 0be2f1a77  1y ago  Ada Lovelace
  initial auth guard
      + if (exp < now) return false;

The same reel lives in a web view — run linelore serve, paste a GitHub permalink:

Why

Source code records what is true now and discards why it got that way. The reasoning — the dead ends, the load-bearing weirdness, the "we tried the obvious thing and it broke" — lives in commit history, PR threads, and people's heads, never in the file you're reading. linelore is a small step toward recovering that: point it at a line and it reconstructs the line's story from the one place the "why" is actually written down.

Tracing works fully offline — it is all built on git log -L. The one opt-in exception is --why, which brings its own model.

Install

npm install -g linelore

Usage

linelore <file>:<line>            # trace a single line
linelore <file> <line>            # same, space-separated
linelore <file> <start> <end>     # trace a line range
linelore <file>:<line> --json     # structured output for tooling
linelore <file>:<line> --at-head  # line numbers are HEAD's, not the working tree's
linelore <file>:<line> --prs      # pull in each commit's merging PR discussion
linelore <file>:<line> --why      # ask Claude why the line evolved this way
linelore serve                    # web view: paste a permalink, get the reel

Uncommitted changes

Line numbers mean what your editor shows. If the file has uncommitted changes, linelore maps the line back to HEAD before tracing it, so :42 follows the line you are actually looking at rather than whatever now sits at line 42 of the last commit:

$ linelore src/auth.ts:42
the lore of src/auth.ts:42
  uncommitted changes above · that's HEAD 39
  ...

If the line is one you are editing right now, linelore traces the history of the text it replaced — usually exactly the "why" you were reaching for. A line you have only just typed has no history, and it says so instead of guessing. Pass --at-head to opt out and number lines as of the last commit.

Pull-request discussion (--prs)

Commit messages carry the what; the argument usually happened on the PR. --prs finds the pull request that merged each commit in the reel and pulls its discussion in — the description, and the review thread with bots filtered out:

$ linelore src/auth.ts:42 --prs

...the reel, each commit tagged `· PR #7`...

pull requests
#7 Harden auth against clock skew  — ada
    We saw 30s skew in prod; loosen the check.
    bob: should the tolerance be configurable?
    … 3 more comments · https://github.com/you/repo/pull/7

The terminal shows excerpts; --json carries the full text under a pulls key. Commits that were pushed directly stay untagged. Works on GitHub remotes; public repos need no credentials (set GITHUB_TOKEN for private repos or more rate-limit headroom, and GITHUB_API_URL for GitHub Enterprise-style hosts that serve the same API). A failed lookup never costs you the reel — it still prints, with the error on stderr.

Intent synthesis (--why)

The reel shows what changed; --why asks Claude to read the arc and say why. It appends a short synthesis after the reel (or a why field to --json output):

$ linelore src/auth.ts:42 --why
...the reel...

why
  The check was born strict and loosened deliberately: clock-skew failures
  pushed an exact comparison toward a tolerance window, and the constant
  extraction that followed was housekeeping around that same decision.

It is opt-in and bring-your-own-key. Three providers are supported:

| --provider | Key | Default model | Notes | | --- | --- | --- | --- | | anthropic (default) | ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN | claude-opus-4-8 | ANTHROPIC_BASE_URL honored | | mistral (alias: vibe) | MISTRAL_API_KEY | mistral-large-latest | Mistral Vibe accounts work here | | openai | OPENAI_API_KEY | — (--model required) | any OpenAI-compatible endpoint via OPENAI_BASE_URL, e.g. OpenRouter or a local Ollama |

--model <id> overrides the default. The prompt instructs the model to say when the record is too thin to support a conclusion rather than invent one. Combine with --prs and the PR discussions join the evidence the model reads.

Everything outside --prs and --why works offline; nothing talks to a network unless you ask.

Web view (linelore serve)

Run linelore serve inside a clone and it hosts the reel on localhost (port 5673 — LORE on a phone keypad; --port overrides). Paste a GitHub permalink — the kind the y key mints, …/blob/<sha>/<path>#L42 or #L40-L55 — or a plain file:line, and the page renders the same reel as the terminal, dark and monospaced.

Permalinks are traced at their pinned ref, so the line numbers mean what GitHub showed, even if your checkout has moved on. Branch permalinks work too, including branch names with slashes. Tracing is done by your local clone; nothing leaves your machine, and permalinks for a different repo than the served one are refused rather than guessed at. The URL updates as you trace (?t=…), so a reel can be shared with anyone else running linelore serve in the same repo.

Roadmap

  • [x] Trace a line range through history via git log -L (offline, zero-dep)
  • [x] Structured --json output
  • [x] Intent synthesis — an optional layer that reads the arc of changes and summarizes why the line evolved the way it did (opt-in, brings its own model): --why
  • [x] Follow a line whose number has drifted in the working tree
  • [x] Pull in the merging PR's discussion for each commit: --prs
  • [x] A web view: paste a permalink, get the reel: linelore serve

Development

npm install
npm run build          # tsc → dist/
npm run dev -- src/foo.ts:10
npm test

Zero runtime dependencies. Requires Node ≥ 20 and git on PATH.

License

MIT