Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .agents/skills/github-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ license: Apache-2.0

Multi-step workflows (pre-merge checklist, debug CI, release, fetch and reply to PR comments): [references/workflows.md](./references/workflows.md).

## Pull Request Review Comments

Before drafting or posting new PR review findings, read and follow
[references/review-comments.md](./references/review-comments.md). It defines the
finding format, classification vocabulary, human-approval and attribution rules,
and posting completion criteria.

## Scripts

**PR comments: use the CLI helper** (PEP 723 + Typer + PyGithub + Pydantic). Run from repo root or from this skill directory. No `gh` binary required for fetch/reply (uses GitHub API with `GITHUB_TOKEN` or `--token`; optional fallback: `gh auth token`). If `GITHUB_TOKEN` is not set, run `export GITHUB_TOKEN=$(gh auth token)` before invoking the helper (or pass `--token`). Requires network; in Agent use `required_permissions: ["all"]` per [sandbox behavior](https://cursor.com/docs/agent/tools/terminal).
Expand All @@ -18,7 +25,8 @@ Path from repo root: `.agents/skills/github-cli/scripts/gh_pr_helper.py` (or `sc

| Command | Description |
|---------|-------------|
| `uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- comments [PR_NUMBER]` | Fetch all PR comments (inline + top-level). Single JSON object to stdout: `{ "pr_number", "repo", "inline": [...], "top_level": [...] }`. Omit PR to use current branch's open PR. |
| `uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- comments [PR_NUMBER]` | Fetch all PR discussion (inline comments + submitted review bodies + top-level comments). Single JSON object to stdout: `{ "pr_number", "repo", "inline": [...], "reviews": [...], "top_level": [...] }`. Omit PR to use current branch's open PR. |
| `uv run --script ... -- submit-review <PR_NUMBER> --review-file path/to/review.json` | Submit one approved inline review, abort if the PR head changed, and return the review URL plus each inline comment URL. |
| `uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- reply <COMMENT_ID> "Reply body"` | Post a reply to an inline review comment. |
| `uv run --script ... -- reply <COMMENT_ID> --reply-file -` | Reply body from stdin. |
| `uv run --script ... -- reply <COMMENT_ID> --reply-file path/to/body.md` | Reply body from file. |
Expand Down Expand Up @@ -90,6 +98,9 @@ EOF
# Inline code review comments on a PR
gh api repos/NVIDIA-NeMo/Safe-Synthesizer/pulls/<number>/comments

# Submitted reviews and their summary bodies
gh api repos/NVIDIA-NeMo/Safe-Synthesizer/pulls/<number>/reviews

# Issue discussion thread
gh api repos/NVIDIA-NeMo/Safe-Synthesizer/issues/<number>/comments

Expand Down
176 changes: 176 additions & 0 deletions .agents/skills/github-cli/references/review-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<!-- SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

# Agent-Assisted Pull Request Reviews

Use this contract when drafting or posting new PR review findings. Replies in an
existing thread follow the reply workflow in `workflows.md`.

The finding-header shape and classification style are based on CodeRabbit's
review-comment template. Expected handling, exact approval, and agent
attribution are Safe Synthesizer additions.

## Contents

- [Workflow](#workflow)
- [Submit an Approved Review](#submit-an-approved-review)
- [Finding Format](#finding-format)
- [Area](#area)
- [Impact](#impact)
- [Effort/Value](#effortvalue)
- [Expected Handling](#expected-handling)
- [Attribution and Approval](#attribution-and-approval)

## Workflow

1. Pin the PR head and verify every finding against that revision. Tie each
finding to changed code and a commentable diff line.
2. Read existing inline comments, submitted review bodies, and top-level
comments. Remove duplicate findings and account for decisions already
recorded in the discussion.
3. Classify each finding by area, impact, effort/value, and expected handling.
Keep these dimensions independent: a critical issue can be a quick win, and
a minor issue can be a heavy lift.
4. Draft the exact comment text and line target for human review. Mark the draft
as unapproved and keep it off GitHub.
5. Obtain explicit approval of the exact comments. A material text or line-target
change requires approval again.
6. Recheck the PR head immediately before posting. Re-verify findings affected by
new commits and reapprove materially revised comments.
7. Post only the approved artifact with the helper below. Return the review URL
and direct links to every posted comment.

Completion criterion: every posted finding is current, non-duplicative,
classified, explicitly approved, truthfully attributed, and linked in the
handoff.

## Submit an Approved Review

Save the exact approved review as JSON. `head_sha` must be the full 40-character
SHA verified during review. Each comment targets a line in that revision's diff:

```json
{
"head_sha": "0000000000000000000000000000000000000000",
"body": "Review summary.\n\n_Agent-assisted review: generated by @reviewer's Agent and approved for posting by @reviewer._",
"comments": [
{
"path": "src/example.py",
"line": 42,
"side": "RIGHT",
"body": "🎯 _Functional Correctness_ | 🟡 _Minor_ | ⚡ _Quick win_ | 🤖 _Agent-fix candidate_\n\n**Reject the invalid value here.**\n\nExplain the trigger, impact, and smallest practical fix."
}
]
}
```

For a multiline target, also set `start_line` and `start_side`. Then submit all
approved findings as one non-approving `COMMENT` review:

```bash
uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- \
submit-review <PR_NUMBER> --review-file path/to/approved-review.json
```

The helper validates the artifact before making a network request, compares
`head_sha` with the live PR head, and aborts on a mismatch. On success it emits
one JSON object containing `review_url` and a direct `html_url` for each entry in
`comments`. Never edit the approved artifact between approval and submission.

## Finding Format

Use this shape:

```markdown
🎯 _Functional Correctness_ | 🟡 _Minor_ | ⚡ _Quick win_ | 🤖 _Agent-fix candidate_

**Reject a blank `replacement_plan` string here.**

An empty or whitespace-only string passes this validator. `resolve_plan` then
reports a generic plan-source error instead of identifying the invalid field.
Reject blank strings during config validation so the failure is precise.
```

After the metadata, write:

1. A short, imperative title.
2. One compact explanation containing the triggering condition, observable
impact, and smallest practical fix.
3. An optional proposed fix or committable suggestion only when the change is
localized and unambiguous.

Use impact and expected handling instead of calling a finding a "blocker."

## Area

Choose exactly one:

- `🎯 Security & Privacy` — exploitation, sensitive-data exposure, permissions,
authentication, or privacy guarantees.
- `🎯 Data Integrity & Integration` — corruption, schema/API contract mismatch,
migrations, or cross-system consistency.
- `🎯 Performance & Scalability` — latency, throughput, memory, algorithmic cost,
or load-dependent degradation.
- `🎯 Stability & Availability` — crashes, hangs, deadlocks, resource leaks, or
operational failure.
- `🎯 Functional Correctness` — behavior produces the wrong result or violates a
functional contract.
- `🎯 Maintainability & Code Quality` — structure creates concrete future change
risk without a current functional failure.

## Impact

Choose exactly one:

- `🔴 Critical` — security/privacy exposure, data loss, contamination, or a
broken release or core pipeline.
- `🟠 Major` — materially incorrect behavior, a broken public contract, invalid
configuration behavior, or a likely production failure.
- `🟡 Minor` — localized incorrect behavior or missing focused regression
protection.
- `🔵 Trivial` — negligible behavioral impact; normally suppress.
- `⚪ Info` — context without required action; normally suppress.

## Effort/Value

Choose exactly one. This is a cost/value judgment, not a linear size estimate:

- `⚡ Quick win` — a worthwhile, localized fix.
- `🏗️ Heavy lift` — worthwhile but requires substantial or cross-module work.
- `⚖️ Poor tradeoff` — implementation cost is disproportionate to the impact.
- `🫧 Low value` — little practical benefit; normally suppress.

## Expected Handling

Choose exactly one:

- `🤖 Agent-fix candidate` — localized and unambiguous enough for an agent to
implement and test. The author verifies the patch.
- `👤 Author review required` — the author must evaluate the finding before
merge; an agent may assist but must not resolve the judgment autonomously.
- `🧭 Human decision required` — settle a product, contract, or architecture
decision before an agent implements a fix.
- `📌 Follow-up acceptable` — the finding may be deferred after acknowledgment.

`Agent-fix candidate` classifies suitability; it does not authorize repository
changes. Apply it automatically only inside a workflow that explicitly authorizes
review-fix iteration. Otherwise wait for implementation authorization.

## Attribution and Approval

For several inline comments submitted as one review, end the review summary with:

```markdown
_Agent-assisted review: generated by @<reviewer>'s Agent and approved for posting by @<reviewer>._
```

For comments posted individually without a shared summary, end each comment with:

```markdown
_Generated by @<reviewer>'s Agent; approved for posting by @<reviewer>._
```

Use this attribution only after the named reviewer approves the exact text and
line target for posting. Report full-diff human review separately in the PR
template. Before posting approval, use draft-only language and make no
attribution claim on GitHub.
19 changes: 16 additions & 3 deletions .agents/skills/github-cli/references/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ git stash pop

## Fetch and Address Review Comments

For "address PR comments" or "pull comments from PR N", use the **CLI helper** first. It returns a single JSON object (inline + top-level comments) and can post replies without the `gh` binary (GitHub API + `GITHUB_TOKEN`).
For "address PR comments" or "pull comments from PR N", use the **CLI helper** first. It returns a single JSON object covering inline comments, submitted review bodies, and top-level comments. It can also submit approved reviews and post replies without the `gh` binary (GitHub API + `GITHUB_TOKEN`).

### Use the CLI helper (recommended)

Expand All @@ -234,9 +234,13 @@ From repo root (or skill dir). If `GITHUB_TOKEN` is not set, set it first: `expo
# Optional: ensure token for API (helper uses GITHUB_TOKEN or gh auth token)
export GITHUB_TOKEN=$(gh auth token)

# Fetch all comments (single JSON: pr_number, repo, inline[], top_level[])
# Fetch all discussion (single JSON: pr_number, repo, inline[], reviews[], top_level[])
uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- comments <PR_NUMBER>

# Submit an exact, approved, head-pinned review artifact and receive direct URLs
uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- \
submit-review <PR_NUMBER> --review-file path/to/approved-review.json

# Reply to an inline review comment (comment_id from the inline[].id in the JSON above)
uv run --script .agents/skills/github-cli/scripts/gh_pr_helper.py -- reply <COMMENT_ID> "Fixed in beefcafe"
# Or from stdin:
Expand All @@ -253,6 +257,12 @@ Fixed in commit `beefcafe`. The logic now uses the helper and the test was updat

Workflow: you can draft the reply with the user in a file (e.g. `reply.md` or `pr-171-reply.md`), edit it until they’re happy, then run `reply <COMMENT_ID> --reply-file path/to/reply.md` to post it. No need to paste a long body on the command line.

The approved review artifact schema and the exact-approval rules are in
[review-comments.md](./review-comments.md#submit-an-approved-review). Scan all
three arrays returned by `comments` before drafting new findings; a submitted
review body can already contain the same finding or record a decision that
changes it.

- Omit `PR_NUMBER` to use the current branch’s open PR. Optional: `--repo OWNER/REPO`, `--token` / `-t`.
- In Agent use `required_permissions: ["all"]` (sandbox blocks network; see [Terminal docs](https://cursor.com/docs/agent/tools/terminal)).
- For batch-verifying many comment locations in parallel, consider an [explore subagent](https://cursor.com/docs/subagents).
Expand All @@ -261,12 +271,15 @@ Workflow: you can draft the reply with the user in a file (e.g. `reply.md` or `p

When the helper is not available or you need raw API JSON:

**Get all comments (inline + top-level):**
**Get all discussion (inline + review summaries + top-level):**

```bash
# Inline code review comments (not in gh pr view --json comments)
gh api repos/NVIDIA-NeMo/Safe-Synthesizer/pulls/<number>/comments

# Submitted review summaries
gh api repos/NVIDIA-NeMo/Safe-Synthesizer/pulls/<number>/reviews

# Top-level PR conversation
gh pr view <number> --json comments -q '.comments[] | "\(.author.login): \(.body)"'
# Or raw JSON:
Expand Down
Loading
Loading