@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,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 3,
3
3
  "packageName": "@appsforgood/next-supabase-kit",
4
- "packageVersion": "0.4.2",
4
+ "packageVersion": "0.4.3",
5
5
  "stack": "next-supabase",
6
6
  "installedAt": "2026-09-06T01:00:41.569Z",
7
7
  "docs": [
@@ -17,78 +17,78 @@
17
17
  "antigravity"
18
18
  ],
19
19
  "templateHashes": {
20
- "AGENTS.md": "c1792ecc8bd4836505574015ab08c0fc593d93f4c5ef518489bb85d2af66be8a",
21
- "USER_GUIDE.md": "87c73c7d2501429953e8b7bbfb4061dfecaa1d818e585706aeccfb44d6aeb058"
20
+ "AGENTS.md": "10a63cd533136555b5cd3b0a189fcd4091339918e62236f20b6dcd7628885369",
21
+ "USER_GUIDE.md": "3948a5ef1d9b4b1e58853aa0bb0d6fa85168964bac97a7b673c40956ba10c4af",
22
+ "USER_GUIDE.html": "344229e19becf962fa1aabd5e9ec32474171782cfc49bd3b894d751810a2b31a"
22
23
  },
23
24
  "assetHashes": {
24
- "AGENTS.md": "d5b570847e7e283a4603055445d6b8cf87dd6e041305c6a3909fa7cde327db81",
25
- "USER_GUIDE.md": "0c7c8e543a52503299d7819a9359d4d635f32e3ab6ca0f8eaadf034b26798c32",
25
+ "AGENTS.md": "10a63cd533136555b5cd3b0a189fcd4091339918e62236f20b6dcd7628885369",
26
+ "USER_GUIDE.md": "3948a5ef1d9b4b1e58853aa0bb0d6fa85168964bac97a7b673c40956ba10c4af",
27
+ "USER_GUIDE.html": "344229e19becf962fa1aabd5e9ec32474171782cfc49bd3b894d751810a2b31a",
26
28
  ".cursor/rules/cursor-agent-kit.mdc": "850026beea86067d95925eea15eb447365d6a956e0f7f475ebd7fef89043d44b",
27
29
  "CLAUDE.md": "d5095edff182babe5c13717bb16cadcd95569d9e4abd37ceb307bb1448b65557",
28
30
  ".cursor/agents/planner.md": "90676313078391848072fd3a4dc24d8479a7911aa8e7f68a38f46b73074aa6d4",
29
31
  ".cursor/agents/app-engineer.md": "e37f6a4f03eb4f66021b5a599657468e9cb33d11abd86a83df02fe198e471b12",
30
32
  ".cursor/agents/security.md": "d71de67a6c66198c02db47357b9a91d86601659c843835ecb481e9edc651a238",
31
- ".cursor/agents/design.md": "04277841a61c9b3f0ea970a14319fe7c1c199a6be5483d5e69b65c231f8764f8",
32
- ".cursor/agents/qa.md": "a4f77a26ee91d0065d5ef9f7a48ebe9f4466b2d17a2d63cb0ffcbc4bc24b9a73",
33
+ ".cursor/agents/design.md": "0e9568eec2312c8eae94bf0ab74c4e60f99f546d72609910e86194fc0d1f9df3",
34
+ ".cursor/agents/qa.md": "fc978f65c920610628731eb5f709ba72de6cb6568803450ff036474beed18736",
33
35
  ".cursor/agents/copy.md": "11e7df36d16221d71e3290dc5ba07711df7320895ad2215eeebec5afcf43bf21",
34
- ".cursor/skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
36
+ ".cursor/skills/planning/SKILL.md": "3d472a6477c8e075a25b83105180199294a6aca60d6a06a827c382f7dba952b7",
35
37
  ".cursor/skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
36
38
  ".cursor/skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
37
39
  ".cursor/skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
38
40
  ".cursor/skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
39
- ".cursor/skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
40
- ".cursor/skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
41
- ".cursor/skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
42
- ".cursor/skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
41
+ ".cursor/skills/frontend-design/SKILL.md": "aea5a467ec40a5359a70b5f2b649b96f9ca43b7cb1d44289cfb2e809badef9d1",
42
+ ".cursor/skills/accessibility-wcag/SKILL.md": "f76b2c31bc6c60f31c7e07d2a19569a1af9be0505948206f8bcb05cd1d716ac6",
43
+ ".cursor/skills/browser-qa/SKILL.md": "b7758f5e8e69317c60363954fd019e03ef9b3d77cc79b30cc3767d151a261234",
44
+ ".cursor/skills/testing-qa/SKILL.md": "a9840dd5dba27cd2990e9c58aee7238ac7e4666bf57d11700f4d4d8b1f9d3427",
43
45
  ".cursor/skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
46
+ ".cursor/skills/deslop/SKILL.md": "cd8ef7f6bdcff86f78ef9d4a94b944a585077629144184d854d6e29ff1569823",
44
47
  ".cursor/skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
45
48
  ".claude/agents/planner.md": "90676313078391848072fd3a4dc24d8479a7911aa8e7f68a38f46b73074aa6d4",
46
49
  ".claude/agents/app-engineer.md": "e37f6a4f03eb4f66021b5a599657468e9cb33d11abd86a83df02fe198e471b12",
47
50
  ".claude/agents/security.md": "d71de67a6c66198c02db47357b9a91d86601659c843835ecb481e9edc651a238",
48
- ".claude/agents/design.md": "04277841a61c9b3f0ea970a14319fe7c1c199a6be5483d5e69b65c231f8764f8",
49
- ".claude/agents/qa.md": "a4f77a26ee91d0065d5ef9f7a48ebe9f4466b2d17a2d63cb0ffcbc4bc24b9a73",
51
+ ".claude/agents/design.md": "0e9568eec2312c8eae94bf0ab74c4e60f99f546d72609910e86194fc0d1f9df3",
52
+ ".claude/agents/qa.md": "fc978f65c920610628731eb5f709ba72de6cb6568803450ff036474beed18736",
50
53
  ".claude/agents/copy.md": "11e7df36d16221d71e3290dc5ba07711df7320895ad2215eeebec5afcf43bf21",
51
54
  ".codex/agents/planner.toml": "f55f218778ae76942e6c7ea9a159e89dc5c13466b0effa0c43935b29d8182d11",
52
55
  ".codex/agents/app-engineer.toml": "f76f6f9a531974becdd863bfb4a0bf1b6810e966d31b7fb6a4f41f8791a8fb59",
53
56
  ".codex/agents/security.toml": "9e202a8125ddce38d84487a59d7c7cd7328acb8c441704f670b8331042be15f0",
54
- ".codex/agents/design.toml": "6b9114c3ab55db610cc38632939930d966282a427ba0fba4c4c6178f43d10725",
55
- ".codex/agents/qa.toml": "07f53a37d896203707bcb28d19e5a502194a3276faa387bff3739e8d876af564",
57
+ ".codex/agents/design.toml": "30b24febb56e398007e1b0daaf4b499f60e5d74efc6d0a5888960d007c7829ab",
58
+ ".codex/agents/qa.toml": "b53d2491a339a872f1c775f636025bf35c8fb81c5a3b199cb20ada86ac786889",
56
59
  ".codex/agents/copy.toml": "76e0b1e54139a6d4dc5140f7214aceaa72f186e45f561c6708e1263747ac07fd",
57
60
  ".github/copilot-instructions.md": "f5d26cc16aebd5b82f5fb75b85a59e17b802ddb444e50cc25e61a37c616e738f",
58
61
  ".antigravity/agent-kit/plugin.json": "e2f156fdd68ca706dd289152722bfd07ebb0c29a16afadcfdf178a723ecb6a90",
59
62
  ".antigravity/agent-kit/commands/plan.toml": "2f72ca9f76265a2255686bad4cb1075563884ab7b7da2199ab9a2a30106792de",
60
- ".antigravity/agent-kit/commands/browser-qa.toml": "f94071c6eca96ae3e0d2c493abfc65d5215acaa7a2bb1423fe1c7d61743e37ef",
63
+ ".antigravity/agent-kit/commands/browser-qa.toml": "aa229438dd3a36d9f139a6002a4e7ba80d7e32e541a8a17215f9f189a57d156d",
61
64
  ".antigravity/agent-kit/commands/security.toml": "4622b2d38795f9d58662b225bce2291d14e58644aa0aed5607b9b567ddf342c5",
62
- ".antigravity/agent-kit/commands/frontend.toml": "3f0f03b8094e0103e47709f6af6fba09b3dd7a0decc22191777f8ae5770f064c",
65
+ ".antigravity/agent-kit/commands/frontend.toml": "4e31d698779d6fd6383a349b3483413e862d98eb79f7e812789dc26091b5b421",
63
66
  ".antigravity/agent-kit/commands/copy.toml": "40ad093163915a9f000bf8344e49c37dc2d735ab404e84430323502af0bf031e",
64
- ".antigravity/agent-kit/commands/test.toml": "238f3d670c0ecabeab38204fe0a42b32fc5cbdad885b706715f17075c855c9d7",
67
+ ".antigravity/agent-kit/commands/test.toml": "5b230c0e4343bec71e9da36c02bb1f533479f1a87700ea8ceeabbfcc72a2f5c0",
65
68
  ".antigravity/agent-kit/commands/ship.toml": "dfa8a6bc654e7bfbf06ad1af59f122a8b116b84008b5ab9325ce21eba3eab9ef",
66
- ".antigravity/runtime-skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
69
+ ".antigravity/runtime-skills/planning/SKILL.md": "3d472a6477c8e075a25b83105180199294a6aca60d6a06a827c382f7dba952b7",
67
70
  ".antigravity/runtime-skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
68
71
  ".antigravity/runtime-skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
69
72
  ".antigravity/runtime-skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
70
73
  ".antigravity/runtime-skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
71
- ".antigravity/runtime-skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
72
- ".antigravity/runtime-skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
73
- ".antigravity/runtime-skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
74
- ".antigravity/runtime-skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
74
+ ".antigravity/runtime-skills/frontend-design/SKILL.md": "aea5a467ec40a5359a70b5f2b649b96f9ca43b7cb1d44289cfb2e809badef9d1",
75
+ ".antigravity/runtime-skills/accessibility-wcag/SKILL.md": "f76b2c31bc6c60f31c7e07d2a19569a1af9be0505948206f8bcb05cd1d716ac6",
76
+ ".antigravity/runtime-skills/browser-qa/SKILL.md": "b7758f5e8e69317c60363954fd019e03ef9b3d77cc79b30cc3767d151a261234",
77
+ ".antigravity/runtime-skills/testing-qa/SKILL.md": "a9840dd5dba27cd2990e9c58aee7238ac7e4666bf57d11700f4d4d8b1f9d3427",
75
78
  ".antigravity/runtime-skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
79
+ ".antigravity/runtime-skills/deslop/SKILL.md": "cd8ef7f6bdcff86f78ef9d4a94b944a585077629144184d854d6e29ff1569823",
76
80
  ".antigravity/runtime-skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
77
- "skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
81
+ "skills/planning/SKILL.md": "3d472a6477c8e075a25b83105180199294a6aca60d6a06a827c382f7dba952b7",
78
82
  "skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
79
83
  "skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
80
84
  "skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
81
85
  "skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
82
- "skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
83
- "skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
84
- "skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
85
- "skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
86
+ "skills/frontend-design/SKILL.md": "aea5a467ec40a5359a70b5f2b649b96f9ca43b7cb1d44289cfb2e809badef9d1",
87
+ "skills/accessibility-wcag/SKILL.md": "f76b2c31bc6c60f31c7e07d2a19569a1af9be0505948206f8bcb05cd1d716ac6",
88
+ "skills/browser-qa/SKILL.md": "b7758f5e8e69317c60363954fd019e03ef9b3d77cc79b30cc3767d151a261234",
89
+ "skills/testing-qa/SKILL.md": "a9840dd5dba27cd2990e9c58aee7238ac7e4666bf57d11700f4d4d8b1f9d3427",
86
90
  "skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
87
- "skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
88
- "USER_GUIDE.html": "7781238feb3e87b2fa539ac7a74a735632542e02c6f3dfed10846246a7bada96",
89
- ".cursor/skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0",
90
- ".antigravity/runtime-skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0",
91
- "skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0"
92
- },
93
- "updatedAt": "2026-09-09T05:16:37.821Z"
91
+ "skills/deslop/SKILL.md": "cd8ef7f6bdcff86f78ef9d4a94b944a585077629144184d854d6e29ff1569823",
92
+ "skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f"
93
+ }
94
94
  }
@@ -2,5 +2,5 @@ name = "browser-qa"
2
2
  description = "Live browser QA with desktop and mobile screenshots."
3
3
 
4
4
  prompt = """
5
- Act as the QA agent. Use the browser-qa skill. Do not review code alone. Open the app, capture desktop and mobile screenshots, read the images, then give accept / accept-with-nits / reject.
5
+ Act as the QA agent. Use the browser-qa skill. 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: keyboard-only pass. Do not accept contrast from the screenshot alone.
6
6
  """
@@ -2,5 +2,5 @@ name = "frontend"
2
2
  description = "UI review from screenshots first."
3
3
 
4
4
  prompt = """
5
- Act as the design agent. Review the running UI from screenshots first. Desktop and mobile. Reject generic AI-looking layout.
5
+ Act as the design agent. Name the mode (setup, build, review, or detect) and the surface. Use the frontend-design skill. If DESIGN.md is missing or this is a new repo, run setup: scan what is here, then ask what they need (who it is for, what they must get done, what this pass should produce). Recommend from the answers. Write style guide and principles only after that, and before CSS. Otherwise review the running UI from screenshots first. Desktop and mobile. Reject generic AI-looking layout. Detect means audit only — no edits.
6
6
  """
@@ -2,5 +2,5 @@ name = "test"
2
2
  description = "Run tests, then browser-qa for UI."
3
3
 
4
4
  prompt = """
5
- Act as the QA agent. Run applicable tests, then use browser-qa for any user-visible change.
5
+ Act as the QA agent. Use the testing-qa skill: run applicable tests and list the commands. Then use browser-qa for any user-visible change. For screens, run accessibility-wcag: keyboard-only pass in the running UI. Do not treat toBeVisible as a screenshot.
6
6
  """
@@ -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
 
@@ -1,21 +1,121 @@
1
1
  ---
2
2
  name: frontend-design
3
- description: Use when building or reviewing user-facing UI. Commit one simple palette and type pairing. Reject default AI layouts, timid color spreads, and decoration that is not the task.
3
+ description: Use when setting up design on a new repo, or building, reviewing, or auditing UI. Name the mode (setup, build, review, or detect). Setup asks what the user needs, then recommends principles before CSS.
4
4
  ---
5
5
 
6
6
  # Frontend Design
7
7
 
8
8
  Build or review a screen as if a stranger must name the product from the first viewport. Simple and specific beats decorated.
9
9
 
10
- Scan 2026-09-06 (structure only, no bodies copied): Anthropic `frontend-design` (updated 2026-06), addyosmani `frontend-ui-engineering`, `educlopez/ui-craft`, `funboy322/avoid-ai-design`, `superdesigndev/superdesign-skill`.
10
+ Scan 2026-09-12 (structure only, no bodies copied): Anthropic `frontend-design` (2026-06), addyosmani `frontend-ui-engineering`, `educlopez/ui-craft`, `funboy322/avoid-ai-design`, `superdesigndev/superdesign-skill`, `google-labs-code/design.md`. Do not install their CLIs, canvases, MCP servers, or slash-command catalogs.
11
11
 
12
12
  ## Use when
13
13
 
14
- Any user-facing layout, component, HTML page, or “it looks generic.” Required for `USER_GUIDE.html` and for app screens.
14
+ Any user-facing layout, component, HTML page, or “it looks generic.” Required for `USER_GUIDE.html` and for app screens. Also required on a **new repo** or first UI job when `DESIGN.md` is missing or TBD — run `setup` before CSS.
15
+
16
+ ## Mode
17
+
18
+ Name the mode before CSS. Default is `setup` when `DESIGN.md` is missing or TBD, `review` when the UI already exists, `build` when it does not.
19
+
20
+ | Mode | Do |
21
+ | --- | --- |
22
+ | `setup` | New repo or missing/TBD `DESIGN.md`. Scan, then ask what they need. Recommend from the answers. Record principles and style-guide rules only after that. No CSS unless they then ask to build. |
23
+ | `build` | Write tokens and one layout idea, then CSS. Screenshot after. |
24
+ | `review` | Screenshot first. Findings table, then fix P0s. |
25
+ | `detect` | Audit only. No edits. Use when asked to scan, flag, or not change code. |
26
+
27
+ ## Surface
28
+
29
+ Pick one profile and stay at that depth. Setup names a likely surface after the scan; it does not require one before questions.
30
+
31
+ | Profile | Depth |
32
+ | --- | --- |
33
+ | `landing` / standalone artifact | Full direction. Spend boldness once. |
34
+ | `app-chrome` | Quiet and dense. Loading, empty, error, and success before decoration. |
35
+ | `inside-design-system` | Surgical. Keep tokens and primitives. Swap tells; do not invent a second brand. |
36
+ | `kit-html` | This pack’s charcoal assignment desk. Not a SaaS landing page. |
37
+
38
+ ## Setup (new repo)
39
+
40
+ Run this when any of these is true: `DESIGN.md` is missing; it is still TBD / `[product]` / “your product”; the user asked to set up design, a style guide, or principles; this is first UI work after `init`.
41
+
42
+ The job is **asking good questions so you know what they need**. Docs and tokens are the record of that conversation. Do **not** dump a 17-doc council template. Do **not** paste this kit’s charcoal desk onto the product. `init` does not install `DESIGN.md`.
43
+
44
+ ### 1. Scan first — do not re-ask what you can read
45
+
46
+ Read enough to name:
47
+
48
+ - Product name and one-line job from README / `package.json`
49
+ - Router: App Router (`app/`) vs Pages (`pages/`)
50
+ - Styling: Tailwind, CSS modules, CSS variables, shadcn/ui, Radix, other component library
51
+ - Fonts: `next/font`, self-hosted, or unset
52
+ - Auth or first useful screens (login, invite, empty app)
53
+ - Existing tokens in `globals.css`, Tailwind theme, or a mature `STYLE_GUIDE.md`
54
+
55
+ Report the architecture in a short list, then ask. If a real visual system already exists, stay surgical (`inside-design-system`) and offer to record it rather than invent a second brand.
56
+
57
+ ### 2. Ask what they need
58
+
59
+ Setup is an interview. Use the scan as context, not as a quiz.
60
+
61
+ **How to ask**
62
+
63
+ - One message, in their language (the work, the person), not ours (hex, motion budget, “three personality traits”).
64
+ - Skip anything they already answered or the scan already settled.
65
+ - If an answer is vague (“make it modern,” “make it pop”), ask one follow-up: *what should a stranger see, and what would be the wrong product?*
66
+ - Do not ask them to pick a hex, a font, or a motion budget until you know the need.
67
+ - Public words still belong to Copy.
68
+
69
+ **Need questions** (ask these; drop any they already covered)
70
+
71
+ 1. What are we setting up, and what do you need from this pass — principles, a style guide, a first-screen direction, or all of it?
72
+ 2. Who has to succeed, and what are they trying to finish?
73
+ 3. On the first useful screen, what must they be able to do?
74
+ 4. What is already decided — brand, components, legal, accessibility — and what must it *not* look like?
75
+ 5. When this works, what is in front of them? When it fails, what did we get wrong?
76
+
77
+ Listen. Follow up once if needed. Then recommend.
78
+
79
+ ### 3. Recommend from the answers, then pause
80
+
81
+ Best practices are tailored, not a canned list. Always include:
82
+
83
+ - The **need** you heard, in one sentence.
84
+ - **Principles (4–6)** that serve that need. Default bar unless they overrode it: first screen = the work; one field, one ink, one accent, one line; states before decoration; WCAG 2.1 AA contrast (4.5:1 text); match the existing stack; no left-edge selection rails.
85
+ - **Visual direction** only if they asked for one: a token recipe from Color below that fits *this* domain, or a surgical pass if shadcn/existing tokens already exist. Downstream apps never copy kit charcoal `#10100e`. Two one-sentence options and a pick.
86
+ - **Anti-references** in their words, plus any 2026 defaults that would make this the wrong product.
87
+ - What you will write vs what can wait.
88
+
89
+ Pause for confirm. If the session is non-interactive, or the user said to proceed, **state assumptions** and continue.
90
+
91
+ ### 4. Record what they need — no CSS yet
92
+
93
+ Write only the files this pass called for. Default, when they want a style guide and principles, is a **short** product `DESIGN.md` (not the 160-line kit template):
94
+
95
+ ```markdown
96
+ # DESIGN.md
97
+
98
+ ## Need
99
+ ## Product
100
+ ## Who it is for
101
+ ## First-screen job
102
+ ## Architecture found
103
+ ## Principles
104
+ ## Tokens
105
+ | Token | Value | Use |
106
+ | --- | --- | --- |
107
+ ## Anti-references
108
+ ```
109
+
110
+ `STYLE_GUIDE.md`: if missing, write a short **Frontend (product)** section (tokens live in `DESIGN.md`, states, stack, anti-slop). If a mature guide already exists, **append** that section — do not overwrite.
111
+
112
+ Then stop. If they asked to build a screen, switch to `build`. Setup does **not** require screenshots when nothing can render yet. Do not drop `requiredTools` on the Design agent.
15
113
 
16
114
  ## Ground in the subject
17
115
 
18
- Name the product, the user, and this screen’s job before CSS. Tokens come from the domain (materials, time of day, one real object) — not from a theme pack. A toy store and a ledger cannot share a palette.
116
+ Name the product, the user, and this screen’s job before CSS. Read `DESIGN.md` when it exists — tokens there are normative; prose is how to apply them. Tokens come from the domain (materials, time of day, one real object) — not from a theme pack. A toy store and a ledger cannot share a palette.
117
+
118
+ Match the project’s stack (CSS variables, Tailwind, existing component library). Do not mix a second styling approach.
19
119
 
20
120
  **This kit’s HTML** (`USER_GUIDE.html`): charcoal assignment desk.
21
121
 
@@ -40,7 +140,7 @@ One field, one ink, one accent, one line. That is enough.
40
140
 
41
141
  1. **Dominant field** (~80%): the page. Flat. Not a gradient, not a mesh.
42
142
  2. **Ink** (~15%): body text. Contrast ≥ 4.5:1 (3:1 for large type).
43
- 3. **Accent** (~5%): one action or one required state. Recolor-as-decoration fails.
143
+ 3. **Accent** (~5%): one action or one required state. A few placements in the first viewport (primary CTA, one required/fail). Recolor-as-decoration fails.
44
144
  4. **Line / well**: borders and code wells, one step off the field.
45
145
 
46
146
  Recipes (pick one that fits the product, then stop):
@@ -77,7 +177,9 @@ One family, or two that are obviously different (display vs mono). Inter + syste
77
177
  - Mobile (~390): the primary CTA still fits above the fold.
78
178
  - Hierarchy from size, weight, and space — not from cards.
79
179
  - Landing and marketing pages take a full direction. App chrome (settings, tables) stays quiet and dense.
80
- - Reject: centered hero + two pills + three icon cards; glass navbar; four-column empty footer; fake metrics; broadsheet hairlines + dense newsprint columns (that look is itself a 2026 default).
180
+ - Do not mark selection or severity with a left edge stroke. That pattern reads as default AI/SaaS chrome even on flat full-bleed sheets.
181
+ - Prefer: radio + tint, check + tint, or typography/weight. Keep one accent for the primary CTA, not as a row edge.
182
+ - Reject: centered hero + two pills + three icon cards; glass navbar; four-column empty footer; fake metrics; broadsheet hairlines + dense newsprint columns (that look is itself a 2026 default); left selection rails; callouts whose only cue is a thick left border.
81
183
 
82
184
  ## Motion
83
185
 
@@ -85,23 +187,55 @@ None, or one moment that answers a click. Fade-and-slide on every section is gen
85
187
 
86
188
  ## Process
87
189
 
88
- 1. Name the product, the user, and the job of this screen.
89
- 2. Write the 4–6 tokens and one-sentence layout idea.
90
- 3. Check the plan is not a 2026 default (cream editorial, neon-on-black decoration, SaaS card kit, newsprint desk, last week’s “tasteful” swap). If it is, change one axis: field, accent, or structure.
91
- 4. Build. Spend boldness once. Remove one accessory.
92
- 5. Screenshot desktop (~1280) and mobile (~390). Fix from pixels. Ask: would a stranger believe a person chose this?
190
+ If mode is `setup`, follow **Setup** instead of this list.
191
+
192
+ 1. Name the mode, the surface profile, the product, the user, and the job of this screen.
193
+ 2. Read `DESIGN.md` and existing tokens if they exist. If the brief names a look, follow it — including when it asks for a 2026 default.
194
+ 3. Write the 4–6 tokens and one-sentence layout idea (build), or skip to screenshots (review/detect).
195
+ 4. Check the plan is not a 2026 default (cream editorial, neon-on-black decoration, SaaS card kit, newsprint desk, last week’s “tasteful” swap). If it is and the brief did not ask, change one axis: field, accent, or structure.
196
+ 5. Build or rewrite at the profile’s depth. Spend boldness once. Remove one accessory.
197
+ 6. Screenshot desktop (~1280) and mobile (~390). Fix from pixels. Ask: would a stranger believe a person chose this?
198
+ 7. If you cannot render, mark visual findings **inferred** and say so. Code-level tells (literal `from-indigo-500`, Inter, untouched shadcn zinc) stay **code-certain**.
93
199
 
94
200
  ## Checks
95
201
 
96
202
  - A stranger can name the product from the first screen.
97
- - Loading, empty, error, disabled, success exist where the flow has them.
98
- - Focus visible, tap targets usable.
203
+ - Loading, empty, error, disabled, success exist where the flow has them. Color is not the only state signal.
204
+ - Focus visible, tap targets usable. Keyboard order matches visual order. Keyboard, labels, and contrast fail-closed live in `accessibility-wcag` — a pretty screenshot is not a keyboard pass.
99
205
  - Copy on the screen is real. If words are public-facing, Copy runs `deslop` last.
100
206
 
207
+ ## Review output
208
+
209
+ For `review` and `detect`, use a table. Do not approve from a vibe.
210
+
211
+ | Severity | Finding | Where | Confidence |
212
+ | --- | --- | --- | --- |
213
+ | P0 | Layperson would call it AI-made, or it blocks use | screenshot or file | code-certain / inferred |
214
+ | P1 | A designer would notice | screenshot or file | code-certain / inferred |
215
+ | P2 | Craft gap | screenshot or file | code-certain / inferred |
216
+
217
+ P0 list lives in `deslop`. A clean catalog pass is necessary but not enough: the result must still look chosen for this product.
218
+
219
+ ## Reject
220
+
221
+ - Approving UI from TSX or HTML alone.
222
+ - Starting CSS on a new product before `setup` when `DESIGN.md` is missing or TBD.
223
+ - Quizzing them on hex, fonts, or motion before you know what they need.
224
+ - Writing `DESIGN.md` from a template without asking what this setup is for.
225
+ - Overwriting a mature `STYLE_GUIDE.md`.
226
+ - Pasting this kit’s charcoal desk onto a downstream product.
227
+ - Installing a design MCP, canvas CLI, or slash-command pack to “do design.”
228
+ - Detect-mode edits.
229
+ - A full rebuild inside an existing design system when a surgical pass would do.
230
+ - Mesh gradients, noise overlays, and decorative atmosphere as the default “bold” move (older `frontend-design` forks). The brief can ask; the model must not invent it.
231
+ - “We’ll make it distinctive later.” Use the product’s tokens now.
232
+
101
233
  ## Tools
102
234
 
103
- `browser` + `screenshot` + `image-review` first. Do not approve UI from TSX or HTML alone.
235
+ `browser` + `screenshot` + `image-review` first for `build`, `review`, and `detect`. Do not approve UI from TSX or HTML alone. Setup may skip capture when nothing can render yet.
104
236
 
105
237
  ## Done when
106
238
 
107
- Desktop and mobile images were read. Token list is in the change or in `DESIGN.md`. No P0 slop from `deslop` remains unless Design names it as an accepted exception.
239
+ **Setup:** architecture was reported, need questions were asked (and followed up if vague) or assumptions stated, recommendations match what they need, and the files this pass called for were written. No unsolicited CSS. Screenshots are not required if nothing can render.
240
+
241
+ **Build / review / detect:** Mode and surface were named. Desktop and mobile images were read (or detect listed what could not be rendered). Token list is in the change or in `DESIGN.md`. No P0 slop from `deslop` remains unless Design names it as an accepted exception. Detect ends with the table and no file edits.
@@ -16,11 +16,12 @@ Planning, roadmaps, “what should we do,” or any request that needs an owner.
16
16
  3. Name the skill that owner must run first:
17
17
  - App engineer: `nextjs-app-router` and, if data/auth, `supabase-auth-rls` / `postgres-migrations`
18
18
  - Security: `owasp-security-review` + `supabase-auth-rls`
19
- - Design: `frontend-design`
20
- - QA: `browser-qa` (screens) and `testing-qa` (commands)
19
+ - Design: `frontend-design` (name setup, build, review, or detect) and, for screens, `accessibility-wcag`
20
+ - QA: `browser-qa` (screens), `testing-qa` (commands), and `accessibility-wcag` for user-facing screens
21
21
  - Copy: `product-copy` then `deslop` last
22
- 4. Add extra reviewers: Security for auth/data/secrets, Design for UI, QA for behavior/UI, Copy for public words.
23
- 5. If the change is user-visible, list the desktop and mobile screenshots QA must capture.
22
+ 4. If the work is user-visible and `DESIGN.md` is missing, TBD, or the user asked for a style guide / principles: owner is Design in `setup` first. Design must ask what they need before inventing tokens. Do not let App engineer invent tokens.
23
+ 5. Add extra reviewers: Security for auth/data/secrets, Design for UI, QA for behavior/UI, Copy for public words.
24
+ 6. If the change is user-visible, list the desktop and mobile screenshots QA must capture. Setup may skip screenshots when nothing can render yet.
24
25
 
25
26
  ## Done when
26
27
 
@@ -28,4 +29,4 @@ Owner, extra reviewers, required skills, preserved behavior, and required screen
28
29
 
29
30
  ## Reject
30
31
 
31
- Implementing in the planning pass. Asking one chat to play every role. Skipping `supabase-auth-rls` because “it’s just a table.”
32
+ Implementing in the planning pass. Asking one chat to play every role. Skipping `supabase-auth-rls` because “it’s just a table.” Skipping `nextjs-app-router` because the route is small. Skipping Design `setup` on a new product UI because “we’ll pick colors in CSS.” Skipping `accessibility-wcag` because “contrast looks fine in the screenshot.” Skipping `testing-qa` because “we’ll add tests later” on auth/RLS.
@@ -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.