skills/qa-sync/SKILL.md
Synchronize the markdown test plan in docs/qa/ with the current state of the codebase. Use after adding or modifying features to keep the plan up to date, or to bootstrap a test plan for the first time. Do NOT use to execute tests (use /qa-run instead) and do NOT use to design product specs (use /express-need instead).
npx skillsauth add nicolas-codemate/claudecodeconfig qa-syncInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Keep docs/qa/*.md in sync with the codebase. This skill:
qa-writer agent.docs/qa/README.md as an index.This skill writes files. It does not commit them — the user reviews the diff and commits when ready.
| Flag | Default | Effect |
|---|---|---|
| --from <commit> | auto-detected from git log -- docs/qa/ | Override the diff base commit |
| --flow <name> | all flows | Restrict the sync to a single flow file (e.g., auth) |
| --dry-run | off | Print the operations without writing anything |
Read .claude/ticket-config.json (the existing project workflow config). Check whether it has a qa section. If .claude/ticket-config.json does not exist at all, instruct the user to run /init-project first and stop. Do NOT create it from this skill — that is /init-project's job.
If a qa section already exists, skip to Step 2.
If no qa section exists, run the bootstrap wizard described in
references/bootstrap.md: architecture detection, base URL
auto-detection, Docker preflight and pre-run hook questions, the Symfony-specific proposal,
the config write, and the supporting files. Come back here for Step 2 once it is written.
Resolve the base commit:
if [ -n "$FROM_FLAG" ]; then
BASE="$FROM_FLAG"
IS_FIRST_RUN=0
else
BASE=$(git log -n 1 --format=%H -- docs/qa/ 2>/dev/null)
IS_FIRST_RUN=0
fi
if [ -z "$BASE" ]; then
BASE=$(git rev-list --max-parents=0 HEAD | tail -n 1)
IS_FIRST_RUN=1
fi
Collect the application diff (filter to web-relevant files; exclude tests and tooling):
git diff --stat "$BASE"..HEAD -- \
':!*.test.*' ':!*.spec.*' ':!__tests__/' \
':!*.lock' ':!*.lockb' ':!*.lock.json' \
':!.github/' ':!docs/qa/' \
'*.tsx' '*.ts' '*.jsx' '*.js' '*.vue' '*.svelte' \
'*.php' '*.py' '*.rb' '*.go' \
'src/' 'app/' 'pages/' 'routes/' 'controllers/' 'views/' 'templates/'
If the diff is empty, output No application changes since last QA sync. Test plan is up to date. and exit.
Otherwise capture the same range with git diff (full content) and measure the size:
DIFF_BYTES=$(git diff "$BASE"..HEAD -- <same path filters as above> | wc -c)
| Scenario | Diff size | Strategy |
|---|---|---|
| Incremental sync | ≤ 200 KB | Inline the full diff in the agent prompt (current default). |
| Incremental sync | > 200 KB | Print: Le diff dépasse 200 KB depuis le dernier sync (<X> KB). Plusieurs syncs ont probablement été manqués. Relance avec --from <commit> pour cibler un sous-ensemble. Stop the skill. |
| First run | ≤ 200 KB | Inline the full diff (e.g., a small repo or a brand-new project). |
| First run | > 200 KB | Switch to route-map mode (below). Do NOT inline the diff — at first run on a mature codebase, the entire app is "diff", which means inlining produces a payload the agent can't usefully exploit. |
When IS_FIRST_RUN=1 and DIFF_BYTES > 200000:
Build a route map by grepping the project's routing surface. Adapt to the stack detected during bootstrap (references/bootstrap.md §1a):
# React Router (component-style routes)
grep -rEn '<Route[^>]+path=' frontend/src 2>/dev/null
# File-based routers
ls frontend/src/pages/ frontend/src/app/ pages/ app/ 2>/dev/null
# Symfony controllers
grep -rEn "#\[Route\(" src/ 2>/dev/null
# Express / Fastify / Koa
grep -rEn "(app|router)\.(get|post|put|delete|patch)\(" src/ app/ 2>/dev/null
# Django urls.py
grep -rEn "path\(|re_path\(" */urls.py 2>/dev/null
# Laravel routes
cat routes/web.php routes/api.php 2>/dev/null
Run git diff --stat "$BASE"..HEAD -- <filters> and keep the file list (no content).
Pass to the qa-writer agent:
git diff --stat output (filenames only).The agent's Synthesis phase will then operate by reading the source on demand instead of waiting for an inlined diff.
Launch the qa-writer agent with the existing plan plus the diff context. The prompt shape
depends on the mode picked in Step 2 — inline diff by default, route-map on a first run over a
large codebase. Both prompts, and the shared block on preconditions and textual assertions they
both end with, live in references/synthesis-prompts.md.
Capture the agent's ## Operations YAML block and the optional selectors_to_harden: list.
Parse the YAML. For each operation:
ADD: append the scenario block (and a top-level ## <Scenario name> heading derived from the id) to target_file. Create the file if missing with this header:
# <Flow name from filename, capitalized>
Scenarios for the <flow> user flow.
UPDATE with changes: locate the scenario by id (search for id: <ID> in YAML blocks), present the change description as a comment under the scenario heading, then ask the user via AskUserQuestion whether to apply automatically (with current → proposed selector mapping) or open the file for manual edit. Avoid silent surgical edits — selector changes are best reviewed.
UPDATE with replace_with: replace the existing YAML block in place, keeping the section heading.
REMOVE: delete the scenario heading and YAML block. If the file becomes empty, also remove the file (confirm with the user first).
If --flow <name> is set, skip operations whose target_file is not docs/qa/<name>.md.
If --dry-run, print the operations as a table and exit without writing.
docs/qa/README.mdAfter all operations applied, scan docs/qa/*.md (excluding README), count scenarios per file (one scenario = one YAML fenced block with a top-level id: key), and rewrite the index:
# QA Test Plan
Living test plan for this project. Maintained by `/qa-sync`, executed by `/qa-run`.
## Coverage
| Flow | File | Scenarios | Last sync |
|------|------|-----------|-----------|
| Auth | [auth.md](auth.md) | 3 | <date du dernier commit du fichier> |
| Checkout | [checkout.md](checkout.md) | 5 | ... |
**Total:** N scenarios across M flows.
## How to update
- Run `/qa-sync` after merging features to keep this plan current.
- Run `/qa-run [--flow <name>]` to execute scenarios via Playwright.
- Edit individual `<flow>.md` files manually for fine-grained tweaks.
## Format
Each scenario is a fenced YAML block. See [scenario-format reference](../../.claude/skills/qa-sync/references/scenario-format.md) (read by Claude) for the schema.
Use git log -n 1 --format=%cs -- "<file>" for the last sync date per file (ISO date). Fall back to — if no commit yet.
Show the user what changed:
git diff --stat docs/qa/
Print a final block:
## QA sync done
- N operations applied (X added, Y updated, Z removed)
- Files touched: docs/qa/auth.md, docs/qa/checkout.md
- Run `/qa-run` to execute the updated plan, or `git diff docs/qa/` to review.
Commit when ready (skill does not commit automatically).
If the agent returned a selectors_to_harden: list (see qa-writer output format), append a "Selectors to harden" block right after the recap so the user sees the technical debt left by this pass:
## Selectors to harden
The QA plan currently uses fallback selectors for the following elements. Add a stable
test attribute (matching the project's convention) to each so future syncs can use it:
- `frontend/src/pages/NotFoundPage.tsx` — Go Home link → suggested `data-testid=not-found-go-home-link` (used by NOT-FOUND-01)
- `frontend/src/components/AnnotationCard.tsx` — Delete button → suggested `data-testid=delete-annotation-btn` (used by ANNOTATIONS-DELETE-01)
Treat this as a small follow-up PR — once these attributes land, re-run `/qa-sync` to tighten the scenarios.
Skip this block entirely if the list is empty or absent.
qa-writer output: if the agent returned an empty operations: [], do not regenerate the README. Print the agent's note and exit.ADD op uses an id already present in another file, stop and ask which file should own it.git diff docs/qa/ and commits manually (or via /commit)./qa-run./express-need.development
Method to diagnose and raise the Lighthouse performance score of a public page (landing, marketing, home). Use when asked to improve Lighthouse/PageSpeed scores, when auditing the first uncached paint of a public page, or when a landing embedded in a SPA must reach a top score. Do NOT use for in-app screen performance (data loading, rendering). For a brand-new landing, the first recommendation is static HTML with no framework runtime — most of this skill exists for when that is not an option.
tools
Audits a project's Claude Code setup against real usage — mines the project's conversations (worktrees included), confronts the project's skills/agents/CLAUDE.md with best practices, and proposes adjustments or new skills/agents/rules. Use when the user asks to audit the project config, analyze project conversations, or find automation opportunities for the current project. Do NOT use for the global ~/.claude configuration (use /audit-config instead).
development
Coaching workflow orchestrator. Guides the developer through implementation without writing code.
development
Disciplined methodology for code architecture refactoring. Use when the user asks to refactor architecture, decouple code, restructure a family of classes, redesign an interface, or rename/reorganize a set of related components. Forces a big-picture analysis before any code is written. Do NOT use for simple bug fixes, feature additions, or single-file refactoring.