Skip to main content

Serve mode

botctl serve is the current runtime-backed observation and HTTP facade.

It is one of the main user-facing commands, alongside runtime, dashboard, and yolo.

The central runtime process holds the tmux control-mode connection open and rebases that stream with periodic capture-pane snapshots. serve connects to that runtime and exposes a session-scoped foreground stream plus optional HTTP API.

In managed mode, serve auto-starts the runtime in a hidden tmux session when needed. Use --unmanaged if you want it to require an already-running runtime instead.

What it does today

serve runs in the foreground and emits structured events to stdout from the runtime's shared event stream.

Current behavior:

  • requires an existing local runtime
  • narrows the shared runtime stream to one tmux session or one explicit pane
  • emits human-readable or JSONL events
  • can also expose a localhost HTTP API for polling clients and web UIs
  • uses the same runtime-owned pane snapshots and guarded action scheduler seen by dashboard and yolo

Basic usage

Observe one session:

botctl serve --session demo

This is the main session-scoped live observation facade. Use it when you want a foreground stream; use observe only when you specifically want a bounded diagnostic sample.

Observe one specific pane inside that session:

botctl serve --session demo --pane %19

Use JSONL output for tooling:

botctl serve --session demo --format jsonl

Expose the local HTTP API for a browser-based control surface:

botctl serve --session demo --http 127.0.0.1:8787 --allowed-origin http://localhost:3000

Repeat --allowed-origin URL for each browser origin that should be able to call the API.

Current HTTP endpoints include:

  • GET /instances
  • GET /instances/:id
  • POST /instances/:id/prompt
  • POST /instances/:id/actions/:action
  • POST /instances/:id/interactions/:optionId

For the full route, payload, and response reference, see HTTP API reference.

The prompt endpoint accepts JSON like:

{
"text": "Summarize the current repo",
"submit_delay_ms": 100
}

You can also point serve at an explicit state root so it reaches the right runtime socket:

botctl serve --session demo --state-dir /tmp/botctl-state

Slow down periodic reconciliation:

botctl serve --session demo --reconcile-ms 5000

Event kinds

The current stream includes:

  • runtime-started
  • pane-discovered
  • pane-snapshot-updated
  • pane-state-changed
  • yolo-enabled
  • yolo-disabled
  • yolo-monitoring-stopped
  • action-requested
  • action-executed
  • action-failed
  • pane-removed

Snapshot-bearing events include:

  • pane metadata
  • current classified state
  • classifier signals
  • whether the state changed
  • desired and effective yolo state
  • wait duration and last stop reason when available

Current scope

This is the current implementation, not the final remote/API product yet.

Implemented now:

  • explicit runtime command
  • runtime-owned tmux observation and periodic reconciliation
  • runtime-owned guarded action execution
  • runtime-owned yolo supervision
  • foreground session-scoped serve stream and polling HTTP API

Not implemented yet:

  • SSE endpoints
  • full reconstructed terminal screen model
  • remote/distributed runtimes

Safety rules

Serve mode keeps the same safety rules as the rest of botctl:

  • targeting stays explicit
  • observation stays scoped to the requested tmux session or explicit pane
  • Unknown remains a refusal state
  • serve mode does not bypass guarded workflow checks
  • the HTTP API only exposes panes inside the served tmux session
  • the HTTP API exposes visible prompt options conservatively; when a dialog cannot be selected safely yet, it falls back to low-level confirmation controls

Current limits:

  • it still depends on a local runtime you start explicitly
  • it does not expose SSE yet
  • classification still depends on capture-plus-merge heuristics, not a full terminal model

Relationship to the larger plan

The current shipped shape is already the central-runtime design: one local runtime owns observation and actions, and serve is the session-scoped facade over that owner.