Desktop control plane for CLI agents

Run many agents.
Join when ready.

Give every account its own terminal, send the whole stage before waiting, and hand a complete, explicitly published result bundle to the stage that follows.

  • No credentials stored
  • Fail-closed routing
  • Raw PTY history is never journaled
LIVE WORKFLOW SEQ 1842
C Codex · buildL1 · routed
MATCHED
A Claude · reviewL2 · env-only
WORKING
C Codex · researchL1 · routed
QUEUED

REAL PRODUCT UI

See the control loop, not a cinematic substitute.

These are deterministic captures of the real renderer with inert fixture data. No account, agent, PTY, or production journal was opened to make them.

The real Agent Orchestrator editor waiting at a Join Agents barrier with two of three result lanes ready.
Fan out first. Three lanes share one visible workflow; downstream work remains stopped at 2 / 3.
The real editor after Join Agents reaches three of three and explicitly attaches the complete result bundle to synthesis.
Join once. At 3 / 3, a bounded result bundle crosses into synthesis explicitly.
The real Runs view showing protected interrupted-run evidence and a decision-required resume inspection.
Keep the proof. Protected evidence can be inspected; inspection never executes or replays.
01

Route identity

Select an agent and an account. The assurance badge tells you what the launch can actually guarantee.

02

Fan out work

Sessions keep running behind their tabs, so one workflow can prompt several accounts without losing output.

03

Join, then hand off

One barrier watches every prompted lane. In explicit-result mode, only a complete bounded bundle can feed the next agent stage.

FIRST RUN

From install to a trustworthy run.

Use the smallest path that matches the account guarantee you really have.

  1. 1

    Open Agent Accounts

    Choose Agents in the bottom toolbar. Routed Codex accounts are discovered; local profiles are created here.

    Inspect
  2. 2

    Confirm the badge

    L1 means routed. L2 means env-only. L0 means native. These are different guarantees, not cosmetic labels.

    Verify
  3. 3

    Start one session

    Open the account and log in inside its terminal if needed. The app does not accept or persist credentials.

    Connect
  4. 4

    Graduate to a workflow

    Open the team, place every Send to Agent block before one Join Agents barrier, and add the second account only after the first path is sound.

    Automate

ACCOUNT ASSURANCE

Say exactly what the launch guarantees.

Assurance describes construction of the child session. It never claims that an upstream agent service is available or authenticated.

L1

STRONGEST AVAILABLE ROUTE

Alias resolution is owned by ai-agent-entrypoint.

The orchestrator discovers Codex aliases with doctor output and launches through codex shell <alias>. If that route cannot be resolved, launch fails closed. In a workflow, an Agent Session block waits for the account shell, invokes its session-local codex wrapper once with a fixed trailing shell exit, and then observes the configured settle period. Opening the same account manually leaves you at the interactive shell.

  • Account route is centrally resolved
  • Canonical paths are sanitized before UI
  • Manifest is never edited by this app
Use this wording Routed account

Do not expand this into a claim about service-side isolation.

RECIPE COMPOSER

Fan out first. Join the stage once.

The composer is a planning aid. It keeps profile IDs blank so the resulting idea stays portable across machines.

BLOCK PLAN Builder + reviewer

          

Role-specific sends all precede the shared barrier. For one common prompt, target All workflow agents; multi-target typing happens concurrently.

SIGNAL-AWARE JOIN LAB

A fast reply should count before the barrier begins.

Each prompt records an opaque activity checkpoint before submission. The shared join observes every eligible session from its own checkpoint, even if one replies before the Join Agents block starts.

team stage / shared join ready

00 Press replay to watch three readiness signals converge.

Waiting for a run
1

Scope the stage

Include each workflow-owned agent session prompted since the previous Wait for Agent or Join Agents.

2

Observe concurrently

Each session advances independently on new bounded PTY activity: a literal marker or new-output idle.

3

Require the whole team

Continue at M / M ready. Timeout or premature exit stops downstream blocks by default and leaves remaining sessions open.

EXPLICIT ESCAPE HATCH Choose Continue with warning only when downstream blocks are safe with an incomplete team. Idle observes silence, not semantic success.

WORKFLOW INTEGRITY

The run is stable. The editor stays yours.

Starting a run captures the ordered blocks and parameters it will use. Later edits belong to the next run.

01

Immutable run snapshot

Manual and scheduled runs execute a captured workflow value. Dragging, editing, or renaming in the UI cannot rewrite the active run.

02

Non-destructive schedule

A due saved workflow starts from its persisted snapshot without replacing the editor or clearing dirty state. An open unsaved draft never overrides that saved schedule source.

03

Protected resume preflight

Run Journal records main-owned status and block visits. After its cheap evidence gate, an explicit local preflight can decrypt the captured snapshot, prove nested-loop visit order, verify protected results, classify runtime reconstruction, and re-resolve accounts. Only redacted facts return to the Runs view; no replay action exists. Stable cursor pages and preview-first retention stay metadata-only.

The journal is durable evidence, not an automatic resume point. “Boundary recorded” means the cheap metadata gate found durable, untruncated evidence and may offer Inspect protected evidence. That explicit inspection is bound to the displayed source revision and runs only in main: it checks protected bytes with the same versioned workflow validator, proves the exact visit prefix, verifies result bindings, classifies runtime state, and resolves current profile authority. The report omits paths, prompts, commands, profile IDs, block IDs, and result bodies. “Boundary verified” still is not permission to execute. An interrupted block may already have produced an external effect, so it is never retried automatically. Explicit bounded results can feed a later Send block; arbitrary PTY history cannot, and workflows remain ordered programs rather than a general DAG. Protected journal files stay until you explicitly delete a run or confirm a previewed count/age retention plan. Retention is never automatic, and active runs are never candidates. Framing does not neutralize indirect prompt injection: restrict tools or require human review when a result contains untrusted source data. Generated result input also crosses a separate main-process capability check; shell profiles, manual tabs, and composite custom commands cannot receive it. Each record has a hard size bound. Listing uses stable cursor pages backed by a rebuildable public-metadata index that contains no ciphertext or result bodies. Startup recovery still validates source records so an unknowable active run fails containment closed.

SCHEDULED PRE-WARM

One morning, two usage windows.

Metered CLI-agent plans start a rolling 5-hour usage window at your first message. A scheduled early ping decides when that clock starts — before you even sit down.

05:00

The scheduled ping

A daily cron workflow opens the agent, sends one trivial prompt, and exits. The provider's 5-hour window now spans 05:00–10:00.

09:00

You start working

Your real session lands in the tail of the pre-warmed window instead of opening a fresh one that would run until 14:00.

10:00

The window rolls over

Your next prompt opens a fresh 10:00–15:00 window. One working morning spans two windows' worth of usage — per account, so multi-account fan-out pre-warms every login at once.

This shifts when a window you already pay for begins; it does not create free usage, and weekly caps are unaffected. The Usage-window pre-warm template ships the pattern ready to run — tune the ping time to your own burn rate, and keep the machine awake for the scheduled minute (the heartbeat survives tray and lock, not sleep).

TRUST BOUNDARIES

Terminal display and result storage take separate paths.

Live PTY data reaches xterm for interaction. The matcher keeps a bounded activity window in main, while only an explicitly framed result crosses into protected journal storage.

RENDERER

Workflow + terminals

  • Block parameters
  • Session tabs and status
  • Live terminal stream
  • Opaque checkpoints
MAIN PROCESS

SessionRegistry

  • Bounded matcher history
  • Framed result capture
  • Concurrent stage readiness
  • Serialized ConPTY exits
CHILD PROCESS

Agent session

  • Routed or local launch
  • Interactive CLI output
  • Process-tree lifecycle
Never crosses into workflow JSON or session metadata

Raw PTY history, child environment values, canonical account-home paths, and the resolved executable.

WHEN A ROUTE BREAKS

Fail closed, then repair the source.

A missing routed alias does not silently open the native login. Correct discovery and retry.

WHEN A JOIN IS INCOMPLETE

Stop the stage, keep context visible.

Join Agents stops downstream execution by default. Inspect the open sessions, strengthen the marker, then retry.

WHEN A SCHEDULE FIRES

Run the saved snapshot off-screen.

The current editor selection and unsaved-change state remain untouched while the scheduled workflow runs.

DEVELOPER HANDOFF

One local loop. Three honest checks.

Main-process logic is CommonJS and unit tested. Renderer modules are exercised by the Electron self-test.

PowerShell
npm install
npm start

npm run check
npm test
npm run smoke
npm run checkSyntax + static docs contract
npm testMain-process + renderer behavior
npm run smokeElectron startup and cleanup path
Read the repository guide