Skip to main content

Crate ashlar_control

Crate ashlar_control 

Source
Expand description

Agent control port: a hardened loopback JSON-lines server, its client, and the standard method set every app answers.

 agent / MCP / CLI ──TCP 127.0.0.1──▶ Server (connection threads) ──Request──▶ app thread
                                                                         │ handle(req, dispatch, ui, info)
                     ◀────────── {"id","ok","result"|"error"} ◀──────────┘

The server never touches app state: it parses, authenticates and queues Requests; the app thread answers them with handle (standard app.*/engine.* methods from any ashlar_command::Dispatch, everything else from the app’s UiHandler). The protocol is documented in docs/control-protocol.md.

Modules§

key
The control key: a random secret the app writes to a file only its user can read, and that every request must carry. One rule for the app (which writes it) and the clients (which read it): <dir>/control-key.<instance>, <dir> being a folder the app chooses (its settings folder), <instance> the Flatpak instance id or local-<port>.

Structs§

AppInfo
Who is answering: reported by app.version.
Client
A connection to 127.0.0.1:<port> (the control port is loopback only, so the key never leaves the machine). Reconnects when the app closed the kept connection or restarted (a restart also means a new key, read again from the key file), but only before a request was sent: once any byte of a request reached the socket it is never sent again, so a mutating command cannot run twice when the app dies mid-request.
Config
Server settings. Config::new gives the hardened defaults.
NoUi
No UI: a headless session. ui.* methods are refused with a hint.
Request
One request on its way to the app thread. Answer it with Request::reply (or a shortcut); a request dropped unanswered replies with an error by itself, so the connection never hangs. It may be kept and answered on a later frame (the element is not on screen yet, a screenshot needs the next paint).
Server
A running control server. Dropping it closes the port and every open connection, and removes the key file.

Enums§

ClockOp
What an app.clock request asks for.
ControlError
Why a control-port operation failed.
Reply
One reply. detail carries machine-readable context for an error (a CommandError as JSON, the step results of a failed batch).

Constants§

APP_CLOCK
The clock method. Answered by the windowed runtime (ashlar-app), which lists it in app.version; a headless session refuses it.
DEBUG_METHODS
The debugger vocabulary (element snapshots with refs, actions on targets, waits; see docs/control-protocol.md). Not part of UI_METHODS: a UiHandler reports each one only once it answers it, so clients never list a tool the app cannot serve.
DEFAULT_MAX_LINE
Default longest request line (bytes, without the newline).
MAX_BATCH
Most steps one engine.batch may hold.
MAX_REPLY
Longest reply line accepted (screenshots travel inline as base64).
MAX_STEP_MS
Longest single step_ms: one minute.
PROTOCOL_VERSION
Version of the method vocabulary, reported by app.version. Bumped on incompatible changes.
STANDARD_METHODS
Methods every app answers, headless or not (auth is handled by the transport).
UI_METHODS
The canonical UI vocabulary. A UiHandler answers the ones it supports (and may add more ui.* methods). See docs/control-protocol.md for the parameters.
UI_SCENE
ui.scene {name?}: apply one of the app’s named scenes, or with no name list them ({scenes: [..]}). Answered only by apps that declare scenes.

Traits§

UiHandler
The app’s answer to everything outside STANDARD_METHODS: ui.*, app.quit and any app-specific methods. Implemented by the UI runtime.

Functions§

answer
Answer one request synchronously (headless serving, tests). A request the UI handler keeps for later is answered with an error.
explain
A command’s error as a reply, explained against commands (what the app lists). detail keeps the error’s kind and id; an unknown command adds suggestions ([{id, params}]) and says “did you mean …” in the message, bad parameters add takes (the command’s parameters) and name them in the message unless it already lists them.
explain_reply
explain for a reply that came from elsewhere (a running app, a worker): an error whose detail.kind is unknown or bad_params (or whose message starts with “unknown command”) and that is not explained yet. commands is only called when there is something to explain. Anything else comes back unchanged.
handle
Answer one request on the app thread: standard methods from dispatch, everything else from ui (which may keep the request for a later frame).
matches_query
Whether a command matches a lower-case filter on its id, label or menu path.
serve_stream
Serve the control protocol on a private byte stream (a child’s stdin/stdout) without a key: handle answers each request synchronously. Returns when input ends or sends junk.

Type Aliases§

Wake
Repaint callback: called after a request is queued for the app thread.