> ## Documentation Index
> Fetch the complete documentation index at: https://panopticon-cli.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Conversations & Handoff

> Spawn agents, talk to them, branch a conversation to try another approach, and carry context across the context wall with a deliberate handoff — all from Command Deck

export const ThemedImage = ({light, dark, alt = ""}) => {
  const [darkMode, setDarkMode] = useState(null);
  useEffect(() => {
    const root = document.documentElement;
    const syncTheme = () => setDarkMode(root.classList.contains("dark"));
    const observer = new MutationObserver(syncTheme);
    syncTheme();
    observer.observe(root, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  if (darkMode === null) return null;
  return <img src={darkMode ? dark ?? light : light} alt={alt} loading="lazy" />;
};

# Conversations & Handoff

Overdeck is as much a tool for **managing conversations with agents** as it is a
workflow engine. Command Deck treats every agent session as a first-class
conversation: you spawn it, watch it work, talk to it mid-task, branch it to try
a different approach, and — when it nears the context wall or you want to switch
models — hand it off to a fresh conversation that inherits the context that
matters.

<ThemedImage light="/images/dashboard/command-deck-hero-light.png" dark="/images/dashboard/command-deck-hero-dark.png" alt="Command Deck with a live conversation: project and conversation sidebar, issue tree, the agent's turn-by-turn tool calls, and the awareness rail" />

## The conversation surface

Each conversation has a live **Conversation** view and a **Terminal** view of the
same session. The conversation pane streams the agent's turns — reasoning, tool
calls, file reads and edits, command output — as they happen. Below it sits the
composer, where you type to steer the agent the way you'd pair-program with a
colleague.

| Control | What it does |
| :- | :- |
| **Composer** | Send a message to the running agent mid-task — correct its approach, point it at a file, or tell it to stop and rethink |
| **Model picker** | Hot-swap the model for the next message — Sonnet → Opus → Kimi/GPT/Gemini — without losing the conversation |
| **Reasoning effort** | Tune how hard the model thinks per message (e.g. *Extra High*) |
| **Conversation / Terminal toggle** | Switch between the rendered conversation and the raw terminal of the same session (the native CLI for OpenCode and Codex) |
| **Copy link** | Grab the `overdeck.localhost/conv/<id>` URL to share or reopen a conversation |
| **Context window meter** | See how much of the window is used — your cue that a handoff is coming |
| **Bookmarks** | Mark a message by clicking the icon beside it, then reopen the list from the header to jump back to it |

A new conversation's effort is chosen with an effort picker next to the model picker, both on the Home composer and the Command Deck sidebar. The **New conversation with options…** dialog (below) has its own effort field, which defaults to the effort the conversation would get anyway and shows where that default comes from, for example `Default: high (default)` or `Default: medium (project)`.

### Changing effort while a conversation runs

Pick a level in the composer's effort picker while the session runs. For Claude
Code, Overdeck sends `/effort <level>` to the session and keeps the new level
only after Claude Code confirms it in the transcript; a session that is mid-turn
is refused, so try again when it is idle. While the change applies the picker
reads `Applying…`, and then it shows the level and where it came from, such as
`High · default` or `Low · set`. `terminal` means the session was changed with
`/effort` in the native CLI. Claude Code also saves `low` through `xhigh` as the
default for your own new sessions of that model in `~/.claude/settings.json`;
Overdeck's sessions always launch with an explicit effort, so they are not
affected.

The model picker spans the harness (Claude Code, Pi, Codex) and every routed
provider, each with live per-million pricing — so a mid-conversation swap is one
click:

<ThemedImage light="/images/dashboard/model-picker-light.png" dark="/images/dashboard/model-picker-dark.png" alt="The composer model and harness picker, showing Claude Code / Pi / Codex harnesses over Anthropic and other provider models with per-million pricing" />

### New conversation with options

The `+` in the Command Deck header is a split button:

* **The `+` itself** is quick create. It starts a conversation at once with the
  sidebar's model, harness and effort. No dialog opens.
* **The caret beside it** opens a menu with one item, **New conversation with
  options…**. The command palette has the same action.

The dialog sets options for one conversation. Nothing you choose in it changes
what the next quick create uses. Its fields are:

* **Project** and **Working directory.** The project starts as the deck's
  project. The working directory starts as the project path, and you can point
  it at any directory inside the project, such as a package in a monorepo.
* **Model** and **Harness.**
* **Effort.** It lists the levels the model supports and starts at the default
  effort, with its source shown beside it. A model with no effort setting
  shows "Not supported by this model".
* **No context** starts the conversation without Overdeck's context: no
  bundled rules, no project or workspace layers, no session briefing, no memory
  injection on each prompt, and no resume message. It starts faster and costs
  fewer tokens per turn. The conversation still shows up in the dashboard with
  live activity, and resuming or forking it keeps it bare.
* **Skip CLAUDE.md** (Claude Code only) also turns off Claude Code's own
  memory: `~/.claude/CLAUDE.md`, project `CLAUDE.md` files and auto memory.
  Without it, a bare conversation still reads those files, because Claude Code
  loads them itself.
* **Skills.** Each skill shows the state it would inherit and an Inherit / On /
  Off choice. A choice applies to this conversation only, at every launch,
  resume, restart and fork. See [Skills](/features/skills).
* **Linked issue.** Search the issues the dashboard knows by identifier or
  title.
* **First message** (optional).

After **Create**, the dialog closes and the new conversation opens.

See [Bare conversations](https://github.com/eltmon/overdeck/blob/main/docs/CONTEXT-LAYERS.md#bare-conversations-no-overdeck-context)
for the full list of what is skipped and what keeps running.

### Starting from Home

Both Simple and Advanced Home carry a composer at the top of the page, so you
can start a conversation or a terminal without opening the Command Deck or
picking a project first:

* **Enter** asks the composer's current agent, exactly as typed — no seed
  prompt, no project required.
* **Ctrl+Enter** (or choosing "Run in terminal:") opens the terminal drawer in
  the relevant deck and runs the typed text as a command in a fresh shell.
* **"Talk it through first:"** (Simple mode only) sends the same text through
  a discuss-then-file prompt: the agent asks clarifying questions and files an
  issue only once you say it's ready.

The composer's project chip lists every registered project, a **no project**
choice, and **Add a project…**. Choosing no project — or having none
registered yet — starts the conversation or terminal in your home folder
(`~/Projects` if it exists, otherwise your home directory) instead of blocking
you. In the Command Deck, that same no-project state is the **No project**
deck, always reachable from the sidebar's Projects section, and offered as
"Start without a project" when nothing else is selected.

If a conversation ends up outside any project — started from Home before a
project existed, say — its pane shows a "Not in a project · Move to
project…" chip so you can attach it to a project later without losing the
conversation.

### Native OpenCode CLI in Terminal

For an OpenCode conversation, **Terminal** attaches OpenCode's own interactive
CLI to the same running server and the same session, instead of showing the
Overdeck host log. What you type there and what you send from the composer land
in one session and one transcript; no second OpenCode server or session starts.
Dashboard messages still travel over the structured ACP connection, never as
keystrokes into this terminal.

Terminal has two panes for OpenCode:

| Pane | What it shows |
| :- | :- |
| **Native CLI** | `opencode attach` running against the conversation's server and session. Overdeck opens it the first time you select Terminal and reuses it after that. |
| **Runtime log** | The conversation's own terminal, the Overdeck ACP host log that Terminal showed before. |

Switching back to Conversation, changing conversations, or closing the browser
tab leaves the native CLI running. **Close native CLI** stops only that
terminal; the conversation keeps running. Stopping, archiving, deleting, or
restarting the conversation also stops its native CLI.

A conversation started before Overdeck recorded the OpenCode server port shows
**Restart required for the native CLI**. Stop and resume the conversation to
attach; nothing restarts automatically. **Show runtime log** keeps the host log
available meanwhile. Codex conversations get the same two panes (next section);
other harnesses keep their existing Terminal view.

### Native Codex CLI in Terminal

For a Codex conversation, **Terminal** attaches the real interactive Codex CLI
to the conversation's own app-server and the same thread, with
`codex resume --remote`. You can type in it, run slash commands, and answer
approvals there, and the dashboard stays connected to the same thread over its
structured app-server connection. No second app-server or thread starts.

| Pane | What it shows |
| :- | :- |
| **Native CLI** | The Codex TUI attached to the conversation's thread. Overdeck opens it the first time you select Terminal and reuses it after that. |
| **Runtime log** | The conversation's own terminal: the Overdeck app-server host log (`[turn] started`, `[stderr] …`) that Terminal showed before, with its line input and `y`/`n` approval shortcut. |

Both sides share one thread:

* A message typed in the native CLI is a turn in the conversation. It appears
  in the dashboard transcript and cost like any other turn, from the same
  Codex rollout.
* An approval shows in both places. Whichever side answers first wins, and the
  other side's prompt disappears.
* A model or effort you pick with `/model` in the native CLI stays in effect for
  the next dashboard message. Changing effort in the dashboard afterwards
  applies again from the next dashboard message.
* Esc in the native CLI interrupts the current turn, like the dashboard's stop
  button.

You can open Terminal while a turn is running or an approval is waiting. The
native CLI shows the running turn and the pending prompt. Switching back to
Conversation, changing conversations, or closing the browser tab leaves the
native CLI running. **Close native CLI** stops only that terminal; the
conversation and any running turn continue. Stopping, archiving, deleting, or
restarting the conversation also stops its native CLI. If the conversation's
Codex app-server stops on its own, Overdeck closes the native CLI too and says
so in Runtime log; restart the conversation to use Terminal again.

Sub-agents the conversation spawns belong to it: their approvals show in the
dashboard, and their activity and cost count toward the conversation.

`/new`, `/resume`, and `/fork` in the native CLI move only that terminal to
another Codex thread. The dashboard stays on the conversation's thread, and the
next time you open Terminal, Overdeck replaces the native CLI with one on the
conversation's thread.

When the native CLI is not available, Terminal says why and nothing restarts:

| Message | Meaning |
| :- | :- |
| **Restart required for the native CLI** | The conversation started before Overdeck exposed a native endpoint for it. Stop and resume the conversation. |
| **Upgrade required for the native CLI** | The installed Codex CLI is older than 0.153.4. Upgrade Codex, then stop and resume the conversation. |
| **Native CLI not available yet** | The conversation has no saved Codex turn yet. Send a first message, then select **Try again**. |
| **Native CLI unavailable** | For example, the conversation uses the legacy `codex.transport: tui`, where its own terminal already runs the Codex CLI. Terminal opens on **Runtime log** for these conversations, with Native CLI as the second tab. |

## Attachments

You can attach files to a composer message in three ways:

* **Paperclip button** — click the attach icon in the composer toolbar and select one or more files.
* **Drag and drop** — drop files directly onto the composer area.
* **Paste** — paste an image from your clipboard (screenshots, copied files, etc.).

Supported attachments include images (`png`, `jpg`, `gif`, `webp`) and text/code/PDF
files such as `md`, `json`, `ts`, `py`, `log`, `csv`, `yaml`, and `pdf`. Files are
uploaded to the conversation's private attachment folder,
`~/.overdeck/conversation-attachments/<conversation>/`, and the message the agent
receives refers to each one as `@<absolute path>`.

### Viewing images

Click an image thumbnail in the composer to open it full size, even while it is
still uploading. A sent message that includes an image shows a thumbnail under
its text; click it to open the image full size. Press Escape or click outside
the image to close it. If the file was removed, the thumbnail does not appear
and the path stays in the message.

### Vision gating

Image attachments are only sent to models that support vision. If you attach an
image while a text-only model is selected, the image is dropped with a clear
notice and any text/code/PDF attachments still go through. Switch to a
vision-capable model (for example, MiMo V2.5) to include images.

### File size and limits

* Maximum attachment size: **5 MB** per file.
* Maximum message length: **50,000** characters.
* Unsupported or binary file types are rejected at selection time with a toast.

## Bookmarks

Click the icon beside an assistant or user message to bookmark it, using its
first line as the label. The icon turns into a filled bookmark; clicking it
again opens a popover to rename or remove the bookmark. The **Bookmarks**
header button opens a list showing each bookmark's label and time — clicking
a label scrolls the timeline to that message and outlines it briefly.

Bookmarks survive reloads and new messages because they point at the
transcript message's stable id, not its position in the list. They are
stored by Overdeck and never written into the agent's own transcript, and
they stay with this conversation — a handoff or fork does not copy them. If
a bookmarked message is no longer in the loaded transcript, its row in the
list shows "This message is not in the loaded transcript."

## Why hand off?

A conversation accumulates context as it works: dead ends it already ruled out,
the file relationships it discovered, the half-finished approach it's mid-stride
on. When the context window fills up, that knowledge is the most expensive thing
to lose. A naive "summarize and continue" throws away the nuance.

A **handoff** is a deliberate context transfer. Instead of a passive summary, an
agent reads the conversation and writes a structured Markdown handoff document —
capturing the dead ends, the important files, and the suggested next steps — and
that document becomes the seed message for a brand-new conversation. The new
agent starts with a clean context window but inherits what mattered.

Reach for a handoff when:

* A long-running conversation is near the context wall.
* The current agent knows dead ends, hazards, or file relationships a passive summary would miss.
* You want a deliberate context transfer before switching models, harnesses, or tasks.

Use a plain **Fresh summary** when a quick passive summary is enough; use **Exact
copy** only when you need to carry the raw history verbatim within a
Claude-Code-compatible session.

## Continue: the three ways to start a new conversation

Open the **Continue** dialog from a conversation's action menu, or type
`/handoff` (optionally followed by focus text) in the composer to jump straight
to handoff mode. The dialog presents three intents, ordered richest to lightest:

<ThemedImage light="/images/handoff/continue-modal-light.png" dark="/images/handoff/continue-modal-dark.png" alt="The Continue dialog with Agent handoff selected, a new-conversation name, harness and launch-model pickers, and a focus field" />

| Intent | What it does | Best for |
| :- | :- | :- |
| **Fresh summary** *(recommended)* | An LLM distills the prior context into a seed message. For very large conversations the history is chunked, each chunk building on the previous summary. | Most cases — a clean, structured starting point |
| **Agent handoff** | An agent writes a Markdown handoff document, optionally focused on a specific next task, that becomes the seed message. | Deliberate handoffs where dead ends, key files, and next steps matter |
| **Exact copy** | Copies the raw conversation history verbatim — no summary generated. | Picking up exactly where you left off, **same model only** |

The **Project** picker controls where the successor appears in the project tree,
independently of its working directory. It defaults to **Same as source**, so an
isolated handoff worktree stays associated with the source conversation's
project. Choose another registered project only when the successor belongs
somewhere else.

<Note>
  **Fast summary** is an advanced toggle under *Fresh summary* that skips the LLM
  and extracts a bullet list of user messages, files modified, and tools used
  directly from the history — cheaper and instant, but rougher.
</Note>

<Warning>
  **Exact copy** carries raw history that may contain model-specific data (such as
  signed thinking blocks) that won't validate on a different provider. Use a
  **summary** or **handoff** when switching models.
</Warning>

### Launch model vs. authoring model

Two model choices live in this dialog, and they are independent:

* **Launch model** — the model the *new conversation* will run on. Defaults to the parent conversation's model.
* **Authoring model** — the model that *writes the summary or handoff document*. Independent of the launch model; cheaper models like Haiku work well for straightforward cases, larger models for nuanced conversations.

## Progressive disclosure: Advanced options

The dialog keeps the common case to one screen. Everything else lives behind
**Advanced options**, which expands to reveal the authoring controls:

<ThemedImage light="/images/handoff/continue-modal-advanced-light.png" dark="/images/handoff/continue-modal-advanced-dark.png" alt="The Continue dialog with Advanced options expanded, showing the authored-by choice (external vs source), authoring harness, and authoring model" />

| Authored by | Behavior |
| :- | :- |
| **External session** *(default)* | A clean session reads the transcript from disk and writes the document. The source conversation is never touched — its context stays clean, and the source can even be ended. Pick the authoring model and harness here. |
| **Source session** | The live source agent writes the document in-conversation. This adds the prompt and document to the source's context, and uses whatever model the source is running. Right when the source has live state — open files, recent commands, in-flight reasoning — a transcript reader would miss. |

If a source-authored handoff stalls or produces an invalid document, Overdeck
falls back to a summary fork automatically.

## The help panel

Every option in the dialog is explained inline — click the **?** to open the
*Continue Options* reference without leaving the flow:

<ThemedImage light="/images/handoff/continue-help-light.png" dark="/images/handoff/continue-help-dark.png" alt="The Continue Options help panel explaining fresh summary, fast summary, agent handoff, and exact copy" />

## Handing off from the CLI

The dialog is the visual front-end for `pan handoff`. The CLI does exactly what
the dialog does, and the two are interchangeable.

```bash theme={null}
pan handoff [conv] [focus...]
```

The trailing text after the conversation reference becomes the **focus** — no
flag required.

### Hand off the conversation you're in

If you're an agent inside a conversation and want to hand off *your own*
conversation, omit `<conv>` (or pass `self`). The command identifies your
conversation deterministically from the session you're running in — no scanning,
no guessing.

```bash theme={null}
pan handoff                               # hand off this conversation, no focus
pan handoff self wire the Stripe webhook  # hand off this conversation, with focus
```

Because focus text is positional, prefer the explicit `self` token whenever you
pass focus — a bare first word like `pan handoff continue the wiring` is read as
a *conversation reference* named "continue", not as focus. `self` removes the
ambiguity. Run `pan conv current` (alias `pan conv whoami`) to print exactly
which conversation you resolve to.

### Hand off a specific conversation

```bash theme={null}
pan handoff 42
pan handoff source-conv continue the API wiring
pan handoff source-conv --model claude-sonnet-4-6
pan handoff source-conv --harness pi
pan handoff source-conv --cwd /path/to/project
pan handoff source-conv --cwd ../isolated-worktree --project mind-your-now
pan handoff source-conv --author source uses-source-agent-and-pollutes-its-context
pan handoff source-conv --author external --author-model claude-haiku-4-5 cheap clean handoff
```

### Options

| Option | Description |
| :- | :- |
| `[conv]` | Conversation id or name. Omit (or pass `self`) to hand off the conversation you're in. |
| `[focus...]` | Positional focus text — what the successor should concentrate on. **≤ 10,000 characters.** |
| `--model <model>` | Model for the new (forked) conversation. Defaults to the parent's model. |
| `--effort <level>` | Reasoning effort for the new conversation (`low`, `medium`, `high`, `xhigh`, `max`). Defaults to the source conversation's effort, clamped to the new model. |
| `--harness <harness>` | Harness for the new conversation: `claude-code` or `pi`. |
| `--cwd <path>` | Working directory for the new conversation. |
| `--project <key-or-name>` | Registered project for the successor. Defaults to inheriting the source conversation's project, even when `--cwd` points outside that project's directory. |
| `--author <who>` | Who authors the handoff doc: `external` (default) or `source`. |
| `--author-model <model>` | Model for the external authoring session (only when `--author=external`). Falls back to `conversations.handoff_author_model` in `config.yaml` when omitted — there is no built-in default, so set one of the two or the handoff fails with a clear error. |
| `--author-harness <harness>` | Harness for the external authoring session: `claude-code` or `pi` (external only). |
| `--skill <name>` | Turn this skill on for the new conversation only (repeatable). `<name>` is a native skill name or a pack skill id `<pack>/<skill>`. |
| `--pack <id>` | Turn on every non-opt-in skill of this cached skill pack, for the new conversation only (repeatable). |
| `--hold` | Create and launch the new conversation without sending the kickoff. Start it with Send in the dashboard composer, or `pan handoff start <conv>`. |

<Note>
  **Focus is hard-capped at 10,000 characters** (PAN-3737; multi-line is fine). A longer focus is rejected with
  `focus must be 10000 characters or fewer` and no
  conversation is created. Keep it short and task-oriented — the detail belongs in
  the transcript the author reads; the focus only steers what the author
  emphasizes.
</Note>

### Holding a handoff

`--hold` creates and launches the successor's session without sending the
kickoff, so you can inspect it before it starts working:

```bash theme={null}
pan handoff self --hold Read .pan/handoff-brief.md FIRST and follow it exactly.
```

The successor's dashboard composer shows a waiting notice with the kickoff
text already filled in; pressing Send there starts it. From the terminal, run
`pan handoff start <conv>` (id or name) instead — it sends the held kickoff
exactly once. A second `pan handoff start` on the same conversation, or one on
a conversation that was never held, exits 1 with "No held kickoff: the
conversation was already started or was never held".

### Fallback behavior

`pan handoff <conv>` always tries to create a usable new conversation. If the
live-agent handoff can't complete, Overdeck falls back to a summary fork and
prints the reason:

| Reason | Meaning |
| :- | :- |
| `source-ended` | The source conversation is already ended. |
| `handoff-timeout` | The source didn't write both the document and its `.done` sentinel in time. |
| `handoff-validation` | The document didn't satisfy the handoff contract. |
| `source-workspace-devcontainer` | The source can't write to the host handoff directory from inside a workspace container. |

A successful handoff prints the new conversation id, tmux session, model,
harness, dashboard link, and the handoff document path. Fallbacks print the same
details plus a yellow fallback notice.

## Branch to explore

A handoff isn't only for the context wall — it's also how you **branch**. Fork a
conversation to try an alternative approach, keep the original intact, compare
both, and continue with the one you like. Cheaper than restarting from scratch,
and the original's context is never lost.

## Pull requests on conversations

A conversation shows the pull request its work lives on. A badge next to the
branch chip, on the conversation row and in the open conversation's header,
shows the PR number, colored by state: blue
for open, amber when a review needs a human, green for merged, red for closed
without merging, and muted for drafts. A `×` marks failing checks. Hover it for
the repository, number, state, and title; click it to open the PR. `+N` means the
conversation has more than one linked PR.

Links come from **branch detection**. About 30 seconds after the dashboard starts,
and every 60 seconds after that, Overdeck reads each GitHub project's pull
requests once and links every PR whose head branch equals the branch a
conversation's working directory is on. Agent conversations whose workspace
cannot be read fall back to `feature/<issue>`. A conversation on the project's
default branch is never linked by branch. In the project's main checkout, which
every conversation there shares, an operator conversation is linked by branch
only while its terminal is running, so idle conversations never pick up the PR
of whatever branch the checkout is on. A merged PR stays linked after the
checkout goes back to the default branch. The same sweep refreshes the stored
state of linked PRs, so the badge renders without a live GitHub call. Open PRs
refresh on every sweep, closed PRs at most every 15 minutes, and merged PRs are
final and never re-read. A linked PR the project listing doesn't include (older
than its 100 most recent PRs, in another repository, or on a conversation
outside any GitHub project) is read on its own. After three failed reads in a
row, Overdeck skips that repository for 15 minutes.

### Linking a pull request by hand

Open a conversation's actions (the row's `⋮`, the open conversation's header
`⋮`, or a right-click on the row, the header, or its tab) and choose **Link pull
request…**. Type a PR URL, a
GitLab merge request URL, `#42`, or `owner/repo#42`, then press Enter. `#42`
means PR 42 of the conversation's project repository. When the conversation
shows a PR, the same menu offers **Unlink #42**.

**Pull requests…** in the same menu opens a dialog that lists every PR linked to
the conversation. It shows why each one is linked (`manual`, `agent`, `created`,
`branch-detected`, or `unlinked`) and which one the badge shows. From there you
can link another PR, unlink or relink one, and refresh their status from the
forge.

In a transcript, right-click a pull request or merge request link and choose
**Link to conversation**. If that PR is the one the conversation shows, the menu
offers **Unlink from conversation** instead.

Agents and scripts use the CLI. `<query>` is the conversation name, or a title
fragment that matches exactly one conversation (`pan conv current` prints the
one you're in):

```bash theme={null}
pan conv link-pr <query> <url|#42|owner/repo#42>   # --source agent|manual
pan conv unlink-pr <query> <url|#42|owner/repo#42>
pan conv prs <query> [--json]                      # * marks the PR shown
```

`link-pr` records the source `agent` when it runs inside an agent
(`OVERDECK_AGENT_ID` is set) and `manual` otherwise. The verbs go through the
dashboard, so every open client updates at once. With the dashboard down they
write the link directly. They exit 2 when no conversation matches, and 1 on any
other error.

Rules:

* Only a repository configured for the conversation's project can be linked:
  the project's `github_repo` or `gitlab_repo`, a URL-shaped
  `workspace.repos[].remote`, or the `origin` remote of the project checkout or
  of the conversation's working directory. Anything else is refused, and
  nothing is stored.
* A PR you link by hand wins over one found by branch detection.
* Unlinking hides the link, and branch detection won't add that PR back. Linking
  the same PR by hand again restores it.
* A new link fetches the PR's state within seconds, so it doesn't wait for the
  next sweep.

When the pipeline opens the pull request for an issue (`pan done`, or the review
pipeline), it links that PR to every agent conversation for the issue and every
conversation working inside the issue's workspace, with the source `created`.
Those conversations show the PR at once, without waiting for a sweep. The
pipeline never restores a PR you unlinked.

The other direction works too: an issue's **Code** card lists every conversation
linked to the issue's PR, with why it's linked (opened by the pipeline, linked
by hand, linked by an agent, or on the same branch). Click one to open it.

### On issue and workspace rows

The issue's row in Command Deck's project tree, and its row in the sidebar
Workspaces rail, show the same badge as a conversation's — the PR's number,
colored by state and review, with a `×` for failing checks — read from the
issue's derived state rather than a conversation's link. It appears within
seconds of `pan done` opening the PR. A PR that closed without merging is not
shown there.

Linking never archives or stops a conversation unless you turn on auto-archive:

```bash theme={null}
pan conv auto-archive-on-merge        # prints on or off (default: off)
pan conv auto-archive-on-merge on     # or off
```

When it's on, an operator conversation is archived when a linked PR goes from
open to merged or closed and every PR still linked to it is merged or closed.
It happens once, at that change, so a conversation you unarchive stays. A
conversation whose terminal session is still alive is never archived, nothing is
ever stopped, and agent conversations are never archived (the pipeline owns
them).

Not yet shipped (tracked in [#3822](https://github.com/eltmon/overdeck/issues/3822)):
GitLab merge request status, the Pull requests page, and search by PR number.

## Conversations from your other machines

Arrives in the next release (v0.65.0), and needs Session Vault set up on this machine
([Session Vault](/configuration/session-vault)).

Claude Code and Codex conversations that another machine saved to the vault appear in the
conversation list with a "from `<machine>`" chip. Hovering it reads "Read-only copy from
`<machine>`".

Opening one shows the transcript. The composer is replaced by "Read-only copy from
`<machine>`.", the command `pan vault resume <id>`, and a **Continue here** button.

**Continue here** opens a dialog titled `Continue "<title>"` that says "Saved on
`<machine>`." and where the conversation will continue. Cases, one sentence each:

* Code snapshot: it says which snapshot it applies here, or that the checkout has
  uncommitted changes so the snapshot goes into a new workspace.
* Drift: when branch, commit or dirty state differs, it lists the differences and offers
  **Continue**, **Continue with a note** and **Cancel**.
* No project: "No registered project matches `<slug>`." with **Clone and register
  `<slug>`**, which opens the Add project dialog.
* Another machine continued it first: "Already continued on `<machine>`." and nothing
  changes.
* A harness without native resume: the dialog shows the `pan vault resume <id>` command
  instead.

After it continues, the conversation opens on this machine as a normal conversation.

See [Session Vault: Continue on another machine](/configuration/session-vault#continue-on-another-machine)
for the CLI path instead of repeating it.

## Reviewing changes in the diff panel

Open the diff panel from a conversation to review what changed. Besides
**All turns**, **vs main** and the per-turn chips, it has a **Compare…** view
for any two points in the conversation's repository. It works in a local-only
repository too: no remote and no pull request are needed.

1. Click **Compare…**.
2. Pick a **base** and a **head**. Each box suggests branches, tags and recent
   commits, and accepts any ref you type, such as a SHA or `HEAD~2`.
3. Choose **A..B** to see every difference between the two, or **A...B** to see
   only the head's changes since the two diverged.
4. Click **Compare** (or press Enter), then pick a file to read its diff.

The selection is part of the page URL. Use the pop-out button to open the
comparison in its own window, and bookmark that URL to come back to the same
comparison later.

The **ignore whitespace** toggle in the panel header hides changes that only
re-indent or re-space lines, so a reformatted block no longer hides the real
change. It applies to the diff in every view, and the panel remembers it in this
browser. A turn's file list can still name a file whose only change was
whitespace; opening it then shows no net changes.

## See also

* [Mission Control](/features/mission-control) — the project tree and activity timeline around your conversations
* [Cloister](/features/cloister) — model routing, stuck-agent detection, and lifecycle management
* [Harnesses](/configuration/harnesses) — `claude-code` vs `pi`, and the ToS rules that gate them
* `pan conv current` (alias `pan conv whoami`) — print the conversation you're running inside
* `pan fork [conv]` — create a summary or plain fork without asking the source agent to author a handoff
* [Session Vault](/configuration/session-vault): save conversations off-machine and continue them elsewhere

## Subagent activity and direct messages

Select a child in the conversation's agent rail to read its transcript. Active
children display “Working for …” with the same activity indicator as the main
conversation.

A bottom composer appears when the selected child supports direct messages.
For Codex, this requires a loaded child in a conversation running the structured
app-server transport. Messages go to that child's existing thread, with its
current model and permissions. Drafts are separate for each child.

Claude Code sessions, Codex terminal sessions, and unavailable children show the
transcript without a composer. Messages are never relayed through the main agent.
Existing Codex conversations need a restart after upgrading their host before
they can expose this capability. If delivery cannot be confirmed, check the
child's transcript before retrying.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.