parley-cli 0.1.0-rc5

Terminal-first review tool for AI-generated code changes
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
<!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 -&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"
  }
];
    </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>