cli-consumption 0.1.1__tar.gz → 0.2.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 (118) hide show
  1. cli_consumption-0.2.1/.github/workflows/ci.yml +64 -0
  2. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.github/workflows/release.yaml +6 -1
  3. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/AGENTS.md +2 -1
  4. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/CONTRIBUTING.md +17 -3
  5. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/PKG-INFO +107 -17
  6. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/README.md +94 -11
  7. cli_consumption-0.2.1/SECURITY.md +37 -0
  8. cli_consumption-0.2.1/docs/architecture.md +124 -0
  9. cli_consumption-0.2.1/docs/decisions/0001-versioned-schema-migrations.md +50 -0
  10. cli_consumption-0.2.1/docs/decisions/0002-canonical-utc-timestamps.md +94 -0
  11. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/docs/privacy.md +39 -3
  12. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/docs/provider-support.md +20 -0
  13. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/docs/roadmap.md +10 -2
  14. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/pyproject.toml +16 -7
  15. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/_shared.py +40 -1
  16. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/aider.py +25 -25
  17. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/amazon_q.py +4 -1
  18. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/amp.py +2 -1
  19. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/base.py +4 -0
  20. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/claude.py +20 -21
  21. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/cline.py +6 -1
  22. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/codex.py +79 -30
  23. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/continue_cli.py +2 -1
  24. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/copilot.py +14 -14
  25. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/crush.py +7 -2
  26. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/cursor.py +18 -14
  27. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/gemini.py +17 -14
  28. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/goose.py +6 -1
  29. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/grok.py +5 -6
  30. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/kilo.py +6 -1
  31. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/kimi.py +2 -1
  32. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/mistral_vibe.py +18 -17
  33. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/opencode.py +6 -1
  34. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/openhands.py +3 -2
  35. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/pi.py +12 -12
  36. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/plandex.py +2 -1
  37. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/qwen.py +14 -14
  38. cli_consumption-0.2.1/src/cli_consumption/adapters/registry.py +250 -0
  39. cli_consumption-0.2.1/src/cli_consumption/api.py +143 -0
  40. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/cli.py +238 -128
  41. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/dashboard.py +59 -22
  42. cli_consumption-0.2.1/src/cli_consumption/exporting.py +55 -0
  43. cli_consumption-0.2.1/src/cli_consumption/migrations/__init__.py +1 -0
  44. cli_consumption-0.2.1/src/cli_consumption/migrations/env.py +20 -0
  45. cli_consumption-0.2.1/src/cli_consumption/migrations/versions/__init__.py +1 -0
  46. cli_consumption-0.2.1/src/cli_consumption/migrations/versions/v0001_baseline.py +269 -0
  47. cli_consumption-0.2.1/src/cli_consumption/migrations/versions/v0002_minimize_subagents.py +78 -0
  48. cli_consumption-0.2.1/src/cli_consumption/migrations/versions/v0003_canonical_timestamps.py +94 -0
  49. cli_consumption-0.2.1/src/cli_consumption/models.py +397 -0
  50. cli_consumption-0.2.1/src/cli_consumption/reporting.py +198 -0
  51. cli_consumption-0.2.1/src/cli_consumption/retention.py +66 -0
  52. cli_consumption-0.2.1/src/cli_consumption/schema.py +355 -0
  53. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/storage.py +115 -138
  54. cli_consumption-0.2.1/src/cli_consumption/sync.py +80 -0
  55. cli_consumption-0.2.1/src/cli_consumption/timestamps.py +17 -0
  56. cli_consumption-0.2.1/tests/smoke_minimal_install.py +69 -0
  57. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_aider_adapter.py +16 -1
  58. cli_consumption-0.2.1/tests/test_api.py +164 -0
  59. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_cli.py +289 -1
  60. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_codex_adapter.py +83 -1
  61. cli_consumption-0.2.1/tests/test_exporting.py +85 -0
  62. cli_consumption-0.2.1/tests/test_input_limits.py +57 -0
  63. cli_consumption-0.2.1/tests/test_migrations_and_retention.py +752 -0
  64. cli_consumption-0.2.1/tests/test_packaging.py +26 -0
  65. cli_consumption-0.2.1/tests/test_provider_registry.py +191 -0
  66. cli_consumption-0.2.1/tests/test_reporting.py +248 -0
  67. cli_consumption-0.2.1/tests/test_snapshot_contract.py +75 -0
  68. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_storage_and_exports.py +62 -3
  69. cli_consumption-0.2.1/tests/test_sync.py +104 -0
  70. cli_consumption-0.2.1/tests/test_timestamps.py +61 -0
  71. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/uv.lock +257 -12
  72. cli_consumption-0.1.1/.github/workflows/ci.yml +0 -26
  73. cli_consumption-0.1.1/docs/architecture.md +0 -80
  74. cli_consumption-0.1.1/src/cli_consumption/api.py +0 -66
  75. cli_consumption-0.1.1/src/cli_consumption/exporting.py +0 -31
  76. cli_consumption-0.1.1/src/cli_consumption/models.py +0 -60
  77. cli_consumption-0.1.1/src/cli_consumption/sync.py +0 -25
  78. cli_consumption-0.1.1/tests/test_api.py +0 -61
  79. cli_consumption-0.1.1/tests/test_sync.py +0 -33
  80. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/add-cli-adapter/SKILL.md +0 -0
  81. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/add-cli-adapter/agents/openai.yaml +0 -0
  82. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/audit-usage-privacy/SKILL.md +0 -0
  83. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/audit-usage-privacy/agents/openai.yaml +0 -0
  84. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/evolve-storage-schema/SKILL.md +0 -0
  85. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/evolve-storage-schema/agents/openai.yaml +0 -0
  86. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/yeet-github/SKILL.md +0 -0
  87. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/yeet-github/agents/openai.yaml +0 -0
  88. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/yolo/SKILL.md +0 -0
  89. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.agents/skills/yolo/agents/openai.yaml +0 -0
  90. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.gitignore +0 -0
  91. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.pre-commit-config.yaml +0 -0
  92. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/.python-version +0 -0
  93. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/LICENSE +0 -0
  94. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/NOTICE +0 -0
  95. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/__init__.py +0 -0
  96. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/__main__.py +0 -0
  97. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/adapters/__init__.py +0 -0
  98. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/src/cli_consumption/py.typed +0 -0
  99. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/conftest.py +0 -0
  100. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_amazon_q_adapter.py +0 -0
  101. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_amp_adapter.py +0 -0
  102. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_claude_adapter.py +0 -0
  103. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_cline_adapter.py +0 -0
  104. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_continue_adapter.py +0 -0
  105. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_copilot_adapter.py +0 -0
  106. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_crush_adapter.py +0 -0
  107. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_cursor_adapter.py +0 -0
  108. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_gemini_adapter.py +0 -0
  109. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_goose_adapter.py +0 -0
  110. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_grok_adapter.py +0 -0
  111. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_kilo_adapter.py +0 -0
  112. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_kimi_adapter.py +0 -0
  113. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_mistral_vibe_adapter.py +0 -0
  114. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_opencode_adapter.py +0 -0
  115. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_openhands_adapter.py +0 -0
  116. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_pi_adapter.py +0 -0
  117. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_plandex_adapter.py +0 -0
  118. {cli_consumption-0.1.1 → cli_consumption-0.2.1}/tests/test_qwen_adapter.py +0 -0
@@ -0,0 +1,64 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ quality:
13
+ runs-on: ubuntu-latest
14
+ env:
15
+ TEST_POSTGRESQL_URL: postgresql+psycopg://postgres:postgres@127.0.0.1:5432/cli_consumption_test
16
+ services:
17
+ postgres:
18
+ image: postgres:17-alpine
19
+ env:
20
+ POSTGRES_DB: cli_consumption_test
21
+ POSTGRES_PASSWORD: postgres
22
+ POSTGRES_USER: postgres
23
+ ports:
24
+ - 5432:5432
25
+ options: >-
26
+ --health-cmd "pg_isready -U postgres -d cli_consumption_test"
27
+ --health-interval 5s
28
+ --health-timeout 5s
29
+ --health-retries 10
30
+ steps:
31
+ - uses: actions/checkout@v7.0.1
32
+ - uses: astral-sh/setup-uv@v10.0.1
33
+ with:
34
+ enable-cache: true
35
+ python-version: "3.14"
36
+ - run: uv sync --locked --all-groups --all-extras
37
+ - run: uv run pre-commit run --all-files --show-diff-on-failure
38
+ - run: uv run ruff format --check .
39
+ - run: uv run ruff check .
40
+ - run: uv run ty check --output-format github
41
+ - run: uv run pytest --cov --cov-report=term-missing
42
+ - run: uv build
43
+ - name: Smoke test the minimal wheel
44
+ run: |
45
+ wheel="$(find dist -maxdepth 1 -name '*.whl' -print -quit)"
46
+ uv run --isolated --no-project --python 3.14 \
47
+ --with "${wheel}" python tests/smoke_minimal_install.py
48
+
49
+ compatibility:
50
+ runs-on: ubuntu-latest
51
+ env:
52
+ UV_PYTHON: ${{ matrix.python-version }}
53
+ strategy:
54
+ fail-fast: false
55
+ matrix:
56
+ python-version: ["3.12", "3.13", "3.14"]
57
+ steps:
58
+ - uses: actions/checkout@v7.0.1
59
+ - uses: astral-sh/setup-uv@v10.0.1
60
+ with:
61
+ enable-cache: true
62
+ python-version: ${{ matrix.python-version }}
63
+ - run: uv sync --locked --all-groups --all-extras
64
+ - run: uv run pytest
@@ -84,13 +84,18 @@ jobs:
84
84
  with:
85
85
  enable-cache: true
86
86
  python-version: "3.14"
87
- - run: uv sync --locked --all-groups
87
+ - run: uv sync --locked --all-groups --all-extras
88
88
  - run: uv run pre-commit run --all-files --show-diff-on-failure
89
89
  - run: uv run ruff format --check .
90
90
  - run: uv run ruff check .
91
91
  - run: uv run ty check --output-format github
92
92
  - run: uv run pytest --cov --cov-report=term-missing
93
93
  - run: uv build
94
+ - name: Smoke test the minimal wheel
95
+ run: |
96
+ wheel="$(find dist -maxdepth 1 -name '*.whl' -print -quit)"
97
+ uv run --isolated --no-project --python 3.14 \
98
+ --with "${wheel}" python tests/smoke_minimal_install.py
94
99
  - name: Upload distributions
95
100
  uses: actions/upload-artifact@v7.0.1
96
101
  with:
@@ -6,7 +6,7 @@ Read this file, `README.md`, `CONTRIBUTING.md`, and the relevant documents under
6
6
  `docs/` before changing the repository. Keep changes scoped to one short-lived branch
7
7
  and one coherent pull request.
8
8
 
9
- The project is a Python 3.14+ package managed exclusively with `uv`. Do not introduce
9
+ The project is a Python 3.12+ package managed exclusively with `uv`. Do not introduce
10
10
  another package manager, task runner, ORM, web framework, or migration tool without an
11
11
  accepted architecture decision.
12
12
 
@@ -39,6 +39,7 @@ accepted architecture decision.
39
39
  Run all of the following before requesting review:
40
40
 
41
41
  ```bash
42
+ uv sync --all-extras --all-groups
42
43
  uv run pre-commit run --all-files
43
44
  uv run ruff format --check .
44
45
  uv run ruff check .
@@ -6,7 +6,7 @@
6
6
  git switch main
7
7
  git pull --ff-only
8
8
  git switch -c feat/short-description
9
- uv sync --all-groups
9
+ uv sync --all-extras --all-groups
10
10
  uv run pre-commit install
11
11
  ```
12
12
 
@@ -16,12 +16,26 @@ file manually.
16
16
  ## Make a change
17
17
 
18
18
  Keep provider parsing behind the adapter interface and normalized persistence behind
19
- the storage module. A new field must have a documented meaning across providers or be
20
- explicitly namespaced as provider-specific.
19
+ the storage module. Register providers once in the adapter registry rather than adding
20
+ parallel CLI or detection lists. A new field must have a documented meaning across
21
+ providers or be explicitly namespaced as provider-specific.
21
22
 
22
23
  Do not add telemetry. Test fixtures must be synthetic and must not contain copied user
23
24
  conversations or credentials.
24
25
 
26
+ Schema changes require a forward Alembic migration for both SQLite and PostgreSQL, an
27
+ explicit downgrade boundary, legacy-adoption tests, and mixed-version deployment notes.
28
+ Snapshot protocol changes must preserve strict validation, bounded payloads, generic
29
+ errors, and the documented server-first upgrade sequence. Export changes must preserve
30
+ deterministic ordering, bounded-memory CSV streaming, complete selected conversation
31
+ graphs, and spreadsheet-formula neutralization.
32
+
33
+ Provider readers must use the bounded file and JSONL helpers in `adapters/_shared.py`,
34
+ must not follow direct provider-file symlinks, and must stay within the shared snapshot
35
+ record budget. Every registered adapter test module must include a synthetic canary and
36
+ assert its absence from the normalized snapshot; shared privacy tests cover all later
37
+ output surfaces.
38
+
25
39
  ## Validate and review
26
40
 
27
41
  Run the quality gates documented in `AGENTS.md`, inspect the complete diff, then open a
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cli-consumption
3
- Version: 0.1.1
3
+ Version: 0.2.1
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
@@ -15,15 +15,22 @@ Classifier: Development Status :: 3 - Alpha
15
15
  Classifier: Environment :: Console
16
16
  Classifier: License :: OSI Approved :: Apache Software License
17
17
  Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
18
20
  Classifier: Programming Language :: Python :: 3.14
19
21
  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
22
+ Requires-Python: >=3.12
23
+ Requires-Dist: alembic>=1.14
24
+ Requires-Dist: pydantic>=2.10
24
25
  Requires-Dist: sqlalchemy>=2.0
25
26
  Requires-Dist: typer>=0.15
26
- Requires-Dist: uvicorn>=0.34
27
+ Provides-Extra: postgres
28
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'postgres'
29
+ Provides-Extra: server
30
+ Requires-Dist: fastapi>=0.115; extra == 'server'
31
+ Requires-Dist: uvicorn>=0.34; extra == 'server'
32
+ Provides-Extra: sync
33
+ Requires-Dist: httpx>=0.27; extra == 'sync'
27
34
  Description-Content-Type: text/markdown
28
35
 
29
36
  # CLI Consumption
@@ -34,18 +41,22 @@ machines, and can send metadata-only snapshots to a central collector.
34
41
 
35
42
  It never stores prompts, responses, tool arguments, credentials, or raw provider
36
43
  events. Local token counters are usage metadata, not billing records. Read the
37
- [privacy boundary](docs/privacy.md) before sharing a database or report.
44
+ [privacy boundary](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/privacy.md)
45
+ before sharing a database or report.
38
46
 
39
47
  ## Quick start
40
48
 
41
- CLI Consumption requires Python 3.14 or newer and uses
49
+ CLI Consumption requires Python 3.12 or newer and uses
42
50
  [`uv`](https://docs.astral.sh/uv/).
51
+ Supporting 3.12–3.14 keeps the package usable on more existing development and CI
52
+ images without changing its architecture; the compatibility matrix exercises all
53
+ three versions.
43
54
 
44
55
  From a checkout, collect every supported CLI detected on the machine and generate a
45
56
  self-contained dashboard:
46
57
 
47
58
  ```bash
48
- uv sync
59
+ uv sync --all-extras
49
60
  uv run cli-consumption collect --provider all
50
61
  uv run cli-consumption export --output reports
51
62
  ```
@@ -66,6 +77,12 @@ uv tool run cli-consumption collect --provider all
66
77
  uv tool run cli-consumption export --output reports
67
78
  ```
68
79
 
80
+ The default installation covers local collection, SQLite storage, and exports. Install
81
+ only the optional runtime capabilities you use: `cli-consumption[sync]` for the sync
82
+ client, `cli-consumption[server]` for the collector service, and
83
+ `cli-consumption[postgres]` for PostgreSQL. Extras can be combined, for example
84
+ `cli-consumption[server,postgres]` on a central collector.
85
+
69
86
  To run the latest unreleased GitHub source:
70
87
 
71
88
  ```bash
@@ -104,7 +121,7 @@ Use the provider name below with `--provider` to select one CLI explicitly.
104
121
 
105
122
  Provider formats are internal and can change without notice. The detailed extraction
106
123
  rules and qualification versions are documented in
107
- [Provider support](docs/provider-support.md).
124
+ [Provider support](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/provider-support.md).
108
125
 
109
126
  ## Collect copied data
110
127
 
@@ -126,6 +143,11 @@ Copy only the required provider data. For Codex, copy the `sessions/` directory
126
143
  never `auth.json` or other credentials. Globally identical conversation IDs are
127
144
  deduplicated, and the most complete copy wins.
128
145
 
146
+ 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.
150
+
129
151
  Map original working-directory prefixes to stable project labels with repeated
130
152
  `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
131
153
 
@@ -147,7 +169,7 @@ uv run cli-consumption collect --provider plandex \
147
169
 
148
170
  The dashboard can filter by time, provider, machine, project, and model. It reports
149
171
  activity, token composition, cache efficiency, latency and duration distributions,
150
- technical throughput, context pressure, work-item reliability, configuration cohorts,
172
+ turn rate, context pressure, work-item reliability, configuration cohorts,
151
173
  compactions, subagent delegation, and ingestion quality. Availability varies by
152
174
  provider, as summarized in the table above.
153
175
 
@@ -162,6 +184,19 @@ Share-safe reports still disclose aggregate work patterns and remain private
162
184
  operational data. A technically completed turn is not a measure of task quality or
163
185
  productivity.
164
186
 
187
+ Limit an export to conversations whose activity overlaps a half-open UTC window:
188
+
189
+ ```bash
190
+ uv run cli-consumption export --output reports \
191
+ --since 2026-08-01 --until 2026-08-31
192
+ ```
193
+
194
+ Dates denote UTC calendar boundaries; timestamps must include a timezone. An included
195
+ conversation is exported with its complete child graph rather than partially redacted
196
+ to the window. CSV rows are streamed in stable primary-key order. Spreadsheet formula
197
+ prefixes in text cells are neutralized with a leading apostrophe; CSV remains a
198
+ detailed operational-data export, not a share-safe format.
199
+
165
200
  ## SQLite and PostgreSQL
166
201
 
167
202
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -175,6 +210,30 @@ uv run cli-consumption collect --provider all \
175
210
  Pass credentials through environment variables or a secret manager rather than shell
176
211
  history. `CLI_CONSUMPTION_DATABASE` can provide the database setting.
177
212
 
213
+ Database schemas are upgraded automatically when a command opens them. Existing
214
+ unversioned databases that exactly match a published schema are adopted before the
215
+ upgrade; unknown or modified schemas are refused. Back up production databases before
216
+ upgrading and do not run mixed application versions against one database while a
217
+ migration is in progress. See the
218
+ [migration decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0001-versioned-schema-migrations.md)
219
+ for rollback and compatibility rules.
220
+
221
+ Timezone-aware timestamps are normalized to fixed-width UTC strings during ingestion.
222
+ Revision `0003` rewrites legacy timestamp text in bounded batches and adds an indexed
223
+ conversation end-time path; see the
224
+ [timestamp decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0002-canonical-utc-timestamps.md)
225
+ for the exact representation and downgrade boundary.
226
+
227
+ Preview retention before deleting normalized metadata:
228
+
229
+ ```bash
230
+ uv run cli-consumption retention --keep-days 90 --database usage.sqlite
231
+ uv run cli-consumption retention --keep-days 90 --database usage.sqlite --apply
232
+ ```
233
+
234
+ The first command is a dry run. `--apply` deletes old conversations and their child
235
+ rows, old subagent relationships, and old ingestion-run records.
236
+
178
237
  ## Central collector API
179
238
 
180
239
  Copied files are simplest for personal or air-gapped use. For recurring collection
@@ -196,8 +255,31 @@ uv run cli-consumption sync --provider all \
196
255
  ```
197
256
 
198
257
  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.
258
+ deployments also need TLS and standard operational controls. The sync client refuses
259
+ plain HTTP beyond loopback unless `--allow-insecure` is passed explicitly. See
260
+ [Architecture](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/architecture.md) for the trade-offs.
261
+
262
+ Snapshots use strict schema version 1. The collector rejects request bodies larger
263
+ than 32 MiB and snapshots containing more than 250,000 normalized records. A sync
264
+ client checks `/api/v1/capabilities` before sending when the endpoint exposes it.
265
+ Upgrade the server before clients whenever supported snapshot schemas change.
266
+
267
+ ## Provider diagnostics
268
+
269
+ `providers` reads the central adapter registry. Its machine-readable mode checks local
270
+ default stores and emits deterministic JSON:
271
+
272
+ ```bash
273
+ uv run cli-consumption providers --json
274
+ ```
275
+
276
+ Each provider reports one of `no-data`, `detected`, `compatible`, `degraded`, or
277
+ `unsupported-schema`. Diagnostics parse enough metadata to assess compatibility but do
278
+ not persist it and never include paths, identifiers, record contents, counts, or parser
279
+ errors in their output. Schema version 2 also declares whether token counters are
280
+ additive, conversation aggregates, context snapshots, or unavailable. Dashboard token
281
+ per-turn percentiles use only additive providers rather than treating missing measures
282
+ as zero.
201
283
 
202
284
  ## Commands
203
285
 
@@ -208,13 +290,18 @@ deployments also need TLS and standard operational controls. See
208
290
  | `serve` | Run the central collection API. |
209
291
  | `export` | Write the HTML dashboard and optional CSV tables. |
210
292
  | `providers` | List provider names and support status. |
293
+ | `retention` | Preview or apply deletion of metadata outside a retention window. |
211
294
 
212
295
  Run `uv run cli-consumption COMMAND --help` for all options.
213
296
 
297
+ `collect`, `export`, and `retention` accept `--json` for deterministic
298
+ machine-readable results. `collect --strict` rejects snapshots containing malformed
299
+ provider records before opening the destination database.
300
+
214
301
  ## Development
215
302
 
216
303
  ```bash
217
- uv sync --all-groups
304
+ uv sync --all-extras --all-groups
218
305
  uv run pre-commit install
219
306
  uv run pre-commit run --all-files
220
307
  uv run ruff format --check .
@@ -225,9 +312,12 @@ uv build
225
312
  ```
226
313
 
227
314
  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.
315
+ `main`. Read
316
+ [CONTRIBUTING.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/CONTRIBUTING.md)
317
+ and [AGENTS.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/AGENTS.md)
318
+ before changing the project. Security issues follow the private reporting guidance in
319
+ [SECURITY.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/SECURITY.md).
230
320
 
231
321
  ## License
232
322
 
233
- Licensed under the [Apache License 2.0](LICENSE).
323
+ Licensed under the [Apache License 2.0](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/LICENSE).
@@ -6,18 +6,22 @@ machines, and can send metadata-only snapshots to a central collector.
6
6
 
7
7
  It never stores prompts, responses, tool arguments, credentials, or raw provider
8
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.
9
+ [privacy boundary](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/privacy.md)
10
+ before sharing a database or report.
10
11
 
11
12
  ## Quick start
12
13
 
13
- CLI Consumption requires Python 3.14 or newer and uses
14
+ CLI Consumption requires Python 3.12 or newer and uses
14
15
  [`uv`](https://docs.astral.sh/uv/).
16
+ Supporting 3.12–3.14 keeps the package usable on more existing development and CI
17
+ images without changing its architecture; the compatibility matrix exercises all
18
+ three versions.
15
19
 
16
20
  From a checkout, collect every supported CLI detected on the machine and generate a
17
21
  self-contained dashboard:
18
22
 
19
23
  ```bash
20
- uv sync
24
+ uv sync --all-extras
21
25
  uv run cli-consumption collect --provider all
22
26
  uv run cli-consumption export --output reports
23
27
  ```
@@ -38,6 +42,12 @@ uv tool run cli-consumption collect --provider all
38
42
  uv tool run cli-consumption export --output reports
39
43
  ```
40
44
 
45
+ The default installation covers local collection, SQLite storage, and exports. Install
46
+ only the optional runtime capabilities you use: `cli-consumption[sync]` for the sync
47
+ client, `cli-consumption[server]` for the collector service, and
48
+ `cli-consumption[postgres]` for PostgreSQL. Extras can be combined, for example
49
+ `cli-consumption[server,postgres]` on a central collector.
50
+
41
51
  To run the latest unreleased GitHub source:
42
52
 
43
53
  ```bash
@@ -76,7 +86,7 @@ Use the provider name below with `--provider` to select one CLI explicitly.
76
86
 
77
87
  Provider formats are internal and can change without notice. The detailed extraction
78
88
  rules and qualification versions are documented in
79
- [Provider support](docs/provider-support.md).
89
+ [Provider support](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/provider-support.md).
80
90
 
81
91
  ## Collect copied data
82
92
 
@@ -98,6 +108,11 @@ Copy only the required provider data. For Codex, copy the `sessions/` directory
98
108
  never `auth.json` or other credentials. Globally identical conversation IDs are
99
109
  deduplicated, and the most complete copy wins.
100
110
 
111
+ 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
+
101
116
  Map original working-directory prefixes to stable project labels with repeated
102
117
  `--project NAME=PATH_PREFIX` options. The longest matching prefix wins:
103
118
 
@@ -119,7 +134,7 @@ uv run cli-consumption collect --provider plandex \
119
134
 
120
135
  The dashboard can filter by time, provider, machine, project, and model. It reports
121
136
  activity, token composition, cache efficiency, latency and duration distributions,
122
- technical throughput, context pressure, work-item reliability, configuration cohorts,
137
+ turn rate, context pressure, work-item reliability, configuration cohorts,
123
138
  compactions, subagent delegation, and ingestion quality. Availability varies by
124
139
  provider, as summarized in the table above.
125
140
 
@@ -134,6 +149,19 @@ Share-safe reports still disclose aggregate work patterns and remain private
134
149
  operational data. A technically completed turn is not a measure of task quality or
135
150
  productivity.
136
151
 
152
+ Limit an export to conversations whose activity overlaps a half-open UTC window:
153
+
154
+ ```bash
155
+ uv run cli-consumption export --output reports \
156
+ --since 2026-08-01 --until 2026-08-31
157
+ ```
158
+
159
+ Dates denote UTC calendar boundaries; timestamps must include a timezone. An included
160
+ conversation is exported with its complete child graph rather than partially redacted
161
+ to the window. CSV rows are streamed in stable primary-key order. Spreadsheet formula
162
+ prefixes in text cells are neutralized with a leading apostrophe; CSV remains a
163
+ detailed operational-data export, not a share-safe format.
164
+
137
165
  ## SQLite and PostgreSQL
138
166
 
139
167
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -147,6 +175,30 @@ uv run cli-consumption collect --provider all \
147
175
  Pass credentials through environment variables or a secret manager rather than shell
148
176
  history. `CLI_CONSUMPTION_DATABASE` can provide the database setting.
149
177
 
178
+ Database schemas are upgraded automatically when a command opens them. Existing
179
+ unversioned databases that exactly match a published schema are adopted before the
180
+ upgrade; unknown or modified schemas are refused. Back up production databases before
181
+ upgrading and do not run mixed application versions against one database while a
182
+ migration is in progress. See the
183
+ [migration decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0001-versioned-schema-migrations.md)
184
+ for rollback and compatibility rules.
185
+
186
+ Timezone-aware timestamps are normalized to fixed-width UTC strings during ingestion.
187
+ Revision `0003` rewrites legacy timestamp text in bounded batches and adds an indexed
188
+ conversation end-time path; see the
189
+ [timestamp decision](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/decisions/0002-canonical-utc-timestamps.md)
190
+ for the exact representation and downgrade boundary.
191
+
192
+ Preview retention before deleting normalized metadata:
193
+
194
+ ```bash
195
+ uv run cli-consumption retention --keep-days 90 --database usage.sqlite
196
+ uv run cli-consumption retention --keep-days 90 --database usage.sqlite --apply
197
+ ```
198
+
199
+ The first command is a dry run. `--apply` deletes old conversations and their child
200
+ rows, old subagent relationships, and old ingestion-run records.
201
+
150
202
  ## Central collector API
151
203
 
152
204
  Copied files are simplest for personal or air-gapped use. For recurring collection
@@ -168,8 +220,31 @@ uv run cli-consumption sync --provider all \
168
220
  ```
169
221
 
170
222
  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.
223
+ deployments also need TLS and standard operational controls. The sync client refuses
224
+ plain HTTP beyond loopback unless `--allow-insecure` is passed explicitly. See
225
+ [Architecture](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/architecture.md) for the trade-offs.
226
+
227
+ Snapshots use strict schema version 1. The collector rejects request bodies larger
228
+ than 32 MiB and snapshots containing more than 250,000 normalized records. A sync
229
+ client checks `/api/v1/capabilities` before sending when the endpoint exposes it.
230
+ Upgrade the server before clients whenever supported snapshot schemas change.
231
+
232
+ ## Provider diagnostics
233
+
234
+ `providers` reads the central adapter registry. Its machine-readable mode checks local
235
+ default stores and emits deterministic JSON:
236
+
237
+ ```bash
238
+ uv run cli-consumption providers --json
239
+ ```
240
+
241
+ Each provider reports one of `no-data`, `detected`, `compatible`, `degraded`, or
242
+ `unsupported-schema`. Diagnostics parse enough metadata to assess compatibility but do
243
+ not persist it and never include paths, identifiers, record contents, counts, or parser
244
+ errors in their output. Schema version 2 also declares whether token counters are
245
+ additive, conversation aggregates, context snapshots, or unavailable. Dashboard token
246
+ per-turn percentiles use only additive providers rather than treating missing measures
247
+ as zero.
173
248
 
174
249
  ## Commands
175
250
 
@@ -180,13 +255,18 @@ deployments also need TLS and standard operational controls. See
180
255
  | `serve` | Run the central collection API. |
181
256
  | `export` | Write the HTML dashboard and optional CSV tables. |
182
257
  | `providers` | List provider names and support status. |
258
+ | `retention` | Preview or apply deletion of metadata outside a retention window. |
183
259
 
184
260
  Run `uv run cli-consumption COMMAND --help` for all options.
185
261
 
262
+ `collect`, `export`, and `retention` accept `--json` for deterministic
263
+ machine-readable results. `collect --strict` rejects snapshots containing malformed
264
+ provider records before opening the destination database.
265
+
186
266
  ## Development
187
267
 
188
268
  ```bash
189
- uv sync --all-groups
269
+ uv sync --all-extras --all-groups
190
270
  uv run pre-commit install
191
271
  uv run pre-commit run --all-files
192
272
  uv run ruff format --check .
@@ -197,9 +277,12 @@ uv build
197
277
  ```
198
278
 
199
279
  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.
280
+ `main`. Read
281
+ [CONTRIBUTING.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/CONTRIBUTING.md)
282
+ and [AGENTS.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/AGENTS.md)
283
+ before changing the project. Security issues follow the private reporting guidance in
284
+ [SECURITY.md](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/SECURITY.md).
202
285
 
203
286
  ## License
204
287
 
205
- Licensed under the [Apache License 2.0](LICENSE).
288
+ Licensed under the [Apache License 2.0](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/LICENSE).
@@ -0,0 +1,37 @@
1
+ # Security policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes are made on the latest released version and on `main`. Older releases
6
+ are not maintained as separate security branches. Upgrade to the latest release before
7
+ reporting a problem that may already have been fixed.
8
+
9
+ ## Reporting a vulnerability
10
+
11
+ Do not open a public issue for a suspected vulnerability. Email
12
+ `lombardo.guillaume@gmail.com` with the subject `CLI Consumption security report` and
13
+ include:
14
+
15
+ - the affected version and operating system;
16
+ - the provider, command, or API surface involved;
17
+ - reproduction steps using synthetic data;
18
+ - the expected and observed impact;
19
+ - any suggested mitigation.
20
+
21
+ Do not send real prompts, responses, credentials, provider databases, or other private
22
+ conversation data. Use a synthetic canary when demonstrating a disclosure.
23
+
24
+ The maintainer will acknowledge the report, assess whether it crosses the documented
25
+ privacy or security boundary, and coordinate a fix and disclosure when appropriate.
26
+
27
+ ## Security boundary
28
+
29
+ Provider files and incoming snapshots are untrusted input. Relevant reports include
30
+ content or credential disclosure, unsafe filesystem traversal, denial of service,
31
+ authentication bypass, cross-machine data corruption, and generated dashboards that
32
+ perform network requests or execute provider-controlled content.
33
+
34
+ Operational exposure caused solely by publishing a normalized database or detailed CSV
35
+ is outside the vulnerability boundary: those artifacts intentionally contain private
36
+ operational metadata. The precise allowed and prohibited fields are documented in the
37
+ [privacy boundary](https://github.com/Guillaume-Lombardo/cli-consumption/blob/main/docs/privacy.md).