Skip to content

Semantic events ​

Snapshots make UI state reliable. Semantic events make integrations simple.

ts
const unsubscribe = surface.onEvent((event) => {
  if (event.type === 'tool.completed') {
    refreshBusinessState(event.conversationId);
  }
});

Event guarantees ​

Every event includes:

  • type: a product-shaped discriminant;
  • seq: a surface-local monotonic sequence number;
  • occurredAt: an ISO timestamp;
  • origin: action, notification, or lifecycle;
  • conversationId when the event belongs to one conversation;
  • event-specific serializable data.

The matching snapshot mutation is applied before the event is emitted.

Event families ​

FamilyExamples
Surfaceconnection, ready/error, bootstrap, close
Authenticationaccount state, login progress/completion, logout
Catalogsconversations, models, skills, plugins, permissions
Conversationselection, settings, rename, archive/delete, history replacement and incremental prepends
Messagesadd/update/complete/delete, generated media
Turnsstart/complete/error, interruption, context compaction
Toolsstart/progress/complete, confirmations, user input
File activityread, edit, and create paths for host-owned navigation
Sub-agentscollaboration tool calls and agent activity for host-owned presentation
Plans and goalsplan updates, goal set/clear/status
Queues and diffsqueued prompts, git diff updates
Usagecontext usage and account rate limits
Remote controlconnection status changes for host-owned native behavior

Conversation-scoped subscription ​

Node conversation handles filter the same stream by identity:

ts
const conversation = surface.conversation(conversationId);

conversation.onEvent((event) => {
  console.log(event.type, event.conversationId);
});

Vue controller ​

useCodexSurface exposes the last event and a local subscription API:

ts
const surface = useCodexSurface(rendererApi);

const stop = surface.onEvent((event) => {
  if (event.type === 'turn.completed') celebrate();
});

Vue scope disposal automatically unregisters the underlying renderer listeners. rendererApi may come from Electron preload or createCodexWebSurfaceClient(); event semantics are identical.

When to use which ​

  • Render from snapshots.
  • Use conversation.historyPrepended for progressive background hydration; each event contains only the newly materialized chronological batch.
  • Trigger business refreshes or analytics from semantic events.
  • Use file.activity to reveal or focus the full path in an app-owned sidebar; the SDK reports the operation but does not own file navigation.
  • Use subagent.* to maintain an app-owned agent tree or workspace. The SDK exposes typed activity but deliberately provides no standard sub-agent UI.
  • Use remoteControl.statusChanged when app-owned native behavior depends on whether Codex remote control is disabled, connecting, connected, or errored.
  • Never rebuild full conversation state by replaying events.
  • Use readConversationHistory after a history-replacement event when an integration needs the full historical payload.

See the event API, history guide, and remote-control guide.

Released under the Apache License 2.0.