@juliantanx/aiusage 1.3.4 → 1.4.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.
- package/README.md +22 -558
- package/dist/index.js +3744 -1943
- package/dist/web/_app/immutable/assets/0.C3RIkHY2.css +1 -0
- package/dist/web/_app/immutable/assets/11.D51Gzh6j.css +1 -0
- package/dist/web/_app/immutable/assets/4.CUknm1Jh.css +1 -0
- package/dist/web/_app/immutable/assets/6.BETPk561.css +1 -0
- package/dist/web/_app/immutable/assets/_layout.BqRkZ3UP.css +1 -0
- package/dist/web/_app/immutable/assets/_page.BETPk561.css +1 -0
- package/dist/web/_app/immutable/assets/_page.CQBzp_Oe.css +1 -0
- package/dist/web/_app/immutable/assets/_page.CUknm1Jh.css +1 -0
- package/dist/web/_app/immutable/chunks/ToolSelector.CCE1hHr0.js +2 -0
- package/dist/web/_app/immutable/chunks/api.CTjBjPiU.js +1 -0
- package/dist/web/_app/immutable/chunks/entry.BDsSAg1a.js +3 -0
- package/dist/web/_app/immutable/chunks/{index.B0Aytz_K.js → index.BXQEgizy.js} +1 -1
- package/dist/web/_app/immutable/chunks/{index.CPsgU-fv.js → index.CNvYz5e_.js} +1 -1
- package/dist/web/_app/immutable/chunks/{scheduler.DFD7qxcZ.js → scheduler.DeaWU70L.js} +1 -1
- package/dist/web/_app/immutable/chunks/{stores.DIJRlQaL.js → stores.BYIFXXy3.js} +1 -1
- package/dist/web/_app/immutable/chunks/stores.mBipGgjw.js +1 -0
- package/dist/web/_app/immutable/entry/{app.C3JWF8LV.js → app.CCbAFnKJ.js} +2 -2
- package/dist/web/_app/immutable/entry/start.BDGHATsW.js +1 -0
- package/dist/web/_app/immutable/nodes/0.vOgxhWzP.js +1 -0
- package/dist/web/_app/immutable/nodes/{1.ClCXLnt8.js → 1.C4vnvuzM.js} +1 -1
- package/dist/web/_app/immutable/nodes/{10.a_45vAk_.js → 10.BejenNwL.js} +1 -1
- package/dist/web/_app/immutable/nodes/11.Dx1YcRkP.js +1 -0
- package/dist/web/_app/immutable/nodes/{12.DoQ9E1LV.js → 12.C9dQuDmx.js} +1 -1
- package/dist/web/_app/immutable/nodes/13.VP7fU2h5.js +1 -0
- package/dist/web/_app/immutable/nodes/{2.BB8OyOCP.js → 2.DniTC2eC.js} +1 -1
- package/dist/web/_app/immutable/nodes/{3.Cfms9ru5.js → 3.BY0PLmXV.js} +1 -1
- package/dist/web/_app/immutable/nodes/4.BUb_3Atw.js +1 -0
- package/dist/web/_app/immutable/nodes/{5.BvbSC3f6.js → 5.DJ0O-s5e.js} +1 -1
- package/dist/web/_app/immutable/nodes/6.nquf-x9G.js +9 -0
- package/dist/web/_app/immutable/nodes/{7.Civ32duh.js → 7.BDm05vE_.js} +1 -1
- package/dist/web/_app/immutable/nodes/{8.TXFmgrFA.js → 8.mB-sVW7r.js} +1 -1
- package/dist/web/_app/immutable/nodes/{9.B9_1-2xn.js → 9.8PYvwJik.js} +1 -1
- package/dist/web/_app/version.json +1 -1
- package/dist/web/index.html +9 -9
- package/package.json +2 -2
- package/dist/web/_app/immutable/assets/0.bPTGJZag.css +0 -1
- package/dist/web/_app/immutable/assets/11.DoWxheGb.css +0 -1
- package/dist/web/_app/immutable/assets/4.D4N7n6x9.css +0 -1
- package/dist/web/_app/immutable/assets/6.CcFk1fVK.css +0 -1
- package/dist/web/_app/immutable/assets/_layout.QS8Tu4KK.css +0 -1
- package/dist/web/_app/immutable/assets/_page.CGsCDBRD.css +0 -1
- package/dist/web/_app/immutable/assets/_page.CcFk1fVK.css +0 -1
- package/dist/web/_app/immutable/assets/_page.D4N7n6x9.css +0 -1
- package/dist/web/_app/immutable/chunks/ToolSelector.D-ihlQCZ.js +0 -2
- package/dist/web/_app/immutable/chunks/api.BR248OCH.js +0 -1
- package/dist/web/_app/immutable/chunks/entry.Bw49Judx.js +0 -3
- package/dist/web/_app/immutable/chunks/stores.B1g8D8DV.js +0 -1
- package/dist/web/_app/immutable/entry/start.DJaQZyhE.js +0 -1
- package/dist/web/_app/immutable/nodes/0.BGBMbwBp.js +0 -1
- package/dist/web/_app/immutable/nodes/11.Uz-0jVL7.js +0 -1
- package/dist/web/_app/immutable/nodes/13.6lDoUYy7.js +0 -1
- package/dist/web/_app/immutable/nodes/4.BRcdKGbJ.js +0 -1
- package/dist/web/_app/immutable/nodes/6.B4H7Hfou.js +0 -9
package/README.md
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
# aiusage — AI Coding Assistant Usage Tracker
|
|
2
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
3
|
[](https://www.npmjs.com/package/@juliantanx/aiusage)
|
|
8
4
|
[](https://github.com/juliantanx/aiusage/actions/workflows/test.yml)
|
|
9
5
|
[](https://opensource.org/licenses/MIT)
|
|
10
|
-
[](https://nodejs.org/)
|
|
11
|
-
[](https://aiusage.jtanx.com)
|
|
12
6
|
|
|
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
|
-
```
|
|
7
|
+
**[aiusage.jtanx.com](https://aiusage.jtanx.com)** · English | [中文](https://github.com/juliantanx/aiusage/blob/main/README_zh.md)
|
|
24
8
|
|
|
25
|
-
|
|
9
|
+
Track token usage, cost, and sessions across **22 AI coding tools** in one local dashboard. No accounts. No telemetry. No cloud required.
|
|
26
10
|
|
|
27
11
|
<p align="center">
|
|
28
12
|
<img src="https://raw.githubusercontent.com/juliantanx/aiusage/a527444cf87a9c1e92f1440282ed4e94f744b910/packages/site/static/screenshots/dashboard-home.png" alt="aiusage dashboard home" width="32%" />
|
|
@@ -30,559 +14,39 @@ Open `http://localhost:3847` to explore the dashboard.
|
|
|
30
14
|
<img src="https://raw.githubusercontent.com/juliantanx/aiusage/a527444cf87a9c1e92f1440282ed4e94f744b910/packages/site/static/screenshots/sessions.png" alt="aiusage sessions dashboard" width="32%" />
|
|
31
15
|
</p>
|
|
32
16
|
|
|
33
|
-
|
|
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
|
-
```
|
|
17
|
+
## Quick Start
|
|
70
18
|
|
|
71
|
-
|
|
19
|
+
**Prerequisites:** Node.js 20+
|
|
72
20
|
|
|
73
21
|
```bash
|
|
74
|
-
|
|
22
|
+
npm install -g @juliantanx/aiusage
|
|
23
|
+
aiusage parse
|
|
24
|
+
aiusage serve
|
|
75
25
|
```
|
|
76
26
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
pnpm rebuild:sqlite
|
|
81
|
-
```
|
|
27
|
+
Open `http://localhost:3847` to explore the dashboard.
|
|
82
28
|
|
|
83
|
-
|
|
29
|
+
## Supported Tools
|
|
84
30
|
|
|
85
|
-
|
|
31
|
+
| | | | | |
|
|
32
|
+
|---|---|---|---|---|
|
|
33
|
+
| `Claude Code` | `Codex` | `OpenCode` | `Cursor` | `Hermes` |
|
|
34
|
+
| `Qoder` | `OpenClaw` | `KiloCode` | `Copilot` | `Gemini CLI` |
|
|
35
|
+
| `Kimi Code` | `CodeBuddy` | `Kiro` | `Grok Build` | `Antigravity` |
|
|
36
|
+
| `Roo Code` | `Zed` | `Goose` | `oh-my-pi` | `pi` |
|
|
37
|
+
| `Craft` | `Droid` | | | |
|
|
86
38
|
|
|
87
39
|
## Why aiusage
|
|
88
40
|
|
|
89
|
-
Your AI coding tools each log usage separately — different formats, different machines, no shared view. aiusage pulls it all into one local dashboard
|
|
41
|
+
Your AI coding tools each log usage separately — different formats, different machines, no shared view. aiusage pulls it all into one local dashboard:
|
|
90
42
|
|
|
91
43
|
- **One dashboard** for tokens, cost, model mix, and tool-call activity
|
|
92
44
|
- **Multi-machine sync** via GitHub, S3, or R2 — entirely optional
|
|
93
45
|
- **Your data stays local** by default
|
|
94
46
|
|
|
95
|
-
##
|
|
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
|
-
```
|
|
292
|
-
|
|
293
|
-
**Step 1 — Choose a sync backend**
|
|
294
|
-
|
|
295
|
-
**Option A: GitHub (recommended)**
|
|
296
|
-
|
|
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
|
|
299
|
-
|
|
300
|
-
**Option B: AWS S3 / Cloudflare R2**
|
|
301
|
-
|
|
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
|
|
305
|
-
|
|
306
|
-
**Step 2 — Install and configure on each machine**
|
|
307
|
-
|
|
308
|
-
On every machine that uses Claude Code, Codex, OpenClaw, OpenCode, Hermes, or Qoder:
|
|
309
|
-
|
|
310
|
-
```bash
|
|
311
|
-
# Install aiusage CLI
|
|
312
|
-
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
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
**Step 3 — Parse and sync on each machine**
|
|
330
|
-
|
|
331
|
-
```bash
|
|
332
|
-
aiusage parse
|
|
333
|
-
aiusage sync
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
**Step 4 — View aggregated data on any machine**
|
|
337
|
-
|
|
338
|
-
```bash
|
|
339
|
-
aiusage sync
|
|
340
|
-
aiusage summary
|
|
341
|
-
aiusage serve
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
**Automate (recommended)**
|
|
345
|
-
|
|
346
|
-
```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
|
|
354
|
-
```
|
|
355
|
-
|
|
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)`.
|
|
364
|
-
|
|
365
|
-
---
|
|
366
|
-
|
|
367
|
-
### Docker Deployment
|
|
368
|
-
|
|
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.
|
|
370
|
-
|
|
371
|
-
**Architecture:**
|
|
372
|
-
|
|
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
|
-
```
|
|
378
|
-
|
|
379
|
-
**How data flows**
|
|
380
|
-
|
|
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.
|
|
384
|
-
|
|
385
|
-
**Data storage in Docker**
|
|
386
|
-
|
|
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 |
|
|
393
|
-
|
|
394
|
-
All data lives under `/root/.aiusage`, which is declared as a `VOLUME`. You **must** mount this volume to persist data across container restarts.
|
|
395
|
-
|
|
396
|
-
**Step 1 — Pull image and run**
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
# Pull image
|
|
400
|
-
docker pull juliantanx/aiusage
|
|
401
|
-
|
|
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
|
|
408
|
-
|
|
409
|
-
# Configure sync backend
|
|
410
|
-
docker exec -it aiusage aiusage init \
|
|
411
|
-
--backend github \
|
|
412
|
-
--repo <user>/aiusage-data \
|
|
413
|
-
--token ghp_xxxxxxxxxxxxxxxxxxxx
|
|
414
|
-
|
|
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**
|
|
422
|
-
|
|
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
|
-
```
|
|
430
|
-
|
|
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.
|
|
432
|
-
|
|
433
|
-
**Step 3 — Access**
|
|
434
|
-
|
|
435
|
-
Open `http://<server-ip>:3847`.
|
|
436
|
-
|
|
437
|
-
For HTTPS with a custom domain:
|
|
438
|
-
|
|
439
|
-
```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
|
-
}
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
**Build image yourself (optional)**
|
|
456
|
-
|
|
457
|
-
A `Dockerfile` is included in the project root:
|
|
458
|
-
|
|
459
|
-
```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)
|
|
563
|
-
```
|
|
564
|
-
|
|
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.
|
|
570
|
-
|
|
571
|
-
### Can I use aiusage across multiple machines?
|
|
572
|
-
|
|
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.
|
|
574
|
-
|
|
575
|
-
### Does aiusage run a background parser automatically?
|
|
576
|
-
|
|
577
|
-
No. By default, you run `aiusage parse` manually. You can automate parsing and syncing with cron, Task Scheduler, or your own scheduler.
|
|
578
|
-
|
|
579
|
-
### Which assistants are supported?
|
|
580
|
-
|
|
581
|
-
aiusage currently supports Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.
|
|
582
|
-
|
|
583
|
-
### Can I inspect the raw database myself?
|
|
47
|
+
## Documentation
|
|
584
48
|
|
|
585
|
-
|
|
49
|
+
Full documentation — CLI reference, Docker deployment, sync setup, desktop widget, and more — is available on the **[Docs page](https://aiusage.jtanx.com/docs)**.
|
|
586
50
|
|
|
587
51
|
## Friends
|
|
588
52
|
|
|
@@ -592,9 +56,9 @@ Yes. aiusage stores data in a local SQLite database, and the README already docu
|
|
|
592
56
|
|
|
593
57
|
<a href="https://www.star-history.com/?repos=juliantanx%2Faiusage&type=date&logscale=&legend=top-left">
|
|
594
58
|
<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=
|
|
596
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=
|
|
597
|
-
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=
|
|
59
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&theme=dark&legend=top-left&t=20260603" />
|
|
60
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260603" />
|
|
61
|
+
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260603" />
|
|
598
62
|
</picture>
|
|
599
63
|
</a>
|
|
600
64
|
|