소스 정보
- 저장소
- loomantix/claude-platform
- 최근 소스 활동
- 2026년 5월 3일 04:18
- 감지된 SKILL.md 언어
- 영어
- 스타
- 2
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/loomantix/claude-platform --skill copilot-review명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | copilot-review |
| description | Address GitHub Copilot code review comments on a PR systematically |
| argument-hint | PR number (e.g., 1206) |
You are helping a developer address GitHub Copilot code review comments on a pull request. Follow a systematic approach: fetch comments, create an isolated worktree, analyze each comment, address or defer appropriately, reply to confirm resolution, and iterate until complete.
Goal: Validate the PR and set up the working environment
Arguments: $ARGUMENTS (PR number)
Actions:
Validate PR number from arguments
Fetch PR details:
gh pr view <pr-number> --json number,title,headRefName,baseRefName,state
Verify PR is open and ready for review
Create todo list with all phases
Goal: Load and categorize all Copilot code review comments
IMPORTANT — jq quoting pitfalls:
--jq expressions passed directly to gh api are fragile because of shell/YAML quoting (especially with !=, embedded \n, and nested quotes)!= is a valid jq operator; the issues come from how the shell parses gh api --jq arguments, not from jq itself--jq filters (or none), save raw JSON to a temp file first, then run richer jq queries against that fileActions:
Fetch all PR comments to a temp file (single API call, reused for all queries):
gh api --paginate repos/{owner}/{repo}/pulls/<pr-number>/comments > /tmp/pr-<pr-number>-comments.json
Extract Copilot top-level comments (those without in_reply_to_id):
jq '[.[] | select((.user.login | test("copilot"; "i")) and (.in_reply_to_id == null or .in_reply_to_id == 0)) | {id, path, line, body: (.body | split("\n")[0][:120])}]' /tmp/pr-<pr-number>-comments.json
Extract reply target IDs (which comments already have human replies):
jq '[.[] | select(.in_reply_to_id > 0) | .in_reply_to_id] | unique' /tmp/pr-<pr-number>-comments.json
Compute unaddressed comments (Copilot comments whose ID is not in the replied set):
jq '[.[] | select((.user.login | test("copilot"; "i")) and (.in_reply_to_id == null or .in_reply_to_id == 0)) | {id, path, line, body: (.body | split("\n")[0][:120])}] as $all | [.[] | select(.in_reply_to_id > 0) | .in_reply_to_id] | unique as $replied | $all | map(select(.id as $cid | $replied | index($cid) | not))' /tmp/pr-<pr-number>-comments.json
Read full body of each unaddressed comment when needed:
jq '.[] | select(.id == <comment-id>) | .body' /tmp/pr-<pr-number>-comments.json
Categorize each unaddressed comment after reading the file:
Present summary to user:
Ask user for confirmation before proceeding
Goal: Create an isolated environment for making changes
Actions:
Get PR branch name from Phase 0 data (headRefName)
Check if worktree already exists:
git worktree list | grep "copilot-review-<pr-number>"
Create or reset worktree:
If worktree doesn't exist:
git fetch origin <branch-name>
git worktree add worktrees/copilot-review-<pr-number> origin/<branch-name>
If worktree exists:
git -C worktrees/copilot-review-<pr-number> fetch origin
git -C worktrees/copilot-review-<pr-number> checkout <branch-name>
git -C worktrees/copilot-review-<pr-number> reset --hard origin/<branch-name>
Verify worktree is ready:
git -C worktrees/copilot-review-<pr-number> status
git -C worktrees/copilot-review-<pr-number> log --oneline -3
Set worktree path for subsequent operations:
worktrees/copilot-review-<pr-number>/git -C worktrees/copilot-review-<pr-number>Goal: Address each unaddressed Copilot comment systematically
For each unaddressed comment, perform the following cycle:
Read the file at the path specified in the comment
Understand the context:
Classify the resolution approach:
If Fix:
just lint-fixIf Defer:
gh issue create --title "<issue-title>" \
--label "tech-debt,from-copilot-review" \
--body "## Context\n\nThis issue was identified during Copilot code review of PR #<pr-number>.\n\n## Original Comment\n\n<copilot-comment-body>\n\n## Recommendation\n\n<suggested-approach>\n\n## Related\n\n- PR #<pr-number>"
If Dismiss:
Do NOT post a reply here. The reply needs to reference the real commit SHA, which doesn't exist until after Phase 4's push. Posting now means the SHA is a placeholder the model substitutes with garbage (or skips the reply entirely). Replies are posted in Phase 4 step 6 using the real SHA.
Build a resolution row in memory for this comment:
{
"comment_id": <numeric id from GitHub>,
"path": "<file path>",
"line": <line number or null>,
"resolution": "fix" | "defer" | "dismiss",
"explanation": "<one-line: what changed / why deferred / why dismissed>",
"defer_issue_url": "<URL or null — only set on defer>"
}
Accumulate rows in an in-memory list as you iterate the comment loop. Do not try to append-write the JSON file row-by-row — naïve append produces invalid JSON. Phase 3 finishes by writing the full array once.
After the loop completes, write the accumulated array once:
Write(file_path="/tmp/copilot-review-<pr-number>-resolutions.json",
content=<json-array-of-all-resolution-rows>)
Phase 4 step 6 reads this file and posts one reply per row.
Goal: Save changes, push to the PR branch, verify the push landed, then post one reply per recorded resolution using the real commit SHA.
Actions:
Verify changes (in worktree):
git -C worktrees/copilot-review-<pr-number> status
git -C worktrees/copilot-review-<pr-number> diff
Run quality checks (in worktree):
cd worktrees/copilot-review-<pr-number> && just lint-fix
cd worktrees/copilot-review-<pr-number> && just typecheck
Commit changes (only if there are code changes from "fix" resolutions):
cd worktrees/copilot-review-<pr-number> && git add -A && git commit -m "fix(review): address copilot feedback"
Push to remote and capture the real SHA:
git -C worktrees/copilot-review-<pr-number> push origin <branch-name>
PUSHED_SHA=$(git -C worktrees/copilot-review-<pr-number> rev-parse HEAD)
PUSHED_SHA_SHORT=$(git -C worktrees/copilot-review-<pr-number> rev-parse --short=8 HEAD)
If push is rejected (remote has new commits):
git -C worktrees/copilot-review-<pr-number> pull --rebase origin <branch-name>
git -C worktrees/copilot-review-<pr-number> push origin <branch-name>
PUSHED_SHA=$(git -C worktrees/copilot-review-<pr-number> rev-parse HEAD)
PUSHED_SHA_SHORT=$(git -C worktrees/copilot-review-<pr-number> rev-parse --short=8 HEAD)
Verify the push landed on the PR head before posting replies — GitHub's PR API is eventually consistent, so headRefOid can lag the actual ref by a few seconds:
verify_pr_head() {
local attempt
for attempt in 1 2 3 4; do
local pr_head
pr_head=$(gh pr view <pr-number> --json headRefOid --jq '.headRefOid')
if [[ "$pr_head" == "$PUSHED_SHA" ]]; then
return 0
$(( attempt * ))
>&2
1
}
verify_pr_head || 1
Goal: Get fresh Copilot feedback on the updated code
Actions:
Check if Copilot auto-reviews on push
If no automatic review, trigger manually via GraphQL.
IMPORTANT: Copilot is a Bot, not a User — gh pr edit --add-reviewer and the REST requested_reviewers endpoint do not work for Copilot. Use the GraphQL requestReviews mutation with botIds:
PR_NODE=$(gh pr view <pr-number> --json id --jq '.id')
gh api graphql \
-f query='mutation($prId:ID!,$botIds:[ID!]){requestReviews(input:{pullRequestId:$prId,botIds:$botIds,union:true}){pullRequest{id}}}' \
-f prId="$PR_NODE" \
-f botIds='BOT_kgDOCnlnWA'
Copilot bot node id is BOT_kgDOCnlnWA (constant). Verify with gh api repos/{owner}/{repo}/pulls/<n>/requested_reviewers --jq '.users[].login' → expected Copilot. The mutation is idempotent — safe to call across iterations.
Wait for the new Copilot review to appear (filter by Copilot's login, then take the most recent):
gh api repos/{owner}/{repo}/pulls/<pr-number>/reviews \
--jq '[.[] | select(.user.login | test("copilot"; "i"))] | last | {id, submitted_at, user: .user.login}'
Fetch new comments and check for any new unaddressed items
Goal: Determine if another resolution cycle is needed
Actions:
Count new unaddressed comments from the latest Copilot review
If new comments exist:
If no new comments:
Goal: Summarize all work done and provide next steps
Actions:
Generate summary report:
Cleanup worktree (optional, ask user):
git worktree remove worktrees/copilot-review-<pr-number>
Provide next steps:
GitHub's PR comment API (POST repos/{owner}/{repo}/pulls/{pull_number}/comments) uses a oneOf schema. You must use exactly one of these patterns:
jq -n \
--arg body "$BODY" \
--arg commit_id "$HEAD_SHA" \
--arg path "$FILE_PATH" \
--argjson line $LINE_NUM \
--arg side "RIGHT" \
'{body: $body, commit_id: $commit_id, path: $path, line: $line, side: $side}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -
jq -n \
--arg body "$BODY" \
--arg commit_id "$HEAD_SHA" \
--arg path "$FILE_PATH" \
--argjson line $END_LINE \
--argjson start_line $START_LINE \
--arg side "RIGHT" \
'{body: $body, commit_id: $commit_id, path: $path, line: $line, start_line: $start_line, side: $side, start_side: "RIGHT"}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -
jq -n \
--arg body "$BODY" \
--arg commit_id "$HEAD_SHA" \
--arg path "$FILE_PATH" \
--arg subject_type "file" \
'{body: $body, commit_id: $commit_id, path: $path, subject_type: $subject_type}' \
| gh api -X POST "repos/{owner}/{repo}/pulls/{pull_number}/comments" --input -
line must be within the PR diff for that file. If the target line isn't in a diff hunk, the API returns 422. Fall back to subject_type: "file".commit_id must match the PR's current HEAD when creating or re-posting a review comment. After a force-push, existing inline comments become "Outdated" and remain anchored to the old commit SHA. You can still edit their body text via PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}, but you cannot change their diff anchor; to re-anchor to the new HEAD you must delete and recreate the comment.subject_type cannot be combined with line/start_line/side. The API uses oneOf — pick one pattern.position (deprecated) or include subject_type: "line" explicitly (not a valid creation param, only returned in responses).After a force-push, all existing inline comments become "outdated" (anchored to the old commit SHA). To re-anchor comments to the new commit:
gh api --paginate repos/{owner}/{repo}/pulls/{pull_number}/commentsuser.login or body pattern){path, body, original_line, original_start_line, subject_type} from eachgh api -X DELETE repos/{owner}/{repo}/pulls/comments/{id}grep -n on actual files to find correct line numbers for the new commitIf GitHub API fails:
If worktree creation fails:
git branch -r | grep <branch-name>git fetch origin <branch-name>If reply posting fails:
gh pr comment <pr-number> --body "Re: Copilot comment on <file>:<line>\n\n<reply-message>"
Post replies now that the real SHA is in hand. Read /tmp/copilot-review-<pr-number>-resolutions.json and post one reply per row, building each body with ${PUSHED_SHA_SHORT} substituted inline.
Reply body templates:
For Fix:
Fixed in `${PUSHED_SHA_SHORT}`.
<explanation from resolutions.json>
For Defer:
Deferred — tracking in <defer_issue_url>.
<explanation: why this is being deferred rather than fixed in this PR>
For Dismiss:
Dismissing — false positive.
<explanation: why the reviewer's reasoning doesn't apply>
Post each reply via:
gh api -X POST repos/{owner}/{repo}/pulls/<pr-number>/comments/<comment_id>/replies \
-f body="<assembled body>"
If any single reply POST fails, log it and continue with the rest — partial reply coverage is better than none. Surface the count of failed-reply POSTs in the Phase 7 completion summary.