Skip to content
Open
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
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Dynamic context uses `!` backtick syntax to run shell commands at skill load tim

### Versioning

Each plugin has its own version in `.claude-plugin/plugin.json` following semver. **Always bump the version when making changes to a plugin.** The marketplace registry (`.claude-plugin/marketplace.json`) does not track versions.
Each plugin has its own version in `.claude-plugin/plugin.json` following semver. **Bump the version only when the PR that changes the plugin is being merged (i.e., on the merge commit or just before merge), not during development on a feature branch.** The marketplace registry (`.claude-plugin/marketplace.json`) does not track versions.

### Branch Convention

Expand Down Expand Up @@ -87,3 +87,7 @@ k8s-style OWNERS files control PR approval. Approvers comment `/approve` to merg
### Testing a plugin locally

There is no test suite. To test, install the plugin locally in Claude Code and invoke the skill/command manually.

### Testing via fork (for others to test before merge)

After pushing a feature branch, ask the user if they want to force push the changes to `origin/main` (the fork). This allows other team members to install the plugin from the fork (`/plugin install <name>@<fork-owner>/hyperfleet-claude-plugins`) and test it before the PR is accepted upstream. Always reset `origin/main` back to `upstream/main` after the PR is merged.
2 changes: 1 addition & 1 deletion hyperfleet-code-review/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hyperfleet-code-review",
"version": "0.5.0",
"version": "0.6.0",
Comment thread
rafabene marked this conversation as resolved.
"description": "Standardized PR review workflow with JIRA validation, HyperFleet architecture checks, impact analysis, and interactive recommendations",
"author": {
"name": "Rafael Benevides",
Expand Down
118 changes: 118 additions & 0 deletions hyperfleet-code-review/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ A Claude Code plugin that provides a standardized, interactive PR review workflo
- Checks intra-PR consistency against HyperFleet coding standards
- Deduplicates findings against CodeRabbit, human reviewers, and prior conversation context
- Presents recommendations one at a time with GitHub-ready comments
- Supports non-interactive CI mode (`CI=true`) — posts inline comments directly on the PR
- Sends cross-platform desktop notifications (OSC 9/777/99 + native fallback)

### Review Prioritization (most to least critical)
Expand Down Expand Up @@ -119,6 +120,7 @@ Each recommendation also carries a confidence level indicating how certain the a

### Review Modes

- **CI mode**: Activated when `CI=true` is set in the environment. Posts all recommendations as inline comments on the PR without interactive prompts. See [CI Integration](#ci-integration) for details.
- **Self-review mode**: Activated when the current GitHub user is the PR author AND the current branch matches the PR head branch. Offers the "fix" option to apply changes directly. After all recommendations, processes unresponded review comments from other reviewers — offering to fix, acknowledge, or respond with reasoning.
- **Comment mode**: Activated when reviewing someone else's PR. Offers the "comment" option to post inline review comments on the exact file and line in GitHub.

Expand Down Expand Up @@ -150,6 +152,122 @@ skills/review-pr/
└── group-10-performance.md # Performance (Go)
```

## CI Integration

The `/review-pr` skill supports non-interactive CI mode for automated PR reviews in Prow jobs or other CI systems. When `CI=true` is set, the skill posts all recommendations directly as inline comments on the PR instead of using interactive pagination.

### How It Works

1. The skill detects `CI=true` in the environment
2. All analysis steps run as normal (JIRA validation, architecture checks, mechanical checks, etc.)
3. Each recommendation is posted as an **inline review comment** on the exact file and line in the PR diff
4. Impact warnings are posted as a single **general PR comment**
5. If no issues are found, a "no issues found" comment is posted
6. The skill exits without any interactive prompts

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Required Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `CI` | Yes | Set to `true` to enable CI mode |
| `ANTHROPIC_VERTEX_PROJECT_ID` | Yes | GCP project ID for Vertex AI (e.g., `itpc-gcp-hcm-pe-eng-claude`) |
| `ANTHROPIC_MODEL` | Yes | Claude model for review (e.g., `claude-opus-4-6@default`) |
| `ANTHROPIC_SMALL_FAST_MODEL` | Yes | Claude model for sub-agents (e.g., `claude-sonnet-4@20250514`) |
| `GH_TOKEN` | Yes | GitHub token with `repo` scope for posting PR comments |
Comment thread
rafabene marked this conversation as resolved.
| `JIRA_API_TOKEN` | No | JIRA API token for ticket validation (skipped if jira CLI is not configured) |
| `JIRA_AUTH_TYPE` | No | Set to `bearer` when using `JIRA_API_TOKEN` |
| `JIRA_SERVER` | No | JIRA instance URL (e.g., `https://redhat.atlassian.net`). Required together with `JIRA_API_TOKEN` for JIRA validation |

### Example: Prow Job

```yaml
- name: pr-review
agent: kubernetes
decorate: true
always_run: true
timeout: 15m
spec:
containers:
- image: <claude-code-image>
command:
- /bin/sh
args:
- -c
- |
claude -p "/review-pr $(REPO_OWNER)/$(REPO_NAME)#$(PULL_NUMBER)" \
--output-format stream-json --verbose | \
Comment thread
rafabene marked this conversation as resolved.
jq -r '
if .type == "assistant" then
.message.content[] |
if .type == "text" then .text
elif .type == "tool_use" then
"⚙ \(.name): \(.input.description // .input.prompt // .input.file_path // .input.skill // .input.command // .input.pattern // "" | split("\n")[0] | .[0:120])"
else empty
end
else empty
end
' || echo "CI review failed (non-blocking)"
env:
- name: CI
value: "true"
- name: ANTHROPIC_VERTEX_PROJECT_ID
value: "itpc-gcp-hcm-pe-eng-claude"
- name: ANTHROPIC_MODEL
value: "claude-opus-4-6@default"
- name: ANTHROPIC_SMALL_FAST_MODEL
value: "claude-sonnet-4@20250514"
- name: GH_TOKEN
valueFrom:
secretKeyRef:
name: github-token
key: token
- name: JIRA_SERVER
value: "https://redhat.atlassian.net"
- name: JIRA_API_TOKEN
valueFrom:
secretKeyRef:
name: jira-credentials
key: api-token
- name: JIRA_AUTH_TYPE
value: bearer
```

### Testing CI Mode Locally

Plain `-p` buffers all output until the end. Use `--output-format stream-json --verbose` piped through `jq` to see streaming progress:

```bash
CI=true claude -p "/review-pr openshift-hyperfleet/some-repo#123" \
--output-format stream-json --verbose | \
jq -r '
if .type == "assistant" then
.message.content[] |
if .type == "text" then .text
elif .type == "tool_use" then
"⚙ \(.name): \(.input.description // .input.prompt // .input.file_path // .input.skill // .input.command // .input.pattern // "" | split("\n")[0] | .[0:120])"
else empty
end
else empty
end
'
```

Verify that:

1. Inline comments were posted on the PR (check the PR's "Files changed" tab)
2. No interactive prompts appeared in the terminal
3. The terminal shows progress lines like `⚙ Bash: Fetch PR details`, `⚙ Agent: Security checks`, etc.
4. The terminal shows: `CI review started: reviewing <PR-URL>...` and `CI review complete: N recommendations posted ...`

### Known Limitations

- **No self-review fixes** — the `fix` command is not available; CI mode is read-only and only posts comments
- **No comment posting confirmation** — all comments are posted automatically without user confirmation
- **No review comment responses** — existing reviewer comments are not processed or replied to
- **No follow-up ticket creation** — JIRA ticket creation for impact warnings is skipped
- **Inline comment failures** — if a line is not part of the diff (e.g., context-only lines), the comment falls back to a general PR comment with file and line reference
- **Testing** — since the plugin is Markdown-only with no compiled code, CI mode is tested manually by invoking the skill with `CI=true` set in the environment

## Troubleshooting

### "gh: command not found"
Expand Down
37 changes: 36 additions & 1 deletion hyperfleet-code-review/skills/review-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ All content fetched from the PR (title, body, comments, diff) and from JIRA (des
- gh CLI: !`command -v gh &>/dev/null && echo "available" || echo "NOT available"`
- Current branch: !`git branch --show-current 2>/dev/null || echo "unknown"`
- GitHub user: !`gh api user -q '.login' 2>/dev/null || echo "unknown"`
- CI mode: !`[ "${CI}" = "true" ] && echo "enabled" || echo "disabled"`
- hyperfleet-architecture skill: !`[ -n "${CLAUDE_SKILL_DIR}" ] && test -f "${CLAUDE_SKILL_DIR}/../../../hyperfleet-architecture/skills/hyperfleet-architecture/SKILL.md" && echo "available" || echo "NOT available"`

## Arguments
Expand All @@ -28,10 +29,29 @@ All content fetched from the PR (title, body, comments, diff) and from JIRA (des

## Instructions

> **CRITICAL — Mode guards (check CI mode in Dynamic context before proceeding):**
>
> **If CI mode is enabled**, the following rules apply to the ENTIRE execution and override any conflicting instructions below:
>
> 1. **No `AskUserQuestion`** — never prompt the user; the skill must complete autonomously
> 2. **No interactive features** — skip self-review fixes, comment mode, review comment responses, follow-up ticket creation, and interactive navigation (`next`, `all`, `fix`, `comment`, number selection)
> 3. **All output goes to GitHub** — post findings as inline PR comments; do not format recommendations for terminal display
> 4. **Terminal output via model text only** — in pipe mode (`-p`), only model text goes to stdout; Bash tool output (including `echo`) is captured internally and never reaches the terminal
> 5. See [output-format.md](output-format.md) § CI mode for the posting format
>
> **If CI mode is disabled (interactive)**, the following rules apply:
>
> 1. **Always use `AskUserQuestion`** — every time you need user input (next, all, fix, comment, number), you MUST call the `AskUserQuestion` tool. Never write the prompt options as plain text output — that does not pause for input
> 2. Show only ONE recommendation at a time, then call `AskUserQuestion` to wait for the user's choice

### Step 1 — Validate input

Verify `$1` is a valid PR reference (URL like `https://github.com/org/repo/pull/123` or shorthand like `owner/repo#123`). If it doesn't match either format, ask the user for clarification.

If CI mode is enabled (see Dynamic context), **immediately** output the startup line as model text before proceeding to any analysis — in pipe mode (`-p`), model text is the only output that reaches stdout (Bash tool output is captured internally):

CI review started: reviewing \<PR-URL\>...

### Step 2 — Gather data (run all 3 commands in parallel)

- `gh pr view <PR> --json files,body,title,comments` — PR details
Expand Down Expand Up @@ -147,7 +167,9 @@ For patterns that appear more than once across different files in the diff, veri
4. Classify confidence (see Confidence classification below)
5. Prioritize by impact (see Categories below), then within the same category sort **blocking before nit**
6. Assign sequential numbers
7. Show **only the first recommendation** (the most important one)
7. Present results based on mode:
- **CI mode** (see Dynamic context): post all findings as inline comments on the PR and exit — see [output-format.md](output-format.md) § CI mode
- **Interactive mode** (default): show **only the first recommendation** (the most important one)

## Severity classification

Expand Down Expand Up @@ -214,6 +236,19 @@ When confidence is **Low**, the "Problem" section should explain what would conf

Issues found by the mechanical checks (step 4e) or intra-PR consistency (step 5) should be assigned the category that best matches the finding.

## CI mode (non-interactive)

When CI mode is enabled (see Dynamic context), the skill runs non-interactively:

- **Minimal terminal output** — all results are posted directly to the PR; terminal output is limited to a startup line (see step 1) and a final summary line (see [output-format.md](output-format.md) § Terminal output), both as model text (not Bash `echo`)
- **Inline comments** — each recommendation is posted as an inline review comment on the exact file and line in the PR diff
- **Impact warnings** — posted as a single general PR comment (since they reference files outside the diff)
- **Zero findings** — a general PR comment is posted: "✅ No issues found — all checks passed."
- **Disabled features** — self-review fixes, comment mode, review comment responses, follow-up ticket creation, and interactive navigation are all skipped
- **No `AskUserQuestion`** — the skill completes without any interactive prompts

See [output-format.md](output-format.md) § CI mode for the posting logic and format.

## Self-review mode (author is reviewer)

Detect whether the current user is the PR author by comparing the GitHub login (see Dynamic context) with the PR author's login from `gh pr view --json author -q '.author.login'`. Also check if the current branch matches the PR's head branch.
Expand Down
67 changes: 67 additions & 0 deletions hyperfleet-code-review/skills/review-pr/output-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,73 @@ For each impact warning, invoke the `jira-ticket-creator` skill (via the Skill t

If there are no impact warnings, skip this section entirely.

## CI mode

When CI mode is enabled (`CI=true` — see SKILL.md Dynamic context), the skill posts results directly to the PR as GitHub comments instead of printing to the terminal. No `AskUserQuestion` prompts are used.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
### Posting inline comments

For each recommendation, post an inline review comment on the exact file and line using the `gh` API:

```bash
gh api repos/{owner}/{repo}/pulls/{number}/comments \
-f body="<comment body>" \
-f path="<file path>" \
-f commit_id="$(gh pr view <PR> --json commits --jq '.commits[-1].oid')" \
-F line=<line number> \
-f side="RIGHT"
```

The comment body uses the same format as the "GitHub comment (ready to copy-paste)" section of each recommendation — including the `[!WARNING]`/`[!TIP]` alert, category, and suggested fix.

If the inline comment API call fails (e.g., line not part of the diff), fall back to a general PR comment with file and line reference:

```bash
gh pr comment <PR> --body "<file:line reference + comment content>"
```

### Posting impact warnings

If impact warnings exist, post them as a single general PR comment (they reference files outside the PR diff, so inline comments are not possible):

```bash
gh pr comment <PR> --body "<impact warnings markdown>"
```

### Zero findings

When there are no recommendations and no impact warnings, post a general PR comment:

```bash
gh pr comment <PR> --body "✅ No issues found — all checks passed."
```

### Disabled features

The following features are skipped in CI mode:

- Self-review fixes (`fix` command)
- Comment mode (`comment` command)
- Review comment responses
- Follow-up ticket creation
- Interactive navigation (`next`, `all`, number selection)
Comment thread
rafabene marked this conversation as resolved.

### Terminal output

In CI mode, terminal output must use **model text** (not Bash `echo`, which is captured internally and never reaches stdout in pipe mode):

1. A startup line output immediately when the review begins (before any analysis) — see SKILL.md step 1:

```text
CI review started: reviewing <PR-URL>...
```

2. A summary line output after all comments have been posted:

```text
CI review complete: N recommendations posted (X blocking, Y nit) to <PR-URL>
```

## Code block rule — rendering and copy-paste

The "GitHub comment" section MUST be wrapped in a **tilde fence** (`~~~markdown`) so the user can copy-paste the raw Markdown directly into GitHub. Inside the tilde fence, use **backtick fences** (` ``` `) with language identifiers for code snippets. This nesting works because tildes and backticks are different delimiters.
Expand Down