diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 727fcfb..90e3fe3 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -17,12 +17,18 @@ reviews: collapse_walkthrough: false sequence_diagrams: true changed_files_summary: true + + finishing_touches: + docstrings: + enabled: true + auto_review: enabled: true drafts: false base_branches: - "main" - "develop" + path_filters: - "!**/node_modules/**" - "!**/.next/**" @@ -35,30 +41,84 @@ reviews: - "!**/migrations/**" - "!**/*.min.js" - "!**/coverage/**" + + # ── @claude trigger instructions per severity ───────────────────────────── + # CodeRabbit will append a trigger comment to each finding so the + # claude-assistant workflow can detect and act on it automatically. + # The workflow watches for coderabbitai[bot] comments containing @claude. + review_comment_instructions: > + After every finding you post, append a trigger line based on severity: + + For CRITICAL findings (security vulnerabilities, data loss risk, crash bugs): + End your comment with exactly: + `@claude fix: critical — [one line summary of the issue]` + + For MAJOR findings (logic errors, incorrect API usage, missing error handling, + broken stack rules, AEST date bug, force unwrap without justification, + bare except:, missing type hints on public functions): + End your comment with exactly: + `@claude fix: major — [one line summary of the issue]` + + For MINOR findings (code quality, naming, documentation gaps, style): + End your comment with exactly: + `@claude fix: minor — [one line summary of the issue]` + + For NITPICK findings (purely preference-level, cosmetic): + End your comment with exactly: + `@claude issue: nitpick — [one line summary of the issue]` + + Important: nitpick findings should create a GitHub issue, NOT fix inline. + All other severities should attempt an inline fix on the PR branch. + path_instructions: - # -- Python / Home Assistant Integration -- + # — Next.js / TypeScript — + - path: "**/*.ts" + instructions: > + Check for: strict TypeScript (no `any`), correct Prisma usage, proper + Next.js 14 App Router patterns, server vs client component boundaries, + missing error boundaries, unhandled promise rejections. + - path: "**/*.tsx" + instructions: > + Verify: no client components importing server-only modules, correct use + of Suspense and loading.tsx, accessibility (aria labels, semantic HTML), + no hardcoded colours outside the design token system. + - path: "**/api/**" + instructions: > + Every route MUST have: input validation, error handling, correct HTTP + status codes, no exposed secrets or PII in responses. + - path: "**/prisma/**" + instructions: > + Check migrations are additive (no destructive schema changes without + explicit comment), indexes on foreign keys, no raw SQL without + parameterisation. + # — Swift / SwiftUI — + - path: "**/*.swift" + instructions: > + Check for: Swift concurrency correctness (no data races, correct actor + isolation), memory leaks (weak self in closures), SwiftUI view + efficiency (no unnecessary redraws), proper error handling with + Result/throws, no force unwraps without a comment justifying them. + - path: "**/Services/**" + instructions: > + Verify actor isolation, correct async/await usage, no blocking main + thread operations, proper cancellation handling. + # — Python / Flask — - path: "**/*.py" instructions: > Check for: type hints on all public functions, no bare `except:`, SQL injection risks, missing input sanitisation, secrets not in code, - proper async/await usage for Home Assistant integration patterns, - APScheduler job error handling. - - path: "**/custom_components/**" - instructions: > - Verify Home Assistant integration patterns: correct use of - async_setup_entry, config flow validation, proper coordinator - patterns, entity naming conventions, and manifest.json correctness. + Flask Blueprint structure respected, APScheduler job error handling. - path: "**/templates/**" instructions: > Verify Jinja2 templates escape user input, no XSS vectors, correct use of url_for(). - # -- GitHub Actions -- + # — GitHub Actions — - path: ".github/workflows/**" instructions: > Check: no hardcoded secrets (use ${{ secrets.X }}), pinned action versions (SHA preferred), no `pull_request_target` misuse, correct permissions blocks, jobs have timeout-minutes set. - # -- Documentation -- + # — Documentation — - path: "**/*.md" instructions: > Verify: no broken links, code examples match actual implementation, diff --git a/.github/workflows/claude-assistant.yml b/.github/workflows/claude-assistant.yml index 0a68b01..bcf4ecd 100644 --- a/.github/workflows/claude-assistant.yml +++ b/.github/workflows/claude-assistant.yml @@ -32,6 +32,43 @@ jobs: with: fetch-depth: 1 + - name: Detect CodeRabbit trigger and severity + id: cr_detect + run: | + BODY="${{ github.event.comment.body }}" + SENDER="${{ github.event.comment.user.login }}" + + IS_CR_BOT="false" + CR_SEVERITY="" + CR_SUMMARY="" + ACTION="human" + + if [ "$SENDER" = "coderabbitai[bot]" ]; then + IS_CR_BOT="true" + if echo "$BODY" | grep -q "@claude fix: critical"; then + CR_SEVERITY="critical" + ACTION="fix" + CR_SUMMARY=$(echo "$BODY" | grep -o "@claude fix: critical — .*" | sed 's/@claude fix: critical — //') + elif echo "$BODY" | grep -q "@claude fix: major"; then + CR_SEVERITY="major" + ACTION="fix" + CR_SUMMARY=$(echo "$BODY" | grep -o "@claude fix: major — .*" | sed 's/@claude fix: major — //') + elif echo "$BODY" | grep -q "@claude fix: minor"; then + CR_SEVERITY="minor" + ACTION="fix" + CR_SUMMARY=$(echo "$BODY" | grep -o "@claude fix: minor — .*" | sed 's/@claude fix: minor — //') + elif echo "$BODY" | grep -q "@claude issue: nitpick"; then + CR_SEVERITY="nitpick" + ACTION="issue" + CR_SUMMARY=$(echo "$BODY" | grep -o "@claude issue: nitpick — .*" | sed 's/@claude issue: nitpick — //') + fi + fi + + echo "is_cr_bot=$IS_CR_BOT" >> $GITHUB_OUTPUT + echo "cr_severity=$CR_SEVERITY" >> $GITHUB_OUTPUT + echo "cr_summary=$CR_SUMMARY" >> $GITHUB_OUTPUT + echo "action=$ACTION" >> $GITHUB_OUTPUT + - name: Run Claude Code Action uses: anthropics/claude-code-action@v1 with: @@ -40,7 +77,7 @@ jobs: --model claude-sonnet-4-6 --max-turns 10 custom_instructions: | - You are operating on Ryan's repositories. Follow these rules absolutely: + You are operating on Ryan's repositories. Follow these rules absolutely. IDENTITY: You are a senior engineer working within Ryan's established workflow. @@ -54,7 +91,7 @@ jobs: - Branch naming: {type}/{description}-{issue-number} CODE STANDARDS by stack: - - Next.js/TypeScript: no `any`, strict types, App Router patterns, Prisma additive migrations only + - Next.js/TypeScript: no any, strict types, App Router patterns, Prisma additive migrations only - Swift/SwiftUI: actor isolation enforced, no force unwraps without JUSTIFIED comment, @MainActor for UI - Python/Flask: type hints on all public functions, no bare except:, Flask Blueprint structure @@ -73,11 +110,41 @@ jobs: - Never auto-merge — output PR URL and stop - Always update CHANGELOG.md - CODERABBIT: After opening a PR, mention that CodeRabbit will review it automatically. - Do not merge until CodeRabbit approves and Ryan confirms. + CODERABBIT TRIGGER HANDLING: + + Detect step outputs passed from the workflow: + IS_CR_BOT: ${{ steps.cr_detect.outputs.is_cr_bot }} + CR_SEVERITY: ${{ steps.cr_detect.outputs.cr_severity }} + CR_SUMMARY: ${{ steps.cr_detect.outputs.cr_summary }} + ACTION: ${{ steps.cr_detect.outputs.action }} - FOR SMALL TASKS (issue mentions): - If assigned to an issue or mentioned with a task description: + IF IS_CR_BOT is true AND ACTION is fix (critical, major, or minor): + 1. Read the full CodeRabbit comment to understand the finding completely + 2. Locate the exact file and line referenced in the comment + 3. Understand the issue — do not guess beyond what is stated + 4. Write the minimal fix that resolves the finding — do not refactor beyond it + 5. Run the appropriate check for the affected file type: + .ts/.tsx: npx tsc --noEmit and npm run lint + .swift: swiftlint --strict + .py: ruff check . and mypy . --ignore-missing-imports + 6. If the check passes, commit on the current PR branch: + fix({scope}): {cr_summary} + Resolves CodeRabbit {cr_severity} finding. + Auto-fixed via CodeRabbit @claude trigger. + 7. Push to the PR branch — never to main + 8. Reply to the CodeRabbit comment: Fixed in [SHA]. [One sentence describing the change.] + 9. Stop — do not open new PRs for CR fixes + + IF IS_CR_BOT is true AND ACTION is issue (nitpick): + 1. Read the full CodeRabbit comment to understand the nitpick + 2. Do NOT make any code changes — nitpicks are never fixed inline + 3. Create a GitHub issue with: title starting with style:, label style and coderabbit-nitpick, assignee @me + 4. Reply to the CodeRabbit comment: Tracked in issue #[N]. Not fixing inline per project convention. + 5. Stop + + HUMAN TRIGGER HANDLING (IS_CR_BOT is false): + + FOR SMALL TASKS (@claude in issue body or assigned): 1. Analyse the issue and related codebase 2. Create a branch 3. Implement the fix/feature @@ -86,7 +153,11 @@ jobs: 6. Comment on the issue with the PR link 7. Stop — do not merge - FOR CODE REVIEW QUESTIONS (PR/issue comments with @claude): - Answer the question directly with reference to the actual code. + FOR CODE REVIEW QUESTIONS (@claude in PR comment): + Answer directly with reference to actual code. If suggesting a fix, provide the exact code change. Do not open PRs for review answers unless explicitly asked. + + FOR DEEP REVIEW (@claude review in PR comment): + Apply linus-code-reviewer standard. + Score 1-10. Critical/Serious/Minor. BLOCK/NEEDS WORK/LGTM verdict.