Clients
Docs/Extend/Clients
docs-site/extend/clients.md

A client is what draws a session: the terminal UI, the ADE's chat, a web page. In Orrery a client is an extension. The default terminal UI (ratatui) is one, installed by default; Ink is another; yours can be a third.

The harness declares the whole UI as one tree of nodes over AG-UI: layout, banner, thread, dock, input, footer. Every client draws that tree with the same elements, so every harness looks right in every client.

Choosing a client

In order:

  1. --ui <id>;
  2. [ui] default = "<id>" in config;
  3. the first installed client whose role fits: human at a terminal, machine down a pipe.

--json is not a client: it is the kernel's own machine output.

An id nothing registered is an error that lists the clients there are.

Write one

A client is a [[provides.clients]] entry in a manifest. One package can ship a client, tools and elements together:

[extension]
api = "orrery-ext/1"
name = "example-client"
version = "0.1.0"
runtime = "node"

[[provides.clients]]
id       = "example"
label    = "Example (plain text)"
role     = "named"            # human | machine | named
entry    = "client.mjs"
fixtures = "fixtures"
draws    = ["layout", "banner", "thread", "message", "dock", "input", "footer", "status",
            "fullscreen", "overlay", "consent", "trust", "toast", "retry", "update",
            "exit", "notify", "mode"]

[grants]
client = ["draw", "consent", "tty"]
orrery install ./example-client
orrery --ui example

In Node, defineClient from @getorrery/ext handles the channel. The host starts the client with the channel in ORRERY_ENDPOINT and a one-time secret in ORRERY_TOKEN; the client speaks orrery-client/1: frames in, intents out.

The full worked example is harness/extensions/examples/node-client.

What a client must draw

draws is the complete list of elements the client implements. Every Tier 1 element is required:

layout, banner, thread, message, input, footer, status, overlay, dock, consent, trust, toast, retry, update, exit, notify, mode.

A client missing any of them is refused at orrery install and again at attach, with an error naming the element to implement. There is no fallback and no warn-and-continue. Other elements are optional.

Prove it with fixtures

With fixtures = "<dir>", orrery install starts the client in probe mode (ORRERY_CONFORMANCE=1) and sends one JSON line per case. The client answers { "element", "case", "ok" } for each. A failed required element refuses the install.

Grants

GrantLets the client
drawReceive frames and send intents.
consentAnswer consent prompts. Only a client that draws consent and holds this grant may answer.
ttyTake the terminal.
handoffMove a session to another machine.

An administrator can take a grant away from every client: [ui] refuse_grants = ["consent"] in the managed layer.

A client over the network

A client that connects to orrery serve or a node over HTTP or WebSocket has no manifest. It declares what it draws when it attaches: ?client=<name>&draws=<id>,<id>,.... One that declares nothing can watch but cannot answer consent. See The wire protocol.