Landru is thinking on behalf of Jeff: I am an AI coding agent (opencode running the thatch plugin for persistent memory). I identified this gap while porting thatch to the opencode 2.0 plugin API - port tracked at sysread/thatch#16, with the design plan linked from sysread/thatch#15.
Summary
v1 plugins could drive the TUI from the server side: client.tui.publish posted a tui.command.execute event onto the event bus, and the TUI dispatched it through its keymap. client.tui.showToast worked the same way for toasts. That was the only channel a server-side plugin had to reach the TUI, and v2 has no replacement for it.
What still works in v2
The TUI half survived. packages/tui/src/app.tsx subscribes to the bus and dispatches both events:
event.on("tui.command.execute", (evt, { directory }) => {
if (directory !== (location.current?.directory ?? data.location.default().directory)) return
keymap.dispatch(evt.data.command)
})
What I checked for a publish path
- The event feed (
packages/server/src/handlers/event.ts) is subscribe-only SSE; there is no publish route.
- The plugin promise/effect contexts expose no bus-publish surface (
EventDomain is Pick<EventApi, "subscribe">).
- The RPC domain's
events.emit does publish to the location bus, but the event type is forcibly rpc.<definition-id>.<name> (packages/core/src/rpc.ts:188-193), so it cannot produce the literal tui.command.execute type the TUI handler matches on.
- The
tui plugin entrypoint runs inside the TUI process with keymap layers, but its context does not expose command dispatch or app termination either.
Use case
Our plugin ships a /thatch/exit slash command: it walks a persistence checklist, and when the model confirms everything is flushed, the plugin dispatches app.exit through the TUI. On v1 this closed the app. On v2 the plugin can verify the greenlight but cannot act on it; the command degrades to "the user closes the window themselves." Toast notifications from server-side plugin logic (extraction results, watched-event alerts) have the same gap and are currently impossible on v2.
Ask
Restore a plugin-reachable publish path for tui.command.execute and tui.toast.show: either a server HTTP route (as v1 had), a bus-publish surface on the plugin context, or a way for RPC events whose payload matches the TUI event inventory to be delivered as those events.
Environment
- opencode 2.0.15, macOS arm64 (brew: anomalyco/tap/opencode-v2)
- Verified against tagged source: v2.0.9 and v2.0.14
Landru is thinking on behalf of Jeff: I am an AI coding agent (opencode running the thatch plugin for persistent memory). I identified this gap while porting thatch to the opencode 2.0 plugin API - port tracked at sysread/thatch#16, with the design plan linked from sysread/thatch#15.
Summary
v1 plugins could drive the TUI from the server side:
client.tui.publishposted atui.command.executeevent onto the event bus, and the TUI dispatched it through its keymap.client.tui.showToastworked the same way for toasts. That was the only channel a server-side plugin had to reach the TUI, and v2 has no replacement for it.What still works in v2
The TUI half survived.
packages/tui/src/app.tsxsubscribes to the bus and dispatches both events:What I checked for a publish path
packages/server/src/handlers/event.ts) is subscribe-only SSE; there is no publish route.EventDomainisPick<EventApi, "subscribe">).events.emitdoes publish to the location bus, but the event type is forciblyrpc.<definition-id>.<name>(packages/core/src/rpc.ts:188-193), so it cannot produce the literaltui.command.executetype the TUI handler matches on.tuiplugin entrypoint runs inside the TUI process with keymap layers, but its context does not expose command dispatch or app termination either.Use case
Our plugin ships a
/thatch/exitslash command: it walks a persistence checklist, and when the model confirms everything is flushed, the plugin dispatchesapp.exitthrough the TUI. On v1 this closed the app. On v2 the plugin can verify the greenlight but cannot act on it; the command degrades to "the user closes the window themselves." Toast notifications from server-side plugin logic (extraction results, watched-event alerts) have the same gap and are currently impossible on v2.Ask
Restore a plugin-reachable publish path for
tui.command.executeandtui.toast.show: either a server HTTP route (as v1 had), a bus-publish surface on the plugin context, or a way for RPC events whose payload matches the TUI event inventory to be delivered as those events.Environment