usage-cli 0.31.4__tar.gz → 0.31.6__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.
- {usage_cli-0.31.4 → usage_cli-0.31.6}/PKG-INFO +36 -33
- {usage_cli-0.31.4 → usage_cli-0.31.6}/README.md +35 -32
- {usage_cli-0.31.4 → usage_cli-0.31.6}/i18n.json +5 -5
- {usage_cli-0.31.4 → usage_cli-0.31.6}/installer/setup_hook.py +1 -1
- {usage_cli-0.31.4 → usage_cli-0.31.6}/pricing.py +6 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/pyproject.toml +1 -1
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_statusline.py +7 -89
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_statusline_grok.py +13 -4
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_wintray.py +31 -1
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/PKG-INFO +36 -33
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_statusline.py +22 -52
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_statusline_grok.py +8 -2
- {usage_cli-0.31.4 → usage_cli-0.31.6}/wintray/app.py +13 -3
- {usage_cli-0.31.4 → usage_cli-0.31.6}/LICENSE +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/agy.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/claude.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/codex.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/grok.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/muse.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/rate_limits.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/registry.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/adapters/types.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/aggregator.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/blocks.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/diagnoser.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/dispatch_ledger.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/insights.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/persona_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/reporter.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/subscription.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/analyzer/usage_snapshot.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/doctor.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/fsevents_watch.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/i18n.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/installer/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/installer/login_item.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/installer/session_hooks.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/installer/statusline_settings.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/agy_disk_cache.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/agy_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/agy_quota_probe.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/cache_quarantine.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/claude_paths.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/codex_disk_cache.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/codex_events.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/codex_fork_replay.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/codex_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/codex_paths.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/disk_cache_common.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/disk_cache_lifecycle.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/grok_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/grok_quota_probe.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/history_disk_cache.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/history_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/jsonl_limits.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/jsonl_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/loaders/muse_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/main.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/actions.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/agy.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/app.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/chrome.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/grok.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/menu.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/notify.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/popover.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/prefs.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/refresh.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/state.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/title.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/menubar/update.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/base.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/dynamic_height.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/panel_scale.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/panel_window.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/panel_window_state.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/payload.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/web_panel.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/panels/window_drag.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/prefs.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/project_resolver.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/agy_window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/burn_rate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/codex_window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/usage_rate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/quota/window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/service_status.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/setup.cfg +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/setup_app.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_adapters_claude.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_adapters_codex.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_adapters_rate_limits.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_aggregator.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_agy_adapter.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_agy_disk_cache.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_agy_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_agy_quota_probe.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_agy_window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_analyzer_blocks.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_analyzer_pipeline.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_burn_rate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_cache_quarantine.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_claude_paths.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_codex_consistency.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_codex_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_codex_window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_diagnoser.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_disk_cache_shards.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_dispatch_ledger.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_doctor.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_dynamic_height.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_fsevents_watch.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_grok_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_grok_quota_probe.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_history_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_hook_scripts_are_standalone.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_html_report_snapshot.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_i18n_format_fallback.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_i18n_key_parity.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_i18n_packaged_path.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_insights.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_jsonl_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_login_item.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_main.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar_agy.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar_grok.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar_notify.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar_prefs.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_menubar_state.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_muse_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_packaged_resources.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_packaging.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_panel_footer_layout.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_panel_scale.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_panel_window_state.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_panels.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_panels_lazy_import.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_persona_loader.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_pricing.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_project_resolver.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_report_daily_chart.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_report_filter_js.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_reporter_build_data.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_service_status.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_session_resume.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_setup_app.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_setup_hook.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_setup_hook_coexistence.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_setup_hook_resume.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_setup_hook_terse.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_subprocess_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_subscription.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_time_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_tui.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_tui_sprite.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_ui_tables.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_update_checker.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_update_gate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_update_release_notes.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_cli.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_client.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_diagnosis_snapshot.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_dir_sweeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_lang.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_logging.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_notifications.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_rate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_snapshot.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_snapshot_replay.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_statusline_agy.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_statusline_forwarder.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_terse_mode.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_usage_terse_reminder.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_web_panel_payload.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_wheel_packaging.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_win_login_item.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_window_keeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tests/test_windows_manifest.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tui/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tui/app.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/tui/sprite.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/html_report.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_charts.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_daily_chart.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_filter.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_ledger.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_scripts.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/report_styles.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/ui/tables.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/updates/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/updates/checker.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/updates/gate.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/updates/release_notes.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/SOURCES.txt +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/dependency_links.txt +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/entry_points.txt +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/requires.txt +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.egg-info/top_level.txt +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_cli.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_client.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/subprocess_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/time_utils.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/usage_dir_sweeper.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/usage_lang.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_common/usage_logging.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_diagnosis_snapshot.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_notifications.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_session_resume.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_statusline_agy.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_statusline_forwarder.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_terse_mode.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/usage_terse_reminder.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/wintray/__init__.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/wintray/login_item.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/wintray/menu.py +0 -0
- {usage_cli-0.31.4 → usage_cli-0.31.6}/wintray/watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: usage-cli
|
|
3
|
-
Version: 0.31.
|
|
3
|
+
Version: 0.31.6
|
|
4
4
|
Summary: usage — 在 macOS menu bar 與 Windows 系統匣顯示 Claude Code、Codex、Antigravity 用量的小工具(也提供終端機 TUI)
|
|
5
5
|
License-Expression: AGPL-3.0-only
|
|
6
6
|
Requires-Python: >=3.13
|
|
@@ -24,9 +24,9 @@ Dynamic: license-file
|
|
|
24
24
|
|
|
25
25
|
# usage
|
|
26
26
|
|
|
27
|
-
###
|
|
27
|
+
### Your Claude Code, Codex, Antigravity and Grok CLI quota, always on screen.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
`usage` puts your 5-hour and weekly limits in the macOS menu bar or Windows system tray, colored from green to red. Hitting the limit halfway through a long refactor is a bad way to find out you were running low. Now you see it coming. There's nothing to run and no page to open.
|
|
30
30
|
|
|
31
31
|
[繁體中文](docs/README.zh-TW.md) · [简体中文](docs/README.zh-CN.md) · English · [日本語](docs/README.ja.md) · [한국어](docs/README.ko.md) | [Discussions](https://github.com/aqua5230/usage/discussions) | [Landing page](https://aqua5230.github.io/usage/)
|
|
32
32
|
|
|
@@ -43,7 +43,9 @@ Running out of quota mid-session is expensive — especially during a long refac
|
|
|
43
43
|
<img src="docs/showcase-v3.en.png" alt="usage — Claude Code, Codex, and Antigravity quota pinned to the macOS menu bar" width="820">
|
|
44
44
|
</p>
|
|
45
45
|
|
|
46
|
-
Claude Code and Codex numbers
|
|
46
|
+
Claude Code and Codex numbers come from log files already on your machine. Antigravity quota comes from Google's official quota endpoint, using the sign-in the Antigravity CLI already stores locally.
|
|
47
|
+
|
|
48
|
+
`usage` also helps you spend less. The status line warns you before your context window bloats or your prompt cache goes cold, and a Token Saver toggle keeps replies short. In an A/B test on real sessions, late replies stayed ~40% shorter instead of growing 84% longer.
|
|
47
49
|
|
|
48
50
|
## Quick Start
|
|
49
51
|
|
|
@@ -51,10 +53,10 @@ Claude Code and Codex numbers are read passively from log files already on your
|
|
|
51
53
|
brew install --cask aqua5230/usage/usage
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
**Not on macOS?** `uvx usage-cli` runs the terminal interface anywhere, Linux included — no install, no menu bar.
|
|
55
|
-
|
|
56
56
|
It lands in your Applications folder automatically. Open it once; if macOS 15 or later blocks it, go to System Settings → Privacy & Security, scroll down, and click **Open Anyway**. On macOS 14 or earlier, right-click **Open** once to pass Gatekeeper. Then click the menu bar icon. Prefer a direct download or want the full setup flow? See [Install](#install) below.
|
|
57
57
|
|
|
58
|
+
**Not on macOS?** `uvx usage-cli` runs the terminal interface anywhere, Linux included — no install, no menu bar.
|
|
59
|
+
|
|
58
60
|
**Jump to:** [What You Get](#what-you-get) · [Privacy](#privacy--data-sources) · [Requirements](#requirements) · [Install](#install) · [Status Line](#first-launch-set-up-the-status-line) · [Windows](#windows-support) · [Themes](#theme-gallery) · [Troubleshooting](#troubleshooting) · [Comparison](#comparison) · [Not a Fit?](#when-usage-isnt-the-right-fit) · [Development](#development)
|
|
59
61
|
|
|
60
62
|
## What You Get
|
|
@@ -63,21 +65,22 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
63
65
|
|
|
64
66
|
- **Always-on Monitor:** Your quota lives in the menu bar, color-coded from green to red. Click when you want the full session, weekly, and per-project breakdown.
|
|
65
67
|
- **Antigravity Support:** Antigravity (Gemini) session and weekly quota show up as a third card in every theme except World Cup 2026, which stays a two-team HUD. Numbers come straight from the official quota API, using the sign-in the Antigravity CLI already keeps on your machine — refreshed every few minutes, with live reset countdowns. Antigravity keeps two separate quota pools: the card shows Gemini by default, and tapping the `Gemini ⇄` tag next to the title switches it to Claude / GPT — the choice is remembered.
|
|
66
|
-
- **Grok CLI Support:** A fourth card reads Grok CLI's weekly credit percentage straight from its own local debug log
|
|
68
|
+
- **Grok CLI Support:** A fourth card reads Grok CLI's weekly credit percentage straight from its own local debug log. Grok CLI doesn't expose session or burn-rate data, so the card shows a single weekly bar; its per-request token usage still counts toward today's cost and project totals like Claude Code and Codex.
|
|
67
69
|
- **Muse Code Spending:** Muse Code's per-request tokens and cost count toward today's cost, project totals, the HTML report, and the `usage` CLI, read from its own local session logs. Muse keeps no local quota data, so there is no Muse quota card.
|
|
68
|
-
- **Service Status Alerts:** An orange-red banner appears when Claude Code, Claude API, or Codex API has an outage or degraded performance, read from their public Statuspage.io pages
|
|
70
|
+
- **Service Status Alerts:** An orange-red banner appears when Claude Code, Claude API, or Codex API has an outage or degraded performance, read from their public Statuspage.io pages. Antigravity isn't covered; it has no public status page.
|
|
69
71
|
- **Context Nudges & Notifications:** When your context window hits 70% — or earlier when it is filling fast — the status line nudges you to `/clear` or `/compact` to prevent token waste. You can also opt-in to system notifications for quota limits and recoveries.
|
|
70
72
|
- **Prompt Cache Health:** The status line shows Claude Code's prompt cache hit rate with a countdown to expiry, so you can tell at a glance whether finishing now still reuses the cached context or lets it go cold and re-sends everything. Once it has gone cold, the countdown turns into how many tokens your next message will re-cache. Needs Claude Code 2.1.251 or newer; on older versions the segment simply doesn't appear.
|
|
71
73
|
- **Hide Sections:** Only use one or two of the tools? Hide the Claude Code, Codex, Grok CLI, or Antigravity section from the menu bar and panels completely with a single click.
|
|
72
74
|
|
|
73
75
|
### Workflow Helpers
|
|
74
76
|
|
|
75
|
-
- **Progress Concierge:** Open a new Claude Code session and `usage` hands your last progress straight to the AI, including your last request, uncommitted changes, and unfinished todos. No `/resume`, no recap. When you do `/resume` a conversation that sat long enough for its cache to expire, it warns you how many tokens the next message will re-send and suggests `/compact` first.
|
|
77
|
+
- **Progress Concierge:** Open a new Claude Code session and `usage` hands your last progress straight to the AI, including your last request, uncommitted changes, and unfinished todos. No `/resume`, no recap. When you do `/resume` a conversation that sat long enough for its cache to expire, it warns you how many tokens the next message will re-send and suggests `/compact` first. Off by default.
|
|
76
78
|
- **Token Saver:** A menu-bar toggle asks Claude Code and Codex to answer more tersely and in plainer language, saving output tokens while keeping code and error messages byte-exact. A light reminder keeps long conversations from drifting back to verbose — in an A/B test on real sessions, late replies stayed ~40% shorter instead of drifting 84% longer.
|
|
77
|
-
- **
|
|
79
|
+
- **Auto-start 5-hour Session:** Off by default. Turn it on and, right after a 5-hour quota resets, `usage` sends one tiny message to each tool (Claude with Haiku, Antigravity with Gemini 3.5 Flash Low, Codex with its cheapest model) so the next 5-hour window starts counting right away. Those messages do use a little quota, but the amount is negligible. Checking your quota never sends a message; only this switch does.
|
|
80
|
+
- **Terminal Integration:** `usage status --json` hands your Claude Code and Codex quota to any tool that can run a command — Starship, tmux, or your own scripts. Reads the same local files as the menu bar. [Ready-made snippets](docs/DEVELOPMENT.md#quota-status-for-other-tools-usage-status).
|
|
78
81
|
- **Token-waste Health Check:** A daily background diagnosis scans your logs for waste, including repeated file reads, polluter directories, and noisy Bash output. If it finds issues, a one-line heads-up appears; say "show me" and the AI walks you through fixes.
|
|
79
82
|
|
|
80
|
-
###
|
|
83
|
+
### Stay Current
|
|
81
84
|
|
|
82
85
|
- **AI Update Daily:** Opens a daily-updated public [page](https://aqua5230.github.io/ai-updates/) covering Claude Code, Codex, and Antigravity, with the full history kept. Reviewed items get a plain-language summary in all five UI languages; unreviewed ones show the original source text.
|
|
83
86
|
|
|
@@ -88,20 +91,20 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
88
91
|
### Experience & Customization
|
|
89
92
|
|
|
90
93
|
- **16 Visual Themes:** Switch between panel styles including Default, Matrix, Windows 95, Vintage Newspaper, Cloud Observation, Midnight Aquarium, Prism Arcade, Black Hole, World Cup 2026, Lepidoptera, Migration, Stained Glass, Origami, Sketchbook, Heart Monitor, and Catppuccin (official palette, all four flavors).
|
|
91
|
-
- **Place the Panel Anywhere:**
|
|
94
|
+
- **Place the Panel Anywhere:** Drag the panel from any empty spot to wherever you want it, and it reopens there next time. It stays put when another app takes focus — a second click on the menu bar icon, or Escape, closes it.
|
|
92
95
|
- **Drag to Reorder:** Grab any quota card and drag it up or down to swap the order — the arrangement is shared across every theme with quota cards (all except World Cup 2026) and survives restarts.
|
|
93
96
|
- **Automatic Localization:** UI text is available in Traditional Chinese, Simplified Chinese, English, Japanese, and Korean, automatically matching your system settings.
|
|
94
97
|
|
|
95
98
|
## Privacy & Data Sources
|
|
96
99
|
|
|
97
|
-
- Claude Code and Codex numbers are read
|
|
98
|
-
- Antigravity quota requires network access, and only if you use it: quota is fetched from Google's official quota endpoint using the OAuth credential the Antigravity CLI already stored after sign-in — read from macOS Keychain, Windows Credential Manager, or a local token file depending on CLI version. `usage` reads that credential without writing it back and keeps any refreshed access token in memory only; the call itself
|
|
100
|
+
- Claude Code and Codex numbers are read from local log files on your machine.
|
|
101
|
+
- Antigravity quota requires network access, and only if you use it: quota is fetched from Google's official quota endpoint using the OAuth credential the Antigravity CLI already stored after sign-in — read from macOS Keychain, Windows Credential Manager, or a local token file depending on CLI version. `usage` reads that credential without writing it back and keeps any refreshed access token in memory only; the call itself reads quota metadata.
|
|
99
102
|
- Background network activity: the Antigravity quota/token endpoints above, public Claude and Codex status pages to flag outages, a public model-pricing table to estimate cost (falls back to built-in prices offline), and occasionally checking GitHub for a new version. Claude Code and Codex log contents are never uploaded.
|
|
100
103
|
|
|
101
104
|
## Requirements
|
|
102
105
|
|
|
103
106
|
- macOS 12 (Monterey) or newer, or Windows 10/11
|
|
104
|
-
- Claude Code, Codex, or
|
|
107
|
+
- Claude Code, Codex, Antigravity, or Grok CLI has been used at least once (so local usage data exists).
|
|
105
108
|
- (Source runs only) Python 3.13.
|
|
106
109
|
|
|
107
110
|
## Install
|
|
@@ -167,21 +170,22 @@ Privacy policy: this program will not transfer any information to other networke
|
|
|
167
170
|
Switch between **16 visual themes** directly from the UI:
|
|
168
171
|
|
|
169
172
|
<p align="center">
|
|
170
|
-
<img src="docs/classic.en.png" width="
|
|
171
|
-
<img src="docs/matrix.en.png" width="
|
|
172
|
-
<img src="docs/win95.en.png" width="
|
|
173
|
-
<img src="docs/newspaper.en.png" width="
|
|
174
|
-
<img src="docs/cloud_observation.en.png" width="
|
|
175
|
-
<img src="docs/aquarium.en.png" width="
|
|
176
|
-
<img src="docs/prism_arcade.en.png" width="
|
|
177
|
-
<img src="docs/stained_glass.en.png" width="
|
|
178
|
-
<img src="docs/origami.en.png" width="
|
|
179
|
-
<img src="docs/black_hole.en.png" width="
|
|
180
|
-
<img src="docs/
|
|
181
|
-
<img src="docs/
|
|
182
|
-
<img src="docs/
|
|
183
|
-
<img src="docs/
|
|
184
|
-
<img src="docs/
|
|
173
|
+
<img src="docs/classic.en.png" width="24%" alt="Classic theme" />
|
|
174
|
+
<img src="docs/matrix.en.png" width="24%" alt="Matrix theme" />
|
|
175
|
+
<img src="docs/win95.en.png" width="24%" alt="Windows 95 theme" />
|
|
176
|
+
<img src="docs/newspaper.en.png" width="24%" alt="Newspaper theme" />
|
|
177
|
+
<img src="docs/cloud_observation.en.png" width="24%" alt="Cloud Observation theme" />
|
|
178
|
+
<img src="docs/aquarium.en.png" width="24%" alt="Midnight Aquarium theme" />
|
|
179
|
+
<img src="docs/prism_arcade.en.png" width="24%" alt="Prism Arcade theme" />
|
|
180
|
+
<img src="docs/stained_glass.en.png" width="24%" alt="Stained Glass theme" />
|
|
181
|
+
<img src="docs/origami.en.png" width="24%" alt="Origami theme" />
|
|
182
|
+
<img src="docs/black_hole.en.png" width="24%" alt="Black Hole theme" />
|
|
183
|
+
<img src="docs/world_cup.en.png" width="24%" alt="World Cup 2026 theme" />
|
|
184
|
+
<img src="docs/lepidoptera.en.png" width="24%" alt="Lepidoptera theme" />
|
|
185
|
+
<img src="docs/migration.en.png" width="24%" alt="Migration theme" />
|
|
186
|
+
<img src="docs/catppuccin.en.png" width="24%" alt="Catppuccin theme" />
|
|
187
|
+
<img src="docs/sketchbook.en.png" width="24%" alt="Sketchbook theme" />
|
|
188
|
+
<img src="docs/heart_monitor.en.png" width="24%" alt="Heart Monitor theme" />
|
|
185
189
|
</p>
|
|
186
190
|
|
|
187
191
|
## Troubleshooting
|
|
@@ -215,14 +219,13 @@ If the menu bar shows `--`, it's usually not broken — there's just no local da
|
|
|
215
219
|
| AI Update Daily | ✅ | — | — |
|
|
216
220
|
| Progress Concierge & Token Saver | ✅ | — | — |
|
|
217
221
|
| Token-waste Health Check | ✅ | — | — |
|
|
218
|
-
| No LLM API calls to read quota | ✅ | ✅ | ✅ |
|
|
219
222
|
| Open-source license | AGPL-3.0 | MIT | — |
|
|
220
223
|
|
|
221
224
|
## When usage Isn't the Right Fit
|
|
222
225
|
|
|
223
226
|
- You only live in the terminal and don't want another menu bar icon running in the background — a one-off CLI check fits better.
|
|
224
|
-
- You don't use Claude Code, Codex, or
|
|
225
|
-
- You
|
|
227
|
+
- You don't use Claude Code, Codex, Antigravity, or Grok CLI — there's no local usage data for `usage` to read.
|
|
228
|
+
- You want a menu bar on Linux. Only macOS and Windows have one today, though the terminal interface (`uvx usage-cli`) runs on Linux.
|
|
226
229
|
|
|
227
230
|
## Development
|
|
228
231
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
# usage
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Your Claude Code, Codex, Antigravity and Grok CLI quota, always on screen.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
`usage` puts your 5-hour and weekly limits in the macOS menu bar or Windows system tray, colored from green to red. Hitting the limit halfway through a long refactor is a bad way to find out you were running low. Now you see it coming. There's nothing to run and no page to open.
|
|
10
10
|
|
|
11
11
|
[繁體中文](docs/README.zh-TW.md) · [简体中文](docs/README.zh-CN.md) · English · [日本語](docs/README.ja.md) · [한국어](docs/README.ko.md) | [Discussions](https://github.com/aqua5230/usage/discussions) | [Landing page](https://aqua5230.github.io/usage/)
|
|
12
12
|
|
|
@@ -23,7 +23,9 @@ Running out of quota mid-session is expensive — especially during a long refac
|
|
|
23
23
|
<img src="docs/showcase-v3.en.png" alt="usage — Claude Code, Codex, and Antigravity quota pinned to the macOS menu bar" width="820">
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
|
-
Claude Code and Codex numbers
|
|
26
|
+
Claude Code and Codex numbers come from log files already on your machine. Antigravity quota comes from Google's official quota endpoint, using the sign-in the Antigravity CLI already stores locally.
|
|
27
|
+
|
|
28
|
+
`usage` also helps you spend less. The status line warns you before your context window bloats or your prompt cache goes cold, and a Token Saver toggle keeps replies short. In an A/B test on real sessions, late replies stayed ~40% shorter instead of growing 84% longer.
|
|
27
29
|
|
|
28
30
|
## Quick Start
|
|
29
31
|
|
|
@@ -31,10 +33,10 @@ Claude Code and Codex numbers are read passively from log files already on your
|
|
|
31
33
|
brew install --cask aqua5230/usage/usage
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
**Not on macOS?** `uvx usage-cli` runs the terminal interface anywhere, Linux included — no install, no menu bar.
|
|
35
|
-
|
|
36
36
|
It lands in your Applications folder automatically. Open it once; if macOS 15 or later blocks it, go to System Settings → Privacy & Security, scroll down, and click **Open Anyway**. On macOS 14 or earlier, right-click **Open** once to pass Gatekeeper. Then click the menu bar icon. Prefer a direct download or want the full setup flow? See [Install](#install) below.
|
|
37
37
|
|
|
38
|
+
**Not on macOS?** `uvx usage-cli` runs the terminal interface anywhere, Linux included — no install, no menu bar.
|
|
39
|
+
|
|
38
40
|
**Jump to:** [What You Get](#what-you-get) · [Privacy](#privacy--data-sources) · [Requirements](#requirements) · [Install](#install) · [Status Line](#first-launch-set-up-the-status-line) · [Windows](#windows-support) · [Themes](#theme-gallery) · [Troubleshooting](#troubleshooting) · [Comparison](#comparison) · [Not a Fit?](#when-usage-isnt-the-right-fit) · [Development](#development)
|
|
39
41
|
|
|
40
42
|
## What You Get
|
|
@@ -43,21 +45,22 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
43
45
|
|
|
44
46
|
- **Always-on Monitor:** Your quota lives in the menu bar, color-coded from green to red. Click when you want the full session, weekly, and per-project breakdown.
|
|
45
47
|
- **Antigravity Support:** Antigravity (Gemini) session and weekly quota show up as a third card in every theme except World Cup 2026, which stays a two-team HUD. Numbers come straight from the official quota API, using the sign-in the Antigravity CLI already keeps on your machine — refreshed every few minutes, with live reset countdowns. Antigravity keeps two separate quota pools: the card shows Gemini by default, and tapping the `Gemini ⇄` tag next to the title switches it to Claude / GPT — the choice is remembered.
|
|
46
|
-
- **Grok CLI Support:** A fourth card reads Grok CLI's weekly credit percentage straight from its own local debug log
|
|
48
|
+
- **Grok CLI Support:** A fourth card reads Grok CLI's weekly credit percentage straight from its own local debug log. Grok CLI doesn't expose session or burn-rate data, so the card shows a single weekly bar; its per-request token usage still counts toward today's cost and project totals like Claude Code and Codex.
|
|
47
49
|
- **Muse Code Spending:** Muse Code's per-request tokens and cost count toward today's cost, project totals, the HTML report, and the `usage` CLI, read from its own local session logs. Muse keeps no local quota data, so there is no Muse quota card.
|
|
48
|
-
- **Service Status Alerts:** An orange-red banner appears when Claude Code, Claude API, or Codex API has an outage or degraded performance, read from their public Statuspage.io pages
|
|
50
|
+
- **Service Status Alerts:** An orange-red banner appears when Claude Code, Claude API, or Codex API has an outage or degraded performance, read from their public Statuspage.io pages. Antigravity isn't covered; it has no public status page.
|
|
49
51
|
- **Context Nudges & Notifications:** When your context window hits 70% — or earlier when it is filling fast — the status line nudges you to `/clear` or `/compact` to prevent token waste. You can also opt-in to system notifications for quota limits and recoveries.
|
|
50
52
|
- **Prompt Cache Health:** The status line shows Claude Code's prompt cache hit rate with a countdown to expiry, so you can tell at a glance whether finishing now still reuses the cached context or lets it go cold and re-sends everything. Once it has gone cold, the countdown turns into how many tokens your next message will re-cache. Needs Claude Code 2.1.251 or newer; on older versions the segment simply doesn't appear.
|
|
51
53
|
- **Hide Sections:** Only use one or two of the tools? Hide the Claude Code, Codex, Grok CLI, or Antigravity section from the menu bar and panels completely with a single click.
|
|
52
54
|
|
|
53
55
|
### Workflow Helpers
|
|
54
56
|
|
|
55
|
-
- **Progress Concierge:** Open a new Claude Code session and `usage` hands your last progress straight to the AI, including your last request, uncommitted changes, and unfinished todos. No `/resume`, no recap. When you do `/resume` a conversation that sat long enough for its cache to expire, it warns you how many tokens the next message will re-send and suggests `/compact` first.
|
|
57
|
+
- **Progress Concierge:** Open a new Claude Code session and `usage` hands your last progress straight to the AI, including your last request, uncommitted changes, and unfinished todos. No `/resume`, no recap. When you do `/resume` a conversation that sat long enough for its cache to expire, it warns you how many tokens the next message will re-send and suggests `/compact` first. Off by default.
|
|
56
58
|
- **Token Saver:** A menu-bar toggle asks Claude Code and Codex to answer more tersely and in plainer language, saving output tokens while keeping code and error messages byte-exact. A light reminder keeps long conversations from drifting back to verbose — in an A/B test on real sessions, late replies stayed ~40% shorter instead of drifting 84% longer.
|
|
57
|
-
- **
|
|
59
|
+
- **Auto-start 5-hour Session:** Off by default. Turn it on and, right after a 5-hour quota resets, `usage` sends one tiny message to each tool (Claude with Haiku, Antigravity with Gemini 3.5 Flash Low, Codex with its cheapest model) so the next 5-hour window starts counting right away. Those messages do use a little quota, but the amount is negligible. Checking your quota never sends a message; only this switch does.
|
|
60
|
+
- **Terminal Integration:** `usage status --json` hands your Claude Code and Codex quota to any tool that can run a command — Starship, tmux, or your own scripts. Reads the same local files as the menu bar. [Ready-made snippets](docs/DEVELOPMENT.md#quota-status-for-other-tools-usage-status).
|
|
58
61
|
- **Token-waste Health Check:** A daily background diagnosis scans your logs for waste, including repeated file reads, polluter directories, and noisy Bash output. If it finds issues, a one-line heads-up appears; say "show me" and the AI walks you through fixes.
|
|
59
62
|
|
|
60
|
-
###
|
|
63
|
+
### Stay Current
|
|
61
64
|
|
|
62
65
|
- **AI Update Daily:** Opens a daily-updated public [page](https://aqua5230.github.io/ai-updates/) covering Claude Code, Codex, and Antigravity, with the full history kept. Reviewed items get a plain-language summary in all five UI languages; unreviewed ones show the original source text.
|
|
63
66
|
|
|
@@ -68,20 +71,20 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
68
71
|
### Experience & Customization
|
|
69
72
|
|
|
70
73
|
- **16 Visual Themes:** Switch between panel styles including Default, Matrix, Windows 95, Vintage Newspaper, Cloud Observation, Midnight Aquarium, Prism Arcade, Black Hole, World Cup 2026, Lepidoptera, Migration, Stained Glass, Origami, Sketchbook, Heart Monitor, and Catppuccin (official palette, all four flavors).
|
|
71
|
-
- **Place the Panel Anywhere:**
|
|
74
|
+
- **Place the Panel Anywhere:** Drag the panel from any empty spot to wherever you want it, and it reopens there next time. It stays put when another app takes focus — a second click on the menu bar icon, or Escape, closes it.
|
|
72
75
|
- **Drag to Reorder:** Grab any quota card and drag it up or down to swap the order — the arrangement is shared across every theme with quota cards (all except World Cup 2026) and survives restarts.
|
|
73
76
|
- **Automatic Localization:** UI text is available in Traditional Chinese, Simplified Chinese, English, Japanese, and Korean, automatically matching your system settings.
|
|
74
77
|
|
|
75
78
|
## Privacy & Data Sources
|
|
76
79
|
|
|
77
|
-
- Claude Code and Codex numbers are read
|
|
78
|
-
- Antigravity quota requires network access, and only if you use it: quota is fetched from Google's official quota endpoint using the OAuth credential the Antigravity CLI already stored after sign-in — read from macOS Keychain, Windows Credential Manager, or a local token file depending on CLI version. `usage` reads that credential without writing it back and keeps any refreshed access token in memory only; the call itself
|
|
80
|
+
- Claude Code and Codex numbers are read from local log files on your machine.
|
|
81
|
+
- Antigravity quota requires network access, and only if you use it: quota is fetched from Google's official quota endpoint using the OAuth credential the Antigravity CLI already stored after sign-in — read from macOS Keychain, Windows Credential Manager, or a local token file depending on CLI version. `usage` reads that credential without writing it back and keeps any refreshed access token in memory only; the call itself reads quota metadata.
|
|
79
82
|
- Background network activity: the Antigravity quota/token endpoints above, public Claude and Codex status pages to flag outages, a public model-pricing table to estimate cost (falls back to built-in prices offline), and occasionally checking GitHub for a new version. Claude Code and Codex log contents are never uploaded.
|
|
80
83
|
|
|
81
84
|
## Requirements
|
|
82
85
|
|
|
83
86
|
- macOS 12 (Monterey) or newer, or Windows 10/11
|
|
84
|
-
- Claude Code, Codex, or
|
|
87
|
+
- Claude Code, Codex, Antigravity, or Grok CLI has been used at least once (so local usage data exists).
|
|
85
88
|
- (Source runs only) Python 3.13.
|
|
86
89
|
|
|
87
90
|
## Install
|
|
@@ -147,21 +150,22 @@ Privacy policy: this program will not transfer any information to other networke
|
|
|
147
150
|
Switch between **16 visual themes** directly from the UI:
|
|
148
151
|
|
|
149
152
|
<p align="center">
|
|
150
|
-
<img src="docs/classic.en.png" width="
|
|
151
|
-
<img src="docs/matrix.en.png" width="
|
|
152
|
-
<img src="docs/win95.en.png" width="
|
|
153
|
-
<img src="docs/newspaper.en.png" width="
|
|
154
|
-
<img src="docs/cloud_observation.en.png" width="
|
|
155
|
-
<img src="docs/aquarium.en.png" width="
|
|
156
|
-
<img src="docs/prism_arcade.en.png" width="
|
|
157
|
-
<img src="docs/stained_glass.en.png" width="
|
|
158
|
-
<img src="docs/origami.en.png" width="
|
|
159
|
-
<img src="docs/black_hole.en.png" width="
|
|
160
|
-
<img src="docs/
|
|
161
|
-
<img src="docs/
|
|
162
|
-
<img src="docs/
|
|
163
|
-
<img src="docs/
|
|
164
|
-
<img src="docs/
|
|
153
|
+
<img src="docs/classic.en.png" width="24%" alt="Classic theme" />
|
|
154
|
+
<img src="docs/matrix.en.png" width="24%" alt="Matrix theme" />
|
|
155
|
+
<img src="docs/win95.en.png" width="24%" alt="Windows 95 theme" />
|
|
156
|
+
<img src="docs/newspaper.en.png" width="24%" alt="Newspaper theme" />
|
|
157
|
+
<img src="docs/cloud_observation.en.png" width="24%" alt="Cloud Observation theme" />
|
|
158
|
+
<img src="docs/aquarium.en.png" width="24%" alt="Midnight Aquarium theme" />
|
|
159
|
+
<img src="docs/prism_arcade.en.png" width="24%" alt="Prism Arcade theme" />
|
|
160
|
+
<img src="docs/stained_glass.en.png" width="24%" alt="Stained Glass theme" />
|
|
161
|
+
<img src="docs/origami.en.png" width="24%" alt="Origami theme" />
|
|
162
|
+
<img src="docs/black_hole.en.png" width="24%" alt="Black Hole theme" />
|
|
163
|
+
<img src="docs/world_cup.en.png" width="24%" alt="World Cup 2026 theme" />
|
|
164
|
+
<img src="docs/lepidoptera.en.png" width="24%" alt="Lepidoptera theme" />
|
|
165
|
+
<img src="docs/migration.en.png" width="24%" alt="Migration theme" />
|
|
166
|
+
<img src="docs/catppuccin.en.png" width="24%" alt="Catppuccin theme" />
|
|
167
|
+
<img src="docs/sketchbook.en.png" width="24%" alt="Sketchbook theme" />
|
|
168
|
+
<img src="docs/heart_monitor.en.png" width="24%" alt="Heart Monitor theme" />
|
|
165
169
|
</p>
|
|
166
170
|
|
|
167
171
|
## Troubleshooting
|
|
@@ -195,14 +199,13 @@ If the menu bar shows `--`, it's usually not broken — there's just no local da
|
|
|
195
199
|
| AI Update Daily | ✅ | — | — |
|
|
196
200
|
| Progress Concierge & Token Saver | ✅ | — | — |
|
|
197
201
|
| Token-waste Health Check | ✅ | — | — |
|
|
198
|
-
| No LLM API calls to read quota | ✅ | ✅ | ✅ |
|
|
199
202
|
| Open-source license | AGPL-3.0 | MIT | — |
|
|
200
203
|
|
|
201
204
|
## When usage Isn't the Right Fit
|
|
202
205
|
|
|
203
206
|
- You only live in the terminal and don't want another menu bar icon running in the background — a one-off CLI check fits better.
|
|
204
|
-
- You don't use Claude Code, Codex, or
|
|
205
|
-
- You
|
|
207
|
+
- You don't use Claude Code, Codex, Antigravity, or Grok CLI — there's no local usage data for `usage` to read.
|
|
208
|
+
- You want a menu bar on Linux. Only macOS and Windows have one today, though the terminal interface (`uvx usage-cli`) runs on Linux.
|
|
206
209
|
|
|
207
210
|
## Development
|
|
208
211
|
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"grok_stale_tooltip": "資料來自 Grok CLI 本機 log,不是即時 API;請最近執行過 grok 指令後再查看,才會更新。",
|
|
105
105
|
"codex_stale_minutes": "約 {minutes} 分鐘前",
|
|
106
106
|
"codex_stale_hours": "約 {hours} 小時前",
|
|
107
|
-
"codex_stale_tooltip": "Claude 有即時回報所以很準;Codex 沒有,usage
|
|
107
|
+
"codex_stale_tooltip": "Claude 有即時回報所以很準;Codex 沒有,usage 會讀它本機偶爾留下的紀錄,可能比實際略舊。繼續在終端機跑 Codex 就會自動更新。",
|
|
108
108
|
"history_load_error_file": "讀不到使用紀錄檔",
|
|
109
109
|
"history_load_error_parse": "使用紀錄格式異常",
|
|
110
110
|
"history_load_error_unknown": "使用紀錄暫時無法讀取",
|
|
@@ -532,7 +532,7 @@
|
|
|
532
532
|
"grok_stale_tooltip": "Data comes from Grok CLI's local log, not a live API. Run a grok command recently for it to update.",
|
|
533
533
|
"codex_stale_minutes": "about {minutes} minutes ago",
|
|
534
534
|
"codex_stale_hours": "about {hours} hours ago",
|
|
535
|
-
"codex_stale_tooltip": "Claude is accurate because it reports in real time; Codex does not, so usage
|
|
535
|
+
"codex_stale_tooltip": "Claude is accurate because it reports in real time; Codex does not, so usage reads the local records it leaves occasionally, which may be slightly older than reality. Keep running Codex in the terminal and it will update automatically.",
|
|
536
536
|
"history_load_error_file": "Couldn't read usage files",
|
|
537
537
|
"history_load_error_parse": "Usage data format issue",
|
|
538
538
|
"history_load_error_unknown": "Usage data temporarily unavailable",
|
|
@@ -960,7 +960,7 @@
|
|
|
960
960
|
"grok_stale_tooltip": "资料来自 Grok CLI 本地日志,不是即时 API;请最近运行过 grok 指令后再查看,才会更新。",
|
|
961
961
|
"codex_stale_minutes": "约 {minutes} 分钟前",
|
|
962
962
|
"codex_stale_hours": "约 {hours} 小时前",
|
|
963
|
-
"codex_stale_tooltip": "Claude 有实时回报所以很准;Codex 没有,usage
|
|
963
|
+
"codex_stale_tooltip": "Claude 有实时回报所以很准;Codex 没有,usage 会读取它本机偶尔留下的记录,可能比实际略旧。继续在终端运行 Codex 就会自动更新。",
|
|
964
964
|
"history_load_error_file": "读不到使用记录文件",
|
|
965
965
|
"history_load_error_parse": "使用记录格式异常",
|
|
966
966
|
"history_load_error_unknown": "使用记录暂时无法读取",
|
|
@@ -1388,7 +1388,7 @@
|
|
|
1388
1388
|
"grok_stale_tooltip": "データは Grok CLI のローカルログから読み取るもので、リアルタイム API ではありません。更新するには最近 grok コマンドを実行してください。",
|
|
1389
1389
|
"codex_stale_minutes": "約 {minutes} 分前",
|
|
1390
1390
|
"codex_stale_hours": "約 {hours} 時間前",
|
|
1391
|
-
"codex_stale_tooltip": "Claude はリアルタイムに報告するので正確です。Codex にはそれがないため、usage は Codex
|
|
1391
|
+
"codex_stale_tooltip": "Claude はリアルタイムに報告するので正確です。Codex にはそれがないため、usage は Codex がローカルに時々残す記録を読み取り、実際より少し古い場合があります。ターミナルで Codex を使い続けると自動的に更新されます。",
|
|
1392
1392
|
"history_load_error_file": "使用履歴ファイルを読み込めません",
|
|
1393
1393
|
"history_load_error_parse": "使用履歴データの形式に問題があります",
|
|
1394
1394
|
"history_load_error_unknown": "使用履歴データを一時的に取得できません",
|
|
@@ -1816,7 +1816,7 @@
|
|
|
1816
1816
|
"grok_stale_tooltip": "데이터는 Grok CLI의 로컬 로그에서 읽으며 실시간 API가 아닙니다. 업데이트하려면 최근에 grok 명령을 실행하세요.",
|
|
1817
1817
|
"codex_stale_minutes": "약 {minutes}분 전",
|
|
1818
1818
|
"codex_stale_hours": "약 {hours}시간 전",
|
|
1819
|
-
"codex_stale_tooltip": "Claude는 실시간으로 보고하므로 정확합니다. Codex는 그렇지 않아 usage가 Codex가 로컬에 가끔 남기는
|
|
1819
|
+
"codex_stale_tooltip": "Claude는 실시간으로 보고하므로 정확합니다. Codex는 그렇지 않아 usage가 Codex가 로컬에 가끔 남기는 기록을 읽으며, 실제보다 조금 오래된 값일 수 있습니다. 터미널에서 Codex를 계속 실행하면 자동으로 업데이트됩니다.",
|
|
1820
1820
|
"history_load_error_file": "사용 기록 파일을 읽을 수 없습니다",
|
|
1821
1821
|
"history_load_error_parse": "사용 기록 형식에 문제가 있습니다",
|
|
1822
1822
|
"history_load_error_unknown": "사용 기록을 일시적으로 불러올 수 없습니다",
|
|
@@ -86,7 +86,7 @@ PREV_SL_KEY = "previousStatusLine"
|
|
|
86
86
|
# Where the status-line switch parks the live statusLine while it is off, so it
|
|
87
87
|
# never overwrites the pre-install backup under PREV_SL_KEY.
|
|
88
88
|
DISABLED_SL_KEY = "disabledStatusLine"
|
|
89
|
-
HOOK_VERSION = "1.
|
|
89
|
+
HOOK_VERSION = "1.8"
|
|
90
90
|
FORWARDER_VERSION = "1.1"
|
|
91
91
|
# Antigravity's Go runner hands its status-line command to cmd.exe unquoted, so
|
|
92
92
|
# every character cmd.exe treats specially has to be kept out of the path.
|
|
@@ -527,6 +527,12 @@ def _fallback_pricing() -> PricingTable:
|
|
|
527
527
|
"cache_creation_input_token_cost": 2.5e-6,
|
|
528
528
|
"cache_read_input_token_cost": 0.2e-6,
|
|
529
529
|
},
|
|
530
|
+
"gpt-6.1-sol": {
|
|
531
|
+
"input_cost_per_token": 2e-6,
|
|
532
|
+
"output_cost_per_token": 10e-6,
|
|
533
|
+
"cache_creation_input_token_cost": 2.5e-6,
|
|
534
|
+
"cache_read_input_token_cost": 0.1e-6,
|
|
535
|
+
},
|
|
530
536
|
"gpt-6-luna": {
|
|
531
537
|
"input_cost_per_token": 0.1e-6,
|
|
532
538
|
"output_cost_per_token": 0.5e-6,
|
|
@@ -697,7 +697,7 @@ def test_render_outputs_multiline_colored_statusline(
|
|
|
697
697
|
assert "$" not in output # cost line removed in v0.10.0
|
|
698
698
|
|
|
699
699
|
|
|
700
|
-
def
|
|
700
|
+
def test_render_shows_prompt_cache_hit_without_countdown(
|
|
701
701
|
monkeypatch: pytest.MonkeyPatch,
|
|
702
702
|
) -> None:
|
|
703
703
|
monkeypatch.setenv("TT_LANG", "zh_TW")
|
|
@@ -708,10 +708,8 @@ def test_render_shows_prompt_cache_hit_with_countdown(
|
|
|
708
708
|
"cost": {"total_duration_ms": 720000},
|
|
709
709
|
"prompt_cache": {
|
|
710
710
|
"caching_observed": True,
|
|
711
|
-
"warm": True,
|
|
712
711
|
"hit_ratio": 0.9072975151245158,
|
|
713
712
|
"expires_at": now.timestamp() + 43 * 60,
|
|
714
|
-
"recache_tokens_if_cold": 180_000,
|
|
715
713
|
},
|
|
716
714
|
}
|
|
717
715
|
|
|
@@ -720,90 +718,10 @@ def test_render_shows_prompt_cache_hit_with_countdown(
|
|
|
720
718
|
line3 = output.splitlines()[0]
|
|
721
719
|
assert "快取:" in line3
|
|
722
720
|
assert "91%" in line3
|
|
723
|
-
assert "
|
|
724
|
-
assert "已冷" not in line3
|
|
721
|
+
assert "43min" not in line3
|
|
725
722
|
assert "\033[2m\033[38;5;111m" in line3
|
|
726
723
|
|
|
727
724
|
|
|
728
|
-
@pytest.mark.parametrize(
|
|
729
|
-
("lang", "warm", "expires_offset", "expected"),
|
|
730
|
-
[
|
|
731
|
-
("zh-TW", False, -1, "已冷·下輪重寫 180k"),
|
|
732
|
-
("en", False, -1, "cold·re-cache 180k"),
|
|
733
|
-
("zh-TW", None, -1, "已冷·下輪重寫 180k"),
|
|
734
|
-
("zh-TW", True, 0, "已冷·下輪重寫 180k"),
|
|
735
|
-
("zh-TW", False, 60, "已冷·下輪重寫 180k"),
|
|
736
|
-
],
|
|
737
|
-
)
|
|
738
|
-
def test_render_shows_recache_tokens_when_prompt_cache_is_cold(
|
|
739
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
740
|
-
lang: str,
|
|
741
|
-
warm: bool | None,
|
|
742
|
-
expires_offset: int,
|
|
743
|
-
expected: str,
|
|
744
|
-
) -> None:
|
|
745
|
-
monkeypatch.setenv("USAGE_LANG", lang)
|
|
746
|
-
monkeypatch.setattr(usage_statusline, "get_width", lambda: 116)
|
|
747
|
-
now = datetime(2026, 1, 1, 12, 0, tzinfo=UTC)
|
|
748
|
-
prompt_cache: dict[str, object] = {
|
|
749
|
-
"caching_observed": True,
|
|
750
|
-
"hit_ratio": 0.9,
|
|
751
|
-
"expires_at": now.timestamp() + expires_offset,
|
|
752
|
-
"recache_tokens_if_cold": 180_000,
|
|
753
|
-
}
|
|
754
|
-
if warm is not None:
|
|
755
|
-
prompt_cache["warm"] = warm
|
|
756
|
-
|
|
757
|
-
output = usage_statusline.render({"prompt_cache": prompt_cache}, now)
|
|
758
|
-
|
|
759
|
-
assert "90%" in output
|
|
760
|
-
assert f" ({expected})" in output
|
|
761
|
-
assert "剩" not in output
|
|
762
|
-
assert "left" not in output
|
|
763
|
-
assert f"{usage_statusline.C['dim']}{usage_statusline.C['magenta']} ({expected})" in output
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
@pytest.mark.parametrize("recache_tokens", [None, 0, True, "180000"])
|
|
767
|
-
def test_render_omits_recache_text_for_invalid_token_counts(
|
|
768
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
769
|
-
recache_tokens: object,
|
|
770
|
-
) -> None:
|
|
771
|
-
monkeypatch.setenv("USAGE_LANG", "zh-TW")
|
|
772
|
-
monkeypatch.setattr(usage_statusline, "get_width", lambda: 116)
|
|
773
|
-
now = datetime(2026, 1, 1, 12, 0, tzinfo=UTC)
|
|
774
|
-
output = usage_statusline.render(
|
|
775
|
-
{
|
|
776
|
-
"prompt_cache": {
|
|
777
|
-
"caching_observed": True,
|
|
778
|
-
"warm": False,
|
|
779
|
-
"hit_ratio": 0.9,
|
|
780
|
-
"expires_at": now.timestamp() - 1,
|
|
781
|
-
"recache_tokens_if_cold": recache_tokens,
|
|
782
|
-
}
|
|
783
|
-
},
|
|
784
|
-
now,
|
|
785
|
-
)
|
|
786
|
-
|
|
787
|
-
assert "快取:" in output
|
|
788
|
-
assert "(" not in output
|
|
789
|
-
assert "已冷" not in output
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
def test_render_omits_recache_text_when_token_count_is_missing(
|
|
793
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
794
|
-
) -> None:
|
|
795
|
-
monkeypatch.setenv("USAGE_LANG", "zh-TW")
|
|
796
|
-
monkeypatch.setattr(usage_statusline, "get_width", lambda: 116)
|
|
797
|
-
now = datetime(2026, 1, 1, 12, 0, tzinfo=UTC)
|
|
798
|
-
output = usage_statusline.render(
|
|
799
|
-
{"prompt_cache": {"caching_observed": True, "warm": False, "hit_ratio": 0.9}},
|
|
800
|
-
now,
|
|
801
|
-
)
|
|
802
|
-
|
|
803
|
-
assert "快取:" in output
|
|
804
|
-
assert "(" not in output
|
|
805
|
-
|
|
806
|
-
|
|
807
725
|
@pytest.mark.parametrize(
|
|
808
726
|
"prompt_cache",
|
|
809
727
|
(None, {"caching_observed": False, "hit_ratio": 0.91}),
|
|
@@ -893,12 +811,12 @@ def test_render_prompt_cache_degrades_for_narrow_widths(
|
|
|
893
811
|
}
|
|
894
812
|
|
|
895
813
|
monkeypatch.setattr(usage_statusline, "get_width", lambda: 29)
|
|
896
|
-
|
|
897
|
-
assert "Session:" not in
|
|
898
|
-
assert "Cache:" in
|
|
899
|
-
assert "43min" not in
|
|
814
|
+
pct_only = usage_statusline.render(payload, now)
|
|
815
|
+
assert "Session:" not in pct_only
|
|
816
|
+
assert "Cache:" in pct_only
|
|
817
|
+
assert "43min" not in pct_only
|
|
900
818
|
|
|
901
|
-
monkeypatch.setattr(usage_statusline, "get_width", lambda:
|
|
819
|
+
monkeypatch.setattr(usage_statusline, "get_width", lambda: 17)
|
|
902
820
|
without_cache = usage_statusline.render(payload, now)
|
|
903
821
|
assert "Session:" not in without_cache
|
|
904
822
|
assert "Cache:" not in without_cache
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import json
|
|
10
|
+
import os
|
|
10
11
|
import re
|
|
11
12
|
import tomllib
|
|
12
13
|
from pathlib import Path
|
|
@@ -71,6 +72,11 @@ def _visible(value: str) -> str:
|
|
|
71
72
|
return _ANSI.sub("", value)
|
|
72
73
|
|
|
73
74
|
|
|
75
|
+
def test_progress_bar_chars_are_platform_specific() -> None:
|
|
76
|
+
assert usage_statusline_grok._progress_bar_chars("nt") == ("█", "░")
|
|
77
|
+
assert usage_statusline_grok._progress_bar_chars("posix") == ("■", "□")
|
|
78
|
+
|
|
79
|
+
|
|
74
80
|
def test_render_fixture_contains_expected_status(
|
|
75
81
|
monkeypatch: pytest.MonkeyPatch,
|
|
76
82
|
tmp_path: Path,
|
|
@@ -82,11 +88,12 @@ def test_render_fixture_contains_expected_status(
|
|
|
82
88
|
monkeypatch.setenv("COLUMNS", "300")
|
|
83
89
|
|
|
84
90
|
output = _visible(usage_statusline_grok.render(_fixture_data()))
|
|
91
|
+
filled, empty = usage_statusline_grok._progress_bar_chars(os.name)
|
|
85
92
|
|
|
86
93
|
assert "project(main)" in output
|
|
87
|
-
assert "
|
|
94
|
+
assert f"週配額:{filled * 3}{empty * 5} 42%" in output
|
|
88
95
|
assert re.search(r"\(剩[0-9]+d[0-9]+h\)", output)
|
|
89
|
-
assert "
|
|
96
|
+
assert f"對話窗:{filled}{empty * 7} 8% / 2.0M" in output
|
|
90
97
|
assert "會話時長:20min" in output
|
|
91
98
|
assert "Grok 4.6/深思" in output
|
|
92
99
|
assert output.count("\n") == 1
|
|
@@ -160,7 +167,8 @@ def test_render_degrades_for_narrow_terminal(
|
|
|
160
167
|
assert "Weekly:42%" in first_line
|
|
161
168
|
assert "Context:8%" in first_line
|
|
162
169
|
assert "left" not in first_line
|
|
163
|
-
|
|
170
|
+
filled, _empty = usage_statusline_grok._progress_bar_chars(os.name)
|
|
171
|
+
assert filled not in first_line
|
|
164
172
|
|
|
165
173
|
|
|
166
174
|
def _patch_grok_paths(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> tuple[Path, Path, Path]:
|
|
@@ -377,5 +385,6 @@ def test_render_shows_zero_quota_when_percent_is_omitted(
|
|
|
377
385
|
monkeypatch.setenv("COLUMNS", "300")
|
|
378
386
|
|
|
379
387
|
output = _visible(usage_statusline_grok.render(_fixture_data()))
|
|
388
|
+
_filled, empty = usage_statusline_grok._progress_bar_chars(os.name)
|
|
380
389
|
|
|
381
|
-
assert "
|
|
390
|
+
assert f"週配額:{empty * 8} 0%" in output
|