billy-lyc/neuropilot/qc-agent-skill
Claude Code and agent skill by billy-lyc/neuropilot
- community
Checking that the SKILL.md file is still in the repository.
Semi-automatic QC agent for structural MRI (T1w and T2w). Runs Raw Image QC → Brain Extraction QC → Registration QC → Segmentation QC (T1w only) → Surface QC (T1w only). For each step: auto-detects and localises problems in the image, shows annotated PNG, proposes fix, user says yes/no, agent applies fix and shows before/after. Use when the user wants to QC T1w or T2w images, check skull stripping, registration, FreeSurfer segmentation, or generate a QC report.
Install
npx vskill@latest install billy-lyc/neuropilot/qc-agent-skillSKILL.md
Structural QC Agent (T1w / T2w)
Typemenuat any time to return to the step selection menu.
## 🔒 OUTPUT TARGET + DISMISS (cross-step contract — ask FIRST, applies to all 5 steps)Before step 1, the FIRST thing the skill MUST ask the user is where corrected/kept data goes(steps/_shared/qc_target.py→$QC_OUT/qc_target.json):- `overwrite` (default) — fixes are applied IN PLACE in the source dataset; dismissed subjects are left untouched.- `new` — create a fresh output folder and COPY each kept+fixed subject into it; dismissed subjects are simply never copied.- `custom <path>` — same asnewat a user-given path.DISMISS = the user drops a subject. Any step's review can dismiss →POST /dismiss→appended to the ONE shared$QC_EXCLUDED($QC_OUT/excluded_subjects.json, viaqc_exclude.py).Every later step's generator already filters this list (step1 dashboard, qc_html, step3build_html1,step407/08, step503/06) — a dismissed subject never reappears downstream.-new/custom: a dismissed subject is NOT copied to the output.overwrite: it is left alone in source.- After step 5, runpython steps/_shared/qc_dismissed_report.py→$QC_OUT/dismissed_subjects.{md,html}= a table of everything the user dropped. REPORT only — never auto-delete the user's data.SIGN-OFF = every "Export decision" button (all 5 steps) is gated by a reviewer-signature modal(steps/_shared/qc_sign_js.py→qcSign()): it requires Full name + Onyen/email + a confirmcheckbox before the export proceeds (identity remembered inlocalStorage, re-confirmed each export).On confirm itPOST /sign→ appended to$QC_OUT/signoffs.json(audit ledger, never overwritten:{by, onyen, step, at, summary}) so a supervisor can see WHO confirmed each batch. The server thatserves the dashboards (scripts/qc_server.py) holds both/dismissand/sign; if a page reportsunknown endpointon sign/dismiss, the servedqc_server.pyis stale — restart it.
Core interaction loop (applies to every QC step)
Every step follows this exact pattern:
CRITICAL: Never show a PNG as a file path or markdown link. Always use SendUserFile so the image renders inline. Every PNG must be sent immediately after it is generated — before showing any text description.
The re-run option ([R]) must always appear, even after a successful autofix. If user chooses re-run: ask which parameters to change, submit SLURM job, wait, re-QC from this step.
NEVER silently apply any fix. Always tell the user what was found and ask before touching anything.
Severity tiers — how to present and what to offer
| Tier | When | What to say | Options to offer | |
|---|---|---|---|---|
| Mild | Issue present but unlikely to affect downstream analysis | "Small issue found: [X]. OK to fix directly." | Fix / Skip | |
| Moderate | Clear problem; rerunning the pipeline is the natural first fix | "Issue found: [X]. A pipeline rerun is likely to fix this." | Rerun / Manual fix / Skip | |
| Severe | Complete failure OR rerun almost certainly won't help | "Severe issue: [X]. Rerun unlikely to help — attempting manual fix." | Manual fix / Skip |
How to judge "rerun won't help":
- NCC < 0.45 AND NMI < 0.06 after ANTs re-registration → image itself has quality issues
- Euler < −500 after checking skull strip quality → surface topology is too damaged
- dseg > 50% labels missing → segmentation never ran or input was wrong
True UNSAFE (only 2 cases — flag and stop, do not attempt fix)
- Raw image is empty or all-zero (data is gone)
- Image is clearly not a brain (wrong scan acquired)
Everything else: attempt a fix.
Step 0 — Collect inputs
Follow this exact sequence: paths first → discover subjects → select subject → details.
Step 0a — Paths:
Ask:
- "What is your BIDS root directory? (raw input data, e.g. /path/to/bids)"
- "What is your derivatives root directory? (pipeline outputs — fMRIPrep, FreeSurfer, etc.)"
Step 0b — Discover subjects (agent runs automatically):
List discovered subjects, then ask user to select.
Step 0c — Session, modality, QC output directory:
Auto-detect sessions:
Ask: session / modality (T1w or T2w) / output directory.
Fixed files always go to `$QC_OUT/fixed/`.
After all inputs confirmed:
═══ T1w PIPELINE ═══
Step 1 — Raw Image QC
(Corresponds to IBIS Phase A/B: "Did we get usable data?" + "Which series to use?")
⭐ LOCKED — canonical Step-1 cohort review pipeline (use this exact format for every new dataset)
This is the fixed, agreed solution. Reuse the same scripts, the same call order, and the same HTML logic on any new cohort. Do NOT substitute other generators.
Scripts (do not swap):
- detection (per subject) →
check_raw_image.py→ writes one*_step1.jsonper subject (holds the
grade: PASS/WARN/FAIL, slightly stricter than MRIQC) + a 3-view screenshot.
- cohort review HTML → `generate_interactive_dashboard.py` (this is THE generator). It renders
whatever grade is in the *_step1.json and produces the dashboard_v5-style page: MRIQC comparison panel, per-card screenshot, an inline niivue viewer under each screenshot, per-card decision buttons, exportDecisions() + copyJson(), and the POST `/save` auto-save to the cluster. No motion-score-distribution bar.
- Decision buttons (LOCKED): exactly three — `PASS` / `DISMISS` / `FLAG`, keyboard `1` / `2` / `3`.
There is NO "APPLY FIX" button (removed — Step 1 is raw-image triage, not a fix stage). Do not re-add it or renumber the keys.
- 🧊 Per-card inline niivue viewer (LOCKED — same machinery as Step-2 review): each card embeds a
real niivue <canvas> UNDER its screenshot (same width) showing THAT subject's raw T1 (*_step1.json → data["path"], grayscale — no mask in Step 1), scroll=slice / drag=pan / scroll=zoom. niivue is imported in-page from the jsDelivr ESM CDN (@niivue/niivue@0.67.0/+esm); volumes are served same-origin by qc_server.py's POST /stage_all (symlinks under <served-dir>/_nv_vols/). Canvas MUST be position:absolute;inset:0 inside a fixed-height .nv-canvas-wrap (else it grows forever); toggleCard()→window.__nvEnsure(idx) inits a viewer only when its card opens. This REPLACES the old freeview-window "View 3D" button (no iframe, no port 9081 — tunnel only the dashboard port 8802).
- serve + JSON auto-save + same-origin volumes →
qc_server.py(GET no-cache +POST /save+POST /stage_all).
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingqc-agent-skill/SKILL.md
Popularity
- Repository stars
- 54
- Repository forks
- 5
- 7-day trend score
- 20
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/billy-lyc/neuropilot/qc-agent-skill)