anomalyco / anomalyco/opencode
[FEATURE]: Cross-project session event bus + a documented plugin-safe way to subscribe to it
@jlongster is already working on this.
Since Aug 27, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
[FEATURE]: Cross-project session event bus + a documented plugin-safe way to subscribe to it
(drafted after building a subagent-monitoring plugin on Desktop v1.18.23 / Windows 11; complements #38604)
Problem
There is currently no working path for a plugin (or any local client) to observe session activity across all of a user's projects:
- The plugin
eventhook is dead in the Desktop app — tracked in #38604. In our repro the hook receives zero calls while tasks run (seen: {}). - Subscribing from inside the plugin via the SDK hits version drift: the documented surface exposes
client.event.list()per current docs, but the runtime client here only shipsclient.event.subscribe(). Feature-detecting both works, but this is an undocumented contract that can silently break again. - Whatever subscription method is used,
/eventonly deliversserver.connected/server.heartbeat— nosession.created,session.updated,message.part.updated, no tool events — even while agents are actively running in known project directories. This holds both for the unscoped stream and for{ query: { directory } }variants. - The only channel that works at all is polling
client.session.list({ query: { directory } })separately for every project directory — and discovering those directories requires scraping the Desktop app's internal state files (%APPDATA%/ai.opencode.desktop/opencode.global.dat), which is unsupported and will break silently.
Net result: we built a live subagent tree dashboard (localhost SSE page showing task → @explore/@general subagents → tools) and ~80% of its plumbing exists solely to work around the missing event access.
Field observations (reproducible)
- Desktop v1.18.23, Windows 11; single NodeService core process hosts all workspaces (verified: one API listener, one app instance).
- Plugin loaded globally from
~/.config/opencode/plugins/; visible in UI as active (matches #38604). - Hook probe instrumented to count every received event by type across restarts and multiple real agent runs:
eventhook — 0 invocations ever; SDK stream —server.*only;session.listpolling — returns sessions when scoped to the rightdirectory, empty otherwise. - SDK client keys confirmed at runtime:
event.subscribepresent,event.listabsent (docs say otherwise).
Proposal
- A global scope for the event stream, e.g.
/event?scope=all(orX-Scope: global), deliveringsession.*/message.part.updated/ tool events for every directory served by that core, without requiring callers to know every workspace path. - Pin down and document one SDK subscription entry point usable from plugins (
event.subscribevsevent.list— today they diverge between docs and runtime builds), ideally with a stable signature and an explicit promise of shape stability. - Carry parent lineage on session events so consumers can build subagent trees without cross-referencing lists:
session.createdalready hasinfo.parentID, but idle/status does not (#30043), and list endpoints lack a parentID filter (#34936). Standardizing this would make subagent observability nearly free. - (Stretch) any mechanism for a plugin/UI contribution to render out-of-band output (panel, toast, sidecar page) so monitors like ours don't need to bootstrap their own HTTP server on a random port (today: port-collision races between opencode instances).
Related
- #38604 — Desktop plugin hooks never invoked (the root cause of point 1)
- #30043 —
session.statusshould includeparentID - #34936 — parentID filter for session lists
- #28695 — session lifecycle context hooks
- #34553 — Desktop vs CLI plugin behavior differences
Happy to contribute a PR for the global-scope flag if pointed at the right dispatch site — we have a real-world consumer (the dashboard plugin) to validate against.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.