Series 2/2: Multi-Model Collaboration & Quota Management in Practice (Part 1: Building a Cross-Model Collaborative Workflow with Google Antigravity)
When you run tasks in parallel across Google Antigravity (Gemini), Claude Code, OpenAI Codex, and GitHub Copilot, a progress bar that simply says 40% used is not very useful.
Burning 40% in the first 30 minutes of a 5-hour quota window means you will hit a wall in another hour; burning 40% with 20 minutes left before reset means you have more quota than you can finish.
To make an always-on desktop quota monitor answer "At my current pace, how much longer can I keep working today?", I worked with the agents to build two things:
paceFraction) 0.0%.
To know whether a quota pool is about to blow up—or whether it still has plenty of slack—you only need to compare two ratios:
usedFraction
usedFraction = consumed / total
paceFraction = 1.0 - (resetsAt - now) / windowDuration
rate = usedFraction / paceFraction
projectedRunOut = windowStart + windowDuration / rate
For example: suppose a 5-hour window starts at 09:00 and resets at 14:00. At 10:00, one-fifth of the window has passed ( paceFraction = 20%, so the white tick sits at 20%).
If you have already used 40% by then, your burn rate is 2x the sustainable pace (rate = 2.0). At that speed, your entire quota will bottom out 5 / 2 = 2.5 hours after the window started—at 11:30.
So on each Leap EDGE card:
rate > 1.15), the bar shifts color and lights up a red pill: ▲ RUNS OUT 11:30.⏱ LASTS TO RESET.
With a single glance, you immediately know whether to route the next heavy task to another AI subscription.
All of this came out of iterating back and forth with Gemini 4 Argon while designing and tuning the implementation.
I already had a 22 KB vanilla HTML/CSS/JS web dashboard (?mode=edge). My initial idea was to wrap it in Tauri v2 (Rust + system WebView) as a desktop widget for macOS and Linux.
However, this widget isn't used like a normal app: you don't open it for five minutes and close it—it stays pinned to your desktop all day as a background monitor.
After looking into how macOS handles WebView processes, I decided not to put a WebView in the default path:
| Dimension | Electron | Tauri v2 (Rust + WKWebView) | Leap EDGE (Swift Dual-Engine Universal Binary) |
|---|---|---|---|
| Binary size | ~220 MB | ~6 MB ( target/ build cache ~800 MB) |
483 KB (arm64 +x86_64 combined) |
| Persistent processes | 4+ (Chromium) | 3 ( Host +WebKit.WebContent +GPU ) |
1 (pure CoreGraphics by default, zero WebKit) |
| Background wakeups & App Nap | High idle drain | 1s JS setInterval clock keeps waking IPC |
300s data poll + 60s clock tick (with 5s tolerance) |
| macOS desktop integration | Needs plugins | Requires objc2 FFI for low-level window flags |
Native 1-line desktop-level pinning & 👻 Click-Through |
According to Apple's WebKit WKProcessPool documentation and the Apple App Nap Power Efficiency Guide, simply instantiating a WKWebView spawns separate web-content and rendering subprocesses; on top of that, a 1-second JavaScript setInterval for a live clock keeps waking the rendering pipeline.
Just to draw five fixed-format dark quota cards, the default path doesn't need a browser engine running 24/7.
So we built a dual-engine switch inside a single leap-edge.swift file:
/api/usage JSON and draws the five cards (Copilot, AGY, Claude Pro/Team, Codex) plus live macOS Menu Bar indicators using AppKit and NSBezierPath. Idle CPU stays at window.ignoresMouseEvents = true so mouse clicks pass straight through to the Terminal or IDE behind it.WKWebView (🌐 Web Mode)removeFromSuperview() and sets the instance to nil, returning all WebKit subprocess memory to the OS.
With both Macs covered, I also have two Ubuntu machines on my desk: a ThinkPad X1 Carbon, and a Surface Pro 7 used for demos and meetings.
On Linux, we applied the exact same philosophy—a single-file, zero-third-party-dependency leap-edge.py that supports two modes:
leap-edge.py --status and --json)--gui)
Looking back at this two-day build, the biggest win wasn't saving a few dozen megabytes of RAM—it was clarifying two things:
Thanks for reading.