Appearance
Protos & Codegen
Soma defines its peer-facing (libp2p) message schemas in proto/ using Protocol Buffers. These are Rust-only wire formats; the desktop renderer no longer uses them for IPC (it talks to the Tauri host over commands — see below).
Where the .proto files live
- Daemon peer messages:
proto/daemon/v1/daemon.proto - Agent messages:
proto/agent/v1/agent.proto - Membership/capabilities:
proto/space/v1/membership.proto
How Rust bindings are generated
Rust types and gRPC service stubs are built at compile time by the soma-proto-build crate:
- Crate:
backend/crates/proto-build - Build script:
backend/crates/proto-build/build.rs - Modules re-exported from:
backend/crates/proto-build/src/lib.rs
build.rs uses tonic_prost_build to compile the .proto files into the crate’s OUT_DIR, and tonic::include_proto! pulls them into Rust modules.
The build script defaults to the workspace proto/ directory, but it also accepts SOMA_PROTO_ROOT as an override. That keeps local builds working today while making it possible to point the backend at an external contracts checkout later.
Practical implications:
- Editing a
.protofile will trigger rebuilds automatically (cargo:rerun-if-changed=...). - There is no checked-in generated Rust code; it is produced by Cargo builds.
Buf configuration
The repo includes Buf config files under proto/:
proto/buf.yamlproto/buf.gen.yaml
They currently act as scaffolding for linting/managed-mode workflows; Rust codegen is performed by Cargo (tonic_prost_build) rather than a Buf plugin.
Buf is also the right place to keep future cross-repo lint/breaking checks once contracts move out of this monorepo.
How TypeScript types reach the renderer
The .proto files are Rust-only — they describe the libp2p wire formats. There is no longer a TypeScript proto-codegen package: desktop/desktop-proto (@soma/proto) was removed with the Electron app.
The renderer no longer speaks gRPC. The Tauri host exposes its behaviour as #[tauri::command]s, and tauri-specta walks that command graph to emit TypeScript wire types into desktop/desktop-sdk/src/bindings/. The renderer consumes them through the typed @soma/sdk facade — never by hand-writing wire types and never from generated proto stubs.
Quick local checks
- Compile Rust bindings:
cargo build -p soma-proto-build - Compile a Rust crate that uses the protos:
cargo build -p somad - Regenerate the
@soma/sdkbindings: build the Tauri host (the specta export runs as part of thedesktop-commandsbuild); the output lands indesktop/desktop-sdk/src/bindings/.