codex-usage-tracking 0.4.0__tar.gz → 0.4.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.
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/.codex-plugin/plugin.json +1 -1
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/CHANGELOG.md +7 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/PKG-INFO +6 -3
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/README.md +5 -2
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/cli-reference.md +56 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/dashboard-guide.md +2 -2
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/development.md +8 -7
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/install.md +2 -0
- codex_usage_tracking-0.4.1/docs/one-dot-oh-readiness.md +226 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/pricing-and-credits.md +4 -1
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/pyproject.toml +1 -1
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/check_release.py +100 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/smoke_installed_package.py +46 -2
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-tracker/scripts/run_mcp.py +2 -2
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/__init__.py +1 -1
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/PKG-INFO +6 -3
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/SOURCES.txt +1 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_cli_lifecycle.py +38 -1
- codex_usage_tracking-0.4.1/tests/test_cli_release.py +392 -0
- codex_usage_tracking-0.4.1/tests/test_dashboard_state.py +92 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_plugin_installer.py +2 -1
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_store_dashboard_mcp.py +3 -0
- codex_usage_tracking-0.4.0/docs/one-dot-oh-readiness.md +0 -130
- codex_usage_tracking-0.4.0/tests/test_cli_release.py +0 -178
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/.mcp.json +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/AGENTS.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/CONTRIBUTING.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/LICENSE +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/MANIFEST.in +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/SECURITY.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/assets/icon.svg +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/architecture.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/call-detail-panel.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/insight-overview.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/assets/ux/thread-investigation.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/cli-json-schemas.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/mcp.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/privacy.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/docs/ui-ux-improvement-plan.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/benchmark_synthetic_history.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/scripts/install_local_plugin.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/setup.cfg +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/__main__.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/allowance.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/api_payloads.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/cli.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/context.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/costing.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/dashboard.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/diagnostics.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/formatting.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/json_contracts.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/mcp_server.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/models.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/parser.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/paths.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/__init__.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/assets/icon.svg +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.css +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.js +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_template.html +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/docs/dashboard-guide.html +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/rate_cards/codex-credit-rates.json +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/plugin_installer.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_config.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_estimates.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/pricing_openai.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/projects.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/recommendations.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/redaction.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/reports.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/schema.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/server.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/store.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/support.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracker/threads.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/dependency_links.txt +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/entry_points.txt +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/requires.txt +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/src/codex_usage_tracking.egg-info/top_level.txt +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_allowance.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_json_contracts.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_mcp_launcher.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_parser.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_pricing.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_privacy.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_projects.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_recommendations.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_schema.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_store_migrations.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_support.py +0 -0
- {codex_usage_tracking-0.4.0 → codex_usage_tracking-0.4.1}/tests/test_threads.py +0 -0
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.1 - 2026-06-09
|
|
6
|
+
|
|
7
|
+
- Harden the production PyPI workflow so manual publishing must run from `main` or a tag ref before artifacts are downloaded and uploaded.
|
|
8
|
+
- Strengthen `scripts/check_release.py` so it validates the publish-ref preflight inside both the TestPyPI and PyPI jobs.
|
|
9
|
+
- Check off completed 1.0 readiness items with evidence for migration coverage, localhost dashboard smoke testing, and the protected GitHub `pypi` environment.
|
|
10
|
+
- Pin the marketplace MCP runtime launcher to the exact `codex-usage-tracking==0.4.1` package.
|
|
11
|
+
|
|
5
12
|
## 0.4.0 - 2026-06-09
|
|
6
13
|
|
|
7
14
|
- Add official Python 3.14 support across CI, package classifiers, README/install docs, and installed-package Docker smoke coverage.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: Unofficial local Codex plugin and dashboard for investigating aggregate token usage, costs, caching, and thread patterns.
|
|
5
5
|
Author: Douglas Monsky
|
|
6
6
|
License-Expression: MIT
|
|
@@ -253,10 +253,13 @@ This is optional. The normal shell install above is the fastest trusted path for
|
|
|
253
253
|
## Current Limitations
|
|
254
254
|
|
|
255
255
|
- This is a sidecar dashboard and plugin, not a native Codex chat overlay.
|
|
256
|
+
- Codex upstream log formats can change, and parser compatibility may require tracker updates.
|
|
256
257
|
- Token counts come from Codex's logged counters; the tracker does not re-tokenize prompts.
|
|
257
|
-
- Pricing and
|
|
258
|
-
-
|
|
258
|
+
- Pricing and rate-card sources can change outside this project.
|
|
259
|
+
- Pricing and Codex credit estimates depend on local rate data and confidence labels and are not guaranteed to match exact billing.
|
|
260
|
+
- Live account allowance cannot be read automatically by this local tracker; remaining 5-hour and weekly allowance is only available when you configure copied values.
|
|
259
261
|
- Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
|
|
262
|
+
- Plugin discovery limitations are separate from core Python CLI/dashboard support.
|
|
260
263
|
- Parent-child thread relationships are only as good as the metadata Codex logs; inferred auto-review attachments are labeled as inferred.
|
|
261
264
|
|
|
262
265
|
## Roadmap
|
|
@@ -216,10 +216,13 @@ This is optional. The normal shell install above is the fastest trusted path for
|
|
|
216
216
|
## Current Limitations
|
|
217
217
|
|
|
218
218
|
- This is a sidecar dashboard and plugin, not a native Codex chat overlay.
|
|
219
|
+
- Codex upstream log formats can change, and parser compatibility may require tracker updates.
|
|
219
220
|
- Token counts come from Codex's logged counters; the tracker does not re-tokenize prompts.
|
|
220
|
-
- Pricing and
|
|
221
|
-
-
|
|
221
|
+
- Pricing and rate-card sources can change outside this project.
|
|
222
|
+
- Pricing and Codex credit estimates depend on local rate data and confidence labels and are not guaranteed to match exact billing.
|
|
223
|
+
- Live account allowance cannot be read automatically by this local tracker; remaining 5-hour and weekly allowance is only available when you configure copied values.
|
|
222
224
|
- Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
|
|
225
|
+
- Plugin discovery limitations are separate from core Python CLI/dashboard support.
|
|
223
226
|
- Parent-child thread relationships are only as good as the metadata Codex logs; inferred auto-review attachments are labeled as inferred.
|
|
224
227
|
|
|
225
228
|
## Roadmap
|
|
@@ -4,6 +4,14 @@ This page lists the common command-line workflows. For tested JSON contract ids,
|
|
|
4
4
|
|
|
5
5
|
## Index And Setup
|
|
6
6
|
|
|
7
|
+
Run first-time setup:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
codex-usage-tracker setup
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`setup` installs or refreshes the local plugin wrapper, initializes local config templates when needed, refreshes the aggregate index, runs `doctor`, and prints whether Codex needs a restart for plugin discovery.
|
|
14
|
+
|
|
7
15
|
Refresh the local aggregate index:
|
|
8
16
|
|
|
9
17
|
```bash
|
|
@@ -27,6 +35,36 @@ codex-usage-tracker inspect-log ~/.codex/sessions/YYYY/MM/DD/rollout-...jsonl --
|
|
|
27
35
|
|
|
28
36
|
`inspect-log` reports parser adapter, aggregate token-count events, session ids, models, and parser diagnostics. It does not store raw prompts, assistant messages, tool output, or transcript snippets.
|
|
29
37
|
|
|
38
|
+
Check setup without writing files:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
codex-usage-tracker doctor
|
|
42
|
+
codex-usage-tracker doctor --suggest-repair
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`doctor` validates local paths, database state, parser diagnostics, pricing and allowance config, dashboard output, plugin files, and MCP importability. `--suggest-repair` adds likely next commands without making changes.
|
|
46
|
+
|
|
47
|
+
Reset only the local aggregate database:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
codex-usage-tracker reset-db --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`reset-db` deletes tracker-owned aggregate SQLite rows. It does not delete raw Codex logs and requires `--yes`.
|
|
54
|
+
|
|
55
|
+
## Plugin Lifecycle
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
codex-usage-tracker install-plugin
|
|
59
|
+
codex-usage-tracker install-plugin --python .venv/bin/python
|
|
60
|
+
codex-usage-tracker upgrade-plugin
|
|
61
|
+
codex-usage-tracker uninstall-plugin
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`install-plugin` writes the package-owned local Codex plugin wrapper, companion skills, and MCP config. Use the `--python` form for source checkouts that should use a repo-local virtual environment.
|
|
65
|
+
|
|
66
|
+
`upgrade-plugin` refreshes an existing wrapper in place. `uninstall-plugin` removes only the tracker-owned plugin wrapper and marketplace entry.
|
|
67
|
+
|
|
30
68
|
## Dashboard
|
|
31
69
|
|
|
32
70
|
```bash
|
|
@@ -110,6 +148,14 @@ codex-usage-tracker export --output usage.csv --limit 0
|
|
|
110
148
|
|
|
111
149
|
Use `--privacy-mode redacted` or `--privacy-mode strict` before sharing CSV output.
|
|
112
150
|
|
|
151
|
+
## Support Bundle
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
codex-usage-tracker --privacy-mode strict support-bundle --output ~/.codex-usage-tracker/support-bundle.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Support bundles are diagnostic summaries for issues. They include package, platform, doctor, schema, parser, pricing, allowance, threshold, project-config, and privacy metadata. They exclude raw logs, aggregate rows, prompts, assistant messages, tool output, and context text.
|
|
158
|
+
|
|
113
159
|
## Local Config
|
|
114
160
|
|
|
115
161
|
```bash
|
|
@@ -125,6 +171,16 @@ codex-usage-tracker init-projects
|
|
|
125
171
|
|
|
126
172
|
Local config files live under `~/.codex-usage-tracker/` and are never committed by this project.
|
|
127
173
|
|
|
174
|
+
Stable local config files:
|
|
175
|
+
|
|
176
|
+
- `pricing.json`: schema `_schema: codex-usage-tracker-pricing-v1`, optional `_source`, `models`, `aliases`, and `_estimated_models`. `models` maps model labels to USD-per-million-token rates such as `input`, `cached_input`, and `output`.
|
|
177
|
+
- `rate-card.json`: schema `codex-usage-tracker-codex-rate-card-v1`, optional `_source`, `credit_rates`, and `aliases`. `credit_rates` maps Codex model labels to credit rates for aggregate token counters.
|
|
178
|
+
- `allowance.json`: schema `codex-usage-tracker-allowance-v1`, `windows`, optional `credit_rates`, and `aliases`. `windows` stores copied 5-hour, weekly, or other allowance snapshots such as `remaining_percent`, `reset_at`, `remaining_credits`, and `total_credits`.
|
|
179
|
+
- `thresholds.json`: JSON object keyed by recommendation threshold names such as `low_cache_ratio`, `high_context_percent`, and `high_cost_usd`. Unknown keys are ignored.
|
|
180
|
+
- `projects.json`: JSON object with `aliases`, `ignored_paths`, and `tags` for local project attribution.
|
|
181
|
+
|
|
182
|
+
These config schemas are part of the 1.0 compatibility surface. New optional fields may be added, but existing meanings should not change without documentation and a compatibility plan.
|
|
183
|
+
|
|
128
184
|
## Privacy Mode
|
|
129
185
|
|
|
130
186
|
`--privacy-mode` is a global option, so place it before the subcommand:
|
|
@@ -22,9 +22,9 @@ codex-usage-tracker init-allowance
|
|
|
22
22
|
codex-usage-tracker parse-allowance "5h 79% 6:50 PM Weekly 33% Jun 7"
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
To tune review thresholds locally, run `codex-usage-tracker init-thresholds` and edit `~/.codex-usage-tracker/thresholds.json`. These thresholds control low-cache, high-context, high-uncached-input, large-thread, reasoning-spike, low-output, and high-cost recommendations.
|
|
25
|
+
To tune review thresholds locally, run `codex-usage-tracker init-thresholds` and edit `~/.codex-usage-tracker/thresholds.json`. This file is a JSON object keyed by recommendation threshold names such as `low_cache_ratio`, `high_context_percent`, and `high_cost_usd`; unknown keys are ignored. These thresholds control low-cache, high-context, high-uncached-input, large-thread, reasoning-spike, low-output, and high-cost recommendations.
|
|
26
26
|
|
|
27
|
-
To tune project attribution locally, run `codex-usage-tracker init-projects` and edit `~/.codex-usage-tracker/projects.json`. The dashboard derives project name, relative cwd, branch, tags, and a hashed remote origin from aggregate `cwd` and local Git metadata when available.
|
|
27
|
+
To tune project attribution locally, run `codex-usage-tracker init-projects` and edit `~/.codex-usage-tracker/projects.json`. This file supports `aliases`, `ignored_paths`, and `tags`. The dashboard derives project name, relative cwd, branch, tags, and a hashed remote origin from aggregate `cwd` and local Git metadata when available.
|
|
28
28
|
|
|
29
29
|
Before sharing screenshots or generated artifacts, use `--privacy-mode redacted` or `--privacy-mode strict` before the subcommand:
|
|
30
30
|
|
|
@@ -38,7 +38,7 @@ fix/<issue-number>-short-description
|
|
|
38
38
|
docs/<issue-number>-short-description
|
|
39
39
|
chore/<issue-number>-short-description
|
|
40
40
|
test/<issue-number>-short-description
|
|
41
|
-
release/0.4.
|
|
41
|
+
release/0.4.1
|
|
42
42
|
hotfix/0.3.3
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -91,7 +91,7 @@ blocked
|
|
|
91
91
|
Recommended milestones:
|
|
92
92
|
|
|
93
93
|
```text
|
|
94
|
-
0.4.
|
|
94
|
+
0.4.1
|
|
95
95
|
1.0-readiness
|
|
96
96
|
1.0.0
|
|
97
97
|
```
|
|
@@ -147,8 +147,8 @@ python scripts/smoke_installed_package.py --docker
|
|
|
147
147
|
To verify the public PyPI package instead of the local checkout:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
|
-
python scripts/smoke_installed_package.py --from-pypi --version 0.4.
|
|
151
|
-
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.
|
|
150
|
+
python scripts/smoke_installed_package.py --from-pypi --version 0.4.1
|
|
151
|
+
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
Docker avoids local toolchain side effects during install testing. Keep one local `pipx` smoke for platform-specific PATH and plugin-discovery behavior, but use Docker for repeatable Linux package verification.
|
|
@@ -264,8 +264,8 @@ After the release branch merges, tag from updated `main`, not from an unreviewed
|
|
|
264
264
|
```bash
|
|
265
265
|
git switch main
|
|
266
266
|
git pull --ff-only
|
|
267
|
-
git tag -a v0.4.
|
|
268
|
-
git push origin v0.4.
|
|
267
|
+
git tag -a v0.4.1 -m "codex-usage-tracker 0.4.1"
|
|
268
|
+
git push origin v0.4.1
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
Do not create or push release tags without maintainer approval.
|
|
@@ -274,12 +274,13 @@ Do not create or push release tags without maintainer approval.
|
|
|
274
274
|
|
|
275
275
|
Publishing uses GitHub Actions Trusted Publishing through `.github/workflows/publish.yml`; do not upload from a local machine and do not add PyPI or TestPyPI API tokens.
|
|
276
276
|
|
|
277
|
-
The first public package release, `0.3.0`, was published on June 8, 2026. Patch release `0.3.1` followed the same day to ship the live-dashboard skill launch fix. Patch release `0.3.2` made dashboard launch refresh the default and added runtime enablement for context loading. Minor release `0.4.0` added Python 3.14 support, release recovery docs, stricter privacy/support-bundle regression coverage, and large-history benchmark thresholds:
|
|
277
|
+
The first public package release, `0.3.0`, was published on June 8, 2026. Patch release `0.3.1` followed the same day to ship the live-dashboard skill launch fix. Patch release `0.3.2` made dashboard launch refresh the default and added runtime enablement for context loading. Minor release `0.4.0` added Python 3.14 support, release recovery docs, stricter privacy/support-bundle regression coverage, and large-history benchmark thresholds. Patch release `0.4.1` hardened the PyPI publish workflow and checked off completed 1.0 readiness gates:
|
|
278
278
|
|
|
279
279
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.0`
|
|
280
280
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.1`
|
|
281
281
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.2`
|
|
282
282
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.4.0`
|
|
283
|
+
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.4.1`
|
|
283
284
|
- PyPI: `https://pypi.org/project/codex-usage-tracking/`
|
|
284
285
|
- TestPyPI: `https://test.pypi.org/project/codex-usage-tracking/`
|
|
285
286
|
|
|
@@ -38,6 +38,8 @@ By default the tracker looks for Codex JSONL logs under `~/.codex`, stores its o
|
|
|
38
38
|
|
|
39
39
|
Windows support should work for the core dashboard/CLI when Codex writes readable JSONL logs, but plugin discovery is tied to Codex's local plugin directory behavior. Run `codex-usage-tracker doctor --suggest-repair` after setup if Codex does not show the plugin.
|
|
40
40
|
|
|
41
|
+
Plugin discovery limitations are separate from core Python CLI/dashboard support. If Codex cannot discover the local plugin wrapper, the installed command, SQLite index, generated dashboard, localhost server, and CLI JSON reports can still work.
|
|
42
|
+
|
|
41
43
|
## Upgrade
|
|
42
44
|
|
|
43
45
|
```bash
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# 1.0 Readiness
|
|
2
|
+
|
|
3
|
+
This checklist tracks the work needed to move from the first public PyPI releases toward a stable 1.0 contract. Keep all verification data synthetic or aggregate-only.
|
|
4
|
+
|
|
5
|
+
Each completed checkbox names the primary verification command inline. The evidence reference section at the end maps those commands to the concrete tests, scripts, workflow checks, or public-install smokes that prove the completed items.
|
|
6
|
+
|
|
7
|
+
## Compatibility Promise
|
|
8
|
+
|
|
9
|
+
- CLI command names documented in `docs/cli-reference.md` are stable after 1.0.
|
|
10
|
+
- JSON schema IDs documented in `docs/cli-json-schemas.md` are stable after 1.0.
|
|
11
|
+
- New JSON fields may be added in minor releases, but existing required fields should not be removed or change type without a new schema version.
|
|
12
|
+
- MCP tool names and response schemas are stable after 1.0.
|
|
13
|
+
- CSV export columns are stable after 1.0 unless a new export schema or version flag is introduced.
|
|
14
|
+
- Config file schemas for pricing, allowance, thresholds, projects, and rate cards are stable after 1.0.
|
|
15
|
+
- Privacy-mode semantics are stable after 1.0.
|
|
16
|
+
- SQLite migrations must support upgrade from the last pre-1.0 release to 1.0.
|
|
17
|
+
|
|
18
|
+
Not guaranteed:
|
|
19
|
+
|
|
20
|
+
- Codex upstream log format stability.
|
|
21
|
+
- OpenAI pricing or rate-card source stability.
|
|
22
|
+
- Automatic access to live account allowance.
|
|
23
|
+
- Exact billing equivalence.
|
|
24
|
+
|
|
25
|
+
## 1. Public Install And Package Metadata
|
|
26
|
+
|
|
27
|
+
- [x] Verify the current public PyPI version is visible as `0.4.1`: `python -c "import json, urllib.request; print(json.load(urllib.request.urlopen('https://pypi.org/pypi/codex-usage-tracking/json'))['info']['version'])"`.
|
|
28
|
+
- [x] Verify public venv install for `0.4.1`: `python -m venv /tmp/codex-usage-pypi-smoke && . /tmp/codex-usage-pypi-smoke/bin/activate && python -m pip install codex-usage-tracking==0.4.1 && codex-usage-tracker --version`.
|
|
29
|
+
- [x] Verify public pipx install path for `0.4.1`: `PIPX_HOME=/tmp/codex-usage-pipx-home PIPX_BIN_DIR=/tmp/codex-usage-pipx-bin pipx install codex-usage-tracking==0.4.1 && /tmp/codex-usage-pipx-bin/codex-usage-tracker --version`.
|
|
30
|
+
- [x] Verify installed package resources from a built wheel: `python scripts/smoke_installed_package.py`.
|
|
31
|
+
- [x] Verify installed package resources in Linux Docker: `python scripts/smoke_installed_package.py --docker`.
|
|
32
|
+
- [x] Verify public PyPI package in Docker: `python scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1`.
|
|
33
|
+
- [x] Verify PyPI metadata names remain unchanged: `python scripts/check_release.py`.
|
|
34
|
+
- [x] Add Python 3.14 as an official support target after CI, package classifiers, docs, and installed-package smoke coverage were added. Docker smoke coverage uses `python:3.14-slim` by default. Track this in issue #12.
|
|
35
|
+
|
|
36
|
+
## 2. Upgrade And Migration
|
|
37
|
+
|
|
38
|
+
- [x] Add synthetic legacy SQLite fixture test proving `init_db` upgrades without data loss: `python -m pytest tests/test_store_migrations.py`.
|
|
39
|
+
- [x] Reassess whether a synthetic v0.3-style SQLite fixture is required; the current legacy migration fixture covers active schema drift, so no separate v0.3 fixture is currently needed: `python -m pytest tests/test_store_migrations.py`.
|
|
40
|
+
- [x] Verify `schema_state` reports expected version and checksum after migration: `python -m pytest tests/test_store_migrations.py`.
|
|
41
|
+
- [x] Verify `rebuild-index` clears only tracker-owned aggregate tables: `python -m pytest tests/test_store_dashboard_mcp.py`.
|
|
42
|
+
- [x] Verify `reset-db` does not touch raw Codex logs: `python -m pytest tests/test_cli_lifecycle.py`.
|
|
43
|
+
- [x] Verify refresh metadata and parser diagnostics survive migration: `python -m pytest tests/test_store_migrations.py tests/test_parser.py`.
|
|
44
|
+
- [x] Verify CSV export columns after migration: `python -m pytest tests/test_store_migrations.py`.
|
|
45
|
+
|
|
46
|
+
## 3. CLI Compatibility
|
|
47
|
+
|
|
48
|
+
- [x] Confirm every documented command in `docs/cli-reference.md` exists: `python -m pytest tests/test_cli_release.py`.
|
|
49
|
+
- [x] Confirm no documented command is removed without a deprecation plan: manual diff review plus `python -m pytest tests/test_cli_release.py`.
|
|
50
|
+
- [x] Verify command help works from an installed wheel: `python scripts/smoke_installed_package.py`.
|
|
51
|
+
- [x] Verify lifecycle commands still return actionable errors without real logs: `python -m pytest tests/test_cli_lifecycle.py`.
|
|
52
|
+
|
|
53
|
+
## 4. MCP Compatibility
|
|
54
|
+
|
|
55
|
+
- [x] Verify MCP tool names remain documented in `docs/mcp.md`: `python -m pytest tests/test_cli_release.py`.
|
|
56
|
+
- [x] Verify MCP JSON responses use tracked schema IDs where applicable: `python -m pytest tests/test_store_dashboard_mcp.py`.
|
|
57
|
+
- [x] Verify companion skill packaged copy matches source skill: `python scripts/check_release.py`.
|
|
58
|
+
- [x] Verify plugin installer writes MCP config from an installed wheel: `python scripts/smoke_installed_package.py`.
|
|
59
|
+
|
|
60
|
+
## 5. JSON Contract Stability
|
|
61
|
+
|
|
62
|
+
- [x] Verify every documented `--json` command has a tracked schema: `python -m pytest tests/test_json_contracts.py`.
|
|
63
|
+
- [x] Verify every schema in `docs/cli-json-schemas.md` exists in `src/codex_usage_tracker/json_contracts.py`: `python -m pytest tests/test_json_contracts.py`.
|
|
64
|
+
- [x] Verify every schema in `json_contracts.py` is documented: `python -m pytest tests/test_json_contracts.py`.
|
|
65
|
+
- [x] Verify known payload examples pass `validate_json_payload_contract`: `python -m pytest tests/test_json_contracts.py`.
|
|
66
|
+
- [x] Verify invalid or missing required fields fail contract validation: `python -m pytest tests/test_json_contracts.py`.
|
|
67
|
+
- [x] Cover query, recommendations, summary, session, doctor, pricing-coverage, dashboard, export, support-bundle, and plugin lifecycle JSON payload contracts: `python -m pytest tests/test_json_contracts.py`.
|
|
68
|
+
|
|
69
|
+
## 6. CSV Export Stability
|
|
70
|
+
|
|
71
|
+
- [x] Verify expected CSV columns for aggregate exports: `python -m pytest tests/test_cli_lifecycle.py`.
|
|
72
|
+
- [x] Verify redacted and strict privacy CSV exports omit private metadata: `python -m pytest tests/test_privacy.py`.
|
|
73
|
+
- [x] Verify migration fixtures still export the expected CSV shape: `python -m pytest tests/test_store_migrations.py`.
|
|
74
|
+
|
|
75
|
+
## 7. Config File Stability
|
|
76
|
+
|
|
77
|
+
- [x] Verify pricing config initialization and parsing: `python -m pytest tests/test_pricing.py`.
|
|
78
|
+
- [x] Verify allowance and rate-card config initialization and parsing: `python -m pytest tests/test_allowance.py`.
|
|
79
|
+
- [x] Verify threshold config initialization and parsing: `python -m pytest tests/test_recommendations.py`.
|
|
80
|
+
- [x] Verify project alias/tag config initialization and parsing: `python -m pytest tests/test_projects.py`.
|
|
81
|
+
- [x] Document config schema changes before release: manual review of `docs/pricing-and-credits.md`, `docs/dashboard-guide.md`, and `docs/cli-reference.md`; enforced by `python -m pytest tests/test_cli_release.py`.
|
|
82
|
+
|
|
83
|
+
## 8. Dashboard Behavior
|
|
84
|
+
|
|
85
|
+
- [x] Verify dashboard aggregate payload remains raw-context-free: `python -m pytest tests/test_store_dashboard_mcp.py`.
|
|
86
|
+
- [x] Verify dashboard URL state round trips: `python -m pytest tests/test_dashboard_state.py`.
|
|
87
|
+
- [x] Verify dashboard formatting helpers: `node --check src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js`.
|
|
88
|
+
- [x] Verify dashboard data helpers: `node --check src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js`.
|
|
89
|
+
- [x] Verify active-history and all-history state labels: `python -m pytest tests/test_cli_release.py tests/test_store_dashboard_mcp.py`.
|
|
90
|
+
- [x] Run a manual localhost dashboard smoke before release with temporary aggregate-only paths: `codex-usage-tracker serve-dashboard --open` plus `curl -fsS http://127.0.0.1:8897/dashboard.html`.
|
|
91
|
+
|
|
92
|
+
## 9. Privacy And Sharing Safety
|
|
93
|
+
|
|
94
|
+
- [x] Verify dashboard payloads in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
|
|
95
|
+
- [x] Verify query JSON in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
|
|
96
|
+
- [x] Verify session JSON in normal, redacted, and strict modes: `python -m pytest tests/test_privacy.py`.
|
|
97
|
+
- [x] Verify CSV export in redacted and strict modes: `python -m pytest tests/test_privacy.py`.
|
|
98
|
+
- [x] Verify strict mode does not leak raw cwd, source paths, branch, remote labels, project tags, or synthetic private project names: `python -m pytest tests/test_privacy.py`.
|
|
99
|
+
- [x] Verify raw context fields never appear in SQLite, CSV, dashboard payloads, support bundles, generated static HTML, docs, or screenshots: `python -m pytest tests/test_privacy.py scripts/check_release.py`.
|
|
100
|
+
|
|
101
|
+
## 10. Support-Bundle Safety
|
|
102
|
+
|
|
103
|
+
- [x] Verify support bundles include package version, Python version, OS/platform, doctor status, schema state, parser diagnostics, pricing status, allowance status, threshold status, project config status, and privacy metadata: `python -m pytest tests/test_support.py`.
|
|
104
|
+
- [x] Verify support bundles exclude raw logs, prompt text, assistant text, tool output, context text, and raw source paths in strict mode: `python -m pytest tests/test_support.py`.
|
|
105
|
+
- [x] Update issue templates to request only strict-mode support bundles: `python scripts/check_release.py`.
|
|
106
|
+
|
|
107
|
+
## 11. Large-History Performance
|
|
108
|
+
|
|
109
|
+
- [x] Run synthetic 10k benchmark: `python scripts/benchmark_synthetic_history.py --rows 10000 --json --enforce-thresholds`.
|
|
110
|
+
- [x] Run synthetic 100k benchmark: `python scripts/benchmark_synthetic_history.py --rows 100000 --json --enforce-thresholds`.
|
|
111
|
+
- [x] Run synthetic 500k benchmark as a release gate when practical: `python scripts/benchmark_synthetic_history.py --rows 500000 --json --enforce-thresholds`.
|
|
112
|
+
- [x] Define thresholds for active-only dashboard query, all-history dashboard query, since/until, model/effort, min_tokens, recommendations, pricing coverage, and project summary.
|
|
113
|
+
- [x] Add a smaller CI-safe benchmark if it can stay fast and deterministic.
|
|
114
|
+
|
|
115
|
+
## 12. Release Process
|
|
116
|
+
|
|
117
|
+
- [x] Verify publish workflow publishes `codex-usage-tracking`, not `codex-usage-tracker`: `python scripts/check_release.py`.
|
|
118
|
+
- [x] Verify publish workflow uses Trusted Publishing, not API tokens: `python scripts/check_release.py`.
|
|
119
|
+
- [x] Verify TestPyPI and PyPI jobs exist and publish only on workflow dispatch or release events: `python scripts/check_release.py`.
|
|
120
|
+
- [x] Verify manual PyPI workflow dispatch is restricted to `main` or tag refs: `python scripts/check_release.py`.
|
|
121
|
+
- [x] Verify PyPI job is gated by environment `pypi`: `gh api repos/douglasmonsky/codex-usage-tracker/environments/pypi`.
|
|
122
|
+
- [x] Verify dist filenames match `codex_usage_tracking`: `python -m build && python scripts/check_release.py --dist`.
|
|
123
|
+
- [ ] Verify TestPyPI process: run `Publish Python package` with `target=testpypi` only when intentionally testing release publication.
|
|
124
|
+
- [ ] Verify PyPI process: publish a GitHub Release or run workflow dispatch with `target=pypi` only when intentionally publishing a reviewed release.
|
|
125
|
+
- [x] Document release recovery by cutting a new patch version when an uploaded artifact is wrong: see `docs/development.md`.
|
|
126
|
+
|
|
127
|
+
## 13. Known Limitations
|
|
128
|
+
|
|
129
|
+
- [x] Document that Codex upstream log formats can change and parser compatibility may require updates.
|
|
130
|
+
- [x] Document that pricing and rate-card sources can change outside this project.
|
|
131
|
+
- [x] Document that live account allowance cannot be read automatically by this local tracker.
|
|
132
|
+
- [x] Document that cost and credit estimates are not guaranteed to match exact billing.
|
|
133
|
+
- [x] Document platform/plugin discovery limitations separately from the core Python CLI/dashboard support.
|
|
134
|
+
|
|
135
|
+
## Evidence References
|
|
136
|
+
|
|
137
|
+
These references are the concrete proof behind completed checklist items. Public package smoke commands are version-specific to `0.4.1`; all repo tests use synthetic or aggregate-only data.
|
|
138
|
+
|
|
139
|
+
### Public Install And Package Metadata
|
|
140
|
+
|
|
141
|
+
- Public PyPI version, public venv install, and public pipx install are proven by the exact public-install commands in section 1.
|
|
142
|
+
- Built-wheel and installed-resource coverage is proven by `scripts/smoke_installed_package.py` and `tests/test_cli_release.py::test_installed_package_smoke_checks_help_for_stable_commands`.
|
|
143
|
+
- Linux package-resource coverage is proven by `scripts/smoke_installed_package.py --docker`.
|
|
144
|
+
- Public PyPI Docker coverage is proven by `scripts/smoke_installed_package.py --docker --from-pypi --version 0.4.1`.
|
|
145
|
+
- PyPI metadata, package/distribution names, package resources, source/wheel member names, Python 3.10-3.14 support metadata, CI workflow requirements, publish workflow safety text, and tracked secret patterns are proven by `scripts/check_release.py`, `scripts/check_release.py --dist`, and `tests/test_cli_release.py::test_release_check_script_passes`.
|
|
146
|
+
|
|
147
|
+
### Upgrade And Migration
|
|
148
|
+
|
|
149
|
+
- Legacy SQLite migration, schema state, migration idempotence, malformed legacy schema handling, and migration CSV shape are proven by `tests/test_store_migrations.py`.
|
|
150
|
+
- The v0.3 fixture decision is covered by `tests/test_store_migrations.py`; no additional v0.3-specific fixture is currently required because the active pre-1.0 migration path is already represented by the legacy fixture.
|
|
151
|
+
- `rebuild-index` clearing only tracker-owned aggregate rows is proven by `tests/test_store_dashboard_mcp.py::test_rebuild_index_clears_aggregate_rows_before_rescan`.
|
|
152
|
+
- `reset-db` preserving raw Codex logs is proven by `tests/test_cli_lifecycle.py::test_setup_support_bundle_and_reset_db_cli`.
|
|
153
|
+
- Refresh metadata and parser diagnostics are proven by `tests/test_store_migrations.py`, `tests/test_parser.py`, and `tests/test_store_dashboard_mcp.py::test_refresh_reports_skipped_corrupt_token_events`.
|
|
154
|
+
|
|
155
|
+
### CLI Compatibility
|
|
156
|
+
|
|
157
|
+
- Documented CLI command existence and stable command coverage are proven by `tests/test_cli_release.py::test_cli_reference_documents_only_existing_stable_commands` and `tests/test_cli_release.py::test_stable_cli_commands_are_not_removed_without_a_deprecation_plan`.
|
|
158
|
+
- Installed-wheel subcommand help coverage is proven by `scripts/smoke_installed_package.py` and guarded by `tests/test_cli_release.py::test_installed_package_smoke_checks_help_for_stable_commands`.
|
|
159
|
+
- Lifecycle actionable errors without real logs are proven by `tests/test_cli_lifecycle.py::test_lifecycle_commands_return_actionable_errors_without_real_logs`.
|
|
160
|
+
|
|
161
|
+
### MCP Compatibility
|
|
162
|
+
|
|
163
|
+
- MCP tool documentation parity is proven by `tests/test_cli_release.py::test_mcp_tool_names_remain_documented`.
|
|
164
|
+
- MCP JSON response schema IDs and wrapper payload contracts are proven by `tests/test_store_dashboard_mcp.py::test_mcp_wrappers_smoke`.
|
|
165
|
+
- Companion skill source/package parity is proven by `scripts/check_release.py`.
|
|
166
|
+
- Installed-wheel plugin MCP config is proven by `scripts/smoke_installed_package.py`.
|
|
167
|
+
|
|
168
|
+
### JSON Contract Stability
|
|
169
|
+
|
|
170
|
+
- Documented schema table parity, runtime schema ID tracking, example validation, invalid-payload rejection, and minimal payload validation are proven by `tests/test_json_contracts.py`.
|
|
171
|
+
- README and CLI schema doc references are additionally guarded by `tests/test_cli_release.py::test_cli_json_schema_doc_lists_tracked_contracts`.
|
|
172
|
+
|
|
173
|
+
### CSV Export Stability
|
|
174
|
+
|
|
175
|
+
- Aggregate CSV columns are proven by `tests/test_cli_lifecycle.py::test_report_json_and_query_cli`.
|
|
176
|
+
- Redacted and strict privacy CSV behavior is proven by `tests/test_privacy.py::test_privacy_modes_cover_dashboard_query_session_and_csv` and `tests/test_privacy.py::test_aggregate_outputs_exclude_raw_transcript_content`.
|
|
177
|
+
- Migration CSV shape is proven by `tests/test_store_migrations.py::test_csv_export_keeps_current_columns_after_legacy_migration`.
|
|
178
|
+
|
|
179
|
+
### Config File Stability
|
|
180
|
+
|
|
181
|
+
- Pricing config initialization and parsing are proven by `tests/test_pricing.py` and `tests/test_cli_lifecycle.py::test_rate_card_allowance_and_pricing_snapshot_cli`.
|
|
182
|
+
- Allowance and Codex rate-card config initialization/parsing are proven by `tests/test_allowance.py` and `tests/test_cli_lifecycle.py::test_rate_card_allowance_and_pricing_snapshot_cli`.
|
|
183
|
+
- Threshold config initialization/parsing is proven by `tests/test_recommendations.py::test_threshold_template_and_overrides`.
|
|
184
|
+
- Project alias, ignored-path, tag, and privacy behavior is proven by `tests/test_projects.py`.
|
|
185
|
+
- Config schema documentation coverage is proven by `tests/test_cli_release.py::test_local_config_schema_docs_reference_stable_fields`.
|
|
186
|
+
|
|
187
|
+
### Dashboard Behavior
|
|
188
|
+
|
|
189
|
+
- Aggregate-only dashboard payloads and CSV are proven by `tests/test_store_dashboard_mcp.py::test_dashboard_and_csv_are_aggregate_only` and `tests/test_privacy.py::test_aggregate_outputs_exclude_raw_transcript_content`.
|
|
190
|
+
- URL-state round trips are proven by `tests/test_dashboard_state.py::test_dashboard_url_state_round_trips`.
|
|
191
|
+
- Dashboard helper syntax is proven by the `node --check` commands in section 8 and the CI dashboard JavaScript syntax job.
|
|
192
|
+
- Active/all-history payload behavior is proven by `tests/test_store_dashboard_mcp.py::test_dashboard_history_scope_excludes_archived_rows_by_default` and `tests/test_store_dashboard_mcp.py::test_dashboard_server_usage_api_switches_history_scope`.
|
|
193
|
+
- Active/all-history user-facing labels are proven by `tests/test_cli_release.py::test_dashboard_history_scope_labels_remain_user_facing`.
|
|
194
|
+
- No-context startup and runtime context enablement are proven by `tests/test_store_dashboard_mcp.py::test_dashboard_server_can_enable_context_api_at_runtime` and `tests/test_privacy.py::test_context_server_requires_loopback_origin_token_and_enablement`.
|
|
195
|
+
- Manual localhost smoke is proven by running `codex-usage-tracker serve-dashboard --open` against temporary database, config, output, and Codex-home paths on `127.0.0.1:8897`, then probing `/dashboard.html` with `curl -fsS`.
|
|
196
|
+
|
|
197
|
+
### Privacy And Sharing Safety
|
|
198
|
+
|
|
199
|
+
- Dashboard, query, session, CSV, support-bundle, and generated-static-HTML privacy behavior is proven by `tests/test_privacy.py`.
|
|
200
|
+
- Strict project metadata redaction is proven by `tests/test_privacy.py::test_privacy_modes_cover_dashboard_query_session_and_csv` and `tests/test_projects.py::test_project_privacy_modes_redact_sensitive_metadata`.
|
|
201
|
+
- Raw context exclusion and explicit context loading are proven by `tests/test_privacy.py::test_context_loading_is_explicit_redacted_and_not_static_html`, `tests/test_privacy.py::test_context_server_requires_loopback_origin_token_and_enablement`, and `tests/test_store_dashboard_mcp.py::test_context_loads_raw_log_only_on_demand`.
|
|
202
|
+
- Tracked-file secret scanning is proven by `scripts/check_release.py`.
|
|
203
|
+
|
|
204
|
+
### Support-Bundle Safety
|
|
205
|
+
|
|
206
|
+
- Support-bundle payload shape and secret safety are proven by `tests/test_support.py::test_support_bundle_default_mode_contract_and_secret_safety`.
|
|
207
|
+
- Strict support-bundle path and doctor-text redaction is proven by `tests/test_support.py::test_support_bundle_strict_mode_redacts_local_paths_and_doctor_text`.
|
|
208
|
+
- Safe issue-template requests are proven by `scripts/check_release.py`.
|
|
209
|
+
|
|
210
|
+
### Large-History Performance
|
|
211
|
+
|
|
212
|
+
- Benchmark command behavior and threshold contract are smoke-tested by `tests/test_cli_release.py::test_synthetic_history_benchmark_script_smoke`.
|
|
213
|
+
- Release-size 10k, 100k, and 500k benchmark claims are proven by running `python scripts/benchmark_synthetic_history.py --rows 10000 100000 500000 --json --enforce-thresholds` before release work when practical.
|
|
214
|
+
- CI-safe benchmark coverage is proven by the CI `Release readiness` job through `tests/test_cli_release.py::test_synthetic_history_benchmark_script_smoke`.
|
|
215
|
+
|
|
216
|
+
### Release Process
|
|
217
|
+
|
|
218
|
+
- Normal CI package build plus `twine check` and dist verification are proven by `.github/workflows/ci.yml` and enforced by `scripts/check_release.py::_check_ci_workflow`.
|
|
219
|
+
- Publish workflow package name, Trusted Publishing, TestPyPI/PyPI job presence, event guards, no push/PR publishing, no token/password publishing, and manual PyPI main/tag preflight are proven by `scripts/check_release.py::_check_publish_workflow`.
|
|
220
|
+
- The GitHub `pypi` environment gate is proven by `gh api repos/douglasmonsky/codex-usage-tracker/environments/pypi`, which reports a `required_reviewers` protection rule and `can_admins_bypass=false`.
|
|
221
|
+
- Dist filename and wheel/sdist member checks are proven by `python -m build`, `python -m twine check dist/*`, and `python scripts/check_release.py --dist`.
|
|
222
|
+
- Release recovery documentation is proven by `scripts/check_release.py` required-file and docs checks.
|
|
223
|
+
|
|
224
|
+
### Known Limitations
|
|
225
|
+
|
|
226
|
+
- Parser-format drift, pricing/rate-card drift, live allowance, non-billing-equivalence, and plugin-discovery boundary documentation are proven by `tests/test_cli_release.py::test_known_limitations_are_documented`.
|
|
@@ -83,8 +83,11 @@ Configure the usage component:
|
|
|
83
83
|
|
|
84
84
|
## Accuracy Notes
|
|
85
85
|
|
|
86
|
+
- Codex upstream log formats can change, and parser compatibility may require tracker updates before new event shapes are fully understood.
|
|
87
|
+
- Pricing and rate-card sources can change outside this project. Refresh or pin local files when reports need a known source snapshot.
|
|
86
88
|
- Local Codex logs may not include usage from other ChatGPT agentic surfaces that share the same allowance.
|
|
87
|
-
-
|
|
89
|
+
- Live account allowance cannot be read automatically by this local tracker, and the dashboard does not infer live remaining allowance from the logged-in account plan.
|
|
88
90
|
- Pricing can change after a report is generated. Use `pin-pricing` when you need reproducible historical cost estimates.
|
|
89
91
|
- Rows with direct model/rate-card matches are more trustworthy than inferred aliases or local overrides.
|
|
90
92
|
- Cost and credit calculations use aggregate counters; the tracker does not re-tokenize prompts or reconstruct usage from raw text.
|
|
93
|
+
- Cost and credit estimates are not guaranteed to match exact billing.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codex-usage-tracking"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.1"
|
|
8
8
|
description = "Unofficial local Codex plugin and dashboard for investigating aggregate token usage, costs, caching, and thread patterns."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -110,6 +110,7 @@ def main() -> int:
|
|
|
110
110
|
failures.extend(_check_required_files())
|
|
111
111
|
failures.extend(_check_versions())
|
|
112
112
|
failures.extend(_check_docs())
|
|
113
|
+
failures.extend(_check_issue_templates())
|
|
113
114
|
failures.extend(_check_packaging_metadata())
|
|
114
115
|
failures.extend(_check_tracked_files_for_secrets())
|
|
115
116
|
if args.dist:
|
|
@@ -173,6 +174,37 @@ def _check_docs() -> list[str]:
|
|
|
173
174
|
return failures
|
|
174
175
|
|
|
175
176
|
|
|
177
|
+
def _check_issue_templates() -> list[str]:
|
|
178
|
+
failures: list[str] = []
|
|
179
|
+
templates = {
|
|
180
|
+
"bug_report.yml": [
|
|
181
|
+
"Do not paste real Codex logs",
|
|
182
|
+
"strict support bundle",
|
|
183
|
+
"--privacy-mode strict support-bundle",
|
|
184
|
+
],
|
|
185
|
+
"parser_log_compatibility.yml": [
|
|
186
|
+
"Do not attach or paste raw Codex JSONL logs",
|
|
187
|
+
"Synthetic log shape",
|
|
188
|
+
],
|
|
189
|
+
"pricing_or_allowance.yml": [
|
|
190
|
+
"Do not paste account screenshots with private details",
|
|
191
|
+
"--privacy-mode strict pricing-coverage --json",
|
|
192
|
+
],
|
|
193
|
+
}
|
|
194
|
+
for filename, required_texts in templates.items():
|
|
195
|
+
path = REPO_ROOT / ".github" / "ISSUE_TEMPLATE" / filename
|
|
196
|
+
if not path.exists():
|
|
197
|
+
failures.append(f"missing issue template: {path.relative_to(REPO_ROOT)}")
|
|
198
|
+
continue
|
|
199
|
+
text = path.read_text(encoding="utf-8")
|
|
200
|
+
for required in required_texts:
|
|
201
|
+
if required not in text:
|
|
202
|
+
failures.append(
|
|
203
|
+
f"{path.relative_to(REPO_ROOT)} is missing safe-reporting text: {required}"
|
|
204
|
+
)
|
|
205
|
+
return failures
|
|
206
|
+
|
|
207
|
+
|
|
176
208
|
def _check_packaging_metadata() -> list[str]:
|
|
177
209
|
sys.path.insert(0, str(REPO_ROOT / "src"))
|
|
178
210
|
from codex_usage_tracker.plugin_installer import plugin_manifest
|
|
@@ -231,6 +263,7 @@ def _check_packaging_metadata() -> list[str]:
|
|
|
231
263
|
if "PACKAGE_SPEC_MARKER" not in launcher:
|
|
232
264
|
failures.append("MCP runtime launcher should invalidate cached runtimes when package spec changes")
|
|
233
265
|
failures.extend(_check_python_support_metadata(project))
|
|
266
|
+
failures.extend(_check_ci_workflow())
|
|
234
267
|
failures.extend(_check_publish_workflow())
|
|
235
268
|
return failures
|
|
236
269
|
|
|
@@ -279,6 +312,14 @@ def _check_publish_workflow() -> list[str]:
|
|
|
279
312
|
"id-token: write",
|
|
280
313
|
"repository-url: https://test.pypi.org/legacy/",
|
|
281
314
|
"python -m twine check dist/*",
|
|
315
|
+
"if: github.event_name == 'workflow_dispatch' && inputs.target == 'testpypi'",
|
|
316
|
+
"if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.target == 'pypi')",
|
|
317
|
+
"echo \"ref=$GITHUB_REF\"",
|
|
318
|
+
"echo \"sha=$GITHUB_SHA\"",
|
|
319
|
+
"refs/heads/main|refs/tags/*",
|
|
320
|
+
"Manual PyPI publishing must run from main or a tag ref.",
|
|
321
|
+
"name: testpypi",
|
|
322
|
+
"name: pypi",
|
|
282
323
|
"https://test.pypi.org/project/codex-usage-tracking/",
|
|
283
324
|
"https://pypi.org/project/codex-usage-tracking/",
|
|
284
325
|
]:
|
|
@@ -290,6 +331,65 @@ def _check_publish_workflow() -> list[str]:
|
|
|
290
331
|
failures.append("publish workflow must not publish on pull requests")
|
|
291
332
|
if "secrets." in workflow or "api-token" in workflow or "password:" in workflow:
|
|
292
333
|
failures.append("publish workflow must not use token secrets or password-based publishing")
|
|
334
|
+
for job_name in ["publish-testpypi", "publish-pypi"]:
|
|
335
|
+
job_block = _workflow_job_block(workflow, job_name)
|
|
336
|
+
if job_block is None:
|
|
337
|
+
failures.append(f"publish workflow is missing job: {job_name}")
|
|
338
|
+
continue
|
|
339
|
+
for required in [
|
|
340
|
+
"Verify PyPI publish ref",
|
|
341
|
+
"echo \"event=$GITHUB_EVENT_NAME\"",
|
|
342
|
+
"echo \"ref=$GITHUB_REF\"",
|
|
343
|
+
"echo \"sha=$GITHUB_SHA\"",
|
|
344
|
+
"refs/heads/main|refs/tags/*",
|
|
345
|
+
"Manual PyPI publishing must run from main or a tag ref.",
|
|
346
|
+
]:
|
|
347
|
+
if required not in job_block:
|
|
348
|
+
failures.append(f"publish workflow {job_name} job is missing preflight: {required}")
|
|
349
|
+
return failures
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def _workflow_job_block(workflow: str, job_name: str) -> str | None:
|
|
353
|
+
match = re.search(
|
|
354
|
+
rf"(?ms)^ {re.escape(job_name)}:\n(?P<body>.*?)(?=^ [A-Za-z0-9_-]+:\n|\Z)",
|
|
355
|
+
workflow,
|
|
356
|
+
)
|
|
357
|
+
if not match:
|
|
358
|
+
return None
|
|
359
|
+
return match.group("body")
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _check_ci_workflow() -> list[str]:
|
|
363
|
+
workflow_path = REPO_ROOT / ".github" / "workflows" / "ci.yml"
|
|
364
|
+
if not workflow_path.exists():
|
|
365
|
+
return ["missing CI workflow: .github/workflows/ci.yml"]
|
|
366
|
+
workflow = workflow_path.read_text(encoding="utf-8")
|
|
367
|
+
failures: list[str] = []
|
|
368
|
+
for required in [
|
|
369
|
+
"name: Build package",
|
|
370
|
+
"python -m build",
|
|
371
|
+
"python -m twine check dist/*",
|
|
372
|
+
"python scripts/check_release.py --dist",
|
|
373
|
+
]:
|
|
374
|
+
if required not in workflow:
|
|
375
|
+
failures.append(f"CI package job is missing required build check: {required}")
|
|
376
|
+
return failures
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _check_ci_workflow() -> list[str]:
|
|
380
|
+
workflow_path = REPO_ROOT / ".github" / "workflows" / "ci.yml"
|
|
381
|
+
if not workflow_path.exists():
|
|
382
|
+
return ["missing CI workflow: .github/workflows/ci.yml"]
|
|
383
|
+
workflow = workflow_path.read_text(encoding="utf-8")
|
|
384
|
+
failures: list[str] = []
|
|
385
|
+
for required in [
|
|
386
|
+
"name: Build package",
|
|
387
|
+
"python -m build",
|
|
388
|
+
"python -m twine check dist/*",
|
|
389
|
+
"python scripts/check_release.py --dist",
|
|
390
|
+
]:
|
|
391
|
+
if required not in workflow:
|
|
392
|
+
failures.append(f"CI package job is missing required build check: {required}")
|
|
293
393
|
return failures
|
|
294
394
|
|
|
295
395
|
|