agentleFS
sfrangulovsfrangulov/skill-graveyard/CLAUDE.md

skill-graveyard

CLAUDE.md10 starsChanged 6 months agoMITView on GitHub

A CLI that audits which Claude Code skills the user actually invokes. It parses local session JSONL logs and cross-references the skill installs on disk to surface two signals from one parser: The four user-facing buckets (active / dead / missing / hallucinated) and their definitions are documented in README.md and are a stable contract. No secrets, no proprietary client names, no real session data ever lands in docs/ or README.md. Sample CLI output on the live site uses anonymized…

  • Installs packages
  • Commits and pushes
  • In this repositoryOne other file it gives its agents.

The file

We split this CLAUDE.md into the rules it gives an agent

12 rules. About 0 are common, 9 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    No telemetry. No network calls anywhere in the runtime.

    line 59
  2. Distinctive:

    Use only if release-please is blocked and a release is urgent:

    line 86
  3. Distinctive:

    Don't push automatically after committing.

    line 105
  4. Distinctive:

    Don't run destructive git operations (force-push, hard reset, branch delete) without confirmation.

    line 106
  5. Very specific:

    Use bd for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists

    line 126
  6. Very specific:

    Run bd prime for detailed command reference and session close protocol

    line 127
  7. Very specific:

    Use bd remember for persistent knowledge — do NOT use MEMORY.md files

    line 128
  8. Distinctive:

    File issues for remaining work: - Create issues for anything that needs follow-up

    line 138
  9. Distinctive:

    Verify: - All changes committed AND pushed

    line 148
  10. Distinctive:

    NEVER stop before pushing - that leaves work stranded locally

    line 153
  11. Distinctive:

    NEVER say "ready to push when you are" - YOU must push

    line 154
  12. Distinctive:

    If push fails, resolve and retry until it succeeds <!-- END BEADS INTEGRATION -->

    line 155

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

A CLI that audits which Claude Code skills the user actually invokes. It parses local session JSONL logs and cross-references the skill installs on disk to surface two signals from one parser:

  1. Dead installs — skills present on disk, never invoked → safe to remove.
  2. Hallucinated invocations — skills invoked that aren't installed → external-framework registrations, model tool/skill confusion, or typos.

The four user-facing buckets (active / dead / missing / hallucinated) and their definitions are documented in README.md and are a stable contract.

This repo is public

No secrets, no proprietary client names, no real session data ever lands in docs/ or README.md. Sample CLI output on the live site uses anonymized project names (e.g. client-analytics, clientco/web-platform) — keep that pattern when refreshing screenshots. If you spot a real-looking name slipping in, mask it before pushing.

Layout

This is an npm workspaces monorepo:

  • packages/core/ — @skill-graveyard/core (published). Shared parser, discovery, paths, tokenizer, known_tools. Generic parseToolCalls<T> lets sister CLIs reuse the JSONL stream.
  • packages/skill-graveyard/ — published as skill-graveyard. CLI, all subcommand implementations (audit, prune, suggest, projects, cost, outdated), format.ts.
  • packages/mcp-graveyard/ — published as mcp-graveyard. CLI for auditing MCP server tool usage. Mirrors skill-graveyard's bucket model (active/dead/missing/hallucinated) but for MCP servers.
  • packages/memory-graveyard/ — published as memory-graveyard. CLI auditing per-project MEMORY.md index + memory/*.md entries. v1 surface: audit, lint, prune, projects. Same monorepo conventions; no plugin distribution.
  • skills/skill-graveyard/SKILL.md, skills/mcp-graveyard/SKILL.md, skills/memory-graveyard/SKILL.md — Agent Skill manifests for skills.sh. Discovered when users run npx skills add sfrangulov/skill-graveyard. NOT shipped in any npm tarball — read directly from the GitHub repo.
  • release-please-config.json, .release-please-manifest.json — release-please configuration (per-package settings, current version baseline). See the Release section below.
  • .github/workflows/release-please.yml — automated release workflow (open Release PR on push to main, publish + tag + GH release on PR merge).
  • docs/ — Pages site (docs/index.html) and design specs (docs/specs/).

Inside each package:

  • src/cli.ts (skill-graveyard only) — argument routing; no business logic.
  • src/{audit,prune,suggest,projects,cost,outdated}.ts — one subcommand per file (skill-graveyard).
  • src/{parser,discovery,paths,tokenizer,known_tools}.ts — primitives (core).
  • src/format.ts (skill-graveyard) — every terminal rendering helper (sparkbars, tables, colors). Subcommands return data; this file prints.
  • src/*.test.ts — colocated; flat under each package's src/.

Development

npm install
npm run build --workspace=@skill-graveyard/core   # build core first; skill-graveyard depends on its dist
npm run dev --workspace=skill-graveyard -- <subcommand>   # tsx, no build step
npm run typecheck    # both workspaces (delegates via --workspaces --if-present)
npm test             # both workspaces
npm run build        # both workspaces

Node ≥18. Runtime deps: gpt-tokenizer (in @skill-graveyard/core). skill-graveyard itself only depends on @skill-graveyard/core at runtime.

Tests

Each package runs the same node --import tsx --test src/*.test.ts pattern. Single *, unquoted, shell-expanded — do not change to 'src/**/*.test.ts': bash on Ubuntu CI doesn't expand ** without globstar, and node --test on Node 20 won't expand a literal glob either. Both failure modes have happened. If tests ever need subdirectories within a package, switch the test runner — don't paper over the glob.

Tests use real fs against os.tmpdir() fixtures. No fs mocking. The whole purpose of this tool is correctly walking real Claude Code install layouts; mocked filesystem tests would defeat the point.

Intentional non-features

These look like missing features. Verify with the user before "fixing":

  • prune never executes /plugin remove. It prints the command for the user to run inside Claude Code. Invoking CC slash commands from outside the runtime is fragile and is explicitly out of scope.
  • prune ignores project-scoped skills (<project>/.claude/skills/). Per-project artifacts are intentional.
  • No telemetry. No network calls anywhere in the runtime. README.md promises "all analysis is local" — keep it true.
  • The cost subcommand uses cl100k_base BPE as a proxy for Claude's tokenizer (Anthropic doesn't publish one for Claude 3+). User-facing output must keep the 5–15% drift disclaimer.
  • No Claude Code plugin / slash commands. We tried, then removed in skill-graveyard@0.10.0 / mcp-graveyard@0.3.0. The plugin layout repeatedly collided with skills.sh-bundled SKILLs in the /<plugin>: namespace and the autocomplete UX never landed cleanly. If reintroducing, the SKILL files in skills/ MUST stay outside the plugin's auto-scanned paths (Claude Code's plugin loader picks up <plugin-root>/skills/ automatically), or the namespace collision will reappear.
  • prune --apply semantics differ across the three CLIs by design. mcp-graveyard prune --apply and memory-graveyard prune --apply both execute (with backups), because they operate on files we own. skill-graveyard prune only prints removal commands — disabling installed skills/plugins requires invoking Claude Code's runtime (claude /plugin remove), which is fragile from outside CC. Don't "fix" this divergence to match — the asymmetry is the right answer.

Release

Automated via release-please

Do not run npm publish, git tag, or gh release create manually. All three packages release through release-please, configured in release-please-config.json + .release-please-manifest.json and driven by .github/workflows/release-please.yml. Manual workflows compete with the bot and create version drift.

How it works:

  1. Author commits with conventional-commit prefixes when the change should ship as a release: fix: (patch), feat: (minor), feat!: or BREAKING CHANGE: in body (major). chore:/docs:/refactor:/test:/ci: show in CHANGELOG history but don't bump versions. Bare imperative subjects without a prefix are fine for non-release changes.
  2. On push to main, the release-please action either opens or updates a "Release PR" listing the queued bumps for any package with releasable commits. GitHub setting required: Settings → Actions → General → "Allow GitHub Actions to create and approve pull requests" must be ON, otherwise the bot fails with "GitHub Actions is not permitted to create or approve pull requests."
  3. Merging the Release PR triggers the publish job: tags (<component>@vX.Y.Z), GitHub releases, and conditional npm publish per package. Uses NPM_TOKEN automation token, no OTP. Core publishes first if its release was created.

Things to know:

  • bin path in each package must be dist/cli.js — no ./ prefix. With ./, npm strips the entire bin entry from the published tarball with only a warning. npm pkg fix normalizes this.
  • For skill-graveyard, the prepack/postpack scripts copy README.md, LICENSE from repo root into the package dir at pack time (so the npm package displays the canonical README). If npm pack errors mid-way during local debugging, postpack does NOT run — manually clean with rm -f packages/skill-graveyard/{README.md,LICENSE} if git status is dirty.
  • mcp-graveyard ships its own README from inside the package, no prepack hack.
  • @skill-graveyard/core has no GitHub release per release-please config — internal-facing only.
  • Marketplace-merged Release PRs need the autorelease label. If you ever have to open a release PR manually (because the bot was blocked when it tried), copy the autorelease: pending label that release-please normally adds — without it, release-please won't recognize the merge as a release commit and won't create tags / GH releases / npm publishes.

Manual fallback (emergency only)

Use only if release-please is blocked and a release is urgent:

  1. Bump version in packages/<name>/package.json and .release-please-manifest.json lockstep. Add a ## [X.Y.Z] section to packages/<name>/CHANGELOG.md.
  2. npm publish --workspace=<name> with an interactive OTP — ask the user to run ! npm publish --workspace=<name> --otp=NNNNNN so the result lands in the conversation.
  3. git tag -a <component>@vX.Y.Z and push.
  4. gh release create <component>@vX.Y.Z with notes from the CHANGELOG entry.
  5. release-please will resync its state on the next push.

Docs site

The Pages site (https://sfrangulov.github.io/skill-graveyard/) deploys automatically from main branch, path /docs. Any push touching docs/ triggers pages-build-deployment. Live URL is referenced from README.md, the homepage field in package.json, and homepage in .claude-plugin/plugin.json — change all three together if the URL ever moves.

CI

.github/workflows/ci.yml runs typecheck, test, build per workspace via an 8-cell matrix: {@skill-graveyard/core, skill-graveyard, mcp-graveyard, memory-graveyard} × {Node 20, Node 22}. fail-fast: false — one cell's failure does not cancel the others. Before any CLI's typecheck/test/build runs, a conditional step builds @skill-graveyard/core first (the CLIs import types from packages/core/dist/).

Conventions

  • Commit subjects are short, lowercase, imperative ("fix ci test glob", not "Fixed the CI test glob"). Conventional-commits prefixes (fix:, feat:, chore:, docs:, etc.) are permitted but not required — use them when they help release tooling infer bump types, otherwise a bare imperative subject is fine. No Co-Authored-By line unless the user asks for one.
  • Don't push automatically after committing. Wait for explicit confirmation.
  • Don't run destructive git operations (force-push, hard reset, branch delete) without confirmation.
  • .claude/ at the repo root is local Claude Code state. It's untracked and intentionally not in .gitignore — leave it alone.
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:7510c1e2 -->

Beads Issue Tracker

This project uses bd (beads) for issue tracking. Run bd prime to see full workflow context and commands.

Quick Reference

bd ready              # Find available work
bd show <id>          # View issue details
bd update <id> --claim  # Claim work
bd close <id>         # Complete work

Rules

  • Use bd for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
  • Run bd prime for detailed command reference and session close protocol
  • Use bd remember for persistent knowledge — do NOT use MEMORY.md files

Architecture in one line: issues live in a local Dolt DB; sync uses refs/dolt/data on your git remote; .beads/issues.jsonl is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.

Session Completion

When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.

MANDATORY WORKFLOW:

  1. File issues for remaining work - Create issues for anything that needs follow-up
  2. Run quality gates (if code changed) - Tests, linters, builds
  3. Update issue status - Close finished work, update in-progress items
  4. PUSH TO REMOTE - This is MANDATORY:
    git pull --rebase
    git push
    git status  # MUST show "up to date with origin"
  5. Clean up - Clear stashes, prune remote branches
  6. Verify - All changes committed AND pushed
  7. Hand off - Provide context for next session

CRITICAL RULES:

  • Work is NOT complete until git push succeeds
  • NEVER stop before pushing - that leaves work stranded locally
  • NEVER say "ready to push when you are" - YOU must push
  • If push fails, resolve and retry until it succeeds
<!-- END BEADS INTEGRATION -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.