docs/happy-wire.md
This document describes the shared wire package: @slopus/happy-wire.
Before happy-wire, wire-level message and session-protocol schemas were duplicated across packages (CLI, app, server, and agent). That caused drift risk and made protocol evolution harder.
@slopus/happy-wire centralizes those shared schemas and types so all clients and services agree on the same wire contract.
@slopus/happy-wirepackages/happy-wire^0.1.0Shared from @slopus/happy-wire:
messages.ts: SessionMessageContentSchema, SessionMessageSchema, MessageMetaSchema, SessionProtocolMessageSchema, MessageContentSchema (top-level role union: user|agent|session), UpdateNewMessageBodySchema, UpdateSessionBodySchema, UpdateMachineBodySchema, CoreUpdateContainerSchemalegacyProtocol.ts: UserMessageSchema (role: 'user'), AgentMessageSchema (role: 'agent'), LegacyMessageContentSchema (role-discriminated union for legacy only)These are used for encrypted message/update contracts (new-message, update-session, update-machine).
Shared from @slopus/happy-wire:
sessionEventSchemasessionEnvelopeSchemacreateEnvelope(...)SessionEnvelope and related typesThis is the canonical schema for the unified session protocol event stream.
Current role set in sessionEnvelopeSchema:
'user' (user-originated envelope)'agent' (agent/system output envelopes)Current session wire payload shape (decrypted message body):
role is always 'session' for session-protocol recordscontent is the session envelope object directly (not wrapped under content.data)content.role ('user' | 'agent')content.time (Unix ms)User text rollout toggle:
ENABLE_SESSION_PROTOCOL_SEND (truthy: 1, true, yes)role = 'session', content.role = 'user')role = 'user', content.type = 'text') and drops modern user payloadsrole = 'session', content.role = 'user')packages/happy-cli)@slopus/happy-wire directly.src/sessionProtocol/types.ts now re-exports from @slopus/happy-wire as compatibility shim.src/api/types.ts now source shared message/update schemas from @slopus/happy-wire.packages/happy-app)sources/sync/apiTypes.ts now import these from @slopus/happy-wire:
ApiMessageSchemaApiUpdateNewMessageSchemaApiUpdateSessionStateSchemaApiUpdateMachineStateSchemapackages/happy-server)SessionMessageContent from @slopus/happy-wire.SessionMessageContent type for new-message payload typing.packages/happy-agent)RawMessage now aliases SessionMessage from @slopus/happy-wire.All other workspace packages now declare a versioned dependency on @slopus/happy-wire.
This intentionally mirrors post-publish consumption and reduces hidden coupling to workspace-local files.
@slopus/happy-wire is configured the same way as existing publishable libraries in this repo:
pkgrollbuild: typecheck + bundletest: build + vitestprepublishOnly: build + testrelease: release-itpublishConfigUse the same release entrypoint as other publishable packages:
yarn release
# choose happy-wire
or:
yarn workspace @slopus/happy-wire release
When building workspaces from a clean checkout, build @slopus/happy-wire first so dependent packages can resolve generated dist outputs.
@slopus/happy-wire.happy-wire version is available.happy-wire should stay focused on wire contracts only (types + Zod schemas + small helpers).