mcpField
C
codeant-resolve-pr-comments

codeant-resolve-pr-comments

github.com/codeant-aiTesting & quality347 installsUpdated 9w ago
Repository

About codeant-resolve-pr-comments

Resolve CodeAnt PR Comments is an agent skill for finding and handling unresolved inline CodeAnt suggestions on pull requests. It uses the configured source-control provider, requires approval before edits, verifies fixes before resolving threads, and avoids CodeAnt telemetry.

Key features

  1. 01Supports GitHub, GitLab, Bitbucket, and Azure DevOps
  2. 02Fetches and filters unresolved inline suggestions
  3. 03Validates and classifies findings
  4. 04Requires approval before edits
  5. 05Verifies fixes before resolving threads

Use cases

  1. 01Find unresolved CodeAnt suggestions on a PR
  2. 02Review findings before making approved changes
  3. 03Verify fixes and resolve corresponding threads
  4. 04Handle PR comments using configured provider access

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/codeant-ai/skills --skill codeant-resolve-pr-comments

After installing, type/codeant-resolve-pr-commentsin Claude Code to confirm it loaded.

Details

From the project README

Resolve CodeAnt PR Comments

Use the source-control provider as the source of truth for PR metadata, review comments, and thread state. Never install, update, invoke, or fall back to codeant-cli. Never send CodeAnt telemetry.

Workflow

  1. Run the preflight checks.
  2. Select exactly one provider adapter and fetch every result page.
  3. Keep only unresolved inline CodeAnt threads.
  4. Validate and classify every finding.
  5. Present the plan and obtain approval before editing.
  6. Apply approved fixes and run relevant verification.
  7. Resolve only threads whose fixes were applied and verified.
  8. Report results and offer to commit and push.
  9. After all PR work is complete, perform the one-request skill update check.

1. Preflight

Inspect the repository without modifying it:

git status --short
git branch --show-current
git remote -v

Preserve all pre-existing changes. Detect the provider from the remote host:

  • github.com or GitHub Enterprise: GitHub.
  • gitlab.com or self-managed GitLab: GitLab.
  • bitbucket.org: Bitbucket Cloud.
  • Another Bitbucket Server/Data Center host: Bitbucket Data Center.
  • dev.azure.com, ssh.dev.azure.com, or *.visualstudio.com: Azure DevOps.

If detection is ambiguous, ask which provider hosts the PR. If the user supplied a PR/MR URL or number, use it. Otherwise find an open PR whose source branch exactly equals the current branch. If on the default branch, require a PR number or URL. If zero or multiple exact matches exist, stop and ask the user to identify the PR.

Use already-configured provider authentication. Do not probe multiple authentication methods during preflight; follow the selected provider adapter's authentication precedence. Do not install CLIs, expose tokens, print credential-bearing headers, or put secrets in generated files. If authentication is missing, name the required provider login/token and stop.

Filter CodeAnt suggestions

After fetching the PR's review comments, retain only unresolved inline suggestions generated by CodeAnt. Treat an inline comment as CodeAnt-generated when either condition is true:

  • Its author login, username, nickname, or display name case-insensitively equals codeant-ai, codeant-ai[bot], codeant-bot, or CodeAnt AI.
  • Its body contains a CodeAnt action URL beginning with https://app.codeant.ai/fix-in-ide or https://app.codeant.ai/feedback.

Use the body signature because GitLab and Azure DevOps can attribute CodeAnt comments to the connected human account. Do not require a bot author when the body signature matches, and do not run a separate identity-discovery or confirmation step. Do not classify a comment from the word CodeAnt alone; require an exact service-account name or CodeAnt action URL.

Skip general PR comments, summaries, quality-gate reports, system messages, deleted comments, drafts, and replies that do not begin an inline finding. If no matching suggestions remain, report that the PR has no unresolved CodeAnt inline suggestions and stop. Otherwise continue directly to validation.

2. Provider adapters

Choose only the matching adapter. Normalize each actionable item to:

thread_id, comment_id, author_id, body, path, line, url,
resolved, outdated_or_stale, provider

Retain provider-native IDs exactly because they are required for resolution.

GitHub

Require authenticated gh. Determine the PR and repository:

gh auth status
gh pr view <number-or-url> --json number,title,url,state,headRefName,baseRefName
gh repo view --json nameWithOwner --jq .nameWithOwner

Without a PR number, try gh pr view on the current branch. If necessary, list exact branch matches:

gh pr list --head "<branch>" --state open \
  --json number,title,url,state,headRefName,baseRefName

Fetch and paginate review threads with GitHub GraphQL. Use --paginate --slurp; the pagination variable must be named $endCursor:

gh api graphql --paginate --slurp \
  -f owner='<owner>' \
  -f name='<repository>' \
  -F number=<pr-number> \
  -f query='query($owner: String!, $name: String!, $number: Int!, $endCursor: String) {
    repository(owner: $owner, name: $name) {
      pullRequest(number: $number) {
        number title url
        reviewThreads(first: 100, after: $endCursor) {
          nodes {
            id isResolved isOutdated
            comments(first: 100) {
              nodes {
                databaseId
                author { login }
                body path line originalLine createdAt url
              }
            }
          }
          pageInfo { hasNextPage endCursor }
        }
      }
    }
  }'

Retry this read-only fetch up to three times for transient HTTP 429, 502, 503, or 504 responses, honoring Retry-After when present. Do not retry authentication, authorization, schema, or validation errors.

Across every returned page, keep a thread only when:

  • isResolved is false.
  • The root comment matches the CodeAnt author-or-body filtering rule.
  • The root comment has a non-null path; use line, falling back to originalLine only to locate historical context.

Carry isOutdated into stale validation. Resolve a successfully fixed thread with its GraphQL thread node ID, not the numeric comment ID:

gh api graphql \
  -f threadId='<thread-node-id>' \
  -f query='mutation($threadId: ID!) {
    resolveReviewThread(input: {threadId: $threadId}) {
      thread { id isResolved }
    }
  }'

Require the response to confirm isResolved: true.

GitLab

Require authenticated glab. A GitLab merge request IID is project-local; do not confuse it with a global database ID.

glab auth status
glab mr view <iid-or-url> --output json
glab repo view --output json

Without an IID, find the sole open MR whose source_branch exactly matches the current branch:

glab mr list --source-branch "<branch>" --state opened --output json

Use the numeric project ID returned by glab repo view to avoid path-encoding errors. Fetch all discussion pages:

glab api --paginate \
  "projects/<project-id>/merge_requests/<mr-iid>/discussions?per_page=100"

Keep a discussion only when:

  • individual_note is false.
  • Its root note matches the CodeAnt author-or-body filtering rule. GitLab may show the connected human user as the author, so accept a matching CodeAnt action URL in body.
  • The CodeAnt root note is resolvable: true and resolved: false.
  • The note has a diff position with new_path or old_path; prefer new_line, otherwise use old_line for context.

Carry the discussion id as thread_id and the root note id as comment_id. Resolve a successfully fixed discussion:

glab api --method PUT \
  "projects/<project-id>/merge_requests/<mr-iid>/discussions/<discussion-id>" \
  -f resolved=true

Require the returned discussion to show the relevant resolvable note as resolved.

Bitbucket Cloud

Use the Bitbucket Cloud REST API 2.0 with existing OAuth, access-token, or API-token authentication. Parse <workspace>/<repo-slug> from the remote or PR URL. Never echo the credential.

If no PR number was supplied, list open PRs and select the sole exact source.branch.name match. Use URL encoding for query values:

GET https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests
    ?state=OPEN&pagelen=100

Fetch all comment pages and follow the response's next URL until it is absent:

GET https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests/<pr-id>/comments
    ?pagelen=100

Keep a comment only when:

  • deleted is not true and pending is not true.
  • It is a root comment, not a reply.
  • inline.path is present; use inline.to for the new-file line or inline.from for the old-file line.
  • resolution is null or absent.
  • The comment matches the CodeAnt author-or-body filtering rule using user.nickname, user.display_name, or content.raw.

Retain the root comment id. Resolve a successfully fixed thread:

POST https://api.bitbucket.org/2.0/repositories/<workspace>/<repo-slug>/pullrequests/<pr-id>/comments/<comment-id>/resolve
Accept: application/json

Require HTTP 200 and a returned resolution object. Never delete the comment as a substitute for resolving it.

Bitbucket Data Center

Use the host's /rest/api/latest API with existing bearer, personal-access-token, or session authentication. Parse <base-url>, <project-key>, and <repo-slug> from the remote or PR URL.

If no PR ID was supplied, paginate open PRs and select the sole item whose fromRef.displayId exactly matches the current branch:

GET <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests
    ?state=OPEN&limit=100&start=<offset>

Follow nextPageStart until isLastPage is true. Fetch all comment pages the same way:

GET <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests/<pr-id>/comments
    ?limit=100&start=<offset>

Keep root comments that match the CodeAnt author-or-body filtering rule using author.name, author.slug, author.displayName, or text, and whose anchor.path is present, pending is not true, state is OPEN, and threadResolved is false. Use anchor.line and the full anchored path.

To resolve a successfully fixed thread, first refetch the comment to obtain its current version, then update it with optimistic concurrency:

PUT <base-url>/rest/api/latest/projects/<project-key>/repos/<repo-slug>/pull-requests/<pr-id>/comments/<comment-id>
Content-Type: application/json

{
  "id": <comment-id>,
  "version": <current-version>,
  "text": <unchanged-current-text>,
  "state": "OPEN",
  "severity": <unchanged-current-severity>,
  "threadResolved": true
}

Preserve the current text, state, severity, and required properties. On HTTP 409, refetch and retry only if the thread is still the same unresolved comment. Require the response to show threadResolved: true.

Azure DevOps (ADO)

Use Azure DevOps REST API 7.1. Parse the organization, project, and repository from the remote or PR URL. Prefer immutable repository and identity IDs.

Apply this authentication precedence before making the first request:

  1. Check whether AZURE_DEVOPS_PAT is non-empty without printing or otherwise exposing its value.
  2. If it is present, normalize it locally before authentication:
    • Treat the original value as the PAT by default.
    • Consider it Base64-encoded only when it uses canonical standard Base64 syntax (allowing omitted trailing padding), strict decoding succeeds, and decoding then re-encoding produces the same value after padding normalization.
    • Use the decoded value only when it is a recognized Azure DevOps PAT: either the legacy 52-character format or the current 84-character format with the fixed AZDO signature at its documented position. Also accept a decoded HTTP Basic payload of <username>:<PAT> when the portion after the first colon matches one of those PAT formats; use only the PAT portion as the password.
    • Otherwise leave the original value unchanged. Never make trial API requests to decide whether the value is encoded. Use the resulting PAT immediately as the password for HTTP Basic authentication. Skip Azure CLI, Azure DevOps CLI, credential-manager, and other authentication discovery. Decode and construct authorization values only in memory; never print the PAT or credential-bearing header or write either to a file.
  3. If a PAT-authenticated request returns HTTP 401 or 403, report that the PAT is invalid, expired, lacks access, or has insufficient scope, and stop. Do not silently fall back to another identity because that can mask PAT configuration errors and access resources as an unintended user.
  4. Only when AZURE_DEVOPS_PAT is absent, use an already-configured OAuth or Microsoft Entra token. Do not start an interactive login. If no non-interactive credential is already available, identify the missing authentication and stop.

If no PR ID was supplied, URL-encode the full source ref and select the sole active exact match:

GET https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullrequests
    ?searchCriteria.status=active
    &searchCriteria.sourceRefName=refs/heads/<branch>
    &$top=100
    &api-version=7.1

Fetch PR threads:

GET https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullRequests/<pr-id>/threads
    ?api-version=7.1

Keep a thread only when:

  • status is active or pending.
  • threadContext.filePath is present; use rightFileStart.line, otherwise leftFileStart.line.
  • Its root non-system, non-deleted comment has commentType: text.
  • The root comment matches the CodeAnt author-or-body filtering rule using author.uniqueName, author.displayName, or content. Azure DevOps may show the connected human user as the author.

Carry the numeric thread id and root comment id. Resolve a successfully fixed thread by marking it fixed:

PATCH https://dev.azure.com/<organization>/<project>/_apis/git/repositories/<repository-id>/pullRequests/<pr-id>/threads/<thread-id>
Content-Type: application/json

{"status":"fixed"}

Use api-version=7.1 and require the returned thread to show status: fixed. Do not use closed, wontFix, or byDesign for an applied fix.

3. Validate every finding

Group findings by file. For each finding:

  1. Read the complete comment and at least 30 lines above and below the referenced line.
  2. Inspect definitions, callers, tests, and repository guidance needed to understand the claimed behavior.
  3. Identify the defect, expected behavior, reproduction path, and any fenced suggestion.
  4. If the provider marks the position outdated, the file is gone, or current code no longer matches the claim, assign STALE unless the same defect clearly remains at the referenced code.
  5. Treat Architect Review and Logical Review comments as actionable. Read the complete Prompt for AI Agent section and draft a localized fix when no suggestion is supplied.
  6. Validate syntax, scope, imports, types, error handling, public interfaces, edge cases, concurrency, and compatibility with callers.
  7. Prefer the smallest correct fix. Do not refactor adjacent code for style.

Assign exactly one verdict:

  • ACCEPT: The defect is real and the localized fix is safe without changing a public contract or weakening handling.
  • LIKELY ACCEPT: The fix is sound, but a behavior change may affect callers or requires targeted validation.
  • DO NOT ACCEPT: The proposal is unsafe, unjustified, depends on unavailable APIs, or requires broader design work than a focused patch can safely provide.
  • STALE: The referenced code or defect is no longer present.

Do not reject an Architect or Logical Review solely because it lacks a ready-made patch.

4. Present the plan before editing

Report the provider, PR number, title, link, and unresolved CodeAnt inline-thread count. Group every finding by verdict. For each, include:

  • File and line.
  • One-line issue summary.
  • Validation rationale.
  • Intended before/after change when applicable.
  • For LIKELY ACCEPT, the exact callers, tests, or behavior needing verification.

State that ACCEPT fixes are ready and ask whether to include named LIKELY ACCEPT fixes. Do not edit before approval. Never apply DO NOT ACCEPT or STALE findings.

5. Apply and verify

After approval:

  1. Recheck git status --short and preserve pre-existing edits.
  2. Apply only confirmed fixes to files referenced by comments, except narrowly required tests or imports.
  3. Review the diff for accidental changes and interactions between fixes.
  4. Run the narrowest relevant formatter, static checks, and tests; expand when shared behavior changed.
  5. Repair only failures caused by these edits. If a fix cannot be verified, revert only that fix if safely separable, leave its thread unresolved, and report it.

6. Resolve and report

Resolving a thread is an external mutation. Resolve threads sequentially only after the user approved the corresponding fix and local verification passed. Continue after individual resolution failures.

Never resolve DO NOT ACCEPT, STALE, skipped, partially fixed, or unverified findings. Refetch thread state after resolution when the provider response is ambiguous.

Final report:

  • Applied and verified fixes with file, line, verdict, and test result.
  • Unapplied findings with verdict and reason.
  • Provider thread IDs resolved and any resolution failures.
  • Final git status --short and files changed by this workflow.

Offer to commit and push selected files. Do not commit or push without explicit approval.

7. Check for a skill update

Run this best-effort check only after all PR work is complete and the final report is prepared, but before sending that report. It must never delay, change, or invalidate the PR workflow.

Resolve the path of the currently loaded codeant-resolve-pr-comments/SKILL.md without scanning unrelated directories. If its path cannot be determined or the file is not writable, skip the check silently. Otherwise make exactly one unauthenticated GitHub API request, saving its raw response to a temporary file:

curl --fail --silent --show-error \
  --connect-timeout 2 --max-time 5 \
  -H 'Accept: application/vnd.github.raw+json' \
  -H 'X-GitHub-Api-Version: 2022-11-28' \
  'https://api.github.com/repos/CodeAnt-AI/skills/contents/skills/codeant-resolve-pr-comments/SKILL.md?ref=main' \
  -o '<temporary-file>'

Do not make a second request, follow up through releases, commits, tags, or package managers, or retry a failed request. Before using the response, require HTTP success and verify that it is a plausible skill file: it must begin with YAML frontmatter, declare exactly name: codeant-resolve-pr-comments, contain # Resolve CodeAnt PR Comments, and contain exactly one <!-- codeant-skill-version: <positive-integer> --> marker.

Compare the remote marker with the current file's marker locally. If the remote version is equal to or lower than the current version, delete the temporary file and add only Skill update: already current to the final report. If the remote version is higher, atomically replace only the current skill file, preserve its existing permissions, delete the temporary file, and add Skill update: updated; the new instructions apply next session to the final report. Never overwrite a newer local version. If validation, comparison, or replacement fails, remove the temporary file when possible and add one concise non-blocking note; do not retry.

Guardrails

  • Fetch every pagination page before claiming the list is complete.
  • Treat provider-native thread state as authoritative.
  • Validate suggestions individually; never batch-apply blindly.
  • Preserve unrelated user changes and avoid unrelated files.
  • Flag conflicting comments rather than choosing silently.
  • Never disclose access tokens, PATs, cookies, or verbose auth output.
  • Never install, invoke, or rely on codeant-cli for any step.

Comments

Markdown supported