launch
SkillMediaRun the Inspector app locally, any mode (dev bucket / offline fixtures / live dev or prod Space), any worktree, conflict-free.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the launch skill
What this skill tells your AI
The instructions your AI receives, as published by qud-technologies/quranic-universal-audio in .claude/skills/launch/SKILL.md and read by ahel’s review.
One script runs every way of starting the Inspector and keeps parallel launches from colliding. You almost never need to think — just run it.
python scripts/devenv/launch.py [up] [--mode MODE] [flags]
The script (scripts/devenv/launch.py) owns everything that used to go wrong by hand: free-port allocation, per-worktree SQLite isolation (INSPECTOR_DB_PATH), interpreter pinning (sys.executable, so no python3-vs-Python313 split), Vite⇄backend proxy wiring, readiness polling (/healthz + the Vite port), and a machine-wide registry so it can list / down / doctor every stack. It prints human URLs and a LAUNCH_JSON {…} line an agent can parse.
Just run it
| Goal | Command |
|---|---|
| Run the app (real DEV data, default) | python scripts/devenv/launch.py |
| Read-only look at PROD data (local) | python scripts/devenv/launch.py up --mode prod |
| Fully offline (no token/network) | python scripts/devenv/launch.py up --mode fixtures |
| Run a different worktree | `… up --worktree <name |
| Open in a browser too | … up --open |
| What's running? | python scripts/devenv/launch.py list |
| Stop this worktree's stack | python scripts/devenv/launch.py down |
| Stop everything | python scripts/devenv/launch.py down --all |
| Fix "wrong port / two Flasks / stale Vite" | python scripts/devenv/launch.py doctor --fix |
Modes
Every mode is fully local — your branch's Flask backend + Vite, no HF Space proxy, no hf-mount. Bucket reads use the hffs fallback (sub-second on the dev bucket; the bigger prod bucket is slower, multi-second cold); audio CDN-falls-back via the proxy. The only thing that changes between modes is which data the backend reads. Needs HF_TOKEN (in .env) for the bucket modes.
- dev (default) — backend reads the DEV bucket, read-write. The everyday mode: runs your branch end-to-end (audio + analysis included), HMR for FE changes.
- prod — backend reads the PROD bucket, read-only (two guards:
INSPECTOR_READ_ONLY=1makes the storage backend refuse every write — segment saves, manifests, job records — andINSPECTOR_DB_SYNC=0keeps DB commits local). Nothing local can mutate production by any path; an edit attempt fails loud rather than corrupting prod. A safe look at real production data. First reads are slow (big uncached prod bucket over hffs). - fixtures — fully offline: filesystem backend on seeded fixtures (auto-seeds on first run) + Vite. No token, no network.
Per-content read source
The bucket isn't the fastest source for every content type locally. By default in dev/prod:
- Audio → CDN (not the bucket): the bucket's hffs full-MP3 read is slow locally, and the CDN is the same audio for most reciters.
--bucket-audioforces the bucket (to verify the re-encoded/stereo-fixed audio that can differ from the CDN).fixturesalways reads local audio (offline, no CDN). - Peaks → bucket (slim
peaks/*.json.gz):--ffmpeg-peaksskips them so the FE computes per-segment peaks via ffmpeg instead. - Shards / detailed / manifest → bucket always (no toggle).
Knobs: INSPECTOR_AUDIO_FROM_BUCKET / INSPECTOR_PEAKS_FROM_BUCKET (the launcher owns these per mode; the flags above override).
For agents (driving the running app)
Run up (it starts both backend + Vite), read the LAUNCH_JSON line for the url, then drive that URL with a browser MCP. Use dev (the default).
Default driver: chrome-devtools-mcp. Measured on this app's Dashboard, its a11y snapshot is ~2.6× smaller than playwright's (≈14 KB vs ≈38 KB for the same page), its actions return a one-line ack (snapshot is opt-in, not forced on every call), and it carries the DevTools tools we actually use here — network request bodies, console, performance_start_trace, evaluate_script, throttling/emulation. Net: fewer tokens per step and the right debugging surface.
Reach for playwright instead only for pure interaction (multi-step forms, exploratory clicking) where its auto-snapshot-on-every-action is convenient and you don't need network/console/perf.
Typical loop: navigate_page → take_snapshot (grab the uids) → click/fill by uid → take_screenshot. There's no built-in liveness check — your first navigate + take_snapshot already tells you whether the stack is serving real data.
Parallel & conflict-safety
Two worktrees (or two stacks) can run at once: ports are allocated free + reserved in the registry, and each worktree gets its own INSPECTOR_DB_PATH so the local SQLite never clobbers. doctor detects the failure modes we actually hit — two processes bound to one port (serving stale code), a foreign/orphan Flask or Vite, dead registry entries — and --fix cleans them.
The bucket is NOT isolated, though. All dev stacks (and the live dev Space) share one dev bucket: the DB syncs full-file with a CAS guard (no row merge) and per-reciter content is last-write-wins, so two concurrent dev writers can clobber each other — the single-writer invariant. Launch warns when you start a 2nd dev stack while another is up. For a safe parallel stack use prod (read-only) or fixtures (local disk, fully isolated); only ever edit in one dev stack at a time.
Env ownership (.env vs launch)
The launcher owns every run-mode knob — INSPECTOR_BACKEND, INSPECTOR_FILESYSTEM_ROOT, INSPECTOR_ALLOW_PROD_BUCKET, INSPECTOR_READ_ONLY, INSPECTOR_DB_SYNC, INSPECTOR_AUTO_MOUNT, INSPECTOR_DB_PATH — and sets them per mode, so a stale .env can't perturb the profile. dev forces ALLOW_PROD_BUCKET=0 (can never touch prod; fails closed if .env names the prod repo). .env only supplies secrets + identity (HF/GitHub/QF tokens, session secret, dev-owner id) and the one per-machine choice the launcher reads in dev: your own INSPECTOR_BUCKET_REPO dev bucket. Those knobs in .env matter only when hand-running python inspector/app.py.
Notes
- First run in a fresh worktree needs deps:
scripts/devenv/setup.sh(ornpm ciininspector/frontend). Thewtskill's setup does this. - The full app runs locally on Windows — audio + analysis included, no
hf-mountneeded. Bucket reads go through thehffsfallback (dev bucket sub-second; prod bucket multi-second cold) and audio CDN-falls-back via the proxy. A shard 404 indevis the released-gate (the reciter isn'treleasedin this worktree's isolated DB) or missing bucket data, not a platform limit. FE changes are always live via local Vite. - Logs:
<worktree>/.local/launch/logs/. Registry:<main-worktree>/.local/launch/registry.json(gitignored). - Python changes need a
down+up(Flask reloader is off by design — single-worker invariant). Vite changes hot-reload.
Signals
- GitHub stars
- 33
- Forks
- 4
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
launch-qud-technologies- Source
- github.com/qud-technologies/quranic-universal-audio