Structured View Setup
How to confirm prerequisites, choose the structured view or terminal view per session, and drive it from a remote daemon or the command line. For what the structured view is and which agents it supports, see the Structured view overview.
Requirements
- aoe built with
--features serve(the structured view ships alongside the web dashboard). - Node.js 20 or newer on
PATH. The structured view spawns an ACP agent subprocess; for the bundledaoe-agentruntime it uses Vercel AI SDK 6, which requires Node 20+. - For Claude Code via the official ACP adapter, you also need a
claude loginsession.
If Node.js is missing or too old, the structured view refuses to start and a session for that agent falls back to the terminal view with an actionable warning pointing at the install path for your OS.
Verify
aoe acp doctor
Sample output on a machine where Claude is installed but the others aren’t:
ACP doctor
==========
The structured view is the ACP-based structured rendering. It is the default
in the web dashboard; `aoe add` and the TUI default to the terminal view.
Pass --structured-view or --agent to opt a CLI session in (or flip a session
from the session view).
[OK] Node runtime v22.21.0
path: /opt/homebrew/bin/node
Configured agents:
[!! ] aoe-agent (aoe's bundled multi-provider agent (Vercel AI SDK 6))
[OK] claude (Anthropic Claude via the official ACP adapter …)
[OK] claude-code (Alias for `claude` (legacy name))
[!! ] codex (OpenAI Codex CLI via Zed adapter …)
install: npm install -g @zed-industries/codex-acp
[!! ] gemini (Google Gemini CLI; native ACP via `gemini --acp`)
install: npm install -g @google/gemini-cli (then `gemini --acp`)
[!! ] opencode (OpenCode (SST); native ACP via `opencode acp`)
install: curl -fsSL https://opencode.ai/install | bash (then `opencode acp`)
[!! ] pi (Pi coding agent (`pi`) via the pi-acp adapter …)
install: npm install -g pi-acp (also requires `npm install -g @earendil-works/pi-coding-agent`)
[!! ] vibe (Mistral Vibe; native ACP via the bundled `vibe-acp` binary)
install: follow https://github.com/mistralai/mistral-vibe (ships the `vibe-acp` binary)
Overall: partial
aoe acp doctor --fix will npm install -g the npm-distributed
adapters (claude / codex / pi). The native CLIs (opencode / gemini /
vibe) you install through their own channels.
If Node is missing the report exits 1; if some agents are unreachable
it exits 2; otherwise 0. Pass --json for machine-readable output.
Choosing the view
Per session
From the web wizard (primary)
The web new-session wizard shows a per-session Use structured view toggle,
on by default for ACP-capable agents. Open aoe serve, click New
session, pick the agent, leave the toggle on, and create. No CLI
required. Tools without a verified ACP adapter (and custom agents without
agent_acp_cmd) have no toggle and run in the terminal view.
From the CLI (optional)
Unlike the web wizard, aoe add defaults to the terminal view, matching
the TUI. Opt into the structured view per session with --structured-view,
or by naming a specific ACP agent with --agent (which implies it):
# Terminal/PTY view (the default).
aoe add . --cmd claude
# Structured view for an ACP-capable tool.
aoe add . --cmd claude --structured-view
# Pick a specific ACP agent + model (implies the structured view).
aoe add . --agent aoe-agent --model gpt-5
aoe add . --agent aoe-agent --model llama3.3:ollama
aoe add . --agent gemini
If you pass --agent for an agent whose adapter isn’t installed, aoe add
errors with an install hint; with --structured-view (no --agent), a
missing adapter falls back to the terminal view with a warning so the
command still succeeds.
Launch command and session name
--cmd <tool> resolves through session.agent_command_override for
structured-view sessions, the same as for terminal sessions. With
[session.agent_command_override]
opencode = "opencode-plannotator"
aoe add . --cmd opencode launches opencode-plannotator,
not the bare opencode binary; the override’s binary replaces the
registry command and the agent’s required ACP args are preserved (so
opencode acp becomes opencode-plannotator acp). The override is
applied only to a built-in agent whose registry binary matches the
tool’s own binary; adapter-backed agents such as Claude keep using
session.agent_acp_cmd for a full command swap.
The web new-session wizard shows the resolved launch command read-only so you can confirm it before the session starts.
Session naming differs by entry point. By default aoe add does not
prompt for a name: it uses --title when given, otherwise the worktree
branch name, otherwise a generated name. Pass -i/--interactive to get
the same name prompt the TUI n flow and the web new-session wizard
provide; it shows the generated default and pressing Enter accepts it.
--interactive requires a terminal and is ignored when --title is
given, so scripted and non-interactive aoe add calls keep auto-naming.
To name a session non-interactively, pass --title "<name>".
For web-created structured-view sessions, configure per-agent defaults under
[session.acp_defaults.<agent>] so the dashboard starts that agent with
the desired model and, when the adapter advertises it, reasoning effort:
[session.acp_defaults.opencode]
model = "openai/gpt-5.5"
effort = "high"
Global configuration
The structured view’s tuning knobs live in config.toml under [acp]:
[acp]
default_agent = "aoe-agent"
approval_timeout_secs = 300
destructive_require_double_confirm = true
max_concurrent_workers = 5
max_concurrent_resumes = 4 # cap on parallel cold-start spawns/attaches (#1088)
replay_events = 0 # 0 = unlimited history; set a positive value to cap per-session rows (also caps the web client's in-memory activity buffer, #1111)
replay_bytes = 5_242_880
node_path = ""
show_tool_durations = true # per-tool elapsed-time label in the web UI
queue_drain_mode = "combined" # how the composer drains client-side queued prompts: "combined" | "serial" (#1031)
force_end_turn_threshold_secs = 30 # seconds of streaming silence before the spinner offers a "Force end turn" button (#1100)
silent_orphan_grace_secs = 120 # daemon-side watchdog grace when the adapter stops talking with no in-flight tool; 0 disables (#1240)
silent_orphan_fast_grace_secs = 20 # accelerated grace used once a cost-populated UsageUpdate has arrived for the current prompt (#1240)
auto_stop_idle_secs = 0 # auto-stop agent workers idle this many seconds; 0 disables (default); the next prompt respawns the worker (#1689)
max_concurrent_resumes bounds how many agent workers the reconciler
spawns/attaches in parallel on aoe serve cold start. Default 4 keeps
Node.js bootup memory bounded for laptops/Pis; raise on beefier hosts.
Clamped at runtime by min(this, max_concurrent_workers).max(1). The
supervisor’s per-agent install gate serialises only the first spawn of
each agent per daemon lifetime, so the claude-agent-acp lazy-install
race is safe even at high parallelism (#1088).
auto_stop_idle_secs reclaims resources from abandoned sessions. When
set to a positive value, the daemon stops any agent worker that has
seen no events and has no in-flight turn for that many seconds, freeing
its claude-agent-acp subprocess. The stop is seamless: the session keeps
its place in the sidebar, the timeline shows a Stopped event with
reason idle_auto_stop, and the next prompt you send respawns a fresh
worker (resuming the agent-side transcript) within a couple of seconds.
A mid-turn worker is never stopped. The check runs about once a minute,
so the effective stop can lag the threshold by up to a minute. Default
0 disables the feature. This covers agent workers only; plain
TUI/tmux sessions are not affected (#1689).
AOE_ACP_NODE=/path/to/node overrides Node discovery for one process
(useful when the host’s PATH-side Node is the wrong version and you can’t
change PATH).
Upgraders: migration v005 seeded the old
[cockpit]section and v006 flipped itsreplay_eventsto unlimited. Migration v012 renames the section to[acp](dropping the retired master switch anddefault_for_claudekeys) and migrates per-session state, so an upgraded config lands on[acp]automatically.
Choosing terminal vs structured
Which view a new session gets depends on where you start it:
- Web wizard: defaults to the structured view; leave the Use structured view toggle off to get the terminal view.
- CLI (
aoe add) and the TUI: default to the terminal view. From the CLI, opt into the structured view with--structured-viewor--agent. - Either way, you can switch an existing session from the session view at any time (the agent restarts in a fresh pane; open files and worktree state are preserved).
Non-ACP tools always run in the terminal view, with no toggle.
Cross-machine attach
Set AOE_DAEMON_URL (and optionally AOE_DAEMON_TOKEN) to point at
a remote aoe serve daemon, then either:
# Browse the remote daemon's structured-view sessions and pick one.
AOE_DAEMON_URL=https://aoe.example.com AOE_DAEMON_TOKEN=… aoe
# Or jump straight into a known session id.
aoe acp attach <session_id> --daemon-url https://aoe.example.com
When AOE_DAEMON_URL is set, the TUI swaps the local home view for
a remote agent-session picker. Local-only operations (tmux attach,
aoe stop, file edit) aren’t available against a remote; for
those, use the web dashboard or SSH into the host machine.
The env override also retargets aoe serve --status and the
aoe acp * verbs: with AOE_DAEMON_URL set, --status pings
the remote endpoint and reports its reachability instead of inspecting
the local serve.pid file. Unset the variable (or run env -u AOE_DAEMON_URL aoe serve --status) to fall back to local introspection.
Headless CLI verbs
For scripting and quick checks, every structured-view operation has a
matching aoe acp <verb> that talks to the same daemon:
| Verb | What it does |
|---|---|
aoe acp history <id> | Dump the persisted transcript |
aoe acp status <id> | Print highest/lowest seq and the daemon source |
aoe acp prompt <id> <text> | Send a prompt (- reads from stdin) |
aoe acp approve <id> <nonce> [--always|--deny] | Resolve a pending approval |
aoe acp cancel <id> | Cancel the in-flight prompt |
aoe acp tail <id> | Stream broadcast frames to stdout as JSON lines |
aoe acp attach <id> | Open the TUI structured view directly for this session id |
Every verb (including attach) requires an aoe serve daemon to be
already running, and exits with an actionable hint if none is found.
Start one with aoe serve --daemon (localhost) or
aoe serve --daemon --remote (Tailscale/Cloudflare), or set
AOE_DAEMON_URL to attach to a remote daemon. The CLI deliberately
does not spawn a daemon on your behalf so the localhost-vs-tunnel
choice stays explicit.
CLI reference
aoe acp doctor [--json] [--fix]
aoe acp agents
aoe acp ps [--json]
aoe acp stop <session> # graceful: SIGTERM the runner
aoe acp stop --all
aoe acp kill <session> # immediate: SIGKILL the runner
aoe acp logs [--session <id>] [--follow]
aoe acp restart <session> # stop + let daemon respawn