TUI plugins can only show global toasts, so a notification about one session shows up identically while the user is looking at a different tab; this lets plugins tag a toast with a sessionID and have the TUI decide how to present it.
Special things to note
Behavior change in the built-in notifications plugin: a failed session you are not viewing now shows an error toast with an Open action. Previously it was dropped and only surfaced as an OS notification plus the tab's error marker.
Scoped to TUI plugins only. Server plugins still have no way to toast: tui.toast.show in packages/schema/src/tui-event.ts has listeners in app.tsx but no publisher in V2. Adding sessionID to that event and a publish path is a follow-up.
The policy lives in the plugin adapter, not in ui/toast.tsx, because ToastProvider mounts above RouteProvider and DataProvider and cannot see sessions.
The adapter in packages/tui/src/plugin/api.tsx applies the presentation policy before handing off to the global toast queue:
ui.toast.show(options)
if no sessionID
show as-is
if root(routed session) == root(options.sessionID) # same family: parent or subagent open
show as-is
else
title = options.title ?? session.title
action = "Open" -> route.navigate({ type: "session", sessionID })
show
The built-in notifications plugin drops its hand-rolled route check and uses the field instead:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why the change
TUI plugins can only show global toasts, so a notification about one session shows up identically while the user is looking at a different tab; this lets plugins tag a toast with a sessionID and have the TUI decide how to present it.
Special things to note
Change outline
One optional field on the plugin contract:
// packages/plugin/src/tui/context.ts export interface ToastOptions { readonly title?: string readonly message: string readonly variant?: ToastVariant readonly duration?: number + readonly sessionID?: string }The adapter in packages/tui/src/plugin/api.tsx applies the presentation policy before handing off to the global toast queue:
ui.toast.show(options) if no sessionID show as-is if root(routed session) == root(options.sessionID) # same family: parent or subagent open show as-is else title = options.title ?? session.title action = "Open" -> route.navigate({ type: "session", sessionID }) showThe built-in notifications plugin drops its hand-rolled route check and uses the field instead:
Files:
packages/plugin/src/tui/context.ts # ToastOptions.sessionID packages/tui/src/plugin/api.tsx # session-aware toast adapter packages/tui/src/feature-plugins/system/notifications.ts # uses sessionID packages/tui/test/cli/cmd/tui/notifications.test.ts # asserts tagged toast +packages/tui/test/plugin-toast.test.tsx # adapter policy tests