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

# Ocean CLI — agent flows, REPL, and scripting

> All execution happens on Cloudflare; the CLI streams or polls remotely.


<!-- sources-of-truth: cli/README.md, cli/CLAUDE.md, cli/src/commands/workflow.ts, cli/src/commands/chat.ts, cli/src/lib/slash-commands.ts, cli/src/lib/custom-commands.ts, cli/src/lib/mcp-client.ts | last-synced: 2026-09-24 (re-verified: --async only honors -i, --inputs/--json silently ignored, against cli/src/commands/workflow.ts workflowRunCommand — matches, no drift found) -->

## Running agents and workflows from the terminal

All execution happens on Cloudflare; the CLI streams or polls remotely.

### Saved flow, live stream (Studio session)

```bash
ocean workflow run <id> -i "AI startups in fintech"
ocean workflow run <id> --inputs inputs.json     # named inputs (flat string map)
ocean observatory run <id> -i "query"            # event-timeline view instead
```

The stream ends with the formatted result. If the flow is a conversational
agent that pauses (a question or a payment approval), the CLI prints it and
prompts you inline — the run continues in place until final. Non-interactive
shells get a resume hint (`ocean execution continue <id>`) instead.

### Async dispatch + poll (API key)

```bash
ocean workflow run <id> --async -i "ping"   # prints execution id immediately
ocean execution status <exec-id>            # queued/running/completed (+ ⏸ block if paused)
ocean execution output <exec-id>            # result markdown when completed
```

`--async` supports only `-i` (single input) — `--inputs` and `--json` are
silently ignored on the async path; named inputs need a sync `workflow run` or
Studio. The execution id is also remembered as `last_execution_id` for
follow-ups (a config save — see the key-persistence note under Scripting).

### Ad-hoc YAML, nothing saved (API key preferred)

```bash
ocean workflow run-yaml flow.yaml -i "input text"
```

With a key: executes through https://api.plungeai.com (One API + result
redemption). With only a session it falls back to Studio's execute proxy and
prints the raw engine envelope JSON instead of redeemed markdown. `{input}` in
the YAML receives `-i`. Author the YAML with the `plungeai-workflows` skill;
test with `run-yaml` before `ocean workflow create`.

### One registry agent as a tool (API key)

```bash
ocean agent contract exa-agent                   # discover operations + params
ocean agent run exa-agent "latest Cloudflare Workers news"
ocean agent call exa-agent search --params '{"query":"cloudflare workers"}'
```

### Bounded autonomous mission (API key)

```bash
ocean mission "find the three strongest competitors to X and compare pricing" \
  --max-iter 5 --criteria "table with sources" --sync
```

Without `--sync` the mission dispatches async and the CLI polls every 5s (600s
cap, then exit 1). The waiter declares the run terminal when
completed/failed/cancelled/error appears ANYWHERE in the status text — not just
the `**Status:**` field — so a workflow name containing "failed" or "error"
ends the wait on the first poll and the result is fetched prematurely. Prefer
`--sync` for short missions; keep those words out of goals; for long missions
poll `ocean execution status <id>` yourself and match the `**Status:**` line.

## Results, threads, follow-ups

```bash
ocean execution list -l 10                        # recent runs
ocean execution conversation <id>                 # full thread: input → result → follow-ups
ocean workflow followup <wf-id> "and by region?"  # ask about the last run (-e picks another)
ocean execution continue <id>                     # answer a pending question
ocean execution continue <id> --approve           # approve a pending action
ocean execution export <id> -f docx -o report.docx
ocean execution save-version <id> "pre-edit"      # snapshot; restore-version to roll back
```

Everything in this block except `execution status`/`output` needs the Studio
session — a key-only script cannot list, continue a paused run, follow up, or
export.

## The AI terminal (REPL)

`ocean` (no args) opens the chat REPL — the same harness agent Studio uses.
Plain language works for both **building** ("build a workflow that watches the
market") and **acting on your account** ("show my ten last runs", "export the
last result as docx", "what's on my schedule this week?"). Mutating actions ask
for confirmation; when a decision is yours, the agent asks a structured
question you answer inline.

Type `/help` for the grouped palette. Slash commands mirror the CLI noun
groups:

| Group | Commands |
|---|---|
| Workflow agents | `/flows` `/folders` `/bots` `/show` `/run` `/create` `/save` `/run-yaml` `/refine` `/edit` `/versions` `/restore` `/undo` `/delete` |
| Runs & results | `/runs` `/results` (`/results inline [N]`) `/results agent` `/results folder` `/followup` `/thread` |
| Schedules | `/schedule` `/schedule jobs` `/schedule runs` |
| Platform | `/registry` `/agent` `/mission` `/memory` `/templates` `/learn` `/whoami` `/local` |
| Session & settings | `/help` `/sessions` `/continue` `/export` `/new` `/mode` `/depth` `/details` `/voice` `/doctor` `/exit` |

Legacy names stay as aliases (`/plans` and `/plan-generate` are retired stubs that only print a hint to use `/create` or `/new`): `/agentflows`→`/flows`, `/workflow(s)`→`/flows`,
`/agentfolder`→`/folders`, `/executions`→`/runs`, `/resultbyagent`→`/results agent`,
`/resultbyfolder`→`/results folder`, `/schedulejobs`→`/schedule jobs`,
`/scheduleruns`→`/schedule runs`, `/build`→`/create`, `/tweak`→`/edit`.

REPL behaviors worth knowing:
- `/create [name]` runs Agentic Build on the current Think conversation —
  chat the design first, then `/create Market Monitor`.
- `/save <name>` saves the YAML block from the last AI reply; `/run-yaml`
  executes it ad hoc.
- `/results` opens a fast metadata-only picker (paginated, Esc exits). Plain
  requests like "show me my last five results" open the same local picker with
  no AI round-trip.
- `/mode research|plan|build` and `/depth quick|standard|deep|ultra` persist
  to config; `/details` toggles the SSE tool trace.
- Voice: **Ctrl+T** push-to-talk in the prompt; `/voice` modal mic (Enter to
  stop); `/voice on|off` speaks replies aloud. Recording needs `sox`.
- `/edit` uses an inline terminal YAML editor; Ctrl+E opens `$OCEAN_EDITOR`
  (set it to a terminal editor if `$EDITOR` is a GUI app).
- `/exit` (or Ctrl+C) quits.

### Custom slash commands

Markdown files in `~/.ocean/commands/` become REPL commands (built-in names
can't be shadowed):

```markdown
---
description: Review workflow for missing agents
target: refine        # chat | refine
depth: standard       # quick | standard | deep | ultra
---

Review this workflow for missing error handling and suggest improvements.
Focus on: $ARGUMENTS
```

`$ARGUMENTS` receives everything typed after the command; `$1`, `$2`, …
receive positional words. `target: refine` applies the prompt as a workflow
refine; `target: chat` (default) sends it as a chat turn.

### Command shell (non-AI)

`ocean shell` gives an `ocean›` prompt that runs plain subcommands
(`workflow list`, `execution output <id>`, …) without re-invoking the binary —
handy for exploratory sessions without the AI.

## Scripting and CI patterns

- **Inject the key via env, never argv** — but know that `OCEAN_API_KEY` only
  overrides the config key for the process: any command that saves CLI state
  (`workflow run`/`run --async`, `refine`, `chat`, `ocean run`,
  `observatory run`) writes the merged config back and PERSISTS the env key
  into `~/.ocean/config.json` (0600). On shared or persistent runners use a
  throwaway `HOME` (`export HOME=$(mktemp -d)`) or finish with `ocean logout`;
  `whoami`, `doctor`, `run-yaml`, `agent run`, `memory`, `mission` never save.
- **Kill ANSI color in CI:** with `$CI` set the CLI force-enables color even
  when piped — escape codes break word-boundary greps like `\bcompleted\b`.
  Export `NO_COLOR=1` for anything you parse, or use `--json` (never colored).
- **Force non-interactive output:** pass any flag to `workflow list`
  (`--json`, `--limit`, `--kind`, `--search`); give explicit ids instead of
  relying on pickers; prefer `--json` where offered (`whoami`, `workflow list`,
  `execution status`, `schedule get/create/update`, `workflow run --json`,
  `ocean run "<prompt>" --json`). Caveat: `whoami --json` and key-path
  `execution status --json` wrap platform markdown in a single JSON string
  field — you still parse the markdown inside.
- **Gate on exit codes — with one asymmetry:** exit codes are 0/1 only. Sync
  `workflow run` exits 1 when the run itself errors, but `execution status`/
  `output` of a FAILED run exit 0 (they successfully report the failure) — an
  async CI gate must parse the status value (skeleton below). `ocean doctor`
  is the canonical preflight gate.
- **Destructive confirms:** `workflow delete`/`restore`/`undo` prompt `[y/N]`
  with no `--yes` flag — in scripts pipe `echo y | ocean workflow delete <id>`;
  an EOF answer cancels with exit 0, so the script "succeeds" without deleting.
- **One-shot AI in a script:** `ocean run "summarize this week's runs" --json`
  → `{content, conversationId}`; `-c` continues the same conversation next call.

Async run-and-wait skeleton (bounded, failure-gated, status-FIELD match):

```bash
set -euo pipefail
export NO_COLOR=1
out=$(ocean workflow run "$WORKFLOW_ID" --async -i "$INPUT")
exec_id=$(printf '%s' "$out" | grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|exec-[[:alnum:]-]+' | head -1)
[ -n "$exec_id" ] || { echo "no execution id"; exit 1; }
status=""
for i in $(seq 1 120); do   # 10 min cap
  st=$(ocean execution status "$exec_id" 2>&1 || true)
  status=$(printf '%s' "$st" | grep -oiE 'Status:\*{0,2} *(completed|failed|cancelled|error)|^(completed|failed|cancelled|error)\b' | grep -oiE 'completed|failed|cancelled|error' | head -1 || true)
  [ -n "$status" ] && break
  sleep 5
done
[ "$status" = "completed" ] || { echo "run ended: ${status:-timeout}"; exit 1; }
ocean execution output "$exec_id"
```

Match the status FIELD, never the whole line — the status line embeds the
workflow NAME (Studio path: `<status> <workflow_name>`; MCP path:
`**Workflow:** <name>`), so a flow named "Failed Payments Monitor" would
terminate a whole-line grep on the first poll.

CI preflight:

```bash
ocean doctor || exit 1
ocean whoami --json   # {"whoami":"<markdown>"} — one string field; grep it for the expected user/tier
```

## Rules when driving the CLI as an agent

- Discover ids live (`ocean registry …`, `ocean workflow list`,
  `ocean agent contract <id>`) — never invent agent or workflow ids.
- Relay platform-rendered output verbatim; don't re-summarize `whoami`,
  `memory`, `mission`, or `agent run` results.
- Test YAML with `run-yaml` before saving; expect the save lint to refuse
  `memory_owner:` and to require bots (`--kind bot`) to be exactly one
  `type: harness` task whose mission ends with `task_complete`.
- Update schedules only through `ocean schedule update` (fresh-GET → merge →
  PUT keeps delivery targets intact); `--deliver` on update REPLACES targets.
