SuperAPI AI Directory

repos-pull-request-review

Coding & development

View repository

Updated 10-15 21:11

About this skill

Pull Request Review

This Skill approaches PRs from thereviewer'sperspective: find the PRs to look at, understand them, and respond to them. Author-side operations such as creating PRs, publishing drafts, and setting auto-complete use repos-pull-request-write。

Project Selection

  • If the user provides a project name (for example "Contoso project"), use it directly and do not call the project list API.

  • If not provided, ask the user to provide one.

  • If still not provided, list the projects for the user to choose from:

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/_apis/projects?%24top=500&api-version=7.1"
    
  • If the user wants "all projects", repeat rule 1 for each project in the list; if there are more than 20 projects, first tell the user the count and confirm once.

  • Do not continue until the user provides or selects a project.

Repository is optional: when listing PRs, omitting it means the entire project; if the user specifies a repository, use _apis/git/repositories/{repository}/pullrequests。

Connection and Authentication

Always use curl to call the Azure DevOps REST API directly; each command carries its own authentication parameters.

  • Organization: read the environment variable AZURE_DEVOPS_ORG(organization name, for example contoso). If it is not set, ask the user once; if what the user gives is a URL, extract the organization name from https://dev.azure.com/{org} or https://{org}.visualstudio.com .
  • Host: except for dev.azure.com, the host for the Identities API that queries group members is vssps.dev.azure.com。
  • Token: send the PAT with Basic authentication:-u ":$AZURE_DEVOPS_PAT"; if only AZURE_DEVOPS_EXT_PATis set (the variable used by the Azure CLI azure-devops extension), use that instead. When using a Microsoft Entra ID token instead, switch to -H "Authorization: Bearer $AZURE_DEVOPS_TOKEN". If neither is set, ask the user to set AZURE_DEVOPS_PAT in their own terminal and retry, then stop. Read the token only from environment variables: do not ask the user to paste the token into the conversation, and do not print it or write it to a file.
  • PAT permission scopes: Code (Read), Work Items (Read), Identity (Read); commenting, replying, resolving discussions, and voting additionally require Code (Read & write).
  • Encoding: URL-encode project and repository names in paths and file paths in query strings (write spaces as %20); in query strings write $ as %24(for example %24top) to avoid shell expansion.
  • Errors: HTTP 401, 403, 203, or an HTML login page in the response means the token is invalid, expired, or has insufficient permissions; report it and stop. HTTP 404 means the organization, project, repository, or PR ID is wrong.
  • Windows PowerShell: call curl.exe(not the curl alias), and write the environment variable as $env:AZURE_DEVOPS_PAT; PowerShell does not support <<'EOF', so first write the JSON body to a temporary file, then send it with --data-binary "@body.json" .

Current User

Rules 1 and 4 require the current user's identity ID (this endpoint does not carry api-version):

curl -sS -u ":$AZURE_DEVOPS_PAT" "https://dev.azure.com/$AZURE_DEVOPS_ORG/_apis/connectionData"

Use authenticatedUser.id;authenticatedUser.providerDisplayName is the display name.

Rules

1. List PRs awaiting my review or created by me

  • PRs awaiting my review:

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/pullrequests?searchCriteria.reviewerId={myId}&searchCriteria.status=active&%24top=100&api-version=7.1"
    

    reviewerId only findsPRs directlyassigned to me. To cover PRs assigned to my team or group:

    1. Without reviewerId list searchCriteria.status=active PRs, and pick out reviewers in reviewers[] whose isContainer is true .

    2. Get my direct group memberships (memberOf is a list of group descriptors):

      curl -sS -u ":$AZURE_DEVOPS_PAT" \
        "https://vssps.dev.azure.com/$AZURE_DEVOPS_ORG/_apis/identities?identityIds={myId}&queryMembership=Direct&api-version=7.1"
      
    3. Use identityIds={groupId1},{groupId2} to look up the descriptorof these group reviewers in one go; any that appear in my memberOf count as "awaiting my review via {group name}".

  • PRs I created: replace reviewerId with searchCriteria.creatorId={myId}。

  • Other filters:searchCriteria.targetRefName=refs/heads/main、searchCriteria.status=completed|abandoned|all。

  • For paging use %24top and %24skip; when the number of returned items equals %24top , fetch the next page.

  • The list API's description is truncated to 400 characters; when you need the full description, use rule 2 to get a single PR.

  • When there are no PRs, explicitly state that no PRs match the criteria.

Example: "List the PRs awaiting my review in the Contoso project", "Which PRs have I opened in Contoso that haven't been merged yet?"

2. Review a single PR

  1. Get the PR (no need to know the repository):

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/pullrequests/{pullRequestId}?api-version=7.1"
    

    Note down repository.id、repository.project.id(project GUID),repository.webUrl、isDraft、mergeStatus、reviewers[].vote、autoCompleteSetBy。

  2. Get iterations, use the last one's id、sourceRefCommit.commitId and commonRefCommit.commitId(merge base):

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/iterations?api-version=7.1"
    
  3. Get the changed files of the entire PR relative to the merge base (%24compareTo=0):

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/iterations/{iterationId}/changes?%24compareTo=0&%24top=2000&api-version=7.1"
    

    changeEntries[] has item.path、changeType(add, edit, delete, rename) and changeTrackingId(used for inline comments). If the response has nextSkip , use %24skip={nextSkip} to fetch the next page.

  4. Generate the diff: the server does not provide a diff, so fetch the file contents of both versions and compare them locally. When there are more than 20 files, list them first and ask the user to choose or pick the key files based on risk.

    curl -sS -u ":$AZURE_DEVOPS_PAT" -o base.txt \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/items?path={filePath}&versionDescriptor.version={commonRefCommit}&versionDescriptor.versionType=commit&api-version=7.1"
    curl -sS -u ":$AZURE_DEVOPS_PAT" -o source.txt \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/items?path={filePath}&versionDescriptor.version={sourceRefCommit}&versionDescriptor.versionType=commit&api-version=7.1"
    git diff --no-index --unified=3 base.txt source.txt
    

    Without %24format , plain text content is returned. Added files return 404 on the base (TF401174), deleted files return 404 on the source: treat that side as an empty file. For binary files, just note "binary file changed". Put temporary files in the temp directory and delete them after use.

  5. Get the threads, keeping only threads whose comments[0].commentType is not systemand whose isDeleted is not true :

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/threads?api-version=7.1"
    

    status is active or pending means unresolved;threadContext.filePath and threadContext.rightFileStart.line are the positions of inline comments.

  6. Get the linked work items (returns value[].id), then use POST _apis/wit/workitemsbatch to get System.Title、System.State、System.WorkItemType:

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/workitems?api-version=7.1"
    
  7. Get the branch policy evaluation results.artifactId must use theproject GUID(the repository.project.idfrom step 1), not the project name:

    curl -sS -u ":$AZURE_DEVOPS_PAT" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/policy/evaluations?artifactId=vstfs:///CodeReview/CodeReviewId/{projectGuid}/{pullRequestId}&api-version=7.1-preview.1"
    

    This resource is only available in the preview version.configuration.isBlocking Those with true and whose status is not approved or notApplicable are the reasons the PR is blocked;configuration.type.displayName is the policy name.

Example: "Review PR 1234 in the Contoso project for me", "Why can't PR 1234 be merged yet?"

3. Look up a PR from a commit

curl -sS -u ":$AZURE_DEVOPS_PAT" -X POST -H "Content-Type: application/json" \
  "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repository}/pullrequestquery?api-version=7.1" \
  -d '{"queries":[{"type":"commit","items":["{commitSha}"]}]}'

This is a read-only query (returns HTTP 201 on success).type: commit Find the PRs that contain the commit;type: lastMergeCommit find the PRs merged with that commit.results[0] is the lookup table for { "<sha>": [PR, ...] } . The commit SHA must be the full 40 characters.

Example: "Which PR brought in commit 1a2b3c4?"

4. Comments, replies, resolving discussions, voting (writes)

Before each write action, list the content about to be sent (PR, file and line numbers, full comment text, vote value or status) for the user, and execute only after one confirmation. Present review comments you generate to the user first, and let the user decide whether to post them.

  • Add a general comment:

    curl -sS -u ":$AZURE_DEVOPS_PAT" -X POST -H "Content-Type: application/json" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/threads?api-version=7.1" \
      -d '{"comments":[{"parentCommentId":0,"content":"建議補上單元測試。","commentType":1}],"status":1}'
    
  • Add an inline comment: add location information to the above body.changeTrackingId comes from rule 2, step 3,secondComparingIteration is the id:

    "threadContext": {"filePath": "/src/app.cs", "rightFileStart": {"line": 42, "offset": 1}, "rightFileEnd": {"line": 42, "offset": 1}},
    "pullRequestThreadContext": {"changeTrackingId": 3, "iterationContext": {"firstComparingIteration": 1, "secondComparingIteration": 2}}
    
  • Reply to a thread:

    curl -sS -u ":$AZURE_DEVOPS_PAT" -X POST -H "Content-Type: application/json" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/threads/{threadId}/comments?api-version=7.1" \
      -d '{"parentCommentId":1,"content":"已修正,謝謝。","commentType":1}'
    
  • Change thread status(for example, mark as resolved):

    curl -sS -u ":$AZURE_DEVOPS_PAT" -X PATCH -H "Content-Type: application/json" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/threads/{threadId}?api-version=7.1" \
      -d '{"status":2}'
    

    Status values:1 active、2 fixed (resolved),3 wontFix、4 closed、5 byDesign、6 pending。

  • Vote({myId} comes from "current user"; if I am not yet a reviewer, I will be added automatically):

    curl -sS -u ":$AZURE_DEVOPS_PAT" -X PUT -H "Content-Type: application/json" \
      "https://dev.azure.com/$AZURE_DEVOPS_ORG/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/reviewers/{myId}?api-version=7.1" \
      -d '{"vote":10}'
    

    Vote values:10 approved,5 approved with suggestions,0 no vote (withdrawn),-5 waiting for author,-10 rejected.

Present the result

Votes are presented with emoji: ✅ approved (10), ☑️ approved with suggestions (5), ⏳ no vote (0), ⏸️ waiting for author (-5), ❌ rejected (-10). The PR link format is {repository.webUrl}/pullrequest/{pullRequestId}; branch names have refs/heads/。

PR listPresent as a table: PR ID (clickable link), title (append 📝 for draft), repository, author, target branch, my vote, creation date. For PRs "through groups waiting for my review", note the group name after the title.

Single PR reviewPresent in order:

  1. Summary: title, author, source → target branch, status (including draft,mergeStatus whether there are conflicts), whether auto-complete is set.
  2. Blocking reasons: list all blocking policies that have not passed; when all pass, clearly state that it can be merged.
  3. Reviewers: each reviewer and vote, whether they are a required reviewer (isRequired)。
  4. Changed files: table listing paths and change types, and the total number of files.
  5. Change highlights: summarize important changes file by file according to the diff, possible risks (error handling, security, compatibility, missing tests) and concrete suggestions; indicate that these are AI-generated review comments.
  6. Unresolved threads: author, file and line numbers, content summary; if there are none, state so clearly.
  7. Linked work items: ID (link https://dev.azure.com/{organization}/{project}/_workitems/edit/{ID}), type, title, status; if there are none, remind that the PR should link to a work item.