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

# CLI reference

> oceancode is one binary: oceancode [subcommand] [flags] [args]. With no subcommand it starts Ocean pager. acp runs it as an editor agent, and serve, run, goal and workflow run it headless. 01 · Getting started explains the three boot shapes. This page lists every subcommand, its flags and its …


`oceancode` is one binary: `oceancode [subcommand] [flags] [args]`. With no subcommand it starts Ocean
pager. `acp` runs it as an editor agent, and `serve`, `run`, `goal` and `workflow` run it headless.
[01 · Getting started](/oceancode) explains the three boot shapes. This page lists every
subcommand, its flags and its exit codes.

## Flag syntax

Most engine commands parse flags with a port of Go's `flag` package: the default shape, `serve`, `acp`,
`migrate`, `run`, `workflow`, `goal`, `ledger`, `export`, `login`, `logout`, `key` and `auth`. Go's rules
apply:

- `-name` and `--name` are the same flag. A value is written `--name value` or `--name=value`. Single-letter
  flags cannot be bundled: `-vc` is one flag named `vc`.
- Parsing stops at the first argument that is not a flag, or at a bare `--`, which is dropped. Everything
  after that point is positional, even if it looks like a flag.
- A boolean flag never takes the next argument; turn one off with `--name=false`. Integer flags accept
  Go's base prefixes (`0x1000`, `0o10000`, `0b…`) and `_` separators.
- `-h`/`--help` prints `Usage of <name>:` and the flag list to **stderr**, then exits **0**. An unknown
  flag, a missing value or a bad value prints the error and the usage to stderr, then exits **2**.

The capability and maintenance commands (`plugin`, `mcp`, `skill`, `trust`, `hooks`, `jev`, `inspect`,
`doctor`, `update`, `verify-release`, `uninstall`, `claude`) parse their arguments by hand. Write their
flags with two dashes, exactly as shown. Most of them reject `--help` with a usage error (exit 1).
**`update` ignores `--help` and runs a real update**, so never try `oceancode update --help`.

## Global flags

`--version` must be the first argument. `--data-dir` and `--fake-llm-sse` are removed from the whole
command line before the subcommand is chosen, so a `run` prompt that contains the words `--data-dir x`
loses them.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--version` | — | — | Print `oceancode <version> (<build stamp>)` and exit 0. Needs no database, config or terminal. `-v` is **not** an alias: it means `--verbose`. |
| `--data-dir <dir>` | string | the app data dir | Where `auth.json` and the other per-install state live, for commands that boot the engine. Also `--data-dir=<dir>`. |
| `--fake-llm-sse <file>` | string, repeatable | none | Test hook: replay a recorded provider SSE body for each turn, in order, repeating the last one. Also `--fake-llm-sse=<file>`. |

`OC_DETERMINISTIC=1` is read at the same point: it pins the clock and seed that ids are minted from, so
two runs produce identical id sequences. Every invocation except `--version` checks for orphaned sessions
left by a crashed run. When it finds any, it prints one line to stderr: ``note: <n> orphaned session(s)
from a previous run — run `oceancode doctor` for details``.

## Common engine flags

`--db`, `--directory` and `--verbose` are **not** global; each command declares them. They mean the same
thing everywhere, so the per-command tables below omit them.

| Flag | Type | Default | Meaning | Taken by |
|---|---|---|---|---|
| `--db` | string | `oceancode.db` | Path to the session database. | the default shape, `run`, `serve`, `acp`, `workflow run`/`pause`/`resume`/`stop`, `goal`, `ledger`, `export`, `migrate` |
| `--directory` | string | current directory | Working directory. For `workflow runs` it is the project to filter by. | the same, minus `migrate`, plus `workflow runs` |
| `--verbose`, `-v` | bool | off | Trace every outbound LLM provider request/response to stderr, with credentials masked. | the default shape, `run`, `serve`, `acp`, `workflow run` and its control verbs, `goal` |

## Exit codes

| Code | Meaning | Where |
|---:|---|---|
| 0 | Success, or `-h`/`--help` on a Go-flag command. | all |
| 1 | The command failed. The message is printed to stderr as `error: <message>`. | all |
| 2 | Flag parse error (unknown flag, missing or bad value). | Go-flag commands |

`oceancode run` exits with a **typed code** once its turn has started. A failure before that (boot, flag
validation, an empty message) is exit 1. A turn that ends while background sub-agents it started still work
does not end the run: `run` waits for them and for the turns their results start, and exits on the last.

| Code | Meaning | Stop reason(s) |
|---:|---|---|
| 0 | finished | `finished`, `waiting` |
| 2 | permission rejected | `permission_rejected` |
| 3 | budget | `budget` |
| 4 | time | `time` |
| 5 | no progress | `no_progress`, `max_steps`, `doom_loop` |
| 6 | error | `error`, `hook_blocked`; also a `--json-schema` that cannot be satisfied |
| 130 | interrupt | `user_interrupt` |

`oceancode workflow run` and `oceancode goal` exit by the run's final status:

| Code | Status |
|---:|---|
| 0 | `complete` (and a `--validate-only` check) |
| 2 | `failed`, `cancelled`, `interrupted`, `budget_limited`, or any unrecognised status |
| 3 | a pause: `user_paused`, `back_off_paused`, `no_progress_paused`, `infra_paused`, `blocked` |

Exit 2 from `run` can be a permission rejection or a flag error; the stderr text tells them apart.

## `oceancode` (no subcommand)

```bash
oceancode [--db <path>] [--directory <dir>] [--listen <host:port>] [--tui pager] [-v]
```

Execs Ocean pager, which runs the engine inside its own process. stdout must be a terminal; otherwise it
fails with ``stdout is not a terminal — use `oceancode serve` for headless serving``. The pager binary is
looked up in this order: `OC_PAGER_BIN`, then next to `oceancode` (also next to its target if `oceancode`
is a symlink), then `PATH`. Here `--verbose` becomes the pager's `--debug`.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--listen` | string | `127.0.0.1:4096` | HTTP bind address handed to the pager. A non-loopback address needs `OC_SERVER_PASSWORD`. |
| `--tui` | string | empty | Kept for old scripts: empty or `pager` is accepted, `ocean` is refused (the native TUI was removed), and any other value is an error. Falls back to `OC_TUI`. |

See [19 · Ocean pager](/oceancode/pager).

## `oceancode run`

```bash
oceancode run [flags] <message…>
```

Runs one non-interactive turn and exits with the typed code above. **Flags must come before the
message**, because a flag after it is sent to the model as text; a bound flag placed after the message
also prints a warning that the run is not bounded by it. When stdin is not a terminal, `run` reads it to
EOF and appends it to the message, so close stdin (`</dev/null`) when the prompt is only an argument. An
empty message fails with `you must provide a message`.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--agent` | string | empty | Agent to use. |
| `--model`, `-m` | string | empty | Model to use, `provider/model`. |
| `--variant` | string | empty | Model variant (provider-specific reasoning effort, e.g. `high`, `max`). |
| `--title` | string | truncated prompt | Session title. |
| `--continue`, `-c` | bool | off | Continue the last session. |
| `--session`, `-s` | string | empty | Session id to continue. |
| `--resume-title`, `-r` | string | empty | Resume the most recent session whose title matches this text. |
| `--fork` | bool | off | Fork the session before continuing. An error unless `--continue` or `--session` is also given. |
| `--auto` | bool | off | Auto-approve permissions that are not explicitly denied (dangerous!). |
| `--output-format` | string | `text` | `stream-json` (NDJSON per event), `json` (one buffered result object), or `text`. Takes precedence over `--format`. |
| `--format` | string | `default` | Deprecated. `default` = text; `json` = the `stream-json` framing. |
| `--tools` | string | all | Restrict the advertised tools to these comma-separated ids. An unknown id is an error. |
| `--disallowed-tools` | string | empty | Remove these comma-separated tool ids from the advertised set. |
| `--allow` | string | empty | Append allow permission rules, e.g. `"Bash(git *),Edit(src/**)"`. |
| `--deny` | string | empty | Append deny permission rules (last match wins, so a `--deny` beats an overlapping `--allow`). |
| `--append-system-prompt` | string | empty | Append this text to the run's system context. |
| `--json-schema` | string | empty | Validate the model's final JSON against this JSON Schema (a file path or inline JSON). On a mismatch the model is re-prompted with the validation errors, up to a retry limit. Prints the validated object; exits 6 if the schema cannot be satisfied. |
| `--max-usd` | string | unset | USD bound for this session: a number, `off`, or `subscription` (no bound; spend shows the list-price estimate). |
| `--max-minutes` | string | unset | Wall-clock bound: minutes, `90m`, `8h`, `2d`, or `off`. |
| `--max-steps` | string | unset | Step bound per turn, `1..=1000`, or `default` to clear a stored override. |
| `--tideline`, `--shelve` | string | unset | The Session Ledger tideline: `<pct>%` (a share of the model's context), `<limit>`, or `default`. `--shelve` is the older spelling. |
| `--window` | string | — | Removed. Any value fails with `--window was renamed: use --tideline`. |
| `--subagent` | string | unset | The model this session's sub-agents run, `provider/model`. |
| `--atif` | string | empty | When the turn ends, write the session's ATIF-v1.8 trajectory (JSON) to this path. |

See [07 · Headless and server](/oceancode/headless-and-server) and
[08 · Bounding a long run](/oceancode/bounding-a-long-run).

## `oceancode serve`

```bash
oceancode serve [--port <n>] [--host <ip>] [--db <path>] [--directory <dir>] [-v]
```

Starts the engine with its HTTP surface only and no UI. The banner goes to stdout and diagnostics to
stderr. A non-loopback `--host` without `OC_SERVER_PASSWORD` is refused before anything boots.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--port` | int | `4096` | TCP port to listen on. |
| `--host` | string | `127.0.0.1` | Interface to bind. A non-loopback host requires `OC_SERVER_PASSWORD`. |

See [07 · Headless and server](/oceancode/headless-and-server).

## `oceancode acp`

```bash
oceancode acp [--db <path>] [--directory <dir>] [-v]
```

Serves the engine as an Agent Client Protocol agent over stdin/stdout, which is how Xcode and other ACP
editors launch it. stdout carries only newline-delimited JSON-RPC; the banner, diagnostics and tracing go
to stderr. There is no HTTP surface, and the command returns when the editor closes stdin. It takes only
the common engine flags. See [20 · Xcode and other ACP editors](/oceancode/xcode).

## `oceancode workflow`

```bash
oceancode workflow run <name|path> [--args <json>] [--budget <n>] [--validate-only] [-m <provider/model>]
oceancode workflow runs [--all] [--directory <dir>]
oceancode workflow pause|resume|stop <run_id> [--budget <n>]
```

`run` starts a host-run Rhai workflow and prints each `workflow_updated` body to stdout as one JSON line.
The last line is the terminating body, and the command exits with the workflow/goal code above. Put the
name or path **first**, then the flags. `runs` lists the persisted runs for the current project, newest
first; it takes no `--db` or `--verbose`. `pause`, `resume` and `stop` (run id first) only act on a run
that is live in the engine that same command boots.

| Flag | Sub-subcommands | Type | Default | Meaning |
|---|---|---|---|---|
| `--args` | `run` | string | `{}` | JSON object bound to the workflow's `args` global. |
| `--budget` | `run`, control verbs | string | from config | `run`: absolute bound on cumulative child-agent calls, `1..=1024`. `resume`: a higher call bound that lifts a budget-limited run. |
| `--validate-only` | `run` | bool | off | Metadata and compile check only; launches no agent. |
| `--model`, `-m` | `run` | string | empty | `provider/model` for steps that name no model. There is no default provider. |
| `--all` | `runs` | bool | off | List runs from every project. |

See [07 · Headless and server](/oceancode/headless-and-server).

## `oceancode goal`

```bash
oceancode goal "<objective>" [--budget <n>] [-m <provider/model>] [--db <path>] [--directory <dir>] [-v]
```

Launches the built-in `goal` workflow (Plan → Work → Verify) and prints each `goal_updated` body to stdout
as one JSON line. It exits with the workflow/goal code above. The **objective must be the first
argument**, with the flags after it. A missing objective, or a flag in first place, fails with
`missing objective: usage: oceancode goal "<objective>" [--budget <n>] [--model <provider/model>]`.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--budget` | string | from config | Absolute bound on cumulative child-agent calls for the goal, `1..=1024`. |
| `--model`, `-m` | string | empty | Default model for every goal agent that names none. There is no default provider. |

See [07 · Headless and server](/oceancode/headless-and-server).

## `oceancode ledger`

```bash
oceancode ledger path [--db <path>] [--directory <dir>] <session-id>
oceancode ledger rebuild [--merge] [--yes] [--db <path>] [--directory <dir>] <session-id>
```

`path` prints the absolute ledger directory of the session. `rebuild` rebuilds the ledger mechanically and
prints `rebuilt <n> turn(s) in <dir>`. `--merge` then prints the number of merge chunks and asks
`fold forward with model calls? [y/N]` on stderr before folding them forward, which costs model calls.
The session id is read after the flags, so **write the flags first**; a flag placed after the id is not
applied. With the ledger disabled (`ledger.enabled = false`), `rebuild` fails.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--merge` | bool | off | `rebuild` only: fold the merge backlog forward after the rebuild (model calls). |
| `--yes` | bool | off | `rebuild` only: skip the y/N confirmation for `--merge`. |

See [06 · Session ledger and export](/oceancode/session-ledger-and-export).

## `oceancode export`

```bash
oceancode export (--md | --atif) [--out <path>|-] [--db <path>] [--directory <dir>] <session-id>
```

Writes a whole session as one Markdown document or as an ATIF-v1.8 trajectory (JSON). Pass exactly one of
`--md` or `--atif`. As with `ledger`, the session id is read after the flags, so write the flags first.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--md` | bool | off | Write the session as one Markdown document. |
| `--atif` | bool | off | Write the session as an ATIF-v1.8 trajectory (JSON). |
| `--out` | string | `-` | Output path; `-` writes to stdout. |

See [06 · Session ledger and export](/oceancode/session-ledger-and-export).

## `oceancode login`

```bash
oceancode login [--provider claude|copilot|codex] [--no-browser]
```

Logs in to a provider and stores the credential in the data dir's `auth.json`. `claude` (the default;
also `anthropic`, `claude-pro`, `claude-max`) runs the Claude Pro/Max OAuth flow: it prints the authorize
URL and reads the pasted code from stdin. `copilot` (`github-copilot`) and `codex` (`openai`) run the
OAuth 2.0 device-code flow and store the credential under `github-copilot` or `openai`.

| Flag | Type | Default | Meaning |
|---|---|---|---|
| `--provider` | string | `claude` | Provider to log in to: `claude`, `copilot` or `codex`. |
| `--no-browser` | bool | off | Print the authorize URL only; do not try to open a browser. |

A `--features platform` build adds `--provider ocean` (dashboard sign-in that stores the Ocean account
key) and `--sso-token <token>` (stores a gateway SSO session token). See
[15 · Platform mode](/oceancode/platform-mode).

## `oceancode logout`

```bash
oceancode logout [anthropic|zai-coding-plan|ocean]
```

Removes one provider's stored credential from `auth.json`; the default is `anthropic`. Accepted names:
`anthropic`/`claude`, `zai-coding-plan`/`zai`/`glm`/`zai-coding`/`glmcoding`, and `ocean`/`plungeai`. If
nothing is stored, it prints `No stored <provider> credential.` and exits 0. Takes no flags.

## `oceancode key`

```bash
oceancode key [<provider>] [<api-key>]
```

Stores an API key in `auth.json` (type `api`). The provider defaults to `anthropic` and takes the same
names as `logout`. With no key on the command line, the key is read from stdin when stdin or stdout is
not a terminal; in a terminal, a non-Anthropic provider prompts for it. With no key at all, the command
prints the credential status for `anthropic` and `zai-coding-plan`. A key without the expected `sk-ant-`
prefix triggers a warning but is still stored. Takes no flags.

## `oceancode auth`

```bash
oceancode auth
```

An interactive picker: `1` Anthropic API key, `2` Claude subscription (runs `login`), `3` GLM coding plan
(runs `key zai-coding-plan`). Needs both stdin and stdout to be a terminal and fails otherwise. Takes no
flags.

## `oceancode claude`

```bash
oceancode claude
```

Checks the claude-code provider before you use it. It reports the `claude` binary's path (or `claude.bin`
from config), its `--version`, and whether a Claude Code login is present. Advisory only: it exits 0
whatever it finds. Any argument fails with `usage: oceancode claude`.

## `oceancode inspect`

```bash
oceancode inspect [--json]
```

Prints where every config key, skill, agent, command, MCP server and instruction file comes from, for the
**current directory** (there are no `--dir`/`--home` flags). Each human row is
`kind id winning-layer source`, and the last line is `INSPECT_OK sources=<n>`. With `--json` the JSON
array goes to stdout and the sentinel to stderr. Boots nothing. See
[09 · Capabilities and plugins](/oceancode/capabilities).

## `oceancode plugin`

```bash
oceancode plugin [--root <home>] <subcommand>
```

`--root` (also `--root=<home>`) overrides the home that the stores live under
(`<home>/.oceancode/plugins` and `<home>/.oceancode/marketplaces`).

| Sub-subcommand | Prints |
|---|---|
| `marketplace add <spec>` / `update <n>` / `remove <n>` | `PLUGIN marketplace-added\|marketplace-updated\|marketplace-removed <name>` |
| `marketplace list` | `<name> plugins=<n>` per marketplace |
| `install <name-or-path> [--trust] [--marketplace <m>]` | `PLUGIN installed <name> <version>`, plus `PLUGIN trusted <name>` with `--trust` |
| `list` | `<name> <version> enabled=<bool> trusted=<bool>` per plugin |
| `uninstall <n>` / `update <n>` | `PLUGIN uninstalled <n>` / `PLUGIN updated <n> <version>` |
| `enable <n>` / `disable <n>` | `PLUGIN enabled\|disabled <n>` |
| `enable-all` / `disable-all` | `PLUGIN enabled-all\|disabled-all count=<n>` |
| `trust <n> [--off]` | `PLUGIN trusted\|untrusted <n>` |
| `validate <n>` | `PLUGIN validated <n> ok=<bool>`, then one `  - <problem>` line per problem |
| `import --from claude-code [--trust] [--no-repo-trust] [--dry-run] [--home <h>] [--dir <d>]` | Ends with `IMPORT_OK plugins=<n> marketplaces=<m> repo_trust=<bool>` (`IMPORT_DRY_RUN_OK …` under `--dry-run`). `import` takes `--home`/`--dir`, not `--root`. |

See [09 · Capabilities and plugins](/oceancode/capabilities).

## `oceancode mcp`

```bash
oceancode mcp [--root <dir> | --dir <dir>] [--home <h>] <subcommand>
```

`--root` (or its alias `--dir`) selects the project directory where `.mcp.json` lives; the default is the
current directory. `--home` selects the home tier.

| Sub-subcommand | Behaviour |
|---|---|
| `add <name> --command <cmd> [--arg <a>]… [--env K=V]…` | Writes a stdio server to `<dir>/.mcp.json` under `mcpServers.<name>`. Prints `MCP added <name> stdio`. |
| `add <name> --url <url> [--header K=V]…` | Writes a remote (`type: http`) server. Prints `MCP added <name> remote`. Pass exactly one of `--command` or `--url`. |
| `remove <name>` | Deletes the entry from `.mcp.json`. Prints `MCP removed <name>`. |
| `enable <name>` / `disable <name>` | Clears or sets the server's held-disabled bit in the trust store. Prints `MCP_ENABLED`/`MCP_DISABLED <name>`. |
| `list` | One row per discovered server: `name  stdio\|remote  tier  trusted\|untrusted  enabled\|disabled\|shadowed  source`. |
| `login <name>` / `logout <name>` | `login` prints the OAuth callback URL and contacts no network. `logout` clears the stored OAuth entry. |
| `doctor` | Connects to each server with a 2-second budget and prints one status row per server (`connected`, `needs-auth`, `failed`, `disabled`, `untrusted`). |

See [11 · MCP servers](/oceancode/mcp).

## `oceancode skill`

```bash
oceancode skill [--root <dir>] [--dir <d>] [--home <h>] <subcommand>
```

| Sub-subcommand | Behaviour |
|---|---|
| `create <name> [--description <text>]` | Writes `<root>/.oceancode/skills/<name>/SKILL.md` (`--root` defaults to the current directory) and prints `SKILL created <path>`. Refuses to overwrite an existing skill. |
| `list [--json]` | One row per discovered skill: `id  tier  trusted\|untrusted  state  description`. `state` is `enabled` or the reason the skill is disabled. |
| `enable <id>` / `disable <id>` | Flips one skill's user-tier enable bit. `<id>` is a stable id, or a bare name that matches exactly one skill. Prints `SKILL enabled\|disabled <id>`. |
| `enable-all` / `disable-all` | Prints `SKILL enabled-all` / `SKILL disabled-all count=<n>`. |

See [09 · Capabilities and plugins](/oceancode/capabilities).

## `oceancode trust`

```bash
oceancode trust show | repo on|off | mcp <name> on|off|clear  [--dir <d>] [--home <h>]
```

Reads and sets the per-project trust record in `<home>/.oceancode/trust.json`. `show` prints
`repo=<bool>`, then one `mcp <name>=<bool>` line per override and one `disabled <name>` line per held
server. Every subcommand ends with `TRUST_OK`. `repo` grants or revokes repo-tier execution (repo hooks
and `.mcp.json` servers). `mcp` sets a per-server override that takes precedence over `repo`, or clears
it. See [11 · MCP servers](/oceancode/mcp).

## `oceancode hooks`

```bash
oceancode hooks [--dir <d>] [--home <h>] list [--json]
oceancode hooks add <Event> --command <cmd> [--matcher <re>] [--timeout <s>] [--scope user|project|local]
oceancode hooks remove <Event> --command <cmd> [--matcher <re>] [--scope user|project|local]
```

`list` prints every hook source file the boot loader reads: one line per source with its tier, its trust,
whether it is loaded (or held, and why) and its path, followed by its handlers. The output ends with
`HOOKS_OK sources=<n> handlers=<m> loaded=<k>`. `--json` prints `{"repo_trusted", "sources"}` and no
sentinel. `add` and `remove` edit Claude Code's `settings.json` for the chosen scope (default `project`)
and print `HOOK_ADDED <path>` or `HOOK_REMOVED <path>`. Removing a handler that does not exist fails with
`hooks remove: no such handler`. See [10 · Hooks](/oceancode/hooks).

## `oceancode jev`

```bash
oceancode jev status [--json]
oceancode jev probe [--record --point <p> --case <id> --request <req.json> --out <fixture.json> [--expect <json>]]
oceancode jev labels [--implicit | --unlabelled [--point <p>]] [--root <ledger dir>] [--out <file>]
oceancode jev questions --json
oceancode jev verdicts --in <cases.jsonl>
```

Inspects the Jev decision layer, read from the current directory and the environment (no `--dir`/`--home`
flags). `status` prints one `point mode endpoint-host` line for each of the nine decision points —
`permission`, `output_view`, `supervisor`, `triage`, `visibility`, `check`, `guidance`, `snippets`,
`effort` — then `JEV_STATUS_OK points=9`; `--json` prints `{points, endpoint, thresholds}` instead, with
`JEV_STATUS_EMITTED points=9` on stderr. On a project with no `jev` section every point is `off`:

```text
permission   off     -
output_view  off     -
…
effort       off     -
JEV_STATUS_OK points=9
```

`probe` makes one live call to Jev and prints `JEV_PROBE_OK`
or `JEV_PROBE_FAIL <why>`; `probe --record` records a fixture. `labels` exports labelled decisions
(`JEV_LABELS_OK added=<n> total=<m>`), each row's `source` telling a person's answer (`shadow-user`) from
the labels the `effort` and `snippets` points write themselves (`implicit-effort`, `implicit-snippets`);
`--unlabelled` requires `--out`. The `tool_tiers` and `relevance` points were retired on 2026-10-21
and no verb lists them. `questions --json` and
`verdicts --in` print the decision points' question sets and policy verdicts for the bench. Only `probe`
calls Jev. See [13 · Jev decisions](/oceancode/jev-decisions).

## `oceancode doctor`

```bash
oceancode doctor [--storage]
```

Reports orphaned sessions (registry entries whose process died without a clean exit) and captured panic
reports found under the data dir. `--storage` adds the storage report: the sizes of `oceancode.db` and its
WAL, the session count, and the ledger directory's size and oldest session age. Read-only; any other
argument is ignored. See [18 · Operations](/oceancode/operations).

## `oceancode migrate`

```bash
oceancode migrate [--db <path>]
```

Opens the database named by `--db` (default `oceancode.db`), migrates it to the current schema, prints
`opened and migrated <path>`, and exits.

## `oceancode update`

```bash
oceancode update [--self-test]
```

Updates itself to the newest release on the configured channel; `OC_UPDATE_CHANNEL` (`stable`/`beta`)
overrides `update.channel`. Both `oceancode` and `ocean-pager` are verified first, swapped atomically, and
rolled back together if a health check fails. Prints `UPDATE_APPLIED from=<old> to=<new>`, or
`oceancode <v> is already the newest <channel> release`. `--self-test` exercises the swap and rollback
offline on stub binaries and prints `UPDATE_OK from=<old> to=<new> rollback_tested=1`, then
`UPDATE_SELF_TEST_OK binaries=2`. No other argument is recognised. See
[17 · Distribution and updates](/oceancode/distribution).

## `oceancode verify-release`

```bash
oceancode verify-release <artifact> [--pubkey <base64>] [--sha256sums <path>]
```

Verifies the artifact's minisign `<artifact>.minisig` signature without any external tool. `--pubkey`
replaces the embedded release key; `--sha256sums` also checks the artifact's entry in that `SHA256SUMS`
file. Prints `VERIFY_RELEASE_OK file=<name>`. See [17 · Distribution and updates](/oceancode/distribution).

## `oceancode uninstall`

```bash
oceancode uninstall [--purge] [--yes] [--dry-run]
```

Removes the installed `oceancode` binary from `OC_INSTALL_DIR` (default `~/.local/bin`). `--purge` also
removes the app's config and data dirs, but never a project's `.oceancode/oceancode.db`. Unless `--yes` is
given, it lists every path and asks you to type `oceancode` to confirm. `--dry-run` prints
`would remove: <path>` lines and removes nothing. The last line is `UNINSTALL_OK removed=<n>`. See
[17 · Distribution and updates](/oceancode/distribution).

## See also

- [01 · Getting started](/oceancode) — the three boot shapes.
- [02 · Configuration](/oceancode/configuration) — every `OC_*` variable these commands read.
- [07 · Headless and server](/oceancode/headless-and-server) — `run`, `serve`, `workflow`, `goal` in depth.
- [09 · Capabilities and plugins](/oceancode/capabilities), [10 · Hooks](/oceancode/hooks), [11 · MCP servers](/oceancode/mcp) — the capability commands.
- [17 · Distribution and updates](/oceancode/distribution) — `update`, `verify-release`, `uninstall`.
