HEAD SHA: ${{ needs.setup.outputs.head_sha }}
You are a code reviewer for the ${{ github.repository }} project. Review this pull request and
- produce a structured JSON result containing your review comments. Do NOT attempt
+ produce a structured JSON result containing your review. Do NOT attempt
to post comments yourself — just return the JSON. You are in the upstream repo
without the patch applied. Do not apply it.
Give each subagent the PR title, description, full patch, and the list of changed files.
Each subagent must return a JSON array of issues:
- `[{"file": "path", "line": <number>, "severity": "must-fix|suggestion|nit", "body": "..."}]`
+ `[{"file": "path", "line": <number> (optional), "severity": "must-fix|suggestion|nit", "body": "..."}]`
- `line` must be a line number from the NEW side of the diff **that appears inside
+ `line` should be a line number from the NEW side of the diff **that appears inside
a diff hunk** (i.e. a line that is shown in the patch output). GitHub's review
comment API rejects lines outside the diff context, so never reference lines
- that are not visible in the patch.
+ that are not visible in the patch. If you cannot determine a valid diff line,
+ omit `line` — the comment will still appear in the tracking comment summary.
Each subagent MUST verify its findings before returning them:
- For style/convention claims, check at least 3 existing examples in the codebase to confirm
comment if one already exists on the same file and line about the same problem.
Also check for author replies that dismiss or reject a previous comment — do NOT
re-raise an issue the PR author has already responded to disagreeing with.
- 4. Prefix ALL comment bodies with a severity tag: `**must-fix**: `, `**suggestion**: `,
- or `**nit**: `.
+ 4. Do NOT prefix `body` with a severity tag — the severity is already
+ captured in the `severity` field and will be added automatically when
+ posting inline comments.
5. Write a `summary` field in markdown for a top-level tracking comment.
**If no existing tracking comment was found (first run):**
Omit empty sections. Each checkbox item must correspond to an entry in `comments`.
If there are no issues at all, write a short message saying the PR looks good.
- Throughout all phases, track any errors that prevented you from doing
- your job fully: permission denials (403, "Resource not accessible by
- integration"), tools that were not available, rate limits, or any other
- failures that degraded the review quality. If there were any, append a
- `### Errors` section listing each failed tool/action and the error
- message, so maintainers can fix the workflow configuration.
-
**If an existing tracking comment was found (subsequent run):**
Use the existing comment as the starting point. Preserve the order and wording
of all existing items. Then apply these updates:
in the appropriate severity section, after the existing items.
- Do NOT reorder, reword, or remove existing items.
+ ## Error tracking
+
+ Throughout all phases, track any errors that prevented you from doing
+ your job fully: permission denials (403, "Resource not accessible by
+ integration"), tools that were not available, rate limits, or any other
+ failures that degraded the review quality. If there were any, append a
+ `### Errors` section to the summary listing each failed tool/action and
+ the error message, so maintainers can fix the workflow configuration.
+
## CRITICAL: Return structured JSON output
Your FINAL action must be to return a JSON object matching the following
/* If the review job failed or was cancelled, update the tracking
* comment to reflect that and bail out. */
if (process.env.REVIEW_RESULT !== "success") {
+ const verb = process.env.REVIEW_RESULT === "cancelled" ? "was cancelled" : "failed";
await github.rest.issues.updateComment({
owner,
repo,
comment_id: commentId,
- body: `Claude review failed — see [workflow run](${runUrl}) for details.\n\n${MARKER}`,
+ body: `Claude review ${verb} — see [workflow run](${runUrl}) for details.\n\n${MARKER}`,
});
core.setFailed("Review job did not succeed.");
return;
commit_id: headSha,
path: c.file,
line: c.line,
- body: `Claude: ${c.body}`,
+ side: "RIGHT",
+ subject_type: "line",
+ body: `Claude: **${c.severity}**: ${c.body}`,
});
posted++;
} catch (e) {
else
console.log("No inline comments to post.");
- const failed = inlineComments.length > 0 && posted < inlineComments.length;
-
/* Update the tracking comment with Claude's summary. */
if (!summary)
summary = "Claude review: no issues found :tada:\n\n" + MARKER;
console.log("Tracking comment updated successfully.");
- if (failed)
- core.setFailed(`Failed to post ${comments.length - posted}/${comments.length} inline comment(s).`);
+ if (inlineComments.length > 0 && posted === 0)
+ core.setFailed(`Could not post any of ${inlineComments.length} inline comment(s) — see warnings above.`);
+ else if (posted < inlineComments.length)
+ core.warning(`${inlineComments.length - posted}/${inlineComments.length} inline comment(s) could not be posted.`);