@mhd1999/skillhub-tracker
v0.4.0
Published
SkillHub Claude Code usage tracker — reports token usage from ~/.claude/projects/*.jsonl to a SkillHub project.
Readme
@mhd1999/skillhub-tracker
Client-side npm package that reports Claude Code token usage to a SkillHub project. Runs locally on each developer's machine; never sends transcripts — only the per-turn usage block (model + token counts + session id + timestamp).
How it works
initwrites credentials to~/.skillhub-tracker/config.json, adds aSessionEndhook to~/.claude/settings.jsonthat runsskillhub-track flush, and (on Unix) schedules a periodicflushvia crontab so reporting doesn't depend on SessionEnd firing.- On every SessionEnd — and on the cron timer —
flushruns. flushwalks~/.claude/projects/*/*.jsonl, parses the new bytes since the last run (byte-offset cursor in~/.skillhub-tracker/cursor.json), extracts(session_id, model, usage, timestamp)from each assistant turn, and POSTs them in batches to/api/usage/events.- Server-side dedup on
(project, session_id, occurred_at, model)means re-runningflushis safe.
Skipped: full transcripts, prompts, tool call payloads — only the token-count block is sent.
SessionEnd is best-effort. If a user closes the terminal window or the process is killed, Claude Code may never fire SessionEnd, so that session's
flushis skipped. No data is lost — the usage already lives in the JSONL transcript, and the nextflush(next clean session, a manual run, or a scheduledcron) re-reads everything past the cursor and uploads it. For reporting that doesn't depend on how a session ends, add a periodic flush withskillhub-track cron(see below).
Install
npm install -g @mhd1999/skillhub-trackerConfigure
Attribute usage to you with a Personal Access Token (skh_…, issued in the SkillHub UI under your profile → tokens):
skillhub-track init \
--api-url http://skillhub.mor.local:8000 \
--project your-project \
--pat skh_xxxxxxxxxxxx--pat makes flush send X-PAT + X-Project-Slug, so each turn is credited to your user.
Legacy project token (unattributed)
The project MCP token (issued at project creation in the admin UI) still works, but usage stays unattributed — no per-user breakdown — and flush prints a one-line warning:
skillhub-track init --api-url http://skillhub.mor.local:8000 --project your-project --token mcp_xxxxxxxxxxxxExisting users — re-init to attribute usage
If you configured with --token on v0.2.0, re-run init with --pat to start attributing usage to your user (it overwrites the stored credential):
skillhub-track init --api-url http://skillhub.mor.local:8000 --project your-project --pat skh_xxxxxxxxxxxxCommands
| Command | Description |
|---|---|
| init | Write config + install SessionEnd hook |
| flush [--quiet] | Parse new bytes from JSONL transcripts and upload |
| status | Show config, pending byte count per file |
| cron [--every <min>] | Schedule a periodic flush via crontab (default 30 min) |
| cron --status / cron --remove | Show / remove the scheduled flush |
| uninstall | Remove the SessionEnd hook (config + cursor are kept) |
Scheduled flush
init already schedules this automatically (every 30 min on Unix); pass
--no-cron to opt out or --cron-every <minutes> to change the interval. The
cron command manages the schedule afterwards:
skillhub-track cron --status # */30 * * * * <node> <cli> flush --quiet # skillhub-tracker
skillhub-track cron --every 15 # change interval
skillhub-track cron --removeRuns flush on a timer regardless of how Claude Code sessions end, so usage is
reported even when terminals are closed abruptly. Idempotent (re-running updates
the same line) and leaves the user's other cron jobs untouched. Windows: cron
isn't available — the command prints the equivalent Task Scheduler (schtasks)
invocation instead.
Files
| Path | Purpose |
|---|---|
| ~/.skillhub-tracker/config.json | API URL + project + token (mode 0600) |
| ~/.skillhub-tracker/cursor.json | Per-file byte offsets already uploaded |
| ~/.skillhub-tracker/tracker.log | One-line per flush run (audit trail) |
| ~/.claude/settings.json | SessionEnd hook entry (marker: skillhub-tracker) |
Test locally
After init, run a Claude Code session, then either let SessionEnd fire automatically, or:
skillhub-track flush # ✓ scanned=12 parsed=87 uploaded=87 deduped=0
skillhub-track flush # ✓ scanned=12 parsed=0 uploaded=0 deduped=0
skillhub-track status