@juliantanx/aiusage 1.2.1 → 1.3.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 (99) hide show
  1. package/README.md +151 -26
  2. package/dist/index.js +2568 -1478
  3. package/dist/web/_app/immutable/assets/0.C5PeBlns.css +1 -0
  4. package/dist/web/_app/immutable/assets/10.D4XIqeEN.css +1 -0
  5. package/dist/web/_app/immutable/assets/11.CR85TxeS.css +1 -0
  6. package/dist/web/_app/immutable/assets/12.DAmfvZ5J.css +1 -0
  7. package/dist/web/_app/immutable/assets/2.G6nSchsK.css +1 -0
  8. package/dist/web/_app/immutable/assets/3.DQh9JikT.css +1 -0
  9. package/dist/web/_app/immutable/assets/4.CnA4GaE5.css +1 -0
  10. package/dist/web/_app/immutable/assets/5.D4N7n6x9.css +1 -0
  11. package/dist/web/_app/immutable/assets/6.CrsKlz6Y.css +1 -0
  12. package/dist/web/_app/immutable/assets/7.CQvfgmQf.css +1 -0
  13. package/dist/web/_app/immutable/assets/8.DDodt1Wn.css +1 -0
  14. package/dist/web/_app/immutable/assets/9.ApFevNUr.css +1 -0
  15. package/dist/web/_app/immutable/assets/ToolSelector.BRqFUj1Q.css +1 -0
  16. package/dist/web/_app/immutable/assets/ToolSelector.Bqx3ytrl.css +1 -0
  17. package/dist/web/_app/immutable/assets/_layout.C2s9Ry1h.css +1 -0
  18. package/dist/web/_app/immutable/assets/_page.ApFevNUr.css +1 -0
  19. package/dist/web/_app/immutable/assets/_page.CQvfgmQf.css +1 -0
  20. package/dist/web/_app/immutable/assets/_page.CR85TxeS.css +1 -0
  21. package/dist/web/_app/immutable/assets/_page.CmayGpOu.css +1 -0
  22. package/dist/web/_app/immutable/assets/_page.CnA4GaE5.css +1 -0
  23. package/dist/web/_app/immutable/assets/_page.CrsKlz6Y.css +1 -0
  24. package/dist/web/_app/immutable/assets/_page.D4N7n6x9.css +1 -0
  25. package/dist/web/_app/immutable/assets/_page.DAmfvZ5J.css +1 -0
  26. package/dist/web/_app/immutable/assets/_page.DDodt1Wn.css +1 -0
  27. package/dist/web/_app/immutable/assets/_page.DQh9JikT.css +1 -0
  28. package/dist/web/_app/immutable/assets/_page.DewAUGiJ.css +1 -0
  29. package/dist/web/_app/immutable/chunks/ToolSelector.CnQ-eszE.js +2 -0
  30. package/dist/web/_app/immutable/chunks/{api.Cv9iCeAW.js → api.OwJBmtEN.js} +1 -1
  31. package/dist/web/_app/immutable/chunks/{entry.CsncxtbZ.js → entry.DWbp2XzC.js} +1 -1
  32. package/dist/web/_app/immutable/chunks/i18n.BOq44pYI.js +1 -0
  33. package/dist/web/_app/immutable/chunks/{index.BjVwNvJa.js → index.CPsgU-fv.js} +1 -1
  34. package/dist/web/_app/immutable/chunks/{index.CUfK07C5.js → index.wix8pgil.js} +1 -1
  35. package/dist/web/_app/immutable/chunks/scheduler.DFD7qxcZ.js +1 -0
  36. package/dist/web/_app/immutable/chunks/stores.B1g8D8DV.js +1 -0
  37. package/dist/web/_app/immutable/chunks/{stores.UWwZtiEq.js → stores.C3ZtRBEM.js} +1 -1
  38. package/dist/web/_app/immutable/entry/{app.DOglqJ4_.js → app.7Tmcb_qs.js} +2 -2
  39. package/dist/web/_app/immutable/entry/start.CuMG7ijt.js +1 -0
  40. package/dist/web/_app/immutable/nodes/0.GiWuXD22.js +1 -0
  41. package/dist/web/_app/immutable/nodes/{1.DO29y7Dm.js → 1.CNbcoUIj.js} +1 -1
  42. package/dist/web/_app/immutable/nodes/10.DgPr3L-S.js +1 -0
  43. package/dist/web/_app/immutable/nodes/11.TrX-RGQX.js +1 -0
  44. package/dist/web/_app/immutable/nodes/12.ZW7n1TLF.js +1 -0
  45. package/dist/web/_app/immutable/nodes/2.D0gEY9nh.js +3 -0
  46. package/dist/web/_app/immutable/nodes/3.CcnPu3DZ.js +1 -0
  47. package/dist/web/_app/immutable/nodes/4.CCaCZRNi.js +13 -0
  48. package/dist/web/_app/immutable/nodes/5.Bxx7TNGK.js +1 -0
  49. package/dist/web/_app/immutable/nodes/6.8zY9a_YX.js +1 -0
  50. package/dist/web/_app/immutable/nodes/7.bOnMUP4_.js +9 -0
  51. package/dist/web/_app/immutable/nodes/8.01X9rJRT.js +1 -0
  52. package/dist/web/_app/immutable/nodes/9.DabFUxt3.js +1 -0
  53. package/dist/web/_app/version.json +1 -1
  54. package/dist/web/index.html +12 -11
  55. package/package.json +5 -3
  56. package/dist/chunk-2DX56FB6.js +0 -522
  57. package/dist/dist-4I33E46P.js +0 -42
  58. package/dist/web/_app/immutable/assets/0.Cynllvu4.css +0 -1
  59. package/dist/web/_app/immutable/assets/10.Doxq00gF.css +0 -1
  60. package/dist/web/_app/immutable/assets/11.D5bUq0yE.css +0 -1
  61. package/dist/web/_app/immutable/assets/12.BA90S8v7.css +0 -1
  62. package/dist/web/_app/immutable/assets/2.fho1OPpm.css +0 -1
  63. package/dist/web/_app/immutable/assets/3.DwwXF_G1.css +0 -1
  64. package/dist/web/_app/immutable/assets/4.CVp0A8QV.css +0 -1
  65. package/dist/web/_app/immutable/assets/5.DM2hVWjt.css +0 -1
  66. package/dist/web/_app/immutable/assets/6.NdKfVCiG.css +0 -1
  67. package/dist/web/_app/immutable/assets/7.CeV8yHSX.css +0 -1
  68. package/dist/web/_app/immutable/assets/8.BCdjuhVX.css +0 -1
  69. package/dist/web/_app/immutable/assets/9.ClvwkhDe.css +0 -1
  70. package/dist/web/_app/immutable/assets/ToolSelector.BKgB2QVk.css +0 -1
  71. package/dist/web/_app/immutable/assets/ToolSelector.HSbC8-q9.css +0 -1
  72. package/dist/web/_app/immutable/assets/_layout.BpydV4rl.css +0 -1
  73. package/dist/web/_app/immutable/assets/_page.BA90S8v7.css +0 -1
  74. package/dist/web/_app/immutable/assets/_page.BCdjuhVX.css +0 -1
  75. package/dist/web/_app/immutable/assets/_page.CVp0A8QV.css +0 -1
  76. package/dist/web/_app/immutable/assets/_page.CeV8yHSX.css +0 -1
  77. package/dist/web/_app/immutable/assets/_page.ClvwkhDe.css +0 -1
  78. package/dist/web/_app/immutable/assets/_page.D5bUq0yE.css +0 -1
  79. package/dist/web/_app/immutable/assets/_page.DM2hVWjt.css +0 -1
  80. package/dist/web/_app/immutable/assets/_page.DTuZozBR.css +0 -1
  81. package/dist/web/_app/immutable/assets/_page.Doxq00gF.css +0 -1
  82. package/dist/web/_app/immutable/assets/_page.DwwXF_G1.css +0 -1
  83. package/dist/web/_app/immutable/assets/_page.NdKfVCiG.css +0 -1
  84. package/dist/web/_app/immutable/chunks/ToolSelector.RXWBkdpM.js +0 -2
  85. package/dist/web/_app/immutable/chunks/i18n.CrmYDWvg.js +0 -1
  86. package/dist/web/_app/immutable/chunks/scheduler.DukoKnjQ.js +0 -1
  87. package/dist/web/_app/immutable/entry/start.BH01iOT0.js +0 -1
  88. package/dist/web/_app/immutable/nodes/0.eiglG3hs.js +0 -1
  89. package/dist/web/_app/immutable/nodes/10.Jb_wogsG.js +0 -1
  90. package/dist/web/_app/immutable/nodes/11.CpuiQa6R.js +0 -1
  91. package/dist/web/_app/immutable/nodes/12.BiWlfD7q.js +0 -1
  92. package/dist/web/_app/immutable/nodes/2.CQudsTBz.js +0 -3
  93. package/dist/web/_app/immutable/nodes/3.Dg9c_XQX.js +0 -1
  94. package/dist/web/_app/immutable/nodes/4.DE3OvqSg.js +0 -11
  95. package/dist/web/_app/immutable/nodes/5.sGu0NOiv.js +0 -1
  96. package/dist/web/_app/immutable/nodes/6.BOL9Fhgv.js +0 -1
  97. package/dist/web/_app/immutable/nodes/7.B2wRNntO.js +0 -1
  98. package/dist/web/_app/immutable/nodes/8.BVACtdPg.js +0 -1
  99. package/dist/web/_app/immutable/nodes/9.DXxXyKe4.js +0 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # aiusage
2
2
 
3
- Track AI coding assistant usage, token consumption, cost, and tool calls in one place across Claude Code, Codex, OpenClaw, OpenCode, and Hermes.
3
+ Track AI coding assistant usage, token consumption, cost, and tool calls in one place across Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.
4
4
 
5
5
  English | [中文](https://github.com/juliantanx/aiusage/blob/main/README_zh.md)
6
6
 
@@ -14,7 +14,7 @@ English | [中文](https://github.com/juliantanx/aiusage/blob/main/README_zh.md)
14
14
 
15
15
  ## Quick Start
16
16
 
17
- **Prerequisites:** Node.js >= 18 (tested on v18 LTS and v22 LTS; Node.js 16 and below are not supported)
17
+ **Prerequisites:** Node.js 18 or later
18
18
 
19
19
  ```bash
20
20
  # Install
@@ -67,26 +67,142 @@ pnpm rebuild:sqlite
67
67
 
68
68
  ## Screenshots
69
69
 
70
- ![Homepage dashboard](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@main/docs/assets/readme/home.png)
70
+ ![Homepage dashboard](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@0ae8299/docs/assets/readme/home.png)
71
71
 
72
- ![Overview page](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@main/docs/assets/readme/overview.png)
72
+ ![Overview page](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@0ae8299/docs/assets/readme/overview.png)
73
73
 
74
- ![Token usage page](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@main/docs/assets/readme/token.png)
74
+ ![Token usage page](https://cdn.jsdelivr.net/gh/juliantanx/aiusage@0ae8299/docs/assets/readme/token.png)
75
75
 
76
- ## Common Commands
76
+ ## CLI Reference
77
77
 
78
- | Command | Purpose |
79
- | --- | --- |
80
- | `aiusage` | Print the same terminal summary as `aiusage summary` |
81
- | `aiusage parse` | Import newly appended local session data from discovered source paths |
82
- | `aiusage serve` | Start the local dashboard and runtime settings controller |
83
- | `aiusage summary` | Print a usage summary in the terminal |
84
- | `aiusage status` | Show database path, schema version, and record counts |
85
- | `aiusage sync` | Push and pull data with a configured remote backend |
86
- | `aiusage export` | Export records as CSV, JSON, or NDJSON |
87
- | `aiusage clean` | Remove old data |
88
- | `aiusage recalc` | Recalculate costs with updated pricing |
89
- | `aiusage init` | Configure a sync backend |
78
+ ### `aiusage` (default)
79
+
80
+ Print a usage summary to the terminal (same as `aiusage summary`).
81
+
82
+ ### `aiusage parse`
83
+
84
+ Import newly appended local session data from discovered source paths.
85
+
86
+ | Option | Description |
87
+ |--------|-------------|
88
+ | `--tool <tool>` | Only parse a specific tool: `claude-code`, `codex`, `openclaw`, `opencode`, `hermes`, `qoder` |
89
+ | `--progress` | Show real-time progress bar on stderr (TTY only, silent in pipes/CI) |
90
+
91
+ ```bash
92
+ aiusage parse # Parse all tools
93
+ aiusage parse --tool claude-code # Only parse Claude Code logs
94
+ aiusage parse --progress # Show progress bar while parsing
95
+ ```
96
+
97
+ ### `aiusage serve`
98
+
99
+ Start the local web dashboard and runtime settings controller.
100
+
101
+ | Option | Description | Default |
102
+ |--------|-------------|---------|
103
+ | `-p, --port <port>` | Port number | `3847` |
104
+
105
+ ```bash
106
+ aiusage serve # Start on port 3847
107
+ aiusage serve -p 8080 # Start on port 8080
108
+ ```
109
+
110
+ ### `aiusage summary`
111
+
112
+ Print a usage summary in the terminal.
113
+
114
+ | Option | Description |
115
+ |--------|-------------|
116
+ | `--device <id>` | Filter by device instance ID |
117
+ | `--tool <tool>` | Filter by tool type |
118
+
119
+ ```bash
120
+ aiusage summary # All-time summary
121
+ aiusage summary --tool claude-code # Single tool
122
+ ```
123
+
124
+ ### `aiusage status`
125
+
126
+ Show version, device name, DB path, schema version, table/view counts, record count, DB size, and sync status.
127
+
128
+ ### `aiusage export`
129
+
130
+ Export records as CSV, JSON, or NDJSON.
131
+
132
+ | Option | Description | Required |
133
+ |--------|-------------|----------|
134
+ | `--format <format>` | Output format: `csv`, `json`, `ndjson` | Yes |
135
+ | `-o, --output <file>` | Output file path (default: stdout) | No |
136
+
137
+ ```bash
138
+ aiusage export --format csv # CSV to stdout
139
+ aiusage export --format json -o report.json # JSON to file
140
+ aiusage export --format ndjson # NDJSON to stdout
141
+ ```
142
+
143
+ ### `aiusage clean`
144
+
145
+ Remove old records from the local database based on age.
146
+
147
+ | Option | Description | Default |
148
+ |--------|-------------|---------|
149
+ | `--before <duration>` | Delete data older than this duration (e.g. `30d`, `180d`) | `180d` |
150
+
151
+ ```bash
152
+ aiusage clean # Delete records older than 180 days
153
+ aiusage clean --before 30d # Delete records older than 30 days
154
+ aiusage clean --before 90d --yes # Delete records older than 90 days, skip confirm
155
+ ```
156
+
157
+ ### `aiusage reset`
158
+
159
+ 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.
160
+
161
+ | Option | Description |
162
+ |--------|-------------|
163
+ | `--yes` | Skip confirmation prompt (required to execute) |
164
+
165
+ ```bash
166
+ aiusage reset --yes # Wipe all data, then run `aiusage parse` to re-import
167
+ ```
168
+
169
+ ### `aiusage recalc`
170
+
171
+ Recalculate costs using the latest pricing data.
172
+
173
+ ```bash
174
+ aiusage recalc
175
+ ```
176
+
177
+ ### `aiusage init`
178
+
179
+ Configure a sync backend for multi-machine data aggregation.
180
+
181
+ | Option | Description |
182
+ |--------|-------------|
183
+ | `--backend <backend>` | Sync backend: `github`, `s3`, `skip` |
184
+ | `--repo <repo>` | GitHub repository (format: `username/repo-name`) |
185
+ | `--token <token>` | GitHub Personal Access Token |
186
+ | `--bucket <bucket>` | S3 bucket name |
187
+ | `--prefix <prefix>` | S3 object prefix (default: `aiusage/`) |
188
+ | `--endpoint <endpoint>` | S3 endpoint URL |
189
+ | `--region <region>` | S3 region (default: `auto`) |
190
+ | `--access-key-id <id>` | S3 access key ID |
191
+ | `--secret-access-key <key>` | S3 secret access key |
192
+ | `--device <alias>` | Device alias |
193
+
194
+ ```bash
195
+ aiusage init --backend github --repo user/aiusage-data --token ghp_xxx
196
+ aiusage init --backend s3 --bucket my-bucket --endpoint https://xxx.r2.cloudflarestorage.com --access-key-id AKIAxxx --secret-access-key xxx
197
+ ```
198
+
199
+ ### `aiusage sync`
200
+
201
+ Push and pull data with the configured remote backend.
202
+
203
+ ```bash
204
+ aiusage sync
205
+ ```
90
206
 
91
207
  ## Web Dashboard
92
208
 
@@ -132,7 +248,7 @@ For single-machine usage, Quick Start is enough.
132
248
 
133
249
  ### Multi-Machine Sync
134
250
 
135
- Use this to aggregate token usage from multiple machines into one dashboard. Works with Claude Code, Codex, OpenClaw, OpenCode, and Hermes.
251
+ Use this to aggregate token usage from multiple machines into one dashboard. Works with Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.
136
252
 
137
253
  **Architecture:**
138
254
 
@@ -157,7 +273,7 @@ Machine C ──┘
157
273
 
158
274
  **Step 2 — Install and configure on each machine**
159
275
 
160
- On every machine that uses Claude Code, Codex, OpenClaw, OpenCode, or Hermes:
276
+ On every machine that uses Claude Code, Codex, OpenClaw, OpenCode, Hermes, or Qoder:
161
277
 
162
278
  ```bash
163
279
  # Install aiusage CLI
@@ -320,7 +436,8 @@ docker build -t aiusage .
320
436
  |------|------|
321
437
  | Local database | `~/.aiusage/cache.db` |
322
438
  | Config | `~/.aiusage/config.json` |
323
- | State (watermarks, sync) | `~/.aiusage/state.json` |
439
+ | Sync state | `~/.aiusage/state.json` |
440
+ | Parse watermarks | `~/.aiusage/watermark.json` |
324
441
 
325
442
  ### Default Source Paths
326
443
 
@@ -333,6 +450,8 @@ docker build -t aiusage .
333
450
  | OpenClaw | `~/.openclaw/agents/*/sessions/` | `~/.openclaw/agents/*/sessions/` | `%USERPROFILE%\.openclaw\agents\*\sessions\` |
334
451
  | OpenCode | `~/Library/Application Support/opencode/opencode.db` | `~/.local/share/opencode/opencode.db` | `%APPDATA%\opencode\opencode.db` |
335
452
  | Hermes | `~/.hermes/state.db` | `~/.hermes/state.db` | `%USERPROFILE%\.hermes\state.db` |
453
+ | Qoder (sessions) | `~/.qoder/logs/sessions/` | `~/.qoder/logs/sessions/` plus WSL-mounted Windows user homes | `%USERPROFILE%\.qoder\logs\sessions\` |
454
+ | 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` |
336
455
 
337
456
  Discovery behavior:
338
457
 
@@ -341,9 +460,13 @@ Discovery behavior:
341
460
  - **OpenClaw** — scans each agent's `sessions/` directory under `~/.openclaw/agents/*/sessions/` and skips checkpoint files.
342
461
  - **OpenCode** — reads the SQLite database file directly instead of `.jsonl` logs.
343
462
  - **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).
463
+ - **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.
464
+ - **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.
344
465
 
345
466
  > On Linux, OpenCode respects `$XDG_DATA_HOME` if set.
346
467
 
468
+ 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.
469
+
347
470
  ### Custom Source Paths
348
471
 
349
472
  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:
@@ -355,12 +478,14 @@ If you installed a tool to a non-default location, override the paths in the **S
355
478
  "codex": "/custom/path/.codex/sessions",
356
479
  "openclaw": "/custom/sessions-dir",
357
480
  "opencode": "/custom/path/opencode.db",
358
- "hermes": "/custom/path/.hermes/state.db"
481
+ "hermes": "/custom/path/.hermes/state.db",
482
+ "qoder": "/custom/path/.qoder/logs/sessions",
483
+ "qoder-db": "/custom/path/local.db"
359
484
  }
360
485
  }
361
486
  ```
362
487
 
363
- Only the paths you specify are overridden; unspecified tools fall back to their defaults.
488
+ 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.
364
489
 
365
490
  ## Database Visualization
366
491
 
@@ -410,9 +535,9 @@ packages/
410
535
 
411
536
  <a href="https://www.star-history.com/?repos=juliantanx%2Faiusage&type=date&logscale=&legend=top-left">
412
537
  <picture>
413
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&theme=dark&legend=top-left&t=20260522" />
414
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260522" />
415
- <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260522" />
538
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&theme=dark&legend=top-left&t=20260524" />
539
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260524" />
540
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=juliantanx/aiusage&type=date&legend=top-left&t=20260524" />
416
541
  </picture>
417
542
  </a>
418
543