Product updates for the scomp protocol, Rust SDK, and embedded sandbox runtime.Documentation Index
Fetch the complete documentation index at: https://docs.scomp.dev/llms.txt
Use this file to discover all available pages before exploring further.
Week of May 11, 2026
Two major redesigns landed this week: an API idiomacy pass that reshaped the SDK surface, and a developer-experience pass that overhauls how you declare and call bindings.New features
Ergonomic binding macros. Define a binding with a single attribute or abind! macro — no more hand-rolling handler structs. The #[binding] attribute turns any function into a binding, picks up its /// doc comment as the description, supports an effects = [...] annotation, and emits a unit struct so you can pass server.bind(add) without parens. The same binding gains a .call(...) inherent method for use from Rust. The bind! macro (formerly bind_fn!) covers the closure form, with both sync and async arms. See Runtimes and bindings.
Client-declared bindings. Clients can now declare their own bindings that the server can invoke — bringing the protocol’s symmetric peer model fully to the SDK. The server can call back into the client over the same connection.
Session resumption. Reconnect to an existing session after a transport drop without losing state. The server keeps your session, replays what it owes, and resumes from where you left off.
Client-side binding introspection. Clients can now query the server’s declared bindings (client_bindings) to discover what’s available before invoking — useful for agents that want to inspect a runtime’s capabilities at connection time.
Native client.invoke. Clients can call server bindings directly with a typed invoke method, no more hand-building eval strings. Matches the spec’s §8.3 invoke shape.
Builder-style construction with sensible defaults. Spin up a server with WebSocket + QuickJS preconfigured — ScompServer::builder() gives you a working setup in a few lines. Runtime and transport are now feature-gated, so you only pay for what you use.
Binding hints field. Bindings can now advertise hints — kind, latency, and an open key/value map — so agents can make better decisions about when and how to call them. Defined in spec §7.1.1. See Wire format.
Updates
Typestate client API.ScompClient now splits into ScompClient (unconnected) and ConnectedClient (connected), so you can’t accidentally call connection-only methods on a disconnected client. The compiler catches misuse at build time.
Unified binding registry. Client and server now share a single binding registry and a single inbound-invoke parser. Strict validation on both sides, no more divergent code paths.
Peer<R> typestate. The peer type is now generic over its runtime, making custom runtimes a first-class extension point.
Idiomatic SDK surface. Renamed and tightened several public types for consistency: ServerBindingHandler → BindingHandler, WireObserver trait replaces the set_on_send / set_on_recv pair, and the prelude now re-exports bind and binding for one-line imports.
Slimmer dependencies. scomp_core no longer depends on tokio or thiserror, and scomp drops thiserror entirely — smaller compile times, fewer transitive deps.
Better error reporting. QuickJS runtime errors now use LLM-readable messages, with cross-connection function references properly scoped. Error codes are aligned with the spec.
JS eval ergonomics. The runtime now accepts bare object literals and zero-argument binding calls (add() instead of add({})) — matching what an agent naturally writes.
Bug fixes
- Fixed non-deterministic compliance failures caused by a close-handshake race.
- Function-reference lifecycle now uses proper refcounting; references with shared lifetime no longer leak.
BindScompFnsderive now rejects enums with a clear error instead of producing broken code.default_bindings::helpis sync (it always was — the signature now matches).- The scomp-agent extends chat history across turns instead of replacing it.
- QuickJS console binding registration fixed; rebind no longer leaves stale handlers.