cli-consumption 0.2.1__tar.gz → 0.3.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 (114) hide show
  1. cli_consumption-0.3.0/CHANGELOG.md +84 -0
  2. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/PKG-INFO +73 -28
  3. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/README.md +71 -27
  4. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/pyproject.toml +15 -1
  5. cli_consumption-0.3.0/src/cli_consumption/adapters/_shared.py +418 -0
  6. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/aider.py +21 -17
  7. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/amazon_q.py +16 -12
  8. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/amp.py +29 -41
  9. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/claude.py +24 -31
  10. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/cline.py +27 -16
  11. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/codex.py +32 -18
  12. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/continue_cli.py +26 -21
  13. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/copilot.py +20 -18
  14. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/crush.py +69 -76
  15. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/cursor.py +20 -15
  16. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/gemini.py +33 -43
  17. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/goose.py +66 -71
  18. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/grok.py +28 -25
  19. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/kilo.py +65 -74
  20. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/kimi.py +8 -4
  21. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/mistral_vibe.py +10 -5
  22. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/opencode.py +50 -68
  23. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/openhands.py +34 -45
  24. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/pi.py +29 -48
  25. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/plandex.py +11 -5
  26. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/qwen.py +24 -34
  27. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/registry.py +49 -5
  28. cli_consumption-0.3.0/src/cli_consumption/api.py +463 -0
  29. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/cli.py +33 -8
  30. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/dashboard.py +566 -232
  31. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/exporting.py +0 -4
  32. cli_consumption-0.3.0/src/cli_consumption/migrations/versions/v0004_subagent_scope_freshness.py +38 -0
  33. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/reporting.py +76 -1
  34. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/schema.py +90 -12
  35. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/storage.py +99 -31
  36. cli_consumption-0.2.1/.agents/skills/add-cli-adapter/SKILL.md +0 -21
  37. cli_consumption-0.2.1/.agents/skills/add-cli-adapter/agents/openai.yaml +0 -4
  38. cli_consumption-0.2.1/.agents/skills/audit-usage-privacy/SKILL.md +0 -22
  39. cli_consumption-0.2.1/.agents/skills/audit-usage-privacy/agents/openai.yaml +0 -4
  40. cli_consumption-0.2.1/.agents/skills/evolve-storage-schema/SKILL.md +0 -21
  41. cli_consumption-0.2.1/.agents/skills/evolve-storage-schema/agents/openai.yaml +0 -4
  42. cli_consumption-0.2.1/.agents/skills/yeet-github/SKILL.md +0 -66
  43. cli_consumption-0.2.1/.agents/skills/yeet-github/agents/openai.yaml +0 -4
  44. cli_consumption-0.2.1/.agents/skills/yolo/SKILL.md +0 -50
  45. cli_consumption-0.2.1/.agents/skills/yolo/agents/openai.yaml +0 -4
  46. cli_consumption-0.2.1/.github/workflows/ci.yml +0 -64
  47. cli_consumption-0.2.1/.github/workflows/release.yaml +0 -154
  48. cli_consumption-0.2.1/.pre-commit-config.yaml +0 -35
  49. cli_consumption-0.2.1/.python-version +0 -1
  50. cli_consumption-0.2.1/AGENTS.md +0 -68
  51. cli_consumption-0.2.1/CONTRIBUTING.md +0 -56
  52. cli_consumption-0.2.1/SECURITY.md +0 -37
  53. cli_consumption-0.2.1/docs/architecture.md +0 -124
  54. cli_consumption-0.2.1/docs/decisions/0001-versioned-schema-migrations.md +0 -50
  55. cli_consumption-0.2.1/docs/decisions/0002-canonical-utc-timestamps.md +0 -94
  56. cli_consumption-0.2.1/docs/privacy.md +0 -106
  57. cli_consumption-0.2.1/docs/provider-support.md +0 -422
  58. cli_consumption-0.2.1/docs/roadmap.md +0 -33
  59. cli_consumption-0.2.1/src/cli_consumption/adapters/_shared.py +0 -180
  60. cli_consumption-0.2.1/src/cli_consumption/api.py +0 -143
  61. cli_consumption-0.2.1/tests/conftest.py +0 -133
  62. cli_consumption-0.2.1/tests/smoke_minimal_install.py +0 -69
  63. cli_consumption-0.2.1/tests/test_aider_adapter.py +0 -204
  64. cli_consumption-0.2.1/tests/test_amazon_q_adapter.py +0 -67
  65. cli_consumption-0.2.1/tests/test_amp_adapter.py +0 -257
  66. cli_consumption-0.2.1/tests/test_api.py +0 -164
  67. cli_consumption-0.2.1/tests/test_claude_adapter.py +0 -218
  68. cli_consumption-0.2.1/tests/test_cli.py +0 -1171
  69. cli_consumption-0.2.1/tests/test_cline_adapter.py +0 -102
  70. cli_consumption-0.2.1/tests/test_codex_adapter.py +0 -256
  71. cli_consumption-0.2.1/tests/test_continue_adapter.py +0 -266
  72. cli_consumption-0.2.1/tests/test_copilot_adapter.py +0 -348
  73. cli_consumption-0.2.1/tests/test_crush_adapter.py +0 -304
  74. cli_consumption-0.2.1/tests/test_cursor_adapter.py +0 -230
  75. cli_consumption-0.2.1/tests/test_exporting.py +0 -85
  76. cli_consumption-0.2.1/tests/test_gemini_adapter.py +0 -275
  77. cli_consumption-0.2.1/tests/test_goose_adapter.py +0 -269
  78. cli_consumption-0.2.1/tests/test_grok_adapter.py +0 -304
  79. cli_consumption-0.2.1/tests/test_input_limits.py +0 -57
  80. cli_consumption-0.2.1/tests/test_kilo_adapter.py +0 -292
  81. cli_consumption-0.2.1/tests/test_kimi_adapter.py +0 -82
  82. cli_consumption-0.2.1/tests/test_migrations_and_retention.py +0 -752
  83. cli_consumption-0.2.1/tests/test_mistral_vibe_adapter.py +0 -207
  84. cli_consumption-0.2.1/tests/test_opencode_adapter.py +0 -261
  85. cli_consumption-0.2.1/tests/test_openhands_adapter.py +0 -313
  86. cli_consumption-0.2.1/tests/test_packaging.py +0 -26
  87. cli_consumption-0.2.1/tests/test_pi_adapter.py +0 -287
  88. cli_consumption-0.2.1/tests/test_plandex_adapter.py +0 -68
  89. cli_consumption-0.2.1/tests/test_provider_registry.py +0 -191
  90. cli_consumption-0.2.1/tests/test_qwen_adapter.py +0 -295
  91. cli_consumption-0.2.1/tests/test_reporting.py +0 -248
  92. cli_consumption-0.2.1/tests/test_snapshot_contract.py +0 -75
  93. cli_consumption-0.2.1/tests/test_storage_and_exports.py +0 -342
  94. cli_consumption-0.2.1/tests/test_sync.py +0 -104
  95. cli_consumption-0.2.1/tests/test_timestamps.py +0 -61
  96. cli_consumption-0.2.1/uv.lock +0 -987
  97. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/.gitignore +0 -0
  98. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/LICENSE +0 -0
  99. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/NOTICE +0 -0
  100. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/__init__.py +0 -0
  101. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/__main__.py +0 -0
  102. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/__init__.py +0 -0
  103. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/adapters/base.py +0 -0
  104. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/__init__.py +0 -0
  105. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/env.py +0 -0
  106. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/versions/__init__.py +0 -0
  107. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/versions/v0001_baseline.py +0 -0
  108. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/versions/v0002_minimize_subagents.py +0 -0
  109. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/migrations/versions/v0003_canonical_timestamps.py +0 -0
  110. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/models.py +0 -0
  111. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/py.typed +0 -0
  112. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/retention.py +0 -0
  113. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/sync.py +0 -0
  114. {cli_consumption-0.2.1 → cli_consumption-0.3.0}/src/cli_consumption/timestamps.py +0 -0
@@ -0,0 +1,84 @@
1
+ # Changelog
2
+
3
+ Notable user-visible changes to CLI Consumption are documented in this file. The
4
+ format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases
5
+ use [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.3.0] - 2026-08-29
10
+
11
+ ### Added
12
+
13
+ - Added privacy-safe database readiness checks and bounded request correlation for the
14
+ collector service ([#35]).
15
+
16
+ ### Changed
17
+
18
+ - Provider input processing now enforces cumulative discovery, byte, SQLite row, and
19
+ structured-field limits across a complete collection ([#31]).
20
+ - Dashboard generation now preflights bounded selections, streams its output, and
21
+ atomically replaces an existing report only after a successful write ([#32]).
22
+ - Concurrent schema initialization, upgrade, and downgrade are now serialized on
23
+ SQLite and PostgreSQL, with SQLite lock waits capped at 15 seconds ([#34]).
24
+ - Published source distributions exclude repository-only tests and automation while
25
+ retaining release metadata, the changelog and README, license notices, the runtime
26
+ package, and Hatchling's rebuild `.gitignore` ([#33]).
27
+ - Identical adapter primitives are shared while provider-specific parsing semantics
28
+ remain isolated ([#36]).
29
+
30
+ ### Fixed
31
+
32
+ - Older, identical, graph-only, and partially stale snapshots can no longer erase a
33
+ newer subagent relationship graph ([#30]).
34
+
35
+ ## [0.2.1] - 2026-08-29
36
+
37
+ ### Changed
38
+
39
+ - Hardened ingestion privacy and normalized persisted timestamps to canonical,
40
+ fixed-width UTC values ([#29]).
41
+
42
+ ## [0.2.0] - 2026-08-29
43
+
44
+ ### Added
45
+
46
+ - Added versioned SQLite and PostgreSQL schema migrations, retention previews, and a
47
+ metadata-only central collector and synchronization client ([#28]).
48
+ - Added streamed CSV exports, time-window selection, and a share-safe dashboard
49
+ profile ([#28]).
50
+
51
+ ### Changed
52
+
53
+ - Strengthened snapshot validation, transport defaults, storage deduplication, and
54
+ privacy regression coverage ([#28]).
55
+
56
+ ## [0.1.1] - 2026-08-27
57
+
58
+ ### Added
59
+
60
+ - Added the Mistral Vibe CLI adapter ([#27]).
61
+
62
+ ## [0.1.0] - 2026-08-27
63
+
64
+ ### Changed
65
+
66
+ - Refreshed the provider guide for the first minor release ([#26]).
67
+
68
+ [Unreleased]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.3.0...HEAD
69
+ [0.3.0]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.2.1...v0.3.0
70
+ [0.2.1]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.2.0...v0.2.1
71
+ [0.2.0]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.1.1...v0.2.0
72
+ [0.1.1]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.1.0...v0.1.1
73
+ [0.1.0]: https://github.com/Guillaume-Lombardo/cli-consumption/compare/v0.0.18...v0.1.0
74
+ [#26]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/26
75
+ [#27]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/27
76
+ [#28]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/28
77
+ [#29]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/29
78
+ [#30]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/30
79
+ [#31]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/31
80
+ [#32]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/32
81
+ [#33]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/33
82
+ [#34]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/34
83
+ [#35]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/35
84
+ [#36]: https://github.com/Guillaume-Lombardo/cli-consumption/pull/36
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cli-consumption
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: Analyze and consolidate AI coding CLI consumption across machines.
5
5
  Project-URL: Homepage, https://github.com/Guillaume-Lombardo/cli-consumption
6
6
  Project-URL: Documentation, https://github.com/Guillaume-Lombardo/cli-consumption#readme
7
+ Project-URL: Changelog, https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/CHANGELOG.md
7
8
  Project-URL: Issues, https://github.com/Guillaume-Lombardo/cli-consumption/issues
8
9
  Project-URL: Repository, https://github.com/Guillaume-Lombardo/cli-consumption.git
9
10
  Author-email: Guillaume Lombardo <lombardo.guillaume@gmail.com>
@@ -95,29 +96,29 @@ uv tool run --from git+https://github.com/Guillaume-Lombardo/cli-consumption \
95
96
  `--provider all` detects the supported data stores found in their default locations.
96
97
  Use the provider name below with `--provider` to select one CLI explicitly.
97
98
 
98
- | CLI | Provider name | Default local source | Particularities and limits |
99
- | --- | --- | --- | --- |
100
- | Aider | `aider` | `~/.aider/analytics.jsonl` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
101
- | Amazon Q Developer CLI | `amazon-q` | `~/.local/share/amazon-q/data.sqlite3` | Persistent conversations only; request timing is available, but token counters are not. |
102
- | Amp | `amp` | `~/.local/share/amp/threads/` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
103
- | 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. |
104
- | Cline CLI | `cline` | `~/.cline/data/sessions/sessions.db` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
105
- | Codex | `codex` | `~/.codex/sessions/` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
106
- | Continue CLI | `continue` | `~/.continue/sessions/` | Token usage when present; session files lack reliable per-message timing and duration. |
107
- | Crush | `crush` | `~/.local/share/crush/` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
108
- | Cursor CLI | `cursor` | `~/.cursor/` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
109
- | Gemini CLI | `gemini` | `~/.gemini/tmp/` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
110
- | GitHub Copilot CLI | `copilot` | `~/.copilot/session-state/` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
111
- | Goose | `goose` | `~/.local/share/goose/sessions/sessions.db` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
112
- | Grok Build | `grok` | `~/.grok/sessions/` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
113
- | Kilo Code | `kilo` | `~/.local/share/kilo/kilo.db` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
114
- | Kimi Code CLI | `kimi` | `~/.kimi/sessions/` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
115
- | 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. |
116
- | OpenCode | `opencode` | `~/.local/share/opencode/opencode.db` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
117
- | OpenHands CLI | `openhands` | `~/.openhands/conversations/` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
118
- | Pi | `pi` | `~/.pi/agent/sessions/` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
119
- | 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. |
120
- | Qwen Code | `qwen` | `~/.qwen/projects/` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
99
+ | CLI | Provider name | Aliases | Default local source | Token semantics | Particularities and limits |
100
+ | --- | --- | --- | --- | --- | --- |
101
+ | Aider | `aider` | — | `~/.aider/analytics.jsonl` | `additive` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
102
+ | Amazon Q Developer CLI | `amazon-q` | — | `~/.local/share/amazon-q/data.sqlite3` | `unavailable` | Persistent conversations only; request timing is available, but token counters are not. |
103
+ | Amp | `amp` | — | `~/.local/share/amp/threads/` | `additive` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
104
+ | Claude Code | `claude` | `claude-code` | `~/.claude/projects/` | `additive` | Main sessions, tokens, tools, and compactions; no subagents, context windows, or provider-reported durations. |
105
+ | Cline CLI | `cline` | — | `~/.cline/data/sessions/sessions.db` | `additive` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
106
+ | Codex | `codex` | — | `~/.codex/sessions/` | `additive` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
107
+ | Continue CLI | `continue` | — | `~/.continue/sessions/` | `additive` | Token usage when present; session files lack reliable per-message timing and duration. |
108
+ | Crush | `crush` | — | `~/.local/share/crush/` | `context-snapshot` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
109
+ | Cursor CLI | `cursor` | — | `~/.cursor/` | `unavailable` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
110
+ | Gemini CLI | `gemini` | — | `~/.gemini/tmp/` | `additive` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
111
+ | GitHub Copilot CLI | `copilot` | — | `~/.copilot/session-state/` | `conversation-aggregate` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
112
+ | Goose | `goose` | — | `~/.local/share/goose/sessions/sessions.db` | `additive` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
113
+ | Grok Build | `grok` | — | `~/.grok/sessions/` | `additive` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
114
+ | Kilo Code | `kilo` | — | `~/.local/share/kilo/kilo.db` | `additive` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
115
+ | Kimi Code CLI | `kimi` | — | `~/.kimi/sessions/` | `additive` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
116
+ | Mistral Vibe CLI | `mistral-vibe` | — | `~/.vibe/logs/session/` | `conversation-aggregate` | Session-level token aggregates, user turns, tools, and compactions; no per-message timestamps or historical model attribution. |
117
+ | OpenCode | `opencode` | — | `~/.local/share/opencode/opencode.db` | `additive` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
118
+ | OpenHands CLI | `openhands` | — | `~/.openhands/conversations/` | `additive` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
119
+ | Pi | `pi` | — | `~/.pi/agent/sessions/` | `additive` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
120
+ | Plandex | `plandex` | — | `/plandex-server` | `additive` | Requires an offline copy of a self-hosted `PLANDEX_BASE_DIR`; hosted accounts are not accessed, and models/tools are unavailable. |
121
+ | Qwen Code | `qwen` | — | `~/.qwen/projects/` | `additive` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
121
122
 
122
123
  Provider formats are internal and can change without notice. The detailed extraction
123
124
  rules and qualification versions are documented in
@@ -141,12 +142,19 @@ uv run cli-consumption collect --provider codex \
141
142
 
142
143
  Copy only the required provider data. For Codex, copy the `sessions/` directory but
143
144
  never `auth.json` or other credentials. Globally identical conversation IDs are
144
- deduplicated, and the most complete copy wins.
145
+ deduplicated, and the most complete copy wins. After a subagent scope is first seen,
146
+ its relationship graph is replaced only when at least one conversation from that
147
+ provider and source machine is strictly more complete and none is less complete.
148
+ Identical, graph-only, or older copies cannot erase a newer graph.
145
149
 
146
150
  Provider files are untrusted. Monolithic JSON files are limited to 64 MiB, JSONL files
147
- to 256 MiB with an 8 MiB per-line limit, and a snapshot to 250,000 normalized records
148
- while it is being built. Direct provider-file symlinks are refused. `collect --strict`
149
- refuses to write a snapshot when malformed records were skipped.
151
+ to 256 MiB with an 8 MiB per-line limit, 512 MiB of provider-file bytes actually read,
152
+ and discovery to 10,000 candidate entries per provider collection. Provider SQLite
153
+ inputs share a cumulative 512 MiB limit across databases and active WAL, SHM, or
154
+ journal sidecars, plus 250,000 selected rows, 8 MiB per structured field, and 256 MiB
155
+ across structured fields. A snapshot is limited to 250,000 normalized records while it
156
+ is being built. Direct provider-file symlinks are refused. `collect --strict` refuses
157
+ to write a snapshot when malformed records were skipped.
150
158
 
151
159
  Map original working-directory prefixes to stable project labels with repeated
152
160
  `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
@@ -197,6 +205,19 @@ to the window. CSV rows are streamed in stable primary-key order. Spreadsheet fo
197
205
  prefixes in text cells are neutralized with a leading apostrophe; CSV remains a
198
206
  detailed operational-data export, not a share-safe format.
199
207
 
208
+ Dashboard generation preflights the selected report before streaming its tables. The
209
+ selection is limited to 250,000 rows and 128 MiB of selected scalar values, and the
210
+ final self-contained HTML is limited to 128 MiB of bytes actually encoded. If an
211
+ accumulated database exceeds these limits, narrow it with `--since` and/or `--until`.
212
+ A dashboard is streamed through a temporary file in its destination directory,
213
+ synchronized, and atomically replaces an older dashboard only after generation
214
+ succeeds.
215
+
216
+ When `--csv` and the dashboard are requested together, each CSV is still streamed
217
+ before dashboard generation. The dashboard file is atomic, but the output directory
218
+ as a whole is not: a dashboard limit or write failure can leave newly written CSV
219
+ files alongside the preserved older dashboard.
220
+
200
221
  ## SQLite and PostgreSQL
201
222
 
202
223
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -224,6 +245,10 @@ conversation end-time path; see the
224
245
  [timestamp decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0002-canonical-utc-timestamps.md)
225
246
  for the exact representation and downgrade boundary.
226
247
 
248
+ Revision `0004` adds internal per-scope state that serializes subagent graph freshness
249
+ decisions. It does not add snapshot or export fields; see the
250
+ [subagent freshness decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0003-subagent-scope-freshness.md).
251
+
227
252
  Preview retention before deleting normalized metadata:
228
253
 
229
254
  ```bash
@@ -233,6 +258,9 @@ uv run cli-consumption retention --keep-days 90 --database usage.sqlite --apply
233
258
 
234
259
  The first command is a dry run. `--apply` deletes old conversations and their child
235
260
  rows, old subagent relationships, and old ingestion-run records.
261
+ Internal subagent-scope coordination rows remain as replay guards, so an older
262
+ graph-only copy cannot recreate relationships after retention. They contain only the
263
+ provider, source-machine label, and a lock counter and are never exported.
236
264
 
237
265
  ## Central collector API
238
266
 
@@ -259,6 +287,23 @@ deployments also need TLS and standard operational controls. The sync client ref
259
287
  plain HTTP beyond loopback unless `--allow-insecure` is passed explicitly. See
260
288
  [Architecture](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/architecture.md) for the trade-offs.
261
289
 
290
+ Use `GET /health` as the process liveness probe; it never opens the database. Use
291
+ `GET /ready` as the traffic readiness probe; it returns `200` only when the database
292
+ is reachable and its schema is the expected revision, otherwise a generic `503`.
293
+ The readiness path uses one fixed schema query and returns within a two-second
294
+ application deadline. PostgreSQL uses a separate unpooled engine with connection and
295
+ server-side timeouts configured at startup; SQLite lock waiting is capped at 1.5
296
+ seconds. If a network stack ignores its connection timeout, the single daemon probe
297
+ may continue after the response, but no second probe or connection starts until it
298
+ finishes. Configure the orchestrator probe timeout slightly above two seconds as an
299
+ independent safeguard.
300
+ Both endpoints are intentionally unauthenticated so infrastructure probes can call
301
+ them, and every HTTP response carries a bounded `X-Request-ID`. Put the collector
302
+ behind a TLS-terminating reverse proxy or platform ingress. Configure request rate
303
+ limits, connection limits, trusted proxy headers, and access-log redaction there; the
304
+ application does not implement a second rate limiter and disables Uvicorn access logs
305
+ to avoid recording untrusted URLs or query strings.
306
+
262
307
  Snapshots use strict schema version 1. The collector rejects request bodies larger
263
308
  than 32 MiB and snapshots containing more than 250,000 normalized records. A sync
264
309
  client checks `/api/v1/capabilities` before sending when the endpoint exposes it.
@@ -60,29 +60,29 @@ uv tool run --from git+https://github.com/Guillaume-Lombardo/cli-consumption \
60
60
  `--provider all` detects the supported data stores found in their default locations.
61
61
  Use the provider name below with `--provider` to select one CLI explicitly.
62
62
 
63
- | CLI | Provider name | Default local source | Particularities and limits |
64
- | --- | --- | --- | --- |
65
- | Aider | `aider` | `~/.aider/analytics.jsonl` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
66
- | Amazon Q Developer CLI | `amazon-q` | `~/.local/share/amazon-q/data.sqlite3` | Persistent conversations only; request timing is available, but token counters are not. |
67
- | Amp | `amp` | `~/.local/share/amp/threads/` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
68
- | 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. |
69
- | Cline CLI | `cline` | `~/.cline/data/sessions/sessions.db` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
70
- | Codex | `codex` | `~/.codex/sessions/` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
71
- | Continue CLI | `continue` | `~/.continue/sessions/` | Token usage when present; session files lack reliable per-message timing and duration. |
72
- | Crush | `crush` | `~/.local/share/crush/` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
73
- | Cursor CLI | `cursor` | `~/.cursor/` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
74
- | Gemini CLI | `gemini` | `~/.gemini/tmp/` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
75
- | GitHub Copilot CLI | `copilot` | `~/.copilot/session-state/` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
76
- | Goose | `goose` | `~/.local/share/goose/sessions/sessions.db` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
77
- | Grok Build | `grok` | `~/.grok/sessions/` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
78
- | Kilo Code | `kilo` | `~/.local/share/kilo/kilo.db` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
79
- | Kimi Code CLI | `kimi` | `~/.kimi/sessions/` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
80
- | 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. |
81
- | OpenCode | `opencode` | `~/.local/share/opencode/opencode.db` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
82
- | OpenHands CLI | `openhands` | `~/.openhands/conversations/` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
83
- | Pi | `pi` | `~/.pi/agent/sessions/` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
84
- | 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. |
85
- | Qwen Code | `qwen` | `~/.qwen/projects/` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
63
+ | CLI | Provider name | Aliases | Default local source | Token semantics | Particularities and limits |
64
+ | --- | --- | --- | --- | --- | --- |
65
+ | Aider | `aider` | — | `~/.aider/analytics.jsonl` | `additive` | Requires opt-in analytics logging; no projects, tools, cache/reasoning split, or provider-reported durations. |
66
+ | Amazon Q Developer CLI | `amazon-q` | — | `~/.local/share/amazon-q/data.sqlite3` | `unavailable` | Persistent conversations only; request timing is available, but token counters are not. |
67
+ | Amp | `amp` | — | `~/.local/share/amp/threads/` | `additive` | Per-inference tokens and context windows; no subthreads, compactions, reasoning split, or latency. |
68
+ | Claude Code | `claude` | `claude-code` | `~/.claude/projects/` | `additive` | Main sessions, tokens, tools, and compactions; no subagents, context windows, or provider-reported durations. |
69
+ | Cline CLI | `cline` | — | `~/.cline/data/sessions/sessions.db` | `additive` | Uses the session index and message artifacts; no costs or arbitrary task metadata. |
70
+ | Codex | `codex` | — | `~/.codex/sessions/` | `additive` | Richest support: timing, context pressure, settings, compactions, work items, and subagent relationships. |
71
+ | Continue CLI | `continue` | — | `~/.continue/sessions/` | `additive` | Token usage when present; session files lack reliable per-message timing and duration. |
72
+ | Crush | `crush` | — | `~/.local/share/crush/` | `context-snapshot` | Reads registered per-project SQLite stores; token counters are a latest-context snapshot, not additive usage. |
73
+ | Cursor CLI | `cursor` | — | `~/.cursor/` | `unavailable` | Composer 2 transcripts and chat metadata; no per-message time or tokens, and model attribution is incomplete. |
74
+ | Gemini CLI | `gemini` | — | `~/.gemini/tmp/` | `additive` | Replays active history and rewinds; hashed projects are not reversed and nested agents are excluded. |
75
+ | GitHub Copilot CLI | `copilot` | — | `~/.copilot/session-state/` | `conversation-aggregate` | Tokens are latest shutdown aggregates and cannot be assigned to individual turns. |
76
+ | Goose | `goose` | — | `~/.local/share/goose/sessions/sessions.db` | `additive` | Supports SQLite schema v16; no legacy JSONL, subagents, reasoning tokens, or latency. |
77
+ | Grok Build | `grok` | — | `~/.grok/sessions/` | `additive` | Per-prompt aggregates, reasoning effort, TTFT, and auto-compactions; no costs or subagent relationships. |
78
+ | Kilo Code | `kilo` | — | `~/.local/share/kilo/kilo.db` | `additive` | CLI SQLite store only; excludes legacy IDE tasks, cloud sessions, subagents, context windows, and costs. |
79
+ | Kimi Code CLI | `kimi` | — | `~/.kimi/sessions/` | `additive` | Wire v1 events, context windows, and compactions; selected model is not persisted and is reported as `unknown`. |
80
+ | Mistral Vibe CLI | `mistral-vibe` | — | `~/.vibe/logs/session/` | `conversation-aggregate` | Session-level token aggregates, user turns, tools, and compactions; no per-message timestamps or historical model attribution. |
81
+ | OpenCode | `opencode` | — | `~/.local/share/opencode/opencode.db` | `additive` | SQLite v2 only; no legacy storage, child sessions, context windows, or costs. |
82
+ | OpenHands CLI | `openhands` | — | `~/.openhands/conversations/` | `additive` | SDK persistence with context windows, reasoning effort, and condensations; excludes cloud-only conversations and delegates. |
83
+ | Pi | `pi` | — | `~/.pi/agent/sessions/` | `additive` | Counts all persisted branches; no branch relationships, custom-directory auto-detection, context windows, or provider-reported durations. |
84
+ | Plandex | `plandex` | — | `/plandex-server` | `additive` | Requires an offline copy of a self-hosted `PLANDEX_BASE_DIR`; hosted accounts are not accessed, and models/tools are unavailable. |
85
+ | Qwen Code | `qwen` | — | `~/.qwen/projects/` | `additive` | Follows the active branch and records context windows and compactions; excludes archived and sidechain sessions. |
86
86
 
87
87
  Provider formats are internal and can change without notice. The detailed extraction
88
88
  rules and qualification versions are documented in
@@ -106,12 +106,19 @@ uv run cli-consumption collect --provider codex \
106
106
 
107
107
  Copy only the required provider data. For Codex, copy the `sessions/` directory but
108
108
  never `auth.json` or other credentials. Globally identical conversation IDs are
109
- deduplicated, and the most complete copy wins.
109
+ deduplicated, and the most complete copy wins. After a subagent scope is first seen,
110
+ its relationship graph is replaced only when at least one conversation from that
111
+ provider and source machine is strictly more complete and none is less complete.
112
+ Identical, graph-only, or older copies cannot erase a newer graph.
110
113
 
111
114
  Provider files are untrusted. Monolithic JSON files are limited to 64 MiB, JSONL files
112
- to 256 MiB with an 8 MiB per-line limit, and a snapshot to 250,000 normalized records
113
- while it is being built. Direct provider-file symlinks are refused. `collect --strict`
114
- refuses to write a snapshot when malformed records were skipped.
115
+ to 256 MiB with an 8 MiB per-line limit, 512 MiB of provider-file bytes actually read,
116
+ and discovery to 10,000 candidate entries per provider collection. Provider SQLite
117
+ inputs share a cumulative 512 MiB limit across databases and active WAL, SHM, or
118
+ journal sidecars, plus 250,000 selected rows, 8 MiB per structured field, and 256 MiB
119
+ across structured fields. A snapshot is limited to 250,000 normalized records while it
120
+ is being built. Direct provider-file symlinks are refused. `collect --strict` refuses
121
+ to write a snapshot when malformed records were skipped.
115
122
 
116
123
  Map original working-directory prefixes to stable project labels with repeated
117
124
  `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
@@ -162,6 +169,19 @@ to the window. CSV rows are streamed in stable primary-key order. Spreadsheet fo
162
169
  prefixes in text cells are neutralized with a leading apostrophe; CSV remains a
163
170
  detailed operational-data export, not a share-safe format.
164
171
 
172
+ Dashboard generation preflights the selected report before streaming its tables. The
173
+ selection is limited to 250,000 rows and 128 MiB of selected scalar values, and the
174
+ final self-contained HTML is limited to 128 MiB of bytes actually encoded. If an
175
+ accumulated database exceeds these limits, narrow it with `--since` and/or `--until`.
176
+ A dashboard is streamed through a temporary file in its destination directory,
177
+ synchronized, and atomically replaces an older dashboard only after generation
178
+ succeeds.
179
+
180
+ When `--csv` and the dashboard are requested together, each CSV is still streamed
181
+ before dashboard generation. The dashboard file is atomic, but the output directory
182
+ as a whole is not: a dashboard limit or write failure can leave newly written CSV
183
+ files alongside the preserved older dashboard.
184
+
165
185
  ## SQLite and PostgreSQL
166
186
 
167
187
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -189,6 +209,10 @@ conversation end-time path; see the
189
209
  [timestamp decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0002-canonical-utc-timestamps.md)
190
210
  for the exact representation and downgrade boundary.
191
211
 
212
+ Revision `0004` adds internal per-scope state that serializes subagent graph freshness
213
+ decisions. It does not add snapshot or export fields; see the
214
+ [subagent freshness decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0003-subagent-scope-freshness.md).
215
+
192
216
  Preview retention before deleting normalized metadata:
193
217
 
194
218
  ```bash
@@ -198,6 +222,9 @@ uv run cli-consumption retention --keep-days 90 --database usage.sqlite --apply
198
222
 
199
223
  The first command is a dry run. `--apply` deletes old conversations and their child
200
224
  rows, old subagent relationships, and old ingestion-run records.
225
+ Internal subagent-scope coordination rows remain as replay guards, so an older
226
+ graph-only copy cannot recreate relationships after retention. They contain only the
227
+ provider, source-machine label, and a lock counter and are never exported.
201
228
 
202
229
  ## Central collector API
203
230
 
@@ -224,6 +251,23 @@ deployments also need TLS and standard operational controls. The sync client ref
224
251
  plain HTTP beyond loopback unless `--allow-insecure` is passed explicitly. See
225
252
  [Architecture](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/architecture.md) for the trade-offs.
226
253
 
254
+ Use `GET /health` as the process liveness probe; it never opens the database. Use
255
+ `GET /ready` as the traffic readiness probe; it returns `200` only when the database
256
+ is reachable and its schema is the expected revision, otherwise a generic `503`.
257
+ The readiness path uses one fixed schema query and returns within a two-second
258
+ application deadline. PostgreSQL uses a separate unpooled engine with connection and
259
+ server-side timeouts configured at startup; SQLite lock waiting is capped at 1.5
260
+ seconds. If a network stack ignores its connection timeout, the single daemon probe
261
+ may continue after the response, but no second probe or connection starts until it
262
+ finishes. Configure the orchestrator probe timeout slightly above two seconds as an
263
+ independent safeguard.
264
+ Both endpoints are intentionally unauthenticated so infrastructure probes can call
265
+ them, and every HTTP response carries a bounded `X-Request-ID`. Put the collector
266
+ behind a TLS-terminating reverse proxy or platform ingress. Configure request rate
267
+ limits, connection limits, trusted proxy headers, and access-log redaction there; the
268
+ application does not implement a second rate limiter and disables Uvicorn access logs
269
+ to avoid recording untrusted URLs or query strings.
270
+
227
271
  Snapshots use strict schema version 1. The collector rejects request bodies larger
228
272
  than 32 MiB and snapshots containing more than 250,000 normalized records. A sync
229
273
  client checks `/api/v1/capabilities` before sending when the endpoint exposes it.
@@ -4,11 +4,12 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cli-consumption"
7
- version = "0.2.1"
7
+ version = "0.3.0"
8
8
  description = "Analyze and consolidate AI coding CLI consumption across machines."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
11
  license = "Apache-2.0"
12
+ license-files = ["LICENSE", "NOTICE"]
12
13
  authors = [{ name = "Guillaume Lombardo", email = "lombardo.guillaume@gmail.com" }]
13
14
  keywords = ["ai", "cli", "codex", "observability", "tokens", "usage"]
14
15
  classifiers = [
@@ -36,6 +37,7 @@ sync = ["httpx>=0.27"]
36
37
  [project.urls]
37
38
  Homepage = "https://github.com/Guillaume-Lombardo/cli-consumption"
38
39
  Documentation = "https://github.com/Guillaume-Lombardo/cli-consumption#readme"
40
+ Changelog = "https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/CHANGELOG.md"
39
41
  Issues = "https://github.com/Guillaume-Lombardo/cli-consumption/issues"
40
42
  Repository = "https://github.com/Guillaume-Lombardo/cli-consumption.git"
41
43
 
@@ -46,6 +48,7 @@ cli-consumption = "cli_consumption.cli:app"
46
48
  dev = [
47
49
  "fastapi>=0.115",
48
50
  "httpx>=0.27",
51
+ "hypothesis>=6.165.10",
49
52
  "pre-commit>=4.6.2",
50
53
  "psycopg[binary]>=3.2",
51
54
  "pytest>=8.3",
@@ -58,6 +61,17 @@ dev = [
58
61
  [tool.hatch.build.targets.wheel]
59
62
  packages = ["src/cli_consumption"]
60
63
 
64
+ [tool.hatch.build.targets.sdist]
65
+ include = [
66
+ "/LICENSE",
67
+ "/NOTICE",
68
+ "/CHANGELOG.md",
69
+ "/README.md",
70
+ "/pyproject.toml",
71
+ "/src/cli_consumption",
72
+ ]
73
+ exclude = ["**/__pycache__", "**/*.pyc"]
74
+
61
75
  [tool.pytest.ini_options]
62
76
  addopts = "--strict-config --strict-markers"
63
77
  testpaths = ["tests"]