codeant-resolve-pr-comments
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
- 01Supports GitHub, GitLab, Bitbucket, and Azure DevOps
- 02Fetches and filters unresolved inline suggestions
- 03Validates and classifies findings
- 04Requires approval before edits
- 05Verifies fixes before resolving threads
Use cases
- 01Find unresolved CodeAnt suggestions on a PR
- 02Review findings before making approved changes
- 03Verify fixes and resolve corresponding threads
- 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-commentsAfter installing, type/codeant-resolve-pr-commentsin Claude Code to confirm it loaded.
Details
From the project READMEResolve 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
- Run the preflight checks.
- Select exactly one provider adapter and fetch every result page.
- Keep only unresolved inline CodeAnt threads.
- Validate and classify every finding.
- Present the plan and obtain approval before editing.
- Apply approved fixes and run relevant verification.
- Resolve only threads whose fixes were applied and verified.
- Report results and offer to commit and push.
- 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.comor GitHub Enterprise: GitHub.gitlab.comor 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, orCodeAnt AI. - Its body contains a CodeAnt action URL beginning with
https://app.codeant.ai/fix-in-ideorhttps://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:
isResolvedisfalse.- The root comment matches the CodeAnt author-or-body filtering rule.
- The root comment has a non-null
path; useline, falling back tooriginalLineonly 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_noteisfalse.- 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: trueandresolved: false. - The note has a diff
positionwithnew_pathorold_path; prefernew_line, otherwise useold_linefor 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:
deletedis nottrueandpendingis nottrue.- It is a root comment, not a reply.
inline.pathis present; useinline.tofor the new-file line orinline.fromfor the old-file line.resolutionis null or absent.- The comment matches the CodeAnt author-or-body filtering rule using
user.nickname,user.display_name, orcontent.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:
- Check whether
AZURE_DEVOPS_PATis non-empty without printing or otherwise exposing its value. - 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
AZDOsignature 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.
- 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.
- Only when
AZURE_DEVOPS_PATis 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:
statusisactiveorpending.threadContext.filePathis present; userightFileStart.line, otherwiseleftFileStart.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, orcontent. 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:
- Read the complete comment and at least 30 lines above and below the referenced line.
- Inspect definitions, callers, tests, and repository guidance needed to understand the claimed behavior.
- Identify the defect, expected behavior, reproduction path, and any fenced suggestion.
- If the provider marks the position outdated, the file is gone, or current code no longer matches the claim, assign
STALEunless the same defect clearly remains at the referenced code. - Treat Architect Review and Logical Review comments as actionable. Read the complete
Prompt for AI Agentsection and draft a localized fix when no suggestion is supplied. - Validate syntax, scope, imports, types, error handling, public interfaces, edge cases, concurrency, and compatibility with callers.
- 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:
- Recheck
git status --shortand preserve pre-existing edits. - Apply only confirmed fixes to files referenced by comments, except narrowly required tests or imports.
- Review the diff for accidental changes and interactions between fixes.
- Run the narrowest relevant formatter, static checks, and tests; expand when shared behavior changed.
- 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 --shortand 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-clifor any step.