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 on top of the sandbox, not instead of it: every
app — Python or Rust — runs as a WASM component in its own wasmtime::Store, so
there is no ambient process access outside PGAP to restrict. The Cap column
in the tables below shows which capability is required. Requests without a cap
are available to all apps.
The Python SDK
The recommended way to write a Plexi app is with the Python SDK. It wraps
PGAP into idiomatic Python — subclass App, implement view(), and return
a component tree. 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.
| Field | Type | Required |
|---|---|---|
capability | string | yes |
request_id | string | yes |
secret_get
Request a workspace-scoped secret. Scoped to Init.workspace_root automatically.
| Field | Type | Required |
|---|---|---|
key | string | yes |
file_read
Read a file through the native WASM app runtime host. Requires fs.read and the resolved path must stay inside the a…
Capability: fs.read
| Field | Type | Required |
|---|---|---|
path | string | yes |
file_list
List a directory through the native WASM app runtime host. Requires fs.read and the resolved path must stay inside …
Capability: fs.read
| Field | Type | Required |
|---|---|---|
extensions | string[] | no |
path | string | yes |
save_app_state
Save app state. Host writes to workspace or global JSON file.
| Field | Type | Required |
|---|---|---|
payload | any | yes |
run_get
Request to start a run. Host surfaces in Run palette (Cmd+R).
| Field | Type | Required |
|---|---|---|
intent | string | yes |
payload | any | yes |
run_complete
Signal that a run the app owns has finished.
| Field | Type | Required |
|---|---|---|
result | any | yes |
run_id | string | yes |
notify
Post a notification. All three action_types must dispatch correctly (no TODO).
| Field | Type | Required |
|---|---|---|
actions | NotificationAction[] | no |
body | string | yes |
image_inline | variant | no |
image_pipe_id | string? | no |
input_prompt | string? | no |
kind | NotifyKind | no |
level | string | yes |
notify_id | string? | no |
on_dismiss | string? | no |
options | NotifyOption[] | no |
priority | integer | yes |
required | boolean | no |
response_file | string? | no |
scope | variant | no |
source_context_id | integer? | no |
source_pane_id | integer? | no |
timeout_secs | integer? | no |
title | string | yes |
dismiss_notification
Remove a notification posted by the caller. The host verifies the caller identity against the notification’s stamped …
| Field | Type | Required |
|---|---|---|
notify_id | string | yes |
response_file | string | yes |
source_context_id | integer? | no |
source_pane_id | integer? | no |
set_agent_state
Report agent state for a pane. Called by hook scripts via plexi agent report.
| Field | Type | Required |
|---|---|---|
agent | string | yes |
detail | string? | no |
pane_id | integer | yes |
session_id | string? | no |
state | AgentState | yes |
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 `…
| Field | Type | Required |
|---|---|---|
pane_id | integer | no |
status | PipStatus | yes |
get_agent_states
Get all tracked pane agent states. Writes JSON array to response_file.
| Field | Type | Required |
|---|---|---|
response_file | string | yes |
pipe_open
Open a typed pipe. mode: “json” | “binary” direction: “in” | “out” | “duplex”
| Field | Type | Required |
|---|---|---|
direction | string | yes |
mode | string | yes |
pipe_id | string | yes |
pipe_open_directed
Open a directed JSON pipe to a specific target pane (#286).
| Field | Type | Required |
|---|---|---|
pipe_id | string | yes |
target_pane_id | integer | yes |
pipe_send
Send a JSON-mode pipe message (not for binary pipes).
| Field | Type | Required |
|---|---|---|
payload | any | yes |
pipe_id | string | yes |
status_summary
Update the status text shown in the parent pane chrome.
| Field | Type | Required |
|---|---|---|
text | string | yes |
log_marker
Write one info-level marker line into the running host’s channel log (~/.plexi-<channel>/plexi.log). Sent by `plexi…
| Field | Type | Required |
|---|---|---|
message | string | yes |
response_file | string? | no |
source | string | yes |
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
| Field | Type | Required |
|---|---|---|
args | string[] | no |
layout | string? | no |
type_id | string | yes |
spawn_pane
Unified pane spawn primitive (#592). Supersedes SpawnApp for new apps. Requires panes.spawn capability. layout: o…
Capability: panes.spawn
| Field | Type | Required |
|---|---|---|
agent_cmd | string? | no |
args | string[] | no |
boot_timeout_secs | number? | no |
context_name | string? | no |
cwd | string? | no |
ephemeral | boolean | no |
from_pane_id | integer? | no |
layout | string? | no |
name | string? | no |
no_focus | boolean | no |
path | string? | no |
request_id | string? | no |
response_file | string? | no |
target_context | integer? | no |
type_id | string | yes |
workspace_root | string? | no |
set_pane_title
Set the title displayed on a terminal pane’s tab. Sent by plexi pane set-title over PLEXI_SOCKET.
| Field | Type | Required |
|---|---|---|
name | string | yes |
pane_id | integer | yes |
list_panes
List all open panes. Host writes a JSON array to response_file. Sent by plexi pane list.
| Field | Type | Required |
|---|---|---|
context_id | integer? | no |
response_file | string | yes |
list_contexts
List all open contexts. Host writes a JSON array to response_file. Sent by plexi context list.
| Field | Type | Required |
|---|---|---|
response_file | string | yes |
get_pane_info
Query info for a specific pane by ID. Host writes JSON object to response_file. Sent by plexi pane info.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
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…
| Field | Type | Required |
|---|---|---|
response_file | string | yes |
steps | integer | no |
list_permissions
List permission state across apps (stint 0017). Gated on permissions.manage when arriving over PGAP. Host writes a …
Capability: permissions.manage
| Field | Type | Required |
|---|---|---|
response_file | string | yes |
set_permission
Set the stored permission state for an (app, workspace, capability) triple (stint 0017). Gated on `permissions.manage…
Capability: permissions.manage
| Field | Type | Required |
|---|---|---|
app_id | string | yes |
capability | string | yes |
response_file | string | yes |
state | string | yes |
workspace | string? | no |
slot_write
Write bytes to a named host-managed pane file slot.
| Field | Type | Required |
|---|---|---|
append | boolean | yes |
content | integer[] | yes |
pane_id | integer | yes |
replace | boolean | yes |
response_file | string | yes |
slot_name | string | yes |
slot_read
Read raw bytes from a named host-managed pane file slot.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
slot_name | string | yes |
slot_wait
Block until a named pane file slot’s value matches pattern.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
pattern | string | yes |
response_file | string | yes |
slot_name | string | yes |
timeout_secs | number | yes |
slot_list
List named host-managed pane file slots.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
slot_delete
Delete a named host-managed pane file slot.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
slot_name | string | yes |
workspace_clean_slots
Remove slot files for pane ids that are no longer live in any window.
| Field | Type | Required |
|---|---|---|
dry_run | boolean | yes |
response_file | string | yes |
focus_pane
Move UI focus to a pane by PaneId. Sent by plexi pane focus. Fire-and-forget.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
close_pane
Close a pane by PaneId. Sent by plexi pane close. Fire-and-forget.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
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…
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string? | no |
submit | boolean | no |
text | string | yes |
pane_heartbeat
Configure or disable a host-owned recurring terminal prompt.
| Field | Type | Required |
|---|---|---|
every_ms | integer? | no |
off | boolean | no |
pane_id | integer | yes |
response_file | string? | no |
text | string? | no |
while_idle_only | boolean? | no |
key_pane
Deliver a synthetic key event to any pane. Sent by plexi pane key. For terminal panes, the key is translated to PTY…
| Field | Type | Required |
|---|---|---|
key | string | yes |
pane_id | integer | yes |
response_file | string? | no |
drop_file
Deliver a local path or image URL to the pane through the same production drop handler used by native host drops.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
path_or_url | string | yes |
response_file | string | yes |
click_pane
Deliver a synthetic pointer click to an app pane, in pane-pixel coordinates (origin at the pane’s top-left). Sent by …
| Field | Type | Required |
|---|---|---|
button | string? | no |
pane_id | integer | yes |
response_file | string? | no |
x | number | yes |
y | number | yes |
click_pane_node
Deliver a synthetic click to an app pane by node id, activating the Button/TextInput/ListView node the id names — the…
| Field | Type | Required |
|---|---|---|
button | string? | no |
node_id | string | yes |
pane_id | integer | yes |
response_file | string? | no |
drag_pane
Deliver a sanctioned pointer drag to an app pane: press at from, steps intermediate PointerMoved positions, rel…
| Field | Type | Required |
|---|---|---|
button | string? | no |
from | array? | no |
from_node | string? | no |
pane_id | integer | yes |
response_file | string? | no |
steps | integer? | no |
to | array? | no |
to_node | string? | 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 …
| Field | Type | Required |
|---|---|---|
from_cursor | integer? | no |
full_output | boolean | no |
lines | integer | yes |
pane_id | integer | yes |
response_file | string | yes |
pane_status
Derive one auditable working/idle/blocked verdict from the pane’s agent detector, TUI status bar, and trailing termin…
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
get_pane_state
Query the last-rendered UI state of a pane. Sent by plexi pane state. For app panes: host writes a versioned `seman…
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
response_file | string | yes |
screenshot
Capture the live host window as a PNG through the real render pipeline (egui::ViewportCommand::Screenshot — actual …
| Field | Type | Required |
|---|---|---|
output_path | string | yes |
pane_id | integer? | no |
response_file | string | yes |
send_app_action
Dispatch a semantic action to an app pane. Sent by plexi app action <pane_id> <action> [args...]. Host delivers `Pl…
| Field | Type | Required |
|---|---|---|
action | string | yes |
args | string[] | no |
pane_id | integer | yes |
response_file | string? | no |
create_context
Create a new context. Sent by plexi context new over PLEXI_SOCKET.
| Field | Type | Required |
|---|---|---|
anchor_pane | integer? | no |
focus | boolean | no |
name | string? | no |
parent_context_id | integer? | no |
parent_name | string? | no |
portal_direction | string? | no |
response_file | string? | no |
root | string? | no |
windows | string[] | no |
create_sub_context
Create a sub-context under the caller’s context, pre-populated with a squad of terminal panes in a single window. Sen…
| Field | Type | Required |
|---|---|---|
anchor_pane | integer? | no |
focus | boolean | no |
layout | SubContextLayout | no |
name | string | yes |
panes | string?[] | yes |
parent_context_id | integer? | no |
parent_name | string? | no |
response_file | string? | no |
root | string | yes |
focus_context
Focus existing context by root, or create one. Sent by plexi context open.
| Field | Type | Required |
|---|---|---|
root | string | yes |
set_context_root
Set/update the root of a context. Sent by plexi context set-root. context_id targets the caller’s context (PLEXI_…
| Field | Type | Required |
|---|---|---|
context_id | integer? | no |
root | string | yes |
set_context_description
Set/update the description of a context. Sent by plexi context describe. context_id targets the caller’s context …
| Field | Type | Required |
|---|---|---|
context_id | integer? | no |
description | string | yes |
zoom_into_context
Zoom into a sub-context. Pushes depth stack. Sent by plexi context zoom.
| Field | Type | Required |
|---|---|---|
context_id | integer | yes |
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)…
| Field | Type | Required |
|---|---|---|
name | string? | no |
pane_id | integer? | 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…
| Field | Type | Required |
|---|---|---|
context_id | integer | yes |
http_request
Host-brokered HTTP request. Requires net.http capability. Host replies with `PlexiEvent::HttpResponse { request_id,…
Capability: net.http
| Field | Type | Required |
|---|---|---|
body | string? | no |
headers | object | no |
method | string | no |
request_id | string | yes |
url | string | yes |
open_url
Open an HTTP(S) URL in the user’s default browser.
| Field | Type | Required |
|---|---|---|
url | string | yes |
ai_query
v3.3 brokered AI call. Requires ai.query capability.
Capability: ai.query
| Field | Type | Required |
|---|---|---|
messages | AiMessage[] | yes |
model_tier | ModelTier | yes |
request_id | string | yes |
system | string | yes |
tools | AiTool[] | 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…
| Field | Type | Required |
|---|---|---|
tools | AiTool[] | yes |
tool_result
v3.7 tool protocol (#399). App returns the result of a PlexiEvent::ToolCall invocation. call_id must match the `c…
| Field | Type | Required |
|---|---|---|
call_id | string | yes |
error | string? | no |
output_json | string? | no |
mcp_tool_result
App returns the result of a PlexiEvent::McpToolCall invocation. call_id must match the call_id from the `McpToo…
| Field | Type | Required |
|---|---|---|
call_id | string | yes |
error | string? | no |
result | any | no |
audio_play
Host-owned audio playback via rodio.
| Field | Type | Required |
|---|---|---|
pipe_id | string? | no |
source | string? | no |
state | string | yes |
volume | number | no |
audio_capture
Host-owned audio capture: mic PCM delivered on a binary pipe. device_id selects which input device (from `ListAudio…
| Field | Type | Required |
|---|---|---|
buffer_size | integer | yes |
device_id | string? | no |
pipe_id | string | yes |
sample_rate | integer | yes |
list_audio_devices
Request enumeration of audio devices (#277). Host responds with `PlexiEvent::AudioDevicesListed { request_id, inputs,…
| Field | Type | Required |
|---|---|---|
request_id | string | yes |
list_midi_devices
Request enumeration of MIDI ports (#320). Host responds with `PlexiEvent::MidiDevicesListed { request_id, inputs, out…
| Field | Type | Required |
|---|---|---|
request_id | string | yes |
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
| Field | Type | Required |
|---|---|---|
pipe_id | string | yes |
port_id | string | yes |
close_midi_input
Close the MIDI input previously opened on port_id. The host disconnects from the port and closes the associated bin…
| Field | Type | Required |
|---|---|---|
port_id | string | yes |
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
| Field | Type | Required |
|---|---|---|
bytes | integer[] | yes |
port_id | string | yes |
open_video
Open a video decoder (#345). The host responds with `PlexiEvent::VideoOpenAck { request_id, handle_id, width, height,…
Capability: video.playback
| Field | Type | Required |
|---|---|---|
pipe_id | string | yes |
request_id | string | yes |
source | string | yes |
set_video_state
Drive playback state for a previously-opened video handle (#345). handle_id is the value returned in VideoOpenAck…
| Field | Type | Required |
|---|---|---|
handle_id | integer | yes |
state | VideoState | yes |
close_video
Close a previously-opened video handle (#345). Tears down the decoder thread and the associated binary pipe drains. N…
| Field | Type | Required |
|---|---|---|
handle_id | integer | yes |
cd_request
Request the host to cd all terminals in the same pane group to cwd. Terminals receive cd <cwd>\n written to their…
| Field | Type | Required |
|---|---|---|
cwd | string | yes |
set_timer
Request a one-shot timer. Requires timer capability. Host fires PlexiEvent::Timer { timer_id } after after_ms m…
Capability: timer
| Field | Type | Required |
|---|---|---|
after_ms | integer | yes |
timer_id | string | yes |
cancel_timer
Cancel a pending timer. No-op if the timer has already fired or doesn’t exist.
| Field | Type | Required |
|---|---|---|
timer_id | string | yes |
load_image
Async image fetch brokered through the host. Requires net.http capability. Host fetches src, caches under `handle…
Capability: net.http
| Field | Type | Required |
|---|---|---|
handle | string | yes |
src | string | yes |
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…
| Field | Type | Required |
|---|---|---|
cwd | string? | no |
label | string? | no |
request_id | string | yes |
run_in_linked_terminal
Execute command in a linked terminal pane.
| Field | Type | Required |
|---|---|---|
command | string | yes |
echo | boolean | yes |
terminal_pane_id | integer | yes |
insert_path_token
Insert path into the linked terminal at the cursor position.
| Field | Type | Required |
|---|---|---|
mode | PathTokenMode | yes |
path | string | yes |
terminal_pane_id | integer | yes |
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…
| Field | Type | Required |
|---|---|---|
command | string | yes |
request_id | string | yes |
terminal_pane_id | integer | yes |
open_artifact
Open a workspace artifact (file or directory) via the host.
| Field | Type | Required |
|---|---|---|
mode | ArtifactOpenMode | yes |
path | string | yes |
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…
| Field | Type | Required |
|---|---|---|
title | string | yes |
view_id | string | yes |
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.
| Field | Type | Required |
|---|---|---|
enabled | boolean | yes |
stream_process
Spawn command via sh -c and stream its output back to the app.
| Field | Type | Required |
|---|---|---|
channel | StreamChannel | yes |
command | string | yes |
correlation_id | string | yes |
terminal_pane_id | integer | yes |
cancel_process
Cancel an in-flight StreamProcess. The host sends SIGTERM to the child, waits up to 1s, then SIGKILL. A `PlexiEvent…
| Field | Type | Required |
|---|---|---|
correlation_id | string | yes |
open_file_picker
Show a native file picker dialog. Requires fs.pick capability.
Capability: fs.pick
| Field | Type | Required |
|---|---|---|
filter | string[] | yes |
mode | FilePickerMode | no |
multiple | boolean | yes |
request_id | string | yes |
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…
| Field | Type | Required |
|---|---|---|
streams | EventStreamDecl[] | yes |
emit_event
Emit a semantic app event into the host timeline.
| Field | Type | Required |
|---|---|---|
actor | AppEventActor | yes |
actor_id | string? | no |
caused_by | string? | no |
changed_resources | string[] | no |
event | string | yes |
payload | any | no |
resource_id | string | yes |
resource_scope | string? | no |
revision_after | string | yes |
revision_before | string? | no |
rollback_token | string? | no |
state_ref | string? | no |
suggested_trigger | variant | no |
summary | string | yes |
rollback_verify_result
App’s answer to PlexiEvent::RollbackVerify: the current revision of the queried resource. The host compares it agai…
| Field | Type | Required |
|---|---|---|
checkpoint_id | string | yes |
current_revision | string | yes |
subscribe_app_events
Subscribe this pane to another app’s declared event streams. Gated through the unified broker (`TargetType::AppEventS…
| Field | Type | Required |
|---|---|---|
app_id | string | yes |
event_names | string[] | no |
payload_mode | PayloadMode | yes |
request_id | string | yes |
resource_id | string? | no |
trigger_mode | TriggerMode | yes |
unsubscribe_app_events
Remove a subscription previously created by SubscribeAppEvents. Only the subscriber that owns it may remove it.
| Field | Type | Required |
|---|---|---|
request_id | string | yes |
subscription_id | string | yes |
list_undo_checkpoints
List undo checkpoints from the host undo timeline, newest first. app_id filters to one app; None = this app’s own…
| Field | Type | Required |
|---|---|---|
app_id | string? | no |
request_id | string | yes |
request_rollback
Request rollback of an undo checkpoint. Gated through the unified broker (TargetType::UndoCheckpoint). On allow, th…
| Field | Type | Required |
|---|---|---|
checkpoint_id | string | yes |
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.
shutdown
Request a clean host shutdown. Sent by plexi host stop over a direct notify.sock connection (never over `PLEXI_SO…
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.
| Field | Type | Required |
|---|---|---|
app_id | string | yes |
args | string[] | no |
capabilities | string[] | yes |
compact_threshold | number | no |
feature_flags | string[] | yes |
height | number | no |
protocol | string | yes |
regular_threshold | number | no |
state | any | no |
theme | object | no |
width | number | no |
workspace_root | string | yes |
render
Request a new frame. App replies with DrawCommands terminated by FrameDone.
| Field | Type | Required |
|---|---|---|
canvas_height | number | no |
canvas_width | number | no |
frame_id | integer | yes |
rect | Rect | yes |
resize
Surface was resized. App should re-layout and request a new frame.
| Field | Type | Required |
|---|---|---|
height | number | yes |
width | number | yes |
key
User input event.
| Field | Type | Required |
|---|---|---|
key | string | yes |
modifiers | Modifiers | yes |
pressed | boolean | yes |
click
Mouse click at logical coordinates within the app surface.
| Field | Type | Required |
|---|---|---|
button | MouseButton | yes |
region | string? | no |
x | number | yes |
y | number | yes |
mouse_down
Pointer button pressed (fires on the frame the button goes down).
| Field | Type | Required |
|---|---|---|
button | MouseButton | yes |
modifiers | Modifiers | yes |
x | number | yes |
y | number | yes |
mouse_up
Pointer button released (fires on the frame the button goes up).
| Field | Type | Required |
|---|---|---|
button | MouseButton | yes |
modifiers | Modifiers | yes |
x | number | yes |
y | number | yes |
mouse_move
Pointer moved over the app surface. Only fires when the app has opted in via `DrawCommand::SetMouseTracking { enabled…
| Field | Type | Required |
|---|---|---|
buttons | MouseButton[] | yes |
modifiers | Modifiers | yes |
x | number | yes |
y | number | yes |
command
User submitted a command via the command bar.
| Field | Type | Required |
|---|---|---|
text | string | yes |
action
Semantic action dispatched by plexi app action <pane_id> <action> [args...]. Apps receive this in on_event and di…
| Field | Type | Required |
|---|---|---|
action | string | yes |
args | string[] | no |
capability_decision
Response to a runtime CapabilityRequest.
| Field | Type | Required |
|---|---|---|
capability | string | yes |
granted | boolean | yes |
request_id | string | yes |
secret_value
Secret broker response. value is None when denied.
| Field | Type | Required |
|---|---|---|
key | string | yes |
value | string? | no |
file_read_result
Native WASM app runtime file read result.
| Field | Type | Required |
|---|---|---|
content | array? | no |
error | string? | no |
file_list_result
Native WASM app runtime directory listing result.
| Field | Type | Required |
|---|---|---|
entries | array? | no |
error | string? | no |
run_update
Run lifecycle update from the host.
| Field | Type | Required |
|---|---|---|
payload | any | yes |
run_id | string | yes |
status | string | yes |
pipe_message
Typed pipe message (JSON mode only; binary mode travels on the side channel).
| Field | Type | Required |
|---|---|---|
payload | any | yes |
pipe_id | string | yes |
path_changed
Pane group CWD broadcast. Declared, never constructed — no host path emits this today; sync_app_cwd reassigns `…
| Field | Type | Required |
|---|---|---|
cwd | string | yes |
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 through Plexi configuration. App should update its color state; the next render will pick up the n…
| Field | Type | Required |
|---|---|---|
colors | object | yes |
app_spawned
Confirmation that a SpawnApp request succeeded.
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
type_id | string | yes |
pane_spawned
Confirmation that a SpawnPane request succeeded (#592).
| Field | Type | Required |
|---|---|---|
pane_id | integer | yes |
request_id | string? | no |
pane_spawn_error
SpawnPane could not be fulfilled (#592). reason is a human-readable error.
| Field | Type | Required |
|---|---|---|
reason | string | yes |
request_id | string? | no |
context_state_response
Response to AppRequest::QueryContextState (#1518).
| Field | Type | Required |
|---|---|---|
state | ContextState | yes |
pipe_opened
Binary pipe opened — app connects to socket_path as a unix socket client.
| Field | Type | Required |
|---|---|---|
pipe_id | string | yes |
socket_path | string | yes |
pipe_overrun
Binary pipe backpressure — host dropped dropped_frames frames from the ring.
| Field | Type | Required |
|---|---|---|
dropped_frames | integer | yes |
pipe_id | string | yes |
inject_state
Drop a JSON payload into the app’s on_inject hook. Sent at startup with persisted app state (workspace if available…
| Field | Type | Required |
|---|---|---|
payload | any | yes |
render_seed
DEPRECATED: superseded by the state field on Init. Kept for backwards compatibility with older SDK versions. The he…
| Field | Type | Required |
|---|---|---|
payload | any | yes |
http_response
Host broker response to a DrawCommand::HttpRequest. error is present when the request failed; body may still ca…
| Field | Type | Required |
|---|---|---|
body | string | yes |
error | string? | no |
request_id | string | yes |
status | integer | yes |
notify_action
Sent when the user responds to a notification that included a notify_id.
| Field | Type | Required |
|---|---|---|
action_label | string | yes |
notify_id | string | yes |
value | string? | no |
timer
Fired when a SetTimer timer expires.
| Field | Type | Required |
|---|---|---|
timer_id | string | yes |
image_loaded
Fired when a load_image request completes (success or failure). status is “ok” or “error”. message carries the …
| Field | Type | Required |
|---|---|---|
handle | string | yes |
message | string? | no |
status | string | yes |
text_measured
Response to a DrawCommand::MeasureText request. width and height are in logical pixels at the requested font size.
| Field | Type | Required |
|---|---|---|
height | number | yes |
request_id | string | yes |
width | number | yes |
text_wrapped_measured
Response to a ControlCommand::MeasureTextWrapped request. height is the pixel height of the text when wrapped at …
| Field | Type | Required |
|---|---|---|
height | number | yes |
request_id | string | yes |
paste
Clipboard paste forwarded into the focused app pane.
| Field | Type | Required |
|---|---|---|
text | string | yes |
ai_response
Response to a DrawCommand::AiQuery. Either content is Some (success) or error is Some (failure) — the two a…
| Field | Type | Required |
|---|---|---|
content | string? | no |
error | string? | no |
request_id | string | yes |
tokens_in | integer | yes |
tokens_out | integer | yes |
ai_stream_chunk
Incremental token chunk from a streaming ai_query response. Sent live while the turn runs, before the final `AiRespon…
| Field | Type | Required |
|---|---|---|
delta | string | yes |
done | boolean | no |
reasoning | string? | no |
request_id | string | yes |
tool_call
Host-to-app tool invocation (#399). The broker calls a tool exposed via DrawCommand::ExposeTools by sending this ev…
| Field | Type | Required |
|---|---|---|
call_id | string | yes |
caller_id | string | yes |
input_json | string | yes |
name | string | yes |
mcp_tool_call
External MCP client called a tool declared in [app.mcp]. The app must reply with `DrawCommand::Host(AppRequest::Mcp…
| Field | Type | Required |
|---|---|---|
arguments | any | yes |
call_id | string | yes |
tool_name | string | yes |
audio_devices_listed
Response to a DrawCommand::ListAudioDevices request (#277). Both vectors are always present — empty when enumeratio…
| Field | Type | Required |
|---|---|---|
error | string? | no |
inputs | AudioDeviceWire[] | yes |
outputs | AudioDeviceWire[] | yes |
request_id | string | yes |
audio_capture_started
Sent when a DrawCommand::AudioCapture successfully opened the device and started delivering PCM frames on pipe_id…
| Field | Type | Required |
|---|---|---|
buffer_size | integer | yes |
channels | integer | yes |
device_name | string | yes |
pipe_id | string | yes |
sample_rate | integer | yes |
audio_capture_error
Sent when a DrawCommand::AudioCapture could not be honoured — permission denied, bad device id, no devices, cpal fa…
| Field | Type | Required |
|---|---|---|
error | string | yes |
pipe_id | string | yes |
midi_devices_listed
Response to a DrawCommand::ListMidiDevices request (#320). Both vectors are always present — empty when CoreMIDI fi…
| Field | Type | Required |
|---|---|---|
error | string? | no |
inputs | MidiPortWire[] | yes |
outputs | MidiPortWire[] | yes |
request_id | string | yes |
midi_input_opened
Sent when a DrawCommand::OpenMidiInput successfully opened the port and started forwarding incoming MIDI byte strea…
| Field | Type | Required |
|---|---|---|
pipe_id | string | yes |
port_id | string | yes |
port_name | string | yes |
midi_input_error
Sent when DrawCommand::OpenMidiInput could not be honoured — permission denied, port not found, CoreMIDI failure.
| Field | Type | Required |
|---|---|---|
error | string | yes |
pipe_id | string | yes |
midi_send_error
Sent when DrawCommand::SendMidi could not be honoured. Successful sends produce no event (fire-and-forget); only fa…
| Field | Type | Required |
|---|---|---|
error | string | yes |
port_id | string | yes |
video_open_ack
Sent when a DrawCommand::OpenVideo succeeded (#345). The host has allocated the binary pipe (look for the preceding…
| Field | Type | Required |
|---|---|---|
duration_ms | integer | yes |
fps | number | yes |
handle_id | integer | yes |
height | integer | yes |
request_id | string | yes |
width | integer | yes |
video_open_error
Sent when DrawCommand::OpenVideo could not be honoured (#345) — capability denied, source not found, decoder error,…
| Field | Type | Required |
|---|---|---|
error | string | yes |
request_id | string | yes |
linked_terminal_ready
Response to DrawCommand::RequestLinkedTerminal (#78). Carries the pane id of the freshly-opened terminal so subsequ…
| Field | Type | Required |
|---|---|---|
request_id | string | yes |
terminal_pane_id | integer | yes |
command_preview
Response to DrawCommand::RequestCommandPreview (#78). Returns the command verbatim plus the linked terminal’s curre…
| Field | Type | Required |
|---|---|---|
command | string | yes |
request_id | string | yes |
would_run_in_cwd | string | yes |
nav_back
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…
| Field | Type | Required |
|---|---|---|
view_id | string | yes |
file_picked
Response to DrawCommand::OpenFilePicker. At least one file was selected. paths contains the absolute, canonicaliz…
| Field | Type | Required |
|---|---|---|
paths | string[] | yes |
request_id | string | yes |
file_pick_cancelled
Response to DrawCommand::OpenFilePicker when the user cancelled the dialog without selecting a file, or the app lac…
| Field | Type | Required |
|---|---|---|
request_id | string | yes |
stream_chunk
Chunk of stdout/stderr bytes from an active DrawCommand::StreamProcess child. bytes is a raw byte array (values 0…
| Field | Type | Required |
|---|---|---|
bytes | integer[] | yes |
channel | StreamChannel | yes |
correlation_id | string | yes |
stream_end
Terminal event for a DrawCommand::StreamProcess child. Sent when the child exits, on CancelProcess, or on capabil…
| Field | Type | Required |
|---|---|---|
correlation_id | string | yes |
exit_code | integer | yes |
scroll_offset
Emitted by the host when the scroll offset for a BeginScroll region changes (mouse wheel, drag). The app should re-…
| Field | Type | Required |
|---|---|---|
id | string | yes |
offset_y | number | yes |
scroll
Emitted when the mouse wheel moves over an app pane that has no host-managed scroll region or list_view under the cur…
| Field | Type | Required |
|---|---|---|
delta_y | number | yes |
list_select
Emitted when j/k/up/down changes the list selection. id matches the list_view id field; index is the new select…
| Field | Type | Required |
|---|---|---|
id | string | yes |
index | integer | yes |
list_activate
Emitted when Enter is pressed on the selected item. id matches the list_view id field; index is the activated i…
| Field | Type | Required |
|---|---|---|
id | string | yes |
index | integer | yes |
component_event
Fired when a user interacts with a node that has Interactive wrapping or when a Button/Input node is activated.
| Field | Type | Required |
|---|---|---|
event_type | string | yes |
node_id | string | yes |
payload | any | no |
rollback_verify
Host asks the app whether resource_id is still at expected_revision before rolling back a checkpoint. The app mus…
| Field | Type | Required |
|---|---|---|
checkpoint_id | string | yes |
expected_revision | string | yes |
resource_id | string | yes |
rollback_apply
Host instructs the app to roll resource_id back using the rollback_token the app supplied when it emitted the rev…
| Field | Type | Required |
|---|---|---|
checkpoint_id | string | yes |
resource_id | string | yes |
rollback_token | string | yes |
app_events_subscribed
Response to AppRequest::SubscribeAppEvents. Exactly one of subscription_id / error is set.
| Field | Type | Required |
|---|---|---|
error | string? | no |
request_id | string | yes |
subscription_id | string? | no |
declare_event_streams_result
Response to AppRequest::DeclareEventStreams.
| Field | Type | Required |
|---|---|---|
error | string? | no |
streams | array? | no |
emit_event_result
Response to AppRequest::EmitEvent.
| Field | Type | Required |
|---|---|---|
error | string? | no |
sequence | integer? | no |
app_events_unsubscribed
Response to AppRequest::UnsubscribeAppEvents.
| Field | Type | Required |
|---|---|---|
error | string? | no |
removed | boolean | yes |
request_id | string | yes |
app_event
One subscribed app event, delivered to the subscriber pane. Content beyond the event identity is shaped by the subscr…
| Field | Type | Required |
|---|---|---|
app_id | string | yes |
created_at | string | yes |
event | string | yes |
event_id | integer | yes |
payload | any | no |
resource_id | string | yes |
state_ref | string? | no |
subscription_id | string | yes |
summary | string? | no |
trigger_mode | TriggerMode | yes |
undo_checkpoints
Response to AppRequest::ListUndoCheckpoints: undo checkpoints, newest first, serialized with the spec’s checkpoint …
| Field | Type | Required |
|---|---|---|
checkpoints | any[] | yes |
request_id | string | yes |