feat(app): one-click Crunch — upload the pack, stream progress, land crunch.json (#19)#20
Merged
Conversation
…crunch.json
Welds the pack → crunch → crunch.json round-trip into the app (was: manual
tar/upload/poll/copy-back). A Crunch button per take tars everything except
the full-res camera master (crunch analyses camera.proxy.mp4; the master
stays local for edator), streams it to POST /pack with the hostname pinned
to the origin's public IP — Cloudflare Free caps bodies at 100MB and real
packs blow through that — then polls the job and writes the result to
<take>/crunch.json.
- src-tauri/crunch.rs: tar (shell-out, COPYFILE_DISABLE, explicit file
list), 300MB origin-cap pre-check, origin reachability check with a clear
error, streamed multipart upload (never held in RAM), 5s poll with
transient-error tolerance, roll://crunch events mirroring roll://state.
- crunch.job marker in the take dir → a relaunch resumes polling any job
the last session left in flight (processing runs ~0.6-0.7x realtime).
- Config in ~/.config/roll/config.json ({"crunch_api_key": …}; URL/origin
default) — the key never touches the repo.
- UI: CrunchControl in the library rows + inspector chips — live stage
label, a real progress fill for ocr (the only counted stage), crunched
badge, Re-crunch (crunch keeps improving), Retry with the error on hover.
- NOTE: the origin default is the box's PUBLIC IP, not the tailnet IP as
issue #19 specified — tailscale serve owns tailnet:443 on that box, so
TLS to the tailnet IP gets alerted before Traefik ever sees it.
Closes #19
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
What
Closes #19. The pack → crunch →
crunch.jsonround-trip is now a button.camera.mp4(crunch analysescamera.proxy.mp4; the master stays local for edator), streams it toPOST /pack, pollsGET /jobs/{id}every 5s, writes theresultto<take>/crunch.json.roll://crunchevents following theemit_statepattern — live stage label, real progress fill forocr(the only counted stage), spinner,crunchedbadge, Re-crunch (crunch keeps improving), Retry with the error on hover.crunch.jobmarker 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).~/.config/roll/config.json→{"crunch_api_key": "…"}(URL + origin have defaults). The key never touches the repo.crunch.rsmodule; 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.The issue pins the origin to the tailnet IP (
100.110.19.65:443) — that can't work:tailscale serveowns 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.CRUNCH_E2E_DIR=… cargo test e2e -- --ignored) driving the production functions against real crunch with a real 12s pack: tar 5MB → 202 jobtXyJwvFC→ocr 4/14→transcribe→analyze→completed→ crunch.json landed with the full result (camera/events/moments/segments/transcript), 20.8s end to end.🤖 Generated with Claude Code