cloudaxe-opencode/packages/opencode
Kit Langton ab31c41fee refactor(bus): one GlobalBus emit per event, with optional sync metadata
Today every sync.run produces TWO GlobalBus events:

  1. From bus.publish itself — the projection view:
     { payload: { id, type: "session.created", properties } }

  2. From sync/index.ts — the source-of-truth envelope:
     { payload: { type: "sync", syncEvent: { type: "session.created.1", id, seq, aggregateID, data } } }

These two emits live in different files and discriminate via
`payload.type` — either a real event type or the sentinel "sync".
That collision is the source of confusion in the codebase:
consumers have to know which shape they're looking at.

The duality dates back to:
  - d88912abf0 (Dec 2025): Dax added GlobalBus.emit inside bus.publish.
  - b22add292c (#22347, Apr 2026): James consolidated sync events onto
    GlobalBus by ADDING a second emit with the source envelope.

#22347's stated intent was "consolidate events into a single stream".
Two emits with different shapes on one channel isn't quite that. One
emit per event with a unified shape is.

This PR collapses the two emits into one:

  { payload: { id, type: "session.created", properties, sync?: { name, seq, aggregateID, data } } }

- bus.publish accepts an optional `sync?: SyncMetadata` option.
- sync/index.ts passes it; its own GlobalBus.emit is removed.
- BusEvent.effectPayloads() adds an optional `sync` field to every
  event schema.
- SyncEvent.effectPayloads() is no longer included in the wire schema
  (it's now subsumed by the optional field).
- Consumers migrate from `payload.type === "sync"` filtering to
  `payload.sync != null` filtering. control-plane/workspace.ts
  reconstructs SerializedEvent from { id, sync.* } for replay.

Note: this is a BREAKING SDK wire-format change. External consumers
that read `payload.type === "sync"` or `payload.syncEvent` need to
migrate. Internal opencode consumers all migrated in this PR.

Side observation: the runtime emit was using `payload.syncEvent`
(nested) while the SDK schema declared the fields at top level under
`type: "sync"` — a silent schema drift. Collapsing to one emit also
fixes that drift by definition.

Verified:
  - bun typecheck — clean
  - bun run test test/sync/index.test.ts test/bus/bus-effect.test.ts
    test/server/httpapi-event.test.ts
    test/server/httpapi-event-diagnostics.test.ts — 29/29 green
  - bun run test test/server/httpapi-sdk.test.ts -t "streams sync-backed" — green
2026-05-18 13:23:30 -04:00
..
bin fix(cli): forward signals from npm shim (#26259) 2026-05-08 14:00:51 -05:00
migration chore: generate 2026-05-12 05:20:22 +00:00
script Speed up targeted opencode tests 2026-05-18 16:18:29 +00:00
specs chore: generate 2026-05-16 00:44:10 +00:00
src refactor(bus): one GlobalBus emit per event, with optional sync metadata 2026-05-18 13:23:30 -04:00
test Stabilize watcher test readiness (#28194) 2026-05-18 12:51:46 -04:00
.gitignore Load models.dev snapshot from build global (#28077) 2026-05-17 21:59:44 -04:00
AGENTS.md refactor(instance): remove legacy runtime fallback (#27757) 2026-05-15 23:05:44 +05:30
BUN_SHELL_MIGRATION_PLAN.md
bunfig.toml tui plugins (#19347) 2026-03-27 15:00:26 +01:00
Dockerfile
drizzle.config.ts
git feat: interactive update flow for non-patch releases (#18662) 2026-03-22 23:12:40 +00:00
package.json Speed up targeted opencode tests 2026-05-18 16:18:29 +00:00
parsers-config.ts feat(tui): add syntax highlighting for elixir, fsharp, r, make, vim, xml, agda (#28198) 2026-05-18 13:08:08 -04:00
README.md
sst-env.d.ts
tsconfig.json core: remove @effect/language-service plugin and optimize hot path type performance 2026-04-30 23:21:05 -04:00

js

To install dependencies:

bun install

To run:

bun run index.ts

This project was created using bun init in bun v1.2.12. Bun is a fast all-in-one JavaScript runtime.