Skip to content

Open many terminals at once, and run a program in one - #69

Merged
rajanbor merged 1 commit into
mainfrom
feat/terminal-canvas
Sep 16, 2026
Merged

rajanbor merged 1 commit into
mainfrom
feat/terminal-canvas

Conversation

@rajanbor

Copy link
Copy Markdown
Owner

Change

One terminal at a time, docked at the bottom, is not what the work looks like. The work is several terminals open together — one per task — and in some of them an agent CLI doing a job.

A board of terminals. A window opens in a sandbox you pick, and it moves, resizes, raises, closes, and tidies into columns. Each window states its terminal, sandbox, working directory and policy. Positions and sizes are kept on this machine, so the board comes back as you left it.

Programs inside a terminal. Typing claude, codex, qwen or agentctl opens a session in that window that takes a task per line until exit. claude "a task" answers once from its argument, the way the real CLI takes a first prompt.

agent@product-dev ~/Projects/open-cube % claude
Claude Code — session opened by Open Cube
Standing in: the built-in inspector answers under the read-only policy.
It reads the workbench snapshot. It cannot read file contents, credentials or the network.
Type a task. `exit` closes the session, `help` lists what this shell answers.
The real CLI runs as the sandbox user and signs in with your subscription; both need workbenchd.
Answers come from inspector-local, not Claude Opus — which is not connected.
Try: What is each agent doing right now?
claude > What is each agent doing right now?
4 agents are configured.
 · Chief (orchestrator) is running on "Rebuild the workbench shell" using Claude Opus in sandbox product-dev · 2360000 tokens · $13.32
 …
— inspector-local · 98 tokens · $0.00

domain::TerminalProgram holds each program: the model and provider it would use, its banner, example tasks, and blocked_by — the reason its real binary cannot be launched. A test asserts available and blocked_by are opposites, so a program can never claim to run without saying what is missing. Nothing here launches anything: a program in a sandbox runs as the sandbox user, which is the daemon's work, and the banner says so on every start rather than once.

One terminal, one history. What a terminal does with what is typed moved out of the dock into web/src/lib/terminal.ts, and the buffers moved into the shell, keyed by terminal id. The panel and the board are two views of the same terminals: a session started on the board shows in the panel, the panel's session list includes the board's windows, and clear clears one history rather than one of two.

Transcripts are deliberately not persisted — a session that outlived the window would be a session this app never had. A restored window opens at its shell prompt with its policy and claims nothing about what was said before.

Validation

  • cargo test -p open-cube-core — 28 tests, one new: no program claims to run without saying what is missing, and every program's model and provider exist.
  • pnpm fallback, pnpm build clean.
  • In the browser: opened two terminals in different sandboxes, tidied them into columns, ran claude in one and gave it a task (output above), confirmed the second window kept its own shell and its own policy (network off for review), opened the bottom panel and saw the same transcript with the session marked claude session, reloaded and the board came back in place. Checked light and dark.
  • The submit control: each entry now has an explicit run button beside the field, so the command is reachable by mouse as well as by Return.

Security impact

None. The session is the existing read-only inspector; no process is spawned, no provider is contacted, and the refusals are stated more often rather than less. Board state stored locally is positions and sandbox ids only.

Closes #68.

One terminal at a time, at the bottom of the window, is not how the work looks.
The work is several terminals open together — one per task — and in some of
them an agent CLI doing a job.

There is a board now. A window opens in a sandbox you choose, and it moves,
resizes, raises, closes and tidies into columns. Each window states the
terminal, the sandbox, the working directory and the policy that governs it.
Positions and sizes are kept on this machine, so the board comes back as you
left it.

Typing a program's name opens a session in that window. `claude`, `codex`,
`qwen` and `agentctl` are objects in the engine — `domain::TerminalProgram` —
each naming the model and provider it would use, the banner it prints, example
tasks, and the reason its real binary cannot be launched. A test asserts
`available` and `blocked_by` are opposites, so a program can never claim to run
without saying what is missing.

None of them runs. A program in a sandbox runs as the sandbox user, which is
workbenchd's work, and for a hosted model the provider is not connected either.
What opens is a session against the built-in inspector under the read-only
policy, and the banner says so on every start, not once and not in a tooltip.
Inside the session every line is a task; `claude "a task"` answers once from its
argument, the way the real CLI takes a first prompt; `exit` closes it. Every
answer names the model, the tokens and the cost, as everywhere else.

What a terminal does with what is typed moved out of the dock into
`lib/terminal.ts`, and the buffers moved into the shell, keyed by terminal id.
The panel and the board are now two views of the same terminals: a session
started on the board is visible in the panel, the panel's session list includes
the board's windows, and `clear` clears one history rather than one of two.

Transcripts are deliberately not persisted. A session that outlived the window
would be a session this app never had; a restored window opens at its shell
prompt with its policy and claims nothing about what was said before.

Closes #68
@rajanbor
rajanbor merged commit 4e7966f into main Sep 16, 2026
11 checks passed
@rajanbor
rajanbor deleted the feat/terminal-canvas branch September 16, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terminal canvas: many terminals at once, with agent sessions inside them

1 participant