feat(desktop): reply to PR review threads from the Changes pane
Merged
AV
2mo ago+608+608+012345678901234567890123456789-94-94-01234567890123456789
Summary
- The workspace Changes pane can now reply to PR review threads and post them to GitHub, matching the PR view's Code tab. Each thread bubble gets a reply box (Cmd/Ctrl+Enter submits) and a Reply button beside Resolve.
- New workspace-scoped
git.replyToReviewThreadmutation. The GitHub call it shares withpullRequests.replyToThreadmoves into one helper so the two surfaces can't drift.
Why / Context
Review threads already rendered inline in the Changes pane with resolve/unresolve, but answering one meant leaving for the PR view or GitHub. The PR view had the full reply flow, so this ports that implementation over rather than inventing a second one.
How It Works
git.getPullRequestThreadsalready returns each comment's RESTdatabaseId;useDiffAnnotationsByPathnow puts the first comment's id on the thread metadata asreplyToCommentId.- DiffPane's
CommentThreadowns agit.replyToReviewThreadmutation. On send it clears the draft; on success it invalidates the workspace threads query, and the annotation version hash already includes comment count, so the new comment renders on the next refetch. On failure it toasts and hands the draft back (unless a new one was started). git.replyToReviewThreadlooks up workspace → linked PR row and posts viapulls.createReplyForReviewCommentusing the PR row's repo owner/name/number. A comment id from another PR 404s rather than landing somewhere unexpected.replyToReviewComment(new,git/utils) wraps the octokit call plusactionRejectionErrormapping;pullRequests.replyToThreadis refactored onto it.
Manual QA Checklist
Not run against the live app: no dev app was running from this worktree, and posting a real reply to GitHub is outward-facing. Worth a pass before merge:
- In a workspace linked to a PR with review comments, open the Changes pane: each thread shows the reply box under the comments
- Type a reply and click Reply (or Cmd+Enter): it appears on GitHub and shows in the thread within the 30s poll or on window focus
- Reply stays disabled while the draft is blank or a post is in flight
- With network off or a revoked token: "Couldn't post reply" toast and the draft comes back
- Resolve / Unresolve still work beside the new button
- Resolved and outdated threads still start collapsed; expanding shows the reply box
Testing
bun run typecheck(host-service and desktop)bun test src/trpc/router/git src/trpc/router/pull-requestsin host-service (145 pass). Newreply-to-review-thread.test.ts: happy path, blank body rejected before GitHub, no linked PR → NOT_FOUND, GitHub 404 → NOT_FOUNDbun teston the DiffPane tree in desktop (30 pass). NewCommentThread.test.tsx: submit + clear + invalidate, Cmd+Enter, disabled states, in-flight guard, orphaned thread keeps its draft, failure restores the draftbun run check:i18nclean. Every string the reply box uses already exists in all 17 locales from the PR view, so no catalog changesbun testin packages/i18n (enforced-dirs, display-only) andbiome checkon the changed files
Design Decisions
- PR row over
resolveGithubRepofor the reply target:getCheckJobLogsalready uses the PR row; it needs no remote parsing and names exactly the repo the comment ids came from. - Draft restore on failure: the PR view clears optimistically and can't restore because its reply is a prop callback. Here the component owns the mutation, so restoring is two lines. A small, deliberate divergence.
Follow-ups
- The resolve/unresolve GraphQL mutation is still duplicated between
git.setReviewThreadResolutionandpullRequests.setThreadResolution. The same shared-helper treatment would fit; left out to keep this focused.
https://claude.ai/code/session_01DQF36hf8kmYHRggDxFwXuk
Summary by cubic
Adds reply support for PR review threads in the workspace Changes pane, matching the PR view's Code tab. You can now type a reply in each thread and submit it to GitHub; previously the pane only allowed resolving/unresolving threads.
New Features
- Adds a reply box and Reply button to each thread bubble; Cmd/Ctrl+Enter also submits.
- New workspace-scoped
git.replyToReviewThreadmutation posts the reply to the linked PR. - Failed replies toast an error and restore your draft.
Refactors
- The reply box is now a shared
ReviewThreadReplyComposer, used by the Changes pane and the PR view's Code tab. - The GitHub reply call and error mapping now live in a shared helper used by
pullRequests.replyToThreadand the new mutation. - Thread metadata now carries the first comment's database id so replies thread onto the correct comment.
Summary by CodeRabbit
-
New Features
- Added the ability to reply directly to review comment threads in the diff view.
- Replies support trimmed text, Reply button, and Ctrl/Cmd+Enter submission.
- Drafts are preserved when posting fails, with controls disabled for blank drafts or while submitting.
- Reply controls are now consistent across diff and pull request review threads.
-
Bug Fixes
- Review replies are correctly associated with the selected comment thread.
-
Tests
- Added coverage for reply submission, validation, pending states, draft handling, and error scenarios.