Skip to content

Add macOS menu bar app (apps/macos) with ledger-backed spend#478

Merged
willwashburn merged 8 commits into
mainfrom
macos-app
Jun 17, 2026
Merged

Add macOS menu bar app (apps/macos) with ledger-backed spend#478
willwashburn merged 8 commits into
mainfrom
macos-app

Conversation

@willwashburn

@willwashburn willwashburn commented Jun 17, 2026

Copy link
Copy Markdown
Member

Summary

Brings the Agent Limit macOS menu bar app into the burn monorepo as apps/macos, and wires it to the ledger so it shows spend alongside live rate-limit burndowns. This is the "Burn for Mac" front-end: limits (forward-looking, from provider APIs) + spend (retrospective, from the burn ledger).

What it does

  • Live limits — a flame menu bar icon (orange→red, fills when over pace) and a popover with per-window burndown charts (5-hour, weekly), read from the Claude (api.anthropic.com/api/oauth/usage) and Codex (chatgpt.com/backend-api/wham/usage) usage APIs using the CLIs' existing credentials.
  • Spend (new) — under each window, cost this period vs. last period in USD.

Why it shells out to burn

Cost is not stored in the ledger — burn computes it from its pricing table at query time. Rather than re-derive that pricing in Swift (which would silently drift), the app calls burn summary --provider <p> --since <window-start> --json and reads totalCost.total. "Last period" is cost(since lastStart) − cost(since thisStart) (burn has no --until).

Details:

  • Resolved via a login shell so nvm/Homebrew PATH (and the node the burn shim needs) work even when launched from Finder.
  • Throttled to every 5 min — each burn summary runs an ingest pass (~5s), and runs off the main actor so the UI isn't blocked.
  • Keyed by window name (the per-fetch UsageMetric.id is a fresh UUID each refresh).
  • Provider map: Claude→anthropic, Codex→openai. Hidden entirely if burn isn't installed.

Layout / build

  • Lives at apps/macos/, a SwiftPM app — not wired into the Cargo/pnpm workspaces (own toolchain).
  • swift build or apps/macos/build.shAgentLimit.app. apps/macos/release.sh signs/notarizes/packages a DMG.

Follow-ups (not in this PR)

  • macOS release CI isn't added to burn's workflows yet (didn't want to touch the existing Rust/npm release pipeline blindly) — the local release.sh works; a release-macos.yml building apps/macos is the natural next step.
  • Harden the burn dependency: optionally bundle a compiled burn/relayburn-sdk bridge in the .app so spend works with zero install/PATH assumptions.
  • Supersedes AgentWorkforce/limit PR Add Codex session reader and CLI integration #1 (same app, now homed here).

🤖 Generated with Claude Code

Review in cubic

Relocate the Agent Limit menu bar app into the burn monorepo as
apps/macos and wire it to the ledger:

- Live limits: flame menu bar icon (orange→red, fills when over pace) +
  per-window burndown charts, read from the Claude/Codex usage APIs.
- Spend: under each window, shows cost this period vs. last period in USD,
  read from the burn ledger. Cost isn't stored in the ledger, so it shells
  out to `burn summary --provider <p> --since <ISO> --json` rather than
  re-deriving pricing. Resolved via a login shell (nvm/Homebrew PATH) and
  throttled to every 5 min since each call runs an ingest pass (~5s).
  Hidden when burn isn't installed.
- Provider map: Claude→anthropic, Codex→openai.

Builds with `swift build` / `apps/macos/build.sh`. SwiftPM app, not part
of the Cargo/pnpm workspaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b4122418-6f5c-435e-a410-a3450ced3b64

📥 Commits

Reviewing files that changed from the base of the PR and between 26fdab5 and 0b793c3.

📒 Files selected for processing (6)
  • .github/workflows/release-macos.yml
  • apps/macos/Sources/Burn/BurnApp.swift
  • apps/macos/Sources/Burn/BurnLedger.swift
  • apps/macos/Sources/Burn/Providers.swift
  • apps/macos/Sources/Burn/UsageHistory.swift
  • apps/macos/Sources/Burn/UsageViewModel.swift
🚧 Files skipped from review as they are similar to previous changes (4)
  • .github/workflows/release-macos.yml
  • apps/macos/Sources/Burn/UsageHistory.swift
  • apps/macos/Sources/Burn/BurnLedger.swift
  • apps/macos/Sources/Burn/UsageViewModel.swift

📝 Walkthrough

Walkthrough

This PR introduces a complete new macOS menu bar app (apps/macos) written in SwiftUI/Swift Package Manager. The app periodically fetches AI provider (Claude, Codex) usage metrics, renders burndown charts with ideal-vs-actual pacing, and displays per-period spend from the burn CLI. It includes credential reading, history persistence, build/sign/notarize shell scripts, and a GitHub Actions workflow for automated release.

Changes

Burn macOS App

Layer / File(s) Summary
Project scaffold and documentation
apps/macos/Package.swift, apps/macos/App/Info.plist, apps/macos/.gitignore, apps/macos/LICENSE, apps/macos/README.md
Swift Package manifest targeting macOS 13, bundle configuration plist with LSUIElement menu-bar flag, gitignore for build artifacts, MIT license, and full README covering usage, credentials, build/run, release flow, and required secrets.
Core data models and credential reading
apps/macos/Sources/Burn/Models.swift, apps/macos/Sources/Burn/Credentials.swift
Models.swift defines ProviderName, ProviderStatusType, UsageMetric, ProviderStatus (with factory methods), and a fractional-second-tolerant DateParsing helper. Credentials.swift reads Claude tokens from the macOS keychain via /usr/bin/security and Codex tokens from ~/.codex/auth.json, extracting plan type from the JWT payload.
Provider HTTP fetch (Claude + Codex)
apps/macos/Sources/Burn/Providers.swift
Defines UsageProvider protocol; ClaudeProvider and CodexProvider authenticate, call provider REST endpoints, map 401/429/non-200 responses to typed outcomes, parse JSON into UsageMetric arrays, and compute .warning/.ok status from max usage percentage.
Burn ledger spend and usage history persistence
apps/macos/Sources/Burn/BurnLedger.swift, apps/macos/Sources/Burn/UsageHistory.swift
BurnLedger actor invokes the burn CLI (bundled auxiliary or PATH) to query totalCost.total per provider/period. UsageHistoryStore singleton persists rolling UsageSample series to Application Support/Burn/history.json, deduplicating within 1 s and pruning series whose reset is over 1 hour old.
Burndown data model and chart view
apps/macos/Sources/Burn/Burndown.swift, apps/macos/Sources/Burn/BurndownChartView.swift
BurndownBuilder.build() derives BurndownData from a UsageMetric and sample history: ideal remaining line, actual remaining curve, pace delta, and compact flag. BurndownChartView renders a Charts card with a countdown header, over/under-pace capsule, shaded gap area, dashed ideal line, solid actual line, and "now" point marker.
UsageViewModel orchestration
apps/macos/Sources/Burn/UsageViewModel.swift
@MainActor ObservableObject driving periodic refresh, exponential rate-limit backoff, chart building from history samples, throttled spend loading from BurnLedger (≤every 300 s), and headline usage/off-target computation for the menu bar flame icon.
App entry point, popover UI, and brand icons
apps/macos/Sources/Burn/BurnApp.swift, apps/macos/Sources/Burn/ContentView.swift, apps/macos/Sources/Burn/BrandIcon.swift, apps/macos/scripts/...
BurnApp wires an AppDelegate that owns an NSStatusItem (menu-bar flame) and an NSPopover driven by a UsageViewModel publisher. MenuBarIcon renderer computes an orange→red gradient via ImageRenderer. ContentView renders the provider picker, status-switched content area, spend rows, and burndown/simple chart rows. BrandIcon loads and tints SVG provider icons with BrandIconCache. Icon generation scripts produce AppIcon.icns from a programmatically drawn squircle+flame.
Build and release scripts
apps/macos/build.sh, apps/macos/release.sh
build.sh assembles the SwiftPM product into a .app bundle and optionally embeds the Rust burn CLI. release.sh optionally stamps a version, codesigns with hardened runtime (three notarization credential modes), staples the ticket, and packages into an arm64 UDZO DMG.
GitHub Actions release workflow
.github/workflows/release-macos.yml
Manually-triggered workflow computing a date-based macos-vYYYY.M.N version, decoding App Store Connect API key and Developer ID .p12 into a temporary keychain, running release.sh with up to three retries, publishing both a versioned and a moving macos-latest GitHub Release, and uploading the DMG as a 30-day artifact.

Sequence Diagram(s)

sequenceDiagram
  participant Timer
  participant UsageViewModel
  participant ClaudeProvider as ClaudeProvider/CodexProvider
  participant ProviderAPI as Provider REST API
  participant UsageHistoryStore
  participant BurnLedger
  participant BurnCLI as burn CLI

  Timer->>UsageViewModel: tick → refresh()
  UsageViewModel->>ClaudeProvider: fetch()
  ClaudeProvider->>ProviderAPI: GET usage endpoint (Bearer token)
  ProviderAPI-->>ClaudeProvider: JSON metrics / 401 / 429
  ClaudeProvider-->>UsageViewModel: ProviderStatus (.ok / .warning / .rateLimited)
  UsageViewModel->>UsageHistoryStore: record(provider, metric, at: now)
  UsageHistoryStore-->>UsageViewModel: [UsageSample] (deduplicated + persisted)
  UsageViewModel->>UsageViewModel: BurndownBuilder.build(metric, samples) → BurndownData
  UsageViewModel->>BurnLedger: cost(provider, since: windowStart) ×2
  BurnLedger->>BurnCLI: burn summary --provider --since --output json
  BurnCLI-->>BurnLedger: totalCost.total
  BurnLedger-->>UsageViewModel: PeriodSpend (current + lastPeriod)
  UsageViewModel->>UsageViewModel: update charts, spend, menuBarIcon
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 A flame in the menu bar flickers bright,
Tracking your tokens from morning to night.
Burndown curves plotted, the ledger queried,
Credentials read, the keychain not buried.
With notarized DMGs shipped to the world—
The bunny's macOS flag is unfurled! 🔥

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a macOS menu bar app (apps/macos) that integrates spend data from the ledger.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing what the app does, why it shells out to burn, layout/build info, and known follow-ups.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch macos-app

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fafbd2be1b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/macos/Sources/Burn/Credentials.swift
Comment thread apps/macos/README.md Outdated
willwashburn and others added 5 commits June 17, 2026 10:28
Make ledger-backed spend work with no separate install, and wire up
signed/notarized releases for the app.

- Bundle a self-contained native `burn` (compiled from relayburn-cli) into
  AgentLimit.app/Contents/MacOS/burn. BurnLedger prefers this bundled helper
  (exec'd directly — no node/PATH needed) and only falls back to a `burn`
  on PATH for `swift run` dev builds. Spend now works out of the box and
  even builds the ledger from session logs on first run.
- build.sh: `cargo build --release -p relayburn-cli` and copy the binary in
  (skipped with a warning if cargo is absent). release.sh signs the helper
  with a hardened runtime before the app.
- .github/workflows/release-macos.yml: manual workflow_dispatch that builds,
  signs, notarizes, and publishes AgentLimit-arm64.dmg. Uses a macos-v* tag
  scheme + a moving macos-latest pointer for a stable download URL, so it
  never disturbs burn's own v* CLI releases or their "latest" pointer.
  Reuses the same Apple secrets as Pear.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename the macOS app from "Agent Limit" to "Burn" throughout:

- Bundle: CFBundleName/DisplayName/Executable = Burn; identifier
  com.agentworkforce.burn. App is now Burn.app.
- SwiftPM target/module AgentLimit → Burn (Sources/AgentLimit → Sources/Burn,
  AgentLimitApp → BurnApp). Application Support dir → Burn.
- Bundled helper renamed burn → burn-cli to avoid colliding with the `Burn`
  executable on case-insensitive filesystems; BurnLedger looks up burn-cli.
- DMG is Burn-arm64.dmg; release-macos.yml titles "Burn for Mac".
- README + scripts updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverse the earlier naming: the CLI keeps the canonical `burn` name and the
macOS utility becomes BurnOSX (display name still "Burn").

- App bundle BurnOSX.app, executable BurnOSX, id com.agentworkforce.burnosx,
  DMG BurnOSX-arm64.dmg. CFBundleDisplayName stays "Burn" so Finder/menu
  show "Burn".
- Bundled CLI helper restored to `burn` (was burn-cli) — no collision now
  that the app executable is BurnOSX, not Burn. BurnLedger looks up `burn`.
- build.sh decouples the SwiftPM target (Burn) from the bundled app name
  (BurnOSX), so the internal module/Sources stay Burn without churn.
- release-macos.yml + README updated to BurnOSX-arm64.dmg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The menu bar label rendered its colored flame with ImageRenderer().nsImage
*inside* `body`, producing a fresh NSImage on every render pass. That
re-entrant SwiftUI render churns the MenuBarExtra status item — under the
feedback loop it spawns menu bar items without end and locks up the machine.

Render the flame in the view model instead, only when the (usage, offTarget)
state actually changes, and cache it. `MenuBarLabel.body` now just displays the
stable cached image — no rendering, no per-pass NSImage churn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Defense-in-depth for the class of bug that locked up the machine: if the
menu bar label ever re-renders in a tight loop again, count the renders in a
1s sliding window and, past a threshold far above anything legitimate (240/s),
log and NSApp.terminate. A regression now degrades to "the app quit" instead
of "reboot the Mac". The watchdog touches no observed state, so it can't
itself trigger a render.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/release-macos.yml (1)

119-127: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Pin upload-artifact action to full SHA.

Similar to the checkout action, pin actions/upload-artifact to a commit SHA for supply chain security.

Suggested fix
       - name: Upload build artifacts
         if: always()
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
         with:
           name: agentlimit-macos-${{ github.run_id }}
           path: apps/macos/dist/*.dmg
           if-no-files-found: warn
           retention-days: 30
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release-macos.yml around lines 119 - 127, The
actions/upload-artifact action in the Upload build artifacts step is currently
referenced by version tag (v4) instead of being pinned to a specific commit SHA.
Replace the version tag reference in the uses field with the full commit SHA of
the desired version to improve supply chain security. This ensures the exact
version of the action that runs is immutable and verifiable, preventing
potential compromises from future changes to the v4 tag.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release-macos.yml:
- Around line 21-24: Pin the actions/checkout action to its full commit SHA
instead of using the `@v4` tag reference to mitigate supply chain security risks.
Replace `@v4` with the full commit SHA corresponding to that version, and add
persist-credentials: false to the with block to prevent Git credentials from
being stored in the workspace.

In `@apps/macos/Sources/Burn/BurnLedger.swift`:
- Around line 85-99: The capture method waits indefinitely for the process to
exit via process.waitUntilExit(), which can cause the actor to hang if the burn
subprocess hangs. Implement a timeout mechanism for process execution by adding
a timeout interval (e.g., 5-10 seconds) and checking the process status within
that timeout window instead of waiting indefinitely. If the process has not
completed within the timeout period, terminate it and return nil to prevent
blocking subsequent requests.

In `@apps/macos/Sources/Burn/Providers.swift`:
- Around line 14-16: The synchronous I/O operations in Credentials.claude() and
Credentials.codex() are blocking the main thread when called from the MainActor
context in the refresh() method, causing UI stalls. Move the credential loading
calls (the guard statements checking Credentials.claude() and
Credentials.codex()) to execute on a background queue before entering the
MainActor-protected code path, ensuring synchronous I/O does not block the menu
bar UI during refresh or login operations.

In `@apps/macos/Sources/Burn/UsageHistory.swift`:
- Around line 34-37: The key function that builds cache keys by concatenating
provider.rawValue, metric.name, and reset time with "|" delimiters is brittle
because if metric.name contains the "|" character, it will break the key parsing
logic that expects exactly 3 parts when split by "|". Fix this by either
escaping or URL-encoding the metric.name before concatenating it into the key
string in the key(provider:metric:) function, or by using a structured key type
that doesn't rely on delimiter parsing.

In `@apps/macos/Sources/Burn/UsageViewModel.swift`:
- Around line 150-152: The spend throttling condition in the if statement
(checking `!spend.isEmpty` along with `lastSpendAt` and `spendInterval`)
bypasses throttling when burn lookups fail and leave `spend` empty, causing
retries every 60s instead of respecting the 5-minute throttle interval. Remove
the `!spend.isEmpty` check from this condition so throttling is applied
regardless of whether spend was successfully populated. Additionally, reset
`lastSpendAt` to nil in the `select(_:)` method to ensure immediate fetch when
switching providers.

---

Outside diff comments:
In @.github/workflows/release-macos.yml:
- Around line 119-127: The actions/upload-artifact action in the Upload build
artifacts step is currently referenced by version tag (v4) instead of being
pinned to a specific commit SHA. Replace the version tag reference in the uses
field with the full commit SHA of the desired version to improve supply chain
security. This ensures the exact version of the action that runs is immutable
and verifiable, preventing potential compromises from future changes to the v4
tag.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 62ce81fd-7c19-450d-8cd5-55bf2d22f61f

📥 Commits

Reviewing files that changed from the base of the PR and between 2a745c0 and 26fdab5.

⛔ Files ignored due to path filters (2)
  • apps/macos/Sources/Burn/Resources/claude.svg is excluded by !**/*.svg
  • apps/macos/Sources/Burn/Resources/openai.svg is excluded by !**/*.svg
📒 Files selected for processing (22)
  • .github/workflows/release-macos.yml
  • apps/macos/.gitignore
  • apps/macos/App/AppIcon.icns
  • apps/macos/App/Info.plist
  • apps/macos/LICENSE
  • apps/macos/Package.swift
  • apps/macos/README.md
  • apps/macos/Sources/Burn/BrandIcon.swift
  • apps/macos/Sources/Burn/BurnApp.swift
  • apps/macos/Sources/Burn/BurnLedger.swift
  • apps/macos/Sources/Burn/Burndown.swift
  • apps/macos/Sources/Burn/BurndownChartView.swift
  • apps/macos/Sources/Burn/ContentView.swift
  • apps/macos/Sources/Burn/Credentials.swift
  • apps/macos/Sources/Burn/Models.swift
  • apps/macos/Sources/Burn/Providers.swift
  • apps/macos/Sources/Burn/UsageHistory.swift
  • apps/macos/Sources/Burn/UsageViewModel.swift
  • apps/macos/build.sh
  • apps/macos/release.sh
  • apps/macos/scripts/generate-icon.swift
  • apps/macos/scripts/make-icon.sh

Comment thread .github/workflows/release-macos.yml
Comment thread apps/macos/Sources/Burn/BurnLedger.swift Outdated
Comment thread apps/macos/Sources/Burn/Providers.swift Outdated
Comment thread apps/macos/Sources/Burn/UsageHistory.swift
Comment thread apps/macos/Sources/Burn/UsageViewModel.swift Outdated
willwashburn and others added 2 commits June 17, 2026 14:36
Root cause of the "endless menu bar flames" + machine panic: SwiftUI's
MenuBarExtra duplicates its status item when the app's scene body
re-evaluates, spiraling into a status-item/render storm that locks up the
machine. (The earlier in-body ImageRenderer made it worse, but MenuBarExtra
is the core liability.)

Replace MenuBarExtra with a single NSStatusItem created once in an
AppDelegate (via NSApplicationDelegateAdaptor); the app exposes only an inert
Settings scene. The flame image is rendered by the view model and mirrored
onto the status button through the $menuBarIcon publisher — no SwiftUI render
path touches the menu bar, so it cannot duplicate or storm. The popover hosts
the existing SwiftUI ContentView via NSHostingController.

Remove RenderWatchdog (no SwiftUI menu bar body left to guard).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… CI pins

- BurnLedger.capture: bound the wait with a 30s timeout (drain stdout on a
  background queue) so a hung `burn` can't wedge the actor.
- Providers: load Claude/Codex credentials in a detached task so the
  synchronous `security`/file I/O doesn't stall the MainActor refresh.
- UsageViewModel.loadSpend: throttle on time alone (set lastSpendAt up front)
  so failed/burn-missing lookups also back off to 5 min instead of retrying
  every 60s; reset lastSpendAt on provider switch.
- UsageHistory.pruneStaleWindows: read the reset timestamp from the last "|"
  segment, robust to a "|" in a metric name.
- release-macos.yml: pin actions/checkout + upload-artifact to commit SHAs and
  set persist-credentials: false.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@willwashburn willwashburn merged commit abc5bd1 into main Jun 17, 2026
4 checks passed
@willwashburn willwashburn deleted the macos-app branch June 17, 2026 21:54
willwashburn added a commit that referenced this pull request Jun 17, 2026
Resolve apps/macos conflicts from #478 landing on main:
- BurnLedger: keep main's bundled-binary resolution + capture timeout, plus
  this branch's Summary/summary() and ingest-watch for the live tab.
- ContentView: main's content + the Usage/Live tab wrapper.
- Providers, UsageHistory, UsageViewModel, release-macos.yml: take main's
  (off-MainActor creds, throttle fix, key-parse fix, SHA-pinned actions).

main's `burn summary` is now a read verb (ingest gated behind --ingest), which
is exactly what the live poll assumes — so the short poll cadence is cheap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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