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

ModuleContents
json.tsRecursive JsonValue for opaque herdr passthroughs.
envelope.tsRelayRequest, the ready frame, ack/error replies, stream frames, and the RelayServerMessage union.
ops.tsPer-op args, the RELAY_OP_NAMES catalog, OP_RESULT_SCHEMAS (result by op), and the RelayRequestByOp discriminated union.
herdr.tsHerdr entities (pane/tab/workspace/session), list envelopes, dispatch-op results, and GET /relay/health.
streaming.tssubscribe/attach stream bodies: subscriptions, PaneOutputFrame, realtime herdr events.
menu.tsNative slash-command menu events and client responses.
session.tsThe 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 typechecktsc --noEmit (standalone typecheck).
  • pnpm build — emit dist/ (.js + .d.ts). Source imports use explicit .ts extensions 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.