diff --git a/.agents/skills/pr-review-fixer/SKILL.md b/.agents/skills/pr-review-fixer/SKILL.md index be7fee14..d186c12d 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,26 @@ 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}`. +Using the Bash tool yourself — not the auto-exec markdown form (an exclamation +mark immediately before a backtick-fenced command), which runs unconditionally +before you get a turn and is exactly what broke the branch below — check once +whether `gh` is on `PATH`: `command -v gh`. Some session types +(e.g. a remote/cloud session) have no `gh` CLI and rely on the `mcp__github__*` +tools instead. Don't discover this by running the fetch script and reacting to its +failure — check first, with this command, and pick the right path. + +**`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}`. + +**`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 +112,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..084b37f7 --- /dev/null +++ b/.agents/skills/pr-review-fixer/gh-missing.md @@ -0,0 +1,33 @@ +# 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), and ask the user for +the PR number if it's genuinely ambiguous: + +- `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`. 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`.