# CLI — The `txco` command
_The complete command surface, grouped by what you're doing. Every
command supports `--help` for full flags. The chassis selector `--target`
(see [Selecting a chassis](#selecting-a-chassis---target)) plus `--tenant` /
`--json` repeat across the family._
## Selecting a chassis (`--target`)
Every command that talks to a chassis takes **`--target`** — the single flag for
*which chassis*. It accepts, highest precedence first:
1. a **workspace target** from `txco.yaml` (`targets:` — also carries that env's ops / mock policy)
2. a **profile** name — a "named chassis" carrying its own `chassis_url` **and** signing key
3. a **raw admin URL** (`--target https://host:8081`)
```sh
txco apply cloud # a profile (or txco.yaml target) named "cloud"
txco status --target staging
txco auth tenant secrets set OPENAI_KEY --target dev
txco apply --target https://chassis:8081 # a raw URL works too
```
On the deploy verbs (`apply`, `push`, `status`, `diff`) the target may also be a
**bare positional** — `txco apply staging`. A path-like arg (`.`, `./x`, `/x`, or
anything containing `/`) or an existing directory is taken as the workspace dir
instead, so `txco apply ./sub staging` sets both. (`txco push` takes the stack
first: `txco push api staging`.)
The mutating `auth` / `tenant` commands accept it as a trailing positional too —
`txco auth tenant secrets set OPENAI_KEY staging`, `txco auth tenant grant ACTOR staging`.
These are stdlib-flag-parsed, so any flags must come *before* the trailing target
(`secrets set NAME --tenant t staging`, not `… staging --tenant t`).
`--url` / `--addr` (raw URL) and `--profile` (signing identity) still work as
lower-level overrides — `--target` is just the one spelling unified across the
deploy and `auth` / `tenant` families. With `--target` omitted, the active
profile (after `txco login`) supplies the default; otherwise it's
`http://localhost:8081`.
### Write-guard
A command that **mutates** a **non-local** chassis first prints the resolved
target and asks to confirm — `--yes` skips it, and a non-interactive shell
without `--yes` fails closed. So a stray `secrets set` / `hostnames add` can't
silently land on prod. Local chassis (localhost / loopback / `*.localhost`)
never prompt.
### Local dev: no key required
Against a **local** chassis (`localhost` / loopback / `*.localhost` — e.g. the
`txco dev` chassis), `auth` / `tenant` commands don't need an enrolled signing key:
they send unsigned and the open dev chassis accepts. So
`txco auth tenant secrets set OPENAI_KEY` just works locally with no
`bootstrap-local`. A **remote** chassis still requires enrollment; a local chassis
running in signed mode returns a clear 401.
To save the repetition, **`txco dev` auto-registers a `dev` profile** pointing at
the chassis it just started (with `default_tenant: default`), so you can use the
named selector everywhere instead of spelling out the URL + tenant:
```sh
txco apply dev # deploy to the dev chassis
txco auth tenant secrets set SHH_KEY dev # set a secret on it (tenant: default)
txco ui dev # open the dev admin UI
```
## Run & develop
| Command | What it does |
|---|---|
| `txco serve` | Boot the chassis ([runtime reference](./serve.md)) |
| `txco dev` | The dev loop: boots your `txco.yaml` apps + an ephemeral chassis, watches `OPS/*.txcl` and compute `.js/.ts` files, re-applies on save. Registers a keyless [`dev` profile](#local-dev-no-key-required) for the chassis. `--ui` adds the admin-UI Vite server; `--tcp` / `--dns` add those heads |
| `txco demo` | Ephemeral chassis + browser playground with a guided curriculum (build/web/mail/async/mcp tracks) |
| `txco init ` | Scaffold `OPS//…`; `--from github:…\|oci:…\|dir:…` scaffolds from a template |
| `txco doctor` | Diagnose local setup: home dir, profile, keys, chassis reachability, version sync (`--offline` skips remote checks) |
## Deploy & versions
Stacks change through versioned drafts ([admin-api](./admin-api.md)).
The CLI verbs map onto that flow:
| Command | What it does |
|---|---|
| `txco apply [dir]` | Deploy the whole `OPS/` tree: draft + activate per changed stack; resolves `op://` refs; uploads computes |
| `txco push ` | Like `apply`, one stack |
| `txco pull ` | Materialize a stack's active version (or `--version N`) into local `OPS//` — the inverse of `push` |
| `txco draft ` | Upload a draft *without* activating (stage for review); `--activate` flips it too |
| `txco activate ` | Flip the active-version pointer (defaults to newest draft). Activating an older version = rollback |
| `txco versions ` | List a stack's versions, active one marked |
| `txco diff [dir]` | Compare local `OPS/` against the running chassis |
| `txco lint [dir]` | Validate the `OPS/` tree **offline** (no chassis): name collisions, mis-placed files, txcl parse, unconditional-loop warnings; `--list` prints the op graph; exit 1 on errors (CI-friendly) |
| `txco status [dir]` | Per-stack drift summary; exit 1 on divergence (CI-friendly) |
| `txco edit ` | `$EDITOR` one file of a draft, PATCH it back |
## Nano-ops
| Command | What it does |
|---|---|
| `txco op init ` | Scaffold a `.js`/`.ts` compute next to its rule |
| `txco op build ` | Bundle + compile to wasm (auto-fetches the pinned `javy`) |
| `txco op run --input ` | Execute locally on the same engine production uses |
| `txco op test ` | Run against the scope's `mock-request.json`, diff vs `mock-response.json` |
## Packages
`txco install [ --as `, `txco package
{init,validate,inspect,pull,publish,key,list,upgrade,remove}` — see
[packages](./txco-oci-packages.md).
## Identity & access
| Command | What it does |
|---|---|
| `txco auth bootstrap-local` | First-run: generate a key + enroll it ([admin-api](./admin-api.md)) |
| `txco auth init` / `enroll` / `rotate-key` / `revoke-key` / `revoke-actor` | Key lifecycle |
| `txco auth whoami` (alias `txco whoami`) | What the chassis thinks you are |
| `txco auth invite` / `invitations` / `revoke-invitation` / `accept --token …` | Teammate onboarding |
| `txco auth profiles` / `profile {use,show,remove}` (alias `txco use `) | Named identities; also aliased under `txco config` |
| `txco auth tenants` / `tenant {create,members,grant,revoke}` | Tenant management |
| `txco auth tenant hostnames {add,attach,verify,challenge,list,remove}` | Hostname bindings ([ingress](../routing.md)) |
| `txco auth tenant secrets {set,generate,list,show,describe,rotate,revoke}` | ([Secret store](./runbook-secret-store.md)) |
| `txco auth login` (alias `txco ui`) | Mint a signed browser session, open the admin UI |
| `txco auth sessions {list,revoke}` / `logout` | Browser sessions / stop signing |
| `txco login` / `logout` / `cloud {…}` | **Cloud** account OAuth — distinct from `auth login`, which targets your own chassis |
## Diagnose
| Command | What it does |
|---|---|
| `txco trace [rid\|last]` | Step-by-step trace explorer ([trace](./trace.md)); bare `txco trace` is interactive |
| `txco mcp doctor ` | Probe an MCP server: handshake + tool list ([mcp](./protocols/mcp.md)) |
## Operator & misc
| Command | What it does |
|---|---|
| `txco admin resync --tenant ` | Re-emit control-plane state to the fleet (super-admin) |
| `txco admin tenant {suspend,resume}` | Tenant kill switch (super-admin) |
| `txco snapshot {export,restore,publish}` | Runtime-DB snapshots for fleet bootstrap |
| `txco dns {zone,record,config,render}` | Delegated DNS zones (requires the `dns` personality) |
| `txco cron config {show,set}` | The tenant's cron timezone — `set timezone ` localizes `@cron.*` (default UTC) |
| `txco version` / `update check` / `upgrade` | Version info / check / self-update |
| `txco completion ` | bash/zsh/fish completion script |
| `txco plugin` | List external `txco-` plugins (kubectl convention) |
]