From d4b09f0584fd269dbb19ecd5ffa76729f78c5de8 Mon Sep 17 00:00:00 2001 From: Kevin Strom Date: Wed, 22 Jul 2026 10:25:14 -0700 Subject: [PATCH] chore: add Claude PR review workflow and CLAUDE.md --- .github/workflows/claude-review.yml | 73 +++++++++++++++++++++++++++++ .kiro/steering/AI-MAP.md | 5 ++ CLAUDE.md | 29 ++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 .github/workflows/claude-review.yml create mode 100644 CLAUDE.md diff --git a/.github/workflows/claude-review.yml b/.github/workflows/claude-review.yml new file mode 100644 index 0000000..96dda15 --- /dev/null +++ b/.github/workflows/claude-review.yml @@ -0,0 +1,73 @@ +name: Claude PR Review + +on: + pull_request: + types: [opened, ready_for_review, synchronize] + +# Cancel a superseded review when new commits are pushed — cost control. +concurrency: + group: claude-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + issues: write + id-token: write + +jobs: + review: + # Skip drafts; review when marked ready. + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # full history so Claude can diff against base + + - uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + prompt: | + Review pull request #${{ github.event.pull_request.number }} in + ${{ github.repository }} as a rigorous senior reviewer. Post your + review as a PR comment, with file-anchored comments for specific + issues. End with a clear verdict: approve, approve-with-nits, or + request-changes, and list blocking items separately from nits. + + Project context: this repo is a visual page builder for Nuxt, + built task-by-task from specs. Read .kiro/steering/AI-MAP.md and + the relevant files in ".kiro/specs/" and "MD Instructions/" before + judging the diff — PRs here are usually either spec documents or + implementations of a spec. + + Review standards for this repo, in priority order: + + 1. VERIFY, don't trust. If the PR contains code, run the actual + acceptance toolchain from a clean state: npm ci (a lockfile out + of sync with package.json is an automatic blocker), then + npm test, npm run typecheck, npm run lint, npm run build. + Report exact failures. A fresh clone must work — missing + postinstall/prepare steps are blockers, not nits. + + 2. Spec traceability. If the PR implements a numbered task, check + the implementation against that spec's acceptance criteria and + flag criteria that are unmet or silently reinterpreted. + + 3. Consistency across sources of truth. Flag contradictions + between the diff, .kiro/steering/AI-MAP.md, .kiro/specs/, and + "MD Instructions/" — including stale version pins and paths. + + 4. Registry purity rule: nothing imported by /compiler, its CLI, + or /server may transitively import .vue files. Check imports. + + 5. Standard review: correctness, types (no `any`), security, + and whether tests actually assert what they claim. + + Do not restate the diff or praise padding. Credit genuinely good + decisions in one or two lines. Be specific enough that a follow-up + commit can address every point without asking questions. + claude_args: | + --max-turns 30 + --allowedTools "Bash(npm ci),Bash(npm install),Bash(npm test),Bash(npm run typecheck),Bash(npm run lint),Bash(npm run build),Bash(npx nuxt prepare),Bash(git diff:*),Bash(git log:*)" diff --git a/.kiro/steering/AI-MAP.md b/.kiro/steering/AI-MAP.md index 4808dde..5142a9d 100644 --- a/.kiro/steering/AI-MAP.md +++ b/.kiro/steering/AI-MAP.md @@ -126,6 +126,10 @@ A serializable JSON tree (`PageNode` with children/slots). Must survive `/registry/entries.ts` (never `/registry/index.ts` which pulls .vue files) - Columns block: only accepts Column children (enforced by registry + validation) - Zod pinned to ^4 +- PRs are automatically reviewed by Claude via + `.github/workflows/claude-review.yml`. Review feedback posted by the + github-actions Claude bot on a PR should be treated like human review + feedback: address blockers before merge. ## How to Update This File @@ -141,3 +145,4 @@ After completing a task: |------|----------|---------| | — | @formkit/drag-and-drop spike required | Task 07 requires proving nested named-slot drops work before full wiring. If it can't, fall back to custom pointer-events for canvas, keep library for flat lists. | | — | Columns only accepts Column children | `allowedChildren: ['Column']` on Columns entry + `allowedParents: ['Columns']` on Column entry. Both validated by `validateAgainstRegistry` (Task 03). Drop-target guard (Task 07) checks both directions. Column.span is a number prop (min:1, max:4). | +| — | CLAUDE.md mirrors steering conventions for non-Kiro agents | `CLAUDE.md` at the repo root provides the same project conventions to Claude Code and the GitHub Actions reviewer. When conventions in `.kiro/steering/` change, `CLAUDE.md` must be updated in sync. | diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9cabaa2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,29 @@ +# CLAUDE.md + +This repository is primarily built by Kiro using the specs in `.kiro/specs/` +and the task instructions in `MD Instructions/`. Claude (GitHub Actions +reviewer, Claude Code sessions) must follow the same project conventions. + +## Read these first + +- `.kiro/steering/AI-MAP.md` — project map, key files, conventions, and the + Decisions Log. Treat the Decisions Log as settled; do not relitigate it in + reviews. +- `.kiro/steering/Git-Branching-and-Merging.md` — branch/PR workflow. Never + commit directly to main. +- `MD Instructions/00-START-HERE.md` — architecture overview and task order. + +## Non-negotiable conventions + +- Nuxt 4 (stable defaults, no `future.compatibilityVersion`), Nuxt UI v4, + Tailwind v4, TypeScript strict, no `any`. +- Blocks (`app/components/blocks/`) use Tailwind only — never Nuxt UI. + Editor chrome (`app/components/editor/`) uses Nuxt UI. +- Registry purity: `/compiler`, its CLI, and `/server` may only import + registry data from `/registry/entries.ts` — never anything that + transitively imports `.vue` files. +- Component tests mounting Nuxt UI components use `mountSuspended` from + `@nuxt/test-utils/runtime` (Vitest environment `nuxt`); pure unit tests + opt into node via a `// @vitest-environment node` docblock. +- A fresh clone must pass: `npm ci && npm test && npm run typecheck && + npm run lint && npm run build`.