Host events
Every event is a JSON object with an event field. A plugin receives them
through api.on(name, fn); on the wire (which the runtime speaks for the
plugin) they are the notification host/event after
host/events.subscribe.
A plugin receives an event only when it holds the permission in the last
column (see ../AGENTS.md, Permissions); an event with none goes to every
enabled plugin. The events of a plugin without the grant are dropped
before they reach it, for "*" listeners too.
event |
Fields | When | Permission |
|---|---|---|---|
terminal |
kind (created, title, exit, bell, closed), terminal: { id, title, cwd, workspaceId, running, exitCode } (only { id } for closed) |
a terminal was opened, renamed itself, rang the bell, ended or was closed | terminal |
agent |
chatId, taskId?, kind |
an agent event was applied to a chat; kind is an AgentEvent body (kind.event is text_delta, reasoning_delta, tool_call_started, tool_call_updated, approval, approval_resolved, question, question_resolved, plan, usage, session_info, config_options, commands, notice, task, run_started, run_finished; taskId names the subagent the event belongs to). approval_resolved also follows an answer on the app's approval card. |
chats.read |
user_message |
chatId, item |
the user's prompt was added | chats.read |
transcript_reset |
chatId |
the transcript was replaced (history load, restore) | chats.read |
chat_changed |
chat |
title, status, options or archive flag changed | chats.read |
chat_removed |
chatId |
chats.read |
|
inputs_changed |
chatId, snapshot: InputSnapshot |
durable input, delivery evidence, policy metadata or lifecycle changed; ignore snapshots older than the current generation/revision | chats.read |
run_settled |
chatId, run: SettledRun |
native completion and required transcript/checkpoint accounting finished; includes outcome, generation, stoppedAt, optional usageLimit, and whether cancellation reserved a steer | chats.read |
turn_changes |
chatId, itemId, workspaceId, paths |
a turn finished; paths are the files it changed, relative to the workspace (from the checkpoint journal), itemId is the turn's prompt. Only for a turn that had a checkpoint before it. chats.turn_changes gives the last one again |
chats.read |
security_request |
request (SecurityRequest, see host-api.md) |
something waits for the user on a native card: a plugin to be enabled or to get more permissions, the publish row after a turn that changed a plugin, or a report to the marketplace. A request with a chatId belongs in that chat's transcript (ui.securityCard) |
chats.read |
security_resolved |
id, outcome (enabled, cancelled, superseded, published, sent) |
the user answered a card, or a newer one replaced it (a newer request for the same plugin or the same setting; the next turn's publish row, or the next prompt) | chats.read |
workspaces_changed |
added, removed, reordered, or sessions imported | ||
agents_changed |
enabled set or auth state changed, a sign-in or sign-out finished, or a provider registered or removed agents after it loaded (api.agents.register, api.agents.unregister) |
||
settings_changed |
the user changed a setting (settings.get returns the new values) |
||
plugins_changed |
a plugin loaded, failed, or reloaded | ||
plugin_changed |
name |
one plugin's folder changed or a panel asked to re-render | |
access_changed |
plugin |
a plugin was enabled or turned off, or got or lost a grant (plugin is its folder name) |
|
notice |
level, message |
something the user should see | |
open_chat |
chatId |
something asked the window to show this chat (host/ui.open_chat, or the updater's merge chat) |
chats.read |
git_changed |
workspaceId |
something git status shows changed in the repository git.watch watches (a file git does not ignore, the index, HEAD or refs); bursts arrive as one |
git.read |
updates_changed |
an update check finished, or an update started or ended (updates.status has the rest) |
||
market_changed |
updates (MarketUpdate[], see host-api.md) |
the marketplace's news for the installed plugins changed: a newer version, or a yanked or malicious installed one (market.updates gives them again) |
market |
market_account |
signedIn, error? |
a marketplace sign-in (market.login) finished or failed, or the user signed out |
market |
market_bug_form |
plugins, text? |
something asked for the bug report form (cvg bug, market.open_bug_form from Settings or the Help menu): the market plugin opens it with these plugins |
market |
market_bug_report |
requestId, reportId, number |
the send card sent a bug report (market.request_bug_report) |
market |
plugin_settings_changed |
plugin |
a plugin's own settings changed (the settings page, the plugin itself, or a change card's Cancel); plugins.settings gives its section again. The plugin itself hears api.settings.onChange instead |
plugins.manage |
keybindings_changed |
keybindings.json changed, by the Keyboard Shortcuts section or by hand; the kernel binds every key again and kernel/commands has the new keys |
agent events are frequent while a run streams. Views only re-render on
them when their on list includes "agent" or a listener calls
view.update(); the plugin's runtime holds those renders back to at most
one per view every 30 ms.
The chat plugin applies them to its own transcript copy (see its
applyEvent).
run_finished is a native event, not a queue-release barrier. An
inputs_changed snapshot with settling: true still blocks dispatch. Required
settlement failure leaves it blocked and reports lastRun.error; it does not emit
run_settled. A usage_blocked agent event can arrive while native retries or
tools continue: show the warning, but do not cancel work or arm stopped recovery
until a failed run has actually settled. See host-api.md for scheduler authority
and agent-protocol.md for consumption/rejection/usage evidence.
Source: plugins/docs/events.md in the Divergence repository, built with this site.