| name | branchdiff-resolve |
| description | Read open review comments and resolve them by making code fixes. Use this skill when the user asks to fix review comments, resolve threads, address feedback, or handle code review findings. Also triggers for "fix the issues", "address the review", "resolve comments", or any request to act on code review feedback from branchdiff. |
| user-invocable | true |
branchdiff Resolve Skill
You are reading open review threads and resolving them by making the code changes they ask for.
Resolve is local-only
branchdiff agent resolve and dismiss change local review state only — they never post to or mutate the remote PR (GitHub/Bitbucket). Remote resolution is opt-in via --sync (off by default). Do not push, sync, or resolve anything remotely from this skill unless --sync was explicitly requested.
Arguments
url (optional, preferred) — one of three forms:
- branchdiff URL —
http://localhost:5391/diff?b1=origin%2Fdevelopment&b2=origin%2Ffeature&mode=git. The session is already running: take host+port from it, URL-decode b1/b2, and note includeStaged=1/includeUnstaged=1 if present (they mirror the browser's working-changes checkboxes — when set, read an uncommitted file with agent file --staged or no --ref, never --ref <b2>, same as the review skill).
- GitHub PR URL —
https://github.com/owner/repo/pull/123. Auto-creates a session.
- Bitbucket PR URL —
https://bitbucket.org/workspace/repo/pull-requests/123. Same.
thread-id (optional): resolve one thread instead of every open one — /branchdiff-resolve abc123.
ref (optional, fallback): the git ref that was reviewed. A matching live session is reused; otherwise a new one starts. Single ref (HEAD~3, main, v1.0.0), range (main..feature), or two refs (main feature). Defaults to the working tree.
instructions (optional): free-form guidance for this pass, e.g. "skip anything under ai/", "only fix must-fix threads". Apply it in addition to the workflow below.
notify (optional, default off): fire desktop toasts (resolve started / complete) via branchdiff agent notify, so the user is pinged even away from the chat. Standalone only — see the gate under Instructions. Best-effort; silently skipped if the OS has no notifier.
Session isolation (MANDATORY — do this before any branchdiff agent call)
Several branchdiff sessions run at once on one repo (two PRs in two terminals, or several automated passes in parallel). Work on exactly one and never drift onto another PR's session.
Resolve your session selector once, before anything else. Every command below is written with a $SEL placeholder — compute it first and pass it on every call. Do not rely on inherited environment: a sub-shell, a background Bash call, or a nested agent may not see it.
SEL="--session $BRANCHDIFF_SESSION_ID"
SEL="--port $BRANCHDIFF_PORT"
branchdiff list --repo
SEL="--port <that one port>"
CLI Reference
branchdiff agent diff [--include-staged] [--include-unstaged] $SEL
branchdiff agent file <path> [--ref <ref> | --staged] $SEL
branchdiff agent list [--status open|resolved|dismissed] [--json] $SEL
branchdiff agent comment --file <path> --line <n> [--end-line <n>] [--side new|old] --body "<text>" $SEL
branchdiff agent general-comment --body "<text>" $SEL
branchdiff agent resolve <id> [--summary "<text>"] [--sync] $SEL
branchdiff agent dismiss <id> [--reason "<text>"] [--sync] $SEL
branchdiff agent reply <id> --body "<text>" $SEL
branchdiff agent refresh [--allow-stale] $SEL
branchdiff agent notify "<title>" "<body>" [--open-url <url>]
--file, --line, --body are required for comment
--end-line defaults to --line (single-line comment)
--side defaults to new
general-comment creates a diff-level comment not tied to any file or line
<id> accepts full UUID or 8-char prefix
resolve/dismiss are local-only; --sync also resolves the thread on the remote PR — pass it only when the user asked for it
agent diff --include-staged/--include-unstaged and agent file --staged only apply when your checked-out branch is b1 or b2 of the current session — otherwise they no-op with a warning, since staged/unstaged content doesn't belong to either side of an unrelated branch pair
Prerequisites
-
branchdiff must be runnable. Run which branchdiff. Not found, but a PATH hint was appended below (automated runs add one)? export PATH with it and retry before installing anything. Still not found: npm install -g @encryptioner/branchdiff. If that also fails (no network or permission in this sandbox), STOP and report the exact error. Same rule if a branchdiff agent command that worked a moment ago starts failing mid-pass: STOP. Never fall back to reading, reviewing or fixing the checkout by hand — manual work posts nothing branchdiff can track or dedupe, and reposts as a duplicate on the next automated pass.
-
Get a session. Start commands run via the Bash tool with run_in_background: true; then wait and verify with branchdiff agent list $SEL.
- branchdiff URL — the server is already running, so just verify. Only if no session is live (or its refs don't match b1/b2), start one:
branchdiff <b1> <b2> --no-open (e.g. branchdiff origin/development origin/feature --no-open; wait 2 seconds).
- PR URL —
branchdiff <pr-url> --no-open checks the PR out, derives the base/compare refs, and starts the session; wait 5–15 seconds (network calls). Needs gh installed and authenticated (gh auth status) for GitHub, or BITBUCKET_USERNAME + BITBUCKET_API_TOKEN for Bitbucket.
ref only — branchdiff --no-open (working tree), branchdiff HEAD~3 --no-open (a ref), or branchdiff <base> <compare> --no-open (branch comparison); wait 2 seconds. Or run /branchdiff-review first — it starts the session.
Need more context?
Unsure about a command, flag, or workflow detail? branchdiff review guide prints the full agent reference — CLI commands, review/resolve workflows, multi-instance safety rules, and the import JSON schema. Read it before proceeding.
Where your edits land (MANDATORY — settle this before the first Edit)
Reviewing only reads; resolving writes. An edit goes to whatever tree you are standing in, and that is not always the branch that was reviewed.
Do not gate on the branch name. Fixing on a branch other than b2 is routine: the fix may belong on a branch that later merges into b2, on a rebased or renamed successor, on a shared base several review branches feed from, or b2 may already be merged into where you stand. A name check rejects all of those. What matters is whether the code the comment is about is present in the tree you are editing.
-
Get the reviewed refs — BD_B1/BD_B2 if set, else the session's b1/b2 from branchdiff agent list --json $SEL.
-
If BD_WORKTREE is set, do not edit there. That directory is a detached checkout branchdiff made so the reviewer could read b2 without disturbing your branch. Commits made in it belong to no branch and are lost on the next prune — change directory to a real checkout first.
-
Establish that the reviewed code is here.
git merge-base --is-ancestor <b2> HEAD && echo "contains b2"
Succeeds → HEAD already contains every reviewed commit; edit here (this also covers "b2 was merged into this branch"). Otherwise decide per file, not per branch: fetch the reviewed copy and compare it against the one on disk.
branchdiff agent file <path> --ref <b2> $SEL
- Identical → the reviewed code is here verbatim. Edit here.
- Different, but the code the comment describes is present → the branches diverged elsewhere; the finding still applies. Edit here, judging against the surrounding code you actually see.
- The code the comment describes is absent → do not guess. See step 5.
If that fetch errors ("does not exist at ref") and the URL that started this session had includeStaged/includeUnstaged set, the file was staged or unstaged when reviewed, not committed — re-fetch with agent file <path> --staged $SEL or agent file <path> $SEL (no --ref) before comparing.
-
Locate findings by code, not by line number. Line numbers come from the b1→b2 diff and are valid only there — on any other branch, and on b2 itself after later commits, they point at the wrong place. Find the code the comment quotes or describes, confirm it is the same construct, and fix that; if you cannot find it, treat it as absent. A file that has moved on may also mean the issue is already fixed — check before editing, and if it is, resolve the thread with a summary saying so instead of changing anything.
-
A thread you cannot place stops that thread, not the run. Do not check anything out yourself; the user may have uncommitted work. Reply on the thread saying the code was not found in the current tree, naming the branch you are on and the reviewed ref, then move to the next thread. Report the unplaced threads at the end.
Instructions
Notifications (--notify). Fire branchdiff agent notify toasts only when the user passed --notify and the BRANCHDIFF_PASS_ID environment variable is unset (you are standalone). If it is set, branchdiff auto is driving you and already fires its own toasts — skip every agent notify call. Reuse the session URL you already have from Prerequisites (given in a branchdiff URL, or printed in the startup banner) for --open-url; never call branchdiff list just to fire a toast.
Start toast (once, before Step 1, when notifications are active):
branchdiff agent notify "branchdiff: resolve started" "<PR # or ref pair>" --open-url <session-url>
Step 1: List open threads
branchdiff agent list --status open --json $SEL
The JSON carries each thread's full comment body, file path, line numbers, and side. Filter to the thread-id argument if one was given. No open threads → tell the user there is nothing to resolve.
Step 2: Process each thread
Use subagents when your runtime has them and enough threads are independent (Claude Code's Task tool, or an equivalent parallel-task mechanism) — one per thread, never two on the same file. A subagent reads, edits, and reports back what it changed; it never calls agent resolve/dismiss/reply itself, so exactly one actor mutates thread state: you, after reading its report. A handful of threads, or threads sharing a file, are cheaper done sequentially.
For each open thread, check the comments array and author.type field ("user" or "agent"):
a. Skip general comments (filePath __general__) — summaries, not actionable code changes.
b. Skip threads whose last comment is an agent reply asking the user a question ("Could you clarify...?") with no user answer yet — the agent is waiting on input. Threads where the agent left the original finding are actionable; process those.
b'. Resolve directly, no code change, if the last comment is a human sign-off. Most recent comment has author.type: "user" and signals agreement or closure ("fixed", "done", "ok", "lgtm", "not needed", "wontfix", "nvm", "please close", "thanks")? The commenter already made the call, whether or not you can find a matching code change:
branchdiff agent resolve <thread-id> --summary "Resolved per <name>'s reply: \"<their words>\"" $SEL
Move on — skip c–e for this thread.
c. Read the comment body and act on its intent: a suggested code change → make it; a docs suggestion → write the docs; a question implying action ("should we add X?") → treat it as a request to do that. Genuinely unclear → ask:
branchdiff agent reply <thread-id> --body "Could you clarify what change you'd like here?" $SEL
d. Read the source file and find the construct the comment is about — search for the code it quotes or names rather than jumping to line, which is only accurate on b2 at review time. Read enough surrounding context to be sure it is the same construct, then edit.
e. Resolve the thread with a summary:
branchdiff agent resolve <thread-id> --summary "Fixed: <brief description>" $SEL
Valid concern but the fix should not be applied now? Dismiss instead:
branchdiff agent dismiss <thread-id> --reason "<why it won't be addressed>" $SEL
Project rules
Before editing, read every relevant CLAUDE.md (or GEMINI.md, AGENTS.md) — the root one and any in directories holding files you will change. They define import conventions, naming and type rules, framework patterns, build/test commands, and architecture constraints. Fixes MUST comply. If a comment suggests a change that violates a project rule, apply its intent using the project's convention instead.
If you have not yet run the "Where your edits land" checks, do them now — an edit in a detached review worktree is silently thrown away, and an edit at the comment's line number on a diverged branch lands in the wrong place.
Step 3: Verify the fixes before resolving
A resolved thread is a claim that the code now works. Check it:
- Run the project's own checks — build, typecheck, lint, test as named in CLAUDE.md (or the
scripts block of package.json / equivalent). Take the narrowest relevant one, not the full suite, unless the change is broad.
- A failure caused by your edit → fix it before resolving the thread.
- A failure that predates your edit → leave it alone and say so in the resolve summary. Do not expand the change to chase unrelated breakage.
- No runnable checks in the project → say that in your final message rather than implying the fixes were verified.
Only resolve threads whose fix you have actually exercised.
Step 4: Confirm and surface the session
branchdiff agent list $SEL
branchdiff list --repo
Verify every applicable thread is resolved, then take the URL fresh from branchdiff list --repo (scoped to this repo, not every session on the machine — never a port you recall from earlier) and always print it back to the user so they can jump straight to the browser view.
Completion toast (when notifications are active, once you have the counts — reuse the start toast's URL):
branchdiff agent notify "branchdiff: resolve done" "Resolve complete — N resolved, M remaining" --open-url <session-url>
Resolved N threads. Resolved status appears in the browser within ~2 seconds.
Session:
Notes
- Use the 8-char prefix of the thread
id as <thread-id>
- A thread can be resolved even if the fix is on a different line than the original comment
- Use
--reason in dismiss to leave context for other reviewers
- Run
branchdiff agent list --status resolved to see everything that has been resolved