<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Parley Docs</title>
<meta
name="description"
content="Parley docs for terminal-first review workflow, TUI controls, and MCP automation."
/>
<script>
(() => {
const saved = localStorage.getItem("parley-docs-theme");
document.documentElement.dataset.theme =
saved === "light" || saved === "dark" ? saved : "dark";
})();
</script>
<link rel="stylesheet" href="/vendor/system.css/system.css" />
<link rel="stylesheet" href="/app.css" />
</head>
<body>
<script>
window.__PARLEY_DOCS__ = [
{
"slug": "overview",
"title": "Parley Overview",
"summary": "Parley is a terminal-first review tool for local git diffs, optimized for iterative AI-assisted code review.",
"headings": [
{
"depth": 1,
"text": "Parley Overview",
"id": "parley-overview"
},
{
"depth": 2,
"text": "Core model",
"id": "core-model"
},
{
"depth": 2,
"text": "How to think about the app",
"id": "how-to-think-about-the-app"
},
{
"depth": 2,
"text": "Thread model at a glance",
"id": "thread-model-at-a-glance"
},
{
"depth": 2,
"text": "Review model at a glance",
"id": "review-model-at-a-glance"
},
{
"depth": 2,
"text": "AI eligibility summary",
"id": "ai-eligibility-summary"
},
{
"depth": 2,
"text": "Typical session",
"id": "typical-session"
},
{
"depth": 2,
"text": "Revision sources",
"id": "revision-sources"
},
{
"depth": 1,
"text": "everything after HEAD~2 (exclude that commit)",
"id": "everything-after-head2-exclude-that-commit"
},
{
"depth": 1,
"text": "everything after and including HEAD~2",
"id": "everything-after-and-including-head2"
},
{
"depth": 2,
"text": "File references in comment drafts",
"id": "file-references-in-comment-drafts"
},
{
"depth": 2,
"text": "Local state and diff filtering",
"id": "local-state-and-diff-filtering"
},
{
"depth": 2,
"text": "What `pending` means",
"id": "what-pending-means"
},
{
"depth": 2,
"text": "Completion behavior",
"id": "completion-behavior"
}
],
"html": "<h1 id=\"parley-overview\">Parley Overview</h1>\n<p>Parley is a terminal-first review tool for local git diffs, optimized for iterative AI-assisted code review.</p>\n<p>Review discussions are anchored to concrete diff lines, and both thread state and review state are explicit.</p>\n<h2 id=\"core-model\">Core model</h2>\n<ul>\n<li><strong>Threaded line review</strong>: each comment thread is anchored to file path + line reference.</li>\n<li><strong>Thread lifecycle</strong>: <code>open</code>, <code>pending</code>, <code>addressed</code>.</li>\n<li><strong>Review lifecycle</strong>: <code>open</code>, <code>under_review</code>, <code>done</code>.</li>\n<li><strong>Keyboard-first workflow</strong>: full navigation and review operations without leaving the terminal.</li>\n<li><strong>Optional AI automation</strong>: run AI thread replies/refactors while keeping state transitions human-controlled.</li>\n</ul>\n<h2 id=\"how-to-think-about-the-app\">How to think about the app</h2>\n<p>Parley is not just a diff viewer and not just a notes file.</p>\n<p>It combines:</p>\n<ul>\n<li>a diff source: working tree, commit, or range</li>\n<li>a local review session: named review metadata stored under <code>.parley/</code></li>\n</ul>\n<p>Each review is its own context. Switching reviews changes the comment threads, replies, and review status shown in the TUI; it does not change the active diff source.</p>\n<p>That review session tracks threads as structured objects with:</p>\n<ul>\n<li>an anchor line in the diff</li>\n<li>an original author</li>\n<li>a thread status</li>\n<li>ordered replies</li>\n</ul>\n<p>This is why status changes are opinionated:</p>\n<ul>\n<li>new thread -> <code>open</code></li>\n<li>reply from the original commenter -> <code>open</code></li>\n<li>reply from anyone else, including AI -> <code>pending</code></li>\n<li>original commenter marks resolution -> <code>addressed</code></li>\n</ul>\n<p>The review state is then derived from the unresolved thread set until you explicitly set it to <code>done</code>.</p>\n<h2 id=\"thread-model-at-a-glance\">Thread model at a glance</h2>\n<ul>\n<li>A thread starts as <code>open</code> when a comment is created.</li>\n<li>Replies do not carry their own status; they update the parent thread status.</li>\n<li>When the original thread author replies, the thread becomes <code>open</code>.</li>\n<li>When a different author replies (including AI in normal flows), the thread becomes <code>pending</code>.</li>\n<li><code>addressed</code> is explicit: the original thread author marks the thread resolved.</li>\n</ul>\n<h2 id=\"review-model-at-a-glance\">Review model at a glance</h2>\n<ul>\n<li><code>open</code>: at least one thread is <code>open</code>.</li>\n<li><code>under_review</code>: no <code>open</code> threads remain.</li>\n<li><code>done</code>: explicitly set complete state.</li>\n<li><code>done</code> is guarded: unresolved threads block normal transition to <code>done</code>.</li>\n<li>If unresolved threads appear after <code>done</code>, the review auto-reopens to <code>open</code>.</li>\n</ul>\n<h2 id=\"ai-eligibility-summary\">AI eligibility summary</h2>\n<ul>\n<li>AI runs are skipped when review state is <code>done</code>.</li>\n<li><code>reply</code> mode targets <code>open</code> + <code>pending</code> threads by default.</li>\n<li><code>refactor</code> mode targets <code>open</code> threads only.</li>\n<li>Explicitly selected thread IDs can override reply-mode filtering (details in <code>docs/review-workflow.md</code>).</li>\n</ul>\n<h2 id=\"typical-session\">Typical session</h2>\n<pre><code class=\"language-bash\">parley review create my-review\nparley review start my-review\nparley tui --review my-review\n</code></pre>\n<p>The TUI requires an explicit existing review. Create the review first with <code>parley review create <name></code>, then open it with <code>parley tui --review <name></code>.</p>\n<p>If you are running over SSH and your terminal client does not play well with mouse reporting, start the TUI with <code>--no-mouse</code>.</p>\n<h2 id=\"revision-sources\">Revision sources</h2>\n<p>By default, Parley reviews the current working tree diff against <code>HEAD</code>.</p>\n<p>You can also open historical diffs directly in the TUI:</p>\n<pre><code class=\"language-bash\">parley tui --commit HEAD~2\nparley tui --base origin/trunk --head feature/my-branch\nparley tui --base v0.1.0\n# everything after HEAD~2 (exclude that commit)\nparley tui --base HEAD~2 --head HEAD\n# everything after and including HEAD~2\nparley tui --base HEAD~2^ --head HEAD\n</code></pre>\n<ul>\n<li><code>--commit <rev></code> reviews that commit against its first parent.</li>\n<li><code>--base <rev></code> reviews <code><rev>..HEAD</code>.</li>\n<li><code>--base <rev> --head <rev></code> reviews an explicit tree-to-tree range.</li>\n<li>Use <code>--base <rev> --head HEAD</code> to review everything after <code><rev></code>.</li>\n<li>Use <code>--base <rev>^ --head HEAD</code> to include <code><rev></code> itself in that cumulative range.</li>\n</ul>\n<p>AI sessions and TUI refresh use the same selected revision source, so they stay aligned with the diff you opened.</p>\n<p>From inside the TUI, use <code>Ctrl+k</code> to open the command palette, choose <code>Open Commit Picker</code>, then search by commit message or SHA. <code>Enter</code> switches the active diff source to the selected commit, and <code>Esc</code> closes the picker without changing the current diff.</p>\n<p>Use <code>Ctrl+k</code> and <code>Open Review Picker</code> to switch the active review context. The picker filters by review name or state and shows each review's thread counts. Applying a review reloads the review-owned comments while keeping the current diff source.</p>\n<p>Use <code>Ctrl+k</code> and <code>Create Review</code> to create a new review from inside the TUI and switch to it immediately. Entering a name in the review picker that has no matches also opens the create-review prompt.</p>\n<p>Current limitation:</p>\n<ul>\n<li>the selected revision source is not persisted into the review session yet, so reopening the review later still requires passing the same CLI flags again.</li>\n</ul>\n<h2 id=\"file-references-in-comment-drafts\">File references in comment drafts</h2>\n<p>Inside the inline comment or reply editor, <code>@</code> opens file matching against the current diff. Accepting a file switches the active diff pane to that file and enters a line-picker mode so you can move to or click the exact diff line before Parley inserts <code>@path:line</code> into the draft.</p>\n<p>The editor itself calls out that a line still needs to be selected, and once the reference is inserted Parley restores the pane, file, and line where the draft originally started.</p>\n<p>This keeps file references understandable to humans reading the thread instead of relying on a bare path plus a manually typed line number.</p>\n<p>Inside that same draft editor, <code>Alt+b</code> moves backward by the previous whitespace-delimited word and <code>Alt+d</code> deletes forward through the next one.</p>\n<h2 id=\"local-state-and-diff-filtering\">Local state and diff filtering</h2>\n<p>Parley stores config under <code>.parley/</code> and review-owned data under normalized review directories:</p>\n<pre><code class=\"language-text\">.parley/\n config.toml\n reviews/\n <review-name>/\n review.json\n logs/\n tui.log\n</code></pre>\n<p>Comments, replies, thread state, review state, and TUI logs belong to that review directory.</p>\n<p>Older flat files such as <code>.parley/reviews/<review-name>.json</code> are still readable.</p>\n<p>Those <code>.parley/</code> files are ignored by default when Parley builds the review diff, so local review metadata does not pollute the file sidebar. This behavior is configurable through <code>.parley/config.toml</code>:</p>\n<pre><code class=\"language-toml\">ignore_parley_dir = false\n</code></pre>\n<h2 id=\"what-pending-means\">What <code>pending</code> means</h2>\n<ul>\n<li><code>pending</code> indicates the thread is waiting on counterpart follow-up after a reply.</li>\n<li>A thread returns to <code>open</code> when the original author replies again or explicitly marks it open.</li>\n</ul>\n<h2 id=\"completion-behavior\">Completion behavior</h2>\n<ul>\n<li><code>done</code> is blocked while unresolved threads remain.</li>\n<li>Use force done (<code>Shift+D</code> in TUI) only when intentionally closing with unresolved threads.</li>\n</ul>\n"
},
{
"slug": "quickstart",
"title": "Quickstart",
"summary": "Covers Build, What Parley is actually doing, and Create a review session.",
"headings": [
{
"depth": 1,
"text": "Quickstart",
"id": "quickstart"
},
{
"depth": 2,
"text": "Build",
"id": "build"
},
{
"depth": 2,
"text": "What Parley is actually doing",
"id": "what-parley-is-actually-doing"
},
{
"depth": 2,
"text": "Create a review session",
"id": "create-a-review-session"
},
{
"depth": 2,
"text": "Open the TUI on your current changes",
"id": "open-the-tui-on-your-current-changes"
},
{
"depth": 2,
"text": "Open a specific commit or range",
"id": "open-a-specific-commit-or-range"
},
{
"depth": 1,
"text": "everything after HEAD~2 (exclude that commit)",
"id": "everything-after-head2-exclude-that-commit"
},
{
"depth": 1,
"text": "everything after and including HEAD~2",
"id": "everything-after-and-including-head2"
},
{
"depth": 2,
"text": "The core workflow",
"id": "the-core-workflow"
},
{
"depth": 3,
"text": "Example: review one issue end to end",
"id": "example-review-one-issue-end-to-end"
},
{
"depth": 3,
"text": "Example: use AI on a thread",
"id": "example-use-ai-on-a-thread"
},
{
"depth": 2,
"text": "Core controls",
"id": "core-controls"
},
{
"depth": 3,
"text": "Navigation",
"id": "navigation"
},
{
"depth": 3,
"text": "Search and jump",
"id": "search-and-jump"
},
{
"depth": 3,
"text": "Threads",
"id": "threads"
},
{
"depth": 3,
"text": "File references in comments",
"id": "file-references-in-comments"
},
{
"depth": 3,
"text": "Comment editor word motions",
"id": "comment-editor-word-motions"
},
{
"depth": 3,
"text": "Review state",
"id": "review-state"
},
{
"depth": 3,
"text": "AI and tools",
"id": "ai-and-tools"
},
{
"depth": 2,
"text": "A realistic first session",
"id": "a-realistic-first-session"
},
{
"depth": 2,
"text": "Config",
"id": "config"
},
{
"depth": 3,
"text": "Which status to set before AI",
"id": "which-status-to-set-before-ai"
},
{
"depth": 2,
"text": "Refresh after edits",
"id": "refresh-after-edits"
}
],
"html": "<h1 id=\"quickstart\">Quickstart</h1>\n<h2 id=\"build\">Build</h2>\n<pre><code class=\"language-bash\">cargo build --release\n</code></pre>\n<h2 id=\"what-parley-is-actually-doing\">What Parley is actually doing</h2>\n<p>Parley separates two things:</p>\n<ul>\n<li>a <strong>diff source</strong> you are reviewing</li>\n<li>a <strong>review session</strong> stored under <code>.parley/</code></li>\n</ul>\n<p>The diff source is the code you see in the TUI:</p>\n<ul>\n<li>the current working tree by default</li>\n<li>a specific commit with <code>--commit</code></li>\n<li>a base/head range with <code>--base</code> and <code>--head</code></li>\n</ul>\n<p>The review session is the structured review state Parley keeps locally:</p>\n<ul>\n<li>named reviews such as <code>my-review</code></li>\n<li>line-anchored comment threads</li>\n<li>thread statuses: <code>open</code>, <code>pending</code>, <code>addressed</code></li>\n<li>review states: <code>open</code>, <code>under_review</code>, <code>done</code></li>\n</ul>\n<p>That matters because comments are not just free-form notes. Each thread is attached to a file path and line reference, and replies update the parent thread status.</p>\n<p>The review session is the comment context. Switching reviews changes which comments and review state are visible, while the selected diff source stays as-is.</p>\n<h2 id=\"create-a-review-session\">Create a review session</h2>\n<pre><code class=\"language-bash\">./target/release/parley review create my-review\n./target/release/parley review start my-review\n</code></pre>\n<p><code>review create</code> creates the local session. <code>review start</code> moves it into <code>under_review</code>, but the moment you add an <code>open</code> thread, the review state automatically becomes <code>open</code> again.</p>\n<h2 id=\"open-the-tui-on-your-current-changes\">Open the TUI on your current changes</h2>\n<pre><code class=\"language-bash\">./target/release/parley tui --review my-review\n</code></pre>\n<p><code>--review</code> is required, and the review must already exist. Create it first with <code>review create</code>.</p>\n<p>If your terminal or SSH session mishandles mouse reporting, disable mouse capture:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --review my-review --no-mouse\n</code></pre>\n<p>The TUI never creates or guesses a startup review. Review context is explicit so comments are always written under the intended review.</p>\n<h2 id=\"open-a-specific-commit-or-range\">Open a specific commit or range</h2>\n<p>By default, the TUI opens the current working tree diff. You can also open historical revisions:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --commit HEAD~2\n./target/release/parley tui --base origin/trunk --head feature/my-branch\n./target/release/parley tui --base v0.1.0\n# everything after HEAD~2 (exclude that commit)\n./target/release/parley tui --base HEAD~2 --head HEAD\n# everything after and including HEAD~2\n./target/release/parley tui --base HEAD~2^ --head HEAD\n</code></pre>\n<ul>\n<li><code>--commit <rev></code> shows that commit against its first parent.</li>\n<li><code>--base <rev></code> defaults <code>head</code> to <code>HEAD</code>.</li>\n<li><code>--base <rev> --head <rev></code> shows an explicit range.</li>\n<li>Use <code>--base <rev> --head HEAD</code> to review everything after <code><rev></code>.</li>\n<li>Use <code>--base <rev>^ --head HEAD</code> to include <code><rev></code> itself in that cumulative range.</li>\n</ul>\n<p>Refresh (<code>R</code>) keeps using the same source while the TUI session stays open, and AI prompt context follows that same diff source.</p>\n<p>You can also switch to a specific commit from inside the TUI:</p>\n<ol>\n<li>Press <code>Ctrl+k</code> to open the command palette.</li>\n<li>Choose <code>Open Commit Picker</code>.</li>\n<li>Type part of a commit message, short SHA, or full SHA to filter the recent commit list.</li>\n<li>Use <code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, <code>Home</code>, or <code>End</code> to select a commit.</li>\n<li>Press <code>Enter</code> to apply it.</li>\n</ol>\n<p>The picker changes only Parley's active diff source. It does not run <code>git checkout</code> or modify the working tree.</p>\n<p>To switch comment context without changing the diff:</p>\n<ol>\n<li>Press <code>Ctrl+k</code> to open the command palette.</li>\n<li>Choose <code>Open Review Picker</code>.</li>\n<li>Filter by review name or state.</li>\n<li>Press <code>Enter</code> to apply the selected review.</li>\n</ol>\n<p>The TUI reloads comments from the selected review and keeps the current diff source.</p>\n<p>To create a new review from inside the TUI, use <code>Ctrl+k</code> and <code>Create Review</code>. The new review becomes active immediately, and later comments are written to that review's directory. If the review picker has no matches for the typed name, pressing <code>Enter</code> opens the same create-review prompt with that name.</p>\n<p>Current limitation:</p>\n<ul>\n<li>reopening the review later does not restore the revision source automatically; pass the same flags again.</li>\n</ul>\n<h2 id=\"the-core-workflow\">The core workflow</h2>\n<p>Think of the normal flow like this:</p>\n<ol>\n<li>Open a diff.</li>\n<li>Move to a changed line.</li>\n<li>Create a thread on that line.</li>\n<li>Reply until the issue is resolved.</li>\n<li>Mark the thread addressed.</li>\n<li>When nothing unresolved remains, move the review to <code>done</code>.</li>\n</ol>\n<h3 id=\"example-review-one-issue-end-to-end\">Example: review one issue end to end</h3>\n<p>Say you open a diff and find a risky change in <code>src/lib.rs</code>.</p>\n<ol>\n<li>Move to the line with <code>j/k</code>, <code>PgUp/PgDn</code>, or search.</li>\n<li>Press <code>m</code> or <code>c</code> to open a draft on that line.</li>\n<li>Write a comment such as:</li>\n</ol>\n<pre><code class=\"language-text\">This branch drops the error context. Can we keep the original cause here?\n</code></pre>\n<ol start=\"4\">\n<li>Save with <code>Ctrl+s</code>.</li>\n</ol>\n<p>That creates a thread anchored to the selected diff line, and the thread starts as <code>open</code>.</p>\n<p>If someone else replies, for example:</p>\n<pre><code class=\"language-text\">I pushed a fix and kept the original error chain.\n</code></pre>\n<p>the thread becomes <code>pending</code>.</p>\n<p>If the original commenter replies again, the thread goes back to <code>open</code>.</p>\n<p>When the original commenter is satisfied, they mark it <code>addressed</code>.</p>\n<p>Only the original commenter can normally change a thread to <code>open</code>, <code>pending</code>, or <code>addressed</code>. That is enforced by the review model.</p>\n<h3 id=\"example-use-ai-on-a-thread\">Example: use AI on a thread</h3>\n<ul>\n<li><code>x</code> runs AI refactor on the selected <code>open</code> thread</li>\n<li><code>X</code> runs AI reply on the selected thread</li>\n<li><code>A</code> runs AI refactor across all eligible threads in the review</li>\n</ul>\n<p>Typical pattern:</p>\n<ol>\n<li>Leave a thread <code>open</code>.</li>\n<li>Press <code>x</code> on that thread.</li>\n<li>AI adds a reply to the thread.</li>\n<li>Because AI is a different author, the thread becomes <code>pending</code>.</li>\n<li>You inspect the code changes and either reopen the thread or mark it addressed.</li>\n</ol>\n<p>If the review is already <code>done</code>, AI runs are skipped.</p>\n<h2 id=\"core-controls\">Core controls</h2>\n<h3 id=\"navigation\">Navigation</h3>\n<ul>\n<li><code>h/l</code>: previous or next file</li>\n<li><code>j/k</code>: move line cursor down or up</li>\n<li><code>PgUp/PgDn</code>: page scroll</li>\n<li><code>Ctrl+u/Ctrl+d</code>: half-page scroll</li>\n<li><code>g/G</code>: jump to first or last line</li>\n<li><code>zz</code>: center active line</li>\n</ul>\n<h3 id=\"search-and-jump\">Search and jump</h3>\n<ul>\n<li><code>:<line></code>: go to line</li>\n<li><code>/query</code>: set diff search query</li>\n<li><code>n/p</code>: next or previous search hit</li>\n</ul>\n<h3 id=\"threads\">Threads</h3>\n<ul>\n<li><code>m</code> or <code>c</code>: create thread on selected line</li>\n<li><code>r</code>: reply to selected thread</li>\n<li><code>N/P</code>: jump next or previous thread</li>\n<li><code>[/]</code>: select previous or next thread in current file</li>\n<li><code>e</code>: toggle selected thread expansion</li>\n<li><code>Shift+E</code>: cycle thread density (<code>compact</code>/<code>expanded</code>)</li>\n<li><code>a/o/f</code>: addressed/open/force-address selected thread</li>\n</ul>\n<h3 id=\"file-references-in-comments\">File references in comments</h3>\n<ul>\n<li>Type <code>@</code> inside the comment or reply box to open file matching.</li>\n<li>Use <code>Enter</code> or <code>Tab</code> on a file match to open that file in the active diff pane and switch into line-picker mode.</li>\n<li>The comment editor explicitly tells you to select a diff line before the reference is confirmed.</li>\n<li>In line-picker mode, use <code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, or <code>g/G</code> to move the diff cursor, then <code>Enter</code> or <code>Tab</code> to insert <code>@path:line</code>.</li>\n<li>If mouse support is enabled, clicking a diff line during line-picker mode inserts that line immediately.</li>\n<li>After inserting the reference, Parley restores the file, pane, and diff line where the draft started.</li>\n<li><code>Esc</code> cancels the line picker and leaves the bare <code>@path</code> reference in the comment buffer.</li>\n</ul>\n<h3 id=\"comment-editor-word-motions\">Comment editor word motions</h3>\n<ul>\n<li><code>Alt+b</code>: move backward one whitespace-delimited word in the draft</li>\n<li><code>Alt+d</code>: delete forward through the next whitespace-delimited word in the draft</li>\n</ul>\n<h3 id=\"review-state\">Review state</h3>\n<ul>\n<li><code>s</code>: set review <code>open</code></li>\n<li><code>w</code>: set review <code>under_review</code></li>\n<li><code>d</code>: set review <code>done</code> (blocked if unresolved threads exist)</li>\n<li><code>Shift+D</code>: force set review <code>done</code></li>\n</ul>\n<p>Review state mostly follows thread state:</p>\n<ul>\n<li>any <code>open</code> thread means the review is <code>open</code></li>\n<li>no <code>open</code> threads means the review is <code>under_review</code></li>\n<li><code>done</code> is explicit and guarded</li>\n</ul>\n<p><code>done</code> is blocked while unresolved threads remain. In practice, that means both <code>open</code> and <code>pending</code> threads prevent a normal transition to <code>done</code>.</p>\n<h3 id=\"ai-and-tools\">AI and tools</h3>\n<ul>\n<li><code>x</code>: AI refactor selected thread</li>\n<li><code>X</code>: AI reply selected thread</li>\n<li><code>A</code>: AI refactor full review</li>\n<li><code>K</code>: cancel current AI run</li>\n<li><code>H</code>: toggle AI stream popup</li>\n<li><code>L</code>: open log file in <code>less</code></li>\n<li><code>Ctrl+k</code>: open command palette</li>\n<li>Command palette <code>Open Commit Picker</code>: switch the active diff source to a recent commit</li>\n<li>Command palette <code>Open Review Picker</code>: switch the active review context</li>\n<li>Command palette <code>Create Review</code>: create a new review context and switch to it</li>\n<li><code>Ctrl+f</code>: focus files filter input</li>\n<li><code>?</code>: open in-app docs/help overlay</li>\n</ul>\n<h2 id=\"a-realistic-first-session\">A realistic first session</h2>\n<pre><code class=\"language-bash\">./target/release/parley review create parser-cleanup\n./target/release/parley review start parser-cleanup\n./target/release/parley tui --review parser-cleanup\n</code></pre>\n<p>Inside the TUI:</p>\n<ul>\n<li>move through changed files with <code>h/l</code></li>\n<li>move inside the diff with <code>j/k</code></li>\n<li>press <code>c</code> on a changed line to leave a thread</li>\n<li>press <code>r</code> on that thread to reply later</li>\n<li>press <code>R</code> after editing code in another terminal</li>\n<li>press <code>a</code> when the original reviewer considers the issue resolved</li>\n<li>press <code>d</code> when the review is actually complete</li>\n</ul>\n<p>For a historical review:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --review parser-cleanup --base origin/trunk --head feature/parser-cleanup\n</code></pre>\n<p>That lets you keep one named review session while pointing the TUI at an explicit base/head diff.</p>\n<h2 id=\"config\">Config</h2>\n<p>Parley reads configuration from <code>.parley/config.toml</code> and stores review-owned state under <code>.parley/reviews/<review-name>/</code>.</p>\n<p>Each review directory contains:</p>\n<pre><code class=\"language-text\">review.json\nlogs/tui.log\n</code></pre>\n<p>All comments, replies, thread status, review status, and TUI logs for that review stay under this directory.</p>\n<p>Older flat review files in <code>.parley/reviews/<review-name>.json</code> are still loaded.</p>\n<p>By default, Parley ignores its own <code>.parley/</code> files when building the review diff so that review metadata and logs do not show up in the file list.</p>\n<p>To include <code>.parley/</code> in the diff again, set:</p>\n<pre><code class=\"language-toml\">ignore_parley_dir = false\n</code></pre>\n<h3 id=\"which-status-to-set-before-ai\">Which status to set before AI</h3>\n<ul>\n<li>For <code>refactor</code> (<code>x</code> or <code>A</code>): thread must be <code>open</code>.</li>\n<li>For <code>reply</code> (<code>X</code>): thread should be <code>open</code> or <code>pending</code>.</li>\n<li>If review is <code>done</code>, AI runs are skipped.</li>\n<li>Use explicit thread selection from MCP if you need reply mode on an <code>addressed</code> thread.</li>\n</ul>\n<h2 id=\"refresh-after-edits\">Refresh after edits</h2>\n<p>Inside TUI:</p>\n<pre><code class=\"language-text\">R\n</code></pre>\n<p>This reloads review metadata and the active diff source.</p>\n<ul>\n<li>For the normal workflow, that means the current working tree diff.</li>\n<li>If you opened the TUI with <code>--commit</code> or <code>--base</code> / <code>--head</code>, refresh keeps using that same historical source.</li>\n</ul>\n"
},
{
"slug": "keybindings",
"title": "Keybindings",
"summary": "Covers Navigation, Search and jump, and Threads.",
"headings": [
{
"depth": 1,
"text": "Keybindings",
"id": "keybindings"
},
{
"depth": 2,
"text": "Navigation",
"id": "navigation"
},
{
"depth": 2,
"text": "Search and jump",
"id": "search-and-jump"
},
{
"depth": 2,
"text": "Threads",
"id": "threads"
},
{
"depth": 3,
"text": "File references inside the comment box",
"id": "file-references-inside-the-comment-box"
},
{
"depth": 3,
"text": "Comment editor word motions",
"id": "comment-editor-word-motions"
},
{
"depth": 2,
"text": "Review state",
"id": "review-state"
},
{
"depth": 2,
"text": "AI",
"id": "ai"
},
{
"depth": 2,
"text": "Layout and tools",
"id": "layout-and-tools"
},
{
"depth": 2,
"text": "Help pane",
"id": "help-pane"
}
],
"html": "<h1 id=\"keybindings\">Keybindings</h1>\n<h2 id=\"navigation\">Navigation</h2>\n<ul>\n<li><code>h/l</code>: previous/next file</li>\n<li><code>j/k</code>: down/up line</li>\n<li><code>PgUp/PgDn</code>: page scroll</li>\n<li><code>Ctrl+u/Ctrl+d</code>: half-page scroll</li>\n<li><code>g/G</code>: top/bottom</li>\n<li><code>zz</code>: center active line</li>\n</ul>\n<h2 id=\"search-and-jump\">Search and jump</h2>\n<ul>\n<li><code>:<line></code>: go to line</li>\n<li><code>/query</code>: set search query</li>\n<li><code>n/p</code>: next/previous search match</li>\n</ul>\n<h2 id=\"threads\">Threads</h2>\n<ul>\n<li><code>m</code> or <code>c</code>: create thread on selected line</li>\n<li><code>r</code>: reply to selected thread</li>\n<li><code>N/P</code>: next/previous thread</li>\n<li><code>[/]</code>: previous/next selected thread in file</li>\n<li><code>e</code>: toggle selected thread expansion</li>\n<li><code>Shift+E</code>: cycle thread density</li>\n<li><code>a</code>: mark addressed</li>\n<li><code>o</code>: mark open</li>\n<li><code>f</code>: force-address selected thread</li>\n<li><code>u</code>: re-anchor selected thread to the currently selected diff line</li>\n</ul>\n<h3 id=\"file-references-inside-the-comment-box\">File references inside the comment box</h3>\n<ul>\n<li>Type <code>@</code> in the comment or reply box to open the file reference picker.</li>\n<li><code>↑/↓</code> or <code>PgUp/PgDn</code>: move through file matches</li>\n<li><code>Enter</code> or <code>Tab</code>: accept the selected file and enter line-picker mode</li>\n<li>While line-picker mode is active, Parley opens that file in the current diff pane and tells you to select a diff line in the editor itself.</li>\n<li><code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, <code>g/G</code>: move to the target diff line</li>\n<li><code>Enter</code> or <code>Tab</code>: insert <code>@path:line</code> for the currently selected line</li>\n<li>Mouse: click a diff line while line-picker mode is active to insert that line immediately</li>\n<li>After inserting the reference, Parley returns to the file and diff line where you started writing the draft.</li>\n<li><code>Esc</code>: cancel the picker; if the file is already inserted, it leaves the bare <code>@path</code> in place</li>\n</ul>\n<h3 id=\"comment-editor-word-motions\">Comment editor word motions</h3>\n<ul>\n<li><code>Alt+b</code>: move backward one whitespace-delimited word in the draft</li>\n<li><code>Alt+d</code>: delete forward through the next whitespace-delimited word in the draft</li>\n</ul>\n<h2 id=\"review-state\">Review state</h2>\n<ul>\n<li><code>s</code>: set review state <code>open</code></li>\n<li><code>w</code>: set review state <code>under_review</code></li>\n<li><code>d</code>: set review state <code>done</code> (guarded)</li>\n<li><code>Shift+D</code>: force set <code>done</code></li>\n</ul>\n<h2 id=\"ai\">AI</h2>\n<ul>\n<li><code>x</code>: AI refactor selected thread</li>\n<li><code>X</code>: AI reply selected thread</li>\n<li><code>A</code>: AI refactor review</li>\n<li><code>K</code>: cancel active AI run</li>\n<li><code>H</code>: toggle AI stream popup</li>\n<li><code>L</code>: open logs in <code>less</code></li>\n</ul>\n<h2 id=\"layout-and-tools\">Layout and tools</h2>\n<ul>\n<li><code>?</code>: open help docs</li>\n<li><code>Ctrl+k</code>: command palette</li>\n<li>Command palette <code>Open Commit Picker</code>: open recent commits, filter by message or SHA, and apply the selected commit as the active diff source</li>\n<li>Command palette <code>Open Review Picker</code>: open reviews, filter by name or state, and apply the selected review as the active comment context</li>\n<li>Command palette <code>Create Review</code>: create a new review context and switch to it</li>\n<li><code>Ctrl+f</code>: file filter input</li>\n<li><code>Shift+U</code>: edit user name</li>\n<li><code>V</code>: toggle split diff</li>\n<li><code>S</code>: toggle side-by-side diff</li>\n<li><code>Tab</code>: switch active diff pane</li>\n<li><code></></code>: resize files pane</li>\n<li><code>b</code>: toggle thread navigator</li>\n</ul>\n<h2 id=\"help-pane\">Help pane</h2>\n<ul>\n<li><code>Tab</code> / <code>Shift+Tab</code> or <code>h/l</code>: switch help doc tab</li>\n<li><code>1-9</code>: direct tab select</li>\n<li><code>j/k</code>, <code>PgUp/PgDn</code>, <code>g/G</code>: scroll help content</li>\n<li><code></></code>: zoom help pane</li>\n<li><code>Esc</code> or <code>?</code>: close help pane</li>\n</ul>\n"
},
{
"slug": "review-workflow",
"title": "Review Workflow",
"summary": "Covers Thread model, Thread status transitions, and Review state reconciliation.",
"headings": [
{
"depth": 1,
"text": "Review Workflow",
"id": "review-workflow"
},
{
"depth": 2,
"text": "1. Thread model (authoritative)",
"id": "1-thread-model-authoritative"
},
{
"depth": 2,
"text": "2. Thread status transitions",
"id": "2-thread-status-transitions"
},
{
"depth": 3,
"text": "Automatic transitions",
"id": "automatic-transitions"
},
{
"depth": 3,
"text": "Manual transitions",
"id": "manual-transitions"
},
{
"depth": 2,
"text": "3. Review state reconciliation",
"id": "3-review-state-reconciliation"
},
{
"depth": 2,
"text": "4. Threading practice",
"id": "4-threading-practice"
},
{
"depth": 2,
"text": "5. Drive thread state deliberately",
"id": "5-drive-thread-state-deliberately"
},
{
"depth": 2,
"text": "6. AI eligibility matrix (what status to use before sending to AI)",
"id": "6-ai-eligibility-matrix-what-status-to-use-before-sending-to-ai"
},
{
"depth": 3,
"text": "Mode = `refactor`",
"id": "mode-refactor"
},
{
"depth": 3,
"text": "Mode = `reply`",
"id": "mode-reply"
},
{
"depth": 2,
"text": "7. Post-AI behavior",
"id": "7-post-ai-behavior"
},
{
"depth": 2,
"text": "8. Refresh after code edits",
"id": "8-refresh-after-code-edits"
},
{
"depth": 2,
"text": "9. Reviewing historical revisions",
"id": "9-reviewing-historical-revisions"
}
],
"html": "<h1 id=\"review-workflow\">Review Workflow</h1>\n<h2 id=\"1-thread-model-authoritative\">1. Thread model (authoritative)</h2>\n<p>Each thread is a single <code>LineComment</code> with:</p>\n<ul>\n<li>anchor (<code>file_path</code>, <code>old_line</code>, <code>new_line</code>, <code>side</code>)</li>\n<li>thread <code>status</code> (<code>open</code>, <code>pending</code>, <code>addressed</code>)</li>\n<li>thread <code>author</code> (original commenter)</li>\n<li>ordered replies</li>\n</ul>\n<p>Replies do not have thread status. A reply event updates the parent thread status.</p>\n<h2 id=\"2-thread-status-transitions\">2. Thread status transitions</h2>\n<h3 id=\"automatic-transitions\">Automatic transitions</h3>\n<ul>\n<li>New comment created -> <code>open</code></li>\n<li>Reply by original thread author -> <code>open</code></li>\n<li>Reply by different author (including AI in normal flows) -> <code>pending</code></li>\n</ul>\n<h3 id=\"manual-transitions\">Manual transitions</h3>\n<ul>\n<li>Mark open: original thread author -> <code>open</code></li>\n<li>Mark addressed: original thread author -> <code>addressed</code></li>\n<li>Force mark addressed: force path (no author gate) -> <code>addressed</code></li>\n</ul>\n<h2 id=\"3-review-state-reconciliation\">3. Review state reconciliation</h2>\n<p>Review state is reconciled from thread statuses:</p>\n<ul>\n<li>if any thread is <code>open</code>, review is <code>open</code></li>\n<li>else if no thread is <code>open</code>, review is <code>under_review</code></li>\n<li><code>done</code> is explicit and guarded</li>\n</ul>\n<p><code>done</code> guard:</p>\n<ul>\n<li>normal set to <code>done</code> fails when unresolved threads (<code>open</code> or <code>pending</code>) exist</li>\n<li>force done bypasses this check</li>\n<li>if new unresolved activity appears after <code>done</code>, review auto-reopens to <code>open</code></li>\n</ul>\n<h2 id=\"4-threading-practice\">4. Threading practice</h2>\n<p>Use line-level comments for actionable feedback. Keep one issue per thread so resolution is obvious.</p>\n<h2 id=\"5-drive-thread-state-deliberately\">5. Drive thread state deliberately</h2>\n<ul>\n<li>Use <code>open</code> when code changes are required.</li>\n<li>Use <code>pending</code> when a reply is waiting on counterpart action.</li>\n<li>Use <code>addressed</code> when the original reviewer confirms resolution.</li>\n</ul>\n<p>Example:</p>\n<ul>\n<li>reviewer leaves a comment -> <code>open</code></li>\n<li>author replies "fixed in 9d2b3af" -> <code>pending</code></li>\n<li>reviewer checks the change and is still unhappy -> reply reopens thread to <code>open</code></li>\n<li>reviewer is satisfied -> mark <code>addressed</code></li>\n</ul>\n<h2 id=\"6-ai-eligibility-matrix-what-status-to-use-before-sending-to-ai\">6. AI eligibility matrix (what status to use before sending to AI)</h2>\n<p>Global precondition:</p>\n<ul>\n<li>review must not be <code>done</code> (AI session is skipped otherwise)</li>\n</ul>\n<h3 id=\"mode-refactor\">Mode = <code>refactor</code></h3>\n<ul>\n<li>No explicit <code>comment_ids</code> (auto-target):\n<ul>\n<li>processed: <code>open</code></li>\n<li>skipped: <code>pending</code>, <code>addressed</code></li>\n</ul>\n</li>\n<li>Explicit <code>comment_ids</code>:\n<ul>\n<li>processed: <code>open</code></li>\n<li>skipped: <code>pending</code>, <code>addressed</code></li>\n</ul>\n</li>\n</ul>\n<p>What this means:</p>\n<ul>\n<li>set thread to <code>open</code> before running AI refactor</li>\n<li><code>pending</code> or <code>addressed</code> threads will not be processed in refactor mode</li>\n</ul>\n<h3 id=\"mode-reply\">Mode = <code>reply</code></h3>\n<ul>\n<li>No explicit <code>comment_ids</code> (auto-target):\n<ul>\n<li>processed: <code>open</code>, <code>pending</code></li>\n<li>skipped: <code>addressed</code></li>\n</ul>\n</li>\n<li>Explicit <code>comment_ids</code>:\n<ul>\n<li>processed: any selected status (including <code>addressed</code>)</li>\n<li>skipped by status filter: none</li>\n</ul>\n</li>\n</ul>\n<p>What this means:</p>\n<ul>\n<li>for normal reply runs, use <code>open</code> or <code>pending</code></li>\n<li>explicit thread targeting can still send an <code>addressed</code> thread to AI reply mode</li>\n</ul>\n<h2 id=\"7-post-ai-behavior\">7. Post-AI behavior</h2>\n<ul>\n<li>AI output is persisted as a reply in the target thread.</li>\n<li>In typical human-authored threads, this sets thread status to <code>pending</code>.</li>\n<li>Review state then reconciles based on resulting thread statuses.</li>\n</ul>\n<p>Example:</p>\n<ul>\n<li>thread is <code>open</code></li>\n<li>you press <code>x</code> for AI refactor</li>\n<li>AI posts a reply into that thread</li>\n<li>thread becomes <code>pending</code></li>\n<li>you inspect the code and either mark it <code>addressed</code> or reopen it</li>\n</ul>\n<h2 id=\"8-refresh-after-code-edits\">8. Refresh after code edits</h2>\n<p>After code edits or automation runs, refresh in TUI so thread anchors and diff context stay current.</p>\n<p>If the TUI was opened with <code>--commit</code> or <code>--base</code> / <code>--head</code>, refresh keeps using that same revision source instead of falling back to the working tree.</p>\n<h2 id=\"9-reviewing-historical-revisions\">9. Reviewing historical revisions</h2>\n<p>Parley can review more than the live working tree:</p>\n<ul>\n<li><code>parley tui --commit <rev></code>: diff that commit against its first parent</li>\n<li><code>parley tui --base <rev></code>: diff <code><rev>..HEAD</code></li>\n<li><code>parley tui --base <rev> --head <rev></code>: diff an explicit base/head range</li>\n<li><code>parley tui --base <rev> --head HEAD</code>: diff everything after <code><rev></code></li>\n<li><code>parley tui --base <rev>^ --head HEAD</code>: diff everything after and including <code><rev></code></li>\n</ul>\n<p>AI sessions use the same selected revision source for prompt context.</p>\n<p>Inside the TUI, <code>Ctrl+k</code> opens the command palette. Select <code>Open Commit Picker</code> to choose from recent commits, filter by message or SHA, and press <code>Enter</code> to apply the selected commit as the active diff source.</p>\n<p>Select <code>Open Review Picker</code> from the same command palette to switch review context. This reloads comments, replies, and review state from the selected review while keeping the active working tree, commit, or range diff unchanged.</p>\n<p>Select <code>Create Review</code> to create a new review context from inside the TUI and switch to it immediately. New comments then persist under that review's directory.</p>\n<p>Current limitation:</p>\n<ul>\n<li>the revision source is not stored in the review session yet, so a later reopen still needs the same CLI flags.</li>\n</ul>\n"
},
{
"slug": "mcp",
"title": "MCP Integration",
"summary": "Parley exposes an MCP-compatible JSON-RPC interface over stdio.",
"headings": [
{
"depth": 1,
"text": "MCP Integration",
"id": "mcp-integration"
},
{
"depth": 2,
"text": "Transport",
"id": "transport"
},
{
"depth": 2,
"text": "Typical tools",
"id": "typical-tools"
},
{
"depth": 2,
"text": "`run_ai_session` behavior",
"id": "runaisession-behavior"
},
{
"depth": 2,
"text": "Example calls",
"id": "example-calls"
},
{
"depth": 2,
"text": "Notes",
"id": "notes"
}
],
"html": "<h1 id=\"mcp-integration\">MCP Integration</h1>\n<p>Parley exposes an MCP-compatible JSON-RPC interface over stdio.</p>\n<h2 id=\"transport\">Transport</h2>\n<ul>\n<li>Supports both <code>Content-Length</code> framed and newline-delimited JSON-RPC messages.</li>\n<li>Implements <code>initialize</code>, <code>tools/list</code>, and <code>tools/call</code>.</li>\n</ul>\n<h2 id=\"typical-tools\">Typical tools</h2>\n<ul>\n<li><code>list_reviews</code></li>\n<li><code>get_review</code></li>\n<li><code>list_open_comments</code></li>\n<li><code>add_reply</code></li>\n<li><code>mark_comment_addressed</code></li>\n<li><code>mark_comment_open</code></li>\n<li><code>set_review_state</code></li>\n<li><code>run_ai_session</code></li>\n</ul>\n<h2 id=\"runaisession-behavior\"><code>run_ai_session</code> behavior</h2>\n<p>Inputs:</p>\n<ul>\n<li><code>provider</code>: <code>codex</code> | <code>claude</code> | <code>opencode</code></li>\n<li><code>mode</code>: <code>reply</code> | <code>refactor</code> (optional; defaults by API call site)</li>\n<li><code>comment_ids</code>: optional explicit thread IDs</li>\n</ul>\n<p>Global gate:</p>\n<ul>\n<li>if review state is <code>done</code>, the AI session is skipped</li>\n</ul>\n<p>Target filtering:</p>\n<ul>\n<li><code>mode=refactor</code>:\n<ul>\n<li>auto-target (<code>comment_ids</code> omitted): only <code>open</code> threads</li>\n<li>explicit <code>comment_ids</code>: still only <code>open</code> threads are processed</li>\n</ul>\n</li>\n<li><code>mode=reply</code>:\n<ul>\n<li>auto-target (<code>comment_ids</code> omitted): <code>open</code> and <code>pending</code></li>\n<li>explicit <code>comment_ids</code>: status filter is bypassed for selection, so <code>addressed</code> can be processed</li>\n</ul>\n</li>\n</ul>\n<p>After processing:</p>\n<ul>\n<li>AI response is added as a thread reply</li>\n<li>thread status typically becomes <code>pending</code> (different-author reply path)</li>\n</ul>\n<h2 id=\"example-calls\">Example calls</h2>\n<p>Reply mode over all eligible threads:</p>\n<pre><code class=\"language-json\">{\n "name": "run_ai_session",\n "arguments": {\n "review_name": "my-review",\n "provider": "codex",\n "mode": "reply"\n }\n}\n</code></pre>\n<p>Refactor mode over open threads only:</p>\n<pre><code class=\"language-json\">{\n "name": "run_ai_session",\n "arguments": {\n "review_name": "my-review",\n "provider": "codex",\n "mode": "refactor"\n }\n}\n</code></pre>\n<p>Reply mode on explicit thread IDs:</p>\n<pre><code class=\"language-json\">{\n "name": "run_ai_session",\n "arguments": {\n "review_name": "my-review",\n "provider": "codex",\n "mode": "reply",\n "comment_ids": [12, 18]\n }\n}\n</code></pre>\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>Tools that operate on review state require an explicit <code>review_name</code>.</li>\n<li>Thread state updates are explicit tool calls.</li>\n<li><code>set_review_state</code> accepts Parley review states (<code>open</code>, <code>under_review</code>, <code>done</code>).</li>\n<li><code>run_ai_session</code> supports <code>reply</code> and <code>refactor</code> modes.</li>\n</ul>\n"
}
];
</script>
<div class="site-shell">
<header class="topbar">
<a class="brandmark" href="/">
<span class="brandmark-badge">P</span>
<span class="brandmark-copy">
<span class="brandmark-label">Docs</span>
<span class="brandmark-name">Parley</span>
</span>
</a>
<div class="topbar-actions">
<a class="chip-link btn" href="/docs/overview">Open docs</a>
<button class="theme-button btn" data-theme-toggle type="button">Use dark mode</button>
</div>
</header>
<section class="hero">
<div class="hero-grid">
<div>
<p class="eyebrow">AI agent code review</p>
<h1>AI generated code you can trust</h1>
<p>
Parley is a terminal-first review tool for local git diffs, optimized for iterative
AI-assisted code review. Threads, review state, and AI runs stay explicit so you can
inspect and drive agent-generated changes instead of guessing what happened.
</p>
</div>
<div class="hero-stats" id="hero-stats">
<article class="stat-card fade-in">
<strong>4</strong>
<span>core docs</span>
</article>
</div>
</div>
</section>
<section class="section">
<div class="section-header">
<div>
<p class="eyebrow">What matters</p>
<h2 class="section-title">The docs track the actual workflow</h2>
</div>
<p class="section-copy">
Review lifecycle, TUI controls, thread state, and MCP behavior. Short names, obvious
entry points, minimal chrome.
</p>
</div>
<div class="feature-grid" id="feature-grid"></div>
</section>
<section class="section">
<div class="section-header">
<div>
<p class="eyebrow">Documents</p>
<h2 class="section-title">Open the part you need</h2>
</div>
<p class="section-copy">
Each document is generated from the repository source and surfaced here with section
count and a short summary so the entry point is obvious.
</p>
</div>
<div class="doc-grid" id="docs-grid"></div>
</section>
</div>
<script src="/site.js"></script>
<script src="/home.js"></script>
</body>
</html>