This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
AgentMeter (@ymstar/agentmeter) is a CLI that tracks token consumption for AI agents (Claude Code, Cursor, Gemini CLI). It hooks into Claude Code's PostToolUse event to capture every tool call, records token usage and estimated costs into a local SQLite database, and provides terminal stats, a web dashboard, CSV/JSON export, and budget alerts.
npm run build # Compile TypeScript to dist/ + copy dashboard static assets
npm run test # Run all tests (vitest run)
npm run dev # Watch mode compilation (tsc --watch)
npx tsc --noEmit # Type-check only (used in CI lint job)There is no linter or formatter configured. CI type-checks with npx tsc --noEmit on Node 20 and 22.
ES modules ("type": "module" in package.json). Target ES2022 with Node16 module resolution.
initcommand writes aPostToolUsehook into~/.claude/settings.jsonthat runsnpx -y @ymstar/agentmeter hook- Claude Code fires the hook after every tool use, passing tool name, input, response, session_id, model, agent_type, cwd via stdin JSON
hookcommand parses stdin, detects model/agent type via fallback chains, estimates tokens (three-layer: parse MCP usage fields → estimate from text at 4 chars/token ASCII, 2 chars/token CJK → character count), calculates cost, inserts into SQLite- SQLite lives at
~/.agentmeter/meter.db
src/index.ts— CLI entry point usingnode:utilparseArgs. Routes to:init,hook,stats,dashboard,budget,exportsrc/commands/hook.ts— Core data collection. ContainsdetectModel()(input → env vars → settings file → default Sonnet) anddetectAgentType()(input → env vars → UUID pattern →~/.claudeexistence)src/db/client.ts—MeterDBclass wrappingbetter-sqlite3. Singletool_callstable with migration support (adds columns viaALTER TABLEbased onPRAGMA table_info). WAL mode enabledsrc/token/pricing.ts— HardcodedMODEL_PRICINGtable for Claude, GPT, and Gemini models. Unknown models default to Claude Sonnet pricingsrc/dashboard/server.ts— Rawnode:httpserver (no framework). REST API at/api/overview,/api/daily,/api/tools,/api/sessions,/api/models,/api/agents,/api/calls. Default port 3940
| Path | Purpose | Managed by |
|---|---|---|
~/.claude/settings.json |
Claude Code settings (hook injection) | init command |
~/.agentmeter/meter.db |
SQLite database | hook, stats, export, budget, dashboard |
~/.agentmeter/config.json |
Budget limits | budget command |
- No external framework dependencies. HTTP server is raw
node:http, CLI parser isnode:utilparseArgs, dashboard frontend loads Chart.js from CDN - Synchronous SQLite. All DB operations use synchronous
better-sqlite3. Themain()in index.ts is async but command handlers are synchronous - DB_PATH is duplicated across
hook.ts,stats.ts,export.ts,budget.ts, anddashboard/server.ts— each definesconst DB_PATH = join(homedir(), ".agentmeter", "meter.db") - Build copies static assets —
npm run buildrunstscthencp -r src/dashboard/static dist/dashboard/to include the frontend files in dist
Tests are in tests/ using Vitest. Four test files: db.test.ts, token.test.ts, budget.test.ts, export.test.ts.
npm run test # Run all tests
npx vitest run tests/db.test.ts # Run a single test fileThe project uses GitHub Actions to automatically publish to npm when a GitHub Release is created.
-
Update version in
package.json:npm version patch # or minor / major -
Commit and push version bump:
git add package.json package-lock.json git commit -m "chore: bump version to X.Y.Z" git push origin master -
Create a GitHub Release (triggers npm publish automatically):
gh release create vX.Y.Z \ --repo ymstar/agentmeter \ --title "vX.Y.Z" \ --notes "## Changes\n- ..."
-
GitHub Actions (
.github/workflows/publish.yml) will automatically:- Checkout code
- Install dependencies (
npm ci) - Build (
npm run build) - Run tests (
npm test) - Publish to npm (
npm publish --provenance --access public)
.github/workflows/ci.yml runs on every push/PR to master:
- Build + Test on Node 20 and 22
- Lint (type-check with
npx tsc --noEmit) on Node 22
- NPM_TOKEN secret must be configured in the GitHub repository settings
- The token needs
publishpermission for the@ymstar/agentmeterpackage