# Command-line interface

Codex MMO has one Python command surface exposed through two installed entrypoints:

- `codex-mmo` is the primary user command. With no control command it creates and attaches to a new interactive MMO session. It also accepts every control command documented below.
- `codex-mmoctl` exposes the same control commands but never inserts an implicit `run`. It is useful when a script should fail instead of accidentally starting an interactive session.

Run `codex-mmo --help` for the complete top-level map and `codex-mmo COMMAND --help` for command-specific options. Help and version reporting do not initialize profiles, gateways, providers, or session state.

## Command groups

The command tree follows the runtime concepts users operate:

| Command | Purpose |
|---|---|
| `run`, `resume`, `exec` | Start, reattach to, or noninteractively submit root work |
| `profile` | List, inspect, validate, compile, select, install, clone, remove, diagnose, or smoke-test profiles |
| `tool-mcp` | Inspect and validate operator-owned third-party Tool MCP definitions |
| `catalog` | Inspect model/route inventory and run optional live discovery or verification |
| `gateway` | Inspect and control local Switchyard gateway processes |
| `session` | Inspect and control durable MMO session lifecycle |
| `jobs` | Inspect workers and read losslessly paged evidence |
| `eval` | Validate, run, inspect, and compare evaluation suites |
| `doctor`, `validate` | Diagnose one profile or validate the complete local configuration |
| `clean` | Delete only terminal state older than explicit or configured retention thresholds |
| `auth` | Run built-in Codex authentication in the configured base Codex home |

`version` and `--version` print package version 8.0.0. `prompt` prints the reusable orchestration prompt.

Global `--json`, `--quiet`, and `--debug` flags may appear before or after a control command, provided they occur before an explicit `--` passthrough separator. Everything after that separator belongs to Codex:

```bash
codex-mmo --quiet profile validate adaptive-engineering
codex-mmo session list --json
codex-mmo run --profile visual-engineering -- --image screenshot.png
```

Abbreviated option names are rejected. A close command or option typo may receive a conservative suggestion.

## Human and machine output

Structured commands adapt to stdout:

- on a terminal, they render compact human-readable tables or labeled details;
- in a pipe or redirected file, they emit strict JSON;
- `--json` forces strict JSON even on a terminal.

JSON is deterministic, UTF-8, and rejects non-finite numbers. Human tables may omit optional columns when the terminal is narrow, but identifiers and other required values are never truncated; a labeled block layout is used when necessary. Codex MMO's control output does not use color or animation. The attached stock Codex TUI retains its own terminal behavior.

Some interfaces are deliberately raw rather than structured. `run` and `resume` attach a TUI, `gateway logs` forwards log text, and `auth` forwards the Codex login interface; these commands reject `--json`. Without `--json`, `exec` prints only the root result. With `--json`, it prints the complete execution record. Scalar commands retain concise text by default and return named JSON objects when `--json` is explicit.

Examples for automation:

```bash
# JSON is automatic because stdout is a pipe.
codex-mmo session list | jq -r '.[].session_id'

# Force JSON while inspecting it interactively.
codex-mmo jobs status JOB_ID --json | jq .

# Keep requested data separate from diagnostics.
codex-mmo catalog verify --remote >report.json 2>diagnostics.log
```

Requested results are written to stdout. Warnings, progress, usage guidance, and errors are written to stderr. Stable, line-oriented stage progress appears only when stderr is an interactive terminal; `--quiet` suppresses that progress without suppressing requested results, warnings, or failures. Redirected and piped commands receive no spinner frames, carriage-return animation, or ANSI decoration.

Machine-readable failures requested with `--json` are JSON objects on stderr. They contain a stable `error_type` category and message, plus a hint when one is available. `--debug` adds the Python exception type and traceback for unexpected diagnosis; it never changes the exit status or move errors to stdout.

## Exit status

| Status | Meaning |
|---:|---|
| `0` | The requested operation succeeded |
| `1` | Validation, execution, lookup, provider, or runtime operation failed |
| `2` | Command syntax or an option combination was invalid |
| `130` | The command was interrupted with Ctrl-C/SIGINT |
| `128 + signal` | A directly represented child process ended from a signal; for example SIGTERM is `143` |
| `141` | A downstream pipeline consumer closed stdout (broken pipe/SIGPIPE convention) |

Validation commands return nonzero when their report does not pass. `jobs wait` returns `1` while requested jobs remain unfinished after its caller wait. A release-mode evaluation returns `1` when an eligible promotion gate fails. The CLI never reports success merely because it was able to print a failure report.

## Interactive and noninteractive input

`exec` accepts either one positional prompt or non-empty UTF-8 text from noninteractive stdin:

```bash
codex-mmo exec --profile incident-hypothesis-triage "Analyze this incident"
printf '%s\n' "Analyze this incident" | codex-mmo exec --profile incident-hypothesis-triage
```

When stdin is a terminal, omitting the prompt is an immediate usage error; `exec` never waits on an invisible prompt. In CI, cron, and pipelines, an empty or whitespace-only stdin is also an error.

`--wall-timeout` is an external caller boundary, not a model instruction or execution budget. If reached, the noninteractive client detaches while the durable root thread and evidence remain resumable.

## Session and worker lifecycle

Use the lifecycle verbs according to their exact meaning:

- `session detach` disconnects the client while admitted work continues live.
- `session pause` checkpoints evidence, interrupts admitted turns, retires hosts, and releases execution capacity.
- `session continue` re-admits and resumes the same paused root and worker threads.
- `session compact` compacts the same paused root and returns it to cold pause.
- `session stop` requests evidence finalization, waits the operator grace, and retires every host.
- `session cancel` terminates immediately while retaining available evidence.

`resume` reattaches only to a resumable generation-8 session. Supply exactly one session/thread identifier or `--last`; `--all` is valid only with `--last`. `run resume` is rejected because `run` means a deliberately new session.

Worker results are losslessly paged. Start with cursor zero and follow `next_cursor` until it is null:

```bash
codex-mmo jobs result JOB_ID --json
codex-mmo jobs result JOB_ID --cursor NEXT_CURSOR --json
```

Reading evidence does not accept a result or integrate a patch.

## Configuration and precedence

Installed defaults come from the runtime's `config/settings.toml`. The user file at `~/.config/codex-mmo/settings.toml` (or the install manifest's configured root) overlays those defaults and rejects unknown or invalid keys. Settings are static inputs to newly compiled state; existing sessions retain their immutable snapshot.

Profile selection follows this order:

1. an explicit command `--profile`;
2. the profile written by `codex-mmo profile use` in `active-profile`;
3. `default_profile` in merged settings.

For commands that query the installed Codex model catalog, the executable follows explicit `--codex-bin`, then `MMO_CODEX_BIN`, then `codex_bin` in settings. The base home follows explicit `--codex-home`, then `CODEX_HOME`, then `base_codex_home` in settings.

Live provider-discovery URL overrides follow explicit CLI options, then their corresponding environment variables, then the reviewed catalog endpoint: `MMO_OPENCODE_MODELS_URL`, `MMO_OPENCODE_ZEN_MODELS_URL`, `MMO_OPENROUTER_MODELS_URL`, `MMO_ZAI_MODELS_URL`, and `MMO_ZAI_CODING_MODELS_URL`. Provider credentials are loaded from the protected credentials file and launch environment according to the security contract; they are never printed by normal or debug CLI output.

The installer follows absolute `XDG_DATA_HOME`, `XDG_CONFIG_HOME`, and `XDG_STATE_HOME` values, plus the project-specific `XDG_BIN_HOME`. Empty or relative values use documented per-user fallbacks. See [Installation](INSTALLATION.md) for paths and [Troubleshooting](TROUBLESHOOTING.md) for recovery guidance.

## Destructive operations

`clean` preserves its established noninteractive semantics and never prompts. It only considers terminal jobs and sessions older than the selected thresholds; active work is not eligible. Preview the exact thresholds and eligible counts first:

```bash
codex-mmo clean --dry-run --json
codex-mmo clean --job-days 30 --session-days 90 --json
```

Profile removal, job/session cancellation, stop, installer replacement, and uninstaller purge remain explicit commands or flags. Scripts should inspect their exit status and stderr rather than parsing human prose.
