codex-usage-tracking 0.11.0__tar.gz → 0.11.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.11.0 → codex_usage_tracking-0.11.2}/.codex-plugin/plugin.json +1 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/CHANGELOG.md +11 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/PKG-INFO +1 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/development.md +7 -7
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/one-dot-oh-readiness.md +8 -8
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/pyproject.toml +1 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/skills/codex-usage-tracker/scripts/run_mcp.py +2 -2
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/__init__.py +1 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics.js +45 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics_snapshots.js +35 -8
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_live.js +3 -3
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tables.css +15 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/PKG-INFO +1 -1
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_cli_release.py +40 -19
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_diagnostics_snapshots.py +60 -2
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_live.py +97 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_payload.py +3 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/.mcp.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/AGENTS.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/CONTRIBUTING.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/LICENSE +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/MANIFEST.in +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/README.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/SECURITY.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/assets/icon.svg +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/architecture.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-call-investigator-evidence.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-call-investigator-preview.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-call-investigator.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-diagnostics-git-expanded.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-diagnostics.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/ux/call-detail-panel.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/ux/insight-overview.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/assets/ux/thread-investigation.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/call-drilldown-performance-checklist.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/cli-json-schemas.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/cli-reference.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/dashboard-guide.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/install.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/mcp.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/pricing-and-credits.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/privacy.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/ui-ux-improvement-plan.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/docs/usage-drain-modeling.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/scripts/benchmark_synthetic_history.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/scripts/check_release.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/scripts/install_local_plugin.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/scripts/model_usage_drain.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/scripts/smoke_installed_package.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/setup.cfg +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/__main__.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/allowance.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/api_payloads.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/call_origin.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/cli.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/cli_parser.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/context.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/costing.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/dashboard.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_facts.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_reports.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_analysis.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_concentration.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_constants.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_events.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_report.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshot_rows.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostic_snapshots.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/diagnostics.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/formatting.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/i18n.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/json_contracts.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/mcp_server.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/models.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/parser.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/paths.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/__init__.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/assets/icon.svg +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_actions.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_analysis.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call_diagnostics.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_call_investigator.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_cells.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_data.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_detail.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_details.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_diagnostics_facts.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_events.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_filters.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_format.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_i18n.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_insights.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_insights.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_layout.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_payload_cache.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_responsive.css +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_state.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_status.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tables.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_template.html +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/dashboard_tooltips.js +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/ar.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/de.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/en.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/es.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/fr.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/it.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/ja.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/ko.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/pt.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/ru.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/vi.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/dashboard/locales/zh-Hans.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator-evidence.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator-preview.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-call-investigator.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls-preview.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-calls.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-details.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-diagnostics-git-expanded.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-diagnostics.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-insights.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/dashboard-threads.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/plugin-prompts.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/assets/plugin-thread-leaderboard.png +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/docs/dashboard-guide.html +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/rate_cards/codex-credit-rates.json +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/skills/codex-usage-api/SKILL.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_data/skills/codex-usage-tracker/SKILL.md +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/plugin_installer.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/pricing.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/pricing_config.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/pricing_estimates.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/pricing_openai.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/projects.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/recommendations.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/redaction.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/reports.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/schema.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/server.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/server_utils.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/store.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/store_query_sql.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/store_schema.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/store_sources.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/store_thread_summaries.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/support.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/threads.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/usage_drain_model.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/usage_drain_reports.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracker/usage_drain_time_series.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/SOURCES.txt +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/dependency_links.txt +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/entry_points.txt +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/requires.txt +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/src/codex_usage_tracking.egg-info/top_level.txt +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/store_dashboard_helpers.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_allowance.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_call_origin.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_cli_lifecycle.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_context_evidence.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_data.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_server.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_state.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_dashboard_status.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_diagnostic_snapshots.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_i18n.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_json_contracts.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_mcp_integration.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_mcp_launcher.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_parser.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_plugin_installer.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_pricing.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_privacy.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_projects.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_recommendations.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_redaction.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_schema.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_store_dashboard_mcp.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_store_migrations.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_support.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_threads.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_usage_drain_model.py +0 -0
- {codex_usage_tracking-0.11.0 → codex_usage_tracking-0.11.2}/tests/test_usage_drain_reports.py +0 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.11.2 - 2026-06-23
|
|
6
|
+
|
|
7
|
+
- Fix served dashboard shell hydration so `serve-dashboard --no-refresh` reliably populates the calls table from `/api/usage` when the initial HTML contains zero rows but indexed rows are available.
|
|
8
|
+
- Harden the synthetic source-log benchmark smoke test so shared-runner timing noise does not leave a stale red release check.
|
|
9
|
+
- Improve benchmark smoke test failures so future threshold failures report the parsed JSON payload and threshold details instead of only a generic subprocess error.
|
|
10
|
+
|
|
11
|
+
## 0.11.1 - 2026-06-23
|
|
12
|
+
|
|
13
|
+
- Move projected weekly credits to the top of the Diagnostics tab and add the 95% CI range to the projection table.
|
|
14
|
+
- Add per-section `Reload` controls for stale or missing diagnostic snapshot cards so one failed or missing section can be recomputed without a full diagnostics refresh.
|
|
15
|
+
|
|
5
16
|
## 0.11.0 - 2026-06-22
|
|
6
17
|
|
|
7
18
|
- Add usage-drain diagnostic reports for token accounting, allowance breakpoints, predictive model highlights, weekly visible usage, weekly projected credits, and cumulative thread cost curves.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.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
|
|
@@ -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.11.
|
|
41
|
+
release/0.11.2
|
|
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.11.
|
|
94
|
+
0.11.2
|
|
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.11.
|
|
150
|
-
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.11.
|
|
149
|
+
python scripts/smoke_installed_package.py --from-pypi --version 0.11.2
|
|
150
|
+
python scripts/smoke_installed_package.py --docker --from-pypi --version 0.11.2
|
|
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.
|
|
@@ -294,8 +294,8 @@ After the release branch merges, tag from updated `main`, not from an unreviewed
|
|
|
294
294
|
```bash
|
|
295
295
|
git switch main
|
|
296
296
|
git pull --ff-only
|
|
297
|
-
git tag -a v0.11.
|
|
298
|
-
git push origin v0.11.
|
|
297
|
+
git tag -a v0.11.2 -m "codex-usage-tracker 0.11.2"
|
|
298
|
+
git push origin v0.11.2
|
|
299
299
|
```
|
|
300
300
|
|
|
301
301
|
Do not create or push release tags without maintainer approval.
|
|
@@ -304,7 +304,7 @@ Do not create or push release tags without maintainer approval.
|
|
|
304
304
|
|
|
305
305
|
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.
|
|
306
306
|
|
|
307
|
-
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. Minor release `0.9.0` adds persisted diagnostic snapshots, on-demand diagnostic refresh, tool/command/file-read/concentration reports, and Diagnostics dashboard panels. Minor release `0.10.0` adds Git/GitHub CLI diagnostics, file-modification diagnostics, and derived call timing fields across the dashboard and API. Patch release `0.10.1` adds lightweight action timing to context evidence and ships the synthetic Git Interactions README screenshot. Minor release `0.11.0` adds usage-drain diagnostic reports, projected weekly credit charts, and cumulative thread cost curves.
|
|
307
|
+
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. Minor release `0.9.0` adds persisted diagnostic snapshots, on-demand diagnostic refresh, tool/command/file-read/concentration reports, and Diagnostics dashboard panels. Minor release `0.10.0` adds Git/GitHub CLI diagnostics, file-modification diagnostics, and derived call timing fields across the dashboard and API. Patch release `0.10.1` adds lightweight action timing to context evidence and ships the synthetic Git Interactions README screenshot. Minor release `0.11.0` adds usage-drain diagnostic reports, projected weekly credit charts, and cumulative thread cost curves. Patch release `0.11.1` improves the Diagnostics weekly projection table and stale snapshot reload controls. Patch release `0.11.2` hardens the synthetic source-log benchmark smoke test and improves benchmark failure diagnostics.
|
|
308
308
|
|
|
309
309
|
- GitHub Release: `https://github.com/douglasmonsky/codex-usage-tracker/releases/tag/v0.3.0`
|
|
310
310
|
- 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.11.
|
|
28
|
-
- [x] Verify public venv install for `0.11.
|
|
29
|
-
- [x] Verify public pipx install path for `0.11.
|
|
27
|
+
- [x] Verify the current public PyPI version is visible as `0.11.2`: `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.11.2`: `python -m venv /tmp/codex-usage-pypi-smoke && . /tmp/codex-usage-pypi-smoke/bin/activate && python -m pip install codex-usage-tracking==0.11.2 && codex-usage-tracker --version`.
|
|
29
|
+
- [x] Verify public pipx install path for `0.11.2`: `PIPX_HOME=/tmp/codex-usage-pipx-home PIPX_BIN_DIR=/tmp/codex-usage-pipx-bin pipx install codex-usage-tracking==0.11.2 && /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.11.
|
|
32
|
+
- [x] Verify public PyPI package in Docker: `python scripts/smoke_installed_package.py --docker --from-pypi --version 0.11.2`.
|
|
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.11.
|
|
137
|
+
These references are the concrete proof behind completed checklist items. Public package smoke commands are version-specific to `0.11.2`; 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.11.
|
|
144
|
+
- Public PyPI Docker coverage is proven by `scripts/smoke_installed_package.py --docker --from-pypi --version 0.11.2`.
|
|
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.11.
|
|
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.11.
|
|
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.11.2`.
|
|
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.11.2`.
|
|
224
224
|
- Release recovery documentation is proven by `scripts/check_release.py` required-file and docs checks.
|
|
225
225
|
|
|
226
226
|
### Known Limitations
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codex-usage-tracking"
|
|
7
|
-
version = "0.11.
|
|
7
|
+
version = "0.11.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"
|
|
@@ -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.11.
|
|
18
|
+
"codex-usage-tracking==0.11.2",
|
|
19
19
|
)
|
|
20
|
-
RUNTIME_VERSION = "0.11.
|
|
20
|
+
RUNTIME_VERSION = "0.11.2"
|
|
21
21
|
PACKAGE_SPEC_MARKER = ".codex-usage-tracker-package-spec"
|
|
22
22
|
MODULE_CHECK = (
|
|
23
23
|
"import importlib.metadata; "
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
let errorMessage = '';
|
|
31
31
|
let snapshotRefreshStatus = 'idle';
|
|
32
32
|
let snapshotRefreshError = '';
|
|
33
|
+
let sectionRefreshStatuses = {};
|
|
33
34
|
let requestGeneration = 0;
|
|
34
35
|
let payloads = emptyPayloads();
|
|
35
36
|
let selectedFactKey = '';
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
errorMessage = '';
|
|
83
84
|
snapshotRefreshStatus = 'idle';
|
|
84
85
|
snapshotRefreshError = '';
|
|
86
|
+
sectionRefreshStatuses = {};
|
|
85
87
|
selectedFactKey = '';
|
|
86
88
|
payloads = emptyPayloads();
|
|
87
89
|
factCallPayloads.clear();
|
|
@@ -110,6 +112,7 @@
|
|
|
110
112
|
errorMessage = '';
|
|
111
113
|
snapshotRefreshStatus = 'idle';
|
|
112
114
|
snapshotRefreshError = '';
|
|
115
|
+
sectionRefreshStatuses = {};
|
|
113
116
|
selectedFactKey = '';
|
|
114
117
|
payloads = emptyPayloads();
|
|
115
118
|
factCallPayloads.clear();
|
|
@@ -134,6 +137,7 @@
|
|
|
134
137
|
]);
|
|
135
138
|
if (generation !== requestGeneration || signature !== activeSignature) return;
|
|
136
139
|
payloads = { facts, tools, compactions, ...snapshots };
|
|
140
|
+
sectionRefreshStatuses = {};
|
|
137
141
|
status = 'ready';
|
|
138
142
|
} catch (error) {
|
|
139
143
|
if (generation !== requestGeneration || signature !== activeSignature) return;
|
|
@@ -173,6 +177,7 @@
|
|
|
173
177
|
const snapshots = refreshPayload.sections || {};
|
|
174
178
|
if (signature !== activeSignature) return;
|
|
175
179
|
payloads = { ...payloads, ...snapshots };
|
|
180
|
+
sectionRefreshStatuses = {};
|
|
176
181
|
snapshotRefreshStatus = 'ready';
|
|
177
182
|
} catch (error) {
|
|
178
183
|
if (signature !== activeSignature) return;
|
|
@@ -182,6 +187,38 @@
|
|
|
182
187
|
renderIfActive();
|
|
183
188
|
}
|
|
184
189
|
|
|
190
|
+
async function refreshDiagnosticSnapshot(sectionKey) {
|
|
191
|
+
const section = snapshotRenderer.sections.find(candidate => candidate.key === sectionKey);
|
|
192
|
+
if (!section || sectionRefreshStatuses[sectionKey] === 'refreshing') return;
|
|
193
|
+
const signature = activeSignature;
|
|
194
|
+
sectionRefreshStatuses = { ...sectionRefreshStatuses, [sectionKey]: 'refreshing' };
|
|
195
|
+
renderIfActive();
|
|
196
|
+
try {
|
|
197
|
+
const filters = getDiagnosticFilters();
|
|
198
|
+
const snapshotFilters = { include_archived: filters?.include_archived || '0' };
|
|
199
|
+
const payload = await fetchPayload(
|
|
200
|
+
section.refreshPath,
|
|
201
|
+
snapshotFilters,
|
|
202
|
+
{ method: 'POST' },
|
|
203
|
+
);
|
|
204
|
+
if (signature !== activeSignature) return;
|
|
205
|
+
payloads = { ...payloads, [sectionKey]: payload };
|
|
206
|
+
sectionRefreshStatuses = { ...sectionRefreshStatuses, [sectionKey]: 'ready' };
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (signature !== activeSignature) return;
|
|
209
|
+
payloads = {
|
|
210
|
+
...payloads,
|
|
211
|
+
[sectionKey]: {
|
|
212
|
+
...(payloads[sectionKey] || {}),
|
|
213
|
+
status: 'error',
|
|
214
|
+
error: error.message || String(error),
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
sectionRefreshStatuses = { ...sectionRefreshStatuses, [sectionKey]: 'error' };
|
|
218
|
+
}
|
|
219
|
+
renderIfActive();
|
|
220
|
+
}
|
|
221
|
+
|
|
185
222
|
async function fetchFactCalls(factType, factName, options = {}) {
|
|
186
223
|
const key = factKey(factType, factName);
|
|
187
224
|
const append = Boolean(options.append);
|
|
@@ -308,7 +345,7 @@
|
|
|
308
345
|
${snapshotRenderer.readoutMetric('Snapshot sections', snapshotRenderer.readyCount(payloads))}
|
|
309
346
|
<span class="diagnostics-note">Structured labels only. Raw context remains on-demand in the call investigator.</span>
|
|
310
347
|
</div>
|
|
311
|
-
${snapshotRenderer.renderPanels({ loading, payloads })}
|
|
348
|
+
${snapshotRenderer.renderPanels({ loading, payloads, sectionRefreshStatuses })}
|
|
312
349
|
${factRenderer.renderFactSection('facts', 'Top Diagnostic Facts', 'Structured facts associated with model calls.', payloads.facts, loading)}
|
|
313
350
|
${factRenderer.renderFactSection('tools', 'Tool and Function Activity', 'Tool/function facts associated with model calls.', payloads.tools, loading)}
|
|
314
351
|
${factRenderer.renderFactSection('compactions', 'Compaction Activity', 'Compaction facts and post-compaction associated costs.', payloads.compactions, loading)}
|
|
@@ -477,6 +514,13 @@
|
|
|
477
514
|
void refreshDiagnosticSnapshots();
|
|
478
515
|
return;
|
|
479
516
|
}
|
|
517
|
+
const sectionRefreshButton = target.closest('[data-diagnostics-section-refresh]');
|
|
518
|
+
if (sectionRefreshButton && diagnosticsPanelEl.contains(sectionRefreshButton)) {
|
|
519
|
+
event.preventDefault();
|
|
520
|
+
event.stopPropagation();
|
|
521
|
+
void refreshDiagnosticSnapshot(sectionRefreshButton.dataset.diagnosticsSectionRefresh || '');
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
480
524
|
const loadMoreButton = target.closest('[data-diagnostics-call-load-more]');
|
|
481
525
|
if (loadMoreButton && diagnosticsPanelEl.contains(loadMoreButton)) {
|
|
482
526
|
event.preventDefault();
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
`;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function renderPanels({ loading, payloads }) {
|
|
51
|
+
function renderPanels({ loading, payloads, sectionRefreshStatuses = {} }) {
|
|
52
52
|
const featuredUsageDrain = renderFeaturedUsageDrain(payloads.usageDrain);
|
|
53
53
|
return `
|
|
54
54
|
${featuredUsageDrain}
|
|
55
55
|
<div class="diagnostics-snapshot-grid">
|
|
56
|
-
${sections.map(section => renderPanel(section, payloads[section.key], loading)).join('')}
|
|
56
|
+
${sections.map(section => renderPanel(section, payloads[section.key], loading, sectionRefreshStatuses[section.key] || '')).join('')}
|
|
57
57
|
</div>
|
|
58
58
|
`;
|
|
59
59
|
}
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
if (!payload || payload.status !== 'ready') return '';
|
|
63
63
|
const timeSeries = payload?.time_series || {};
|
|
64
64
|
const charts = [];
|
|
65
|
-
if (Array.isArray(timeSeries.visible_usage?.points) && timeSeries.visible_usage.points.length) {
|
|
66
|
-
charts.push(renderVisibleUsageChart(timeSeries.visible_usage));
|
|
67
|
-
}
|
|
68
65
|
if (Array.isArray(timeSeries.weekly_credit_projection?.points) && timeSeries.weekly_credit_projection.points.length) {
|
|
69
66
|
charts.push(renderWeeklyProjectionChart(timeSeries.weekly_credit_projection));
|
|
70
67
|
}
|
|
68
|
+
if (Array.isArray(timeSeries.visible_usage?.points) && timeSeries.visible_usage.points.length) {
|
|
69
|
+
charts.push(renderVisibleUsageChart(timeSeries.visible_usage));
|
|
70
|
+
}
|
|
71
71
|
if (!charts.length) return '';
|
|
72
72
|
return `
|
|
73
73
|
<div class="diagnostics-featured-charts" data-diagnostics-featured="usage-drain">
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
`;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function renderPanel(section, payload, loading) {
|
|
79
|
+
function renderPanel(section, payload, loading, sectionRefreshStatus) {
|
|
80
80
|
const meta = snapshotMeta(payload);
|
|
81
81
|
const state = snapshotState(payload, loading);
|
|
82
82
|
const body = state ? renderState(state) : renderBody(section.key, payload);
|
|
@@ -87,13 +87,32 @@
|
|
|
87
87
|
<h3>${escapeHtml(section.title)}</h3>
|
|
88
88
|
<p>${escapeHtml(meta)}</p>
|
|
89
89
|
</div>
|
|
90
|
-
|
|
90
|
+
${renderSnapshotHeaderActions(section, payload, loading, sectionRefreshStatus)}
|
|
91
91
|
</div>
|
|
92
92
|
${body}
|
|
93
93
|
</div>
|
|
94
94
|
`;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
function renderSnapshotHeaderActions(section, payload, loading, sectionRefreshStatus) {
|
|
98
|
+
const refreshing = sectionRefreshStatus === 'refreshing';
|
|
99
|
+
const reloadButton = snapshotRefreshable(payload, loading)
|
|
100
|
+
? `<button class="toolbar-button diagnostics-section-refresh" type="button" data-diagnostics-section-refresh="${escapeHtml(section.key)}" ${refreshing ? 'disabled' : ''}>${escapeHtml(refreshing ? 'Reloading...' : 'Reload')}</button>`
|
|
101
|
+
: '';
|
|
102
|
+
return `
|
|
103
|
+
<div class="diagnostics-section-actions">
|
|
104
|
+
<span>${escapeHtml(refreshing ? 'refreshing' : snapshotBadge(payload, loading))}</span>
|
|
105
|
+
${reloadButton}
|
|
106
|
+
</div>
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function snapshotRefreshable(payload, loading) {
|
|
111
|
+
if (loading) return false;
|
|
112
|
+
if (!payload) return true;
|
|
113
|
+
return payload.status !== 'ready';
|
|
114
|
+
}
|
|
115
|
+
|
|
97
116
|
function renderBody(key, payload) {
|
|
98
117
|
if (key === 'overview') return renderOverview(payload);
|
|
99
118
|
if (key === 'toolOutput') return renderToolOutput(payload);
|
|
@@ -475,13 +494,14 @@
|
|
|
475
494
|
</div>
|
|
476
495
|
</div>
|
|
477
496
|
${renderSimpleTable(
|
|
478
|
-
['Week', 'Plan', 'Observed %', 'Credits', 'Projected/week', 'Confidence'],
|
|
497
|
+
['Week', 'Plan', 'Observed %', 'Credits', 'Projected/week', '95% CI', 'Confidence'],
|
|
479
498
|
chartPoints.slice(-6).map(point => [
|
|
480
499
|
point.label,
|
|
481
500
|
humanizeMetric(point.rate_limit_plan_type || 'unknown'),
|
|
482
501
|
pct(Number(point.observed_usage_delta_percent || 0) / 100),
|
|
483
502
|
numberText(point.observed_standard_usage_credits),
|
|
484
503
|
numberText(point.projected_weekly_credits),
|
|
504
|
+
weeklyProjectionCiText(point),
|
|
485
505
|
humanizeMetric(point.confidence),
|
|
486
506
|
]),
|
|
487
507
|
'No weekly projection points in this snapshot.',
|
|
@@ -529,6 +549,13 @@
|
|
|
529
549
|
return String(label || '').replace(/^Reset\s+/i, '');
|
|
530
550
|
}
|
|
531
551
|
|
|
552
|
+
function weeklyProjectionCiText(point) {
|
|
553
|
+
if (point.ci_low === null || point.ci_low === undefined || point.ci_high === null || point.ci_high === undefined) {
|
|
554
|
+
return 'n/a';
|
|
555
|
+
}
|
|
556
|
+
return `${numberText(point.ci_low)} - ${numberText(point.ci_high)}`;
|
|
557
|
+
}
|
|
558
|
+
|
|
532
559
|
function weeklyProjectionPlanKey(point) {
|
|
533
560
|
return point.rate_limit_plan_type || 'unknown';
|
|
534
561
|
}
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
if (rowCountChanged || refreshChanged) {
|
|
226
226
|
refreshDashboardLive();
|
|
227
227
|
} else if (rowsNeedHydration()) {
|
|
228
|
-
hydrateDashboardRows();
|
|
228
|
+
await hydrateDashboardRows();
|
|
229
229
|
}
|
|
230
230
|
} catch (_error) {
|
|
231
231
|
// Background freshness checks must never interrupt the local dashboard.
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
rowHydrationComplete = getData().length >= rowHydrationTarget();
|
|
292
292
|
updateRowLoadProgress();
|
|
293
293
|
} else if (rowsNeedHydration()) {
|
|
294
|
-
hydrateDashboardRows();
|
|
294
|
+
await hydrateDashboardRows();
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
const result = shellPayload.refresh_result || {};
|
|
@@ -356,7 +356,7 @@
|
|
|
356
356
|
rowHydrationComplete = false;
|
|
357
357
|
}
|
|
358
358
|
applyDashboardPayload(nextPayload);
|
|
359
|
-
if (!['call', 'diagnostics'].includes(activeView())) hydrateDashboardRows({ reset: resetRows });
|
|
359
|
+
if (!['call', 'diagnostics'].includes(activeView())) await hydrateDashboardRows({ reset: resetRows });
|
|
360
360
|
const result = nextPayload.refresh_result || {};
|
|
361
361
|
const indexed = result.inserted_or_updated_events === undefined
|
|
362
362
|
? ''
|
|
@@ -344,7 +344,15 @@
|
|
|
344
344
|
font-weight: 680;
|
|
345
345
|
line-height: 1.35;
|
|
346
346
|
}
|
|
347
|
-
.diagnostics-section-
|
|
347
|
+
.diagnostics-section-actions {
|
|
348
|
+
display: flex;
|
|
349
|
+
flex: 0 0 auto;
|
|
350
|
+
align-items: center;
|
|
351
|
+
justify-content: flex-end;
|
|
352
|
+
gap: 8px;
|
|
353
|
+
flex-wrap: wrap;
|
|
354
|
+
}
|
|
355
|
+
.diagnostics-section-actions > span {
|
|
348
356
|
flex: 0 0 auto;
|
|
349
357
|
padding: 3px 8px;
|
|
350
358
|
border: 1px solid var(--line);
|
|
@@ -355,6 +363,12 @@
|
|
|
355
363
|
font-weight: 780;
|
|
356
364
|
white-space: nowrap;
|
|
357
365
|
}
|
|
366
|
+
.diagnostics-section-refresh {
|
|
367
|
+
min-height: 26px;
|
|
368
|
+
padding: 5px 9px;
|
|
369
|
+
font-size: 11px;
|
|
370
|
+
line-height: 1.1;
|
|
371
|
+
}
|
|
358
372
|
.diagnostics-table-wrap {
|
|
359
373
|
overflow-x: auto;
|
|
360
374
|
border: 1px solid var(--line);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-usage-tracking
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.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
|
|
@@ -352,10 +352,8 @@ def test_cli_json_schema_doc_lists_tracked_contracts() -> None:
|
|
|
352
352
|
|
|
353
353
|
|
|
354
354
|
def test_synthetic_history_benchmark_script_smoke(tmp_path: Path) -> None:
|
|
355
|
-
|
|
356
|
-
result = subprocess.run(
|
|
355
|
+
payload = _run_benchmark_json(
|
|
357
356
|
[
|
|
358
|
-
sys.executable,
|
|
359
357
|
"scripts/benchmark_synthetic_history.py",
|
|
360
358
|
"--rows",
|
|
361
359
|
"100",
|
|
@@ -368,13 +366,7 @@ def test_synthetic_history_benchmark_script_smoke(tmp_path: Path) -> None:
|
|
|
368
366
|
"--threshold-scale",
|
|
369
367
|
"5",
|
|
370
368
|
],
|
|
371
|
-
check=True,
|
|
372
|
-
capture_output=True,
|
|
373
|
-
text=True,
|
|
374
|
-
cwd=repo_root,
|
|
375
|
-
env=_subprocess_env(),
|
|
376
369
|
)
|
|
377
|
-
payload = json.loads(result.stdout)
|
|
378
370
|
|
|
379
371
|
assert payload["threshold_scale"] == 5.0
|
|
380
372
|
assert payload["benchmarks"][0]["rows"] == 100
|
|
@@ -398,10 +390,8 @@ def test_synthetic_history_benchmark_script_smoke(tmp_path: Path) -> None:
|
|
|
398
390
|
|
|
399
391
|
|
|
400
392
|
def test_synthetic_history_benchmark_with_source_logs_smoke(tmp_path: Path) -> None:
|
|
401
|
-
|
|
402
|
-
result = subprocess.run(
|
|
393
|
+
payload = _run_benchmark_json(
|
|
403
394
|
[
|
|
404
|
-
sys.executable,
|
|
405
395
|
"scripts/benchmark_synthetic_history.py",
|
|
406
396
|
"--rows",
|
|
407
397
|
"100",
|
|
@@ -413,17 +403,12 @@ def test_synthetic_history_benchmark_with_source_logs_smoke(tmp_path: Path) -> N
|
|
|
413
403
|
"--json",
|
|
414
404
|
"--enforce-thresholds",
|
|
415
405
|
"--threshold-scale",
|
|
416
|
-
"
|
|
406
|
+
"10",
|
|
417
407
|
],
|
|
418
|
-
check=True,
|
|
419
|
-
capture_output=True,
|
|
420
|
-
text=True,
|
|
421
|
-
cwd=repo_root,
|
|
422
|
-
env=_subprocess_env(),
|
|
423
408
|
)
|
|
424
|
-
payload = json.loads(result.stdout)
|
|
425
409
|
benchmark = payload["benchmarks"][0]
|
|
426
410
|
|
|
411
|
+
assert payload["threshold_scale"] == 10.0
|
|
427
412
|
assert benchmark["threshold_status"] == "pass"
|
|
428
413
|
assert benchmark["threshold_failures"] == []
|
|
429
414
|
assert benchmark["source_logs_generated"] > 0
|
|
@@ -443,6 +428,42 @@ def test_synthetic_history_benchmark_with_source_logs_smoke(tmp_path: Path) -> N
|
|
|
443
428
|
assert benchmark["context_loads"]["middle"]["source_scan_ms"] >= 0
|
|
444
429
|
|
|
445
430
|
|
|
431
|
+
def _run_benchmark_json(args: list[str]) -> dict[str, object]:
|
|
432
|
+
repo_root = Path(__file__).resolve().parents[1]
|
|
433
|
+
result = subprocess.run(
|
|
434
|
+
[sys.executable, *args],
|
|
435
|
+
check=False,
|
|
436
|
+
capture_output=True,
|
|
437
|
+
text=True,
|
|
438
|
+
cwd=repo_root,
|
|
439
|
+
env=_subprocess_env(),
|
|
440
|
+
)
|
|
441
|
+
try:
|
|
442
|
+
payload = json.loads(result.stdout)
|
|
443
|
+
except json.JSONDecodeError as exc:
|
|
444
|
+
raise AssertionError(
|
|
445
|
+
"benchmark did not emit JSON\n"
|
|
446
|
+
f"returncode={result.returncode}\n"
|
|
447
|
+
f"stdout={result.stdout}\n"
|
|
448
|
+
f"stderr={result.stderr}"
|
|
449
|
+
) from exc
|
|
450
|
+
if result.returncode != 0:
|
|
451
|
+
failures = [
|
|
452
|
+
failure
|
|
453
|
+
for benchmark in payload.get("benchmarks", [])
|
|
454
|
+
if isinstance(benchmark, dict)
|
|
455
|
+
for failure in benchmark.get("threshold_failures", [])
|
|
456
|
+
]
|
|
457
|
+
raise AssertionError(
|
|
458
|
+
"benchmark exited nonzero\n"
|
|
459
|
+
f"returncode={result.returncode}\n"
|
|
460
|
+
f"threshold_failures={failures}\n"
|
|
461
|
+
f"stderr={result.stderr}\n"
|
|
462
|
+
f"payload={json.dumps(payload, indent=2)}"
|
|
463
|
+
)
|
|
464
|
+
return payload
|
|
465
|
+
|
|
466
|
+
|
|
446
467
|
def _subprocess_env() -> dict[str, str]:
|
|
447
468
|
env = dict(os.environ)
|
|
448
469
|
repo_root = Path(__file__).resolve().parents[1]
|
|
@@ -294,6 +294,60 @@ console.log(JSON.stringify({
|
|
|
294
294
|
assert payload["leaksRawPath"] is False
|
|
295
295
|
|
|
296
296
|
|
|
297
|
+
def test_dashboard_stale_snapshot_panels_render_reload_buttons() -> None:
|
|
298
|
+
payload = _run_snapshot_renderer_script(
|
|
299
|
+
"""
|
|
300
|
+
const renderer = factory.create({
|
|
301
|
+
escapeHtml,
|
|
302
|
+
formatTimestamp: value => value,
|
|
303
|
+
number: new Intl.NumberFormat('en-US'),
|
|
304
|
+
pct: value => `${Math.round(Number(value || 0) * 100)}%`,
|
|
305
|
+
renderState: message => `<div>${escapeHtml(message)}</div>`,
|
|
306
|
+
rowInvestigatorLink: () => '<a>1,000</a>',
|
|
307
|
+
tokenText: value => new Intl.NumberFormat('en-US').format(Number(value || 0)),
|
|
308
|
+
});
|
|
309
|
+
const html = renderer.renderPanels({
|
|
310
|
+
loading: false,
|
|
311
|
+
payloads: {
|
|
312
|
+
overview: {
|
|
313
|
+
status: 'missing',
|
|
314
|
+
snapshot: {
|
|
315
|
+
history_scope: 'active',
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
toolOutput: {
|
|
319
|
+
status: 'ready',
|
|
320
|
+
refreshed: false,
|
|
321
|
+
snapshot: {
|
|
322
|
+
computed_at: '2026-06-20T00:00:00Z',
|
|
323
|
+
history_scope: 'active',
|
|
324
|
+
source_logs_scanned: 1,
|
|
325
|
+
},
|
|
326
|
+
summary: { function_calls: 1 },
|
|
327
|
+
functions: [],
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
sectionRefreshStatuses: {
|
|
331
|
+
overview: 'refreshing',
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
console.log(JSON.stringify({
|
|
335
|
+
hasOverviewReload: html.includes('data-diagnostics-section-refresh="overview"'),
|
|
336
|
+
overviewReloads: html.includes('Reloading...'),
|
|
337
|
+
hasCommandsReload: html.includes('data-diagnostics-section-refresh="commands"'),
|
|
338
|
+
hasToolOutputReload: html.includes('data-diagnostics-section-refresh="toolOutput"'),
|
|
339
|
+
readyBadgeStillVisible: html.includes('<span>stored</span>'),
|
|
340
|
+
}));
|
|
341
|
+
"""
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
assert payload["hasOverviewReload"] is True
|
|
345
|
+
assert payload["overviewReloads"] is True
|
|
346
|
+
assert payload["hasCommandsReload"] is True
|
|
347
|
+
assert payload["hasToolOutputReload"] is False
|
|
348
|
+
assert payload["readyBadgeStillVisible"] is True
|
|
349
|
+
|
|
350
|
+
|
|
297
351
|
def test_dashboard_usage_drain_charts_render_as_featured_first() -> None:
|
|
298
352
|
payload = _run_snapshot_renderer_script(
|
|
299
353
|
"""
|
|
@@ -370,11 +424,13 @@ const html = renderer.renderPanels({
|
|
|
370
424
|
console.log(JSON.stringify({
|
|
371
425
|
hasFeaturedBlock: html.includes('data-diagnostics-featured="usage-drain"'),
|
|
372
426
|
featuredBeforeGrid: html.indexOf('data-diagnostics-featured="usage-drain"') < html.indexOf('diagnostics-snapshot-grid'),
|
|
373
|
-
|
|
427
|
+
projectionBeforeWeekly: html.indexOf('Projected weekly credits over time') < html.indexOf('Weekly usage over time'),
|
|
374
428
|
projectionBeforeOverview: html.indexOf('Projected weekly credits over time') < html.indexOf('Overview'),
|
|
375
429
|
weeklyChartTitleCount: (html.match(/<strong>Weekly usage over time<\\/strong>/g) || []).length,
|
|
376
430
|
weeklyRemainingPolylineCount: (html.match(/stroke="#059669"/g) || []).length,
|
|
377
431
|
projectedChartTitleCount: (html.match(/<strong>Projected weekly credits over time<\\/strong>/g) || []).length,
|
|
432
|
+
hasCiColumn: html.includes('95% CI'),
|
|
433
|
+
hasFormattedCiRange: html.includes('25,000 - 35,000') && html.includes('36,000 - 44,000'),
|
|
378
434
|
labelsRemainingAllowance: html.includes('Usage remaining') && html.includes('Weekly remaining'),
|
|
379
435
|
labelsVisibleUsage: html.includes('Visible usage'),
|
|
380
436
|
preservesMoneyCents: html.includes('$0.10'),
|
|
@@ -384,11 +440,13 @@ console.log(JSON.stringify({
|
|
|
384
440
|
|
|
385
441
|
assert payload["hasFeaturedBlock"] is True
|
|
386
442
|
assert payload["featuredBeforeGrid"] is True
|
|
387
|
-
assert payload["
|
|
443
|
+
assert payload["projectionBeforeWeekly"] is True
|
|
388
444
|
assert payload["projectionBeforeOverview"] is True
|
|
389
445
|
assert payload["weeklyChartTitleCount"] == 1
|
|
390
446
|
assert payload["weeklyRemainingPolylineCount"] == 2
|
|
391
447
|
assert payload["projectedChartTitleCount"] == 1
|
|
448
|
+
assert payload["hasCiColumn"] is True
|
|
449
|
+
assert payload["hasFormattedCiRange"] is True
|
|
392
450
|
assert payload["labelsRemainingAllowance"] is True
|
|
393
451
|
assert payload["labelsVisibleUsage"] is False
|
|
394
452
|
assert payload["preservesMoneyCents"] is True
|