DEV Community

Pranesh Nikhar
Pranesh Nikhar

Posted on

Gravekeeper: a Día de los Muertos cemetery for dead code

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

Every repository that lived long enough has a cemetery: files nobody imports anymore, exported functions whose callers were all deleted, dependencies swept in for one task that never checked out. Static analyzers call them "errors." Gravekeeper calls them what they are — the dead — and gives them the send-off the calendar demands.

This is my entry for the Hacktoberfest Open-Source AI Challenge: Week 4 — Ghost in the Machine. A ghost, to me, is something that keeps returning without being invoked: code nobody invokes that still stares at you from the editor. Día de los Muertos is the tradition of honoring the past with real memories, not made-up ones — so Gravekeeper mines the real life story of every dead file (birth commit, last sighting, authors, line counts) straight out of git history, and puts that on the tombstone.

Gravekeeper rendering a candlelit code cemetery for CVE-Lens

What it does

Three rites, three commands, against any JS/TS repo:

node src/index.ts scan path/to/your/repo    # the census — knip + git forensics, no AI
node src/index.ts write path/to/your/repo   # the epitaphs — Gemini API, strict JSON
node src/index.ts render path/to/your/repo  # the cemetery — offline single-file HTML + graveyard.md
Enter fullscreen mode Exit fullscreen mode

The result is a candlelit cemetery you can walk through in the browser — tombstone cards, candle glow, marigold palette — plus a graveyard.md you can commit next to the removal PR, so the reason those lines are gone never evaporates with the conversation that decided it.

An epitaph expanded: born, summoned, laid to rest

How the machine works

  • Census — knip inside the target repo for an AST-grounded list of dead files, dead exports/types, unused dependencies. Static-reachable facts, not style opinions. Big respect to the knip folks (1, 2).
  • Forensics — for every grave, git history is mined locally: birth date (first commit), last sighting (last commit), total commits, authors, line counts. As this write-up argues, your git history already knows where the codebase hurts — Gravekeeper just reads the obituaries.
  • Epitaphs — batches of deceased records go to the model with a sexton's voice; the reply is read back as strict JSON (epitaph, causeOfDeath, finalWords) with a 90 s per-attempt timeout, 4 attempts with backoff, and per-grave failure isolation: a batch that never comes back leaves an unmarked grave — never a crashed rite.
  • Interment — the census + epitaphs inline into one self-contained HTML page (no CDN, opens from file://) and a markdown memorial.

Why open innovation matters for what I built

The body of the machine is deliberately open and local:

  • The census is open source. knip (MIT) is the evidence engine; I add zero magic to its verdicts — what it says is dead is dead.
  • Every fact is local. Birth, death, and authorship come from your own git history. The tool works with the lights — and the internet — off, and private repos stay private. Nothing is sent anywhere except the epitaph batch itself.
  • The cemetery belongs to the repo. It renders one HTML file with no CDN, no fonts, no tracking — a graveyard inherits to the next maintainer like a headstone should.
  • The memory is open. graveyard.md is plain markdown: commit it, review it in PRs, grep it in a year. The reason of removal lives in the open, not inside someone's proprietary dashboard.
  • The AI is at the fringe, and swappable. The one closed piece today is the epitaph voice (Gemini via @google/genai). It only has to return JSON — provider-agnostic by construction — and the v2 roadmap is a local open-weight Gemma voice for fully offline burials.

Open innovation here isn't ideology. It's the only reason a tool about other people's repositories gets to run inside them at all.

Run it on your own repo

git clone https://github.com/praneshnikhar/gravekeeper
cd gravekeeper && npm install
printf "GEMINI_API_KEY=your-key\n" > .env   # free at https://aistudio.google.com/apikey
node src/index.ts full path/to/your/repo
open path/to/your/repo/.gravekeeper/graveyard.html
Enter fullscreen mode Exit fullscreen mode

No build step: Node 24+ executes the TypeScript sources directly, and the tool never writes outside <repo>/.gravekeeper/. MIT licensed.

The full cemetery: filters, stats, tombstone cards

Planned rites (v2)

gravekeeper bury (delete marked graves and attach the epitaphs to the removal commit), more analyzer backbones beyond JS/TS (ruff, vulture, deadgrep), and GitHub Pages burials so a team can visit its cemetery from anywhere.

The code is at github.com/praneshnikhar/gravekeeper — celebrate your dead before you delete them.

Top comments (0)