The CLI is how you scaffold, run, and operate an app. `create-oke` writes the project;
`oke` is the day-to-day binary (dev loop, schema, vault, docker, doctor).

For developers who already know the model — look up a command, its flags, and what it
writes.

<Callout title="The one rule">
  Prefer the CLI for environment wiring (`oke dev`, `oke db`, `oke docker`). Put behavior in Flows
  and `oke.config.ts` — never invent a ninth element or hand-edit the Manifest.
</Callout>

## Smallest Example

<Steps>

<Step>
### Scaffold an app

```bash
bunx create-oke@latest notes --yes
cd notes
```

</Step>

<Step>
### Run the dev loop

```bash
bun run dev
```

`bun run dev` is the portable form (`bunx oke dev` is the same). Bare `oke` needs `node_modules/.bin` on PATH — PowerShell does not add it.

Compose comes up (pull / create / start progress streams into the boot status
lines), the backend listens on **6530**, Console on **6533**, app MCP on **6535**,
docs MCP on **6536**. Open `http://localhost:6533`. Quit with **Ctrl+C**.

On a TTY, after schema push, `oke dev` also:

1. Prompts one-by-one for any Vault boot gaps (writes `.env.local`) — e.g.
   `OPENROUTER_API_KEY` when create-oke / `oke ai setup` / Keel declared the
   OpenRouter contract without a value.
2. Asks to run `oke db seed` when a seed module exists and `.oke/state.json` has
   not recorded that seed identity yet. Run `oke db seed` anytime later.

</Step>

</Steps>

## Progressive Patterns

<Tabs items={["Daily", "Schema", "Ship", "Scaffold"]}>

<Tab value="Daily">

```bash
oke dev                 # watch · Console · client types · Docker Compose
oke test                # bun test with PGLite posture
oke doctor              # secrets · ports · schema drift
oke doctor --diff       # CI gate: undeclared contract breaks
```

</Tab>

<Tab value="Schema">

```bash
oke db push             # sync domain schema (dev; auto under oke dev)
oke db generate         # versioned SQL under drizzle/
oke db migrate          # apply migrations (prod)
oke schema generate     # core + plugin stub → .oke/schema/oke.ts
```

**Consequence:** `oke schema generate` is not `oke db generate`. The first writes the
framework stub; the second emits your app's Drizzle migrations.

</Tab>

<Tab value="Ship">

```bash
oke docker --prod       # derive production Compose
oke build --target bun  # tree-shaken bundle
oke start               # production entry (Docker CMD)
```

</Tab>

<Tab value="Scaffold">

```bash
bunx create-oke@latest my-app --yes
bunx create-oke@latest my-app -t advanced --locales ar --proxy caddy
bunx create-oke@latest          # interactive (TTY only)
```

</Tab>

</Tabs>

## Port Map

| Port     | Surface              | Who starts it           |
| -------- | -------------------- | ----------------------- |
| **6530** | Backend API          | `oke dev` / `oke start` |
| **6533** | Developer Console    | `oke dev`               |
| **6535** | App MCP              | `oke dev`               |
| **6536** | Docs MCP (read-only) | `oke dev`               |

Override app / console / mcp listen ports in `oke.config.ts` `ports` — see
[Configuration](/docs/reference/configuration#ports).

## `oke` Commands

| Command      | Purpose                                                      | Key flags / subs                                                                                                                                          |
| ------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dev`        | Watch · hot reload · Console · client types (Docker Compose) | `--docker\|-d [roles]`, `--no-db-push`, `--entry\|-e`                                                                                                     |
| `test`       | Run bun test with PGLite test posture                        |                                                                                                                                                           |
| `start`      | Production entry (Docker CMD)                                | `--entry\|-e`, `--port\|-p`                                                                                                                               |
| `doctor`     | Secrets · ports · stub/domain schema drift                   | `--manifest`, `--diff`, `--before`, `--after`, `--base`, `--json`                                                                                         |
| `stack`      | Preview images / tags / ports (writes nothing)               | `--config`, `--json`                                                                                                                                      |
| `schema`     | Core + plugin tables → `.oke/schema/oke.ts`                  | `generate` (`--check`, `--manifest`, `--out`)                                                                                                             |
| `db`         | Domain schema                                                | `push` · `generate` · `migrate` · `seed` · `studio` · `search-backfill`                                                                                   |
| `client`     | Ambient types for a separate frontend repo                   | `add <url>` (`--out`)                                                                                                                                     |
| `vault`      | Secrets                                                      | `set` · `list` · `import` · `key` · `init` · `status` · `seal` · `unseal` · `rotate` · `rotate-master` · `audit` · `purge-expired` · `backup` · `restore` |
| `docker`     | Derive compose · clean leftover stacks                       | `--prod\|-p`, `--out`, `--config`, `--manifest`; sub `clean`                                                                                              |
| `images`     | List / pin digests                                           | `list` · `pin`                                                                                                                                            |
| `build`      | Tree-shaken bundle                                           | `--target\|-t bun\|node\|edge`, `--entry`, `--outdir`                                                                                                     |
| `eval`       | Prompt eval sets (CI gate)                                   | `--manifest`                                                                                                                                              |
| `ai`         | Configure AI driver + models                                 | `setup` (`--provider`, `--chat`, `--vision`, `--embed`, `--yes`)                                                                                          |
| `branch`     | Fork journaled state                                         | `<name>`, `--at\|-a`                                                                                                                                      |
| `replay`     | Re-invoke a past Flow from Runs                              | `--request-id\|-r`, `--entry`, `--dry-run`, `--live`                                                                                                      |
| `privacy`    | Crypto-shred subject data                                    | `erase` (`--subject\|-s`)                                                                                                                                 |
| `upgrade`    | Breaking-change codemods + diff                              | `--apply\|-a`                                                                                                                                             |
| `console`    | Console helpers                                              | `claim-code` (`--json`)                                                                                                                                   |
| `gates`      | Gate catalogue from Manifest                                 | `list` (`--manifest`, `--json`)                                                                                                                           |
| `completion` | Shell completion script                                      | `bash` · `zsh` · `fish`                                                                                                                                   |
| `mode`       | **Deprecated** — `oke dev` always uses Docker Compose        | `--help`                                                                                                                                                  |

Bare `oke` (TTY) opens the interactive board; `oke --help` prints the catalogue.

### `oke db` detail

Shared flags on push / generate / migrate / studio: `--config\|-c`, `--env name`
(`dev` · `test` · `prod`). Seed adds `--force`, `--entry`. Search-backfill adds
`--batch n` and a `<table>` positional.

```bash
oke db push --env dev
oke db migrate --env prod
oke db seed --force
oke db search-backfill notes --batch 500
```

## `create-oke`

| Flag                             | Meaning                                                   |
| -------------------------------- | --------------------------------------------------------- |
| `-t, --template <id>`            | `standard` (default) or `advanced`                        |
| `--sql <id>`                     | Store SQL dialect — only `postgres` (test stays `pglite`) |
| `-y, --yes`                      | No prompts; defaults + bun install (no `oke dev`)         |
| `--install` / `--no-install`     | Run or skip `bun install` after scaffold                  |
| `--agents-md` / `--no-agents-md` | Write `AGENTS.md` (default on)                            |
| `--ai` / `--no-ai` / `--ai skip` | Configure or skip AI setup                                |
| `--locales <tags>`               | Extra languages beyond English (e.g. `ar` or `ar,fr`)     |
| `--pgdog` / `--no-pgdog`         | Pin PgDog in front of Postgres                            |
| `--proxy <id>` / `--no-proxy`    | `none` · `caddy` · `traefik` · `nginx`                    |
| `-h, --help`                     | Show help                                                 |

## Troubleshooting

<Accordions>

<Accordion title="oke is not recognized (Windows PowerShell)">
  PowerShell has no local `oke` on PATH. Use `bun run dev` or `bunx oke dev`. New Cursor/VS Code
  terminals inherit `node_modules/.bin` from `.vscode/settings.json`. Global: `bun install -g
  okengine`.
</Accordion>

<Accordion title="Cannot find package zod from a global okengine (Windows)">
  `oke` resolved to `%USERPROFILE%\.bun\install\global\node_modules\okengine`. From a framework
  checkout run `bun install` then `bun run dev:keel` — not a global `oke`. Keel links with a Windows
  junction; a plain symlink needs Developer Mode and fails with `EPERM`.
</Accordion>

<Accordion title="Ctrl+C emptied the new create-oke folder (Windows)">
  Interrupting install or `bun run dev` used to delete a folder create-oke had just created. On
  Windows that wipe often failed mid-tree (`EBUSY`) and left an empty or half-deleted project.

After scaffold, Ctrl+C only stops the process. `cd` into the folder and run `bun run dev` again.
Missing `docker` is a separate install — Compose needs it on PATH.

</Accordion>

<Accordion title="Console shows Shell assets not built">
  `:6533` is up but the SPA files were not found. Published `okengine` ships them. Upgrade past the
  Windows path bug (`file://` `/C:/…` lookup), then restart `bun run dev`. From a framework
  checkout, run `bun run build` or keep `oke dev` so Vite HMR attaches.
</Accordion>

<Accordion title="password authentication failed for user oke">
  Postgres was initialized with an older password than `.env.local` — usual after deleting and
  recreating the folder. `oke dev` resets that project's volumes when it sees this.

Already failed? From the app folder: `oke docker clean` then `bun run dev`. Run commands
inside the project (`o1`), not the parent `oke` directory.

</Accordion>

<Accordion title="OKE1020 on oke dev (Compose)">
  The app child had no Manifest to stamp effects (`main.health`). `oke dev` now hands the parent
  extract to the child. A failed extract appends `Manifest extract failed — …` (`oxc-parser`).
</Accordion>

<Accordion title="oke start: no entry found">
  Set `package.json` `okengine.entry` or `main`, pass `--entry`, or keep a conventional
  `src/app.ts`. Production imports that module; the app must call `createBunRuntime().serve` itself.
</Accordion>

<Accordion title="Confusion: oke schema generate vs oke db generate">
  `oke schema generate` emits framework / plugin stub tables under `.oke/schema/`. `oke db generate`
  emits versioned domain SQL via Drizzle. Use `db` for your app tables; use `schema` when the stub
  drifted after a plugin change.
</Accordion>

<Accordion title="oke mode still in muscle memory">
  `oke mode` is deprecated. `oke dev` always starts Docker Compose. There is no soft-compat for old
  `local` / `docker` env map keys — rename to `dev` / `test` / `prod` in
  [Configuration](/docs/reference/configuration).
</Accordion>

<Accordion title="OKE1110 after deploy">
  Domain tables are missing in prod (no auto-DDL). Run `oke db migrate` against that environment —
  see [Errors](/docs/reference/errors).
</Accordion>

<Accordion title="Claim code missing for first Console operator">
  The setup claim code prints on the `oke dev` TTY board and is mirrored to gitignored
  `.oke/claim-code`. Run `oke console claim-code` while setup is open.
</Accordion>

</Accordions>

## Learn more

- [Configuration](/docs/reference/configuration) — `oke.config.ts` drivers and ports
- [Environment Variables](/docs/reference/environment-variables) — what Compose writes
- [Security](/docs/reference/security) — Host / Origin / `allowedHosts`
- [The Architecture](/docs/understand/the-architecture) — one contract; `oke doctor --diff` reviews it
- [Vault](/docs/elements/vault) — `oke vault` rotate / unseal

## Next

<Cards>
  <Card
    title="Configuration"
    description="Every option in oke.config.ts."
    href="/docs/reference/configuration"
  />
  <Card
    title="Security"
    description="Host, Origin, planes, and MCP posture."
    href="/docs/reference/security"
  />
  <Card title="Client" description="Typed createClient for your flows." href="/docs/client" />
</Cards>
