feat(bin): serve quota dashboard on the tailnet - #3
Merged
Merged
Conversation
Adds a stdlib-only Python server that shells quota-axi --json per request and serves one self-contained page (fleet summary, one card per provider, live/signed-out/error states in quota-axi's own words, 30s client refresh), matching the design in data/fm-quota-dashboard/report.md. Binds only to this host's own Tailscale IPv4 address, confirmed via `tailscale ip -4`, and refuses to start otherwise - never 0.0.0.0, never a public interface.
Raise the shell-out to 45s so one slow provider degrades instead of blanking the page. Prove the listener is address-scoped via 127.0.0.2, and keep the scripts index voice cluster intact.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Same validated change as kunchenguid#2945, opened here so it can be merged on this fork. Head
b96295f7.Intent
Implement the approved quota-dashboard design from data/fm-quota-dashboard/report.md so the captain can open remaining AI credits from his iPhone on the existing tailnet. Requirements: ship a small stdlib-only Python server under bin/ (bin/fm-quota-dashboard-serve.py) that shells 'quota-axi --json' on each data request and serves one self-contained page; no new collector, framework, n8n path, Electron, or public host. Bind only to this host's Tailscale IPv4 address (confirmed live via 'tailscale ip -4'), never 0.0.0.0 or a public interface, and refuse to start if that address cannot be confirmed. Do not emit account emails, tokens, or credential paths in the page - only plain 'quota-axi --json' is ever called, never '--full' (which is the flag that would add account emails). Layout matches the report: fleet summary line, one card per provider, live/signed-out/error states rendered using quota-axi's own strings verbatim, client refresh about every 30s via setInterval, no client-side quota math beyond countdown formatting from each window's resetsAt. Added executable tests (tests/fm-quota-dashboard-serve.test.sh) covering bind-host refusal of non-tailnet addresses (wildcard 0.0.0.0, a public address not owned by this host, and an unconfirmable tailscale address), JSON passthrough without secrets (byte-exact passthrough of quota-axi's own --json output, proving no --full flag is ever passed), and the page/data/404/502 routes - all through the running server's public HTTP interface via PATH-shimmed tailscale/quota-axi stubs, never by reading implementation source. Documented how to start it and the phone URL (http://:/, MagicDNS equivalent, and an optional user-level systemd unit that stays local/operator-owned) in the script's own header comment plus a one-line docs/scripts.md index entry, per this repo's mechanics-tier documentation convention (header/--help is authoritative, docs/scripts.md is just the pointer). No systemd unit file was added to the tracked tree since there is no existing precedent in this repo for tracked systemd units and the unit is optional/operator-copied. Verified end-to-end against the real quota-axi and real tailscale on this host, and visually verified the rendered page in a real browser at iPhone width (390x844) matches the report's screenshot evidence (single-column card grid, status dots, pace-colored bars, provider-specific signed-out/error text). This is a ship task on firstmate's own repo (shared tracked material) delivered via the no-mistakes pipeline per the project's standing delivery posture.
Later accepted requirements that a reviewer reading only the diff would otherwise flag as surprises: pace-behind and pace-on_pace both render green, pace-unknown stays grey, pace-ahead is red. Stale providers keep cached windows and numbers but must look stale (distinct mark plus quota-axi's own last-refreshed line from state.refreshedAt) and must not count as live. The 502 body stays the short exception message; do not put quota-axi stderr on the page because that can include credential paths. QUOTA_AXI_TIMEOUT_SECS is 45 so the shell-out outlives quota-axi's chained 15s provider aborts and a partial report can reach the page. The default-path bind test uses 127.0.0.2 and proves 127.0.0.1 is refused, so a wildcard listener cannot pass. The docs/scripts.md index row sits after the voice cluster, not inside it. percentRemaining labels use Math.round to match quota-axi's TUI; bar width uses the raw value. Push target is the bingb0t5/firstmate fork. Never use --yes; ask-user findings escalate.
What Changed
quota-axi --jsondata and renders provider status, quota windows, pace, and reset countdowns.Risk Assessment
✅ Low: The change is well-bounded and conforms to the stated dashboard, tailnet binding, data passthrough, privacy, documentation, and executable-test requirements, with no material source defect found.
Testing
The focused public-HTTP suite passed bind refusal, exact secret-safe JSON passthrough, cache headers, page/data/404/502 routes, and address-scoped listening; the real tailscale and quota-axi integration served successfully, Chrome confirmed the approximately 30-second refresh cycle, and the 390x844 screenshot showed a clean single-column dashboard without horizontal overflow.
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
tests/fm-quota-dashboard-serve.test.sh:1- The required "executable tests" were added with mode 100644, sotests/fm-quota-dashboard-serve.test.shcannot be run directly using the repository's documentedtests/<subject>.test.shinterface. Change the file mode to 100755, or confirm that non-executable tests are intentionally acceptable despite the stated requirement.🔧 Fix: Make quota dashboard tests executable
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
tests/fm-quota-dashboard-serve.test.shpython3 bin/fm-quota-dashboard-serve.py --helpReal integration checks:tailscale ip -4andquota-axi --jsonStarted the real service withpython3 bin/fm-quota-dashboard-serve.py --port 18787Openedhttp://100.98.227.1:18787/in Chrome at 390x844 and visually inspected the single-column layout, fleet summary, status dots, pace colors, countdowns, and provider-specific error/auth textVerified the rendered viewport hadscrollWidth390 atinnerWidth390Waited 31 seconds and verified the footer advanced fromupdated 5:39:56 PMtoupdated 5:40:26 PM; Chrome network history showed repeated successful/data.jsonrequestsStopped the browser and server, then confirmedgit status --shortremained clean✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.