Every developer has a folder full of dead projects. Nobody has ever gotten an autopsy report. This skill scans the machine for abandoned repos, works out why each one died from its git history, finds the user's personal death patterns, and picks the one corpse worth digging up — then helps ship it.
Everything runs locally. No API, no network, nothing leaves the machine.
kondo/npkill, not thispython3 scripts/graveyard.py ~/dev ~/projects
Point it at wherever projects actually live. If you don't know where that is, ask — one question beats sweeping someone's home directory uninvited. No args scans the usual suspects (~/dev, ~/projects, ~/code, ~/Desktop, ...). Useful flags:
--days 90 — how long silent before a repo counts as dead (default 45)--json report.json — full machine-readable data--me work@email.com — claim commits made under other emails (repeatable);
without it, projects committed via a work identity or a builder tool get
skipped as "not yours"--include-foreign — also include repos the user barely committed to
(skipped by default: clones, forks, work checkouts are not their corpses)--state FILE — remember scans and resurrections; enables relapse watchThe script is read-only. It never writes inside a scanned repo.
The script gives you four blocks: census, the dead (with cause of death),
patterns, and the top 3 by "pulse" (resurrectability score). Causes are
evidence-based guesses, not verdicts — each comes with the evidence line that
justifies it. If a cause looks wrong, check the evidence before repeating it.
The cause taxonomy and what each one means for resurrection is in
references/causes-of-death.md — read it before writing the report.
The script can only read git. You can ask. For corpses whose primary cause is
unknown or slow_fade — the low-confidence verdicts — ask the user one
question each, two or three total at most:
"
recipe-scraper— the history just shows it drifting. Do you remember what actually stopped you?"
Blend the answers in, and label verdicts honestly in the report: (forensic) for what git showed, (confirmed) for what the user told you. Testimony beats a forensic guess — update the tombstone, not just the prose. Two questions is a conversation; five is a deposition.
Turn the script output into a report the user will actually feel. Format:
Carve the resurrection pick (and only it) as an ASCII tombstone card — stone is earned, not sprayed; every other corpse stays a line in the table:
.------------------------.
/ \
| tab-sensei |
| Apr — May 2026 |
| 54 commits · 12 days |
| |
| died of deploy fear |
| |
| "It worked. It just |
| never shipped." |
___|____________________________|___
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Center the text, keep the card under 44 columns so it never wraps, epitaph last. If the graveyard is empty, no card — don't carve a stone for nobody.
Epitaph rules — this is where the whole thing lives or dies:
Offer --redact framing if the user wants to share the report: project names
swapped for project-1..n, causes and patterns intact.
Pick ONE corpse. Highest pulse wins unless its idea is dead in the world too. Before deciding, read the top candidate's README and skim the code — then do the world-check, the part only you can do because the script can't see the present:
Cite what you find in the plan. "This got easier: X exists now" is the strongest argument for digging; "the window closed" is the strongest for leaving it buried.
Then write the resurrection plan. The per-cause dig strategy is in
references/causes-of-death.md (each cause has a "resurrection angle" —
deploy-fear corpses need shipping steps only, wall deaths need the managed
alternative, scope explosions get one feature extracted). Plan rules:
When to leave it buried — say it plainly when it's true: the user doesn't care anymore (a shrug at the interview is closure, not a project); the window closed and the world shipped the idea; or every candidate is weak. "Nothing here is worth digging up, and that's fine — here's what the patterns say about the next project" is a legitimate and useful ending.
When the user commits to a resurrection, record it (ask once where to keep
the state file — ~/.project-graveyard.json is a sane default):
python3 scripts/graveyard.py --state ~/.project-graveyard.json \
--mark-resurrected /path/to/the/corpse
Scans run with --state hold past resurrections to their promise: the report
gains a RELAPSE WATCH block showing whether each resurrected project is
holding or going silent again. When one relapses, say it plainly and make the
user choose — recommit or bury it honestly. A second silent death is an
answer, not a failure; close the loop instead of prescribing a third attempt.
No tool follows up on its own prescription. This one does — that's the point
of keeping state.
When the user proposes building something new, check the graveyard for prior
attempts before scaffolding anything — grep the state file (or a fresh
--json report) for name and README overlap. If there's a match:
"You already built about 60% of this. It's called
project-14, it died in March at the auth step, and its parser still works. Resurrect instead?"
Don't be preachy about it. Mention it once, let them choose, drop it.
git init, backup
tools). The scanner handles nested repos, but if the census looks absurd,
that's usually why.--me that@email.com.finished (deploy config + pushed + README)
from dead, but the heuristic is rough — ask before eulogizing anything the
user considers done.scripts/graveyard.py — scanner + autopsy + pulse ranking (stdlib, offline, read-only)references/causes-of-death.md — the taxonomy: signals, confidence, and the per-cause resurrection strategy