Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Use the mods API changedplugins/mods/api

Nearest release: v2.1.306, published under an hour after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 21 Oct 2026 02:10 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 21 Oct 2026 02:37 UTC.

Upstream edited
Recorded here
Lines+36added
Lines−0removed
From line 207 where the diff opens
First seen 1 Oct 2026 this site's first read of the page
Recorded edits12to this page, all time

The whole hunk

from line 207, old and new numbered
/
lines
from line 207
207207| `$.ui.status(text)` | One line under the prompt that stays until you change it. It starts with `⚠` and the mod's name, as in `⚠ my-mod: checks: 3 passing`. |
208208| `$.ui.toast(text)` | A toast notification with the mod's name that disappears after a few seconds. It's a box at the top right in [fullscreen rendering](/docs/en/fullscreen), and one line at the right under the prompt in the classic renderer. |
209209| `$.ui.log(text)` | A dim line in the transcript that Claude doesn't read. It starts with `●` and the mod's name, as in `● my-mod: build finished`. |
210| `$.ui.notify(text)` | A notification from their terminal, outside Claude Code, sent the way their [`preferredNotifChannel`](/docs/en/settings-reference#preferrednotifchannel) setting says. The mod's name is its title unless you pass a non-empty `{ title }`, which is shown as you give it. |
211 
212`$.ui.notify` is the only one of these that answers. It resolves to `{ isSent: true, channel }` when the user's channel wrote the notification to their terminal. `channel` is the setting's value that sent it, such as `kitty` or `terminal_bell`. The `terminal_bell` channel rings the bell and shows neither your text nor the title.
213 
214Otherwise the call resolves to `{ isSent: false, reason }`:
215 
216| `reason` | Meaning |
217| :- | :- |
218| `disabled` | The user set `preferredNotifChannel` to `notifications_disabled` |
219| `no-channel` | The setting is `auto` and their terminal has no notification Claude Code can send |
220| `no-surface` | The session has no terminal, as in a `-p` run, the Agent SDK, the desktop app, the VS Code extension, or a cloud session. Also the answer to a call made before the session starts, while your mod is loading, and to a call made while Claude Code is exiting |
221| `refused` | Another mod's hook on `ui.notify` answered in Claude Code's place without sending |
222 
223The call rejects instead of resolving when `text` isn't a string, when another mod's hook on `ui.notify` returns `{ deny }`, or when writing to the terminal fails.
224 
225Your mod can't choose the channel, and Claude Code doesn't limit how often a mod notifies. The user's setting is the only switch.
226 
227When the call reaches a running session, the user's [`Notification` hooks](/docs/en/hooks#notification) run with the type `plugin_notification`. They run even when the answer is `disabled`, and in a session with no terminal, where the answer is `no-surface`. No hook runs for a call made before the session starts or while Claude Code is exiting. The hook your mod called `$.ui.notify` from is left out of that run, so a `classic.Notification` hook that notifies isn't called again for its own notification.
228 
229A terminal doesn't report whether it showed the notification, so `isSent: true` means it was sent, not that the user saw it.
230 
231This example notifies when the main conversation's turn ends without an interruption, and falls back to a toast when no notification with text went out. It doesn't wait for the notification before passing the event on, because the user's `Notification` hooks run first and can take a while:
232 
233```javascript theme={null}
234on('turn.complete', ($, e, next) => {
235 const isMainTurn = e.agentId === undefined && !e.isAborted
236 const fallBack = () => $.ui.toast('Turn finished')
237 if (isMainTurn) {
238 $.ui.notify('Turn finished').then(sent => {
239 const hasText = sent.isSent && sent.channel !== 'terminal_bell'
240 if (!hasText) fallBack()
241 }, fallBack)
242 }
243 return next(e)
244})
245```
210246 
211247In the [VS Code extension](/docs/en/plugins/mods/interface#draw-in-the-vs-code-extension), status lines and toasts show above the prompt box instead, and log lines in the conversation.
212248 
Feedback