Compare commits

...

2 Commits

Author SHA1 Message Date
Pablo F.G
d182b88b1a chore: optimize root hooks with prek builtin, priority and new checks
Migrate 6 hooks from remote pre-commit-hooks repo to prek builtin (Rust
native, offline, instant). Add check-added-large-files and
check-case-conflict. Assign priorities for parallel execution: fast
checks at P0, Python formatting chain at P1-P3, linters at P4, heavy
analysis at P5-P6. Use glob patterns for file matching.

Open questions for review:
- pretty-format-json: builtin vs remote (possible behavior diff)
- detect-private-key: excluded due to false positives in tests
- Fixer changes on existing files: include or defer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:16:27 +02:00
Pablo F.G
15eaaeb681 chore(ui): migrate UI hooks to prek workspace mode
Replace the Husky-based UI pre-commit script with native prek workspace
discovery. UI now has its own .pre-commit-config.yaml with orphan: true,
so prek auto-discovers and runs UI hooks (typecheck, lint, tests, build)
only on ui/ files. Typecheck and lint run in parallel via priority: 0.

- Create ui/.pre-commit-config.yaml with 4 local hooks
- Remove ui-checks hook from root .pre-commit-config.yaml
- Delete ui/.husky/ directory (no longer needed without Husky)
- Remove Claude Code review hook and its docs (unused, to discuss in PR)
- Update ui/.dockerignore and ui/README.md references

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:36:18 +02:00
9 changed files with 96 additions and 935 deletions

View File

@@ -1,18 +1,34 @@
repos:
## GENERAL
## FAST CHECKS & FIXERS (priority 0, all parallel, Rust-native offline)
- repo: builtin
hooks:
- id: check-merge-conflict
priority: 0
- id: check-json
priority: 0
- id: check-added-large-files
args: [--maxkb=1024]
priority: 0
- id: check-case-conflict
priority: 0
- id: end-of-file-fixer
priority: 0
- id: trailing-whitespace
priority: 0
- id: no-commit-to-branch
priority: 0
- id: pretty-format-json
args: ["--autofix", --no-sort-keys, --no-ensure-ascii]
priority: 0
## CHECK-YAML (needs --unsafe for CloudFormation templates in contrib/, stays remote)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-merge-conflict
- id: check-yaml
args: ["--unsafe"]
exclude: prowler/config/llm_config.yaml
- id: check-json
- id: end-of-file-fixer
- id: trailing-whitespace
- id: no-commit-to-branch
- id: pretty-format-json
args: ["--autofix", --no-sort-keys, --no-ensure-ascii]
priority: 0
## TOML
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
@@ -21,13 +37,15 @@ repos:
- id: pretty-format-toml
args: [--autofix]
files: pyproject.toml
priority: 0
## GITHUB ACTIONS
- repo: https://github.com/zizmorcore/zizmor-pre-commit
rev: v1.6.0
hooks:
- id: zizmor
files: ^\.github/
files: { glob: ".github/**" }
priority: 0
## BASH
- repo: https://github.com/koalaman/shellcheck-precommit
@@ -35,8 +53,9 @@ repos:
hooks:
- id: shellcheck
exclude: contrib
priority: 0
## PYTHON
## PYTHON FORMATTING CHAIN (strict order: autoflake → isort → black)
- repo: https://github.com/myint/autoflake
rev: v2.3.1
hooks:
@@ -48,6 +67,7 @@ repos:
"--remove-all-unused-imports",
"--remove-unused-variable",
]
priority: 1
- repo: https://github.com/pycqa/isort
rev: 5.13.2
@@ -55,20 +75,33 @@ repos:
- id: isort
exclude: ^skills/
args: ["--profile", "black"]
priority: 2
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
exclude: ^skills/
priority: 3
## PYTHON LINTERS (post-formatting, parallel)
- repo: https://github.com/pycqa/flake8
rev: 7.0.0
hooks:
- id: flake8
exclude: (contrib|^skills/)
args: ["--ignore=E266,W503,E203,E501,W605"]
priority: 4
## DOCKER
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
hooks:
- id: hadolint
args: ["--ignore=DL3013"]
priority: 0
## POETRY (check before lock)
- repo: https://github.com/python-poetry/poetry
rev: 2.1.1
hooks:
@@ -76,73 +109,63 @@ repos:
name: API - poetry-check
args: ["--directory=./api"]
pass_filenames: false
priority: 5
- id: poetry-lock
name: API - poetry-lock
args: ["--directory=./api"]
pass_filenames: false
priority: 6
- id: poetry-check
name: SDK - poetry-check
args: ["--directory=./"]
pass_filenames: false
priority: 5
- id: poetry-lock
name: SDK - poetry-lock
args: ["--directory=./"]
pass_filenames: false
priority: 6
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
hooks:
- id: hadolint
args: ["--ignore=DL3013"]
## HEAVY ANALYSIS (parallel at their priority level)
- repo: local
hooks:
- id: pylint
name: pylint
entry: bash -c 'pylint --disable=W,C,R,E -j 0 -rn -sn prowler/'
language: system
files: '.*\.py'
files: { glob: "**/*.py" }
priority: 5
- id: trufflehog
name: TruffleHog
description: Detect secrets in your data.
entry: bash -c 'trufflehog --no-update git file://. --only-verified --fail'
# For running trufflehog in docker, use the following entry instead:
# entry: bash -c 'docker run -v "$(pwd):/workdir" -i --rm trufflesecurity/trufflehog:latest git file:///workdir --only-verified --fail'
language: system
stages: ["pre-commit", "pre-push"]
priority: 5
- id: bandit
name: bandit
description: "Bandit is a tool for finding common security issues in Python code"
entry: bash -c 'bandit -q -lll -x '*_test.py,./contrib/,./.venv/,./skills/' -r .'
language: system
files: '.*\.py'
files: { glob: "**/*.py" }
priority: 4
- id: safety
name: safety
description: "Safety is a tool that checks your installed dependencies for known security vulnerabilities"
# TODO: Botocore needs urllib3 1.X so we need to ignore these vulnerabilities 77744,77745. Remove this once we upgrade to urllib3 2.X
# TODO: 79023 & 79027 knack ReDoS until `azure-cli-core` (via `cartography`) allows `knack` >=0.13.0
# TODO: 86217 because `alibabacloud-tea-openapi == 0.4.3` don't let us upgrade `cryptography >= 46.0.0`
entry: bash -c 'safety check --ignore 70612,66963,74429,76352,76353,77744,77745,79023,79027,86217'
language: system
priority: 5
- id: vulture
name: vulture
description: "Vulture finds unused code in Python programs."
entry: bash -c 'vulture --exclude "contrib,.venv,api/src/backend/api/tests/,api/src/backend/conftest.py,api/src/backend/tasks/tests/,skills/" --min-confidence 100 .'
language: system
files: '.*\.py'
- id: ui-checks
name: UI - Husky Pre-commit
description: "Run UI pre-commit checks (Claude Code validation + healthcheck)"
entry: bash -c 'cd ui && .husky/pre-commit'
language: system
files: '^ui/.*\.(ts|tsx|js|jsx|json|css)$'
pass_filenames: false
verbose: true
files: { glob: "**/*.py" }
priority: 4

View File

@@ -13,5 +13,5 @@ README.md
!.next/static
!.next/standalone
.git
.husky
.pre-commit-config.yaml
scripts/setup-git-hooks.js

View File

@@ -1,231 +0,0 @@
#!/bin/bash
# Prowler UI - Pre-Commit Hook
# Optionally validates ONLY staged files against AGENTS.md standards using Claude Code
# Controlled by CODE_REVIEW_ENABLED in .env
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🚀 Prowler UI - Pre-Commit Hook"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Load .env file (look in git root directory)
GIT_ROOT=$(git rev-parse --show-toplevel)
if [ -f "$GIT_ROOT/ui/.env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/ui/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f "$GIT_ROOT/.env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" "$GIT_ROOT/.env" | cut -d'=' -f2 | tr -d ' ')
elif [ -f ".env" ]; then
CODE_REVIEW_ENABLED=$(grep "^CODE_REVIEW_ENABLED" .env | cut -d'=' -f2 | tr -d ' ')
else
CODE_REVIEW_ENABLED="false"
fi
# Normalize the value to lowercase
CODE_REVIEW_ENABLED=$(echo "$CODE_REVIEW_ENABLED" | tr '[:upper:]' '[:lower:]')
echo -e "${BLUE} Code Review Status: ${CODE_REVIEW_ENABLED}${NC}"
echo ""
# Get staged files in the UI folder only (what will be committed)
# Always use GIT_ROOT-relative pathspecs so detection works regardless of cwd
STAGED_FILES=$(git -C "$GIT_ROOT" diff --cached --name-only --diff-filter=ACM -- 'ui/' | grep -E '\.(tsx?|jsx?)$' || true)
if [ "$CODE_REVIEW_ENABLED" = "true" ]; then
if [ -z "$STAGED_FILES" ]; then
echo -e "${YELLOW}⚠️ No TypeScript/JavaScript files staged to validate${NC}"
echo ""
else
echo -e "${YELLOW}🔍 Running Claude Code standards validation...${NC}"
echo ""
echo -e "${BLUE}📋 Files to validate:${NC}"
echo "$STAGED_FILES" | while IFS= read -r file; do echo " - $file"; done
echo ""
echo -e "${BLUE}📤 Sending to Claude Code for validation...${NC}"
echo ""
# Build prompt with full file contents
VALIDATION_PROMPT=$(
cat <<'PROMPT_EOF'
You are a code reviewer for the Prowler UI project. Analyze the full file contents of changed files below and validate they comply with AGENTS.md standards.
**RULES TO CHECK:**
1. React Imports: NO `import * as React` or `import React, {` → Use `import { useState }`
2. TypeScript: NO union types like `type X = "a" | "b"` → Use const-based: `const X = {...} as const`
3. Tailwind: NO `var()` or hex colors in className → Use Tailwind utilities and semantic color classes. Exception: `var()` is allowed when passing colors to chart/graph components that require CSS color strings (not Tailwind classes) for their APIs.
4. cn(): Use for merging multiple classes or for conditionals (handles Tailwind conflicts with twMerge) → `cn(BUTTON_STYLES.base, BUTTON_STYLES.active, isLoading && "opacity-50")`
5. React 19: NO `useMemo`/`useCallback` without reason
6. Zod v4: Use `.min(1)` not `.nonempty()`, `z.email()` not `z.string().email()`. All inputs must be validated with Zod.
7. File Org: 1 feature = local, 2+ features = shared
8. Directives: Server Actions need "use server", clients need "use client"
9. Implement DRY, KISS principles. (example: reusable components, avoid repetition)
10. Layout must work for all the responsive breakpoints (mobile, tablet, desktop)
11. ANY types cannot be used - CRITICAL: Check for `: any` in all visible lines
12. Use the components inside components/shadcn if possible
13. Check Accessibility best practices (like alt tags in images, semantic HTML, Aria labels, etc.)
=== FILES TO REVIEW ===
PROMPT_EOF
)
# Add full file contents for each staged file
for file in $STAGED_FILES; do
VALIDATION_PROMPT="$VALIDATION_PROMPT
=== FILE: $file ===
$(cat "$file" 2>/dev/null || echo "Error reading file")"
done
VALIDATION_PROMPT="$VALIDATION_PROMPT
=== END FILES ===
**IMPORTANT: Your response MUST start with exactly one of these lines:**
STATUS: PASSED
STATUS: FAILED
**If FAILED:** List each violation with File, Line Number, Rule Number, and Issue.
**If PASSED:** Confirm all files comply with AGENTS.md standards.
**Start your response now with STATUS:**"
# Send to Claude Code
if VALIDATION_OUTPUT=$(echo "$VALIDATION_PROMPT" | claude 2>&1); then
echo "$VALIDATION_OUTPUT"
echo ""
# Check result - STRICT MODE: fail if status unclear
if echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: PASSED"; then
echo ""
echo -e "${GREEN}✅ VALIDATION PASSED${NC}"
echo ""
elif echo "$VALIDATION_OUTPUT" | grep -q "^STATUS: FAILED"; then
echo ""
echo -e "${RED}❌ VALIDATION FAILED${NC}"
echo -e "${RED}Fix violations before committing${NC}"
echo ""
exit 1
else
echo ""
echo -e "${RED}❌ VALIDATION ERROR${NC}"
echo -e "${RED}Could not determine validation status from Claude Code response${NC}"
echo -e "${YELLOW}Response must start with 'STATUS: PASSED' or 'STATUS: FAILED'${NC}"
echo ""
echo -e "${YELLOW}To bypass validation temporarily, set CODE_REVIEW_ENABLED=false in .env${NC}"
echo ""
exit 1
fi
else
echo -e "${YELLOW}⚠️ Claude Code not available${NC}"
fi
echo ""
fi
else
echo -e "${YELLOW}⏭️ Code review disabled (CODE_REVIEW_ENABLED=false)${NC}"
echo ""
fi
# Run healthcheck (typecheck and lint check) only if there are UI changes
if [ -z "$STAGED_FILES" ]; then
echo -e "${YELLOW}⏭️ No UI files staged, skipping healthcheck/tests/build${NC}"
echo ""
exit 0
fi
echo -e "${BLUE}🏥 Running healthcheck...${NC}"
echo ""
cd "$GIT_ROOT/ui"
if pnpm run healthcheck; then
echo ""
echo -e "${GREEN}✅ Healthcheck passed${NC}"
echo ""
else
echo ""
echo -e "${RED}❌ Healthcheck failed${NC}"
echo -e "${RED}Fix type errors and linting issues before committing${NC}"
echo ""
exit 1
fi
# Run unit tests (targeted based on staged files)
echo -e "${BLUE}🧪 Running unit tests...${NC}"
echo ""
# Get staged source files (exclude test files)
# Use GIT_ROOT so pathspecs are always correct regardless of cwd
STAGED_SOURCE_FILES=$(git -C "$GIT_ROOT" diff --cached --name-only --diff-filter=ACM -- 'ui/*.ts' 'ui/*.tsx' | sed 's|^ui/||' | grep -v '\.test\.\|\.spec\.\|vitest\.config\|vitest\.setup' || true)
# Check if critical paths changed (lib/, types/, config/)
CRITICAL_PATHS_CHANGED=$(git -C "$GIT_ROOT" diff --cached --name-only -- 'ui/lib/' 'ui/types/' 'ui/config/' 'ui/middleware.ts' 'ui/vitest.config.ts' 'ui/vitest.setup.ts' || true)
if [ -n "$CRITICAL_PATHS_CHANGED" ]; then
echo -e "${YELLOW}Critical paths changed - running ALL unit tests${NC}"
if pnpm run test:run; then
echo ""
echo -e "${GREEN}✅ Unit tests passed${NC}"
echo ""
else
echo ""
echo -e "${RED}❌ Unit tests failed${NC}"
echo -e "${RED}Fix failing tests before committing${NC}"
echo ""
exit 1
fi
elif [ -n "$STAGED_SOURCE_FILES" ]; then
echo -e "${YELLOW}Running tests related to changed files:${NC}"
echo "$STAGED_SOURCE_FILES" | while IFS= read -r file; do [ -n "$file" ] && echo " - $file"; done
echo ""
# shellcheck disable=SC2086 # Word splitting is intentional - vitest needs each file as separate arg
if pnpm exec vitest related $STAGED_SOURCE_FILES --run; then
echo ""
echo -e "${GREEN}✅ Unit tests passed${NC}"
echo ""
else
echo ""
echo -e "${RED}❌ Unit tests failed${NC}"
echo -e "${RED}Fix failing tests before committing${NC}"
echo ""
exit 1
fi
else
echo -e "${YELLOW}No source files changed - running ALL unit tests${NC}"
if pnpm run test:run; then
echo ""
echo -e "${GREEN}✅ Unit tests passed${NC}"
echo ""
else
echo ""
echo -e "${RED}❌ Unit tests failed${NC}"
echo -e "${RED}Fix failing tests before committing${NC}"
echo ""
exit 1
fi
fi
# Run build
echo -e "${BLUE}🔨 Running build...${NC}"
echo ""
if pnpm run build; then
echo ""
echo -e "${GREEN}✅ Build passed${NC}"
echo ""
else
echo ""
echo -e "${RED}❌ Build failed${NC}"
echo -e "${RED}Fix build errors before committing${NC}"
echo ""
exit 1
fi

View File

@@ -0,0 +1,37 @@
orphan: true
repos:
- repo: local
hooks:
- id: ui-typecheck
name: UI - TypeScript Check
entry: pnpm run typecheck
language: system
files: '\.(ts|tsx|js|jsx)$'
pass_filenames: false
priority: 0
- id: ui-lint
name: UI - ESLint
entry: pnpm run lint:check
language: system
files: '\.(ts|tsx|js|jsx)$'
pass_filenames: false
priority: 0
- id: ui-tests
name: UI - Unit Tests
entry: pnpm exec vitest related --run
language: system
files: '\.(ts|tsx|js|jsx)$'
exclude: '\.test\.|\.spec\.|vitest\.config|vitest\.setup'
pass_filenames: true
priority: 1
- id: ui-build
name: UI - Build
entry: pnpm run build
language: system
files: '\.(ts|tsx|js|jsx|json|css)$'
pass_filenames: false
priority: 2

View File

@@ -85,10 +85,10 @@ git clone git@github.com:prowler-cloud/ui.git
pnpm install
```
**Note:** The `pnpm install` command will automatically configure Git hooks for code quality checks. If you experience issues, you can manually configure them:
**Note:** The `pnpm install` command will automatically configure prek Git hooks for code quality checks. If hooks are not installed, run from the repo root:
```bash
git config core.hooksPath "ui/.husky"
prek install
```
#### Run the development server

View File

@@ -1015,14 +1015,6 @@
"strategy": "installed",
"generatedAt": "2026-01-19T13:54:24.770Z"
},
{
"section": "devDependencies",
"name": "husky",
"from": "9.1.7",
"to": "9.1.7",
"strategy": "installed",
"generatedAt": "2025-10-22T12:36:37.962Z"
},
{
"section": "devDependencies",
"name": "jsdom",
@@ -1031,14 +1023,6 @@
"strategy": "installed",
"generatedAt": "2026-01-29T16:42:27.795Z"
},
{
"section": "devDependencies",
"name": "lint-staged",
"from": "15.5.2",
"to": "15.5.2",
"strategy": "installed",
"generatedAt": "2025-10-22T12:36:37.962Z"
},
{
"section": "devDependencies",
"name": "postcss",

View File

@@ -1,115 +0,0 @@
# Code Review - Quick Start
## 3 Steps to Enable
### 1. Open `.env`
```bash
nano ui/.env
# or your favorite editor
```
### 2. Find this line
```bash
CODE_REVIEW_ENABLED=false
```
### 3. Change it to
```bash
CODE_REVIEW_ENABLED=true
```
**Done! ✅**
---
## What Happens Now
Every time you `git commit`:
```
✅ If your code complies with AGENTS.md standards:
→ Commit executes normally
❌ If there are standard violations:
→ Commit is BLOCKED
→ You see the errors in the terminal
→ Fix the code
→ Commit again
```
---
## Example
```bash
$ git commit -m "feat: add new component"
🏁 Prowler UI - Pre-Commit Hook
Code Review Status: true
🔍 Running Claude Code standards validation...
📋 Files to validate:
- components/my-feature.tsx
📤 Sending to Claude Code for validation...
STATUS: FAILED
- File: components/my-feature.tsx:45
Rule: React Imports
Issue: Using 'import * as React'
Expected: import { useState } from "react"
❌ VALIDATION FAILED
Fix violations before committing
# Fix the file and commit again
$ git commit -m "feat: add new component"
🏁 Prowler UI - Pre-Commit Hook
Code Review Status: true
🔍 Running Claude Code standards validation...
✅ VALIDATION PASSED
# Commit successful ✅
```
---
## Disable Temporarily
If you need to commit without validation:
```bash
# Option 1: Change in .env
CODE_REVIEW_ENABLED=false
# Option 2: Bypass (use with caution!)
git commit --no-verify
```
---
## What Gets Validated
- ✅ Correct React imports
- ✅ TypeScript patterns (const-based types)
- ✅ Tailwind CSS (no var() or hex in className)
- ✅ cn() utility (only for conditionals)
- ✅ No useMemo/useCallback without reason
- ✅ Zod v4 syntax
- ✅ File organization
- ✅ Directives "use client"/"use server"
---
## More Info
Read `CODE_REVIEW_SETUP.md` for:
- Troubleshooting
- Complete details
- Advanced configuration

View File

@@ -1,296 +0,0 @@
# Code Review Setup - Prowler UI
Guide to set up automatic code validation with Claude Code in the commit hook.
## Overview
The code review system works like this:
1. **When you enable `CODE_REVIEW_ENABLED=true` in `.env`**
- When you `git commit`, the pre-commit hook runs
- Only validates TypeScript/JavaScript files you're committing
- Uses Claude Code to check if they comply with AGENTS.md
- If there are violations → **BLOCKS the commit**
- If everything is fine → Continues normally
2. **When `CODE_REVIEW_ENABLED=false` (default)**
- The pre-commit hook does not run validation
- No standards validation
- Developers can commit without restrictions
## Installation
### 1. Ensure Claude Code is in your PATH
```bash
# Verify that claude is available in terminal
which claude
# If it doesn't appear, check your Claude Code CLI installation
```
### 2. Enable validation in `.env`
In `/ui/.env`, find the "Code Review Configuration" section:
```bash
#### Code Review Configuration ####
# Enable Claude Code standards validation on commit hook
# Set to 'true' to validate changes against AGENTS.md standards via Claude Code
# Set to 'false' to skip validation
CODE_REVIEW_ENABLED=false # ← Change this to 'true'
```
**Options:**
- `CODE_REVIEW_ENABLED=true` → Enables validation
- `CODE_REVIEW_ENABLED=false` → Disables validation (default)
### 3. The hook is ready
The `.husky/pre-commit` file already contains the logic. You don't need to install anything else.
## How It Works
### Normal Flow (with validation enabled)
```bash
$ git commit -m "feat: add new component"
# Pre-commit hook executes automatically
🚀 Prowler UI - Pre-Commit Hook
Code Review Status: true
📋 Files to validate:
- components/new-feature.tsx
- types/new-feature.ts
📤 Sending to Claude Code for validation...
# Claude analyzes the files...
=== VALIDATION REPORT ===
STATUS: PASSED
All files comply with AGENTS.md standards.
✅ VALIDATION PASSED
# Commit continues ✅
```
### If There Are Violations
```bash
$ git commit -m "feat: add new component"
# Claude detects issues...
=== VALIDATION REPORT ===
STATUS: FAILED
- File: components/new-feature.tsx:15
Rule: React Imports
Issue: Using 'import * as React' instead of named imports
Expected: import { useState } from "react"
❌ VALIDATION FAILED
Please fix the violations before committing:
1. Review the violations listed above
2. Fix the code according to AGENTS.md standards
3. Commit your changes
4. Try again
# Commit is BLOCKED ❌
```
## What Gets Validated
The system verifies that files comply with:
### 1. React Imports
```typescript
// ❌ WRONG
import * as React from "react"
import React, { useState } from "react"
// ✅ CORRECT
import { useState } from "react"
```
### 2. TypeScript Type Patterns
```typescript
// ❌ WRONG
type SortOption = "high-low" | "low-high"
// ✅ CORRECT
const SORT_OPTIONS = {
HIGH_LOW: "high-low",
LOW_HIGH: "low-high",
} as const
type SortOption = typeof SORT_OPTIONS[keyof typeof SORT_OPTIONS]
```
### 3. Tailwind CSS
```typescript
// ❌ WRONG
className="bg-[var(--color)]"
className="text-[#ffffff]"
// ✅ CORRECT
className="bg-card-bg text-white"
```
### 4. cn() Utility
```typescript
// ❌ WRONG
className={cn("flex items-center")}
// ✅ CORRECT
className={cn("h-3 w-3", isCircle ? "rounded-full" : "rounded-sm")}
```
### 5. React 19 Hooks
```typescript
// ❌ WRONG
const memoized = useMemo(() => value, [])
// ✅ CORRECT
// Don't use useMemo (React Compiler handles it)
const value = expensiveCalculation()
```
### 6. Zod v4 Syntax
```typescript
// ❌ WRONG
z.string().email()
z.string().nonempty()
// ✅ CORRECT
z.email()
z.string().min(1)
```
### 7. File Organization
```
// ❌ WRONG
Code used by 2+ features in feature-specific folder
// ✅ CORRECT
Code used by 1 feature → local in that feature
Code used by 2+ features → in shared/global
```
### 8. Use Directives
```typescript
// ❌ WRONG
export async function updateUser() { } // Missing "use server"
// ✅ CORRECT
"use server"
export async function updateUser() { }
```
## Disable Temporarily
If you need to commit without validation temporarily:
```bash
# Option 1: Change in .env
CODE_REVIEW_ENABLED=false
git commit
# Option 2: Use git hook bypass
git commit --no-verify
# Option 3: Disable the hook
chmod -x .husky/pre-commit
git commit
chmod +x .husky/pre-commit
```
**⚠️ Note:** `--no-verify` skips ALL hooks.
## Troubleshooting
### "Claude Code CLI not found"
```
⚠️ Claude Code CLI not found in PATH
To enable: ensure Claude Code is in PATH and CODE_REVIEW_ENABLED=true
```
**Solution:**
```bash
# Check where claude-code is installed
which claude-code
# If not found, add to your ~/.zshrc:
export PATH="$HOME/.local/bin:$PATH" # or where it's installed
# Reload the terminal
source ~/.zshrc
```
### "Validation inconclusive"
If Claude Code cannot determine the status:
```
⚠️ Could not determine validation status
Allowing commit (validation inconclusive)
```
The commit is allowed automatically. If you want to be stricter, you can:
1. Manually review files against AGENTS.md
2. Report the analysis problem to Claude
### Build fails after validation
```
❌ Build failed
```
If validation passes but build fails:
1. Check the build error
2. Fix it locally
3. Commit and try again
## View the Full Report
Reports are saved in temporary files that are deleted afterward. To see the detailed report in real-time, watch the hook output:
```bash
git commit 2>&1 | tee commit-report.txt
```
This will save everything to `commit-report.txt`.
## For the Team
### Enable on your machine
```bash
cd ui
# Edit .env locally and set:
CODE_REVIEW_ENABLED=true
```
### Recommended Flow
1. **During development**: `CODE_REVIEW_ENABLED=false`
- Iterate faster
- Build check still runs
2. **Before final commit**: `CODE_REVIEW_ENABLED=true`
- Verify you meet standards
- Prevent PRs rejected for violations
3. **In CI/CD**: You could add additional validation
- (future) Server-side validation in GitHub Actions
## Questions?
If you have questions about the standards being validated, check:
- `AGENTS.md` - Complete architecture guide
- `CLAUDE.md` - Project-specific instructions

View File

@@ -1,241 +0,0 @@
# Code Review System Documentation
Complete documentation for the Claude Code-powered commit validation system.
## Quick Navigation
**Want to get started in 3 steps?**
→ Read: [`CODE_REVIEW_QUICK_START.md`](./CODE_REVIEW_QUICK_START.md)
**Want complete technical details?**
→ Read: [`CODE_REVIEW_SETUP.md`](./CODE_REVIEW_SETUP.md)
---
## What This System Does
Automatically validates code against AGENTS.md standards when you commit using Claude Code.
```
git commit
(Optional) Claude Code validation
If violations found → Commit is BLOCKED ❌
If code complies → Commit continues ✅
```
**Key Feature:** Configurable with a single variable in `.env`
- `CODE_REVIEW_ENABLED=true` → Validates (recommended before commits)
- `CODE_REVIEW_ENABLED=false` → Skip validation (default, for iteration)
---
## File Guide
| File | Purpose | Read Time |
|------|---------|-----------|
| [`CODE_REVIEW_QUICK_START.md`](./CODE_REVIEW_QUICK_START.md) | 3-step setup & examples | 5 min |
| [`CODE_REVIEW_SETUP.md`](./CODE_REVIEW_SETUP.md) | Complete technical guide | 15 min |
---
## What Gets Validated
When validation is enabled, the system checks:
**React Imports**
- Must use: `import { useState } from "react"`
- Not: `import * as React` or `import React, {`
**TypeScript Types**
- Must use: `const STATUS = {...} as const; type Status = typeof STATUS[...]`
- Not: `type Status = "a" | "b"`
**Tailwind CSS**
- Must use: `className="bg-card-bg text-white"`
- Not: `className="bg-[var(...)]"` or `className="text-[#fff]"`
**cn() Utility**
- Must use for: `cn("h-3", isActive && "bg-blue")`
- Not for: `cn("static-class")`
**React 19 Hooks**
- No: `useMemo()` / `useCallback()` without documented reason
- Use: Nothing (React Compiler handles optimization)
**Zod v4 Syntax**
- Must use: `z.email()`, `.min(1)`
- Not: `z.string().email()`, `.nonempty()`
**File Organization**
- 1 feature uses → Keep local in feature folder
- 2+ features use → Move to shared/global
**Directives**
- Server Actions must have: `"use server"`
- Client Components must have: `"use client"`
---
## Installation (For Your Team)
### Step 1: Decide if you want validation
- **Optional:** Each developer decides
- **Team policy:** Consider making it standard before commits
### Step 2: Enable in your environment
```bash
# Edit ui/.env
CODE_REVIEW_ENABLED=true
```
### Step 3: Done!
Your next `git commit` will validate automatically.
---
## Support
| Question | Answer |
|----------|--------|
| How do I enable it? | Change `CODE_REVIEW_ENABLED=true` in `.env` |
| How do I disable it? | Change `CODE_REVIEW_ENABLED=false` in `.env` |
| How do I bypass? | Use `git commit --no-verify` (emergency only) |
| What if Claude Code isn't found? | Check PATH: `which claude` |
| What if hook doesn't run? | Check executable: `chmod +x .husky/pre-commit` |
| How do I test it? | Enable validation and commit code with violations to test |
| What if I don't have Claude Code? | Validation is skipped gracefully |
---
## Key Features
**No Setup Required**
- Uses Claude Code already in your PATH
- No API keys needed
- Works offline (if Claude Code supports it)
**Smart Validation**
- Only checks files being committed
- Not the entire codebase
- Fast: ~10-30 seconds with validation enabled
**Flexible**
- Can be enabled/disabled per developer
- Can be disabled temporarily with `git commit --no-verify`
- Default is disabled (doesn't interrupt workflow)
**Clear Feedback**
- Shows exactly what violates standards
- Shows file:line references
- Explains how to fix each issue
**Well Documented**
- 5 different documentation files
- For different needs and levels
- Examples and troubleshooting included
---
## Architecture
```
┌─────────────────────────────────────────┐
│ Developer commits code │
└────────────────┬────────────────────────┘
┌─────────────────┐
│ Pre-Commit Hook │
│ (.husky/pre-commit)
└────────┬────────┘
Read CODE_REVIEW_ENABLED from .env
┌──────────────────────────┐
│ If false (disabled) │
└────────┬─────────────────┘
exit 0 (OK)
Commit continues ✅
┌──────────────────────────┐
│ If true (enabled) │
└────────┬─────────────────┘
Extract staged files
(git diff --cached)
Build prompt with git diff
Send to: claude < prompt
Analyze against AGENTS.md
Return: STATUS: PASSED or FAILED
Parse with: grep "^STATUS:"
┌──────────────────┐
│ PASSED detected │
└────────┬─────────┘
exit 0 (OK)
Commit continues ✅
┌──────────────────┐
│ FAILED detected │
└────────┬─────────┘
Show violations
exit 1 (FAIL)
Commit is BLOCKED ❌
Developer fixes code
Developer commits again
```
---
## Getting Started
1. **Read:** [`CODE_REVIEW_QUICK_START.md`](./CODE_REVIEW_QUICK_START.md) (5 minutes)
2. **Enable:** Set `CODE_REVIEW_ENABLED=true` in your `ui/.env`
3. **Test:** Commit some code and see validation in action
4. **For help:** See the troubleshooting section in [`CODE_REVIEW_SETUP.md`](./CODE_REVIEW_SETUP.md)
---
## Implementation Details
- **Files Modified:** 1 (`.husky/pre-commit`)
- **Files Created:** 3 (documentation)
- **Hook Size:** ~120 lines of bash
- **Dependencies:** Claude Code CLI (already available)
- **Setup Time:** 1 minute
- **Default:** Disabled (no workflow interruption)
---
## Questions?
- **How to enable?** → `CODE_REVIEW_QUICK_START.md`
- **How does it work?** → `CODE_REVIEW_SETUP.md`
- **Troubleshooting?** → See troubleshooting section in `CODE_REVIEW_SETUP.md`
---
## Status
**Ready to Use**
The system is fully implemented, documented, and tested. You can enable it immediately with a single variable change.
---
**Last Updated:** November 6, 2024
**Status:** Complete Implementation