# Sessions from the command line

Find, watch, and steer an agent session from the CLI with ch session — the six subcommands, the five ways to scope a list, and who can use each one.

Source: https://codeherder.com/docs/session-cli/

Find, watch, and steer an agent session from the CLI with ch session — the six subcommands, the five ways to scope a list, and who can use each one.

`ch session` is the command-line counterpart to the [Sessions view](https://codeherder.com/docs/following-a-live-session/): the same live window onto what an agent is doing right now, and the same terminal you’d otherwise reach with **Drop in**. It has six subcommands — `list`, `show`, `tail`, `stop`, `input`, and `attach` — and nothing else. Most sessions aren’t something you create or edit yourself — they’re something the engine spawns when a stage starts — but you can start one directly, from your own checkout, with [`ch start`](https://codeherder.com/docs/local-sessions/).

## Finding sessions

`ch session list` takes exactly one scope:

```
ch session list                    # this task's sessions (CH_TASK_ID if set)
ch session list <taskId>           # a specific task's sessions
ch session list me                 # your own agent's sessions
ch session list agent <agentRef>   # one agent's sessions
ch session list device <deviceRef> # everything that has run on one device
ch session list workspace [<ref>]  # every session in a workspace (yours if <ref> is omitted)
```

Naming a task ID together with a scope keyword, or two scope keywords together, is a usage error — `ch` names both scopes you tried to combine rather than guessing which one you meant. `workspace` can also be spelled `ws`. `ch session list` is one of four `ch` commands built on this same leading-scope grammar — see [Choosing whose data a list shows](https://codeherder.com/docs/using-the-cli/#choosing-whose-data-a-list-shows) for the shared rules.

The bare form (and an explicit `<taskId>`) falls back to `CH_TASK_ID` the same way `ch task` commands do — see [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/) for that convention. The `workspace` scope falls back to your current workspace the same way the global `--workspace` flag does.

**Live by default, on two scopes.** `agent` and `me` (which resolves to your own agent) return only live sessions by default. The `task`, `device`, and `workspace` scopes all return every session, live or finished, unless you narrow them. `--active` narrows any scope down to sessions that are live right now; `--all` widens it back to everything; the two are mutually exclusive.

```
ch session list agent <agentRef> --all      # include that agent's finished sessions too
ch session list <taskId> --active           # only this task's live sessions
```

`--repo <ref>` narrows any scope to sessions that targeted one repository — pass its name or its ID.

Like most `ch` lists, this one pages: 50 rows by default, 200 at most, with `--cursor` to resume — see [Paging through long lists](https://codeherder.com/docs/using-the-cli/#paging-through-long-lists) for how that works.

## Reading one session

```
ch session show [<sessionId>]
```

Inside an agent session, `ch` already knows which session it’s running in, so `<sessionId>` is optional there — omit it and the command acts on the session you’re in. Outside one, pass the id you got from `list`.

`show` prints the session’s fields plus an `actions:` line — the server’s own answer to what you may do with this session right now. Read that line rather than guessing: it only lists `stop`, `tail`, `input`, or `attach` when you’re actually allowed to run them, and it changes as the session’s state changes.

The rule behind it: `stop`, `tail`, and `attach` show up while the session hasn’t ended; `input` only shows up once the session is genuinely running, not while it’s still starting up.

When CodeHerder flags the session stale, `show` also prints a `stale:` row next to `actions:` — for example, `stale: device_silent (last device contact 2026-08-25T07:10:04Z)`. The row is absent otherwise. See [When a session goes quiet](https://codeherder.com/docs/following-a-live-session/#when-a-session-goes-quiet) for what the flag means and what CodeHerder does next.

## Watching a session

```
ch session tail [<sessionId>] [--lines N]
```

While a session is live, this prints a short preview of its terminal output. `--lines` defaults to 20 and caps at 200.

Once a session has ended, `tail` switches automatically to its post-mortem record: same command, nothing extra to remember. It prints everything the run captured before it died, so `--lines` doesn’t apply here. A note on stderr flags that you’re looking at a finished session, so the output itself stays clean if you’re piping it somewhere. Add `--json` and the response includes a `postMortem` field, so a script can tell which case it got. If nothing was captured — the run printed nothing, or the record aged out — you get the plain “no scrollback for an ended session” message instead.

This is CLI-only. The web app’s live-terminal page has no equivalent, so `tail` is your only way to see what an agent’s session printed as it died.

## Steering a session

```
ch session input [<sessionId>] --text "some text" [--submit]
ch session input [<sessionId>] --text-file notes.txt
ch session stop [<sessionId>] [--signal SIGKILL]
```

`input` delivers text to the session’s terminal, exactly like the web app’s Send box — and like the Send box, it’s recorded in the workspace’s activity feed. `--text` takes it inline, or use `--text-file <path|->` — see [Using the ch CLI](https://codeherder.com/docs/using-the-cli/) for the three ways every `ch` command accepts a body of text. Add `--submit` to send a trailing Enter along with it. This only works while the session is genuinely running, the same rule `show` ’s `actions:` line reflects.

`stop` ends the session’s run. `--signal` defaults to `SIGTERM`. Stopping a session that has already finished is harmless — the command just reports its current state back to you rather than erroring. A session you stop this way ends with a **Released** outcome, not a failure — see [What the state badges mean](https://codeherder.com/docs/following-a-live-session/#what-the-state-badges-mean).

## Connecting to a session’s terminal

```
ch session attach [<sessionId>]
```

Opens a live terminal onto the session — the same one the web app’s **Drop in** button opens. You need an interactive terminal on stdin (it won’t work piped into a script), and it isn’t available on Windows hosts. Once connected, press **Ctrl-]** to detach without stopping the session.

## Who can do what

`list` and `show` are open to any workspace member who can see the session — agents included. `tail`, `stop`, `input`, and `attach` all require the same thing: a **human** who is either a workspace owner or admin, or the operator of the session’s agent (the person who created it). That’s the same rule [Following a live agent session](https://codeherder.com/docs/following-a-live-session/#the-live-terminal-page) states for the web app’s live-terminal page, so the CLI and the web app never disagree.

## How this relates to sandbox and dev-session

A session is one activation of an agent — one clean-context process doing one piece of work. `ch sandbox` covers the durable worktree a task’s sessions run inside; `ch dev-session` covers the same idea for a worktree you spin up yourself, with no task behind it; and [`ch start`](https://codeherder.com/docs/local-sessions/) turns a checkout you already have into a session with no worktree of its own. `ch session` is the one place to find, read, and steer the process itself, whichever of these it’s running in — see [Core concepts](https://codeherder.com/docs/concepts/) for the full model.

## Related guides

- [Following a live agent session](https://codeherder.com/docs/following-a-live-session/) — the web app’s Sessions view and live-terminal page, and what “Released” and the other outcomes mean
- [Interactive dev sessions](https://codeherder.com/docs/dev-sessions/) — sessions you create yourself, with no task behind them
- [Start a session in your own checkout](https://codeherder.com/docs/local-sessions/) — turn a checkout you already have into a session
- [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/) — installing the CLI and the `CH_TASK_ID` convention
- [Using the ch CLI](https://codeherder.com/docs/using-the-cli/) — paging, the three ways to supply text, and referring to things on the command line
