Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:02:45 +08:00
commit 31e7ee93ec
15 changed files with 7495 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
---
name: linter-driven-development
description: META ORCHESTRATOR for complete implementation workflow - design, test, lint, refactor, review, commit. Use for any code change that should result in a commit (features, bug fixes, refactors). Ensures clean code with tests, linting passes, and design validation.
---
# Linter-Driven Development Workflow (TypeScript + React)
META ORCHESTRATOR for implementation workflow: design → test → lint → refactor → review → commit.
Use for any commit: features, bug fixes, refactors.
## When to Use
- Implementing any code change that should result in a commit
- Need automatic workflow management with quality gates
- Want to ensure: clean code + tests + linting + design validation + accessibility
## Workflow Phases
### Phase 1: Design (if needed)
- If new components/types/major changes needed → invoke @component-designing skill
- Output: Component design plan with types, hooks, and structure
### Phase 2: Implementation
- Follow @testing skill principles (Jest + React Testing Library)
- Write tests + implementation in parallel (not necessarily test-first)
- Aim for 100% coverage on new leaf components/hooks (pure logic with no external dependencies)
- Leaf types: Pure logic (can compose other leaf types), no API/DB/file system access
- Orchestrating types: Coordinate leaf types and external systems, need integration tests
- Test from user perspective (public API only)
### Phase 3: Linter Loop
Run quality checks in this order:
1. **Type Check**: `npm run typecheck` (TypeScript compiler)
2. **Lint Check**: `npm run lintcheck` (ESLint validation)
3. **Format Check**: `npm run formatcheck` (Prettier validation)
4. **Style Check**: `npm run stylecheck` (Stylelint for SCSS)
If any failures detected:
- Run auto-fixes:
- `npm run lint` (ESLint --fix)
- `npm run format` (Prettier --write)
- `npm run stylefix` (Stylelint --fix)
- Re-run quality checks
- If still failing (complexity, design issues):
- Interpret failures (cognitive complexity, cyclomatic complexity, etc.)
- Invoke @refactoring skill to fix (use storifying, extract functions/hooks, early returns)
- Re-run checks
- Repeat until all checks pass clean
**Alternative**: If project has combined commands:
- Check: `npm run checkall` or `npm run check`
- Fix: `npm run fix`
### Phase 4: Pre-Commit Design Review (ADVISORY)
- Invoke @pre-commit-review skill
- Review validates design principles (not code correctness)
- Includes accessibility checks (ARIA, semantic HTML, keyboard nav)
- Categorized findings: Design Debt / Readability Debt / Polish Opportunities
- If issues found in broader file context, flag for potential refactor
- **User decides**: commit as-is, apply fixes, or expand scope
### Phase 5: Commit Ready
- Type checking passes ✅
- ESLint passes ✅
- Prettier passes ✅
- Stylelint passes ✅
- Tests pass with target coverage ✅
- Design review complete (advisory) ✅
- Present summary + commit message suggestion
## Output Format
```
📋 COMMIT READINESS SUMMARY
✅ Type Check: Passed (0 errors)
✅ ESLint: Passed (0 issues)
✅ Prettier: Passed (all files formatted)
✅ Stylelint: Passed (0 style issues)
✅ Tests: 92% coverage (3 leaf hooks at 100%, 1 orchestrating component, 18 test cases)
⚠️ Design Review: 3 findings (see below)
🎯 COMMIT SCOPE
Modified:
- src/features/auth/LoginForm.tsx (+65, -20 lines)
- src/features/auth/useAuth.ts (+30, -5 lines)
Added:
- src/features/auth/types.ts (new: UserId, Email types)
- src/features/auth/AuthContext.tsx (new context provider)
Tests:
- src/features/auth/LoginForm.test.tsx (+95 lines)
- src/features/auth/useAuth.test.ts (new)
- src/features/auth/types.test.ts (new)
⚠️ DESIGN REVIEW FINDINGS
🔴 DESIGN DEBT (Recommended to fix):
- src/features/auth/LoginForm.tsx:45 - Primitive obsession detected
Current: function validateEmail(email: string): boolean
Better: Use Zod schema or branded Email type with validation
Why: Type safety, validation guarantee, prevents invalid emails
Fix: Use @component-designing to create self-validating Email type
- src/features/auth/useAuth.ts:78 - Prop drilling detected
Auth state passed through 3+ component levels
Why: Tight coupling, hard to maintain
Fix: Extract AuthContext or use composition pattern
🟡 READABILITY DEBT (Consider fixing):
- src/features/auth/LoginForm.tsx:120 - Mixed abstraction levels
Component mixes validation logic with UI rendering
Why: Harder to understand and test independently
Fix: Use @refactoring to extract custom hooks (useValidation)
- src/features/auth/LoginForm.tsx:88 - Cognitive complexity: 18 (max: 15)
Nested conditionals for form validation
Why: Hard to understand logic flow
Fix: Use @refactoring to extract validation functions or use Zod
🟢 POLISH OPPORTUNITIES:
- src/features/auth/types.ts:12 - Missing JSDoc comments
Public types should have documentation
- src/features/auth/LoginForm.tsx:45 - Consider semantic HTML
Use <form> with proper ARIA labels for better accessibility
- src/features/auth/useAuth.ts:34 - Missing error boundaries
Consider wrapping async operations with error handling
📝 BROADER CONTEXT:
While reviewing LoginForm.tsx, noticed similar validation patterns in
RegisterForm.tsx and ProfileForm.tsx (src/features/user/). Consider
extracting a shared validation hook or creating branded types for common
fields (Email, Username, Password) used across the application.
💡 SUGGESTED COMMIT MESSAGE
Add self-validating Email and UserId types to auth feature
- Introduce Email type with RFC 5322 validation using Zod
- Introduce UserId branded type for type safety
- Refactor LoginForm to use validated types
- Extract useAuth hook for auth state management
- Add AuthContext to eliminate prop drilling
- Achieve 92% test coverage with React Testing Library
Follows component composition principles and reduces primitive obsession.
────────────────────────────────────────
Would you like to:
1. Commit as-is (ignore design findings)
2. Fix design debt only (🔴), then commit
3. Fix design + readability debt (🔴 + 🟡), then commit
4. Fix all findings (🔴 🟡 🟢), then commit
5. Refactor broader scope (address validation patterns across features), then commit
```
## Complexity Thresholds (SonarJS)
These metrics trigger @refactoring when exceeded:
- **Cognitive Complexity**: max 15
- **Cyclomatic Complexity**: max 10
- **Expression Complexity**: max 5
- **Function Length**: max 200 lines
- **File Length**: max 600 lines
- **Nesting Level**: max 4
## Workflow Control
**Sequential Phases**: Each phase depends on previous phase completion
- Design must complete before implementation
- Implementation must complete before linting
- Linting must pass before review
- Review must complete before commit
**Iterative Linting**: Phase 3 loops until clean
**Advisory Review**: Phase 4 never blocks, always asks user
## Integration with Other Skills
This orchestrator **invokes** other skills automatically:
- @component-designing (Phase 1, if needed)
- @testing (Phase 2, principles applied)
- @refactoring (Phase 3, when linter fails on complexity)
- @pre-commit-review (Phase 4, always)
After committing, consider:
- If feature complete → invoke @documentation skill
- If more work needed → run this workflow again for next commit
## Common Linter Failures and Resolutions
### TypeScript Errors (npm run typecheck)
- Type mismatches → Fix types or add proper type guards
- Missing types → Add explicit types or interfaces
- Cannot fix automatically → Manual intervention required
### ESLint Failures (npm run lintcheck)
**Auto-fixable**:
- Import sorting (simple-import-sort)
- Unused imports (unused-imports)
- Formatting issues covered by Prettier
- Simple style violations
**Requires refactoring** (invoke @refactoring):
- Cognitive/cyclomatic complexity
- Max lines per function
- Expression complexity
- Nested control flow
- React hooks violations
- Component design issues
### Prettier Failures (npm run formatcheck)
- Always auto-fixable with `npm run format`
- No manual intervention needed
### Stylelint Failures (npm run stylecheck)
- Most auto-fixable with `npm run stylefix`
- Class naming violations may require manual fixes
## Best Practices
1. **Run checks frequently** during development
2. **Fix one complexity issue at a time** (don't batch refactoring)
3. **Trust the advisory review** (design debt causes future pain)
4. **Test after each refactoring** (ensure behavior unchanged)
5. **Commit frequently** (small, focused commits)

View File

@@ -0,0 +1,443 @@
# Linter-Driven Development Reference (TypeScript + React)
## Overview
The linter-driven development workflow ensures code quality through automated tooling and design validation. This orchestrator manages the complete lifecycle from design to commit-ready code.
## Quality Tool Stack
### 1. TypeScript Compiler (`tsc`)
**Command**: `npm run typecheck`
**Purpose**: Type safety validation
**Can auto-fix**: No
**Failure resolution**: Manual type fixes or refactoring
### 2. ESLint
**Command**:
- Check: `npm run lintcheck`
- Fix: `npm run lint`
**Purpose**: Code quality, style, and complexity analysis
**Plugins used**:
- `eslint-plugin-sonarjs` - Complexity metrics (THE KEY PLUGIN)
- `typescript-eslint` - TypeScript-aware linting
- `eslint-plugin-react` - React best practices
- `eslint-plugin-react-hooks` - Hooks rules enforcement
- `eslint-plugin-jsx-a11y` - Accessibility rules
- `eslint-plugin-import` - Import/export management
- `eslint-plugin-unused-imports` - Remove dead code
- `eslint-plugin-simple-import-sort` - Auto-sort imports
- `eslint-plugin-promise` - Async/await best practices
- `eslint-plugin-security` - Security vulnerabilities
**Can auto-fix**: Many rules (formatting, imports, simple violations)
**Requires refactoring**: Complexity rules, design issues
### 3. Prettier
**Command**:
- Check: `npm run formatcheck`
- Fix: `npm run format`
**Purpose**: Code formatting consistency
**Can auto-fix**: Always (100% auto-fixable)
### 4. Stylelint
**Command**:
- Check: `npm run stylecheck`
- Fix: `npm run stylefix`
**Purpose**: SCSS/CSS linting
**Can auto-fix**: Most rules
## Workflow Phases in Detail
### Phase 1: Design
**Trigger**: New components, custom hooks, major architectural changes
**Actions**:
1. Invoke @component-designing skill
2. Answer design questions:
- Component composition strategy?
- State management approach?
- Custom hooks needed?
- Type definitions required?
3. Receive design plan with:
- Component structure
- Props interfaces
- Custom hooks
- Type definitions
- File organization
**Output**: Design document ready for implementation
### Phase 2: Implementation + Testing
**Testing principles** (from @testing skill):
- Write tests for public API only
- Use React Testing Library patterns
- Test user behavior, not implementation
- Use MSW for API mocking (real HTTP)
- Avoid `waitFor` with arbitrary delays
- Achieve 100% coverage on leaf components/hooks (no dependencies on other types)
- Integration tests for orchestrating components (test interactions and composition)
**Implementation approach**:
- Parallel development (test + code together)
- Focus on behavior validation
- Use real implementations over mocks
- Follow component composition patterns
- Push business logic into leaf types for better testability
### Phase 3: Linter Loop
This is the core quality gate with multiple sub-checks:
#### Step 1: Type Checking
```bash
npm run typecheck
```
**Checks**: TypeScript compilation, type safety
**Failures**: Type errors, missing types, type mismatches
**Resolution**:
- Fix types manually
- Add type assertions where needed
- Use type guards for narrowing
- Cannot proceed if failing
#### Step 2: ESLint Check
```bash
npm run lintcheck
```
**Checks**: Code quality, complexity, React rules, hooks rules, a11y
**Failures**: See "ESLint Failure Categories" below
**Resolution**:
- Auto-fix: `npm run lint`
- If auto-fix insufficient → manual fixes or invoke @refactoring
#### Step 3: Prettier Check
```bash
npm run formatcheck
```
**Checks**: Code formatting consistency
**Failures**: Inconsistent formatting
**Resolution**: Always auto-fix with `npm run format`
#### Step 4: Stylelint Check
```bash
npm run stylecheck
```
**Checks**: SCSS/CSS quality and consistency
**Failures**: Style violations, naming issues
**Resolution**: Auto-fix with `npm run stylefix`, some manual fixes
#### Loop Behavior
```
Run all checks → Any fail? → Run auto-fixes → Re-run checks
Still failing?
Complexity/design issues?
Invoke @refactoring
Re-run checks
Loop until pass
```
### Phase 4: Pre-Commit Review (Advisory)
**Always invoked**, even if linter passes.
**Purpose**: Validate design principles that linters cannot enforce
**Scope**:
- **Primary**: All changed code in current commit
- **Secondary**: Broader file context (flags patterns for future refactoring)
**Categories**:
- 🔴 **Design Debt**: Will cause pain when extending code
- Primitive obsession (string IDs, unvalidated inputs)
- Prop drilling (state passed through 3+ levels)
- Tight coupling
- Missing error boundaries
- Non-self-validating types
- 🟡 **Readability Debt**: Hard to understand and work with
- Mixed abstraction levels
- Complex nested logic
- Inline styles or logic
- Poor naming
- Missing component extraction
- 🟢 **Polish Opportunities**: Minor improvements
- Missing JSDoc
- Accessibility enhancements
- Type refinements
- Better naming
**Output**: Advisory report with specific line references and fix suggestions
**User Decision Points**:
1. Commit as-is (accept debt)
2. Fix design debt (🔴) - recommended
3. Fix design + readability (🔴 + 🟡)
4. Fix all (🔴 🟡 🟢)
5. Expand scope (refactor related code)
### Phase 5: Commit Ready
**Checklist**:
- ✅ Type checking passes
- ✅ ESLint passes
- ✅ Prettier passes
- ✅ Stylelint passes
- ✅ Tests pass (100% coverage on leaf types, integration tests on orchestrating components)
- ✅ Design review complete (advisory)
**Output**:
- Commit readiness summary
- Suggested commit message
- List of modified/added files
- Coverage report
- Design review findings
- User decision prompt
## Coverage Targets
Follow @testing skill principles for coverage strategy:
- **Leaf types** (pure logic, no external dependencies): 100% unit test coverage
- **Orchestrating types** (coordinate pieces, call external systems): Integration tests
See **testing/reference.md** for:
- Detailed coverage targets explanation
- Examples of leaf vs orchestrating types
- Testing approach for each type
- Architectural benefits
## ESLint Failure Categories
### Category 1: Auto-Fixable (npm run lint)
These are fixed automatically:
- Unused imports (`unused-imports/no-unused-imports`)
- Import sorting (`simple-import-sort/imports`)
- Missing semicolons, quotes, spacing (handled by Prettier)
- Simple style violations
- Arrow function simplification (`arrow-body-style`)
**Action**: Run `npm run lint` → Re-run checks → Continue
### Category 2: Requires Manual Fix
These need developer intervention but are straightforward:
- `@typescript-eslint/no-explicit-any` - Replace any with proper types
- `no-console` - Remove or replace with proper logging
- `react/jsx-key` - Add key props to list items
- `react-hooks/exhaustive-deps` - Fix hook dependencies
- Type-related issues
**Action**: Fix issues manually → Re-run checks → Continue
### Category 3: Requires Refactoring (invoke @refactoring)
These indicate design or complexity problems:
- `sonarjs/cognitive-complexity` (max: 15)
- `sonarjs/cyclomatic-complexity` (max: 10)
- `sonarjs/expression-complexity` (max: 5)
- `sonarjs/max-lines-per-function` (max: 200)
- `sonarjs/max-lines` (max: 600)
- `sonarjs/nested-control-flow` (max: 4 levels)
- `react/no-unstable-nested-components` - Extract components
- `react/no-multi-comp` - Split into multiple files
**Action**: Invoke @refactoring skill → Apply patterns (storifying, extract hooks/functions, early returns, simplify conditionals) → Re-run checks → Continue
## Complexity Thresholds Explained
### Cognitive Complexity (max: 15)
**What it measures**: How difficult is it to understand the code?
**Increments for**: Nested structures, breaks in linear flow, recursion
**Why it matters**: High cognitive load → more bugs, harder maintenance
**How to fix**: Invoke @refactoring skill which applies **storifying** - making code read like a story at single abstraction level. See refactoring/reference.md for detailed techniques and examples.
**Example violation**:
```tsx
// Cognitive complexity: 18 (too high!)
function validateUser(user: User): ValidationResult {
if (user) { // +1
if (user.email) { // +2 (nested)
if (isValidEmail(user.email)) { // +3 (nested)
if (user.age >= 18) { // +4 (nested)
if (user.country === 'US') { // +5 (nested)
return { valid: true }
} else { // +1
return { valid: false, reason: 'Not in US' }
}
}
} else { // +1
return { valid: false, reason: 'Invalid email' }
}
}
}
return { valid: false, reason: 'Missing user' }
}
```
**How to fix**: Invoke @refactoring skill to storify with early returns (see refactoring/reference.md)
### Cyclomatic Complexity (max: 10)
**What it measures**: Number of independent paths through code
**Increments for**: if, else, case, &&, ||, while, for, catch
**Why it matters**: More paths → more test cases needed, higher bug risk
**Fix strategies**: Extract functions, use polymorphism, simplify conditionals
### Expression Complexity (max: 5)
**What it measures**: Number of operators in a single expression
**Increments for**: &&, ||, ternary operators
**Why it matters**: Hard to read, error-prone
**Example violation**:
```tsx
// Expression complexity: 6 (too high!)
const isValid = user && user.email && isValidEmail(user.email) && user.age >= 18 && user.country === 'US' && !user.banned
```
**Fix**: Extract to variables or validation function
### Storifying Pattern
When cognitive complexity is high, invoke @refactoring skill which applies storifying patterns (making code read like a story at single abstraction level).
See **refactoring/reference.md** for:
- Detailed storifying explanation with examples
- TypeScript and React examples
- When and how to apply storifying
- Step-by-step storifying process
## Integration with Other Skills
### @component-designing
**When invoked**: Phase 1, if new components/major changes needed
**Input**: Feature requirements
**Output**: Component structure, props, hooks, types
**Next step**: Proceed to Phase 2 implementation
### @testing
**When applied**: Phase 2, during implementation
**Input**: Component/hook to test
**Output**: Test files with React Testing Library
**Principles**: User-centric testing, real implementations
### @refactoring
**When invoked**: Phase 3, when linter fails on complexity
**Input**: Failing component/function + linter error
**Output**: Refactored code that passes linter
**Patterns**: Storifying, extract hooks/functions, simplify logic, early returns, single abstraction levels
### @pre-commit-review
**When invoked**: Phase 4, always (advisory)
**Input**: All changed code + file context
**Output**: Design review findings (🔴 🟡 🟢)
**Decision**: User chooses whether to apply fixes
### @documentation
**When invoked**: After commit (feature complete)
**Input**: Implemented feature
**Output**: Storybook stories, JSDoc, feature docs
**Purpose**: Documentation for humans and AI
## Command Alternatives
Different projects may use different naming conventions:
### Option 1: Separate check/fix commands
```bash
# Checks (validation only)
npm run typecheck
npm run lintcheck
npm run formatcheck
npm run stylecheck
# Fixes (auto-fix where possible)
npm run lint
npm run format
npm run stylefix
```
### Option 2: Combined commands
```bash
# Check all quality gates
npm run checkall # or npm run check
# Fix all auto-fixable issues
npm run fix
```
### Option 3: Task runner (if available)
```bash
# Using task runner (e.g., make, task)
task lint
task fix
```
**Plugin should detect** which commands are available from `package.json` scripts.
## Best Practices
### 1. Fail Fast, Fix Fast
- Run linter frequently during development
- Don't accumulate linter errors
- Fix auto-fixable issues immediately
### 2. Trust Complexity Metrics
- SonarJS complexity rules are calibrated well
- If it flags complexity → there's real complexity
- Refactor rather than disable
### 3. Respect Advisory Review
- Design debt compounds over time
- Fix 🔴 before committing when possible
- Track accepted debt in tickets
### 4. Test After Refactoring
- Complexity fixes can introduce bugs
- Re-run tests after @refactoring
- Verify behavior unchanged
### 5. Commit Granularly
- Small, focused commits
- Each commit passes all gates
- Easy to review and revert
## Troubleshooting
### "Type errors won't go away"
- TypeScript errors require manual fixes
- Consider if types are correct (not the code)
- Use type guards for narrowing
- Add type assertions as last resort
### "ESLint keeps failing after auto-fix"
- Auto-fix only handles simple rules
- Complexity rules need refactoring
- Invoke @refactoring skill
- May need architectural changes
### "Linter passes but review finds issues"
- Expected! Linters can't enforce design principles
- Review catches: primitive obsession, coupling, architecture
- User decides whether to fix
### "Too many findings in review"
- Common for legacy code
- Fix incrementally (design debt first)
- Consider broader refactor ticket
- Don't let perfect be enemy of good
## Related Files
- For design patterns: See @component-designing/reference.md
- For testing strategies: See @testing/reference.md
- For refactoring patterns: See @refactoring/reference.md
- For review principles: See @pre-commit-review/reference.md