AgentSkillsCN

add-check

在 roto-rooter 中新增一项静态分析检查。当用户希望为 React Router 应用程序创建新的检查、验证规则或分析器时使用此功能。它可指导实现那些需要跨文件应用上下文的检查,例如路由与组件之间的关系。

SKILL.md
--- frontmatter
name: add-check
description: Add a new static analysis check to roto-rooter. Use when the user wants to create a new check, validation rule, or analyzer for React Router applications. Guides implementation of checks that require cross-file application context like route/component relationships.

Add Check Skill

Add a new check to roto-rooter: /add-check <check-name>

Scope

Only add checks that require cross-file application context. This tool analyzes route/component relationships that ESLint cannot see.

Add checks that: cross-reference routes, components, and exports; validate references match actual application structure; require multi-file AST analysis; validate against external schema files (e.g., Drizzle ORM schema).

Reject checks that: can be an ESLint rule; examine single files in isolation; check generic React/TypeScript patterns. If rejectable, explain why and recommend the appropriate ESLint rule instead.

Implementation Steps

  1. Types - Add category to AnalyzerIssue.category union in src/types.ts

  2. Check file - Create src/checks/<name>-check.ts:

    • Export check<PascalName>(components: ComponentAnalysis[], routes?: RouteDefinition[], rootDir?: string): AnalyzerIssue[]
    • Use findBestMatch() from ../utils/suggestion.js for typo suggestions
    • Add fix property to issues when auto-fix is possible (see "Auto-Fix Guidelines" below)
  3. Register - In src/analyzer.ts: import the check, add to enabledChecks default list, add invocation block

  4. Tests - Create test/<name>-check.test.ts using vitest. Always add realistic fixtures to test/fixtures/sample-app/app/routes/ and register them in routes.ts. Tests should use these fixtures to verify behavior. CLI integration tests in test/cli.test.ts cover end-to-end behavior.

  5. Fix Integration Tests - If the check generates auto-fixes, add end-to-end tests in test/fix-integration.test.ts that verify:

    • Issue is detected with a fix
    • applyFixes() modifies files correctly
    • Re-running analyze() shows the issue is resolved
    • See existing tests in fix-integration.test.ts for the pattern
  6. Parser (if needed) - Extend component-parser.ts, route-parser.ts, or action-parser.ts for new AST patterns

  7. Documentation - Update README.md and CLAUDE.md to list the new check

  8. Verify - Run npm test

Summary Output

After implementing the check, output a summary that includes example CLI output showing what the check failure looks like:

code
## Check Implementation Complete: <check-name>

### Files Changed
- src/types.ts - Added '<check-name>' to category union
- src/checks/<check-name>-check.ts - New check implementation
- src/analyzer.ts - Registered check
- test/<check-name>-check.test.ts - Tests
- README.md, CLAUDE.md - Documentation

### Example Output
$ rr app/routes/example.tsx
app/routes/example.tsx:15:5 error [<check-name>] <Error message here>
  |
  | <code snippet showing the problematic line>
  |
  Suggestion: <suggestion text>

Found 1 issue (1 error, 0 warnings)

Auto-Fix Guidelines

When an issue has a deterministic fix that won't introduce other problems, add an auto-fix:

  1. Track source spans - In the parser, capture SourceSpan for any values that might need fixing (attribute values, identifiers, etc.) using getNodeSpan() from ast-utils.ts

  2. Create fix edits - Add a fix property with description and edits array to issues. Study existing checks for the pattern.

  3. Fixable vs unfixable - Only auto-fix when:

    • The fix is deterministic (e.g., typo correction with fuzzy match)
    • No business logic is required (don't auto-generate loaders/actions)
    • The fix won't break other code (be conservative)
  4. Test the fix - Add integration tests in test/fix-integration.test.ts that verify the complete cycle

Test Fixture Requirements

Every check must have realistic test fixtures that demonstrate both positive and negative cases:

  1. Create fixture file - Add a .tsx file to test/fixtures/sample-app/app/routes/ that contains:

    • Real-world patterns the check should catch (positive cases)
    • Valid patterns the check should NOT flag (negative cases / false positive prevention)
  2. Register the route - Add the fixture to test/fixtures/sample-app/app/routes.ts

  3. Update route count - Update the route count in test/route-parser.test.ts

  4. Write fixture-based tests - Tests should:

    • Parse the fixture using parseComponent()
    • Run the check against it
    • Verify both that issues ARE found for problematic patterns AND that issues are NOT found for valid patterns

Issue Guidelines

Severity Levels

error - Use for issues that will:

  • Cause render failures or runtime exceptions
  • Result in inconsistent behavior across users (e.g., different locales, timezones, browsers)
  • Break functionality in ways users will notice (missing data, broken navigation, form failures)
  • Cause hydration mismatches that force React to discard and re-render

warning - Use for issues that:

  • Log errors to the browser console but don't affect user-visible behavior
  • Have a less efficient but functional fallback (e.g., performance degradation)
  • May cause problems only in edge cases or specific configurations
  • Are best practices violations that don't directly impact users

When in doubt, prefer error. Users can configure checks to ignore specific issues, but they can't escalate warnings they missed.

Message Format

  • Messages: specific, actionable, include the problematic value
  • Always include accurate location (line/column) and code snippet

Reference

Study existing checks in src/checks/ and parsers in src/parsers/ for patterns and idioms.