Skip to Content
Docs

Protocol

How the desktop talks to an app's Python, line by line.

View as Markdown

Protocol 1 between the desktop and an app's Python worker: NDJSON on stdin and stdout, one object per line, at most 1 MiB. Host call ids (id) and worker request ids (rid) are separate spaces. Generates docs/protocol.md and the TypeScript message types.

Worker to Mixel

typeFieldsNotes
ready{protocol, sdk, actions: [ActionSpec], permissions: [code]}First line. The host refuses the worker if it uses a permission app.json doesn't declare.
fatal{error: Error}The app could not load. The worker exits.
progress`{id, fraction: numbernull, label}`
event{id, name, body}From ox.emit. The host forwards it to the page that made call id.
result{id, body}What the action returned, as JSON. Exports become {items: [Item]}.
error{id, error: Error}Codes: bad_input, problem, cancelled (with kept), crashed.
library{rid, op: "add", kind, path, title, metadata}Add a file to the Library. Answered by library-result.
cloud{rid, method, path, body}An allow-listed cloud call. The token never reaches the worker.

Mixel to worker

typeFieldsNotes
call{id, action, input, handed?: [path]}Run an action. The host has already checked input against its schema. handed lists the input files the person gave with Open with: the app may read them, not write next to them (ox.beside is None).
cancel{id}Stop: the action's next ox.progress raises ox.Cancelled.
library-result{rid, status, body}The answer to a library request.
cloud-result{rid, status, body}The answer to a cloud request.
shutdown{}Finish, then exit. The host kills the worker after 3 s.

Types

  • ActionSpec = {name, title, input: JSON Schema object whose properties carry "x-ox": {control, accept?, multiple?, label?, placeholder?, step?, unit?, origin?}, timeout: seconds}. A slider on an array of 2 numbers is a range: [start, end]. origin is a slider's no-change value when it isn't the minimum: the track fills from it.
  • Error = {code, message, hint?, detail?, kept?: [Item]}
  • Item = {id, kind: sound | midi | other, title, path}

Limits: a line or a result is at most 1 MiB, an event body 256 KiB; progress is coalesced to 20 a second.

On this page