···117117- Adds header comments with `@generated` marker and lexicon NSID
118118- Handles XRPC queries, procedures, subscriptions, and errors
119119- Generates proper module tree with Rust 2018 style
120120+- **XrpcRequest trait**: Implemented directly on params/input structs (not marker types), with GATs for Output<'de> and Err<'de>
121121+- **IntoStatic trait**: All generated types implement `IntoStatic` to convert borrowed types to owned ('static) variants
122122+- **Collection trait**: Implemented on record types directly, with const NSID
120123121124## Current State & Next Steps
122125···128131- ✅ CidLink wrapper type with automatic `{"$link": "cid"}` serialization in JSON
129132- ✅ Integration test with real Bluesky thread data validates round-trip correctness
130133- ✅ Lexicon code generation with forward compatibility and proper lifetime handling
134134+- ✅ IntoStatic implementations for all generated types (structs, enums, unions)
135135+- ✅ XrpcRequest trait with GATs, implemented on params/input types directly
136136+- ✅ HttpClient and XrpcClient traits with generic send_xrpc implementation
137137+- ✅ Response wrapper with parse() (borrowed) and into_output() (owned) methods
138138+- ✅ Structured error types (ClientError, TransportError, EncodeError, DecodeError, HttpError, AuthError)
131139132140### Next Steps
133133-1. **Lexicon Resolution**: Fetch lexicons from web sources (atproto authorities, git repositories) and parse into corpus
134134-2. **Custom Lexicon Support**: Allow users to plug in their own generated lexicons alongside jacquard-api types in the client/server layer
135135-3. **Client Implementation**: Build HTTP client layer for XRPC operations in the main `jacquard` crate
136136-4. **Public API**: Design the main API surface in `jacquard` that re-exports and wraps generated types
137137-5. **DID Document Support**: Parsing, validation, and resolution of DID documents
138138-6. **OAuth Implementation**: OAuth flow support for authentication
139139-7. **Examples & Documentation**: Create examples and improve documentation
140140-8. **Testing**: Comprehensive tests for generated code and round-trip serialization
141141+1. **Concrete HttpClient Implementation**: Implement HttpClient for reqwest::Client and potentially other HTTP clients
142142+2. **Error Handling Improvements**: Add XRPC error parsing, better HTTP status code handling, structured error responses
143143+3. **Authentication**: Session management, token refresh, DPoP support
144144+4. **Body Encoding**: Support for non-JSON encodings (CBOR, multipart, etc.) in procedures
145145+5. **Lexicon Resolution**: Fetch lexicons from web sources (atproto authorities, git repositories) and parse into corpus
146146+6. **Custom Lexicon Support**: Allow users to plug in their own generated lexicons alongside jacquard-api types in the client/server layer
147147+7. **Public API**: Design the main API surface in `jacquard` that re-exports and wraps generated types
148148+8. **DID Document Support**: Parsing, validation, and resolution of DID documents
149149+9. **OAuth Implementation**: OAuth flow support for authentication
150150+10. **Examples & Documentation**: Create examples and improve documentation
151151+11. **Testing**: Comprehensive tests for generated code and round-trip serialization
···1010#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
1111#[serde(rename_all = "camelCase")]
1212pub struct DisableRule<'a> {}
1313+impl jacquard_common::IntoStatic for DisableRule<'_> {
1414+ type Output = DisableRule<'static>;
1515+ fn into_static(self) -> Self::Output {
1616+ DisableRule {
1717+ extra_data: self.extra_data.into_static(),
1818+ }
1919+ }
2020+}
2121+1322///Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository.
1423#[jacquard_derive::lexicon]
1524#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
···35443645impl jacquard_common::types::collection::Collection for Postgate<'_> {
3746 const NSID: &'static str = "app.bsky.feed.postgate";
4747+}
4848+4949+impl jacquard_common::IntoStatic for Postgate<'_> {
5050+ type Output = Postgate<'static>;
5151+ fn into_static(self) -> Self::Output {
5252+ Postgate {
5353+ created_at: self.created_at.into_static(),
5454+ detached_embedding_uris: self.detached_embedding_uris.into_static(),
5555+ embedding_rules: self.embedding_rules.into_static(),
5656+ post: self.post.into_static(),
5757+ extra_data: self.extra_data.into_static(),
5858+ }
5959+ }
3860}
···3232 ///The state of the video processing job. All values not listed as a known value indicate that the job is in process.
3333 #[serde(borrow)]
3434 pub state: jacquard_common::CowStr<'a>,
3535+}
3636+3737+impl jacquard_common::IntoStatic for JobStatus<'_> {
3838+ type Output = JobStatus<'static>;
3939+ fn into_static(self) -> Self::Output {
4040+ JobStatus {
4141+ blob: self.blob.into_static(),
4242+ did: self.did.into_static(),
4343+ error: self.error.into_static(),
4444+ job_id: self.job_id.into_static(),
4545+ message: self.message.into_static(),
4646+ progress: self.progress.into_static(),
4747+ state: self.state.into_static(),
4848+ extra_data: self.extra_data.into_static(),
4949+ }
5050+ }
3551}