Skip to main content

Module schema

Module schema 

Source
Expand description

Which request and response type each RPC command carries.

§Why this exists

The frontend talks to srv through 284 hand-written command stubs (frontend/app/store/rpc-api/*.ts) and a 2,819-line hand-maintained frontend/types/srv-types.d.ts, every one of them headed “keep in sync with the agentmux-srv RPC”. docs/reports/REPORT_DRY_AND_MODULARITY_AUDIT_2026_09_06.md §2.1 counted 334 such comments and one live drift found by hand.

The obvious fix — derive the TypeScript types from the Rust ones — does not work on its own, and docs/specs/SPEC_RPC_BINDINGS_CODEGEN_2026_09_07.md §2 explains why: which command takes which request and returns which response is not data anywhere in srv. Each handler picks its request type inline (serde_json::from_value::<CommandXData>(data)) and builds its response ad hoc (serde_json::to_value(&x), json!({"ok": true})). A type generator can emit every struct and still not know how to pair them into a callable stub.

This module is that missing mapping, recorded as a side effect of registration itself (RpcEngine::register_typed) rather than written down a second time — so it cannot drift from the handlers the way a hand-maintained list would. It is deliberately just the mapping: no TypeScript is emitted here, and adding a code generator on top is a separate change against an already-proven registry (spec §3.4 step 1).

§What a binding is

One row per command registered through the typed path, holding the fully qualified Rust type names of its request and response. Handlers still on the untyped register_handler contribute nothing — they are simply absent, which is what makes an incremental migration possible.

Structs§

RpcBinding
The request/response pair for one command.
RpcSchema
Every typed command registered on one engine.
TsType
How a Rust type reads in TypeScript, as ts-rs itself renders it.

Functions§

ts_type
T as TypeScript: its ts-rs name, and the exported types that name uses.