# Start a session on a device

Source: https://codeherder.com/docs/dev-sessions/

Start a session on a device for work that isn't tied to a task, as yourself or as an agent.

Most sessions start because an agent picked up a task. You can also start one yourself, whenever you want, with no task behind it. CodeHerder cuts a fresh git worktree on one of your devices and opens a live terminal in it. Use it to try something out, run a one-off command, or poke at a branch without filing a task first. In the Sessions list, these show a **Remote** badge.

If you’d rather work in a checkout you already have, see [Start a session in your own checkout](https://codeherder.com/docs/local-sessions/). That kind shows a **Local** badge.

A session like this belongs to the person who started it. It has no workflow and no stages, and it never appears on a task’s Workflow panel. Its spend counts as task-free. See [Task-bound vs. task-free spend](https://codeherder.com/docs/costs/#task-bound-vs-task-free-spend).

You can run the session as **yourself** or as an **agent**. Run as yourself, you work in the terminal with your own identity. Run as an agent, the session uses that agent’s launch config.

## Who can start one

- **As yourself:** any workspace member can do this, on a device they own. Owners and admins can use any eligible device in the workspace.
- **As an agent:** only owners and admins can do this.

Only a person can launch a session as themselves. An agent can’t.

## Starting a session

**Web app:** Open **Sessions** in the sidebar and click **New session**. The form asks for:

| Field | Required? | What it does |
| --- | --- | --- |
| **Launch as** | No | **Myself** is the default. It runs the session as you. Pick an agent to run it with that agent’s configuration. |
| **Device** | No | Which device runs the session. Leave it on **Auto (recommended)** and CodeHerder picks an eligible device. For **Myself**, Auto picks a device that has a harness installed. |
| **Repo** | No | The repository to check out into the worktree. Leave it blank (**No repo (empty sandbox)**) for a terminal with no checkout. |
| **Base branch** | No | The branch the worktree is cut from. Available only after you pick a repo. |
| **Branch** | No | The name of the new branch. Available only after you pick a repo. |
| **Title** | No | A label so you can find the session later. |

Click **Create session**. When the worktree is ready, you land in the session’s live terminal. If no device can take the work right now, CodeHerder says why instead of failing without a reason.

A session doesn’t use the workspace’s default repo. If you want a worktree, pick a repo yourself. The default-repo shortcut applies only to a task’s build session. See [Connecting repositories](https://codeherder.com/docs/repositories/).

**CLI:**

```
ch session create --agent <agentId> \
  [--device <deviceId>] [--repo <repoId>] [--base-ref <ref>] [--branch <branch>] [--title <title>]
```

On the command line, `--agent` is required, so `ch session create` always runs as an agent. To work as yourself from the CLI, use `ch start` in a checkout you already have. See [Start a session in your own checkout](https://codeherder.com/docs/local-sessions/). The other options match the web form. Leave out `--device` and CodeHerder picks one. Leave out `--repo` and you get no checkout.

`ch session create` doesn’t open a terminal. The session is provisioned and then waits as **ready**. It prints an id, and that id is for `resume`:

```
ch session resume <id>   # the id that create printed
ch session attach <id>   # the same id
```

Both commands take the id that `create` printed. `ch session resume` prints `spawned session <sessionId>`. `ch session attach` also takes that session id, from the `resume` output or from `ch session list`. If the session has no live process, `attach` tells you to run `ch session resume <id>` first.

By default, in a session started as an agent, commits carry you as author if your email address is verified. The agent is the committer. A repo with its own commit identity overrides both names. See [Whose name is on a commit](https://codeherder.com/docs/task-commits/#whose-name-is-on-a-commit).

## Finding your sessions

The **Sessions** list shows every session, task-driven or not. The **Type** column shows **Remote** for a session you started on a device.

A control above the list switches between **Live**, **Open**, and **All**. **Live** is the default. It shows only sessions with a running terminal. **Open** adds sessions that are provisioning, ready, or stopped. **All** adds closed ones too.

**CLI:**

```
ch sandbox list workspace --dev     # sessions started with no task
ch sandbox show <sandboxId>
```

Add `--all` to include closed sessions.

## Dropping into a session

A live session row shows a **▶ Drop in** button. It opens the live-terminal page that task sessions use. See [Following a live agent session](https://codeherder.com/docs/following-a-live-session/) for the terminal, the Send box, and the audit trail. Those rules apply here unchanged.

**CLI:**

```
ch session attach <sessionId>
```

Run `attach` from macOS or Linux, in an interactive terminal. It doesn’t work from Windows, a script, or a pipe. Press **Ctrl-]** to detach without stopping the session. Ctrl-C goes to the remote process as a keystroke and doesn’t detach you.

A session id stays tied to one run. After the session stops, that id no longer connects, and `attach` reports that the session is no longer running. Run `ch session resume <id>`, then attach with the new session id that `resume` prints. A **ready** session that was never started has no session id yet, so start or resume it first.

## Lifecycle

A session moves through **provision → ready → active → stopped**. A stopped session isn’t gone. You can bring it back, or abandon it for good.

- **provision**: CodeHerder is setting up the worktree on the device.
- **ready**: The worktree is set up, but no terminal is running yet.
- **active**: The session has a live terminal you can drop into.
- **stopped**: The running process is halted. The session and its worktree are kept, so you can bring it back. A session can stop for other reasons than your click. See [Automatic lifecycle](https://codeherder.com/docs/dev-sessions/#automatic-lifecycle).
- **abandoned**: The session is retired for good. It can’t be brought back.

**Start and Resume** bring a session active. Use **Start** on a ready row and **Resume** on a stopped row. The worktree, branch, and device stay the same. The device must be **Online**. In the web app, click the button on the row. On the CLI:

```
ch session resume <id>
```

**Stop** halts the running process. In the web app, open **More** on the row, choose **Stop**, and confirm. On the CLI:

```
ch sandbox state <sandboxId> stopped
```

**Abandon** retires the session for good. In the web app, open **More**, choose **Abandon**, and confirm. On the CLI:

```
ch sandbox state <sandboxId> abandoned
```

The person who started the session can start, resume, and stop it. Owners and admins can do this too. Only owners and admins can abandon a session.

## Resuming keeps the conversation

When you resume a session, the new session picks up the same conversation. It keeps the event rules you set, the rules you muted, its standing instruction, and any event waiting for it. The device, the worktree, and the terminal can all be new. What a session hears follows the conversation, not the worktree. A new session in the same worktree is a new conversation, and it starts with the defaults. See [Choosing what reaches an agent session](https://codeherder.com/docs/subscriptions/).

## Automatic lifecycle

CodeHerder also moves a session between **active** and **stopped** on its own, in two cases:

- **Your device reboots or reconnects.** An active session comes back to active on its own once the device is **Online** again.
- **The session sits idle.** A session left active with no activity for about two weeks is stopped, which frees the device for other work. Your worktree, branch, and terminal history stay as they were. The session shows as **stopped**, and you can resume it any time.

When you stop a session, or CodeHerder stops it for being idle, its run ends with a **Released** outcome. That isn’t a failure. See [Sandbox state vs. a run’s outcome](https://codeherder.com/docs/following-a-live-session/#sandbox-state-vs-a-runs-outcome).

One rule applies throughout: **stopping a session turns off automatic resume for it.** A stopped session stays stopped, even after its device reconnects. Resuming it turns automatic resume back on.

## Related guides

- [Following a live agent session](https://codeherder.com/docs/following-a-live-session/): the live-terminal page, the Send box, and the audit trail
- [Managing your devices](https://codeherder.com/docs/devices/): pick and prepare the device a session runs on
- [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/): agents, launch configs, and the `ch` command-line tool
- [Start a session in your own checkout](https://codeherder.com/docs/local-sessions/): the other kind you start yourself, in a checkout you already have
