Stu Mason · Folkestone, Kent
One entryMerged PR· StuMason/roll· Swift

PR #20 merged: feat(app): one-click Crunch — upload the pack, stream progress, land crunch.json (#19)

additions
+1287
deletions
-14
files changed
10

What

Closes #19. The pack → crunch → crunch.json round-trip is now a button.

  • Crunch per take (library rows + inspector chips): tars everything except camera.mp4 (crunch analyses camera.proxy.mp4; the master stays local for edator), streams it to POST /pack, polls GET /jobs/{id} every 5s, writes the result to <take>/crunch.json.
  • Status via roll://crunch events following the emit_state pattern — live stage label, real progress fill for ocr (the only counted stage), spinner, crunched badge, Re-crunch (crunch keeps improving), Retry with the error on hover.
  • Resume: a crunch.job marker sits in the take dir while a job's in flight; on relaunch the app resumes polling anything the last session left running (~0.6–0.7× realtime processing is long enough to quit mid-crunch).
  • Fail fast: >300MB pre-check before taring; origin reachability check before any work, with the actual problem in the message.
  • Config: ~/.config/roll/config.json{"crunch_api_key": "…"} (URL + origin have defaults). The key never touches the repo.
  • Rust: crunch.rs module; tar via shell-out (COPYFILE_DISABLE, explicit file list — same lessons as roll-push.sh), streamed multipart (never held in RAM). New deps: reqwest / tokio / tokio-util.

⚠️ One deviation from the issue

The issue pins the origin to the tailnet IP (100.110.19.65:443) — that can't work: tailscale serve owns tailnet:443 on the box (it proxies the ts.net dashboard), so TLS with the crunch SNI gets alerted before Traefik ever sees it. The default origin is the box's public IP (159.195.194.97:443) instead — still zero Cloudflare in the path (no 100MB cap), still validates the real LE cert (verified: curl --resolve → 200, /pack → 401 without key), and works even when the tailnet's down.

Verified

  • cargo test: 6 unit tests (tar contract: master excluded, plain relative paths, no AppleDouble; config defaults) — green, 0 warnings. tsc + vite build clean.
  • Live e2e (CRUNCH_E2E_DIR=… cargo test e2e -- --ignored) driving the production functions against real crunch with a real 12s pack: tar 5MB → 202 job tXyJwvFCocr 4/14transcribeanalyzecompleted → crunch.json landed with the full result (camera/events/moments/segments/transcript), 20.8s end to end.

🤖 Generated with Claude Code