---
title: CLI reference
path: reference/cli
status: published
---

# ScaiFlux Usage

## Install

```bash
pip install -e ".[dev]"       # dev + test stack
pip install -e ".[mcp]"       # include MCP client support
```

First-time setup — easiest path:

```bash
scaiflux setup
```

Walks through three prompts: pick the ScaiGrid endpoint (ScaiLabs
default or a custom URL), paste a ScaiGrid API key (`sgk_live_...`),
and pick a default model from the discovered catalog. Optionally
scaffolds `.scaiflux.json` + `SCAIFLUX.md` in the current directory.
Re-runnable any time.

The REPL detects first-run automatically: launching `scaiflux` with
no credentials file and a TTY will offer to run the wizard before
dropping you in. Scripted invocations get a hint and continue.

---

For headless or already-scripted setups, drive `login` directly:

```bash
# Interactive (ScaiKey OAuth PKCE, opens a browser):
export SCAIGRID_BASE_URL="https://scaigrid.example.com"
export SCAIKEY_BASE_URL="https://scaikey.example.com"
export SCAIKEY_TENANT="your-tenant"
export SCAIKEY_CLIENT_ID="scaiflux-cli"
scaiflux login

# Headless ScaiGrid API key:
scaiflux login --scaigrid-url https://scaigrid.example.com --api-key sgk_live_...

# BYO OpenAI-compatible backend (no ScaiGrid):
export OPENAI_API_KEY="sk-..."
export OPENAI_BASE_URL="https://compat.example/v1"
```

The session and discovered model catalog live in
`~/.scaiflux/credentials.json` (mode 0600); `scaiflux logout` clears it.

## Top-level subcommands

| Command | What it does |
|---------|--------------|
| `scaiflux setup` | First-run wizard — endpoint + API key + default model + optional workspace scaffold |
| `scaiflux login` | Authenticate via ScaiKey OAuth PKCE (or `--api-key sgk_live_...`) |
| `scaiflux logout` | Remove `~/.scaiflux/credentials.json` |
| `scaiflux prompt <text>` | Run a one-shot prompt, streaming the response |
| `scaiflux repl` | Launch the interactive REPL with tab-completed slash commands |
| `scaiflux serve` | Run as an NDJSON-over-stdio service driven by an external controller (see **`SERVE.md`**) |
| `scaiflux status` | Snapshot of workspace + config + session state |
| `scaiflux doctor` | Health checks (Python, credentials, workspace, config) |
| `scaiflux sandbox` | Container-marker detection report |
| `scaiflux init` | Scaffold `.scaiflux.json` + `SCAIFLUX.md` + `.gitignore` entries |
| `scaiflux system-prompt` | Print the assembled system prompt |
| `scaiflux dump-manifests` | Dump tool + slash-command catalogs as JSON |
| `scaiflux bootstrap-plan` | Print the 5-phase bootstrap plan |
| `scaiflux plugin {list,install,enable,disable,uninstall,update}` | Manage plugins |
| `scaiflux agents {list,show <name>}` | List configured sub-agents |
| `scaiflux mcp {list,show <name>,status}` | List + probe configured MCP servers |
| `scaiflux skills {list,show <name>}` | List discovered skills |
| `scaiflux session {list,replay,fork}` | Inspect, replay, or branch stored sessions |
| `scaiflux version` | Print the ScaiFlux version |

### Session subcommand

```bash
scaiflux session list                                # all sessions in this workspace
scaiflux session replay <id|latest|path>             # print the transcript
scaiflux session fork <id|latest> --at <turn>        # branch a new session at turn N
```

`fork` defaults to a full copy when `--at` is omitted; `--at 0` keeps
just the first message.

## `prompt` flags

| Flag | Default | Purpose |
|------|---------|---------|
| `--model, -m` | (from session) | Frontend model slug (see `scaiflux doctor` for the discovered list) |
| `--max-tokens` | `1024` | Cap on output tokens per turn |
| `--workspace, -w` | `.` | Workspace root (tool execution + session files) |
| `--permission-mode` | `danger-full-access` | One of `read-only` / `workspace-write` / `danger-full-access` / `prompt` / `plan` |
| `--dangerously-skip-permissions` | off | Force `danger-full-access` unattended |
| `--max-iterations` | `20` | Max tool-loop iterations |
| `--resume <id\|latest\|path>` | — | Resume an existing session |
| `--output-format {text,json}` | `text` | Text streams directly; JSON emits a single envelope with `message`, `model`, `usage`, `estimated_cost`, `tool_uses`, `tool_results`, `auto_compaction` |
| `--allowedTools <csv>` | all | Comma-separated tool-name filter |

## REPL slash commands

Type `/help` inside the REPL for the full list. Every command is real —
no stubs. Categories:

- **session**: `/help`, `/exit`/`/quit`, `/clear`, `/compact`, `/save
  <key> [--global]`, `/export [json|jsonl|md] [path]`, `/tasks`,
  `/team`, `/cron`, `/session {list,resolve,replay,fork,delete,clear}`
- **project**: `/init`, `/memory [edit [<file>]]`, `/diff`, `/files`,
  `/release-notes [N]`, `/commit [run]`, `/pr [run]`, `/issue run <subject>`
- **config**: `/model`, `/mode`, `/config`, `/hooks`, `/providers`,
  `/poolnoodle on|off|status` (easter egg persona 🛟)
- **tools**: `/sandbox`, `/agents`, `/subagent`, `/skills`, `/mcp`,
  `/plugin`, `/desktop`, `/review`, `/advisor`, `/insights`,
  `/security-review`
- **debug**: `/version`, `/status`, `/doctor`, `/system-prompt`,
  `/cost`, `/usage`, `/stats`, `/context`, `/telemetry [tail N]`

For a narrative tour of the REPL experience (session picker, ESC
interrupt, context-usage bar, Poolnoodle mode, etc.), see
**`REPL_WALKTHROUGH.md`**.

## Serve mode (remote control)

For programmatic orchestration — e.g. ScaiForge driving a sandboxed
ScaiFlux instance — use `scaiflux serve`. The process speaks NDJSON
over stdio: one JSON command per line on stdin, one JSON event per
line on stdout. Stderr stays for human-readable logs.

```bash
scaiflux serve --workspace ./project --model scailabs/poolnoodle-omni
```

One process == one session. Permissions are always proxied to the
controller; on `deny` the model receives a synthetic tool-error and
can adapt in-turn (the turn isn't aborted). The wire schema
(`scaiflux/cli/protocol.py`) is the contract — `extra="forbid"` on
both write and read, with `PROTOCOL_VERSION` in the `ready` event.

Full reference, event tables, and an end-to-end transcript:
**`SERVE.md`**.

Workflow `run` mode (opt-in): `/commit run` pipes the generated message
into `git commit -F -`. `/pr run` parses the first line as the PR title,
the rest as the body, and invokes `gh pr create`. `/issue run <subject>`
calls `gh issue create` with the generated body. The non-`run` form just
renders the suggestion.

## Plan mode

Start with `--permission-mode plan` to get "think first, execute after I
nod" behavior. The model is told (via a plan-mode stanza in the system
prompt) that writes, shell commands, and other mutating tools will be
denied by the enforcer — so it should explore the workspace, draft a
numbered plan, and call the `exit_plan_mode` tool with that plan. The
plan is printed to stderr for your review; answering `y` flips the
runtime to `workspace-write` and lets execution proceed. Plan mode is
only registered at bootstrap, so entering it via `/mode plan` mid-
session won't surface `exit_plan_mode` — restart to pick it up.

## Config hierarchy

Later sources override earlier ones:

1. User — `~/.scaiflux/settings.local.json`
2. Project — `<ws>/.scaiflux.json`
3. Local — `<ws>/.scaiflux/settings.local.json`

Scalars replace; dicts merge recursively; `permissions.allow/deny/ask`
and `hooks.*` lists concatenate.

## Auto-compaction

Configurable via the `SCAIFLUX_AUTO_COMPACT_INPUT_TOKENS` env var
(default 100 000). When cumulative input tokens cross the threshold, the
runtime retains the last 4 messages, records an `AutoCompactionEvent`
in the JSON prompt output, and continues.

## Project memory

Files auto-loaded into the system prompt (walked up from the workspace):
- `SCAIFLUX.md`
- `SCAIFLUX.local.md`
- `.scaiflux/instructions.md`
