<!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="Workflow-focused Parley documentation for terminal review, TUI controls, and MCP integration."
/>
<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" />
<link
id="hljs-theme"
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github-dark.min.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js"></script>
</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": 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>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>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 main --head feature/my-branch\nparley tui --base v0.1.0\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</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>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 reviews, logs, and config under <code>.parley/</code>.</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": 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<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>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>If only one review exists, Parley can resolve that review automatically, but using <code>--review</code> is the clearest form.</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 main --head feature/my-branch\n./target/release/parley tui --base v0.1.0\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</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>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><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 main --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 stores its local state in <code>.parley/</code> and reads configuration from <code>.parley/config.toml</code>.</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</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><code>Ctrl+f</code>: file filter input</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</ul>\n<p>AI sessions use the same selected revision source for prompt context.</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>Uses <code>Content-Length</code> framed 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>Review names can be resolved from current branch context.</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">System View</span>
<span class="brandmark-name">Parley Docs</span>
</span>
</a>
<div class="topbar-actions">
<a class="chip-link btn" href="/">Docs home</a>
<button class="theme-button btn" data-theme-toggle type="button">Use dark mode</button>
</div>
</header>
<div class="shell-grid">
<aside class="side-panel" id="side-panel" data-collapsed="false">
<div class="search-panel">
<label class="visually-hidden" for="search-input">Filter docs</label>
<input
class="search-input"
id="search-input"
type="search"
placeholder="Filter docs or sections"
/>
</div>
<button class="nav-toggle btn" id="nav-toggle" type="button">Hide contents</button>
<div class="nav-region">
<h2>Documents</h2>
<ul class="docs-nav" id="docs-nav"></ul>
</div>
</aside>
<main class="content-panel">
<p class="eyebrow" id="page-kicker">Document</p>
<h1 class="page-title" id="page-title">Loading…</h1>
<p class="page-intro" id="page-intro">
Parsing document metadata and content.
</p>
<div class="doc-meta-row" id="doc-meta-row"></div>
<article class="doc-article fade-in" id="doc-article"></article>
<div class="section" id="doc-nav-section">
<div class="section-header">
<div>
<p class="eyebrow">More docs</p>
<h2 class="section-title">Previous and next</h2>
</div>
</div>
<ul class="doc-nav-links" id="doc-nav-links"></ul>
</div>
</main>
<aside class="side-panel">
<h2>On this page</h2>
<p class="muted">Anchors from generated headings.</p>
<ul class="toc-list" id="toc-list"></ul>
</aside>
</div>
</div>
<script>
const themeObserver = new MutationObserver(() => {
const theme = document.documentElement.dataset.theme;
document.getElementById("hljs-theme").href =
theme === "dark"
? "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github-dark.min.css"
: "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/github.min.css";
});
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ["data-theme"],
});
</script>
<script src="/site.js"></script>
<script src="/docs-app.js"></script>
</body>
</html>