tokentrail 0.1.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.
Files changed (34) hide show
  1. tokentrail-0.1.0/LICENSE +202 -0
  2. tokentrail-0.1.0/NOTICE +4 -0
  3. tokentrail-0.1.0/PKG-INFO +423 -0
  4. tokentrail-0.1.0/README.md +388 -0
  5. tokentrail-0.1.0/pyproject.toml +80 -0
  6. tokentrail-0.1.0/setup.cfg +4 -0
  7. tokentrail-0.1.0/src/tokentrail/__init__.py +3 -0
  8. tokentrail-0.1.0/src/tokentrail/__main__.py +3 -0
  9. tokentrail-0.1.0/src/tokentrail/adapters/__init__.py +21 -0
  10. tokentrail-0.1.0/src/tokentrail/adapters/base.py +34 -0
  11. tokentrail-0.1.0/src/tokentrail/adapters/claude_code.py +126 -0
  12. tokentrail-0.1.0/src/tokentrail/adapters/generic_jsonl.py +62 -0
  13. tokentrail-0.1.0/src/tokentrail/analytics.py +111 -0
  14. tokentrail-0.1.0/src/tokentrail/cli.py +318 -0
  15. tokentrail-0.1.0/src/tokentrail/config.py +61 -0
  16. tokentrail-0.1.0/src/tokentrail/emit.py +78 -0
  17. tokentrail-0.1.0/src/tokentrail/git_collector.py +99 -0
  18. tokentrail-0.1.0/src/tokentrail/mirror.py +206 -0
  19. tokentrail-0.1.0/src/tokentrail/models.py +109 -0
  20. tokentrail-0.1.0/src/tokentrail/pricing.py +62 -0
  21. tokentrail-0.1.0/src/tokentrail/segment.py +153 -0
  22. tokentrail-0.1.0/src/tokentrail/server.py +75 -0
  23. tokentrail-0.1.0/src/tokentrail/service.py +104 -0
  24. tokentrail-0.1.0/src/tokentrail/state.py +83 -0
  25. tokentrail-0.1.0/src/tokentrail/static/dashboard.html +499 -0
  26. tokentrail-0.1.0/src/tokentrail/store.py +182 -0
  27. tokentrail-0.1.0/src/tokentrail/sync.py +109 -0
  28. tokentrail-0.1.0/src/tokentrail.egg-info/PKG-INFO +423 -0
  29. tokentrail-0.1.0/src/tokentrail.egg-info/SOURCES.txt +32 -0
  30. tokentrail-0.1.0/src/tokentrail.egg-info/dependency_links.txt +1 -0
  31. tokentrail-0.1.0/src/tokentrail.egg-info/entry_points.txt +2 -0
  32. tokentrail-0.1.0/src/tokentrail.egg-info/requires.txt +14 -0
  33. tokentrail-0.1.0/src/tokentrail.egg-info/top_level.txt +1 -0
  34. tokentrail-0.1.0/tests/test_telemetry.py +531 -0
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
@@ -0,0 +1,4 @@
1
+ TokenTrail
2
+ Copyright 2026 Sunil Bodeddula
3
+
4
+ This product is licensed under the Apache License, Version 2.0 (see LICENSE).
@@ -0,0 +1,423 @@
1
+ Metadata-Version: 2.4
2
+ Name: tokentrail
3
+ Version: 0.1.0
4
+ Summary: Local telemetry and dashboard for AI coding agents: tokens, tools, skills, health and shipped code.
5
+ Author: Sunil Bodeddula
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/sunil-bodeddula-pro/tokentrail
8
+ Project-URL: Issues, https://github.com/sunil-bodeddula-pro/tokentrail/issues
9
+ Keywords: ai-agents,observability,telemetry,llm,claude-code,dashboard,tokens
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Environment :: Web Environment
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Classifier: Topic :: System :: Monitoring
20
+ Requires-Python: >=3.12
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ License-File: NOTICE
24
+ Provides-Extra: gcs
25
+ Requires-Dist: google-cloud-storage>=2.10; extra == "gcs"
26
+ Provides-Extra: s3
27
+ Requires-Dist: boto3>=1.28; extra == "s3"
28
+ Provides-Extra: all
29
+ Requires-Dist: google-cloud-storage>=2.10; extra == "all"
30
+ Requires-Dist: boto3>=1.28; extra == "all"
31
+ Provides-Extra: dev
32
+ Requires-Dist: ruff>=0.17; extra == "dev"
33
+ Requires-Dist: mypy>=2.4; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # TokenTrail
37
+
38
+ [![CI](https://github.com/sunil-bodeddula-pro/tokentrail/actions/workflows/ci.yml/badge.svg)](https://github.com/sunil-bodeddula-pro/tokentrail/actions/workflows/ci.yml)
39
+ [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
40
+
41
+ **See what your AI agents actually do with your tokens.** TokenTrail is local-first observability for AI agents. It shows how they spend tokens, call tools and load skills, where they get stuck, and how all of that turns into shipped code. It runs on your own machine.
42
+
43
+ ![The TokenTrail dashboard: six KPI cards (sessions, tokens, velocity, healthy share, high-velocity rate, tool calls) above the chart grid, with demo data](docs/images/overview.png)
44
+
45
+ <sub>All screenshots use the [demo data](#try-it-with-demo-data), not real sessions.</sub>
46
+
47
+ ## Why TokenTrail?
48
+
49
+ AI coding agents now do a lot of real work, but most of it happens out of sight. A session runs for twenty minutes, burns half a million tokens, and you only see the final answer. Was it efficient? Did it loop on a failing test? Did it ever use the skill you wrote for exactly this task? Is the expensive model worth it for this kind of work? And when the agent's history is cleared, the evidence is gone too.
50
+
51
+ TokenTrail answers those questions from data your agents already leave on disk, without changing how you work.
52
+
53
+ ## What it does
54
+
55
+ 1. **Collects** each agent's local session logs as they're written. Claude Code works out of the box, and any other agent can write a simple [JSON-lines event format](docs/event-format.md).
56
+ 2. **Keeps its own record** in a store of plain JSON files, synced every 30 seconds. Clearing an agent's history loses nothing, and nothing is parsed twice.
57
+ 3. **Measures every request:** tokens (input, output, cache reads and writes, reasoning), cache hit rate, estimated cost, steps, tool calls and errors, file writes, skills and subagents.
58
+ 4. **Classifies each run's health:** High-Velocity, Positive, Tool Loops, Wandering (lots of steps, nothing written) or High Error Rate. You can see at a glance which requests went well and which didn't.
59
+ 5. **Connects agent work to shipped code** by reading the git history of the repositories the agents worked in: your commits, AI-credited commits, linked issues, and tokens and cost per commit.
60
+ 6. **Shows it all on a local dashboard,** with filters by time, agent, model, outcome and machine, ten charts, a searchable session table, and an inspector for every run.
61
+ 7. **Optionally mirrors the store** to Google Cloud Storage, S3 or a shared folder, so you can see several machines in one place. Prompt text is removed before upload.
62
+
63
+ ## Questions it answers
64
+
65
+ | Question | Where to look |
66
+ | :--- | :--- |
67
+ | How much are my agents costing me, and is prompt caching working? | Tokens consumed card (cache hit %, estimated cost), Token anatomy |
68
+ | Which requests went badly, and why? | Session health chart, the Health filter, the inspector (longest repeat, errors, writes) |
69
+ | Is the agent stuck in a loop re-running the same failing command? | Tool Loops outcome, Outcome token waste ("tool loop inflation") |
70
+ | Which model gets my kind of work done for the fewest tokens? | Token spend vs task effectiveness (tokens per successful run, by model) |
71
+ | Are my skills and agent instructions being used? | Top skills activated |
72
+ | Is the agent reading sensibly, or dumping whole files and logs? | Tool invocation frequency (read-to-edit ratio), Token anatomy (tool output share) |
73
+ | Which repositories take the most agent time? | Workspace distribution and turn latency |
74
+ | What does a commit cost me in agent tokens and dollars? | Cross-Domain ROI |
75
+
76
+ ## Who it helps
77
+
78
+ - **Developers using AI agents every day** can tighten prompts, catch loops early, keep cache hit rates high, and pick the right model for each job.
79
+ - **Authors of skills, agent instructions and custom agents** can check whether their skills fire and whether a change made runs faster or slower.
80
+ - **Team leads and platform teams** can mirror several machines into one bucket and see usage, cost and health across the team, with prompts redacted.
81
+ - **Anyone curious about cost** gets an API-equivalent estimate per run, per model and per commit, even on a flat-rate plan.
82
+
83
+ ## What it isn't
84
+
85
+ - **Not a cloud service.** There's no account and no backend. Data stays on your machine unless you configure a remote.
86
+ - **Not a tracing SDK for production LLM apps.** It watches agents you run, from their logs, with no code changes. To trace an application you're deploying, use an APM or LLM tracing tool.
87
+ - **It doesn't call any model.** Analysis is plain counting, so using TokenTrail costs no tokens.
88
+ - **Costs are estimates** at API list prices, not your invoice.
89
+
90
+ ## Screenshots
91
+
92
+ | | |
93
+ | :---: | :---: |
94
+ | ![Charts: session health donut, top skills, tool frequency and model step velocity](docs/images/charts.png) | ![Session inspector for a run flagged as a tool loop: tokens, tools, longest repeat, duration and cost](docs/images/inspector.png) |
95
+ | **Health, skills, tools and velocity.** Ten charts in all, grouped by tokens, effectiveness, time and tools. | **The inspector.** One run flagged as a tool loop: the same command repeated six times. |
96
+ | ![Cross-Domain ROI: tokens and agent steps per commit, cost per commit, cache savings, linked issues](docs/images/roi.png) | |
97
+ | **Cross-Domain ROI.** Agent tokens, steps and cost per commit, and what caching saved. | |
98
+
99
+ ## Try it with demo data
100
+
101
+ No agent needed. The demo script writes a month of made-up sessions for three agents and four small git repositories into one folder. Your real history and store aren't touched.
102
+
103
+ ```bash
104
+ git clone https://github.com/sunil-bodeddula-pro/tokentrail && cd tokentrail
105
+ python3 examples/demo_data.py # writes ./tokentrail-demo
106
+ PYTHONPATH=src python3 -m tokentrail --config tokentrail-demo/config.json
107
+ ```
108
+
109
+ Then open http://127.0.0.1:8765. Delete the `tokentrail-demo` folder when you're done.
110
+
111
+ ---
112
+
113
+ ## Table of contents
114
+
115
+ 1. [Install and quick start](#1-install-and-quick-start)
116
+ 2. [Commands and settings](#2-commands-and-settings)
117
+ 3. [The store, remote mirrors and privacy](#3-the-store-remote-mirrors-and-privacy)
118
+ 4. [Architecture](#4-architecture)
119
+ 5. [Dashboard guide](#5-dashboard-guide)
120
+ 6. [Engineer's playbook](#6-engineers-playbook)
121
+ 7. [Adding an agent](#7-adding-an-agent)
122
+ 8. [Pricing](#8-pricing)
123
+ 9. [Co-located agent skill](#9-co-located-agent-skill)
124
+ 10. [Testing and contributing](#10-testing-and-contributing)
125
+
126
+ ---
127
+
128
+ ## 1. Install and quick start
129
+
130
+ ```bash
131
+ pip install tokentrail # or: pipx install tokentrail
132
+ pip install 'tokentrail[gcs]' # add Google Cloud Storage support
133
+ pip install 'tokentrail[s3]' # add AWS S3 (and S3-compatible) support
134
+
135
+ tokentrail init # choose the store folder and an optional remote; runs the first sync
136
+ tokentrail # open the dashboard at http://127.0.0.1:8765 (it keeps syncing while open)
137
+ tokentrail service install # optional: keep syncing in the background at login
138
+ ```
139
+
140
+ Until the first release is on PyPI, install from GitHub with `pip install git+https://github.com/sunil-bodeddula-pro/tokentrail`. From a source checkout, run `pip install -e .` or use `PYTHONPATH=src python3 -m tokentrail …`.
141
+
142
+ `tokentrail init` asks three questions; `--yes` accepts the defaults:
143
+
144
+ | Question | Default |
145
+ | :--- | :--- |
146
+ | Local store folder | `~/.tokentrail/store` |
147
+ | Remote mirror | none (`gs://bucket/path`, `s3://bucket/path`, or a folder) |
148
+ | Seconds between syncs | 30 |
149
+
150
+ ---
151
+
152
+ ## 2. Commands and settings
153
+
154
+ | Command | What it does |
155
+ | :--- | :--- |
156
+ | `tokentrail init` | Save settings, check the remote is reachable, run the first sync. `--service` also installs the background service; `--keep-prompts-remote` uploads prompt text too |
157
+ | `tokentrail` or `tokentrail dashboard` | Pull other machines' data, sync, and serve the dashboard. `--port`, `--host`, `--sync-interval SECONDS` (0 = read the store only) |
158
+ | `tokentrail daemon` | Sync on a timer with no dashboard. This is what the service runs |
159
+ | `tokentrail sync` | Sync once and exit |
160
+ | `tokentrail pull` | Download other machines' data from the remote, and restore any of this machine's files missing locally |
161
+ | `tokentrail status` | Where data lives, how much there is, which machines, when it last synced |
162
+ | `tokentrail summary --days 30` | Headline numbers in the terminal |
163
+ | `tokentrail export --json F --csv F` | Everything as JSON (runs, commits, KPIs, breakdowns, ROI), or one CSV row per task run |
164
+ | `tokentrail service install \| uninstall \| print` | Run `daemon` at login: a systemd user unit (Linux), a launchd agent (macOS) or a Task Scheduler task (Windows). `print` shows what would be installed |
165
+
166
+ **Sync interval:** `--sync-interval SECONDS` (or `--interval`) on `init`, `dashboard` and `daemon` sets how often TokenTrail syncs, for example `tokentrail --port 8765 --sync-interval 60`. Without it, the `sync_interval` setting is used, which is 30 seconds unless you changed it. With `init`, the value is saved to the config. The dashboard page refreshes at the same interval until you pick another one in its Auto-sync menu.
167
+
168
+ Options that work with every command except `service`: `--config FILE`, `--store DIR`, `--remote URI`, `--no-remote`, `--days N` (0 = everything) and `--no-git`.
169
+
170
+ Settings live in `~/.config/tokentrail/config.json` (`%APPDATA%\tokentrail\config.json` on Windows; `TOKENTRAIL_CONFIG` points elsewhere). Command-line options win over the file.
171
+
172
+ | Setting | Default | Meaning |
173
+ | :--- | :--- | :--- |
174
+ | `store` | `~/.tokentrail/store` | The local store, the system of record |
175
+ | `remote` | `""` | Optional mirror: `gs://…`, `s3://…`, `file://…` or a folder path |
176
+ | `redact_remote` | `true` | Remove prompt text and titles before upload |
177
+ | `sync_interval` | 30 | Seconds between syncs |
178
+ | `machine_id` | `""` | Blank: a stable name, your hostname plus four hex characters, is created and kept in `<store>/.machine-id` |
179
+ | `adapters` | `["claude-code", "generic"]` | Which sources to read |
180
+ | `claude_dir` | `~/.claude/projects` | Claude Code transcripts |
181
+ | `events_dir` | `~/.tokentrail/events` | Generic events from any agent |
182
+ | `pricing` | `""` | JSON file overriding prices per model ([Pricing](#8-pricing)) |
183
+ | `repos` | `[]` | Extra git repositories to include, besides those the agents worked in |
184
+ | `author_emails` | `[]` | Count commits by these emails as yours (default: `git config user.email`) |
185
+ | `ai_tag` | `""` | Extra regex marking AI-assisted commits, besides `Co-Authored-By` trailers |
186
+ | `git_days` | 365 | How much git history to read |
187
+
188
+ ---
189
+
190
+ ## 3. The store, remote mirrors and privacy
191
+
192
+ ### The store
193
+
194
+ The store is a folder of plain JSON files. There is one file per conversation, written atomically (to a temporary file, then renamed into place):
195
+
196
+ ```
197
+ ~/.tokentrail/store/
198
+ .machine-id this machine's name
199
+ .mirror-state.json what has been uploaded and downloaded (never uploaded)
200
+ v1/<machine>/
201
+ runs/<agent>/<conversation>.json the task runs of one conversation
202
+ commits/<repo>.json commits from that repository
203
+ manifest.json counts and the last sync time
204
+ sources.json which agent files have been read, by size and mtime (never uploaded)
205
+ v1/<other-machine>/… pulled from the remote
206
+ ```
207
+
208
+ - **Incremental:** a sync re-reads an agent file only when its size or modification time changes, or when prices change. A quiet sync takes milliseconds and costs no tokens; TokenTrail never calls a model.
209
+ - **Never deletes:** when an agent's history file disappears, its conversations stay in the store. When a file shrinks, the stored runs and the new runs are merged, so nothing is lost.
210
+ - **Git** is re-read every five minutes, not every sync, and commits are merged by SHA.
211
+
212
+ ### Remote mirrors
213
+
214
+ | Remote | Needs | Credentials |
215
+ | :--- | :--- | :--- |
216
+ | `gs://bucket/prefix` | `pip install 'tokentrail[gcs]'` | Application Default Credentials (`gcloud auth application-default login`, or a service account) |
217
+ | `s3://bucket/prefix` | `pip install 'tokentrail[s3]'` | The usual AWS chain (`AWS_PROFILE`, environment variables, SSO, instance roles). For MinIO, Cloudflare R2 and other S3-compatible stores, set `AWS_ENDPOINT_URL` |
218
+ | `file:///path` or a path | nothing | A network drive or a synced folder |
219
+
220
+ - **Push:** after each sync, this machine's changed files are uploaded. Files are compared by MD5, so an unchanged file is never sent twice.
221
+ - **Pull:** when the dashboard starts, and every five minutes while it runs, other machines' new files are downloaded. Each machine writes only under its own `v1/<machine>/` prefix, so machines never overwrite each other.
222
+ - **Restore:** `tokentrail pull` on a machine whose store was wiped brings its files back from the remote. They come back redacted if they were uploaded redacted.
223
+
224
+ ### Privacy
225
+
226
+ - **Local only by default.** The dashboard binds to `127.0.0.1`. Your prompts are in the data, so don't expose the dashboard on a network.
227
+ - **Redacted remotes.** With `redact_remote` on (the default), the `prompt` and `title` of every run are emptied before upload, and the run is marked `redacted`. Token counts, tool names, models, workspaces and timings are still uploaded.
228
+ - **Use a private bucket.** Workspace and repository names, commit subjects and author emails are not redacted.
229
+ - **No telemetry about you.** TokenTrail makes no network calls except to the remote you configure.
230
+
231
+ ---
232
+
233
+ ## 4. Architecture
234
+
235
+ ```
236
+ agent logs ──▶ adapter ──▶ Events ──▶ segment.build_runs ──▶ TaskRun records ──┐
237
+ git repos ──▶ git_collector ──▶ Commit records ───────────────────────────────┤
238
+ ▼
239
+ Syncer (every 30 s) ──▶ Store (JSON files) ◀──▶ Mirror (gs:// · s3:// · folder)
240
+ │
241
+ ▼
242
+ TelemetryState ──▶ HTTP API ──▶ dashboard, summary, export
243
+ ```
244
+
245
+ - **Adapters** (`adapters/`) turn one agent's logs into normalized `Event`s: prompt, response, tool call, tool result and title. This is the only agent-specific code.
246
+ - **Segmentation** (`segment.py`) groups events into task runs, totals tokens, tools, errors, writes and skills, prices each step, and classifies health.
247
+ - **Syncer, Store and Mirror** (`sync.py`, `store.py`, `mirror.py`) keep the durable record described above.
248
+ - **Analytics** (`analytics.py`) computes the KPIs for the CLI and the JSON export. The dashboard computes the same figures in the browser, so its filters respond instantly.
249
+
250
+ | Source | Default path | What's extracted |
251
+ | :--- | :--- | :--- |
252
+ | Claude Code | `~/.claude/projects/<project>/<session>.jsonl` | Prompts, per-response token usage (input, output, cache read and write, reasoning), model, tool calls and their errors, skills (`Skill` tool, or reads of `*/skills/<name>/SKILL.md`), subagent steps, working directory, title |
253
+ | Generic events | `~/.tokentrail/events/**/*.jsonl` | The same fields, written by any agent ([format](docs/event-format.md)) |
254
+ | Git history | Repositories found from the sessions' working directories, plus `repos` | Conventional commit type and scope, linked issues (`#123`, `ABC-123`, `b/123`), your commits, and AI-credited commits (`Co-Authored-By: Claude / Copilot / Gemini / Cursor / Codex…`, or `ai_tag`) |
255
+
256
+ The browser polls `/api/telemetry` at the interval you choose (15 s, 30 s, 60 s, 5 min or off), and again when you switch back to the tab. **Sync now** forces an immediate sync through `POST /api/sync`.
257
+
258
+ ---
259
+
260
+ ## 5. Dashboard guide
261
+
262
+ ### 5.1 Top bar
263
+
264
+ - **Mode tabs:**
265
+ - **TokenTrail:** sessions, tokens, models, skills and tool friction.
266
+ - **Code Deliverables:** your local git commits.
267
+ - **Cross-Domain ROI:** agent spend set against commits shipped.
268
+ - **Auto-sync and Sync now:** how often the page refreshes, the time of the last sync, and a manual re-scan button.
269
+ - **Theme toggle:** dark (the default) or light. Your choice is remembered.
270
+
271
+ ### 5.2 Filter bar
272
+
273
+ - **Time window:** Today, Last 7 days, Last 30 days or All, or a custom From/To range. It applies to every KPI, chart and table.
274
+ - **Granularity:**
275
+ - **Task runs** (default) split each conversation at every prompt (`<id>#1`, `<id>#2`…). Use this to measure what one request costs.
276
+ - **Conversations** merge a whole thread into one record. Use this to measure what a feature cost end to end.
277
+ - **Search:** case-insensitive, across run ID, prompt, title, model, workspace, agent, skills and tool names.
278
+ - **Agent, model and health outcome filters:** narrow down to one agent, one model or one outcome to see why runs struggled.
279
+ - **Machine filter:** appears when the store holds more than one machine's data.
280
+ - **Store line:** under the top bar, the store path, this machine's name, the remote and the last sync.
281
+
282
+ ### 5.3 KPI cards
283
+
284
+ | Card | Definition | How to read it |
285
+ | :--- | :--- | :--- |
286
+ | Total sessions | Task runs (or conversations) in the filter, plus distinct conversations | Overall usage volume |
287
+ | Tokens consumed | `input + cache_write + output`; the sub-label shows cache reads, **cache hit %** = `cache_read / (input + cache_write + cache_read)`, and estimated cost | Target cache hit **≥ 85%**: prompt caching is working and input costs fall sharply |
288
+ | Average velocity | `steps / sessions`, where a step is one model response | Lower is faster. 15 to 35 steps per run means well-scoped prompts; over 60 suggests broad prompts or retry loops |
289
+ | Healthy sessions | Share of runs that are High-Velocity or Positive | Target **≥ 80%**. Below 75%, look at the Tool Loops and High Error Rate slices |
290
+ | High velocity rate | Share of runs finishing in **≤ 30 steps with 0 errors** | One-shot efficiency. 50% or more at task-run granularity means prompts and skills lead the agent straight to the right files |
291
+ | Tool invocations | Total tool calls, and **tool error rate** = `errors / max(tool_calls, steps)` | Target **< 1.5%**. Spikes usually mean failing builds or tests, missing environment variables, or stale edit targets |
292
+
293
+ ### 5.4 The ten charts
294
+
295
+ Chart sub-tabs filter them: All (10), Tokens (4), Effectiveness (4), Time and latency (3), Tools and skills (3).
296
+
297
+ 1. **Model utilization** (donut): share of sessions per model. Check that light work runs on fast models and hard work on strong ones.
298
+ 2. **Token anatomy** (donut): new context split into **tool outputs**, **model reasoning**, **model responses** and **user instructions**. Tool outputs and prompts are estimated at 4 characters per token. When tool outputs dominate (often over 90%), prefer targeted searches and line-bounded reads over dumping whole files or logs.
299
+ 3. **Session health and friction** (donut): the five mutually exclusive outcomes, checked in this order.
300
+
301
+ | Outcome | Rule |
302
+ | :--- | :--- |
303
+ | Failure: High Error Rate | ≥ 4 tool errors, or an error rate ≥ 20% with ≥ 6 steps |
304
+ | Friction: Tool Loops | ≥ 4 identical consecutive tool calls on the same target |
305
+ | Wandering: Zero File Writes | > 45 steps with no file writes and no skills |
306
+ | High-Velocity (≤30 steps) | ≤ 30 steps and 0 errors |
307
+ | Positive (Standard) | Everything else: clean, longer runs |
308
+
309
+ 4. **Top skills activated** (bars): skills the agent loaded. If a skill you wrote never appears, sharpen the trigger words in its description.
310
+ 5. **Tool invocation frequency** (bars), with the read-to-edit ratio. Healthy is about 3:1 to 5:1. If a shell tool dwarfs reads and edits by 10:1, the agent is probably using shell commands to view files or polling in a loop.
311
+ 6. **Model step velocity** (bars): average steps per run by model. Lower finishes faster.
312
+ 7. **Token spend vs task effectiveness** (bars and line): average tokens per run, **tokens per healthy run**, and success rate by model, with the most effective model named. Tokens per success is the real efficiency measure: a model that costs more per run but rarely loops often costs less per solved task.
313
+ 8. **Outcome token waste** (bars): average tokens per outcome, with a **Tool loop inflation** banner showing extra tokens burned by looping runs compared with clean ones.
314
+ 9. **Daily activity and token volume** (wide): sessions per day for the last 14 active days, with tokens as a line.
315
+ 10. **Workspace distribution and turn latency** (wide): sessions per repository, with average steps and seconds per step.
316
+
317
+ ### 5.5 Session explorer and inspector
318
+
319
+ - **Table:** run ID, prompt, agent, model, workspace, steps, tokens, cache hit, tools, skills, health and start time. Click a column to sort.
320
+ - **Inspector:** click a row to open it. It shows the machine, the full prompt (or "redacted" for runs pulled from a redacted remote), every tool with its call count, skills, writes and errors, the longest repeat, duration and seconds per step, the token split, estimated cost and cache savings.
321
+
322
+ ### 5.6 Code Deliverables
323
+
324
+ - **KPIs:** matching commits, your commits, AI-credited commits and linked issues.
325
+ - **Charts:** commits by repository, and by conventional commit type.
326
+ - **Table:** recent commits.
327
+ - **Filters:** the time window and search apply here too.
328
+
329
+ ### 5.7 Cross-Domain ROI
330
+
331
+ - **KPIs:**
332
+ - Tokens per commit of yours.
333
+ - Agent steps per commit.
334
+ - Estimated cost per commit.
335
+ - Context cache savings: what cached input would have cost at the full input price, minus what it did cost.
336
+ - Issues linked.
337
+ - **Chart:** tokens against commits by day.
338
+
339
+ Sessions and commits are matched by day only. Read it as correlation, not attribution.
340
+
341
+ ---
342
+
343
+ ## 6. Engineer's playbook
344
+
345
+ | Signal | Likely cause | What to do |
346
+ | :--- | :--- | :--- |
347
+ | Tool loop inflation above +300% | The agent keeps re-running a failing build or test, or retrying a broken edit | Stop the turn after the same command fails twice. Put the exact test and lint commands in your agent instructions file or a skill |
348
+ | Wandering: Zero File Writes runs | An open-ended prompt with no clear deliverable | Name the target files or package in the prompt, or plan first for exploratory work |
349
+ | Cache hit below 75% | Many short one-turn conversations, or switching workspaces mid-thread | Keep related work in one thread and workspace. Compact rather than restart when context grows |
350
+ | Rare skill activations on common workflows | The agent solves recurring tasks from scratch | Write or refine a skill with explicit trigger phrases in its description |
351
+ | Tool error rate above 1.5% | Failing commands, missing environment, stale edit targets | Open the High Error Rate runs in the inspector and fix the commonest failing tool |
352
+ | One model has a far higher tokens per success | It loops or wanders more on your work | Route that kind of task to the more effective model |
353
+
354
+ ---
355
+
356
+ ## 7. Adding an agent
357
+
358
+ There are two ways, and neither touches the analytics.
359
+
360
+ 1. **Write generic events** from the agent, a wrapper or a log converter. See [docs/event-format.md](docs/event-format.md). From Python:
361
+
362
+ ```python
363
+ from tokentrail.emit import EventLog
364
+
365
+ log = EventLog(agent="My Agent")
366
+ log.prompt("Refactor billing")
367
+ log.response(model="my-model", input=1200, output=300)
368
+ log.tool_call("edit_file", target="billing.py")
369
+ log.tool_result(error=False, chars=420)
370
+ ```
371
+
372
+ 2. **Write an adapter** in `src/tokentrail/adapters/`: a class with `name`, `sources()` (files to read) and `events(path)` (a list of `Event`). Register it in `ADAPTERS`, add a branch to `make_adapters` in `cli.py`, and add a fixture test. [CONTRIBUTING.md](CONTRIBUTING.md) walks through it. `claude_code.py` is a complete example in about 100 lines.
373
+
374
+ ---
375
+
376
+ ## 8. Pricing
377
+
378
+ Costs are **estimates at API list prices**, calculated per response from the model name.
379
+
380
+ - **Built-in prices:** Anthropic's published rates (input, output, cache read, cache write per million tokens) in `pricing.py`.
381
+ - **Subscriptions:** if you're on a flat-rate plan, read cost as "what this would have cost on the API".
382
+ - **Unknown models** are shown as unpriced, not guessed.
383
+ - **Overrides:** add or override any model, including other vendors' and local ones, with a JSON file:
384
+
385
+ ```json
386
+ {"gpt-x": [1.25, 10.0, 0.125, 1.25], "local-llama": [0, 0, 0, 0]}
387
+ ```
388
+
389
+ Each value is `[input, output, cache_read, cache_write]` in US dollars per million tokens. Matching is by prefix, so `claude-opus-5-5` covers dated variants. Point the `pricing` setting at the file. Changing prices re-prices every agent file that still exists on the next sync; conversations whose source file is gone keep the prices they were stored with.
390
+
391
+ ---
392
+
393
+ ## 9. Co-located agent skill
394
+
395
+ `skills/tokentrail/` is an agent skill. Copy or link it into your agent's skills folder so the agent can run the tool and interpret it for you.
396
+
397
+ - `SKILL.md`: when to use it, the commands, and how to act on the signals.
398
+ - `references/telemetry_schema.md`: the `TaskRun` and `Commit` fields, the health rules, and the HTTP API.
399
+ - `evals/evals.json`: trigger and behaviour checks for the skill.
400
+
401
+ ---
402
+
403
+ ## 10. Testing and contributing
404
+
405
+ ```bash
406
+ python3 -m unittest discover -s tests -v # standard library only
407
+ python3 -m pytest -v # also works, if pytest is installed
408
+ ```
409
+
410
+ Lint, formatting and strict type checks, as CI runs them:
411
+
412
+ ```bash
413
+ pip install -e '.[dev]' # ruff and mypy
414
+ ruff check . && ruff format --check . && mypy
415
+ ```
416
+
417
+ The tests write fixtures to a temporary directory. They never read your real agent logs or touch the network: the GCS and S3 backends are tested against in-memory fakes.
418
+
419
+ Contributions are welcome, especially adapters for other agents. See [CONTRIBUTING.md](CONTRIBUTING.md), and [SECURITY.md](SECURITY.md) for reporting a vulnerability.
420
+
421
+ ## License
422
+
423
+ Apache License 2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).