diff --git a/.agents/skills/pr-review-fixer/SKILL.md b/.agents/skills/pr-review-fixer/SKILL.md index be7fee14..55d0ebe1 100644 --- a/.agents/skills/pr-review-fixer/SKILL.md +++ b/.agents/skills/pr-review-fixer/SKILL.md @@ -7,7 +7,7 @@ description: > PR comments", "address review feedback", "fix review comments", "what comments are on this PR", "respond to code review", or similar. Trigger even if they just say "let's fix the PR comments" or "what did reviewers say". -allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh) Bash(${CLAUDE_SKILL_DIR}/scripts/resolve-thread.sh *) Bash(gh pr comment *) +allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh) Bash(${CLAUDE_SKILL_DIR}/scripts/resolve-thread.sh *) Bash(gh pr comment *) Bash(command -v gh) mcp__github__pull_request_read mcp__github__resolve_review_thread mcp__github__add_reply_to_pull_request_comment mcp__github__add_issue_comment --- # PR Review Comment Fixer @@ -17,10 +17,22 @@ whatever the user approves. ## Phase 1: Fetch threads -Run !`${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh`. It resolves the current PR, fetches review -threads, review bodies, and issue comments, and filters out resolved threads and -empty bodies with `jq` before any of it reaches you: you only ever see live, -unresolved feedback. Output is `{threads, reviews, issueComments}`. +Check whether `gh` is on `PATH`: `command -v gh`. Some sessions (e.g. a +remote/cloud session) have no `gh` CLI and use `mcp__github__*` tools instead. + +**`gh` available:** run `${CLAUDE_SKILL_DIR}/scripts/fetch-review-threads.sh` via +the Bash tool. It resolves the current PR, fetches review threads, review bodies, +and issue comments, and filters out resolved threads and empty bodies with `jq` +before any of it reaches you: you only ever see live, unresolved feedback. Output +is `{threads, reviews, issueComments}`. If the script fails to resolve a PR for +the current branch, ask the user for the PR number or URL and retry. + +**`gh` missing:** read [`gh-missing.md`](./gh-missing.md)'s "Phase 1" section and +follow it instead — it reconstructs the same `{threads, reviews, issueComments}` +shape via `mcp__github__pull_request_read`. + +Either way, everything from Phase 2 on reads `{threads, reviews, issueComments}` +the same way regardless of which path produced it. If all three arrays are empty, tell the user and stop. @@ -96,17 +108,20 @@ Parse the user's free-text reply to determine which comments to fix. Be flexible For each selected comment: - If `small` or `medium`: implement the fix now. After editing, confirm with a brief - "Fixed #N: [what changed]" note. Then resolve the thread: + "Fixed #N: [what changed]" note. Then resolve the thread — `gh` available: ```bash ${CLAUDE_SKILL_DIR}/scripts/resolve-thread.sh ``` + `gh` missing: [`gh-missing.md`](./gh-missing.md)'s "Phase 4" section. (Only resolve inline threads; top-level review bodies and issue comments don't have a thread ID to resolve.) - If `large`: don't attempt it now. Say: "Comment N is too large for this session: suggest tackling it in a dedicated follow-up." Do not resolve the thread. - If the comment is a **question**: no code change needed. Explain the answer - (optionally as a reply via `gh pr comment --body ...` if the user wants - to post it, but don't do this unless asked). Resolve the thread after answering. + (optionally posted as a reply, if the user wants it posted, but don't do this unless + asked — `gh` available: `gh pr comment --body ...`; `gh` missing: + [`gh-missing.md`](./gh-missing.md)'s "Phase 4" section). Resolve the thread after + answering. After all fixes are applied, give a short summary of what was changed and what was deferred. diff --git a/.agents/skills/pr-review-fixer/gh-missing.md b/.agents/skills/pr-review-fixer/gh-missing.md new file mode 100644 index 00000000..a3ce02fe --- /dev/null +++ b/.agents/skills/pr-review-fixer/gh-missing.md @@ -0,0 +1,35 @@ +# Fallback: gh is missing + +Reached from `SKILL.md` only when Phase 1's `command -v gh` check comes back +empty (e.g. a remote/cloud session with no `gh` CLI, relying on the +`mcp__github__*` tools instead). Skip this file entirely when `gh` is available. + +## Phase 1: fetch threads + +Reconstruct the same `{threads, reviews, issueComments}` shape from +`mcp__github__pull_request_read`. This skill's `allowed-tools` grants no git +command, so don't try to derive owner/repo/PR number by shelling out — use +what you already know about the repo from this session's own context (its +scope, working directory, or what the user told you). This fallback has no +way to look up the PR number on its own: if it isn't already clear from +context, ask the user for it before making the call below. + +- `method: get_review_comments` → review threads. Each has `id` (the GraphQL + thread node ID — this is what `resolve_review_thread` below needs, keep it), + `is_resolved`, `path`, `line`, and `comments[]` with `author`/`body`/`html_url` + (Phase 4 needs `html_url` to build a reply, keep it too). Keep only + `is_resolved == false` — the tool doesn't filter this for you the way the + script's `jq` does. +- `method: get_reviews` → review bodies; keep only non-empty `body`. +- `method: get_comments` → top-level PR/issue comments (the script's + `issueComments`). + +## Phase 4: resolve and reply + +- Resolve a thread with `mcp__github__resolve_review_thread`, passing the + thread's GraphQL `id` (kept from `get_review_comments` above). +- A reply, if the user wants one posted: + - Inline thread reply: `mcp__github__add_reply_to_pull_request_comment` + with the numeric comment ID from the thread's comment `html_url` (the + `#discussion_r` suffix — not the thread's GraphQL `id`). + - Top-level PR comment: `mcp__github__add_issue_comment`.