parley-cli 0.3.1

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
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
<!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": 1,
        "text": "everything after HEAD~2 (exclude that commit)",
        "id": "everything-after-head2-exclude-that-commit"
      },
      {
        "depth": 1,
        "text": "everything after and including HEAD~2",
        "id": "everything-after-and-including-head2"
      },
      {
        "depth": 2,
        "text": "Root directory reviews",
        "id": "root-directory-reviews"
      },
      {
        "depth": 2,
        "text": "Finding code and hotspots",
        "id": "finding-code-and-hotspots"
      },
      {
        "depth": 2,
        "text": "File references in comment drafts",
        "id": "file-references-in-comment-drafts"
      },
      {
        "depth": 2,
        "text": "Split diffs, logs, and AI sessions",
        "id": "split-diffs-logs-and-ai-sessions"
      },
      {
        "depth": 2,
        "text": "AI agent transports",
        "id": "ai-agent-transports"
      },
      {
        "depth": 3,
        "text": "`.parley/config.toml` AI provider config",
        "id": "parleyconfigtoml-ai-provider-config"
      },
      {
        "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 thread state is 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>: TUI progress is based on per-thread status.</li>\n<li><strong>Keyboard-first workflow</strong>: full navigation and review operations without leaving the terminal.</li>\n<li><strong>Optional AI automation</strong>: run AI thread replies/refactors while keeping state transitions human-controlled.</li>\n</ul>\n<h2 id=\"how-to-think-about-the-app\">How to think about the app</h2>\n<p>Parley is not just a diff viewer and not just a notes file.</p>\n<p>It combines:</p>\n<ul>\n<li>a diff source: working tree, commit, or range</li>\n<li>a local review session: named review metadata stored under <code>.parley/</code></li>\n</ul>\n<p>Each review is its own context. Switching reviews changes the comment threads, replies, and review status shown in the TUI; it does not change the active diff source.</p>\n<p>That review session tracks threads as structured objects with:</p>\n<ul>\n<li>an anchor line in the diff</li>\n<li>an original author</li>\n<li>a thread status</li>\n<li>ordered replies</li>\n</ul>\n<p>This is why status changes are opinionated:</p>\n<ul>\n<li>new thread -&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 TUI treats individual thread status as the source of review progress.</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>addressed</code>: this thread is complete.</li>\n<li>Thread <code>addressed</code> is the completion signal.</li>\n</ul>\n<h2 id=\"ai-eligibility-summary\">AI eligibility summary</h2>\n<ul>\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> and <code>pending</code> threads by default.</li>\n<li>Explicit selected-thread AI actions target the selected thread regardless of status.</li>\n</ul>\n<h2 id=\"typical-session\">Typical session</h2>\n<pre><code class=\"language-bash\">parley review create my-review\nparley review start my-review\nparley tui --review my-review\n</code></pre>\n<p>The TUI requires an explicit existing review. Create the review first with <code>parley review create &lt;name&gt;</code>, then open it with <code>parley tui --review &lt;name&gt;</code>.</p>\n<p>If you are running over SSH and your terminal client does not play well with mouse reporting, start the TUI with <code>--no-mouse</code>.</p>\n<h2 id=\"revision-sources\">Revision sources</h2>\n<p>By default, Parley reviews the current working tree diff against <code>HEAD</code>.</p>\n<p>You can also open historical diffs directly in the TUI:</p>\n<pre><code class=\"language-bash\">parley tui --commit HEAD~2\nparley tui --base origin/trunk --head feature/my-branch\nparley tui --base v0.1.0\n# everything after HEAD~2 (exclude that commit)\nparley tui --base HEAD~2 --head HEAD\n# everything after and including HEAD~2\nparley tui --base HEAD~2^ --head HEAD\n</code></pre>\n<ul>\n<li><code>--commit &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<li>Use <code>--base &lt;rev&gt; --head HEAD</code> to review everything after <code>&lt;rev&gt;</code>.</li>\n<li>Use <code>--base &lt;rev&gt;^ --head HEAD</code> to include <code>&lt;rev&gt;</code> itself in that cumulative range.</li>\n</ul>\n<p>AI sessions and TUI refresh use the same selected revision source, so they stay aligned with the diff you opened.</p>\n<p>From inside the TUI, use <code>Ctrl+k</code> to open the command palette, choose <code>Open Commit Picker</code>, then search by commit message or SHA. <code>Enter</code> switches the active diff source to the selected commit, and <code>Esc</code> closes the picker without changing the current diff.</p>\n<p>Use <code>Ctrl+k</code> and <code>Open Review Picker</code> to switch the active review context. The picker filters by review name or state and shows each review's thread counts. Applying a review reloads the review-owned comments while keeping the current diff source.</p>\n<p>Use <code>Ctrl+k</code> and <code>Create Review</code> to create a new review from inside the TUI and switch to it immediately. Entering a name in the review picker that has no matches also opens the create-review prompt.</p>\n<p>Current limitation:</p>\n<ul>\n<li>the selected revision source is not persisted into the review session yet, so reopening the review later still requires passing the same CLI flags again.</li>\n</ul>\n<h2 id=\"root-directory-reviews\">Root directory reviews</h2>\n<p>Use <code>--root</code> when you want to review files in the current repository root instead of a git diff:</p>\n<pre><code class=\"language-bash\">parley tui --review my-review --root\n</code></pre>\n<p><code>--review</code> is still required, and the review must already exist. Create it first with <code>parley review create &lt;name&gt;</code>.</p>\n<p>Root mode loads tracked files plus untracked files that are not ignored by git. It skips <code>.git/</code>, <code>.parley/</code>, and <code>worktrees/</code>. Files are shown as context lines, so comments attach to the current file line numbers instead of added or removed diff lines.</p>\n<p>Root mode is lazy-loaded for startup performance. The TUI builds the file tree first, shows load progress while file data hydrates, and loads file content when the file is selected or opened from search. Root mode opens raw source by default. Press <code>D</code> / <code>Shift+d</code> or use command palette <code>Toggle Root JSON/Markdown Rendering</code> to switch JSON files into pretty-printed display and Markdown files into readable rendered text rows.</p>\n<h2 id=\"finding-code-and-hotspots\">Finding code and hotspots</h2>\n<p>Current-file search is available from <code>/</code> and uses <code>rg</code> when available with a <code>grep</code> fallback. Codebase search is available from <code>Ctrl+g</code> or command palette <code>Search Codebase</code>; results update while typing, show the match count and search engine, and <code>Enter</code> or mouse click opens the selected file at the matched line.</p>\n<p>The git file heatmap is available from <code>M</code> or command palette <code>Show Git File Heatmap</code>. It scans git history only when requested, not at startup, and renders per-file hotspots as colored cells.</p>\n<p>Heatmap sort modes:</p>\n<ul>\n<li><code>churn</code>: added plus removed lines</li>\n<li><code>added</code>: total lines added</li>\n<li><code>removed</code>: total lines removed</li>\n<li><code>commits</code>: commits touching the file</li>\n<li><code>net-growth</code>: added minus removed lines</li>\n<li><code>net-shrink</code>: removed minus added lines</li>\n<li><code>volatility</code>: churn per touching commit</li>\n<li><code>path</code>: path name</li>\n</ul>\n<p>Press <code>s</code> in the heatmap to cycle sort mode and <code>S</code> to reverse sort direction. Heatmap color intensity follows the active sort metric, so the strongest color always means the file is hottest for the current sort.</p>\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<p>Comment drafts wrap inside the editor instead of extending as one long terminal line. Wrapped display preserves words when possible, so long comments remain readable before saving.</p>\n<h2 id=\"split-diffs-logs-and-ai-sessions\">Split diffs, logs, and AI sessions</h2>\n<p>Use <code>Ctrl+v</code> or command palette <code>Toggle Split View</code> to toggle split view, <code>S</code> to toggle side-by-side diff layout, and <code>Tab</code> to switch the active pane. Added and removed lines use tinted backgrounds so large diffs are easier to scan.</p>\n<p>Use <code>v</code> or <code>V</code> for visual line selection before creating a range comment. After selecting a range, <code>m</code> or <code>c</code> opens the comment box at the bottom of the selection. Saved range comments keep the covered lines highlighted and send the selected line range to AI prompt context.</p>\n<p>Use <code>Ctrl+t</code> or command palette <code>Open Thread Selector</code> to search all threads in the active review by file, status, id, line reference, or body preview. Selecting a thread jumps to its file and focuses the thread. In root mode, stale or detached comments are still shown at their stored line reference when the original anchor text no longer matches current file content.</p>\n<p>AI task output is tracked as file-scoped sessions in the TUI. Starting an AI run opens and follows the current file's AI log popup. <code>H</code> toggles that popup; navigating away does not discard that file's session output. <code>L</code> opens the global AI activity pane, which lists running and recent sessions across files and jumps back to the selected file/session with <code>Enter</code>.</p>\n<p>Comments and AI logs are intentionally separate. Comments remain durable review state anchored to file lines and ranges. AI logs are transient session transcripts from ACP, Pi RPC, or CLI transport events, including provider startup/config failures. Agent output becomes a review reply only through the explicit AI reply/refactor flow that persists a reply on the target thread.</p>\n<h2 id=\"ai-agent-transports\">AI agent transports</h2>\n<p>Parley prefers persistent agent transports over one-shot CLI prompt execution:</p>\n<ul>\n<li><code>opencode</code>: ACP via <code>opencode acp</code></li>\n<li><code>codex</code>: ACP via <code>codex-acp</code></li>\n<li><code>claude</code>: ACP via <code>claude-agent-acp</code></li>\n<li><code>pi</code>: persistent JSONL RPC via <code>pi --mode rpc --no-session</code>, not ACP</li>\n</ul>\n<p>Provider config still supports <code>transport = &quot;cli&quot;</code> as an explicit fallback. ACP agents stream <code>session/update</code> events into the per-file AI logs, and final thread replies are built from agent message chunks rather than thought chunks.</p>\n<p>If an older config points ACP transport at a one-shot CLI command such as <code>codex exec</code>, <code>claude -p</code>, or <code>opencode run</code>, Parley rejects the run before spawning the process and shows the config error in the AI logs. Configure an ACP-capable command such as <code>codex-acp</code>, <code>claude-agent-acp</code>, or <code>opencode acp</code>, or set <code>transport = &quot;cli&quot;</code> when one-shot CLI mode is intentional.</p>\n<p>Use <code>i</code> in the TUI to cycle the active AI provider. The active provider is shown in the status panel.</p>\n<p>Use <code>I</code> in the TUI to toggle the active AI transport between ACP and CLI for providers that support both. The selected transport is saved as <code>ai.default_transport</code>, which accepts only the generic <code>acp</code> and <code>cli</code> choices. Pi ignores the toggle and keeps using provider-specific <code>pi_rpc</code>.</p>\n<h3 id=\"parleyconfigtoml-ai-provider-config\"><code>.parley/config.toml</code> AI provider config</h3>\n<p>Parley reads project-local config from <code>.parley/config.toml</code>. If the file is missing, these AI defaults are used:</p>\n<pre><code class=\"language-toml\">[ai]\ntimeout_seconds = 120\ndefault_provider = &quot;opencode&quot;\ndefault_transport = &quot;acp&quot;\n\n[ai.codex]\ntransport = &quot;acp&quot;\nclient = &quot;codex-acp&quot;\nargs = []\n\n[ai.claude]\ntransport = &quot;acp&quot;\nclient = &quot;claude-agent-acp&quot;\nargs = []\n\n[ai.opencode]\ntransport = &quot;acp&quot;\nclient = &quot;opencode&quot;\nargs = [&quot;acp&quot;]\nmodel_arg = &quot;-m&quot;\n\n[ai.pi]\ntransport = &quot;pi_rpc&quot;\nclient = &quot;pi&quot;\nargs = [&quot;--mode&quot;, &quot;rpc&quot;, &quot;--no-session&quot;]\n</code></pre>\n<p>Use CLI transport only for explicit one-shot command mode:</p>\n<pre><code class=\"language-toml\">[ai.codex]\ntransport = &quot;cli&quot;\nclient = &quot;codex&quot;\nargs = [&quot;exec&quot;]\n\n[ai.claude]\ntransport = &quot;cli&quot;\nclient = &quot;claude&quot;\nargs = [&quot;-p&quot;]\n\n[ai.opencode]\ntransport = &quot;cli&quot;\nclient = &quot;opencode&quot;\nargs = [&quot;run&quot;]\n</code></pre>\n<p>Custom prompt templates can be configured globally or per AI mode:</p>\n<pre><code class=\"language-toml\">[ai]\nprompt_path = &quot;prompts/ai.md&quot;\nreply_prompt_path = &quot;prompts/reply.md&quot;\nrefactor_prompt_path = &quot;prompts/refactor.md&quot;\n</code></pre>\n<h2 id=\"local-state-and-diff-filtering\">Local state and diff filtering</h2>\n<p>Parley stores config under <code>.parley/</code> and review-owned data under normalized review directories:</p>\n<pre><code class=\"language-text\">.parley/\n  config.toml\n  reviews/\n    &lt;review-name&gt;/\n      review.json\n      logs/\n        tui.log\n</code></pre>\n<p>Comments, replies, thread state, review state, and TUI logs belong to that review directory.</p>\n<p>Older flat files such as <code>.parley/reviews/&lt;review-name&gt;.json</code> are still readable.</p>\n<p>Those <code>.parley/</code> files are ignored by default when Parley builds the review diff, so local review metadata does not pollute the file sidebar. This behavior is configurable through <code>.parley/config.toml</code>:</p>\n<pre><code class=\"language-toml\">ignore_parley_dir = false\n</code></pre>\n<h2 id=\"what-pending-means\">What <code>pending</code> means</h2>\n<ul>\n<li><code>pending</code> indicates the thread is waiting on counterpart follow-up after a reply.</li>\n<li>A thread returns to <code>open</code> when the original author replies again or explicitly marks it open.</li>\n</ul>\n<h2 id=\"completion-behavior\">Completion behavior</h2>\n<ul>\n<li>TUI completion is per-thread: <code>a</code> marks the selected thread addressed, and <code>o</code> reopens it.</li>\n</ul>\n"
  },
  {
    "slug": "quickstart",
    "title": "Quickstart",
    "summary": "Covers Build, What Parley is actually doing, and Create a review session.",
    "headings": [
      {
        "depth": 1,
        "text": "Quickstart",
        "id": "quickstart"
      },
      {
        "depth": 2,
        "text": "Build",
        "id": "build"
      },
      {
        "depth": 2,
        "text": "What Parley is actually doing",
        "id": "what-parley-is-actually-doing"
      },
      {
        "depth": 2,
        "text": "Create a review session",
        "id": "create-a-review-session"
      },
      {
        "depth": 2,
        "text": "Open the TUI on your current changes",
        "id": "open-the-tui-on-your-current-changes"
      },
      {
        "depth": 2,
        "text": "Open a specific commit or range",
        "id": "open-a-specific-commit-or-range"
      },
      {
        "depth": 1,
        "text": "everything after HEAD~2 (exclude that commit)",
        "id": "everything-after-head2-exclude-that-commit"
      },
      {
        "depth": 1,
        "text": "everything after and including HEAD~2",
        "id": "everything-after-and-including-head2"
      },
      {
        "depth": 2,
        "text": "Review the current root directory",
        "id": "review-the-current-root-directory"
      },
      {
        "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": 3,
        "text": "Customize AI task prompts",
        "id": "customize-ai-task-prompts"
      },
      {
        "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": 3,
        "text": "Split diff layout",
        "id": "split-diff-layout"
      },
      {
        "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<li>the current repository root with <code>--root</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 state exists for compatibility, but TUI completion is thread-based</li>\n</ul>\n<p>That matters because comments are not just free-form notes. Each thread is attached to a file path and line reference, and replies update the parent thread status.</p>\n<p>The review session is the comment context. Switching reviews changes which comments and review state are visible, while the selected diff source stays as-is.</p>\n<h2 id=\"create-a-review-session\">Create a review session</h2>\n<pre><code class=\"language-bash\">./target/release/parley review create my-review\n./target/release/parley review start my-review\n</code></pre>\n<p><code>review create</code> creates the local session. <code>review start</code> moves it into <code>under_review</code>, but the moment you add an <code>open</code> thread, the review state automatically becomes <code>open</code> again.</p>\n<h2 id=\"open-the-tui-on-your-current-changes\">Open the TUI on your current changes</h2>\n<pre><code class=\"language-bash\">./target/release/parley tui --review my-review\n</code></pre>\n<p><code>--review</code> is required, and the review must already exist. Create it first with <code>review create</code>.</p>\n<p>If your terminal or SSH session mishandles mouse reporting, disable mouse capture:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --review my-review --no-mouse\n</code></pre>\n<p>The TUI never creates or guesses a startup review. Review context is explicit so comments are always written under the intended review.</p>\n<h2 id=\"open-a-specific-commit-or-range\">Open a specific commit or range</h2>\n<p>By default, the TUI opens the current working tree diff. You can also open historical revisions:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --commit HEAD~2\n./target/release/parley tui --base origin/trunk --head feature/my-branch\n./target/release/parley tui --base v0.1.0\n# everything after HEAD~2 (exclude that commit)\n./target/release/parley tui --base HEAD~2 --head HEAD\n# everything after and including HEAD~2\n./target/release/parley tui --base HEAD~2^ --head HEAD\n</code></pre>\n<ul>\n<li><code>--commit &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<li>Use <code>--base &lt;rev&gt; --head HEAD</code> to review everything after <code>&lt;rev&gt;</code>.</li>\n<li>Use <code>--base &lt;rev&gt;^ --head HEAD</code> to include <code>&lt;rev&gt;</code> itself in that cumulative range.</li>\n</ul>\n<p>Refresh (<code>R</code>) keeps using the same source while the TUI session stays open, and AI prompt context follows that same diff source.</p>\n<p>You can also switch to a specific commit from inside the TUI:</p>\n<ol>\n<li>Press <code>Ctrl+k</code> to open the command palette.</li>\n<li>Choose <code>Open Commit Picker</code>.</li>\n<li>Type part of a commit message, short SHA, or full SHA to filter the recent commit list.</li>\n<li>Use <code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, <code>Home</code>, or <code>End</code> to select a commit.</li>\n<li>Press <code>Enter</code> to apply it.</li>\n</ol>\n<p>The picker changes only Parley's active diff source. It does not run <code>git checkout</code> or modify the working tree.</p>\n<p>To switch comment context without changing the diff:</p>\n<ol>\n<li>Press <code>Ctrl+k</code> to open the command palette.</li>\n<li>Choose <code>Open Review Picker</code>.</li>\n<li>Filter by review name or state.</li>\n<li>Press <code>Enter</code> to apply the selected review.</li>\n</ol>\n<p>The TUI reloads comments from the selected review and keeps the current diff source.</p>\n<p>To create a new review from inside the TUI, use <code>Ctrl+k</code> and <code>Create Review</code>. The new review becomes active immediately, and later comments are written to that review's directory. If the review picker has no matches for the typed name, pressing <code>Enter</code> opens the same create-review prompt with that name.</p>\n<p>Current limitation:</p>\n<ul>\n<li>reopening the review later does not restore the revision source automatically; pass the same flags again.</li>\n</ul>\n<h2 id=\"review-the-current-root-directory\">Review the current root directory</h2>\n<p>Use root mode when you want to review the repository as files, not as a git diff:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --review my-review --root\n</code></pre>\n<p><code>--review</code> is still required, and the review must already exist. Root mode does not create or guess a review.</p>\n<p>Root mode includes tracked files and untracked files that are not ignored by gitignore rules. It skips <code>.git/</code>, <code>.parley/</code>, and <code>worktrees/</code>. Each file is displayed as context lines, so comments attach to the file's current line numbers.</p>\n<p>Startup in root mode lazy-loads file content. The file tree appears first, load progress is shown while data hydrates, and individual files load when selected or opened from search. Root mode opens raw source by default. Press <code>D</code> / <code>Shift+d</code> or use command palette <code>Toggle Root JSON/Markdown Rendering</code> to switch <code>.json</code> files into pretty-printed JSON and Markdown files into readable rendered text rows.</p>\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 each issue is resolved, mark its thread addressed.</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 unresolved 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>Starting an AI run opens and follows the current file's AI logs so provider startup/config errors and stream output are visible.</p>\n<h3 id=\"customize-ai-task-prompts\">Customize AI task prompts</h3>\n<p>Parley always builds thread context from the selected comment, replies, target file, diff hunk, and referenced files. You can replace the final task instructions appended to that context with markdown files configured in <code>.parley/config.toml</code>.</p>\n<p>Use one shared prompt for all AI modes:</p>\n<pre><code class=\"language-toml\">[ai]\nprompt_path = &quot;prompts/parley-ai.md&quot;\n</code></pre>\n<p>Or use mode-specific prompts:</p>\n<pre><code class=\"language-toml\">[ai]\nreply_prompt_path = &quot;prompts/parley-reply.md&quot;\nrefactor_prompt_path = &quot;prompts/parley-refactor.md&quot;\n</code></pre>\n<p>Mode-specific paths take precedence over <code>prompt_path</code>. Relative paths are resolved from the repository root where Parley is started. If a configured prompt file cannot be read, the AI session fails before invoking the provider.</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>/&lt;text&gt;</code>: search within the current file</li>\n<li><code>Ctrl+g</code>: open codebase search popup</li>\n<li>File and codebase search use <code>rg</code> when available and fall back to <code>grep</code></li>\n<li>Codebase search respects gitignore rules and updates results while you type</li>\n<li><code>Enter</code> or mouse click on a result opens the matched file and line</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>v</code> or <code>V</code>: start or clear visual line selection</li>\n<li>With visual line selection active, move to the end of the range and press <code>m</code> or <code>c</code> to open the comment box at the bottom of that range</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>Ctrl+t</code>: open the global thread selector</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<li>Long comment drafts wrap inside the editor, preserving whole words when possible</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</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>thread <code>addressed</code> is the completion signal used in the TUI</li>\n</ul>\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>i</code>: cycle AI provider (<code>codex</code>, <code>claude</code>, <code>opencode</code>, <code>pi</code>)</li>\n<li><code>I</code>: toggle AI transport (<code>acp</code> or <code>cli</code>) for providers that support both</li>\n<li><code>K</code>: cancel current AI run</li>\n<li><code>H</code>: toggle per-file AI logs popup</li>\n<li><code>L</code>: toggle the global AI activity pane</li>\n<li>AI activity <code>Enter</code>: jump to the selected file/session logs</li>\n<li><code>Ctrl+k</code>: open command palette</li>\n<li>Command palette <code>Search Codebase</code>: open live repository search</li>\n<li>Command palette <code>Show AI Activity</code>: open the global AI session activity pane</li>\n<li>Command palette <code>Toggle AI Transport</code>: switch between ACP and CLI for the active provider</li>\n<li>Command palette <code>Open Thread Selector</code>: search and jump across all review threads</li>\n<li>Command palette <code>Show Git File Heatmap</code>: scan git history on demand and show file hotspots</li>\n<li>Command palette <code>Open Commit Picker</code>: switch the active diff source to a recent commit</li>\n<li>Command palette <code>Open Review Picker</code>: switch the active review context</li>\n<li>Command palette <code>Create Review</code>: create a new review context and switch to it</li>\n<li><code>M</code>: open the git file heatmap</li>\n<li>Heatmap <code>s</code>: cycle sort by churn, added, removed, commits, net growth, net shrink, volatility, or path</li>\n<li>Heatmap <code>S</code>: reverse the active heatmap sort</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<p>By default, agent providers use persistent transports instead of spawning a one-shot CLI prompt for every thread. OpenCode uses ACP with <code>opencode acp</code>, Codex uses <code>codex-acp</code>, Claude uses <code>claude-agent-acp</code>, and Pi uses <code>pi --mode rpc --no-session</code>. Pi is RPC, not ACP. Set a provider's <code>transport = &quot;cli&quot;</code> in <code>.parley/config.toml</code> only when you explicitly need the old one-shot behavior. If ACP is configured with a non-ACP command such as <code>codex exec</code> or <code>opencode run</code>, Parley fails fast and shows the config error in the AI logs.</p>\n<p>The default <code>.parley/config.toml</code> AI shape is:</p>\n<pre><code class=\"language-toml\">[ai]\ntimeout_seconds = 120\ndefault_provider = &quot;opencode&quot;\ndefault_transport = &quot;acp&quot;\n\n[ai.codex]\ntransport = &quot;acp&quot;\nclient = &quot;codex-acp&quot;\nargs = []\n\n[ai.claude]\ntransport = &quot;acp&quot;\nclient = &quot;claude-agent-acp&quot;\nargs = []\n\n[ai.opencode]\ntransport = &quot;acp&quot;\nclient = &quot;opencode&quot;\nargs = [&quot;acp&quot;]\nmodel_arg = &quot;-m&quot;\n\n[ai.pi]\ntransport = &quot;pi_rpc&quot;\nclient = &quot;pi&quot;\nargs = [&quot;--mode&quot;, &quot;rpc&quot;, &quot;--no-session&quot;]\n</code></pre>\n<p>For one-shot CLI mode, configure the provider explicitly:</p>\n<pre><code class=\"language-toml\">[ai.codex]\ntransport = &quot;cli&quot;\nclient = &quot;codex&quot;\nargs = [&quot;exec&quot;]\n</code></pre>\n<p>The TUI can also switch transport at runtime with <code>I</code>. The active selection is stored as <code>ai.default_transport</code>, which accepts only the generic <code>acp</code> and <code>cli</code> choices. Parley uses built-in CLI profiles for <code>codex</code>, <code>claude</code>, and <code>opencode</code> when that value is <code>cli</code>. Pi keeps using provider-specific <code>pi_rpc</code>.</p>\n<p>Parley stores AI output as per-file session logs in memory while the TUI is open. Starting an AI run opens/follows the current file logs. <code>H</code> shows transcripts for the current file, and <code>L</code> shows a global activity index for running and recent sessions. Review comments are separate durable state; AI output is added to a thread only when the AI review flow persists a reply.</p>\n<p>The thread selector is separate from the per-file thread navigator. <code>Ctrl+t</code> searches all threads in the active review and jumps to the selected file/thread with <code>Enter</code>. In root mode, comments whose original anchor text no longer matches are still displayed at their stored line reference so pending threads do not disappear after refactors.</p>\n<h3 id=\"split-diff-layout\">Split diff layout</h3>\n<ul>\n<li><code>Ctrl+v</code>: toggle split view</li>\n<li>Command palette <code>Toggle Split View</code>: toggle split view from the command list</li>\n<li><code>S</code>: toggle side-by-side diff layout</li>\n<li><code>Tab</code>: switch active diff pane</li>\n<li>Added and removed lines use tinted backgrounds to make changed regions easier to scan</li>\n</ul>\n<h2 id=\"a-realistic-first-session\">A realistic first session</h2>\n<pre><code class=\"language-bash\">./target/release/parley review create parser-cleanup\n./target/release/parley review start parser-cleanup\n./target/release/parley tui --review parser-cleanup\n</code></pre>\n<p>Inside the TUI:</p>\n<ul>\n<li>move through changed files with <code>h/l</code></li>\n<li>move inside the diff with <code>j/k</code></li>\n<li>press <code>c</code> on a changed line to leave a thread</li>\n<li>press <code>r</code> on that thread to reply later</li>\n<li>press <code>R</code> after editing code in another terminal</li>\n<li>press <code>a</code> when the original reviewer considers the issue resolved</li>\n<li>press <code>d</code> when the review is actually complete</li>\n</ul>\n<p>For a historical review:</p>\n<pre><code class=\"language-bash\">./target/release/parley tui --review parser-cleanup --base origin/trunk --head feature/parser-cleanup\n</code></pre>\n<p>That lets you keep one named review session while pointing the TUI at an explicit base/head diff.</p>\n<h2 id=\"config\">Config</h2>\n<p>Parley reads configuration from <code>.parley/config.toml</code> and stores review-owned state under <code>.parley/reviews/&lt;review-name&gt;/</code>.</p>\n<p>Each review directory contains:</p>\n<pre><code class=\"language-text\">review.json\nlogs/tui.log\n</code></pre>\n<p>All comments, replies, thread status, review status, and TUI logs for that review stay under this directory.</p>\n<p>Older flat review files in <code>.parley/reviews/&lt;review-name&gt;.json</code> are still loaded.</p>\n<p>By default, Parley ignores its own <code>.parley/</code> files when building the review diff so that review metadata and logs do not show up in the file list.</p>\n<p>To include <code>.parley/</code> in the diff again, set:</p>\n<pre><code class=\"language-toml\">ignore_parley_dir = false\n</code></pre>\n<h3 id=\"which-status-to-set-before-ai\">Which status to set before AI</h3>\n<ul>\n<li>For review-wide <code>refactor</code> (<code>A</code>): target threads must be <code>open</code> or <code>pending</code>.</li>\n<li>For selected-thread AI (<code>x</code> or <code>X</code>): the selected thread is sent unless it is <code>addressed</code>.</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": "Root file rendering",
        "id": "root-file-rendering"
      },
      {
        "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>q</code>: quit</li>\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<li><code>R</code>: refresh review and diff/root source</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>/&lt;text&gt;</code>: search within the current file (<code>rg</code>, falling back to <code>grep</code>)</li>\n<li><code>Ctrl+g</code>: open codebase search popup (<code>rg</code>, falling back to <code>grep</code>)</li>\n<li>Code search <code>type</code>: update results live</li>\n<li>Code search <code>Enter</code>: open selected file and line</li>\n<li>Code search <code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, <code>Home</code>, <code>End</code>: move selected result</li>\n<li>Code search mouse: click a result to open that file and line</li>\n<li>Code search <code>Esc</code>: close search</li>\n<li><code>n/p</code>: next/previous in-diff 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>v</code> or <code>V</code>: start or clear visual line selection for a range comment</li>\n<li>With visual line selection active, move with <code>j/k</code> or arrows, then press <code>m</code> or <code>c</code> to open the comment box at the bottom of the selected range</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>Ctrl+t</code>: open global thread selector</li>\n<li>Thread selector <code>Enter</code>: jump to selected thread and file</li>\n<li>Thread selector <code>type</code>: filter by file, status, id, line, or body preview</li>\n<li><code>e</code>: toggle selected thread expansion</li>\n<li><code>Shift+E</code>: cycle thread density</li>\n<li><code>a</code>: mark addressed</li>\n<li><code>o</code>: mark open</li>\n<li><code>f</code>: force-address selected thread</li>\n<li><code>u</code>: re-anchor selected thread to the currently selected diff line</li>\n</ul>\n<h3 id=\"file-references-inside-the-comment-box\">File references inside the comment box</h3>\n<ul>\n<li>Type <code>@</code> in the comment or reply box to open the file reference picker.</li>\n<li><code>↑/↓</code> or <code>PgUp/PgDn</code>: move through file matches</li>\n<li><code>Enter</code> or <code>Tab</code>: accept the selected file and enter line-picker mode</li>\n<li>While line-picker mode is active, Parley opens that file in the current diff pane and tells you to select a diff line in the editor itself.</li>\n<li><code>↑/↓</code>, <code>j/k</code>, <code>PgUp/PgDn</code>, <code>g/G</code>: move to the target diff line</li>\n<li><code>Enter</code> or <code>Tab</code>: insert <code>@path:line</code> for the currently selected line</li>\n<li>Mouse: click a diff line while line-picker mode is active to insert that line immediately</li>\n<li>After inserting the reference, Parley returns to the file and diff line where you started writing the draft.</li>\n<li><code>Esc</code>: cancel the picker; if the file is already inserted, it leaves the bare <code>@path</code> in place</li>\n</ul>\n<h3 id=\"comment-editor-word-motions\">Comment editor word motions</h3>\n<ul>\n<li><code>Alt+b</code>: move backward one whitespace-delimited word in the draft</li>\n<li><code>Alt+d</code>: delete forward through the next whitespace-delimited word in the draft</li>\n<li>Long comments wrap inside the editor, preserving whole words when possible</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</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>i</code>: cycle AI provider (<code>codex</code>, <code>claude</code>, <code>opencode</code>, <code>pi</code>)</li>\n<li><code>I</code>: toggle AI transport between ACP and CLI for providers that support both</li>\n<li><code>K</code>: cancel active AI run</li>\n<li><code>H</code>: toggle per-file AI logs popup</li>\n<li><code>L</code>: toggle global AI activity pane</li>\n<li>Starting an AI run opens/follows the current file's AI logs so provider startup errors and stream output are visible.</li>\n<li>AI activity <code>Enter</code>: jump to the selected file/session logs</li>\n<li>AI activity <code>j/k</code>, <code>PgUp/PgDn</code>, <code>Home</code>, <code>End</code>: select a session</li>\n</ul>\n<h2 id=\"layout-and-tools\">Layout and tools</h2>\n<ul>\n<li><code>?</code>: open help docs</li>\n<li><code>Ctrl+k</code>: command palette</li>\n<li>Command palette <code>Search Codebase</code>: open live repository search</li>\n<li>Command palette <code>Show AI Activity</code>: open the global AI session activity pane</li>\n<li>Command palette <code>Toggle AI Transport</code>: switch between ACP and CLI for the active provider</li>\n<li>Command palette <code>Toggle Active File Group</code>: collapse or expand the active file group</li>\n<li>Command palette <code>Collapse All File Groups</code>: collapse every file group visible under the current filter</li>\n<li>Command palette <code>Open Commit Picker</code>: open recent commits, filter by message or SHA, and apply the selected commit as the active diff source</li>\n<li>Command palette <code>Open Review Picker</code>: open reviews, filter by name or state, and apply the selected review as the active comment context</li>\n<li>Command palette <code>Open Thread Selector</code>: search and jump across all review threads</li>\n<li>Command palette <code>Create Review</code>: create a new review context and switch to it</li>\n<li><code>M</code> or command palette <code>Show Git File Heatmap</code>: scan full git history on demand and show file hotspots</li>\n<li>Heatmap <code>s</code>: cycle sort (<code>churn</code>, <code>added</code>, <code>removed</code>, <code>commits</code>, <code>net-growth</code>, <code>net-shrink</code>, <code>volatility</code>, <code>path</code>)</li>\n<li>Heatmap <code>S</code>: reverse sort direction</li>\n<li>Heatmap color follows the active sort metric</li>\n<li><code>Ctrl+f</code>: file filter input</li>\n<li><code>F</code>: cycle file filter mode</li>\n<li><code>O</code>: cycle file sort mode</li>\n<li><code>Shift+U</code>: edit user name</li>\n<li><code>t</code>: open theme picker</li>\n<li><code>T</code>: toggle light/dark theme variant</li>\n<li><code>Ctrl+v</code>: toggle split view</li>\n<li>Command palette <code>Toggle Split View</code>: toggle split view without using the visual-selection key</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>Enter</code>: collapse or expand the active file group</li>\n<li><code>Shift+C</code>: collapse all visible file groups</li>\n<li>Mouse: click a file group header to collapse or expand it</li>\n<li><code>b</code>: toggle thread navigator</li>\n</ul>\n<h2 id=\"root-file-rendering\">Root file rendering</h2>\n<ul>\n<li><code>D</code> / <code>Shift+d</code>: toggle rendered document view in <code>--root</code> mode.</li>\n<li>Rendered document view is off by default; root mode opens files as raw source rows.</li>\n<li>With rendered document view enabled, <code>.json</code> files are shown as pretty-printed JSON.</li>\n<li>With rendered document view enabled, <code>.md</code>, <code>.markdown</code>, <code>.mdown</code>, and <code>.mkd</code> files are rendered as readable Markdown text rows.</li>\n<li><code>R</code>: refresh the root source if file content changed while Parley is open.</li>\n<li>Command palette <code>Toggle Root JSON/Markdown Rendering</code>: same as <code>D</code> / <code>Shift+d</code>.</li>\n<li>Command palette search terms <code>json</code>, <code>markdown</code>, <code>pretty</code>, or <code>render</code> surface the toggle.</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"
      },
      {
        "depth": 2,
        "text": "10. Reviewing the current root directory",
        "id": "10-reviewing-the-current-root-directory"
      },
      {
        "depth": 2,
        "text": "11. Searching and hotspot review",
        "id": "11-searching-and-hotspot-review"
      },
      {
        "depth": 2,
        "text": "12. Custom AI task prompts",
        "id": "12-custom-ai-task-prompts"
      }
    ],
    "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>TUI completion is handled per thread with <code>addressed</code>.</li>\n</ul>\n<p>Review-level completion is not exposed by the TUI. Thread <code>addressed</code> is the completion signal.</p>\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<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: any selected status</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>review-wide AI refactor selects <code>open</code> and <code>pending</code> threads by default</li>\n<li>explicit selected-thread refactor targets the selected thread unless it is <code>addressed</code></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 selected-thread reply targets the selected thread unless it is <code>addressed</code></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<li><code>parley tui --base &lt;rev&gt; --head HEAD</code>: diff everything after <code>&lt;rev&gt;</code></li>\n<li><code>parley tui --base &lt;rev&gt;^ --head HEAD</code>: diff everything after and including <code>&lt;rev&gt;</code></li>\n</ul>\n<p>AI sessions use the same selected revision source for prompt context.</p>\n<h2 id=\"10-reviewing-the-current-root-directory\">10. Reviewing the current root directory</h2>\n<p>Use <code>parley tui --review &lt;name&gt; --root</code> to review the current repository root without requiring a git diff or commit. <code>--review</code> is required, and the review must already exist. Create it first with <code>parley review create &lt;name&gt;</code>.</p>\n<p>Root-directory review mode loads tracked files plus untracked files that are not ignored by gitignore rules. It skips <code>.git</code>, <code>.parley</code>, and <code>worktrees/</code> directories. Each file is shown as context lines so comments can attach to the current file line numbers.</p>\n<p>Root-directory review mode lazy-loads file content for startup performance. The TUI shows the file tree first, shows progress while file data loads, and opens file content when selected or when code search jumps to a match. JSON files are pretty-printed for display, and Markdown files are rendered into readable text rows.</p>\n<h2 id=\"11-searching-and-hotspot-review\">11. Searching and hotspot review</h2>\n<p>Use <code>/</code> to search within the current file. Use <code>Ctrl+g</code> or command palette <code>Search Codebase</code> to search the repository from inside the TUI. Parley uses <code>rg</code> when available and falls back to <code>grep</code>; codebase results update while typing and <code>Enter</code> or mouse click opens the selected file and line.</p>\n<p>Use <code>M</code> or command palette <code>Show Git File Heatmap</code> to scan git history on demand. The heatmap ranks files by the selected metric and colors each file cell from the active sort value.</p>\n<p>Heatmap sort modes:</p>\n<ul>\n<li><code>churn</code>: added plus removed lines</li>\n<li><code>added</code>: total lines added</li>\n<li><code>removed</code>: total lines removed</li>\n<li><code>commits</code>: commits touching the file</li>\n<li><code>net-growth</code>: added minus removed lines</li>\n<li><code>net-shrink</code>: removed minus added lines</li>\n<li><code>volatility</code>: churn per touching commit</li>\n<li><code>path</code>: path name</li>\n</ul>\n<p>Inside the heatmap, <code>s</code> cycles sort mode and <code>S</code> reverses direction.</p>\n<h2 id=\"12-custom-ai-task-prompts\">12. Custom AI task prompts</h2>\n<p>Parley's AI prompt has two parts:</p>\n<ul>\n<li>generated review context from the selected thread, replies, target file, diff hunk, and referenced files</li>\n<li>task instructions for the selected AI mode</li>\n</ul>\n<p>Configure markdown files in <code>.parley/config.toml</code> to replace the task-instruction part:</p>\n<pre><code class=\"language-toml\">[ai]\nprompt_path = &quot;prompts/parley-ai.md&quot;\nreply_prompt_path = &quot;prompts/parley-reply.md&quot;\nrefactor_prompt_path = &quot;prompts/parley-refactor.md&quot;\n</code></pre>\n<p><code>reply_prompt_path</code> is used for reply mode, and <code>refactor_prompt_path</code> is used for refactor mode. If a mode-specific path is absent, Parley falls back to <code>prompt_path</code>. If no custom prompt path is configured, Parley uses the built-in prompt for that mode.</p>\n<p>Relative paths are resolved from the repository root where Parley is started. If a configured markdown file cannot be read, the AI session fails before invoking the provider.</p>\n<p>Inside the TUI, <code>Ctrl+k</code> opens the command palette. Select <code>Open Commit Picker</code> to choose from recent commits, filter by message or SHA, and press <code>Enter</code> to apply the selected commit as the active diff source.</p>\n<p>Select <code>Open Review Picker</code> from the same command palette to switch review context. This reloads comments, replies, and review state from the selected review while keeping the active working tree, commit, or range diff unchanged.</p>\n<p>Select <code>Create Review</code> to create a new review context from inside the TUI and switch to it immediately. New comments then persist under that review's directory.</p>\n<p>Current limitation:</p>\n<ul>\n<li>the revision source is not stored in the review session yet, so a later reopen still needs the same CLI flags.</li>\n</ul>\n"
  },
  {
    "slug": "mcp",
    "title": "MCP Integration",
    "summary": "Parley exposes an MCP-compatible JSON-RPC interface over stdio.",
    "headings": [
      {
        "depth": 1,
        "text": "MCP Integration",
        "id": "mcp-integration"
      },
      {
        "depth": 2,
        "text": "Transport",
        "id": "transport"
      },
      {
        "depth": 2,
        "text": "Typical tools",
        "id": "typical-tools"
      },
      {
        "depth": 2,
        "text": "Embedded documentation",
        "id": "embedded-documentation"
      },
      {
        "depth": 2,
        "text": "`run_ai_session` behavior",
        "id": "runaisession-behavior"
      },
      {
        "depth": 2,
        "text": "Example calls",
        "id": "example-calls"
      },
      {
        "depth": 2,
        "text": "Notes",
        "id": "notes"
      }
    ],
    "html": "<h1 id=\"mcp-integration\">MCP Integration</h1>\n<p>Parley exposes an MCP-compatible JSON-RPC interface over stdio.</p>\n<h2 id=\"transport\">Transport</h2>\n<ul>\n<li>Supports both <code>Content-Length</code> framed and newline-delimited JSON-RPC messages.</li>\n<li>Implements <code>initialize</code>, <code>tools/list</code>, <code>tools/call</code>, <code>resources/list</code>, and <code>resources/read</code>.</li>\n<li>Advertises embedded documentation through MCP resources with <code>parley://docs/{slug}</code> URIs.</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<li><code>get_documentation</code></li>\n</ul>\n<h2 id=\"embedded-documentation\">Embedded documentation</h2>\n<p>Agents can discover Parley's built-in markdown docs through <code>resources/list</code> and read any page with <code>resources/read</code>.</p>\n<p>Available resource URIs:</p>\n<ul>\n<li><code>parley://docs/keybindings</code></li>\n<li><code>parley://docs/overview</code></li>\n<li><code>parley://docs/quickstart</code></li>\n<li><code>parley://docs/review-workflow</code></li>\n<li><code>parley://docs/mcp</code></li>\n</ul>\n<p>Agents that prefer tools can call <code>get_documentation</code>.</p>\n<p>Inputs:</p>\n<ul>\n<li><code>doc</code>: optional doc slug, title, source path, or URI. If omitted, the tool returns the available docs list.</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>review-wide AI selects threads by thread status; explicit comment IDs target those comments directly</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 unresolved 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;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>Tools that operate on review state require an explicit <code>review_name</code>.</li>\n<li>Thread state updates are explicit tool calls.</li>\n<li><code>set_review_state</code> accepts Parley review states (<code>open</code>, <code>under_review</code>).</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>