# Start a session in your own checkout

Turn the git checkout you're already sitting in into a CodeHerder session, in the same terminal, with nothing cloned or moved.

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

Turn the git checkout you're already sitting in into a CodeHerder session, in the same terminal, with nothing cloned or moved.

A dev session gives you a fresh worktree that CodeHerder cuts on a device. This works the other way around: you’re already sitting in a checkout on your own machine, and you turn it into a CodeHerder session right where it is — same terminal, same directory, nothing checked out or moved.

```
ch start
```

There’s no worktree to provision and no branch to pick — it starts from the terminal you’re already sitting in. If nothing is set up on this machine yet, `ch start` sets it up for you (see [Setting up the first time](https://codeherder.com/docs/local-sessions/#setting-up-the-first-time) below). Not sure whether it will work before you run it? See [Check before you start](https://codeherder.com/docs/local-sessions/#check-before-you-start) below.

## What you need

- **macOS or Linux, in a real terminal.** `ch start` isn’t available on Windows, and it refuses if stdin isn’t an interactive terminal — so it won’t run from a script or a pipe.
- **The top level of a git checkout.** Run it from the repository root, not a subdirectory.
- **A workspace where you’re a member**, using a device you own — or one you administer as an owner or admin. Unlike a dev session, which needs owner or admin access to create, this only needs ordinary membership on your own device.

If any of these aren’t true, `ch start` tells you exactly which one failed rather than a generic error — see [If it refuses](https://codeherder.com/docs/local-sessions/#if-it-refuses) below.

## Check before you start

`ch start --check` runs the same checks `ch start` itself runs before it does anything, including your credentials, whether you’re at a git top level, which harness it would pick, which workspace it would use, whether a device-server is reachable, whether that device runs through a container executor, whether it has a session root configured, whether your device is registered and linked to that workspace, whether you have a free worktree slot, and whether your CLI is up to date. It creates no sandbox, starts no device-server, and registers no device. It only reads.

```
ch start --check
```

Each check comes back with one of four verdicts:

- **pass** — this step will succeed.
- **repairable** — `ch start` fixes this itself, so it’s never a reason to stop.
- **fail** — something needs your attention. For most causes, the line names the exact command to fix it.
- **unknown** — the check couldn’t read the fact it needed. Also never a reason to stop.

The command exits `0` unless at least one check comes back `fail`, in which case it exits `1`. That makes it safe to run in a script or a CI job — unlike plain `ch start`, which needs a real terminal and refuses on a pipe.

When everything passes, it prints one short line:

```
ch start --check: all clear — workspace <workspaceId> (acme/widgets), source: --workspace flag; device <deviceId> registered; harness: Claude Code
```

When something needs attention, it lists only the checks that didn’t pass, then a count:

```
[FAIL] workspace: no workspace resolved (source: unset) — fix: pass --workspace <ref>, or `export CH_WORKSPACE_ID=<id>` (see `ch workspace list`)
[UNKNOWN] device_workspace_link: not checked yet — workspace or device not resolved
9/11 checks pass
```

Pass `--json` for a structured version of the same report — `{"data":{"ok":false,"checks":[{"key":"workspace","status":"fail","summary":"..."},...]}}` — so a script can gate on `ok` instead of parsing the text.

`--check` predicts the same launch you’re about to run, so pass it the same `--harness` and `--no-autostart` flags you intend to use — a different combination can change which checks matter.

## Setting up the first time

You do **not** need to run `ch device-server` by hand first. If `ch start` doesn’t find one already running on this machine, it registers the device and starts one for you, in the background, then waits for it to come up. It prints where the device-server’s own log is going, in case anything is slow to start.

That first-run registration also marks this machine as a **personal** device: it joins the workspace disabled, so the engine never hands it someone else’s tasks — it’s there to run your own `ch start` sessions, nothing more. `ch start` prints the device’s ID and the command to share it with the rest of the workspace:

```
ch device enable <deviceId>
```

See [Managing your devices](https://codeherder.com/docs/devices/#personal-devices) for what that changes and who’s allowed to run it.

## The device server it starts

The device server `ch start` puts up for you is temporary, not something to manage yourself the way you would one started with `ch device-server`. It stops itself once your session ends, whether that’s a clean exit or `ch start` failing partway through. While a session is still running on it, though, it stays up — even a session from an earlier `ch start`.

If it’s ever left running with nothing on it, say the terminal got killed outright, it gives up on its own after about 10 minutes idle. The device doesn’t disappear when that happens; it just goes Offline.

A device server you start yourself, with plain `ch device-server`, is never stopped this way.

## Choosing a harness

`ch start` offers only a coding-agent CLI proven to open a real interactive terminal you can type into — today that’s all five: Claude Code, Codex, Cursor, OpenCode, and Pi. With more than one interactive harness installed it asks which one to use; with exactly one it just proceeds. Pass `--harness <name>` to skip the prompt:

```
ch start
ch start --harness claude
ch start --repo acme/widgets --title "fix the flaky test"
```

Flags, all optional:

- **`--harness <name>`** — which coding-agent CLI to run. Must have a proven interactive shape (today, all five: `claude`, `codex`, `cursor`, `opencode`, `pi`); naming an unrecognized value, or one not installed on this device, refuses and names the fix.
- **`--repo <ref>`** — which registered repository this checkout counts as, if the match isn’t obvious. See [Repo binding](https://codeherder.com/docs/local-sessions/#repo-binding) below.
- **`--title <text>`** — a friendly label so you can find the session later.
- **`--no-autostart`** — refuse instead of starting a device-server automatically, if you’d rather run `ch device-server` yourself.
- **`--check`** — run the preflight instead of starting a session. See [Check before you start](https://codeherder.com/docs/local-sessions/#check-before-you-start) above.

## What the banner tells you

Once the session is up, it prints a short banner before handing you the terminal: the sandbox and session IDs, the directory, which harness is running, whether a repo is bound yet, and whether the change-shape report and other awareness features are on, pending, or off (and why). It also tells you who can see the session and confirms that spend is tracked against the workspace. The session runs as you, the human who typed the command, never as an agent persona — every API mutation it makes (task comments, task creates, and so on) is attributed to your own identity. The idea is that the session tells you up front what it can and can’t see, instead of leaving you to find out the hard way.

## Repo binding

Pass `--repo` and the binding is immediate. Leave it off and CodeHerder settles it shortly after launch, once the session’s first awareness scan runs — `ch sandbox show <sandboxId>` shows the settled answer. If your checkout’s remote matches more than one repository registered in the workspace, name the one you mean with `--repo`.

## Detaching, reattaching, and stopping

Press **Ctrl-]** to detach without stopping the session — it keeps running, and so does the device server behind it (see [The device server it starts](https://codeherder.com/docs/local-sessions/#the-device-server-it-starts) above). To come back to it:

```
ch sandbox list workspace     # find it — its Type is "local"
ch session attach <sessionId> # reattach to its terminal
```

To stop it for good:

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

and bring it back later with:

```
ch sandbox activate <sandboxId>
```

One important difference from a dev session: this kind of session does **not** come back on its own if your device reboots. Reattach or reactivate it by hand when you’re ready.

## Your files stay put

CodeHerder never clones your repository, cuts a worktree, or switches your branch for this kind of session — your checkout stays exactly as you left it, on whatever branch and commit you were already on.

## Cost and visibility

Token spend from the session is attributed to the workspace and visible to its admins, and counts as task-free spend — see [Task-bound vs. task-free spend](https://codeherder.com/docs/costs/#task-bound-vs-task-free-spend) for how that’s tracked and rolled up.

## If it refuses

Run `ch start --check` first — see [Check before you start](https://codeherder.com/docs/local-sessions/#check-before-you-start) above. It names the exact cause and, for most of them, the exact fix command. Here is what each cause means:

| What it says, in short | What it means |
| --- | --- |
| Not logged in | Run `ch login`. |
| Not a git repository / not the top level | Run it from the root of a git checkout, not a subdirectory or a plain folder. |
| The path is a symlink, or isn’t a directory | `ch start` needs a real directory, not a symlinked one. |
| Inside the device’s own session storage | Your checkout happens to sit inside the folder the device uses for its own worktrees — move it, or use that folder for a different checkout. |
| No usable harness | Install one of the harnesses named in the message. |
| `ch start --check` flags: more than one harness candidate | Not a refusal — `ch start` prompts you to pick one. Pass `--harness <name>` to skip the prompt. |
| No workspace resolved | Pass `--workspace <ref>`, or set `CH_WORKSPACE_ID` — see `ch workspace list`. |
| Signed in as a different user than the device server | Run `ch start` as the same OS user account that’s running `ch device-server`. |
| Platform not supported | `ch start` needs macOS or Linux. |
| `CH_DOCKER_EXECUTOR` is set | Unset it — `ch start` refuses outright on a container executor. |
| The device server itself runs through a container executor | Run that device-server without a container executor. |
| No session root configured on this device | Set `--session-root` (or `CH_SESSION_ROOT`) on `ch device-server` and restart it. |
| Your device isn’t linked to this workspace, and you aren’t an owner or admin there | Have an owner or admin run `ch device link-workspace <deviceId> --workspace <ref>` — or, if you are an owner or admin, `ch start` links it for you automatically. |
| Your device is archived | Run `ch device restore <deviceId>`. |
| No free worktree slot on this device | Run `ch device reclaim <deviceId>`, or stop an old session with `ch sandbox state <sandboxId> stopped`. |
| `ch start --check` flags: CLI more than a patch behind the server | Not a refusal — `ch start` self-updates and restarts when it can, or carries on otherwise. Run `ch self-update` to get ahead of it. |

## Related guides

- [Interactive dev sessions](https://codeherder.com/docs/dev-sessions/) — the other kind of session you create yourself, on a fresh worktree CodeHerder cuts for you
- [Sessions from the command line](https://codeherder.com/docs/session-cli/) — find, watch, and steer any session, this kind included
- [Following a live agent session](https://codeherder.com/docs/following-a-live-session/) — the live-terminal page and what the state badges mean
- [Managing your devices](https://codeherder.com/docs/devices/) — what it means to own a device
- [Understanding costs](https://codeherder.com/docs/costs/) — how spend is tracked and who can see it
