pi_codes/lib.rs
1//! # pi-codes
2//!
3//! Typed Rust SDK for the [pi coding agent](https://github.com/earendil-works/pi)
4//! (`@earendil-works/pi-coding-agent`): serde models of the
5//! `pi --mode json` JSONL event stream and the `pi --mode rpc`
6//! stdin/stdout command protocol, plus an async (Tokio) RPC client.
7//!
8//! ```no_run
9//! # #[cfg(feature = "async-client")]
10//! # async fn demo() -> pi_codes::Result<()> {
11//! use pi_codes::{PiRpcClient, RpcCommand};
12//!
13//! let mut client = PiRpcClient::start().await?;
14//! let state = client.request_ok(RpcCommand::GetState { id: None }).await?;
15//! println!("session: {:?}", state.data);
16//! client.shutdown().await?;
17//! # Ok(())
18//! # }
19//! ```
20//!
21//! ## Wire contract
22//!
23//! - RPC framing is strict JSONL: records split on `\n` only (`\r`
24//! tolerated); U+2028/U+2029 are legal inside strings and must not
25//! split records.
26//! - Unknown event types decode to [`io::PiEvent::Unknown`] with the
27//! payload preserved — ignore them rather than treating them as
28//! errors, so CLI upgrades degrade soft.
29//! - Unmodeled commands can be sent via [`rpc::RpcCommand::Raw`].
30//!
31//! **Alpha**: unlike the sibling crates, the crate version does not yet
32//! name the tested pi release — it stays 0.0.x while the API settles.
33//! The tested release is still machine-readable via
34//! [`version::tested_cli_version`].
35
36pub mod cli;
37pub mod error;
38#[cfg(feature = "types")]
39pub mod io;
40#[cfg(feature = "types")]
41pub mod rpc;
42pub mod version;
43
44#[cfg(feature = "async-client")]
45pub mod client_async;
46
47pub use cli::{Mode, PiCliBuilder};
48pub use error::{Error, Result};
49#[cfg(feature = "types")]
50pub use io::{ContentBlock, Model, PiEvent, PiMessage, Usage};
51#[cfg(feature = "types")]
52pub use rpc::{AgentState, BashResult, RpcCommand, RpcResponse, StreamingBehavior};
53
54#[cfg(feature = "async-client")]
55pub use client_async::PiRpcClient;