Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: `rad config schema` emits JSON Schema
n4ch7 committed 11 months ago
commit b608a7880695a2e21fe25240238f0d26e13a82c2
parent 5a2f26eaa7a18faf42ce6c0d2e0d0da3b9385491
14 files changed +1062 -59
modified Cargo.lock
@@ -3,6 +3,21 @@
version = 4

[[package]]
+
name = "addr2line"
+
version = "0.22.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
+
dependencies = [
+
 "gimli",
+
]
+

+
[[package]]
+
name = "adler"
+
version = "1.0.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+

+
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -44,6 +59,20 @@ dependencies = [
]

[[package]]
+
name = "ahash"
+
version = "0.8.11"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+
dependencies = [
+
 "cfg-if",
+
 "getrandom",
+
 "once_cell",
+
 "serde",
+
 "version_check",
+
 "zerocopy",
+
]
+

+
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -184,6 +213,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"

[[package]]
+
name = "backtrace"
+
version = "0.3.73"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
+
dependencies = [
+
 "addr2line",
+
 "cc",
+
 "cfg-if",
+
 "libc",
+
 "miniz_oxide 0.7.4",
+
 "object",
+
 "rustc-demangle",
+
]
+

+
[[package]]
name = "base-x"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -237,6 +281,21 @@ dependencies = [
]

[[package]]
+
name = "bit-set"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
+
dependencies = [
+
 "bit-vec",
+
]
+

+
[[package]]
+
name = "bit-vec"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
+

+
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -286,6 +345,12 @@ dependencies = [
]

[[package]]
+
name = "borrow-or-share"
+
version = "0.2.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3eeab4423108c5d7c744f4d234de88d18d636100093ae04caf4825134b9c3a32"
+

+
[[package]]
name = "bstr"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -303,12 +368,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"

[[package]]
+
name = "bytecount"
+
version = "0.6.8"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
+

+
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"

[[package]]
+
name = "bytes"
+
version = "1.10.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+

+
[[package]]
name = "bytesize"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -656,6 +733,15 @@ dependencies = [
]

[[package]]
+
name = "email_address"
+
version = "0.2.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449"
+
dependencies = [
+
 "serde",
+
]
+

+
[[package]]
name = "emojis"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -693,6 +779,17 @@ dependencies = [
]

[[package]]
+
name = "fancy-regex"
+
version = "0.14.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298"
+
dependencies = [
+
 "bit-set",
+
 "regex-automata",
+
 "regex-syntax",
+
]
+

+
[[package]]
name = "faster-hex"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -736,10 +833,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
dependencies = [
 "crc32fast",
-
 "miniz_oxide",
+
 "miniz_oxide 0.8.8",
]

[[package]]
+
name = "fluent-uri"
+
version = "0.3.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1918b65d96df47d3591bed19c5cca17e3fa5d0707318e4b5ef2eae01764df7e5"
+
dependencies = [
+
 "borrow-or-share",
+
 "ref-cast",
+
 "serde",
+
]
+

+
[[package]]
+
name = "fnv"
+
version = "1.0.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+

+
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -749,6 +863,66 @@ dependencies = [
]

[[package]]
+
name = "fraction"
+
version = "0.15.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7"
+
dependencies = [
+
 "lazy_static",
+
 "num",
+
]
+

+
[[package]]
+
name = "futures-channel"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+
dependencies = [
+
 "futures-core",
+
 "futures-sink",
+
]
+

+
[[package]]
+
name = "futures-core"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+

+
[[package]]
+
name = "futures-io"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+

+
[[package]]
+
name = "futures-sink"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+

+
[[package]]
+
name = "futures-task"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+

+
[[package]]
+
name = "futures-util"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+
dependencies = [
+
 "futures-core",
+
 "futures-io",
+
 "futures-sink",
+
 "futures-task",
+
 "memchr",
+
 "pin-project-lite",
+
 "pin-utils",
+
 "slab",
+
]
+

+
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -790,6 +964,12 @@ dependencies = [
]

[[package]]
+
name = "gimli"
+
version = "0.29.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+

+
[[package]]
name = "git-ref-format"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1346,6 +1526,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"

[[package]]
+
name = "hermit-abi"
+
version = "0.3.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+

+
[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1364,6 +1550,84 @@ dependencies = [
]

[[package]]
+
name = "http"
+
version = "1.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+
dependencies = [
+
 "bytes",
+
 "fnv",
+
 "itoa",
+
]
+

+
[[package]]
+
name = "http-body"
+
version = "1.0.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+
dependencies = [
+
 "bytes",
+
 "http",
+
]
+

+
[[package]]
+
name = "http-body-util"
+
version = "0.1.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+
dependencies = [
+
 "bytes",
+
 "futures-core",
+
 "http",
+
 "http-body",
+
 "pin-project-lite",
+
]
+

+
[[package]]
+
name = "httparse"
+
version = "1.10.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+

+
[[package]]
+
name = "hyper"
+
version = "1.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
+
dependencies = [
+
 "bytes",
+
 "futures-channel",
+
 "futures-util",
+
 "http",
+
 "http-body",
+
 "httparse",
+
 "itoa",
+
 "pin-project-lite",
+
 "smallvec",
+
 "tokio",
+
 "want",
+
]
+

+
[[package]]
+
name = "hyper-util"
+
version = "0.1.10"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
+
dependencies = [
+
 "bytes",
+
 "futures-channel",
+
 "futures-util",
+
 "http",
+
 "http-body",
+
 "hyper",
+
 "pin-project-lite",
+
 "socket2",
+
 "tokio",
+
 "tower-service",
+
 "tracing",
+
]
+

+
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1575,6 +1839,12 @@ dependencies = [
]

[[package]]
+
name = "ipnet"
+
version = "2.11.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+

+
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1620,14 +1890,42 @@ dependencies = [

[[package]]
name = "js-sys"
-
version = "0.3.69"
+
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
+
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
+
 "once_cell",
 "wasm-bindgen",
]

[[package]]
+
name = "jsonschema"
+
version = "0.30.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f1b46a0365a611fbf1d2143104dcf910aada96fafd295bab16c60b802bf6fa1d"
+
dependencies = [
+
 "ahash",
+
 "base64 0.22.1",
+
 "bytecount",
+
 "email_address",
+
 "fancy-regex",
+
 "fraction",
+
 "idna",
+
 "itoa",
+
 "num-cmp",
+
 "num-traits",
+
 "once_cell",
+
 "percent-encoding",
+
 "referencing",
+
 "regex",
+
 "regex-syntax",
+
 "reqwest",
+
 "serde",
+
 "serde_json",
+
 "uuid-simd",
+
]
+

+
[[package]]
name = "keccak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1762,6 +2060,21 @@ dependencies = [
]

[[package]]
+
name = "mime"
+
version = "0.3.17"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+

+
[[package]]
+
name = "miniz_oxide"
+
version = "0.7.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
+
dependencies = [
+
 "adler",
+
]
+

+
[[package]]
name = "miniz_oxide"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1771,6 +2084,18 @@ dependencies = [
]

[[package]]
+
name = "mio"
+
version = "1.0.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
+
dependencies = [
+
 "hermit-abi",
+
 "libc",
+
 "wasi",
+
 "windows-sys 0.52.0",
+
]
+

+
[[package]]
name = "multibase"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1837,6 +2162,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"

[[package]]
+
name = "num"
+
version = "0.4.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
+
dependencies = [
+
 "num-bigint",
+
 "num-complex",
+
 "num-integer",
+
 "num-iter",
+
 "num-rational",
+
 "num-traits",
+
]
+

+
[[package]]
+
name = "num-bigint"
+
version = "0.4.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+
dependencies = [
+
 "num-integer",
+
 "num-traits",
+
]
+

+
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1854,6 +2203,21 @@ dependencies = [
]

[[package]]
+
name = "num-cmp"
+
version = "0.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa"
+

+
[[package]]
+
name = "num-complex"
+
version = "0.4.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+
dependencies = [
+
 "num-traits",
+
]
+

+
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1864,9 +2228,9 @@ dependencies = [

[[package]]
name = "num-iter"
-
version = "0.1.44"
+
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
+
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
 "autocfg",
 "num-integer",
@@ -1874,10 +2238,21 @@ dependencies = [
]

[[package]]
+
name = "num-rational"
+
version = "0.4.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
+
dependencies = [
+
 "num-bigint",
+
 "num-integer",
+
 "num-traits",
+
]
+

+
[[package]]
name = "num-traits"
-
version = "0.2.18"
+
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
 "autocfg",
 "libm",
@@ -1890,10 +2265,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"

[[package]]
+
name = "object"
+
version = "0.36.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+
dependencies = [
+
 "memchr",
+
]
+

+
[[package]]
name = "once_cell"
-
version = "1.19.0"
+
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"

[[package]]
name = "opaque-debug"
@@ -1902,6 +2286,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"

[[package]]
+
name = "outref"
+
version = "0.5.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
+

+
[[package]]
name = "p256"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1941,9 +2331,9 @@ dependencies = [

[[package]]
name = "parking_lot"
-
version = "0.12.1"
+
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
 "lock_api",
 "parking_lot_core",
@@ -2006,6 +2396,18 @@ dependencies = [
]

[[package]]
+
name = "pin-project-lite"
+
version = "0.2.16"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+

+
[[package]]
+
name = "pin-utils"
+
version = "0.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+

+
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2190,6 +2592,7 @@ dependencies = [
 "emojis",
 "fastrand",
 "git2",
+
 "jsonschema",
 "libc",
 "localtime",
 "log",
@@ -2203,6 +2606,7 @@ dependencies = [
 "radicle-crypto",
 "radicle-git-ext",
 "radicle-ssh",
+
 "schemars",
 "serde",
 "serde_json",
 "siphasher 1.0.1",
@@ -2232,6 +2636,7 @@ dependencies = [
 "radicle-node",
 "radicle-surf",
 "radicle-term",
+
 "schemars",
 "serde",
 "serde_json",
 "shlex",
@@ -2543,6 +2948,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"

[[package]]
+
name = "ref-cast"
+
version = "1.0.24"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
+
dependencies = [
+
 "ref-cast-impl",
+
]
+

+
[[package]]
+
name = "ref-cast-impl"
+
version = "1.0.24"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.89",
+
]
+

+
[[package]]
+
name = "referencing"
+
version = "0.30.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c8eff4fa778b5c2a57e85c5f2fe3a709c52f0e60d23146e2151cbef5893f420e"
+
dependencies = [
+
 "ahash",
+
 "fluent-uri",
+
 "once_cell",
+
 "parking_lot",
+
 "percent-encoding",
+
 "serde_json",
+
]
+

+
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2572,6 +3011,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"

[[package]]
+
name = "reqwest"
+
version = "0.12.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
+
dependencies = [
+
 "base64 0.22.1",
+
 "bytes",
+
 "futures-channel",
+
 "futures-core",
+
 "futures-util",
+
 "http",
+
 "http-body",
+
 "http-body-util",
+
 "hyper",
+
 "hyper-util",
+
 "ipnet",
+
 "js-sys",
+
 "log",
+
 "mime",
+
 "once_cell",
+
 "percent-encoding",
+
 "pin-project-lite",
+
 "serde",
+
 "serde_json",
+
 "serde_urlencoded",
+
 "sync_wrapper",
+
 "tokio",
+
 "tower",
+
 "tower-service",
+
 "url",
+
 "wasm-bindgen",
+
 "wasm-bindgen-futures",
+
 "web-sys",
+
 "windows-registry",
+
]
+

+
[[package]]
name = "rfc6979"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2603,6 +3079,12 @@ dependencies = [
]

[[package]]
+
name = "rustc-demangle"
+
version = "0.1.24"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+

+
[[package]]
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2616,6 +3098,12 @@ dependencies = [
]

[[package]]
+
name = "rustversion"
+
version = "1.0.20"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
+

+
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2640,6 +3128,31 @@ dependencies = [
]

[[package]]
+
name = "schemars"
+
version = "1.0.0-alpha.17"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "88ef2a6523400a2228db974a8ddc9e1d3deaa04f51bddd7832ef8d7e531bafcc"
+
dependencies = [
+
 "dyn-clone",
+
 "ref-cast",
+
 "schemars_derive",
+
 "serde",
+
 "serde_json",
+
]
+

+
[[package]]
+
name = "schemars_derive"
+
version = "1.0.0-alpha.17"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c6d4e1945a3c9e58edaa708449b026519f7f4197185e1b5dbc689615c1ad724d"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "serde_derive_internals",
+
 "syn 2.0.89",
+
]
+

+
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2703,13 +3216,37 @@ dependencies = [
]

[[package]]
+
name = "serde_derive_internals"
+
version = "0.29.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.89",
+
]
+

+
[[package]]
name = "serde_json"
-
version = "1.0.116"
+
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
+
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
 "indexmap",
 "itoa",
+
 "memchr",
+
 "ryu",
+
 "serde",
+
]
+

+
[[package]]
+
name = "serde_urlencoded"
+
version = "0.7.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+
dependencies = [
+
 "form_urlencoded",
+
 "itoa",
 "ryu",
 "serde",
]
@@ -2800,6 +3337,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"

[[package]]
+
name = "slab"
+
version = "0.4.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+
dependencies = [
+
 "autocfg",
+
]
+

+
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2983,6 +3529,15 @@ dependencies = [
]

[[package]]
+
name = "sync_wrapper"
+
version = "1.0.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+
dependencies = [
+
 "futures-core",
+
]
+

+
[[package]]
name = "synstructure"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3112,6 +3667,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"

[[package]]
+
name = "tokio"
+
version = "1.42.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2209a14885b74764cce87ffa777ffa1b8ce81a3f3166c6f886b83337fe7e077f"
+
dependencies = [
+
 "backtrace",
+
 "libc",
+
 "mio",
+
 "pin-project-lite",
+
 "socket2",
+
 "windows-sys 0.52.0",
+
]
+

+
[[package]]
+
name = "tower"
+
version = "0.5.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+
dependencies = [
+
 "futures-core",
+
 "futures-util",
+
 "pin-project-lite",
+
 "sync_wrapper",
+
 "tokio",
+
 "tower-layer",
+
 "tower-service",
+
]
+

+
[[package]]
+
name = "tower-layer"
+
version = "0.3.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+

+
[[package]]
+
name = "tower-service"
+
version = "0.3.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+

+
[[package]]
+
name = "tracing"
+
version = "0.1.41"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+
dependencies = [
+
 "pin-project-lite",
+
 "tracing-core",
+
]
+

+
[[package]]
+
name = "tracing-core"
+
version = "0.1.33"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+
dependencies = [
+
 "once_cell",
+
]
+

+
[[package]]
name = "tree-sitter"
version = "0.24.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3264,6 +3879,12 @@ dependencies = [
]

[[package]]
+
name = "try-lock"
+
version = "0.2.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+

+
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3345,6 +3966,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"

[[package]]
+
name = "uuid"
+
version = "1.16.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
+

+
[[package]]
+
name = "uuid-simd"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "23b082222b4f6619906941c17eb2297fff4c2fb96cb60164170522942a200bd8"
+
dependencies = [
+
 "outref",
+
 "uuid",
+
 "vsimd",
+
]
+

+
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3357,6 +3995,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"

[[package]]
+
name = "vsimd"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
+

+
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3367,6 +4011,15 @@ dependencies = [
]

[[package]]
+
name = "want"
+
version = "0.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+
dependencies = [
+
 "try-lock",
+
]
+

+
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3374,23 +4027,24 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

[[package]]
name = "wasm-bindgen"
-
version = "0.2.92"
+
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
+
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
 "cfg-if",
+
 "once_cell",
+
 "rustversion",
 "wasm-bindgen-macro",
]

[[package]]
name = "wasm-bindgen-backend"
-
version = "0.2.92"
+
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
+
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
 "bumpalo",
 "log",
-
 "once_cell",
 "proc-macro2",
 "quote",
 "syn 2.0.89",
@@ -3398,10 +4052,23 @@ dependencies = [
]

[[package]]
+
name = "wasm-bindgen-futures"
+
version = "0.4.50"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
+
dependencies = [
+
 "cfg-if",
+
 "js-sys",
+
 "once_cell",
+
 "wasm-bindgen",
+
 "web-sys",
+
]
+

+
[[package]]
name = "wasm-bindgen-macro"
-
version = "0.2.92"
+
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
+
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
@@ -3409,9 +4076,9 @@ dependencies = [

[[package]]
name = "wasm-bindgen-macro-support"
-
version = "0.2.92"
+
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
+
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
 "proc-macro2",
 "quote",
@@ -3422,9 +4089,22 @@ dependencies = [

[[package]]
name = "wasm-bindgen-shared"
-
version = "0.2.92"
+
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
+
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+
dependencies = [
+
 "unicode-ident",
+
]
+

+
[[package]]
+
name = "web-sys"
+
version = "0.3.77"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
+
dependencies = [
+
 "js-sys",
+
 "wasm-bindgen",
+
]

[[package]]
name = "winapi-util"
@@ -3445,6 +4125,41 @@ dependencies = [
]

[[package]]
+
name = "windows-link"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+

+
[[package]]
+
name = "windows-registry"
+
version = "0.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
+
dependencies = [
+
 "windows-result",
+
 "windows-strings",
+
 "windows-targets 0.53.0",
+
]
+

+
[[package]]
+
name = "windows-result"
+
version = "0.3.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
+
dependencies = [
+
 "windows-link",
+
]
+

+
[[package]]
+
name = "windows-strings"
+
version = "0.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
+
dependencies = [
+
 "windows-link",
+
]
+

+
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3486,7 +4201,7 @@ dependencies = [
 "windows_aarch64_gnullvm 0.52.5",
 "windows_aarch64_msvc 0.52.5",
 "windows_i686_gnu 0.52.5",
-
 "windows_i686_gnullvm",
+
 "windows_i686_gnullvm 0.52.5",
 "windows_i686_msvc 0.52.5",
 "windows_x86_64_gnu 0.52.5",
 "windows_x86_64_gnullvm 0.52.5",
@@ -3494,6 +4209,22 @@ dependencies = [
]

[[package]]
+
name = "windows-targets"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
+
dependencies = [
+
 "windows_aarch64_gnullvm 0.53.0",
+
 "windows_aarch64_msvc 0.53.0",
+
 "windows_i686_gnu 0.53.0",
+
 "windows_i686_gnullvm 0.53.0",
+
 "windows_i686_msvc 0.53.0",
+
 "windows_x86_64_gnu 0.53.0",
+
 "windows_x86_64_gnullvm 0.53.0",
+
 "windows_x86_64_msvc 0.53.0",
+
]
+

+
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3506,6 +4237,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"

[[package]]
+
name = "windows_aarch64_gnullvm"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+

+
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3518,6 +4255,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"

[[package]]
+
name = "windows_aarch64_msvc"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+

+
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3530,12 +4273,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"

[[package]]
+
name = "windows_i686_gnu"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+

+
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"

[[package]]
+
name = "windows_i686_gnullvm"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+

+
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3548,6 +4303,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"

[[package]]
+
name = "windows_i686_msvc"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+

+
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3560,6 +4321,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"

[[package]]
+
name = "windows_x86_64_gnu"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+

+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3572,6 +4339,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"

[[package]]
+
name = "windows_x86_64_gnullvm"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+

+
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3584,6 +4357,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"

[[package]]
+
name = "windows_x86_64_msvc"
+
version = "0.53.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+

+
[[package]]
name = "winnow"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3646,6 +4425,26 @@ dependencies = [
]

[[package]]
+
name = "zerocopy"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+
dependencies = [
+
 "zerocopy-derive",
+
]
+

+
[[package]]
+
name = "zerocopy-derive"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.89",
+
]
+

+
[[package]]
name = "zerofrom"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
modified radicle-cli/Cargo.toml
@@ -46,11 +46,12 @@ tree-sitter-bash = { version = "0.23.3" }
tree-sitter-go = { version = "0.23.4" }
tree-sitter-md = { version = "0.3.2" }
zeroize = { version = "1.1" }
+
schemars = { version = "1.0.0-alpha.17" }

[dependencies.radicle]
version = "0"
path = "../radicle"
-
features = ["logger"]
+
features = ["logger", "schemars"]

[dependencies.radicle-cli-test]
version = "0"
modified radicle-cli/src/commands/config.rs
@@ -23,6 +23,7 @@ Usage
    rad config init --alias <alias> [<option>...]
    rad config edit [<option>...]
    rad config get <key> [<option>...]
+
    rad config schema [<option>...]
    rad config set <key> <value> [<option>...]
    rad config unset <key> [<option>...]
    rad config push <key> <value> [<option>...]
@@ -43,6 +44,7 @@ enum Operation {
    #[default]
    Show,
    Get(String),
+
    Schema,
    Set(String, String),
    Push(String, String),
    Remove(String, String),
@@ -79,6 +81,7 @@ impl Args for Options {
                }
                Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
                    "show" => op = Some(Operation::Show),
+
                    "schema" => op = Some(Operation::Schema),
                    "edit" => op = Some(Operation::Edit),
                    "init" => op = Some(Operation::Init),
                    "get" => {
@@ -140,6 +143,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
            let profile = ctx.profile()?;
            term::json::to_pretty(&profile.config, path.as_path())?.print();
        }
+
        Operation::Schema => {
+
            term::json::to_pretty(&schemars::schema_for!(Config), path.as_path())?.print();
+
        }
        Operation::Get(key) => {
            let mut temp_config = RawConfig::from_file(&path)?;
            let key: ConfigPath = key.into();
modified radicle/Cargo.toml
@@ -35,6 +35,7 @@ sqlite = { version = "0.32.0", features = ["bundled"] }
tempfile = { version = "3.3.0" }
thiserror = { version = "1" }
unicode-normalization = { version = "0.1" }
+
schemars = { version = "1.0.0-alpha.17", optional = true }

[dependencies.chrono]
version = "0.4.0"
@@ -75,6 +76,7 @@ emojis = { version = "0.6" }
pretty_assertions = { version = "1.3.0" }
qcheck-macros = { version = "1", default-features = false }
qcheck = { version = "1", default-features = false }
+
jsonschema = { version = "0.30" }

[dev-dependencies.radicle-crypto]
path = "../radicle-crypto"
modified radicle/src/cli.rs
@@ -1,6 +1,11 @@
/// CLI configuration.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(rename = "CliConfig")
+
)]
pub struct Config {
    /// Whether to show hints or not in the CLI.
    #[serde(default)]
modified radicle/src/explorer.rs
@@ -81,8 +81,9 @@ impl std::fmt::Display for ExplorerUrl {
}

/// A public explorer, eg. `https://app.radicle.xyz`.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
+
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(transparent)]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Explorer(String);

impl Default for Explorer {
modified radicle/src/identity/doc/id.rs
@@ -20,7 +20,17 @@ pub enum IdError {

/// A repository identifier.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-
pub struct RepoId(git::Oid);
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
+
pub struct RepoId(
+
    #[cfg_attr(feature = "schemars", schemars(
+
        with = "String",
+
        description = "A repository identifier. Starts with \"rad:\", followed by a multibase Base58 encoded Git object identifier.",
+
        regex(pattern = r"rad:z[1-9a-km-zA-HJ-NP-Z]+"),
+
        length(min = 5),
+
        example = &"rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
+
    ))]
+
    git::Oid,
+
);

impl fmt::Display for RepoId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
modified radicle/src/lib.rs
@@ -23,6 +23,8 @@ pub mod logger;
pub mod node;
pub mod profile;
pub mod rad;
+
#[cfg(feature = "schemars")]
+
pub(crate) mod schemars_ext;
pub mod serde_ext;
pub mod sql;
pub mod storage;
modified radicle/src/node.rs
@@ -181,7 +181,7 @@ impl Penalty {
}

/// Repository sync status for our own refs.
-
#[derive(Debug, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(tag = "status")]
#[serde(rename_all = "camelCase")]
pub enum SyncStatus {
@@ -221,7 +221,7 @@ impl PartialOrd for SyncStatus {
}

/// Node user agent.
-
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
pub struct UserAgent(String);

impl UserAgent {
@@ -291,10 +291,25 @@ impl AsRef<str> for UserAgent {
    }
}

-
/// Node alias.
-
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, serde::Serialize, serde::Deserialize)]
+
/// Node alias, i.e. a short and memorable name for it.
+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
#[serde(try_from = "String", into = "String")]
-
pub struct Alias(String);
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
+
pub struct Alias(
+
    // To exclude control characters, one might be inclined to use the character
+
    // class `[[:cntrl:]]` which is understood by the `regex` crate.
+
    // However, the patterns in JSON schema must conform to ECMA-262, which does
+
    // not specify the character class.
+
    // Thus, we unfold its definition from <https://www.unicode.org/reports/tr18/#cntrl>,
+
    // which refers to the "general category" named "Cc",
+
    // see <https://unicode.org/reports/tr44/#General_Category_Values>.
+
    // We obtain the two ranges below from <https://www.unicode.org/notes/tn36/Categories.txt>.
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(regex(pattern = r"^[^\x00-\x1F\x7F-\x9F\s]{0,32}$"), length(max = 32))
+
    )]
+
    String,
+
);

impl Alias {
    /// Create a new alias from a string. Panics if the string is not a valid alias.
@@ -411,7 +426,7 @@ impl TryFrom<&sqlite::Value> for Alias {
}

/// Options passed to the "connect" node command.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectOptions {
    /// Establish a persistent connection.
    pub persistent: bool,
@@ -500,10 +515,30 @@ impl<T: Serialize> CommandResult<T> {
}

/// Peer public protocol address.
-
#[derive(Wrapper, WrapperMut, Clone, Eq, PartialEq, Debug, Hash, From, Serialize, Deserialize)]
+
#[derive(Clone, Eq, PartialEq, Debug, Hash, From, Wrapper, WrapperMut, Serialize, Deserialize)]
#[wrapper(Deref, Display, FromStr)]
#[wrapper_mut(DerefMut)]
-
pub struct Address(#[serde(with = "crate::serde_ext::string")] NetAddr<HostName>);
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(description = "\
+
    An IP address, or a DNS name, or a Tor onion name, followed by the symbol ':', \
+
    followed by a TCP port number.\
+
")
+
)]
+
pub struct Address(
+
    #[serde(with = "crate::serde_ext::string")]
+
    #[cfg_attr(feature = "schemars", schemars(
+
        with = "String",
+
        regex(pattern = r"^.+:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$"),
+
        extend("examples" = [
+
            "xmrhfasfg5suueegrnc4gsgyi2tyclcy5oz7f5drnrodmdtob6t2ioyd.onion:8776",
+
            "seed.example.com:8776",
+
            "192.0.2.0:31337",
+
        ]),
+
    ))]
+
    NetAddr<HostName>,
+
);

impl Address {
    /// Check whether this address is from the local network.
@@ -667,7 +702,7 @@ impl Session {
}

/// A seed for some repository, with metadata about its status.
-
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Seed {
    /// The Node ID.
@@ -708,7 +743,7 @@ impl Seed {
    }
}

-
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
+
#[derive(Clone, Debug, Serialize, Deserialize)]
/// Represents a set of seeds with associated metadata. Uses an RNG
/// underneath, so every iteration returns a different ordering.
#[serde(into = "Vec<Seed>", from = "Vec<Seed>")]
modified radicle/src/node/config.rs
@@ -5,6 +5,7 @@ use std::{fmt, net};

use cyphernet::addr::PeerAddr;
use localtime::LocalDuration;
+
use serde::{Deserialize, Serialize};
use serde_json as json;

use crate::node;
@@ -57,8 +58,9 @@ pub mod seeds {
}

/// Peer-to-peer network.
-
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Network {
    #[default]
    Main,
@@ -94,16 +96,25 @@ impl Network {
}

/// Configuration parameters defining attributes of minima and maxima.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Limits {
    /// Number of routing table entries before we start pruning.
    pub routing_max_size: usize,
    /// How long to keep a routing table entry before being pruned.
    #[serde(with = "crate::serde_ext::localtime::duration")]
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(with = "crate::schemars_ext::localtime::LocalDuration")
+
    )]
    pub routing_max_age: LocalDuration,
    /// How long to keep a gossip message entry before pruning it.
    #[serde(with = "crate::serde_ext::localtime::duration")]
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(with = "crate::schemars_ext::localtime::LocalDuration")
+
    )]
    pub gossip_max_age: LocalDuration,
    /// Maximum number of concurrent fetches per peer connection.
    pub fetch_concurrency: usize,
@@ -138,10 +149,19 @@ impl Default for Limits {
/// Limiter for byte streams.
///
/// Default: 500MiB
-
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(into = "String", try_from = "String")]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(transparent)
+
)]
pub struct FetchPackSizeLimit {
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(with = "crate::schemars_ext::bytesize::ByteSize")
+
    )]
    limit: bytesize::ByteSize,
}

@@ -213,8 +233,9 @@ impl Default for FetchPackSizeLimit {
}

/// Connection limits.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ConnectionLimits {
    /// Max inbound connections.
    pub inbound: usize,
@@ -232,16 +253,18 @@ impl Default for ConnectionLimits {
}

/// Rate limts for a single connection.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct RateLimit {
    pub fill_rate: f64,
    pub capacity: usize,
}

/// Rate limits for inbound and outbound connections.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct RateLimits {
    pub inbound: RateLimit,
    pub outbound: RateLimit,
@@ -263,9 +286,30 @@ impl Default for RateLimits {
}

/// Full address used to connect to a remote node.
-
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Hash)]
-
#[serde(transparent)]
-
pub struct ConnectAddress(#[serde(with = "crate::serde_ext::string")] PeerAddr<NodeId, Address>);
+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(description = "\
+
    A node address to connect to. Format: An Ed25519 public key in multibase encoding, \
+
    followed by the symbol '@', followed by an IP address, or a DNS name, or a Tor onion \
+
    name, followed by the symbol ':', followed by a TCP port number.\
+
")
+
)]
+
pub struct ConnectAddress(
+
    #[serde(with = "crate::serde_ext::string")]
+
    #[schemars(
+
        with = "String",
+
        regex(pattern = r"^.+@.+:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{0,5})|([0-9]{1,4}))$"),
+
        extend("examples" = [
+
            "z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776",
+
            "z6MkvUJtYD9dHDJfpevWRT98mzDDpdAtmUjwyDSkyqksUr7C@xmrhfasfg5suueegrnc4gsgyi2tyclcy5oz7f5drnrodmdtob6t2ioyd.onion:8776",
+
            "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi@seed.example.com:8776",
+
            "z6MkkfM3tPXNPrPevKr3uSiQtHPuwnNhu2yUVjgd2jXVsVz5@192.0.2.0:31337",
+
        ]),
+
    )]
+
    PeerAddr<NodeId, Address>,
+
);

impl From<PeerAddr<NodeId, Address>> for ConnectAddress {
    fn from(value: PeerAddr<NodeId, Address>) -> Self {
@@ -300,8 +344,9 @@ impl Deref for ConnectAddress {
}

/// Peer configuration.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum PeerConfig {
    /// Static peer set. Connect to the configured peers and maintain the connections.
    Static,
@@ -316,8 +361,9 @@ impl Default for PeerConfig {
}

/// Relay configuration.
-
#[derive(Debug, Copy, Clone, Default, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Relay {
    /// Always relay messages.
    Always,
@@ -329,8 +375,9 @@ pub enum Relay {
}

/// Proxy configuration.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "mode")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum AddressConfig {
    /// Proxy connections to this address type.
    Proxy {
@@ -343,8 +390,9 @@ pub enum AddressConfig {
}

/// Default seeding policy. Applies when no repository policies for the given repo are found.
-
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "default")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum DefaultSeedingPolicy {
    /// Allow seeding.
    Allow {
@@ -379,13 +427,19 @@ impl From<DefaultSeedingPolicy> for SeedingPolicy {
}

/// Service configuration.
-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(rename = "NodeConfig")
+
)]
pub struct Config {
    /// Node alias.
    pub alias: Alias,
-
    /// Address to listen on.
+
    /// Socket address (a combination of IPv4 or IPv6 address and TCP port) to listen on.
    #[serde(default)]
+
    #[cfg_attr(feature = "schemars", schemars(example = &"127.0.0.1:8776"))]
    pub listen: Vec<net::SocketAddr>,
    /// Peer configuration.
    #[serde(default)]
@@ -409,6 +463,10 @@ pub struct Config {
    /// Log level.
    #[serde(default = "defaults::log")]
    #[serde(with = "crate::serde_ext::string")]
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(with = "crate::schemars_ext::log::Level")
+
    )]
    pub log: log::Level,
    /// Whether or not our node should relay messages.
    #[serde(default, deserialize_with = "crate::serde_ext::ok_or_default")]
modified radicle/src/node/policy.rs
@@ -35,7 +35,7 @@ pub struct FollowPolicy {
}

/// Seeding policy of a node or repo.
-
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "policy")]
pub enum SeedingPolicy {
    /// Allow seeding.
@@ -159,6 +159,7 @@ impl TryFrom<&sqlite::Value> for Policy {
/// Follow scope of a seeded repository.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Scope {
    /// Seed remotes that are explicitly followed.
    Followed,
modified radicle/src/profile/config.rs
@@ -25,6 +25,7 @@ pub enum ConfigError {
/// Local radicle configuration.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Config {
    /// Public explorer. This is used for generating links.
    #[serde(default)]
@@ -360,3 +361,19 @@ impl From<String> for ConfigPath {
        ConfigPath(parts)
    }
}
+

+
#[cfg(test)]
+
#[allow(clippy::unwrap_used)]
+
mod test {
+
    #[test]
+
    fn schema() {
+
        use super::Config;
+
        use crate::prelude::Alias;
+
        use serde_json::to_value;
+

+
        let schema = to_value(schemars::schema_for!(Config)).unwrap();
+
        let config = to_value(Config::new(Alias::new("schema"))).unwrap();
+
        jsonschema::validate(&schema, &config)
+
            .expect("generated configuration should validate under generated JSON Schema");
+
    }
+
}
added radicle/src/schemars_ext.rs
@@ -0,0 +1,59 @@
+
//! This module contains auxiliary definitions for generating JSONSchemas.
+
//! See <https://graham.cool/schemars/examples/5-remote_derive/>.
+
#![allow(dead_code)]
+

+
use schemars::JsonSchema;
+

+
pub(crate) mod log {
+
    use super::*;
+

+
    /// See [`::log::Level`]
+
    #[derive(JsonSchema)]
+
    #[schemars(
+
        remote = "log::Level",
+
        description = "A log level.",
+
        rename_all = "UPPERCASE"
+
    )]
+
    pub(crate) enum Level {
+
        /// Designates very serious errors.
+
        Error,
+
        /// Designates hazardous situations.
+
        Warn,
+
        /// Designates useful information.
+
        Info,
+
        /// Designates lower priority information.
+
        Debug,
+
        /// Designates very low priority, often extremely verbose, information.
+
        Trace,
+
    }
+
}
+

+
pub(crate) mod bytesize {
+
    use super::*;
+

+
    /// See [`::bytesize::ByteSize`] as well as [`::bytesize::parse`].
+
    /// Note that the pattern here is a little more restrictive than
+
    /// the actual parsing logic, as it enforces particular casing and whitespace.
+
    /// However, the regular expression is easier to read.
+
    #[derive(JsonSchema)]
+
    #[schemars(
+
        remote = "bytesize::ByteSize",
+
        description = "Byte quantities using unit prefixes according to SI or ISO/IEC 80000-13.",
+
        extend("examples" = ["7 G", "50.3 TiB", "200 B", "4 Ki", "10 MB"]),
+
    )]
+
    pub(crate) struct ByteSize(
+
        #[schemars(regex(pattern = r"^\d+(\.\d+)? ((K|M|G|T|P)i?B?|B)$"))] String,
+
    );
+
}
+

+
pub(crate) mod localtime {
+
    use super::*;
+

+
    /// See [`::localtime::LocalDuration`]
+
    #[derive(JsonSchema)]
+
    #[schemars(
+
        remote = "localtime::LocalDuration",
+
        description = "A time duration measured locally in milliseconds."
+
    )]
+
    pub(crate) struct LocalDuration(u64);
+
}
modified radicle/src/web.rs
@@ -1,29 +1,36 @@
-
use std::collections::HashSet;
-

-
use serde::{Deserialize, Serialize};
-

use crate::prelude::RepoId;
+
use schemars::JsonSchema;
+
use serde::{Deserialize, Serialize};
+
use std::collections::HashSet;

/// Web configuration.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(rename = "WebConfig")
+
)]
pub struct Config {
    /// Pinned content.
    pub pinned: Pinned,
    /// URL pointing to an image used in the header of a node page.
    #[serde(default, skip_serializing_if = "Option::is_none")]
+
    #[cfg_attr(feature = "schemars", schemars(url))]
    pub banner_url: Option<String>,
    /// URL pointing to an image used as the node avatar.
    #[serde(default, skip_serializing_if = "Option::is_none")]
+
    #[cfg_attr(feature = "schemars", schemars(url))]
    pub avatar_url: Option<String>,
    /// Node description.
    #[serde(default, skip_serializing_if = "Option::is_none")]
+
    #[cfg_attr(feature = "schemars", schemars(url))]
    pub description: Option<String>,
}

/// Pinned content. This can be used to pin certain content when
/// listing, e.g. pin repositories on a web client.
-
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
+
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct Pinned {
    /// Pinned repositories.