pr-review-agent 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # PR Review Agent
2
+
3
+ AI-powered pull request review agent for Claude Code, OpenCode, and other AI coding assistants.
4
+
5
+ Analyzes PRs against your project's architectural patterns and generates an interactive preview with inline editing.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npx pr-review-agent@latest
11
+ ```
12
+
13
+ The interactive installer asks for your AI assistant (Claude Code, OpenCode) and scope (global or project-level).
14
+
15
+ ### Non-interactive
16
+
17
+ ```bash
18
+ npx pr-review-agent --claude --global # Claude Code, user-wide
19
+ npx pr-review-agent --claude --local # Claude Code, project only
20
+ npx pr-review-agent --opencode --global # OpenCode, user-wide
21
+ ```
22
+
23
+ ### Uninstall
24
+
25
+ ```bash
26
+ npx pr-review-agent --claude --global --uninstall
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ After installing, in your AI assistant:
32
+
33
+ ```
34
+ /pr-review:review https://github.com/org/repo/pull/123
35
+ ```
36
+
37
+ The agent will:
38
+ 1. Fetch the PR diff via GitHub CLI (`gh`)
39
+ 2. Analyze code against your `REVIEW-PLAN.md` checklist and project skills
40
+ 3. Generate `findings.json` + `config.json`
41
+ 4. Output a summary of findings
42
+
43
+ ### Preview UI
44
+
45
+ Start the local server to view and edit findings:
46
+
47
+ ```bash
48
+ node .claude/pr-review/serve.js
49
+ # Open http://localhost:3847
50
+ ```
51
+
52
+ Features:
53
+ - Filter by severity, category, file
54
+ - Inline editing with live preview
55
+ - Create/edit/delete categories
56
+ - Auto-save to disk
57
+
58
+ ## What Gets Installed
59
+
60
+ Everything lives inside `.claude/` (like GSD uses `.claude/get-shit-done/`):
61
+
62
+ | Location | Files |
63
+ |----------|-------|
64
+ | `.claude/commands/pr-review/` | Slash commands (`review.md`, `setup.md`) |
65
+ | `.claude/agents/` | Agent definition (`pr-reviewer.md`) |
66
+ | `.claude/pr-review/` | UI template, server, review plan, findings data |
67
+
68
+ ## Configuration
69
+
70
+ Edit `.claude/pr-review/REVIEW-PLAN.md` to customize what the agent checks. The agent also reads `CLAUDE.md` and project skills automatically.
71
+
72
+ ## Requirements
73
+
74
+ - Node.js >= 18
75
+ - GitHub CLI (`gh`) installed and authenticated
76
+ - Claude Code, OpenCode, or compatible AI assistant
77
+
78
+ ## License
79
+
80
+ MIT
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: pr-reviewer
3
+ description: Automated PR code review agent. Analyzes pull request diffs against project-specific architectural patterns, conventions, and best practices. Produces structured findings with severity levels and generates an interactive HTML preview.
4
+ tools: Read, Bash, Grep, Glob, Write
5
+ color: blue
6
+ ---
7
+
8
+ <role>
9
+ You are a PR Review Agent. You perform comprehensive code reviews on GitHub pull requests by analyzing diffs against project-specific conventions, architectural patterns, and best practices.
10
+
11
+ **CRITICAL: Mandatory Initial Read**
12
+ If the prompt contains a `<files_to_read>` block, you MUST use the `Read` tool to load every file listed there before performing any other actions.
13
+
14
+ Before starting any review:
15
+ 1. Read `./CLAUDE.md` (or equivalent project instructions file) for project conventions
16
+ 2. Read `./REVIEW-PLAN.md` for review criteria
17
+ 3. Check for project-specific skills/patterns in the config directory
18
+ 4. If skills define architecture rules, those rules are MANDATORY review criteria
19
+ </role>
20
+
21
+ <project_context>
22
+ **Discover project patterns automatically:**
23
+ 1. Read `./CLAUDE.md` — project conventions, commands, architecture
24
+ 2. Read `./REVIEW-PLAN.md` — review checklist configured by developer
25
+ 3. Check for project skills directories — architectural skills that define how code should be written
26
+ 4. Read skill index files for pattern summaries, load specific rules as needed
27
+
28
+ **Pattern Priority (highest first):**
29
+ 1. Security vulnerabilities (auth, injection, secrets)
30
+ 2. Architectural violations (patterns defined in REVIEW-PLAN.md and skills)
31
+ 3. i18n violations (hardcoded text)
32
+ 4. Design token violations (hardcoded colors)
33
+ 5. Missing API documentation
34
+ 6. Testing gaps
35
+ 7. Code style/naming
36
+ </project_context>
37
+
38
+ <core_principle>
39
+ **Goal-backward review**: Start from "what patterns MUST this code follow" and verify each file against those patterns.
40
+
41
+ **Signal over noise**: Only report actionable findings. If a file follows all patterns correctly, stay silent. A 29% silence rate is healthy (inspired by GitHub Copilot's approach).
42
+
43
+ **Never approve or block**: Post findings as comments only. The human reviewer decides what to enforce.
44
+
45
+ **Three severity levels:**
46
+ - **Critical** (red): Must fix before merge — bugs, security issues, major architectural violations
47
+ - **Warning** (yellow): Should fix — pattern inconsistencies, missing documentation, minor architectural gaps
48
+ - **Suggestion** (blue): Consider improving — style, optimizations, naming improvements
49
+ </core_principle>
50
+
51
+ <execution_flow>
52
+
53
+ <step name="prerequisites" priority="first">
54
+ ## Step 0: Verify GitHub CLI
55
+
56
+ ```bash
57
+ gh auth status
58
+ ```
59
+
60
+ If `gh` is not found or not authenticated, STOP and inform the user:
61
+ - Windows: `winget install GitHub.cli --source winget`
62
+ - macOS: `brew install gh`
63
+ - Then: `gh auth login`
64
+
65
+ Without `gh` CLI, this agent cannot function.
66
+ </step>
67
+
68
+ <step name="detect_config" priority="first">
69
+ ## Step 0.5: Detect PR Review Directory
70
+
71
+ Locate the pr-review runtime directory. Check in order:
72
+ 1. `./__CONFIG_DIR__/pr-review/` (local project install)
73
+ 2. `$HOME/__CONFIG_DIR__/pr-review/` (global user install)
74
+
75
+ Store the resolved path as `PR_REVIEW_DIR` for subsequent steps.
76
+ If neither exists, inform user to run the installer: `npx pr-review-agent`
77
+ </step>
78
+
79
+ <step name="load_context" priority="first">
80
+ ## Step 1: Load Review Context
81
+
82
+ 1. Read CLAUDE.md (or project instructions) for project rules
83
+ 2. Read ./REVIEW-PLAN.md for checklist. If missing, generate from template at `$PR_REVIEW_DIR/templates/review-plan.md`
84
+ 3. Read any project skills for architectural patterns
85
+ 4. Parse the PR URL/number from arguments
86
+ 5. Fetch PR metadata:
87
+ ```bash
88
+ gh pr view {PR_NUMBER} --repo {OWNER/REPO} --json title,body,headRefName,baseRefName,files,additions,deletions,changedFiles
89
+ ```
90
+ 6. Fetch existing review comments to avoid duplicates:
91
+ ```bash
92
+ gh api repos/{OWNER/REPO}/pulls/{PR_NUMBER}/comments --paginate --jq '.[] | "FILE: \(.path)\nBODY: \(.body)\n---"'
93
+ ```
94
+ </step>
95
+
96
+ <step name="analyze_changes">
97
+ ## Step 2: Analyze Code Changes
98
+
99
+ For each code file in the PR (skip .planning/, .md, lock files, migrations):
100
+
101
+ 1. Fetch the diff:
102
+ ```bash
103
+ gh api repos/{OWNER/REPO}/pulls/{PR_NUMBER}/files --paginate --jq '.[] | select(.filename == "FILE") | .patch'
104
+ ```
105
+
106
+ 2. Analyze against REVIEW-PLAN.md checklist categories.
107
+
108
+ 3. For each finding, record:
109
+ - file path, category, severity (critical/warning/suggestion)
110
+ - title (short, descriptive), body (detailed explanation with code examples)
111
+ - line number (approximate)
112
+
113
+ **Deduplication rules:**
114
+ - If the same pattern violation appears in 5+ files, consolidate into one finding referencing all files
115
+ - If an existing comment already covers a finding, skip it
116
+ </step>
117
+
118
+ <step name="generate_output">
119
+ ## Step 3: Generate Review Output
120
+
121
+ ### 3a. Write findings JSON
122
+ Write the findings array to `$PR_REVIEW_DIR/findings.json`
123
+
124
+ ### 3b. Update config.json
125
+ Write/update `$PR_REVIEW_DIR/config.json` with PR metadata and category definitions.
126
+
127
+ The HTML template (`$PR_REVIEW_DIR/index.html`) loads data dynamically from these JSON files via `fetch()`.
128
+
129
+ ### 3c. Summary report
130
+ Print a summary table with counts by category and severity.
131
+ </step>
132
+
133
+ <step name="post_comments">
134
+ ## Step 4: Post Comments (Optional)
135
+
136
+ Only if the user requests it (`--post` flag). Consolidate findings per file to reduce noise.
137
+ </step>
138
+
139
+ </execution_flow>
140
+
141
+ <success_criteria>
142
+ - [ ] All code files in PR analyzed against REVIEW-PLAN.md checklist
143
+ - [ ] No duplicate findings (checked against existing comments)
144
+ - [ ] findings.json written with structured data
145
+ - [ ] config.json written with PR metadata
146
+ - [ ] Summary printed to user
147
+ - [ ] User prompted about posting comments
148
+ </success_criteria>
package/bin/install.js ADDED
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pr-review-agent installer
4
+ * Usage: npx pr-review-agent@latest
5
+ *
6
+ * Installs the PR review agent (commands, agents, template files)
7
+ * into your AI coding assistant's config directory.
8
+ *
9
+ * Supports: Claude Code, OpenCode (more coming)
10
+ * Scope: Global (user-wide) or Local (project-only)
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+ const readline = require('readline');
16
+ const os = require('os');
17
+
18
+ const VERSION = require('../package.json').version;
19
+ const PKG_ROOT = path.resolve(__dirname, '..');
20
+
21
+ // ===== Runtime definitions =====
22
+ const RUNTIMES = {
23
+ claude: {
24
+ name: 'Claude Code',
25
+ configDirName: '.claude',
26
+ globalDir: () => path.join(process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude')),
27
+ localDir: () => path.join(process.cwd(), '.claude'),
28
+ commandsDir: 'commands/pr-review',
29
+ agentsDir: 'agents',
30
+ },
31
+ opencode: {
32
+ name: 'OpenCode',
33
+ configDirName: '.config/opencode',
34
+ globalDir: () => path.join(os.homedir(), '.config', 'opencode'),
35
+ localDir: () => path.join(process.cwd(), '.config', 'opencode'),
36
+ commandsDir: 'commands/pr-review',
37
+ agentsDir: 'agents',
38
+ },
39
+ };
40
+
41
+ // ===== ANSI colors =====
42
+ const c = {
43
+ reset: '\x1b[0m',
44
+ bold: '\x1b[1m',
45
+ dim: '\x1b[2m',
46
+ purple: '\x1b[35m',
47
+ green: '\x1b[32m',
48
+ yellow: '\x1b[33m',
49
+ red: '\x1b[31m',
50
+ cyan: '\x1b[36m',
51
+ blue: '\x1b[34m',
52
+ };
53
+
54
+ // ===== CLI arg parsing =====
55
+ const args = process.argv.slice(2);
56
+ const flags = new Set(args.filter(a => a.startsWith('--')).map(a => a.slice(2)));
57
+
58
+ function hasFlag(name) { return flags.has(name); }
59
+
60
+ // ===== Helpers =====
61
+ function log(msg = '') { process.stdout.write(msg + '\n'); }
62
+
63
+ function banner() {
64
+ log('');
65
+ log(` ${c.purple}${c.bold}╔═══════════════════════════════════════╗${c.reset}`);
66
+ log(` ${c.purple}${c.bold}║ PR Review Agent v${VERSION.padEnd(12)}║${c.reset}`);
67
+ log(` ${c.purple}${c.bold}╚═══════════════════════════════════════╝${c.reset}`);
68
+ log('');
69
+ log(` ${c.dim}AI-powered PR review for Claude Code & more${c.reset}`);
70
+ log('');
71
+ }
72
+
73
+ function prompt(question) {
74
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
75
+ return new Promise(resolve => {
76
+ rl.question(` ${question}`, answer => { rl.close(); resolve(answer.trim()); });
77
+ });
78
+ }
79
+
80
+ function mkdirp(dir) {
81
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
82
+ }
83
+
84
+ // configDirName is set during install (e.g. '.claude', '.config/opencode')
85
+ let configDirName = '.claude';
86
+
87
+ function copyFile(src, dest) {
88
+ mkdirp(path.dirname(dest));
89
+ // Rewrite __CONFIG_DIR__ placeholder in text files (.md, .js)
90
+ const ext = path.extname(src);
91
+ if (['.md', '.js', '.json'].includes(ext)) {
92
+ let content = fs.readFileSync(src, 'utf-8');
93
+ content = content.replace(/__CONFIG_DIR__/g, configDirName);
94
+ fs.writeFileSync(dest, content, 'utf-8');
95
+ } else {
96
+ fs.copyFileSync(src, dest);
97
+ }
98
+ }
99
+
100
+ function copyDir(src, dest) {
101
+ mkdirp(dest);
102
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
103
+ const srcPath = path.join(src, entry.name);
104
+ const destPath = path.join(dest, entry.name);
105
+ if (entry.isDirectory()) copyDir(srcPath, destPath);
106
+ else copyFile(srcPath, destPath);
107
+ }
108
+ }
109
+
110
+ // ===== Uninstall =====
111
+ function uninstall(configDir) {
112
+ const toRemove = [
113
+ path.join(configDir, 'commands', 'pr-review'),
114
+ path.join(configDir, 'agents', 'pr-reviewer.md'),
115
+ path.join(configDir, 'pr-review'),
116
+ ];
117
+
118
+ let removed = 0;
119
+ for (const p of toRemove) {
120
+ if (fs.existsSync(p)) {
121
+ const stat = fs.statSync(p);
122
+ if (stat.isDirectory()) fs.rmSync(p, { recursive: true });
123
+ else fs.unlinkSync(p);
124
+ removed++;
125
+ log(` ${c.red}removed${c.reset} ${p}`);
126
+ }
127
+ }
128
+
129
+ if (removed === 0) log(` ${c.yellow}Nothing to uninstall.${c.reset}`);
130
+ else log(`\n ${c.green}Uninstalled PR Review Agent.${c.reset}`);
131
+ log('');
132
+ }
133
+
134
+ // ===== Install =====
135
+ function install(runtime, configDir) {
136
+ const rt = RUNTIMES[runtime];
137
+ // Set configDirName for path rewriting in copyFile
138
+ configDirName = rt.configDirName;
139
+ // Template goes inside configDir as pr-review/ (like GSD uses get-shit-done/)
140
+ const templateDest = path.join(configDir, 'pr-review');
141
+
142
+ log(` ${c.cyan}Installing for ${rt.name}...${c.reset}`);
143
+ log('');
144
+
145
+ // 1. Copy commands
146
+ const cmdSrc = path.join(PKG_ROOT, 'commands', 'pr-review');
147
+ const cmdDest = path.join(configDir, rt.commandsDir);
148
+ copyDir(cmdSrc, cmdDest);
149
+ const cmdCount = fs.readdirSync(cmdSrc).length;
150
+ log(` ${c.green}+${c.reset} ${cmdCount} commands ${c.dim}→ ${cmdDest}${c.reset}`);
151
+
152
+ // 2. Copy agent
153
+ const agentSrc = path.join(PKG_ROOT, 'agents', 'pr-reviewer.md');
154
+ const agentDest = path.join(configDir, rt.agentsDir, 'pr-reviewer.md');
155
+ copyFile(agentSrc, agentDest);
156
+ log(` ${c.green}+${c.reset} 1 agent ${c.dim}→ ${agentDest}${c.reset}`);
157
+
158
+ // 3. Copy runtime files (index.html, serve.js, templates/)
159
+ const runtimeFiles = ['index.html', 'serve.js', '.gitignore'];
160
+ mkdirp(templateDest);
161
+ for (const f of runtimeFiles) {
162
+ const src = path.join(PKG_ROOT, 'template', f);
163
+ if (fs.existsSync(src)) copyFile(src, path.join(templateDest, f));
164
+ }
165
+ // Copy review-plan template (used by /pr-review:setup to generate REVIEW-PLAN.md)
166
+ const tplSrc = path.join(PKG_ROOT, 'template', 'templates');
167
+ const tplDest = path.join(templateDest, 'templates');
168
+ if (fs.existsSync(tplSrc)) copyDir(tplSrc, tplDest);
169
+ log(` ${c.green}+${c.reset} runtime ${c.dim}→ ${templateDest}${c.reset}`);
170
+
171
+ // 4. Write version file
172
+ fs.writeFileSync(path.join(templateDest, '.version'), VERSION);
173
+
174
+ // 5. Ensure .gitignore in template dir
175
+ const gitignorePath = path.join(templateDest, '.gitignore');
176
+ if (!fs.existsSync(gitignorePath)) {
177
+ fs.writeFileSync(gitignorePath, '# Generated on each review run\nfindings.json\nconfig.json\n');
178
+ }
179
+
180
+ log('');
181
+ log(` ${c.green}${c.bold}PR Review Agent v${VERSION} installed!${c.reset}`);
182
+ log('');
183
+ log(` ${c.bold}Quick start:${c.reset}`);
184
+ log(` ${c.dim}1.${c.reset} Generate your review plan (first time only):`);
185
+ log(` ${c.cyan}/pr-review:setup${c.reset}`);
186
+ log(` ${c.dim}2.${c.reset} Review a PR:`);
187
+ log(` ${c.cyan}/pr-review:review <pr-url>${c.reset}`);
188
+ log(` ${c.dim}3.${c.reset} Preview findings in browser:`);
189
+ log(` ${c.cyan}node ${rt.configDirName}/pr-review/serve.js${c.reset}`);
190
+ log('');
191
+ log(` ${c.dim}Commands:${c.reset}`);
192
+ log(` /pr-review:setup ${c.dim}— Generate REVIEW-PLAN.md for your project${c.reset}`);
193
+ log(` /pr-review:review ${c.dim}— Analyze a PR against your review plan${c.reset}`);
194
+ log('');
195
+ }
196
+
197
+ // ===== Main =====
198
+ async function main() {
199
+ const isTTY = process.stdin.isTTY && process.stdout.isTTY;
200
+
201
+ // Non-interactive defaults
202
+ if (!isTTY || hasFlag('help')) {
203
+ if (hasFlag('help')) {
204
+ banner();
205
+ log(` ${c.bold}Usage:${c.reset} npx pr-review-agent@latest [options]`);
206
+ log('');
207
+ log(` ${c.bold}Options:${c.reset}`);
208
+ log(` --claude Install for Claude Code`);
209
+ log(` --opencode Install for OpenCode`);
210
+ log(` --global Install user-wide (default)`);
211
+ log(` --local Install in current project only`);
212
+ log(` --uninstall Remove the agent`);
213
+ log(` --help Show this help`);
214
+ log('');
215
+ log(` ${c.bold}Examples:${c.reset}`);
216
+ log(` npx pr-review-agent ${c.dim}# interactive${c.reset}`);
217
+ log(` npx pr-review-agent --claude --local ${c.dim}# Claude, project-level${c.reset}`);
218
+ log(` npx pr-review-agent --claude --global --uninstall`);
219
+ log('');
220
+ return;
221
+ }
222
+ // Non-TTY or has specific flags: resolve from args
223
+ const rt = ['claude', 'opencode'].find(r => hasFlag(r)) || 'claude';
224
+ const scope = hasFlag('local') ? 'local' : 'global';
225
+ const dir = scope === 'local' ? RUNTIMES[rt].localDir() : RUNTIMES[rt].globalDir();
226
+ if (hasFlag('uninstall')) return uninstall(dir);
227
+ return install(rt, dir);
228
+ }
229
+
230
+ banner();
231
+
232
+ // Detect flags for non-interactive mode
233
+ const runtimeFlag = ['claude', 'opencode'].find(r => hasFlag(r));
234
+ const scopeFlag = hasFlag('local') ? 'local' : hasFlag('global') ? 'global' : null;
235
+
236
+ // 1. Select runtime
237
+ let runtime = runtimeFlag;
238
+ if (!runtime) {
239
+ log(` ${c.bold}Select your AI coding assistant:${c.reset}`);
240
+ log('');
241
+ log(` ${c.cyan}1${c.reset}) Claude Code`);
242
+ log(` ${c.cyan}2${c.reset}) OpenCode`);
243
+ log('');
244
+ const choice = await prompt(`${c.bold}Enter choice [1]:${c.reset} `);
245
+ runtime = choice === '2' ? 'opencode' : 'claude';
246
+ log('');
247
+ }
248
+
249
+ // 2. Select scope
250
+ let scope = scopeFlag;
251
+ if (!scope) {
252
+ log(` ${c.bold}Install scope:${c.reset}`);
253
+ log('');
254
+ log(` ${c.cyan}1${c.reset}) Global ${c.dim}— available in all projects (${RUNTIMES[runtime].globalDir()})${c.reset}`);
255
+ log(` ${c.cyan}2${c.reset}) Local ${c.dim}— this project only (${RUNTIMES[runtime].localDir()})${c.reset}`);
256
+ log('');
257
+ const choice = await prompt(`${c.bold}Enter choice [1]:${c.reset} `);
258
+ scope = choice === '2' ? 'local' : 'global';
259
+ log('');
260
+ }
261
+
262
+ const configDir = scope === 'local'
263
+ ? RUNTIMES[runtime].localDir()
264
+ : RUNTIMES[runtime].globalDir();
265
+
266
+ // 3. Uninstall or install
267
+ if (hasFlag('uninstall')) {
268
+ uninstall(configDir);
269
+ } else {
270
+ install(runtime, configDir);
271
+ }
272
+ }
273
+
274
+ main().catch(err => {
275
+ log(`\n ${c.red}${c.bold}Error:${c.reset} ${err.message}`);
276
+ process.exit(1);
277
+ });
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: pr-review:review
3
+ description: Analyze a GitHub PR against project architectural patterns and generate an interactive review preview. Posts comments to GitHub optionally.
4
+ argument-hint: "<pr-url-or-number> [--post] [--focus security|i18n|architecture|design-tokens|all]"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ - AskUserQuestion
12
+ agent: pr-reviewer
13
+ ---
14
+
15
+ <objective>
16
+ Perform a comprehensive code review on a GitHub pull request by analyzing diffs against
17
+ project-specific conventions defined in project instructions, skills, and ./REVIEW-PLAN.md.
18
+ Generates structured findings and optionally posts comments to the PR.
19
+ </objective>
20
+
21
+ <execution_context>
22
+ @./REVIEW-PLAN.md
23
+ @./CLAUDE.md
24
+ </execution_context>
25
+
26
+ <context>
27
+ PR identifier: $ARGUMENTS (GitHub URL, org/repo#N, or PR number)
28
+
29
+ **Flags:**
30
+ - `--post` — Post findings as comments on the GitHub PR
31
+ - `--focus security` — Focus on security patterns only
32
+ - `--focus i18n` — Focus on i18n violations only
33
+ - `--focus architecture` — Focus on architectural patterns only
34
+ - `--focus design-tokens` — Focus on design token violations only
35
+ - `--focus all` — Full review (default)
36
+
37
+ **Prerequisites:**
38
+ - GitHub CLI (`gh`) installed and authenticated
39
+ - `./REVIEW-PLAN.md` exists (run `/pr-review:setup` to generate it)
40
+
41
+ **First run:** If `REVIEW-PLAN.md` doesn't exist, generate it from the template at
42
+ `__CONFIG_DIR__/pr-review/templates/review-plan.md` — copy to `./REVIEW-PLAN.md` and ask the
43
+ user to customize the "Project-Specific Rules" section before proceeding.
44
+ </context>
45
+
46
+ <process>
47
+ 1. Verify gh CLI is available and authenticated
48
+ 2. Detect pr-review directory (local `__CONFIG_DIR__/pr-review/` or global `$HOME/__CONFIG_DIR__/pr-review/`)
49
+ 3. If REVIEW-PLAN.md doesn't exist at project root, generate it from template and notify user
50
+ 4. Load project context (project instructions, skills, REVIEW-PLAN.md)
51
+ 5. Fetch PR metadata and existing comments
52
+ 6. Analyze each code file against review checklist
53
+ 7. Generate structured findings (`$PR_REVIEW_DIR/findings.json`)
54
+ 8. Generate config (`$PR_REVIEW_DIR/config.json`)
55
+ 9. Print summary to user
56
+ 10. If --post flag: ask confirmation then post comments to PR
57
+ </process>
58
+
59
+ <success_criteria>
60
+ - [ ] All code files analyzed against project patterns
61
+ - [ ] findings.json created
62
+ - [ ] config.json created
63
+ - [ ] Summary table displayed
64
+ - [ ] Comments posted to PR (if --post flag used)
65
+ </success_criteria>
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: pr-review:setup
3
+ description: Initialize PR review for the current project. Generates REVIEW-PLAN.md with project-specific criteria.
4
+ argument-hint: ""
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Glob
10
+ - AskUserQuestion
11
+ ---
12
+
13
+ <objective>
14
+ Set up PR review for the current project. Generates a REVIEW-PLAN.md at the project
15
+ root with review criteria tailored to the project's stack and patterns.
16
+
17
+ This is similar to how `/gsd:new-project` generates PROJECT.md — the review plan
18
+ is a project-level file that developers edit and commit, not agent infrastructure.
19
+ </objective>
20
+
21
+ <context>
22
+ $ARGUMENTS
23
+
24
+ **What gets created:**
25
+ - `./REVIEW-PLAN.md` — Review criteria checklist at project root (developer-editable, committed to repo)
26
+
27
+ **What already exists (installed by the agent):**
28
+ - `__CONFIG_DIR__/pr-review/index.html` — Interactive preview UI
29
+ - `__CONFIG_DIR__/pr-review/serve.js` — Local dev server for the preview
30
+ - `__CONFIG_DIR__/pr-review/templates/review-plan.md` — Base template
31
+ </context>
32
+
33
+ <process>
34
+
35
+ ## Step 1: Check Prerequisites
36
+
37
+ ```bash
38
+ gh --version 2>/dev/null || echo "gh not installed"
39
+ gh auth status 2>/dev/null || echo "gh not authenticated"
40
+ ```
41
+
42
+ If `gh` is not available, ask the user:
43
+ - "GitHub CLI is required for PR review. Would you like to install it?"
44
+ - Windows: `winget install GitHub.cli --source winget`
45
+ - macOS: `brew install gh`
46
+ - Then: `gh auth login`
47
+
48
+ ## Step 2: Detect PR Review Directory
49
+
50
+ Locate the pr-review runtime:
51
+ 1. `./__CONFIG_DIR__/pr-review/` (local)
52
+ 2. `$HOME/__CONFIG_DIR__/pr-review/` (global)
53
+
54
+ If neither exists, inform user to install: `npx pr-review-agent`
55
+
56
+ ## Step 3: Discover Project Context
57
+
58
+ Read these files to understand the project:
59
+ - `./CLAUDE.md` or equivalent project instructions
60
+ - Project skills directory (if any)
61
+ - `package.json` or equivalent — detect stack
62
+
63
+ ## Step 4: Generate REVIEW-PLAN.md
64
+
65
+ 1. Read the base template from `$PR_REVIEW_DIR/templates/review-plan.md`
66
+ 2. Ask the user about their project:
67
+ - Backend framework and patterns to enforce
68
+ - Frontend framework and patterns to enforce
69
+ - Key rules they want every PR checked against
70
+ - Any additional custom criteria
71
+ 3. Generate `./REVIEW-PLAN.md` at the project root, customizing the template
72
+ with the project's specific stack, patterns, and rules
73
+ 4. If project instructions or skills define architectural patterns, incorporate those
74
+ automatically into the "Project-Specific Rules" section
75
+
76
+ **Important:** Do NOT hardcode framework-specific rules in the template.
77
+ Generate them dynamically based on what the project actually uses.
78
+
79
+ ## Step 5: Confirm
80
+
81
+ Tell the user:
82
+ - Where REVIEW-PLAN.md was created
83
+ - That they can edit it anytime
84
+ - That the agent reads it before every `/pr-review:review` run
85
+ - How to start reviewing: `/pr-review:review <pr-url>`
86
+
87
+ </process>
88
+
89
+ <success_criteria>
90
+ - [ ] gh CLI verified or installation guided
91
+ - [ ] Project stack detected
92
+ - [ ] REVIEW-PLAN.md generated at project root with project-specific criteria
93
+ - [ ] User informed about next steps
94
+ </success_criteria>
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "pr-review-agent",
3
+ "version": "1.0.0",
4
+ "description": "AI-powered PR review agent for Claude Code, OpenCode, and other AI coding assistants. Analyzes pull requests against project-specific architectural patterns with an interactive preview UI.",
5
+ "bin": {
6
+ "pr-review-agent": "bin/install.js"
7
+ },
8
+ "files": [
9
+ "bin",
10
+ "commands",
11
+ "agents",
12
+ "template"
13
+ ],
14
+ "keywords": [
15
+ "claude-code",
16
+ "code-review",
17
+ "pull-request",
18
+ "ai-agent",
19
+ "opencode",
20
+ "pr-review",
21
+ "linter"
22
+ ],
23
+ "author": "TheRocketCodeMX",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/TheRocketCodeMX/pr-review-agent"
31
+ }
32
+ }