@_mustachio/ai-review-agent 0.1.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 +213 -0
- package/action.yml +57 -0
- package/bin/cli.js +161 -0
- package/dist/default.txt +41 -0
- package/dist/index.js +32559 -0
- package/dist/index.js.map +1 -0
- package/dist/licenses.txt +583 -0
- package/dist/sourcemap-register.js +1 -0
- package/package.json +43 -0
- package/prompts/default.txt +41 -0
- package/src/core/engine.js +422 -0
- package/src/core/prompt.js +22 -0
- package/src/core/review.js +130 -0
- package/src/index.js +67 -0
- package/src/platforms/bitbucket.js +198 -0
- package/src/platforms/github.js +120 -0
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# @_mustachio/ai-review-agent
|
|
2
|
+
|
|
3
|
+
AI-powered pull request code review agent. Works as a CLI tool, npm library, or GitHub Action. Supports GitHub and Bitbucket.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Inline comments** on specific lines of the PR diff
|
|
8
|
+
- **Hunk-aware context** — reads code surrounding changed lines, not just the diff
|
|
9
|
+
- **Diff chunking** — splits large PRs into parallel review chunks
|
|
10
|
+
- **Custom rules** — point at a file or directory of coding standards (SOLID, CLEAN, etc.)
|
|
11
|
+
- **Configurable prompt** — bring your own review prompt template
|
|
12
|
+
- **Multi-platform** — GitHub Actions and Bitbucket Pipelines
|
|
13
|
+
- **JSON output** — use `--output-only` for scripting and custom integrations
|
|
14
|
+
- **Prompt injection mitigation** — PR metadata wrapped in delimiters
|
|
15
|
+
- **Stale review cleanup** — dismisses/deletes previous AI reviews on new commits
|
|
16
|
+
- **Binary file detection** — skips images, compiled files, etc.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### npx (any CI or local)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx @_mustachio/ai-review-agent \
|
|
24
|
+
--platform github \
|
|
25
|
+
--token $GH_TOKEN \
|
|
26
|
+
--rules ./docs/standards/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### GitHub Actions
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
name: AI Code Review
|
|
33
|
+
|
|
34
|
+
on:
|
|
35
|
+
pull_request:
|
|
36
|
+
types: [opened, synchronize, reopened]
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
review:
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
permissions:
|
|
42
|
+
pull-requests: write
|
|
43
|
+
contents: read
|
|
44
|
+
env:
|
|
45
|
+
GH_TOKEN: ${{ github.token }}
|
|
46
|
+
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v4
|
|
49
|
+
with:
|
|
50
|
+
fetch-depth: 0
|
|
51
|
+
|
|
52
|
+
- uses: actions/setup-node@v4
|
|
53
|
+
with:
|
|
54
|
+
node-version: '24'
|
|
55
|
+
|
|
56
|
+
- uses: ./packages/ai-review-agent
|
|
57
|
+
with:
|
|
58
|
+
severity-threshold: 'blocking'
|
|
59
|
+
rules: docs/standards/standards.md
|
|
60
|
+
opencode-config: ${{ github.workspace }}/.github/opencode.json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
When published, replace `uses: ./packages/ai-review-agent` with:
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
- uses: the-human-mustachio/ai-review-agent@v1
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Bitbucket Pipelines
|
|
70
|
+
|
|
71
|
+
```yaml
|
|
72
|
+
pipelines:
|
|
73
|
+
pull-requests:
|
|
74
|
+
'**':
|
|
75
|
+
- step:
|
|
76
|
+
name: AI Code Review
|
|
77
|
+
script:
|
|
78
|
+
- npx @_mustachio/ai-review-agent --rules ./docs/standards/ --severity-threshold blocking
|
|
79
|
+
# BB_TOKEN must be set as a secured repository variable
|
|
80
|
+
# with pullrequest:write and repository:write scopes
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Local / JSON Output
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Just get the review as JSON (no comments posted)
|
|
87
|
+
npx @_mustachio/ai-review-agent \
|
|
88
|
+
--output-only \
|
|
89
|
+
--base-branch main \
|
|
90
|
+
--rules ./standards/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## CLI Options
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
PLATFORMS:
|
|
97
|
+
--platform <name> github, bitbucket (auto-detected if omitted)
|
|
98
|
+
--token <token> API token (or set GH_TOKEN / BB_TOKEN env var)
|
|
99
|
+
|
|
100
|
+
PR METADATA (auto-detected in CI):
|
|
101
|
+
--pr-number <n> PR number
|
|
102
|
+
--pr-title <title> PR title
|
|
103
|
+
--pr-author <author> PR author
|
|
104
|
+
--pr-body <body> PR description
|
|
105
|
+
--base-branch <branch> Base branch (default: main)
|
|
106
|
+
|
|
107
|
+
REVIEW OPTIONS:
|
|
108
|
+
--prompt <path> Custom prompt template
|
|
109
|
+
--rules <path> Rules file or directory
|
|
110
|
+
--exclude <patterns> Comma-separated exclude globs
|
|
111
|
+
--max-diff-size <n> Max diff chars per chunk (default: 100000)
|
|
112
|
+
--severity-threshold <s> Fail threshold: blocking, warning, info
|
|
113
|
+
--opencode-version <v> Pinned opencode-ai version (default: 0.2.21)
|
|
114
|
+
--opencode-config <path> OpenCode config file
|
|
115
|
+
--api-key <key> AI provider API key
|
|
116
|
+
--post-review <bool> Post approve/request-changes (default: true)
|
|
117
|
+
|
|
118
|
+
OUTPUT:
|
|
119
|
+
--output-only Print JSON to stdout, exit 0 (approved) or 1 (rejected)
|
|
120
|
+
--help Show help
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## GitHub Action Inputs
|
|
124
|
+
|
|
125
|
+
| Input | Description | Default |
|
|
126
|
+
|-------|-------------|---------|
|
|
127
|
+
| `api-key` | AI provider API key (optional if set in env) | |
|
|
128
|
+
| `severity-threshold` | Fail threshold: `blocking`, `warning`, `info` | `blocking` |
|
|
129
|
+
| `prompt` | Path to custom prompt template | built-in |
|
|
130
|
+
| `post-review` | Post approve/request-changes review | `true` |
|
|
131
|
+
| `max-diff-size` | Max diff size per chunk (chars) | `100000` |
|
|
132
|
+
| `exclude-patterns` | Comma-separated exclude globs | |
|
|
133
|
+
| `opencode-config` | Path to OpenCode config file | |
|
|
134
|
+
| `rules` | Path to rules file or directory | |
|
|
135
|
+
| `opencode-version` | Pinned opencode-ai version | `0.2.21` |
|
|
136
|
+
|
|
137
|
+
## Custom Rules
|
|
138
|
+
|
|
139
|
+
Point `--rules` at a single file or a directory:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Single file
|
|
143
|
+
--rules docs/standards/standards.md
|
|
144
|
+
|
|
145
|
+
# Directory (all files concatenated with headers)
|
|
146
|
+
--rules .github/review-rules/
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Example rules directory:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
.github/review-rules/
|
|
153
|
+
SOLID.md
|
|
154
|
+
CLEAN.md
|
|
155
|
+
security.md
|
|
156
|
+
testing.md
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Each file's content is injected into the review prompt as evaluation criteria.
|
|
160
|
+
|
|
161
|
+
## Output Format
|
|
162
|
+
|
|
163
|
+
The review JSON (from `--output-only` or the internal pipeline):
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"approve": false,
|
|
168
|
+
"summary": "PR introduces a clean architecture violation.",
|
|
169
|
+
"issues": [
|
|
170
|
+
{
|
|
171
|
+
"severity": "blocking",
|
|
172
|
+
"message": "Core imports from infra — violates dependency rule",
|
|
173
|
+
"file": "packages/core/src/organization/organization.usecase.ts",
|
|
174
|
+
"line": 3,
|
|
175
|
+
"endLine": 4
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"recommendation": "Remove the infra import and use a repository port."
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Platform Differences
|
|
183
|
+
|
|
184
|
+
| Capability | GitHub | Bitbucket |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| Inline comments | PR review API | Individual comment API |
|
|
187
|
+
| Block merge | `REQUEST_CHANGES` review | Build status `FAILED` |
|
|
188
|
+
| Allow merge | `APPROVE` review | Build status `SUCCESSFUL` + approve |
|
|
189
|
+
| Stale cleanup | Dismiss previous reviews | Delete previous comments |
|
|
190
|
+
| Auth token | Automatic `GITHUB_TOKEN` | Manual `BB_TOKEN` (secured variable) |
|
|
191
|
+
| PR metadata | From event payload | Fetched via API |
|
|
192
|
+
|
|
193
|
+
## Library Usage
|
|
194
|
+
|
|
195
|
+
```js
|
|
196
|
+
const { runFullReview } = require('@_mustachio/ai-review-agent');
|
|
197
|
+
|
|
198
|
+
const review = await runFullReview({
|
|
199
|
+
baseBranch: 'main',
|
|
200
|
+
prTitle: 'Add feature X',
|
|
201
|
+
prAuthor: 'dev',
|
|
202
|
+
prBody: 'Description here',
|
|
203
|
+
prNumber: 42,
|
|
204
|
+
rulesPath: './standards.md',
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
console.log(review.approve); // true/false
|
|
208
|
+
console.log(review.issues); // [{severity, message, file, line}]
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
MIT
|
package/action.yml
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: 'AI Code Review'
|
|
2
|
+
description: 'AI-powered PR code review using OpenCode'
|
|
3
|
+
branding:
|
|
4
|
+
icon: 'eye'
|
|
5
|
+
color: 'purple'
|
|
6
|
+
|
|
7
|
+
inputs:
|
|
8
|
+
api-key:
|
|
9
|
+
description: 'API key for the AI provider (e.g. Anthropic, OpenAI). Optional if already set in environment.'
|
|
10
|
+
required: false
|
|
11
|
+
default: ''
|
|
12
|
+
severity-threshold:
|
|
13
|
+
description: 'Minimum severity to block merge (blocking, warning, info)'
|
|
14
|
+
required: false
|
|
15
|
+
default: 'blocking'
|
|
16
|
+
prompt:
|
|
17
|
+
description: 'Path to a custom prompt template file'
|
|
18
|
+
required: false
|
|
19
|
+
default: ''
|
|
20
|
+
post-review:
|
|
21
|
+
description: 'Whether to post a PR review (approve/request-changes) in addition to a comment'
|
|
22
|
+
required: false
|
|
23
|
+
default: 'true'
|
|
24
|
+
max-diff-size:
|
|
25
|
+
description: 'Maximum diff size in characters before truncation (default: 100000)'
|
|
26
|
+
required: false
|
|
27
|
+
default: '100000'
|
|
28
|
+
exclude-patterns:
|
|
29
|
+
description: 'Comma-separated glob patterns of files to exclude from the diff (e.g. "*.lock,dist/**")'
|
|
30
|
+
required: false
|
|
31
|
+
default: ''
|
|
32
|
+
opencode-config:
|
|
33
|
+
description: 'Path to OpenCode config file'
|
|
34
|
+
required: false
|
|
35
|
+
default: ''
|
|
36
|
+
rules:
|
|
37
|
+
description: 'Path to a file or directory of review rules. If a directory, all files are loaded and concatenated. Rules are injected into the prompt as evaluation criteria.'
|
|
38
|
+
required: false
|
|
39
|
+
default: ''
|
|
40
|
+
opencode-version:
|
|
41
|
+
description: 'Pinned version of opencode-ai to install (default: 0.2.21)'
|
|
42
|
+
required: false
|
|
43
|
+
default: '0.2.21'
|
|
44
|
+
|
|
45
|
+
outputs:
|
|
46
|
+
approved:
|
|
47
|
+
description: 'Whether the review approved the PR (true/false)'
|
|
48
|
+
summary:
|
|
49
|
+
description: 'Review summary text'
|
|
50
|
+
issues-count:
|
|
51
|
+
description: 'Total number of issues found'
|
|
52
|
+
blocking-count:
|
|
53
|
+
description: 'Number of blocking issues found'
|
|
54
|
+
|
|
55
|
+
runs:
|
|
56
|
+
using: 'node24'
|
|
57
|
+
main: 'dist/index.js'
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { runFullReview, shouldFailForThreshold, countBySeverity } = require('../src/core/engine');
|
|
4
|
+
const githubPlatform = require('../src/platforms/github');
|
|
5
|
+
const bitbucketPlatform = require('../src/platforms/bitbucket');
|
|
6
|
+
|
|
7
|
+
const PLATFORMS = {
|
|
8
|
+
github: githubPlatform,
|
|
9
|
+
bitbucket: bitbucketPlatform,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
const args = parseArgs(process.argv.slice(2));
|
|
14
|
+
|
|
15
|
+
if (args.help) {
|
|
16
|
+
printUsage();
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const log = console.log;
|
|
21
|
+
|
|
22
|
+
// Detect or use specified platform
|
|
23
|
+
let platformName = args.platform;
|
|
24
|
+
if (!platformName && !args['output-only']) {
|
|
25
|
+
for (const [name, platform] of Object.entries(PLATFORMS)) {
|
|
26
|
+
if (platform.detect()) {
|
|
27
|
+
platformName = name;
|
|
28
|
+
log(`Auto-detected platform: ${name}`);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Get PR metadata — from platform or CLI args
|
|
35
|
+
let prMeta;
|
|
36
|
+
if (platformName && !args['output-only']) {
|
|
37
|
+
const platform = PLATFORMS[platformName];
|
|
38
|
+
if (!platform) {
|
|
39
|
+
console.error(`Unknown platform: ${platformName}. Supported: ${Object.keys(PLATFORMS).join(', ')}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const token = args.token || process.env.GH_TOKEN || process.env.GITHUB_TOKEN || process.env.BB_TOKEN || process.env.BITBUCKET_TOKEN;
|
|
43
|
+
prMeta = await platform.getPrMetadata(token);
|
|
44
|
+
} else {
|
|
45
|
+
// Manual mode — require CLI args
|
|
46
|
+
prMeta = {
|
|
47
|
+
prNumber: args['pr-number'] || '0',
|
|
48
|
+
prTitle: args['pr-title'] || '',
|
|
49
|
+
prAuthor: args['pr-author'] || '',
|
|
50
|
+
prBody: args['pr-body'] || '',
|
|
51
|
+
baseBranch: args['base-branch'] || 'main',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Run the review
|
|
56
|
+
const review = await runFullReview({
|
|
57
|
+
baseBranch: prMeta.baseBranch,
|
|
58
|
+
prTitle: prMeta.prTitle,
|
|
59
|
+
prAuthor: prMeta.prAuthor,
|
|
60
|
+
prBody: prMeta.prBody,
|
|
61
|
+
prNumber: prMeta.prNumber,
|
|
62
|
+
promptPath: args.prompt || undefined,
|
|
63
|
+
rulesPath: args.rules || undefined,
|
|
64
|
+
excludePatterns: args.exclude || '',
|
|
65
|
+
maxDiffSize: parseInt(args['max-diff-size'] || '100000', 10),
|
|
66
|
+
opencodeVersion: args['opencode-version'] || undefined,
|
|
67
|
+
opencodeConfig: args['opencode-config'] || undefined,
|
|
68
|
+
apiKey: args['api-key'] || undefined,
|
|
69
|
+
log,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Output JSON if requested
|
|
73
|
+
if (args['output-only']) {
|
|
74
|
+
console.log(JSON.stringify(review, null, 2));
|
|
75
|
+
process.exit(review.approve ? 0 : 1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Post to platform
|
|
79
|
+
const token = args.token || process.env.GH_TOKEN || process.env.GITHUB_TOKEN || process.env.BB_TOKEN || process.env.BITBUCKET_TOKEN;
|
|
80
|
+
if (!token) {
|
|
81
|
+
console.error('Error: No token provided. Use --token or set GH_TOKEN / BB_TOKEN env var.');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const platform = PLATFORMS[platformName];
|
|
86
|
+
await platform.postReview(review, {
|
|
87
|
+
prNumber: prMeta.prNumber,
|
|
88
|
+
token,
|
|
89
|
+
postReview: args['post-review'] !== 'false',
|
|
90
|
+
log,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Check threshold
|
|
94
|
+
const threshold = args['severity-threshold'] || 'blocking';
|
|
95
|
+
const fail = shouldFailForThreshold(review, threshold);
|
|
96
|
+
if (fail) {
|
|
97
|
+
console.error(fail);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const blockingCount = countBySeverity(review.issues, 'blocking');
|
|
102
|
+
log(`Review complete. Approved: ${review.approve}. Issues: ${review.issues.length} (${blockingCount} blocking).`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parseArgs(argv) {
|
|
106
|
+
const args = {};
|
|
107
|
+
for (let i = 0; i < argv.length; i++) {
|
|
108
|
+
const arg = argv[i];
|
|
109
|
+
if (arg.startsWith('--')) {
|
|
110
|
+
const key = arg.slice(2);
|
|
111
|
+
const next = argv[i + 1];
|
|
112
|
+
if (!next || next.startsWith('--')) {
|
|
113
|
+
args[key] = true;
|
|
114
|
+
} else {
|
|
115
|
+
args[key] = next;
|
|
116
|
+
i++;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return args;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function printUsage() {
|
|
124
|
+
console.log(`
|
|
125
|
+
ai-review-agent - AI-powered code review for pull requests
|
|
126
|
+
|
|
127
|
+
USAGE:
|
|
128
|
+
ai-review-agent [options]
|
|
129
|
+
|
|
130
|
+
PLATFORMS:
|
|
131
|
+
--platform <name> Platform to use: github, bitbucket (auto-detected if omitted)
|
|
132
|
+
--token <token> API token for posting reviews (or set GH_TOKEN / BB_TOKEN env var)
|
|
133
|
+
|
|
134
|
+
PR METADATA (auto-detected in CI, required for --output-only):
|
|
135
|
+
--pr-number <n> PR number
|
|
136
|
+
--pr-title <title> PR title
|
|
137
|
+
--pr-author <author> PR author
|
|
138
|
+
--pr-body <body> PR description
|
|
139
|
+
--base-branch <branch> Base branch (default: main)
|
|
140
|
+
|
|
141
|
+
REVIEW OPTIONS:
|
|
142
|
+
--prompt <path> Path to custom prompt template
|
|
143
|
+
--rules <path> Path to rules file or directory
|
|
144
|
+
--exclude <patterns> Comma-separated glob patterns to exclude
|
|
145
|
+
--max-diff-size <n> Max diff size in chars (default: 100000)
|
|
146
|
+
--severity-threshold <s> Fail threshold: blocking, warning, info (default: blocking)
|
|
147
|
+
--opencode-version <v> Pinned opencode-ai version
|
|
148
|
+
--opencode-config <path> Path to OpenCode config file
|
|
149
|
+
--api-key <key> API key for AI provider
|
|
150
|
+
--post-review <bool> Post approve/request-changes review (default: true)
|
|
151
|
+
|
|
152
|
+
OUTPUT:
|
|
153
|
+
--output-only Print JSON review to stdout and exit (no platform posting)
|
|
154
|
+
--help Show this help
|
|
155
|
+
`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
main().catch((err) => {
|
|
159
|
+
console.error(`Fatal: ${err.message}`);
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|
package/dist/default.txt
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
You are an expert code reviewer. All context is provided below — do NOT use any tools, do NOT read any files, do NOT explore the codebase.
|
|
2
|
+
|
|
3
|
+
Respond with ONLY valid JSON (no markdown, no code blocks, no extra text).
|
|
4
|
+
|
|
5
|
+
Schema:
|
|
6
|
+
{
|
|
7
|
+
"approve": boolean,
|
|
8
|
+
"summary": "1-2 sentence overview",
|
|
9
|
+
"issues": [
|
|
10
|
+
{
|
|
11
|
+
"severity": "blocking" | "warning" | "info",
|
|
12
|
+
"message": "concise description under 120 chars",
|
|
13
|
+
"file": "path/to/file.ts",
|
|
14
|
+
"line": 42,
|
|
15
|
+
"endLine": 45
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"recommendation": "brief next steps"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Rules:
|
|
22
|
+
- approve=true only if NO blocking issues
|
|
23
|
+
- blocking = bugs, security issues, breaking changes
|
|
24
|
+
- warning = code quality, missing tests, improvements
|
|
25
|
+
- info = minor suggestions, style nits
|
|
26
|
+
- "file" must be an exact path from the diff header (e.g. the "b/" path)
|
|
27
|
+
- "line" must be a line number from the diff's @@ hunk headers (the "+" side)
|
|
28
|
+
- "endLine" is optional, only include if the issue spans multiple lines
|
|
29
|
+
- Maximum 10 issues total
|
|
30
|
+
- Some files (lockfiles, build artifacts, the review action itself) are intentionally excluded. Do NOT flag missing files unless the diff has broken imports.
|
|
31
|
+
|
|
32
|
+
{{RULES}}
|
|
33
|
+
|
|
34
|
+
PR Title: {{PR_TITLE}}
|
|
35
|
+
Author: {{PR_AUTHOR}}
|
|
36
|
+
Description: {{PR_BODY}}
|
|
37
|
+
|
|
38
|
+
{{CONTEXT}}
|
|
39
|
+
|
|
40
|
+
Diff:
|
|
41
|
+
{{DIFF}}
|