How tuicr Syncs and Displays Remote PR Review Threads: Architecture and Implementation

tuicr synchronizes remote pull request review threads from GitHub, GitLab, or Bitbucket by fetching them through forge-specific backends, caching them in a unified model, and rendering them inline with diffs using a visibility-controlled filtering system.

The agavra/tuicr repository implements a terminal-based code review workflow that aggregates discussions from multiple forges into a unified interface. Understanding how tuicr syncs and displays remote PR review threads requires examining its three-stage pipeline that bridges remote APIs with local terminal rendering while maintaining cursor-accurate layouts.

Fetching Remote Threads via the ForgeBackend Trait

When a user executes tuicr pr open, the application initiates synchronization through the App::load_pr flow. This delegates to platform-specific backends that implement the ForgeBackend trait defined in src/forge/traits.rs (lines 470-484).

Each forge provides its own backend implementation:

These implementations override the list_review_threads method to execute platform-specific API calls, returning deserialized thread data for uniform processing.

// In the main event loop (simplified)
let pr = app.open_pr(target).await?;               // fetches PR details
let threads = backend.list_review_threads(&pr)?;   // remote fetch
app.forge_review_threads = remote_comments::dedupe_threads(threads);
app.session.remote_comments_visibility = PrCommentsVisibility::default(); // Unresolved

Normalizing Data in the Remote Comments Model

After fetching, tuicr converts platform-specific responses into vendor-agnostic structures defined in src/forge/remote_comments.rs. The central types include:

  • RemoteReviewThread: Represents a complete discussion thread with metadata
  • RemoteReviewComment: Individual comments containing author, body, and timestamp
  • RemoteReviewSummary: PR-level review summaries from maintainers
  • PrCommentsVisibility: Enum at lines 145-155 controlling display state (Unresolved, All, Hide)

The session stores fetched data in App::forge_review_threads and App::forge_review_summaries. Before storage, tuicr removes duplicates using dedupe_threads (lines 46-57), preventing redundant entries when refreshing PR data.

Rendering Threads with Cursor-Aware Layout

The display logic integrates with diff rendering in src/ui/diff_unified.rs (lines 13-20) and src/ui/diff_side_by_side.rs. During the render phase, the UI consults app.session.remote_comments_visibility (lines 182-190) to determine thread eligibility.

The rendering pipeline executes three critical steps:

  1. Filtering: filter_threads (lines 90-110) applies the visibility enum to include or exclude resolved discussions
  2. Layout Calculation: thread_display_lines or summary_display_lines (lines 196-210) compute vertical space requirements, ensuring cursor arithmetic remains accurate for terminal navigation
  3. Side Anchoring: RemoteCommentSide::Right or Left positions comments on the added or base side of the diff hunk

This architecture allows remote review threads to appear inline with code changes without disrupting the terminal's coordinate system.

Controlling Visibility with the :comments Command

Users manipulate thread visibility at runtime through the :comments command, which accepts Unresolved, All, or Hide arguments. The handler updates session state via set_remote_comments_visibility, immediately triggering a re-render with the new filter applied.

// Handler for the `:comments` command
match args[0] {
    "unresolved" => app.set_remote_comments_visibility(PrCommentsVisibility::Unresolved),
    "all"        => app.set_remote_comments_visibility(PrCommentsVisibility::All),
    "hide"       => app.set_remote_comments_visibility(PrCommentsVisibility::Hide),
    _ => {}
}

Exporting Remote Threads to Markdown

When users execute :clip or :export, the src/output/markdown.rs module (lines 11-20) processes both local and remote comments through the same pipeline. The exporter inserts a configurable header (default: "## Upstream") at lines 470-500, then converts RemoteReviewThread structures into markdown format alongside local review notes.

let export = Export::new(&app.session);
let markdown = export.to_markdown(); // injects remote_comments_header and threads
println!("{}", markdown);

Summary

  • tuicr fetches remote PR review threads through the ForgeBackend trait implemented by GitHub, GitLab, and Bitbucket backends in src/forge/
  • Raw API responses normalize into RemoteReviewThread and RemoteReviewComment structures in src/forge/remote_comments.rs, with deduplication handled by dedupe_threads
  • The PrCommentsVisibility enum controls display states (Unresolved, All, Hide) and persists across the review session in app.session
  • Diff renderers in src/ui/diff_unified.rs use filter_threads and thread_display_lines to calculate cursor-accurate layouts that anchor to RemoteCommentSide values
  • Remote threads export seamlessly via src/output/markdown.rs using the remote_comments_header configuration, ensuring upstream discussions appear in final review documents

Frequently Asked Questions

How does tuicr handle duplicate remote comments when reloading a PR?

tuicr removes duplicate entries using the dedupe_threads function in src/forge/remote_comments.rs (lines 46-57) before storing fetched data in App::forge_review_threads. This ensures that refreshing a pull request doesn't create redundant thread entries in the session cache.

Can tuicr display resolved review threads or only unresolved ones?

Users control visibility through the :comments command with three options: Unresolved (default), All, or Hide. The PrCommentsVisibility enum in src/forge/remote_comments.rs (lines 145-155) drives the filter_threads logic that determines which threads render in the diff view.

Which files handle the actual API calls to GitHub, GitLab, and Bitbucket?

Platform-specific implementations reside in src/forge/github/gh.rs (lines 350-360), src/forge/gitlab/glab.rs (lines 470-480), and src/forge/bitbucket/bkt.rs (lines 485-496). Each implements the list_review_threads method from the ForgeBackend trait defined in src/forge/traits.rs (lines 470-484).

How are remote threads positioned correctly in side-by-side diffs?

The renderer uses RemoteCommentSide::Right or Left to anchor comments to the appropriate diff side, while thread_display_lines in src/forge/remote_comments.rs (lines 196-210) calculates exact line heights. This ensures cursor arithmetic remains accurate in both unified and side-by-side modes defined in src/ui/diff_unified.rs and src/ui/diff_side_by_side.rs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →