cli-consumption 0.0.2__tar.gz → 0.0.4__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 (54) hide show
  1. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/yolo/SKILL.md +6 -6
  2. cli_consumption-0.0.4/.agents/skills/yolo/agents/openai.yaml +4 -0
  3. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.github/workflows/ci.yml +2 -2
  4. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.github/workflows/release.yaml +6 -6
  5. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/PKG-INFO +41 -3
  6. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/README.md +40 -2
  7. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/docs/architecture.md +2 -1
  8. cli_consumption-0.0.4/docs/provider-support.md +54 -0
  9. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/docs/roadmap.md +2 -1
  10. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/pyproject.toml +1 -1
  11. cli_consumption-0.0.4/src/cli_consumption/adapters/__init__.py +5 -0
  12. cli_consumption-0.0.4/src/cli_consumption/adapters/claude.py +394 -0
  13. cli_consumption-0.0.4/src/cli_consumption/adapters/opencode.py +463 -0
  14. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/cli.py +90 -29
  15. cli_consumption-0.0.4/tests/test_claude_adapter.py +218 -0
  16. cli_consumption-0.0.4/tests/test_cli.py +267 -0
  17. cli_consumption-0.0.4/tests/test_opencode_adapter.py +261 -0
  18. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/uv.lock +1 -1
  19. cli_consumption-0.0.2/.agents/skills/yolo/agents/openai.yaml +0 -4
  20. cli_consumption-0.0.2/docs/provider-support.md +0 -24
  21. cli_consumption-0.0.2/src/cli_consumption/adapters/__init__.py +0 -3
  22. cli_consumption-0.0.2/tests/test_cli.py +0 -137
  23. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/add-cli-adapter/SKILL.md +0 -0
  24. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/add-cli-adapter/agents/openai.yaml +0 -0
  25. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/audit-usage-privacy/SKILL.md +0 -0
  26. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/audit-usage-privacy/agents/openai.yaml +0 -0
  27. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/evolve-storage-schema/SKILL.md +0 -0
  28. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/evolve-storage-schema/agents/openai.yaml +0 -0
  29. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/yeet-github/SKILL.md +0 -0
  30. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.agents/skills/yeet-github/agents/openai.yaml +0 -0
  31. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.gitignore +0 -0
  32. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.pre-commit-config.yaml +0 -0
  33. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/.python-version +0 -0
  34. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/AGENTS.md +0 -0
  35. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/CONTRIBUTING.md +0 -0
  36. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/LICENSE +0 -0
  37. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/NOTICE +0 -0
  38. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/docs/privacy.md +0 -0
  39. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/__init__.py +0 -0
  40. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/__main__.py +0 -0
  41. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/adapters/base.py +0 -0
  42. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/adapters/codex.py +0 -0
  43. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/api.py +0 -0
  44. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/dashboard.py +0 -0
  45. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/exporting.py +0 -0
  46. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/models.py +0 -0
  47. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/py.typed +0 -0
  48. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/storage.py +0 -0
  49. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/src/cli_consumption/sync.py +0 -0
  50. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/tests/conftest.py +0 -0
  51. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/tests/test_api.py +0 -0
  52. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/tests/test_codex_adapter.py +0 -0
  53. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/tests/test_storage_and_exports.py +0 -0
  54. {cli_consumption-0.0.2 → cli_consumption-0.0.4}/tests/test_sync.py +0 -0
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: yolo
3
- description: Publish the current Codex work in a GitHub pull request, squash-merge it, then clean up its local and remote branches. Use only when the user explicitly invokes `$yolo` or requests the full publish, merge, and cleanup sequence.
3
+ description: Publish the current Codex work in a GitHub pull request, squash-merge it, then clean up its local and remote branches without additional approval prompts. Use only when the user explicitly invokes `$yolo` or requests the full publish, merge, and cleanup sequence.
4
4
  ---
5
5
 
6
6
  # Publish, merge, and clean up
7
7
 
8
- Run each phase in order from the repository root. The implicit pull request is the one for the current Codex work and current branch.
8
+ Run each phase in order from the repository root. The implicit pull request is the one for the current Codex work and current branch. Treat the explicit `$yolo` invocation as advance approval to push, create or ready the pull request, squash-merge it, and delete its exact source branch. Do not pause for additional confirmation during a successful, unambiguous run.
9
9
 
10
10
  ## 1. Publish
11
11
 
12
12
  1. Read all repository instructions and the product specification referenced by `AGENTS.md`.
13
- 2. Load and follow `$yeet-github` in full to inspect, validate, commit, push, and open a draft pull request.
13
+ 2. Load and follow `$yeet-github` in full to inspect, validate, commit, push, and open a draft pull request, except do not request its approval before pushing or publishing: the explicit `$yolo` invocation already provides that approval.
14
14
  3. Retain the exact source and target branches, pushed SHA, pull-request number, and URL.
15
15
  4. Stop after any failure or ambiguous external result. Never merge or clean up after a partial failure.
16
16
 
@@ -21,8 +21,8 @@ Run each phase in order from the repository root. The implicit pull request is t
21
21
  3. Inspect required checks, reviews, conversations, and protections with `gh pr checks` and `gh pr view --json mergeStateStatus,reviewDecision,statusCheckRollup`.
22
22
  4. Mark a ready draft with `gh pr ready <number>`.
23
23
  5. Watch pending checks with `gh pr checks <number> --watch --interval 10`; stop and report any failing check.
24
- 6. Present the final state and obtain explicit approval immediately before merging and deleting branches.
25
- 7. After approval, use `gh pr merge <number> --squash --delete-branch --match-head-commit <source-sha>`.
24
+ 6. Present the verified final state as a progress update, then continue without requesting approval.
25
+ 7. Use `gh pr merge <number> --squash --delete-branch --match-head-commit <source-sha>`.
26
26
  8. If GitHub queues the merge, keep monitoring. Clean up only after `gh pr view <number> --json state,mergedAt,mergeCommit` reports `MERGED`.
27
27
 
28
28
  ## 3. Clean up
@@ -32,7 +32,7 @@ Run each phase in order from the repository root. The implicit pull request is t
32
32
  3. Run `git fetch --prune origin`.
33
33
  4. Switch to the target branch and update it only by fast-forward with `git switch <target-branch>` and `git pull --ff-only origin <target-branch>`.
34
34
  5. Delete the exact local source branch if it remains. `git branch -D <source-branch>` is allowed only after verified squash merge.
35
- 6. If the unprotected remote branch remains, obtain fresh explicit approval before `git push origin --delete <source-branch>`.
35
+ 6. If the exact unprotected remote source branch remains, delete it with `git push origin --delete <source-branch>` without requesting additional approval.
36
36
  7. Run `git status --short --branch` and report the final state.
37
37
 
38
38
  ## Guardrails
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Yolo GitHub"
3
+ short_description: "Publish, squash-merge, and clean up without prompts"
4
+ default_prompt: "Use $yolo to publish, squash-merge, and clean up the current GitHub work without additional approval prompts."
@@ -12,8 +12,8 @@ jobs:
12
12
  quality:
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
- - uses: actions/checkout@v4
16
- - uses: astral-sh/setup-uv@v6
15
+ - uses: actions/checkout@v7.0.1
16
+ - uses: astral-sh/setup-uv@v10.0.1
17
17
  with:
18
18
  enable-cache: true
19
19
  python-version: "3.14"
@@ -25,7 +25,7 @@ jobs:
25
25
  release-sha: ${{ steps.version.outputs.release-sha }}
26
26
  version: ${{ steps.version.outputs.version }}
27
27
  steps:
28
- - uses: actions/checkout@v4
28
+ - uses: actions/checkout@v7.0.1
29
29
  with:
30
30
  fetch-depth: 0
31
31
  ref: ${{ inputs.release_sha || github.sha }}
@@ -77,10 +77,10 @@ jobs:
77
77
  permissions:
78
78
  contents: read
79
79
  steps:
80
- - uses: actions/checkout@v4
80
+ - uses: actions/checkout@v7.0.1
81
81
  with:
82
82
  ref: ${{ needs.detect-version.outputs.release-sha }}
83
- - uses: astral-sh/setup-uv@v6
83
+ - uses: astral-sh/setup-uv@v10.0.1
84
84
  with:
85
85
  enable-cache: true
86
86
  python-version: "3.14"
@@ -92,7 +92,7 @@ jobs:
92
92
  - run: uv run pytest --cov --cov-report=term-missing
93
93
  - run: uv build
94
94
  - name: Upload distributions
95
- uses: actions/upload-artifact@v4
95
+ uses: actions/upload-artifact@v7.0.1
96
96
  with:
97
97
  name: python-package-distributions
98
98
  path: dist/
@@ -105,7 +105,7 @@ jobs:
105
105
  permissions:
106
106
  contents: write
107
107
  steps:
108
- - uses: actions/checkout@v4
108
+ - uses: actions/checkout@v7.0.1
109
109
  with:
110
110
  fetch-depth: 0
111
111
  ref: ${{ needs.detect-version.outputs.release-sha }}
@@ -141,7 +141,7 @@ jobs:
141
141
  id-token: write
142
142
  steps:
143
143
  - name: Download distributions
144
- uses: actions/download-artifact@v4
144
+ uses: actions/download-artifact@v8.0.1
145
145
  with:
146
146
  name: python-package-distributions
147
147
  path: dist/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cli-consumption
3
- Version: 0.0.2
3
+ Version: 0.0.4
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
@@ -33,8 +33,8 @@ models, tokens, tools, conversations, and turns. It can analyze one workstation,
33
33
  consolidate copied data from several machines, or send metadata-only snapshots to a
34
34
  central collector.
35
35
 
36
- Codex is fully supported. Claude Code, OpenCode, Kilo Code, and Pi are planned behind
37
- the same provider-neutral adapter contract.
36
+ Codex, OpenCode, and the core Claude Code local transcript format are supported. Kilo
37
+ Code and Pi are planned behind the same provider-neutral adapter contract.
38
38
 
39
39
  The collector deliberately excludes prompts, responses, tool arguments, and
40
40
  credentials. See [Privacy](docs/privacy.md) before sharing a database or export.
@@ -96,6 +96,28 @@ hostname:
96
96
  uv run cli-consumption collect --database usage.sqlite
97
97
  ```
98
98
 
99
+ Select Claude Code to read `~/.claude/projects/` instead:
100
+
101
+ ```bash
102
+ uv run cli-consumption collect --provider claude --database usage.sqlite
103
+ ```
104
+
105
+ Select OpenCode to read `~/.local/share/opencode/opencode.db` instead:
106
+
107
+ ```bash
108
+ uv run cli-consumption collect --provider opencode --database usage.sqlite
109
+ ```
110
+
111
+ Use `all` to detect and collect every supported provider present on the machine:
112
+
113
+ ```bash
114
+ uv run cli-consumption collect --provider all --database usage.sqlite
115
+ ```
116
+
117
+ With explicit copied sources, each path is inspected for the provider-specific
118
+ `sessions/` or `projects/` directory. Sources that contain no supported provider data
119
+ are rejected instead of silently skipped.
120
+
99
121
  For an offline multi-machine workflow, copy only each machine's Codex `sessions/`
100
122
  directory into a trusted analysis location. Do not copy `auth.json` or other
101
123
  credentials. Then repeat `--source`:
@@ -118,6 +140,22 @@ uv run cli-consumption collect \
118
140
  --project cli-consumption=/home/me/dev/cli-consumption
119
141
  ```
120
142
 
143
+ Copied Claude Code sources point to the configuration directory containing `projects/`:
144
+
145
+ ```bash
146
+ uv run cli-consumption collect --provider claude \
147
+ --source desktop=/data/claude/desktop \
148
+ --source laptop=/data/claude/laptop
149
+ ```
150
+
151
+ Copied OpenCode sources point to the data directory containing `opencode.db`:
152
+
153
+ ```bash
154
+ uv run cli-consumption collect --provider opencode \
155
+ --source desktop=/data/opencode/desktop \
156
+ --source laptop=/data/opencode/laptop
157
+ ```
158
+
121
159
  ## SQLite and PostgreSQL
122
160
 
123
161
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -5,8 +5,8 @@ models, tokens, tools, conversations, and turns. It can analyze one workstation,
5
5
  consolidate copied data from several machines, or send metadata-only snapshots to a
6
6
  central collector.
7
7
 
8
- Codex is fully supported. Claude Code, OpenCode, Kilo Code, and Pi are planned behind
9
- the same provider-neutral adapter contract.
8
+ Codex, OpenCode, and the core Claude Code local transcript format are supported. Kilo
9
+ Code and Pi are planned behind the same provider-neutral adapter contract.
10
10
 
11
11
  The collector deliberately excludes prompts, responses, tool arguments, and
12
12
  credentials. See [Privacy](docs/privacy.md) before sharing a database or export.
@@ -68,6 +68,28 @@ hostname:
68
68
  uv run cli-consumption collect --database usage.sqlite
69
69
  ```
70
70
 
71
+ Select Claude Code to read `~/.claude/projects/` instead:
72
+
73
+ ```bash
74
+ uv run cli-consumption collect --provider claude --database usage.sqlite
75
+ ```
76
+
77
+ Select OpenCode to read `~/.local/share/opencode/opencode.db` instead:
78
+
79
+ ```bash
80
+ uv run cli-consumption collect --provider opencode --database usage.sqlite
81
+ ```
82
+
83
+ Use `all` to detect and collect every supported provider present on the machine:
84
+
85
+ ```bash
86
+ uv run cli-consumption collect --provider all --database usage.sqlite
87
+ ```
88
+
89
+ With explicit copied sources, each path is inspected for the provider-specific
90
+ `sessions/` or `projects/` directory. Sources that contain no supported provider data
91
+ are rejected instead of silently skipped.
92
+
71
93
  For an offline multi-machine workflow, copy only each machine's Codex `sessions/`
72
94
  directory into a trusted analysis location. Do not copy `auth.json` or other
73
95
  credentials. Then repeat `--source`:
@@ -90,6 +112,22 @@ uv run cli-consumption collect \
90
112
  --project cli-consumption=/home/me/dev/cli-consumption
91
113
  ```
92
114
 
115
+ Copied Claude Code sources point to the configuration directory containing `projects/`:
116
+
117
+ ```bash
118
+ uv run cli-consumption collect --provider claude \
119
+ --source desktop=/data/claude/desktop \
120
+ --source laptop=/data/claude/laptop
121
+ ```
122
+
123
+ Copied OpenCode sources point to the data directory containing `opencode.db`:
124
+
125
+ ```bash
126
+ uv run cli-consumption collect --provider opencode \
127
+ --source desktop=/data/opencode/desktop \
128
+ --source laptop=/data/opencode/laptop
129
+ ```
130
+
93
131
  ## SQLite and PostgreSQL
94
132
 
95
133
  A file path selects SQLite. A SQLAlchemy URL selects PostgreSQL:
@@ -16,7 +16,8 @@ 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 is the first complete implementation.
19
+ work-item intervals. Codex exposes the complete analytics contract; Claude Code and
20
+ OpenCode expose the core dimensions available in their local stores.
20
21
  - `models`: define the transport boundary shared by offline and API ingestion.
21
22
  - `storage`: owns the normalized schema, idempotent replacement rules, SQLite, and
22
23
  PostgreSQL engine creation.
@@ -0,0 +1,54 @@
1
+ # Provider support
2
+
3
+ | Provider | Status | Initial source |
4
+ | --- | --- | --- |
5
+ | Codex | Supported | Local rollout JSONL and optional metadata-only subagent state |
6
+ | Claude Code | Supported (core) | Local project transcript JSONL |
7
+ | OpenCode | Supported (core) | Local SQLite v2 session store |
8
+ | Kilo Code | Planned | To be verified before implementation |
9
+ | Pi | Planned | To be verified before implementation |
10
+
11
+ “Supported” means the adapter has synthetic fixtures, extracts conversations, turns,
12
+ models, token usage, and tool names when available, and passes privacy regression tests.
13
+ It does not mean that token counters are equivalent to invoices.
14
+
15
+ `--provider all` detects every supported provider from its expected data directory and
16
+ ingests each metadata-only snapshot independently. With no explicit source it checks
17
+ the local default homes; repeated `--source` paths are filtered by detected format.
18
+
19
+ Codex additionally exposes provider-reported turn duration and TTFT, model context
20
+ window samples, bounded reasoning/collaboration/service-tier labels, timestamped
21
+ compactions, technical work-item categories and durations, and local thread-spawn
22
+ relationships. Work-item content and rate-limit payloads are deliberately excluded.
23
+ Subagent state can remain `open` after a child thread is technically closed; reporting
24
+ therefore derives closure from collected child turns when they are available.
25
+
26
+ Claude Code reads top-level sessions from
27
+ `~/.claude/projects/<project>/<session-id>.jsonl` (or `CLAUDE_CONFIG_DIR`). It extracts
28
+ main-session turns, models, token usage, tool names, and compaction timestamps while
29
+ discarding prompts, responses, tool inputs/results, paths, branches, and arbitrary
30
+ metadata. Streaming fragments are deduplicated by request or message identifier.
31
+
32
+ Claude Code emits uncached, cache-read, and cache-creation input separately. Normalized
33
+ `input_tokens` is their sum, with each component retained in its corresponding field.
34
+ The internal transcript schema can change between Claude Code releases and local usage
35
+ is not billing data. This first increment does not collect subagent transcripts,
36
+ context-window sizes, effort/service-tier settings, TTFT, provider-reported duration,
37
+ or technical work-item intervals.
38
+
39
+ OpenCode reads `opencode.db` from its XDG data directory (normally
40
+ `~/.local/share/opencode/`). It extracts v2 session messages, model references, token
41
+ usage, tool names, and compaction timestamps while discarding message text, reasoning,
42
+ tool inputs/results, shell commands/output, paths, titles, errors, costs, and arbitrary
43
+ metadata. Model labels combine OpenCode's provider and model identifiers.
44
+
45
+ OpenCode reports uncached input, cache reads, cache writes, visible output, and
46
+ reasoning separately. Normalized input and output totals include their respective
47
+ components. The adapter does not currently read pre-v2 JSON storage, legacy
48
+ `message`/`part` tables, child-session relationships, context-window sizes, or
49
+ provider-reported cost. The SQLite schema is internal and may change without notice;
50
+ local token events are not billing data.
51
+
52
+ Provider formats can change without notice. Unknown fields are ignored; malformed
53
+ provider records are counted and skipped. Compatibility fixes should add a fixture for
54
+ both the old and new format whenever possible.
@@ -3,6 +3,7 @@
3
3
  ## Current foundation
4
4
 
5
5
  - Complete Codex local collector
6
+ - Core Claude Code local transcript collector
6
7
  - Offline multi-machine deduplication
7
8
  - SQLite and PostgreSQL storage
8
9
  - Metadata-only central collection API
@@ -11,7 +12,7 @@
11
12
 
12
13
  ## Next provider increments
13
14
 
14
- 1. Validate Claude Code's local and endpoint formats, then add its adapter.
15
+ 1. Extend Claude Code support only where local metadata has reliable semantics.
15
16
  2. Add OpenCode with the same normalized contract.
16
17
  3. Add Kilo Code and Pi after format and licensing review.
17
18
  4. Add cross-provider comparison views once at least two adapters expose reliable model
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cli-consumption"
7
- version = "0.0.2"
7
+ version = "0.0.4"
8
8
  description = "Analyze and consolidate AI coding CLI consumption across machines."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.14"
@@ -0,0 +1,5 @@
1
+ from cli_consumption.adapters.claude import ClaudeAdapter
2
+ from cli_consumption.adapters.codex import CodexAdapter
3
+ from cli_consumption.adapters.opencode import OpenCodeAdapter
4
+
5
+ __all__ = ["ClaudeAdapter", "CodexAdapter", "OpenCodeAdapter"]