Skip to content

Add interactive terminal grids to executable documents #717

Description

@taras

Story

As a repository user, I want an executable document to open several interactive
terminals in one foreground grid, so I can work with multiple coding-agent
sessions and an ordinary repository shell at the same time.

The grid is declared as document structure. A host decides how to present it.
The first host may use tmux, but the document does not name tmux sessions,
windows, panes, targets, commands, or key bindings. A later host can use another
terminal multiplexer, emulator, or native interface without changing the
document.

Example

The exact component names and props are an architecture decision. This sketch
shows the intended experience rather than freezing that API:

<Terminal.Grid columns={2}>
  <Terminal title="Architect">
    <Agent name="codex">
      <Session.Launch session="architect">
        ...prepared Architect instructions...
      </Session.Launch>
    </Agent>
  </Terminal>

  <Terminal title="Planner">
    <Agent name="codex">
      <Session.Launch session="planner">
        ...prepared Planner instructions...
      </Session.Launch>
    </Agent>
  </Terminal>

  <Terminal title="Implementor">
    <Agent name="claude">
      <Session.Launch session="implementor">
        ...prepared Implementor instructions...
      </Session.Launch>
    </Agent>
  </Terminal>

  <Terminal title="Workspace" />
</Terminal.Grid>

Running the selected document target attaches the user to one 2-by-2 foreground
workspace. The three paired terminals run their native coding-agent UIs. The
self-closing terminal starts the host's ordinary interactive shell in the
contextual working directory.

Current gap

<Session.Launch> currently takes the root CLI execution's one
foreground-terminal lease. Two native launches are sequential by construction;
concurrent launches refuse even when they name different Agent sessions. An
ordinary executable block is piped and captured, so it cannot substitute for an
interactive terminal.

The repository contains a tmux demo launcher, but it is a shell script with
tmux-specific process and layout commands. Copying that machinery into an
executable document would make the authored workflow depend on one terminal
provider and would bypass the session ownership, cancellation, teardown, and
native-launch contracts established by #517.

Contract

The grid is the run's foreground experience. XMD remains its supervising parent
and remains alive while the grid is attached. Leaving or closing that experience
ends the grid scope, cancels every still-running pane, waits for their teardown,
and only then settles the document execution. No child process or interactive
terminal is orphaned.

Grid setup is atomic from the document's perspective. The host validates and
prepares the complete layout before exposing it. If any pane cannot be created
or started, every pane already prepared or started is torn down and the grid
fails without presenting a partial workspace.

Once the grid is active, panes settle independently. One shell or native Agent
UI exiting does not close or cancel its siblings. Its pane remains visible with
the terminal status, while the other panes stay interactive. Closing the whole
grid cancels the panes that are still active.

Each pane has its own interactive terminal ownership. A Session.Launch inside
a pane uses that pane rather than competing for the root terminal, while its
existing Agent-session coordinator, construction route, provider-native
identity, executable binding, instruction-layer, durability, and replay rules
remain intact. ACP and a native UI still never own one logical Agent session
concurrently.

Layout and terminal execution are provider-neutral. Authored structure describes
the grid, pane order, pane titles, and pane content. The selected host provider
owns terminal allocation, composite presentation, attachment, terminal status,
and provider-specific cleanup. Provider-specific identifiers and commands do
not enter component props, bindings, durable records, or diagnostics.

This story does not advertise another native Agent provider. A pane may launch
only an Agent the host already advertises under the existing native-launch
proof. Controlled providers can prove the grid independent of a real Agent CLI;
production Codex support requires its own applicable native integration proof.

Architecture to settle

Before implementation, reconcile this capability with the current
foreground-terminal and native-launch architecture:

  • choose the smallest public component vocabulary and authored forms that
    express a grid, an interactive pane, and the default shell without exposing a
    provider;
  • define how direct pane children begin concurrently while normal executable
    document flow remains ordered;
  • place terminal allocation and pane-scoped launch authority so contextual
    provider selection remains replaceable but cannot mint terminal ownership;
  • define the atomic setup boundary, the point at which the grid becomes visible,
    and how startup failure tears down work already begun;
  • define how pane exit, grid close, cancellation, host failure, and complete
    teardown settle the grid and the document;
  • preserve the native session launch's durable phases and completed-replay rule
    while a live launch runs inside a pane rather than on the root terminal; and
  • define non-executing syntax and validation behavior without starting a
    terminal provider or probing tmux, a terminal emulator, a shell, or an Agent
    CLI.

Acceptance

  • A checked-in executable Markdown journey opens a two-by-two grid containing
    at least two concurrent controlled native Agent sessions and one interactive
    shell pane.
  • Both controlled Agent sessions become interactive concurrently; an
    implementation that serializes their Session.Launch operations fails the
    journey.
  • Exiting one pane leaves every sibling active and leaves the settled pane and
    its terminal status visible.
  • Closing the grid cancels all active pane work, waits for every process and
    provider finalizer, restores terminal state, and leaves no child process or
    terminal session running.
  • Failure to prepare or start any pane presents no partial grid and tears down
    every pane already prepared or started.
  • Cancelling during setup, attachment, or active use reaches the same complete
    teardown boundary and never lets the document continue while a pane remains
    live.
  • A paired interactive pane gives its nested Session.Launch only that pane's
    terminal. Two panes do not share input, output, terminal status, or terminal
    ownership.
  • A self-closing interactive pane starts the configured default shell in the
    contextual working directory; provider absence refuses before a shell starts
    or a partial grid appears.
  • A tmux-backed production provider and a controlled non-tmux test provider run
    the same authored document structure and produce the same lifecycle outcomes.
  • xmd syntax and document validation describe and validate the complete public
    surface without creating a grid, attaching a terminal, starting a shell, or
    contacting an Agent provider.
  • A completed replay starts no terminal provider and launches no shell or Agent
    UI; incomplete durable launch history retains the existing Launch a deterministically prepared Agent session in its native UI #517 identity and
    reconciliation behavior.
  • The native session launch specification and architecture.md describe how
    pane-scoped terminal ownership composes with the root foreground experience.

Related and out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions