# Using the CLI

> Applies to: ChengOS v0.2.0+ ｜ Last verified: 2026-09-25 ｜ Source: `crates/cheng-cli/src/main.rs`, `crates/cheng-cli/src/commands.rs`, `crates/cheng-cli/src/config.rs`, `crates/cheng-cli/src/back_roots.rs`

Run `cheng` with no arguments to start chatting in the current directory. Everything else is
either a subcommand or a slash command inside a session.

## Subcommands

```bash
cheng chat          # interactive session in the current directory (the default)
cheng back          # headless background agent serving this directory
cheng sessions      # your CLI sessions on the server (find an id to --resume)
cheng history       # durable conversations, including paused and historical work
cheng ps            # background agents you started
cheng stop <id>     # stop a background agent by PID or session id
cheng logs <id>     # show a background agent's log file
cheng restart <id>  # restart a background agent
cheng rm <id>       # remove stopped or stale agent metadata
cheng prune         # remove all stopped and stale agent metadata
```

Note the distinction between `sessions` and `history`: a **session** is a CLI connection with a
sandbox, while a **conversation** is durable dialogue that outlives it. That is why
`--resume-conversation` exists — you can pick up work whose original session has expired.

## `cheng chat` flags

| Flag | Purpose |
|---|---|
| `--server <url>` | API base URL |
| `--token <token>` | Bearer token — prefer `CHENG_TOKEN` |
| `--workspace <uuid\|name>` | Workspace to select |
| `--workflow <uuid\|name>` | Workflow to select |
| `--resume <session-uuid>` | Resume an existing CLI session |
| `--resume-conversation <uuid>` | Resume a conversation even if its session expired |
| `--cwd <path>` | Sandbox root (default: current directory) |
| `--read-only` | Create the sandbox read-only |
| `--workspace-mode <mode>` | `server_local` or `client_local` |
| `--auth-storage <policy>` | Credential storage policy |
| `--lang <en\|zh>` | UI language (default: auto-detect) |

`--resume-conversation` conflicts with `--resume`, `--workspace`, and `--workflow`: the
conversation already determines all three, so specifying them would be contradictory.

Use `--read-only` when you want an agent to analyse a repository without any possibility of it
writing — a stronger guarantee than instructing it not to.

## Background agents

`cheng back` runs a headless agent that serves the current directory as a client-local
workspace for the web UI. This is how you let the browser editor operate on files that live on
your machine rather than on the server.

Background mode is **always client-local** — `cheng back` deliberately has no
`--workspace-mode` flag, because serving your local directory is the entire purpose.

One agent process can serve **several directories**, each with its own sandbox and access:

```bash
cheng back --root ~/works/api --root ~/works/docs:ro
```

`--root PATH[:ro]` is repeatable; `:ro` serves that root read-only, and `--read-only` makes every
root read-only (the narrower access always wins). Roots must not nest — serve the common parent
instead. Without `--root`, the `back_roots` list in the config file applies, and without either
the launch directory is served. There is deliberately no "serve everything" form: declaring a
broad root is an explicit, written decision, because unattended scheduled tasks inherit it.

`cheng back --status`, `--stop`, and `--logs` act on the agent recorded for the current
directory. Manage agents by id with `ps`, `stop`, `logs`, `restart`, `rm`, and `prune`.
`ps -a` includes stopped and stale agents.

## Slash commands

Some slash commands are handled locally by the CLI; others are sent to the server. The
difference is visible in what they affect: local ones change your terminal, server ones change
the conversation.

**Local**

| Command | Effect |
|---|---|
| `/exit`, `/quit` | Leave |
| `/think on\|off\|status` | Show or hide the model's reasoning |
| `/details on\|off\|status` | Expand or collapse trace items (bare `/details` toggles) |
| `/copy`, `/copy-all` | Copy the selection or the whole transcript |
| `/export-md [path] [--details]` | Export the session as Markdown |
| `/rollback`, `/rewind` | Open the dialogue rollback selector |

**Server**

`/new`, `/workspace`, `/workflow`, `/channel`, `/model`, `/status`, `/cancel`, `/approve`,
`/reject`, `/help`, `/compact`, `/shortcuts` (alias `/kj`, `/kjlist`), `/presets` (alias `/fl`,
`/fllist`).

`/compact` is the one to remember on a long session: it condenses conversation history so the
context window stops being the limiting factor.

A pasted absolute path such as `/home/user/file.txt` is **not** treated as a command — a first
token containing another `/` is recognised as a path. Unknown `/word` input also stays a normal
message rather than producing a command error.

## Approvals in the terminal

When a workflow needs a human decision the session shows an approval prompt; `/approve` and
`/reject` answer it. The same mechanism as the editor's approval cards, and the same
`waiting_for_review` execution state.

Not every file change asks. Small, scoped, undoable edits run automatically; overwrites,
protected paths, deletes, moves, multi-file change sets, and shell or test runs always prompt,
and the prompt names the reason. In a client-local session the CLI itself answers the server's
**preflight** request, describing the planned change before anything is written. See
[Tool-call Approval Policy](/docs/agent-approval-policy).

## Resilience

If the event stream goes silent for 30 seconds, the CLI reconciles the foreground execution
against the API instead of waiting forever — so a dropped connection surfaces real state rather
than hanging. Sessions are server-side, so a terminal that dies has not lost the work: find it
with `cheng sessions` and `--resume`.

## Next steps

- [Installing the CLI](/docs/cli-install) — configuration and tokens.
- [ReAct agent guide](/docs/agent-react-guide) — what the agent behind the prompt is doing.
