Documentation / Cards

Terminal and providers

Each terminal card is a real process from a provider — Claude, Codex, Cursor, Antigravity, OpenCode, Cline, Command Code or a plain shell.

Each terminal card is a real PTY, running a provider or a plain shell. Stellar does not simulate a terminal: what appears in the card is the process.

Providers

Provider What runs
claude Claude Code
codex Codex
cursor Cursor
antigravity Antigravity (Gemini)
opencode OpenCode
cline Cline
commandcode Command Code
bash a shell, with no agent behind it

The last two are not code: they are data. The built-in catalog declares the binary, how the session id comes in, which flag carries the system prompt, where the MCP config lives, effort and model — and the arguments are synthesized from that declaration. It is what lets you declare your own: a providers.json in the configuration folder registers a new CLI without restarting the app (see Where data lives).

The provider is chosen at card creation. It is not inherited from whoever dispatched: a task that does not declare a provider is refused, on purpose — pinning the whole chain to the provider that started would be too silent a decision.

Installed is not ready

The binary resolving on the PATH answers one question only. Availability has four answers, and each one is as large as the proof behind it:

Answer What backs it
missing the binary does not resolve on the PATH
not-ready installed, and the declared probe answered that it is not ready (a missing credential, for example)
ready installed, and the probe answered that it is
unknown installed, and the app does not know — no probe was declared, or it never answered

unknown is the default of a provider that declares nothing, and it never becomes “ready” out of optimism. The case that forced this is measured: a CLI installed and without a credential showed as available, the spawn “succeeded” and the card stayed silent forever. The probe lives in the provider declaration because “ready” varies per harness — and what the app reads is the field the tool itself prints, not the exit code.

Zoom without reflow

The canvas zoom is optical: the text scales like an image, without firing fit() or reflowing columns and rows mid-session. The PTY is resized only when you drag the card’s physical edge.

Session and resume

Every card can be resumed with the provider’s session id, but not the same way — and the difference that matters is between imposing and resuming.

Imposing is creating the session already with the id Stellar chose. Only two providers know how: claude, with --session-id, and cursor, with --new-session-id. On cursor the imposing flag does not show in --help, and for a while the app used --resume for both roles — which asked to resume a session that did not exist yet.

Resuming is pointing at a session that already exists, discovered in the provider’s store: cline (--id), codex (resume <id> — a subcommand, not a flag), opencode (--session), commandcode (--resume) and antigravity (--conversation). None of these accepts an unknown id: an imposed id would be ignored silently.

The registry keeps two distinct ids: the resumeId requested at spawn and the sessionId discovered at runtime. When the provider imposes an id different from the requested one, the second is the one that counts.

And the imposition is checked, not presumed. After the spawn, the app reads the store declared by the provider and looks for the imposed id there. If it does not find it, the declaration was contradicted by measurement and the session watcher takes over again — instead of the card pointing forever at a session that does not exist. The check exists because canImposeSessionId: true is a claim in a configuration file, and nothing checked it: that is how the cline defect (the flag was for resuming) and the cursor one (the flag was wrong) got through.

Where there is neither imposition nor a discoverable session, the registry stays absent, honestly, instead of inventing an id.

Quota and agent death

Providers die from quota in the middle of the work. Before concluding that the agent failed, read the card’s scrollback: a quota death looks like a bug death when nobody looks.