cli-consumption 0.0.18__tar.gz → 0.1.1__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 (90) hide show
  1. cli_consumption-0.1.1/PKG-INFO +233 -0
  2. cli_consumption-0.1.1/README.md +205 -0
  3. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/docs/architecture.md +6 -6
  4. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/docs/provider-support.md +76 -9
  5. cli_consumption-0.1.1/docs/roadmap.md +25 -0
  6. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/pyproject.toml +1 -1
  7. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/__init__.py +2 -0
  8. cli_consumption-0.1.1/src/cli_consumption/adapters/mistral_vibe.py +281 -0
  9. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/cli.py +7 -0
  10. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_cli.py +38 -0
  11. cli_consumption-0.1.1/tests/test_mistral_vibe_adapter.py +207 -0
  12. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/uv.lock +1 -1
  13. cli_consumption-0.0.18/PKG-INFO +0 -453
  14. cli_consumption-0.0.18/README.md +0 -425
  15. cli_consumption-0.0.18/docs/roadmap.md +0 -41
  16. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/add-cli-adapter/SKILL.md +0 -0
  17. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/add-cli-adapter/agents/openai.yaml +0 -0
  18. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/audit-usage-privacy/SKILL.md +0 -0
  19. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/audit-usage-privacy/agents/openai.yaml +0 -0
  20. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/evolve-storage-schema/SKILL.md +0 -0
  21. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/evolve-storage-schema/agents/openai.yaml +0 -0
  22. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/yeet-github/SKILL.md +0 -0
  23. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/yeet-github/agents/openai.yaml +0 -0
  24. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/yolo/SKILL.md +0 -0
  25. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.agents/skills/yolo/agents/openai.yaml +0 -0
  26. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.github/workflows/ci.yml +0 -0
  27. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.github/workflows/release.yaml +0 -0
  28. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.gitignore +0 -0
  29. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.pre-commit-config.yaml +0 -0
  30. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/.python-version +0 -0
  31. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/AGENTS.md +0 -0
  32. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/CONTRIBUTING.md +0 -0
  33. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/LICENSE +0 -0
  34. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/NOTICE +0 -0
  35. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/docs/privacy.md +0 -0
  36. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/__init__.py +0 -0
  37. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/__main__.py +0 -0
  38. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/_shared.py +0 -0
  39. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/aider.py +0 -0
  40. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/amazon_q.py +0 -0
  41. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/amp.py +0 -0
  42. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/base.py +0 -0
  43. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/claude.py +0 -0
  44. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/cline.py +0 -0
  45. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/codex.py +0 -0
  46. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/continue_cli.py +0 -0
  47. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/copilot.py +0 -0
  48. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/crush.py +0 -0
  49. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/cursor.py +0 -0
  50. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/gemini.py +0 -0
  51. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/goose.py +0 -0
  52. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/grok.py +0 -0
  53. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/kilo.py +0 -0
  54. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/kimi.py +0 -0
  55. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/opencode.py +0 -0
  56. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/openhands.py +0 -0
  57. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/pi.py +0 -0
  58. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/plandex.py +0 -0
  59. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/adapters/qwen.py +0 -0
  60. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/api.py +0 -0
  61. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/dashboard.py +0 -0
  62. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/exporting.py +0 -0
  63. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/models.py +0 -0
  64. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/py.typed +0 -0
  65. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/storage.py +0 -0
  66. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/src/cli_consumption/sync.py +0 -0
  67. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/conftest.py +0 -0
  68. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_aider_adapter.py +0 -0
  69. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_amazon_q_adapter.py +0 -0
  70. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_amp_adapter.py +0 -0
  71. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_api.py +0 -0
  72. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_claude_adapter.py +0 -0
  73. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_cline_adapter.py +0 -0
  74. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_codex_adapter.py +0 -0
  75. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_continue_adapter.py +0 -0
  76. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_copilot_adapter.py +0 -0
  77. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_crush_adapter.py +0 -0
  78. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_cursor_adapter.py +0 -0
  79. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_gemini_adapter.py +0 -0
  80. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_goose_adapter.py +0 -0
  81. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_grok_adapter.py +0 -0
  82. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_kilo_adapter.py +0 -0
  83. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_kimi_adapter.py +0 -0
  84. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_opencode_adapter.py +0 -0
  85. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_openhands_adapter.py +0 -0
  86. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_pi_adapter.py +0 -0
  87. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_plandex_adapter.py +0 -0
  88. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_qwen_adapter.py +0 -0
  89. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_storage_and_exports.py +0 -0
  90. {cli_consumption-0.0.18 → cli_consumption-0.1.1}/tests/test_sync.py +0 -0
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.5
2
+ Name: cli-consumption
3
+ Version: 0.1.1
4
+ Summary: Analyze and consolidate AI coding CLI consumption across machines.
5
+ Project-URL: Homepage, https://github.com/Guillaume-Lombardo/cli-consumption
6
+ Project-URL: Documentation, https://github.com/Guillaume-Lombardo/cli-consumption#readme
7
+ Project-URL: Issues, https://github.com/Guillaume-Lombardo/cli-consumption/issues
8
+ Project-URL: Repository, https://github.com/Guillaume-Lombardo/cli-consumption.git
9
+ Author-email: Guillaume Lombardo <lombardo.guillaume@gmail.com>
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ License-File: NOTICE
13
+ Keywords: ai,cli,codex,observability,tokens,usage
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Requires-Python: >=3.14
21
+ Requires-Dist: fastapi>=0.115
22
+ Requires-Dist: httpx>=0.27
23
+ Requires-Dist: psycopg[binary]>=3.2
24
+ Requires-Dist: sqlalchemy>=2.0
25
+ Requires-Dist: typer>=0.15
26
+ Requires-Dist: uvicorn>=0.34
27
+ Description-Content-Type: text/markdown
28
+
29
+ # CLI Consumption
30
+
31
+ CLI Consumption measures how AI coding CLIs use models, tokens, tools,
32
+ conversations, and turns. It runs locally, can consolidate copied data from several
33
+ machines, and can send metadata-only snapshots to a central collector.
34
+
35
+ It never stores prompts, responses, tool arguments, credentials, or raw provider
36
+ events. Local token counters are usage metadata, not billing records. Read the
37
+ [privacy boundary](docs/privacy.md) before sharing a database or report.
38
+
39
+ ## Quick start
40
+
41
+ CLI Consumption requires Python 3.14 or newer and uses
42
+ [`uv`](https://docs.astral.sh/uv/).
43
+
44
+ From a checkout, collect every supported CLI detected on the machine and generate a
45
+ self-contained dashboard:
46
+
47
+ ```bash
48
+ uv sync
49
+ uv run cli-consumption collect --provider all
50
+ uv run cli-consumption export --output reports
51
+ ```
52
+
53
+ Open `reports/dashboard.html` locally. It makes no network requests. Detailed
54
+ normalized CSV tables are generated only when `--csv` is passed.
55
+
56
+ To collect a single CLI, use its provider name. For example, with Codex:
57
+
58
+ ```bash
59
+ uv run cli-consumption collect --provider codex --database usage.sqlite
60
+ ```
61
+
62
+ From PyPI, no permanent installation is required:
63
+
64
+ ```bash
65
+ uv tool run cli-consumption collect --provider all
66
+ uv tool run cli-consumption export --output reports
67
+ ```
68
+
69
+ To run the latest unreleased GitHub source:
70
+
71
+ ```bash
72
+ uv tool run --from git+https://github.com/Guillaume-Lombardo/cli-consumption \
73
+ cli-consumption providers
74
+ ```
75
+
76
+ ## Supported CLIs
77
+
78
+ `--provider all` detects the supported data stores found in their default locations.
79
+ Use the provider name below with `--provider` to select one CLI explicitly.
80
+
81
+ | CLI | Provider name | Default local source | Particularities and limits |
82
+ | --- | --- | --- | --- |
83
+ | Aider | `aider` | `~/.aider/analytics.jsonl` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
84
+ | Amazon Q Developer CLI | `amazon-q` | `~/.local/share/amazon-q/data.sqlite3` | Persistent conversations only; request timing is available, but token counters are not. |
85
+ | Amp | `amp` | `~/.local/share/amp/threads/` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
86
+ | Claude Code | `claude` | `~/.claude/projects/` | Main sessions, tokens, tools, and compactions; no subagents, context windows, or provider-reported durations. `claude-code` is accepted as an alias. |
87
+ | Cline CLI | `cline` | `~/.cline/data/sessions/sessions.db` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
88
+ | Codex | `codex` | `~/.codex/sessions/` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
89
+ | Continue CLI | `continue` | `~/.continue/sessions/` | Token usage when present; session files lack reliable per-message timing and duration. |
90
+ | Crush | `crush` | `~/.local/share/crush/` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
91
+ | Cursor CLI | `cursor` | `~/.cursor/` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
92
+ | Gemini CLI | `gemini` | `~/.gemini/tmp/` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
93
+ | GitHub Copilot CLI | `copilot` | `~/.copilot/session-state/` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
94
+ | Goose | `goose` | `~/.local/share/goose/sessions/sessions.db` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
95
+ | Grok Build | `grok` | `~/.grok/sessions/` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
96
+ | Kilo Code | `kilo` | `~/.local/share/kilo/kilo.db` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
97
+ | Kimi Code CLI | `kimi` | `~/.kimi/sessions/` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
98
+ | Mistral Vibe CLI | `mistral-vibe` | `~/.vibe/logs/session/` | Session-level token aggregates, user turns, tools, and compactions; no per-message timestamps or historical model attribution. |
99
+ | OpenCode | `opencode` | `~/.local/share/opencode/opencode.db` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
100
+ | OpenHands CLI | `openhands` | `~/.openhands/conversations/` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
101
+ | Pi | `pi` | `~/.pi/agent/sessions/` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
102
+ | Plandex | `plandex` | `/plandex-server` | Requires an offline copy of a self-hosted `PLANDEX_BASE_DIR`; hosted accounts are not accessed, and models/tools are unavailable. |
103
+ | Qwen Code | `qwen` | `~/.qwen/projects/` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
104
+
105
+ Provider formats are internal and can change without notice. The detailed extraction
106
+ rules and qualification versions are documented in
107
+ [Provider support](docs/provider-support.md).
108
+
109
+ ## Collect copied data
110
+
111
+ `--source [LABEL=]PATH` points to a provider home directory and can be repeated. With
112
+ `--provider all`, each path is inspected and unmatched sources are rejected. With one
113
+ provider selected, each path must contain that provider's expected store.
114
+
115
+ For example, consolidate trusted copies of Codex data from several machines:
116
+
117
+ ```bash
118
+ uv run cli-consumption collect --provider codex \
119
+ --source desktop=/data/codex/desktop \
120
+ --source laptop=/data/codex/laptop \
121
+ --source server=/data/codex/server \
122
+ --database usage.sqlite
123
+ ```
124
+
125
+ Copy only the required provider data. For Codex, copy the `sessions/` directory but
126
+ never `auth.json` or other credentials. Globally identical conversation IDs are
127
+ deduplicated, and the most complete copy wins.
128
+
129
+ Map original working-directory prefixes to stable project labels with repeated
130
+ `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
131
+
132
+ ```bash
133
+ uv run cli-consumption collect --provider codex \
134
+ --source desktop=/data/codex/desktop \
135
+ --project cli-consumption=/home/me/dev/cli-consumption
136
+ ```
137
+
138
+ Plandex auto-detection checks `/plandex-server`. For any other trusted offline copy of
139
+ a self-hosted server data directory, pass the path explicitly:
140
+
141
+ ```bash
142
+ uv run cli-consumption collect --provider plandex \
143
+ --source server=/srv/plandex-server --database usage.sqlite
144
+ ```
145
+
146
+ ## Explore and share reports
147
+
148
+ The dashboard can filter by time, provider, machine, project, and model. It reports
149
+ activity, token composition, cache efficiency, latency and duration distributions,
150
+ technical throughput, context pressure, work-item reliability, configuration cohorts,
151
+ compactions, subagent delegation, and ingestion quality. Availability varies by
152
+ provider, as summarized in the table above.
153
+
154
+ Generate a more shareable dashboard by pseudonymizing labels, grouping tool names,
155
+ rounding timestamps to days, and hiding small cohort rows:
156
+
157
+ ```bash
158
+ uv run cli-consumption export --output shared-report --share-safe
159
+ ```
160
+
161
+ Share-safe reports still disclose aggregate work patterns and remain private
162
+ operational data. A technically completed turn is not a measure of task quality or
163
+ productivity.
164
+
165
+ ## SQLite and PostgreSQL
166
+
167
+ A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
168
+
169
+ ```bash
170
+ uv run cli-consumption collect --provider all --database usage.sqlite
171
+ uv run cli-consumption collect --provider all \
172
+ --database postgresql+psycopg://usage@localhost/cli_consumption
173
+ ```
174
+
175
+ Pass credentials through environment variables or a secret manager rather than shell
176
+ history. `CLI_CONSUMPTION_DATABASE` can provide the database setting.
177
+
178
+ ## Central collector API
179
+
180
+ Copied files are simplest for personal or air-gapped use. For recurring collection
181
+ across machines, start the metadata-only API:
182
+
183
+ ```bash
184
+ export CLI_CONSUMPTION_API_TOKEN="$(your-secret-provider)"
185
+ uv run cli-consumption serve \
186
+ --database postgresql+psycopg://usage@localhost/cli_consumption \
187
+ --host 0.0.0.0
188
+ ```
189
+
190
+ Then send all locally detected snapshots from another machine:
191
+
192
+ ```bash
193
+ export CLI_CONSUMPTION_API_TOKEN="$(your-secret-provider)"
194
+ uv run cli-consumption sync --provider all \
195
+ --endpoint https://usage.example.test
196
+ ```
197
+
198
+ The application refuses to bind beyond localhost without a token. Production
199
+ deployments also need TLS and standard operational controls. See
200
+ [Architecture](docs/architecture.md) for the trade-offs.
201
+
202
+ ## Commands
203
+
204
+ | Command | Purpose |
205
+ | --- | --- |
206
+ | `collect` | Collect local or copied provider data into SQL. |
207
+ | `sync` | Collect and send metadata-only snapshots to a central API. |
208
+ | `serve` | Run the central collection API. |
209
+ | `export` | Write the HTML dashboard and optional CSV tables. |
210
+ | `providers` | List provider names and support status. |
211
+
212
+ Run `uv run cli-consumption COMMAND --help` for all options.
213
+
214
+ ## Development
215
+
216
+ ```bash
217
+ uv sync --all-groups
218
+ uv run pre-commit install
219
+ uv run pre-commit run --all-files
220
+ uv run ruff format --check .
221
+ uv run ruff check .
222
+ uv run ty check
223
+ uv run pytest --cov --cov-report=term-missing
224
+ uv build
225
+ ```
226
+
227
+ Development uses short-lived branches and squash-merged pull requests into protected
228
+ `main`. Read [CONTRIBUTING.md](CONTRIBUTING.md) and [AGENTS.md](AGENTS.md) before
229
+ changing the project.
230
+
231
+ ## License
232
+
233
+ Licensed under the [Apache License 2.0](LICENSE).
@@ -0,0 +1,205 @@
1
+ # CLI Consumption
2
+
3
+ CLI Consumption measures how AI coding CLIs use models, tokens, tools,
4
+ conversations, and turns. It runs locally, can consolidate copied data from several
5
+ machines, and can send metadata-only snapshots to a central collector.
6
+
7
+ It never stores prompts, responses, tool arguments, credentials, or raw provider
8
+ events. Local token counters are usage metadata, not billing records. Read the
9
+ [privacy boundary](docs/privacy.md) before sharing a database or report.
10
+
11
+ ## Quick start
12
+
13
+ CLI Consumption requires Python 3.14 or newer and uses
14
+ [`uv`](https://docs.astral.sh/uv/).
15
+
16
+ From a checkout, collect every supported CLI detected on the machine and generate a
17
+ self-contained dashboard:
18
+
19
+ ```bash
20
+ uv sync
21
+ uv run cli-consumption collect --provider all
22
+ uv run cli-consumption export --output reports
23
+ ```
24
+
25
+ Open `reports/dashboard.html` locally. It makes no network requests. Detailed
26
+ normalized CSV tables are generated only when `--csv` is passed.
27
+
28
+ To collect a single CLI, use its provider name. For example, with Codex:
29
+
30
+ ```bash
31
+ uv run cli-consumption collect --provider codex --database usage.sqlite
32
+ ```
33
+
34
+ From PyPI, no permanent installation is required:
35
+
36
+ ```bash
37
+ uv tool run cli-consumption collect --provider all
38
+ uv tool run cli-consumption export --output reports
39
+ ```
40
+
41
+ To run the latest unreleased GitHub source:
42
+
43
+ ```bash
44
+ uv tool run --from git+https://github.com/Guillaume-Lombardo/cli-consumption \
45
+ cli-consumption providers
46
+ ```
47
+
48
+ ## Supported CLIs
49
+
50
+ `--provider all` detects the supported data stores found in their default locations.
51
+ Use the provider name below with `--provider` to select one CLI explicitly.
52
+
53
+ | CLI | Provider name | Default local source | Particularities and limits |
54
+ | --- | --- | --- | --- |
55
+ | Aider | `aider` | `~/.aider/analytics.jsonl` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
56
+ | Amazon Q Developer CLI | `amazon-q` | `~/.local/share/amazon-q/data.sqlite3` | Persistent conversations only; request timing is available, but token counters are not. |
57
+ | Amp | `amp` | `~/.local/share/amp/threads/` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
58
+ | Claude Code | `claude` | `~/.claude/projects/` | Main sessions, tokens, tools, and compactions; no subagents, context windows, or provider-reported durations. `claude-code` is accepted as an alias. |
59
+ | Cline CLI | `cline` | `~/.cline/data/sessions/sessions.db` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
60
+ | Codex | `codex` | `~/.codex/sessions/` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
61
+ | Continue CLI | `continue` | `~/.continue/sessions/` | Token usage when present; session files lack reliable per-message timing and duration. |
62
+ | Crush | `crush` | `~/.local/share/crush/` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
63
+ | Cursor CLI | `cursor` | `~/.cursor/` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
64
+ | Gemini CLI | `gemini` | `~/.gemini/tmp/` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
65
+ | GitHub Copilot CLI | `copilot` | `~/.copilot/session-state/` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
66
+ | Goose | `goose` | `~/.local/share/goose/sessions/sessions.db` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
67
+ | Grok Build | `grok` | `~/.grok/sessions/` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
68
+ | Kilo Code | `kilo` | `~/.local/share/kilo/kilo.db` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
69
+ | Kimi Code CLI | `kimi` | `~/.kimi/sessions/` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
70
+ | Mistral Vibe CLI | `mistral-vibe` | `~/.vibe/logs/session/` | Session-level token aggregates, user turns, tools, and compactions; no per-message timestamps or historical model attribution. |
71
+ | OpenCode | `opencode` | `~/.local/share/opencode/opencode.db` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
72
+ | OpenHands CLI | `openhands` | `~/.openhands/conversations/` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
73
+ | Pi | `pi` | `~/.pi/agent/sessions/` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
74
+ | Plandex | `plandex` | `/plandex-server` | Requires an offline copy of a self-hosted `PLANDEX_BASE_DIR`; hosted accounts are not accessed, and models/tools are unavailable. |
75
+ | Qwen Code | `qwen` | `~/.qwen/projects/` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
76
+
77
+ Provider formats are internal and can change without notice. The detailed extraction
78
+ rules and qualification versions are documented in
79
+ [Provider support](docs/provider-support.md).
80
+
81
+ ## Collect copied data
82
+
83
+ `--source [LABEL=]PATH` points to a provider home directory and can be repeated. With
84
+ `--provider all`, each path is inspected and unmatched sources are rejected. With one
85
+ provider selected, each path must contain that provider's expected store.
86
+
87
+ For example, consolidate trusted copies of Codex data from several machines:
88
+
89
+ ```bash
90
+ uv run cli-consumption collect --provider codex \
91
+ --source desktop=/data/codex/desktop \
92
+ --source laptop=/data/codex/laptop \
93
+ --source server=/data/codex/server \
94
+ --database usage.sqlite
95
+ ```
96
+
97
+ Copy only the required provider data. For Codex, copy the `sessions/` directory but
98
+ never `auth.json` or other credentials. Globally identical conversation IDs are
99
+ deduplicated, and the most complete copy wins.
100
+
101
+ Map original working-directory prefixes to stable project labels with repeated
102
+ `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
103
+
104
+ ```bash
105
+ uv run cli-consumption collect --provider codex \
106
+ --source desktop=/data/codex/desktop \
107
+ --project cli-consumption=/home/me/dev/cli-consumption
108
+ ```
109
+
110
+ Plandex auto-detection checks `/plandex-server`. For any other trusted offline copy of
111
+ a self-hosted server data directory, pass the path explicitly:
112
+
113
+ ```bash
114
+ uv run cli-consumption collect --provider plandex \
115
+ --source server=/srv/plandex-server --database usage.sqlite
116
+ ```
117
+
118
+ ## Explore and share reports
119
+
120
+ The dashboard can filter by time, provider, machine, project, and model. It reports
121
+ activity, token composition, cache efficiency, latency and duration distributions,
122
+ technical throughput, context pressure, work-item reliability, configuration cohorts,
123
+ compactions, subagent delegation, and ingestion quality. Availability varies by
124
+ provider, as summarized in the table above.
125
+
126
+ Generate a more shareable dashboard by pseudonymizing labels, grouping tool names,
127
+ rounding timestamps to days, and hiding small cohort rows:
128
+
129
+ ```bash
130
+ uv run cli-consumption export --output shared-report --share-safe
131
+ ```
132
+
133
+ Share-safe reports still disclose aggregate work patterns and remain private
134
+ operational data. A technically completed turn is not a measure of task quality or
135
+ productivity.
136
+
137
+ ## SQLite and PostgreSQL
138
+
139
+ A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
140
+
141
+ ```bash
142
+ uv run cli-consumption collect --provider all --database usage.sqlite
143
+ uv run cli-consumption collect --provider all \
144
+ --database postgresql+psycopg://usage@localhost/cli_consumption
145
+ ```
146
+
147
+ Pass credentials through environment variables or a secret manager rather than shell
148
+ history. `CLI_CONSUMPTION_DATABASE` can provide the database setting.
149
+
150
+ ## Central collector API
151
+
152
+ Copied files are simplest for personal or air-gapped use. For recurring collection
153
+ across machines, start the metadata-only API:
154
+
155
+ ```bash
156
+ export CLI_CONSUMPTION_API_TOKEN="$(your-secret-provider)"
157
+ uv run cli-consumption serve \
158
+ --database postgresql+psycopg://usage@localhost/cli_consumption \
159
+ --host 0.0.0.0
160
+ ```
161
+
162
+ Then send all locally detected snapshots from another machine:
163
+
164
+ ```bash
165
+ export CLI_CONSUMPTION_API_TOKEN="$(your-secret-provider)"
166
+ uv run cli-consumption sync --provider all \
167
+ --endpoint https://usage.example.test
168
+ ```
169
+
170
+ The application refuses to bind beyond localhost without a token. Production
171
+ deployments also need TLS and standard operational controls. See
172
+ [Architecture](docs/architecture.md) for the trade-offs.
173
+
174
+ ## Commands
175
+
176
+ | Command | Purpose |
177
+ | --- | --- |
178
+ | `collect` | Collect local or copied provider data into SQL. |
179
+ | `sync` | Collect and send metadata-only snapshots to a central API. |
180
+ | `serve` | Run the central collection API. |
181
+ | `export` | Write the HTML dashboard and optional CSV tables. |
182
+ | `providers` | List provider names and support status. |
183
+
184
+ Run `uv run cli-consumption COMMAND --help` for all options.
185
+
186
+ ## Development
187
+
188
+ ```bash
189
+ uv sync --all-groups
190
+ uv run pre-commit install
191
+ uv run pre-commit run --all-files
192
+ uv run ruff format --check .
193
+ uv run ruff check .
194
+ uv run ty check
195
+ uv run pytest --cov --cov-report=term-missing
196
+ uv build
197
+ ```
198
+
199
+ Development uses short-lived branches and squash-merged pull requests into protected
200
+ `main`. Read [CONTRIBUTING.md](CONTRIBUTING.md) and [AGENTS.md](AGENTS.md) before
201
+ changing the project.
202
+
203
+ ## License
204
+
205
+ Licensed under the [Apache License 2.0](LICENSE).
@@ -16,12 +16,12 @@ provider files -> adapter -> metadata-only snapshot -> SQL storage -> dashboard/
16
16
 
17
17
  - `adapters`: parse a CLI's local data into conversations, turns, model calls, tool
18
18
  calls, context-pressure samples, bounded turn settings, compactions, and content-free
19
- work-item intervals. Codex exposes the complete analytics contract; Aider, Amazon Q
19
+ work-item intervals. Codex exposes the complete analytics contract. Aider, Amazon Q
20
20
  Developer CLI, Amp, Cline CLI, Claude Code, Continue CLI, Crush, Cursor CLI, Gemini
21
- CLI, GitHub Copilot CLI, Goose, Kilo Code, Kimi Code CLI, OpenCode, Pi, Plandex, and
22
- Qwen Code expose the core dimensions available in their stores. OpenHands CLI
23
- exposes the same core dimensions plus context windows and condensation timestamps
24
- from its SDK persistence.
21
+ CLI, GitHub Copilot CLI, Goose, Grok Build, Kilo Code, Kimi Code CLI, OpenCode,
22
+ OpenHands CLI, Pi, Plandex, and Qwen Code expose the reliable subset available in
23
+ each local store. The exact differences are maintained in
24
+ [Provider support](provider-support.md).
25
25
  - `models`: define the transport boundary shared by offline and API ingestion.
26
26
  - `storage`: owns the normalized schema, idempotent replacement rules, SQLite, and
27
27
  PostgreSQL engine creation.
@@ -73,7 +73,7 @@ to an older strict API is rejected before ingestion, so central deployments must
73
73
  upgrade the server first. Downgrading a writer after rich metadata has been ingested is
74
74
  not supported because old writers do not know how to replace the new child rows.
75
75
 
76
- ## Adapter roadmap
76
+ ## Adapter qualification
77
77
 
78
78
  Adapters are introduced one at a time because local data formats are undocumented or
79
79
  can evolve independently. Each adapter must have synthetic fixtures, format detection,