agwatch-cli
v2.1.0
Published
Terminal analytics CLI for AI coding agents, usage, costs, tokens, and providers
Downloads
113
Maintainers
Readme
agwatch is a terminal analytics CLI for AI coding workflows. It reads local usage data from supported agents, normalizes it into a shared event model, and renders that data as an interactive dashboard or structured summary output.
It is built to answer practical questions such as:
- How much did each agent, model, project, or activity cost?
- Which tools and shell commands were used most?
- How many input, output, cached, and written tokens were consumed?
- Which provider usage windows are close to their limits?
What It Shows
agwatch organizes usage into panels so you can inspect both totals and breakdowns quickly.
Agent Analytics
Across enabled agents, the dashboard and summary can show:
- Total cost
- Total calls
- Session count
- Cache hit rate
- Input, output, cached, and written token counts
- Daily activity trends
- Usage by project
- Usage by activity type
- Usage by model
- Tool call frequency
- Shell command frequency
- MCP server usage
Agent Organization
Data is grouped in two ways:
All Agentsaggregates usage from every enabled agent- Per-agent tabs show isolated usage for each configured agent
The default config currently supports:
OpenCodevia SQLite or JSON-based local dataClaude Codevia local JSONL project logsCodexvia local JSONL session logs
Provider Panel
The dashboard also includes a provider usage panel for configured providers.
For each provider, agwatch shows:
- Provider name
- Data source:
apiorbrowser-fallback - Scrape time
- Every usage or quota limit returned by the provider
- The provider's label, usage percentage, and reset time/date for each limit
- Provider-specific error state when usage could not be fetched
Limit rows are dynamic. Providers may expose only a weekly limit, only a rolling/session limit, or additional daily/monthly/model limits. agwatch renders the limits found in the trusted usage API response or usage-page cards instead of fabricating missing rows. Newly returned limits appear without an agwatch code update.
Supported providers currently include:
OpenAIAnthropicZ.AIOpenCode Go
Installation
Requirements
- Node.js
22+ - Access to local agent data files
Global Install
npm install -g agwatch-cliRun Without Installing Globally
npx agwatch-cli dashboardQuick Start
agwatch
agwatch dashboard
agwatch summary
agwatch summary --range today --jsonCommands
dashboard
Launch the interactive terminal dashboard.
agwatch
agwatch dashboard
agwatch dashboard --range today
agwatch dashboard --range 30d
agwatch dashboard --watchagwatch and agwatch dashboard do the same thing. If no subcommand is provided, the CLI starts the interactive dashboard by default.
summary
Print a non-interactive usage report.
agwatch summary
agwatch summary --range 7d
agwatch summary --from 2026-04-01 --to 2026-04-20
agwatch summary --jsonCLI Flags
Shared Time Range Flags
| Flag | Values | Description |
|---|---|---|
| --range | today, 7d, 30d, month | Preset reporting range |
| --from | YYYY-MM-DD | Custom start date for summary |
| --to | YYYY-MM-DD | Custom end date for summary |
Summary Flags
| Flag | Description |
|---|---|
| --json | Emit structured JSON instead of text |
Dashboard Flags
| Flag | Description |
|---|---|
| --watch | Auto-refresh usage data every 3 seconds |
| --provider-debug | Enable provider debug logging in non-interactive contexts |
| --provider-startup-timeout-ms <ms> | Timeout for background provider loading during startup |
| --provider-manual-timeout-ms <ms> | Timeout for manual provider refresh actions |
| --provider-fallback <mode> | Browser fallback policy: never, on_auth_error, on_any_error |
Provider Runtime Defaults
| Option | Default |
|---|---|
| provider debug | false |
| startup timeout | 25000 ms |
| manual timeout | 35000 ms |
| fallback mode | on_auth_error |
Dashboard Keybindings
| Key | Action |
|---|---|
| q | Quit |
| 1-4 | Switch time period |
| ↑ ↓ | Cycle periods |
| ← → | Switch agent tabs |
| u | Refresh usage data |
| r | Refresh pricing data |
| v | Refresh provider usage |
| a | Refresh all data |
| p | Open provider setup menu |
| l | Open layout mode menu |
Dashboard Panels
| Panel | What it shows |
|---|---|
| Overview | Total cost, calls, sessions, cache hit rate, and token totals |
| Providers | Provider usage percentages, reset windows (5h, weekly, monthly when available), scrape source, and provider errors |
| By Project | Cost, tokens, and sessions grouped by project |
| By Model | Cost, tokens, and calls grouped by model |
| By Activity | Cost and calls grouped by inferred workflow type such as coding, debugging, or testing |
| Daily Activity | Per-day cost, tokens, and calls |
| Core Tools | Tool usage frequency |
| Shell Commands | Shell command frequency |
| MCP Servers | MCP server usage frequency |
Progress bars are relative to the highest row in each panel.
Configuration
Configuration is stored in:
~/.config/agwatch/config.jsonOn first run, agwatch creates this file automatically.
Example Config
{
"agents": [
{
"id": "opencode",
"label": "OpenCode",
"enabled": true,
"source": "opencode",
"type": "sqlite",
"paths": [
"~/.local/share/opencode/opencode.db",
"~/.opencode/opencode.db",
"~/.config/opencode/opencode.db"
]
},
{
"id": "claude",
"label": "Claude Code",
"enabled": true,
"source": "claude",
"type": "jsonl",
"paths": [
"~/.claude/projects"
]
},
{
"id": "codex",
"label": "Codex",
"enabled": true,
"source": "codex",
"type": "jsonl",
"paths": [
"~/.codex/sessions"
]
}
],
"providers": [],
"dashboard": {
"resizeMode": "auto"
}
}dashboard.resizeMode can be auto or responsive. auto keeps the default behavior of resizing the terminal window for the dashboard. responsive keeps the terminal window unchanged and adapts the layout to the current terminal width.
Agent Fields
| Field | Type | Description |
|---|---|---|
| id | string | Stable internal identifier |
| label | string | Display name used in tabs and UI |
| enabled | boolean | Whether the agent is included in aggregation |
| source | opencode | claude | codex | Adapter implementation; required for custom JSONL agent IDs and inferred as opencode for SQLite/JSON |
| type | sqlite | json | jsonl | Local storage format |
| paths | string[] | Candidate paths to search for agent data |
Provider Fields
| Field | Type | Description |
|---|---|---|
| id | string | Provider identifier |
| label | string | Display name |
| enabled | boolean | Whether provider scraping is enabled |
Provider Setup
Provider configuration is handled from inside the dashboard.
- Open the dashboard.
- Press
pto open the provider menu. - Choose a supported provider.
- Authenticate in the browser flow.
- Return to the dashboard to view provider usage.
If browser automation dependencies are missing, agwatch prompts to install them during setup. The optional runtime is stored at ~/.config/agwatch/browser-runtime (or under $XDG_CONFIG_HOME) so it survives agwatch npm upgrades and is reused for every provider and re-authentication. Puppeteer's Chrome for Testing download uses its standard cross-platform cache and is downloaded only when its expected executable is missing.
When cookies expire or a provider rejects the saved session, agwatch clears that session and offers re-authentication. An already installed browser runtime is detected and reused; the installation prompt appears only when the runtime is actually unavailable or incomplete.
Provider usage is fetched live on dashboard startup and provider refresh. Usage results are not persisted in a provider cache; authentication cookies and the separate model-pricing cache are persisted as described below.
Provider Session Security
When you authenticate a provider, agwatch captures the browser session cookies needed to fetch your usage data and stores them locally so you are not prompted to log in on every run.
What is stored
Only authentication-relevant cookies are saved — session tokens, auth tokens, and httpOnly server-set cookies. Analytics, tracking, and other non-auth cookies are discarded before the file is written.
Encryption
Stored cookies are encrypted at rest using AES-256-GCM.
The encryption key is derived per-provider using HKDF-SHA256 keyed from a stable machine-bound identifier:
| Platform | Machine identifier |
|---|---|
| Windows | HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid |
| macOS | IOPlatformSerialNumber via ioreg |
| Linux | /etc/machine-id or /var/lib/dbus/machine-id |
If the platform identifier cannot be read, key derivation falls back to username@hostname, and finally to a fixed emergency fallback in unusually restricted environments. Cookie encryption is local protection, not a substitute for OS account and filesystem security.
File permissions
Cookie files are written with owner-only access:
| Platform | Enforcement |
|---|---|
| macOS / Linux | chmod 0600 at write time |
| Windows | icacls removes inherited ACLs and grants full control only to the current user |
Storage location
~/.config/agwatch/provider-cookies/<provider-id>.jsonExpiry
Cookies with past expiry timestamps are filtered out automatically on every load. If all stored cookies for a provider have expired, the file is deleted. Reconfigure that provider from the dashboard provider menu to authenticate again.
Pricing
Model pricing is fetched from the LiteLLM pricing database and cached locally.
- Source:
https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json - Cache file:
~/.config/agwatch/pricing-cache.json - Cache TTL:
24 hours
Behavior:
agwatchuses cached prices when the cache is still fresh.- It fetches fresh prices when the cache is stale.
- If fetching fails, it falls back to the last cached pricing.
- If no pricing is available, unknown costs resolve to
$0. - If a source record already contains a non-zero cost, that stored cost is used.
Summary Output
Text Output
The text summary includes:
- Summary totals
- Top models
- Top projects
- Daily activity
- Activity breakdown
JSON Output
agwatch summary --json returns:
metadatasummarypanels.dailyActivitypanels.byProjectpanels.byActivitypanels.byModelpanels.toolspanels.shellCommandspanels.mcpServers
Data Sources
agwatch reads local agent data and converts it into a shared usage event model.
OpenCode
Reads session, message, and tool-call data from local OpenCode storage.
- SQLite is preferred when available
- SQLite is read through
sql.js - Explicit legacy JSON configurations and standard JSON fallback discovery are supported
Claude Code
Reads local JSONL project logs from the Claude Code projects directory.
Codex
Reads local JSONL session logs from the Codex sessions directory.
Architecture
Data Layer -> Domain Layer -> Aggregation Layer -> Presentation Layersrc/
cli/ command dispatch and argument parsing
adapters/ agent-specific readers for OpenCode, Claude Code, and Codex
domain/ shared types and normalization
services/ loading, aggregation, pricing, and provider services
tui/ Ink-based dashboard UI
output/ text and JSON summary renderers
config/ config loading and time ranges
utils/ formatting, grouping, dates, and error handlingTech Stack
- TypeScript
- Node.js
- Ink
- React
- Commander
- sql.js
- dayjs
- zod
Development
Install Dependencies
npm installBuild
npm run buildWatch Mode
npm run devType Check
npm run typecheckYou can also run:
npm run lintTest
npm testTests use Node.js's built-in test runner and rebuild from a clean dist/ directory first.
Run Locally
npm start
node dist/cli/index.js dashboard --range today
node dist/cli/index.js summary --range 7dNotes
npm testruns the regression suite with Node.js's built-in test runner.- The package exposes the
agwatchbinary fromdist/cli/index.js. - Required Node.js version is
22+.
License
MIT
