Review TUI mode

Updated Jul 27, 2026

Launch an interactive terminal interface for navigating and filtering review comments on a pull request:

frankie --tui --pr-url https://github.com/owner/repo/pull/123 --token ghp_example

The TUI uses bubbletea-rs to provide a keyboard-driven experience for reviewing comments.

Keyboard shortcuts

Table: Review list keyboard shortcuts.

Key Action
j, Move cursor down
k, Move cursor up
PgDn Page down
PgUp Page up
Home, g Go to first item
End, G Go to last item
f Cycle filter (All/Unresolved)
Esc Clear filter or exit context
c Open full-screen diff context
[ Previous diff hunk
] Next diff hunk
t Enter time-travel mode
s Generate PR discussion summary
a Start inline reply drafting
v Verify selected comment
V Verify filtered comments
x Run Codex on filtered comments
r Refresh from GitHub
? Toggle help overlay
q Quit

Time-travel mode keyboard shortcuts

Table: Time-travel mode keyboard shortcuts.

Key Action
h Navigate to previous (older) commit
l Navigate to next (newer) commit
Esc Exit time-travel mode
q Quit

PR discussion summary keyboard shortcuts

Table: PR discussion summary mode keyboard shortcuts.

Key Action
j, Move to the next summary item
k, Move to the previous summary item
PgDn Page down through summary items
PgUp Page up through summary items
Home, g Jump to the first summary item
End, G Jump to the final summary item
Enter Jump back to the linked comment detail view
Esc Return to the review list
? Toggle help overlay
q Quit

Background sync

The TUI automatically refreshes review comments from GitHub every 30 seconds. During a background sync:

  • New comments are added to the list
  • Updated comments are refreshed
  • Deleted comments are removed
  • The current selection is preserved (unless the selected comment was deleted)

A [Loading…] indicator appears in the header during sync. Manual refresh with r uses the same incremental sync logic.

Codex execution from the TUI

Press x in the review list to run codex app-server using the currently filtered comments as input. Frankie serializes the filtered comments as JSONL, starts Codex, and polls the process stream via the app-server JSON-RPC protocol.

During execution, the status bar switches from key hints to live Codex status updates. Each update is derived from streamed JSONL events (or from malformed line warnings when an event cannot be parsed).

Each run writes a transcript to:

  • ${XDG_STATE_HOME:-$HOME/.local/state}/frankie/codex-transcripts/

Transcript filenames follow this pattern:

  • <owner>-<repo>-pr-<number>-<utc-yyyymmddThhmmssZ>.jsonl

If Codex exits with a non-zero status, Frankie shows an explicit TUI error that includes the exit code (when available) and transcript path to aid diagnosis.

Session resumption

When the x key is used to start a Codex run, Frankie checks for an interrupted session from a previous run against the same pull request. If one is found, the status bar shows a prompt:

Interrupted session from 2026-02-15 10:00 UTC. Resume? [y/n]
  • Pressing y resumes the interrupted session. Frankie reconnects to the prior Codex server-side thread using the thread/resume JSON Remote Procedure Call (JSON-RPC) method. This preserves any approvals and conversation state from the interrupted run. New content is appended to the existing transcript file after a --- session resumed --- separator.
  • Pressing n or Esc declines the prompt and starts a fresh Codex run.

Session state is stored in JSON sidecar files alongside each transcript (<transcript-name>.session.json). These files record the thread ID, PR context, status, and timestamps. Interrupted sessions with a valid thread ID are eligible for resumption.

Inline reply drafting

Press a in the review list to start drafting a reply for the currently selected comment. The draft appears inline in the comment detail pane and is edited entirely from the keyboard.

In reply-draft mode:

  • Use keys 1 to 9 to insert template slots 1 to 9.
  • Use E to request AI expansion and W to request AI rewording.
  • Use Y to apply the current AI preview, or N to discard it.
  • Type any printable key to edit the draft text.
  • Use Backspace to delete one character.
  • Mark the draft as ready to send with Enter.
  • Discard the draft and return to the review list with Esc.

Draft length is enforced while typing and during template insertion. Frankie counts Unicode scalar values, not bytes. If a template or edit would exceed the configured maximum, the change is rejected and an inline error is shown.

Enter only marks the draft as ready to send in this phase. It does not post the reply to GitHub yet.

When AI rewrite succeeds, Frankie shows a side-by-side preview and labels the candidate as AI-originated before applying it. If the AI call fails, Frankie keeps the original draft and surfaces a fallback error.

Reply drafting can be configured through the same config layering as other Frankie settings:

  • --reply-max-length <COUNT> / FRANKIE_REPLY_MAX_LENGTH
  • --reply-templates '<json-array>' / FRANKIE_REPLY_TEMPLATES
  • reply_max_length and reply_templates in .frankie.toml

Filters

The TUI supports filtering review comments by several criteria:

  • All — Show all review comments
  • Unresolved — Show only comments that are not replies (root comments)
  • By file — Show comments on a specific file path
  • By reviewer — Show comments from a specific author
  • By commit range — Show comments within a commit range

Filters execute locally without requiring a full reload from GitHub. The cursor position is preserved when changing filters (clamped to valid range if the filtered list is shorter).

TUI display

The TUI displays:

  • Header — Application name with loading indicator when refreshing
  • Filter bar — Active filter with count of filtered vs total comments
  • Review list — Scrollable list with cursor indicator showing author, file, line number, and a preview of the comment body
  • Comment detail pane — Displays the selected comment with full body text and inline code context
  • Full-screen diff context — Dedicated view for navigating between diff hunks for the current review list selection
  • Status bar — Keyboard shortcut hints or error message if present

Comment detail view

When a comment is selected in the review list, the detail pane displays:

  • Comment header — Author name, file path, and line number
  • Comment body — Full text of the review comment
  • Code context — The diff hunk showing the code being reviewed, with syntax highlighting when available

Code context is extracted from the GitHub review comment's diff_hunk field and rendered with syntax highlighting based on the file extension. If the file type is not recognized or highlighting fails, the code is displayed as plain text.

Long code lines are wrapped to a maximum of 80 columns (or the terminal width if narrower) to ensure readability without horizontal scrolling.

Full-screen diff context

Pressing c in the review list opens a full-screen diff context view. The view shows the current diff hunk with file metadata and allows jumping between hunks using [ (previous) and ] (next). Pressing Esc returns to the review list without losing the current selection.

Time-travel mode

Time-travel mode displays the exact code state when a review comment was made. This is useful for understanding what was observed at the time a comment was left, especially when the code has changed significantly since then.

To enter time-travel mode:

  1. Select a review comment in the list
  2. Press t to enter time-travel mode

Frankie loads the commit snapshot associated with the comment and displays:

  • Commit information — SHA, message, author, and timestamp
  • File content — The file as it appeared at that commit
  • Line mapping status — Whether the commented line still exists and where

Line mapping verification shows one of these statuses:

  • Exact match — The line is at the same position in both commits
  • Moved — The line has moved to a different position (shows offset)
  • Deleted — The line no longer exists in the current commit
  • ? Not found — Unable to locate the line in the commit

Navigating commits

While in time-travel mode, the h and l keys navigate through the commit history:

  • h moves to the previous (older) commit
  • l moves to the next (newer) commit

The header shows the current position in the commit history (e.g., "Commit 2 of 5").

Requirements

Time-travel mode requires:

  • The selected review comment must carry both a commit SHA and a file path. Comments without these fields cannot be used for time travel.
  • A local Git repository (Frankie must be run from within the repository or the repository must be discoverable).
  • The commit SHA referenced by the comment must exist in the local repository.

The number of commits loaded into the history is controlled by the commit_history_limit configuration option (default 50). It can be set via .frankie.toml, the FRANKIE_COMMIT_HISTORY_LIMIT environment variable, or the --commit-history-limit CLI flag. Lower values speed up loading in repositories with long histories; higher values provide more navigation depth.

If these requirements are not met, Frankie displays a clear error message explaining what is missing.

Time-travel errors

  • No local repository — Displays "No local repository available. Clone the repository to use time-travel mode."
  • Commit not found — Displays "Commit not found in local repository. The commit may have been force-pushed away."