agenttelemetry-app 2.0.0__tar.gz
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.
- agenttelemetry_app-2.0.0/LICENSE +21 -0
- agenttelemetry_app-2.0.0/MANIFEST.in +28 -0
- agenttelemetry_app-2.0.0/PKG-INFO +495 -0
- agenttelemetry_app-2.0.0/README.md +471 -0
- agenttelemetry_app-2.0.0/__init__.py +3 -0
- agenttelemetry_app-2.0.0/__main__.py +7 -0
- agenttelemetry_app-2.0.0/accounts.py +355 -0
- agenttelemetry_app-2.0.0/agenttelemetry_app.egg-info/PKG-INFO +495 -0
- agenttelemetry_app-2.0.0/agenttelemetry_app.egg-info/SOURCES.txt +71 -0
- agenttelemetry_app-2.0.0/agenttelemetry_app.egg-info/dependency_links.txt +1 -0
- agenttelemetry_app-2.0.0/agenttelemetry_app.egg-info/entry_points.txt +4 -0
- agenttelemetry_app-2.0.0/agenttelemetry_app.egg-info/top_level.txt +1 -0
- agenttelemetry_app-2.0.0/chart.umd.min.js +20 -0
- agenttelemetry_app-2.0.0/cli.py +47 -0
- agenttelemetry_app-2.0.0/dashboard.py +2413 -0
- agenttelemetry_app-2.0.0/docs/python-package.md +63 -0
- agenttelemetry_app-2.0.0/index.html +465 -0
- agenttelemetry_app-2.0.0/manifest.json +22 -0
- agenttelemetry_app-2.0.0/native.py +135 -0
- agenttelemetry_app-2.0.0/parser.py +4202 -0
- agenttelemetry_app-2.0.0/pyproject.toml +55 -0
- agenttelemetry_app-2.0.0/session_names.py +270 -0
- agenttelemetry_app-2.0.0/setup.cfg +4 -0
- agenttelemetry_app-2.0.0/setup.py +27 -0
- agenttelemetry_app-2.0.0/static/app.css +650 -0
- agenttelemetry_app-2.0.0/static/apple-touch-icon.png +0 -0
- agenttelemetry_app-2.0.0/static/charts.js +330 -0
- agenttelemetry_app-2.0.0/static/core.js +522 -0
- agenttelemetry_app-2.0.0/static/icon-192.png +0 -0
- agenttelemetry_app-2.0.0/static/icon-512.png +0 -0
- agenttelemetry_app-2.0.0/static/tool-icons/LICENSE.hermes.txt +21 -0
- agenttelemetry_app-2.0.0/static/tool-icons/LICENSE.openclaw.txt +21 -0
- agenttelemetry_app-2.0.0/static/tool-icons/LICENSE.simple-icons.txt +30 -0
- agenttelemetry_app-2.0.0/static/tool-icons/README.md +21 -0
- agenttelemetry_app-2.0.0/static/tool-icons/claude.svg +1 -0
- agenttelemetry_app-2.0.0/static/tool-icons/copilot.svg +1 -0
- agenttelemetry_app-2.0.0/static/tool-icons/cursor.svg +1 -0
- agenttelemetry_app-2.0.0/static/tool-icons/hermes.svg +7 -0
- agenttelemetry_app-2.0.0/static/tool-icons/openai.svg +1 -0
- agenttelemetry_app-2.0.0/static/tool-icons/openclaw.svg +18 -0
- agenttelemetry_app-2.0.0/static/tool-icons/opencode.svg +1 -0
- agenttelemetry_app-2.0.0/static/views.js +2749 -0
- agenttelemetry_app-2.0.0/sw.js +70 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Uttam Deb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
include pyproject.toml
|
|
2
|
+
include setup.py
|
|
3
|
+
include README.md
|
|
4
|
+
include LICENSE
|
|
5
|
+
include __init__.py
|
|
6
|
+
include __main__.py
|
|
7
|
+
include cli.py
|
|
8
|
+
include dashboard.py
|
|
9
|
+
include parser.py
|
|
10
|
+
include native.py
|
|
11
|
+
include accounts.py
|
|
12
|
+
include session_names.py
|
|
13
|
+
include index.html
|
|
14
|
+
include chart.umd.min.js
|
|
15
|
+
include manifest.json
|
|
16
|
+
include sw.js
|
|
17
|
+
include docs/python-package.md
|
|
18
|
+
recursive-include static *.css *.js *.png *.svg *.txt *.md
|
|
19
|
+
prune tests
|
|
20
|
+
prune website
|
|
21
|
+
prune macos
|
|
22
|
+
prune windows
|
|
23
|
+
prune .github
|
|
24
|
+
prune build
|
|
25
|
+
prune dist
|
|
26
|
+
prune .usage_cache.json
|
|
27
|
+
prune .peers
|
|
28
|
+
global-exclude .usage_cache.json .usage_cache.json.tmp .peers.json server.log *.py[cod]
|
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agenttelemetry-app
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: A private, local dashboard for AI coding agent usage
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/uttamdeb/agent-telemetry
|
|
7
|
+
Project-URL: Repository, https://github.com/uttamdeb/agent-telemetry
|
|
8
|
+
Project-URL: Issues, https://github.com/uttamdeb/agent-telemetry/issues
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Utilities
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# AgentTelemetry
|
|
26
|
+
|
|
27
|
+
**Live, local telemetry for your AI coding agents.** AgentTelemetry reads the interaction
|
|
28
|
+
logs your tools already write to your own machine and serves a clean, interactive
|
|
29
|
+
dashboard — estimated spend, tokens, active time, cache efficiency, an **Anthropic vs OpenAI
|
|
30
|
+
vs Google** provider comparison, an activity calendar, and breakdowns by **model, provider,
|
|
31
|
+
day, hour, weekday, tool, IDE, project and session** — plus how much **disk** all these logs
|
|
32
|
+
eat, and suggestions for spending less, drawn from your own numbers.
|
|
33
|
+
|
|
34
|
+
**Your data stays on your machine** — unless you turn on [Your devices](#your-devices-optional)
|
|
35
|
+
to combine two of your own computers over your local network. Optional account lookups
|
|
36
|
+
contact the provider only after you choose **Read once**; account metadata is never shared
|
|
37
|
+
with paired devices. No account, no API key, no
|
|
38
|
+
telemetry, no dependencies — just Python's standard library and a vendored copy of Chart.js.
|
|
39
|
+
|
|
40
|
+
Covers **Claude Code · Claude Desktop · Codex · GitHub Copilot · Cursor · OpenCode · Hermes Agent · OpenClaw**.
|
|
41
|
+
|
|
42
|
+
## Download the app
|
|
43
|
+
|
|
44
|
+
| Platform | Download |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| macOS 13+ · Apple Silicon | **[Download DMG](https://github.com/uttamdeb/agent-telemetry/releases/download/v2.0.0/AgentTelemetry-2.0.0-macos-arm64.dmg)** |
|
|
47
|
+
| macOS 13+ · Intel | **[Download DMG](https://github.com/uttamdeb/agent-telemetry/releases/download/v2.0.0/AgentTelemetry-2.0.0-macos-x86_64.dmg)** |
|
|
48
|
+
| Windows 10/11 · x64 | **[Download EXE installer](https://github.com/uttamdeb/agent-telemetry/releases/download/v2.0.0/AgentTelemetry-2.0.0-windows-x64-setup.exe)** |
|
|
49
|
+
|
|
50
|
+
**Python is bundled — no terminal setup needed.** macOS: open the DMG, drag the app to
|
|
51
|
+
Applications and open it. Windows: run the installer and open AgentTelemetry from Start.
|
|
52
|
+
Open at Login is optional. Quit the app and wait for saving before installing an update;
|
|
53
|
+
upgrades and uninstall preserve telemetry history.
|
|
54
|
+
|
|
55
|
+
If you have archived history in a source checkout, leave **Open AgentTelemetry**
|
|
56
|
+
unchecked in Windows setup, open the app manually and **Import existing data** before
|
|
57
|
+
starting monitoring. On macOS, opening the app manually also lets you import first.
|
|
58
|
+
|
|
59
|
+
These builds are unsigned/unnotarized. macOS may require **System Settings → Privacy &
|
|
60
|
+
Security → Open Anyway**; Windows SmartScreen may require **More info → Run anyway**.
|
|
61
|
+
[All releases](https://github.com/uttamdeb/agent-telemetry/releases) ·
|
|
62
|
+
[SHA-256 checksums](https://github.com/uttamdeb/agent-telemetry/releases/download/v2.0.0/SHA256SUMS.txt)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Preview
|
|
67
|
+
|
|
68
|
+
<table>
|
|
69
|
+
<tr>
|
|
70
|
+
<th>Menu bar companion</th>
|
|
71
|
+
<th>Usage dashboard</th>
|
|
72
|
+
</tr>
|
|
73
|
+
<tr>
|
|
74
|
+
<td><img src="docs/screenshots/macos-menu-bar.png" width="300" alt="AgentTelemetry menu bar popover with today's token and spend totals and display settings"></td>
|
|
75
|
+
<td><img src="docs/screenshots/dashboard-overview.png" width="640" alt="AgentTelemetry dashboard showing token trends and usage breakdowns by tool and model"></td>
|
|
76
|
+
</tr>
|
|
77
|
+
</table>
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
81
|
+
With [uv](https://docs.astral.sh/uv/getting-started/installation/) installed:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uvx agenttelemetry-app
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Or install with Python 3.9+:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python -m pip install agenttelemetry-app
|
|
91
|
+
agenttelemetry
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Then open **http://127.0.0.1:7878**. The Python package starts the local browser dashboard;
|
|
95
|
+
use the [app downloads](#download-the-app) for the menu bar or system tray companion.
|
|
96
|
+
See [Python package details](docs/python-package.md) for its per-user data location.
|
|
97
|
+
|
|
98
|
+
To run from a source checkout with Python 3.8+:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone https://github.com/uttamdeb/agent-telemetry.git
|
|
102
|
+
cd agent-telemetry
|
|
103
|
+
python3 dashboard.py
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then open **http://127.0.0.1:7878**. The source checkout needs no package installation.
|
|
107
|
+
|
|
108
|
+
> First run parses your local logs (can take ~30–60s if you have large Codex logs), writes
|
|
109
|
+
> a cache, and is instant thereafter. The page auto-refreshes every ~15s, so a session
|
|
110
|
+
> you're running *right now* shows up within seconds.
|
|
111
|
+
|
|
112
|
+
Options: `python3 dashboard.py --port 9000` · `--rebuild` (ignore cache, full re-parse) ·
|
|
113
|
+
`--interval 20` (background refresh seconds) · `--data-dir /path/to/state` (store the
|
|
114
|
+
cache and optional device-sharing files outside the checkout). Without `--data-dir`, current
|
|
115
|
+
checkout behavior is unchanged. Or `./run.sh [flags]`.
|
|
116
|
+
|
|
117
|
+
## Subscription limits and account details
|
|
118
|
+
|
|
119
|
+
The bottom of Cost shows subscription limits for Codex and Claude Code when they
|
|
120
|
+
have a session today on this device. Codex's locally recorded snapshots show reset
|
|
121
|
+
times. Choose **Refresh account & limits** to read the installed Codex CLI's account,
|
|
122
|
+
auth type, plan and current limits once. Claude's **Refresh account** reads its auth,
|
|
123
|
+
provider and optional plan; percentage meters require the optional local status-line
|
|
124
|
+
capture. Both actions ask before a lookup that may contact the provider.
|
|
125
|
+
|
|
126
|
+
Missing data stays unavailable. Older snapshots are stale; percentages are never
|
|
127
|
+
estimated from tokens or combined across devices. Session details show recorded
|
|
128
|
+
creator/account IDs with their attribution limits. Account metadata is private to the
|
|
129
|
+
source device. See [setup, research and limitations](docs/account-limits.md).
|
|
130
|
+
|
|
131
|
+
## Install the menu bar / system tray app
|
|
132
|
+
|
|
133
|
+
Use the [app downloads](#download-the-app) above for a ready-to-run installation.
|
|
134
|
+
To build/install from a checkout, run **`python3 install.py` on macOS** or **`python install.py` on Windows**.
|
|
135
|
+
The installer detects the OS, installs its matching native client for the current user and
|
|
136
|
+
opens it. Use `--no-launch` to install without opening. Linux keeps the browser dashboard.
|
|
137
|
+
|
|
138
|
+
| Platform | Native client | Source installation requirements |
|
|
139
|
+
| --- | --- | --- |
|
|
140
|
+
| macOS 13+ | SwiftUI/AppKit menu item, token/spend popover and embedded dashboard | Python to run the installer; Swift 5.8+ and a macOS SDK to build the app. The app then uses its bundled Python. |
|
|
141
|
+
| Windows 10/11 | Branded tray icon and native summary popover matching the macOS layout; dashboard in your browser | Standard Python 3.8+ including `pythonw.exe`. No pip packages or separate GUI toolkit. |
|
|
142
|
+
|
|
143
|
+
After installation, **web Settings → Menu bar / system tray** has a toggle to launch or
|
|
144
|
+
quit the native app. Status reflects the app's heartbeat, not just a launch attempt. You
|
|
145
|
+
can also open **AgentTelemetry.app** in `~/Applications` or **AgentTelemetry** from the
|
|
146
|
+
Windows Start menu. The app's **Open at Login** and **Start monitoring when app opens**
|
|
147
|
+
options are separate and off by default. Opening from the installer or web toggle starts
|
|
148
|
+
monitoring for that launch. No dashboard setting is required to open an app manually.
|
|
149
|
+
|
|
150
|
+
Both native popovers put a monitoring switch above today's token/spend cards, with
|
|
151
|
+
expandable **Details & settings**, a dashboard button and always-visible refresh/quit
|
|
152
|
+
controls. Windows follows the system light/dark or high-contrast theme, scales to the
|
|
153
|
+
tray's monitor, and scrolls settings on smaller displays. Tab/Space/Enter operate the
|
|
154
|
+
native controls; Escape or clicking elsewhere closes the panel. Icon mode uses the
|
|
155
|
+
AgentTelemetry app icon; the numeric display remains available. Both have a text tooltip.
|
|
156
|
+
Windows uses Segoe UI and opens the full dashboard in your browser; macOS uses its
|
|
157
|
+
system font and embeds it.
|
|
158
|
+
|
|
159
|
+
Both clients reuse a dashboard already running on port 7878 and stop only a backend they
|
|
160
|
+
started. A web/native app using a custom dashboard port is not supported by the native
|
|
161
|
+
clients. Failure shows stale figures explicitly, and retries can recover. Import existing
|
|
162
|
+
data before first app-owned monitoring if you need archived history: importing validates
|
|
163
|
+
and copies the ledger without overwriting existing app data or changing the originals.
|
|
164
|
+
For that flow, install with `--no-launch`, open the app manually and choose Import before
|
|
165
|
+
Start monitoring. A default install attaches safely when the old dashboard is still running.
|
|
166
|
+
|
|
167
|
+
Browser windows, the macOS menu bar and the Windows tray share one refresh interval:
|
|
168
|
+
15 seconds (default), 1/5/15 minutes, or Manual. Change it in web Settings or the native
|
|
169
|
+
app while monitoring. They sample a small shared clock each second and show figures
|
|
170
|
+
from the same snapshot; a manual refresh in either app updates the others too, normally
|
|
171
|
+
within a second plus request time. Manual continues listening for those explicit refreshes.
|
|
172
|
+
The native figures are today's usage across all tools and connected devices; compare
|
|
173
|
+
them with an unfiltered Today dashboard. Pause pauses only that browser's figures.
|
|
174
|
+
Changing the interval does not restart the backend or reload the embedded dashboard.
|
|
175
|
+
The server's `--interval` controls log parsing separately. Older attached backends without
|
|
176
|
+
the sync API retain independent polling until upgraded and restarted.
|
|
177
|
+
|
|
178
|
+
Read the [macOS guide](macos/AgentTelemetryMac/README.md) and
|
|
179
|
+
[Windows guide](windows/README.md) for paths, controls and development checks. macOS
|
|
180
|
+
downloads and source builds are ad-hoc signed; a Developer ID signed/notarized installer
|
|
181
|
+
is not supplied. The backend remains stdlib-only and no runtime update checks
|
|
182
|
+
are added. The macOS packaging step downloads a hash-pinned Python runtime explicitly.
|
|
183
|
+
|
|
184
|
+
Local app integrations can use `GET /api/health` for a small readiness response that contains
|
|
185
|
+
no usage data, and `GET /api/summary` for today's token total and API-equivalent estimated
|
|
186
|
+
spend. Both are read-only; they follow the dashboard's existing host and origin rules.
|
|
187
|
+
`GET /api/sync` supplies the shared display clock; `POST /api/sync` sets its validated
|
|
188
|
+
interval through the same JSON/same-origin CSRF guard. The data and summary HTTP endpoints
|
|
189
|
+
retain one serialized snapshot per display tick, in memory only; the ledger is unaffected.
|
|
190
|
+
`GET /api/native` reports local app status. `POST /api/native` requires the same CSRF guard
|
|
191
|
+
as all writes. `POST /api/shutdown` additionally requires the owning Windows client's
|
|
192
|
+
per-process control token; a normal standalone dashboard cannot be stopped by that route.
|
|
193
|
+
|
|
194
|
+
> `--rebuild` deletes the cache, and with it every session whose log has since been deleted
|
|
195
|
+
> from disk (see [Storage](#storage--what-these-logs-cost-you-in-disk)). Copy
|
|
196
|
+
> `.usage_cache.json` somewhere safe first if you've cleaned up old logs.
|
|
197
|
+
|
|
198
|
+
**Requirements:** Python 3.8+ on **macOS, Linux or Windows**. On Windows run
|
|
199
|
+
`python dashboard.py` (or `run.cmd`); on macOS/Linux `python3 dashboard.py` (or `./run.sh`).
|
|
200
|
+
|
|
201
|
+
It works on anyone's machine because **nothing is hardcoded** — every location is derived at
|
|
202
|
+
runtime from your own `$HOME` / `%APPDATA%` / `%LOCALAPPDATA%` / `$XDG_*`, the numbers are
|
|
203
|
+
read live from your own logs on every refresh, and the disk figures come from your own drive.
|
|
204
|
+
Two people running this see two completely different dashboards.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Everyone sees *their own* usage
|
|
209
|
+
|
|
210
|
+
This is the important part if you're sharing it: the dashboard has **no bundled data**.
|
|
211
|
+
On each machine it scans that user's own logs (`~/.claude`, `~/.codex`,
|
|
212
|
+
`~/Library/Application Support/…`, `~/.local/share/opencode`, `~/.hermes`, …) and builds a **fresh**
|
|
213
|
+
`.usage_cache.json` locally. That cache is **gitignored and never committed**, so a clone
|
|
214
|
+
starts empty and shows only the cloning user's numbers. (If you ever *copy the folder*
|
|
215
|
+
instead of cloning, delete `.usage_cache.json` first — that file is your personal data.)
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Data sources
|
|
220
|
+
|
|
221
|
+
| Tool | Where it reads | Tokens |
|
|
222
|
+
|---|---|---|
|
|
223
|
+
| **Claude Code** | `~/.claude/projects/**/*.jsonl` | exact (in/out/cache read+write, 5m/1h tiers) |
|
|
224
|
+
| **Claude Desktop** (agent mode) | `Claude/local-agent-mode-sessions/**` under App Support / `%APPDATA%` / `~/.config` | exact |
|
|
225
|
+
| **Codex** | `~/.codex/sessions/**`, `~/.codex/archived_sessions/**` | exact (in/cached/out/reasoning); subagents are identified and labelled |
|
|
226
|
+
| **GitHub Copilot** | VS Code-family `chatSessions/*.{json,jsonl}`; SDK/CLI `~/.copilot/session-state/*/events.jsonl`, enriched from VS Code `agentSessionData/*/session.db` | recorded request/turn tokens where available; SDK shutdown totals where safely dated. SDK gaps show a warning tooltip and unavailable/partial usage; older non-SDK chats retain text estimates. Premium multipliers are separate from estimated dollars. |
|
|
227
|
+
| **Cursor** (native AI) | `Cursor/User/globalStorage/state.vscdb` under App Support / `%APPDATA%` / `~/.config` | partial — model, mode, timestamps, tool calls and AI-line stats are exact; tokens are on only ~2% of messages |
|
|
228
|
+
| **OpenCode** | `~/.local/share/opencode/opencode.db`, `%LOCALAPPDATA%\opencode\opencode.db`, `~/.opencode/opencode.db` (or `$OPENCODE_DATA_DIR`) | V1/V2 SQLite; exact (in/out/reasoning/cache), prompts and tools; cost is read from OpenCode's own per-message value |
|
|
229
|
+
| **Hermes Agent** | `~/.hermes/state.db` (or `$HERMES_HOME`, `%LOCALAPPDATA%\hermes`) | exact (in/out/cache/reasoning, per model) |
|
|
230
|
+
| **OpenClaw** | `~/.openclaw/agents/<agent>/agent/openclaw-agent.sqlite` (or `$OPENCLAW_STATE_DIR`; also the older `~/.clawdbot`, `~/.moltbot`) and the older per-session `sessions/*.jsonl` | exact (in/out/cache read/cache write/reasoning, per response); its own logged cost is used only for a model with no verified price. Large events are stored zstd-compressed: read with the `zstd` command or Python 3.14+ |
|
|
231
|
+
|
|
232
|
+
A tool you don't use simply contributes nothing. **Attribution is by tool, not by model** —
|
|
233
|
+
a Claude or GPT model used *inside* Copilot/Cursor/OpenCode/Hermes/OpenClaw counts under that tool, and the
|
|
234
|
+
Models table lists each `model × tool` row separately.
|
|
235
|
+
|
|
236
|
+
Copilot's newer SDK-based agent sessions use a different store from older Copilot Chat.
|
|
237
|
+
AgentTelemetry joins their event history to VS Code's saved per-turn usage using native
|
|
238
|
+
session and event IDs. Custom endpoint models, including Cloudflare GLM 5.3, still count
|
|
239
|
+
as **Copilot**. A warning beside a session explains missing usage, partial coverage,
|
|
240
|
+
errors or interruptions. Missing SDK usage is never guessed from chat length or presented
|
|
241
|
+
as a known zero. See [Copilot SDK data coverage](docs/copilot-sdk.md) for sources and limits.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## What you get
|
|
246
|
+
|
|
247
|
+
Eight views in a left-hand sidebar, light + dark theme, everything date-filterable, and the
|
|
248
|
+
**name of this machine** at the top — so a screenshot always says which computer it came from.
|
|
249
|
+
|
|
250
|
+
The controls read as a sentence above every view — "**Tokens** from **all tools** over
|
|
251
|
+
**the last 30 days** ‹ ›" — click a bold phrase to change it; the arrows step back and
|
|
252
|
+
forward a period at a time. Inside them: the **measure** (**Tokens · Cost · Messages · Time**
|
|
253
|
+
— tokens by default; every chart and ranking switches together), the **period** (today, the
|
|
254
|
+
last 7–365 days, this week / month / quarter / year, last month, all time, or a custom
|
|
255
|
+
range), and a single **Filters** panel (tool, provider, model, project, IDE / surface, and *exact tokens only*).
|
|
256
|
+
Active filters show as removable chips. Every figure is compared with the equal-length
|
|
257
|
+
period just before it, and every chart has a **table view** (the grid icon) so nothing is
|
|
258
|
+
readable only by hovering.
|
|
259
|
+
|
|
260
|
+
**Overview** — one hero number (the chosen measure, tokens by default) with its change vs
|
|
261
|
+
the previous period. In Tokens mode, hover over or keyboard-focus the total for a tooltip
|
|
262
|
+
showing tokens excluding cache reads; Escape dismisses it. An estimated-spend sparkline
|
|
263
|
+
sits below; Messages and Time keep spend in a tile.
|
|
264
|
+
The per-day chart is stacked by tool, followed by supporting tiles, **tool, model and project mix**, highlights,
|
|
265
|
+
an **hour × weekday heatmap**, and token mix per tool. The 12-month activity calendar and
|
|
266
|
+
**Monthly rhythm** token chart let you click a day or month to select that period.
|
|
267
|
+
Both keep their historical window while honoring tool, provider, model, project, IDE,
|
|
268
|
+
device and exact-token filters; Monthly rhythm also has a table view with full counts.
|
|
269
|
+
With another device connected, **By device** compares each computer's share of the
|
|
270
|
+
selected measure (tokens, messages, estimated cost or active time), with a table view.
|
|
271
|
+
It follows the same date and usage filters as the rest of Overview.
|
|
272
|
+
|
|
273
|
+
**Cost** — total with per-active-day, 30-day run rate, per session and per prompt ·
|
|
274
|
+
cumulative spend by tool against the previous period · **cache hit rate and what caching
|
|
275
|
+
saved you** · spend by model, by project and by **token type** (what cache reads vs writes vs
|
|
276
|
+
output actually cost you) · effective rate by model, as *all tokens* or *per output* (the one
|
|
277
|
+
that's comparable across providers) · daily spend.
|
|
278
|
+
|
|
279
|
+
**Models** — provider cards (who made the model, independent of the tool that ran it) ·
|
|
280
|
+
sortable `model × tool` table with a ⚠ on any model missing a price · model timeline ·
|
|
281
|
+
provider share over time · **provider × tool matrix** · **model efficiency** (how often each
|
|
282
|
+
model's edits land first time, retries per edit, tokens and cost per prompt).
|
|
283
|
+
|
|
284
|
+
**Tools & agents** — active time, tool calls per prompt, context amplification, subagent
|
|
285
|
+
share, MCP and web calls, Copilot premium requests, Cursor's AI lines kept · top tool calls
|
|
286
|
+
· calls by category · **what your prompts were for** (building, fixing, refactoring,
|
|
287
|
+
testing, exploring, git, deploys… — each prompt classified by what the agent did: the files
|
|
288
|
+
it edited and the commands it ran; Claude Code & Codex) · **edits that landed first time** (one-shot rate per tool, retries,
|
|
289
|
+
and what the retried prompts cost) · **where you work** (IDE × tool) · MCP servers, with the
|
|
290
|
+
tools used out of those each server offered · **Skills** · the full tool list.
|
|
291
|
+
|
|
292
|
+
**Projects** — ranked by the chosen measure, concentration stats, and a searchable table
|
|
293
|
+
where clicking a row opens that project's sessions.
|
|
294
|
+
|
|
295
|
+
**Sessions** — real session titles, tool, project, model, tokens, cost, prompts, replies,
|
|
296
|
+
tool calls, active time, cache % — search, sort, and click any row for a detail panel.
|
|
297
|
+
Claude and Codex sessions also show completed compactions in the selected date range.
|
|
298
|
+
Claude records manual/auto counts, context before → after, and duration in the detail
|
|
299
|
+
panel. Codex checkpoints provide completion times; missing manual/auto triggers and
|
|
300
|
+
context sizes show **Not recorded**. Newer Codex completion records can supply
|
|
301
|
+
duration when their request/turn/thread identities and timing match exactly one checkpoint.
|
|
302
|
+
Missing or ambiguous timing shows **Unavailable**. Codex compaction request usage,
|
|
303
|
+
when logged, is already included in token/cost totals and is never counted again.
|
|
304
|
+
Compaction-only days remain visible. Events survive log deletion once recorded;
|
|
305
|
+
older ledger entries without event metadata say “Not recorded.” Context sizes are
|
|
306
|
+
separate from billed tokens: missing compaction request usage/cost is not inferred. Events
|
|
307
|
+
belong to the session and are not attributed to a model filter.
|
|
308
|
+
|
|
309
|
+
Use the pencil beside a session name (or **Rename** in its detail panel) to rename it
|
|
310
|
+
in the **original tool**. A warning shows the old/new names and exact target before
|
|
311
|
+
anything is saved. Close the session in its original tool before confirming, and reload
|
|
312
|
+
that tool if needed. Token, cost, prompt, tool-call and compaction records stay intact.
|
|
313
|
+
Previous title metadata is backed up privately in
|
|
314
|
+
`AgentTelemetryNative/session-title-backups/`, separately from the usage ledger.
|
|
315
|
+
This supports local Claude Code transcripts, Codex through its installed CLI’s
|
|
316
|
+
[official name API](https://learn.chatgpt.com/docs/app-server), and OpenCode’s SQLite
|
|
317
|
+
session stores. Other formats, remote sessions and deleted logs cannot be edited.
|
|
318
|
+
Tool/provider icons are bundled locally, including the OpenAI mark for Codex; no remote
|
|
319
|
+
logo requests occur. Their sources and licenses are in `static/tool-icons/README.md`.
|
|
320
|
+
|
|
321
|
+
**Optimize** — suggestions derived from your own logs, ranked by what they'd save: sessions
|
|
322
|
+
re-reading a very large context, thinking share, tool-heavy sessions that never delegated,
|
|
323
|
+
cache written but never read, a costly model doing light work, what each **Skill** costs,
|
|
324
|
+
edits that needed a retry, oversized **CLAUDE.md / AGENTS.md**, sessions that open heavier
|
|
325
|
+
than your leanest ones, wasted file reads, installed skills and agents you never use, and
|
|
326
|
+
MCP servers you never call, barely use, or load everywhere but use in one project. Nothing is shown unless
|
|
327
|
+
your data supports it, and because the estimates overlap they are never summed.
|
|
328
|
+
|
|
329
|
+
**Storage** — see below.
|
|
330
|
+
|
|
331
|
+
**Keyboard** — `1`/`7`/`3`/`9`/`a` ranges, `m` month-to-date, `,` / `.` previous / next
|
|
332
|
+
period, `Shift`+`T`/`C`/`M`/`A` tokens / cost / messages / active time, `[` sidebar, `/`
|
|
333
|
+
search, `t` theme, `r` refresh.
|
|
334
|
+
|
|
335
|
+
**Links** — every filter is in the address bar, so a reload, a bookmark or a pasted link opens
|
|
336
|
+
the same view. `?range=` takes `today`, `7d`, `30d`, `mtd`… or `custom` with
|
|
337
|
+
`&from=2026-09-01&to=2026-09-15`; then `?metric=`, `?tools=`, `?providers=`, `?models=`,
|
|
338
|
+
`?projects=`, `?ides=`, `?devices=` (repeat a param for each value), `?exact=1`, `?q=` for the
|
|
339
|
+
search box, and `#cost`, `#sessions`… for the tab. For example
|
|
340
|
+
`/?range=7d&metric=cost&tools=claude&projects=sims#cost`. Only what differs from the default
|
|
341
|
+
is written, and changing a filter never adds a browser-history entry.
|
|
342
|
+
|
|
343
|
+
**Version and updates** — the sidebar footer shows the running version. *Check for updates*
|
|
344
|
+
asks GitHub (the only time the dashboard goes online, and only when you click); *Update*
|
|
345
|
+
fast-forwards your checkout and restarts the server. It refuses if you have local edits or
|
|
346
|
+
commits that aren't on GitHub. A copy that isn't a git clone has no update button.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Storage — what these logs cost you in disk
|
|
351
|
+
|
|
352
|
+
The tools you use write a *lot* to disk, and nothing else tells you how much. The **Storage**
|
|
353
|
+
tab shows total footprint and per-tool bytes, a free-space gauge that warns when the drive is
|
|
354
|
+
nearly full, storage accumulation over time, the largest individual log files, **bytes per 1M
|
|
355
|
+
tokens** (which tool stores its history most expensively), AI data on disk AgentTelemetry does
|
|
356
|
+
*not* analyse, and copy-paste cleanup commands **generated for your own paths and your own
|
|
357
|
+
shell** (`find` on macOS/Linux, PowerShell on Windows). AgentTelemetry never deletes anything
|
|
358
|
+
itself.
|
|
359
|
+
|
|
360
|
+
Deleting old logs does **not** shrink your analytics — AgentTelemetry keeps every session it has
|
|
361
|
+
already parsed, so the cleanup is safe.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Cost notes (read this)
|
|
366
|
+
|
|
367
|
+
Costs are **estimates** computed as `tokens × price` — the tools store token counts, **not
|
|
368
|
+
dollars**, so cost is always derived. Rates live in `parser.py → PRICING` as
|
|
369
|
+
`(input, output, cache_write_5m, cache_write_1h, cache_read)` per 1M tokens; edit freely
|
|
370
|
+
(recomputed on each request, no re-parse needed).
|
|
371
|
+
|
|
372
|
+
- **Anthropic** rates are current list prices (Opus 5.5 $4/$20, Opus 5 & 4.x $5/$25, Sonnet 5
|
|
373
|
+
& 5.5 $2/$10, Sonnet 4.x $3/$15, Haiku 4.5 $1/$5; cache write 1.25×/2× input for 5-min/1-hour, cache
|
|
374
|
+
read 0.1× — 0.05× on Opus 5.5). **OpenAI** GPT-5.4/5.5/5.6/6 are verified from OpenAI docs;
|
|
375
|
+
older/other models are estimates.
|
|
376
|
+
- **Haiku 5.5** uses [Anthropic's published rates](https://platform.claude.com/docs/en/about-claude/pricing):
|
|
377
|
+
$0.10/$0.50 per million input/output tokens up to 100K prompt tokens, $0.50/$2.50
|
|
378
|
+
above 100K. The threshold includes cached input and applies to each request.
|
|
379
|
+
Available Claude logs backfill this pricing detail on a normal restart; token and
|
|
380
|
+
message counts stay unchanged. Older archives/peers and other tools without that
|
|
381
|
+
detail use the short-prompt rate. Optimize model substitutions conservatively use
|
|
382
|
+
the higher tier when the target request size is unknown.
|
|
383
|
+
- **Price changes are date-aware.** When a vendor cuts a price (OpenAI's GPT-5.6 cuts of
|
|
384
|
+
2026-07-30 and 2026-08-21), usage from before the change keeps the rate it had then —
|
|
385
|
+
see `parser.py → PRICE_HISTORY`.
|
|
386
|
+
- **These are API-equivalent values.** If you're on a subscription (Claude Max/Pro, Codex,
|
|
387
|
+
Copilot), you don't pay per token — the $ is "what this would cost at API rates."
|
|
388
|
+
- **Cursor** rarely logs token counts, and **older Copilot chats** have none, so their tokens
|
|
389
|
+
(and thus $) are rough. Current Copilot builds log real per-request tokens, which are used.
|
|
390
|
+
Copilot's honest metric is **request count** and its **premium-request** total (both shown);
|
|
391
|
+
Cursor's is **messages, tool calls and AI lines kept** (also shown).
|
|
392
|
+
- **Billing details that change the price are applied**: prompt-cache writes at their own
|
|
393
|
+
rate (Claude and GPT-5.6/GPT-6), Claude fast mode, US-only inference (1.1x) and web
|
|
394
|
+
searches ($10/1K). A forked or subagent Codex thread's replay of its parent is skipped,
|
|
395
|
+
so it isn't billed twice.
|
|
396
|
+
- A model with no price row reads as **$0** — add it to `PRICING` (see below).
|
|
397
|
+
- **Gemini** (2.5, 3, 3.1 and 3.5 to 3.8: Pro, Flash, Flash-Lite, Computer Use) is priced
|
|
398
|
+
when it runs through supported tools, at the Standard rate for prompts up to 200K
|
|
399
|
+
tokens. Live, TTS, image and embedding models are not priced, and nor are the higher Pro rate
|
|
400
|
+
for longer prompts or audio input. The Gemini CLI itself writes no token counts to read.
|
|
401
|
+
- **Gemini 4 Argon** is recognized across the supported tools and uses Google's
|
|
402
|
+
[announced introductory rates](https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-4-argon/):
|
|
403
|
+
$2 input, $10 output and $0.10 cached input per 1M tokens. Access is still limited to
|
|
404
|
+
trusted testers, and Google has not listed a public API model ID. These are API-equivalent
|
|
405
|
+
estimates for Argon usage found in logs. The later $4/$20 rate has no effective date yet
|
|
406
|
+
and is not applied ahead of time; cache storage charges are not modeled.
|
|
407
|
+
|
|
408
|
+
## Note on log retention
|
|
409
|
+
|
|
410
|
+
Some tools delete old logs. **Claude Code** prunes transcripts after `cleanupPeriodDays`
|
|
411
|
+
(default **30**); **Codex** keeps everything. The dashboard also keeps parsed sessions in
|
|
412
|
+
its cache even after a tool deletes the on-disk log, so totals don't silently shrink once seen.
|
|
413
|
+
|
|
414
|
+
You can change Claude Code's retention window from the dashboard itself — the **⚙** button
|
|
415
|
+
at the foot of the sidebar edits `cleanupPeriodDays` in your own `~/.claude/settings.json` (leave it blank
|
|
416
|
+
to fall back to the tool's default). The write is atomic and keeps a `.bak`; every other
|
|
417
|
+
setting in the file is preserved untouched. It's the only file outside its own cache that the
|
|
418
|
+
dashboard ever writes.
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Extending it
|
|
423
|
+
|
|
424
|
+
- **Add a model's price / fix an unknown model:** edit `PRICING` (and, if needed, the
|
|
425
|
+
model-name normalizer) in `parser.py`. Verify rates against the vendor's docs.
|
|
426
|
+
- **Add a new tool:** add its paths + a `parse_*` function in `parser.py`, wire `discover()`
|
|
427
|
+
and `update_file()`, then add it to `SRC`/`ORDER` in `static/core.js` and give it a
|
|
428
|
+
`--t-<source>` colour in `static/app.css`. The tool colours are a colour-blind-validated
|
|
429
|
+
palette whose *order* is the safety mechanism — see AGENTS.md before changing them.
|
|
430
|
+
|
|
431
|
+
See **[AGENTS.md](AGENTS.md)** for a concise, agent-oriented guide (any coding agent can run
|
|
432
|
+
and extend this from that file).
|
|
433
|
+
|
|
434
|
+
## Files
|
|
435
|
+
|
|
436
|
+
`dashboard.py` (server + cache + cost + `/api/storage`) · `parser.py` (log parsers + pricing) ·
|
|
437
|
+
`index.html` (shell) · `static/app.css` · `static/core.js` · `static/charts.js` ·
|
|
438
|
+
`static/views.js` · `chart.umd.min.js` (vendored Chart.js) · `AGENTS.md` · `run.sh`.
|
|
439
|
+
|
|
440
|
+
## Install it as an app (optional)
|
|
441
|
+
|
|
442
|
+
The dashboard can run as a standalone window in your Dock or taskbar. It's **off by
|
|
443
|
+
default** — open the **⚙** menu and turn on *Install as an app*, then use your browser's
|
|
444
|
+
Install / Add to Dock. That registers a service worker so the shell still opens when
|
|
445
|
+
`dashboard.py` isn't running; your usage data is never cached, `/api/` always hits the live
|
|
446
|
+
server. Turning it off again unregisters the worker and clears its cache.
|
|
447
|
+
|
|
448
|
+
## Your devices (optional)
|
|
449
|
+
|
|
450
|
+
Use your coding agents on more than one computer? You can see them all in one dashboard.
|
|
451
|
+
It's **off by default** and works over your **local network** only. Open **⚙ → Your devices**:
|
|
452
|
+
|
|
453
|
+
1. On the computer you want to read from, click **Share this device…**. It shows an
|
|
454
|
+
address (like `your-mac.local:7879`) and a pairing code.
|
|
455
|
+
2. On the computer you're looking from, enter that address and code, then click **Connect…**.
|
|
456
|
+
3. To see each one from the other, do both steps on both.
|
|
457
|
+
|
|
458
|
+
Once connected, a **Devices** filter appears and the header reads "…from all tools **on all
|
|
459
|
+
devices**…". The sidebar device card also becomes a dropdown: choose **All devices** or
|
|
460
|
+
one computer. Both controls share the same filter, which is preserved in the URL.
|
|
461
|
+
The connected device's usage is fetched every minute, and a copy is kept in
|
|
462
|
+
`.peers/` so it still shows while that computer is asleep. Disconnecting deletes the copy.
|
|
463
|
+
|
|
464
|
+
What sharing sends: session titles (often the start of a prompt), project and branch names,
|
|
465
|
+
log file paths, models, token counts, costs and times. Full prompts, replies and file
|
|
466
|
+
contents are never sent. Sharing opens one read-only port (7879) that answers only to the
|
|
467
|
+
pairing code. The dashboard itself stays on `127.0.0.1`. The connection is **not
|
|
468
|
+
encrypted**, so share only on a network you trust. The setup checks on the Optimize tab
|
|
469
|
+
(instruction files, installed skills, MCP servers) and the Storage tab still describe only
|
|
470
|
+
the computer you're looking at. `.peers.json` and `.peers/` are gitignored.
|
|
471
|
+
|
|
472
|
+
**If it can't connect**, the error says which of these it is:
|
|
473
|
+
|
|
474
|
+
- **The other device's firewall.** On Windows, allow Python on *private* networks when asked,
|
|
475
|
+
and set the Wi-Fi to Private (Settings → Network & internet). On macOS, allow incoming
|
|
476
|
+
connections when asked.
|
|
477
|
+
- **A VPN** (like 1.1.1.1 with WARP) on either device can get in the way.
|
|
478
|
+
- **A `.local` name that doesn't resolve.** Use the IP address shown next to it instead.
|
|
479
|
+
|
|
480
|
+
Once connected, a device that moves to a new IP address is still found: every answer
|
|
481
|
+
lists the other addresses it can be reached at, and those are tried when the saved one
|
|
482
|
+
stops working.
|
|
483
|
+
|
|
484
|
+
## Contributing
|
|
485
|
+
|
|
486
|
+
See **[CONTRIBUTING.md](CONTRIBUTING.md)** — it covers the setup, the hard rules
|
|
487
|
+
(stdlib only, nothing hardcoded, never commit your cache), how to add a tool source or
|
|
488
|
+
a model price, and how to test a change. **[AGENTS.md](AGENTS.md)** is the architecture
|
|
489
|
+
guide. Please read the note on setting your git email before your first commit.
|
|
490
|
+
|
|
491
|
+
Found a security problem? See **[SECURITY.md](SECURITY.md)** — don't open a public issue.
|
|
492
|
+
|
|
493
|
+
## License
|
|
494
|
+
|
|
495
|
+
MIT — see [LICENSE](LICENSE).
|