Expand description
AgentMux Pub/Sub system: event brokering with scoped subscriptions. Port of Go’s pkg/wps/wps.go + wpstypes.go (Wave Terminal’s original names).
The Broker supports:
- All-scope subscriptions (receive all events of a type)
- Exact-scope subscriptions (e.g., “block:uuid”)
- Star-scope subscriptions (e.g., “block:*”)
- Event persistence (history/replay)
Structs§
- Broker
- The central pub/sub broker for MuxEvents.
- Broker
Inner 🔒 - Broker
Subscription 🔒 - MuxEvent
- One event on the broker. The envelope is typed;
datais each event’s own payload, still untyped (any) on the frontend: srv builds most payloads withjson!, so there is no Rust type per event to generate yet. - Persist
Event 🔒Wrap - Persist
Key 🔒 - Stream
Pos - One transcript stream’s position for an append: the records it wrote are
lines
line .. linesof generationgenofstream. - Subscription
Request - WSFile
Event Data
Constants§
- EVENT_
AGENT_ CONTEXT_ USAGE - Where an agent process will auto-compact, as its CLI reports it. See
agent_context_usage.rs. - EVENT_
AGENT_ FAILURE - Fired when an agent subprocess exits non-zero (or reports an error on its
terminal
resultframe). Carries the classifiedAgentFailureso the pane shows the real cause instead of a bare exit code. - EVENT_
AGENT_ MESSAGE_ ACCEPTED - Fired by
SubprocessController::spawn_turnwhen a user message is picked up (either direct-spawn or queue drain). Frontend uses this to promote pendingPendingMessageentries into the conversation document. Payload:{ block_id, message_id }. - EVENT_
AGENT_ RESUME_ RETRY - Fired by the persistent controller’s stale-
--resumerecovery path (retry_after_resume_failure/publish_resume_retry_status,docs/status/STATUS_STALE_RESUME_LIVE_REPRO_AND_FIX_PLAN_2026_08_23.md§6.2) so the pane can show a “Reconnecting…” readout instead of going silent for the ~seconds-to-tens-of-seconds it can take the controller to detect a stale registrysession_idand respawn against a recovered one. Payload:{ "status": "retrying", "startedAt": "<rfc3339>" }or{ "status": "resolved" }.persist: 2(unlikecompaction_started’spersist: 0) is deliberate: both ends of this signal travel over this same MPS channel (there’s no separate out-of-band completion marker the waycompact_boundaryis for compaction), so replaying the latest retrying→resolved pair to a freshly (re)subscribed pane is always the correct current state, not a stale echo — seepublish_resume_retry_status’s own doc comment for why 2, not 1. - EVENT_
AGENT_ RUNTIME - What an agent process was actually spawned with. See
agent_runtime.rs. - EVENT_
AGENT_ TURN - The agent’s turn as the user sees it, over however many CLI passes. See
blockcontroller::health::TurnLedger. - EVENT_
ATTACHMENT_ BATCH_ DONE - EVENT_
ATTACHMENT_ FAILED - EVENT_
ATTACHMENT_ PROGRESS - Image attachment processing (SPEC_AGENT_PANE_IMAGE_ATTACHMENTS_2026_09_26.md
§6.5). Scoped
block:<id>of the pane that started the batch. Payloads areAttachmentProgressEvent/AttachmentReadyEvent/AttachmentFailedEvent/AttachmentBatchDoneEventinrpc_types::attachments. - EVENT_
ATTACHMENT_ READY - EVENT_
BLOCK_ ACTIVITY - Fired by the agent-pane PTY read loop when an OSC 0/2 window-title sequence
from Claude Code is extracted. Carries the normalised conversation-topic string
so the frontend can surface it as a
term:osc_titletab label. Payload:{ "blockId": "...", "activity": "auth refactor" }. - EVENT_
BLOCK_ CLOSE - EVENT_
BLOCK_ FILE - EVENT_
BLOCK_ STATS - EVENT_
BTW_ ANSWER_ CHUNK - Fired by the
/btwslash command’s one-shot side-question turn (server/agent_handlers/side_question.rs,AskSideQuestionCommand) — one event perAgentEventtranslated from the throwaway turn’s stream-json output (sameClaudeTranslatorthe drone Agent block runner uses,agents/translator/claude.rs), plus a final event with"done": truewhen the turn completes (successfully, with an error, or via a timeout/no-response fallback). - EVENT_
CONFIG - EVENT_
CONN_ CHANGE - EVENT_
CONTROLLER_ STATUS - EVENT_
CRON_ CHANGED - Fired whenever a cron job is created, fires, is paused/resumed, or
deleted (SPEC_SWARM_LONG_RUNNING_PROCESS_ROWS_2026_07_20 Phase 2).
Payload-free, unscoped — the Swarm pane just reloads the full list via
cron.ListActiveon receipt, the same “any event of this type ⇒ refetch” patternshell_node_create/shell_chunk(op:"exit")already use. - EVENT_
DOCK_ CLEAR - Fired by
handle_muxspect_dock_clearwhen amuxspect dock clearrequest is served. Scopedblock:<id>, same convention asshell_node_create— only a renderer currently displaying that block receives it. Payload:{ node_id }. The receiving renderer flips that oneToolNodetostatus: "canceled"via theForceCancelToolNodedocument-reducer command; a renderer without that node (already resolved, or a different pane’s block) no-ops. Seedocs/specs/SPEC_MUXSPECT_DOCK_DIAGNOSIS_AND_REMEDIATION_2026_08_06.md§3.2. - EVENT_
INSTALL_ PROGRESS - EVENT_
MUX_ OBJ_ UPDATE - EVENT_
REMOTES_ CHANGE - The Connectors → Remotes list changed in a way
connchangedoesn’t cover: a remote’s settings, or a recent one forgotten (SPEC_REMOTES_PANE_2026_10_05.md §4.6). - EVENT_
ROUTE_ GONE - EVENT_
SHELL_ CHUNK - Fired per stdout/stderr line and on process exit by
ShellNodeRunner.op: "chunk"carries{ shell_id, kind, content, timestamp };op: "exit"carries{ shell_id, exit_code, timestamp }. - EVENT_
SHELL_ NODE_ CREATE - Fired by
handle_shell_createwhen a persistent shell is launched. Frontend creates the ShellNode row on receipt. Payload:{ shell_id, cmd, cwd?, title, timestamp }. - EVENT_
SUBAGENT_ BACKFILL_ STATUS - Fired by
SubagentWatcher::scan_session_subagents(the pane-reopen cold-backfill entry point,subagent_watcher/scan.rs) so a pane can show its BrainSpinner overlay (block.tsx’sready()gate) until its own subagent/dispatch history has actually finished backfilling, instead of exposing the Activity Dock’s genuinely-changing intermediate states — seedocs/retro/retro-activity-dock-flicker-survives-debounce-fix-2026-08-24.md§5 option 1/2. Payload:{ "status": "started" | "done" }.persist: 2, same rationale asEVENT_AGENT_RESUME_RETRYabove — both ends travel over this one channel, so a mount-timeEventReadHistoryCommandread (guarding the same “pane subscribed after the backend already finished” race that event’s own hook already handles) always recovers the correct current status rather than a stale one. - EVENT_
SYS_ INFO - EVENT_
USER_ ATTENTION - A call to action srv holds open started or ended:
{ key, block_id, kind, text, window_ids, active }(backend/user_attention.rs). - EVENT_
USER_ INPUT - EVENT_
WIDGET_ PACKAGES - The widget packages changed: installed, approved, edited, removed
(SPEC_USER_WIDGETS_AND_WIDGET_API_2026_10_09.md §8). Payload
{ packages }. - EVENT_
WIDGET_ REQUESTS - Agents’ widget install requests waiting for the user:
{ requests }. - EVENT_
WIDGET_ STORAGE - A widget package’s storage changed:
{ id, keys }, never the values. - FILE_
OP_ APPEND - FILE_
OP_ CREATE - FILE_
OP_ DELETE - FILE_
OP_ INVALIDATE - FILE_
OP_ REPLACE - A transcript
outputreplaced by other content (restore):posnames the new generation and its line count (Phase 5a-3). - FILE_
OP_ TRUNCATE - MAX_
PERSIST 🔒 - REMAKE_
ARR_ 🔒THRESHOLD
Traits§
- WpsClient
- Trait for event delivery to connected clients.
Functions§
- add_
to_ 🔒scope_ map - add_
unique 🔒 - is_zero 🔒
- publish_
block_ activity - Publish a Claude Code OSC window-title activity string to the frontend
for a given agent-pane block. Frontend subscribes to
block:activityevents scoped toblock:{block_id}and writes the payload toterm:osc_titleblock metadata, which the tab label reads. - publish_
install_ progress - Publish a single install-progress line to the frontend for a given block.
The frontend subscribes to
install_progressevents scoped toblock:{block_id}and displays each message as a log line in the agent presentation view. - remove_
from_ 🔒all_ scopes - scope_
has_ 🔒star - star_
match 🔒 - Simple star matching: each segment separated by
sepis compared. “*” matches any single segment, “**” matches any remaining segments.
Type Aliases§
- Broker
Observer - See
Broker::add_observer. - Replay
Key 🔒 - Tracks
(route_id, event_name, scope)tuples whose persisted history has already been replayed to a given route. Skipping replay on resubscribe prevents the frontend’seventsubflushes (sent on every listener add/remove, once per conn_id) from re-emitting completed bash logs on every pane mount or tab switch. Codex P2 on PR #817; route keying updated PR #1418.