launch
SkillMediaRun the Inspector app locally, any mode (dev bucket / offline fixtures / live dev or prod Space), any worktree, conflict-free.
Use launch in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add launch and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the launch skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
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
- 44
- Forks
- 6
- Last commit
- Oct 2026
- Hacker News mentions
- 20
Advanced
- Item type
- skill
- Key
launch-qud-technologies- Source
- github.com/qud-technologies/quranic-universal-audio
github.com/qud-technologies/quranic-universal-audio
Related picks
Skill · thedaviddias
The pick for JavaScriptmodern-javascript-patterns
Skill · wshobson
The pick for JavaScriptpython-performance-optimization
Skill · wshobson
The pick for Pythonpython-pro
Skill · jeffallan
The pick for Pythonintegration-flask
Skill · posthog
The pick for Flaskflask-api-development
Skill · aj-geddes
The pick for Flask