codex-usage-tracking 0.7.0__tar.gz → 0.8.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.7.0 → codex_usage_tracking-0.8.1}/.codex-plugin/plugin.json +1 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/CHANGELOG.md +13 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/PKG-INFO +2 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/README.md +1 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/architecture.md +2 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/cli-json-schemas.md +56 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/cli-reference.md +14 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/dashboard-guide.md +12 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/development.md +7 -7
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/one-dot-oh-readiness.md +8 -8
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/privacy.md +3 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/pyproject.toml +1 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/scripts/check_release.py +2 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/scripts/smoke_installed_package.py +2 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/skills/codex-usage-tracker/scripts/run_mcp.py +2 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/__init__.py +1 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/cli.py +79 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/cli_parser.py +88 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/context.py +78 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/dashboard.py +3 -0
- codex_usage_tracking-0.8.1/src/codex_usage_tracker/diagnostic_facts.py +636 -0
- codex_usage_tracking-0.8.1/src/codex_usage_tracker/diagnostic_reports.py +507 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/json_contracts.py +32 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/models.py +23 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/parser.py +49 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.js +76 -4
- codex_usage_tracking-0.8.1/src/codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics.js +672 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_events.js +6 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_i18n.js +1 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_layout.css +6 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_live.js +91 -10
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_responsive.css +2 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js +1 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tables.css +181 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_template.html +4 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/dashboard-guide.html +10 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/schema.py +15 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/server.py +141 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/store.py +546 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/store_schema.py +36 -1
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/store_sources.py +7 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/PKG-INFO +2 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/SOURCES.txt +4 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_cli_lifecycle.py +165 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_cli_release.py +1 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_context_evidence.py +67 -0
- codex_usage_tracking-0.8.1/tests/test_dashboard_live.py +245 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_dashboard_payload.py +51 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_dashboard_server.py +47 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_dashboard_state.py +2 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_json_contracts.py +1 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_parser.py +150 -2
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_privacy.py +4 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_store_dashboard_mcp.py +393 -7
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_store_migrations.py +8 -3
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/.mcp.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/AGENTS.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/CONTRIBUTING.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/LICENSE +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/MANIFEST.in +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/SECURITY.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/assets/icon.svg +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-call-investigator-evidence.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-call-investigator-preview.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-call-investigator.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/ux/call-detail-panel.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/ux/insight-overview.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/assets/ux/thread-investigation.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/call-drilldown-performance-checklist.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/install.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/mcp.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/pricing-and-credits.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/docs/ui-ux-improvement-plan.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/scripts/benchmark_synthetic_history.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/scripts/install_local_plugin.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/setup.cfg +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/__main__.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/allowance.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/api_payloads.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/call_origin.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/costing.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/diagnostics.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/formatting.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/i18n.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/mcp_server.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/paths.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/__init__.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/assets/icon.svg +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.css +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_actions.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_analysis.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call.css +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call_diagnostics.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call_investigator.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_cells.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_detail.css +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_details.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_filters.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_insights.css +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_insights.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_payload_cache.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_status.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tables.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tooltips.js +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/ar.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/de.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/en.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/es.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/fr.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/it.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/ja.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/ko.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/pt.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/ru.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/vi.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/dashboard/locales/zh-Hans.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator-evidence.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator-preview.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/rate_cards/codex-credit-rates.json +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_data/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/plugin_installer.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/pricing.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/pricing_config.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/pricing_estimates.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/pricing_openai.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/projects.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/recommendations.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/redaction.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/reports.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/server_utils.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/store_query_sql.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/store_thread_summaries.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/support.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/threads.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/dependency_links.txt +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/entry_points.txt +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/requires.txt +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracking.egg-info/top_level.txt +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/store_dashboard_helpers.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_allowance.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_call_origin.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_dashboard_data.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_i18n.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_mcp_integration.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_mcp_launcher.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_plugin_installer.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_pricing.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_projects.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_recommendations.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_redaction.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_schema.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_support.py +0 -0
- {codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/tests/test_threads.py +0 -0
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.8.1 - 2026-06-20
|
|
6
|
+
|
|
7
|
+
- Make Diagnostics fact tables easier to scan by widening and pinning the Fact column while horizontally scrolling.
|
|
8
|
+
- Add API-backed sortable headers to top-level Diagnostics fact tables, including cached input, output, cache ratio, largest call, latest call time, occurrence, call-count, and fact-name sorts.
|
|
9
|
+
|
|
10
|
+
## 0.8.0 - 2026-06-20
|
|
11
|
+
|
|
12
|
+
- Add an aggregate Diagnostics dashboard for inspecting diagnostic facts, associated calls, token totals, and on-demand evidence without persisting raw transcript text.
|
|
13
|
+
- Add diagnostic fact extraction, reporting APIs, dashboard drilldowns, sortable associated-call tables, and load-more controls for larger diagnostic result sets.
|
|
14
|
+
- Add source byte offsets and context seek diagnostics so on-demand evidence loading can seek when offsets are valid and fall back safely when they are missing or stale.
|
|
15
|
+
- Harden dashboard startup so visiting Diagnostics before other views load no longer prevents Calls, Threads, or Insights from hydrating.
|
|
16
|
+
- Make Live refresh use the cached/indexed append path and fetch only newly visible leading rows instead of running the full manual refresh reset cycle.
|
|
17
|
+
|
|
5
18
|
## 0.7.0 - 2026-06-18
|
|
6
19
|
|
|
7
20
|
- Parse latest observed Codex usage snapshots from local rate-limit and token-count log events without persisting raw transcript text.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.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
|
|
@@ -194,7 +194,7 @@ The tracker cannot read your logged-in ChatGPT plan or live remaining usage auto
|
|
|
194
194
|
|
|
195
195
|
- Local SQLite index at `~/.codex-usage-tracker/usage.sqlite3`.
|
|
196
196
|
- Static dashboard generation plus localhost live refresh.
|
|
197
|
-
- `Insights`, `Calls`, and `
|
|
197
|
+
- `Insights`, `Calls`, `Threads`, and `Diagnostics` dashboard views.
|
|
198
198
|
- Active-only dashboards by default, with an explicit `All history` toggle for archived sessions.
|
|
199
199
|
- CLI summaries, queries, CSV export, dashboard generation, doctor checks, and support bundles.
|
|
200
200
|
- MCP tools for Codex sessions that want to query local usage data.
|
|
@@ -156,7 +156,7 @@ The tracker cannot read your logged-in ChatGPT plan or live remaining usage auto
|
|
|
156
156
|
|
|
157
157
|
- Local SQLite index at `~/.codex-usage-tracker/usage.sqlite3`.
|
|
158
158
|
- Static dashboard generation plus localhost live refresh.
|
|
159
|
-
- `Insights`, `Calls`, and `
|
|
159
|
+
- `Insights`, `Calls`, `Threads`, and `Diagnostics` dashboard views.
|
|
160
160
|
- Active-only dashboards by default, with an explicit `All history` toggle for archived sessions.
|
|
161
161
|
- CLI summaries, queries, CSV export, dashboard generation, doctor checks, and support bundles.
|
|
162
162
|
- MCP tools for Codex sessions that want to query local usage data.
|
|
@@ -4,7 +4,7 @@ Codex Usage Tracker is a local sidecar app. It reads aggregate token counters fr
|
|
|
4
4
|
|
|
5
5
|
## Boundaries
|
|
6
6
|
|
|
7
|
-
- `parser.py` converts local JSONL events into aggregate `UsageEvent` records. It also attaches metadata-only call-origin categories, archived-session flags, and conservative thread keys. It must not persist prompts, assistant text, tool output, or transcript snippets.
|
|
7
|
+
- `parser.py` converts local JSONL events into aggregate `UsageEvent` records. It also attaches metadata-only call-origin categories, diagnostic facts from `diagnostic_facts.py`, archived-session flags, and conservative thread keys. It must not persist prompts, assistant text, tool output, command text, patch text, or transcript snippets.
|
|
8
8
|
- `call_origin.py` owns the pure call-origin classifier and migrated-row fallback. It must not open source JSONL files; source-log reads belong in parser refresh or explicit context loading only.
|
|
9
9
|
- `schema.py` owns persisted `usage_events` columns. Add columns there before changing SQLite migrations or export behavior.
|
|
10
10
|
- `store.py` owns SQLite setup, refresh, rebuild, query access, persisted per-thread previous/next call links, materialized thread summaries, source-file refresh cursors, and SQL-backed live dashboard API slices. Keep filesystem scanning, database writes, SQL prefilters, counts, limits, offsets, and incremental refresh decisions here.
|
|
@@ -13,7 +13,7 @@ Codex Usage Tracker is a local sidecar app. It reads aggregate token counters fr
|
|
|
13
13
|
- `costing.py`, `pricing_config.py`, `pricing_openai.py`, `pricing_estimates.py`, and `allowance.py` own cost, credit, rate-card, and allowance annotation. Keep estimate confidence and source metadata attached to rows.
|
|
14
14
|
- `projects.py`, `threads.py`, and `recommendations.py` annotate aggregate rows with project identity, thread relationships, and actionable signals. Project privacy redaction also belongs in `projects.py` so CLI, MCP, dashboard, CSV, and support-bundle surfaces share the same behavior.
|
|
15
15
|
- `dashboard.py` builds aggregate-only static dashboard payloads and writes HTML/assets. `server.py` adds localhost refresh, the compatibility `/api/usage` endpoint, SQL-backed live API slices, and explicit lazy context loading.
|
|
16
|
-
- `plugin_data/dashboard/dashboard_format.js` owns dashboard formatting primitives. `dashboard_data.js` owns row payload and thread relationship helpers. `dashboard_analysis.js` owns scoring, sorting, recommendation, and thread grouping logic. `dashboard_cells.js` owns reusable table/cell HTML helpers. `dashboard_details.js` owns sidebar detail and thread narrative rendering. `dashboard_insights.js` owns insight cards and investigation preset UI. `dashboard_tables.js` owns Calls, Threads, and expanded thread-call table rendering. `dashboard_filters.js` owns date range parsing and row date matching. `dashboard_state.js` owns URL, CSV, and download state utilities. `dashboard_i18n.js`, `dashboard_payload_cache.js`, and `dashboard_tooltips.js` own localization, session aggregate cache, and fast tooltip helpers. `dashboard_call_investigator.js` owns the dedicated call drilldown surface. `dashboard.js` owns top-level DOM rendering, event handling, and API refresh orchestration.
|
|
16
|
+
- `plugin_data/dashboard/dashboard_format.js` owns dashboard formatting primitives. `dashboard_data.js` owns row payload and thread relationship helpers. `dashboard_analysis.js` owns scoring, sorting, recommendation, and thread grouping logic. `dashboard_cells.js` owns reusable table/cell HTML helpers. `dashboard_details.js` owns sidebar detail and thread narrative rendering. `dashboard_insights.js` owns insight cards and investigation preset UI. `dashboard_tables.js` owns Calls, Threads, and expanded thread-call table rendering. `dashboard_diagnostics.js` owns the Diagnostics tab that consumes `/api/diagnostics/*` aggregate payloads. `dashboard_filters.js` owns date range parsing and row date matching. `dashboard_state.js` owns URL, CSV, and download state utilities. `dashboard_i18n.js`, `dashboard_payload_cache.js`, and `dashboard_tooltips.js` own localization, session aggregate cache, and fast tooltip helpers. `dashboard_call_investigator.js` owns the dedicated call drilldown surface. `dashboard.js` owns top-level DOM rendering, event handling, and API refresh orchestration.
|
|
17
17
|
- `context.py` is the only normal path that reads raw log context, and it does so only for one selected record on demand with redaction and size limits. Its default quick mode omits tool output and serialized groups; full serialized JSONL group analysis is explicit.
|
|
18
18
|
- `plugin_installer.py`, `.mcp.json`, `skills/`, and `scripts/check_release.py` own install and packaging behavior.
|
|
19
19
|
- `scripts/benchmark_synthetic_history.py` owns generated large-history query timing and threshold enforcement for 10k, 100k, and 500k aggregate-row fixtures. Its optional `--with-source-logs` mode writes synthetic JSONL source logs to time explicit context loading and to guard normal dashboard payload assembly against source-log reads. It must stay synthetic-only and must not read real Codex logs.
|
|
@@ -46,6 +46,7 @@ Tracked schema ids:
|
|
|
46
46
|
| `codex-usage-tracker-summary-v1` | CLI `summary --json`, CLI `expensive --json`, MCP summary/expensive JSON |
|
|
47
47
|
| `codex-usage-tracker-query-v1` | CLI `query`, MCP `usage_query(...)` |
|
|
48
48
|
| `codex-usage-tracker-recommendations-v1` | CLI `recommendations --json`, MCP `usage_recommendations(response_format="json")` |
|
|
49
|
+
| `codex-usage-tracker-diagnostics-v1` | CLI `diagnostics ... --json`, dashboard server `/api/diagnostics/*` |
|
|
49
50
|
| `codex-usage-tracker-session-v1` | CLI `session --json`, MCP `session_usage(response_format="json")` |
|
|
50
51
|
| `codex-usage-tracker-context-v1` | CLI `context`, MCP `usage_call_context` when raw context is explicitly enabled |
|
|
51
52
|
| `codex-usage-tracker-context-disabled-v1` | MCP `usage_call_context` when raw context is disabled |
|
|
@@ -225,6 +226,61 @@ Schema: `codex-usage-tracker-session-v1`
|
|
|
225
226
|
}
|
|
226
227
|
```
|
|
227
228
|
|
|
229
|
+
## Diagnostics
|
|
230
|
+
|
|
231
|
+
Commands:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
codex-usage-tracker diagnostics summary --json
|
|
235
|
+
codex-usage-tracker diagnostics facts --sort uncached --json
|
|
236
|
+
codex-usage-tracker diagnostics fact-calls --fact-type compaction --fact-name post_compaction --json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Dashboard server API:
|
|
240
|
+
|
|
241
|
+
- `/api/diagnostics/summary`
|
|
242
|
+
- `/api/diagnostics/facts`
|
|
243
|
+
- `/api/diagnostics/fact-calls?fact_type=compaction&fact_name=post_compaction`
|
|
244
|
+
- `/api/diagnostics/compactions`
|
|
245
|
+
- `/api/diagnostics/tools`
|
|
246
|
+
|
|
247
|
+
Schema: `codex-usage-tracker-diagnostics-v1`
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"schema": "codex-usage-tracker-diagnostics-v1",
|
|
252
|
+
"view": "facts",
|
|
253
|
+
"filters": {
|
|
254
|
+
"since": null,
|
|
255
|
+
"until": null,
|
|
256
|
+
"model": null,
|
|
257
|
+
"effort": null,
|
|
258
|
+
"thread": null,
|
|
259
|
+
"min_tokens": null,
|
|
260
|
+
"fact_type": null,
|
|
261
|
+
"fact_name": null,
|
|
262
|
+
"fact_category": null,
|
|
263
|
+
"fact_group": null,
|
|
264
|
+
"include_archived": false,
|
|
265
|
+
"sort": "uncached",
|
|
266
|
+
"direction": "desc",
|
|
267
|
+
"limit": 50,
|
|
268
|
+
"offset": 0,
|
|
269
|
+
"privacy_mode": "normal"
|
|
270
|
+
},
|
|
271
|
+
"row_count": 1,
|
|
272
|
+
"total_matched_rows": 1,
|
|
273
|
+
"truncated": false,
|
|
274
|
+
"raw_context_included": false,
|
|
275
|
+
"rows": [],
|
|
276
|
+
"notes": [
|
|
277
|
+
"Associated token totals are not additive when one call has multiple diagnostic facts."
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Diagnostics payloads report aggregate structured facts such as compaction, tool/function/MCP activity, command families, structured skill labels, search/read loops, and outcome events. They do not include prompts, assistant messages, tool arguments, tool output, patch text, raw commands, command arguments, file contents, or JSONL fragments. Token totals are associated with facts observed before a token-count row; they are not causal allocations.
|
|
283
|
+
|
|
228
284
|
## Pricing Coverage
|
|
229
285
|
|
|
230
286
|
Command:
|
|
@@ -113,6 +113,20 @@ Useful investigations:
|
|
|
113
113
|
- Use `expensive --limit 10` for a quick list of the highest-cost calls.
|
|
114
114
|
- Use `recommendations --json` for ranked action rows and thread rollups with severity score, primary recommendation, and secondary signals.
|
|
115
115
|
|
|
116
|
+
## Diagnostics
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
codex-usage-tracker diagnostics summary
|
|
120
|
+
codex-usage-tracker diagnostics facts --sort uncached
|
|
121
|
+
codex-usage-tracker diagnostics compactions
|
|
122
|
+
codex-usage-tracker diagnostics tools
|
|
123
|
+
codex-usage-tracker diagnostics fact-calls --fact-type compaction --fact-name post_compaction
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Diagnostics expose structured event patterns and their associated token totals. They can show compactions, tool/function/MCP activity, safe command families, structured skill labels, patch outcomes, task completion, search/read loops, and aborted or rolled-back turns. Associated totals are not causal allocations and are not additive when one model call has multiple diagnostic facts.
|
|
127
|
+
|
|
128
|
+
Diagnostic payloads are aggregate-only. They do not include prompts, assistant text, tool arguments, tool output, patch text, raw commands, command arguments, file contents, or JSONL fragments.
|
|
129
|
+
|
|
116
130
|
## JSON Queries
|
|
117
131
|
|
|
118
132
|
```bash
|
|
@@ -65,7 +65,7 @@ The localhost server uses a random per-server token for refresh and context API
|
|
|
65
65
|
|
|
66
66
|

|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
Open the `Insights` view when you want to answer "what needs attention?" before you start sorting tables.
|
|
69
69
|
|
|
70
70
|
- `Needs Attention` cards rank costly threads, Codex allowance usage, low cache reuse, context bloat, unpriced usage, estimated pricing, and reasoning-output spikes from aggregate fields only.
|
|
71
71
|
- `Investigation Presets` apply a view, derived filter, sort order, and explanatory caption together.
|
|
@@ -126,7 +126,17 @@ Use `Threads` view when you want to understand a work session as a group instead
|
|
|
126
126
|
- Expanded calls default to newest first. Click an expanded-call header such as `Time`, `Tokens`, `Cost`, or `Cache` to sort that thread's visible calls without changing the top-level Threads ranking.
|
|
127
127
|
- Subagents with logged parent session ids are shown under the parent thread. Auto-review sessions without explicit parent ids may be attached by cwd and nearby activity and are marked as attached or inferred in the details.
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
## Diagnostics View
|
|
130
|
+
|
|
131
|
+
Use `Diagnostics` view when you want to see what structured event patterns are happening and what token totals are associated with those patterns.
|
|
132
|
+
|
|
133
|
+
- The tab consumes the localhost `/api/diagnostics/*` endpoints; static file dashboards show a live-API unavailable state.
|
|
134
|
+
- The first table shows top diagnostic facts by associated uncached input tokens. Tool/function/MCP/command-family and compaction sections expose narrower slices of the same fact data.
|
|
135
|
+
- Command diagnostics store only a command family such as `pytest`, `git`, or `unknown_command`. Skill and MCP labels are detected only when they are present as structured event metadata.
|
|
136
|
+
- Click `Calls` on a fact row to load associated model calls. Call links and largest-call links open the Call Investigator, where raw context remains explicit and on demand.
|
|
137
|
+
- Associated token totals are not causal allocations and are not additive when one call has multiple diagnostic facts.
|
|
138
|
+
|
|
139
|
+
The same time range, model, reasoning, history scope, cards, and load controls apply in `Insights`, `Calls`, `Threads`, and `Diagnostics` views. Search, confidence, and sort controls currently scope the call/thread tables, not Diagnostics fact totals.
|
|
130
140
|
|
|
131
141
|
## Call Investigator
|
|
132
142
|
|
|
@@ -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.
|
|
41
|
+
release/0.8.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.
|
|
94
|
+
0.8.1
|
|
95
95
|
1.0-readiness
|
|
96
96
|
1.0.0
|
|
97
97
|
```
|
|
@@ -146,8 +146,8 @@ python scripts/smoke_installed_package.py --docker
|
|
|
146
146
|
To verify the public PyPI package instead of the local checkout:
|
|
147
147
|
|
|
148
148
|
```bash
|
|
149
|
-
python scripts/smoke_installed_package.py --from-pypi --version 0.
|
|
150
|
-
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.
|
|
149
|
+
python scripts/smoke_installed_package.py --from-pypi --version 0.8.1
|
|
150
|
+
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.8.1
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
`scripts/check_release.py` treats these public-package smoke commands as release-state claims. Keep their `--version` and `codex-usage-tracking==...` values aligned with `pyproject.toml`; the release gate fails when the docs claim a different public version. It also checks that install docs point at the real PyPI distribution, `codex-usage-tracking`, and keep the warning that `codex-usage-tracker` is a different PyPI package.
|
|
@@ -286,8 +286,8 @@ After the release branch merges, tag from updated `main`, not from an unreviewed
|
|
|
286
286
|
```bash
|
|
287
287
|
git switch main
|
|
288
288
|
git pull --ff-only
|
|
289
|
-
git tag -a v0.
|
|
290
|
-
git push origin v0.
|
|
289
|
+
git tag -a v0.8.1 -m "codex-usage-tracker 0.8.1"
|
|
290
|
+
git push origin v0.8.1
|
|
291
291
|
```
|
|
292
292
|
|
|
293
293
|
Do not create or push release tags without maintainer approval.
|
|
@@ -296,7 +296,7 @@ Do not create or push release tags without maintainer approval.
|
|
|
296
296
|
|
|
297
297
|
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.
|
|
298
298
|
|
|
299
|
-
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` was published by workflow dispatch from `main`; it hardened the PyPI publish workflow and checked off completed 1.0 readiness gates. Minor release `0.5.0` added dashboard localization support and initial language catalogs. Minor release `0.6.0` is the performance and call-drilldown release with SQL-backed live API slices, materialized thread summaries, faster evidence loading, and dashboard runtime module refactors. Patch release `0.6.1` aligns the final README/package screenshots and companion plugin assets. Minor release `0.7.0` adds observed usage snapshots and the latest-observed dashboard card while keeping raw evidence on demand only.
|
|
299
|
+
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` was published by workflow dispatch from `main`; it hardened the PyPI publish workflow and checked off completed 1.0 readiness gates. Minor release `0.5.0` added dashboard localization support and initial language catalogs. Minor release `0.6.0` is the performance and call-drilldown release with SQL-backed live API slices, materialized thread summaries, faster evidence loading, and dashboard runtime module refactors. Patch release `0.6.1` aligns the final README/package screenshots and companion plugin assets. Minor release `0.7.0` adds observed usage snapshots and the latest-observed dashboard card while keeping raw evidence on demand only. Minor release `0.8.0` adds aggregate diagnostics, source-offset context seeking, and live dashboard loading hardening. Patch release `0.8.1` improves Diagnostics fact table readability with pinned fact names and sortable fact columns.
|
|
300
300
|
|
|
301
301
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.0`
|
|
302
302
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.1`
|
|
@@ -24,12 +24,12 @@ Not guaranteed:
|
|
|
24
24
|
|
|
25
25
|
## 1. Public Install And Package Metadata
|
|
26
26
|
|
|
27
|
-
- [x] Verify the current public PyPI version is visible as `0.
|
|
28
|
-
- [x] Verify public venv install for `0.
|
|
29
|
-
- [x] Verify public pipx install path for `0.
|
|
27
|
+
- [x] Verify the current public PyPI version is visible as `0.8.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.8.1`: `python -m venv /tmp/codex-usage-pypi-smoke && . /tmp/codex-usage-pypi-smoke/bin/activate && python -m pip install codex-usage-tracking==0.8.1 && codex-usage-tracker --version`.
|
|
29
|
+
- [x] Verify public pipx install path for `0.8.1`: `PIPX_HOME=/tmp/codex-usage-pipx-home PIPX_BIN_DIR=/tmp/codex-usage-pipx-bin pipx install codex-usage-tracking==0.8.1 && /tmp/codex-usage-pipx-bin/codex-usage-tracker --version`.
|
|
30
30
|
- [x] Verify installed package resources from a built wheel: `python scripts/smoke_installed_package.py`.
|
|
31
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.
|
|
32
|
+
- [x] Verify public PyPI package in Docker: `python scripts/smoke_installed_package.py --docker --from-pypi --version 0.8.1`.
|
|
33
33
|
- [x] Verify PyPI metadata names remain unchanged: `python scripts/check_release.py`.
|
|
34
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
35
|
|
|
@@ -134,14 +134,14 @@ Not guaranteed:
|
|
|
134
134
|
|
|
135
135
|
## Evidence References
|
|
136
136
|
|
|
137
|
-
These references are the concrete proof behind completed checklist items. Public package smoke commands are version-specific to `0.
|
|
137
|
+
These references are the concrete proof behind completed checklist items. Public package smoke commands are version-specific to `0.8.1`; all repo tests use synthetic or aggregate-only data.
|
|
138
138
|
|
|
139
139
|
### Public Install And Package Metadata
|
|
140
140
|
|
|
141
141
|
- Public PyPI version, public venv install, and public pipx install are proven by the exact public-install commands in section 1.
|
|
142
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
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.
|
|
144
|
+
- Public PyPI Docker coverage is proven by `scripts/smoke_installed_package.py --docker --from-pypi --version 0.8.1`.
|
|
145
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
146
|
|
|
147
147
|
### Upgrade And Migration
|
|
@@ -219,8 +219,8 @@ These references are the concrete proof behind completed checklist items. Public
|
|
|
219
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
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
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
|
-
- TestPyPI publish process is proven by a workflow-dispatch run on `main`, followed by TestPyPI metadata and clean virtualenv install checks for `codex-usage-tracking==0.
|
|
223
|
-
- PyPI publish process is proven by a workflow-dispatch run on `main`, protected `pypi` environment approval, PyPI metadata visibility, clean virtualenv install, temporary pipx install, and Docker public-package smoke for `codex-usage-tracking==0.
|
|
222
|
+
- TestPyPI publish process is proven by a workflow-dispatch run on `main`, followed by TestPyPI metadata and clean virtualenv install checks for `codex-usage-tracking==0.8.1`.
|
|
223
|
+
- PyPI publish process is proven by a workflow-dispatch run on `main`, protected `pypi` environment approval, PyPI metadata visibility, clean virtualenv install, temporary pipx install, and Docker public-package smoke for `codex-usage-tracking==0.8.1`.
|
|
224
224
|
- Release recovery documentation is proven by `scripts/check_release.py` required-file and docs checks.
|
|
225
225
|
|
|
226
226
|
### Known Limitations
|
|
@@ -15,6 +15,7 @@ The local SQLite database is stored at `~/.codex-usage-tracker/usage.sqlite3` by
|
|
|
15
15
|
- materialized thread-level aggregate summaries for active and all-history scopes
|
|
16
16
|
- source-file refresh metadata such as path, path hash, size, mtime, indexed line/byte offsets, latest aggregate record id, parser diagnostics, and last indexed time
|
|
17
17
|
- observed Codex rate-limit snapshot metadata from local token-count logs, such as plan type, limit id, 5-hour/weekly used percentages, window lengths, and reset times
|
|
18
|
+
- diagnostic fact labels tied to aggregate call records, such as safe event categories, payload type labels, counts, timestamps, and line ranges
|
|
18
19
|
- pricing, credit, allowance, recommendation, and project metadata derived from aggregate fields
|
|
19
20
|
|
|
20
21
|
## Not Stored
|
|
@@ -32,6 +33,8 @@ Those fields are not written to SQLite, CSV exports, generated dashboard HTML, o
|
|
|
32
33
|
|
|
33
34
|
Call-origin metadata is heuristic and confidence-labeled. It stores categories such as `user`, `codex`, or `unknown` plus a reason such as `user_message`, `tool_result`, `post_compaction`, or `agent_continuation`. It does not store the message text, tool output, compaction replacement text, or raw JSONL fragment that produced the category.
|
|
34
35
|
|
|
36
|
+
Diagnostic facts follow the same aggregate-only rule. They can store safe structured labels such as `patch_applied`, `function_call_output`, `post_compaction`, MCP tool/server labels, structured skill labels, and command families such as `pytest`, `git`, or `unknown_command`, along with event counts and source line ranges. Command text may be classified in memory during parsing, but it is not persisted. Diagnostic facts do not store tool arguments, command text, command output, patch text, prompt or assistant text, file contents, raw JSONL fragments, or raw context evidence.
|
|
37
|
+
|
|
35
38
|
## On-Demand Context
|
|
36
39
|
|
|
37
40
|
`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 by default for CLI/MCP requests. The call investigator uses the same endpoint at runtime and requests quick redacted evidence for the selected call when the local context API is enabled; that still does not persist raw context into SQLite, CSV, support bundles, or generated dashboard HTML.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codex-usage-tracking"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.8.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"
|
|
@@ -120,6 +120,7 @@ REQUIRED_FILES = [
|
|
|
120
120
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_tooltips.js",
|
|
121
121
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_status.js",
|
|
122
122
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_events.js",
|
|
123
|
+
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics.js",
|
|
123
124
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_call_diagnostics.js",
|
|
124
125
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard.js",
|
|
125
126
|
"src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js",
|
|
@@ -163,6 +164,7 @@ WHEEL_REQUIRED_MEMBERS = {
|
|
|
163
164
|
"codex_usage_tracker/plugin_data/dashboard/dashboard_tooltips.js",
|
|
164
165
|
"codex_usage_tracker/plugin_data/dashboard/dashboard_status.js",
|
|
165
166
|
"codex_usage_tracker/plugin_data/dashboard/dashboard_events.js",
|
|
167
|
+
"codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics.js",
|
|
166
168
|
"codex_usage_tracker/plugin_data/dashboard/dashboard_call_diagnostics.js",
|
|
167
169
|
"codex_usage_tracker/plugin_data/dashboard/dashboard.js",
|
|
168
170
|
"codex_usage_tracker/plugin_data/dashboard/dashboard_state.js",
|
{codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/scripts/smoke_installed_package.py
RENAMED
|
@@ -46,6 +46,7 @@ CLI_HELP_SUBCOMMANDS = [
|
|
|
46
46
|
"summary",
|
|
47
47
|
"query",
|
|
48
48
|
"recommendations",
|
|
49
|
+
"diagnostics",
|
|
49
50
|
"session",
|
|
50
51
|
"context",
|
|
51
52
|
"dashboard",
|
|
@@ -86,6 +87,7 @@ RESOURCE_PATHS = [
|
|
|
86
87
|
"dashboard/dashboard_events.js",
|
|
87
88
|
"dashboard/dashboard_actions.js",
|
|
88
89
|
"dashboard/dashboard_live.js",
|
|
90
|
+
"dashboard/dashboard_diagnostics.js",
|
|
89
91
|
"dashboard/dashboard_call_diagnostics.js",
|
|
90
92
|
"dashboard/dashboard.js",
|
|
91
93
|
"dashboard/dashboard_state.js",
|
|
@@ -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
|
-
"codex-usage-tracking==0.
|
|
18
|
+
"codex-usage-tracking==0.8.1",
|
|
19
19
|
)
|
|
20
|
-
RUNTIME_VERSION = "0.
|
|
20
|
+
RUNTIME_VERSION = "0.8.1"
|
|
21
21
|
PACKAGE_SPEC_MARKER = ".codex-usage-tracker-package-spec"
|
|
22
22
|
MODULE_CHECK = (
|
|
23
23
|
"import importlib.metadata; "
|
|
@@ -24,6 +24,11 @@ from codex_usage_tracker.api_payloads import (
|
|
|
24
24
|
from codex_usage_tracker.cli_parser import build_parser
|
|
25
25
|
from codex_usage_tracker.context import load_call_context
|
|
26
26
|
from codex_usage_tracker.dashboard import generate_dashboard
|
|
27
|
+
from codex_usage_tracker.diagnostic_reports import (
|
|
28
|
+
build_diagnostics_fact_calls_report,
|
|
29
|
+
build_diagnostics_facts_report,
|
|
30
|
+
build_diagnostics_summary_report,
|
|
31
|
+
)
|
|
27
32
|
from codex_usage_tracker.diagnostics import run_doctor
|
|
28
33
|
from codex_usage_tracker.formatting import (
|
|
29
34
|
format_doctor,
|
|
@@ -387,6 +392,79 @@ def _run_recommendations(args: argparse.Namespace) -> int:
|
|
|
387
392
|
return 0
|
|
388
393
|
|
|
389
394
|
|
|
395
|
+
def _run_diagnostics(args: argparse.Namespace) -> int:
|
|
396
|
+
command = args.diagnostics_command
|
|
397
|
+
if command == "summary":
|
|
398
|
+
report = build_diagnostics_summary_report(
|
|
399
|
+
db_path=args.db,
|
|
400
|
+
limit=args.limit,
|
|
401
|
+
since=args.since,
|
|
402
|
+
until=args.until,
|
|
403
|
+
model=args.model,
|
|
404
|
+
effort=args.effort,
|
|
405
|
+
thread=args.thread,
|
|
406
|
+
min_tokens=args.min_tokens,
|
|
407
|
+
fact_type=args.fact_type,
|
|
408
|
+
fact_name=args.fact_name,
|
|
409
|
+
fact_category=args.fact_category,
|
|
410
|
+
include_archived=args.include_archived,
|
|
411
|
+
sort=args.sort,
|
|
412
|
+
direction=args.direction,
|
|
413
|
+
)
|
|
414
|
+
elif command in {"facts", "compactions", "tools"}:
|
|
415
|
+
report = build_diagnostics_facts_report(
|
|
416
|
+
db_path=args.db,
|
|
417
|
+
limit=args.limit,
|
|
418
|
+
since=args.since,
|
|
419
|
+
until=args.until,
|
|
420
|
+
model=args.model,
|
|
421
|
+
effort=args.effort,
|
|
422
|
+
thread=args.thread,
|
|
423
|
+
min_tokens=args.min_tokens,
|
|
424
|
+
fact_type=_diagnostic_fact_type_filter(args),
|
|
425
|
+
fact_name=getattr(args, "fact_name", None),
|
|
426
|
+
fact_category=getattr(args, "fact_category", None),
|
|
427
|
+
include_archived=args.include_archived,
|
|
428
|
+
sort=args.sort,
|
|
429
|
+
direction=args.direction,
|
|
430
|
+
fact_group="tools" if command == "tools" else None,
|
|
431
|
+
view=command,
|
|
432
|
+
)
|
|
433
|
+
elif command == "fact-calls":
|
|
434
|
+
report = build_diagnostics_fact_calls_report(
|
|
435
|
+
db_path=args.db,
|
|
436
|
+
fact_type=args.fact_type,
|
|
437
|
+
fact_name=args.fact_name,
|
|
438
|
+
limit=args.limit,
|
|
439
|
+
offset=args.offset,
|
|
440
|
+
since=args.since,
|
|
441
|
+
until=args.until,
|
|
442
|
+
model=args.model,
|
|
443
|
+
effort=args.effort,
|
|
444
|
+
thread=args.thread,
|
|
445
|
+
min_tokens=args.min_tokens,
|
|
446
|
+
include_archived=args.include_archived,
|
|
447
|
+
sort=args.sort,
|
|
448
|
+
direction=args.direction,
|
|
449
|
+
privacy_mode=args.privacy_mode,
|
|
450
|
+
)
|
|
451
|
+
else:
|
|
452
|
+
raise ValueError(f"unknown diagnostics command: {command}")
|
|
453
|
+
|
|
454
|
+
if args.as_json:
|
|
455
|
+
_print_json(report.payload)
|
|
456
|
+
return 0
|
|
457
|
+
print(report.render())
|
|
458
|
+
return 0
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def _diagnostic_fact_type_filter(args: argparse.Namespace) -> str | None:
|
|
462
|
+
command = args.diagnostics_command
|
|
463
|
+
if command == "compactions":
|
|
464
|
+
return "compaction"
|
|
465
|
+
return getattr(args, "fact_type", None)
|
|
466
|
+
|
|
467
|
+
|
|
390
468
|
def _run_session(args: argparse.Namespace) -> int:
|
|
391
469
|
rows = query_session_usage(args.db, args.session_id, args.limit)
|
|
392
470
|
rows = apply_project_privacy_to_rows(rows, privacy_mode=args.privacy_mode)
|
|
@@ -805,6 +883,7 @@ _COMMAND_HANDLERS = {
|
|
|
805
883
|
"summary": _run_summary,
|
|
806
884
|
"query": _run_query,
|
|
807
885
|
"recommendations": _run_recommendations,
|
|
886
|
+
"diagnostics": _run_diagnostics,
|
|
808
887
|
"session": _run_session,
|
|
809
888
|
"context": _run_context,
|
|
810
889
|
"dashboard": _run_dashboard,
|
{codex_usage_tracking-0.7.0 → codex_usage_tracking-0.8.1}/src/codex_usage_tracker/cli_parser.py
RENAMED
|
@@ -7,6 +7,11 @@ from pathlib import Path
|
|
|
7
7
|
|
|
8
8
|
from codex_usage_tracker import __version__
|
|
9
9
|
from codex_usage_tracker.context import DEFAULT_CONTEXT_CHARS, DEFAULT_CONTEXT_ENTRIES
|
|
10
|
+
from codex_usage_tracker.diagnostic_reports import (
|
|
11
|
+
DIAGNOSTIC_CALL_SORT_CHOICES,
|
|
12
|
+
DIAGNOSTIC_DIRECTION_CHOICES,
|
|
13
|
+
DIAGNOSTIC_FACT_SORT_CHOICES,
|
|
14
|
+
)
|
|
10
15
|
from codex_usage_tracker.paths import (
|
|
11
16
|
DEFAULT_ALLOWANCE_PATH,
|
|
12
17
|
DEFAULT_CODEX_HOME,
|
|
@@ -70,6 +75,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
70
75
|
_add_summary_parser(subparsers)
|
|
71
76
|
_add_query_parser(subparsers)
|
|
72
77
|
_add_recommendations_parser(subparsers)
|
|
78
|
+
_add_diagnostics_parser(subparsers)
|
|
73
79
|
_add_session_parser(subparsers)
|
|
74
80
|
_add_context_parser(subparsers)
|
|
75
81
|
_add_dashboard_parsers(subparsers)
|
|
@@ -281,6 +287,88 @@ def _add_recommendations_parser(
|
|
|
281
287
|
recommendations.add_argument("--json", action="store_true", dest="as_json")
|
|
282
288
|
|
|
283
289
|
|
|
290
|
+
def _add_diagnostics_parser(
|
|
291
|
+
subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
292
|
+
) -> None:
|
|
293
|
+
diagnostics = subparsers.add_parser(
|
|
294
|
+
"diagnostics",
|
|
295
|
+
help="Inspect aggregate diagnostic facts and their associated token costs",
|
|
296
|
+
)
|
|
297
|
+
diagnostic_subparsers = diagnostics.add_subparsers(
|
|
298
|
+
dest="diagnostics_command",
|
|
299
|
+
required=True,
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
summary = diagnostic_subparsers.add_parser(
|
|
303
|
+
"summary",
|
|
304
|
+
help="Summarize diagnostic facts by fact type",
|
|
305
|
+
)
|
|
306
|
+
_add_diagnostics_fact_filters(summary)
|
|
307
|
+
_add_diagnostics_fact_sort(summary, default_limit=20)
|
|
308
|
+
|
|
309
|
+
facts = diagnostic_subparsers.add_parser(
|
|
310
|
+
"facts",
|
|
311
|
+
help="List diagnostic facts with associated token totals",
|
|
312
|
+
)
|
|
313
|
+
_add_diagnostics_fact_filters(facts)
|
|
314
|
+
_add_diagnostics_fact_sort(facts, default_limit=50)
|
|
315
|
+
|
|
316
|
+
compactions = diagnostic_subparsers.add_parser(
|
|
317
|
+
"compactions",
|
|
318
|
+
help="List compaction diagnostic facts",
|
|
319
|
+
)
|
|
320
|
+
_add_diagnostics_base_filters(compactions)
|
|
321
|
+
_add_diagnostics_fact_sort(compactions, default_limit=50)
|
|
322
|
+
|
|
323
|
+
tools = diagnostic_subparsers.add_parser(
|
|
324
|
+
"tools",
|
|
325
|
+
help="List tool/function diagnostic facts",
|
|
326
|
+
)
|
|
327
|
+
_add_diagnostics_base_filters(tools)
|
|
328
|
+
_add_diagnostics_fact_sort(tools, default_limit=50)
|
|
329
|
+
|
|
330
|
+
fact_calls = diagnostic_subparsers.add_parser(
|
|
331
|
+
"fact-calls",
|
|
332
|
+
help="List calls associated with one diagnostic fact",
|
|
333
|
+
)
|
|
334
|
+
fact_calls.add_argument("--fact-type", required=True)
|
|
335
|
+
fact_calls.add_argument("--fact-name", required=True)
|
|
336
|
+
_add_diagnostics_base_filters(fact_calls)
|
|
337
|
+
fact_calls.add_argument("--offset", type=int, default=0)
|
|
338
|
+
fact_calls.add_argument("--limit", type=int, default=50, help="Maximum rows; use 0 for all")
|
|
339
|
+
fact_calls.add_argument("--sort", choices=DIAGNOSTIC_CALL_SORT_CHOICES, default="tokens")
|
|
340
|
+
fact_calls.add_argument("--direction", choices=DIAGNOSTIC_DIRECTION_CHOICES, default="desc")
|
|
341
|
+
fact_calls.add_argument("--json", action="store_true", dest="as_json")
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _add_diagnostics_base_filters(parser: argparse.ArgumentParser) -> None:
|
|
345
|
+
parser.add_argument("--since", help="Only include calls at or after this ISO date/time")
|
|
346
|
+
parser.add_argument("--until", help="Only include calls at or before this ISO date/time")
|
|
347
|
+
parser.add_argument("--model")
|
|
348
|
+
parser.add_argument("--effort")
|
|
349
|
+
parser.add_argument("--thread")
|
|
350
|
+
parser.add_argument("--min-tokens", type=int)
|
|
351
|
+
parser.add_argument("--include-archived", action="store_true")
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _add_diagnostics_fact_filters(parser: argparse.ArgumentParser) -> None:
|
|
355
|
+
_add_diagnostics_base_filters(parser)
|
|
356
|
+
parser.add_argument("--fact-type")
|
|
357
|
+
parser.add_argument("--fact-name")
|
|
358
|
+
parser.add_argument("--fact-category")
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def _add_diagnostics_fact_sort(
|
|
362
|
+
parser: argparse.ArgumentParser,
|
|
363
|
+
*,
|
|
364
|
+
default_limit: int,
|
|
365
|
+
) -> None:
|
|
366
|
+
parser.add_argument("--limit", type=int, default=default_limit, help="Maximum rows; use 0 for all")
|
|
367
|
+
parser.add_argument("--sort", choices=DIAGNOSTIC_FACT_SORT_CHOICES, default="uncached")
|
|
368
|
+
parser.add_argument("--direction", choices=DIAGNOSTIC_DIRECTION_CHOICES, default="desc")
|
|
369
|
+
parser.add_argument("--json", action="store_true", dest="as_json")
|
|
370
|
+
|
|
371
|
+
|
|
284
372
|
def _add_session_parser(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
|
|
285
373
|
session = subparsers.add_parser("session", help="Show one session's usage")
|
|
286
374
|
session.add_argument("session_id", nargs="?")
|