feat(review): PR-level collapsible metadata + emoji-tagged inline comments
PR-level comment layout (per operator's format guide):
* Summary of Changes — 2-4 bullets, sourced from the agent's new
`summary_changes` JSON field. Falls back to splitting the prose
`summary` if the list is missing.
* Key Risks & Concerns — bullets from the new `risks` JSON field.
* Findings Overview — Markdown table covering every finding
(severity emoji / location / one-line problem). Both anchored and
unanchored findings appear here so the table is the single scan point.
* Unanchored Notes — bullets with severity + fix + Markdown-linked ref,
for findings with no post-change line to anchor.
* AI Usage & Run Details — wrapped in a <details>/<summary> collapsible
so the body stays scannable. Cost line stays inside it.
Inline comment shape:
* Severity badge: 🔴 [HIGH] / 🟡 [MEDIUM] / 🔵 [LOW] / ⚪ [INFO].
Unknown severities fall back to � [INFO].
* 1-2 short paragraphs of problem; **Fix:** label for the fix line.
* Standard ```suggestion fence for replacement code (Gitea/Forgejo
apply-on-click). Language-tagged fences are no longer used for
single-file diffs.
* Reference as a Markdown hyperlink, visible label truncated to
<=60 chars; the underlying URL is preserved verbatim.
* NO per-comment 🪙 token attribution. All telemetry stays in the
collapsible block on the PR-level comment.
Agent prompt updated to emit `summary_changes` and `risks` in the JSON
output (backward-compatible — older outputs missing them still parse;
they fall back to splitting the prose `summary`).
Tests: 15 new (severity emoji mapping, reference truncation, findings
table escaping, collapsible usage rendering, summary_changes+risks
layout). Existing tests updated for the new structure.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -142,12 +142,18 @@ containing STRICT JSON, nothing else after it:
|
||||
```json
|
||||
{
|
||||
"summary": "One-paragraph overview of the change and its risk.",
|
||||
"summary_changes": [
|
||||
"2–4 short bullets explaining what the PR introduces or modifies"
|
||||
],
|
||||
"risks": [
|
||||
"Bullets detailing potential bugs, edge cases, lifecycle issues, or performance risks found across the diff"
|
||||
],
|
||||
"findings": [
|
||||
{
|
||||
"severity": "critical|high|medium|low",
|
||||
"severity": "critical|high|medium|low|info|nit",
|
||||
"path": "path exactly as in the diff `+++ b/` side",
|
||||
"line": 12,
|
||||
"problem": "one line: what is wrong",
|
||||
"problem": "1–2 short paragraphs: what is wrong and why it fails",
|
||||
"fix": "one line: how to fix it",
|
||||
"suggestion": "exact replacement lines for that location, indented as in the file, or \"\" if no safe replacement",
|
||||
"reference": "https://... or \"\""
|
||||
@@ -157,11 +163,16 @@ containing STRICT JSON, nothing else after it:
|
||||
```
|
||||
|
||||
Rules:
|
||||
- `summary_changes` (2–4 bullets) goes into the **Summary of Changes** section.
|
||||
`risks` (bullets) goes into **Key Risks & Concerns**. Both are required;
|
||||
empty arrays are fine when nothing applies.
|
||||
- `suggestion` is the literal new code that replaces the flagged line(s). Minimal —
|
||||
just the changed lines, indented as they'd appear in the file. Empty string `""`
|
||||
when no safe textual replacement exists (e.g. missing test, architectural note).
|
||||
- `problem` is 1–2 short paragraphs (the inline comment shows it verbatim).
|
||||
Lead with the consequence (security / data loss / perf / etc.), then the cause.
|
||||
- At most ~15 findings, highest severity first.
|
||||
- If the diff is clean, output `{"summary":"...","findings":[]}`.
|
||||
- If the diff is clean, output `{"summary":"...","summary_changes":[],"risks":[],"findings":[]}`.
|
||||
- Do NOT repeat anything in `prior_reviews`.
|
||||
- The JSON block must be the LAST thing in your message — the Python shell parses
|
||||
the last ```json fenced block from your output. If you run out of context/steps
|
||||
|
||||
Reference in New Issue
Block a user