usage-cli 0.33.1__tar.gz → 0.33.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.
- {usage_cli-0.33.1 → usage_cli-0.33.2}/PKG-INFO +10 -7
- {usage_cli-0.33.1 → usage_cli-0.33.2}/README.md +9 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/agy.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/claude.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/grok.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/muse.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/rate_limits.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/aggregator.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/blocks.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/persona_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/reporter.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/usage_snapshot.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/i18n.json +0 -25
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/claude_pane.py +7 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/session_hooks.py +10 -10
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/setup_hook.py +8 -12
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/agy_loader.py +1 -1
- usage_cli-0.33.1/usage_client.py → usage_cli-0.33.2/loaders/claude_usage.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/codex_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/grok_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/history_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/muse_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/main.py +6 -112
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/actions.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/agy.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/app.py +7 -23
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/grok.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/manual_refresh.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/menu.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/new_badge.py +3 -3
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/notify.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/prefs.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/refresh.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/state.py +4 -4
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/update.py +5 -8
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/whats_new.py +1 -1
- usage_cli-0.33.2/panels/__init__.py +50 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/base.py +2 -2
- usage_cli-0.33.2/panels/catalog.py +225 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/payload.py +2 -23
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/web_panel.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/pyproject.toml +13 -32
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/agy_window_keeper.py +0 -5
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/codex_window_keeper.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/keeper_outcome.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/quota_snapshot.py +1 -1
- usage_cli-0.33.2/quota/status_payload.py +161 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/window_keeper.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/setup_app.py +9 -13
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_adapters_claude.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_agy_adapter.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_agy_window_keeper.py +2 -1
- usage_cli-0.33.2/tests/test_app_version.py +28 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_check_upstream.py +23 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_claude_pane.py +21 -9
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_claude_paths.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_desktop_quota_display.py +10 -8
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_desktop_quota_review.py +6 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_doctor.py +5 -5
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_fsevents_watch.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_history_loader.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_hook_scripts_are_standalone.py +1 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_i18n_format_fallback.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_i18n_packaged_path.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_main.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_manual_refresh.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar.py +9 -9
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_agy.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_grok.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_prefs.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_state.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_update.py +3 -7
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_muse_loader.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_new_badge.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_packaging.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_panels.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_persona_loader.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_pricing.py +14 -14
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_project_resolver.py +58 -17
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_quota_aware.py +4 -4
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_quota_label.py +2 -3
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_reporter_build_data.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_service_status.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_session_resume.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_setup_hook.py +10 -10
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_setup_hook_coexistence.py +2 -94
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_setup_hook_resume.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_setup_hook_terse.py +6 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_tui.py +6 -5
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_update_checker.py +8 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_cli.py +31 -31
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_client.py +17 -17
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_diagnosis_snapshot.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_notifications.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_statusline.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_statusline_agy.py +3 -3
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_statusline_forwarder.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_statusline_grok.py +2 -2
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_terse_mode.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_terse_reminder.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_web_panel_payload.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_wheel_packaging.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_wintray.py +65 -30
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tui/app.py +2 -17
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/html_report.py +1 -20
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_ledger.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/tables.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/updates/checker.py +0 -4
- {usage_cli-0.33.1 → usage_cli-0.33.2}/updates/whats_new.py +1 -1
- usage_cli-0.33.1/usage_cli.py → usage_cli-0.33.2/usage_app/cli.py +3 -150
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_app}/doctor.py +2 -18
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_cli.egg-info/PKG-INFO +10 -7
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_cli.egg-info/SOURCES.txt +25 -19
- usage_cli-0.33.2/usage_cli.egg-info/entry_points.txt +3 -0
- usage_cli-0.33.2/usage_cli.egg-info/top_level.txt +16 -0
- usage_cli-0.33.2/usage_common/app_version.py +24 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_common}/i18n.py +8 -6
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_common}/pricing.py +0 -5
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_common}/project_resolver.py +49 -32
- usage_cli-0.33.2/usage_hooks/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_quota_aware.py +8 -4
- usage_cli-0.33.2/wintray/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/app.py +24 -83
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/prefs.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/quota_label.py +1 -1
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/watch.py +0 -3
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/whats_new.py +1 -1
- usage_cli-0.33.1/panels/__init__.py +0 -231
- usage_cli-0.33.1/usage_cli.egg-info/entry_points.txt +0 -3
- usage_cli-0.33.1/usage_cli.egg-info/top_level.txt +0 -33
- {usage_cli-0.33.1 → usage_cli-0.33.2}/LICENSE +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/THIRD_PARTY_NOTICES.md +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/codex.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/registry.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/adapters/types.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/diagnoser.py +0 -0
- /usage_cli-0.33.1/usage_diagnosis_snapshot.py → /usage_cli-0.33.2/analyzer/diagnosis_snapshot.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/dispatch_ledger.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/insights.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/analyzer/subscription.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/codex_hook_trust.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/login_item.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/installer/statusline_settings.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/_shared_cache_file.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/agy_disk_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/agy_quota_probe.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/cache_quarantine.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/chromium_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/claude_desktop.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/claude_paths.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/codex_disk_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/codex_events.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/codex_fork_replay.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/codex_paths.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/disk_cache_common.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/disk_cache_lifecycle.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/grok_quota_probe.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/history_disk_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/jsonl_limits.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/loaders/jsonl_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/chrome.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/menubar}/fsevents_watch.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/popover.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/menubar/title.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/dynamic_height.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/panel_scale.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/panel_window.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/panel_window_state.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/panels/window_drag.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/burn_rate.py +0 -0
- /usage_cli-0.33.1/usage_notifications.py → /usage_cli-0.33.2/quota/notifications.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/quota/usage_rate.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/setup.cfg +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_adapters_codex.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_adapters_rate_limits.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_aggregator.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_agy_disk_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_agy_loader.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_agy_quota_probe.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_analyzer_blocks.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_analyzer_pipeline.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_burn_rate.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_cache_quarantine.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_chromium_cache.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_claude_desktop.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_codex_consistency.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_codex_hook_trust.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_codex_loader.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_codex_window_keeper.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_diagnoser.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_disk_cache_shards.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_dispatch_ledger.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_dynamic_height.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_grok_loader.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_grok_quota_probe.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_html_report_snapshot.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_i18n_key_parity.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_insights.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_jsonl_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_keeper_menu.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_keeper_outcome.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_login_item.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_menubar_notify.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_packaged_resources.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_panel_footer_layout.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_panel_scale.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_panel_window_state.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_panels_lazy_import.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_report_daily_chart.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_report_filter_js.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_setup_app.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_subprocess_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_subscription.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_taskbar_menu.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_time_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_tui_sprite.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_ui_tables.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_update_gate.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_update_release_notes.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_dir_sweeper.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_lang.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_logging.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_rate.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_snapshot.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_usage_snapshot_replay.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_whats_new.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_win_login_item.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_window_keeper.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tests/test_windows_manifest.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tui/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/tui/sprite.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_charts.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_daily_chart.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_filter.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_scripts.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/ui/report_styles.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/updates/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/updates/gate.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/updates/release_notes.py +0 -0
- {usage_cli-0.33.1/usage_common → usage_cli-0.33.2/usage_app}/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_cli.egg-info/dependency_links.txt +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_cli.egg-info/requires.txt +0 -0
- {usage_cli-0.33.1/wintray → usage_cli-0.33.2/usage_common}/__init__.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_common}/prefs.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_common}/service_status.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_common/subprocess_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_common/time_utils.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_common/usage_dir_sweeper.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_common/usage_lang.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/usage_common/usage_logging.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_session_resume.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_statusline.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_statusline_agy.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_statusline_forwarder.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_statusline_grok.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_terse_mode.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2/usage_hooks}/usage_terse_reminder.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/login_item.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/menu.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/taskbar_menu.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/taskbar_obstacles.py +0 -0
- {usage_cli-0.33.1 → usage_cli-0.33.2}/wintray/taskbar_overlay.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: usage-cli
|
|
3
|
-
Version: 0.33.
|
|
3
|
+
Version: 0.33.2
|
|
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
|
|
@@ -70,7 +70,7 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
70
70
|
- **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.
|
|
71
71
|
- **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.
|
|
72
72
|
- **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.
|
|
73
|
-
- **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.
|
|
73
|
+
- **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. The context figure turns yellow at 50% or 200K tokens and red at 80% or 400K tokens, whichever comes first. When it changes color, the status line shows the image count and the estimated share of files and command output.
|
|
74
74
|
- **Prompt Cache Health:** The status line shows Claude Code's prompt cache hit rate. For 10 minutes after the cache misses, it also says why — the model changed, the tools changed, you sat idle past the 5-minute TTL, and so on — so you can tell whether the extra tokens came from something you did. The hit rate needs Claude Code 2.1.251 or newer and the reason needs 2.1.260 or newer; on older versions those parts simply don't appear.
|
|
75
75
|
- **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.
|
|
76
76
|
|
|
@@ -79,15 +79,16 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
79
79
|
- **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.
|
|
80
80
|
- **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.
|
|
81
81
|
- **Claude Code side pane (macOS and Windows):** Quotas, conversations, and background jobs inside Claude Code. [See the side pane](#claude-code-side-pane).
|
|
82
|
-
- **Beginner Mode (macOS):** Off by default. After Claude Code answers, up to three technical terms from that answer appear above the prompt, each with a one-line plain explanation in your UI language. Press 9 to mark them understood; terms you skip come back after 1, 3, then 7 days. Understood terms return as a one-question multiple-choice quiz 7, 21, then 60 days later, at most one a day; a wrong answer puts the term back in the hints. `/terms` opens your term history. Picking terms asks Claude Haiku through your Claude Code, so it uses a little Claude quota, and it pauses while your 5-hour quota is at 90% or more.
|
|
83
|
-
- **Quota-Aware Mode (macOS):** Off by default. When a 5-hour quota passes 80%, 90%, or 95%, or a weekly quota passes 95%, Claude Code gets one line with what is left and when it resets. Before a big task, Claude then tells you and lets you pick a smaller part or wait for the reset. It covers Claude Code, Codex, and Antigravity quota, says each level once per conversation, and makes no extra model calls.
|
|
84
|
-
- **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.
|
|
82
|
+
- **Beginner Mode (macOS and Windows):** Off by default. After Claude Code answers, up to three technical terms from that answer appear above the prompt, each with a one-line plain explanation in your UI language. Press 9 to mark them understood; terms you skip come back after 1, 3, then 7 days. Understood terms return as a one-question multiple-choice quiz 7, 21, then 60 days later, at most one a day; a wrong answer puts the term back in the hints. `/terms` opens your term history. Picking terms asks Claude Haiku through your Claude Code, so it uses a little Claude quota, and it pauses while your 5-hour quota is at 90% or more.
|
|
83
|
+
- **Quota-Aware Mode (macOS and Windows):** Off by default. When a 5-hour quota passes 80%, 90%, or 95%, or a weekly quota passes 95%, Claude Code gets one line with what is left and when it resets. Before a big task, Claude then tells you and lets you pick a smaller part or wait for the reset. It covers Claude Code, Codex, and Antigravity quota, says each level once per conversation, and makes no extra model calls.
|
|
84
|
+
- **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.8 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.
|
|
85
85
|
- **Terminal Integration:** `usage status --json` hands your Claude Code, Codex, Antigravity, and Grok 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).
|
|
86
86
|
- **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.
|
|
87
87
|
|
|
88
88
|
### Stay Current
|
|
89
89
|
|
|
90
90
|
- **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.
|
|
91
|
+
- **Release Notes After an Update:** The first launch after an update shows what changed in that version in your UI language, once. Fresh installs skip it.
|
|
91
92
|
|
|
92
93
|
### Reporting & Insight
|
|
93
94
|
|
|
@@ -164,11 +165,13 @@ See your quota, other conversations, and background jobs without leaving Claude
|
|
|
164
165
|
|
|
165
166
|
- **Quotas:** Your 5-hour and weekly limits.
|
|
166
167
|
- **Claude conversations:** Conversations waiting for your permission or MCP input are marked in yellow.
|
|
168
|
+
- **Conversation notifications:** A notification appears when another Claude conversation finishes or starts waiting for you.
|
|
169
|
+
- **Latest reply:** Each conversation row shows the latest assistant reply on its second line.
|
|
167
170
|
- **Background jobs:** Includes subagents started by Claude with the Agent tool and their status.
|
|
168
171
|
|
|
169
172
|
**How to enable**
|
|
170
173
|
|
|
171
|
-
1. In the usage menu bar menu (macOS) or
|
|
174
|
+
1. In the usage menu bar menu (macOS) or system-tray menu (Windows), open the **Claude Code** submenu and check **Side pane**.
|
|
172
175
|
2. Open a new conversation or run `/reload-plugins`.
|
|
173
176
|
3. At terminal widths ≥144 columns, the pane opens on the right automatically. In narrower terminals, enter `/usage-dash`.
|
|
174
177
|
|
|
@@ -188,7 +191,7 @@ Windows has the full core experience: the system-tray UI, Claude Code status-lin
|
|
|
188
191
|
|
|
189
192
|
The system-tray icon shows the remaining session quota percentage for Claude or Codex. Choose **Tray Display Source → Claude Code / Codex** in the right-click menu or panel menu; the change applies immediately and survives restarts (default: Claude). If Codex has no session window, the icon uses its weekly quota instead and the tooltip identifies that window. Missing quota data shows `--`. The tooltip summarizes both tools, with the selected source first. Left-click opens the same 16 quota themes available on macOS (Default plus the other fifteen) in WebView2. Right-click also provides Reset Panel Position and Quit; panel switching, refresh, launch at login, and update checks are in the panel menu.
|
|
190
193
|
|
|
191
|
-
Enable **Show Taskbar Quota** in either menu for a transparent `Codex: 92%` label inside the taskbar, immediately left of the notification area. It follows taskbar position, scaling, and light/dark theme, and hides during fullscreen use or taskbar auto-hide. Click the label to open the panel. If buttons leave insufficient space, it moves just outside the taskbar. The normal app icon remains as a menu entry point; the label follows the selected source and quota window.
|
|
194
|
+
Enable **Show Taskbar Quota** in either menu for a transparent `Codex: 92%` label inside the taskbar, immediately left of the notification area. It follows taskbar position, scaling, and light/dark theme, and hides during fullscreen use or taskbar auto-hide. Click the label to open the panel. If buttons leave insufficient space, it moves just outside the taskbar. The normal app icon remains as a menu entry point; the label follows the selected source and quota window. Right-click the label to open the same menu as the tray icon.
|
|
192
195
|
|
|
193
196
|
Windows differences: the panel opens at the bottom-right of the working area rather than next to the tray icon; update prompts use a system Yes/No dialog.
|
|
194
197
|
|
|
@@ -48,7 +48,7 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
48
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.
|
|
49
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.
|
|
50
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.
|
|
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.
|
|
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. The context figure turns yellow at 50% or 200K tokens and red at 80% or 400K tokens, whichever comes first. When it changes color, the status line shows the image count and the estimated share of files and command output.
|
|
52
52
|
- **Prompt Cache Health:** The status line shows Claude Code's prompt cache hit rate. For 10 minutes after the cache misses, it also says why — the model changed, the tools changed, you sat idle past the 5-minute TTL, and so on — so you can tell whether the extra tokens came from something you did. The hit rate needs Claude Code 2.1.251 or newer and the reason needs 2.1.260 or newer; on older versions those parts simply don't appear.
|
|
53
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.
|
|
54
54
|
|
|
@@ -57,15 +57,16 @@ It lands in your Applications folder automatically. Open it once; if macOS 15 or
|
|
|
57
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.
|
|
58
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.
|
|
59
59
|
- **Claude Code side pane (macOS and Windows):** Quotas, conversations, and background jobs inside Claude Code. [See the side pane](#claude-code-side-pane).
|
|
60
|
-
- **Beginner Mode (macOS):** Off by default. After Claude Code answers, up to three technical terms from that answer appear above the prompt, each with a one-line plain explanation in your UI language. Press 9 to mark them understood; terms you skip come back after 1, 3, then 7 days. Understood terms return as a one-question multiple-choice quiz 7, 21, then 60 days later, at most one a day; a wrong answer puts the term back in the hints. `/terms` opens your term history. Picking terms asks Claude Haiku through your Claude Code, so it uses a little Claude quota, and it pauses while your 5-hour quota is at 90% or more.
|
|
61
|
-
- **Quota-Aware Mode (macOS):** Off by default. When a 5-hour quota passes 80%, 90%, or 95%, or a weekly quota passes 95%, Claude Code gets one line with what is left and when it resets. Before a big task, Claude then tells you and lets you pick a smaller part or wait for the reset. It covers Claude Code, Codex, and Antigravity quota, says each level once per conversation, and makes no extra model calls.
|
|
62
|
-
- **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.
|
|
60
|
+
- **Beginner Mode (macOS and Windows):** Off by default. After Claude Code answers, up to three technical terms from that answer appear above the prompt, each with a one-line plain explanation in your UI language. Press 9 to mark them understood; terms you skip come back after 1, 3, then 7 days. Understood terms return as a one-question multiple-choice quiz 7, 21, then 60 days later, at most one a day; a wrong answer puts the term back in the hints. `/terms` opens your term history. Picking terms asks Claude Haiku through your Claude Code, so it uses a little Claude quota, and it pauses while your 5-hour quota is at 90% or more.
|
|
61
|
+
- **Quota-Aware Mode (macOS and Windows):** Off by default. When a 5-hour quota passes 80%, 90%, or 95%, or a weekly quota passes 95%, Claude Code gets one line with what is left and when it resets. Before a big task, Claude then tells you and lets you pick a smaller part or wait for the reset. It covers Claude Code, Codex, and Antigravity quota, says each level once per conversation, and makes no extra model calls.
|
|
62
|
+
- **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.8 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.
|
|
63
63
|
- **Terminal Integration:** `usage status --json` hands your Claude Code, Codex, Antigravity, and Grok 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).
|
|
64
64
|
- **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.
|
|
65
65
|
|
|
66
66
|
### Stay Current
|
|
67
67
|
|
|
68
68
|
- **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.
|
|
69
|
+
- **Release Notes After an Update:** The first launch after an update shows what changed in that version in your UI language, once. Fresh installs skip it.
|
|
69
70
|
|
|
70
71
|
### Reporting & Insight
|
|
71
72
|
|
|
@@ -142,11 +143,13 @@ See your quota, other conversations, and background jobs without leaving Claude
|
|
|
142
143
|
|
|
143
144
|
- **Quotas:** Your 5-hour and weekly limits.
|
|
144
145
|
- **Claude conversations:** Conversations waiting for your permission or MCP input are marked in yellow.
|
|
146
|
+
- **Conversation notifications:** A notification appears when another Claude conversation finishes or starts waiting for you.
|
|
147
|
+
- **Latest reply:** Each conversation row shows the latest assistant reply on its second line.
|
|
145
148
|
- **Background jobs:** Includes subagents started by Claude with the Agent tool and their status.
|
|
146
149
|
|
|
147
150
|
**How to enable**
|
|
148
151
|
|
|
149
|
-
1. In the usage menu bar menu (macOS) or
|
|
152
|
+
1. In the usage menu bar menu (macOS) or system-tray menu (Windows), open the **Claude Code** submenu and check **Side pane**.
|
|
150
153
|
2. Open a new conversation or run `/reload-plugins`.
|
|
151
154
|
3. At terminal widths ≥144 columns, the pane opens on the right automatically. In narrower terminals, enter `/usage-dash`.
|
|
152
155
|
|
|
@@ -166,7 +169,7 @@ Windows has the full core experience: the system-tray UI, Claude Code status-lin
|
|
|
166
169
|
|
|
167
170
|
The system-tray icon shows the remaining session quota percentage for Claude or Codex. Choose **Tray Display Source → Claude Code / Codex** in the right-click menu or panel menu; the change applies immediately and survives restarts (default: Claude). If Codex has no session window, the icon uses its weekly quota instead and the tooltip identifies that window. Missing quota data shows `--`. The tooltip summarizes both tools, with the selected source first. Left-click opens the same 16 quota themes available on macOS (Default plus the other fifteen) in WebView2. Right-click also provides Reset Panel Position and Quit; panel switching, refresh, launch at login, and update checks are in the panel menu.
|
|
168
171
|
|
|
169
|
-
Enable **Show Taskbar Quota** in either menu for a transparent `Codex: 92%` label inside the taskbar, immediately left of the notification area. It follows taskbar position, scaling, and light/dark theme, and hides during fullscreen use or taskbar auto-hide. Click the label to open the panel. If buttons leave insufficient space, it moves just outside the taskbar. The normal app icon remains as a menu entry point; the label follows the selected source and quota window.
|
|
172
|
+
Enable **Show Taskbar Quota** in either menu for a transparent `Codex: 92%` label inside the taskbar, immediately left of the notification area. It follows taskbar position, scaling, and light/dark theme, and hides during fullscreen use or taskbar auto-hide. Click the label to open the panel. If buttons leave insufficient space, it moves just outside the taskbar. The normal app icon remains as a menu entry point; the label follows the selected source and quota window. Right-click the label to open the same menu as the tray icon.
|
|
170
173
|
|
|
171
174
|
Windows differences: the panel opens at the bottom-right of the working area rather than next to the tray icon; update prompts use a system Yes/No dialog.
|
|
172
175
|
|
|
@@ -15,7 +15,7 @@ from typing import Any
|
|
|
15
15
|
|
|
16
16
|
from loaders.claude_paths import claude_config_dirs
|
|
17
17
|
from loaders.jsonl_utils import iter_jsonl_dicts
|
|
18
|
-
from project_resolver import resolve_project_name
|
|
18
|
+
from usage_common.project_resolver import resolve_project_name
|
|
19
19
|
|
|
20
20
|
from .types import AgentInfo
|
|
21
21
|
|
|
@@ -9,7 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
from loaders import grok_loader as shared_grok_loader
|
|
10
10
|
from loaders.history_loader import UsageEntry as GrokUsageEntry
|
|
11
11
|
|
|
12
|
-
from i18n import t
|
|
12
|
+
from usage_common.i18n import t
|
|
13
13
|
|
|
14
14
|
from .types import AgentInfo, UsageEntry
|
|
15
15
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
from collections import defaultdict
|
|
8
8
|
|
|
9
9
|
from adapters.types import DailyStats, MonthlyStats, SessionStats, UsageEntry, WeeklyStats
|
|
10
|
-
from pricing import calculate_cost
|
|
10
|
+
from usage_common.pricing import calculate_cost
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def aggregate_daily(entries: list[UsageEntry]) -> list[DailyStats]:
|
|
@@ -8,7 +8,7 @@ from collections.abc import Sequence
|
|
|
8
8
|
from datetime import datetime, timedelta, timezone
|
|
9
9
|
|
|
10
10
|
from adapters.types import DailyStats, P90Limits, SessionBlock, UsageEntry
|
|
11
|
-
from pricing import calculate_cost
|
|
11
|
+
from usage_common.pricing import calculate_cost
|
|
12
12
|
|
|
13
13
|
BLOCK_DURATION = timedelta(hours=5)
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ from typing import Any
|
|
|
17
17
|
|
|
18
18
|
from loaders.claude_paths import claude_config_dirs
|
|
19
19
|
from loaders.jsonl_utils import iter_jsonl_dicts
|
|
20
|
-
from project_resolver import project_from_encoded_path, resolve_project_name
|
|
20
|
+
from usage_common.project_resolver import project_from_encoded_path, resolve_project_name
|
|
21
21
|
from usage_common.time_utils import parse_optional_iso8601_utc
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
@@ -24,7 +24,7 @@ from analyzer import persona_loader
|
|
|
24
24
|
from analyzer import subscription
|
|
25
25
|
from adapters import agy, claude, codex, grok, muse
|
|
26
26
|
from adapters.types import AgentInfo, UsageEntry
|
|
27
|
-
from pricing import calculate_cost, is_model_priced
|
|
27
|
+
from usage_common.pricing import calculate_cost, is_model_priced
|
|
28
28
|
|
|
29
29
|
from .aggregator import aggregate_sessions
|
|
30
30
|
from . import diagnoser, dispatch_ledger, usage_snapshot
|
|
@@ -27,7 +27,7 @@ from typing import NotRequired, TypeGuard, TypedDict
|
|
|
27
27
|
|
|
28
28
|
from adapters.types import UsageEntry
|
|
29
29
|
from loaders import cache_quarantine
|
|
30
|
-
from pricing import calculate_cost
|
|
30
|
+
from usage_common.pricing import calculate_cost
|
|
31
31
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
33
33
|
|
|
@@ -52,11 +52,6 @@
|
|
|
52
52
|
"hook_installed_restart": "已安裝完成,請重開 Claude Code 一次",
|
|
53
53
|
"hook_install_failed": "安裝 hook 失敗",
|
|
54
54
|
"hook_install_failed_default": "setup_hook.setup() 回傳失敗",
|
|
55
|
-
"repair_dialog_title": "狀態列設定衝突",
|
|
56
|
-
"repair_dialog_message": "偵測到其他工具佔用了 Claude Code 狀態列。\n要切換成共存模式嗎?usage app 與其他工具可以同時運作。",
|
|
57
|
-
"repair_dialog_repair": "立即修復",
|
|
58
|
-
"repair_dialog_skip": "稍後再說",
|
|
59
|
-
"repair_dialog_never": "不要再問",
|
|
60
55
|
"alert_forwarder_title": "啟用共存模式?",
|
|
61
56
|
"alert_forwarder_body": "偵測到其他 Claude Code 狀態列工具。啟用共存模式後,usage 會透過轉發器與現有工具一起運作。",
|
|
62
57
|
"alert_forwarder_enable": "啟用共存模式",
|
|
@@ -599,11 +594,6 @@
|
|
|
599
594
|
"hook_installed_restart": "Hook installed. Restart Claude Code once.",
|
|
600
595
|
"hook_install_failed": "Hook installation failed",
|
|
601
596
|
"hook_install_failed_default": "setup_hook.setup() returned failure",
|
|
602
|
-
"repair_dialog_title": "Status Line Conflict",
|
|
603
|
-
"repair_dialog_message": "Another tool is using the Claude Code status line.\nSwitch to coexistence mode? usage app can run alongside other tools.",
|
|
604
|
-
"repair_dialog_repair": "Repair Now",
|
|
605
|
-
"repair_dialog_skip": "Later",
|
|
606
|
-
"repair_dialog_never": "Do Not Ask Again",
|
|
607
597
|
"alert_forwarder_title": "Enable coexistence mode?",
|
|
608
598
|
"alert_forwarder_body": "Another Claude Code status line tool was detected. In coexistence mode, usage runs through a forwarder alongside your existing tool.",
|
|
609
599
|
"alert_forwarder_enable": "Enable Coexistence Mode",
|
|
@@ -1146,11 +1136,6 @@
|
|
|
1146
1136
|
"hook_installed_restart": "已安装完成,请重开 Claude Code 一次",
|
|
1147
1137
|
"hook_install_failed": "安装 hook 失败",
|
|
1148
1138
|
"hook_install_failed_default": "setup_hook.setup() 返回失败",
|
|
1149
|
-
"repair_dialog_title": "状态栏设置冲突",
|
|
1150
|
-
"repair_dialog_message": "检测到其他工具占用了 Claude Code 状态栏。\n要切换成共存模式吗?usage app 可以和其他工具同时运行。",
|
|
1151
|
-
"repair_dialog_repair": "立即修复",
|
|
1152
|
-
"repair_dialog_skip": "稍后再说",
|
|
1153
|
-
"repair_dialog_never": "不要再问",
|
|
1154
1139
|
"alert_forwarder_title": "启用共存模式?",
|
|
1155
1140
|
"alert_forwarder_body": "检测到其他 Claude Code 状态栏工具。启用共存模式后,usage 会通过转发器和现有工具一起运行。",
|
|
1156
1141
|
"alert_forwarder_enable": "启用共存模式",
|
|
@@ -1693,11 +1678,6 @@
|
|
|
1693
1678
|
"hook_installed_restart": "フックをインストールしました。Claude Code を一度再起動してください。",
|
|
1694
1679
|
"hook_install_failed": "フックのインストールに失敗しました",
|
|
1695
1680
|
"hook_install_failed_default": "setup_hook.setup() が失敗を返しました",
|
|
1696
|
-
"repair_dialog_title": "ステータスライン設定の競合",
|
|
1697
|
-
"repair_dialog_message": "別のツールが Claude Code のステータスラインを使用しています。\n共存モードに切り替えますか?usage app と他のツールを同時に動かせます。",
|
|
1698
|
-
"repair_dialog_repair": "今すぐ修復",
|
|
1699
|
-
"repair_dialog_skip": "あとで",
|
|
1700
|
-
"repair_dialog_never": "今後表示しない",
|
|
1701
1681
|
"alert_forwarder_title": "共存モードを有効にしますか?",
|
|
1702
1682
|
"alert_forwarder_body": "他の Claude Code ステータスラインツールを検出しました。共存モードでは、usage はフォワーダー経由で既存のツールと一緒に動作します。",
|
|
1703
1683
|
"alert_forwarder_enable": "共存モードを有効化",
|
|
@@ -2240,11 +2220,6 @@
|
|
|
2240
2220
|
"hook_installed_restart": "훅 설치가 완료되었습니다. Claude Code를 한 번 다시 시작하세요.",
|
|
2241
2221
|
"hook_install_failed": "훅 설치에 실패했습니다",
|
|
2242
2222
|
"hook_install_failed_default": "setup_hook.setup()가 실패를 반환했습니다",
|
|
2243
|
-
"repair_dialog_title": "상태 표시줄 설정 충돌",
|
|
2244
|
-
"repair_dialog_message": "다른 도구가 Claude Code 상태 표시줄을 사용 중입니다.\n공존 모드로 전환할까요? usage app과 다른 도구를 함께 실행할 수 있습니다.",
|
|
2245
|
-
"repair_dialog_repair": "지금 복구",
|
|
2246
|
-
"repair_dialog_skip": "나중에",
|
|
2247
|
-
"repair_dialog_never": "다시 묻지 않기",
|
|
2248
2223
|
"alert_forwarder_title": "공존 모드를 활성화할까요?",
|
|
2249
2224
|
"alert_forwarder_body": "다른 Claude Code 상태 표시줄 도구를 감지했습니다. 공존 모드에서는 usage가 포워더를 통해 기존 도구와 함께 실행됩니다.",
|
|
2250
2225
|
"alert_forwarder_enable": "공존 모드 활성화",
|
|
@@ -9,8 +9,8 @@ import shutil
|
|
|
9
9
|
import sys
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
-
from i18n import t as _t
|
|
13
12
|
from installer import setup_hook
|
|
13
|
+
from usage_common.i18n import t as _t
|
|
14
14
|
from usage_common.usage_lang import detect_lang
|
|
15
15
|
|
|
16
16
|
INSTALL_DIR = Path.home() / ".usage" / "claude-pane" / "usage-dash"
|
|
@@ -62,7 +62,7 @@ def _status_argv() -> list[str]:
|
|
|
62
62
|
f"import sys;sys.path[:0]=[{resources!r}+'/lib/python{major}{minor}.zip',"
|
|
63
63
|
f"{resources!r}+'/lib/python{major}.{minor}',"
|
|
64
64
|
f"{resources!r}+'/lib/python{major}.{minor}/lib-dynload',{resources!r}];"
|
|
65
|
-
"import
|
|
65
|
+
"from usage_app import cli;sys.argv=['usage','status','--json'];cli.main()"
|
|
66
66
|
)
|
|
67
67
|
return [
|
|
68
68
|
"/usr/bin/env",
|
|
@@ -72,16 +72,17 @@ def _status_argv() -> list[str]:
|
|
|
72
72
|
"-c",
|
|
73
73
|
bootstrap,
|
|
74
74
|
]
|
|
75
|
+
root = str(Path(__file__).resolve().parent.parent)
|
|
75
76
|
return [
|
|
76
77
|
sys.executable,
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
"--json",
|
|
78
|
+
"-c",
|
|
79
|
+
f"import sys;sys.path.insert(0,{root!r});from usage_app import cli;"
|
|
80
|
+
"sys.argv=['usage','status','--json'];cli.main()",
|
|
80
81
|
]
|
|
81
82
|
|
|
82
83
|
|
|
83
84
|
def _sidecar_text(mod: str = "usage-dash") -> str:
|
|
84
|
-
from i18n import I18N_PATH
|
|
85
|
+
from usage_common.i18n import I18N_PATH
|
|
85
86
|
|
|
86
87
|
bundle = json.loads(I18N_PATH.read_text(encoding="utf-8"))
|
|
87
88
|
english = bundle["en"]
|
|
@@ -20,7 +20,6 @@ from datetime import UTC, datetime
|
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
from typing import Any
|
|
22
22
|
|
|
23
|
-
from i18n import t as _t
|
|
24
23
|
from installer import setup_hook
|
|
25
24
|
from installer.setup_hook import (
|
|
26
25
|
BACKUP_KEY,
|
|
@@ -50,8 +49,9 @@ from installer.setup_hook import (
|
|
|
50
49
|
update_hook,
|
|
51
50
|
)
|
|
52
51
|
from loaders.codex_paths import codex_home
|
|
52
|
+
from usage_common.i18n import t as _t
|
|
53
53
|
from usage_common.usage_lang import detect_lang
|
|
54
|
-
from usage_statusline import _exclusive_lock
|
|
54
|
+
from usage_hooks.usage_statusline import _exclusive_lock
|
|
55
55
|
|
|
56
56
|
CODEX_CONFIG = setup_hook.CODEX_CONFIG
|
|
57
57
|
|
|
@@ -94,7 +94,7 @@ _TERSE_REMINDER_MARKER = "usage-terse-reminder"
|
|
|
94
94
|
_TERSE_REMINDER_MARKERS = (_TERSE_REMINDER_MARKER, "usage_terse_reminder")
|
|
95
95
|
# Independent, opt-in Claude Code UserPromptSubmit hook.
|
|
96
96
|
QUOTA_AWARE_HOOK_TARGET = Path(os.path.expanduser("~/.claude/usage-quota-aware.py"))
|
|
97
|
-
QUOTA_AWARE_HOOK_VERSION = "1.
|
|
97
|
+
QUOTA_AWARE_HOOK_VERSION = "1.1"
|
|
98
98
|
QUOTA_AWARE_MATCHER = ""
|
|
99
99
|
_QUOTA_AWARE_MARKER = "usage-quota-aware"
|
|
100
100
|
_QUOTA_AWARE_MARKERS = (_QUOTA_AWARE_MARKER, "usage_quota_aware")
|
|
@@ -205,9 +205,9 @@ def _migrate_bundled_python_commands_if_needed(
|
|
|
205
205
|
|
|
206
206
|
|
|
207
207
|
def _resolve_resume_source() -> Path:
|
|
208
|
-
# installer/ is one level below the repo root
|
|
208
|
+
# installer/ is one level below the repo root; hook sources live in usage_hooks/.
|
|
209
209
|
paths = [
|
|
210
|
-
Path(__file__).resolve().parent.parent / "usage_session_resume.py",
|
|
210
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_session_resume.py",
|
|
211
211
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_session_resume.py",
|
|
212
212
|
]
|
|
213
213
|
for path in paths:
|
|
@@ -219,7 +219,7 @@ def _resolve_resume_source() -> Path:
|
|
|
219
219
|
|
|
220
220
|
def _resolve_terse_source() -> Path:
|
|
221
221
|
paths = [
|
|
222
|
-
Path(__file__).resolve().parent.parent / "usage_terse_mode.py",
|
|
222
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_terse_mode.py",
|
|
223
223
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_terse_mode.py",
|
|
224
224
|
]
|
|
225
225
|
for path in paths:
|
|
@@ -231,7 +231,7 @@ def _resolve_terse_source() -> Path:
|
|
|
231
231
|
|
|
232
232
|
def _resolve_terse_reminder_source() -> Path:
|
|
233
233
|
paths = [
|
|
234
|
-
Path(__file__).resolve().parent.parent / "usage_terse_reminder.py",
|
|
234
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_terse_reminder.py",
|
|
235
235
|
(Path(sys.executable).resolve().parent.parent / "Resources" / "usage_terse_reminder.py"),
|
|
236
236
|
]
|
|
237
237
|
for path in paths:
|
|
@@ -286,7 +286,7 @@ def _copy_terse_reminder_script() -> None:
|
|
|
286
286
|
def _write_resume_sidecar() -> None:
|
|
287
287
|
"""Mirror i18n.json's rw_prompt/rw_none into a sidecar the stdlib hook can read,
|
|
288
288
|
so the injected wording stays single-sourced and the hook needs no app imports."""
|
|
289
|
-
from i18n import I18N_PATH
|
|
289
|
+
from usage_common.i18n import I18N_PATH
|
|
290
290
|
|
|
291
291
|
try:
|
|
292
292
|
bundle = json.loads(I18N_PATH.read_text(encoding="utf-8"))
|
|
@@ -350,7 +350,7 @@ def _write_resume_sidecar() -> None:
|
|
|
350
350
|
|
|
351
351
|
|
|
352
352
|
def _write_terse_sidecar() -> None:
|
|
353
|
-
from i18n import I18N_PATH
|
|
353
|
+
from usage_common.i18n import I18N_PATH
|
|
354
354
|
|
|
355
355
|
try:
|
|
356
356
|
bundle = json.loads(I18N_PATH.read_text(encoding="utf-8"))
|
|
@@ -1275,7 +1275,7 @@ def self_heal() -> None:
|
|
|
1275
1275
|
|
|
1276
1276
|
def _resolve_quota_aware_source() -> Path:
|
|
1277
1277
|
paths = [
|
|
1278
|
-
Path(__file__).resolve().parent.parent / "usage_quota_aware.py",
|
|
1278
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_quota_aware.py",
|
|
1279
1279
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_quota_aware.py",
|
|
1280
1280
|
]
|
|
1281
1281
|
for path in paths:
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
Claude Code calls the command configured in ~/.claude/settings.json statusLine
|
|
10
10
|
and sends session JSON on stdin whenever it refreshes the status line. The
|
|
11
|
-
installer copies usage_statusline.py to ~/.claude/usage-statusline.py and points
|
|
11
|
+
installer copies usage_hooks/usage_statusline.py to ~/.claude/usage-statusline.py and points
|
|
12
12
|
statusLine at it, so the main app can read a local status file.
|
|
13
13
|
|
|
14
14
|
The previous statusLine is backed up under settings["usage"]["previousStatusLine"]
|
|
@@ -34,9 +34,9 @@ from datetime import UTC, datetime
|
|
|
34
34
|
from pathlib import Path
|
|
35
35
|
from typing import Any, cast
|
|
36
36
|
|
|
37
|
-
from i18n import t as _t
|
|
38
37
|
from loaders.claude_paths import claude_home
|
|
39
38
|
from loaders.codex_paths import codex_home
|
|
39
|
+
from usage_common.i18n import t as _t
|
|
40
40
|
from usage_common.subprocess_utils import hidden_console_kwargs
|
|
41
41
|
|
|
42
42
|
HOOK_TARGET = Path(os.path.expanduser("~/.claude/usage-statusline.py"))
|
|
@@ -118,9 +118,9 @@ def configure_windows_utf8_output() -> None:
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
def _resolve_hook_source() -> Path:
|
|
121
|
-
# installer/ is one level below the repo root
|
|
121
|
+
# installer/ is one level below the repo root; hook sources live in usage_hooks/.
|
|
122
122
|
paths = [
|
|
123
|
-
Path(__file__).resolve().parent.parent / "usage_statusline.py",
|
|
123
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_statusline.py",
|
|
124
124
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_statusline.py",
|
|
125
125
|
]
|
|
126
126
|
for path in paths:
|
|
@@ -132,7 +132,7 @@ def _resolve_hook_source() -> Path:
|
|
|
132
132
|
|
|
133
133
|
def _resolve_forwarder_source() -> Path:
|
|
134
134
|
paths = [
|
|
135
|
-
Path(__file__).resolve().parent.parent / "usage_statusline_forwarder.py",
|
|
135
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_statusline_forwarder.py",
|
|
136
136
|
(
|
|
137
137
|
Path(sys.executable).resolve().parent.parent
|
|
138
138
|
/ "Resources"
|
|
@@ -148,7 +148,7 @@ def _resolve_forwarder_source() -> Path:
|
|
|
148
148
|
|
|
149
149
|
def _resolve_agy_hook_source() -> Path | None:
|
|
150
150
|
paths = [
|
|
151
|
-
Path(__file__).resolve().parent.parent / "usage_statusline_agy.py",
|
|
151
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_statusline_agy.py",
|
|
152
152
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_statusline_agy.py",
|
|
153
153
|
]
|
|
154
154
|
return next((path for path in paths if path.exists()), None)
|
|
@@ -166,7 +166,7 @@ def _agy_hook_script_is_stale() -> bool:
|
|
|
166
166
|
|
|
167
167
|
def _resolve_grok_hook_source() -> Path | None:
|
|
168
168
|
paths = [
|
|
169
|
-
Path(__file__).resolve().parent.parent / "usage_statusline_grok.py",
|
|
169
|
+
Path(__file__).resolve().parent.parent / "usage_hooks" / "usage_statusline_grok.py",
|
|
170
170
|
Path(sys.executable).resolve().parent.parent / "Resources" / "usage_statusline_grok.py",
|
|
171
171
|
]
|
|
172
172
|
return next((path for path in paths if path.exists()), None)
|
|
@@ -1080,10 +1080,6 @@ def _ensure_table_line(content: str, name: str, line_regex: re.Pattern[str], lin
|
|
|
1080
1080
|
return content[:start] + f"\n{line}" + content[start:]
|
|
1081
1081
|
|
|
1082
1082
|
|
|
1083
|
-
def _find_tui_table(content: str) -> re.Match[str] | None:
|
|
1084
|
-
return _find_table(content, "tui")
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
1083
|
def _insert_tui_status_line(content: str, replacement: str) -> str:
|
|
1088
1084
|
return _insert_table_line(content, "tui", replacement)
|
|
1089
1085
|
|
|
@@ -1277,7 +1273,7 @@ def is_codex_setup() -> bool:
|
|
|
1277
1273
|
|
|
1278
1274
|
|
|
1279
1275
|
def _install_forwarder(settings: dict[str, Any]) -> None:
|
|
1280
|
-
"""Copy usage_statusline_forwarder.py to ~/.claude/ and update settings.json."""
|
|
1276
|
+
"""Copy usage_hooks/usage_statusline_forwarder.py to ~/.claude/ and update settings.json."""
|
|
1281
1277
|
_copy_hook_script()
|
|
1282
1278
|
_copy_forwarder_script()
|
|
1283
1279
|
_backup_existing_statusline(settings)
|
|
@@ -28,7 +28,7 @@ from loaders.disk_cache_lifecycle import (
|
|
|
28
28
|
from loaders.disk_cache_lifecycle import (
|
|
29
29
|
flush_caches_on_terminate as _flush_caches_on_terminate,
|
|
30
30
|
)
|
|
31
|
-
from project_resolver import resolve_project_name
|
|
31
|
+
from usage_common.project_resolver import resolve_project_name
|
|
32
32
|
|
|
33
33
|
logger = logging.getLogger(__name__)
|
|
34
34
|
|
|
@@ -18,10 +18,10 @@ from enum import StrEnum
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from typing import Any
|
|
20
20
|
|
|
21
|
-
from i18n import _t
|
|
22
21
|
from installer.setup_hook import current_hook_state
|
|
23
22
|
from loaders import claude_desktop
|
|
24
23
|
from loaders.claude_paths import claude_config_dirs, claude_json_path
|
|
24
|
+
from usage_common.i18n import _t
|
|
25
25
|
from usage_common.usage_lang import detect_lang
|
|
26
26
|
|
|
27
27
|
logger = logging.getLogger(__name__)
|
|
@@ -61,7 +61,7 @@ from loaders.disk_cache_lifecycle import (
|
|
|
61
61
|
)
|
|
62
62
|
from loaders.history_loader import UsageEntry
|
|
63
63
|
from loaders.jsonl_limits import read_bounded_jsonl_line
|
|
64
|
-
from project_resolver import resolve_project_name
|
|
64
|
+
from usage_common.project_resolver import resolve_project_name
|
|
65
65
|
from usage_common.time_utils import parse_optional_iso8601_utc
|
|
66
66
|
|
|
67
67
|
logger = logging.getLogger(__name__)
|
|
@@ -26,7 +26,7 @@ from urllib.parse import unquote_to_bytes
|
|
|
26
26
|
|
|
27
27
|
from loaders.history_loader import UsageEntry
|
|
28
28
|
from loaders.jsonl_limits import read_bounded_jsonl_line
|
|
29
|
-
from project_resolver import resolve_project_name
|
|
29
|
+
from usage_common.project_resolver import resolve_project_name
|
|
30
30
|
from usage_common.time_utils import parse_optional_iso8601_utc
|
|
31
31
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
@@ -30,7 +30,7 @@ from loaders.disk_cache_lifecycle import (
|
|
|
30
30
|
)
|
|
31
31
|
from loaders.history_disk_cache import _shard_index, flush_caches, seed_caches
|
|
32
32
|
from loaders.jsonl_limits import read_bounded_jsonl_line
|
|
33
|
-
from project_resolver import project_from_encoded_path, resolve_project_name
|
|
33
|
+
from usage_common.project_resolver import project_from_encoded_path, resolve_project_name
|
|
34
34
|
from usage_common.time_utils import parse_optional_iso8601_utc
|
|
35
35
|
|
|
36
36
|
logger = logging.getLogger(__name__)
|
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
|
13
13
|
from typing import Any
|
|
14
14
|
|
|
15
15
|
from loaders.history_loader import UsageEntry
|
|
16
|
-
from project_resolver import resolve_project_name
|
|
16
|
+
from usage_common.project_resolver import resolve_project_name
|
|
17
17
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
MUSE_SESSIONS_DIR = Path(os.path.expanduser("~/.local/share/muse/sessions"))
|