@appsforgood/next-supabase-kit 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +2 -1
  3. package/UPGRADE.md +12 -0
  4. package/USER_GUIDE.html +62 -13
  5. package/USER_GUIDE.md +37 -10
  6. package/agents/design/agent.md +14 -6
  7. package/agents/qa/agent.md +3 -1
  8. package/dist/index.js +322 -245
  9. package/dist/index.js.map +1 -1
  10. package/examples/next-supabase-installed/.agent-kit/manifest.json +36 -36
  11. package/examples/next-supabase-installed/.antigravity/agent-kit/commands/browser-qa.toml +1 -1
  12. package/examples/next-supabase-installed/.antigravity/agent-kit/commands/frontend.toml +1 -1
  13. package/examples/next-supabase-installed/.antigravity/agent-kit/commands/test.toml +1 -1
  14. package/examples/next-supabase-installed/.antigravity/runtime-skills/accessibility-wcag/SKILL.md +66 -9
  15. package/examples/next-supabase-installed/.antigravity/runtime-skills/browser-qa/SKILL.md +1 -0
  16. package/examples/next-supabase-installed/.antigravity/runtime-skills/deslop/SKILL.md +7 -1
  17. package/examples/next-supabase-installed/.antigravity/runtime-skills/frontend-design/SKILL.md +149 -15
  18. package/examples/next-supabase-installed/.antigravity/runtime-skills/planning/SKILL.md +6 -5
  19. package/examples/next-supabase-installed/.antigravity/runtime-skills/testing-qa/SKILL.md +53 -12
  20. package/examples/next-supabase-installed/.claude/agents/design.md +14 -6
  21. package/examples/next-supabase-installed/.claude/agents/qa.md +3 -1
  22. package/examples/next-supabase-installed/.codex/agents/design.toml +15 -7
  23. package/examples/next-supabase-installed/.codex/agents/qa.toml +3 -1
  24. package/examples/next-supabase-installed/.cursor/agents/design.md +14 -6
  25. package/examples/next-supabase-installed/.cursor/agents/qa.md +3 -1
  26. package/examples/next-supabase-installed/.cursor/skills/accessibility-wcag/SKILL.md +66 -9
  27. package/examples/next-supabase-installed/.cursor/skills/browser-qa/SKILL.md +1 -0
  28. package/examples/next-supabase-installed/.cursor/skills/deslop/SKILL.md +7 -1
  29. package/examples/next-supabase-installed/.cursor/skills/frontend-design/SKILL.md +149 -15
  30. package/examples/next-supabase-installed/.cursor/skills/planning/SKILL.md +6 -5
  31. package/examples/next-supabase-installed/.cursor/skills/testing-qa/SKILL.md +53 -12
  32. package/examples/next-supabase-installed/AGENTS.md +2 -1
  33. package/examples/next-supabase-installed/USER_GUIDE.html +62 -13
  34. package/examples/next-supabase-installed/USER_GUIDE.md +37 -10
  35. package/examples/next-supabase-installed/skills/accessibility-wcag/SKILL.md +66 -9
  36. package/examples/next-supabase-installed/skills/browser-qa/SKILL.md +1 -0
  37. package/examples/next-supabase-installed/skills/deslop/SKILL.md +7 -1
  38. package/examples/next-supabase-installed/skills/frontend-design/SKILL.md +149 -15
  39. package/examples/next-supabase-installed/skills/planning/SKILL.md +6 -5
  40. package/examples/next-supabase-installed/skills/testing-qa/SKILL.md +53 -12
  41. package/examples/next-supabase-installed/tree.txt +12 -0
  42. package/package.json +1 -1
  43. package/research/agent-skill-gap-report.md +4 -0
  44. package/skills/accessibility-wcag/SKILL.md +66 -9
  45. package/skills/browser-qa/SKILL.md +1 -0
  46. package/skills/deslop/SKILL.md +7 -1
  47. package/skills/frontend-design/SKILL.md +149 -15
  48. package/skills/optional/ui-polish/SKILL.md +2 -2
  49. package/skills/planning/SKILL.md +6 -5
  50. package/skills/testing-qa/SKILL.md +53 -12
  51. package/templates/next-supabase/AGENTS.md +2 -1
@@ -1,27 +1,68 @@
1
1
  ---
2
2
  name: testing-qa
3
- description: Use when adding unit, regression, or smoke tests. Visual proof of a screen always also uses browser-qa.
3
+ description: Use when adding unit, regression, or smoke tests, or when someone says tests pass without listing commands. Visual proof of a screen always also uses browser-qa. RLS tests must fail when another user can read the row.
4
4
  ---
5
5
 
6
6
  # Testing QA
7
7
 
8
+ This skill is **commands**. Screenshots live in `browser-qa`. Keyboard pass lives in `accessibility-wcag`. Policies live in `supabase-auth-rls`. Do not replace those.
9
+
8
10
  ## Use when
9
11
 
10
- Adding or reviewing tests, smoke checks, or regression coverage.
12
+ Adding or reviewing tests, smoke, regression, “is this tested?”, or “tests pass.”
13
+
14
+ ## Do
15
+
16
+ 1. Name the kinds this change needs: unit, regression, smoke. Skip kinds that do not apply; do not skip RLS/auth when data is involved.
17
+ 2. Run the commands that already exist in this repo (`package.json` scripts). Do not invent a second test runner.
18
+ 3. For auth, RLS, or mutations: include a **negative** that fails when another user or anon can read or write the row.
19
+ 4. List what ran, the result, and gaps. If the harness is missing, name it; do not skip silently.
20
+ 5. User-visible work still goes to `browser-qa` (and `accessibility-wcag` for screens). Playwright `toBeVisible` is not that handoff.
21
+
22
+ ## Kinds
23
+
24
+ | Kind | What | Not |
25
+ | --- | --- | --- |
26
+ | Unit | Core logic, schema validation, helpers | A screenshot |
27
+ | Regression | Preserved behavior still holds | Rewriting the old test to match a bug |
28
+ | Smoke | Critical path against a running app (login, primary workflow) | `browser-qa` image review |
29
+
30
+ Smoke may use Playwright if the repo already has it. `toBeVisible` proves a node is in the DOM, not that the screen is correct.
31
+
32
+ ## Auth / RLS
33
+
34
+ `supabase-auth-rls` owns the policy. This skill requires a test that would **fail** if another signed-in user can `select` / `update` / `delete` the row, or if anon can read a private row. A hidden button is not a test of access.
35
+
36
+ Shape (adapt to the repo’s harness):
37
+
38
+ ```ts
39
+ // Must fail the job if RLS is missing or too open
40
+ const { data } = await asOtherUser().from("widgets").select().eq("id", ownerRowId);
41
+ expect(data ?? []).toHaveLength(0);
42
+ ```
43
+
44
+ `ENABLE ROW LEVEL SECURITY` without that negative is not coverage.
45
+
46
+ If the change is App Router, Auth/RLS, or a migration, tests must cover those contracts. This skill does not replace `nextjs-app-router`, `supabase-auth-rls`, `postgres-migrations`, or `owasp-security-review`.
11
47
 
12
- ## Checks
48
+ ## Evidence
13
49
 
14
- - Core logic has unit tests.
15
- - Preserved behavior has regression tests.
16
- - Critical flows have Playwright or equivalent smoke tests.
17
- - Auth, RLS, and mutation paths are prioritized (other-user / anon cannot pass).
18
- - Network failure, empty, and error behavior is covered.
19
- - Gaps are named when infrastructure is missing.
50
+ ```text
51
+ commands:
52
+ - npx vitest run tests/rls.test.ts # pass
53
+ - npm run smoke:install # pass
54
+ gaps: no Playwright harness yet; named
55
+ ```
20
56
 
21
- ## Visual proof
57
+ ## Reject
22
58
 
23
- User-visible screens also require `browser-qa`. This skill does not replace screenshots. Passing `toBeVisible` is not image review.
59
+ - `toBeVisible` (or “the test found the button”) as visual proof. Use `browser-qa`.
60
+ - “Tests pass” with no command list and no results.
61
+ - Skipping RLS/auth tests because “it’s just a table” or “we’ll add tests later.”
62
+ - Replacing `browser-qa` or `accessibility-wcag` with this skill.
63
+ - A green suite that would still pass if another user could read the row.
64
+ - Adding Playwright as a required install of this kit. Use it when the repo already has it.
24
65
 
25
66
  ## Done when
26
67
 
27
- Commands run, results, and residual gaps are listed. RLS/auth tests fail closed when another user can read the row.
68
+ Commands run, results, and residual gaps are listed. RLS/auth tests fail closed when another user or anon can read the row. User-visible work still has `browser-qa` evidence.
@@ -16,6 +16,7 @@ A user-visible change is not done until someone opened the running UI, captured
16
16
  | Implement Next.js or Supabase | `@app-engineer` |
17
17
  | Auth, RLS, secrets, OWASP | `@security` |
18
18
  | UI looks wrong / generic | `@design` |
19
+ | Style guide / first UI / no DESIGN.md | `@design` (setup) |
19
20
  | Is this done? | `@qa` |
20
21
  | Headlines, CTAs, empty states | `@copy` |
21
22
 
@@ -23,7 +24,7 @@ Do not ask one chat to be all six.
23
24
 
24
25
  ## Handoff
25
26
 
26
- Planner names the owner. Security joins auth/data/secret work. Design joins user-facing screens. QA joins any behavior or UI change and **must use the browser**. Copy joins public/conversion copy. Stop there.
27
+ Planner names the owner. Security joins auth/data/secret work. Design joins user-facing screens and first-run style-guide setup. QA joins any behavior or UI change and **must use the browser**. Copy joins public/conversion copy. Stop there.
27
28
 
28
29
  ## Skills
29
30
 
@@ -220,12 +220,15 @@
220
220
  }
221
221
 
222
222
  .rule {
223
- border-left: 4px solid var(--safelight);
224
223
  padding: 0.7rem 0.9rem;
225
- background: #1a1814;
224
+ background: #23160f;
226
225
  margin: 0 0 1.4rem;
227
226
  }
228
227
 
228
+ .rule strong {
229
+ color: var(--safelight);
230
+ }
231
+
229
232
  .steps {
230
233
  display: grid;
231
234
  gap: 0.85rem;
@@ -506,6 +509,14 @@
506
509
  <button class="copy" type="button" data-copy-from="plan-prompt">Copy Planner prompt</button>
507
510
  </div>
508
511
  </article>
512
+ <article class="ticket">
513
+ <header><span>New repo — paste this to Design so it asks what you need</span></header>
514
+ <pre id="design-setup-prompt">
515
+ Act as design. This is a new repo. Scan what is already here, then ask me what we need to set up: who it is for, what they must get done, and what you should produce. Recommend from my answers. Write the style guide and principles with me before any CSS.</pre>
516
+ <div class="copy-row">
517
+ <button class="copy" type="button" data-copy-from="design-setup-prompt">Copy Design setup prompt</button>
518
+ </div>
519
+ </article>
509
520
  </div>
510
521
  <p>
511
522
  You should get a named owner (<code>app-engineer</code>, <code>security</code>, <code>design</code>, <code>qa</code>, or <code>copy</code>) and, if
@@ -541,6 +552,10 @@
541
552
  <td>It looks wrong</td>
542
553
  <td>Design</td>
543
554
  </tr>
555
+ <tr>
556
+ <td>Style guide / first UI / no DESIGN.md</td>
557
+ <td>Design (<code>setup</code>)</td>
558
+ </tr>
544
559
  <tr>
545
560
  <td>Is this done?</td>
546
561
  <td>QA</td>
@@ -583,11 +598,11 @@
583
598
  </tr>
584
599
  <tr>
585
600
  <td><code>frontend-design</code></td>
586
- <td>Layout, simple palette, anti-generic UI</td>
601
+ <td>Setup, build, review, or detect UI. Tokens first. Anti-generic</td>
587
602
  </tr>
588
603
  <tr>
589
604
  <td><code>accessibility-wcag</code></td>
590
- <td>Keyboard, contrast, labels</td>
605
+ <td>Keyboard pass in the running browser. Contrast, labels. Not a screenshot guess</td>
591
606
  </tr>
592
607
  <tr>
593
608
  <td><code>browser-qa</code></td>
@@ -595,7 +610,7 @@
595
610
  </tr>
596
611
  <tr>
597
612
  <td><code>testing-qa</code></td>
598
- <td>Unit / regression / smoke only</td>
613
+ <td>Unit / regression / smoke. List commands run. Not screenshots</td>
599
614
  </tr>
600
615
  <tr>
601
616
  <td><code>product-copy</code></td>
@@ -612,8 +627,9 @@
612
627
  </tbody>
613
628
  </table>
614
629
  <p>
615
- QA of a screen always uses <code>browser-qa</code>, not <code>testing-qa</code> alone. Each agent file names the skills it must run, then points at
616
- <code>catalog.json</code> for the rest.
630
+ QA of a screen always uses <code>browser-qa</code>, not <code>testing-qa</code> alone. User-facing screens also run
631
+ <code>accessibility-wcag</code> (keyboard in the browser, not a contrast guess from the screenshot). Each agent file names the skills it must run,
632
+ then points at <code>catalog.json</code> for the rest.
617
633
  </p>
618
634
  </section>
619
635
 
@@ -677,17 +693,45 @@ Act as the QA agent. Use the browser-qa skill. Do not review code alone. Open th
677
693
  <li>Planner — paste the prompt on ticket 03.</li>
678
694
  <li>App engineer — <code>Implement the plan. Smoke the changed route in the browser before you hand off.</code></li>
679
695
  <li>Security if data, auth, or secrets changed.</li>
680
- <li>Design if the UI changed — <code>Review the running UI from screenshots first. Desktop and mobile. Reject generic AI-looking layout.</code></li>
681
- <li>QA paste the good prompt below.</li>
696
+ <li>
697
+ Design if the UI changed
698
+ <code
699
+ >Act as design. Name the mode (setup, build, review, or detect). Review the running UI from screenshots first. Desktop and mobile. Reject generic
700
+ AI-looking layout.</code
701
+ >
702
+ If <code>DESIGN.md</code> is missing, run setup first.
703
+ </li>
704
+ <li>QA — paste the good prompt below. For screens, also run <code>accessibility-wcag</code>.</li>
682
705
  </ol>
683
- <p>Done when QA attaches both frames plus a verdict.</p>
706
+ <p>Done when QA attaches both frames plus a verdict, and the changed flow passed a keyboard-only check.</p>
684
707
  <h3>Auth / RLS</h3>
685
708
  <p>
686
709
  Planner → App engineer → Security → QA. QA must open login, logout, and denied in the browser. Screenshots still required when the finding is
687
710
  user-visible.
688
711
  </p>
712
+ <h3>New repo design setup</h3>
713
+ <p>After <code>init</code>, before the first product CSS, paste to Design:</p>
714
+ <pre id="design-setup-flow">
715
+ Act as design. This is a new repo. Scan what is already here, then ask me what we need to set up: who it is for, what they must get done, and what you should produce. Recommend from my answers. Write the style guide and principles with me before any CSS.</pre>
716
+ <div class="copy-row">
717
+ <button class="copy" type="button" data-copy-from="design-setup-flow">Copy Design setup prompt</button>
718
+ </div>
719
+ <p>
720
+ Design scans the stack, then asks what you need. Recommendations come from those answers. It writes a short product <code>DESIGN.md</code> and
721
+ frontend <code>STYLE_GUIDE.md</code> rules only after that. It does not paste this kit’s charcoal desk onto the app. Screenshots wait until there is a
722
+ screen to capture.
723
+ </p>
689
724
  <h3>UI polish</h3>
690
- <p>Design + <code>frontend-design</code> + <code>browser-qa</code>. Desktop and mobile. One happy-path shot is a fail.</p>
725
+ <p>
726
+ Design + <code>frontend-design</code> + <code>accessibility-wcag</code> + <code>browser-qa</code>. Name setup, build, review, or detect. Desktop and
727
+ mobile once a screen exists. One happy-path shot is a fail. A contrast guess from the screenshot is a fail.
728
+ </p>
729
+ <h3>Accessibility pass</h3>
730
+ <p>On any user-facing screen, paste to Design or QA:</p>
731
+ <pre id="a11y-prompt">Run accessibility-wcag. Open the changed flow. Keyboard-only pass. Do not accept contrast from the screenshot alone.</pre>
732
+ <div class="copy-row">
733
+ <button class="copy" type="button" data-copy-from="a11y-prompt">Copy accessibility prompt</button>
734
+ </div>
691
735
  <h3>Copy pass</h3>
692
736
  <p>Copy reviews the <em>rendered</em> words in screenshots, not strings in TSX. Run <code>product-copy</code>, then <code>deslop</code> last.</p>
693
737
  </section>
@@ -713,8 +757,9 @@ Do not review code alone. Open the app, capture desktop and mobile screenshots,
713
757
  <li>Open the changed route with the real auth, role, and data.</li>
714
758
  <li>Capture desktop (~1280) and mobile (~390) into <code>qa-evidence/&lt;yyyy-mm-dd&gt;-&lt;slug&gt;/</code>.</li>
715
759
  <li><strong>Read the images.</strong> List blockers from what is on screen.</li>
716
- <li>Run applicable tests. <code>toBeVisible</code> is not a screenshot.</li>
717
- <li>Write <code>notes.md</code> with route, viewports, auth state, verdict.</li>
760
+ <li>Keyboard-only the changed flow (<code>accessibility-wcag</code>). Do not accept contrast from the screenshot alone.</li>
761
+ <li>Run applicable tests (<code>testing-qa</code>). List the commands. <code>toBeVisible</code> is not a screenshot.</li>
762
+ <li>Write <code>notes.md</code> with route, viewports, auth state, keyboard result, commands run, verdict.</li>
718
763
  </ol>
719
764
  <p>Cursor: built-in browser first. Claude, Codex, Copilot, Antigravity: host browser if present, otherwise:</p>
720
765
  <pre id="pw-cmd">
@@ -763,6 +808,10 @@ npx agent-kit update</pre>
763
808
  <td>QA finished from the diff</td>
764
809
  <td>Reject it. Re-run with the good QA prompt.</td>
765
810
  </tr>
811
+ <tr>
812
+ <td>GitHub shows this page as code</td>
813
+ <td>Open <code>USER_GUIDE.html</code> in a browser, or run <code>npx agent-kit guide</code>. GitHub does not render the layout.</td>
814
+ </tr>
766
815
  <tr>
767
816
  <td><code>doctor</code> fails the guide</td>
768
817
  <td>The screenshot fail-closed sentence must stay in <code>USER_GUIDE.md</code> and this page.</td>
@@ -23,6 +23,12 @@ Plan this change. Name the owning agent, extra reviewers, and which screenshots
23
23
 
24
24
  You should get a named owner (`app-engineer`, `security`, `design`, `qa`, or `copy`) and, if the work is user-visible, a desktop + mobile screenshot list.
25
25
 
26
+ If this repo has no product `DESIGN.md` yet, also paste to Design:
27
+
28
+ ```text
29
+ Act as design. This is a new repo. Scan what is already here, then ask me what we need to set up: who it is for, what they must get done, and what you should produce. Recommend from my answers. Write the style guide and principles with me before any CSS.
30
+ ```
31
+
26
32
  ## How to invoke in each IDE
27
33
 
28
34
  ### Cursor
@@ -73,6 +79,7 @@ Files: `.antigravity/agent-kit/commands/*.toml`, `.antigravity/runtime-skills/*/
73
79
  | Implementation | App engineer |
74
80
  | Auth / RLS / secrets | Security |
75
81
  | It looks wrong | Design |
82
+ | Style guide / first UI / no DESIGN.md | Design (`setup`) |
76
83
  | Is this done? | QA |
77
84
  | Landing / CTA words | Copy |
78
85
 
@@ -87,15 +94,15 @@ Do not ask one chat to be all six. Planner names the next specialist. It does no
87
94
  | `supabase-auth-rls` | Auth, RLS, service role, Storage |
88
95
  | `postgres-migrations` | Schema, constraints, RLS in the same change |
89
96
  | `owasp-security-review` | Mutations, uploads, SSRF, secrets |
90
- | `frontend-design` | Layout, simple palette, anti-generic UI |
91
- | `accessibility-wcag` | Keyboard, contrast, labels |
97
+ | `frontend-design` | Setup, build, review, or detect UI. Tokens first. Anti-generic |
98
+ | `accessibility-wcag` | Keyboard pass in the running browser. Contrast, labels. Not a screenshot guess |
92
99
  | `browser-qa` | Any screen. Required for QA of UI |
93
- | `testing-qa` | Unit / regression / smoke only |
100
+ | `testing-qa` | Unit / regression / smoke. List commands run. Not screenshots |
94
101
  | `product-copy` | Headlines and CTAs |
95
102
  | `deslop` | Last copy pass. Copy always runs this |
96
103
  | `ship` | Release, env, rollback |
97
104
 
98
- QA of a screen always uses `browser-qa`, not `testing-qa` alone. Each agent file names the skills it must run, then points at `catalog.json` for the rest.
105
+ QA of a screen always uses `browser-qa`, not `testing-qa` alone. User-facing screens also run `accessibility-wcag` (keyboard in the browser, not a contrast guess from the screenshot). Each agent file names the skills it must run, then points at `catalog.json` for the rest.
99
106
 
100
107
  ## Standard workflows
101
108
 
@@ -104,18 +111,36 @@ QA of a screen always uses `browser-qa`, not `testing-qa` alone. Each agent file
104
111
  1. **Planner** — paste: `Plan this change. Name the owning agent, extra reviewers, and which screenshots QA must capture. Do not write code.`
105
112
  2. **App engineer** — paste: `Implement the plan. Smoke the changed route in the browser before you hand off.`
106
113
  3. **Security** if data/auth/secrets changed.
107
- 4. **Design** if the UI changed — paste: `Review the running UI from screenshots first. Desktop and mobile. Reject generic AI-looking layout.`
108
- 5. **QA** — paste: `Do not review code alone. Open the app, capture desktop and mobile screenshots, read the images, then give accept / accept-with-nits / reject.`
114
+ 4. **Design** if the UI changed — paste: `Act as design. Name the mode (setup, build, review, or detect). Review the running UI from screenshots first. Desktop and mobile. Reject generic AI-looking layout.` If `DESIGN.md` is missing, run setup first.
115
+ 5. **QA** — paste: `Do not review code alone. Open the app, capture desktop and mobile screenshots, read the images, then give accept / accept-with-nits / reject.` For screens, also run `accessibility-wcag`.
109
116
 
110
- Done when QA attaches `qa-evidence/<date>-<slug>/desktop.png` and `mobile.png` plus a verdict.
117
+ Done when QA attaches `qa-evidence/<date>-<slug>/desktop.png` and `mobile.png` plus a verdict, and the changed flow passed a keyboard-only check.
111
118
 
112
119
  ### Auth / RLS change
113
120
 
114
121
  Planner → App engineer → Security → QA. QA must open login/logout/denied in the browser and still run tests. Screenshots required when the finding is user-visible.
115
122
 
123
+ ### New repo design setup
124
+
125
+ After `init`, before the first product CSS, paste to Design:
126
+
127
+ ```text
128
+ Act as design. This is a new repo. Scan what is already here, then ask me what we need to set up: who it is for, what they must get done, and what you should produce. Recommend from my answers. Write the style guide and principles with me before any CSS.
129
+ ```
130
+
131
+ Design scans the stack, then asks what you need. Recommendations come from those answers. It writes a short product `DESIGN.md` and frontend `STYLE_GUIDE.md` rules only after that. It does not paste this kit’s charcoal desk onto the app. Screenshots wait until there is a screen to capture.
132
+
116
133
  ### UI polish
117
134
 
118
- Design + `frontend-design` + `browser-qa`. Desktop and mobile required. One happy-path shot is a fail.
135
+ Design + `frontend-design` + `accessibility-wcag` + `browser-qa`. Name setup, build, review, or detect. Desktop and mobile required once a screen exists. One happy-path shot is a fail. A contrast guess from the screenshot is a fail.
136
+
137
+ ### Accessibility pass
138
+
139
+ On any user-facing screen, paste to Design or QA:
140
+
141
+ ```text
142
+ Run accessibility-wcag. Open the changed flow. Keyboard-only pass. Do not accept contrast from the screenshot alone.
143
+ ```
119
144
 
120
145
  ### Copy pass
121
146
 
@@ -141,8 +166,9 @@ Steps the QA agent must follow:
141
166
  2. Open the changed route with the real auth/role/data state.
142
167
  3. Capture desktop (~1280) and mobile (~390) into `qa-evidence/<yyyy-mm-dd>-<slug>/`.
143
168
  4. **Read the images.** List blockers from what is on screen.
144
- 5. Run applicable tests.
145
- 6. Write `notes.md` with route, viewports, auth state, verdict.
169
+ 5. Keyboard-only the changed flow (`accessibility-wcag`). Do not accept contrast from the screenshot alone.
170
+ 6. Run applicable tests (`testing-qa`). List the commands. `toBeVisible` is not a screenshot.
171
+ 7. Write `notes.md` with route, viewports, auth state, keyboard result, commands run, verdict.
146
172
 
147
173
  Cursor: use the built-in browser first. Claude / Codex / Copilot / Antigravity: use the host browser if present, otherwise Playwright:
148
174
 
@@ -179,5 +205,6 @@ Pristine files refresh. Local edits win or land in `.agent-kit/conflicts/`. Do n
179
205
  | Skill not triggering | Mention the skill name (`browser-qa`) or `@` it in Cursor. |
180
206
  | No browser in Copilot / Codex | Use the Playwright commands in `browser-qa`. |
181
207
  | QA finished from the diff | Reject it. Re-run with the good QA prompt above. |
208
+ | GitHub shows `USER_GUIDE.html` as code | Open the file in a browser. Run `npx agent-kit guide` to print the path. GitHub does not render the layout. |
182
209
  | `doctor` fails USER_GUIDE | The screenshot fail-closed sentence must stay in this file. |
183
210
  | Still have `QUALITY_GATES.md` / `COUNCIL.md` | Expected. `update` does not delete them. `doctor` lists leftovers. |
@@ -1,26 +1,83 @@
1
1
  ---
2
2
  name: accessibility-wcag
3
- description: Use for keyboard, focus, labels, contrast, semantics, and WCAG 2.1 AA checks on user-facing screens.
3
+ description: Use when the user can't tab, a screen reader misses a control, contrast fails, a modal traps focus, or you need a WCAG 2.1 AA pass. Keyboard in the running browser, not a screenshot guess.
4
4
  ---
5
5
 
6
6
  # Accessibility (WCAG 2.1 AA)
7
7
 
8
+ Scan 2026-09-12 (structure only, no bodies copied): W3C WCAG 2.1 AA; GitHub packs that split keyboard / contrast / forms into specialist swarms. This pack keeps **one** skill. Do not install axe, Pa11y, an a11y MCP, or an 11-agent accessibility roster. Visual proof stays in `browser-qa`. Access control stays in `supabase-auth-rls` — hiding a control is not an accessibility pass and not authorization.
9
+
8
10
  ## Use when
9
11
 
10
- Interactive UI, forms, navigation, or any screen a keyboard or screen-reader user will use.
12
+ Interactive UI, forms, navigation, dialogs, menus, tables, or any screen a keyboard or screen-reader user will use. Also when someone says “can't tab”, “contrast looks fine”, “add aria”, “WCAG”, or “is this accessible?”
13
+
14
+ Not a substitute for `frontend-design` (look and tokens) or `owasp-security-review` (auth). Run those as their owners; this skill is the keyboard-and-semantics pass.
15
+
16
+ ## Do
17
+
18
+ 1. Open the **running** changed flow. Name the route, auth state, and what the user must finish.
19
+ 2. Keyboard-only: Tab, Shift+Tab, Enter, Space, and Escape. Record traps, missing focus, and controls you cannot reach.
20
+ 3. Check the mapping table. Skip rows that do not apply; do not skip keyboard because “it's a mouse app.”
21
+ 4. Capture desktop (~1280) and mobile (~390) for `browser-qa`. Screenshots help for contrast and target size; they do not replace step 2.
22
+ 5. Return a findings table (P0 / P1 / P2) with where it showed up and whether it is **code-certain** or **inferred**.
11
23
 
12
24
  ## Checks
13
25
 
14
- - Semantic headings, landmarks, and labels.
15
- - Keyboard order matches visual order; focus is visible.
16
- - Contrast meets 4.5:1 for text.
17
- - Tap targets are usable on mobile.
18
- - Errors are announced; motion is not the only signal.
26
+ Map the change to a concrete control. Skip rows that do not apply.
27
+
28
+ | Area | In this pack |
29
+ | --- | --- |
30
+ | Semantics (1.3.1) | Real headings, landmarks, lists, and buttons. One `h1`. ARIA only when native HTML cannot. |
31
+ | Keyboard (2.1.1, 2.1.2, 2.4.3, 2.4.7) | Tab order matches visual order. Focus is visible. No trap except a real dialog. Escape closes overlays. |
32
+ | Contrast (1.4.3, 1.4.11) | 4.5:1 normal text, 3:1 large text and UI chrome. Do not sign off from the screenshot alone. |
33
+ | Color (1.4.1) | Color or a left-edge rail is not the only selected / error / success signal. |
34
+ | Forms (3.3.1–3.3.3) | Visible `<label htmlFor>`. Errors associated (`aria-describedby` / `aria-invalid`) and announced. |
35
+ | Name, Role, Value (4.1.2) | Custom controls expose name, role, and state. A `div` with an onClick is a finding. |
36
+ | Status (4.1.3) | Save, error, and loading results are announced (live region or a focus move). |
37
+ | Non-text (1.1.1) | `next/image` (and other images) have meaningful `alt`. Decorative images use empty `alt`. |
38
+ | Bypass (2.4.1) | Skip link or landmarks so repeating chrome is skippable. Kit HTML already has a skip link. |
39
+ | Motion | Honor `prefers-reduced-motion`. Motion is not the only signal. |
40
+ | Targets | Taps are usable on mobile. WCAG 2.1 AA does not require 2.2’s 24×24 rule; this pack still rejects unusable hits. |
41
+ | Auth vs a11y | A hidden button is not an a11y fix for unauthorized users. Enforce access in RLS / the server. |
42
+
43
+ ## App Router mapping
44
+
45
+ - **Server Action forms:** every field has a label. Validation errors render in the UI, bound to the field, not only a thrown Error. Disabled submit is explained; `disabled` removes the control from the tab order — do not use it as the only “you cannot do this” hint if the user still needs to reach help text.
46
+ - **Dialogs / sheets:** labelled (`aria-labelledby` or visible title), focus moves in, Tab cycles inside, Escape closes, focus returns to the opener.
47
+ - **Menus / disclosure:** keyboard opens and closes; collapsed content is not in the tab order.
48
+ - **`next/image`:** `alt` describes the image’s job, not the filename.
49
+ - **Kit HTML (`USER_GUIDE.html`):** keep the skip link and safelight `:focus-visible` outline. Do not add `border-left` selection rails. Do not drop `lang` on `<html>`.
50
+
51
+ Field checklist: `checklists/accessibility.md`.
19
52
 
20
53
  ## Tools
21
54
 
22
- Confirm in the running browser. Screenshots help for contrast and target size; keyboard must still be exercised.
55
+ Confirm in the running browser. Preferred: host IDE browser. Playwright is backup for capture, not a substitute for Tab.
56
+
57
+ Screenshots are evidence for contrast, clipping, and target size. **Keyboard must still be exercised.** Optional automated scanners (axe, Pa11y) may run *after* the keyboard pass; they are not the pass.
58
+
59
+ Visual proof: `browser-qa` (`qa-evidence/<date>-<slug>/` plus `notes.md`). Record keyboard results in `notes.md`:
60
+
61
+ ```text
62
+ keyboard: tab-order pass|fail; focus-visible pass|fail; trap none|expected-modal|unexpected
63
+ contrast: measured|inferred-from-screenshot
64
+ ```
65
+
66
+ `inferred-from-screenshot` is not enough to accept.
67
+
68
+ ## Reject
69
+
70
+ - “Contrast looks fine in the screenshot” without a keyboard pass.
71
+ - Approving from TSX, ARIA comments, or a Storybook file without opening the running UI.
72
+ - Color or a left-edge rail as the only selected / error / success signal.
73
+ - Installing axe, Pa11y, or an accessibility MCP as the required tool.
74
+ - Copying a third-party accessibility skill body or standing up an a11y-agent swarm.
75
+ - Treating a hidden control as the accessibility fix for a user who is not allowed to act (that is `supabase-auth-rls`).
76
+ - A modal that does not restore focus, or that traps the page with no Escape.
77
+ - `aria-label` that contradicts visible text.
78
+ - Skipping keyboard because the flow is “mouse-only” or “admin-only.”
79
+ - Kit HTML: dropping the skip link or the `:focus-visible` outline.
23
80
 
24
81
  ## Done when
25
82
 
26
- A keyboard-only pass works on the changed flow and remaining gaps are named.
83
+ A **keyboard-only pass works on the changed flow in the running UI**. Tab order matches visual order. Focus is visible. Remaining gaps are named with severity and code-certain vs inferred. Visual proof is in `browser-qa` evidence. Contrast was not signed off from the screenshot alone.
@@ -54,6 +54,7 @@ Use the host browser when it exists. Playwright is required text for Claude, Cod
54
54
  - Playwright `toBeVisible` with no image.
55
55
  - Updating screenshot baselines without saying what changed in the picture.
56
56
  - Skipping mobile, or skipping auth/empty/error when those states exist.
57
+ - “Contrast looks fine in the screenshot” with no keyboard-only pass (`accessibility-wcag`).
57
58
 
58
59
  ## Screenshot critique
59
60
 
@@ -38,7 +38,7 @@ Second pass: re-read the rewrite. If the same tell remains, rewrite the paragrap
38
38
 
39
39
  ## Visual P0s — fail if still on screen
40
40
 
41
- These are the 2026 convergence cluster. One is a smell. Two or more is a reject.
41
+ These are the 2026 flat AI/SaaS chrome cluster (same family as accent-border cards, glow rails, and card soup). One is a smell. Two or more is a reject. A pick-list row or status well with a left stroke is already a fail.
42
42
 
43
43
  - Purple-to-blue (or indigo) gradient hero, or gradient-clipped headline type
44
44
  - Inter / Roboto / default shadcn zinc as the whole identity
@@ -48,6 +48,12 @@ These are the 2026 convergence cluster. One is a smell. Two or more is a reject.
48
48
  - Acid green or neon vermilion on near-black used as decoration, not meaning
49
49
  - Lucide Sparkles / Zap as the product metaphor
50
50
  - Fake dashboard metrics or DiceBear avatars
51
+ - Left accent bars / left-hand borderlines on selected rows, list items, cards, or success/error/warn wells (the “colored stroke on the left edge” pattern)
52
+ - Thick one-sided colored borders, glow rails, neon strokes, or gradient borders used as the main state cue
53
+
54
+ Selection must use radio/checkbox + light row tint (or weight/space) only. Status wells may use a flat tint fill. No `border-left` accent, no inset bar, no vertical rail as decoration. Keep one accent for the primary CTA, not as a row edge.
55
+
56
+ **Acceptance fixture:** a pick-list row and a “verified” well must pass with **zero** left border accents. If screenshots show a blue/green/amber left stroke, deslop fails.
51
57
 
52
58
  Copy does not restyle the page. It lists the P0s from the screenshot and sends them to Design.
53
59