Skip to content

feat(menubar): Local/Combined usage toggle — Swift, stacked on #567 (#566)#568

Open
ozymandiashh wants to merge 2 commits into
getagentseal:mainfrom
ozymandiashh:feat/menubar-combined-swift-pr
Open

feat(menubar): Local/Combined usage toggle — Swift, stacked on #567 (#566)#568
ozymandiashh wants to merge 2 commits into
getagentseal:mainfrom
ozymandiashh:feat/menubar-combined-swift-pr

Conversation

@ozymandiashh

Copy link
Copy Markdown
Contributor

Summary

Swift half of #566: a Local/Combined toggle in the macOS menubar, on top of the menubar-json --scope combined contract.

Stacked on #567. The first commit here is #567 (the data-layer PR); review/merge that first. Once #567 lands I'll rebase so this shows only the mac/ diff. (Until then the diff below includes #567's TS changes.)

What changed (Swift, mac/)

  • MenubarScope toggle (Settings -> Display), default Local (Combined is opt-in). Persisted in UserDefaults; PayloadCacheKey gains a scope dimension so local/combined cache separately.
  • DataClient.fetch(scope:) via a pure statusSubcommand builder: appends --scope combined only for combined, forces --provider all (the CLI rejects combined with a filter), and coerces multi-day to local (the CLI rejects combined + --days).
  • MenubarPayload decodes the optional combined block; nil when absent (back-compat).
  • The badge always stays on the local payload. The combined network pull lives on a separate cache key and falls back to local with a "Combined unavailable - showing local" indicator, so a slow/offline peer never blocks the badge.
  • Combined scope shows combined totals + a per-device breakdown; the token metric stays input+output (cache excluded) to match local; the per-device daily-budget warning is suppressed against a multi-device total; selecting Combined resets the provider tab to All.

Testing

…tagentseal#566)

The macOS menubar reads `codeburn status --format menubar-json`, which only
ever reflected the local machine. Multi-device "Combined" usage existed only in
the terminal `devices` command. This exposes combined + per-device usage through
the menubar-json contract so the menubar can mirror the combined dashboard.

- Extract the per-device summary + combined reduce that was inline in
  renderDevices into a reusable pure `summarizeDeviceUsage(results, window?)`.
  Error/unreachable devices are excluded from the combined sums (kept in
  perDevice); deviceCount counts all, reachableCount counts the reachable ones.
  renderDevices now formats from it with byte-identical output.
- Add an optional `combined?: CombinedUsage` block to MenubarPayload (perDevice
  list + combined totals incl. calls/sessions). Absent by default.
- Add `--scope local|combined` to `status` (default local). `combined` builds the
  local payload, pulls paired devices (pullDevices isolates per-peer failures),
  and attaches the summary.
- Correctness guards: reject `--scope combined` with `--days` (non-contiguous,
  not representable over the sharing query) and with `--provider`/`--project`/
  `--exclude` (the sharing query carries no filters, so peers would report
  unfiltered usage). Window-scope the cache-token sum to the selected period
  (cache lives in 365-day daily history; current carries no cache counts).

TS/CLI only. The menubar Local/Combined toggle + render is a follow-up.
Mirror the combined multi-device dashboard in the macOS menubar via a
Local/Combined scope toggle (Settings -> Display). Builds on the menubar-json
`--scope combined` contract.

- MenubarScope enum (.local default) persisted in UserDefaults; PayloadCacheKey
  gains a scope dimension so local and combined payloads cache separately.
- DataClient.fetch(scope:): a pure statusSubcommand builder appends
  `--scope combined` only for combined, forces `--provider all` (the CLI rejects
  combined with a provider/project/exclude filter), and coerces multi-day
  selections to local (the CLI rejects combined + --days).
- MenubarPayload decodes the optional `combined` block (per-device + totals);
  nil when absent (back-compat).
- The badge always stays on the local payload; the combined network pull lives
  on a separate cache key and falls back to local with a "Combined unavailable"
  indicator, so a slow/offline peer never blocks the badge.
- Hero shows combined totals + a per-device breakdown in Combined scope; the
  token metric stays input+output (cache excluded) to match local; the
  per-device daily-budget warning is suppressed for a multi-device total;
  selecting Combined resets the provider tab to All.

Tests run via `swift test` (CommandLineTools Testing.framework on the rpath, no
Xcode): scope persistence, argv (local/combined/provider-forcing/multi-day),
cache-key partition, badge-survives-combined-failure, combined decode, token
consistency, provider reset, budget suppression.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant