clanky-contract/README.md
@clanky/contract
Zod schemas plus their inferred TypeScript types for the Clanky wire contract: the relay WebSocket protocol and the Eve session stream. It is the shared wire vocabulary of the bundle — the lead-agent brain, the relay, and the iOS window all speak it. This package lives at the top level of the Clanky monorepo so the agent and clients consume the same schemas from one source.
Sources of truth
The canonical wire contract lives in the Clanky agent backend and is consumed by both the relay implementation and the React Native client:
../clanky-agent/agent/channels/relay.ts— op names,dispatch()results, and the streaming/control op handlers.- Clanky agent Eve session routes — session HTTP shapes and NDJSON stream events.
- The private iOS app's relay and Eve session transports.
Wire keys follow the source: herdr/relay ops are snake_case; Eve session events, menu events, and Eve session HTTP shapes are camelCase.
Layout
| Module | Contents |
|---|---|
json.ts | Recursive JsonValue for opaque herdr passthroughs. |
envelope.ts | RelayRequest, the ready frame, ack/error replies, stream frames, and the RelayServerMessage union. |
ops.ts | Per-op args, the RELAY_OP_NAMES catalog, OP_RESULT_SCHEMAS (result by op), and the RelayRequestByOp discriminated union. |
herdr.ts | Herdr entities (pane/tab/workspace/session), list envelopes, dispatch-op results, and GET /relay/health. |
streaming.ts | subscribe/attach stream bodies: subscriptions, PaneOutputFrame, realtime herdr events. |
menu.ts | Native slash-command menu events and client responses. |
session.ts | The consumed subset of Eve session events, plus the Eve session HTTP request/response shapes. |
Usage
import { RelayRequestByOpSchema, SessionEventSchema } from "@clanky/contract";
const req = RelayRequestByOpSchema.parse({ op: "start", args: { name: "w", argv: ["claude"] } });
const event = SessionEventSchema.parse(JSON.parse(ndjsonLine));
Scripts
pnpm typecheck—tsc --noEmit(standalone typecheck).pnpm build— emitdist/(.js+.d.ts). Source imports use explicit.tsextensions so Node's strip-types runtime and Metro resolve the same package entrypoint; emitted JS rewrites those imports to.js.- Agent and iOS both consume this package through pnpm workspace links from their package-local workspaces. Private EAS builds run from the internal full checkout, so this top-level package is available to the cloud build without a separate public contract repo.
