token-watcher

skill
Guvenlik Denetimi
Basarisiz
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 7 GitHub stars
Code Basarisiz
  • network request — Outbound network request in cloud/smoke.mjs
  • network request — Outbound network request in cloud/worker.js
  • rm -rf — Recursive force deletion command in menubar/build.sh
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

⏱ Token Watcher — local real-time token usage & quota dashboard for AI coding agents (Claude Code, ccmr, Codex, ZCode, dsh, WorkBuddy, Grok Build). 7 sources, zero-dep backend, live SSE panel, macOS menu bar. npx token-watcher serve

README.md

Token Watcher

Local, real-time token usage & quota dashboard for AI coding agents.

One resident process parses the session logs your AI coding tools already
leave on disk, normalizes them into a per-request event stream, and serves a
live dashboard: Codex-style stats, real-time quota cards, vendor balance
polling, cost estimation with reconciliation, and a macOS menu-bar capsule.
Local storage by default. The optional community leaderboard shares only
aggregate statistics after you explicitly opt in.

npm version
CI
license
platform

简体中文 · English

Token Watcher

Screenshot is real running data (vendor balances and project names masked).

Why Token Watcher

Most token trackers recompute a report when you ask. Token Watcher watches
the logs as they're written: FSEvents → incremental parse → SSE push, the
dashboard updates in under a second while your agents work. Everything is
stored as per-request events, not pre-aggregated buckets — so you can
drill from a day, to a session, to a single request's token curve.

It also refuses to lie to you: estimated sources are labeled as such
(Antigravity ≈), models without pricing show up as unpriced instead of a
made-up cost, and vendor balances are reconciled against locally computed
spend so you can see when the estimate drifts.

Token Watcher TokenTracker ccusage Tokscale
Interface Local web dashboard + menu bar Native apps + web CLI reports TUI / CLI
Refresh Real-time (FSEvents + SSE, <1s) Hook-triggered sync Manual run Manual run
Granularity Per-request events 30-min buckets Daily Daily
Sources 13, incl. China stack (ccmr, dsh, Qoder, Kimi Code, WorkBuddy) 39 Multi-agent Multi-agent
Cost LiteLLM prices + balance reconciliation + credits ledger LiteLLM estimate Estimate Estimate
Official quotas Claude / Codex direct-read, Cursor billing CSV 17 providers Limited Several
Telemetry Optional, opt-in aggregate leaderboard Opt-out None None
Install One zero-dependency npm package (incl. universal menu-bar app) npm + platform packages npm npm

Supported tools (13 sources)

Tool Data location What you get
Claude Code ~/.claude/projects Per-request tokens, model mix
ccmr (claude-code-model-router) ~/.claude-gateway/projects Same, with real model names behind the router
Codex ~/.codex/sessions Per-request tokens, official quota % and resets (5h / weekly), models incl. auto-review, tool calls
ZCode ~/.zcode/cli/db/db.sqlite Per-request details, tool calls, GLM Coding Plan credit windows (5h / weekly, official API)
dsh (DeepSeek Harness) ~/.dsh/sessions Per-request details (multi-frame zstd snapshots)
WorkBuddy ~/.WorkBuddy/projects Per-request details + self-learned credit rates
Grok Build ~/.grok/sessions Per-turn usage (incl. vendor cost scale), tool calls
Pi ~/.pi/agent/sessions Per-request details, tool calls
OpenCode ~/.local/share/opencode/opencode.db Per-request details, tool calls
Antigravity ≈ ~/.gemini/antigravity*/brain/**/transcript.jsonl Per planner turn — input from authoritative db context deltas, output estimated from content
Kimi Code ~/.kimi-code/sessions/**/wire.jsonl Per-turn details (3 usage shapes auto-detected)
Qoder ~/.qoder{,-cn}/projects/** Credits ledger (upstream reports credits, not tokens, locally)
Cursor Account-level usage CSV Per-request details — Cursor stores nothing per-request locally, so this polls the official export with local credentials

Not supported: web chats (ChatGPT etc.) — token counts live server-side, nothing to parse.

Honest-caliber notes: Kimi Code, Qoder, Antigravity and Cursor were each
verified on real local data against an independent recomputation, row by row.
Qoder currently reports credits but zero tokens locally — credits go to a
dedicated ledger shown as a "credits spent" card, never fabricated into
tokens. Estimated sources are labeled (≈).

Quick start

npx --yes token-watcher@latest serve
# dashboard opens automatically → http://127.0.0.1:8787

Long-term:

npm install -g token-watcher
token-watcher serve
token-watcher install-agent             # launchd auto-start (macOS)
token-watcher bar                       # menu-bar capsule
token-watcher bar                       # macOS menu-bar capsule

Homebrew: brew install luwill/token-watcher/token-watcher

CLI reference

token-watcher today [--json|--light]            # today's usage (machine-readable / pure ASCII)
token-watcher sessions --day 2026-09-20 [--csv] [--git]   # per-session stats (+ git commit attribution)
token-watcher wrapped [--year 2026] [--json]    # year in review
token-watcher roi [--json]                     # subscription ROI (API-equivalent vs paid)
token-watcher leaderboard [on <name>|off|status|push|url <url>]
                                                # community leaderboard (opt-in, aggregate numbers only)
token-watcher doctor                            # environment + store + per-source health
token-watcher uninstall [--purge-data] [--yes]  # remove all local traces
token-watcher --version

Features

  • Real-time: FSEvents on every source dir → incremental parse → SSE push (<1s)
  • Incremental collection: byte cursors / sqlite watermarks / snapshot re-parse; dedup keys make rescans idempotent; collector versioning auto-backfills on logic upgrades
  • Dashboard: metric cards, year-long GitHub-style heatmap (daily/weekly/cumulative), by-day/model/tool charts, live request feed
  • Session drill-down: click any day → sessions (peak-context estimate) → per-request token curve
  • Quotas: Codex official (direct-read), Claude official (local OAuth token → official usage endpoint; falls back to 5h window estimation)
  • Subscription ROI: this month's API-equivalent cost vs what you actually pay (configure prices in ~/.tokenmeter/subscriptions.json; token-watcher roi)
  • Balances & costs: DeepSeek/Kimi balance polling; LiteLLM pricing with per-model CNY conversion; balance reconciliation; Qoder credits ledger
  • Community leaderboard (opt-in, off by default): see how your daily/weekly/30-day totals stack up against other users — aggregate numbers only, never your raw events. token-watcher leaderboard on <name>
  • Health self-check: parse errors turn red, "file being written but no new events" turns yellow — silent format drift gets caught
  • Exports & backups: CSV, session/annual CLI reports, daily VACUUM INTO snapshots (7 kept)

Subscription ROI

Edit ~/.tokenmeter/subscriptions.json with what you actually pay (one entry
per tool, price_cny or price_usd):

{ "monthly": {
    "claude-code": { "name": "Claude Max", "price_usd": 200 },
    "kimi":        { "name": "Kimi plan",  "price_cny": 49 },
    "glm":         { "tool": "zcode", "models": "glm", "name": "GLM Coding Plan", "price_cny": null },
    "minimax":     { "tool": "zcode", "models": "minimax", "name": "MiniMax (via ZCode)", "price_cny": null } } }

Entry keys are identifiers; tool selects the data source (needed when one
tool carries multiple subscriptions, e.g. GLM and MiniMax both flowing through
ZCode), and models filters aggregation by model prefix. Entries with the
price unset still show their API-equivalent, labeled "price not set".

The dashboard and token-watcher roi then compare this month's API-equivalent
cost (same pricing chain as the cost card, including peak/off-peak) against
your real spend. Clearly labeled as a hypothetical caliber: subscriptions come
with rate limits and API prices may be discounted. Credits-based tools (Qoder)
show this month's credits spent instead of a made-up ratio.

Community leaderboard (opt-in)

Off by default. Join explicitly with a nickname:

token-watcher leaderboard on <nickname>   # join (1-16 chars, no links/@)
token-watcher leaderboard status          # participation + last report state
token-watcher leaderboard push            # report once right now
token-watcher leaderboard off             # stop reporting; daily cleanup after 30d inactivity
token-watcher leaderboard url <https://…> # point at a self-hosted instance

What gets reported — aggregate numbers only, once per hour:

Reported Never leaves your machine
Nickname, a random local UUID (regeneratable) File paths, project names
UTC today's / rolling-7-day / rolling-30-day token totals, request count Per-request rows, timestamps
Dominant model per period (day / 7 / 30 days); legacy weekly model/tool shares (top 5) API keys, machine identifiers
Subscription ROI as a ratio (×N, no amounts) Session content, anything else

The panel can read the public leaderboard even before joining; only opted-in
clients upload usage aggregates. Viewing the panel makes a public GET request
without your random UUID when participation is disabled. doctor shows
the participation state either way. The reference backend is a
Cloudflare Worker + D1 (free tier) in cloud/ — anyone can
self-host one and point the CLI at it. Server-side defenses: name sanitizing,
all-field clamping, 16 KiB request limits, edge rate limiting, 60s per-ID throttling,
and daily cleanup of entries inactive for over 30 days (normally removed within 31 days).
The daily board uses UTC; the rolling-7-day and rolling-30-day boards require a report within 24 hours. Older clients without a 30-day total remain on the day/week boards until upgraded.

The dominant model follows the selected period: UTC today, rolling 7 days, or
rolling 30 days. It is the model with the largest total_tokens sum in that window;
its percentage is rounded against all tokens in the same window. Only the
winner is displayed; ties use model ID order. Events without a model remain in the
denominator but cannot be a dominant model. Model versions remain distinct.
Older reports containing only weekly models show a pending-update message on the
daily/30-day boards instead of reusing weekly data. Tool shares remain weekly.
ROI is a local-calendar-month hypothetical API-equivalent/monthly-fee ratio.
All figures are self-reported and unverified; this is not a competition or audited usage record.
The application database does not store IP addresses; Cloudflare processes network
metadata and uses source IPs for edge rate limiting.

Privacy

Fully local. The dashboard binds to 127.0.0.1 only (with Host validation).
API keys and tokens are used inside the server process only, never stored or
sent to the frontend. Usage data never leaves your machine — with one explicit
exception: the opt-in community leaderboard above, which sends only the
aggregate numbers listed there, only after you run leaderboard on.

Outbound requests (only these; none carry your usage data unless noted): FX
rate (12h), LiteLLM price table (24h), vendor balances (30min, with your key),
Claude official quota (10min, with Claude Code's local OAuth token), Cursor
usage CSV (30min, with a cookie built from local credentials), GLM Coding
Plan credit quota (10min, with ZCode's own local API key; MCP tool quota is
read from local logs only), leaderboard aggregate report (hourly, opt-in
only
), and public leaderboard reads when viewing the dashboard.
Set TOKENMETER_OFFLINE=1 to skip all of them.

Requirements

Node ≥ 22.13 (node:sqlite). macOS fully supported (menu bar + launchd);
core pipeline CI-tested on macOS/Ubuntu/Windows. dsh source needs system
zstd. Non-official tool: parses private local formats that upstreams may
change — the health panel will flag it instead of failing silently.

Architecture

See docs/ARCHITECTURE.md (Chinese, with per-source
format notes and verification methodology). Core: one collector per source
under src/collectors/* (incremental + dedup + version), src/scanner.js
schedules, SQLite event store, HTTP API + SSE in src/server.js, zero-build
frontend in web/. Adding a source = one collector + registry entry + a
color. See CONTRIBUTING.md.

License

MIT

Yorumlar (0)

Sonuc bulunamadi