Skip to main content

codeoid_protocol/
lib.rs

1//! Codeoid wire protocol — Rust port of `src/protocol/types.ts` from the daemon.
2//!
3//! This crate is pure data: no I/O, no async, no Tokio. It defines serde-
4//! compatible types for every message that flows between a Codeoid client and
5//! the daemon's WebSocket server.
6//!
7//! # Design notes
8//!
9//! * **Discriminated unions.** TypeScript uses `type: "foo"` and `kind: "bar"`
10//!   as discriminants. In Rust these map to `#[serde(tag = "type")]` and
11//!   `#[serde(tag = "kind")]` tagged enums.
12//! * **Forward compatibility.** The daemon's design explicitly says "frontends
13//!   ignore unknown kinds". We mirror that by using `#[serde(other)]` on a
14//!   trailing `Unknown` variant and `#[serde(flatten)]` on extensible metadata
15//!   maps. Adding new server-side message kinds never breaks an old Rust
16//!   client — they deserialize into [`DaemonMessage::Unknown`] and the TUI
17//!   logs + skips them.
18//! * **Tool state as full replacement.** [`ToolState`] is a tagged enum where
19//!   each phase carries its own shape. When a [`SessionMessageDelta`] arrives
20//!   with `tool_state_update`, replace the whole [`ToolInfo::state`] — do not
21//!   merge fields.
22//!
23//! # Versioning
24//!
25//! [`PROTOCOL_VERSION`] is compared against the `protocol_version` field the
26//! daemon sends on `auth.ok`. Mismatch is non-fatal (the daemon's additive
27//! changes keep old clients working), but the client warns the user so they
28//! can upgrade.
29
30#![deny(missing_debug_implementations)]
31#![warn(clippy::pedantic)]
32#![allow(clippy::module_name_repetitions)]
33
34pub mod client;
35pub mod daemon;
36pub mod message;
37pub mod session;
38pub mod tool;
39
40pub use client::{Attachment, ClientMessage, SearchScope, SendPriority, SessionImportSource};
41pub use daemon::{
42    AuthOkMsg, ClaudeConfigAgent, ClaudeConfigHook, ClaudeConfigMcpServer, ClaudeConfigScope,
43    ClaudeConfigSkill, DaemonMessage, ErrorCode, ModelInfo, ProviderCommand, SessionExportCounts,
44    SessionExportManifest, SessionExportMetaSlim, SessionExportPayload, SessionExportWorkdir,
45    SessionSearchHit, SessionSearchSnippet, SessionUiRequestMsg, UiRequestMethod, UiResolvedReason,
46};
47pub use message::{
48    ContentPart, IdentityType, MessageIdentity, MessageRole, SessionMessage, SessionMessageDelta,
49};
50pub use session::{
51    ForkedFrom, SessionInfo, SessionMode, SessionStatus, SessionUsage, SessionWorktree, Subagent,
52    TurnUsage,
53};
54pub use tool::{CancelReason, ConfirmedBy, ToolInfo, ToolPhase, ToolState};
55
56/// Wire protocol version this crate speaks.
57///
58/// Compared against [`AuthOkMsg::protocol_version`] on connect. Bump this
59/// alongside the daemon's `PROTOCOL_VERSION` on any breaking change.
60pub const PROTOCOL_VERSION: u32 = 1;