Skip to content

feat(bin): serve quota dashboard on the tailnet - #3

Merged
bingb0t5 merged 7 commits into
mainfrom
fm/fm-quota-dashboard-ship
Aug 24, 2026
Merged

bingb0t5 merged 7 commits into
mainfrom
fm/fm-quota-dashboard-ship

Conversation

@bingb0t5

@bingb0t5 bingb0t5 commented Aug 24, 2026 •

Copy link
Copy Markdown
Owner

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

  • Add a stdlib-only, self-contained quota dashboard that refreshes quota-axi --json data and renders provider status, quota windows, pace, and reset countdowns.
  • Restrict the server to a confirmed local Tailscale IPv4 address, with safe 404 and upstream 502 handling.
  • Document startup and phone access, with executable HTTP-level coverage for binding, routes, JSON passthrough, and secret-safe invocation.

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, so tests/fm-quota-dashboard-serve.test.sh cannot be run directly using the repository's documented tests/<subject>.test.sh interface. 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.sh
  • python3 bin/fm-quota-dashboard-serve.py --help
  • Real integration checks: tailscale ip -4 and quota-axi --json
  • Started the real service with python3 bin/fm-quota-dashboard-serve.py --port 18787
  • Opened http://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 text
  • Verified the rendered viewport had scrollWidth 390 at innerWidth 390
  • Waited 31 seconds and verified the footer advanced from updated 5:39:56 PM to updated 5:40:26 PM; Chrome network history showed repeated successful /data.json requests
  • Stopped the browser and server, then confirmed git status --short remained clean
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

kunchenguid and others added 7 commits August 24, 2026 02:33
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.
@bingb0t5
bingb0t5 merged commit 0caa2d3 into main Aug 24, 2026
13 of 14 checks passed
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.

2 participants