···1-# CLAUDE.md
2-3-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4-5-## Project Overview
6-7-Jacquard is a suite of Rust crates for the AT Protocol (atproto/Bluesky). The project emphasizes spec-compliant, validated, performant baseline types with minimal boilerplate. Key design goals:
8-9-- Validated AT Protocol types including typed at:// URIs
10-- Custom lexicon extension support
11-- Lexicon `Value` type for working with unknown atproto data (dag-cbor or json)
12-- Using as much or as little of the crates as needed
13-14-## Workspace Structure
15-16-This is a Cargo workspace with several crates:
17-18-- **jacquard**: Main library crate with XRPC client and public API surface (re-exports jacquard-api and jacquard-common)
19-- **jacquard-common**: Core AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.) and the `CowStr` type for efficient string handling
20-- **jacquard-lexicon**: Lexicon parsing and Rust code generation from lexicon schemas
21-- **jacquard-api**: Generated API bindings from lexicon schemas (implementation detail, not directly used by consumers)
22-- **jacquard-derive**: Attribute macros (`#[lexicon]`, `#[open_union]`) for lexicon structures
23-24-## Development Commands
25-26-### Using Nix (preferred)
27-```bash
28-# Enter dev shell
29-nix develop
30-31-# Build
32-nix build
33-34-# Run
35-nix develop -c cargo run
36-```
37-38-### Using Cargo/Just
39-```bash
40-# Build
41-cargo build
42-43-# Run tests
44-cargo test
45-46-# Run specific test
47-cargo test <test_name>
48-49-# Run specific package tests
50-cargo test -p <package_name>
51-52-# Run
53-cargo run
54-55-# Auto-recompile and run
56-just watch [ARGS]
57-58-# Format and lint all
59-just pre-commit-all
60-61-# Generate API bindings from lexicon schemas
62-cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i <input_dir> -o <output_dir> [-r <root_module>]
63-# Example:
64-cargo run -p jacquard-lexicon --bin jacquard-codegen -- -i crates/jacquard-lexicon/tests/fixtures/lexicons/atproto/lexicons -o crates/jacquard-api/src -r crate
65-```
66-67-## String Type Pattern
68-69-The codebase uses a consistent pattern for validated string types. Each type should have:
70-71-### Constructors
72-- `new()`: Construct from a string slice with appropriate lifetime (borrows)
73-- `new_owned()`: Construct from `impl AsRef<str>`, taking ownership
74-- `new_static()`: Construct from `&'static str` using `SmolStr`/`CowStr`'s static constructor (no allocation)
75-- `raw()`: Same as `new()` but panics instead of returning `Result`
76-- `unchecked()`: Same as `new()` but doesn't validate (marked `unsafe`)
77-- `as_str()`: Return string slice
78-79-### Traits
80-All string types should implement:
81-- `Serialize` + `Deserialize` (custom impl for latter, sometimes for former)
82-- `FromStr`, `Display`
83-- `Debug`, `PartialEq`, `Eq`, `Hash`, `Clone`
84-- `From<T> for String`, `CowStr`, `SmolStr`
85-- `From<String>`, `From<CowStr>`, `From<SmolStr>`, or `TryFrom` if likely to fail
86-- `AsRef<str>`
87-- `Deref` with `Target = str` (usually)
88-89-### Implementation Details
90-- Use `#[repr(transparent)]` when possible (exception: at-uri type and components)
91-- Use `SmolStr` directly as inner type if most instances will be under 24 bytes
92-- Use `CowStr` for longer strings to allow borrowing from input
93-- Implement `IntoStatic` trait to take ownership of string types
94-95-## Code Style
96-97-- Avoid comments for self-documenting code
98-- Comments should not detail fixes when refactoring
99-- Professional writing within source code and comments only
100-- Prioritize long-term maintainability over implementation speed
101-102-## Testing
103-104-- Write test cases for all critical code
105-- Tests can be run per-package or workspace-wide
106-- Use `cargo test <name>` to run specific tests
107-- Current test coverage: 89 tests in jacquard-common
108-109-## Lexicon Code Generation
110-111-The `jacquard-codegen` binary generates Rust types from AT Protocol Lexicon schemas:
112-113-- Generates structs with `#[lexicon]` attribute for forward compatibility (captures unknown fields in `extra_data`)
114-- Generates enums with `#[open_union]` attribute for handling unknown variants (unless marked `closed` in lexicon)
115-- Resolves local refs (e.g., `#image` becomes `Image<'a>`)
116-- Extracts doc comments from lexicon `description` fields
117-- Adds header comments with `@generated` marker and lexicon NSID
118-- Handles XRPC queries, procedures, subscriptions, and errors
119-- Generates proper module tree with Rust 2018 style
120-- **XrpcRequest trait**: Implemented directly on params/input structs (not marker types), with GATs for Output<'de> and Err<'de>
121-- **IntoStatic trait**: All generated types implement `IntoStatic` to convert borrowed types to owned ('static) variants
122-- **Collection trait**: Implemented on record types directly, with const NSID
123-124-## Current State & Next Steps
125-126-### Completed
127-- ✅ Comprehensive validation tests for all core string types (handle, DID, NSID, TID, record key, AT-URI, datetime, language, identifier)
128-- ✅ Validated implementations against AT Protocol specs and TypeScript reference implementation
129-- ✅ String type interface standardization (Language now has `new_static()`, Datetime has full conversion traits)
130-- ✅ Data serialization: Full serialize/deserialize for `Data<'_>`, `Array`, `Object` with format-specific handling (JSON vs CBOR)
131-- ✅ CidLink wrapper type with automatic `{"$link": "cid"}` serialization in JSON
132-- ✅ Integration test with real Bluesky thread data validates round-trip correctness
133-- ✅ Lexicon code generation with forward compatibility and proper lifetime handling
134-- ✅ IntoStatic implementations for all generated types (structs, enums, unions)
135-- ✅ XrpcRequest trait with GATs, implemented on params/input types directly
136-- ✅ HttpClient and XrpcClient traits with generic send_xrpc implementation
137-- ✅ Response wrapper with parse() (borrowed) and into_output() (owned) methods
138-- ✅ Structured error types (ClientError, TransportError, EncodeError, DecodeError, HttpError, AuthError)
139-140-### Next Steps
141-1. **Concrete HttpClient Implementation**: Implement HttpClient for reqwest::Client and potentially other HTTP clients
142-2. **Error Handling Improvements**: Add XRPC error parsing, better HTTP status code handling, structured error responses
143-3. **Authentication**: Session management, token refresh, DPoP support
144-4. **Body Encoding**: Support for non-JSON encodings (CBOR, multipart, etc.) in procedures
145-5. **Lexicon Resolution**: Fetch lexicons from web sources (atproto authorities, git repositories) and parse into corpus
146-6. **Custom Lexicon Support**: Allow users to plug in their own generated lexicons alongside jacquard-api types in the client/server layer
147-7. **Public API**: Design the main API surface in `jacquard` that re-exports and wraps generated types
148-8. **DID Document Support**: Parsing, validation, and resolution of DID documents
149-9. **OAuth Implementation**: OAuth flow support for authentication
150-10. **Examples & Documentation**: Create examples and improve documentation
151-11. **Testing**: Comprehensive tests for generated code and round-trip serialization