--- name: preflight description: Pre-commit quality check — verifies TypeScript, ESLint, Prettier, Storybook, token sync, and no hardcoded values argument-hint: "[--fix to auto-fix issues]" --- Run quality checks before committing. Reports pass/fail for each check and blocks commit if critical issues are found. **Mode:** $ARGUMENTS (pass `--fix` to attempt auto-fixes, otherwise report-only) **Run these checks in order:** ### 1. TypeScript compilation ```bash npx tsc --noEmit 2>&1 | grep -v "tokens.js" ``` - **Pass:** No errors (the tokens.js declaration warning is a known pre-existing issue — ignore it) - **Fail:** Any other TypeScript errors → report them - **Critical:** Yes — do not commit if this fails ### 2. Storybook build ```bash npx storybook build --quiet 2>&1 ``` - **Pass:** Build succeeds - **Fail:** Build errors → report them - **Critical:** Yes — do not commit if this fails ### 3. Token sync check Compare timestamps: do the generated outputs (`src/theme/generated/tokens.js`, `src/theme/generated/tokens.css`) have an older modification time than any `tokens/**/*.json` file? ```bash # Find newest token JSON file newest_token=$(find tokens/ -name "*.json" -newer src/theme/generated/tokens.js 2>/dev/null | head -5) ``` - **Pass:** No token JSON files are newer than the generated outputs - **Fail:** Token JSON was modified but outputs weren't regenerated - **Fix:** Run `npm run build:tokens` - **Critical:** Yes — stale generated tokens cause silent bugs ### 4. Hardcoded values scan Scan component files for hardcoded colours, spacing, and font values that should use tokens: ```bash # Check for hex colours in component files (excluding stories and tokens) grep -rn "#[0-9a-fA-F]\{3,8\}" src/components/ --include="*.tsx" --include="*.ts" | grep -v ".stories." | grep -v "// ok-hardcode" ``` - **Pass:** No hex colours found in component source files (stories are exempt) - **Fail:** Hardcoded values found → report file and line - **Note:** Lines with `// ok-hardcode` comment are exempted (for rare intentional cases) - **Critical:** No — warn but don't block commit ### 5. Component exports check Verify each component folder has a barrel export (`index.ts`) and the component has `displayName`: ```bash # Check for missing index.ts for dir in src/components/atoms/*/; do [ -f "$dir/index.ts" ] || echo "Missing index.ts: $dir" done # Check for missing displayName (exclude stories) find src/components/atoms/ -name "*.tsx" ! -name "*.stories.tsx" | xargs grep -L "displayName" 2>/dev/null ``` - **Pass:** All component folders have index.ts and components set displayName - **Fail:** Missing exports or displayName - **Critical:** No — warn but don't block commit ### 6. ESLint ```bash npm run lint 2>&1 ``` - **Pass:** No errors - **Fail:** ESLint errors → report them - **Fix:** Run `npm run lint:fix` - **Critical:** Yes — do not commit if this fails ### 7. Prettier ```bash npm run format:check 2>&1 ``` - **Pass:** All files formatted correctly - **Fail:** Formatting issues found → report them - **Fix:** Run `npm run format` - **Critical:** No — warn but don't block commit (Husky pre-commit hook auto-fixes these) ### Report format ``` PREFLIGHT RESULTS ═══════════════════════════════ ✓ TypeScript .............. PASS ✓ Storybook build ........ PASS ✓ Token sync ............. PASS ⚠ Hardcoded values ....... WARN (2 issues) ✓ Component exports ...... PASS ✓ ESLint ................. PASS ✓ Prettier ............... PASS ─────────────────────────────── Result: PASS (safe to commit) ``` Use `PASS`, `FAIL`, or `WARN`. If any critical check fails, the result is `FAIL (do not commit)`. If only warnings, result is `PASS (safe to commit)` with warnings listed. If `--fix` was passed, attempt to fix issues automatically (e.g., run `npm run build:tokens` for stale tokens) and re-check. ### 8. Visual QA spot-check (manual review, non-blocking) If a component was recently modified, do a quick visual review of the source code for these common issues (adapted from impeccable /polish): - **Transition consistency**: All interactive state changes should use `150ms ease-in-out` (FA convention). Flag mismatches. - **Focus-visible**: Every interactive element should have a `:focus-visible` style. Flag any that rely only on hover. - **Touch targets**: Interactive elements should have `minHeight >= 44px` for the largest size (or the mobile-intended size). - **Spacing consistency**: Padding/gap values should use `theme.spacing()` or token CSS variables, not raw px. These are advisory — report as `INFO` lines after the main results. Do not block commit for these.