@juliantanx/aiusage 1.3.4 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +124 -535
  2. package/dist/index.js +6514 -2343
  3. package/dist/web/_app/immutable/assets/0.BYjLgame.css +1 -0
  4. package/dist/web/_app/immutable/assets/11.4MyEKiO6.css +1 -0
  5. package/dist/web/_app/immutable/assets/12.nNHFRI35.css +1 -0
  6. package/dist/web/_app/immutable/assets/13.CAQKz1hf.css +1 -0
  7. package/dist/web/_app/immutable/assets/14.Bcofmxqa.css +1 -0
  8. package/dist/web/_app/immutable/assets/15.F0aA4smG.css +1 -0
  9. package/dist/web/_app/immutable/assets/2.GIkI4O03.css +1 -0
  10. package/dist/web/_app/immutable/assets/3.H3-dDI9U.css +1 -0
  11. package/dist/web/_app/immutable/assets/4.BOWlKC54.css +1 -0
  12. package/dist/web/_app/immutable/assets/5.CLn2x9cs.css +1 -0
  13. package/dist/web/_app/immutable/assets/6.C1lxHTyi.css +1 -0
  14. package/dist/web/_app/immutable/assets/7.oxd6PqWk.css +1 -0
  15. package/dist/web/_app/immutable/assets/8.9jvt5Dym.css +1 -0
  16. package/dist/web/_app/immutable/assets/9.DsmA__AV.css +1 -0
  17. package/dist/web/_app/immutable/assets/ToolSelector.BewzNVhC.css +1 -0
  18. package/dist/web/_app/immutable/assets/ToolSelector.BqfI2BMz.css +1 -0
  19. package/dist/web/_app/immutable/assets/_layout.D8R7GvV-.css +1 -0
  20. package/dist/web/_app/immutable/assets/_page.4MyEKiO6.css +1 -0
  21. package/dist/web/_app/immutable/assets/_page.9jvt5Dym.css +1 -0
  22. package/dist/web/_app/immutable/assets/_page.BOWlKC54.css +1 -0
  23. package/dist/web/_app/immutable/assets/_page.Bcofmxqa.css +1 -0
  24. package/dist/web/_app/immutable/assets/_page.C1lxHTyi.css +1 -0
  25. package/dist/web/_app/immutable/assets/_page.CFfU6gQq.css +1 -0
  26. package/dist/web/_app/immutable/assets/_page.CLn2x9cs.css +1 -0
  27. package/dist/web/_app/immutable/assets/_page.CMG6gS2t.css +1 -0
  28. package/dist/web/_app/immutable/assets/_page.DXX8tyXM.css +1 -0
  29. package/dist/web/_app/immutable/assets/_page.F0aA4smG.css +1 -0
  30. package/dist/web/_app/immutable/assets/_page.H3-dDI9U.css +1 -0
  31. package/dist/web/_app/immutable/assets/_page.ZSDsIDry.css +1 -0
  32. package/dist/web/_app/immutable/assets/_page.oxd6PqWk.css +1 -0
  33. package/dist/web/_app/immutable/chunks/ToolSelector.CofvKVw2.js +2 -0
  34. package/dist/web/_app/immutable/chunks/api.Mv_KcGhp.js +1 -0
  35. package/dist/web/_app/immutable/chunks/entry.PDoHFbXz.js +3 -0
  36. package/dist/web/_app/immutable/chunks/i18n.CwV3KceS.js +1 -0
  37. package/dist/web/_app/immutable/chunks/index.66Vu9Sio.js +1 -0
  38. package/dist/web/_app/immutable/chunks/{index.CPsgU-fv.js → index.m3oCcA6N.js} +1 -1
  39. package/dist/web/_app/immutable/chunks/scheduler.DsWd5xup.js +1 -0
  40. package/dist/web/_app/immutable/chunks/stores.BSI_cVy6.js +1 -0
  41. package/dist/web/_app/immutable/chunks/{stores.DIJRlQaL.js → stores.Botc0ioY.js} +1 -1
  42. package/dist/web/_app/immutable/entry/app.CoPtpbXI.js +2 -0
  43. package/dist/web/_app/immutable/entry/start.CaOJNprV.js +1 -0
  44. package/dist/web/_app/immutable/nodes/0.CZMa2uzk.js +142 -0
  45. package/dist/web/_app/immutable/nodes/{1.ClCXLnt8.js → 1.DJI2NNga.js} +1 -1
  46. package/dist/web/_app/immutable/nodes/10.DTaETIM6.js +1 -0
  47. package/dist/web/_app/immutable/nodes/11.CScZqjVc.js +1 -0
  48. package/dist/web/_app/immutable/nodes/12.DeLNKhlw.js +1 -0
  49. package/dist/web/_app/immutable/nodes/13.BFaBQy6e.js +1 -0
  50. package/dist/web/_app/immutable/nodes/14.BgJEC28r.js +1 -0
  51. package/dist/web/_app/immutable/nodes/15.DjuCO6OE.js +1 -0
  52. package/dist/web/_app/immutable/nodes/2.CoxR54dV.js +3 -0
  53. package/dist/web/_app/immutable/nodes/3.Bua2oewW.js +1 -0
  54. package/dist/web/_app/immutable/nodes/4.DJwmYYKI.js +1 -0
  55. package/dist/web/_app/immutable/nodes/5.CXmtjVJL.js +1 -0
  56. package/dist/web/_app/immutable/nodes/6.kpxBlrHt.js +1 -0
  57. package/dist/web/_app/immutable/nodes/7.LSfdx4vz.js +9 -0
  58. package/dist/web/_app/immutable/nodes/8.ByAI01dT.js +1 -0
  59. package/dist/web/_app/immutable/nodes/9.Ubt4Bfxd.js +1 -0
  60. package/dist/web/_app/version.json +1 -1
  61. package/dist/web/index.html +10 -10
  62. package/dist/web/wechat-support-qr.jpg +0 -0
  63. package/package.json +3 -4
  64. package/dist/web/_app/immutable/assets/0.bPTGJZag.css +0 -1
  65. package/dist/web/_app/immutable/assets/10.C9BKssg5.css +0 -1
  66. package/dist/web/_app/immutable/assets/11.DoWxheGb.css +0 -1
  67. package/dist/web/_app/immutable/assets/12.MAt3PLLc.css +0 -1
  68. package/dist/web/_app/immutable/assets/13.CYY7rvzI.css +0 -1
  69. package/dist/web/_app/immutable/assets/2.CLCMeZwn.css +0 -1
  70. package/dist/web/_app/immutable/assets/3.BB9nMGBG.css +0 -1
  71. package/dist/web/_app/immutable/assets/4.D4N7n6x9.css +0 -1
  72. package/dist/web/_app/immutable/assets/5.BvcBvBEs.css +0 -1
  73. package/dist/web/_app/immutable/assets/6.CcFk1fVK.css +0 -1
  74. package/dist/web/_app/immutable/assets/7.BeGOLIpG.css +0 -1
  75. package/dist/web/_app/immutable/assets/8.yw0F4oCm.css +0 -1
  76. package/dist/web/_app/immutable/assets/ToolSelector.BRqFUj1Q.css +0 -1
  77. package/dist/web/_app/immutable/assets/ToolSelector.Bqx3ytrl.css +0 -1
  78. package/dist/web/_app/immutable/assets/_layout.QS8Tu4KK.css +0 -1
  79. package/dist/web/_app/immutable/assets/_page.BB9nMGBG.css +0 -1
  80. package/dist/web/_app/immutable/assets/_page.BLq-3aJQ.css +0 -1
  81. package/dist/web/_app/immutable/assets/_page.BeGOLIpG.css +0 -1
  82. package/dist/web/_app/immutable/assets/_page.BvEGYIGb.css +0 -1
  83. package/dist/web/_app/immutable/assets/_page.BvcBvBEs.css +0 -1
  84. package/dist/web/_app/immutable/assets/_page.C9BKssg5.css +0 -1
  85. package/dist/web/_app/immutable/assets/_page.CGsCDBRD.css +0 -1
  86. package/dist/web/_app/immutable/assets/_page.CYY7rvzI.css +0 -1
  87. package/dist/web/_app/immutable/assets/_page.CcFk1fVK.css +0 -1
  88. package/dist/web/_app/immutable/assets/_page.D4N7n6x9.css +0 -1
  89. package/dist/web/_app/immutable/assets/_page.MAt3PLLc.css +0 -1
  90. package/dist/web/_app/immutable/chunks/ToolSelector.D-ihlQCZ.js +0 -2
  91. package/dist/web/_app/immutable/chunks/api.BR248OCH.js +0 -1
  92. package/dist/web/_app/immutable/chunks/entry.Bw49Judx.js +0 -3
  93. package/dist/web/_app/immutable/chunks/index.B0Aytz_K.js +0 -1
  94. package/dist/web/_app/immutable/chunks/scheduler.DFD7qxcZ.js +0 -1
  95. package/dist/web/_app/immutable/chunks/stores.B1g8D8DV.js +0 -1
  96. package/dist/web/_app/immutable/entry/app.C3JWF8LV.js +0 -2
  97. package/dist/web/_app/immutable/entry/start.DJaQZyhE.js +0 -1
  98. package/dist/web/_app/immutable/nodes/0.BGBMbwBp.js +0 -1
  99. package/dist/web/_app/immutable/nodes/10.a_45vAk_.js +0 -1
  100. package/dist/web/_app/immutable/nodes/11.Uz-0jVL7.js +0 -1
  101. package/dist/web/_app/immutable/nodes/12.DoQ9E1LV.js +0 -1
  102. package/dist/web/_app/immutable/nodes/13.6lDoUYy7.js +0 -1
  103. package/dist/web/_app/immutable/nodes/2.BB8OyOCP.js +0 -3
  104. package/dist/web/_app/immutable/nodes/3.Cfms9ru5.js +0 -1
  105. package/dist/web/_app/immutable/nodes/4.BRcdKGbJ.js +0 -1
  106. package/dist/web/_app/immutable/nodes/5.BvbSC3f6.js +0 -1
  107. package/dist/web/_app/immutable/nodes/6.B4H7Hfou.js +0 -9
  108. package/dist/web/_app/immutable/nodes/7.Civ32duh.js +0 -1
  109. package/dist/web/_app/immutable/nodes/8.TXFmgrFA.js +0 -1
  110. package/dist/web/_app/immutable/nodes/9.B9_1-2xn.js +0 -1
  111. /package/dist/web/_app/immutable/assets/{9.DpWloLoX.css → 10.DpWloLoX.css} +0 -0
package/README.md CHANGED
@@ -1,607 +1,196 @@
1
- # aiusage — AI Coding Assistant Usage Tracker
2
-
3
- **Website: [aiusage.jtanx.com](https://aiusage.jtanx.com)**
4
-
5
- Track token usage, cost, and sessions across **7 AI coding tools** — local-first, no accounts required.
6
-
7
- [![npm version](https://img.shields.io/npm/v/@juliantanx/aiusage)](https://www.npmjs.com/package/@juliantanx/aiusage)
8
- [![CI](https://github.com/juliantanx/aiusage/actions/workflows/test.yml/badge.svg)](https://github.com/juliantanx/aiusage/actions/workflows/test.yml)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
- [![Node.js](https://img.shields.io/badge/Node.js-20%2B-green.svg)](https://nodejs.org/)
11
- [![Website](https://img.shields.io/badge/Website-aiusage.jtanx.com-blue.svg)](https://aiusage.jtanx.com)
12
-
13
- English | [中文](https://github.com/juliantanx/aiusage/blob/main/README_zh.md)
14
-
15
- ## Quick Start
16
-
17
- **Prerequisites:** Node.js 20 or later
18
-
19
- ```bash
20
- npm install -g @juliantanx/aiusage
21
- aiusage parse
22
- aiusage serve
23
- ```
24
-
25
- Open `http://localhost:3847` to explore the dashboard.
1
+ <h1 align="center">
2
+ <img src="https://cdn.jsdelivr.net/gh/juliantanx/aiusage@main/packages/site/static/logo-icon.svg" alt="AIUsage logo" width="42" align="absmiddle" />
3
+ AIUsage
4
+ </h1>
26
5
 
27
6
  <p align="center">
28
- <img src="https://raw.githubusercontent.com/juliantanx/aiusage/a527444cf87a9c1e92f1440282ed4e94f744b910/packages/site/static/screenshots/dashboard-home.png" alt="aiusage dashboard home" width="32%" />
29
- <img src="https://raw.githubusercontent.com/juliantanx/aiusage/a527444cf87a9c1e92f1440282ed4e94f744b910/packages/site/static/screenshots/overview.png" alt="aiusage overview dashboard" width="32%" />
30
- <img src="https://raw.githubusercontent.com/juliantanx/aiusage/a527444cf87a9c1e92f1440282ed4e94f744b910/packages/site/static/screenshots/sessions.png" alt="aiusage sessions dashboard" width="32%" />
7
+ Local-first usage tracker for AI coding assistants.
31
8
  </p>
32
9
 
33
- > If aiusage is useful, **[star this repo](https://github.com/juliantanx/aiusage)** to help more developers discover it.
34
-
35
- `aiusage` does not run a built-in background parser. If you want automatic imports, schedule `aiusage parse` with cron or Task Scheduler.
36
-
37
- ### Running in Background (PM2)
38
-
39
- `aiusage serve` runs in the foreground and stops when you close the terminal. To keep it running in the background on **Windows, macOS, and Linux**, use [PM2](https://pm2.keymetrics.io/):
40
-
41
- ```bash
42
- # Install PM2 (one-time)
43
- npm install -g pm2
44
-
45
- # Start aiusage as background services (generates config + starts PM2)
46
- aiusage pm2-start
47
-
48
- # Set auto-start on boot (Linux / macOS: run directly; Windows: run the output command as Administrator)
49
- pm2 startup
50
-
51
- # Common commands
52
- pm2 list # View running status
53
- pm2 logs # View logs
54
- pm2 stop all # Stop all services
55
- pm2 restart all # Restart all services
56
- pm2 delete all # Remove all services
57
- ```
58
-
59
- <details>
60
- <summary>Build from source</summary>
61
-
62
- ```bash
63
- git clone https://github.com/juliantanx/aiusage.git
64
- cd aiusage
65
- pnpm install
66
- pnpm build
67
- cd packages/cli
68
- npm link
69
- ```
70
-
71
- After pulling updates, rebuild to pick up changes:
72
-
73
- ```bash
74
- pnpm build
75
- ```
76
-
77
- If you switch Node.js versions locally, recompile the `better-sqlite3` native module for the new version:
78
-
79
- ```bash
80
- pnpm rebuild:sqlite
81
- ```
82
-
83
- > This is only needed when developing from source. Users who install via `npm install -g` do not need to do this — the module is compiled automatically during installation.
84
-
85
- </details>
86
-
87
- ## Why aiusage
88
-
89
- Your AI coding tools each log usage separately — different formats, different machines, no shared view. aiusage pulls it all into one local dashboard with no accounts, no telemetry, and no cloud required.
90
-
91
- - **One dashboard** for tokens, cost, model mix, and tool-call activity
92
- - **Multi-machine sync** via GitHub, S3, or R2 — entirely optional
93
- - **Your data stays local** by default
94
-
95
- ## Supported tools
96
-
97
- | Tool | Status |
98
- |------|--------|
99
- | Claude Code | ✅ |
100
- | Codex | ✅ |
101
- | OpenCode | ✅ |
102
- | Cursor | ✅ |
103
- | Hermes | ✅ |
104
- | Qoder | ✅ |
105
- | OpenClaw | ✅ |
106
-
107
-
108
- ## CLI Reference
109
-
110
- ### `aiusage` (default)
111
-
112
- Print a usage summary to the terminal (same as `aiusage summary`).
113
-
114
- ### `aiusage parse`
115
-
116
- Import newly appended local session data from discovered source paths.
117
-
118
- | Option | Description |
119
- |--------|-------------|
120
- | `--tool <tool>` | Only parse a specific tool: `claude-code`, `codex`, `openclaw`, `opencode`, `hermes`, `qoder`, `cursor` |
121
- | `--progress` | Show real-time progress bar on stderr (TTY only, silent in pipes/CI) |
122
-
123
- ```bash
124
- aiusage parse # Parse all tools
125
- aiusage parse --tool claude-code # Only parse Claude Code logs
126
- aiusage parse --progress # Show progress bar while parsing
127
- ```
128
-
129
- ### `aiusage serve`
130
-
131
- Start the local web dashboard and runtime settings controller.
132
-
133
- | Option | Description | Default |
134
- |--------|-------------|---------|
135
- | `-p, --port <port>` | Port number | `3847` |
136
-
137
- ```bash
138
- aiusage serve # Start on port 3847
139
- aiusage serve -p 8080 # Start on port 8080
140
- ```
141
-
142
- ### `aiusage summary`
143
-
144
- Print a usage summary in the terminal.
145
-
146
- | Option | Description |
147
- |--------|-------------|
148
- | `--device <id>` | Filter by device instance ID |
149
- | `--tool <tool>` | Filter by tool type (`claude-code`, `codex`, `openclaw`, `opencode`, `hermes`, `qoder`, `cursor`) |
150
-
151
- ```bash
152
- aiusage summary # All-time summary
153
- aiusage summary --tool claude-code # Single tool
154
- ```
155
-
156
- ### `aiusage status`
157
-
158
- Show version, device name, DB path, schema version, table/view counts, record count, DB size, and sync status.
159
-
160
- ### `aiusage export`
161
-
162
- Export records as CSV, JSON, or NDJSON.
163
-
164
- | Option | Description | Required |
165
- |--------|-------------|----------|
166
- | `--format <format>` | Output format: `csv`, `json`, `ndjson` | Yes |
167
- | `-o, --output <file>` | Output file path (default: stdout) | No |
168
-
169
- ```bash
170
- aiusage export --format csv # CSV to stdout
171
- aiusage export --format json -o report.json # JSON to file
172
- aiusage export --format ndjson # NDJSON to stdout
173
- ```
174
-
175
- ### `aiusage clean`
176
-
177
- Remove old records from the local database based on age.
178
-
179
- | Option | Description | Default |
180
- |--------|-------------|---------|
181
- | `--before <duration>` | Delete data older than this duration (e.g. `30d`, `180d`) | `180d` |
182
-
183
- ```bash
184
- aiusage clean # Delete records older than 180 days
185
- aiusage clean --before 30d # Delete records older than 30 days
186
- aiusage clean --before 90d --yes # Delete records older than 90 days, skip confirm
187
- ```
188
-
189
- ### `aiusage reset`
190
-
191
- Delete all parsed records, tool calls, synced data, and the parse watermark. Source log files (`~/.claude`, `~/.codex`, etc.) are **not** affected. Use this to re-import everything from scratch.
192
-
193
- | Option | Description |
194
- |--------|-------------|
195
- | `--yes` | Skip confirmation prompt (required to execute) |
196
-
197
- ```bash
198
- aiusage reset --yes # Wipe all data, then run `aiusage parse` to re-import
199
- ```
200
-
201
- ### `aiusage recalc`
202
-
203
- Recalculate costs using the latest pricing data.
204
-
205
- ```bash
206
- aiusage recalc
207
- ```
208
-
209
- ### `aiusage init`
210
-
211
- Configure a sync backend for multi-machine data aggregation.
212
-
213
- | Option | Description |
214
- |--------|-------------|
215
- | `--backend <backend>` | Sync backend: `github`, `s3`, `skip` |
216
- | `--repo <repo>` | GitHub repository (format: `username/repo-name`) |
217
- | `--token <token>` | GitHub Personal Access Token |
218
- | `--bucket <bucket>` | S3 bucket name |
219
- | `--prefix <prefix>` | S3 object prefix (default: `aiusage/`) |
220
- | `--endpoint <endpoint>` | S3 endpoint URL |
221
- | `--region <region>` | S3 region (default: `auto`) |
222
- | `--access-key-id <id>` | S3 access key ID |
223
- | `--secret-access-key <key>` | S3 secret access key |
224
- | `--device <alias>` | Device alias |
225
-
226
- ```bash
227
- aiusage init --backend github --repo user/aiusage-data --token ghp_xxx
228
- aiusage init --backend s3 --bucket my-bucket --endpoint https://xxx.r2.cloudflarestorage.com --access-key-id AKIAxxx --secret-access-key xxx
229
- ```
230
-
231
- ### `aiusage sync`
232
-
233
- Push and pull data with the configured remote backend.
234
-
235
- ```bash
236
- aiusage sync
237
- ```
238
-
239
- ## Web Dashboard
240
-
241
- ```bash
242
- aiusage serve
243
- # Open http://localhost:3847
244
- ```
245
-
246
- `aiusage serve` hosts the following dashboard pages:
247
-
248
- - **Home (`/`)** — live counter homepage. On first load it calls `/api/refresh`, runs one incremental local parse, then loads summary data. After that, it refreshes on the configured dashboard poll interval.
249
- - **Overview (`/overview`)** — totals, cost, active days, and per-tool breakdowns for Today, This Week, This Month, Last 30d, or All Time.
250
- - **Tokens** — token usage trends over time, with breakdown-by-type or combined total view.
251
- - **Cost** — cost trends with by-tool and by-model breakdowns.
252
- - **Models** — model share and distribution.
253
- - **Tool Calls** — tool call frequency and ranking.
254
- - **Projects** — project-level usage rollups.
255
- - **Sessions** — session browsing with filters and pagination.
256
- - **Pricing** — active model pricing reference.
257
- - **Settings** — configure device name, week start day, dashboard poll interval, auto-parse interval, source paths, sync backend, credentials, and local data retention without editing config files manually.
258
- - **Docs** — in-app documentation with CLI reference and feature guides.
259
-
260
- **Settings behavior**
261
-
262
- - **Dashboard Poll Interval** is in milliseconds and only controls the homepage refresh cycle after the initial load.
263
- - **Auto-Parse Interval** is in milliseconds and schedules background `aiusage parse` runs only while `aiusage serve` is running. Set `0` or leave it blank to disable it.
264
- - **Local Data Retention** runs periodic cleanup only while `aiusage serve` is running. Set `0` or leave it blank to keep data forever.
265
- - **Source path** changes take effect on the next parse.
266
- - **Sync backend and credential** changes take effect on the next sync.
267
-
268
- ---
269
-
270
- ## Deployment
271
-
272
- Need multi-machine aggregation or cloud access? Choose your scenario:
273
-
274
- | Scenario | Method | Description |
275
- |----------|--------|-------------|
276
- | Multiple machines, aggregate data | [Multi-Machine Sync](#multi-machine-sync) | Sync via GitHub/S3/R2 |
277
- | Multiple machines + unified dashboard | [Docker Deployment](#docker-deployment) | Run a 24/7 dashboard from synced data |
278
-
279
- For single-machine usage, Quick Start is enough.
280
-
281
- ### Multi-Machine Sync
282
-
283
- Use this to aggregate token usage from multiple machines into one dashboard. Works with Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.
284
-
285
- **Architecture:**
286
-
287
- ```
288
- Machine A ──┐
289
- Machine B ──┼──▶ GitHub / S3 / R2 (shared storage) ──▶ Any machine: aiusage summary / serve
290
- Machine C ──┘
291
- ```
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/@juliantanx/aiusage"><img src="https://img.shields.io/npm/v/@juliantanx/aiusage" alt="npm version" /></a>
12
+ <a href="https://www.npmjs.com/package/@juliantanx/aiusage"><img src="https://img.shields.io/npm/dm/@juliantanx/aiusage" alt="npm downloads" /></a>
13
+ <a href="https://github.com/juliantanx/aiusage/actions/workflows/test.yml"><img src="https://github.com/juliantanx/aiusage/actions/workflows/test.yml/badge.svg" alt="CI" /></a>
14
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
15
+ </p>
292
16
 
293
- **Step 1 — Choose a sync backend**
17
+ <p align="center">
18
+ <strong><a href="https://aiusage.jtanx.com">Website</a></strong> ·
19
+ <strong><a href="https://aiusage.jtanx.com/docs">Docs</a></strong> ·
20
+ <strong><a href="https://aiusage.jtanx.com/leaderboard">Leaderboard</a></strong> ·
21
+ English | <a href="https://github.com/juliantanx/aiusage/blob/main/README_zh.md">中文</a>
22
+ </p>
294
23
 
295
- **Option A: GitHub (recommended)**
24
+ Track tokens, cost, sessions, models, projects, tool calls, and quota pressure across **22 AI coding tools** in one local dashboard. Local use needs no account, sends no telemetry, and does not require cloud sync.
296
25
 
297
- 1. Create a **private** repository on GitHub (for example `aiusage-data`)
298
- 2. Generate a [Personal Access Token](https://github.com/settings/tokens) with `repo` scope
26
+ <p align="center">
27
+ <img src="https://cdn.jsdelivr.net/gh/juliantanx/aiusage@b179e5a37c92e7040a07b84a7b2048821d120aed/packages/site/static/screenshots/aiusage-demo.gif" alt="AIUsage dashboard demo" width="92%" />
28
+ </p>
299
29
 
300
- **Option B: AWS S3 / Cloudflare R2**
30
+ ## Highlights
301
31
 
302
- 1. Create an S3 or R2 bucket
303
- 2. Create an IAM user or role with read/write permissions
304
- 3. Note the access key ID, secret access key, and endpoint
32
+ - **One local dashboard** for tokens, cost, sessions, models, projects, tool calls, and quotas.
33
+ - **Broad parser support** for Claude Code, Codex, OpenCode, Cursor, Copilot, Gemini CLI, and more.
34
+ - **Optional sync** through official cloud sync, GitHub, S3, R2, or MinIO.
35
+ - **Optional public leaderboard** with signed aggregate uploads only.
36
+ - **Desktop widget** for a tray/menu-bar glance at recent usage.
37
+ - **Private by default**: local parsing and local dashboards do not upload your prompts, completions, source code, or file paths.
305
38
 
306
- **Step 2 — Install and configure on each machine**
39
+ ## Quick Start
307
40
 
308
- On every machine that uses Claude Code, Codex, OpenClaw, OpenCode, Hermes, or Qoder:
41
+ **Requirements:** Node.js 20+ on macOS, Linux, or Windows.
309
42
 
310
43
  ```bash
311
- # Install aiusage CLI
312
44
  npm install -g @juliantanx/aiusage
313
-
314
- # Configure sync backend — GitHub
315
- aiusage init --backend github \
316
- --repo <user>/aiusage-data \
317
- --token ghp_xxxxxxxxxxxxxxxxxxxx
318
-
319
- # OR configure sync backend — S3 / R2
320
- aiusage init --backend s3 \
321
- --bucket my-aiusage-bucket \
322
- --prefix aiusage/ \
323
- --endpoint https://<account-id>.r2.cloudflarestorage.com \
324
- --region auto \
325
- --access-key-id AKIAxxxxxxxxxxxx \
326
- --secret-access-key xxxxxxxxxxxxxxxxxxxxxxxxxx
45
+ aiusage serve
327
46
  ```
328
47
 
329
- **Step 3 Parse and sync on each machine**
330
-
331
- ```bash
332
- aiusage parse
333
- aiusage sync
334
- ```
48
+ Open `http://localhost:3847` to use the dashboard. `serve` parses once on startup and then serves the local web UI.
335
49
 
336
- **Step 4 — View aggregated data on any machine**
50
+ Prefer pnpm:
337
51
 
338
52
  ```bash
339
- aiusage sync
340
- aiusage summary
341
- aiusage serve
53
+ pnpm add -g @juliantanx/aiusage
342
54
  ```
343
55
 
344
- **Automate (recommended)**
56
+ Use Docker:
345
57
 
346
58
  ```bash
347
- # Linux/macOS
348
- crontab -e
349
- # Add:
350
- */30 * * * * /usr/local/bin/aiusage parse && /usr/local/bin/aiusage sync >> ~/.aiusage/cron.log 2>&1
351
-
352
- # Windows
353
- schtasks /create /tn "AiusageSync" /tr "aiusage parse && aiusage sync" /sc minute /mo 30
59
+ docker run -d \
60
+ -p 3847:3847 \
61
+ -v ~/.aiusage:/root/.aiusage \
62
+ juliantanx/aiusage
354
63
  ```
355
64
 
356
- **How sync works**
357
-
358
- - Each machine has a unique `deviceInstanceId` generated on first run.
359
- - Each device writes to its own daily file (`{deviceInstanceId}/YYYY/MM/DD.ndjson`) in the remote backend.
360
- - Pull reads other devices' files into the local `synced_records` table; upload writes only this device's files.
361
- - Device-partitioned files avoid write conflicts, so no locking is needed.
362
- - Sync frequency comes from your external scheduler or manual runs; aiusage does not include a built-in sync daemon.
363
- - Session IDs are anonymized via `sha256(device + sessionId)`.
65
+ Docker persists AIUsage data with the `~/.aiusage` mount. To parse AI tool logs from the host, also mount each source log directory and configure the matching `AIUSAGE_*_PATH` variable. See the [Docker docs](https://aiusage.jtanx.com/docs#docker).
364
66
 
365
- ---
67
+ ## Common Commands
366
68
 
367
- ### Docker Deployment
69
+ | Command | What it does |
70
+ |---|---|
71
+ | `aiusage` / `aiusage summary` | Print a terminal summary |
72
+ | `aiusage parse` | Parse supported local AI tool logs |
73
+ | `aiusage serve` | Start the local dashboard on port `3847` |
74
+ | `aiusage status` | Show data source and local database status |
75
+ | `aiusage export --range month` | Export usage data |
76
+ | `aiusage init` | Configure optional sync |
77
+ | `aiusage sync` | Sync with the configured backend |
78
+ | `aiusage widget` | Launch the desktop tray widget |
79
+ | `aiusage leaderboard` | View public leaderboard rankings |
80
+ | `aiusage login` / `aiusage upload` | Authorize this device and upload aggregate leaderboard data |
81
+ | `aiusage pm2-start` | Run dashboard and widget as PM2 background services |
368
82
 
369
- Run the pre-built image on a server for a 24/7 dashboard. The container does **not** run any AI coding tools itself — it serves the web dashboard, can run the same runtime settings controller as `aiusage serve`, and can pull synced data from GitHub, S3, or R2.
83
+ Full CLI reference: [aiusage.jtanx.com/docs#cli-reference](https://aiusage.jtanx.com/docs#cli-reference).
370
84
 
371
- **Architecture:**
85
+ ## Supported Tools
372
86
 
373
- ```
374
- Machine A ──┐ ┌── Browser: https://aiusage.your-domain.com
375
- Machine B ──┼──▶ GitHub / S3 / R2 ──▶ Cloud Server (Docker)
376
- Machine C ──┘ └── port 3847
377
- ```
87
+ | | | | | |
88
+ |---|---|---|---|---|
89
+ | `Claude Code` | `Codex` | `OpenCode` | `Cursor` | `Hermes` |
90
+ | `Qoder` | `OpenClaw` | `KiloCode` | `Copilot` | `Gemini CLI` |
91
+ | `Kimi Code` | `CodeBuddy` | `Kiro` | `Grok Build` | `Antigravity` |
92
+ | `Roo Code` | `Zed` | `Goose` | `oh-my-pi` | `pi` |
93
+ | `Craft` | `Droid` | | | |
378
94
 
379
- **How data flows**
95
+ Default paths and environment variable overrides are documented in [Data Sources](https://aiusage.jtanx.com/docs#settings-sources) and [Source Env Vars](https://aiusage.jtanx.com/docs#settings-env).
380
96
 
381
- 1. Each dev machine runs `aiusage parse && aiusage sync` to upload local usage data.
382
- 2. The Docker container runs `aiusage sync` to pull that data into its local SQLite database.
383
- 3. The web dashboard reads from the local database and displays aggregated stats.
97
+ ## Dashboard Password
384
98
 
385
- **Data storage in Docker**
99
+ The local dashboard is open on localhost by default. Set `AIUSAGE_DASHBOARD_PASSWORD` to protect dashboard APIs.
386
100
 
387
- | Item | Container path | Description |
388
- |------|---------------|-------------|
389
- | Database | `/root/.aiusage/cache.db` | SQLite database with aggregated usage data |
390
- | Config | `/root/.aiusage/config.json` | Sync backend config, runtime settings, and credentials |
391
- | State | `/root/.aiusage/state.json` | Consent and sync runtime state |
392
- | Watermarks | `/root/.aiusage/watermark.json` | Incremental parse cursors |
101
+ | Shell | Command |
102
+ |---|---|
103
+ | macOS / Linux | `AIUSAGE_DASHBOARD_PASSWORD="change-me" aiusage serve` |
104
+ | Windows PowerShell | `$env:AIUSAGE_DASHBOARD_PASSWORD="change-me"; aiusage serve` |
105
+ | Windows CMD | `set AIUSAGE_DASHBOARD_PASSWORD=change-me && aiusage serve` |
393
106
 
394
- All data lives under `/root/.aiusage`, which is declared as a `VOLUME`. You **must** mount this volume to persist data across container restarts.
107
+ For PM2 background services, pass the same variable when starting `aiusage pm2-start`, and use `pm2 restart aiusage-server --update-env` after changing it. Details: [Dashboard Password](https://aiusage.jtanx.com/docs#dashboard-password) and [PM2](https://aiusage.jtanx.com/docs#pm2).
395
108
 
396
- **Step 1 — Pull image and run**
109
+ ## Privacy and Data
397
110
 
398
- ```bash
399
- # Pull image
400
- docker pull juliantanx/aiusage
111
+ AIUsage is designed to be local-first.
401
112
 
402
- # Run container (mount volume for data persistence)
403
- docker run -d \
404
- --name aiusage \
405
- -p 3847:3847 \
406
- -v aiusage-data:/root/.aiusage \
407
- juliantanx/aiusage
113
+ - Local parsing reads tool logs and stores parsed usage in `~/.aiusage/cache.db`.
114
+ - Local dashboard mode does not require an account and does not send telemetry.
115
+ - Optional sync is user-configured and can use official cloud sync, GitHub, S3, R2, or MinIO.
116
+ - Optional leaderboard uploads contain aggregate token totals for ranking periods. They do not include prompts, completions, source code, file paths, or local cost estimates.
117
+ - Cost is an estimate based on pricing metadata and can change when pricing is refreshed or recalculated.
118
+ - Historical totals depend on whether each AI tool still retains its source logs or local databases.
408
119
 
409
- # Configure sync backend
410
- docker exec -it aiusage aiusage init \
411
- --backend github \
412
- --repo <user>/aiusage-data \
413
- --token ghp_xxxxxxxxxxxxxxxxxxxx
120
+ Security issues should be reported privately when possible. See [SECURITY.md](./SECURITY.md).
414
121
 
415
- # Initial data pull
416
- docker exec -it aiusage aiusage sync
417
- ```
418
-
419
- > Without the `-v` flag, data is lost when the container is removed.
420
-
421
- **Step 2 — Scheduled sync**
122
+ ## Sync and Leaderboard
422
123
 
423
- ```bash
424
- # Install cron in container and create scheduled task
425
- docker exec -it aiusage bash -c "apt-get update && apt-get install -y cron"
426
- docker exec -it aiusage bash -c \
427
- 'echo "*/30 * * * * aiusage sync >> /root/.aiusage/cron.log 2>&1" | crontab -'
428
- docker restart aiusage
429
- ```
124
+ Sync and leaderboard are independent optional features.
430
125
 
431
- > Note: `parse` is not needed here unless you also mount local AI session logs into the container. In the standard deployment, only `sync` is needed to pull data from the remote backend.
126
+ - **Sync** keeps your own devices aligned through official cloud sync, GitHub, S3, R2, or MinIO. Configure it with `aiusage init`, then run `aiusage sync`.
127
+ - **Leaderboard** is public ranking for users who explicitly upload aggregate totals. Authorize a device with `aiusage login`, then run `aiusage upload`.
128
+ - Anonymous mode is available in [site settings](https://aiusage.jtanx.com/settings) for leaderboard participation.
432
129
 
433
- **Step 3 Access**
130
+ The official site handles accounts, OAuth login, profile settings, authorized devices, upload review status, and admin moderation. The CLI handles local parsing, local dashboards, sync, terminal summaries, and signed uploads.
434
131
 
435
- Open `http://<server-ip>:3847`.
132
+ ## Desktop Widget
436
133
 
437
- For HTTPS with a custom domain:
134
+ Install the optional tray/menu-bar widget:
438
135
 
439
136
  ```bash
440
- # Caddy (auto HTTPS, recommended)
441
- caddy reverse-proxy --from aiusage.your-domain.com --to localhost:3847
442
-
443
- # Or Nginx
444
- server {
445
- listen 80;
446
- server_name aiusage.your-domain.com;
447
- location / {
448
- proxy_pass http://127.0.0.1:3847;
449
- proxy_set_header Host $host;
450
- proxy_set_header X-Real-IP $remote_addr;
451
- }
452
- }
137
+ npm install -g @juliantanx/aiusage-widget
138
+ aiusage-widget
453
139
  ```
454
140
 
455
- **Build image yourself (optional)**
141
+ The widget reads the same local AIUsage database and can open the full dashboard from its tray menu. See [Widget docs](https://aiusage.jtanx.com/docs#widget).
456
142
 
457
- A `Dockerfile` is included in the project root:
143
+ ## Development
458
144
 
459
145
  ```bash
460
- docker build -t aiusage .
461
- ```
462
-
463
- ---
464
-
465
- ## Data Storage
466
-
467
- | Item | Path |
468
- |------|------|
469
- | Local database | `~/.aiusage/cache.db` |
470
- | Config | `~/.aiusage/config.json` |
471
- | Sync state | `~/.aiusage/state.json` |
472
- | Parse watermarks | `~/.aiusage/watermark.json` |
473
-
474
- ### Default Source Paths
475
-
476
- `aiusage parse` auto-discovers session logs from the following default locations:
477
-
478
- | Tool | macOS | Linux | Windows |
479
- |------|-------|-------|---------|
480
- | Claude Code | `~/.claude/projects/` | `~/.claude/projects/` | `%USERPROFILE%\.claude\projects\` |
481
- | Codex | `~/.codex/sessions/` | `~/.codex/sessions/` | `%USERPROFILE%\.codex\sessions\` |
482
- | OpenClaw | `~/.openclaw/agents/*/sessions/` | `~/.openclaw/agents/*/sessions/` | `%USERPROFILE%\.openclaw\agents\*\sessions\` |
483
- | OpenCode | `~/Library/Application Support/opencode/opencode.db` | `~/.local/share/opencode/opencode.db` | `%APPDATA%\opencode\opencode.db` |
484
- | Hermes | `~/.hermes/state.db` | `~/.hermes/state.db` | `%USERPROFILE%\.hermes\state.db` |
485
- | Qoder (sessions) | `~/.qoder/logs/sessions/` | `~/.qoder/logs/sessions/` plus WSL-mounted Windows user homes | `%USERPROFILE%\.qoder\logs\sessions\` |
486
- | Qoder (SQLite) | `~/Library/Application Support/Qoder/SharedClientCache/cache/db/local.db` | `~/.local/share/Qoder/SharedClientCache/cache/db/local.db` | `%LOCALAPPDATA%\Qoder\SharedClientCache\cache\db\local.db` |
487
- | Cursor | `~/Library/Application Support/Cursor/User/globalStorage/state.vscdb` | `~/.config/Cursor/User/globalStorage/state.vscdb` | `%APPDATA%\Cursor\User\globalStorage\state.vscdb` |
488
-
489
- Discovery behavior:
490
-
491
- - **Claude Code** — recursively scans `~/.claude/projects/**` for `.jsonl` files, including nested subagent logs.
492
- - **Codex** — recursively scans `~/.codex/sessions/**` for `.jsonl` files.
493
- - **OpenClaw** — scans each agent's `sessions/` directory under `~/.openclaw/agents/*/sessions/` and skips checkpoint files.
494
- - **OpenCode** — reads the SQLite database file directly instead of `.jsonl` logs.
495
- - **Hermes** — reads the SQLite database file (`state.db`) directly. Sessions without a recorded end time are still imported if they have token data (e.g. sessions from a force-quit).
496
- - **Qoder (sessions)** — recursively scans structured session segment logs (`logs/sessions/**/segments/*.jsonl`) and imports `model.response.completed` token events. On WSL, aiusage also checks mounted Windows user homes such as `/mnt/c/Users/<user>`, `/mnt/d/Users/<user>`, and `/mnt/e/Users/<user>` for the same Qoder session-log layout.
497
- - **Qoder (SQLite)** — reads the `local.db` SQLite database directly (`SharedClientCache/cache/db/local.db`) and imports assistant messages from the `chat_message` table, joined with `chat_record` for model information. This is the primary source on macOS and is tried alongside the sessions directory.
498
- - **Cursor** — reads Cursor's `state.vscdb` SQLite database directly and imports composer conversations with token usage data.
499
-
500
- > On Linux, OpenCode respects `$XDG_DATA_HOME` if set.
501
-
502
- Qoder Desktop also creates installation files under `Program Files`, UI/cache data under `AppData/Roaming/Qoder` and `AppData/Local/.qoder`, and transcripts under `%USERPROFILE%\.qoder\projects` or `%USERPROFILE%\.qoder\cache`. These are not imported as token records: desktop `Context usage update` log lines are repeated context-window snapshots, and transcripts/conversation-history files do not contain per-request token usage.
503
-
504
- ### Custom Source Paths
505
-
506
- If you installed a tool to a non-default location, override the paths in the **Settings** page of the web dashboard (`http://localhost:3847/settings` → Sources section), or edit `~/.aiusage/config.json` directly:
507
-
508
- ```json
509
- {
510
- "sources": {
511
- "claude-code": "/custom/path/.claude/projects",
512
- "codex": "/custom/path/.codex/sessions",
513
- "openclaw": "/custom/sessions-dir",
514
- "opencode": "/custom/path/opencode.db",
515
- "hermes": "/custom/path/.hermes/state.db",
516
- "qoder": "/custom/path/.qoder/logs/sessions",
517
- "qoder-db": "/custom/path/local.db",
518
- "cursor": "/custom/path/state.vscdb"
519
- }
520
- }
521
- ```
522
-
523
- Only the paths you specify are overridden; unspecified tools fall back to their defaults. `qoder` points to the session logs directory; `qoder-db` points directly to the `local.db` SQLite file.
524
-
525
- ## Database Visualization
526
-
527
- The local database is a standard SQLite file, so you can open it directly in DBeaver, TablePlus, DataGrip, DB Browser for SQLite, or any similar tool.
528
-
529
- ```bash
530
- aiusage status
531
- # Shows the exact DB Path, schema version, and object counts
532
- ```
533
-
534
- - Open `~/.aiusage/cache.db` as a SQLite database.
535
- - Prefer read-only mode in your database tool. `aiusage` writes to the same file and uses WAL mode.
536
- - If your tool asks about sidecar files, keep `cache.db-wal` and `cache.db-shm` alongside the main database file.
537
- - Start with the read-only views:
538
- - `v_usage_records`: one row per usage record with normalized timestamp and token totals
539
- - `v_tool_calls`: tool call rows joined with their parent usage record
540
- - `v_sessions`: session-level aggregates for pivoting and charting
541
- - Raw internal tables remain available for advanced inspection:
542
- - `records`
543
- - `tool_calls`
544
- - `synced_records`
545
- - `sync_tombstones`
546
-
547
- ## Tech Stack
548
-
549
- - **Runtime:** Node.js, TypeScript
550
- - **Database:** better-sqlite3 (local, WAL mode)
551
- - **CLI:** Commander.js
552
- - **Web:** SvelteKit + adapter-static
553
- - **Build:** tsup (core/cli), Vite (web)
554
- - **Sync:** GitHub API, AWS S3 / Cloudflare R2
555
-
556
- ## Project Structure
557
-
558
- ```text
559
- packages/
560
- core/ - Shared types, database schema, pricing data
561
- cli/ - CLI tool for parsing logs, querying data, cloud sync
562
- web/ - SvelteKit web dashboard (SPA)
146
+ git clone https://github.com/juliantanx/aiusage.git
147
+ cd aiusage
148
+ pnpm install
149
+ pnpm build
150
+ pnpm test
151
+ pnpm dev
563
152
  ```
564
153
 
565
- ## FAQ
566
-
567
- ### Does aiusage upload my data?
568
-
569
- No. aiusage is local-first. Your usage data stays on your machine unless you explicitly configure a sync backend.
154
+ Project layout:
570
155
 
571
- ### Can I use aiusage across multiple machines?
156
+ | Path | Purpose |
157
+ |---|---|
158
+ | `packages/core` | Shared types, schema, pricing, and utilities |
159
+ | `packages/cli` | Published CLI, parsers, local API server, sync, PM2 helpers |
160
+ | `packages/web` | Local dashboard UI bundled into the CLI |
161
+ | `packages/widget` | Electron tray/menu-bar widget |
162
+ | `packages/site` | Official website, docs, accounts, uploads, leaderboard |
572
163
 
573
- Yes. You can sync usage data through GitHub, S3, or R2 and then view the combined result from any configured machine or Docker deployment.
164
+ Contributions are welcome. Read [CONTRIBUTING.md](./CONTRIBUTING.md), use the issue templates, and run `pnpm test` before opening a PR.
574
165
 
575
- ### Does aiusage run a background parser automatically?
166
+ ## Documentation
576
167
 
577
- No. By default, you run `aiusage parse` manually. You can automate parsing and syncing with cron, Task Scheduler, or your own scheduler.
168
+ - [Full docs](https://aiusage.jtanx.com/docs)
169
+ - [CLI reference](https://aiusage.jtanx.com/docs#cli-reference)
170
+ - [Docker deployment](https://aiusage.jtanx.com/docs#docker)
171
+ - [Sync setup](https://aiusage.jtanx.com/docs#sync)
172
+ - [Widget](https://aiusage.jtanx.com/docs#widget)
173
+ - [Changelog](./CHANGELOG.md)
174
+ - [Security policy](./SECURITY.md)
578
175
 
579
- ### Which assistants are supported?
176
+ ## Community
580
177
 
581
- aiusage currently supports Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.
178
+ - Bugs: [GitHub Issues](https://github.com/juliantanx/aiusage/issues/new?template=bug_report.md)
179
+ - Feature requests: [GitHub Issues](https://github.com/juliantanx/aiusage/issues/new?template=feature_request.md)
180
+ - Questions: [GitHub Discussions](https://github.com/juliantanx/aiusage/discussions)
582
181
 
583
- ### Can I inspect the raw database myself?
584
-
585
- Yes. aiusage stores data in a local SQLite database, and the README already documents how to open it in tools like DBeaver, TablePlus, DataGrip, or DB Browser for SQLite.
586
-
587
- ## Friends
588
-
589
- [**linux.do**](https://linux.do/) — Thanks to the linux.do community for their support and inspiration during the development of this project.
182
+ [**linux.do**](https://linux.do/) - thanks to the linux.do community for support and inspiration during the development of this project.
590
183
 
591
184
  ## Star History
592
185
 
593
186
  <a href="https://www.star-history.com/?repos=juliantanx%2Faiusage&type=date&logscale=&legend=top-left">
594
187
  <picture>
595
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&theme=dark&legend=top-left&t=20260528" />
596
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260528" />
597
- <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260528" />
188
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&theme=dark&logscale&legend=top-left" />
189
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&logscale&legend=top-left" />
190
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&logscale&legend=top-left" />
598
191
  </picture>
599
192
  </a>
600
193
 
601
- ## Contributing
602
-
603
- Contributions are welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get started.
604
-
605
194
  ## License
606
195
 
607
196
  [MIT](./LICENSE)