A tool that tracks how much — and how happily — your team actually uses your Claude Code skills/agents, and uses that data to keep refining them.
No separate server, no DB. A hook silently accrues skill/agent usage counts with zero
tokens, ratings are left only when you feel like it, and all data lands in a single markdown
file inside the project that merges naturally through git. /tracker then reads that
accumulated usage + ratings to judge "is this agent still worth keeping?" and coordinates
improvements with you.
- Distributed accrual, no conflicts. Each person only
+1s their own git-name line, and ratings are appended to the end of the file. Since everyone touches different lines,git merge/pullblends teammates' records into one file by itself — no sync code needed. - A continuous feedback loop. From the accumulated usage + ratings,
/trackermakes a verdict and suggests a direction → you fix → it accrues again → judge again. The agent evolves to fit your team. - No server. No central server, DB, or accounts — a text file inside the project folder is the whole thing.
- Zero tokens to collect. Usage counts are bumped by a
PreToolUsehook (PowerShell), not an LLM. Numbers pile up quietly, and tokens are only spent when a human runs/evaluateor/trackerdirectly. - A single human-readable file. The data is just markdown, so you can open and read it immediately, fix it by hand, or review it in a PR.
- Rating is 100% optional. Nothing is forced. A teammate types
/evaluateonly when they think "this agent isn't great."
npx github:lsc892/Agent-Tracker # default: English, scope=local
npx github:lsc892/Agent-Tracker --lang ko # Korean (en / ko / ja / zh)
npx github:lsc892/Agent-Tracker --scope all # count global skills too
--lang sets the data md's section headers (## Usage / ## Ratings) and the language of the
/evaluate and /tracker command prompts. The default is English.
--scope sets which invocations are counted. The default local counts only skills/agents
defined in this project's .claude/ (.claude/skills/<name>/, .claude/agents/<name>.md);
all counts every invocation, including global ~/.claude skills and built-in agents.
It never touches the global ~/.claude; it installs only into that project's .claude/:
.claude/tracker/← PowerShell scripts (+ where data accrues).claude/commands/←/evaluate,/tracker,/tracker-statsslash commands.claude/settings.local.json← registers the usage-count hook (machine-local).claude/.gitattributes+ a.git/configmerge driver ← conflict-free data merge (see below)
Restart Claude Code after install and counting kicks in. Re-running npx is idempotent, so
nothing gets registered twice.
To use it straight from a local clone: run
npm linkin this repo, thenagent-trackerin the target project.
Every time a skill is invoked or a subagent is spawned, Claude Code runs tracker-count.ps1
— via the PreToolUse hook for Skill/Agent tool calls, and via the UserPromptSubmit hook
for slash commands (which run skills without going through the Skill tool). This script:
- picks up the skill name on a
Skilltool call, the agent name on anAgenttool call, or the leading/nameof a slash command (counted only when it maps to a real skill definition, so built-ins like/clearare ignored), - figures out who ran it via
git config user.name, then - does a
+1on your own name line in that target's md## Usagesection (adding a new line if absent).
Since no LLM is involved, token cost stays at 0 no matter how much usage piles up.
(evaluate/tracker themselves are excluded from counting.)
/evaluate brainstorming 2 asks too many questions, slow even for simple tasks
/evaluate code-reviewer 5 catches the bug I missed every time
It appends one line - [score] name time | reason under ## Ratings. Score is 1–5,
lower is worse. The reason is required. That's all — it feels like jotting one line in a log.
tracker-report.ps1 -Name <name>prints usage / rating count / average score / file path (zero tokens).- One judge subagent reads the whole md file and assigns a verdict. While doing so:
- Since people usually rate only when annoyed, it looks at the ratio relative to usage and the score distribution, not the absolute number of bad ratings. (5 bad ratings out of 50 uses is fine; 30 out of 50 is a problem.)
- It also checks whether bad ratings are concentrated in one person.
- Conclusion: (a) fine — keep / (b) minor fix / (c) full rewrite / (d) per-user variant.
- It shows you that verdict and the rationale (a summary of what was good/bad), and together you decide a direction that keeps the good and fixes the bad. Changes are applied only after your approval.
Why hand the verdict to a subagent: so the main conversation context isn't filled with dozens of rating-log lines, and the ratio, skew, and severity get synthesized from one viewpoint into just the conclusion.
name kind usage ratings avg
brainstorming skill 8 2 3
commit skill 15 0 -
Explore agent 8 1 2
tracker-report.ps1 (no -Name) scans every skill/*.md and agent/*.md and prints one row per target
(total usage across users, rating count, average). No verdict, no subagent — just the overview.
For a deep verdict on one target, use /tracker <name>.
Each target gets one .claude/tracker/<skill|agent>/<name>.md file:
.claude/tracker/
skill/
brainstorming.md
commit.md
test-driven-development.md
agent/
code-reviewer.md
Explore.md
The contents of one file (e.g. skill/brainstorming.md):
# brainstorming (skill)
## Usage
- alice: 16
- bob: 5
## Ratings
- [2] alice 2026-06-14T09:30 | asks too many questions, slow
- [4] bob 2026-06-15T11:40 | mostly good, occasionally slow- The top
## Usage= cumulative usage counts per git name (updated by the hook) - The bottom
## Ratings= a 1–5 score rating log (appended by/evaluate)
The example above is for English. Header names follow the install language (
--lang ko→## 사용/## 평가, etc.). The scripts read the headers from.claude/tracker/config.json, so counts and ratings always land in the right section in any language.
Since everyone touches only their own line and ratings are only appended, this file merges cleanly
via git merge. Commit and share it, and the whole team's usage + ratings gather in one place.
One person can rack up counts on several branches, so the data files are built to merge with no conflicts:
- Counts use a local running counter. A per-clone
counts.local.jsonlives next to the scripts, is gitignored, and survives branch switches. The hook bumps it by 1 and writes that value into the md. So every branch's count is a snapshot on one ever-increasing sequence — merging by taking the max recovers the true total. - Ratings are append-only and merge by union (both sides kept, duplicates dropped).
This is wired through a git merge driver:
.claude/.gitattributes(committed → shared) mapstracker/**/*.mdto a driver namedtracker.tracker-merge.ps1(committed → shared) does max-on-counts + union-on-ratings.- The installer registers the driver command in this clone's
.git/config. Git does not share driver commands automatically — a deliberate security measure (otherwise cloning a repo could run arbitrary code on merge) — so each teammate gets it just by runningnpxonce (which they already do for the hook). Without the driver, git simply falls back to a normal text merge (no crash, just possible conflicts).
The driver runs only on local
git merge/rebase. GitHub's web "Merge" button merges server-side and won't use it, so merge into your main branch locally if you want it applied.
Run inside the same project folder you installed into:
npx github:lsc892/Agent-Tracker --uninstall
It reverses exactly what the installer did, touching only this project's .claude/ (never the
global ~/.claude):
- removes the count hook from
.claude/settings.local.json(any unrelated hooks/settings are kept) - unregisters the
merge.trackerdriver from this clone's.git/config - drops the
tracker/**/*.md merge=trackerline from.claude/.gitattributes(deletes the file if that was its only line) - deletes the
/evaluate,/tracker,/tracker-statscommand files - deletes
.claude/tracker/— including all accrued counts and ratings
The accrued data is deleted with
.claude/tracker/. If you want to keep it, back that folder up first. (From a local clone you can also runagent-tracker-uninstallafternpm link.)