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

# CLI

> Run one-off agent tasks and durable workflows from the command line

<Note>
  The CLI is designed for **automation and scripting** (CI/CD pipelines, batch processing,
  programmatic control). For interactive terminal experiences, consider tools like [Claude
  Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) or similar TUIs.
</Note>

Xum provides a CLI for running one-off agent tasks without the desktop app. Unlike the interactive desktop experience, `xum run` normally executes a single request to completion and exits. The `--goal` option is an explicit exception: it starts a CLI Goal Run that may perform automatic continuations until the goal is complete or a limit is reached.

<Card title="GitHub Actions Guide" icon="github" href="/guides/github-actions">
  Learn how to use `xum run` in CI/CD pipelines
</Card>

<Note>
  Existing automation can continue invoking `mux`; the legacy package and binary forward to the same
  Xum CLI. New scripts should use `xum`.
</Note>

## Installation

The CLI is available via npm and can be run directly with `npx`:

```bash theme={null}
# Run without installing
npx @coder/xum run "Fix the failing tests"

# Or install globally
npm install -g @coder/xum
xum run "Fix the failing tests"
```

Using `npx @coder/xum` is especially convenient for CI/CD pipelines where you don't want to manage a global installation.

## `xum run`

Execute a one-off agent task:

```bash theme={null}
# Basic usage - run in current directory
npx @coder/xum run "Fix the failing tests"

# Specify a directory
xum run --dir /path/to/project "Add authentication"

# Use SSH runtime
xum run --runtime "ssh user@myserver" "Deploy changes"

# Pipe instructions via stdin
echo "Add logging to all API endpoints" | xum run

# JSON output for scripts
xum run --json "List all TypeScript files" | jq '.type'
```

### Options

| Option                | Short | Description                                                                                                                   | Default           |
| --------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `--dir <path>`        | `-d`  | Project directory                                                                                                             | Current directory |
| `--model <model>`     | `-m`  | Model to use (e.g., `anthropic:claude-sonnet-4-5`)                                                                            | Default model     |
| `--runtime <runtime>` | `-r`  | Runtime: `local`, `worktree`, `ssh <host>`, or `docker <image>`                                                               | `local`           |
| `--mode <mode>`       |       | Agent mode: `plan` or `exec`                                                                                                  | `exec`            |
| `--thinking <level>`  | `-t`  | Thinking level: `OFF`, `LOW`, `MED`, `HIGH`, `MAX`, or `0`–`9` (model-relative, see [Models](/config/models#thinking-levels)) | `MED`             |
| `--budget <usd>`      | `-b`  | Stop when session cost exceeds budget (USD)                                                                                   | No limit          |
| `--goal <objective>`  |       | Start a CLI Goal Run and continue until the persisted goal is complete or a limit stops it                                    | Off               |
| `--goal-budget <n>`   |       | Goal budget (`$5`, `5.00`, or `500c`); separate from `--budget`                                                               | No limit          |
| `--goal-turns <n>`    |       | Maximum automatic goal continuation turns                                                                                     | No limit          |
| `--experiment <id>`   | `-e`  | Enable experiment (repeatable)                                                                                                | None              |
| `--json`              |       | Output NDJSON for programmatic use                                                                                            | Off               |
| `--quiet`             | `-q`  | Only output final result                                                                                                      | Off               |

### CLI Goal Runs

Use `--goal` when a task should keep going across automatic continuations until the agent marks the persisted goal complete:

```bash theme={null}
# Goal text is also used as the initial message when no message/stdin is provided
xum run --goal "Fix the failing tests and verify the suite passes"

# Provide separate kickoff instructions while keeping the objective active
xum run --goal "Ship the migration safely" "Start by inspecting the schema and propose a plan"

# Bound automatic continuations with a goal-specific budget and turn cap
xum run --goal "Complete the refactor" --goal-budget 5.00 --goal-turns 10
```

A CLI Goal Run is intentionally not a strict alias for interactive `/goal`. It is ephemeral to the `xum run` process, does not apply interactive goal defaults, bypasses the interactive continuation cooldown, and exits successfully only when the persisted goal status is `complete`. If neither `--goal-budget` nor `--goal-turns` is provided, Xum warns that the goal is uncapped.

`--budget` remains the hard session spending limit in USD. `--goal-budget` is goal accounting, accepts forms like `$5`, `5.00`, and `500c`, and may allow a final budget-limit wrap-up turn. If the session `--budget` is exceeded, the run stops immediately.

Exit codes for CLI Goal Runs:

| Code  | Meaning                                                    |
| ----- | ---------------------------------------------------------- |
| `0`   | Goal completed (unless the agent set a nonzero exit code)  |
| `1`   | Operational, model, or tool error                          |
| `2`   | Session `--budget` exceeded                                |
| `3`   | Goal stopped incomplete, including goal budget/turn limits |
| `130` | User interrupt                                             |

### Runtimes

* **`local`** (default): Runs directly in the specified directory. Best for one-off tasks.
* **`worktree`**: Creates an isolated git worktree under `~/.xum/src`. Useful for parallel work.
* **`ssh <host>`**: Runs on a remote machine via SSH. Example: `--runtime "ssh user@myserver.com"`
* **`docker <image>`**: Runs in a Docker container. Example: `--runtime "docker node:20"`

### Output Modes

* **Default (TTY)**: Human-readable streaming with tool call formatting
* **`--json`**: NDJSON streaming - each line is a JSON object with event data
* **`--quiet`**: Suppresses streaming output, only shows final assistant response

### Examples

```bash theme={null}
# Goal run with automatic continuations
xum run --goal "Update dependencies, fix resulting tests, and verify the suite passes"

# Quick fix in current directory
xum run "Fix the TypeScript errors"

# Use a specific model with extended thinking
xum run -m anthropic:claude-sonnet-4-5 -t high "Optimize database queries"

# Run on remote server
xum run -r "ssh dev@staging.example.com" -d /app "Update dependencies"

# Scripted usage with JSON output
xum run --json "Generate API documentation" > output.jsonl

# Limit spending to $2.00
xum run --budget 2.00 "Refactor the authentication module"
```

## `xum workflow`

Run a durable workflow JavaScript file from the command line without opening the desktop app. Workflows are addressed by explicit `script_path` values; there is no workflow discovery, `list`, or `show` command. Skill-packaged workflows use `skill://<skill-name>/<file.js>`, and local workflow files use an explicit workspace-contained `.js` path. `xum wf` is a shorthand alias for `xum workflow`.

<Note>
  `xum workflow` is experimental. Invoking the command implicitly enables the `dynamic-workflows`
  experiment for that invocation only. The initial CLI runner supports the `local` runtime only;
  `worktree`, SSH, Docker, and devcontainer workflow execution are blocked until their workflow
  isolation and cleanup semantics are implemented.
</Note>

Use local workflow files for cheap CLI smoke tests. `skill://` paths run the packaged workflow they reference, which may require AI credentials or model budget.

```bash theme={null}
# Run a trusted local workflow file with explicit JSON args
xum workflow run ./workflows/research.js --args-json '{"topic":"workflow runners"}'

# Same as above, using the alias and machine-readable output
xum wf run ./workflows/research.js --args-json '{"topic":"workflow runners"}' --json
```

### Workflow commands

| Command                          | Description                                       |
| -------------------------------- | ------------------------------------------------- |
| `xum workflow run <script_path>` | Run an explicit workflow script in the foreground |

### Workflow options

| Option                       | Description                                                                 |
| ---------------------------- | --------------------------------------------------------------------------- |
| `--dir <path>` / `-d`        | Project directory. When omitted, Xum uses the Git root for the current cwd. |
| `--runtime <runtime>` / `-r` | Runtime selection. Currently only `local` is supported for workflow runs.   |
| `--model <model>` / `-m`     | Model used by workflow-owned child agents.                                  |
| `--thinking <level>` / `-t`  | Thinking level used by workflow-owned child agents.                         |
| `--experiment <id>` / `-e`   | Enable an additional experiment for workflow-owned child agents.            |
| `--json`                     | Emit the final workflow result as a JSON line on stdout.                    |
| `--quiet` / `-q`             | Suppress progress output and print only the final report.                   |
| `--verbose` / `-v`           | Show info-level logs while the workflow command runs.                       |
| `--log-level <level>`        | Set log verbosity to `error`, `warn`, `info`, or `debug`.                   |

### Workflow arguments

Workflows receive structured args. Positional prose is rejected; pass JSON, a JSON file/stdin payload, or explicit `--arg key=value` pairs instead.

Only one argument mode can be used per run:

| Input mode                      | Workflow args value                       |
| ------------------------------- | ----------------------------------------- |
| No args                         | `{}`                                      |
| `--arg key=value`               | Object with lightly coerced scalar values |
| `--args-json '{"base":"main"}'` | Exact JSON value                          |
| `--args-file args.json`         | Exact JSON value read from a file         |
| `--args-stdin`                  | Exact JSON value read from stdin          |

Workspace-file workflow scripts are executable only after the project is trusted. If an explicit local `.js` script path points into an untrusted project, `xum workflow run` fails before executing repo-controlled workflow code. Linked git worktrees inherit trust from the main repository path. Grant trust headlessly with [`xum trust`](#xum-trust).

## `xum trust`

Trust gates all repo-controlled automation: project workflows, hooks, and `.mux` configuration. The desktop app records trust via Settings → Security; `xum trust` writes the same entry in `~/.xum/config.json` headlessly — no desktop app or server required, registering the project if it was never added to Xum. A running desktop instance picks the change up automatically.

```bash theme={null}
# Trust the project containing the current directory (git toplevel)
xum trust

# Trust an explicit directory
xum trust --dir /path/to/repo

# Revoke trust
xum trust --revoke

# Machine-readable output
xum trust --json
```

Run from a linked git worktree (for example a Xum workspace checkout), trust is recorded for the main repository path rather than the ephemeral worktree path. Review a repository before trusting it: trusted projects can execute repo-controlled code.

## `xum server`

Start the HTTP/WebSocket server for remote access (for example, from a phone or another machine):

```bash theme={null}
xum server --host 0.0.0.0 --port 3000
```

Options:

* `--host <host>` - Host/interface to bind to (default: `localhost`)
* `--port <port>` - Port to bind to (default: `3000`)
* `--auth-token <token>` - Bearer token for HTTP/WS auth
* `--no-auth` - Disable authentication entirely
* `--print-auth-token` - Always print the auth token on startup
* `--allow-http-origin` - Accept HTTPS browser origins when a TLS-terminating proxy forwards `X-Forwarded-Proto=http`
* `--ssh-host <host>` - SSH hostname/alias used for editor deep links in browser mode
* `--add-project <path>` - Add and open project at the specified path

Use `--allow-http-origin` only when HTTPS is terminated by an upstream reverse proxy and Xum receives rewritten `X-Forwarded-Proto=http` headers. This compatibility mode is disabled by default. For non-CLI server starts (for example desktop/browser mode), set `XUM_SERVER_ALLOW_HTTP_ORIGIN=1` to opt in.

Auth token precedence:

1. `--no-auth`
2. `--auth-token`
3. `XUM_SERVER_AUTH_TOKEN`
4. Auto-generated token

GitHub owner login for browser sessions is configured separately via `XUM_SERVER_AUTH_GITHUB_OWNER` or `serverAuthGithubOwner` in `~/.xum/config.json`. See [Server Access](/config/server-access).

## `xum acp`

Start the ACP (Agent-Client Protocol) stdio bridge used by editor integrations:

```bash theme={null}
xum acp
```

| Option                 | Description                                       |
| ---------------------- | ------------------------------------------------- |
| `--server-url <url>`   | URL of a running xum server                       |
| `--auth-token <token>` | Bearer token for authenticated server connections |
| `--log-file <path>`    | Write ACP logs to a file instead of stderr        |

For editor-specific setup (Zed, Neovim, JetBrains), see the
[ACP Editor Integrations](/integrations/acp) guide.

## `xum desktop`

Launch the desktop app. This is automatically invoked when running the packaged app or via `electron .`:

```bash theme={null}
xum desktop
```

Note: Requires Electron. When running `xum` with no arguments under Electron, the desktop app launches automatically.

## `xum --version`

Print the version and git commit:

```bash theme={null}
xum --version
# v0.8.4 (abc123)
```

## Debug Environment Variables

These environment variables help diagnose issues with LLM requests and responses.

| Variable                | Purpose                                                                                                                                                                 |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `XUM_DEBUG_LLM_REQUEST` | Set to `1` to log the complete LLM request (system prompt, messages, tools, provider options) as formatted JSON to the debug logs. Useful for diagnosing prompt issues. |

Example usage:

```bash theme={null}
XUM_DEBUG_LLM_REQUEST=1 xum run "Hello world"
```

The output includes:

* `systemMessage`: The full system prompt sent to the model
* `messages`: All conversation messages in the request
* `tools`: Tool definitions with descriptions and input schemas
* `providerOptions`: Provider-specific options (thinking level, etc.)
* `mode`, `thinkingLevel`, `maxOutputTokens`, `toolPolicy`
