A better Rust ATProto crate
102
fork

Configure Feed

Select the types of activity you want to include in your feed.

0.11 version bump

+92 -55
+29 -1
CHANGELOG.md
··· 1 1 # Changelog 2 2 3 - ## [0.10.1] - 2026-03-20 (`jacquard-common`) 3 + ## [0.11.0] - 2026-03-21 4 + 5 + ### Breaking changes 6 + 7 + **Code generation pipeline overhaul** (`jacquard-lexicon`, `jacquard-lexgen`) 8 + - Jacquard's codegen output already was nice to *use*. now it's going to be nice to read. 9 + - New code generation tracks the types used, makes an import block for the file, and then organizes the file with stuff you care about at the top and internal stuff, like the builders, at the bottom. 10 + - Import resolution pass now conditionally generates short paths when types are unambiguous within a module, falling back to fully-qualified paths when collisions exist 11 + - Improved default value handling in generated code, reducing unnecessary boilerplate 12 + 13 + ### Added 14 + 15 + **Hand-written XRPC bootstrap types** (`jacquard-common`) 16 + - Added minimal XRPC endpoint types for `com.atproto.repo.listRecords`, `com.atproto.repo.getRecord`, `com.atproto.identity.resolveHandle`, and `com.atproto.identity.resolveDid` 17 + - These types break circular dependencies between `jacquard-lexgen`/`jacquard-identity` and `jacquard-api`, allowing the codegen tooling and identity resolver to function without depending on the generated API crate 18 + 19 + ### Changed 20 + 21 + **Regenerated API crate** (`jacquard-api`) 22 + - All generated code regenerated with the new codegen pipeline 23 + - Shorter import paths where unambiguous, cleaner builder output, better formatting throughout 24 + 25 + ## [0.10.1] - 2026-03-20 4 26 5 27 ### Fixed 6 28 7 29 **CID deserialization** (`jacquard-common`) 8 30 - Fixed `CidLink` deserialization from CBOR tag-42 bytes through internally-tagged enums (reported by @natalie.sh, fixed by adorable robot) 9 31 - `serde_ipld_dagcbor` buffers tag-42 CIDs as a newtype struct wrapping raw bytes when deserializing through `Content`; the visitor now handles `visit_bytes`, `visit_byte_buf`, and `visit_newtype_struct` to cover this path 32 + 33 + **Lexicon code generation** (`jacquard-lexicon`, `jacquard-api`) 34 + - Fixed `BlobRef` generation producing incorrect code in certain lexicon schemas 35 + 36 + **Identity resolution** (`jacquard-identity`) 37 + - Error message when handle resolution exhausts all resolution methods no longer misleading 10 38 11 39 ## [0.10.0] - 2026-03-20 12 40
+11 -11
Cargo.lock
··· 2392 2392 2393 2393 [[package]] 2394 2394 name = "jacquard" 2395 - version = "0.10.1" 2395 + version = "0.11.0" 2396 2396 dependencies = [ 2397 2397 "bytes", 2398 2398 "clap", ··· 2426 2426 2427 2427 [[package]] 2428 2428 name = "jacquard-api" 2429 - version = "0.10.2" 2429 + version = "0.11.0" 2430 2430 dependencies = [ 2431 2431 "jacquard-common", 2432 2432 "jacquard-derive", ··· 2438 2438 2439 2439 [[package]] 2440 2440 name = "jacquard-axum" 2441 - version = "0.10.0" 2441 + version = "0.11.0" 2442 2442 dependencies = [ 2443 2443 "axum", 2444 2444 "axum-macros", ··· 2480 2480 2481 2481 [[package]] 2482 2482 name = "jacquard-common" 2483 - version = "0.10.1" 2483 + version = "0.11.0" 2484 2484 dependencies = [ 2485 2485 "base64 0.22.1", 2486 2486 "bon", ··· 2535 2535 2536 2536 [[package]] 2537 2537 name = "jacquard-derive" 2538 - version = "0.10.1" 2538 + version = "0.11.0" 2539 2539 dependencies = [ 2540 2540 "heck 0.5.0", 2541 2541 "inventory", ··· 2551 2551 2552 2552 [[package]] 2553 2553 name = "jacquard-identity" 2554 - version = "0.10.0" 2554 + version = "0.11.0" 2555 2555 dependencies = [ 2556 2556 "bon", 2557 2557 "bytes", ··· 2574 2574 2575 2575 [[package]] 2576 2576 name = "jacquard-lexgen" 2577 - version = "0.10.1" 2577 + version = "0.11.0" 2578 2578 dependencies = [ 2579 2579 "clap", 2580 2580 "clap_complete", ··· 2600 2600 2601 2601 [[package]] 2602 2602 name = "jacquard-lexicon" 2603 - version = "0.10.1" 2603 + version = "0.11.0" 2604 2604 dependencies = [ 2605 2605 "bytes", 2606 2606 "cid", ··· 2629 2629 2630 2630 [[package]] 2631 2631 name = "jacquard-oauth" 2632 - version = "0.10.0" 2632 + version = "0.11.0" 2633 2633 dependencies = [ 2634 2634 "base64 0.22.1", 2635 2635 "bytes", ··· 2663 2663 2664 2664 [[package]] 2665 2665 name = "jacquard-repo" 2666 - version = "0.10.0" 2666 + version = "0.11.0" 2667 2667 dependencies = [ 2668 2668 "anyhow", 2669 2669 "bytes", ··· 2831 2831 2832 2832 [[package]] 2833 2833 name = "lazy-collections" 2834 - version = "0.10.1" 2834 + version = "0.11.0" 2835 2835 dependencies = [ 2836 2836 "buffer", 2837 2837 "bytes",
+1 -1
Cargo.toml
··· 5 5 6 6 [workspace.package] 7 7 edition = "2024" 8 - version = "0.10.1" 8 + version = "0.11.0" 9 9 authors = ["Orual <orual@nonbinary.computer>"] 10 10 #repository = "https://github.com/rsform/jacquard" 11 11 repository = "https://tangled.org/nonbinary.computer/jacquard"
+9
README.md
··· 91 91 92 92 [CHANGELOG.md](./CHANGELOG.md) 93 93 94 + #### 0.11 Release Highlights: 95 + 96 + - `jacquard-lexgen` and `jacquard-identity` no longer depend on the generated API crate. This is mostly for my own benefit. 97 + 98 + **Code generation pipeline overhaul** (`jacquard-lexicon`, `jacquard-lexgen`) 99 + - Jacquard's codegen output already was nice to *use*. now it's going to be nice to read. 100 + - New code generation tracks the types used, makes an import block for the file, and then organizes the file with stuff you care about at the top and internal stuff, like the builders, at the bottom. 101 + - Import resolution pass now conditionally generates short paths when types are unambiguous within a module, falling back to fully-qualified paths when collisions exist 102 + 94 103 #### 0.10 Release Highlights: 95 104 96 105 **URL type migration**
+6 -6
binaries/SHA256SUMS
··· 1 - 116bc235583edf4d2fc6b576df2a6188f1f6da947b951f0449884153e3ee87a4 jacquard-codegen_aarch64-unknown-linux-gnu.tar.xz 2 - 8a212ce575a449d6ac22e4f238ea6aea1afe105de77fd8daa8e24409d6e4eb3c jacquard-codegen_x86_64-unknown-linux-gnu.tar.xz 3 - 7d44fd207cf95ad5a9fb587068c19ed3e84540cea23f9d5d2d3519210f9d71b9 lex-fetch_aarch64-unknown-linux-gnu.tar.xz 4 - 196eedb3171380e3e00b583bf11eecc318f356fef28c63f13b81a33ee9e93ee8 lex-fetch_x86_64-unknown-linux-gnu.tar.xz 5 - c01ab49c6cf9b1649a65040058a2762fbcd0b8b82944b11250a8b5e3f00e6904 jacquard-codegen_x86_64-pc-windows-gnu.zip 6 - 9d5b0807ef6291321591be5a66401ded29d933d77bb2411f53b15440ba56ac34 lex-fetch_x86_64-pc-windows-gnu.zip 1 + 5c6fe5c309be8a79de13ac1f69072768d67b6d1b9695307fe994cbb6bf6b3187 jacquard-codegen_aarch64-unknown-linux-gnu.tar.xz 2 + 72b9219761eca2970c361d0271d1dd726ca5d2d47bfb7c1a73713331c2844639 jacquard-codegen_x86_64-unknown-linux-gnu.tar.xz 3 + a1117683e23e40486410bdf0f181db5513aac451b8100fa982b6888b99c3fcb3 lex-fetch_aarch64-unknown-linux-gnu.tar.xz 4 + c4470e85303822752744f27132537e4fe6f37cf9812df0d2f7972b5c5e744d17 lex-fetch_x86_64-unknown-linux-gnu.tar.xz 5 + 7ea42d805b5b4b9a9a7cdfdafdb7a72f994c5b1225a6db9c972c38cb23ff8eeb jacquard-codegen_x86_64-pc-windows-gnu.zip 6 + bb823e97cec224b934f20fe9c344e67db30a42048394ae27ceb751f447de7a56 lex-fetch_x86_64-pc-windows-gnu.zip
binaries/jacquard-codegen_aarch64-unknown-linux-gnu.tar.xz

This is a binary file and will not be displayed.

binaries/jacquard-codegen_x86_64-pc-windows-gnu.zip

This is a binary file and will not be displayed.

binaries/jacquard-codegen_x86_64-unknown-linux-gnu.tar.xz

This is a binary file and will not be displayed.

binaries/lex-fetch_aarch64-unknown-linux-gnu.tar.xz

This is a binary file and will not be displayed.

binaries/lex-fetch_x86_64-pc-windows-gnu.zip

This is a binary file and will not be displayed.

binaries/lex-fetch_x86_64-unknown-linux-gnu.tar.xz

This is a binary file and will not be displayed.

+4 -4
crates/jacquard-api/Cargo.toml
··· 2 2 name = "jacquard-api" 3 3 description = "Generated AT Protocol API bindings for Jacquard" 4 4 edition.workspace = true 5 - version = "0.10.2" 5 + version = "0.11.0" 6 6 authors.workspace = true 7 7 repository.workspace = true 8 8 keywords.workspace = true ··· 15 15 features = [ "bluesky", "other", "streaming" ] 16 16 17 17 [dependencies] 18 - jacquard-common = { version = "0.10", path = "../jacquard-common" } 19 - jacquard-derive = { version = "0.10", path = "../jacquard-derive" } 20 - jacquard-lexicon = { version = "0.10", path = "../jacquard-lexicon", default-features = false } 18 + jacquard-common = { version = "0.11", path = "../jacquard-common" } 19 + jacquard-derive = { version = "0.11", path = "../jacquard-derive" } 20 + jacquard-lexicon = { version = "0.11", path = "../jacquard-lexicon", default-features = false } 21 21 miette.workspace = true 22 22 serde.workspace = true 23 23 thiserror.workspace = true
+5 -5
crates/jacquard-axum/Cargo.toml
··· 1 1 [package] 2 2 name = "jacquard-axum" 3 3 edition.workspace = true 4 - version = "0.10.0" 4 + version = "0.11.0" 5 5 authors.workspace = true 6 6 repository.workspace = true 7 7 keywords.workspace = true ··· 22 22 [dependencies] 23 23 axum = "0.8.6" 24 24 bytes.workspace = true 25 - jacquard = { version = "0.10", path = "../jacquard", default-features = false, features = ["api"] } 26 - jacquard-common = { version = "0.10", path = "../jacquard-common", features = ["reqwest-client"] } 27 - jacquard-derive = { version = "0.10", path = "../jacquard-derive" } 28 - jacquard-identity = { version = "0.10", path = "../jacquard-identity", optional = true } 25 + jacquard = { version = "0.11", path = "../jacquard", default-features = false, features = ["api"] } 26 + jacquard-common = { version = "0.11", path = "../jacquard-common", features = ["reqwest-client"] } 27 + jacquard-derive = { version = "0.11", path = "../jacquard-derive" } 28 + jacquard-identity = { version = "0.11", path = "../jacquard-identity", optional = true } 29 29 miette.workspace = true 30 30 multibase = { version = "0.9.1", optional = true } 31 31 serde.workspace = true
+1 -1
crates/jacquard-common/Cargo.toml
··· 2 2 name = "jacquard-common" 3 3 description = "Core AT Protocol types and utilities for Jacquard" 4 4 edition.workspace = true 5 - version = "0.10.1" 5 + version = "0.11.0" 6 6 authors.workspace = true 7 7 repository.workspace = true 8 8 keywords.workspace = true
+3 -3
crates/jacquard-derive/Cargo.toml
··· 16 16 17 17 [dependencies] 18 18 heck.workspace = true 19 - jacquard-lexicon = { version = "0.10", path = "../jacquard-lexicon", features = ["codegen"] } 19 + jacquard-lexicon = { version = "0.11", path = "../jacquard-lexicon", features = ["codegen"] } 20 20 proc-macro2.workspace = true 21 21 quote.workspace = true 22 22 syn.workspace = true 23 23 24 24 [dev-dependencies] 25 25 inventory = "0.3" 26 - jacquard-common = { version = "0.10", path = "../jacquard-common" } 27 - jacquard-lexicon = { version = "0.10", path = "../jacquard-lexicon" } 26 + jacquard-common = { version = "0.11", path = "../jacquard-common" } 27 + jacquard-lexicon = { version = "0.11", path = "../jacquard-lexicon" } 28 28 serde.workspace = true 29 29 serde_json.workspace = true 30 30 unicode-segmentation = "1.12"
+3 -3
crates/jacquard-identity/Cargo.toml
··· 1 1 [package] 2 2 name = "jacquard-identity" 3 3 edition.workspace = true 4 - version = "0.10.0" 4 + version = "0.11.0" 5 5 authors.workspace = true 6 6 repository.workspace = true 7 7 keywords.workspace = true ··· 22 22 trait-variant.workspace = true 23 23 bon.workspace = true 24 24 bytes.workspace = true 25 - jacquard-common = { version = "0.10", path = "../jacquard-common", features = ["reqwest-client"] } 26 - jacquard-lexicon = { version = "0.10", path = "../jacquard-lexicon", default-features = false } 25 + jacquard-common = { version = "0.11", path = "../jacquard-common", features = ["reqwest-client"] } 26 + jacquard-lexicon = { version = "0.11", path = "../jacquard-lexicon", default-features = false } 27 27 reqwest.workspace = true 28 28 serde.workspace = true 29 29 serde_json.workspace = true
+4 -4
crates/jacquard-lexgen/Cargo.toml
··· 32 32 clap.workspace = true 33 33 glob = "0.3" 34 34 inventory = "0.3" 35 - jacquard-common = { version = "0.10", features = [ "reqwest-client" ], path = "../jacquard-common" } 36 - jacquard-derive = { version = "0.10", path = "../jacquard-derive" } 37 - jacquard-identity = { version = "0.10", path = "../jacquard-identity", features = ["dns"] } 38 - jacquard-lexicon = { version = "0.10", path = "../jacquard-lexicon" } 35 + jacquard-common = { version = "0.11", features = [ "reqwest-client" ], path = "../jacquard-common" } 36 + jacquard-derive = { version = "0.11", path = "../jacquard-derive" } 37 + jacquard-identity = { version = "0.11", path = "../jacquard-identity", features = ["dns"] } 38 + jacquard-lexicon = { version = "0.11", path = "../jacquard-lexicon" } 39 39 kdl = "6" 40 40 miette = { workspace = true, features = ["fancy"] } 41 41 reqwest = { workspace = true, features = ["json", "http2", "system-proxy", "rustls-tls"] }
+3 -3
crates/jacquard-lexicon/Cargo.toml
··· 2 2 name = "jacquard-lexicon" 3 3 description = "Lexicon schema parsing and code generation for Jacquard" 4 4 edition.workspace = true 5 - version = "0.10.1" 5 + version = "0.11.0" 6 6 authors.workspace = true 7 7 repository.workspace = true 8 8 keywords.workspace = true ··· 20 20 dashmap.workspace = true 21 21 heck = { workspace = true, optional = true } 22 22 inventory = "0.3" 23 - jacquard-common = { version = "0.10", path = "../jacquard-common" } 23 + jacquard-common = { version = "0.11", path = "../jacquard-common" } 24 24 miette = { workspace = true } 25 25 multihash.workspace = true 26 26 prettyplease = { workspace = true, optional = true } ··· 39 39 40 40 [dev-dependencies] 41 41 bytes = { workspace = true } 42 - jacquard-derive = { version = "0.10", path = "../jacquard-derive"} 42 + jacquard-derive = { version = "0.11", path = "../jacquard-derive"} 43 43 tempfile = { version = "3.23.0" }
+3 -3
crates/jacquard-oauth/Cargo.toml
··· 1 1 [package] 2 2 name = "jacquard-oauth" 3 - version = "0.10.0" 3 + version = "0.11.0" 4 4 edition.workspace = true 5 5 description = "AT Protocol OAuth 2.1 core types and helpers for Jacquard" 6 6 authors.workspace = true ··· 21 21 streaming = ["jacquard-common/streaming", "dep:n0-future"] 22 22 23 23 [dependencies] 24 - jacquard-common = { version = "0.10", path = "../jacquard-common", features = ["reqwest-client"] } 25 - jacquard-identity = { version = "0.10", path = "../jacquard-identity" } 24 + jacquard-common = { version = "0.11", path = "../jacquard-common", features = ["reqwest-client"] } 25 + jacquard-identity = { version = "0.11", path = "../jacquard-identity" } 26 26 serde = { workspace = true, features = ["derive"] } 27 27 serde_json = { workspace = true } 28 28 smol_str = { workspace = true }
+4 -4
crates/jacquard-repo/Cargo.toml
··· 2 2 name = "jacquard-repo" 3 3 description = "AT Protocol repository primitives: MST, commits, CAR I/O" 4 4 edition.workspace = true 5 - version = "0.10.0" 5 + version = "0.11.0" 6 6 authors.workspace = true 7 7 repository.workspace = true 8 8 keywords.workspace = true ··· 16 16 17 17 [dependencies] 18 18 # Internal 19 - jacquard-common = { path = "../jacquard-common", version = "0.10", features = ["crypto-ed25519", "crypto-k256", "crypto-p256"] } 20 - jacquard-derive = { path = "../jacquard-derive", version = "0.10" } 21 - jacquard-api = { path = "../jacquard-api", version = "0.10", features = ["streaming"] } 19 + jacquard-common = { path = "../jacquard-common", version = "0.11", features = ["crypto-ed25519", "crypto-k256", "crypto-p256"] } 20 + jacquard-derive = { path = "../jacquard-derive", version = "0.11" } 21 + jacquard-api = { path = "../jacquard-api", version = "0.11", features = ["streaming"] } 22 22 23 23 # Serialization 24 24 serde.workspace = true
+6 -6
crates/jacquard/Cargo.toml
··· 120 120 required-features = ["api_bluesky", "loopback"] 121 121 122 122 [dependencies] 123 - jacquard-api = { version = "0.10", path = "../jacquard-api" } 124 - jacquard-common = { version = "0.10", path = "../jacquard-common", features = [ 123 + jacquard-api = { version = "0.11", path = "../jacquard-api" } 124 + jacquard-common = { version = "0.11", path = "../jacquard-common", features = [ 125 125 "reqwest-client", 126 126 ] } 127 - jacquard-oauth = { version = "0.10", path = "../jacquard-oauth" } 128 - jacquard-derive = { version = "0.10", path = "../jacquard-derive", optional = true } 129 - jacquard-identity = { version = "0.10", path = "../jacquard-identity" } 127 + jacquard-oauth = { version = "0.11", path = "../jacquard-oauth" } 128 + jacquard-derive = { version = "0.11", path = "../jacquard-derive", optional = true } 129 + jacquard-identity = { version = "0.11", path = "../jacquard-identity" } 130 130 131 131 132 132 ··· 149 149 150 150 151 151 [target.'cfg(not(target_family = "wasm"))'.dependencies] 152 - jacquard-identity = { version = "0.10", path = "../jacquard-identity", features = ["cache"] } 152 + jacquard-identity = { version = "0.11", path = "../jacquard-identity", features = ["cache"] } 153 153 reqwest = { workspace = true, features = [ 154 154 "http2", 155 155 "gzip",