chore: blog full QR output + dashboard screenshot, hero script phone setup scene (#75)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #75.
This commit is contained in:
Razvan Dimescu
2026-04-10 22:34:41 +03:00
committed by GitHub
parent 2c20c56421
commit 23ff3ce455
3 changed files with 52 additions and 22 deletions

View File

@@ -132,20 +132,41 @@ $ numa setup-phone
Numa Phone Setup
Profile URL: http://192.168.1.16:8765/mobileconfig
Profile URL: http://192.168.1.10:8765/mobileconfig
▀▀▀▀▀▀▀█▀▀██ ██ ▀█▀▀▀▀▀▀▀
█▀▀▀█ █▀▄▀▀▀▀▄▄█ █▀▀▀█
...
██████████████████████████████████
███████████████████████████████████
████ ▄▄▄▄▄ ██ ▀█ ▀▀▀▄▀ ▀▀█ ▄▄▄▄▄ ████
████ █ █ █ ▄▀ ▄█▀▄▀█▄▀█ █ █ ████
████ █▄▄▄█ █ ▀▄▄ ▀ █▄▀▀█▀█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀▄▀▄█▄█ █▄█▄█▄▄▄▄▄▄▄████
████ ▀▄▄▄▄▄█▀ ▀██▄ ▄ ▄▀█▀█ ▄ ▄▄█▀████
█████▄▄▀▄▀▄▄█▄ ▀████▀▄▄▀█▀▀▄ ██▀█████
████▄██▄ ▀▄ █ █ █▀█▄▄██ ▄▄▀▄▀▄ █▀████
█████ ▀ ▄▀ ▄▀▄ ▄▄▀ ██ ▄▀██▄▀█████
████ ▀▀ █▄█▄▀ ▄ █▄ ▄█▀▄ ▀█▀▀ █▀████
████ ██▀█ ▄▄▀█▄▄██▀▄▀ ▀█▄▀ █▀▄▄▀█████
████▄█▄▄▄▄▄█▀▄█▄█▀▀ ▀██▀ ▄▄▄ ▀ ████
████ ▄▄▄▄▄ █▀▀▀▀ ▄█▀ ▀▄ █▄█ ▄▄▀█████
████ █ █ █ ▄ ██▀▄ ▄▄██ ▄ ▄▄▄██████
████ █▄▄▄█ █▄ ▄▀▀▄▄█▀▄▀▄ ▀▄▀ ▄█ █████
████▄▄▄▄▄▄▄█▄▄█▄▄▄█▄█▄▄██████▄▄██████
█████████████████████████████████████
On your iPhone:
1. Open Camera, point at the QR code, tap the yellow banner
2. Allow the download when Safari asks
3. Settings "Profile Downloaded" → Install
4. Settings → General → About → Certificate Trust Settings
3. Open Settings — tap "Profile Downloaded" near the top
(or: Settings → General → VPN & Device Management → Numa DNS)
4. Tap Install (top right), enter passcode, Install again
5. Settings → General → About → Certificate Trust Settings
Toggle ON "Numa Local CA" — required for DoT to work
```
The same QR is available in the dashboard — click "Phone Setup" in the header and the popover renders an SVG QR code pointing at the mobileconfig URL. On mobile viewports it shows a direct download link instead.
<img src="../phone-setup-dashboard.png" alt="Numa dashboard with Phone Setup popover showing QR code and install instructions">
Step 4 is non-negotiable. Even though the CA is bundled in the same profile that installs the DNS settings, iOS still requires the user to explicitly toggle trust in Certificate Trust Settings. It's a deliberate iOS policy to prevent profile-based trust injection — annoying, and correct.
I've been dogfooding this since v0.10 shipped in early April. The phone resolves through Numa over DoT whenever I'm home; persistent connections are visible in the log as a single source port living through dozens of queries. The one real caveat: if the laptop's LAN IP changes, the profile breaks. [RFC 9462 DDR](https://datatracker.ietf.org/doc/html/rfc9462) fixes that — Numa can respond to `_dns.resolver.arpa IN SVCB` with its current IP and iOS picks it up on each network join. Next piece of work.

View File

@@ -7,18 +7,19 @@
# The script:
# 1. Opens the dashboard in Chrome --app mode (clean, no address bar)
# 2. Generates DNS traffic (forward, cache hit, blocked)
# 3. Types "peekm" / "6419" into the Local Services form on camera
# 4. Shows LAN accessibility badge ("local only" / "LAN")
# 5. Checks a blocked domain
# 6. Opens peekm.numa to show the proxy working
# 7. Records via ffmpeg and converts to optimized GIF
# 3. Opens Phone Setup QR popover
# 4. Types "peekm" / "6419" into the Local Services form on camera
# 5. Shows LAN accessibility badge ("local only" / "LAN")
# 6. Checks a blocked domain
# 7. Opens peekm.numa to show the proxy working
# 8. Records via ffmpeg and converts to optimized GIF
set -euo pipefail
# --------------- Configuration ---------------
OUTPUT="${1:-assets/hero-demo.gif}"
PORT=5380
RECORD_SECONDS=20
RECORD_SECONDS=24
VIEWPORT_W=1800
VIEWPORT_H=1100
FPS=12
@@ -230,8 +231,16 @@ dig @127.0.0.1 github.com +short > /dev/null 2>&1
dig @127.0.0.1 ad.doubleclick.net +short > /dev/null 2>&1
sleep 3
# --------------- Scene 2: Add peekm service via UI (3-7s) ---------------
log "Scene 2: Adding peekm.numa service..."
# --------------- Scene 2: Phone Setup popover (3-7s) ---------------
log "Scene 2: Phone Setup QR popover..."
run_js "document.querySelector('#phoneSetup button').click();"
sleep 3
# Dismiss popover
run_js "document.getElementById('phoneSetupPopover').style.display = 'none';"
sleep 1
# --------------- Scene 3: Add peekm service via UI (7-11s) ---------------
log "Scene 3: Adding peekm.numa service..."
# Services panel is now first — scroll to it
run_js "
@@ -249,18 +258,18 @@ sleep 0.3
run_js "document.querySelector('#serviceForm .btn-add').click();"
sleep 2
# --------------- Scene 3: Open peekm.numa (7-11s) ---------------
log "Scene 3: Opening peekm.numa in browser..."
# --------------- Scene 4: Open peekm.numa (11-15s) ---------------
log "Scene 4: Opening peekm.numa in browser..."
open "http://peekm.numa/view/peekm/README.md" 2>/dev/null || true
sleep 4
# --------------- Scene 4: Back to dashboard (11-14s) ---------------
log "Scene 4: Back to dashboard — LAN badges + LOCAL queries visible..."
# --------------- Scene 5: Back to dashboard (15-18s) ---------------
log "Scene 5: Back to dashboard — LAN badges + LOCAL queries visible..."
osascript -e "tell application \"System Events\" to set frontmost of (first process whose unix id is $CHROME_PID) to true" 2>/dev/null || true
sleep 3
# --------------- Scene 5: Check Domain blocker (14-17s) ---------------
log "Scene 5: Check Domain — blocked tracker..."
# --------------- Scene 6: Check Domain blocker (18-21s) ---------------
log "Scene 6: Check Domain — blocked tracker..."
# Scroll down to blocking panel
run_js "
var blockPanel = document.getElementById('blockingPanel');
@@ -273,8 +282,8 @@ sleep 0.3
run_js "document.querySelector('#checkDomainInput').closest('form').querySelector('.btn').click();"
sleep 2
# --------------- Scene 6: Terminal-style dig overlay (17-20s) ---------------
log "Scene 6: dig proof overlay..."
# --------------- Scene 7: Terminal-style dig overlay (21-24s) ---------------
log "Scene 7: dig proof overlay..."
DIG_RESULT=$(dig @127.0.0.1 peekm.numa +short 2>/dev/null | head -1)
run_js "
var overlay = document.createElement('div');

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB