> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beacon.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# beacon handoff

> Pick up a local agent session again, in the same runtime or another one

## Command overview

`beacon handoff` finds the agent sessions stored on this machine so you can pick one up again.

```bash title="Command syntax" theme={null}
beacon handoff list [flags]
beacon handoff export <session-id> [flags]
beacon handoff resume <session-id> [flags]
```

Sessions come from each runtime's own local session store, not from Beacon's runtime log. That store is what the runtime resumes from, and it keeps content the runtime log truncates. Every read is local and read-only: nothing is uploaded, and no runtime file is changed.

## Supported runtimes

| Runtime     | Session store                                           | `--harness` |
| ----------- | ------------------------------------------------------- | ----------- |
| Claude Code | `~/.claude/projects`                                    | `claude`    |
| Codex CLI   | `~/.codex/sessions`                                     | `codex`     |
| OpenCode    | `~/.config/opencode` (SQLite and the legacy file store) | `opencode`  |
| Cline       | `~/.cline/data`                                         | `cline`     |

When a Codex thread has more than one rollout file, `beacon handoff` lists it once, under its newest file. Cline can hold the same task both as a CLI session and in its older task history; the CLI session is the copy that is listed. Cline kanban cards are not sessions and are not listed.

## `beacon handoff list`

Lists resumable sessions, newest first.

```bash theme={null}
beacon handoff list
beacon handoff list --here            # sessions that ran in this directory or below it
beacon handoff list --harness codex   # one runtime
beacon handoff list --json
```

| Flag                                                                    | Description                                                                                                          |
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--harness`                                                             | Only this runtime: `claude`, `codex`, `opencode`, or `cline`.                                                        |
| `--here`                                                                | Only sessions that ran in the current directory or below it.                                                         |
| `--dir`                                                                 | Only sessions that ran in this directory or below it.                                                                |
| `--subagents`                                                           | Include subagent sessions. They are hidden by default, because resuming one resumes a fragment of its parent's task. |
| `--limit`                                                               | Maximum sessions to list. Default `25`; `0` lists all.                                                               |
| `--json`                                                                | Print `{"sessions": [...], "warnings": [...]}`.                                                                      |
| `--claude-projects-dir`, `--codex-dir`, `--opencode-dir`, `--cline-dir` | Read a runtime's store from a non-default location.                                                                  |

A store that cannot be read is reported as a warning (on stderr, or under `warnings` in JSON), and the sessions from the other runtimes are still listed.

## `beacon handoff export`

Writes a handoff brief for one session: a Markdown summary of what it asked for, what it changed, and where it stopped, for another agent or person to continue from.

```bash theme={null}
beacon handoff export 7f3c2a91              # writes ~/.beacon/endpoint/handoffs/<runtime>-<id>-<time>.md
beacon handoff export 7f3c2a91 --print      # write to stdout instead
```

The session id can be a unique prefix of at least six characters. Pass `--harness` when two runtimes use the same id.

A brief has these sections:

* **Source session**: runtime, session id, title, directory, branch, last activity, session file, and activity counts.
* **Where it stood**: the first request, the latest request, and the last agent message.
* **Files changed** and **Recent commands**, with exit codes where the runtime reports them.
* **Recent activity**: the last 30 steps (prompts, agent messages, commands, file changes, tool failures, MCP calls), each cut to 1,200 characters.
* **Before continuing**: check the working tree, and confirm the task before changing anything.

A brief is a summary, not the full transcript. Every event goes through the same secret redaction and truncation as the runtime log before any of it is used. Agent reasoning and file reads are left out. A brief is at most 48 KiB; older steps are dropped first to stay under that. Content is placed in code fences longer than any run of backticks inside it, so quoted text can't close its block and pass itself off as part of the brief.

When a session is no longer in its runtime's store (for example, a deleted transcript), `export` reads it from Beacon's runtime log instead. This works for any runtime Beacon captured, but the log keeps less of each step, and the brief says so.

Briefs are written to `~/.beacon/endpoint/handoffs`. The directory is `0700` and each file is `0600`, because a brief carries prompt text and command output. An existing brief is never overwritten.

| Flag                                | Description                                                                      |
| ----------------------------------- | -------------------------------------------------------------------------------- |
| `--print`                           | Write the brief to stdout instead of a file.                                     |
| `--output-dir`                      | Directory to write the brief into.                                               |
| `--log-path`                        | Runtime log to fall back to. Defaults to the local runtime log.                  |
| `--json`                            | Print `{"path", "from", "session"}`. `from` is `session_store` or `runtime_log`. |
| `--harness` and the `--*-dir` flags | As for `list`.                                                                   |

## `beacon handoff resume`

Picks a session up again, in its own runtime or another one.

```bash theme={null}
beacon handoff resume 7f3c2a91                 # reopen it where it ran
beacon handoff resume 7f3c2a91 --agent codex   # continue a Claude Code session in Codex
beacon handoff resume 7f3c2a91 --new           # a fresh session in the same runtime, from a brief
beacon handoff resume 7f3c2a91 --print         # show what would run; writes and launches nothing
```

There are two ways to resume:

* **Reopen natively.** Beacon reopens the session with its full context when all of these hold: it continues in the same runtime, that runtime's CLI can load this kind of session, and the session file is still on this machine.

  | Runtime     | Command                                      |
  | ----------- | -------------------------------------------- |
  | Claude Code | `claude --resume <id>`                       |
  | Codex CLI   | `codex resume <id>`                          |
  | OpenCode    | `opencode --session <id>`                    |
  | Cline       | `cline --tui --auto-approve false --id <id>` |

* **Start a new session from a brief.** Otherwise, or with `--agent` naming another runtime or with `--new`, Beacon writes a brief (see `export`) and starts a new session. The first message of that session points at the brief:

  | Runtime     | Command                                       |
  | ----------- | --------------------------------------------- |
  | Claude Code | `claude "<prompt>"`                           |
  | Codex CLI   | `codex "<prompt>"`                            |
  | OpenCode    | `opencode --prompt "<prompt>"`                |
  | Cline       | `cline --tui --auto-approve false "<prompt>"` |

  The prompt names the brief by its path and asks the agent to read it, then confirm the task before changing anything. The brief is never inlined into the command line, because a command line is visible to every local user through the process table. The prompt ends with a handoff marker (see below).

Claude Code and Cline subagent sessions, and Cline's older task history, can't be reopened by their CLIs, so they always continue from a brief. A session known only from Beacon's runtime log also continues from a brief, and it needs `--agent` if its own runtime isn't one of the four above.

Cline approves every tool call by default. Beacon always passes `--auto-approve false`, so a session Beacon starts never gets auto-approval on Beacon's say-so. You can still turn it on inside the Cline TUI.

The runtime runs in this terminal, in the session's recorded directory. If that directory no longer exists, Beacon stops rather than starting somewhere else; pass `--cwd` to choose a directory. Beacon prints the plan and asks `Continue? [Y/n]` before launching. Without a terminal, it launches only with `--yes`. `beacon handoff resume` exits with the runtime's own exit code.

| Flag                                                               | Description                                                                                                        |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `--agent`                                                          | Runtime to continue in: `claude`, `codex`, `opencode`, or `cline`. Defaults to the session's own runtime.          |
| `--new`                                                            | Start a new session from a brief even when the session could be reopened.                                          |
| `--cwd`                                                            | Directory to start the runtime in.                                                                                 |
| `--print`                                                          | Show the plan and command without writing a brief or launching anything.                                           |
| `--json`                                                           | With `--print`, describe the plan as JSON (`mode`, `reason`, `target`, `executable`, `args`, `dir`, `brief_path`). |
| `--yes`                                                            | Launch without asking.                                                                                             |
| `--output-dir`, `--log-path`, `--harness`, and the `--*-dir` flags | As for `export`.                                                                                                   |

## Linking a new session to the one it continues

A session started from a brief has a new session id. So that the two stay connected in the telemetry, the first prompt of the new session ends with a handoff marker:

```text theme={null}
[beacon-handoff from=claude_code session=ea7f210f-402b-53b1-aec2-864a488dfcd3]
```

When Beacon's hook adapter records a prompt carrying this marker, it writes a second event, `session.handoff`, next to the usual `prompt.submitted`:

```json theme={null}
{
  "event": { "action": "session.handoff", "category": "session", "fidelity": "observed" },
  "session": { "id": "<the new session>", "working_directory": "/work/api" },
  "handoff": { "source_harness": "claude_code", "source_session_id": "ea7f210f-402b-53b1-aec2-864a488dfcd3" }
}
```

The link event keeps the new session's id, workspace and harness, and leaves the prompt text to the prompt event. Rules can match on `e.handoff.source_harness` and `e.handoff.source_session_id`.

Two paths record the link:

* **Live hooks.** The prompt hook for Claude Code and the Cline and OpenCode plugins record it as the prompt is sent (`harness.collection_method: hook`).
* **Session-store sync.** `beacon endpoint claude sync`, `codex sync`, `opencode sync` and `cline sync` record it when they read the prompt back from the runtime's store (`harness.collection_method: poll`).

Codex CLI prompts reach Beacon over OTLP and through `beacon endpoint codex sync`, not a prompt hook, so a session continued in Codex is linked by the sync. For the other three runtimes, a sync can record the same link a hook already did; the two carry different `collection_method` values, as every other event those runtimes report through both paths does. A sync's link has a deterministic `event.id`, so syncing again never duplicates it.

The marker is a claim made in prompt text, not a verified identity: anyone can type it. `fidelity: observed` records that the marker was seen, not that `beacon handoff resume` wrote it. A native resume keeps the session's own id, so it needs no link.
