Skip to main content

Cockpit overview

The cockpit is where you inspect the record the runner leaves: every plan, run, job, and log, rendered the same way in a CI log and in a terminal. It is part of pillar 4, the runner, and it only ever shows what was planned and what happened.

The cockpit is the unified UX layer for orun. Every surface that shows you what's happening — orun status, orun status --watch, orun get runs, orun logs, and orun tui — flows through the same view-model and the same design tokens.

It is the operator-facing half of orun: planning happens in the compiler; operation happens in the cockpit.

Two generations of the full-screen cockpit ship in the binary today. Cockpit v1 (orun tui, internal/tui) is the default. Cockpit v2 (orun tui-next, internal/tui2) is a preview that rebuilds the same surfaces on a frame-stable kernel; see Cockpit v2 below. Both read the same state and the same design tokens.

orun status · live
▲ orun multi-environment-platform
Plan: sha256-ad6ce · Run: gh-26563885741 · State: running · Duration: 38.2s
Scope: 3 components · 6 jobs · 2 environments

Status:   ✓ 3 succeeded · ◐ 2 running · ○ 1 queued · ✗ 0 failed
Progress: ▓▓▓▓▓▓▓▓▓▓░░░░░ 66%

● api-edge-worker
│  ├─ ✓ build              4.1s
│  ├─ ✓ test               12.3s
│  └─ ◐ verify-deploy      running 19.0s
● database
│  └─ ◐ apply              running 38.2s
○ web-app
   └─ ○ deploy             queued

What "unified" means​

Three things are shared across every cockpit surface:

view-model

One read path

internal/cockpit/bridge.Source reads from either a local .orun/ directory or a remote statebackend.Backend. The CLI and TUI both consume RunView, RunListView, and LogsView — pure value objects with no rendering logic.

design tokens

One palette, one glyph set

internal/cockpit/style owns the violet brand (▲ #7c3aed / #a78bfa), the lifecycle glyphs, and the tree connectors. Both the ANSI layer and the lipgloss theme wrap these constants. Reskinning is one file.

live updates

One polling stream

internal/cockpit/watch emits Update{View, Err, Terminal} on a 500ms cadence (100ms floor). orun status --watch subscribes directly; the TUI subscribes via LiveOrunService.WatchRunView. Refresh and terminal-state semantics are identical.

The glyph language​

The cockpit speaks a small, deliberate vocabulary. Every glyph maps to a status token, which maps to a palette color. Once you know the alphabet, you read every surface fluently.

GlyphTokenMeaning
✓SuccessStep or job completed successfully
✗ErrorStep or job failed
◐RunningIn progress (paired with wall-clock spinner in TUI)
○PendingQueued, not started
↷WarningSkipped (condition gate, dependency failure)
●BrandActive or changed scope marker
▲BrandThe orun wedge — opens every cockpit header

Tree connectors ├─, └─, │ group jobs under components, and steps under jobs. → marks transitions (promotions, redirects). ↻ marks retries.

NO_COLOR=1 strips palette but never strips glyphs — the alphabet survives.

Three surfaces, same frame​

orun status — the one-shot cockpit​

orun status # default frame for the current run
orun status --all # list of recent runs
orun status --watch # live updates until terminal state
orun status --run <id> # specific run by ID

The CLI is the TUI compressed to one frame. No navigation, no panes — just the single most relevant view, rendered through the same view-model and design tokens.

orun logs — grouped log view​

orun logs # all logs from the current run
orun logs --failed # failed steps only
orun logs --job <id> # one job's logs
orun logs --watch # tail live

Logs are grouped by job and step, with … N more lines truncation in dense views. The grouping is built by internal/cockpit/render and is identical in the TUI's Log Explorer pane.

orun tui — the full cockpit​

orun tui # explicit (cockpit v1, the default)
orun # bare invocation opens the cockpit on an interactive terminal
orun tui-next # cockpit v2 (preview); also: orun tui --next, or ORUN_TUI=next

Cockpit v1 is a three-pane Bubble Tea shell: sidebar (surfaces), main pane (active view), inspector (field list for the selection). The two top-level surfaces are Catalog (the home surface) and Activity; Plan Studio, Logs, and History are reached from within them. See cockpit architecture for the full mode and drilldown machine.

The cockpit is the default command — a bare orun opens it on an interactive terminal, and falls back to printing help in non-interactive shells or when ORUN_NO_TUI is set. From Plan Studio you can dry-run (d) or real-run (R, behind a confirm) a plan; a real run executes through the same internal runner as orun run, persists state and per-step logs to .orun/, and streams those logs into the Activity and Logs surfaces live. See the TUI reference for the run and live-log workflow.

Cockpit v2 — orun tui-next (preview)​

Cockpit v2 is the terminal head of Orunbase: the same entities the hosted console renders, at terminal density. It lives in internal/tui2 and is opt-in while it soaks — orun tui-next, orun tui --next, or ORUN_TUI=next all open it, and orun agent --next opens it straight on the Agents surface. The v1 cockpit stays the default until the remaining cloud lanes land and a release has soaked.

SurfaceWhat it shows
HomeStat tiles (components, live sessions, last run), a needs-attention list, latest activity, current scope
AgentsLive local agent sessions, agent types, the launch flow, and the conversation head over the attach protocol
ActivityRuns feed → run → jobs → steps → logs, stream-driven from step-level runner events; the log explorer is the leaf
CatalogEntity explorer by kind, entity detail with relations, and the component work surface — Plan Studio becomes the Compose flow under a component
EventsLocal execution and agent session events

What is different from v1, by construction:

  • Frame stability. Every region renders into a box of exactly the size it is given (tui2/frame); regions are memoized by state revision and size, and one animation scheduler ticks only while something is genuinely live. An idle cockpit renders nothing.
  • Streams over polls. Step progress arrives through the runner's OnStepStart / AfterStepTerminal hooks and catalog refresh through fs-watch on .orun refs, instead of the disk polling v1 relies on.
  • Northwind Mono. The design system (tui2/design) is the terminal projection of the console's Northwind system, built on the same tokens in internal/cockpit/style — so v1, v2, and the CLI still share one palette and one glyph alphabet.
  • Claude Code grammar. One header line, one status line, esc always dismisses, and a command palette is the escape hatch for everything.

ORUN_TUI_PROFILE=/path/to/file.ndjson writes per-frame timings for either cockpit generation; make tui-bench reports the v2 render budgets.

The Catalog surface — knowledge and work in one screen​

The Catalog is the cockpit's home surface (1, or the goto.catalog palette command): the cockpit view of the service-catalog entity model. It replaced the former Browse and Component surfaces — every entity the resolver derived from your workspace is here, and Component entities carry the full work surface:

  • Kind tabs with counts. [ / ] (or ←/→) cycle through the kinds present in the catalog — Component, API, Resource, System, Domain, Group, Composition, Environment, Deployment — each with its entity count. The surface opens on the Component tab; the All tab mixes kinds with a kind glyph per row.
  • Envelope columns per kind. Components lead with OWNER (CODEOWNERS-derived ownership) and STAGE (lifecycle); Compositions show VERSION and lifecycle stage; derived kinds show member counts.
  • Changed / affected overlay. Component rows are badged by the change-detection engine: a filled dot for a directly changed component, a hollow dot for one affected through a dependency. Press c to filter to only the changed and affected components — the cockpit view of orun catalog affected.
  • A walkable graph. ⏎ opens an entity's detail page: identity, ownership, lifecycle, and a Connections list — its members and typed relation edges (dependsOn, partOf, ownedBy, deployedTo, composedBy, …, with ◂ marking incoming edges). Connections are navigable: ⏎ follows an edge to its other endpoint, esc walks back. The header breadcrumb tracks the path.
  • Execution history, in place. A Component's detail page shows its source detail (path, profile, watches), live change state, last-run status, and an Executions section; ⏎ on an execution drills straight into the Activity run → job → logs view, reading the sealed executions under .orun/objectmodel/.
  • Run from the graph. r runs the selected component for the selected environment (confirm-then-execute through the same internal runner as orun run); g composes it in Plan Studio.

Catalog freshness​

The surface stays current on its own:

  • Live, keystroke-free refresh. The cockpit re-reads the catalog on a short interval, so a component you edit on disk — or a catalog written by an external orun plan/run or the universal refresh hook — appears within a few seconds without a reload.
  • Keeps its own catalog fresh. The cockpit resolves a current catalog when it opens (even for a dirty tree). In-session, ctrl+r (or the catalog.refresh palette command) forces an immediate refresh, and the catalog.autorefresh palette command enables periodic re-resolve on change (off by default, persisted in ~/.orun/cockpit.json). When the loaded catalog drifts from the working tree, a ⟳ stale (⌃r) badge appears in the header. See the TUI reference for the full workflow.
  • Freshness gate. When the catalog is fresh for a clean tree, the component work-surface context is served straight from the catalog; a dirty tree falls back to the live intent loader so uncommitted edits show immediately.

Environment selector and component-scoped run​

The cockpit holds one selected environment (shown in the header), cycled with e and remembered between sessions. On a component, r launches a component-scoped run for the selected environment — only when the component is active in it — through the same orun run path (it confirms, then executes and persists state + logs). g opens Plan Studio to compose instead. This uses the existing environment model; it does not change how orun plan/run resolve environments elsewhere.

State, on disk​

The cockpit reads the same record orun run writes: the content-addressed object model under .orun/objectmodel/, where every execution, job, step, and log is an immutable object and refs such as executions/latest and executions/live/<exec-id> point at the current ones. See the state model for the layout.

Anything you can see in the cockpit you can also read with orun status, orun logs, orun describe, or orun objects. Remote state backends (statebackend.Backend) expose the same shape over the wire, and bridge.FromBackend normalises them into the same bridge.Source interface.

What the cockpit deliberately is not​

  • Not a dashboard. It is operator-facing, not stakeholder-facing. There is no aggregated cross-run metrics view, no SLO panel, no graphs of deployment frequency. Those belong upstream, in your observability stack.
  • Not a CI UI. GitHub Actions, Buildkite, and friends remain the systems of record for who triggered what. The cockpit shows you the plan and the execution of one run; the CI shows you the context.
  • Not a state editor. The cockpit reads .orun/, and a real run from Plan Studio appends new run state and logs through the same runner as orun run. It never rewrites or hand-edits existing state — even orun run --resume writes new state rather than mutating the old.