一键导入
launch
Run the Inspector app locally — any mode (dev bucket / offline fixtures / live dev or prod Space), any worktree, conflict-free.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Run the Inspector app locally — any mode (dev bucket / offline fixtures / live dev or prod Space), any worktree, conflict-free.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Headless one-off Inspector admin operations — wraps the same services/admin/* and state.transition the UI calls. Use for quick patches when the Reviews/Users/Permissions/Requests UI surface isn't enough — publish a finished TS job, force-unlock a released reciter, cancel + relaunch a stuck HF job, and similar one-off tasks.
Use when localizing the Inspector frontend — extracting UI strings into Paraglide messages, adding/wiring `m.*()` calls in Svelte components, authoring en/ar message JSON, translating chrome to Arabic (MSA), or verifying i18n coverage. Trigger phrases include "internationalize", "localize", "translate to Arabic", "extract strings", "i18n", "add a message key", "wire up the locale switcher".
Screenshot the real Timestamps analysis view (UnifiedDisplay) for any reciter:surah:verse straight from shards — fast, drift-free, no SPA/audio/OAuth.
Deploy any branch to its HF Space directly from the CLI (local, no push) and monitor until the Space is live.
Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface.
Inspector audio subsystem — everything between bytes-on-disk and an `<audio>` element rendering audio in the browser, plus the extraction → bucket → inspector handoff that produces `reciters/<slug>/` in the first place. Covers both debugging AND building audio features.
| name | launch |
| description | Run the Inspector app locally — any mode (dev bucket / offline fixtures / live dev or prod Space), any worktree, conflict-free. |
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.
| 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 |
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.
INSPECTOR_READ_ONLY=1 makes the storage backend refuse every write — segment saves, manifests, job records — and INSPECTOR_DB_SYNC=0 keeps 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).The bucket isn't the fastest source for every content type locally. By default in dev/prod:
--bucket-audio forces the bucket (to verify the re-encoded/stereo-fixed audio that can differ from the CDN). fixtures always reads local audio (offline, no CDN).peaks/*.json.gz): --ffmpeg-peaks skips them so the FE computes per-segment peaks via ffmpeg instead.Knobs: INSPECTOR_AUDIO_FROM_BUCKET / INSPECTOR_PEAKS_FROM_BUCKET (the launcher owns these per mode; the flags above override).
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.
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 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.
scripts/devenv/setup.sh (or npm ci in inspector/frontend). The wt skill's setup does this.hf-mount needed. Bucket reads go through the hffs fallback (dev bucket sub-second; prod bucket multi-second cold) and audio CDN-falls-back via the proxy. A shard 404 in dev is the released-gate (the reciter isn't released in this worktree's isolated DB) or missing bucket data, not a platform limit. FE changes are always live via local Vite.<worktree>/.local/launch/logs/. Registry: <main-worktree>/.local/launch/registry.json (gitignored).down + up (Flask reloader is off by design — single-worker invariant). Vite changes hot-reload.