Native PTY
NativePty runs a provider’s own interactive terminal interface. The provider handles its native tools and approvals. PTY output is mostly unstructured, so semantic events derived from it carry Fidelity::Inferred.
uuldana-cli relays your keyboard to the pseudo terminal unchanged and follows terminal resizes. On Windows the pseudo terminal is ConPTY. ConPTY asks its host for the cursor position at startup, so the relay answers that query itself; without that, the provider would wait on a reply that is never delivered. On Unix, PTYs do not ask.
The relay can also stop a run gracefully on request, which is how failover ends an agent that ran out of quota. Each adapter declares how many interrupts (Ctrl+C presses) stop its agent gracefully, from 1 to 3; learned adapters declare 2 and give the agent up to 30 seconds to leave, because an agent saves its state on the way out and one that was measured took about twenty seconds. Presses after the first are spaced half a second apart, because presses that arrive together can be read as one, and they are not sent to a program that has already left.
The frame
uuldana-cli uses the terminal’s alternate screen, like a full screen program, and gives your terminal back on exit. The agent does not draw on your terminal directly. Its output goes through a terminal emulator, and only the rows that changed are drawn again, below a header that stays at the top. The header shows uuldana-cli, which agent is working, and any warning, such as “PERMISSIONS BYPASSED”. Because the agent’s pseudo terminal is only as tall as the area under the header, an agent that clears the screen or repaints it cannot remove the header.
The header has nine rows when the terminal is at least 34 rows and 62 columns, one row when it has at least 6 rows, and is left out below that.
The /agent menu is drawn in the same area, as a small screen of its own, and the agent’s screen comes back as it was when the menu closes.
Mouse wheel
uuldana-cli captures the mouse, so where the wheel goes depends on what the agent asked for:
| The agent | The wheel does |
|---|---|
| Asked for mouse reports (some agents do) | The agent is sent the wheel and scrolls its own screen. |
| Uses the alternate screen without the mouse | The agent is sent arrow keys. |
| Anything else | The wheel scrolls uuldana-cli’s history of the agent’s output, three rows per click. |
Shift+PageUp and Shift+PageDown scroll that history too, and any other key returns to the live screen. A new agent does not inherit the mouse mode of the one before it. Because the mouse belongs to uuldana-cli, selecting text needs Shift held down while you drag.
Structured modes
Acp describes the Agent Client Protocol. uuldana-cli is the client, not an ACP coding agent. The runtime speaks newline-delimited JSON-RPC over the child’s standard streams, answers permission requests, and maps messages to events. Automatic rules can only reject a permission request, never allow it.
CustomCli describes a documented provider CLI mode, with framing and stdin behavior declared by the plan.
Capability negotiation forces NativeTerminalUi to Unsupported for every transport other than NativePty. Every learned adapter uses the native terminal.
Terminal dimensions
The portable core rule requires non-zero rows and columns. The transport records a ConPTY maximum of 32767 per dimension because the native size uses signed 16-bit fields. An adapter passes the requested size through instead of silently clamping it.
Cleanup
Windows uses ConPTY and bounded process-tree cleanup through patched vendored libraries (portable-pty and subc-jobobject). Native process management is implementation evidence, not a guarantee that every agent’s interface, plugin loading, or resumability has been tested.