codebyplan 1.5.1 → 1.8.0

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 (205) hide show
  1. package/dist/cli.js +4462 -748
  2. package/package.json +5 -1
  3. package/templates/.gitkeep +0 -0
  4. package/templates/README.md +20 -0
  5. package/templates/agents/cbp-cc-executor.md +213 -0
  6. package/templates/agents/cbp-database-agent.md +229 -0
  7. package/templates/agents/cbp-improve-claude.md +245 -0
  8. package/templates/agents/cbp-improve-round.md +284 -0
  9. package/templates/agents/cbp-mechanical-edits.md +111 -0
  10. package/templates/agents/cbp-research.md +282 -0
  11. package/templates/agents/cbp-round-executor.md +604 -0
  12. package/templates/agents/cbp-security-agent.md +134 -0
  13. package/templates/agents/cbp-task-check.md +213 -0
  14. package/templates/agents/cbp-task-planner.md +582 -0
  15. package/templates/agents/cbp-test-e2e-agent.md +363 -0
  16. package/templates/agents/cbp-testing-qa-agent.md +400 -0
  17. package/templates/context/mcp-docs.md +139 -0
  18. package/templates/hooks/README.md +236 -0
  19. package/templates/hooks/cbp-auto-test-hooks.sh +44 -0
  20. package/templates/hooks/cbp-lint-format-on-edit.sh +159 -0
  21. package/templates/hooks/cbp-maestro-yaml-validate.sh +100 -0
  22. package/templates/hooks/cbp-mcp-migration-guard.sh +32 -0
  23. package/templates/hooks/cbp-mcp-round-sync.sh +79 -0
  24. package/templates/hooks/cbp-mcp-worktree-inject.sh +76 -0
  25. package/templates/hooks/cbp-notify.sh +68 -0
  26. package/templates/hooks/cbp-plugin-dispatch.sh +29 -0
  27. package/templates/hooks/cbp-pre-commit-quality-gate.sh +204 -0
  28. package/templates/hooks/cbp-statusline.sh +347 -0
  29. package/templates/hooks/cbp-subagent-statusline.sh +182 -0
  30. package/templates/hooks/cbp-test-coverage-gate.sh +144 -0
  31. package/templates/hooks/cbp-test-hooks.sh +320 -0
  32. package/templates/hooks/hooks.json +85 -0
  33. package/templates/hooks/validate-context-usage.sh +59 -0
  34. package/templates/hooks/validate-git-commit.sh +78 -0
  35. package/templates/hooks/validate-git-stash-deny.sh +32 -0
  36. package/templates/hooks/validate-structure-lengths.sh +57 -0
  37. package/templates/hooks/validate-structure-lib.sh +104 -0
  38. package/templates/hooks/validate-structure-patterns.sh +54 -0
  39. package/templates/hooks/validate-structure-scope.sh +33 -0
  40. package/templates/hooks/validate-structure-smoke.sh +95 -0
  41. package/templates/hooks/validate-structure-templates.sh +34 -0
  42. package/templates/hooks/validate-structure.sh +69 -0
  43. package/templates/rules/.gitkeep +0 -0
  44. package/templates/rules/README.md +47 -0
  45. package/templates/rules/context-file-loading.md +52 -0
  46. package/templates/rules/scope-vocabulary.md +64 -0
  47. package/templates/rules/todo-backend.md +109 -0
  48. package/templates/settings.project.base.json +55 -0
  49. package/templates/settings.user.base.json +25 -0
  50. package/templates/skills/cbp-build-cc-agent/SKILL.md +139 -0
  51. package/templates/skills/cbp-build-cc-agent/examples/read-only-reviewer.md +32 -0
  52. package/templates/skills/cbp-build-cc-agent/examples/with-hooks.md +41 -0
  53. package/templates/skills/cbp-build-cc-agent/examples/with-skills-preload.md +25 -0
  54. package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +153 -0
  55. package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +37 -0
  56. package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +18 -0
  57. package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +67 -0
  58. package/templates/skills/cbp-build-cc-agent/templates/agent.md +66 -0
  59. package/templates/skills/cbp-build-cc-claude-file/SKILL.md +178 -0
  60. package/templates/skills/cbp-build-cc-claude-file/examples/minimal-project.md +33 -0
  61. package/templates/skills/cbp-build-cc-claude-file/examples/monorepo-with-imports.md +39 -0
  62. package/templates/skills/cbp-build-cc-claude-file/reference/imports.md +72 -0
  63. package/templates/skills/cbp-build-cc-claude-file/reference/what-belongs.md +39 -0
  64. package/templates/skills/cbp-build-cc-claude-file/templates/project-claude-md.md +48 -0
  65. package/templates/skills/cbp-build-cc-claude-file/templates/user-claude-md.md +22 -0
  66. package/templates/skills/cbp-build-cc-memory/SKILL.md +201 -0
  67. package/templates/skills/cbp-build-cc-memory/examples/feedback-memory.md +11 -0
  68. package/templates/skills/cbp-build-cc-memory/examples/project-memory.md +11 -0
  69. package/templates/skills/cbp-build-cc-memory/examples/reference-memory.md +13 -0
  70. package/templates/skills/cbp-build-cc-memory/examples/user-memory.md +14 -0
  71. package/templates/skills/cbp-build-cc-memory/reference/memory-types.md +59 -0
  72. package/templates/skills/cbp-build-cc-memory/reference/when-to-save.md +62 -0
  73. package/templates/skills/cbp-build-cc-memory/templates/MEMORY-index.md +4 -0
  74. package/templates/skills/cbp-build-cc-memory/templates/memory-entry.md +15 -0
  75. package/templates/skills/cbp-build-cc-mode/SKILL.md +99 -0
  76. package/templates/skills/cbp-build-cc-rule/SKILL.md +176 -0
  77. package/templates/skills/cbp-build-cc-rule/examples/global-rule.md +19 -0
  78. package/templates/skills/cbp-build-cc-rule/examples/scoped-rule.md +41 -0
  79. package/templates/skills/cbp-build-cc-rule/reference/paths-patterns.md +48 -0
  80. package/templates/skills/cbp-build-cc-rule/templates/rule.md +32 -0
  81. package/templates/skills/cbp-build-cc-settings/SKILL.md +220 -0
  82. package/templates/skills/cbp-build-cc-settings/examples/hooks-config.json +64 -0
  83. package/templates/skills/cbp-build-cc-settings/examples/permissions-config.json +34 -0
  84. package/templates/skills/cbp-build-cc-settings/examples/sandbox-config.json +42 -0
  85. package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +104 -0
  86. package/templates/skills/cbp-build-cc-settings/reference/permission-rules.md +61 -0
  87. package/templates/skills/cbp-build-cc-settings/reference/scope-precedence.md +73 -0
  88. package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +166 -0
  89. package/templates/skills/cbp-build-cc-settings/templates/settings.json +23 -0
  90. package/templates/skills/cbp-build-cc-settings/templates/settings.local.json +10 -0
  91. package/templates/skills/cbp-build-cc-skill/SKILL.md +154 -0
  92. package/templates/skills/cbp-build-cc-skill/examples/dynamic-context.md +31 -0
  93. package/templates/skills/cbp-build-cc-skill/examples/fork-skill.md +22 -0
  94. package/templates/skills/cbp-build-cc-skill/examples/knowledge-skill.md +25 -0
  95. package/templates/skills/cbp-build-cc-skill/examples/task-skill.md +29 -0
  96. package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +157 -0
  97. package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +35 -0
  98. package/templates/skills/cbp-build-cc-skill/reference/string-substitutions.md +60 -0
  99. package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +90 -0
  100. package/templates/skills/cbp-build-cc-skill/templates/skill.md +51 -0
  101. package/templates/skills/cbp-checkpoint-check/SKILL.md +156 -0
  102. package/templates/skills/cbp-checkpoint-complete/SKILL.md +109 -0
  103. package/templates/skills/cbp-checkpoint-create/SKILL.md +287 -0
  104. package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
  105. package/templates/skills/cbp-checkpoint-update/SKILL.md +115 -0
  106. package/templates/skills/cbp-frontend-a11y/SKILL.md +109 -0
  107. package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +130 -0
  108. package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +122 -0
  109. package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +154 -0
  110. package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +111 -0
  111. package/templates/skills/cbp-frontend-design/SKILL.md +145 -0
  112. package/templates/skills/cbp-frontend-design/reference/nextjs-scss.md +118 -0
  113. package/templates/skills/cbp-frontend-design/reference/rn-expo.md +101 -0
  114. package/templates/skills/cbp-frontend-design/reference/tauri-react.md +82 -0
  115. package/templates/skills/cbp-frontend-ui/SKILL.md +262 -0
  116. package/templates/skills/cbp-frontend-ui/reference/ui-label-maps.md +42 -0
  117. package/templates/skills/cbp-frontend-ui/reference/ui-layout-patterns.md +105 -0
  118. package/templates/skills/cbp-frontend-ui/reference/variant-defaults.md +149 -0
  119. package/templates/skills/cbp-frontend-ux/SKILL.md +181 -0
  120. package/templates/skills/cbp-git-branch-feat-create/SKILL.md +115 -0
  121. package/templates/skills/cbp-git-commit/SKILL.md +278 -0
  122. package/templates/skills/cbp-git-worktree-create/SKILL.md +226 -0
  123. package/templates/skills/cbp-git-worktree-remove/SKILL.md +145 -0
  124. package/templates/skills/cbp-merge-main/SKILL.md +228 -0
  125. package/templates/skills/cbp-round-check/SKILL.md +104 -0
  126. package/templates/skills/cbp-round-end/SKILL.md +183 -0
  127. package/templates/skills/cbp-round-end/reference/findings-presentation.md +44 -0
  128. package/templates/skills/cbp-round-end/reference/inline-fallback.md +35 -0
  129. package/templates/skills/cbp-round-execute/SKILL.md +211 -0
  130. package/templates/skills/cbp-round-execute/reference/inline-fallback.md +59 -0
  131. package/templates/skills/cbp-round-input/SKILL.md +165 -0
  132. package/templates/skills/cbp-round-start/SKILL.md +222 -0
  133. package/templates/skills/cbp-round-update/SKILL.md +163 -0
  134. package/templates/skills/cbp-session-end/SKILL.md +187 -0
  135. package/templates/skills/cbp-session-start/SKILL.md +155 -0
  136. package/templates/skills/cbp-ship/SKILL.md +332 -0
  137. package/templates/skills/cbp-ship/reference/changesets-overview.md +120 -0
  138. package/templates/skills/cbp-ship/reference/eas-cli-overview.md +60 -0
  139. package/templates/skills/cbp-ship/reference/gh-cli-overview.md +135 -0
  140. package/templates/skills/cbp-ship/reference/gh-cli-shipment-commands.md +283 -0
  141. package/templates/skills/cbp-ship/reference/npm-publish-monorepo.md +252 -0
  142. package/templates/skills/cbp-ship/reference/npm-publish-oidc-trusted.md +157 -0
  143. package/templates/skills/cbp-ship/reference/npm-publish-overview.md +171 -0
  144. package/templates/skills/cbp-ship/reference/preflight-checklist.md +88 -0
  145. package/templates/skills/cbp-ship/reference/railway-nestjs-deployment.md +169 -0
  146. package/templates/skills/cbp-ship/reference/railway-overview.md +120 -0
  147. package/templates/skills/cbp-ship/reference/railway-troubleshooting.md +168 -0
  148. package/templates/skills/cbp-ship/reference/release-please-overview.md +99 -0
  149. package/templates/skills/cbp-ship/reference/surface-expo-eas.md +155 -0
  150. package/templates/skills/cbp-ship/reference/surface-npm.md +180 -0
  151. package/templates/skills/cbp-ship/reference/surface-railway.md +152 -0
  152. package/templates/skills/cbp-ship/reference/surface-supabase.md +178 -0
  153. package/templates/skills/cbp-ship/reference/surface-tauri.md +138 -0
  154. package/templates/skills/cbp-ship/reference/surface-vercel.md +124 -0
  155. package/templates/skills/cbp-ship/reference/surface-vscode-ext.md +144 -0
  156. package/templates/skills/cbp-ship/reference/surfaces.md +60 -0
  157. package/templates/skills/cbp-ship/reference/testflight-automation.md +215 -0
  158. package/templates/skills/cbp-ship/reference/testflight-internal-vs-external.md +69 -0
  159. package/templates/skills/cbp-ship/reference/testflight-overview.md +98 -0
  160. package/templates/skills/cbp-ship/reference/versioning.md +116 -0
  161. package/templates/skills/cbp-ship/scripts/detect-surfaces.sh +217 -0
  162. package/templates/skills/cbp-ship/scripts/verify-expo-eas.sh +35 -0
  163. package/templates/skills/cbp-ship/scripts/verify-npm.sh +21 -0
  164. package/templates/skills/cbp-ship/scripts/verify-railway.sh +41 -0
  165. package/templates/skills/cbp-ship/scripts/verify-supabase.sh +19 -0
  166. package/templates/skills/cbp-ship/scripts/verify-tauri.sh +24 -0
  167. package/templates/skills/cbp-ship/scripts/verify-vercel.sh +32 -0
  168. package/templates/skills/cbp-ship/scripts/verify-vscode-ext.sh +25 -0
  169. package/templates/skills/cbp-ship/templates/eas.json +66 -0
  170. package/templates/skills/cbp-ship/templates/railway.toml +15 -0
  171. package/templates/skills/cbp-ship/templates/release-please-config.json +17 -0
  172. package/templates/skills/cbp-ship/templates/vercel.json +19 -0
  173. package/templates/skills/cbp-ship/templates/vscodeignore +21 -0
  174. package/templates/skills/cbp-ship/templates/workflow-changesets.yml +41 -0
  175. package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +53 -0
  176. package/templates/skills/cbp-ship/templates/workflow-npm-publish.yml +36 -0
  177. package/templates/skills/cbp-ship/templates/workflow-release-please.yml +21 -0
  178. package/templates/skills/cbp-ship/templates/workflow-tauri-release.yml +69 -0
  179. package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +31 -0
  180. package/templates/skills/cbp-ship-configure/SKILL.md +296 -0
  181. package/templates/skills/cbp-ship-configure/reference/expo-mobile.md +204 -0
  182. package/templates/skills/cbp-ship-configure/reference/npm-package.md +165 -0
  183. package/templates/skills/cbp-ship-configure/reference/railway-backend.md +199 -0
  184. package/templates/skills/cbp-ship-configure/reference/supabase.md +200 -0
  185. package/templates/skills/cbp-ship-configure/reference/tauri-desktop.md +181 -0
  186. package/templates/skills/cbp-ship-configure/reference/vercel.md +117 -0
  187. package/templates/skills/cbp-ship-configure/reference/vscode-ext.md +155 -0
  188. package/templates/skills/cbp-ship-main/SKILL.md +65 -0
  189. package/templates/skills/cbp-supabase-branch-check/SKILL.md +337 -0
  190. package/templates/skills/cbp-supabase-branch-check/reference/dag-steps.md +29 -0
  191. package/templates/skills/cbp-supabase-migrate/SKILL.md +314 -0
  192. package/templates/skills/cbp-supabase-migrate/reference/advisor-triage.md +70 -0
  193. package/templates/skills/cbp-supabase-migrate/reference/cli-fallback.md +87 -0
  194. package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +58 -0
  195. package/templates/skills/cbp-supabase-setup/SKILL.md +239 -0
  196. package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +121 -0
  197. package/templates/skills/cbp-supabase-setup/reference/cli-fallback.md +109 -0
  198. package/templates/skills/cbp-task-check/SKILL.md +166 -0
  199. package/templates/skills/cbp-task-complete/SKILL.md +206 -0
  200. package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +48 -0
  201. package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +56 -0
  202. package/templates/skills/cbp-task-create/SKILL.md +167 -0
  203. package/templates/skills/cbp-task-start/SKILL.md +239 -0
  204. package/templates/skills/cbp-task-testing/SKILL.md +277 -0
  205. package/templates/skills/cbp-todo/SKILL.md +97 -0
@@ -0,0 +1,262 @@
1
+ ---
2
+ scope: org-shared
3
+ name: cbp-frontend-ui
4
+ description: Visual quality self-review pass invoked twice per round — once by round-executor Step 3.8 (phase 'style_only', no screenshots) for token/spacing/typography/color/cohesion, once by /cbp-round-execute Step 5b (phase 'screenshot_review', with e2e screenshots) for rendered-output review and baseline regressions. Default phase 'full' runs everything for back-compat.
5
+ effort: xhigh
6
+ ---
7
+
8
+ # Frontend UI (Post-Implementation Visual Self-Review)
9
+
10
+ Invoked twice per round in non-`claude_only` profiles:
11
+
12
+ 1. `round-executor` Step 3.8 — `phase: 'style_only'`, no e2e screenshots. Reviews token/spacing/typography/color/cohesion against the just-written code.
13
+ 2. `/cbp-round-execute` Step 5b — `phase: 'screenshot_review'`, with screenshots from `test-e2e-agent`. Reviews rendered output and detects baseline regressions.
14
+
15
+ Default `phase: 'full'` runs everything (back-compat for any caller not yet migrated). Inline counterpart of the up-front `frontend-design` skill — `frontend-design` decides direction before code; `frontend-ui` reviews and polishes after code.
16
+
17
+ ## When this skill fires
18
+
19
+ Round-executor invokes when the round's `files_changed` contains ANY of:
20
+
21
+ - `*.tsx`, `*.jsx` (React, RN, RN-Web components)
22
+ - `*.scss`, `*.css`, `*.module.{scss,css}`
23
+ - Files under design-system / token folders, app-level styles
24
+ - New page / screen / route / component files
25
+
26
+ Same trigger condition as Step 2.7's `frontend-design` pre-implementation pass. If none match, skip — proceed to Step 4 (Quality Checks).
27
+
28
+ ## Input Contract
29
+
30
+ ```yaml
31
+ input:
32
+ task_number: number
33
+ round_number: number
34
+ phase: 'full' | 'style_only' | 'screenshot_review' # Default 'full'. Phase Gate at Workflow start routes execution.
35
+ files_changed: [{path, action}]
36
+ context:
37
+ checkpoint_goal: string
38
+ round_requirements: string
39
+ e2e_screenshots: # Required for phase 'screenshot_review' or 'full' (when present); empty / omitted for 'style_only'. Sourced from round.context.e2e_output.screenshots (populated by test-e2e-agent at /cbp-round-execute Step 5).
40
+ - test_name: string
41
+ path: string # Repo-relative or absolute path to PNG
42
+ page_or_screen: string
43
+ viewport: 'desktop' | 'mobile' | 'tablet' | 'device'
44
+ is_new: bool # No baseline existed (new screen)
45
+ baseline_diff_pct: number | null # Pixel-diff % vs Playwright baseline
46
+ ```
47
+
48
+ ## Output Contract
49
+
50
+ ```yaml
51
+ output:
52
+ status: 'completed'
53
+ findings:
54
+ - category: 'tokens' | 'spacing' | 'typography' | 'color' | 'layout' | 'cohesion' | 'rendered_visual' | 'baseline_regression'
55
+ severity: 'critical' | 'warning' | 'suggestion'
56
+ file: string # Source file OR screenshot path (for rendered_visual / baseline_regression)
57
+ line: number | null # null when finding originates from a screenshot
58
+ issue: string
59
+ suggestion: string
60
+ screenshot: string | null # Path to screenshot this finding was derived from (if any)
61
+ files_changed:
62
+ - path: string
63
+ action: 'modified'
64
+ fix_for: string # Which finding this fix addresses
65
+ screenshot_review:
66
+ reviewed: number # Count of e2e_screenshots reviewed
67
+ baseline_regressions: number # Count with baseline_diff_pct > threshold
68
+ new_screens_reviewed: number # Count with is_new == true
69
+ summary:
70
+ total_issues: number
71
+ critical: number
72
+ warnings: number
73
+ suggestions: number
74
+ auto_fixed: number
75
+ ```
76
+
77
+ The executor writes the output to `round.context.frontend_ui_review` and merges `files_changed` into the round's `files_changed` list.
78
+
79
+ ## Reference Material
80
+
81
+ Pattern references this skill consults during review (folded from former standalone skills):
82
+
83
+ - `reference/ui-layout-patterns.md` — navbar height, focus-visible, z-index layering, fluid heights, logo overflow
84
+ - `reference/variant-defaults.md` — `createResolver`, `SIZE_VARIANTS`, `COLOR_VARIANTS`, `CUSTOM_VARIANTS`, lightweight variant maps
85
+ - `reference/ui-label-maps.md` — humanising DB column names + enum values for user-facing UI
86
+
87
+ ## Workflow
88
+
89
+ ### Phase Gate (preamble)
90
+
91
+ Read `input.phase` (default `'full'` when absent). The gate routes which phases run:
92
+
93
+ | Phase value | Phases that run |
94
+ |-------------|----------------|
95
+ | `'full'` (default) | All phases — 1, 2, 2.5, 3, 4, 5, 6, **6.5** (when `e2e_screenshots[]` non-empty), 7, 8 |
96
+ | `'style_only'` | Phases 1, 2, 2.5, 3, 4, 5, 6, 7, 8 (Phase 6.5 is SKIPPED regardless of `e2e_screenshots[]`) |
97
+ | `'screenshot_review'` | Phases 1 (read changed files only — needed for design-source comparison), **6.5**, 7, 8 (Phase 8 is a no-op for `rendered_visual` / `baseline_regression` — those categories are never auto-fixed) |
98
+
99
+ When `phase === 'screenshot_review'` and `e2e_screenshots[]` is empty, return immediately with `status: 'completed'` and an empty `findings[]` — caller asked for screenshot review but provided no screenshots.
100
+
101
+ When `phase === 'style_only'` and `files_changed[]` contains no UI files (no `*.tsx`, `*.scss`, `*.css`, design-token folders), return immediately with `status: 'completed'` and an empty `findings[]`.
102
+
103
+ ### Phase 1: Read Changed Files
104
+
105
+ Read all `.tsx`, `.scss`, and `variants.ts` files from `files_changed`.
106
+
107
+ ### Phase 2: Design Token Compliance
108
+
109
+ For each SCSS file:
110
+ - Check that colors use semantic tokens (`$color-brand-*`, `$color-highlight-*`), never raw hex/rgb
111
+ - Check spacing uses fluid tokens (`fluid()`, `$spacing-*`), never hardcoded px for layout
112
+ - Check typography uses type scale tokens (`$font-size-*`, `$font-weight-*`)
113
+ - Check z-index uses layering tokens, never arbitrary numbers — see `reference/ui-layout-patterns.md` "Z-Index Layers"
114
+
115
+ For each TSX file:
116
+ - Check inline styles are not used (should be SCSS modules)
117
+ - Check className uses styles from module imports
118
+
119
+ ### Phase 2.5: Design Source Comparison
120
+
121
+ When changed files belong to a page that has design source PNGs at a project-known design-sources path (e.g. `docs/design/`, `docs/development/product/sources/design/`):
122
+
123
+ 1. **Read** the design source PNG for the relevant page/component
124
+ 2. **Compare** the implemented component structure against the design source
125
+ 3. **Flag as critical** any of these mismatches:
126
+ - Wrong control shape (e.g. pill vs flat button, toggle vs stepper)
127
+ - Wrong background color (e.g. grey when design shows white)
128
+ - Missing dividers or separators shown in design
129
+ - Wrong column placement (e.g. controls in label column instead of action column)
130
+ - Wrong row/grid structure (e.g. stacked when design shows inline)
131
+ 4. Add findings to output with `category: 'cohesion'` and `severity: 'critical'`
132
+
133
+ If no design source PNGs exist for the changed pages, skip this phase.
134
+
135
+ ### Phase 3: Spacing Consistency
136
+
137
+ - Verify consistent spacing patterns within components (same spacing system)
138
+ - Check padding/margin consistency across sibling elements
139
+ - Verify fluid spacing is used for layout, em-based for typography-adjacent
140
+
141
+ ### Phase 4: Typography Review
142
+
143
+ - Check font-family assignments use design tokens
144
+ - Verify heading hierarchy (h1 > h2 > h3 in size)
145
+ - Check line-height and letter-spacing use tokens
146
+ - Verify responsive typography uses fluid values
147
+
148
+ ### Phase 5: Color Usage
149
+
150
+ - Check color semantics (brand vs highlight vs accent vs interactive)
151
+ - Verify hover/focus states use correct color variants — see `reference/ui-layout-patterns.md` "Focus-Visible" and `reference/variant-defaults.md` "COLOR_VARIANTS"
152
+ - Check dark mode compatibility if applicable
153
+ - Verify sufficient contrast ratios (reference WCAG)
154
+
155
+ ### Phase 6: Visual Cohesion
156
+
157
+ - Check that new components match visual patterns of existing components
158
+ - Verify consistent border-radius, shadow, and transition usage
159
+ - Check animation patterns follow existing conventions
160
+ - For variant components: verify `variants.ts` follows the resolver patterns in `reference/variant-defaults.md` (no duplicate defaults, correct layer ordering)
161
+ - For DB-sourced strings rendered in JSX (snake_case enums, trigger types, status codes): verify `LABELS` const maps are used per `reference/ui-label-maps.md`
162
+
163
+ ### Phase 6.5: Rendered-Output Visual Review (from E2E screenshots)
164
+
165
+ **Runs only if `e2e_screenshots[]` is non-empty.** This is the critical step that closes the loop — e2e tests proved behavior works; this step checks what the screen actually looks like.
166
+
167
+ For each screenshot in `e2e_screenshots[]`:
168
+
169
+ 1. **Read the PNG via the Read tool** (Claude multimodal — the PNG is shown to the model directly). Do not use Bash to inspect bytes.
170
+ 2. **Check baseline regression** (`baseline_diff_pct != null`):
171
+ - If `baseline_diff_pct > 0.1%`: emit finding `{category: 'baseline_regression', severity: 'critical', file: {path}, screenshot: {path}, issue: 'Pixel diff vs committed baseline: {diff_pct}%', suggestion: 'Inspect the diff PNG (same folder, -diff suffix). Either fix the regression or, if intentional, run `playwright test --update-snapshots` and commit the new baseline.'}`
172
+ - Do NOT auto-update baselines. The user must explicitly approve via QA.
173
+ 3. **Semantic review of rendered output** (both new screens and existing):
174
+ - **Text overflow / truncation** — text clipped, ellipsis in unintended places, buttons cut off
175
+ - **Unstyled elements** — unbranded default fonts, missing styles (flash of unstyled content captured), default blue links
176
+ - **Missing imagery / broken images** — placeholder icons, broken-image glyphs, avatar fallback unstyled
177
+ - **Contrast failures** — text barely visible against background (WCAG fail)
178
+ - **Layout breaks** — overlapping elements, pushed-off-canvas content, unintended scrollbars, empty whitespace where content should be
179
+ - **Loading-state artifacts** — spinner visible in final-state screenshot (data didn't load in time or empty-state is wrong)
180
+ - **Error-boundary leaks** — "Something went wrong" / red error banners that shouldn't be there
181
+ - **Design-source mismatch** (if a design-source PNG exists for the page) — compare rendered to designed
182
+ 4. **Emit findings** with `category: 'rendered_visual'`, the screenshot path in `screenshot`, and `line: null`. Severity: `critical` for broken state (overflow, missing images, error banners, contrast fails), `warning` for cosmetic misalignment, `suggestion` for minor polish.
183
+ 5. **Cross-viewport consistency**: if the same `page_or_screen` appears at multiple viewports (desktop + mobile), verify responsive behavior is correct (nothing cropped at mobile, desktop isn't mobile-sized). Emit `{category: 'layout', severity: 'warning', …}` on mismatch.
184
+
185
+ Populate `screenshot_review` totals.
186
+
187
+ **Do not attempt to auto-fix `rendered_visual` or `baseline_regression` findings** — they feed into user QA and the fix loop, because the root cause is typically in app code/data, not in the SCSS.
188
+
189
+ ### Phase 7: Aggregate Findings
190
+
191
+ Categorize all issues by severity:
192
+ - **Critical**: Hardcoded colors/spacing, missing tokens, broken layout
193
+ - **Warning**: Inconsistent spacing, non-standard patterns
194
+ - **Suggestion**: Minor visual improvements, optional enhancements
195
+
196
+ ### Phase 8: Auto-Fix In-Scope Findings
197
+
198
+ For every finding in `category` ∈ {`tokens`, `spacing`, `typography`, `color`, `layout`, `cohesion`} — critical, warning, and suggestion — apply the fix directly when the target file is in `files_changed`:
199
+
200
+ #### Pre-Edit Scope Gate (MANDATORY)
201
+
202
+ Before any Write/Edit:
203
+
204
+ 1. Build `allowed = new Set(input.files_changed.map(f => f.path))`.
205
+ 2. If the target path is in `allowed`, proceed to apply the fix.
206
+ 3. If the target path is NOT in `allowed`, do NOT edit. Instead:
207
+ - Emit the proposed fix as a `findings[]` entry with the appropriate severity and a `suggestion` describing the change verbatim.
208
+ - Set `auto_fixed = false` for that finding.
209
+ - Increment `summary.out_of_scope_fixes`.
210
+
211
+ The skill's auto-fix capability is for in-scope polish, not opportunistic sweeps of unrelated files. The scope gate prevents the round's diff from absorbing visual changes outside the round's contract.
212
+
213
+ **Specifically forbidden** (always out of scope, never edited regardless of `files_changed`):
214
+
215
+ - `.claude/**` — managed infrastructure under user-level governance
216
+ - Project test infrastructure (e.g., `playwright.config.*`, `e2e/**`) — governed by `test-e2e-agent`
217
+ - DB migrations (e.g., `supabase/migrations/**`) — governed by `database-agent`
218
+ - Vendor mirrors and read-only reference trees
219
+
220
+ #### In-Scope Auto-Fix Procedure
221
+
222
+ For findings whose target file IS in `allowed`:
223
+
224
+ 1. Read the file at the reported line
225
+ 2. Apply the fix (replace hardcoded hex with token, swap px for fluid spacing, improve visual consistency, refine typography, enhance cohesion)
226
+ 3. Track in `files_changed` with `fix_for` referencing the finding
227
+
228
+ Go beyond fixing violations — actively improve visual quality. If spacing could be better, improve it. If a component looks inconsistent with siblings, align it. Deliver polished UI, not just compliant UI.
229
+
230
+ **Do not auto-fix** findings with `category` ∈ {`rendered_visual`, `baseline_regression`} — these surface through QA and the fix loop because the root cause is typically in app state/data, not styling.
231
+
232
+ **Do not modify** component logic or behavior — only visual/design work.
233
+
234
+ ## Completion Criteria
235
+
236
+ - All changed SCSS/TSX files reviewed
237
+ - Token compliance checked
238
+ - Spacing consistency verified
239
+ - **All `e2e_screenshots` reviewed** (when provided) — rendered output checked for overflow, unstyled elements, missing imagery, contrast, layout breaks, loading/error artifacts, design-source fidelity
240
+ - Baseline regressions surfaced (never auto-accepted)
241
+ - Critical/warning issues auto-fixed where possible (styling only, in-scope only)
242
+ - Findings categorized by severity
243
+
244
+ ## Failure Modes
245
+
246
+ | Condition | Status | What to populate |
247
+ |---|---|---|
248
+ | No UI files changed AND `e2e_screenshots[]` is empty | `completed` | Empty `findings[]`, `summary.total_issues: 0`, `screenshot_review: {reviewed: 0, ...}` — caller decided to invoke; return clean |
249
+ | Screenshot path in `e2e_screenshots[]` cannot be read (missing file, corrupt PNG) | `completed` | Add `{category: 'rendered_visual', severity: 'warning', file: {path}, issue: 'Screenshot unreadable — visual review skipped for this state'}` and continue with the remaining screenshots |
250
+ | Design source PNG referenced but missing | `completed` | Skip Phase 2.5 for that page; note in finding with `category: 'cohesion', severity: 'suggestion'` that design source should be added |
251
+ | Auto-fix attempt introduces a syntax error in an SCSS/TSX file | `completed` | Revert the auto-fix, keep the finding as a non-fixed entry, do NOT silently leave the file broken |
252
+
253
+ ## Integration
254
+
255
+ - **Loaded twice per round** (non-`claude_only` profiles):
256
+ 1. `round-executor` Step 3.8 with `phase: 'style_only'` and empty `e2e_screenshots[]` — reviews the just-written code's tokens/spacing/typography/color/cohesion (mandatory when files_changed contains UI / styling files)
257
+ 2. `/cbp-round-execute` Step 5b with `phase: 'screenshot_review'` and screenshots from `round.context.e2e_output.screenshots` — runs Phase 6.5 only (rendered-output review + baseline regressions). Skipped when no e2e ran (`claude_only` / `backend` / `has_ui_work === false`).
258
+ - **Also invoked by**: `/cbp-checkpoint-check` (TASK-2 deliverable, future) with screenshots from a whole-checkpoint e2e run
259
+ - **Consumes**: `e2e_screenshots[]` from `round.context.e2e_output.screenshots` (populated by `test-e2e-agent` at `/cbp-round-execute` Step 5)
260
+ - **Output written to**: `round.context.frontend_ui_review` — when invoked twice per round, the second invocation merges with the first
261
+ - **User-QA construction (downstream)**: this skill emits `findings[]` only — it does NOT construct user_qa items. `/cbp-round-end` Step 3b reads `round.context.frontend_ui_review.findings[]` and aggregates baseline-regression + rendered-visual-critical entries into the round's `user_qa[]`. Single source of truth for the user_qa schema lives at round-end.
262
+ - **Paired with**: `frontend-design` (pre-implementation aesthetic decision), `frontend-ux` (interaction-quality self-review, also Step 3.8)
@@ -0,0 +1,42 @@
1
+ # UI Label Maps
2
+
3
+ Pattern for humanizing DB column names, enum values, and trigger types when displayed in user-facing JSX.
4
+
5
+ When displaying database column names, enum values, trigger types, or status codes in user-facing JSX, define a `LABELS` const map in the same component file (or a shared labels module).
6
+
7
+ ## Pattern
8
+
9
+ ```ts
10
+ const TRIGGER_LABELS: Record<string, string> = {
11
+ port_changed: "Port Changed",
12
+ repo_created: "Repo Created",
13
+ tech_stack_changed: "Tech Stack Changed",
14
+ port_conflict_detected: "Port Conflict",
15
+ created: "Created",
16
+ };
17
+
18
+ function formatTriggerLabel(trigger: string | null | undefined): string {
19
+ if (!trigger) return "Event";
20
+ return TRIGGER_LABELS[trigger] ?? trigger;
21
+ }
22
+ ```
23
+
24
+ ## When to Apply
25
+
26
+ - Rendering DB enum columns in JSX (status, type, action, trigger)
27
+ - Displaying changed_field arrays in audit log UIs
28
+ - Showing column names from JSONB context fields
29
+ - ANY snake_case string sourced from DB that a user will see
30
+
31
+ ## Anti-Pattern
32
+
33
+ NEVER render `{event.trigger}` directly when trigger is a snake_case enum. Users see "PORT_CHANGED" with no context.
34
+
35
+ ## Shared vs Local Maps
36
+
37
+ - **Local** (in component file): map is used in 1 component, fewer than ~10 entries
38
+ - **Shared** (`apps/web/src/lib/labels/`): map is used in 2+ components OR has 10+ entries
39
+
40
+ ## Source
41
+
42
+ CHK-077 TASK-3 Round 2 required adding `TRIGGER_LABELS` + `FIELD_LABELS` maps to `TaskDetail.tsx` after testing-qa flagged raw snake_case in the event timeline.
@@ -0,0 +1,105 @@
1
+ # UI Layout Patterns
2
+
3
+ Navbar layout patterns, focus-visible accessibility conventions, and z-index layering. Ensures consistent navbar implementation and proper focus-visible accessibility across all client projects.
4
+
5
+ Apply when working with Navbar components, focus-visible styles, or z-index layering in `.scss` files.
6
+
7
+ ## 1. Navbar Height is Fluid
8
+
9
+ ```scss
10
+ // layout/_variables.scss
11
+ $navbar-height: fluid(3.5rem, 4.5rem); // 56px -> 72px responsive
12
+ ```
13
+
14
+ All navbar molecules use the layout variable:
15
+
16
+ ```scss
17
+ @use '../../../../styles/layout' as layout;
18
+ .desktop { height: layout.$navbar-height; }
19
+ ```
20
+
21
+ ## 2. Logo Sizing Based on Navbar
22
+
23
+ Logo size derives from navbar height:
24
+
25
+ ```scss
26
+ $_logo-nav-size: calc(#{layout.$navbar-height} * 0.6);
27
+
28
+ .logo {
29
+ &--nav { font-size: $_logo-nav-size; }
30
+ &--nav-mobile { height: layout.$navbar-height; font-size: $_logo-nav-size; }
31
+ }
32
+ ```
33
+
34
+ ## 3. Logo Overflow
35
+
36
+ Logo can overflow navbar with absolute positioning:
37
+
38
+ ```scss
39
+ .logo {
40
+ &--nav {
41
+ position: absolute;
42
+ top: 50%;
43
+ transform: translateY(-50%);
44
+ z-index: calc(layout.z-index('navbar') + 1);
45
+ }
46
+ }
47
+
48
+ .desktop {
49
+ position: relative; // Positioning context
50
+ overflow: visible; // Allow overflow
51
+ }
52
+ ```
53
+
54
+ ## 4. Navbar Variants
55
+
56
+ | Variant | Component | Height | Notes |
57
+ |---------|-----------|--------|-------|
58
+ | Desktop | Desktop molecule | $navbar-height | Logo overflows |
59
+ | Mobile (collapsed) | MobileOpen | $navbar-height | Logo inside |
60
+ | Mobile (expanded) | MobileClose | 100vh | Full-screen overlay |
61
+
62
+ ## 5. Z-Index Layers
63
+
64
+ ```scss
65
+ layout.z-index('navbar') // Base navbar layer
66
+ layout.z-index('navbar') + 1 // Logo (above navbar)
67
+ layout.z-index('overlay') // Mobile menu overlay
68
+ ```
69
+
70
+ ## 6. Focus-Visible: Always Use the Mixin
71
+
72
+ NEVER write inline `:focus-visible` styles. Always use accessibility module mixins:
73
+
74
+ ```scss
75
+ @use '../../styles/accessibility' as a11y;
76
+
77
+ // CORRECT
78
+ .button { @include a11y.focus-visible; }
79
+
80
+ // WRONG
81
+ .button { &:focus-visible { outline: 2px solid #00a7b3; } }
82
+ ```
83
+
84
+ ## 7. Available Focus Mixins
85
+
86
+ | Mixin | Use Case |
87
+ |-------|----------|
88
+ | `focus-visible` | Standard (2px solid, 2px offset) |
89
+ | `focus-visible-offset($offset)` | Custom offset |
90
+ | `focus-visible-inset` | Inset outline (-2px offset) |
91
+
92
+ ## 8. Border-Radius Affects Focus Outline
93
+
94
+ Add `border-radius` for rounded focus outline:
95
+
96
+ ```scss
97
+ .logo {
98
+ border-radius: 4px;
99
+ @include a11y.focus-visible;
100
+ }
101
+ ```
102
+
103
+ ## 9. Focus vs Hover Colors
104
+
105
+ Use `:focus-visible` (not `:focus`) — shows only on keyboard navigation. Different colors for hover (`$hover-active`) vs focus (`$focus-outline`).
@@ -0,0 +1,149 @@
1
+ # Variant Defaults & Button Patterns
2
+
3
+ 3-layer variant architecture using `createResolver` with SIZE, COLOR, and CUSTOM variants, lightweight variant maps for simpler components, plus button-specific patterns.
4
+
5
+ Apply when working with `variants.ts` files, components in `src/components/buttons/`, or components using size/color variant props with BEM modifier classes. Ensures correct variant resolution order and prevents duplicate defaults.
6
+
7
+ ## 1. 3-Layer Architecture
8
+
9
+ ```
10
+ Props -> createResolver -> CSS Classes
11
+ Resolution Order:
12
+ 1. Custom variant (presets)
13
+ 2. Size variant (typography/spacing)
14
+ 3. Color variant (colors/interactions)
15
+ 4. Direct prop overrides (highest priority)
16
+ ```
17
+
18
+ ## 2. Never Duplicate Defaults
19
+
20
+ Values in SIZE/COLOR/CUSTOM_VARIANTS MUST NOT repeat defaults:
21
+
22
+ ```typescript
23
+ // WRONG
24
+ const defaults = { fontWeight: 'medium', typoPx: 's1' };
25
+ const SIZE_VARIANTS = {
26
+ md: { fontSize: 'body-md', fontWeight: 'medium' }, // duplicates default
27
+ };
28
+
29
+ // CORRECT
30
+ const SIZE_VARIANTS = {
31
+ md: { fontSize: 'body-md' }, // only what differs
32
+ };
33
+ ```
34
+
35
+ ## 3. Layer Definitions
36
+
37
+ **SIZE_VARIANTS** (typography/spacing):
38
+ ```typescript
39
+ const SIZE_VARIANTS = {
40
+ sm: { fontSize: 'body-sm' },
41
+ md: { fontSize: 'body-md' },
42
+ lg: { fontSize: 'body-lg', typoPx: 's15', typoPy: 's1' },
43
+ } as const satisfies Record<string, SizeConfig>;
44
+ ```
45
+
46
+ **COLOR_VARIANTS** (colors/interactions):
47
+ ```typescript
48
+ const COLOR_VARIANTS = {
49
+ primary: { bg: 'primary', text: 'inverse' },
50
+ highlight: { bg: 'highlight', text: 'primary' },
51
+ transparent: { bg: 'transparent', text: 'primary' },
52
+ } as const satisfies Record<string, ColorConfig>;
53
+ ```
54
+
55
+ **CUSTOM_VARIANTS** (presets combining size + color + overrides):
56
+ ```typescript
57
+ const CUSTOM_VARIANTS = {
58
+ cta: {
59
+ colorVariant: 'highlight',
60
+ fontFamily: 'accent',
61
+ glow: 'sm',
62
+ },
63
+ } as const satisfies Record<string, CustomConfig>;
64
+ ```
65
+
66
+ ## 4. Type Annotations Required
67
+
68
+ All variant maps MUST use `as const satisfies Record<string, *Config>`.
69
+
70
+ ## 5. createResolver Setup
71
+
72
+ ```typescript
73
+ import { createResolver, SizeConfig, ColorConfig, CustomConfig } from '@/utils/variants';
74
+
75
+ export const getVariant = createResolver({
76
+ sizes: SIZE_VARIANTS,
77
+ colors: COLOR_VARIANTS,
78
+ custom: CUSTOM_VARIANTS,
79
+ defaults,
80
+ });
81
+ ```
82
+
83
+ ## 6. Button Types
84
+
85
+ ```
86
+ src/components/buttons/
87
+ ├── Button/ # Form submit, modal triggers, state changes
88
+ ├── LinkButton/ # Navigation (links)
89
+ └── IconButton/ # Icon-only actions
90
+ ```
91
+
92
+ All buttons use `createResolver`. Each has 5 files: `index.ts`, `Component.tsx`, `Component.module.scss`, `types.ts`, `variants.ts`.
93
+
94
+ ## 7. Button Defaults
95
+
96
+ | Button | Default Size | Default Color |
97
+ |--------|--------------|---------------|
98
+ | Button | md | primary |
99
+ | LinkButton | md | transparent |
100
+ | IconButton | md | transparent |
101
+
102
+ ## 8. SCSS Modifier Includes
103
+
104
+ All buttons include the standard modifier mixins:
105
+
106
+ ```scss
107
+ .button {
108
+ @include typography.font-family;
109
+ @include typography.font-weight;
110
+ @include typography.font-size;
111
+ @include typography.tracking;
112
+ @include typography.leading;
113
+ @include typography.transform;
114
+ @include typography.typo-px;
115
+ @include typography.typo-py;
116
+ @include typography.typo-gap;
117
+ @include borders.border-radius;
118
+ @include borders.border-width;
119
+ @include borders.border-color;
120
+ @include interactive.color-interactive;
121
+ @include shadows.glow;
122
+ @include a11y.focus-visible;
123
+ }
124
+ ```
125
+
126
+ ## 9. Lightweight Variant Maps (Alternative to createResolver)
127
+
128
+ For components that only need prop-to-BEM-suffix resolution without the full variant pipeline, use simple `Record<TypeUnion, string>` maps or direct prop interpolation.
129
+
130
+ **When to use**: Component has 1-2 variant dimensions (size, color) with no defaults merging, no custom presets, and no resolution priority logic. Common in icon components and simple wrappers.
131
+
132
+ **Pattern A — Direct prop interpolation** (no variants.ts needed):
133
+ ```typescript
134
+ // Prop value IS the BEM suffix — no map needed
135
+ styles[`spinner--${size}`]
136
+ styles[`checkmark--text-${color}`]
137
+ ```
138
+
139
+ **Pattern B — Explicit variant map** (in variants.ts):
140
+ ```typescript
141
+ export const SIZE_VARIANTS: Record<ContainerSize, string> = {
142
+ sm: 'sm',
143
+ md: 'md',
144
+ lg: 'lg',
145
+ }
146
+ // Usage: styles[`container--${SIZE_VARIANTS[size]}`]
147
+ ```
148
+
149
+ **Decision rule**: If prop values map 1:1 to BEM suffixes, use Pattern A. If mapping differs from prop names or you want a centralized variants.ts, use Pattern B. If you need defaults merging, resolution priority, or custom presets, use `createResolver` (sections 1-5).