| outline | deep |
|---|
Devframe carries change notifications across channels of differing direction and reach: a node event bus, server RPC, and server-pushed broadcasts and shared state.
Two prefixes mark the wire surface: hub: for hub-layer server RPC (client → server), devframe: for the client-facing protocol (server → client). The internal event bus mirrors the subsystem vocabulary (docks, terminals, messages, commands) — docks:activate fans out to devframe:docks:activate.
Each name lives in code: HUB_EVENTS (@devframes/hub/constants) backs the hub tables, DEVFRAME_EVENTS (devframe/constants) the core ones.
Each subsystem host emits on ctx.<subsystem>.events, consumed inside the same node process by createHubContext, which fans them onto the wire.
| Event | Emitted by | Consumed by | Payload |
|---|---|---|---|
docks:entry:updated |
DocksHost.register / update |
context → devframe:docks shared state |
DevframeDockUserEntry |
docks:activate |
DocksHost.activate() |
context → broadcast + devframe:docks:active |
DevframeDockActivation |
terminals:session:updated |
TerminalsHost register / update / remove / status change |
context → devframe:terminals:updated; terminals plugin |
DevframeTerminalSession |
messages:added / messages:updated / messages:removed / messages:cleared |
MessagesHost mutations |
context → devframe:messages:updated; messages plugin |
entry / entry / id / — |
commands:registered / commands:unregistered |
CommandsHost register / update / unregister |
context → devframe:commands shared state |
entry / id |
| Method | Signature | Purpose |
|---|---|---|
hub:docks:activate |
({ dockId, params? }) => void |
Ask the viewer to switch its active dock — see Deep Linking. |
hub:commands:execute |
(id, ...args) => unknown |
Invoke a registered server command by id. |
hub:messages:add |
(input) => DevframeMessageEntry |
Add a message to the feed (marked from: 'browser'). |
hub:messages:update |
(id, patch) => DevframeMessageEntry | undefined |
Patch a message by id. |
hub:messages:remove |
(id) => void |
Remove a message by id. |
hub:messages:clear |
() => void |
Remove every message. |
hub:terminals:write |
(id, data) => void |
Send input to an interactive PTY session. |
hub:terminals:resize |
(id, cols, rows) => void |
Resize an interactive PTY session. |
hub:terminals:terminate |
(id) => void |
Kill a session's process, keeping it registered. |
hub:terminals:restart |
(id) => void |
Re-run a session's command in place. |
hub:terminals:remove |
(id) => void |
Kill a session's process and drop it from the registry. |
A hub-aware client reads or subscribes via rpc.client.register(...); the client host registers the devframe:docks:activate handler for you.
| Name | Kind | Carries |
|---|---|---|
devframe:docks:activate |
broadcast | Live "switch active dock" request — the client host calls its local switchEntry. |
devframe:terminals:updated |
broadcast | Terminal sessions changed; re-read terminal state. |
devframe:messages:updated |
broadcast | Message list changed; re-read message state. |
devframe:docks |
shared state | Projected dock entry list (DevframeDockEntry[]). |
devframe:docks:active |
shared state | Most recent DevframeDockActivation, so a dock that mounts in response still converges on it. |
devframe:commands |
shared state | Serializable command list, handlers stripped (DevframeServerCommandEntry[]). |
devframe:user-settings |
shared state | Persisted per-workspace hub settings (DevframeDocksUserSettings). |
devframe:terminals |
streaming channel | Live terminal output stream, keyed by session id. |
This map covers notifications only; request/response RPC endpoints (devframe:rpc:server-state:*, devframe:streaming:subscribe, anonymous:devframe:auth, …) are typed in types/rpc-augments.ts, not events.
Emitted on ctx.agent.events; adapters (e.g. the MCP server) re-publish their manifest.
| Event | Emitted by | Payload |
|---|---|---|
agent:manifest:changed |
any tool/resource/provider change | — |
agent:tool:registered / agent:tool:unregistered |
registerTool / unregisterTool |
AgentTool / id |
agent:resource:registered / agent:resource:unregistered |
registerResource / unregisterResource |
AgentResource / id |
Emitted on the RPC client's rpc.events (RpcClientEvents) to track connection lifecycle and errors.
| Event | Carries |
|---|---|
rpc:is-trusted:updated |
Trust gate flipped (boolean). |
rpc:error |
An RPC call rejected (error, method). |
connection:status |
Connection status changed (status, previous). |
connection:error |
A connection-level error (WebSocket errored, or trust refused). |
Pushed to subscribed clients, wired by the framework's own hosts.
| Name | Carries |
|---|---|
devframe:auth:revoked |
This connection's bearer token was revoked; the client drops to untrusted. |
devframe:rpc:client-state:updated |
Full shared-state snapshot for a key. |
devframe:rpc:client-state:patch |
Incremental shared-state patch for a key. |
devframe:streaming:chunk |
A streaming chunk for a subscribed channel/id. |
devframe:streaming:end |
A streaming terminator (optionally an error). |
devframe:streaming:upload-cancel |
Server-side cancel of an in-flight upload. |
Plus one postMessage channel, devframe:remote-assets-error, posted by the remote-assets fallback page to window.parent so an embedding viewer can replace the 502 page.