Decisions › D24

Every real action runs on a live terminal you can read, type into and stop

Decision
D24
Date
2026-10-24
Status
Accepted
Area
contract

Context

While calibrating a moteus board, Zach wanted to see the terminal output in case there is debugging information, and to enter user input if a tool asks. Round 3 had asked the opposite for the default view: no streaming wall, a quiet line under the button. Both stand: the line stays quiet, and the output is one click away.

The decision

Every real action (never a dry run) is a run: the plugin's own command on a pseudo-terminal, with live output, typed input and Stop. Stop sends SIGINT to the plugin's process group, then SIGTERM and SIGKILL after 3 seconds each. The plugin's records leave the terminal on a second file descriptor named in an environment variable, so a wrapped vendor tool inherits the terminal, prints progressively and can prompt, while the structured result still reaches the host.

Output is held in a 2 MiB ring and written as it happens to an asciinema recording, with a 64 MiB total budget. The page streams it with Server-Sent Events as raw bytes, drawn by xterm.js. Each run adds a RunStarted and a RunEnded event to the activity log.

Why

“it would be cool though if I could perhaps see the terminal output or something, in case there is debugging information”

Zach Yamaoka, 24 Oct 2026

“the Claude model is good: you run this and then there is all the terminal's processes you can switch between.”

Zach Yamaoka, 24 Oct 2026

“the tulities are not the main thing and shouldn't be drawing attention”

Zach Yamaoka, notes, 23 Oct 2026

Options considered

Five page proposals draw against the same seam. Two are built; the default is the first.

ProposalState
r1 Terminal panel with tabsBuilt, default
r2 Output in placeBuilt
r3 Runs as rowsNot built yet
r4 Runs in the Activity logNot built yet
r5 A tmux sessionNot built yet

Consequences

  • An old plugin that ignores the variable still works: the host reads the terminal's lines that parse as records.
  • Finished runs persist, so a run's output can be replayed with any asciinema player.
  • A dry run asked while a run holds the same exclusive group is refused at once, because a run can sit at a prompt for minutes.

Evidence

Commits in the app's repository (private):

  • bcbc8a9 2026-10-24 Runs v1 contract
  • 693cb80 2026-10-24 Runs, host side
  • f2c84c2 2026-10-24 Runs, page side: terminal panel with tabs
  • 8ed6504 2026-10-24 Runs: hero video and GIF recorded from the real page

← All decisions