codex-usage-tracking 0.3.1__tar.gz → 0.3.2__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.3.1 → codex_usage_tracking-0.3.2}/.codex-plugin/plugin.json +1 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/CHANGELOG.md +5 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/PKG-INFO +5 -3
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/README.md +4 -2
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/SECURITY.md +1 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/cli-reference.md +5 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/dashboard-guide.md +7 -5
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/development.md +2 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/install.md +6 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/privacy.md +3 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/pyproject.toml +1 -1
- {codex_usage_tracking-0.3.1/src/codex_usage_tracker/plugin_data → codex_usage_tracking-0.3.2}/skills/codex-usage-api/SKILL.md +1 -1
- {codex_usage_tracking-0.3.1/src/codex_usage_tracker/plugin_data → codex_usage_tracking-0.3.2}/skills/codex-usage-tracker/SKILL.md +2 -2
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/skills/codex-usage-tracker/scripts/run_mcp.py +2 -2
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/__init__.py +1 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/cli.py +13 -5
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.css +5 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.js +41 -4
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/docs/dashboard-guide.html +4 -3
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2/src/codex_usage_tracker/plugin_data}/skills/codex-usage-api/SKILL.md +1 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2/src/codex_usage_tracker/plugin_data}/skills/codex-usage-tracker/SKILL.md +2 -2
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/server.py +51 -7
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/PKG-INFO +5 -3
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_cli_release.py +17 -3
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_plugin_installer.py +1 -1
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_store_dashboard_mcp.py +50 -9
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/.mcp.json +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/AGENTS.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/CONTRIBUTING.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/LICENSE +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/MANIFEST.in +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/assets/icon.svg +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/architecture.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/call-detail-panel.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/insight-overview.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/thread-investigation.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/cli-json-schemas.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/mcp.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/pricing-and-credits.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/ui-ux-improvement-plan.md +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/scripts/benchmark_synthetic_history.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/scripts/check_release.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/scripts/install_local_plugin.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/setup.cfg +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/__main__.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/allowance.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/api_payloads.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/context.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/costing.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/dashboard.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/diagnostics.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/formatting.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/json_contracts.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/mcp_server.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/models.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/parser.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/paths.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/__init__.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/assets/icon.svg +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_template.html +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_data/rate_cards/codex-credit-rates.json +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/plugin_installer.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing_config.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing_estimates.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing_openai.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/projects.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/recommendations.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/reports.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/schema.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/store.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/support.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/threads.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/SOURCES.txt +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/dependency_links.txt +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/entry_points.txt +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/requires.txt +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/top_level.txt +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_allowance.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_cli_lifecycle.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_json_contracts.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_mcp_launcher.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_parser.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_pricing.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_projects.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_recommendations.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_schema.py +0 -0
- {codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/tests/test_threads.py +0 -0
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.3.2 - 2026-06-08
|
|
6
|
+
|
|
7
|
+
- Make `open-dashboard` and `serve-dashboard` refresh active-session logs by default, with `--no-refresh` as the explicit cached-index mode.
|
|
8
|
+
- Add a token-protected dashboard action for enabling context loading without restarting a localhost server that started with context loading off.
|
|
9
|
+
|
|
5
10
|
## 0.3.1 - 2026-06-08
|
|
6
11
|
|
|
7
12
|
- Fix packaged Codex Usage Tracker skills so dashboard-open requests start the live localhost dashboard instead of a static snapshot.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
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
|
|
@@ -68,6 +68,8 @@ codex-usage-tracker serve-dashboard --open
|
|
|
68
68
|
|
|
69
69
|
Use your normal Python launcher for your platform: `python3` is common on macOS/Linux, and `py` may be preferable on Windows. On macOS with Homebrew, `brew install pipx` is also fine.
|
|
70
70
|
|
|
71
|
+
`serve-dashboard` refreshes active-session usage before opening by default. Use `--no-refresh` only when you intentionally want to inspect the cached local index.
|
|
72
|
+
|
|
71
73
|
Package naming: the PyPI distribution is `codex-usage-tracking`; the installed command is `codex-usage-tracker`; the GitHub repository remains `douglasmonsky/codex-usage-tracker`. The `codex-usage-tracker` PyPI name is not this project, so avoid similarly named packages when following these docs.
|
|
72
74
|
|
|
73
75
|
Source install for development or branch testing:
|
|
@@ -193,7 +195,7 @@ codex-usage-tracker summary --preset last-7-days
|
|
|
193
195
|
codex-usage-tracker query --since 2026-06-01 --min-credits 1
|
|
194
196
|
codex-usage-tracker session <session-id>
|
|
195
197
|
codex-usage-tracker export --output usage.csv
|
|
196
|
-
codex-usage-tracker dashboard
|
|
198
|
+
codex-usage-tracker open-dashboard
|
|
197
199
|
codex-usage-tracker support-bundle --output ~/.codex-usage-tracker/support-bundle.json
|
|
198
200
|
```
|
|
199
201
|
|
|
@@ -205,7 +207,7 @@ The tracker stores aggregate metrics only: session ids, timestamps, local source
|
|
|
205
207
|
|
|
206
208
|
It does **not** store prompts, assistant messages, tool output, pasted secrets, raw transcript snippets, or raw context in SQLite, CSV exports, generated dashboard HTML, or synthetic screenshots.
|
|
207
209
|
|
|
208
|
-
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can
|
|
210
|
+
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can start off until you enable it from the details panel:
|
|
209
211
|
|
|
210
212
|
```bash
|
|
211
213
|
codex-usage-tracker serve-dashboard --no-context-api --open
|
|
@@ -32,6 +32,8 @@ codex-usage-tracker serve-dashboard --open
|
|
|
32
32
|
|
|
33
33
|
Use your normal Python launcher for your platform: `python3` is common on macOS/Linux, and `py` may be preferable on Windows. On macOS with Homebrew, `brew install pipx` is also fine.
|
|
34
34
|
|
|
35
|
+
`serve-dashboard` refreshes active-session usage before opening by default. Use `--no-refresh` only when you intentionally want to inspect the cached local index.
|
|
36
|
+
|
|
35
37
|
Package naming: the PyPI distribution is `codex-usage-tracking`; the installed command is `codex-usage-tracker`; the GitHub repository remains `douglasmonsky/codex-usage-tracker`. The `codex-usage-tracker` PyPI name is not this project, so avoid similarly named packages when following these docs.
|
|
36
38
|
|
|
37
39
|
Source install for development or branch testing:
|
|
@@ -157,7 +159,7 @@ codex-usage-tracker summary --preset last-7-days
|
|
|
157
159
|
codex-usage-tracker query --since 2026-06-01 --min-credits 1
|
|
158
160
|
codex-usage-tracker session <session-id>
|
|
159
161
|
codex-usage-tracker export --output usage.csv
|
|
160
|
-
codex-usage-tracker dashboard
|
|
162
|
+
codex-usage-tracker open-dashboard
|
|
161
163
|
codex-usage-tracker support-bundle --output ~/.codex-usage-tracker/support-bundle.json
|
|
162
164
|
```
|
|
163
165
|
|
|
@@ -169,7 +171,7 @@ The tracker stores aggregate metrics only: session ids, timestamps, local source
|
|
|
169
171
|
|
|
170
172
|
It does **not** store prompts, assistant messages, tool output, pasted secrets, raw transcript snippets, or raw context in SQLite, CSV exports, generated dashboard HTML, or synthetic screenshots.
|
|
171
173
|
|
|
172
|
-
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can
|
|
174
|
+
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can start off until you enable it from the details panel:
|
|
173
175
|
|
|
174
176
|
```bash
|
|
175
177
|
codex-usage-tracker serve-dashboard --no-context-api --open
|
|
@@ -22,7 +22,7 @@ The MCP `usage_call_context` tool is disabled unless the MCP server process expl
|
|
|
22
22
|
|
|
23
23
|
## Localhost Dashboard Token
|
|
24
24
|
|
|
25
|
-
`serve-dashboard` creates a random per-server API token and embeds it in the generated dashboard HTML for that local server session. The token is used for localhost `/api/usage` refreshes
|
|
25
|
+
`serve-dashboard` creates a random per-server API token and embeds it in the generated dashboard HTML for that local server session. The token is used for localhost `/api/usage` refreshes, `/api/context` requests, and runtime context-loading settings. Treat generated active dashboard files and URLs as local-only artifacts; do not publish them or send them to someone else.
|
|
26
26
|
|
|
27
27
|
The dashboard server rejects non-loopback hosts and cross-origin requests. This is a local hardening measure, not a reason to expose the server on a network interface.
|
|
28
28
|
|
|
@@ -33,11 +33,15 @@ codex-usage-tracker inspect-log ~/.codex/sessions/YYYY/MM/DD/rollout-...jsonl --
|
|
|
33
33
|
codex-usage-tracker dashboard --open
|
|
34
34
|
codex-usage-tracker dashboard --include-archived --open
|
|
35
35
|
codex-usage-tracker open-dashboard
|
|
36
|
+
codex-usage-tracker open-dashboard --no-refresh
|
|
36
37
|
codex-usage-tracker serve-dashboard --open
|
|
38
|
+
codex-usage-tracker serve-dashboard --no-refresh --open
|
|
37
39
|
codex-usage-tracker serve-dashboard --no-context-api --open
|
|
38
40
|
```
|
|
39
41
|
|
|
40
|
-
`serve-dashboard --context-api explicit` is the default and keeps context loading as an explicit per-row action. `serve-dashboard --no-context-api` or `--context-api disabled`
|
|
42
|
+
`serve-dashboard --context-api explicit` is the default and keeps context loading as an explicit per-row action. `serve-dashboard --no-context-api` or `--context-api disabled` starts with context loading off; a token-protected button in the local details panel can enable it without restarting the server.
|
|
43
|
+
|
|
44
|
+
`open-dashboard` and `serve-dashboard` refresh active-session logs before opening by default. Use `--no-refresh` only for an intentionally cached snapshot. The lower-level `dashboard` command writes from the current SQLite index and does not rescan logs.
|
|
41
45
|
|
|
42
46
|
Dashboards default to active sessions only. Use `--include-archived` for an all-history static/opened dashboard, or switch the served dashboard's `History` control from `Active sessions only` to `All history` when you intentionally want archived logs scanned and included.
|
|
43
47
|
|
|
@@ -35,6 +35,8 @@ codex-usage-tracker --privacy-mode strict dashboard --open
|
|
|
35
35
|
|
|
36
36
|
Redacted mode hides raw cwd/source paths, hides Git remote labels, and hashes unnamed projects while preserving configured aliases. Strict mode also hides project-relative cwd, Git branch, and tags. The dashboard header shows the active metadata mode.
|
|
37
37
|
|
|
38
|
+
`serve-dashboard` refreshes active-session logs before opening by default. Use `--no-refresh` only when you intentionally want a cached view of the existing local index.
|
|
39
|
+
|
|
38
40
|
The server keeps the HTML aggregate-only and enables two live features:
|
|
39
41
|
|
|
40
42
|
- `Refresh` rescans local Codex logs and updates the dashboard rows.
|
|
@@ -43,12 +45,12 @@ The server keeps the HTML aggregate-only and enables two live features:
|
|
|
43
45
|
For a static snapshot, use:
|
|
44
46
|
|
|
45
47
|
```bash
|
|
46
|
-
codex-usage-tracker dashboard
|
|
48
|
+
codex-usage-tracker open-dashboard
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
Static file mode can still filter, sort, and inspect aggregate call fields.
|
|
51
|
+
Static file mode can still filter, sort, and inspect aggregate call fields. `open-dashboard` refreshes before writing the snapshot unless you pass `--no-refresh`. Static files cannot refresh from logs or load raw context after opening; use `serve-dashboard` when you want those live controls.
|
|
50
52
|
|
|
51
|
-
The localhost server uses a random per-server token for refresh and context API calls, validates loopback `Host` and `Origin` headers, and can
|
|
53
|
+
The localhost server uses a random per-server token for refresh and context API calls, validates loopback `Host` and `Origin` headers, and can start with context loading off through `codex-usage-tracker serve-dashboard --no-context-api`.
|
|
52
54
|
|
|
53
55
|
## Insights View
|
|
54
56
|
|
|
@@ -141,12 +143,12 @@ When served from localhost, the details panel includes `Load context` and `Inclu
|
|
|
141
143
|
- `Load context` fetches a size-limited, redacted context excerpt for only that call.
|
|
142
144
|
- `Include tool output` repeats the request with tool output included, still redacted and capped.
|
|
143
145
|
- Raw context is not written to SQLite, CSV, or the generated dashboard HTML.
|
|
144
|
-
- If the server was started with `--no-context-api`,
|
|
146
|
+
- If the server was started with `--no-context-api`, context loading starts off. Use `Enable context loading` in the details panel when you want to allow explicit row actions without restarting the dashboard server.
|
|
145
147
|
|
|
146
148
|
## Practical Workflow
|
|
147
149
|
|
|
148
150
|
1. Start with `serve-dashboard --open`.
|
|
149
|
-
2.
|
|
151
|
+
2. Leave `Live` enabled while you work, or click `Refresh` after a Codex run finishes.
|
|
150
152
|
3. Leave `History` on `Active sessions only` for current work. Switch to `All history` when you intentionally want archived sessions included in the live refresh.
|
|
151
153
|
4. Optionally run `parse-allowance` with copied values from Codex Usage or `/status`, or initialize and edit `allowance.json` manually.
|
|
152
154
|
5. Start in `Insights` view and review the highest-severity attention cards.
|
|
@@ -119,10 +119,11 @@ The release checker verifies version alignment, required public docs, packaged p
|
|
|
119
119
|
|
|
120
120
|
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.
|
|
121
121
|
|
|
122
|
-
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:
|
|
122
|
+
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:
|
|
123
123
|
|
|
124
124
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.0`
|
|
125
125
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.1`
|
|
126
|
+
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.2`
|
|
126
127
|
- PyPI: `https://pypi.org/project/codex-usage-tracking/`
|
|
127
128
|
- TestPyPI: `https://test.pypi.org/project/codex-usage-tracking/`
|
|
128
129
|
|
|
@@ -26,6 +26,8 @@ Package naming: the public PyPI distribution is [`codex-usage-tracking`](https:/
|
|
|
26
26
|
|
|
27
27
|
Restart Codex after plugin registration if you want Codex to discover the MCP tools in a fresh session. The localhost dashboard can run immediately.
|
|
28
28
|
|
|
29
|
+
`serve-dashboard` and `open-dashboard` refresh active-session usage before opening by default. Add `--no-refresh` only when you intentionally want to inspect the cached local index without scanning logs first.
|
|
30
|
+
|
|
29
31
|
## Platform Support
|
|
30
32
|
|
|
31
33
|
The CLI, SQLite index, dashboard generator, and localhost server are Python-based and are not macOS-only. CI runs the package on Ubuntu with Python 3.10, 3.11, 3.12, and 3.13.
|
|
@@ -107,8 +109,8 @@ codex-usage-tracker install-plugin --python .venv/bin/python --force
|
|
|
107
109
|
Generate a static dashboard:
|
|
108
110
|
|
|
109
111
|
```bash
|
|
110
|
-
codex-usage-tracker dashboard --open
|
|
111
112
|
codex-usage-tracker open-dashboard
|
|
113
|
+
codex-usage-tracker open-dashboard --no-refresh
|
|
112
114
|
```
|
|
113
115
|
|
|
114
116
|
Serve the dashboard with live aggregate refresh and lazy context loading:
|
|
@@ -119,6 +121,9 @@ codex-usage-tracker serve-dashboard --no-context-api --open
|
|
|
119
121
|
```
|
|
120
122
|
|
|
121
123
|
The server binds to localhost, requires a per-server token for refresh/context endpoints, and rejects non-loopback `Host` or cross-origin `Origin` headers.
|
|
124
|
+
`--no-context-api` starts context loading off; the details panel can enable it later without restarting the server.
|
|
125
|
+
|
|
126
|
+
`open-dashboard` and `serve-dashboard` refresh active-session logs before opening by default. The lower-level `dashboard --open` command writes from the current SQLite index when you need a fully static file-generation step.
|
|
122
127
|
|
|
123
128
|
## Setup Checks
|
|
124
129
|
|
|
@@ -29,12 +29,14 @@ Those fields are not written to SQLite, CSV exports, generated dashboard HTML, o
|
|
|
29
29
|
|
|
30
30
|
`usage_call_context`, `codex-usage-tracker context`, and the `serve-dashboard` context endpoint read a single source JSONL file only when explicitly requested. Returned context is redacted for common secret patterns and capped in size.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Dashboard context loading can start off and then be enabled from the local details panel without restarting:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
codex-usage-tracker serve-dashboard --no-context-api --open
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
The enable action is still token-protected, localhost-only, and does not load any context until you click a row-level context action.
|
|
39
|
+
|
|
38
40
|
For MCP users, `usage_call_context` is additionally disabled unless the MCP server process has this environment variable:
|
|
39
41
|
|
|
40
42
|
```bash
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codex-usage-tracking"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.2"
|
|
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"
|
|
@@ -17,7 +17,7 @@ The only exception is `usage_call_context`, which reads one selected record's lo
|
|
|
17
17
|
|
|
18
18
|
## First Steps
|
|
19
19
|
|
|
20
|
-
1. For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --
|
|
20
|
+
1. For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --context-api explicit --open` so Refresh and Live can use the local API, then report the localhost URL or a brief failure. Refresh is the default for dashboard launch commands; use `--no-refresh` only when the user explicitly asks for a cached snapshot. Use `codex-usage-tracker open-dashboard` only for explicit static/offline snapshots or when the environment cannot keep a long-running server process alive; if you fall back, say the dashboard is static and Live requires `serve-dashboard`.
|
|
21
21
|
2. For "Heaviest thread?", "Thread leaderboard", or similar thread-ranking requests, do not inspect repository files, SQLite schemas, plugin manifests, process lists, dashboard servers, or local logs manually. Refresh the aggregate index, then call `usage_summary(group_by="thread", limit=10, response_format="json")`. If MCP tools are unavailable, run `codex-usage-tracker refresh --json` and `codex-usage-tracker summary --group-by thread --limit 10 --json`.
|
|
22
22
|
3. For normal usage questions, do not inspect repository files, plugin manifests, or local logs first. Start with the aggregate MCP tools. If MCP tools are unavailable, use the CLI JSON fallback below.
|
|
23
23
|
4. Refresh before analysis with `refresh_usage_index` unless the user asks for a static historical snapshot. Keep archived sessions excluded unless the user explicitly asks for all history.
|
|
@@ -17,11 +17,11 @@ The only exception is `usage_call_context`, which intentionally reads one select
|
|
|
17
17
|
|
|
18
18
|
## Fast Paths
|
|
19
19
|
|
|
20
|
-
- For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --
|
|
20
|
+
- For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --context-api explicit --open` so Refresh, Live, load-limit, and history-scope controls can call the local API. Refresh is the default for dashboard launch commands; use `--no-refresh` only when the user explicitly asks for a cached snapshot. Keep the server running while the user is using the dashboard. Use `codex-usage-tracker open-dashboard` only when the user explicitly asks for a static/offline snapshot or when the current environment cannot keep a server process running, and say that the result is static and Live requires `serve-dashboard`.
|
|
21
21
|
- For "Heaviest thread?", "Thread leaderboard", or similar thread-ranking requests, do not inspect repository files, SQLite schemas, plugin manifests, process lists, dashboard servers, or local logs manually. Use the tracker API: refresh the aggregate index, then rank threads with `usage_summary(group_by="thread", limit=10, response_format="json")`.
|
|
22
22
|
- If MCP tools are unavailable for thread-ranking requests, run `codex-usage-tracker refresh --json` and `codex-usage-tracker summary --group-by thread --limit 10 --json`. The summary is already ordered by `total_tokens` descending.
|
|
23
23
|
- Answer thread-ranking requests directly from the summary rows. For the heaviest-thread question, lead with the first row's thread and total tokens; for leaderboard requests, show a compact ranked list.
|
|
24
|
-
- If the CLI command is missing for dashboard-open requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli serve-dashboard --
|
|
24
|
+
- If the CLI command is missing for dashboard-open requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli serve-dashboard --context-api explicit --open`. Use the source-checkout `open-dashboard` fallback only for static/offline snapshots or when a long-running server cannot be kept alive.
|
|
25
25
|
- If the CLI command is missing for thread-ranking requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli refresh --json` and `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli summary --group-by thread --limit 10 --json`.
|
|
26
26
|
- If neither command is available, say briefly that the tracker CLI is not on `PATH` and ask the user to run `codex-usage-tracker setup` or reinstall with `pipx`.
|
|
27
27
|
- Keep dashboard-open narration minimal: one short progress note if needed, then the localhost URL, or if falling back to a static file, the file path plus a note that Live requires `serve-dashboard`. Do not narrate plugin discovery.
|
|
@@ -15,9 +15,9 @@ from pathlib import Path
|
|
|
15
15
|
|
|
16
16
|
PACKAGE_SPEC = os.environ.get(
|
|
17
17
|
"CODEX_USAGE_TRACKER_PACKAGE_SPEC",
|
|
18
|
-
"git+https://github.com/douglasmonsky/codex-usage-tracker.git@
|
|
18
|
+
"git+https://github.com/douglasmonsky/codex-usage-tracker.git@262f51960747a3eb061602e92c929684f8490adb",
|
|
19
19
|
)
|
|
20
|
-
RUNTIME_VERSION = "0.3.
|
|
20
|
+
RUNTIME_VERSION = "0.3.2"
|
|
21
21
|
PACKAGE_SPEC_MARKER = ".codex-usage-tracker-package-spec"
|
|
22
22
|
MODULE_CHECK = (
|
|
23
23
|
"import importlib.metadata; "
|
|
@@ -394,8 +394,12 @@ def _add_dashboard_parsers(
|
|
|
394
394
|
)
|
|
395
395
|
open_dashboard.add_argument(
|
|
396
396
|
"--refresh",
|
|
397
|
-
action=
|
|
398
|
-
|
|
397
|
+
action=argparse.BooleanOptionalAction,
|
|
398
|
+
default=True,
|
|
399
|
+
help=(
|
|
400
|
+
"Refresh the SQLite index before generating the dashboard. "
|
|
401
|
+
"This is the default; use --no-refresh to open the cached index only."
|
|
402
|
+
),
|
|
399
403
|
)
|
|
400
404
|
open_dashboard.add_argument("--codex-home", type=Path, default=DEFAULT_CODEX_HOME)
|
|
401
405
|
open_dashboard.add_argument("--json", action="store_true", dest="as_json")
|
|
@@ -419,13 +423,17 @@ def _add_dashboard_parsers(
|
|
|
419
423
|
serve.add_argument(
|
|
420
424
|
"--no-context-api",
|
|
421
425
|
action="store_true",
|
|
422
|
-
help="
|
|
426
|
+
help="Start with dashboard context loading off; it can be enabled from the local dashboard.",
|
|
423
427
|
)
|
|
424
428
|
serve.add_argument("--open", action="store_true")
|
|
425
429
|
serve.add_argument(
|
|
426
430
|
"--refresh",
|
|
427
|
-
action=
|
|
428
|
-
|
|
431
|
+
action=argparse.BooleanOptionalAction,
|
|
432
|
+
default=True,
|
|
433
|
+
help=(
|
|
434
|
+
"Refresh the SQLite index before generating and serving the dashboard. "
|
|
435
|
+
"This is the default; use --no-refresh to serve the cached index only."
|
|
436
|
+
),
|
|
429
437
|
)
|
|
430
438
|
serve.add_argument("--codex-home", type=Path, default=DEFAULT_CODEX_HOME)
|
|
431
439
|
serve.add_argument("--include-archived", action="store_true")
|
|
@@ -875,6 +875,11 @@
|
|
|
875
875
|
cursor: pointer;
|
|
876
876
|
}
|
|
877
877
|
.context-button:hover { background: #eff6ff; }
|
|
878
|
+
.context-button:disabled {
|
|
879
|
+
cursor: not-allowed;
|
|
880
|
+
opacity: 0.62;
|
|
881
|
+
background: var(--panel);
|
|
882
|
+
}
|
|
878
883
|
.context-button.secondary { color: var(--muted); }
|
|
879
884
|
.context-result {
|
|
880
885
|
margin-top: 12px;
|
|
@@ -1345,17 +1345,24 @@
|
|
|
1345
1345
|
}
|
|
1346
1346
|
function contextControls(row) {
|
|
1347
1347
|
const fileMode = window.location.protocol === 'file:';
|
|
1348
|
-
const
|
|
1349
|
-
const
|
|
1348
|
+
const apiMissing = !apiToken;
|
|
1349
|
+
const apiDisabled = !contextApiEnabled;
|
|
1350
|
+
const disabled = fileMode || apiMissing || apiDisabled ? ' disabled' : '';
|
|
1350
1351
|
const hint = fileMode
|
|
1351
1352
|
? 'Open this dashboard with codex-usage-tracker serve-dashboard to load raw context on demand.'
|
|
1352
|
-
:
|
|
1353
|
-
? 'Context loading
|
|
1353
|
+
: apiMissing
|
|
1354
|
+
? 'Context loading requires a localhost dashboard API token.'
|
|
1355
|
+
: apiDisabled
|
|
1356
|
+
? 'Context loading is off for this dashboard server. Enable it here to load local JSONL context on demand.'
|
|
1354
1357
|
: 'Context is not embedded in this dashboard. Press a button to read this call from the local JSONL source.';
|
|
1358
|
+
const enableButton = !fileMode && !apiMissing && apiDisabled
|
|
1359
|
+
? '<button class="context-button" type="button" data-context-enable>Enable context loading</button>'
|
|
1360
|
+
: '';
|
|
1355
1361
|
return `
|
|
1356
1362
|
<div class="context-actions">
|
|
1357
1363
|
<button class="context-button" type="button" data-context-load${disabled}>Load context</button>
|
|
1358
1364
|
<button class="context-button secondary" type="button" data-context-load-output${disabled}>Include tool output</button>
|
|
1365
|
+
${enableButton}
|
|
1359
1366
|
</div>
|
|
1360
1367
|
<div id="contextResult" class="context-result"><p class="context-note">${escapeHtml(hint)}</p></div>
|
|
1361
1368
|
`;
|
|
@@ -1363,8 +1370,38 @@
|
|
|
1363
1370
|
function bindContextButtons(row) {
|
|
1364
1371
|
const loadButton = detailEl.querySelector('[data-context-load]');
|
|
1365
1372
|
const outputButton = detailEl.querySelector('[data-context-load-output]');
|
|
1373
|
+
const enableButton = detailEl.querySelector('[data-context-enable]');
|
|
1366
1374
|
if (loadButton) loadButton.addEventListener('click', () => loadContext(row, false));
|
|
1367
1375
|
if (outputButton) outputButton.addEventListener('click', () => loadContext(row, true));
|
|
1376
|
+
if (enableButton) enableButton.addEventListener('click', () => enableContextApi(row));
|
|
1377
|
+
}
|
|
1378
|
+
async function enableContextApi(row) {
|
|
1379
|
+
const target = document.getElementById('contextResult');
|
|
1380
|
+
if (!target) return;
|
|
1381
|
+
target.innerHTML = '<p class="context-note">Enabling context loading for this dashboard server...</p>';
|
|
1382
|
+
try {
|
|
1383
|
+
const params = new URLSearchParams({ enabled: '1', _: String(Date.now()) });
|
|
1384
|
+
const response = await fetch(`/api/context-settings?${params.toString()}`, {
|
|
1385
|
+
headers: {
|
|
1386
|
+
'Accept': 'application/json',
|
|
1387
|
+
'X-Codex-Usage-Token': apiToken,
|
|
1388
|
+
},
|
|
1389
|
+
cache: 'no-store',
|
|
1390
|
+
});
|
|
1391
|
+
if (!response.ok) {
|
|
1392
|
+
throw new Error(`Context settings returned HTTP ${response.status}.`);
|
|
1393
|
+
}
|
|
1394
|
+
const payload = await response.json();
|
|
1395
|
+
if (payload.error) throw new Error(payload.error);
|
|
1396
|
+
contextApiEnabled = Boolean(payload.context_api_enabled);
|
|
1397
|
+
showDetail(row);
|
|
1398
|
+
const nextTarget = document.getElementById('contextResult');
|
|
1399
|
+
if (nextTarget && contextApiEnabled) {
|
|
1400
|
+
nextTarget.innerHTML = '<p class="context-note">Context loading is enabled. Press Load context to read this call from the local JSONL source.</p>';
|
|
1401
|
+
}
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
target.innerHTML = `<p class="context-note">${escapeHtml(error.message || String(error))}</p>`;
|
|
1404
|
+
}
|
|
1368
1405
|
}
|
|
1369
1406
|
async function loadContext(row, includeToolOutput) {
|
|
1370
1407
|
const target = document.getElementById('contextResult');
|
|
@@ -86,8 +86,9 @@ codex-usage-tracker serve-dashboard --open</code></pre>
|
|
|
86
86
|
<p>To tune review thresholds locally, run <code>codex-usage-tracker init-thresholds</code> and edit <code>~/.codex-usage-tracker/thresholds.json</code>. These thresholds control low-cache, high-context, high-uncached-input, large-thread, reasoning-spike, low-output, and high-cost recommendations.</p>
|
|
87
87
|
<p>To tune project attribution locally, run <code>codex-usage-tracker init-projects</code> and edit <code>~/.codex-usage-tracker/projects.json</code>. The dashboard derives project name, relative cwd, branch, tags, and a hashed remote origin from aggregate <code>cwd</code> and local Git metadata when available.</p>
|
|
88
88
|
<p>Before sharing screenshots or generated artifacts, put <code>--privacy-mode redacted</code> or <code>--privacy-mode strict</code> before the subcommand, such as <code>codex-usage-tracker --privacy-mode strict serve-dashboard --open</code>. Redacted mode hides raw cwd/source paths, hides Git remote labels, and hashes unnamed projects while preserving configured aliases. Strict mode also hides project-relative cwd, Git branch, and tags. The dashboard header shows the active metadata mode.</p>
|
|
89
|
-
<p>
|
|
90
|
-
<p>The
|
|
89
|
+
<p><code>serve-dashboard</code> refreshes active-session logs before opening by default. Use <code>--no-refresh</code> only when you intentionally want a cached view of the existing local index.</p>
|
|
90
|
+
<p>The server enables live aggregate refresh and on-demand context loading. Static file mode can still filter, sort, and inspect aggregate fields. <code>open-dashboard</code> refreshes before writing the snapshot unless you pass <code>--no-refresh</code>. Static files cannot refresh logs or load context after opening.</p>
|
|
91
|
+
<p>The localhost server uses a random per-server token for refresh and context API calls, validates loopback <code>Host</code> and <code>Origin</code> headers, and can start with context loading off through <code>codex-usage-tracker serve-dashboard --no-context-api</code>.</p>
|
|
91
92
|
|
|
92
93
|
<h2>Insights View</h2>
|
|
93
94
|
<img src="assets/dashboard-insights.png" alt="Insights view with ranked attention cards, investigation presets, and top threads by attention score.">
|
|
@@ -121,7 +122,7 @@ codex-usage-tracker serve-dashboard --open</code></pre>
|
|
|
121
122
|
|
|
122
123
|
<h2>Details And Context</h2>
|
|
123
124
|
<img src="assets/dashboard-details.png" alt="Details panel showing aggregate usage fields for a selected call.">
|
|
124
|
-
<p>The details panel shows primary cost, Codex credits, allowance impact, cache, context, pricing, and next-action signals first. It then groups thread narrative, token/pricing breakdowns, credit confidence and rate-card source metadata, collapsed raw identifiers, and source metadata. When served from localhost with the context API enabled, <code>Load context</code> fetches one redacted, size-limited source excerpt on demand. When started with <code>--no-context-api</code>, context
|
|
125
|
+
<p>The details panel shows primary cost, Codex credits, allowance impact, cache, context, pricing, and next-action signals first. It then groups thread narrative, token/pricing breakdowns, credit confidence and rate-card source metadata, collapsed raw identifiers, and source metadata. When served from localhost with the context API enabled, <code>Load context</code> fetches one redacted, size-limited source excerpt on demand. When started with <code>--no-context-api</code>, context loading starts off; use <code>Enable context loading</code> in the details panel when you want to allow explicit row actions without restarting the dashboard server.</p>
|
|
125
126
|
|
|
126
127
|
<h2>Investigating Long Chat Growth</h2>
|
|
127
128
|
<p class="note">Prompt caching helps, but cached input is not free. Long-running chats can carry a large cached prefix into later turns, so usage can climb quickly even when the visible request looks small.</p>
|
|
@@ -17,7 +17,7 @@ The only exception is `usage_call_context`, which reads one selected record's lo
|
|
|
17
17
|
|
|
18
18
|
## First Steps
|
|
19
19
|
|
|
20
|
-
1. For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --
|
|
20
|
+
1. For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --context-api explicit --open` so Refresh and Live can use the local API, then report the localhost URL or a brief failure. Refresh is the default for dashboard launch commands; use `--no-refresh` only when the user explicitly asks for a cached snapshot. Use `codex-usage-tracker open-dashboard` only for explicit static/offline snapshots or when the environment cannot keep a long-running server process alive; if you fall back, say the dashboard is static and Live requires `serve-dashboard`.
|
|
21
21
|
2. For "Heaviest thread?", "Thread leaderboard", or similar thread-ranking requests, do not inspect repository files, SQLite schemas, plugin manifests, process lists, dashboard servers, or local logs manually. Refresh the aggregate index, then call `usage_summary(group_by="thread", limit=10, response_format="json")`. If MCP tools are unavailable, run `codex-usage-tracker refresh --json` and `codex-usage-tracker summary --group-by thread --limit 10 --json`.
|
|
22
22
|
3. For normal usage questions, do not inspect repository files, plugin manifests, or local logs first. Start with the aggregate MCP tools. If MCP tools are unavailable, use the CLI JSON fallback below.
|
|
23
23
|
4. Refresh before analysis with `refresh_usage_index` unless the user asks for a static historical snapshot. Keep archived sessions excluded unless the user explicitly asks for all history.
|
|
@@ -17,11 +17,11 @@ The only exception is `usage_call_context`, which intentionally reads one select
|
|
|
17
17
|
|
|
18
18
|
## Fast Paths
|
|
19
19
|
|
|
20
|
-
- For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --
|
|
20
|
+
- For "Open dashboard" or similar dashboard-open requests, do not inspect repository files, plugin manifests, tool registries, git status, or local logs first. Start the live localhost dashboard with `codex-usage-tracker serve-dashboard --context-api explicit --open` so Refresh, Live, load-limit, and history-scope controls can call the local API. Refresh is the default for dashboard launch commands; use `--no-refresh` only when the user explicitly asks for a cached snapshot. Keep the server running while the user is using the dashboard. Use `codex-usage-tracker open-dashboard` only when the user explicitly asks for a static/offline snapshot or when the current environment cannot keep a server process running, and say that the result is static and Live requires `serve-dashboard`.
|
|
21
21
|
- For "Heaviest thread?", "Thread leaderboard", or similar thread-ranking requests, do not inspect repository files, SQLite schemas, plugin manifests, process lists, dashboard servers, or local logs manually. Use the tracker API: refresh the aggregate index, then rank threads with `usage_summary(group_by="thread", limit=10, response_format="json")`.
|
|
22
22
|
- If MCP tools are unavailable for thread-ranking requests, run `codex-usage-tracker refresh --json` and `codex-usage-tracker summary --group-by thread --limit 10 --json`. The summary is already ordered by `total_tokens` descending.
|
|
23
23
|
- Answer thread-ranking requests directly from the summary rows. For the heaviest-thread question, lead with the first row's thread and total tokens; for leaderboard requests, show a compact ranked list.
|
|
24
|
-
- If the CLI command is missing for dashboard-open requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli serve-dashboard --
|
|
24
|
+
- If the CLI command is missing for dashboard-open requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli serve-dashboard --context-api explicit --open`. Use the source-checkout `open-dashboard` fallback only for static/offline snapshots or when a long-running server cannot be kept alive.
|
|
25
25
|
- If the CLI command is missing for thread-ranking requests and you are already inside the source checkout, use `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli refresh --json` and `PYTHONPATH=src .venv/bin/python -m codex_usage_tracker.cli summary --group-by thread --limit 10 --json`.
|
|
26
26
|
- If neither command is available, say briefly that the tracker CLI is not on `PATH` and ask the user to run `codex-usage-tracker setup` or reinstall with `pipx`.
|
|
27
27
|
- Keep dashboard-open narration minimal: one short progress note if needed, then the localhost URL, or if falling back to a static file, the file path plus a note that Live requires `serve-dashboard`. Do not narrate plugin discovery.
|
|
@@ -30,6 +30,21 @@ from codex_usage_tracker.paths import (
|
|
|
30
30
|
from codex_usage_tracker.store import refresh_usage_index
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
class _ContextApiState:
|
|
34
|
+
def __init__(self, enabled: bool) -> None:
|
|
35
|
+
self._enabled = enabled
|
|
36
|
+
self._lock = threading.Lock()
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def enabled(self) -> bool:
|
|
40
|
+
with self._lock:
|
|
41
|
+
return self._enabled
|
|
42
|
+
|
|
43
|
+
def set_enabled(self, enabled: bool) -> None:
|
|
44
|
+
with self._lock:
|
|
45
|
+
self._enabled = enabled
|
|
46
|
+
|
|
47
|
+
|
|
33
48
|
def serve_dashboard(
|
|
34
49
|
db_path: Path,
|
|
35
50
|
output_path: Path = DEFAULT_DASHBOARD_PATH,
|
|
@@ -55,6 +70,7 @@ def serve_dashboard(
|
|
|
55
70
|
_validate_context_api_mode(context_api)
|
|
56
71
|
api_token = secrets.token_urlsafe(32)
|
|
57
72
|
context_api_enabled = context_api != "disabled"
|
|
73
|
+
context_api_state = _ContextApiState(context_api_enabled)
|
|
58
74
|
output = generate_dashboard(
|
|
59
75
|
db_path=db_path,
|
|
60
76
|
output_path=output_path,
|
|
@@ -87,13 +103,17 @@ def serve_dashboard(
|
|
|
87
103
|
dashboard_name=output.name,
|
|
88
104
|
context_chars=context_chars,
|
|
89
105
|
api_token=api_token,
|
|
90
|
-
|
|
106
|
+
context_api_state=context_api_state,
|
|
91
107
|
refresh_lock=threading.Lock(),
|
|
92
108
|
)
|
|
93
109
|
server = ThreadingHTTPServer((host, port), handler)
|
|
94
110
|
url = f"http://{_url_host(host)}:{port}/{output.name}"
|
|
95
111
|
print(f"Serving Codex usage dashboard at {url}")
|
|
96
|
-
context_mode =
|
|
112
|
+
context_mode = (
|
|
113
|
+
"enabled for explicit row actions"
|
|
114
|
+
if context_api_enabled
|
|
115
|
+
else "disabled until enabled from the dashboard"
|
|
116
|
+
)
|
|
97
117
|
print("Aggregate rows refresh through /api/usage with a per-server token.")
|
|
98
118
|
print(f"Raw context API is {context_mode}; context is never embedded in the dashboard HTML.")
|
|
99
119
|
if open_browser:
|
|
@@ -122,8 +142,9 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
122
142
|
dashboard_name: str,
|
|
123
143
|
context_chars: int,
|
|
124
144
|
api_token: str,
|
|
125
|
-
context_api_enabled: bool,
|
|
126
145
|
refresh_lock: threading.Lock,
|
|
146
|
+
context_api_enabled: bool = False,
|
|
147
|
+
context_api_state: _ContextApiState | None = None,
|
|
127
148
|
privacy_mode: str = "normal",
|
|
128
149
|
rate_card_path: Path = DEFAULT_RATE_CARD_PATH,
|
|
129
150
|
**kwargs: object,
|
|
@@ -142,7 +163,7 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
142
163
|
self._dashboard_name = dashboard_name
|
|
143
164
|
self._context_chars = context_chars
|
|
144
165
|
self._api_token = api_token
|
|
145
|
-
self.
|
|
166
|
+
self._context_api_state = context_api_state or _ContextApiState(context_api_enabled)
|
|
146
167
|
self._refresh_lock = refresh_lock
|
|
147
168
|
super().__init__(*args, **kwargs)
|
|
148
169
|
|
|
@@ -154,6 +175,9 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
154
175
|
if parsed.path == "/api/context":
|
|
155
176
|
self._handle_context(parsed.query)
|
|
156
177
|
return
|
|
178
|
+
if parsed.path == "/api/context-settings":
|
|
179
|
+
self._handle_context_settings(parsed.query)
|
|
180
|
+
return
|
|
157
181
|
if parsed.path == "/api/usage":
|
|
158
182
|
self._handle_usage(parsed.query)
|
|
159
183
|
return
|
|
@@ -179,10 +203,14 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
179
203
|
|
|
180
204
|
def _handle_context(self, query: str) -> None:
|
|
181
205
|
params = parse_qs(query)
|
|
182
|
-
if not self.
|
|
206
|
+
if not self._context_api_state.enabled:
|
|
183
207
|
self._send_json(
|
|
184
208
|
HTTPStatus.FORBIDDEN,
|
|
185
|
-
{
|
|
209
|
+
{
|
|
210
|
+
"error": "Context loading is disabled for this dashboard server.",
|
|
211
|
+
"context_api_enabled": False,
|
|
212
|
+
"can_enable_context_api": True,
|
|
213
|
+
},
|
|
186
214
|
)
|
|
187
215
|
return
|
|
188
216
|
if not self._has_valid_api_token(params):
|
|
@@ -223,6 +251,22 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
223
251
|
return
|
|
224
252
|
self._send_json(HTTPStatus.OK, payload)
|
|
225
253
|
|
|
254
|
+
def _handle_context_settings(self, query: str) -> None:
|
|
255
|
+
params = parse_qs(query)
|
|
256
|
+
if not self._has_valid_api_token(params):
|
|
257
|
+
self._send_json(HTTPStatus.FORBIDDEN, {"error": "Valid API token is required"})
|
|
258
|
+
return
|
|
259
|
+
enabled = _parse_bool(_first(params.get("enabled")), True)
|
|
260
|
+
self._context_api_state.set_enabled(enabled)
|
|
261
|
+
self._send_json(
|
|
262
|
+
HTTPStatus.OK,
|
|
263
|
+
{
|
|
264
|
+
"schema": "codex-usage-tracker-context-settings-v1",
|
|
265
|
+
"context_api_enabled": self._context_api_state.enabled,
|
|
266
|
+
"raw_context_persisted": False,
|
|
267
|
+
},
|
|
268
|
+
)
|
|
269
|
+
|
|
226
270
|
def _handle_usage(self, query: str) -> None:
|
|
227
271
|
params = parse_qs(query)
|
|
228
272
|
limit = _parse_limit(_first(params.get("limit")), self._limit)
|
|
@@ -264,7 +308,7 @@ class _UsageDashboardHandler(SimpleHTTPRequestHandler):
|
|
|
264
308
|
privacy_mode=self._privacy_mode,
|
|
265
309
|
since=self._since,
|
|
266
310
|
api_token=self._api_token,
|
|
267
|
-
context_api_enabled=self.
|
|
311
|
+
context_api_enabled=self._context_api_state.enabled,
|
|
268
312
|
include_archived=include_archived,
|
|
269
313
|
)
|
|
270
314
|
except sqlite3.Error as exc:
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracking.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
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
|
|
@@ -68,6 +68,8 @@ codex-usage-tracker serve-dashboard --open
|
|
|
68
68
|
|
|
69
69
|
Use your normal Python launcher for your platform: `python3` is common on macOS/Linux, and `py` may be preferable on Windows. On macOS with Homebrew, `brew install pipx` is also fine.
|
|
70
70
|
|
|
71
|
+
`serve-dashboard` refreshes active-session usage before opening by default. Use `--no-refresh` only when you intentionally want to inspect the cached local index.
|
|
72
|
+
|
|
71
73
|
Package naming: the PyPI distribution is `codex-usage-tracking`; the installed command is `codex-usage-tracker`; the GitHub repository remains `douglasmonsky/codex-usage-tracker`. The `codex-usage-tracker` PyPI name is not this project, so avoid similarly named packages when following these docs.
|
|
72
74
|
|
|
73
75
|
Source install for development or branch testing:
|
|
@@ -193,7 +195,7 @@ codex-usage-tracker summary --preset last-7-days
|
|
|
193
195
|
codex-usage-tracker query --since 2026-06-01 --min-credits 1
|
|
194
196
|
codex-usage-tracker session <session-id>
|
|
195
197
|
codex-usage-tracker export --output usage.csv
|
|
196
|
-
codex-usage-tracker dashboard
|
|
198
|
+
codex-usage-tracker open-dashboard
|
|
197
199
|
codex-usage-tracker support-bundle --output ~/.codex-usage-tracker/support-bundle.json
|
|
198
200
|
```
|
|
199
201
|
|
|
@@ -205,7 +207,7 @@ The tracker stores aggregate metrics only: session ids, timestamps, local source
|
|
|
205
207
|
|
|
206
208
|
It does **not** store prompts, assistant messages, tool output, pasted secrets, raw transcript snippets, or raw context in SQLite, CSV exports, generated dashboard HTML, or synthetic screenshots.
|
|
207
209
|
|
|
208
|
-
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can
|
|
210
|
+
On-demand context loading reads a single original local JSONL file only after an explicit row action, redacts common secret patterns, caps returned text size, and can start off until you enable it from the details panel:
|
|
209
211
|
|
|
210
212
|
```bash
|
|
211
213
|
codex-usage-tracker serve-dashboard --no-context-api --open
|
|
@@ -20,7 +20,7 @@ def test_module_cli_version() -> None:
|
|
|
20
20
|
env=_subprocess_env(),
|
|
21
21
|
)
|
|
22
22
|
|
|
23
|
-
assert "codex-usage-tracker 0.3.
|
|
23
|
+
assert "codex-usage-tracker 0.3.2" in result.stdout
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def test_release_check_script_passes() -> None:
|
|
@@ -91,15 +91,29 @@ def test_usage_skills_prefer_live_dashboard_for_open_requests() -> None:
|
|
|
91
91
|
|
|
92
92
|
for skill_path in skill_paths:
|
|
93
93
|
skill_text = skill_path.read_text(encoding="utf-8")
|
|
94
|
-
live_command_index = skill_text.find("serve-dashboard --
|
|
95
|
-
static_command_index = skill_text.find("open-dashboard
|
|
94
|
+
live_command_index = skill_text.find("serve-dashboard --context-api explicit --open")
|
|
95
|
+
static_command_index = skill_text.find("open-dashboard")
|
|
96
96
|
|
|
97
97
|
assert live_command_index != -1, skill_path
|
|
98
98
|
assert static_command_index != -1, skill_path
|
|
99
99
|
assert live_command_index < static_command_index, skill_path
|
|
100
|
+
assert "Refresh is the default" in skill_text
|
|
100
101
|
assert "Live requires `serve-dashboard`" in skill_text
|
|
101
102
|
|
|
102
103
|
|
|
104
|
+
def test_dashboard_launch_commands_refresh_by_default() -> None:
|
|
105
|
+
from codex_usage_tracker.cli import _build_parser
|
|
106
|
+
|
|
107
|
+
parser = _build_parser()
|
|
108
|
+
|
|
109
|
+
assert parser.parse_args(["open-dashboard"]).refresh is True
|
|
110
|
+
assert parser.parse_args(["open-dashboard", "--refresh"]).refresh is True
|
|
111
|
+
assert parser.parse_args(["open-dashboard", "--no-refresh"]).refresh is False
|
|
112
|
+
assert parser.parse_args(["serve-dashboard"]).refresh is True
|
|
113
|
+
assert parser.parse_args(["serve-dashboard", "--refresh"]).refresh is True
|
|
114
|
+
assert parser.parse_args(["serve-dashboard", "--no-refresh"]).refresh is False
|
|
115
|
+
|
|
116
|
+
|
|
103
117
|
def test_cli_json_schema_doc_lists_tracked_contracts() -> None:
|
|
104
118
|
repo_root = Path(__file__).resolve().parents[1]
|
|
105
119
|
docs = (repo_root / "docs" / "cli-json-schemas.md").read_text(encoding="utf-8")
|
|
@@ -34,7 +34,7 @@ def test_install_plugin_writes_generated_wrapper_and_marketplace(tmp_path: Path)
|
|
|
34
34
|
assert result.replaced_existing is False
|
|
35
35
|
assert second.replaced_existing is False
|
|
36
36
|
assert manifest["name"] == "codex-usage-tracker"
|
|
37
|
-
assert manifest["version"] == "0.3.
|
|
37
|
+
assert manifest["version"] == "0.3.2"
|
|
38
38
|
assert manifest["interface"]["defaultPrompt"][:3] == [
|
|
39
39
|
"Open dashboard",
|
|
40
40
|
"Heaviest thread?",
|
|
@@ -833,42 +833,83 @@ def test_dashboard_server_returns_json_for_sqlite_errors(tmp_path: Path, monkeyp
|
|
|
833
833
|
assert "Database error" in context_error["payload"]["error"]
|
|
834
834
|
|
|
835
835
|
|
|
836
|
-
def
|
|
837
|
-
from codex_usage_tracker.server import _UsageDashboardHandler
|
|
836
|
+
def test_dashboard_server_can_enable_context_api_at_runtime(tmp_path: Path) -> None:
|
|
837
|
+
from codex_usage_tracker.server import _ContextApiState, _UsageDashboardHandler
|
|
838
|
+
|
|
839
|
+
codex_home = _make_codex_home(tmp_path)
|
|
840
|
+
db_path = tmp_path / "usage.sqlite3"
|
|
841
|
+
refresh_usage_index(codex_home=codex_home, db_path=db_path)
|
|
842
|
+
record_id = query_session_usage(db_path=db_path, session_id=SESSION_ID)[0]["record_id"]
|
|
843
|
+
context_api_state = _ContextApiState(False)
|
|
838
844
|
|
|
839
845
|
handler = partial(
|
|
840
846
|
_UsageDashboardHandler,
|
|
841
847
|
directory=str(tmp_path),
|
|
842
|
-
db_path=
|
|
848
|
+
db_path=db_path,
|
|
843
849
|
pricing_path=tmp_path / "pricing.json",
|
|
844
850
|
allowance_path=tmp_path / "allowance.json",
|
|
845
851
|
thresholds_path=tmp_path / "thresholds.json",
|
|
846
852
|
projects_path=tmp_path / "projects.json",
|
|
847
853
|
limit=5000,
|
|
848
854
|
since=None,
|
|
849
|
-
codex_home=
|
|
855
|
+
codex_home=codex_home,
|
|
850
856
|
include_archived=False,
|
|
851
857
|
dashboard_name="dashboard.html",
|
|
852
858
|
context_chars=2000,
|
|
853
859
|
api_token="test-token",
|
|
854
|
-
|
|
860
|
+
context_api_state=context_api_state,
|
|
855
861
|
refresh_lock=threading.Lock(),
|
|
856
862
|
)
|
|
857
863
|
server = ThreadingHTTPServer(("127.0.0.1", 0), handler)
|
|
858
864
|
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
859
865
|
thread.start()
|
|
860
866
|
try:
|
|
861
|
-
|
|
862
|
-
f"http://127.0.0.1:{server.server_port}/api/context?record_id=
|
|
867
|
+
disabled_error = _http_error_json(
|
|
868
|
+
f"http://127.0.0.1:{server.server_port}/api/context?record_id={record_id}",
|
|
863
869
|
headers={"X-Codex-Usage-Token": "test-token"},
|
|
864
870
|
)
|
|
871
|
+
enable_without_token = _http_error_json(
|
|
872
|
+
f"http://127.0.0.1:{server.server_port}/api/context-settings?enabled=1"
|
|
873
|
+
)
|
|
874
|
+
with urllib.request.urlopen( # noqa: S310 - local test server only
|
|
875
|
+
urllib.request.Request(
|
|
876
|
+
f"http://127.0.0.1:{server.server_port}/api/context-settings?enabled=1",
|
|
877
|
+
headers={"X-Codex-Usage-Token": "test-token"},
|
|
878
|
+
),
|
|
879
|
+
timeout=5,
|
|
880
|
+
) as response:
|
|
881
|
+
settings_payload = json.loads(response.read().decode("utf-8"))
|
|
882
|
+
with urllib.request.urlopen( # noqa: S310 - local test server only
|
|
883
|
+
urllib.request.Request(
|
|
884
|
+
f"http://127.0.0.1:{server.server_port}/api/usage?limit=1",
|
|
885
|
+
headers={"X-Codex-Usage-Token": "test-token"},
|
|
886
|
+
),
|
|
887
|
+
timeout=5,
|
|
888
|
+
) as response:
|
|
889
|
+
usage_payload = json.loads(response.read().decode("utf-8"))
|
|
890
|
+
with urllib.request.urlopen( # noqa: S310 - local test server only
|
|
891
|
+
urllib.request.Request(
|
|
892
|
+
f"http://127.0.0.1:{server.server_port}/api/context?record_id={record_id}",
|
|
893
|
+
headers={"X-Codex-Usage-Token": "test-token"},
|
|
894
|
+
),
|
|
895
|
+
timeout=5,
|
|
896
|
+
) as response:
|
|
897
|
+
context_payload = json.loads(response.read().decode("utf-8"))
|
|
865
898
|
finally:
|
|
866
899
|
server.shutdown()
|
|
867
900
|
server.server_close()
|
|
868
901
|
thread.join(timeout=5)
|
|
869
902
|
|
|
870
|
-
assert
|
|
871
|
-
assert
|
|
903
|
+
assert disabled_error["status"] == 403
|
|
904
|
+
assert disabled_error["payload"]["context_api_enabled"] is False
|
|
905
|
+
assert disabled_error["payload"]["can_enable_context_api"] is True
|
|
906
|
+
assert enable_without_token["status"] == 403
|
|
907
|
+
assert settings_payload["schema"] == "codex-usage-tracker-context-settings-v1"
|
|
908
|
+
assert settings_payload["context_api_enabled"] is True
|
|
909
|
+
assert settings_payload["raw_context_persisted"] is False
|
|
910
|
+
assert usage_payload["context_api_enabled"] is True
|
|
911
|
+
assert context_payload["loaded_on_demand"] is True
|
|
912
|
+
assert context_payload["raw_context_persisted"] is False
|
|
872
913
|
|
|
873
914
|
|
|
874
915
|
def test_dashboard_query_limit_zero_loads_all_rows(tmp_path: Path) -> None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-calls-preview.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/dashboard-insights.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/plugin-thread-leaderboard.png
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/call-detail-panel.png
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/insight-overview.png
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/docs/assets/ux/thread-investigation.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/scripts/benchmark_synthetic_history.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/__main__.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/allowance.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/api_payloads.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/context.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/costing.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/dashboard.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/diagnostics.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/formatting.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/json_contracts.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/mcp_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/pricing_openai.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/projects.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/recommendations.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/reports.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/support.py
RENAMED
|
File without changes
|
{codex_usage_tracking-0.3.1 → codex_usage_tracking-0.3.2}/src/codex_usage_tracker/threads.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|