## All 46 extension events

These are the complete supplied event names\.&#32;Numbers follow the supplied inventory and make omissions easy to check\.

Unless stated otherwise\,&#32;a notification handler’s returned value does not control the operation\.

### Resources and session lifecycle

| No\. | Event | Payload\/use | Supported result |
| --- | --- | --- | --- |
| 1 | `resources_discover` | `cwd`\,&#32;startup\/reload reason\;&#32;contribute resource paths | `skillPaths`\,&#32;`promptPaths`\,&#32;`themePaths`\;&#32;requires host dispatch\/consumption |
| 2 | `session_start` | Initial initialized session load | Notification |
| 3 | `session_before_switch` | Reason&#32;`new`\,&#32;`resume`&#32;or&#32;`fork`\;&#32;optional target file | `{ cancel }` |
| 4 | `session_switch` | Completed switch\;&#32;reason and previous file | Notification\;&#32;reconstruct current state |
| 5 | `session_before_branch` | Selected user\-message entry ID | `{ cancel, skipConversationRestore }` |
| 6 | `session_branch` | Branch completed\;&#32;previous file | Notification |
| 7 | `session_before_compact` | Preparation\,&#32;branch entries\,&#32;public instructions\,&#32;signal | `{ cancel, compaction }` |
| 8 | `session.compacting` | Session ID and messages about to be summarized | `{ context, prompt, preserveData }` |
| 9 | `session_compact` | Compaction entry and&#32;`fromExtension` | Notification |
| 10 | `session_shutdown` | Teardown | Cleanup\;&#32;concurrent bounded handlers |
| 11 | `session_before_tree` | Tree preparation and signal | `{ cancel, summary }`\;&#32;summary used only when requested |
| 12 | `session_tree` | Old\/new leaf\,&#32;optional summary entry and origin | Notification |

`skipConversationRestore`&#32;means the branch proceeds while in\-memory conversation restoration is skipped\.&#32;It is not cancellation\.

For the cancelable pre\-events\,&#32;cancellation short\-circuits\.&#32;Otherwise the current generic runner retains the last returned result rather than deep\-merging every handler’s object\.&#32;`session.compacting`&#32;likewise uses the last returned result object\;&#32;coordinate cooperating extensions\.

Seed Desk reconstructs after lifecycle events\.&#32;Review Desk invalidates pending authority before navigation\.

### Prompt and provider boundaries

| No\. | Event | Payload\/use | Supported result |
| --- | --- | --- | --- |
| 13 | `context` | Messages before each model call | Replacement&#32;`{ messages }`\,&#32;chained |
| 14 | `before_provider_request` | Provider\-specific logical payload\;&#32;request model in context | Return the replacement payload directly |
| 15 | `provider_request` | Frozen event with final&#32;`payloadJson` | Observation only |
| 16 | `after_provider_response` | Status\,&#32;headers\,&#32;request ID\,&#32;metadata before stream consumption | Observation only |
| 17 | `before_agent_start` | Submitted prompt\,&#32;images\,&#32;current prompt blocks | Custom&#32;`message`&#32;and\/or replacement&#32;`systemPrompt`&#32;blocks |
| 39 | `input` | Input text\,&#32;images and source tag | `{ handled, text, images }`\;&#32;transforms chain\,&#32;handled stops |

`before_provider_request`&#32;replacements chain in load order\.&#32;Provider\-specific payloads are not one universal HTTP schema\.

`provider_request`&#32;is the final logical JSON after those transforms\,&#32;not exact transport bytes or headers\.&#32;Returned values cannot change it\.&#32;Extension observer errors are isolated and are not a reliable dispatch veto\.

An embedding that requires a fail\-closed final\-payload check uses the awaited SDK&#32;`onProviderRequest`&#32;callback\;&#32;rejection there stops dispatch before extension observers\.

The supplied guide identifies&#32;`devin-agent`&#32;as a provider that does not fire the request hook\.&#32;Provider implementation coverage must be checked when relying on these boundaries\;&#32;no live provider was exercised for the workbook examples\.

`after_provider_response`&#32;occurs before the response stream has yielded final assistant usage\.&#32;Use a completed assistant message\,&#32;commonly at&#32;`turn_end`\,&#32;for actual turn token\/cost accounting\.

`input`&#32;source tags are&#32;`interactive`\,&#32;`rpc`&#32;and&#32;`extension`\.&#32;The runner supports all three labels\,&#32;but that does not mean every host path emits the event\.&#32;The supplied RPC\/ACP prompt implementations do not themselves call&#32;`emitInput()`\.&#32;Do not use it as a universal inbound\-policy gateway\.

In typed interactive input flow\,&#32;naming a session from&#32;`input`&#32;can precede the normal first\-message title check\.&#32;That does not imply every initial CLI prompt takes the same path\.

### Agent\,&#32;turn and message notifications

| No\. | Event | Payload\/use | Supported result |
| --- | --- | --- | --- |
| 18 | `agent_start` | Agent\-loop start | Notification |
| 19 | `agent_end` | Messages and optional&#32;`willContinue` | Notification only |
| 20 | `session_stop` | Main\-session settle context\,&#32;turn\/session IDs\,&#32;last assistant\,&#32;`stop_hook_active`\,&#32;signal | `{ continue: true, additionalContext }`&#32;or&#32;`{ decision: "block", reason }` |
| 21 | `turn_start` | Turn index and timestamp | Notification |
| 22 | `turn_end` | Completed turn message and tool results | Notification\;&#32;inspect completed usage here |
| 23 | `message_start` | A message begins | Notification |
| 24 | `message_update` | Assistant message and streaming event\/delta | Notification\;&#32;keep handlers lightweight |
| 25 | `message_end` | Detached completed\-message snapshot | Notification\,&#32;not a rewrite hook |

A turn is one assistant response plus its associated tool results\.&#32;A run can contain several turns and maintenance continuations\.

`session_stop`\:

- is awaited at eligible main\-session settle\;
- does not run for task\/subagent sessions\;
- requires nonempty continuation context\/reason\;
- is capped at eight consecutive continuations\;
- is deferred when automatic continuation or owner\-scoped pending async work means the run is not truly finished\;
- can be cancelled through its signal\.

Use&#32;`stop_hook_active`&#32;to avoid endlessly requesting the same extra pass\.

Streaming notifications can be queued\/detached relative to other host work\.&#32;Do not base an authorization protocol on an assumed universal arrival order of every message and UI frame\.

### Tool execution and approval

| No\. | Event | Payload\/use | Supported result |
| --- | --- | --- | --- |
| 26 | `tool_execution_start` | Call ID\,&#32;name\,&#32;arguments\,&#32;optional intent | Observation |
| 27 | `tool_execution_update` | Call identity\,&#32;arguments and partial result | Observation |
| 28 | `tool_execution_end` | Call identity\,&#32;result and error state | Observation |
| 40 | `tool_approval_requested` | Session\/call\/tool IDs\,&#32;optional reason\,&#32;approval mode | Observation |
| 41 | `tool_approval_resolved` | Session\/call\/tool IDs\,&#32;approved boolean\,&#32;optional reason | Observation |
| 42 | `tool_call` | Call identity and normalized input before execution | `{ block, reason, input }` |
| 43 | `tool_result` | Effective input\,&#32;content\,&#32;details and error state | Patch&#32;`{ content, details, isError }`\,&#32;chained |

A&#32;`tool_execution_start`&#32;event does not prove the side effect happened\;&#32;approval may still be pending\.

Approval events are emitted when the wrapper reaches a required approval gate and relevant handlers are present\.&#32;They are not a way to approve by returning a value\.

Already\-denied calls can short\-circuit before&#32;`tool_call`\.&#32;Schema failures\,&#32;pre\-execution blocks and approval denials do not necessarily traverse the post\-execution&#32;`tool_result`&#32;path\.

`tool_call`&#32;errors\/timeouts fail closed\.&#32;`tool_result`&#32;middleware can change what is reported\,&#32;not reverse external effects\.

### Reliability and domain reminders

| No\. | Event | Payload\/use |
| --- | --- | --- |
| 29 | `auto_compaction_start` | Reason\:&#32;threshold\,&#32;overflow\,&#32;idle or incomplete\;&#32;selected action |
| 30 | `auto_compaction_end` | Action\,&#32;optional result\,&#32;aborted\/willRetry\,&#32;optional error\/skipped |
| 31 | `auto_retry_start` | Attempt\,&#32;maximum attempts\,&#32;delay\,&#32;error message and optional error ID |
| 32 | `auto_retry_end` | Success\,&#32;attempt\,&#32;final error and optional retry\-error presentation updates |
| 33 | `retry_fallback_applied` | From\/to model selectors and configured role |
| 34 | `retry_fallback_succeeded` | Fallback model and role that actually succeeded |
| 35 | `ttsr_triggered` | Rules whose stream matching interrupted generation |
| 36 | `todo_reminder` | Unfinished todos and reminder attempt information |
| 37 | `goal_updated` | Current goal or null and optional goal\-mode state |
| 38 | `credential_disabled` | Provider and truncated diagnostic cause for automatic credential soft\-disable |

These are observations\,&#32;not return\-value control hooks\.

Compaction actions include&#32;`context-full`\,&#32;`remote`\,&#32;`handoff`\,&#32;`shake`&#32;and&#32;`snapcompact`&#32;in the supplied event type\.&#32;A skipped or aborted compaction is not a successful summary\.

`retry_fallback_applied`&#32;means a candidate was selected\.&#32;`retry_fallback_succeeded`&#32;distinguishes actual success\.

`credential_disabled`&#32;is not fired for every user logout\/removal\.&#32;Startup events can be buffered until runtime initialization\;&#32;the runner’s buffer is bounded at 32\.

### Human execution and MCP notifications

| No\. | Event | Payload\/use | Supported result |
| --- | --- | --- | --- |
| 44 | `user_bash` | Command\,&#32;cwd and whether&#32;`!!`&#32;excludes output from model context | Full replacement&#32;`{ result }` |
| 45 | `user_python` | Code\,&#32;cwd and whether&#32;`$$`&#32;excludes output from model context | Full replacement&#32;`{ result }` |
| 46 | `mcp_notification` | Raw server name\,&#32;method and unknown params | Notification |

`user_bash`&#32;concerns human&#32;`!`\/`!!`&#32;execution\,&#32;not every model bash tool or arbitrary&#32;`pi.exec()`&#32;call\.&#32;`user_python`&#32;concerns the corresponding&#32;`$`\/`$$`&#32;user\-code path\.

The first returned user\-execution result replaces default execution\.&#32;Throwing is not a supported blocking result\.

MCP notifications arrive after the manager’s known\-method processing\.&#32;Buffering is bounded at 100 with drop\-oldest behavior at the supplied startup boundaries\.&#32;Validate payloads and do not mistake notifications for durable authority\.

*Source\,&#32;snapshot 2026\-08\-29\:&#32;`packages/coding-agent/src/extensibility/extensions/types.ts`\,&#32;all&#32;`on`&#32;overloads\;&#32;`packages/coding-agent/src/extensibility/shared-events.ts`\;&#32;`runner.ts`\;&#32;`wrapper.ts`\;&#32;`packages/coding-agent/src/session/agent-session.ts`\;&#32;`packages/coding-agent/src/session/bash-runner.ts`\;&#32;`packages/coding-agent/src/modes/rpc/rpc-mode.ts`\.*
