parley-cli 0.1.0-rc5

Terminal-first review tool for AI-generated code changes
Documentation
[
  {
    "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 -&gt; <code>open</code></li>\n<li>reply from the original commenter -&gt; <code>open</code></li>\n<li>reply from anyone else, including AI -&gt; <code>pending</code></li>\n<li>original commenter marks resolution -&gt; <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 &lt;rev&gt;</code> reviews that commit against its first parent.</li>\n<li><code>--base &lt;rev&gt;</code> reviews <code>&lt;rev&gt;..HEAD</code>.</li>\n<li><code>--base &lt;rev&gt; --head &lt;rev&gt;</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 &lt;rev&gt;</code> shows that commit against its first parent.</li>\n<li><code>--base &lt;rev&gt;</code> defaults <code>head</code> to <code>HEAD</code>.</li>\n<li><code>--base &lt;rev&gt; --head &lt;rev&gt;</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>:&lt;line&gt;</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>:&lt;line&gt;</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>&lt;/&gt;</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>&lt;/&gt;</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 -&gt; <code>open</code></li>\n<li>Reply by original thread author -&gt; <code>open</code></li>\n<li>Reply by different author (including AI in normal flows) -&gt; <code>pending</code></li>\n</ul>\n<h3 id=\"manual-transitions\">Manual transitions</h3>\n<ul>\n<li>Mark open: original thread author -&gt; <code>open</code></li>\n<li>Mark addressed: original thread author -&gt; <code>addressed</code></li>\n<li>Force mark addressed: force path (no author gate) -&gt; <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 -&gt; <code>open</code></li>\n<li>author replies &quot;fixed in 9d2b3af&quot; -&gt; <code>pending</code></li>\n<li>reviewer checks the change and is still unhappy -&gt; reply reopens thread to <code>open</code></li>\n<li>reviewer is satisfied -&gt; 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 &lt;rev&gt;</code>: diff that commit against its first parent</li>\n<li><code>parley tui --base &lt;rev&gt;</code>: diff <code>&lt;rev&gt;..HEAD</code></li>\n<li><code>parley tui --base &lt;rev&gt; --head &lt;rev&gt;</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  &quot;name&quot;: &quot;run_ai_session&quot;,\n  &quot;arguments&quot;: {\n    &quot;review_name&quot;: &quot;my-review&quot;,\n    &quot;provider&quot;: &quot;codex&quot;,\n    &quot;mode&quot;: &quot;reply&quot;\n  }\n}\n</code></pre>\n<p>Refactor mode over open threads only:</p>\n<pre><code class=\"language-json\">{\n  &quot;name&quot;: &quot;run_ai_session&quot;,\n  &quot;arguments&quot;: {\n    &quot;review_name&quot;: &quot;my-review&quot;,\n    &quot;provider&quot;: &quot;codex&quot;,\n    &quot;mode&quot;: &quot;refactor&quot;\n  }\n}\n</code></pre>\n<p>Reply mode on explicit thread IDs:</p>\n<pre><code class=\"language-json\">{\n  &quot;name&quot;: &quot;run_ai_session&quot;,\n  &quot;arguments&quot;: {\n    &quot;review_name&quot;: &quot;my-review&quot;,\n    &quot;provider&quot;: &quot;codex&quot;,\n    &quot;mode&quot;: &quot;reply&quot;,\n    &quot;comment_ids&quot;: [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"
  }
]