usage-cli 0.34.4__tar.gz → 0.34.5__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.34.4/usage_cli.egg-info → usage_cli-0.34.5}/PKG-INFO +1 -1
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/muse_quota_probe.py +28 -1
- {usage_cli-0.34.4 → usage_cli-0.34.5}/pyproject.toml +1 -1
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_muse_quota_probe.py +30 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5/usage_cli.egg-info}/PKG-INFO +1 -1
- {usage_cli-0.34.4 → usage_cli-0.34.5}/LICENSE +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/README.md +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/THIRD_PARTY_NOTICES.md +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/agy.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/claude.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/codex.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/grok.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/muse.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/rate_limits.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/registry.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/adapters/types.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/aggregator.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/blocks.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/diagnoser.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/diagnosis_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/dispatch_ledger.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/history_persist.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/insights.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/ledger_backfill.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/persona_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/reporter.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/subscription.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/analyzer/usage_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/i18n.json +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/claude_pane.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/codex_hook_trust.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/login_item.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/session_hooks.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/setup_hook.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/installer/statusline_settings.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/_shared_cache_file.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/agy_disk_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/agy_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/agy_quota_probe.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/cache_quarantine.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/chromium_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/claude_desktop.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/claude_paths.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/claude_usage.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/codex_disk_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/codex_events.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/codex_fork_replay.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/codex_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/codex_paths.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/disk_cache_common.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/disk_cache_lifecycle.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/grok_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/grok_quota_probe.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/history_disk_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/history_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/jsonl_limits.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/jsonl_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/loaders/muse_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/main.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/actions.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/agy.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/app.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/chrome.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/fsevents_watch.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/grok.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/manual_refresh.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/menu.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/muse.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/new_badge.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/notify.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/popover.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/prefs.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/refresh.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/state.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/title.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/update.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/menubar/whats_new.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/base.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/catalog.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/dynamic_height.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/panel_scale.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/panel_window.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/panel_window_state.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/payload.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/web_panel.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/panels/window_drag.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/agy_window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/burn_rate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/codex_window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/keeper_outcome.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/notifications.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/quota_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/status_payload.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/usage_rate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/quota/window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/setup.cfg +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/setup_app.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_adapters_claude.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_adapters_codex.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_adapters_rate_limits.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_aggregator.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_agy_adapter.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_agy_disk_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_agy_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_agy_quota_probe.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_agy_window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_analyzer_blocks.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_analyzer_pipeline.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_app_version.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_burn_rate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_cache_quarantine.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_check_upstream.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_chromium_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_claude_desktop.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_claude_pane.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_claude_paths.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_codex_consistency.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_codex_hook_trust.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_codex_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_codex_window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_compact_cards.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_desktop_fresh_cache.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_desktop_quota_display.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_desktop_quota_review.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_diagnoser.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_disk_cache_shards.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_dispatch_ledger.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_doctor.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_dynamic_height.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_fsevents_watch.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_grok_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_grok_quota_probe.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_history_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_history_persist.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_hook_scripts_are_standalone.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_html_report_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_i18n_format_fallback.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_i18n_key_parity.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_i18n_packaged_path.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_insights.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_jsonl_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_keeper_menu.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_keeper_outcome.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_ledger_backfill.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_login_item.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_main.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_manual_refresh.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_agy.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_grok.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_muse.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_notify.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_prefs.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_state.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_menubar_update.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_muse_coverage.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_muse_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_muse_review_regressions.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_new_badge.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_packaged_resources.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_packaging.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_panel_footer_layout.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_panel_scale.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_panel_window_state.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_panels.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_panels_lazy_import.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_persona_loader.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_pricing.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_project_resolver.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_quota_aware.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_quota_label.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_report_cold_read.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_report_daily_chart.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_report_filter_js.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_report_share_mask.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_reporter_build_data.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_service_status.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_session_resume.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_setup_app.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_setup_hook.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_setup_hook_coexistence.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_setup_hook_resume.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_setup_hook_terse.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_subprocess_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_subscription.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_taskbar_menu.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_taskbar_obstacles.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_time_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_tui.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_tui_sprite.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_ui_tables.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_update_checker.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_update_gate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_update_release_notes.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_cli.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_client.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_diagnosis_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_dir_sweeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_lang.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_logging.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_notifications.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_rate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_snapshot.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_snapshot_replay.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_statusline.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_statusline_agy.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_statusline_forwarder.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_statusline_grok.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_terse_mode.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_usage_terse_reminder.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_web_panel_payload.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_whats_new.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_wheel_packaging.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_win_login_item.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_window_keeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_windows_manifest.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tests/test_wintray.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tui/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tui/app.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/tui/sprite.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/html_report.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_charts.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_daily_chart.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_filter.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_ledger.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_scripts.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/report_styles.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/ui/tables.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/updates/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/updates/checker.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/updates/gate.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/updates/release_notes.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/updates/whats_new.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_app/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_app/cli.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_app/doctor.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_cli.egg-info/SOURCES.txt +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_cli.egg-info/dependency_links.txt +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_cli.egg-info/entry_points.txt +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_cli.egg-info/requires.txt +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_cli.egg-info/top_level.txt +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/app_version.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/i18n.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/prefs.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/pricing.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/project_resolver.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/service_status.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/subprocess_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/time_utils.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/usage_dir_sweeper.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/usage_lang.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_common/usage_logging.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_quota_aware.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_session_resume.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_statusline.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_statusline_agy.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_statusline_forwarder.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_statusline_grok.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_terse_mode.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/usage_hooks/usage_terse_reminder.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/__init__.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/app.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/login_item.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/menu.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/prefs.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/quota_label.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/taskbar_menu.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/taskbar_obstacles.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/taskbar_overlay.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/watch.py +0 -0
- {usage_cli-0.34.4 → usage_cli-0.34.5}/wintray/whats_new.py +0 -0
|
@@ -10,12 +10,14 @@ import json
|
|
|
10
10
|
import logging
|
|
11
11
|
import math
|
|
12
12
|
import os
|
|
13
|
+
import re
|
|
13
14
|
import shutil
|
|
14
15
|
import subprocess
|
|
15
16
|
import tempfile
|
|
16
17
|
import threading
|
|
17
18
|
import time
|
|
18
19
|
from contextlib import suppress
|
|
20
|
+
from datetime import datetime
|
|
19
21
|
from pathlib import Path
|
|
20
22
|
from typing import TypedDict, TypeGuard
|
|
21
23
|
|
|
@@ -27,6 +29,9 @@ CACHE_PATH = Path.home() / ".usage/muse_quota.json"
|
|
|
27
29
|
PROBE_DIR = Path.home() / ".usage/muse-probe"
|
|
28
30
|
MUSE_MODEL = "muse-spark-1.3"
|
|
29
31
|
STALE_SECONDS = 30 * 60
|
|
32
|
+
_EXHAUSTED = re.compile(
|
|
33
|
+
r"Subscription quota exhausted\. Your usage window resets at (\d{4}-\d\d-\d\dT[\d:.]+Z)"
|
|
34
|
+
)
|
|
30
35
|
_probe_lock = threading.Lock()
|
|
31
36
|
_probe_running = False
|
|
32
37
|
_retry_after = 0.0
|
|
@@ -109,6 +114,25 @@ def parse_muse_allowance(stdout: str, checked_at: float) -> MuseQuotaResult | No
|
|
|
109
114
|
return None
|
|
110
115
|
|
|
111
116
|
|
|
117
|
+
def parse_exhausted_window(stdout: str, cached: MuseQuotaResult | None) -> MuseQuotaResult | None:
|
|
118
|
+
"""Read the 429 Muse returns once the 5-hour window is used up; it carries no allowance.
|
|
119
|
+
|
|
120
|
+
Only the window's reset time is known, so the weekly reading and its age stay from ``cached``.
|
|
121
|
+
"""
|
|
122
|
+
match = _EXHAUSTED.search(stdout)
|
|
123
|
+
if cached is None or match is None:
|
|
124
|
+
return None
|
|
125
|
+
try:
|
|
126
|
+
reset = datetime.fromisoformat(match[1]).timestamp()
|
|
127
|
+
except ValueError:
|
|
128
|
+
return None
|
|
129
|
+
return MuseQuotaResult(
|
|
130
|
+
checked_at=cached["checked_at"],
|
|
131
|
+
window=MuseQuotaWindow(used_percent=100.0, resets_at=reset),
|
|
132
|
+
weekly=cached["weekly"],
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
112
136
|
def read_cache() -> MuseQuotaResult | None:
|
|
113
137
|
"""Ignore invalid shared snapshots without deleting or quarantining them."""
|
|
114
138
|
try:
|
|
@@ -214,7 +238,10 @@ def _probe_worker(executable: str) -> None:
|
|
|
214
238
|
process.kill()
|
|
215
239
|
process.communicate()
|
|
216
240
|
raise
|
|
217
|
-
|
|
241
|
+
if process.returncode == 0:
|
|
242
|
+
result = parse_muse_allowance(stdout, time.time())
|
|
243
|
+
else:
|
|
244
|
+
result = parse_exhausted_window(stdout, read_cache())
|
|
218
245
|
if result is not None:
|
|
219
246
|
_write_cache(result)
|
|
220
247
|
succeeded = True
|
|
@@ -75,6 +75,36 @@ def test_exhausted_window_past_100_is_kept(value: int) -> None:
|
|
|
75
75
|
assert result is not None and result["window"]["used_percent"] == value
|
|
76
76
|
|
|
77
77
|
|
|
78
|
+
# Captured from Muse Code 1.4.11 on 2026-10-21 while the 5-hour window was used up.
|
|
79
|
+
EXHAUSTED = json.dumps(
|
|
80
|
+
{
|
|
81
|
+
"payload_type": "run.terminal.failed",
|
|
82
|
+
"payload": {
|
|
83
|
+
"reason": "API error 429 [request_id=x]: Subscription quota exhausted. "
|
|
84
|
+
"Your usage window resets at 2026-10-21T08:28:56Z. (rate_limit_error)"
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
EXHAUSTED_QUOTA = {**quota(), "window": {"used_percent": 100.0, "resets_at": 1792571336.0}}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_exhausted_429_keeps_weekly_and_snapshot_age() -> None:
|
|
92
|
+
assert probe.parse_exhausted_window(EXHAUSTED, quota()) == EXHAUSTED_QUOTA
|
|
93
|
+
assert probe.parse_exhausted_window(EXHAUSTED, None) is None
|
|
94
|
+
assert probe.parse_exhausted_window(json.dumps(event()), quota()) is None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_exhausted_probe_updates_session_window(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
98
|
+
probe.CACHE_PATH.write_text(json.dumps(quota()))
|
|
99
|
+
process = Mock(returncode=1)
|
|
100
|
+
process.poll.return_value = 1
|
|
101
|
+
process.communicate.return_value = (EXHAUSTED, "")
|
|
102
|
+
monkeypatch.setattr(subprocess, "Popen", Mock(return_value=process))
|
|
103
|
+
probe._probe_worker("/fake/muse")
|
|
104
|
+
assert probe.read_cache() == EXHAUSTED_QUOTA
|
|
105
|
+
assert probe._retry_after == 0.0
|
|
106
|
+
|
|
107
|
+
|
|
78
108
|
def test_missing_weekly_is_rejected() -> None:
|
|
79
109
|
raw = event()
|
|
80
110
|
del raw["payload"]["allowance"]["weekly"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|