For AI agents: a documentation index is available at https://www.plungeai.com/docs/llms.txt. Append .md to any page URL, or send Accept: text/markdown, to get markdown. Setup instructions for agents are at https://www.plungeai.com/docs/agents.md. One ozk_ key opens every plane, models included.

Documentation Index: fetch the complete documentation index at /llms.txt. Use this file to discover all available pages before exploring further.

Ocean pager is oceancode's terminal UI. A plain oceancode execs Ocean pager (ocean-pager); the pager and the Ocean engine run in one process over typed ACP channels — no HTTP between UI and engine. --db, --directory, --listen and --verbose are passed through.

The first-party ratatui TUI was removed on 2026-10-05 (its guide pages are in archive/native-tui/docs/). For compatibility --tui pager and OC_TUI=pager are accepted and change nothing (--tui grok is refused as unknown); --tui ocean and OC_TUI=ocean fail with "the native TUI was removed; oceancode starts Ocean pager". The pager's own slash commands, keys and settings are in Ocean pager reference.

Binary

  1. Build the pager: bash scripts/release/build-pager.sh (or cd ocean-pager && cargo build --release -p ocean-pager-bin --locked) → target/release/ocean-pager, the binary oceancode launches.
  2. A plain debug build lands in target/debug/ocean-pager and is never launched. To run a pager from elsewhere, set OC_PAGER_BIN.

Discovery order: OC_PAGER_BIN → ocean-pager beside oceancode (and beside the binary a symlinked oceancode resolves to) → ocean-pager on PATH.

oceancode sets $OC_PAGER_HOME to <data>/oceancode/pager ($XDG_DATA_HOME, else ~/.local/share) — the directory a bare ocean-pager uses too — so the pager never shares ~/.grok. Auto-update, remote fetch, feedback and voice are off. Every pager variable: Environment.

Environment

Read by ocean-pager, not by the engine. Every pager variable is OC_PAGER_*; the old GROK_* names are not read.

VariableEffect
OC_PAGER_HOMEThe pager's state directory (config.toml, sessions, debug logs, the extracted ripgrep under bin/). oceancode sets it; unset → $XDG_DATA_HOME/oceancode/pager, else ~/.local/share/oceancode/pager. GROK_HOME is ignored.
OC_PAGER_LOG_FILEWrite the pager's debug log to exactly this path (honors RUST_LOG).
OC_PAGER_DEBUG_LOGA path, or 1/true for <pager home>/debug/tui-<pid>.txt: turns the debug log on.
OC_PAGER_CONFIGInline JSON config overlay, merged above config.toml.
OC_PAGER_CONFIG_PATHAn extra JSON or TOML config-overlay file (read by extension), merged above config.toml.
OC_PAGER_MANAGED_CONFIG_FAIL_CLOSEDOverrides the requirements fail-closed setting (applies to requirements.toml only).
OC_PAGER_SHELLShell the pager spawns: an executable path (bash, zsh, …); on Windows pwsh, powershell or cmd.
OC_PAGER_THEMEForce a theme name, or auto, without editing the config.
LC_OC_PAGER_THEMESame as OC_PAGER_THEME; the LC_ form survives SSH SendEnv LC_*.
OC_PAGER_APPEARANCEdark or light: the terminal background auto themes assume.
LC_OC_PAGER_APPEARANCESame as OC_PAGER_APPEARANCE, SSH-forwardable.
OC_PAGER_TERMINAL_THEMEFollow the terminal's own palette (on/off; a requirement pin wins).
OC_PAGER_NERD_FONTSNerd Font glyphs in the git status (on/off).
OC_PAGER_FORCE_LEGACY_CONSOLEWindows: ASCII-safe glyphs for the legacy console.
OC_PAGER_SCREEN_MODEInternal: the screen mode a /fullscreen / /minimal relaunch hands to the new process (read and removed at startup).
OC_PAGER_SCREEN_MODE_SWITCHexec forces the legacy re-exec switch between screen modes.
OC_PAGER_SCROLL_SPEEDMouse-wheel scroll speed; applied on first load only (the settings modal persists it).
OC_PAGER_SCROLL_MODEMouse-wheel scroll mode; first load only.
OC_PAGER_SCROLL_LINESLines per wheel notch; first load only.
OC_PAGER_INVERT_SCROLLInvert the wheel direction; first load only.
OC_PAGER_SCROLL_CADENCE_MSRedraw cadence while scrolling (ms).
OC_PAGER_MIN_DRAW_MSMinimum interval between frames (ms).
OC_PAGER_DISPLAY_REFRESH_PROBE_ENABLEDProbe the display refresh rate at startup (on/off).
OC_PAGER_DISPLAY_REFRESH_AUTO_CADENCEDerive the draw cadence from the probed refresh rate (on/off).
OC_PAGER_SCROLL_DEBUGShow the scroll debug HUD.
OC_PAGER_SCROLL_LOGLog scroll input events (unset or 0 = off).
OC_PAGER_FPSShow the frames-per-second HUD.
OC_PAGER_MEMTRACEPeriodic memory trace in the debug log; 0/false/off disables.
OC_PAGER_MEMTRACE_INTERVAL_SECSMemory-trace interval (seconds).
OC_PAGER_MEMTRACE_THRESHOLD_MBMemory trace logs only above this resident size (MB).
OC_PAGER_MOUSE_REPORTING_TOGGLEEnable the mouse-reporting toggle (on/off).
OC_PAGER_SHOW_THINKING_BLOCKSShow model thinking blocks (on/off; overrides the setting).
OC_PAGER_GROUP_TOOL_VERBSGroup consecutive tool calls by verb (on/off; overrides the setting).
OC_PAGER_SHOW_EDIT_DETAILSShow each edit's diff inline (on/off; overrides [ui] show_edit_details).
OC_PAGER_SHOW_RUN_DETAILSFinished agent Runs show the command and first output lines (on/off; overrides [ui] show_run_details).
OC_PAGER_COLLAPSED_EDIT_BLOCKSLegacy: start edit blocks collapsed (on/off); read only when show_edit_details is unset everywhere, as its inverse.
OC_PAGER_CONTEXTUAL_HINTSContextual hints on/off (overrides [ui.contextual_hints]).
OC_PAGER_TIPS_OVERRIDEDebug builds only: `
OC_PAGER_SLASH_COMMAND_TAGSJSON map of tags shown beside slash commands in the / menu.
OC_PAGER_DEFAULT_SELECTED_PERMISSIONWhich permission-card option the cursor starts on.
OC_PAGER_ESC_DOUBLE_PRESS_MSWindow for the double-Esc gesture (ms).
OC_PAGER_DOCKThe dock above the prompt on/off; on by default (0 brings back the Tasks pane at the top; a requirement pin wins, [features] dock in the pager config comes after).
OC_PAGER_DOCK_V2Same switch as OC_PAGER_DOCK, read after it.
OC_PAGER_AGENT_DASHBOARD0 turns /dashboard off.
OC_PAGER_WORKSPACE_DASHBOARDUse the workspace (v2) dashboard layout instead of the persisted v1 layout.
OC_PAGER_SESSION_PICKER_GROUPED1/0: group the session picker (overrides [cli] session_picker_grouped, default on).
OC_PAGER_HUNK_TRACKERHunk-tracker mode (overrides [ui] hunk_tracker_mode).
OC_PAGER_SUGGESTIONSShell-command ghost suggestions (off by default). They request ocean/suggest, which the Ocean engine does not serve, so nothing shows.
OC_PAGER_SUGGESTIONS_AIAI variant of OC_PAGER_SUGGESTIONS (same limitation).
OC_PAGER_SUGGESTIONS_AI_MODELModel id for OC_PAGER_SUGGESTIONS_AI.
OC_PAGER_MCP_PUSH_SERVER_STATUSPush MCP server status updates into the UI (default on).
OC_PAGER_ENVRC_TIMEOUT_SECSTimeout for evaluating a directory's .envrc (seconds; 0 disables).
OC_PAGER_CONNECT_UI_TIMEOUT_SECSSeconds before startup shows the connect-failure report (6 s floor).
OC_PAGER_PROMPT_ACK_TIMEOUT_SECSPrompt acknowledgement timeout (seconds).
OC_PAGER_EXIT_TIMEOUT_SECSForce-exit this many seconds after a quit if teardown hangs (default 20; 0 disables).
OC_PAGER_COPY_FILEBackup file every copy is also written to (default <pager home>/last-copy.txt).
OC_PAGER_OSC52_SINKEmit clipboard writes as OSC 52 for a wrapping terminal.
LC_OC_PAGER_OSC52_SINKSame as OC_PAGER_OSC52_SINK, SSH-forwardable.
OC_PAGER_CLIPBOARD_NO_OSC52Never emit OSC 52 (for hosts that paint it as garbage).
OC_PAGER_CLIPBOARD_NO_NATIVE_READmacOS: don't read the native pasteboard.
OC_PAGER_CLIPBOARD_NO_DATA_CONTROLLinux: skip the Wayland data-control clipboard protocol.
OC_PAGER_SQLITE_JOURNAL_MODESQLite journal mode for the pager's local databases (the WAL kill switch).
OC_PAGER_RESET_CHILD_OOMLinux, internal: set on child processes so they reset the inherited OOM score.
OC_PAGER_EVENTSet for notification hook commands: the event name.
OC_PAGER_MESSAGESet for notification hook commands: the message text.
OC_PAGER_SESSION_IDSet for notification hook commands: the session id.
OC_PAGER_BUNDLE_RG_PATHBuild time: embed this ripgrep binary instead of downloading the release tarball.
OC_PAGER_RG_VERBuild-internal: embedded ripgrep version, set by ocean-pager-ripgrep/build.rs.
OC_PAGER_RG_TARGETBuild-internal: embedded ripgrep target triple.
OC_PAGER_RG_SHA256Build-internal: SHA-256 the extracted ripgrep is verified against.
OC_PAGER_CHANGELOG_OFFLINETests: never fetch the changelog.
OC_PAGER_MDM_NO_EXPAND_TESTTests: macOS managed-preferences layer.
OC_PAGER_TEST_OPEN_URL_FILETests: write opened URLs to this file instead of launching a browser.
OC_PAGER_TEST_FRAME_WRITE_DELAY_MSTests: delay each frame write (ms).
OC_PAGER_TEST_HOLD_TEARDOWN_SECSTests: hold teardown to exercise the exit timeout.

What is wired to the Ocean engine

/, /mcps, /skills, /plugins, /hooks, /workflows, /model, and /effort use the pager chrome and Ocean Services. MCP add/toggle, plugin enable/disable, hook reload, and tool permission cards go through the same ACP methods Grok Build uses. The /workflows picker lists built-in and discovered project/user workflows over ocean/workflows/list (empty when the workflows section is disabled); launching, pausing, resuming and stopping a run go through the workflow tool, not an ext request.

Skills complete in the composer. Typing / and a prefix lists your enabled, user-invocable skills alongside the pager's own commands — a plugin skill under Claude Code's plugin-qualified name (/superpowers:writing-plans, so /super finds every superpowers skill), a project or user skill under its bare name (/formatcode); the prefix narrows the list, Tab/Enter inserts /<skill> into the message box so you can keep typing, and sending dispatches it — the engine expands the skill body into the turn (a typed bare /writing-plans still runs the plugin skill too). The candidates come from ocean/skills/list (fetched at session start; the Ocean engine does not advertise skills as ACP commands), so a disabled skill is never offered. A Space toggle on the Skills tab of the capabilities picker updates the popup live, and the <available_skills> block and skill_* tools shrink on the next step (09 · Capabilities).

The capabilities picker. Each tab (/skills, /plugins, /hooks, /mcps, /workflows, Marketplace) lists only its own kind. On the Skills tab, Space toggles the skill under the cursor and the change sticks (it writes ~/.oceancode/skill-state.json); / opens a search that filters the rows by the skill's name, its slash id, its description and its author, case-insensitively, and a query that matches nothing reads No matches. a / d enable / disable every skill behind a confirm prompt. Each row shows its source — project, user or plugin: <name> — grouped by source.

Group and master toggles. On the Skills, Plugins, Hooks and MCP tabs Space also works above the single row; every change applies on the next step and costs one cache rewrite (09 · Capabilities):

Row / keyAction
Everything (first row) + SpaceMaster switch: off removes skills, MCP tools, hooks and plugin rules from the agent's context, built-in tools stay; asks first
All skills / All plugins / All MCP / All hooks (second row) + SpaceThe whole kind on or off; asks first
a / d (Skills tab)Same as All skills on / off
A Plugin: <name> header (Skills, MCP) or a hook source header + SpaceEvery row in the group; asks first above 10 rows; an all-off group reads [off]
A row + SpaceThat one skill, plugin, hook or MCP server

The picker's last row shows the live counts (skills 22/259 · plugins 2/21 · mcp 1/10 · hooks 8/8 · applies on the next step (one cache rewrite)), prefixed EVERYTHING OFF while the master switch is off. The Plugins tab also lists Claude Code's cached plugins under User (Claude). The Marketplace tab reads ~/.oceancode/marketplaces/** only when you open it (opening /skills or /plugins no longer touches the marketplace), and marketplace content never reaches the prompt or the tool list.

Pasted images

Paste an image from the clipboard (Ctrl+V / Cmd+V) or drag an image file onto the composer; it shows as [Image #1] in your text and goes to the model with the prompt ("what's wrong with this layout? [Image #1]"). Every route carries it — Anthropic, OpenAI chat and Responses (xAI, Groq, OpenRouter, …), Gemini. With several images, each is labelled [Image #N] in the request, so the model matches the name in your text to the right picture.

Limits: at most 20 images per prompt, 3.75 MiB per image once stored (about 5 MB once base64-encoded, the strictest limit of the routes), and 8000 px on either side (Anthropic refuses a larger image before the model runs; sips -Z 2576 <file> brings it under). The engine sends PNG, JPEG, GIF and WebP — the types every route accepts, decided by the image's bytes, not its declared type. The pager re-encodes a TIFF (what a macOS screenshot usually is on the clipboard), BMP, ICO or GIF as PNG before it sends, so those paste and drag in like any other; PNG, JPEG and WebP go as they are. An image over the limits after that, a type the pager cannot decode, or an http(s) source refuses the whole prompt with a message naming the image; nothing is dropped silently.

Dragging from another app. In Ocean AI Terminal a file dragged in from Photos or Finder becomes a chip the same way, and since desktop build 0.8.11 the drop also brings the terminal window to the front: macOS does not activate the window a drag lands on, so with an older build the keys you type next, Enter included, still go to the app the image came from until you click the terminal once.

Resizing. Images are resized so they never make a session fail (the same rules apply to images the read tool returns):

  • An image over 2576 px on its long edge (the most a current Claude model reads; larger is downscaled by the provider anyway) is shrunk to 2576 px when it is pasted or read. The resize is Lanczos3 with the aspect ratio kept; PNG stays PNG and JPEG stays JPEG, GIF and WebP become PNG.
  • When one request carries more than 20 images, Anthropic applies a stricter size limit to every image in it, so any image over 2000 px is sent as a 2000 px copy. The stored session is not changed.
  • If the provider still refuses an image for its size, the engine retries once with every image at or under the limit the provider named, and keeps that limit for the rest of the session.
  • Past 100 images or 24 MiB of image data in one request, the oldest images are replaced by a one-line note ([<name>, <W>x<H> omitted from this request: …; read the file again to see it]).

Text-only models. When the catalog says the current model reads no images (its models.dev entry lists input modalities without image), the text still goes and the image does not; a session note says so: Image #1 not sent: <model> doesn't accept images. A model the catalog cannot describe — an offline seed entry or one you declared under providers.*.models — gets the image. Switching to a text-only model after pasting drops the media from the request on the next turn — and an image a tool returns (read on a PNG) is replaced by a one-line note on such a model — so the provider does not answer 400.

The image is stored inline on the user row of oceancode.db ("files":[{"uri":"data:image/png;base64,…); a reopened session replays that row as text only, and the headless and server prompt bodies (07 · Headless and server) carry text only for now.

The dock: sub-agents above the prompt

Running sub-agents, background commands, monitors, loops and queued prompts live in one dock directly above the prompt, one section each (Agents, Tasks, Watchers, Queued). While a turn runs, its status rides the dock's first header instead of taking a row of its own:

▾ Agents 2  ⸬ Working 2m31s                                     1m20s ⇣12k [stop]
 ⸬ Find every caller of resolveWorkflowAccess — Running: rg -n …   1m15s silent · 4 tools · 38k tok · 2m13s
 ✓ Map the picker code paths                                       9 tools · 52k tok · 48s

A sub-agent row is the task's description, led by a badge only when the mission gave the sub-agent a persona or role (Researcher), then its live activity; the right column shows its tool calls, tokens and elapsed time, plus Ns silent once it has sent nothing for 10 s — amber from a minute, the one to open. The dock counts the agents, so the Ocean bar does not. Ctrl+G hides and shows the dock; a section folds on Enter or a click on its header, show N more opens a long one, ↗ opens a row and [stop] stops it. One blank row separates the transcript from what sits under it; nothing else is spaced.

The transcript keeps a record: Subagent running: "…" when a sub-agent starts and Subagent completed in 48s: "…" · 52k tok · 9 tools when it ends; the running line does not repeat the dock's live figures. OC_PAGER_DOCK=0 (or [features] dock = false) brings back the Tasks pane at the top, the live figures on the transcript row and the agents N count in the bar.

Under a work mode with an at-once limit (23), a sub-agent that must wait for a free slot gets a dock row of its own with a hollow glyph, waiting (4/4 running), which turns into its running row when a slot frees (or closes if the turn is stopped first). Model, the default, has no such limit, so this row never appears there.

The work-mode picker (F4)

F4 or /mode opens the work-mode picker: who decides how agents work together — the model (Model, the default), Jev (Auto), or you (seven diagrams). The list sits on the left and the highlighted mode's picture on the right; moving the cursor redraws it at once. Enter uses the mode for this session, d makes it the current agent's default, e copies a built-in into .oceancode/modes/ to edit, Esc closes. /mode <id> and /mode default do the same without the picker. Every mode but Model shows its badge on the prompt's top border, after the ultracode badge when that is on (delegate ≤4, race ×3, auto → goal · Jev 0.82); Model shows none, so the border is unchanged. F2 › Agent defaults holds a mode row per ring agent, and F2 › Sub-agents the three sub-agent limits (22). The modes, limits and requirements are on 23 · Work modes.

Watching a sub-agent

Open a sub-agent with a double-click or Enter on its dock row (↗), its transcript row or its Agent Dashboard row: the view fills with what the sub-agent does as it does it — its bash commands and their output, reads, greps, edits with their diff, and its text and thinking — with its own context bar. q or Esc closes it.

The engine streams a running sub-agent's activity live under the sub-agent's own session id, while the parent's turn runs and afterwards for a background sub-agent. A finished sub-agent whose view holds nothing yet — or whose view was freed after you closed it — is rebuilt from oceancode.db when you open it (ocean/session/replay). Sub-agents of a session you resumed, or of an earlier pager run, do not open yet.

Goal mode (orchestrate: always)

Set orchestrate: "always" in the workflows section of oceancode.json and a plain prompt is no longer a single turn — it launches the built-in goal workflow, which plans the objective into verifiable deliverables, works in rounds with one resumed worker, and converges only when a panel of adversarial skeptics fails to refute completion (identical gaps two rounds running, or a spent budget, pause instead of looping). The pager's Workflows dock shows the run advancing through its Plan → Work → Verify phases, with the sub-agents of each round beneath it. The Claude-settings ultracode flag does not turn this on — only the explicit orchestrate opt-in does. Headless, the same goal run is oceancode goal "<objective>" (see 07-headless-and-server.md). Since work modes, orchestrate: "always" with no mode set is read as the Goal work mode (23).

What the pager does not do

Login, billing, worktrees, /imagine and Grok memory flush are unsupported (-32601).

Connecting a provider is in the pager: pick a gray /model row, or /connect <provider>. OpenCode-style auth methods:

  • API key — most providers (Google, Groq, Perplexity, …).
  • ChatGPT Plus/Pro — OpenAI, via OpenCode’s JSON deviceauth (auth.openai.com/codex/device), or paste an API key.
  • Claude Pro/Max — Anthropic PKCE (paste the browser code), or paste an API key.
  • GitHub Copilot — GitHub device flow (github.com/login/device).
  • claude-code — oceancode claude (Claude CLI login).
  • Bedrock / Vertex — environment/config, not a prompt.

Already-connected providers open a manage overlay: switch API key ↔ subscription, or d to disconnect (removes auth.json; env-backed providers stay connected until the env var is unset). Credentials go to the same auth.json as oceancode key / oceancode login.

Expired subscription

Ocean runs on the Claude subscription by consuming the active slot Claude Code keeps in ~/.claude/.credentials.json (claudeAiOauth); it never rotates that slot's refresh token. On macOS, once that file's token is within five minutes of expiry, Ocean also reads the Keychain item Claude Code refreshes itself into (Claude Code-credentials, read only) and uses whichever carries the later expiry, so a self-refresh by Claude Code no longer strands Ocean an hour later; no file still means no login. When the slot's access token has expired and carries no refresh token, a prompt cannot be sent, and the turn fails in the transcript with a terminal, actionable message — Claude subscription token has expired: Run oceancode login to reconnect your Claude account. — and no retry countdown or network banner (the failure is not a transport error and is never retried). Run oceancode login, complete the Claude Pro/Max browser flow, and send the prompt again. (Headless, oceancode run prints the same message to stderr and exits non-zero.)

The same holds when the slot expires mid-session: it was valid when the turn started, so the request reached Anthropic and the server rejected the now-dead token with an HTTP 401. On the subscription route that 401 (and a 403) is the same terminal run oceancode login failure — it is never retried — whereas a 401 on an API-key provider stays a generic error (its fix is a new key, not a re-login).

Coming from the native TUI (removed 2026-10-05)

The pager renames some surfaces of the removed native TUI and has no ctrl+x leader — it uses direct chords. The pager equivalents:

Native TUIOcean pagerNotes
/copy/toggle-mouse-reportingToggle terminal mouse capture so text selection/copy works.
/mcp/mcpsThe MCP-servers picker.
/models/modelThe model picker (also gates provider /connect).
/cockpitstatus bar + /contextNo unified cockpit panel; the status bar plus /context show the same figures.
ctrl+x leader chordsdirect chordsThe pager has no ctrl+x prefix. Use ctrl+p (command palette), ctrl+\ (Agent Dashboard), ctrl+t (todos pane), ctrl+m (multiline / model picker off the prompt).

Shift+Tab ring and permission modes

Shift+Tab cycles Build → Auto → Plan → Ask → Debug → Build. Build, Plan, Ask and Debug are the engine's agents (the curated ring in crates/ocean-acp/src/modes.rs); Auto is the one permission stop, Claude Code's "accept edits": the agent stays Build, the prompt border shows auto in yellow, and the engine's permission mode is acceptEdits — edits run without a card, bash and outside-directory asks still prompt (or go to Jev, see 13), and the question tool always asks. Cycling on from Auto drops back to ask before the switch to Plan. The stop is absent while always-approve is on, and when the auto feature is gated off ([auto_mode] enabled = false in the pager config).

The same mode is reachable from /auto, /always-approve (ctrl+o; the engine's bypassPermissions, every card auto-answered by the pager) and the permission_mode row of the settings modal. Each change is persisted to the pager config and sent to the engine as ocean/yolo_mode_changed, so the engine's mode and the border flag agree (see 12 · Permissions and sandbox). A subagent's ask surfaces as its own card, labelled with the subagent.

The agent is the bold flag on the prompt's bottom border (Build blue, Plan violet, Ask green, Debug orange); the permission mode follows it (auto yellow, always-approve red). The Plan agent is plan mode, so it shows once, as Plan; plan approval and commenting L3 appear beside it while a plan is under review.

Each agent can carry a default model and effort (agents.<id>.{model,effort} in oceancode.json, edited under F2 › Agent defaults): Shift+Tab to that agent puts the session on them, the effort clamped to the levels the model offers, and status-bar row 1 follows. Option+Tab (or F3, for terminals that don't send Option as Meta) steps the session's effort up through the current model's levels, wrapping to the lowest, and prints the same "Switched to …" line as /effort. That change lasts for the session: the next Shift+Tab loads the agent's own default again. An agent with no defaults keeps the session's model and effort.

A settings push reaches an open session live — a fleet-router Apply, an F2 edit, or a hand edit of oceancode.json or ~/.claude/settings.json. The pager shows one toast naming what moved, for example Settings applied: sub-agents effort medium · build effort max, and status-bar row 1 shows the new values. The values it names are the main model and effort, ultracode, the sub-agent model and effort, FORCE, and each agent's model and effort. When the push changes the row of the session's current agent and the session still runs that row's old value, the session moves to the new one. A Mesh › Main change moves a session on the previous Main model unless its agent has a row of its own: the row wins (today that leaves Debug, which has no row). A model or effort you changed by hand in this session (/model, Option+Tab) is kept.

Question cards

When the agent asks with the question tool, a card replaces the composer: ↑/↓ walk the answers, Enter picks one (or starts typing on the last row, where you answer in your own words — that text reaches the model as written), ←/→ move between questions.

  • Ctrl+B back to chat leaves the question to give the agent more first — notes, pasted images, links. The turn stops, the answers you had picked land in the composer as My answers so far:, and the agent is told you stopped to add context; send your message and it thinks again and asks only what is still open.
  • Esc steps back (out of the text row, then clears a pick); X dismisses the card without answering; Ctrl+C cancels the turn and the open question with it. A second Ctrl+C while the turn is still cancelling arms quit, and a third quits.

Resuming: the session tree

/resume (and the home screen's list) shows your main sessions only, most recently active first. A session that spawned sub-agents carries a fold glyph and says how many in the right column — › Pager fixes 3 sub · 5m ago — and the sub-sessions stay out of the way until you open it:

  • → (or e) on a parent row opens it: its sub-sessions are fetched the first time and drawn indented underneath; a sub-session that spawned its own folds the same way, as deep as the work went. On a row with nothing to open, → shows the detail card as before.
  • ← closes the detail card if it is open, then folds the sub-sessions away, then moves the selection up to the row's parent.
  • Typing searches titles on the engine, across main sessions and sub-sessions alike. A hit is drawn under its main session, with the rows between them dimmed when they did not match, so you can tell which run it belongs to. Clearing the search brings the folded list back.
  • A row badged open is already running in another pager window on this machine; open it there instead of resuming it twice.
  • Enter resumes whichever row is selected, a sub-session included.

The engine names a session after the first prompt that says something — Hi, Yeah, Do it, Continue, [Image #1] and the like name it only until a real request arrives, so a list of greetings does not happen. /rename still wins over any automatic title.

Search counter and tideline tiers

The top-right status row shows a search N · 0.3s chip once the session has run a grep or glob tool call: N is the number of calls, the time is the last call's latency (green ≤ 1 s, yellow ≤ 5 s, orange above). Click it for the breakdown — calls by tool, last / average / total latency, bytes and files scanned, and how many recursive grep -r / find the model ran through bash (and how many of those were rewritten to rg). The figures are folded from each tool result's metadata (elapsed_ms, files, bytes, search_redirect) in oceancode.db, so they survive a restart; nothing is counted in memory.

The Ocean context row (ctx … N% full · tideline …) is tiered against the tideline limit: green under 80 % of it, yellow from 80 %, orange at or over it (the gauge, the percentage and the tideline clause share the tone). With the ledger off the same tiers apply against the context window. tideline ×12 @30% … carries the number of turns past the tideline (/tideline prints the same figure); no ×N while it is zero.

The bash tool rewrites a plain recursive grep -r … to the bundled ripgrep (POSIX shells; every flag must have an rg equivalent, patterns are literal-safe) and prepends [oceancode] ran as: rg … to the result; any other recursive grep or a find … -name runs as typed under a one-line hint naming the grep / glob tools. A leading cd <dir> &&/; prefix, a trailing 2>/dev/null, | grep -v … / | head followers, and BRE \| alternation are carried or translated verbatim, so the common slow pipelines still rewrite. The ripgrep directory leads the child PATH, so rg is available in bash on every OS where a binary resolves (OC_RG_BIN overrides; see 02).

Ocean session commands

These act on the Ocean engine over _ocean/* / ocean/* ext methods (Ocean backend only):

CommandWhat it does
/tidelineBare shows the ledger state; /tideline now cuts the ledger; <n>%, <tokens>, or default set the tideline (the floor and the presets were removed — a second number or a preset word is refused with the usage line). The old /shelve still works as a hidden alias.
/retentionBare shows how long idle sessions are kept and what the next sweep would delete (retention 7 days · 12 sessions pending · first sweep after <date> (grace), or … · last sweep 5m ago, 340 swept); <days> sets retention.days in the global config and re-arms the sweep at once; off is 0 (keep everything). An out-of-range number is refused with the engine's message. While sessions wait out the 24-hour grace window the context row shows retention N pending and one notice is toasted. See 18 · Operations.
/budgetBare shows the spend cap; $5 (or 5) caps USD, off clears it, subscription switches to list-price mode.
/limitsBare shows the per-turn bounds; steps <n> caps steps, time <90m|1h30m> bounds wall-clock.
/subagentBare reports the effective sub-agent model + source; <provider/model> pins one, default / off / clear removes the override.
/modeBare opens the work-mode picker (as F4); <id> sets this session's work mode; default clears it, so the agent's or the config's mode applies again. Answered with a toast, Mode: <label>. See 23.
/plan add|done|cancel|edit|removeEdit the live todo table (1-based rows); bare /plan still enters plan mode.
/redoRe-apply the turn a /undo (/rewind) reverted, and the files it put back.
/shareShare this session via a public URL (Ocean backend).
/unshareRevoke the current session's share link.
/notifyToggle desktop notifications; /notify on|off sets it explicitly.

Planned: TI-34

The docs assistant is not available yet. You can hand these docs to your own assistant instead.