commit dd89efd3e0ee379d59dd63e3ad17e62e8d11c5bb Author: Zhongwei Li Date: Sat Nov 29 18:01:35 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..b3676e8 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "github", + "description": "Commands for interacting with GitHub issues and pull requests (PRs)", + "version": "1.0.0", + "author": { + "name": "boneskull" + }, + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..573927a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# github + +Commands for interacting with GitHub issues and pull requests (PRs) diff --git a/commands/resolve-review-comments.md b/commands/resolve-review-comments.md new file mode 100644 index 0000000..3374be4 --- /dev/null +++ b/commands/resolve-review-comments.md @@ -0,0 +1,100 @@ +--- +description: Address any valid, outstanding pull request (PR) review comments +argument-hint: [PR_NUMBER] +--- + +# /resolve-review-comments + +## Purpose + +Address any valid, outstanding pull request (PR) review comments + +## Contract + +**Inputs:** `PR_NUMBER` (optional) — PR number to check (defaults to current branch's PR) +**Outputs:** `STATUS= [key=value ...]` + +## Instructions + +1. **Identify the PR:** + - If PR_NUMBER provided, use it + - Otherwise, detect PR from current branch using `gh pr view` + +2. **Fetch review comments:** + - Get all review threads using GitHub GraphQL API + - Filter for unresolved threads + - Show comment details: file, line, author, body + +3. **For each unresolved comment:** + - Read the comment and assess validity + - If valid: + - Implement the suggested fix + - Test the fix (lint, run relevant tests) + - Commit the fix with message referencing the review + - Push to PR branch + - **Add reply to review comment conversation** explaining the fix concisely + - Mark thread as resolved using GraphQL API + - If invalid: + - **Add reply to review comment conversation** explaining why it's invalid concisely + - Mark thread as resolved using GraphQL API + - If unclear: + - Ask user whether to address it or skip + +4. **Output status:** + - Print `STATUS=OK RESOLVED=N` where N is count of resolved comments + - Print `STATUS=FAIL ERROR="message"` on failure + +## Example Workflow + +```bash +# 1. Get unresolved review threads +gh api graphql -f query=' + query { + repository(owner: "OWNER", name: "REPO") { + pullRequest(number: PR_NUM) { + reviewThreads(first: 50) { + nodes { + id + isResolved + comments(first: 10) { + nodes { + id + databaseId + body + path + line + author { login } + } + } + } + } + } + } + } +' + +# 2. Add reply to review comment conversation (NOT issue comment!) +# Use the first comment's databaseId as in_reply_to +gh api repos/OWNER/REPO/pulls/PR_NUM/comments \ + -f body="✅ Fixed in commit abc1234..." \ + -F in_reply_to=COMMENT_DATABASE_ID + +# 3. Resolve the thread +gh api graphql -f query=' + mutation { + resolveReviewThread(input: {threadId: "THREAD_ID"}) { + thread { id isResolved } + } + } +' +``` + +## Constraints + +- Only address comments marked as "valid" after analysis +- Always test fixes before committing +- Use conventional commit messages referencing the review +- Atomic commits per review comment +- Ask user for confirmation on ambiguous cases +- **IMPORTANT:** Add replies to review comment conversations (using `in_reply_to`), NOT to the issue +- Keep replies concise (1-3 sentences explaining fix or why invalid) diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..9f045cd --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,45 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:boneskull/claude-plugins:plugins/github", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "122f6a1a42e5b76326cae583f66d224164d71870", + "treeHash": "5b84c4c9cc3e62977e9be2eddcdea0cc057df451bcbe09c6c161e001672849f7", + "generatedAt": "2025-11-28T10:14:19.095863Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "github", + "description": "Commands for interacting with GitHub issues and pull requests (PRs)", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "b23690e2110e47fa37ade972954c556bb21945e10949b5a6bcdb11b6772090e5" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "d296e1632aff3e819910d65f77a3fef9fdc391733bbc9998559e598473a50d3a" + }, + { + "path": "commands/resolve-review-comments.md", + "sha256": "ff431b20081dbad5f1be2380fe188cc93a06f6ae7466d8a5f251988b602681f0" + } + ], + "dirSha256": "5b84c4c9cc3e62977e9be2eddcdea0cc057df451bcbe09c6c161e001672849f7" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file