PGAP

PGAP (Plexi Generic App Protocol) is the communication layer between app processes and the Plexi host. It runs as newline-delimited JSON over a child process’s stdin/stdout.

How It Works

When you run a Plexi app, the host spawns it as a child process and establishes a bidirectional message channel over stdio. The app sends draw commands describing what to render; the host sends events when the user interacts with the pane.

Host ──render request──► App
Host ◄──draw commands─── App
Host ──input event──────► App

The host owns the render loop. Each frame tick, the host asks each app pane for a fresh set of draw commands and composites them into the UI.

Every message is a JSON object with a type discriminant field. The schema version is 3 — see sdk/protocol/pgap.schema.json for the full machine-readable definition.

Capabilities

Every app declares its capabilities in manifest.toml. The host enforces these at runtime:

[app.capabilities]
capabilities = ["secrets.get", "net.http"]

Capabilities gate PGAP host APIs; they are not a process sandbox and do not restrict what a native Python process can do outside PGAP. The Cap column in the tables below shows which capability is required. Requests without a cap are available to all apps.

Future CPython-in-WASM compatibility work may add a sandboxed Python app route. That is deferred and is not the current SDK v3 execution path.

The Python SDK

The recommended way to write a Plexi app is with the Python SDK. It wraps PGAP into idiomatic Python: define module-level init, update, and view functions, then return effects and component trees. See the SDK reference for the full API.

App → Host Requests

App-to-host requests — go to route_command.

Messages the app sends to request host services.

capability_request

Request a runtime capability prompt. Host shows modal; responds with CapabilityDecision.

FieldTypeRequired
capabilitystringyes
request_idstringyes

secret_get

Request a workspace-scoped secret. Scoped to Init.workspace_root automatically.

FieldTypeRequired
keystringyes

file_read

Read a file through the native ProcessApp host. Requires fs.read and the resolved path must stay inside the app’s w…

Capability: fs.read

FieldTypeRequired
pathstringyes

file_list

List a directory through the native ProcessApp host. Requires fs.read and the resolved path must stay inside the ap…

Capability: fs.read

FieldTypeRequired
extensionsstring[]no
pathstringyes

save_app_state

Save app state. Host writes to workspace or global JSON file.

FieldTypeRequired
payloadanyyes

run_get

Request to start a run. Host surfaces in Run palette (Cmd+R).

FieldTypeRequired
intentstringyes
payloadanyyes

run_complete

Signal that a run the app owns has finished.

FieldTypeRequired
resultanyyes
run_idstringyes

notify

Post a notification. All three action_types must dispatch correctly (no TODO).

FieldTypeRequired
actionsNotificationAction[]no
bodystringyes
image_inlinevariantno
image_pipe_idstring?no
input_promptstring?no
kindNotifyKindno
levelstringyes
notify_idstring?no
on_dismissstring?no
optionsNotifyOption[]no
priorityintegeryes
requiredbooleanno
response_filestring?no
scopevariantno
timeout_secsinteger?no
titlestringyes

set_agent_state

Report agent state for a pane. Called by hook scripts via plexi agent report.

FieldTypeRequired
agentstringyes
detailstring?no
pane_idintegeryes
session_idstring?no
stateAgentStateyes

set_pip_status

Report an app’s own pip status (red/yellow/green) for its activity dot. Fire-and-forget; set by the app process via `…

FieldTypeRequired
pane_idintegerno
statusPipStatusyes

get_agent_states

Get all tracked pane agent states. Writes JSON array to response_file.

FieldTypeRequired
response_filestringyes

pipe_open

Open a typed pipe. mode: “json” | “binary” direction: “in” | “out” | “duplex”

FieldTypeRequired
directionstringyes
modestringyes
pipe_idstringyes

pipe_open_directed

Open a directed JSON pipe to a specific target pane (#286).

FieldTypeRequired
pipe_idstringyes
target_pane_idintegeryes

pipe_send

Send a JSON-mode pipe message (not for binary pipes).

FieldTypeRequired
payloadanyyes
pipe_idstringyes

status_summary

Update the status text shown in the parent pane chrome.

FieldTypeRequired
textstringyes

spawn_app

Request the host to spawn a new app pane. Requires spawn.app capability. layout: “split_h” (new pane right), “spl…

Capability: spawn.app

FieldTypeRequired
argsstring[]no
layoutstring?no
type_idstringyes

spawn_pane

Unified pane spawn primitive (#592). Supersedes SpawnApp for new apps. Requires panes.spawn capability. layout: o…

Capability: panes.spawn

FieldTypeRequired
argsstring[]no
cwdstring?no
ephemeralbooleanno
from_pane_idinteger?no
layoutstring?no
namestring?no
no_focusbooleanno
pathstring?no
pipe_idstring?no
request_idstring?no
response_filestring?no
target_contextinteger?no
type_idstringyes
workspace_rootstring?no

set_pane_title

Set the title displayed on a terminal pane’s tab. Sent by plexi pane set-title over PLEXI_SOCKET.

FieldTypeRequired
namestringyes
pane_idintegeryes

list_panes

List all open panes. Host writes a JSON array to response_file. Sent by plexi pane list.

FieldTypeRequired
context_idinteger?no
response_filestringyes

list_contexts

List all open contexts. Host writes a JSON array to response_file. Sent by plexi context list.

FieldTypeRequired
response_filestringyes

get_pane_info

Query info for a specific pane by ID. Host writes JSON object to response_file. Sent by plexi pane info.

FieldTypeRequired
pane_idintegeryes
response_filestringyes

get_previous_pane_info

Query info for the previously focused pane. Host walks pane_focus_history from the end, finds the Nth live entry, a…

FieldTypeRequired
response_filestringyes
stepsintegerno

list_permissions

List permission state across apps (stint 0017). Gated on permissions.manage when arriving over PGAP. Host writes a …

Capability: permissions.manage

FieldTypeRequired
response_filestringyes

set_permission

Set the stored permission state for an (app, workspace, capability) triple (stint 0017). Gated on `permissions.manage…

Capability: permissions.manage

FieldTypeRequired
app_idstringyes
capabilitystringyes
response_filestringyes
statestringyes
workspacestring?no

slot_write

Write bytes to a named host-managed pane file slot.

FieldTypeRequired
appendbooleanyes
contentinteger[]yes
pane_idintegeryes
replacebooleanyes
response_filestringyes
slot_namestringyes

slot_read

Read raw bytes from a named host-managed pane file slot.

FieldTypeRequired
pane_idintegeryes
response_filestringyes
slot_namestringyes

slot_list

List named host-managed pane file slots.

FieldTypeRequired
pane_idintegeryes
response_filestringyes

slot_delete

Delete a named host-managed pane file slot.

FieldTypeRequired
pane_idintegeryes
response_filestringyes
slot_namestringyes

workspace_clean_slots

Remove slot files for pane ids that are no longer live in any window.

FieldTypeRequired
dry_runbooleanyes
response_filestringyes

focus_pane

Move UI focus to a pane by PaneId. Sent by plexi pane focus. Fire-and-forget.

FieldTypeRequired
pane_idintegeryes

close_pane

Close a pane by PaneId. Sent by plexi pane close. Fire-and-forget.

FieldTypeRequired
pane_idintegeryes

send_to_pane

Write text to a running pane’s PTY stdin. Sent by plexi pane send. \n in text (literal backslash-n) is interprete…

FieldTypeRequired
pane_idintegeryes
response_filestring?no
textstringyes

key_pane

Deliver a synthetic key event to any pane. Sent by plexi pane key. For terminal panes, the key is translated to PTY…

FieldTypeRequired
keystringyes
pane_idintegeryes
response_filestring?no

capture_pane

Read the last N lines from a terminal pane’s PTY scrollback buffer. Sent by plexi pane capture. Host writes a JSON …

FieldTypeRequired
from_cursorinteger?no
full_outputbooleanno
linesintegeryes
pane_idintegeryes
response_filestringyes

get_pane_state

Query the last-rendered UI state of a pane. Sent by plexi pane state. For app panes: host writes a JSON object with…

FieldTypeRequired
pane_idintegeryes
response_filestringyes

send_app_action

Dispatch a semantic action to an app pane. Sent by plexi app action <pane_id> <action> [args...]. Host delivers `Pl…

FieldTypeRequired
actionstringyes
argsstring[]no
pane_idintegeryes
response_filestring?no

create_context

Create a new context. Sent by plexi context new over PLEXI_SOCKET.

FieldTypeRequired
anchor_paneinteger?no
focusbooleanno
namestring?no
parent_namestring?no
portal_directionstring?no
response_filestring?no
rootstring?no
windowsstring[]no

focus_context

Focus existing context by root, or create one. Sent by plexi context open.

FieldTypeRequired
rootstringyes

set_context_root

Set/update the root of a context. Sent by plexi context set-root. context_id targets the caller’s context (PLEXI_…

FieldTypeRequired
context_idinteger?no
rootstringyes

set_context_description

Set/update the description of a context. Sent by plexi context describe. context_id targets the caller’s context …

FieldTypeRequired
context_idinteger?no
descriptionstringyes

zoom_into_context

Zoom into a sub-context. Pushes depth stack. Sent by plexi context zoom.

FieldTypeRequired
context_idintegeryes

zoom_out_of_context

Zoom out of a sub-context. Pops depth stack. Sent by plexi context zoom-out.

No additional fields.

push_pane_to_subcontext

Push a pane into a new sub-context. Sent by plexi context push. pane_id targets the caller’s pane (PLEXI_PANE_ID)…

FieldTypeRequired
namestring?no
pane_idinteger?no

query_context_state

Query the rolled-up ContextState for a context (#1518). The requesting app must be in an ancestor (or the same) con…

FieldTypeRequired
context_idintegeryes

http_request

Host-brokered HTTP request. Requires net.http capability. Host replies with `PlexiEvent::HttpResponse { request_id,…

Capability: net.http

FieldTypeRequired
bodystring?no
headersobjectno
methodstringno
request_idstringyes
urlstringyes

open_url

Open an HTTP(S) URL in the user’s default browser.

FieldTypeRequired
urlstringyes

ai_query

v3.3 brokered AI call. Requires ai.query capability.

Capability: ai.query

FieldTypeRequired
messagesAiMessage[]yes
model_tierModelTieryes
request_idstringyes
systemstringyes
toolsAiTool[]yes

expose_tools

v3.7 tool protocol (#398). App declares its callable tools to the host. The host registers these in the global tool r…

FieldTypeRequired
toolsAiTool[]yes

tool_result

v3.7 tool protocol (#399). App returns the result of a PlexiEvent::ToolCall invocation. call_id must match the `c…

FieldTypeRequired
call_idstringyes
errorstring?no
output_jsonstring?no

mcp_tool_result

App returns the result of a PlexiEvent::McpToolCall invocation. call_id must match the call_id from the `McpToo…

FieldTypeRequired
call_idstringyes
errorstring?no
resultanyno

audio_play

Host-owned audio playback via rodio.

FieldTypeRequired
pipe_idstring?no
sourcestring?no
statestringyes
volumenumberno

audio_capture

Host-owned audio capture: mic PCM delivered on a binary pipe. device_id selects which input device (from `ListAudio…

FieldTypeRequired
buffer_sizeintegeryes
device_idstring?no
pipe_idstringyes
sample_rateintegeryes

list_audio_devices

Request enumeration of audio devices (#277). Host responds with `PlexiEvent::AudioDevicesListed { request_id, inputs,…

FieldTypeRequired
request_idstringyes

list_midi_devices

Request enumeration of MIDI ports (#320). Host responds with `PlexiEvent::MidiDevicesListed { request_id, inputs, out…

FieldTypeRequired
request_idstringyes

open_midi_input

Open a MIDI input port and forward every incoming message as a binary pipe frame on pipe_id. Each frame is a single…

Capability: midi.in

FieldTypeRequired
pipe_idstringyes
port_idstringyes

close_midi_input

Close the MIDI input previously opened on port_id. The host disconnects from the port and closes the associated bin…

FieldTypeRequired
port_idstringyes

send_midi

Send one MIDI 1.0 byte stream to port_id. Fire-and-forget — the host only emits PlexiEvent::MidiSendError if the …

Capability: midi.out

FieldTypeRequired
bytesinteger[]yes
port_idstringyes

open_video

Open a video decoder (#345). The host responds with `PlexiEvent::VideoOpenAck { request_id, handle_id, width, height,…

Capability: video.playback

FieldTypeRequired
pipe_idstringyes
request_idstringyes
sourcestringyes

set_video_state

Drive playback state for a previously-opened video handle (#345). handle_id is the value returned in VideoOpenAck

FieldTypeRequired
handle_idintegeryes
stateVideoStateyes

close_video

Close a previously-opened video handle (#345). Tears down the decoder thread and the associated binary pipe drains. N…

FieldTypeRequired
handle_idintegeryes

cd_request

Request the host to cd all terminals in the same pane group to cwd. Terminals receive cd <cwd>\n written to their…

FieldTypeRequired
cwdstringyes

set_timer

Request a one-shot timer. Requires timer capability. Host fires PlexiEvent::Timer { timer_id } after after_ms m…

Capability: timer

FieldTypeRequired
after_msintegeryes
timer_idstringyes

cancel_timer

Cancel a pending timer. No-op if the timer has already fired or doesn’t exist.

FieldTypeRequired
timer_idstringyes

load_image

Async image fetch brokered through the host. Requires net.http capability. Host fetches src, caches under `handle…

Capability: net.http

FieldTypeRequired
handlestringyes
srcstringyes

request_linked_terminal

Ask the host to open a fresh terminal pane next to this Canvas app and link it. Host responds with `PlexiEvent::Linke…

FieldTypeRequired
cwdstring?no
labelstring?no
request_idstringyes

run_in_linked_terminal

Execute command in a linked terminal pane.

FieldTypeRequired
commandstringyes
echobooleanyes
terminal_pane_idintegeryes

insert_path_token

Insert path into the linked terminal at the cursor position.

FieldTypeRequired
modePathTokenModeyes
pathstringyes
terminal_pane_idintegeryes

request_command_preview

Ask the host to compute the command that would run for a given command string in the linked terminal. Doesn’t execu…

FieldTypeRequired
commandstringyes
request_idstringyes
terminal_pane_idintegeryes

open_artifact

Open a workspace artifact (file or directory) via the host.

FieldTypeRequired
modeArtifactOpenModeyes
pathstringyes

push_nav

App signals it has pushed a navigation level. The host appends the entry to its per-pane nav stack. While the stack h…

FieldTypeRequired
titlestringyes
view_idstringyes

pop_nav

App signals it has popped a navigation level. The host removes the top entry from the per-pane nav stack (saturating …

No additional fields.

set_mouse_tracking

Enable or disable PlexiEvent::MouseMove delivery for this pane.

FieldTypeRequired
enabledbooleanyes

stream_process

Spawn command via sh -c and stream its output back to the app.

FieldTypeRequired
channelStreamChannelyes
commandstringyes
correlation_idstringyes
terminal_pane_idintegeryes

cancel_process

Cancel an in-flight StreamProcess. The host sends SIGTERM to the child, waits up to 1s, then SIGKILL. A `PlexiEvent…

FieldTypeRequired
correlation_idstringyes

open_file_picker

Show a native macOS file picker dialog. Requires fs.pick capability.

Capability: fs.pick

FieldTypeRequired
filterstring[]yes
multiplebooleanyes
request_idstringyes

declare_event_streams

Declare the named event streams this app may emit on. Event names are app-defined but MUST be declared (with a JSON-S…

FieldTypeRequired
streamsEventStreamDecl[]yes

emit_event

Emit a semantic app event into the host timeline.

FieldTypeRequired
actorAppEventActoryes
actor_idstring?no
caused_bystring?no
changed_resourcesstring[]no
eventstringyes
payloadanyno
resource_idstringyes
resource_scopestring?no
revision_afterstringyes
revision_beforestring?no
rollback_tokenstring?no
state_refstring?no
suggested_triggervariantno
summarystringyes

rollback_verify_result

App’s answer to PlexiEvent::RollbackVerify: the current revision of the queried resource. The host compares it agai…

FieldTypeRequired
checkpoint_idstringyes
current_revisionstringyes

subscribe_app_events

Subscribe this pane to another app’s declared event streams. Gated through the unified broker (`TargetType::AppEventS…

FieldTypeRequired
app_idstringyes
event_namesstring[]no
payload_modePayloadModeyes
request_idstringyes
resource_idstring?no
trigger_modeTriggerModeyes

unsubscribe_app_events

Remove a subscription previously created by SubscribeAppEvents. Only the subscriber that owns it may remove it. Fir…

FieldTypeRequired
subscription_idstringyes

list_undo_checkpoints

List undo checkpoints from the host undo timeline, newest first. app_id filters to one app; None = this app’s own…

FieldTypeRequired
app_idstring?no
request_idstringyes

request_rollback

Request rollback of an undo checkpoint. Gated through the unified broker (TargetType::UndoCheckpoint). On allow, th…

FieldTypeRequired
checkpoint_idstringyes

wake

No-op wake. Nudges the (zero-frame-idle) UI thread to run a frame so queued work — spawn-queue files, pane-IPC channe…

No additional fields.

Host → App Events

Messages the host sends to the app.

init

Sent exactly once on startup. App must reply with DrawCommand::Ready.

FieldTypeRequired
app_idstringyes
argsstring[]no
capabilitiesstring[]yes
compact_thresholdnumberno
feature_flagsstring[]yes
heightnumberno
protocolstringyes
regular_thresholdnumberno
stateanyno
themeobjectno
widthnumberno
workspace_rootstringyes

render

Request a new frame. App replies with DrawCommands terminated by FrameDone.

FieldTypeRequired
canvas_heightnumberno
canvas_widthnumberno
frame_idintegeryes
rectRectyes

resize

Surface was resized. App should re-layout and request a new frame.

FieldTypeRequired
heightnumberyes
widthnumberyes

key

User input event.

FieldTypeRequired
keystringyes
modifiersModifiersyes
pressedbooleanyes

click

Mouse click at logical coordinates within the app surface.

FieldTypeRequired
buttonMouseButtonyes
regionstring?no
xnumberyes
ynumberyes

mouse_down

Pointer button pressed (fires on the frame the button goes down).

FieldTypeRequired
buttonMouseButtonyes
modifiersModifiersyes
xnumberyes
ynumberyes

mouse_up

Pointer button released (fires on the frame the button goes up).

FieldTypeRequired
buttonMouseButtonyes
modifiersModifiersyes
xnumberyes
ynumberyes

mouse_move

Pointer moved over the app surface. Only fires when the app has opted in via `DrawCommand::SetMouseTracking { enabled…

FieldTypeRequired
buttonsMouseButton[]yes
modifiersModifiersyes
xnumberyes
ynumberyes

command

User submitted a command via the command bar.

FieldTypeRequired
textstringyes

action

Semantic action dispatched by plexi app action <pane_id> <action> [args...]. Apps receive this in on_event and di…

FieldTypeRequired
actionstringyes
argsstring[]no

capability_decision

Response to a runtime CapabilityRequest.

FieldTypeRequired
capabilitystringyes
grantedbooleanyes
request_idstringyes

secret_value

Secret broker response. value is None when denied.

FieldTypeRequired
keystringyes
valuestring?no

file_read_result

Native ProcessApp file read result.

FieldTypeRequired
contentarray?no
errorstring?no

file_list_result

Native ProcessApp directory listing result.

FieldTypeRequired
entriesarray?no
errorstring?no

run_update

Run lifecycle update from the host.

FieldTypeRequired
payloadanyyes
run_idstringyes
statusstringyes

pipe_message

Typed pipe message (JSON mode only; binary mode travels on the side channel).

FieldTypeRequired
payloadanyyes
pipe_idstringyes

path_changed

Pane group CWD broadcast. Apps in the same group receive this when any member’s CWD changes.

FieldTypeRequired
cwdstringyes

suspend

App is being backgrounded (host window losing focus, app no longer visible).

No additional fields.

resume

App is being foregrounded again.

No additional fields.

shutdown

App is being closed. Process must exit within a short timeout.

No additional fields.

theme

Host theme changed (config hot-reload or macOS system appearance toggle). App should update its color state; the next…

FieldTypeRequired
colorsobjectyes

app_spawned

Confirmation that a SpawnApp request succeeded.

FieldTypeRequired
pane_idintegeryes
type_idstringyes

pane_spawned

Confirmation that a SpawnPane request succeeded (#592).

FieldTypeRequired
pane_idintegeryes
request_idstring?no

pane_spawn_error

SpawnPane could not be fulfilled (#592). reason is a human-readable error.

FieldTypeRequired
reasonstringyes
request_idstring?no

context_state_response

Response to AppRequest::QueryContextState (#1518).

FieldTypeRequired
stateContextStateyes

pipe_opened

Binary pipe opened — app connects to socket_path as a unix socket client.

FieldTypeRequired
pipe_idstringyes
socket_pathstringyes

pipe_overrun

Binary pipe backpressure — host dropped dropped_frames frames from the ring.

FieldTypeRequired
dropped_framesintegeryes
pipe_idstringyes

inject_state

Drop a JSON payload into the app’s on_inject hook. Sent at startup with persisted app state (workspace if available…

FieldTypeRequired
payloadanyyes

render_seed

DEPRECATED: superseded by the state field on Init. Kept for backwards compatibility with older SDK versions. The he…

FieldTypeRequired
payloadanyyes

http_response

Host broker response to a DrawCommand::HttpRequest. error is present when the request failed; body may still ca…

FieldTypeRequired
bodystringyes
errorstring?no
request_idstringyes
statusintegeryes

notify_action

Sent when the user responds to a notification that included a notify_id.

FieldTypeRequired
action_labelstringyes
notify_idstringyes
valuestring?no

timer

Fired when a SetTimer timer expires.

FieldTypeRequired
timer_idstringyes

image_loaded

Fired when a load_image request completes (success or failure). status is “ok” or “error”. message carries the …

FieldTypeRequired
handlestringyes
messagestring?no
statusstringyes

text_measured

Response to a DrawCommand::MeasureText request. width and height are in logical pixels at the requested font size.

FieldTypeRequired
heightnumberyes
request_idstringyes
widthnumberyes

text_wrapped_measured

Response to a ControlCommand::MeasureTextWrapped request. height is the pixel height of the text when wrapped at …

FieldTypeRequired
heightnumberyes
request_idstringyes

paste

Clipboard paste forwarded into the focused app pane.

FieldTypeRequired
textstringyes

ai_response

Response to a DrawCommand::AiQuery. Either content is Some (success) or error is Some (failure) — the two a…

FieldTypeRequired
contentstring?no
errorstring?no
request_idstringyes
tokens_inintegeryes
tokens_outintegeryes

ai_stream_chunk

Incremental token chunk from a streaming ai_query response. Sent live while the turn runs, before the final `AiRespon…

FieldTypeRequired
deltastringyes
donebooleanno
reasoningstring?no
request_idstringyes

tool_call

Host-to-app tool invocation (#399). The broker calls a tool exposed via DrawCommand::ExposeTools by sending this ev…

FieldTypeRequired
call_idstringyes
caller_idstringyes
input_jsonstringyes
namestringyes

mcp_tool_call

External MCP client called a tool declared in [app.mcp]. The app must reply with `DrawCommand::Host(AppRequest::Mcp…

FieldTypeRequired
argumentsanyyes
call_idstringyes
tool_namestringyes

audio_devices_listed

Response to a DrawCommand::ListAudioDevices request (#277). Both vectors are always present — empty when enumeratio…

FieldTypeRequired
errorstring?no
inputsAudioDeviceWire[]yes
outputsAudioDeviceWire[]yes
request_idstringyes

audio_capture_started

Sent when a DrawCommand::AudioCapture successfully opened the device and started delivering PCM frames on pipe_id

FieldTypeRequired
buffer_sizeintegeryes
channelsintegeryes
device_namestringyes
pipe_idstringyes
sample_rateintegeryes

audio_capture_error

Sent when a DrawCommand::AudioCapture could not be honoured — permission denied, bad device id, no devices, cpal fa…

FieldTypeRequired
errorstringyes
pipe_idstringyes

midi_devices_listed

Response to a DrawCommand::ListMidiDevices request (#320). Both vectors are always present — empty when CoreMIDI fi…

FieldTypeRequired
errorstring?no
inputsMidiPortWire[]yes
outputsMidiPortWire[]yes
request_idstringyes

midi_input_opened

Sent when a DrawCommand::OpenMidiInput successfully opened the port and started forwarding incoming MIDI byte strea…

FieldTypeRequired
pipe_idstringyes
port_idstringyes
port_namestringyes

midi_input_error

Sent when DrawCommand::OpenMidiInput could not be honoured — permission denied, port not found, CoreMIDI failure.

FieldTypeRequired
errorstringyes
pipe_idstringyes

midi_send_error

Sent when DrawCommand::SendMidi could not be honoured. Successful sends produce no event (fire-and-forget); only fa…

FieldTypeRequired
errorstringyes
port_idstringyes

video_open_ack

Sent when a DrawCommand::OpenVideo succeeded (#345). The host has allocated the binary pipe (look for the preceding…

FieldTypeRequired
duration_msintegeryes
fpsnumberyes
handle_idintegeryes
heightintegeryes
request_idstringyes
widthintegeryes

video_open_error

Sent when DrawCommand::OpenVideo could not be honoured (#345) — capability denied, source not found, decoder error,…

FieldTypeRequired
errorstringyes
request_idstringyes

linked_terminal_ready

Response to DrawCommand::RequestLinkedTerminal (#78). Carries the pane id of the freshly-opened terminal so subsequ…

FieldTypeRequired
request_idstringyes
terminal_pane_idintegeryes

command_preview

Response to DrawCommand::RequestCommandPreview (#78). Returns the command verbatim plus the linked terminal’s curre…

FieldTypeRequired
commandstringyes
request_idstringyes
would_run_in_cwdstringyes

Emitted by host to app when Escape is pressed and the app’s nav stack depth is > 0. The app handles this by popping i…

FieldTypeRequired
view_idstringyes

file_picked

Response to DrawCommand::OpenFilePicker. At least one file was selected. paths contains the absolute paths chosen…

FieldTypeRequired
pathsstring[]yes
request_idstringyes

file_pick_cancelled

Response to DrawCommand::OpenFilePicker when the user cancelled the dialog without selecting a file, or the app lac…

FieldTypeRequired
request_idstringyes

stream_chunk

Chunk of stdout/stderr bytes from an active DrawCommand::StreamProcess child. bytes is a raw byte array (values 0…

FieldTypeRequired
bytesinteger[]yes
channelStreamChannelyes
correlation_idstringyes

stream_end

Terminal event for a DrawCommand::StreamProcess child. Sent when the child exits, on CancelProcess, or on capabil…

FieldTypeRequired
correlation_idstringyes
exit_codeintegeryes

scroll_offset

Emitted by the host when the scroll offset for a BeginScroll region changes (mouse wheel, drag). The app should re-…

FieldTypeRequired
idstringyes
offset_ynumberyes

scroll

Emitted when the mouse wheel moves over an app pane that has no host-managed scroll region or list_view under the cur…

FieldTypeRequired
delta_ynumberyes

list_select

Emitted when j/k/up/down changes the list selection. id matches the list_view id field; index is the new select…

FieldTypeRequired
idstringyes
indexintegeryes

list_activate

Emitted when Enter is pressed on the selected item. id matches the list_view id field; index is the activated i…

FieldTypeRequired
idstringyes
indexintegeryes

component_event

Fired when a user interacts with a node that has Interactive wrapping or when a Button/Input node is activated.

FieldTypeRequired
event_typestringyes
node_idstringyes
payloadanyno

rollback_verify

Host asks the app whether resource_id is still at expected_revision before rolling back a checkpoint. The app mus…

FieldTypeRequired
checkpoint_idstringyes
expected_revisionstringyes
resource_idstringyes

rollback_apply

Host instructs the app to roll resource_id back using the rollback_token the app supplied when it emitted the rev…

FieldTypeRequired
checkpoint_idstringyes
resource_idstringyes
rollback_tokenstringyes

app_events_subscribed

Response to AppRequest::SubscribeAppEvents. Exactly one of subscription_id / error is set.

FieldTypeRequired
errorstring?no
request_idstringyes
subscription_idstring?no

app_event

One subscribed app event, delivered to the subscriber pane. Content beyond the event identity is shaped by the subscr…

FieldTypeRequired
app_idstringyes
created_atstringyes
eventstringyes
event_idintegeryes
payloadanyno
resource_idstringyes
state_refstring?no
subscription_idstringyes
summarystring?no
trigger_modeTriggerModeyes

undo_checkpoints

Response to AppRequest::ListUndoCheckpoints: undo checkpoints, newest first, serialized with the spec’s checkpoint …

FieldTypeRequired
checkpointsany[]yes
request_idstringyes

Render Commands

Render primitives — go to pending_frame → drawn to screen.

Draw primitives the app emits each frame.

push_clip

Push a clip rect onto the host’s clip stack.

FieldTypeRequired
hnumberyes
wnumberyes
xnumberyes
ynumberyes

pop_clip

Pop the most recently pushed clip rect from the stack.

No additional fields.

rect

Fill a rectangle.

FieldTypeRequired
fillstringyes
glow_colorstring?no
glow_radiusnumberno
gradientvariantno
hnumberyes
hit_regionstring?no
radiusnumberno
strokestring?no
stroke_widthnumberno
wnumberyes
xnumberyes
ynumberyes

text

Draw text at a position.

FieldTypeRequired
alignTextAlignno
boldbooleanno
colorstringyes
elidebooleanyes
hit_regionstring?no
max_linesinteger?no
max_widthnumber?no
monospacebooleanno
selectablebooleanyes
sizenumberyes
textstringyes
xnumberyes
ynumberyes

line

Draw a line segment.

FieldTypeRequired
colorstringyes
widthnumberno
x1numberyes
x2numberyes
y1numberyes
y2numberyes

circle

Draw a filled circle. Alpha is supported via 8-digit hex fill (#rrggbbaa).

FieldTypeRequired
cxnumberyes
cynumberyes
fillstringyes
glow_colorstring?no
glow_radiusnumberno
rnumberyes
strokestring?no
stroke_widthnumberno

arc

Draw a filled arc / pie slice. start_angle and end_angle are in radians, measured clockwise from the right (east)…

FieldTypeRequired
cxnumberyes
cynumberyes
end_anglenumberyes
fillstringyes
rnumberyes
start_anglenumberyes

arc_ring

Draw a stroked arc ring (hollow donut arc). Distinct from Arc (filled pie).

FieldTypeRequired
colorstringyes
cxnumberyes
cynumberyes
end_anglenumberyes
rnumberyes
start_anglenumberyes
stroke_widthnumberno

list

High-level scrollable list — host handles layout and scrolling.

FieldTypeRequired
hnumberno
item_heightnumberno
itemsListItem[]yes
selectedintegeryes
wnumberno
xnumberno
ynumberno

list_view

Host-native scrollable list with j/k navigation, typed row slots, and built-in loading/error/empty states. Host emits…

FieldTypeRequired
errorstring?no
hnumberno
idstringyes
itemsListViewItem[]yes
loadingbooleanno
selectedintegerno
wnumberno
xnumberno
ynumberno

badge

Host-rendered pill badge. The host measures the label with real font metrics, sizes the pill (text_w + padding), and …

FieldTypeRequired
fgstringyes
fillstringyes
font_sizenumberyes
labelstringyes
radiusnumberyes
xnumberyes
ynumberyes

key_chip

Host-rendered keycap chip. The host measures the label with real monospace font metrics, sizes the chip, and centres …

FieldTypeRequired
font_sizenumberyes
labelstringyes
xnumberyes
ynumberyes

key_chip_row

A horizontal row of keycap chips. The host flows them left-to-right with a fixed 2px gap between chips, sizes each ch…

FieldTypeRequired
descriptionstring?no
font_sizenumberyes
keysstring[]yes
xnumberyes
ynumberyes

shortcuts

A multi-group shortcut row. The host owns all layout — chip widths from real font metrics, flow horizontally with con…

FieldTypeRequired
alignShortcutsAlignno
font_sizenumberyes
max_widthnumberyes
pairsShortcutPair[]yes
xnumberyes
ynumberyes

text_row

Multiple text segments rendered horizontally with host-measured layout. The host measures each segment with real font…

FieldTypeRequired
alignTextAlignno
gapnumberyes
itemsTextRowItem[]yes
xnumberyes
ynumberyes

markdown

Render markdown text using the host’s egui_commonmark renderer.

FieldTypeRequired
base_sizenumberyes
colorstringyes
textstringyes
wnumberyes
xnumberyes
ynumberyes

image

Draw an image from a workspace-scoped path or data URL.

FieldTypeRequired
fitstringno
hnumberyes
srcstringyes
wnumberyes
xnumberyes
ynumberyes

avatar

Circular clipped image. src accepts a load_image handle (UUID) or local path. cx, cy are the circle centre in p…

FieldTypeRequired
cxnumberyes
cynumberyes
radiusnumberyes
srcstringyes

skeleton

Animated shimmer placeholder rect for loading states. The host drives a subtle pulsing animation at ~20fps using requ…

FieldTypeRequired
hnumberyes
radiusnumberno
wnumberyes
xnumberyes
ynumberyes

audio_meter

Render an amplitude meter reading from a binary pipe.

FieldTypeRequired
pipe_idstringyes
rectRectyes

begin_scroll

Begin a host-managed vertical scroll region.

FieldTypeRequired
content_heightnumberyes
hnumberyes
idstringyes
wnumberyes
xnumberyes
ynumberyes

end_scroll

Close the most recently opened scroll region.

No additional fields.

layout

Declarative flex layout tree. The host resolves all positions using taffy (flexbox) and real egui font metrics before…

FieldTypeRequired
childrenLayoutChild[]yes
directionLayoutDirectionyes
gapnumberno
xnumberyes
ynumberyes

responsive

Responsive layout — host picks the matching tier based on available rect aspect ratio.

FieldTypeRequired
tiersResponsiveTier[]yes
xnumberyes
ynumberyes

component_tree

Component tree — host renders via render_component_tree(). Added in PGAP v3.5. Host logs a warning and drops if it do…

FieldTypeRequired
rootUiNodeyes

Control Commands

Inline-handled commands (processed directly in ui() or background_tick()).

Inline commands processed outside the render loop.

ready

SDK ready handshake. Sent once by the app after receiving Init. Host captures sdk and features_used; the message is o…

FieldTypeRequired
features_usedstring[]no
protocol_versionstringno
sdkstringno

frame_done

End of frame. Host renders everything queued since last FrameDone.

FieldTypeRequired
frame_idintegeryes

log

Forward a log message into Plexi’s logger (tagged with app_id).

FieldTypeRequired
levelstringyes
messagestringyes

fatal_error

Terminal SDK failure with traceback text. Sent before the app exits nonzero so the host never has to infer Python hoo…

FieldTypeRequired
messagestringyes
tracebackstringyes

schedule_render

Ask the host to trigger a new Render event after after_ms milliseconds. Intended for game loops and animations — em…

FieldTypeRequired
after_msintegeryes

set_scheduler_mode

Declare app render cadence so the host owns recurring animation ticks. mode="idle" disables recurring renders, `mod…

FieldTypeRequired
fpsinteger?no
modestringyes

copy_to_clipboard

Write text to the OS clipboard.

FieldTypeRequired
textstringyes

measure_text

Request a one-shot text measurement. The host measures text at font_size with the proportional font and replies i…

FieldTypeRequired
font_sizenumberyes
monospacebooleanno
request_idstringyes
textstringyes

measure_text_wrapped

Measure the height of text wrapped at max_width using real host font metrics. If max_lines is Some(n), clamps t…

FieldTypeRequired
font_sizenumberyes
max_linesinteger?no
max_widthnumberyes
request_idstringyes
textstringyes

set_min_size

Override the manifest-declared minimum size at runtime. Stored by the host and used as the live effective minimum fro…

FieldTypeRequired
heightnumberyes
widthnumberyes

close_self

Request the host to close this app’s pane gracefully. The host closes the pane on the next frame via the wants_close …

No additional fields.

set_title

Set the display name (tab title) of this app’s own pane. Emitted by the SDK v3 runtime when the app calls `emit.set_t…

FieldTypeRequired
titlestringyes