@volpestyle/clankie-contract
The shared wire vocabulary of the Clankie bundle: Zod schemas plus their inferred TypeScript types for the relay WebSocket protocol, the Eve session stream, and the orchestration surface. The lead-agent brain, the relay, and the Clankies iOS window all speak it from one source.
The contract is also Clankie's trust surface made concrete. Everything the
product promises about remote control and auditability — live terminal attach,
pane read and steer, wake-armed spawns, lead phases (working, awaiting,
harvest_ready, needs_human, blocked), per-pane activity (thinking,
reading, editing, running, searching, spawning, waiting-on-child,
awaiting-input, idle), push on blocked/done, durable transcripts, the usage
ledger — exists here as a typed, parseable schema. If a window can do it, it is
in the contract.
pnpm add @volpestyle/clankie-contract
Usage
import { RelayRequestByOpSchema, SessionEventSchema } from "@volpestyle/clankie-contract";
const req = RelayRequestByOpSchema.parse({ op: "start", args: { name: "w", argv: ["claude"] } });
const event = SessionEventSchema.parse(JSON.parse(ndjsonLine));
Sources of truth
The canonical wire contract lives in the Clankie agent backend and is consumed by both the relay implementation and the iOS client:
clankie-agent/agent/channels/relay.ts: op names,dispatch()results, and the streaming/control op handlers.- Clankie 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. |
orchestration.ts | The orchestration graph surface: spawn events, pane summaries, per-pane activity, and the lead-phase enum. |
garden.ts | Garden action ops: the write surface that lets the window start things — skill enumeration/invocation and garden-managed schedules. |
tool-call-format.ts | Shared pure formatter for tool-call display labels, salient summaries, and categories. |
presence.ts | Clankie's non-primary presence sessions (Discord text/voice, tracker) as enumerated for the window's chat drawer. |
pane-chat.ts | Native pane chat: harness session files rendered as structured, role-tagged transcripts. |
lifecycle.ts | The supervisor's remote cold-start API: up/status/down. |
pairing.ts | The clankie://connect QR / deep-link pairing payload. |
stats.ts | Usage stats: durable daily rollups of the usage ledger, served from the relay stats op. |
tracker.ts | Native work-tracker shapes: issues, comments, actor identity. |
session.ts | The consumed subset of Eve session events, plus the Eve session HTTP request/response shapes. |
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.
The agent consumes this package through a pnpm workspace link from its package-local workspace; the private iOS app consumes the published npm package.
Orchestration Activity
PaneActivity.kind is an open string so new producers can add activity kinds
without breaking old clients. The known producer set is exported as
PANE_ACTIVITY_KNOWN_KINDS; unrecognized values should fall back to generic
movement. PANE_ACTIVITY_TTL_MS is the staleness window. Clients should ignore
activity older than that TTL and fall back to phase-bucket/default behavior.
