Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Add `list_commits` tauri command
Open did:key:z6MkkfM3...sVz5 opened 1 year ago

Returns all commits for a specific repo.

Takes a parent argument as starting point for the git history. Uses the head field of the project payload if not provided.

Instead of since and until timestamps uses cursor and take params to paginate the commit history.

PS: Remove migrate argument since not used anymore

checkcheck-e2e

👉 Workflow runs 👉 Branch on GitHub

31 files changed +961 -188 52c25a90 5c8844db
modified Cargo.lock
@@ -3,6 +3,16 @@
version = 3

[[package]]
+
name = "Inflector"
+
version = "0.11.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+
dependencies = [
+
 "lazy_static",
+
 "regex",
+
]
+

+
[[package]]
name = "addr2line"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -70,6 +80,18 @@ dependencies = [
]

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

+
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -100,6 +122,12 @@ dependencies = [
]

[[package]]
+
name = "allocator-api2"
+
version = "0.2.20"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
+

+
[[package]]
name = "amplify"
version = "4.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -229,6 +257,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"

[[package]]
+
name = "ast_node"
+
version = "0.9.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f9184f2b369b3e8625712493c89b785881f27eedc6cde480a81883cef78868b2"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "swc_macros_common",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "async-trait"
version = "0.1.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -407,6 +447,15 @@ dependencies = [
]

[[package]]
+
name = "better_scoped_tls"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de"
+
dependencies = [
+
 "scoped-tls",
+
]
+

+
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -544,6 +593,9 @@ name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
dependencies = [
+
 "allocator-api2",
+
]

[[package]]
name = "byte-unit"
@@ -1140,6 +1192,56 @@ dependencies = [
]

[[package]]
+
name = "data-url"
+
version = "0.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
+

+
[[package]]
+
name = "deno_ast"
+
version = "0.38.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "584547d27786a734536fde7088f8429d355569c39410427be44695c300618408"
+
dependencies = [
+
 "deno_media_type",
+
 "deno_terminal",
+
 "dprint-swc-ext",
+
 "once_cell",
+
 "percent-encoding",
+
 "serde",
+
 "swc_atoms",
+
 "swc_common",
+
 "swc_ecma_ast",
+
 "swc_ecma_parser",
+
 "swc_eq_ignore_macros",
+
 "text_lines",
+
 "thiserror",
+
 "unicode-width",
+
 "url",
+
]
+

+
[[package]]
+
name = "deno_media_type"
+
version = "0.1.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a8978229b82552bf8457a0125aa20863f023619cfc21ebb007b1e571d68fd85b"
+
dependencies = [
+
 "data-url",
+
 "serde",
+
 "url",
+
]
+

+
[[package]]
+
name = "deno_terminal"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7e6337d4e7f375f8b986409a76fbeecfa4bd8a1343e63355729ae4befa058eaf"
+
dependencies = [
+
 "once_cell",
+
 "termcolor",
+
]
+

+
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1244,6 +1346,63 @@ dependencies = [
]

[[package]]
+
name = "dprint-core"
+
version = "0.66.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f3ab0dd2bedc109d25f0d21afb09b7d329f6c6fa83b095daf31d2d967e091548"
+
dependencies = [
+
 "anyhow",
+
 "bumpalo",
+
 "hashbrown 0.14.5",
+
 "indexmap 2.6.0",
+
 "rustc-hash",
+
 "serde",
+
 "unicode-width",
+
]
+

+
[[package]]
+
name = "dprint-core-macros"
+
version = "0.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1675ad2b358481f3cc46202040d64ac7a36c4ade414a696df32e0e45421a6e9f"
+
dependencies = [
+
 "quote",
+
 "syn 1.0.109",
+
]
+

+
[[package]]
+
name = "dprint-plugin-typescript"
+
version = "0.90.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d7c3c339020ebbbbbe5fc049350935ee2ea2ba5a3fc01f753588639a30404cda"
+
dependencies = [
+
 "anyhow",
+
 "deno_ast",
+
 "dprint-core",
+
 "dprint-core-macros",
+
 "percent-encoding",
+
 "rustc-hash",
+
 "serde",
+
]
+

+
[[package]]
+
name = "dprint-swc-ext"
+
version = "0.16.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "019d17f2c2457c5a70a7cf4505b1a562ca8ab168c0ac0c005744efbd29fcb8fe"
+
dependencies = [
+
 "allocator-api2",
+
 "bumpalo",
+
 "num-bigint",
+
 "rustc-hash",
+
 "swc_atoms",
+
 "swc_common",
+
 "swc_ecma_ast",
+
 "swc_ecma_parser",
+
 "text_lines",
+
]
+

+
[[package]]
name = "dtoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1543,6 +1702,17 @@ dependencies = [
]

[[package]]
+
name = "from_variant"
+
version = "0.1.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "32016f1242eb82af5474752d00fd8ebcd9004bd69b462b1c91de833972d08ed4"
+
dependencies = [
+
 "proc-macro2",
+
 "swc_macros_common",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2027,7 +2197,17 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
-
 "ahash",
+
 "ahash 0.7.8",
+
]
+

+
[[package]]
+
name = "hashbrown"
+
version = "0.14.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
dependencies = [
+
 "ahash 0.8.11",
+
 "allocator-api2",
]

[[package]]
@@ -2070,6 +2250,20 @@ dependencies = [
]

[[package]]
+
name = "hstr"
+
version = "0.2.12"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dae404c0c5d4e95d4858876ab02eecd6a196bb8caa42050dfa809938833fc412"
+
dependencies = [
+
 "hashbrown 0.14.5",
+
 "new_debug_unreachable",
+
 "once_cell",
+
 "phf 0.11.2",
+
 "rustc-hash",
+
 "triomphe",
+
]
+

+
[[package]]
name = "html5ever"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2333,6 +2527,18 @@ dependencies = [
]

[[package]]
+
name = "is-macro"
+
version = "0.3.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2069faacbe981460232f880d26bf3c7634e322d49053aa48c27e3ae642f728f1"
+
dependencies = [
+
 "Inflector",
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "is-wsl"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2858,6 +3064,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
 "num-integer",
 "num-traits",
+
 "serde",
]

[[package]]
@@ -3693,6 +3900,15 @@ dependencies = [
]

[[package]]
+
name = "psm"
+
version = "0.1.23"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205"
+
dependencies = [
+
 "cc",
+
]
+

+
[[package]]
name = "ptr_meta"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3713,6 +3929,15 @@ dependencies = [
]

[[package]]
+
name = "qcheck"
+
version = "1.0.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b439bd4242da51d62d18c95e6a6add749346756b0d1a587dfd0cc22fa6b5f3f0"
+
dependencies = [
+
 "rand 0.8.5",
+
]
+

+
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3747,8 +3972,9 @@ dependencies = [

[[package]]
name = "radicle"
-
version = "0.13.0"
-
source = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git#2d13591ec21e6ce04678e2965f08d145cf2d76ae"
+
version = "0.14.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fd823aeed3ffe73eb82a213e62cb3811f9bdf453844d6e0b14684e0757fb389b"
dependencies = [
 "amplify",
 "base64 0.21.7",
@@ -3762,6 +3988,7 @@ dependencies = [
 "multibase",
 "nonempty",
 "once_cell",
+
 "qcheck",
 "radicle-cob",
 "radicle-crypto",
 "radicle-git-ext",
@@ -3777,8 +4004,9 @@ dependencies = [

[[package]]
name = "radicle-cob"
-
version = "0.12.0"
-
source = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git#2d13591ec21e6ce04678e2965f08d145cf2d76ae"
+
version = "0.13.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "90581a9508ccc310998e991d7acf139d2991297d3fb37d30de07536e10256afb"
dependencies = [
 "fastrand",
 "git2",
@@ -3796,12 +4024,15 @@ dependencies = [
[[package]]
name = "radicle-crypto"
version = "0.11.0"
-
source = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git#2d13591ec21e6ce04678e2965f08d145cf2d76ae"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d1d6a67969719841ad06049597006368eb4238ca63a02d20207654dfd1d2d6ad"
dependencies = [
 "amplify",
 "cyphernet",
 "ec25519",
+
 "fastrand",
 "multibase",
+
 "qcheck",
 "radicle-git-ext",
 "radicle-ssh",
 "serde",
@@ -3813,8 +4044,9 @@ dependencies = [

[[package]]
name = "radicle-dag"
-
version = "0.9.0"
-
source = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git#2d13591ec21e6ce04678e2965f08d145cf2d76ae"
+
version = "0.10.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cb41c7e10ada3a4df960190a96bfb4af56d33ada890f917acc8e3b122b614875"
dependencies = [
 "fastrand",
]
@@ -3836,7 +4068,8 @@ dependencies = [
[[package]]
name = "radicle-ssh"
version = "0.9.0"
-
source = "git+https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git#2d13591ec21e6ce04678e2965f08d145cf2d76ae"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fbee758010fb64482be4b18591fbeb3cbc15b16450d143edf4edb5484c7366c6"
dependencies = [
 "byteorder",
 "log",
@@ -3905,6 +4138,7 @@ dependencies = [
 "radicle-surf",
 "serde",
 "serde_json",
+
 "tempfile",
 "thiserror",
 "ts-rs",
]
@@ -4255,6 +4489,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"

[[package]]
+
name = "rustc-hash"
+
version = "1.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+

+
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4265,9 +4505,9 @@ dependencies = [

[[package]]
name = "rustix"
-
version = "0.38.37"
+
version = "0.38.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
dependencies = [
 "bitflags 2.6.0",
 "errno",
@@ -4325,6 +4565,12 @@ dependencies = [
]

[[package]]
+
name = "scoped-tls"
+
version = "1.0.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+

+
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4640,6 +4886,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"

[[package]]
+
name = "smartstring"
+
version = "1.0.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
+
dependencies = [
+
 "autocfg",
+
 "static_assertions",
+
 "version_check",
+
]
+

+
[[package]]
name = "socket2"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4812,6 +5069,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"

[[package]]
+
name = "stacker"
+
version = "0.1.17"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b"
+
dependencies = [
+
 "cc",
+
 "cfg-if",
+
 "libc",
+
 "psm",
+
 "windows-sys 0.59.0",
+
]
+

+
[[package]]
+
name = "static_assertions"
+
version = "1.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+

+
[[package]]
name = "string_cache"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4838,6 +5114,18 @@ dependencies = [
]

[[package]]
+
name = "string_enum"
+
version = "0.4.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "swc_macros_common",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4850,6 +5138,128 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"

[[package]]
+
name = "swc_atoms"
+
version = "0.6.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125"
+
dependencies = [
+
 "hstr",
+
 "once_cell",
+
 "rustc-hash",
+
 "serde",
+
]
+

+
[[package]]
+
name = "swc_common"
+
version = "0.33.26"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a2f9706038906e66f3919028f9f7a37f3ed552f1b85578e93f4468742e2da438"
+
dependencies = [
+
 "ast_node",
+
 "better_scoped_tls",
+
 "cfg-if",
+
 "either",
+
 "from_variant",
+
 "new_debug_unreachable",
+
 "num-bigint",
+
 "once_cell",
+
 "rustc-hash",
+
 "serde",
+
 "siphasher 0.3.11",
+
 "swc_atoms",
+
 "swc_eq_ignore_macros",
+
 "swc_visit",
+
 "tracing",
+
 "unicode-width",
+
 "url",
+
]
+

+
[[package]]
+
name = "swc_ecma_ast"
+
version = "0.113.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dc1690cc0c9ab60b44ac0225ba1e231ac532f7ba1d754df761c6ee607561afae"
+
dependencies = [
+
 "bitflags 2.6.0",
+
 "is-macro",
+
 "num-bigint",
+
 "phf 0.11.2",
+
 "scoped-tls",
+
 "serde",
+
 "string_enum",
+
 "swc_atoms",
+
 "swc_common",
+
 "unicode-id-start",
+
]
+

+
[[package]]
+
name = "swc_ecma_parser"
+
version = "0.144.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0499e69683ae5d67a20ff0279b94bc90f29df7922a46331b54d5dd367bf89570"
+
dependencies = [
+
 "either",
+
 "new_debug_unreachable",
+
 "num-bigint",
+
 "num-traits",
+
 "phf 0.11.2",
+
 "serde",
+
 "smallvec",
+
 "smartstring",
+
 "stacker",
+
 "swc_atoms",
+
 "swc_common",
+
 "swc_ecma_ast",
+
 "tracing",
+
 "typed-arena",
+
]
+

+
[[package]]
+
name = "swc_eq_ignore_macros"
+
version = "0.1.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
+
name = "swc_macros_common"
+
version = "0.3.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f486687bfb7b5c560868f69ed2d458b880cebc9babebcb67e49f31b55c5bf847"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
+
name = "swc_visit"
+
version = "0.5.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9"
+
dependencies = [
+
 "either",
+
 "swc_visit_macros",
+
]
+

+
[[package]]
+
name = "swc_visit_macros"
+
version = "0.5.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "92807d840959f39c60ce8a774a3f83e8193c658068e6d270dbe0a05e40e90b41"
+
dependencies = [
+
 "Inflector",
+
 "proc-macro2",
+
 "quote",
+
 "swc_macros_common",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "swift-rs"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5297,9 +5707,9 @@ dependencies = [

[[package]]
name = "tempfile"
-
version = "3.13.0"
+
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
 "cfg-if",
 "fastrand",
@@ -5347,6 +5757,15 @@ dependencies = [
]

[[package]]
+
name = "text_lines"
+
version = "0.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7fd5828de7deaa782e1dd713006ae96b3bee32d3279b79eb67ecf8072c059bcf"
+
dependencies = [
+
 "serde",
+
]
+

+
[[package]]
name = "thin-slice"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5580,10 +5999,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
 "pin-project-lite",
+
 "tracing-attributes",
 "tracing-core",
]

[[package]]
+
name = "tracing-attributes"
+
version = "0.1.27"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+
dependencies = [
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.81",
+
]
+

+
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5614,6 +6045,16 @@ dependencies = [
]

[[package]]
+
name = "triomphe"
+
version = "0.1.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e6631e42e10b40c0690bf92f404ebcfe6e1fdb480391d15f17cc8e96eeed5369"
+
dependencies = [
+
 "serde",
+
 "stable_deref_trait",
+
]
+

+
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5625,6 +6066,7 @@ version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a2f31991cee3dce1ca4f929a8a04fdd11fd8801aac0f2030b0fa8a0a3fef6b9"
dependencies = [
+
 "dprint-plugin-typescript",
 "lazy_static",
 "serde_json",
 "thiserror",
@@ -5644,6 +6086,12 @@ dependencies = [
]

[[package]]
+
name = "typed-arena"
+
version = "2.0.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
+

+
[[package]]
name = "typeid"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5703,6 +6151,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"

[[package]]
+
name = "unicode-id-start"
+
version = "1.0.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "02aebfa694eccbbbffdd92922c7de136b9fe764396d2f10e21bce1681477cfc1"
+

+
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5724,6 +6178,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"

[[package]]
+
name = "unicode-width"
+
version = "0.1.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+

+
[[package]]
name = "universal-hash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -6063,7 +6523,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
-
 "windows-sys 0.48.0",
+
 "windows-sys 0.59.0",
]

[[package]]
modified crates/radicle-tauri/Cargo.toml
@@ -18,7 +18,7 @@ tauri-build = { version = "2.0.1", features = ["isolation"] }
anyhow = { version = "1.0.90" }
base64 = { version = "0.22.1" }
log = { version = "0.4.22" }
-
radicle = { git = "https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git" }
+
radicle = { version = "0.14.0" }
radicle-types = { version = "0.1.0", path = "../radicle-types" }
radicle-surf = { version = "0.22.1", features = ["serde"] }
serde = { version = "1.0.210", features = ["derive"] }
modified crates/radicle-tauri/src/commands/repo.rs
@@ -32,3 +32,14 @@ pub async fn diff_stats(
) -> Result<types::cobs::Stats, Error> {
    ctx.diff_stats(rid, base, head)
}
+

+
#[tauri::command]
+
pub async fn list_commits(
+
    ctx: tauri::State<'_, AppState>,
+
    rid: RepoId,
+
    parent: Option<String>,
+
    skip: Option<usize>,
+
    take: Option<usize>,
+
) -> Result<types::cobs::PaginatedQuery<Vec<types::repo::Commit>>, Error> {
+
    ctx.list_commits(rid, parent, skip, take)
+
}
modified crates/radicle-tauri/src/lib.rs
@@ -6,34 +6,10 @@ use tauri::Manager;
use radicle::node::Handle;
use radicle::Node;
use radicle_types::error::Error;
-
use radicle_types::traits::auth::Auth;
-
use radicle_types::traits::cobs::Cobs;
-
use radicle_types::traits::issue::{Issues, IssuesMut};
-
use radicle_types::traits::patch::{Patches, PatchesMut};
-
use radicle_types::traits::repo::Repo;
-
use radicle_types::traits::thread::Thread;
-
use radicle_types::traits::Profile;
+
use radicle_types::AppState;

use commands::{auth, cob, diff, profile, repo, thread};

-
struct AppState {
-
    profile: radicle::Profile,
-
}
-

-
impl Auth for AppState {}
-
impl Repo for AppState {}
-
impl Thread for AppState {}
-
impl Cobs for AppState {}
-
impl Issues for AppState {}
-
impl IssuesMut for AppState {}
-
impl Patches for AppState {}
-
impl PatchesMut for AppState {}
-
impl Profile for AppState {
-
    fn profile(&self) -> radicle::Profile {
-
        self.profile.clone()
-
    }
-
}
-

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    #[cfg(debug_assertions)]
@@ -96,6 +72,7 @@ pub fn run() {
            repo::list_repos,
            repo::repo_by_id,
            repo::diff_stats,
+
            repo::list_commits,
            diff::get_diff,
            cob::get_file_by_oid,
            cob::activity_by_id,
modified crates/radicle-types/Cargo.toml
@@ -7,10 +7,11 @@ edition = "2021"
anyhow = { version = "1.0.90" }
axum = { version = "0.7.5", default-features = false, features = ["json"] }
base64 = { version = "0.22.1" }
-
radicle = { git = "https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git" }
+
radicle = { version = "0.14.0", features = ["test"] }
radicle-surf = { version = "0.22.1", features = ["serde"] }
serde = { version = "1.0.210", features = ["derive"] }
serde_json = { version = "1.0.132" }
thiserror = { version = "1.0.65" }
-
ts-rs = { version = "10.0.0", features = [ "serde-json-impl", "no-serde-warnings" ] }
+
ts-rs = { version = "10.0.0", features = ["serde-json-impl", "no-serde-warnings", "format"] }
localtime = { version = "1.3.1" }
+
tempfile = { version = "3.14.0" }
modified crates/radicle-types/bindings/cob/Never.ts
@@ -1,6 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

/**
-
 *A type alias for the TS type `never`.
+
 * A type alias for the TS type `never`.
 */
export type Never = never;
modified crates/radicle-types/bindings/cob/issue/Action.ts
@@ -3,11 +3,11 @@ import type { Embed } from "../thread/Embed";
import type { State } from "./State";

export type Action =
-
  | { type: "assign"; assignees: Array<string> }
-
  | { type: "edit"; title: string }
-
  | { type: "lifecycle"; state: State }
-
  | { type: "label"; labels: Array<string> }
-
  | { type: "comment"; body: string; replyTo?: string; embeds?: Array<Embed> }
-
  | { type: "comment.edit"; id: string; body: string; embeds?: Array<Embed> }
-
  | { type: "comment.redact"; id: string }
-
  | { type: "comment.react"; id: string; reaction: string; active: boolean };
+
  | { "type": "assign"; assignees: Array<string> }
+
  | { "type": "edit"; title: string }
+
  | { "type": "lifecycle"; state: State }
+
  | { "type": "label"; labels: Array<string> }
+
  | { "type": "comment"; body: string; replyTo?: string; embeds?: Array<Embed> }
+
  | { "type": "comment.edit"; id: string; body: string; embeds?: Array<Embed> }
+
  | { "type": "comment.redact"; id: string }
+
  | { "type": "comment.react"; id: string; reaction: string; active: boolean };
modified crates/radicle-types/bindings/cob/issue/Operation.ts
@@ -3,17 +3,25 @@ import type { Author } from "../Author";
import type { Embed } from "../thread/Embed";
import type { State } from "./State";

-
export type Operation = {
-
  entryId: string;
-
  timestamp: number;
-
  author: Author;
-
} & (
-
  | { type: "assign"; assignees: Array<string> }
-
  | { type: "edit"; title: string }
-
  | { type: "lifecycle"; state: State }
-
  | { type: "label"; labels: Array<string> }
-
  | { type: "comment"; body: string; replyTo?: string; embeds?: Array<Embed> }
-
  | { type: "comment.edit"; id: string; body: string; embeds?: Array<Embed> }
-
  | { type: "comment.redact"; id: string }
-
  | { type: "comment.react"; id: string; reaction: string; active: boolean }
-
);
+
export type Operation =
+
  & { entryId: string; timestamp: number; author: Author }
+
  & (
+
    | { "type": "assign"; assignees: Array<string> }
+
    | { "type": "edit"; title: string }
+
    | { "type": "lifecycle"; state: State }
+
    | { "type": "label"; labels: Array<string> }
+
    | {
+
      "type": "comment";
+
      body: string;
+
      replyTo?: string;
+
      embeds?: Array<Embed>;
+
    }
+
    | {
+
      "type": "comment.edit";
+
      id: string;
+
      body: string;
+
      embeds?: Array<Embed>;
+
    }
+
    | { "type": "comment.redact"; id: string }
+
    | { "type": "comment.react"; id: string; reaction: string; active: boolean }
+
  );
modified crates/radicle-types/bindings/cob/issue/State.ts
@@ -1,6 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { CloseReason } from "./CloseReason";

-
export type State =
-
  | { status: "closed"; reason: CloseReason }
-
  | { status: "open" };
+
export type State = { "status": "closed"; reason: CloseReason } | {
+
  "status": "open";
+
};
modified crates/radicle-types/bindings/cob/patch/Action.ts
@@ -3,92 +3,92 @@ import type { CodeLocation } from "../thread/CodeLocation";
import type { Embed } from "../thread/Embed";

export type Action =
-
  | { type: "edit"; title: string; target: string }
-
  | { type: "label"; labels: Array<string> }
-
  | { type: "lifecycle"; state: { status: "draft" | "open" | "archived" } }
-
  | { type: "assign"; assignees: Array<string> }
-
  | { type: "merge"; revision: string; commit: string }
+
  | { "type": "edit"; title: string; target: string }
+
  | { "type": "label"; labels: Array<string> }
+
  | { "type": "lifecycle"; state: { status: "draft" | "open" | "archived" } }
+
  | { "type": "assign"; assignees: Array<string> }
+
  | { "type": "merge"; revision: string; commit: string }
  | {
-
      type: "review";
-
      revision: string;
-
      summary?: string;
-
      verdict?: string;
-
      labels?: Array<string>;
-
    }
+
    "type": "review";
+
    revision: string;
+
    summary?: string;
+
    verdict?: string;
+
    labels?: Array<string>;
+
  }
  | {
-
      type: "review.edit";
-
      review: string;
-
      summary?: string;
-
      verdict?: string;
-
      labels?: Array<string>;
-
    }
-
  | { type: "review.redact"; review: string }
+
    "type": "review.edit";
+
    review: string;
+
    summary?: string;
+
    verdict?: string;
+
    labels?: Array<string>;
+
  }
+
  | { "type": "review.redact"; review: string }
  | {
-
      type: "review.comment";
-
      review: string;
-
      body: string;
-
      location?: CodeLocation;
-
      reply_to?: string;
-
      embeds?: Array<Embed>;
-
    }
+
    "type": "review.comment";
+
    review: string;
+
    body: string;
+
    location?: CodeLocation;
+
    reply_to?: string;
+
    embeds?: Array<Embed>;
+
  }
  | {
-
      type: "review.comment.edit";
-
      review: string;
-
      comment: string;
-
      body: string;
-
      embeds?: Array<Embed>;
-
    }
-
  | { type: "review.comment.redact"; review: string; comment: string }
+
    "type": "review.comment.edit";
+
    review: string;
+
    comment: string;
+
    body: string;
+
    embeds?: Array<Embed>;
+
  }
+
  | { "type": "review.comment.redact"; review: string; comment: string }
  | {
-
      type: "review.comment.react";
-
      review: string;
-
      comment: string;
-
      reaction: string;
-
      active: boolean;
-
    }
-
  | { type: "review.comment.resolve"; review: string; comment: string }
-
  | { type: "review.comment.unresolve"; review: string; comment: string }
+
    "type": "review.comment.react";
+
    review: string;
+
    comment: string;
+
    reaction: string;
+
    active: boolean;
+
  }
+
  | { "type": "review.comment.resolve"; review: string; comment: string }
+
  | { "type": "review.comment.unresolve"; review: string; comment: string }
  | {
-
      type: "revision";
-
      description: string;
-
      base: string;
-
      oid: string;
-
      resolves?: Array<[string, string]>;
-
    }
+
    "type": "revision";
+
    description: string;
+
    base: string;
+
    oid: string;
+
    resolves?: Array<[string, string]>;
+
  }
  | {
-
      type: "revision.edit";
-
      revision: string;
-
      description: string;
-
      embeds?: Array<Embed>;
-
    }
+
    "type": "revision.edit";
+
    revision: string;
+
    description: string;
+
    embeds?: Array<Embed>;
+
  }
  | {
-
      type: "revision.react";
-
      revision: string;
-
      location?: CodeLocation;
-
      reaction: string;
-
      active: boolean;
-
    }
-
  | { type: "revision.redact"; revision: string }
+
    "type": "revision.react";
+
    revision: string;
+
    location?: CodeLocation;
+
    reaction: string;
+
    active: boolean;
+
  }
+
  | { "type": "revision.redact"; revision: string }
  | {
-
      type: "revision.comment";
-
      revision: string;
-
      location?: CodeLocation;
-
      body: string;
-
      replyTo?: string;
-
      embeds?: Array<Embed>;
-
    }
+
    "type": "revision.comment";
+
    revision: string;
+
    location?: CodeLocation;
+
    body: string;
+
    replyTo?: string;
+
    embeds?: Array<Embed>;
+
  }
  | {
-
      type: "revision.comment.edit";
-
      revision: string;
-
      comment: string;
-
      body: string;
-
      embeds?: Array<Embed>;
-
    }
-
  | { type: "revision.comment.redact"; revision: string; comment: string }
+
    "type": "revision.comment.edit";
+
    revision: string;
+
    comment: string;
+
    body: string;
+
    embeds?: Array<Embed>;
+
  }
+
  | { "type": "revision.comment.redact"; revision: string; comment: string }
  | {
-
      type: "revision.comment.react";
-
      revision: string;
-
      comment: string;
-
      reaction: string;
-
      active: boolean;
-
    };
+
    "type": "revision.comment.react";
+
    revision: string;
+
    comment: string;
+
    reaction: string;
+
    active: boolean;
+
  };
modified crates/radicle-types/bindings/cob/patch/State.ts
@@ -1,7 +1,7 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export type State =
-
  | { status: "draft" }
-
  | { status: "open"; conflicts?: Array<[string, string]> }
-
  | { status: "archived" }
-
  | { status: "merged"; revision: string; commit: string };
+
  | { "status": "draft" }
+
  | { "status": "open"; conflicts?: Array<[string, string]> }
+
  | { "status": "archived" }
+
  | { "status": "merged"; revision: string; commit: string };
modified crates/radicle-types/bindings/cob/thread/CodeRange.ts
@@ -1,5 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

-
export type CodeRange =
-
  | { type: "lines"; range: { start: number; end: number } }
-
  | { type: "chars"; line: number; range: { start: number; end: number } };
+
export type CodeRange = {
+
  "type": "lines";
+
  range: { start: number; end: number };
+
} | { "type": "chars"; line: number; range: { start: number; end: number } };
modified crates/radicle-types/bindings/config/Config.ts
@@ -15,7 +15,7 @@ export type Config = {
  /**
   * Default seeding policy.
   */
-
  seedingPolicy:
-
    | { default: "allow"; scope: "followed" | "all" }
-
    | { default: "block" };
+
  seedingPolicy: { default: "allow"; scope: "followed" | "all" } | {
+
    default: "block";
+
  };
};
added crates/radicle-types/bindings/repo/Commit.ts
@@ -0,0 +1,10 @@
+
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
+

+
export type Commit = {
+
  id: string;
+
  author: { name: string; email: string; time: number };
+
  committer: { name: string; email: string; time: number };
+
  message: string;
+
  summary: string;
+
  parents: Array<string>;
+
};
modified crates/radicle-types/bindings/repo/Visibility.ts
@@ -1,5 +1,6 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

-
export type Visibility =
-
  | { type: "public" }
-
  | { type: "private"; allow?: Array<string> };
+
export type Visibility = { "type": "public" } | {
+
  "type": "private";
+
  allow?: Array<string>;
+
};
modified crates/radicle-types/src/cobs.rs
@@ -52,7 +52,7 @@ impl CobOptions {
    }
}

-
#[derive(Serialize, Deserialize, TS)]
+
#[derive(Serialize, Deserialize, TS, Debug, PartialEq, Clone)]
#[ts(export)]
#[ts(export_to = "cob/")]
pub struct PaginatedQuery<T> {
modified crates/radicle-types/src/config.rs
@@ -6,7 +6,7 @@ use radicle::node::config::DefaultSeedingPolicy;
use radicle::node::Alias;

/// Service configuration.
-
#[derive(TS, Serialize)]
+
#[derive(Debug, TS, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
#[ts(export_to = "config/")]
modified crates/radicle-types/src/lib.rs
@@ -1,5 +1,32 @@
+
use traits::auth::Auth;
+
use traits::cobs::Cobs;
+
use traits::issue::{Issues, IssuesMut};
+
use traits::patch::{Patches, PatchesMut};
+
use traits::repo::Repo;
+
use traits::thread::Thread;
+
use traits::Profile;
+

pub mod cobs;
pub mod config;
pub mod error;
pub mod repo;
+
pub mod test;
pub mod traits;
+

+
pub struct AppState {
+
    pub profile: radicle::Profile,
+
}
+

+
impl Auth for AppState {}
+
impl Repo for AppState {}
+
impl Thread for AppState {}
+
impl Cobs for AppState {}
+
impl Issues for AppState {}
+
impl IssuesMut for AppState {}
+
impl Patches for AppState {}
+
impl PatchesMut for AppState {}
+
impl Profile for AppState {
+
    fn profile(&self) -> radicle::Profile {
+
        self.profile.clone()
+
    }
+
}
modified crates/radicle-types/src/repo.rs
@@ -1,5 +1,6 @@
use std::collections::BTreeSet;

+
use radicle_surf as surf;
use serde::{Deserialize, Serialize};
use ts_rs::TS;

@@ -112,3 +113,33 @@ pub struct ProjectPayloadMeta {
    #[ts(type = "number")]
    pub last_commit_timestamp: i64,
}
+

+
#[derive(Clone, Serialize, TS, Debug, PartialEq)]
+
#[serde(rename_all = "camelCase")]
+
#[ts(export)]
+
#[ts(export_to = "repo/")]
+
pub struct Commit {
+
    #[ts(as = "String")]
+
    pub id: git::Oid,
+
    #[ts(type = "{ name: string; email: string; time: number; }")]
+
    pub author: surf::Author,
+
    #[ts(type = "{ name: string; email: string; time: number; }")]
+
    pub committer: surf::Author,
+
    pub message: String,
+
    pub summary: String,
+
    #[ts(as = "Vec<String>")]
+
    pub parents: Vec<git::Oid>,
+
}
+

+
impl From<surf::Commit> for Commit {
+
    fn from(value: surf::Commit) -> Self {
+
        Self {
+
            id: value.id,
+
            author: value.author,
+
            committer: value.committer,
+
            message: value.message,
+
            summary: value.summary,
+
            parents: value.parents,
+
        }
+
    }
+
}
added crates/radicle-types/src/test.rs
@@ -0,0 +1,58 @@
+
use std::path::Path;
+

+
use radicle::cob::migrate;
+
use radicle::crypto::ssh::Keystore;
+
use radicle::crypto::{KeyPair, Seed};
+
use radicle::node::{Features, Timestamp, UserAgent};
+
use radicle::profile::Home;
+
use radicle::Storage;
+
use radicle::{node, profile};
+

+
pub const TIMESTAMP: u64 = 1671125284;
+

+
/// Create a new profile.
+
pub fn profile(home: &Path, seed: [u8; 32]) -> radicle::Profile {
+
    let home = Home::new(home).unwrap();
+
    let keystore = Keystore::new(&home.keys());
+

+
    let keypair = KeyPair::from_seed(Seed::from(seed));
+
    let alias = node::Alias::new("seed");
+
    let storage = Storage::open(
+
        home.storage(),
+
        radicle::git::UserInfo {
+
            alias: alias.clone(),
+
            key: keypair.pk.into(),
+
        },
+
    )
+
    .unwrap();
+

+
    let mut db = home.policies_mut().unwrap();
+
    db.follow(&keypair.pk.into(), Some(&alias)).unwrap();
+

+
    let node_db = home.database_mut().unwrap();
+
    node_db
+
        .init(
+
            &keypair.pk.into(),
+
            Features::SEED,
+
            &alias,
+
            &UserAgent::default(),
+
            Timestamp::try_from(TIMESTAMP).unwrap(),
+
            [],
+
        )
+
        .unwrap();
+

+
    // Migrate COBs cache.
+
    let mut cobs = home.cobs_db_mut().unwrap();
+
    cobs.migrate(migrate::ignore).unwrap();
+

+
    radicle::storage::git::transport::local::register(storage.clone());
+
    keystore.store(keypair.clone(), "radicle", None).unwrap();
+

+
    radicle::Profile {
+
        home,
+
        storage,
+
        keystore,
+
        public_key: keypair.pk.into(),
+
        config: profile::Config::new(alias),
+
    }
+
}
modified crates/radicle-types/src/traits.rs
@@ -20,3 +20,33 @@ pub trait Profile {
        }
    }
}
+

+
#[cfg(test)]
+
#[allow(clippy::unwrap_used)]
+
mod test {
+
    use std::str::FromStr;
+

+
    use radicle::crypto::test::signer::MockSigner;
+
    use radicle::crypto::Signer;
+
    use radicle::node::{config, Alias};
+

+
    use crate::config::Config;
+
    use crate::{test, AppState, Profile};
+

+
    #[test]
+
    fn config() {
+
        let tmp = tempfile::tempdir().unwrap();
+
        let profile = test::profile(tmp.path(), [0xff; 32]);
+
        let signer = MockSigner::from_seed([0xff; 32]);
+
        let state = AppState { profile };
+

+
        assert_eq!(
+
            Profile::config(&state),
+
            Config {
+
                public_key: *signer.public_key(),
+
                alias: Alias::from_str("seed").unwrap(),
+
                seeding_policy: config::DefaultSeedingPolicy::Block,
+
            }
+
        )
+
    }
+
}
modified crates/radicle-types/src/traits/cobs.rs
@@ -1,4 +1,3 @@
-
use radicle::cob::migrate;
use radicle::cob::object::Storage;
use radicle::storage::refs::draft;
use radicle::storage::{self, ReadStorage};
@@ -59,7 +58,7 @@ pub trait Cobs: Profile {
            &draft_oid.into(),
        )?;

-
        let mut patches = profile.patches_mut(&repo, migrate::ignore)?;
+
        let mut patches = profile.patches_mut(&repo)?;
        patches.write(&cob_id.into())?;

        storage::git::cob::DraftStore::new(&repo, *signer.public_key()).remove(
modified crates/radicle-types/src/traits/issue.rs
@@ -1,4 +1,3 @@
-
use radicle::cob::migrate;
use radicle::issue::cache::Issues as _;
use radicle::node::Handle;
use radicle::storage::ReadStorage;
@@ -17,7 +16,7 @@ pub trait Issues: Profile {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
        let status = status.unwrap_or_default();
-
        let issues = profile.issues(&repo, migrate::ignore)?;
+
        let issues = profile.issues(&repo)?;
        let mut issues: Vec<_> = issues
            .list()?
            .filter_map(|r| {
@@ -43,7 +42,7 @@ pub trait Issues: Profile {
    ) -> Result<Option<cobs::issue::Issue>, Error> {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
-
        let issues = profile.issues(&repo, migrate::ignore)?;
+
        let issues = profile.issues(&repo)?;
        let issue = issues.get(&id.into())?;

        let aliases = &profile.aliases();
@@ -59,7 +58,7 @@ pub trait Issues: Profile {
    ) -> Result<Option<Vec<cobs::thread::Thread>>, Error> {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
-
        let issues = profile.issues(&repo, migrate::ignore)?;
+
        let issues = profile.issues(&repo)?;
        let issue = issues.get(&id.into())?;

        let aliases = &profile.aliases();
@@ -104,7 +103,7 @@ pub trait IssuesMut: Profile {
        let repo = profile.storage.repository(rid)?;
        let signer = profile.signer()?;
        let aliases = profile.aliases();
-
        let mut issues = profile.issues_mut(&repo, migrate::ignore)?;
+
        let mut issues = profile.issues_mut(&repo)?;
        let issue = issues.create(
            new.title,
            new.description,
@@ -133,7 +132,7 @@ pub trait IssuesMut: Profile {
        let repo = profile.storage.repository(rid)?;
        let signer = profile.signer()?;
        let aliases = profile.aliases();
-
        let mut issues = profile.issues_mut(&repo, migrate::ignore)?;
+
        let mut issues = profile.issues_mut(&repo)?;
        let mut issue = issues.get_mut(&cob_id.into())?;

        match action {
modified crates/radicle-types/src/traits/patch.rs
@@ -1,4 +1,3 @@
-
use radicle::cob::migrate;
use radicle::node::Handle;
use radicle::patch::cache::Patches as _;
use radicle::storage;
@@ -22,7 +21,7 @@ pub trait Patches: Profile {
        let take = take.unwrap_or(20);
        let repo = profile.storage.repository(rid)?;
        let aliases = &profile.aliases();
-
        let cache = profile.patches(&repo, migrate::ignore)?;
+
        let cache = profile.patches(&repo)?;
        let patches = match status {
            None => cache.list()?.collect::<Vec<_>>(),
            Some(s) => cache.list_by_status(&s.into())?.collect::<Vec<_>>(),
@@ -55,7 +54,7 @@ pub trait Patches: Profile {
    ) -> Result<Option<cobs::patch::Patch>, Error> {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
-
        let patches = profile.patches(&repo, migrate::ignore)?;
+
        let patches = profile.patches(&repo)?;
        let patch = patches.get(&id.into())?;
        let aliases = &profile.aliases();
        let patches = patch.map(|patch| cobs::patch::Patch::new(id.into(), &patch, aliases));
@@ -70,7 +69,7 @@ pub trait Patches: Profile {
    ) -> Result<Option<Vec<cobs::patch::Revision>>, Error> {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
-
        let patches = profile.patches(&repo, migrate::ignore)?;
+
        let patches = profile.patches(&repo)?;
        let revisions = patches.get(&id.into())?.map(|patch| {
            let aliases = &profile.aliases();

@@ -91,7 +90,7 @@ pub trait Patches: Profile {
    ) -> Result<Option<cobs::patch::Revision>, Error> {
        let profile = self.profile();
        let repo = profile.storage.repository(rid)?;
-
        let patches = profile.patches(&repo, migrate::ignore)?;
+
        let patches = profile.patches(&repo)?;
        let revision = patches.get(&id.into())?.and_then(|patch| {
            let aliases = &profile.aliases();

@@ -117,7 +116,7 @@ pub trait PatchesMut: Profile {
        let repo = profile.storage.repository(rid)?;
        let signer = profile.signer()?;
        let aliases = profile.aliases();
-
        let mut patches = profile.patches_mut(&repo, migrate::ignore)?;
+
        let mut patches = profile.patches_mut(&repo)?;
        let mut patch = patches.get_mut(&cob_id.into())?;

        match action {
modified crates/radicle-types/src/traits/repo.rs
@@ -1,4 +1,3 @@
-
use radicle::cob::migrate;
use radicle_surf as surf;
use serde::{Deserialize, Serialize};

@@ -104,9 +103,9 @@ pub trait Repo: Profile {
            .and_then(|payload| {
                let (_, head) = repo.head().ok()?;
                let commit = repo.commit(head).ok()?;
-
                let patches = profile.patches(repo, migrate::ignore).ok()?;
+
                let patches = profile.patches(repo).ok()?;
                let patches = patches.counts().ok()?;
-
                let issues = profile.issues(repo, migrate::ignore).ok()?;
+
                let issues = profile.issues(repo).ok()?;
                let issues = issues.counts().ok()?;

                let data: repo::ProjectPayloadData = (*payload).clone().try_into().ok()?;
@@ -158,4 +157,161 @@ pub trait Repo: Profile {

        Ok::<_, Error>(diff)
    }
+

+
    fn list_commits(
+
        &self,
+
        rid: identity::RepoId,
+
        parent: Option<String>,
+
        skip: Option<usize>,
+
        take: Option<usize>,
+
    ) -> Result<cobs::PaginatedQuery<Vec<repo::Commit>>, Error> {
+
        let profile = self.profile();
+
        let cursor = skip.unwrap_or(0);
+
        let take = take.unwrap_or(20);
+
        let repo = profile.storage.repository(rid)?;
+

+
        let sha = match parent {
+
            Some(commit) => commit,
+
            None => repo.head()?.1.to_string(),
+
        };
+

+
        let repo = surf::Repository::open(repo.path())?;
+
        let history = repo.history(&sha)?;
+

+
        let mut commits = history
+
            .filter_map(|c| c.map(Into::into).ok())
+
            .skip(cursor)
+
            .take(take + 1); // Take one extra item to check if there's more.
+

+
        let paginated_commits: Vec<_> = commits.by_ref().take(take).collect();
+
        let more = commits.next().is_some();
+

+
        Ok::<_, Error>(cobs::PaginatedQuery {
+
            cursor,
+
            more,
+
            content: paginated_commits.to_vec(),
+
        })
+
    }
+
}
+

+
#[cfg(test)]
+
#[allow(clippy::unwrap_used)]
+
mod test {
+
    use std::str::FromStr;
+

+
    use radicle::crypto::test::signer::MockSigner;
+
    use radicle::{git, test};
+
    use radicle_surf::Author;
+

+
    use crate::cobs;
+
    use crate::repo;
+
    use crate::traits::repo::Repo;
+
    use crate::AppState;
+

+
    #[test]
+
    fn list_commits_pagination() {
+
        let signer = MockSigner::from_seed([0xff; 32]);
+
        let tempdir = tempfile::tempdir().unwrap();
+
        let profile = crate::test::profile(tempdir.path(), [0xff; 32]);
+
        let (rid, _, _, _) =
+
            test::fixtures::project(tempdir.path().join("original"), &profile.storage, &signer)
+
                .unwrap();
+
        let state = AppState { profile };
+
        let commits = Repo::list_commits(&state, rid, None, None, Some(1)).unwrap();
+

+
        assert_eq!(
+
            commits,
+
            cobs::PaginatedQuery {
+
                cursor: 0,
+
                more: true,
+
                content: vec![repo::Commit {
+
                    id: git::Oid::from_str("f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354").unwrap(),
+
                    author: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    committer: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    message: "Second commit".to_string(),
+
                    summary: "Second commit".to_string(),
+
                    parents: vec![
+
                        git::Oid::from_str("08c788dd1be6315de09e3fe09b5b1b7a2b8711d9").unwrap()
+
                    ],
+
                }],
+
            }
+
        );
+

+
        let commits = Repo::list_commits(&state, rid, None, Some(1), None).unwrap();
+

+
        assert_eq!(
+
            commits,
+
            cobs::PaginatedQuery {
+
                cursor: 1,
+
                more: false,
+
                content: vec![repo::Commit {
+
                    id: git::Oid::from_str("08c788dd1be6315de09e3fe09b5b1b7a2b8711d9").unwrap(),
+
                    author: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    committer: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    message: "Initial commit".to_string(),
+
                    summary: "Initial commit".to_string(),
+
                    parents: vec![],
+
                }],
+
            }
+
        );
+
    }
+

+
    #[test]
+
    fn list_commits_with_head() {
+
        let signer = MockSigner::from_seed([0xff; 32]);
+
        let tempdir = tempfile::tempdir().unwrap();
+
        let profile = crate::test::profile(tempdir.path(), [0xff; 32]);
+
        let (rid, _, _, _) =
+
            test::fixtures::project(tempdir.path().join("original"), &profile.storage, &signer)
+
                .unwrap();
+
        let state = AppState { profile };
+
        let commits = Repo::list_commits(
+
            &state,
+
            rid,
+
            Some("08c788dd1be6315de09e3fe09b5b1b7a2b8711d9".to_string()),
+
            None,
+
            None,
+
        )
+
        .unwrap();
+

+
        assert_eq!(
+
            commits,
+
            cobs::PaginatedQuery {
+
                cursor: 0,
+
                more: false,
+
                content: vec![repo::Commit {
+
                    id: git::Oid::from_str("08c788dd1be6315de09e3fe09b5b1b7a2b8711d9").unwrap(),
+
                    author: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    committer: Author {
+
                        name: "anonymous".to_string(),
+
                        email: "anonymous@radicle.xyz".to_string(),
+
                        time: radicle::git::raw::Time::new(1514817556, 0).into(),
+
                    },
+
                    message: "Initial commit".to_string(),
+
                    summary: "Initial commit".to_string(),
+
                    parents: vec![],
+
                }],
+
            }
+
        );
+
    }
}
modified crates/radicle-types/src/traits/thread.rs
@@ -2,7 +2,6 @@ use base64::{engine::general_purpose::STANDARD, Engine as _};
use localtime::LocalTime;

use radicle::cob;
-
use radicle::cob::cache::migrate;
use radicle::git;
use radicle::identity;
use radicle::node::Handle;
@@ -47,7 +46,7 @@ pub trait Thread: Profile {
        let mut node = Node::new(profile.socket());
        let signer = profile.signer()?;
        let repo = profile.storage.repository(rid)?;
-
        let mut issues = profile.issues_mut(&repo, migrate::ignore)?;
+
        let mut issues = profile.issues_mut(&repo)?;
        let mut issue = issues.get_mut(&new.id.into())?;
        let id = new.reply_to.unwrap_or_else(|| {
            let (root_id, _) = issue.root();
@@ -90,7 +89,7 @@ pub trait Thread: Profile {
        let mut node = Node::new(profile.socket());
        let signer = profile.signer()?;
        let repo = profile.storage.repository(rid)?;
-
        let mut patches = profile.patches_mut(&repo, migrate::ignore)?;
+
        let mut patches = profile.patches_mut(&repo)?;
        let mut patch = patches.get_mut(&new.id.into())?;
        let n = new.clone();
        let oid = patch.comment(
modified crates/test-http-api/Cargo.toml
@@ -10,7 +10,7 @@ anyhow = { version = "1.0.90" }
axum = { version = "0.7.5", default-features = false, features = ["json", "query", "tokio", "http1"] }
hyper = { version = "1.4", default-features = false }
lexopt = { version = "0.3.0" }
-
radicle = { git = "https://seed.radicle.xyz/z3gqcJUoA1n9HaHKufZs5FCSGazv5.git" }
+
radicle = { version = "0.14.0" }
radicle-surf = { version = "0.22.1", default-features = false, features = ["serde"] }
radicle-types = { path = "../radicle-types" }
serde = { version = "1", features = ["derive"] }
modified package.json
@@ -16,7 +16,7 @@
    "check-rs": "scripts/check-rs",
    "test:e2e": "TZ='UTC' playwright test",
    "format": "npx prettier '**/*.@(ts|js|svelte|json|css|html|yml)' --write",
-
    "generate-types": "cargo test --manifest-path ./crates/radicle-types/Cargo.toml && npx prettier ./crates/radicle-types/bindings --write",
+
    "generate-types": "cargo test --manifest-path ./crates/radicle-types/Cargo.toml",
    "tauri": "npx tauri"
  },
  "engines": {
modified scripts/check-js
@@ -4,4 +4,4 @@ set -e
npx tsc --noEmit
npx svelte-check --tsconfig tsconfig.json --fail-on-warnings --compiler-warnings missing-custom-element-compile-options:ignore
npx eslint --cache --cache-location node_modules/.cache/eslint --max-warnings 0 .
-
npx prettier "**/*.@(ts|js|svelte|json|css|html|yml)" --ignore-path .gitignore --check --cache
+
npx prettier "**/*.@(ts|js|svelte|json|css|html|yml)" "!crates/**/*" --ignore-path .gitignore --check --cache
modified scripts/check-rs
@@ -1,6 +1,12 @@
#!/bin/sh
set -e

-
cargo check --manifest-path ./crates/radicle-tauri/Cargo.toml
-
cargo clippy --manifest-path ./crates/radicle-tauri/Cargo.toml -- -Dwarnings
-
cargo fmt --manifest-path ./crates/radicle-tauri/Cargo.toml --check
+
crates="radicle-tauri radicle-types test-http-api"
+

+
for crate in $crates; do
+
    echo "Running checks for: $crate"
+
    cargo check --manifest-path ./crates/"$crate"/Cargo.toml --quiet
+
    cargo clippy --manifest-path ./crates/"$crate"/Cargo.toml --quiet -- -Dwarnings
+
    cargo fmt --manifest-path ./crates/"$crate"/Cargo.toml --check --quiet
+
    cargo test --manifest-path ./crates/"$crate"/Cargo.toml --quiet
+
done
modified tests/support/heartwood-release
@@ -1 +1 @@
-
1.0.0

\ No newline at end of file
+
1.1.0-pre.4

\ No newline at end of file