diff --git a/Cargo.lock b/Cargo.lock index d053fc42..79b7f7fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,51 +8,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common 0.1.7", - "generic-array", -] - -[[package]] -name = "aegis" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e07d39d15384924b35b70d7b8fa1f9a2934101dd3fa4722ede163cc4f9b7b960" -dependencies = [ - "cc", - "softaes", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures 0.2.17", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - [[package]] name = "agent-client-protocol" version = "1.2.0" @@ -213,22 +168,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "antithesis_sdk" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08410fcac93669a476c006cd6c4512ac1e2b30fd117231a5d55d8a2c76599b82" -dependencies = [ - "libc", - "libloading", - "linkme", - "once_cell", - "rand 0.8.7", - "rustc_version_runtime", - "serde", - "serde_json", -] - [[package]] name = "anyhow" version = "1.0.103" @@ -264,12 +203,6 @@ dependencies = [ "rustversion", ] -[[package]] -name = "assoc" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdc70193dadb9d7287fa4b633f15f90c876915b31f6af17da307fc59c9859a8" - [[package]] name = "async-channel" version = "2.5.0" @@ -307,7 +240,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.4", + "rustix", "slab", "windows-sys 0.61.2", ] @@ -338,7 +271,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 1.1.4", + "rustix", ] [[package]] @@ -353,7 +286,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.4", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -423,19 +356,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bigdecimal" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" -dependencies = [ - "autocfg", - "libm", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "bincode" version = "1.3.3" @@ -445,29 +365,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex 1.3.0", - "syn", - "which 4.4.2", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -500,25 +397,13 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" dependencies = [ "serde_core", ] -[[package]] -name = "bitvec" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -556,15 +441,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" -[[package]] -name = "branches" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e426eb5cc1900033930ec955317b302e68f19f326cc7bb0c8a86865a826cdf0c" -dependencies = [ - "rustc_version", -] - [[package]] name = "brotli" version = "8.0.4" @@ -597,9 +473,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" +checksum = "1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530" dependencies = [ "memchr", "regex-automata", @@ -733,16 +609,7 @@ dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex 2.0.1", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", + "shlex", ] [[package]] @@ -753,15 +620,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "cfg_block" -version = "0.1.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18758054972164c3264f7c8386f5fc6da6114cb46b619fd365d4e3b2dc3ae487" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chacha20" @@ -788,32 +649,11 @@ dependencies = [ "windows-link", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.7", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" -version = "4.6.1" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011" dependencies = [ "clap_builder", "clap_derive", @@ -821,9 +661,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstream", "anstyle", @@ -1044,15 +884,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32c" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" -dependencies = [ - "rustc_version", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -1138,16 +969,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-skiplist" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.22" @@ -1166,7 +987,7 @@ dependencies = [ "document-features", "mio", "parking_lot", - "rustix 1.1.4", + "rustix", "serde", "signal-hook", "signal-hook-mio", @@ -1195,7 +1016,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] @@ -1208,15 +1028,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - [[package]] name = "daachorse" version = "1.0.1" @@ -1307,25 +1118,6 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" -[[package]] -name = "db-keystore" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a1b2f1087c32a26a8c6c7d89eb80b50c33d8466e2431ea2a8345c969cded18" -dependencies = [ - "anyhow", - "clap", - "futures", - "keyring-core", - "log", - "regex", - "serde", - "serde_json", - "turso", - "uuid", - "zeroize", -] - [[package]] name = "deranged" version = "0.5.8" @@ -1557,26 +1349,6 @@ dependencies = [ "syn", ] -[[package]] -name = "env_filter" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" -dependencies = [ - "env_filter", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1629,12 +1401,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - [[package]] name = "fancy-regex" version = "0.13.0" @@ -1679,17 +1445,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "fastbloom" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" -dependencies = [ - "getrandom 0.3.4", - "libm", - "siphasher", -] - [[package]] name = "fastrand" version = "2.4.1" @@ -1709,7 +1464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" dependencies = [ "cfg-if", - "rustix 1.1.4", + "rustix", "windows-sys 0.59.0", ] @@ -1804,12 +1559,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "futures" version = "0.3.32" @@ -2052,36 +1801,6 @@ dependencies = [ "seq-macro", ] -[[package]] -name = "genawaiter" -version = "0.99.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" -dependencies = [ - "genawaiter-macro", -] - -[[package]] -name = "genawaiter-macro" -version = "0.99.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc" - -[[package]] -name = "generator" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows-link", - "windows-result", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -2098,7 +1817,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "rustix 1.1.4", + "rustix", "windows-link", ] @@ -2143,16 +1862,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - [[package]] name = "gif" version = "0.14.2" @@ -2171,9 +1880,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +checksum = "e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd" dependencies = [ "aho-corasick", "bstr", @@ -2280,15 +1989,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "http" version = "1.4.2" @@ -2301,9 +2001,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -2311,9 +2011,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" dependencies = [ "bytes", "futures-core", @@ -2557,9 +2257,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adf14691c72bcfc1058740436a35bdd3ae9c07d1a941ef00b749e9ea16aefa7" +checksum = "d4ffa3a0547a138e59ddd6fa3b7c672ed47e6ad6a3cd177984ff1116aa5ba742" dependencies = [ "crossbeam-deque", "globset", @@ -2649,35 +2349,6 @@ dependencies = [ "web-time", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "intrusive-collections" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" -dependencies = [ - "memoffset", -] - -[[package]] -name = "io-uring" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9080b15e63775b9a2ac7dca720f7050a8b955e092ea0f6020a4a80f69998cdc0" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.12.0" @@ -2709,15 +2380,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -2865,15 +2527,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "keyring-core" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb1e621458ca9c51aa110bd0339d4751a056b9576bf1253aee1aa560dda0fc9d" -dependencies = [ - "log", -] - [[package]] name = "landlock" version = "0.4.5" @@ -2914,43 +2567,18 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - [[package]] name = "libm" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" -[[package]] -name = "libmimalloc-sys" -version = "0.1.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9" -dependencies = [ - "cc", -] - [[package]] name = "libredox" version = "0.1.18" @@ -2960,32 +2588,6 @@ dependencies = [ "libc", ] -[[package]] -name = "linkme" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83272d46373fb8decca684579ac3e7c8f3d71d4cc3aa693df8759e260ae41cf" -dependencies = [ - "linkme-impl", -] - -[[package]] -name = "linkme-impl" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d59e20403c7d08fe62b4376edfe5c7fb2ef1e6b1465379686d0f21c8df444b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -3019,19 +2621,6 @@ version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - [[package]] name = "lru-slab" version = "0.1.2" @@ -3079,52 +2668,12 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "micromap" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a86d3146ed3995b5913c414f6664344b9617457320782e64f0bb44afd49d74" -[[package]] -name = "miette" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" -dependencies = [ - "cfg-if", - "miette-derive", - "unicode-width 0.1.14", -] - -[[package]] -name = "miette-derive" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "mimalloc" -version = "0.1.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862" -dependencies = [ - "libmimalloc-sys", -] - [[package]] name = "mime" version = "0.3.17" @@ -3158,9 +2707,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "log", @@ -3416,9 +2965,9 @@ dependencies = [ [[package]] name = "octolib" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f212df30162112fe0f06667beb1a1f90bf19e615b44e556f2a124bb75dc51306" +checksum = "8a817b0a599ab2fb1373ab48447333122df4a8d25d90c13181923bddc3fea28c" dependencies = [ "anyhow", "arc-swap", @@ -3458,7 +3007,6 @@ dependencies = [ "clap_complete", "colored", "crossterm", - "db-keystore", "dirs", "dotenvy", "flate2", @@ -3474,7 +3022,6 @@ dependencies = [ "ignore", "image", "indicatif 0.18.6", - "keyring-core", "landlock", "lazy_static", "libc", @@ -3510,7 +3057,7 @@ dependencies = [ "urlencoding", "uuid", "viuer", - "which 8.0.4", + "which", "zstd", ] @@ -3548,12 +3095,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "open" version = "5.4.0" @@ -3582,21 +3123,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" - -[[package]] -name = "pack1" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b7bb0ecf2e447b1f20ee94ee79ef6eed1e9d4b3c36ce1903b9dea3bf205523" -dependencies = [ - "bytemuck", -] - [[package]] name = "parking" version = "2.2.1" @@ -3632,12 +3158,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pastey" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" - [[package]] name = "pem" version = "3.0.6" @@ -3720,27 +3240,15 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.4", + "rustix", "windows-sys 0.61.2", ] -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "opaque-debug", - "universal-hash", -] - [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" [[package]] name = "potential_utf" @@ -3766,16 +3274,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" version = "1.0.106" @@ -3796,29 +3294,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "prost" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" -dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "pulp" version = "0.22.3" @@ -3885,7 +3360,7 @@ dependencies = [ "getrandom 0.4.3", "lru-slab", "rand 0.10.2", - "rand_pcg 0.10.2", + "rand_pcg", "ring", "rustc-hash 2.1.3", "rustls", @@ -3932,12 +3407,6 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.8.7" @@ -4024,15 +3493,6 @@ dependencies = [ "rand 0.9.5", ] -[[package]] -name = "rand_pcg" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_pcg" version = "0.10.2" @@ -4042,15 +3502,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "rapidhash" -version = "4.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da7e78a036ce858e8d55b7e7dc8ba3a88b78350fd2155d3591bbd966b58589e" -dependencies = [ - "rustversion", -] - [[package]] name = "raw-cpuid" version = "11.6.0" @@ -4177,9 +3628,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0e75113e14dc5acb068cd0786884f214f1312650a3d36d269f5c4f3cdee8a2" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -4189,9 +3640,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f388202e4b80542a0921078cc23b6333bcf1409c1e3f86404cae4766a6131db" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -4326,16 +3777,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "roaring" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dedc5658c6ecb3bdb5ef5f3295bb9253f42dcf3fd1402c03f6b1f7659c3c4a9" -dependencies = [ - "bytemuck", - "byteorder", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -4357,29 +3798,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustc_version_runtime" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd18cd2bae1820af0b6ad5e54f4a51d0f3fcc53b05f845675074efcc7af071d" -dependencies = [ - "rustc_version", - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.1.4" @@ -4389,15 +3807,15 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.12.1", + "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.41" +version = "0.23.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" +checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" dependencies = [ "aws-lc-rs", "once_cell", @@ -4547,12 +3965,6 @@ dependencies = [ "syn", ] -[[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" @@ -4758,12 +4170,6 @@ dependencies = [ "digest 0.11.3", ] -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - [[package]] name = "sha2" version = "0.10.9" @@ -4801,38 +4207,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - [[package]] name = "shlex" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" -[[package]] -name = "shuttle" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab17edba38d63047f46780cf7360acf7467fec2c048928689a5c1dd1c2b4e31" -dependencies = [ - "assoc", - "bitvec", - "cfg-if", - "generator", - "hex", - "owo-colors", - "rand 0.8.7", - "rand_core 0.6.4", - "rand_pcg 0.3.1", - "scoped-tls", - "smallvec", - "tracing", -] - [[package]] name = "signal-hook" version = "0.3.18" @@ -4875,15 +4255,15 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "simd_cesu8" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ "rustc_version", "simdutf8", @@ -4907,21 +4287,6 @@ dependencies = [ "time", ] -[[package]] -name = "simsimd" -version = "6.5.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fb3bc3cdce07a7d7d4caa4c54f8aa967f6be41690482b54b24100a2253fa70" -dependencies = [ - "cc", -] - -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - [[package]] name = "slab" version = "0.4.12" @@ -4936,20 +4301,14 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", ] -[[package]] -name = "softaes" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e14297decde697ddf377c25752aead0927d5cfc89c2684d2af96901a4ceeea" - [[package]] name = "spm_precompiled" version = "0.1.4" @@ -4995,15 +4354,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - [[package]] name = "strum" version = "0.27.2" @@ -5022,19 +4372,6 @@ dependencies = [ "strum_macros 0.28.0", ] -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - [[package]] name = "strum_macros" version = "0.27.2" @@ -5065,17 +4402,11 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "symlink" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" - [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -5155,12 +4486,6 @@ dependencies = [ "libc", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" version = "3.27.0" @@ -5170,7 +4495,7 @@ dependencies = [ "fastrand", "getrandom 0.4.3", "once_cell", - "rustix 1.1.4", + "rustix", "windows-sys 0.61.2", ] @@ -5416,9 +4741,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.3" +version = "1.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee" dependencies = [ "bytes", "libc", @@ -5432,9 +4757,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba" dependencies = [ "proc-macro2", "quote", @@ -5480,9 +4805,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c" dependencies = [ "indexmap 2.14.0", "serde_core", @@ -5513,9 +4838,9 @@ dependencies = [ [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tower" @@ -5578,19 +4903,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-appender" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" -dependencies = [ - "crossbeam-channel", - "symlink", - "thiserror 2.0.18", - "time", - "tracing-subscriber", -] - [[package]] name = "tracing-attributes" version = "0.1.31" @@ -5663,200 +4975,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "turso" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832bb70436d4b4d3ed45285c5c6abd62328d5e2486297b32cf2b0812abeba6d4" -dependencies = [ - "mimalloc", - "thiserror 2.0.18", - "tracing", - "tracing-subscriber", - "turso_core", - "turso_sdk_kit", - "turso_sync_sdk_kit", -] - -[[package]] -name = "turso_core" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8ef95330369724a1829b20dc1b728d644eaeb051891971b5d2b5617337a84b" -dependencies = [ - "aegis", - "aes", - "aes-gcm", - "antithesis_sdk", - "arc-swap", - "bigdecimal", - "bitflags", - "branches", - "bumpalo", - "bytemuck", - "cfg_aliases", - "cfg_block", - "chrono", - "crc32c", - "crossbeam-skiplist", - "either", - "fallible-iterator", - "fastbloom", - "hex", - "intrusive-collections", - "io-uring", - "libc", - "libloading", - "libm", - "loom", - "miette", - "num-bigint", - "num-traits", - "pack1", - "parking_lot", - "pastey", - "polling", - "rand 0.9.5", - "rapidhash", - "regex", - "regex-syntax", - "roaring", - "rustc-hash 2.1.3", - "rustix 1.1.4", - "ryu", - "serde_json", - "shuttle", - "simsimd", - "smallvec", - "strum 0.26.3", - "strum_macros 0.26.4", - "tempfile", - "thiserror 2.0.18", - "tracing", - "tracing-subscriber", - "turso_ext", - "turso_macros", - "turso_parser", - "twox-hash", - "uncased", - "uuid", - "windows-sys 0.61.2", -] - -[[package]] -name = "turso_ext" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a47927d766b9ae7e3adf092d5e150dce80533615edc502641797878f190080" -dependencies = [ - "chrono", - "getrandom 0.4.3", - "turso_macros", -] - -[[package]] -name = "turso_macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0cdc6ae079c61aa21a89b595a4d0e19d9d848a2658542252e82f930c57c3d87" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "turso_parser" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b94707e5605411cddbd5a1bd6cc2d6b72181b02223b36b37ba350ed6b71877" -dependencies = [ - "bitflags", - "memchr", - "miette", - "strum 0.26.3", - "strum_macros 0.26.4", - "thiserror 2.0.18", - "turso_macros", -] - -[[package]] -name = "turso_sdk_kit" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a86ce113e5dcedeaad7809d9fa1dc00f837f40ccd8012ac1d2144c57672a34" -dependencies = [ - "bindgen", - "env_logger", - "parking_lot", - "tracing", - "tracing-appender", - "tracing-subscriber", - "turso_core", - "turso_sdk_kit_macros", -] - -[[package]] -name = "turso_sdk_kit_macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca6ee03a3dc5a48a7a63ddd2c8f41aa7bb5195eb96f6a29831447c8cb3d841a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "turso_sync_engine" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c58fe60f17b694f91bd278e93aceca10fb340950f6a8f1aedef11c28b50c4b8" -dependencies = [ - "base64 0.22.1", - "bytes", - "genawaiter", - "http", - "libc", - "prost", - "roaring", - "serde", - "serde_json", - "thiserror 2.0.18", - "tracing", - "turso_core", - "turso_parser", - "uuid", -] - -[[package]] -name = "turso_sync_sdk_kit" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4512c7b28bb3bc09be1ba480ee60234ed9bbeb6686c9348323589ffcec504b93" -dependencies = [ - "bindgen", - "env_logger", - "genawaiter", - "parking_lot", - "tracing", - "tracing-appender", - "tracing-subscriber", - "turso_core", - "turso_sdk_kit", - "turso_sdk_kit_macros", - "turso_sync_engine", -] - -[[package]] -name = "twox-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" -dependencies = [ - "rand 0.9.5", -] - [[package]] name = "typed-path" version = "0.12.3" @@ -5869,15 +4987,6 @@ version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] - [[package]] name = "unicase" version = "2.9.0" @@ -5941,16 +5050,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common 0.1.7", - "subtle", -] - [[package]] name = "untrusted" version = "0.9.0" @@ -5990,13 +5089,12 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.4" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ "getrandom 0.4.3", "js-sys", - "sha1_smol", "wasm-bindgen", ] @@ -6200,21 +5298,9 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - -[[package]] -name = "which" -version = "8.0.4" +version = "8.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d7cd18d4acb58fb3cdfe9ea54e6cd96a4e7d4cc45c56338b236e82dad47248" +checksum = "8f3ef584124b911bcc3875c2f1472e80f24361ceb789bd1c62b3e9a3df9ff43c" dependencies = [ "libc", ] @@ -6487,9 +5573,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "wit-bindgen" @@ -6503,15 +5589,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "x11rb" version = "0.13.2" @@ -6519,7 +5596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "gethostname", - "rustix 1.1.4", + "rustix", "x11rb-protocol", ] @@ -6660,9 +5737,9 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 4c3f9e42..4efe7e68 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,10 +85,6 @@ futures-util = "0.3" # OAuth 2.1 + PKCE authentication oauth2 = { version = "5.0", features = ["reqwest", "rustls-tls"] } -# Credential storage: single cross-platform SQLite store (works headless, no dbus). -# `keyring-core` provides `Entry`; `db-keystore` is the SQLite-backed store. -keyring-core = "1.0" -db-keystore = "0.4" sha2 = "0.11.0" hex = "0.4" serde_urlencoded = "0.7" diff --git a/doc/dev/02-architecture.md b/doc/dev/02-architecture.md index e02c0f3b..26cd99a1 100644 --- a/doc/dev/02-architecture.md +++ b/doc/dev/02-architecture.md @@ -313,7 +313,6 @@ Key external crates: - `clap` -- CLI argument parsing - `serde` / `toml` -- serialization - `oauth2` -- OAuth 2.1 + PKCE -- `keyring` -- secure token storage - `hyper` -- HTTP server - `reedline` -- interactive readline - `syntect` -- syntax highlighting diff --git a/doc/dev/03-mcp-server-development.md b/doc/dev/03-mcp-server-development.md index 0ce7fd13..a5d29de2 100644 --- a/doc/dev/03-mcp-server-development.md +++ b/doc/dev/03-mcp-server-development.md @@ -28,7 +28,7 @@ Three built-in servers are shipped as `[[mcp.servers]]` entries in `config-templ External: | Server | Type | Purpose | |--------|------|---------| -| `filesystem` (octofs) | stdio | `view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, `ast_grep`, `list_files`, `workdir` | +| `filesystem` (octofs) | stdio | `view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, `workdir` | > `filesystem` is **not** declared in `default.toml`'s `[[mcp.servers]]`. It is supplied by a tap and referenced by name in roles' `server_refs` / `allowed_tools`. Only `core`, `runtime`, and `agent` are shipped as built-in server entries. diff --git a/doc/integration/03-daemon-and-hooks.md b/doc/integration/03-daemon-and-hooks.md index 1c3d7bad..fffd59a3 100644 --- a/doc/integration/03-daemon-and-hooks.md +++ b/doc/integration/03-daemon-and-hooks.md @@ -54,7 +54,7 @@ Each running session exposes one per-name IPC endpoint that `octomind send` conn | Platform | Endpoint | Extra | |----------|----------|-------| -| Unix (macOS/Linux) | Unix socket at `~/.local/share/octomind/run/.sock` | PID written to `.pid` | +| Unix (macOS/Linux) | Unix socket at `$XDG_RUNTIME_DIR/octomind/.sock` (fallback: `/octomind-/.sock`) | PID written to `.pid` | | Windows | Named pipe `\\.\pipe\octomind-` | — | These files are created on session start and auto-cleaned when the session exits (a stale socket from a crash is removed on next bind). The injected message is trimmed; an empty message is rejected with `error: empty message`. diff --git a/doc/reference/01-cli-reference.md b/doc/reference/01-cli-reference.md index fa9903de..82551f40 100644 --- a/doc/reference/01-cli-reference.md +++ b/doc/reference/01-cli-reference.md @@ -197,7 +197,7 @@ Inject a message into a running named session. Works against any running session that has started its inject listener (typically a session launched with `--daemon`, but not exclusively). The message reaches the session over a per-OS transport: -- **Unix:** a Unix domain socket at `/.sock` (run dir is `~/.local/share/octomind/run/`). +- **Unix:** a Unix domain socket at `/.sock` (run dir is `$XDG_RUNTIME_DIR/octomind/`, or `/octomind-/` when that variable is unset). - **Windows:** a named pipe `\\.\pipe\octomind-`. The session replies `ok` on successful delivery; any other reply is treated as an error and reported. diff --git a/doc/reference/03-config-reference.md b/doc/reference/03-config-reference.md index f48b5534..5483ab67 100644 --- a/doc/reference/03-config-reference.md +++ b/doc/reference/03-config-reference.md @@ -128,7 +128,7 @@ MCP server definitions. Three types supported: `builtin`, `http`, `stdio`. | `runtime` | `mcp`, `agent`, `skill`, `schedule`, `capability` | Harness reconfiguration and scheduling | | `agent` | `agent_` per `[[agents]]` entry | ACP sub-agent dispatch | -> **`filesystem` is not declared here.** Default roles reference a `filesystem` server in their `server_refs`, but it is **not** a builtin and is **not** defined in this config file's `[[mcp.servers]]`. It is an external `stdio` server backed by `octofs`, provided by the built-in tap. Its tools are `view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, `ast_grep`, `list_files`, and `workdir`. See [MCP Tools](../usage/07-mcp-tools.md) for the full surface. +> **`filesystem` is not declared here.** Default roles reference a `filesystem` server in their `server_refs`, but it is **not** a builtin and is **not** defined in this config file's `[[mcp.servers]]`. It is an external `stdio` server backed by `octofs`, provided by the built-in tap. Its tools are `view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, and `workdir`. See [MCP Tools](../usage/07-mcp-tools.md) for the full surface. #### Common Fields diff --git a/doc/troubleshooting/01-common-issues.md b/doc/troubleshooting/01-common-issues.md index 2fc488ff..517fbd55 100644 --- a/doc/troubleshooting/01-common-issues.md +++ b/doc/troubleshooting/01-common-issues.md @@ -268,8 +268,8 @@ max_session_spending_threshold = 0.0 # Disable the check (<= 0.0 disables) ### Cannot Send to a Running Session `octomind send -n NAME "message"` talks to a session over a Unix domain socket -(`~/.local/share/octomind/run/.sock`; a named pipe `\\.\pipe\octomind-` -on Windows). If you get an error like: +(`$XDG_RUNTIME_DIR/octomind/.sock`, or `/octomind-/.sock` +when that variable is unset; a named pipe `\\.\pipe\octomind-` on Windows). If you get an error like: ``` no running session named 'NAME' (socket not found ...) diff --git a/doc/usage/03-configuration.md b/doc/usage/03-configuration.md index fd76c400..ba754cfe 100644 --- a/doc/usage/03-configuration.md +++ b/doc/usage/03-configuration.md @@ -21,7 +21,7 @@ Full directory structure: sessions/ # Saved sessions logs/ # Debug and error logs cache/ # Cached data - run/ # Per-session Unix sockets and PID files (used by `send` / --daemon) + keystore.json # OAuth tokens for remote MCP servers (mode 0600) learning/ # Cross-session adaptive learning (lessons), scoped by project/role agents/ # Cached tap agent manifests (/.toml) ``` diff --git a/doc/usage/06-roles.md b/doc/usage/06-roles.md index 56c98a4a..1cd329ea 100644 --- a/doc/usage/06-roles.md +++ b/doc/usage/06-roles.md @@ -120,7 +120,7 @@ allowed_tools = [ - `runtime` -- low-level harness control: `mcp` (register servers), `agent` (register dynamic agents), `skill` (load skills), `schedule`, `capability`. Most roles don't need this. - `agent` -- dispatches to `[[agents]]`-defined ACP sub-agents (`agent_` per entry). -> **`filesystem` is not a built-in declared server.** The filesystem tools (`view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, `ast_grep`, `list_files`, `workdir`) come from the **octofs** companion server supplied by the tap/capability layer, not from a `[[mcp.servers]]` entry. If you copy the examples below into a bare standalone config that has no tap/capability providing `filesystem`, the reference is silently dropped and no filesystem tools appear. To see exactly which tools a server exposes, run `/mcp list` (or `/mcp full`) in a session. +> **`filesystem` is not a built-in declared server.** The filesystem tools (`view`, `text_editor`, `batch_edit`, `extract_lines`, `shell`, `workdir`) come from the **octofs** companion server supplied by the tap/capability layer, not from a `[[mcp.servers]]` entry. If you copy the examples below into a bare standalone config that has no tap/capability providing `filesystem`, the reference is silently dropped and no filesystem tools appear. To see exactly which tools a server exposes, run `/mcp list` (or `/mcp full`) in a session. **Pattern syntax:** - `"server:*"` -- all tools from a server (e.g. `agent:*` grants every `agent_` execution tool on the `agent` server) diff --git a/doc/usage/07-mcp-tools.md b/doc/usage/07-mcp-tools.md index 78109039..3df12607 100644 --- a/doc/usage/07-mcp-tools.md +++ b/doc/usage/07-mcp-tools.md @@ -13,7 +13,7 @@ Octomind ships **three builtin MCP servers** declared in the default config (`co | `agent` | builtin | Delegates tasks to configured ACP sub-agents (each `[[agents]]` entry exposes an `agent_` tool) | | `local` | builtin | Project-local shebang-script tools auto-discovered from `/.agents/tools/`. See [Local Tools](17-local-tools.md). | -The filesystem tools (`view`, `text_editor`, `shell`, `ast_grep`, …) are **not** a builtin server. They are served by a separate `octofs` MCP server (a stdio subprocess: command `octofs`, args `["mcp"]`) that is **not declared in the default config**. It is delivered through the built-in default tap [`muvon/tap`](../integration/04-tap-system.md)'s capabilities `filesystem-read` and `filesystem-write`, and roles reach it via `server_refs`/capabilities under the `filesystem` capability name — never a hardcoded `[[mcp.servers]]` block named `filesystem`. See [Filesystem Server Tools (octofs)](#filesystem-server-tools-octofs) below for the prerequisites. +The filesystem tools (`view`, `text_editor`, `shell`, …) are **not** a builtin server. They are served by a separate `octofs` MCP server (a stdio subprocess: command `octofs`, args `["mcp"]`) that is **not declared in the default config**. It is delivered through the built-in default tap [`muvon/tap`](../integration/04-tap-system.md)'s capabilities `filesystem-read` and `filesystem-write`, and roles reach it via `server_refs`/capabilities under the `filesystem` capability name — never a hardcoded `[[mcp.servers]]` block named `filesystem`. See [Filesystem Server Tools (octofs)](#filesystem-server-tools-octofs) below for the prerequisites. `core` and `runtime` are the two split halves of what used to be a single `core` server. The split separates "what the agent uses to do work" (`core`) from "what reconfigures the harness mid-session" (`runtime`). @@ -239,17 +239,6 @@ Read files, view directories, and search file content. - `pattern` (string): Search pattern within file/directory - `content` (string): Content search query -### `list_files` -- List Directory Entries - -List files and directories at a path. Complements `view` (which reads content) when you only need the file listing. - -**Parameters:** -- `path` (string): Directory to list (defaults to the current working directory) - -```json -{"path": "src/"} -``` - ### `text_editor` -- File Editing Comprehensive file manipulation with multiple commands. @@ -342,25 +331,6 @@ Get or set the working directory for file and shell operations. Thread-local: changes only affect the current session. -### `ast_grep` -- AST-Based Code Search - -Search and refactor code using AST patterns with ast-grep (sg). - -**Parameters:** -- `pattern` (string, required): AST pattern using ast-grep syntax -- `language` (string): `"rust"`, `"javascript"`, `"typescript"`, `"python"`, `"go"`, `"java"`, `"c"`, `"cpp"`, `"php"` -- `paths` (array): File paths or glob patterns (default: current directory) -- `rewrite` (string): Rewrite pattern for refactoring -- `json_output` (boolean, default: false): JSON format output -- `context` (integer, default: 0): Context lines around matches -- `update_all` (boolean, default: false): Apply rewrites to all matches - -```json -{"pattern": "console.log($$$)", "language": "javascript"} -{"pattern": "oldFunc($ARGS)", "rewrite": "newFunc($ARGS)", "language": "javascript"} -{"pattern": "class $NAME", "language": "php", "paths": ["src/**/*.php"], "context": 2} -``` - ## Agent Server Tools Each agent configured in `[[agents]]` becomes a separate tool: `agent_`. diff --git a/doc/usage/11-structured-output.md b/doc/usage/11-structured-output.md index 0631f1a6..c746949a 100644 --- a/doc/usage/11-structured-output.md +++ b/doc/usage/11-structured-output.md @@ -2,7 +2,7 @@ Octomind can emit its session activity as machine-readable JSON instead of human-formatted terminal text. This is what you use for automation, CI/CD pipelines, and any program that needs to parse what the agent did. -> **Heads up:** Octomind does **not** currently let you enforce a JSON Schema on the assistant's *answer*. There is no `--schema` CLI flag, and no WebSocket or ACP protocol message accepts a schema. If you came here looking for "make the model reply with exactly this JSON shape," that is not a user-accessible feature today — see [Schema Enforcement](#schema-enforcement-not-user-accessible) below for the full picture. What *is* available is a structured **event stream** (`--format jsonl` and the WebSocket/ACP servers), described next. +> **Heads up:** "structured output" covers two different features here. To make the model's *answer* conform to a JSON Schema, pass `--schema ` to `octomind run` — see [Schema Enforcement](#schema-enforcement---schema) below. Independent of that, the session's *activity* is available as a structured **event stream** (`--format jsonl` and the WebSocket/ACP servers), described next. Note the WebSocket and ACP protocols do not accept a schema — `--schema` exists only on `octomind run`. ## The Automation Surface: `--format jsonl` @@ -50,8 +50,8 @@ Example of a few lines from a `jsonl` run (one object per physical line): ```json {"type":"status","message":"Session created: my-session","session_id":"my-session"} -{"type":"tool_use","tool":"list_files","tool_id":"call_abc","server":"filesystem","params":{"directory":"src"},"session_id":"my-session"} -{"type":"tool_result","tool":"list_files","tool_id":"call_abc","server":"filesystem","content":"src/main.rs\nsrc/lib.rs","success":true,"session_id":"my-session"} +{"type":"tool_use","tool":"view","tool_id":"call_abc","server":"filesystem","params":{"path":"src/"},"session_id":"my-session"} +{"type":"tool_result","tool":"view","tool_id":"call_abc","server":"filesystem","content":"src/main.rs\nsrc/lib.rs","success":true,"session_id":"my-session"} {"type":"assistant","content":"Recent changes refactored the session loop...","session_id":"my-session"} {"type":"cost","session_tokens":1234,"session_cost":0.0025,"input_tokens":1000,"output_tokens":200,"cache_read_tokens":30,"cache_write_tokens":4,"reasoning_tokens":0,"session_id":"my-session"} ``` @@ -74,7 +74,7 @@ Both stream the structured events listed above; neither accepts a schema on sess ## Provider Compatibility (Structured Output Capability) -Whether a provider *can* be asked for native structured output is exposed by each provider's `supports_structured_output(model)`. This capability is currently exercised internally (see [Schema Enforcement](#schema-enforcement-not-user-accessible)), not by a user-facing schema flag. For reference, against the active `octolib 0.21.6`: +Whether a provider *can* be asked for native structured output is exposed by each provider's `supports_structured_output(model)`. This capability gates the `--schema` flag on `octomind run` (see [Schema Enforcement](#schema-enforcement---schema)) and the internal compression decision call. For reference, against the active `octolib 0.21.6`: | Provider | `supports_structured_output` | |----------|------------------------------| @@ -86,23 +86,30 @@ Whether a provider *can* be asked for native structured output is exposed by eac | OpenRouter | Per model's reference capabilities, else Yes | | Anthropic | Trait default — per model's reference capabilities, else No | -When code does request a schema from a provider that returns `false` for the given model, Octomind fails fast: +When a schema is requested from a provider that returns `false` for the given model, Octomind fails fast: ``` Provider 'anthropic' does not support structured output for model ''. Remove the schema parameter or use a compatible provider. ``` -## Schema Enforcement (Not User-Accessible) +## Schema Enforcement (`--schema`) -There **is** a schema mechanism in the codebase, but it is not wired to any user entry point: +Pass a JSON Schema **object** file to `octomind run` to constrain the assistant's replies: -- `ChatSession` has a `schema` field, but it is set to `None` at every construction site and the session-level `with_schema()` builder has no callers. In practice, per-session assistant output is **always** unconstrained — there is no CLI flag, WebSocket message, or ACP method that can populate it. -- The `ProviderResponse.structured_output` field exists in the provider response type, but because no session sets a schema it is always `None` for normal sessions, and there is no display logic that prefers it over `content`. +```bash +echo "List the top 3 TODOs" | octomind run developer:general --format jsonl --schema todos.schema.json +``` + +- The schema applies to **every assistant reply** for the session's lifetime — across multi-turn sessions, resumes, and daemon mode. Tool calls still flow normally underneath; only the final text is constrained. +- The resolved model must support structured output (see the provider table above), or the run fails fast with the error shown there. +- Like `--model`, the schema is a **runtime override** — it is not persisted with the session, so pass it again when resuming. +- The file must contain a JSON Schema object; it is loaded and validated before session init. A ready-to-use example ships at [`config-templates/todos.schema.json`](../../config-templates/todos.schema.json). +- `--schema` exists only on `octomind run` — the WebSocket and ACP session-init messages do not accept a schema. -The one place a schema is genuinely built and used today is **internal**: the conversation-compression decision call. When compression runs, it checks the *decision model's* provider via `supports_structured_output()`; if that returns true, it sends a generated compression schema (`build_compression_schema`) in strict mode to get a reliable decision/summary, otherwise it falls back to an XML-style prompt. This is invisible to your session output and uses the separate compression decision model, not your main model. (Default decision model: `openai:gpt-5-mini` — see [Context Compression](08-compression.md).) +The same mechanism is also used **internally** by the conversation-compression decision call: when compression runs, it checks the *decision model's* provider via `supports_structured_output()`; if true, it sends a generated compression schema in strict mode to get a reliable decision/summary, otherwise it falls back to an XML-style prompt. This is invisible to your session output and uses the separate compression decision model, not your main model. (Default decision model: `openai:gpt-5-mini` — see [Context Compression](08-compression.md).) ## Summary - For machine-readable output, use `--format jsonl` on `octomind run` (or the WebSocket/ACP servers for live streaming). - The JSONL/WebSocket/ACP streams emit typed `ServerMessage` events (`assistant`, `tool_use`, `tool_result`, `cost`, `status`, `error`, `mcp_notification`, `skill`, `injected`, `thinking`). -- There is no user-facing way to enforce a JSON Schema on the assistant's answer. The internal schema mechanism is used only by the compression decision call. +- To enforce a JSON Schema on the assistant's answer, pass `--schema ` to `octomind run` (structured-output-capable models only). The compression decision call uses the same mechanism internally. diff --git a/doc/use-cases/02-event-driven-agent.md b/doc/use-cases/02-event-driven-agent.md index ccb0beb7..32c19302 100644 --- a/doc/use-cases/02-event-driven-agent.md +++ b/doc/use-cases/02-event-driven-agent.md @@ -160,7 +160,7 @@ echo "Summarize what happened in the last hour" | octomind send --name ops-agent ``` `octomind send` connects to the running session over a per-session Unix socket -(`/run/.sock`) or, on Windows, a named pipe (`\\.\pipe\octomind-`). It +(`/.sock`) or, on Windows, a named pipe (`\\.\pipe\octomind-`). It only works **while a daemon/session with that name is live** -- if no such session is running, it fails with `no running session named ''`. The message must be non-empty, and `send` reads back `ok` on success or an error string. (You can pass the message as an diff --git a/doc/use-cases/03-custom-development-workflow.md b/doc/use-cases/03-custom-development-workflow.md index 9482db47..3202c239 100644 --- a/doc/use-cases/03-custom-development-workflow.md +++ b/doc/use-cases/03-custom-development-workflow.md @@ -113,7 +113,7 @@ workflow · dev ╰ ✓ refine 1.4s · $0.0009 · 420 tok · ⚒0 ╭ research -│ ▸ ast_grep · octofs +│ ▸ view · octofs ╰ ✓ research 6.2s · $0.0071 · 2980 tok · ⚒5 ╭ execute diff --git a/doc/use-cases/05-multi-agent-delegation.md b/doc/use-cases/05-multi-agent-delegation.md index 80c65729..26818409 100644 --- a/doc/use-cases/05-multi-agent-delegation.md +++ b/doc/use-cases/05-multi-agent-delegation.md @@ -42,7 +42,7 @@ Use tools to search and read code. Be thorough but focused. [roles.mcp] server_refs = ["filesystem"] -allowed_tools = ["filesystem:view", "filesystem:ast_grep"] +allowed_tools = ["filesystem:view", "filesystem:workdir"] [[roles]] name = "code_reviewer" @@ -66,7 +66,7 @@ server_refs = ["filesystem"] allowed_tools = ["filesystem:view"] ``` -> **Note:** `filesystem` is **not** a built-in server. The default config declares only `core`, `runtime`, and `agent` as MCP servers — the `filesystem` tools (`view`, `text_editor`, `ast_grep`, `shell`, …) are supplied by the default tap (`muvon/tap`). With MCP disabled or that tap not installed, `server_refs = ["filesystem"]` resolves to nothing. See [Tap System](../integration/04-tap-system.md) and [MCP Tools](../usage/07-mcp-tools.md) for how filesystem tools become available. +> **Note:** `filesystem` is **not** a built-in server. The default config declares only `core`, `runtime`, and `agent` as MCP servers — the `filesystem` tools (`view`, `text_editor`, `shell`, …) are supplied by the default tap (`muvon/tap`). With MCP disabled or that tap not installed, `server_refs = ["filesystem"]` resolves to nothing. See [Tap System](../integration/04-tap-system.md) and [MCP Tools](../usage/07-mcp-tools.md) for how filesystem tools become available. ### Step 2: Configure Agents @@ -231,7 +231,7 @@ model = "anthropic:claude-sonnet-4" # Best reasoning # Read-only agent (can't modify files) [roles.mcp] server_refs = ["filesystem"] -allowed_tools = ["filesystem:view", "filesystem:ast_grep"] +allowed_tools = ["filesystem:view", "filesystem:workdir"] # Full-access agent (can edit and run commands) [roles.mcp] diff --git a/src/directories.rs b/src/directories.rs index a515c2e8..7dd7030d 100644 --- a/src/directories.rs +++ b/src/directories.rs @@ -16,7 +16,7 @@ use anyhow::{Context, Result}; use std::fs; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; /// Get the system-wide data directory for octomind /// @@ -82,17 +82,81 @@ pub fn get_sessions_dir() -> Result { } /// Get the run directory path — holds per-session Unix socket and PID files. +/// +/// Runtime state is host-local: Unix sockets can't be bound on NFS and PIDs are +/// meaningless across hosts, so this lives in system runtime/temp storage +/// (wiped on reboot), never in the data dir: +/// - `$XDG_RUNTIME_DIR/octomind` when set (per-user tmpfs, cleaned on logout) +/// - otherwise `/octomind-` (macOS `$TMPDIR` is already +/// per-user; the uid suffix disambiguates a shared `/tmp` on Linux) pub fn get_run_dir() -> Result { - let data_dir = get_octomind_data_dir()?; - let run_dir = data_dir.join("run"); - - if !run_dir.exists() { - fs::create_dir_all(&run_dir)?; + let run_dir = runtime_base_dir(); + ensure_private_dir(&run_dir)?; + + // Run files used to live in the data dir, where nothing wiped them after a + // crash or reboot; clear the legacy location so stale sockets don't linger. + let legacy = get_octomind_data_dir()?.join("run"); + if legacy.exists() { + let _ = fs::remove_dir_all(&legacy); } Ok(run_dir) } +#[cfg(unix)] +fn runtime_base_dir() -> PathBuf { + match std::env::var_os("XDG_RUNTIME_DIR") { + Some(dir) if !dir.is_empty() => PathBuf::from(dir).join("octomind"), + _ => { + let uid = unsafe { libc::getuid() }; + std::env::temp_dir().join(format!("octomind-{uid}")) + } + } +} + +#[cfg(not(unix))] +fn runtime_base_dir() -> PathBuf { + std::env::temp_dir().join("octomind") +} + +/// Create `dir` with mode 0700, or validate a pre-existing one. A dir in shared +/// tmp can be squatted by another user: reject symlinks and foreign owners, and +/// repair permissions that leak to other users. +#[cfg(unix)] +fn ensure_private_dir(dir: &Path) -> Result<()> { + use std::os::unix::fs::{DirBuilderExt, MetadataExt, PermissionsExt}; + + match fs::DirBuilder::new().mode(0o700).create(dir) { + Ok(()) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => { + let meta = fs::symlink_metadata(dir)?; + if !meta.is_dir() { + anyhow::bail!("run dir {} exists but is not a directory", dir.display()); + } + let uid = unsafe { libc::getuid() }; + if meta.uid() != uid { + anyhow::bail!( + "run dir {} is owned by uid {} (expected {}) — refusing to use it", + dir.display(), + meta.uid(), + uid + ); + } + if meta.permissions().mode() & 0o077 != 0 { + fs::set_permissions(dir, fs::Permissions::from_mode(0o700))?; + } + Ok(()) + } + Err(e) => Err(e).context(format!("failed to create run dir {}", dir.display())), + } +} + +#[cfg(not(unix))] +fn ensure_private_dir(dir: &Path) -> Result<()> { + fs::create_dir_all(dir)?; + Ok(()) +} + /// Get the logs directory path pub fn get_logs_dir() -> Result { let data_dir = get_octomind_data_dir()?; @@ -193,6 +257,23 @@ mod tests { assert!(get_cache_dir().is_ok()); } + #[test] + fn test_run_dir_is_private_and_outside_data_dir() { + let run = get_run_dir().unwrap(); + assert!(run.exists()); + assert!(!run.starts_with(get_octomind_data_dir().unwrap())); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mode = fs::metadata(&run).unwrap().permissions().mode(); + assert_eq!( + mode & 0o077, + 0, + "run dir must not be group/world accessible" + ); + } + } + #[test] fn test_config_file_path() { let config_path = get_config_file_path().unwrap(); diff --git a/src/mcp/oauth/token_store.rs b/src/mcp/oauth/token_store.rs index 2dd80980..e2a1a8b7 100644 --- a/src/mcp/oauth/token_store.rs +++ b/src/mcp/oauth/token_store.rs @@ -3,17 +3,19 @@ // Secure OAuth Token Storage // //! OAuth bearer-token storage for remote MCP servers (RFC 9728 discovery → PKCE -//! flow). Backed by a single db-keystore SQLite store via the keyring-core API: -//! cross-platform and works headless (no system keychain / dbus / Secret Service), -//! which is the dominant environment for token *reuse* and *refresh* (ACP under an -//! IDE, websocket server, CI). Tokens are keyed per MCP server name. +//! flow). Tokens live in a single plain JSON file (`/keystore.json`, +//! mode 0600) replaced atomically via temp-file + rename: cross-platform, works +//! headless (no system keychain / dbus / Secret Service), and — unlike SQLite +//! in WAL mode — safe on an NFS-mounted home. Tokens are keyed per MCP server +//! name. Cross-process writes are last-writer-wins: the rename keeps the file +//! always valid, and a lost update at worst forces one extra re-auth. -use anyhow::{anyhow, Result}; -use keyring_core::Entry; +use anyhow::{anyhow, Context, Result}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use std::io::Write; use std::path::{Path, PathBuf}; -use std::sync::OnceLock; +use std::sync::Mutex; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TokenMetadata { @@ -40,103 +42,96 @@ pub enum TokenStoreError { SerializationError(#[from] serde_json::Error), } -const CREDENTIAL_SERVICE: &str = "octomind-oauth"; +/// Serializes in-process read-modify-write cycles on the keystore file. +static FILE_LOCK: Mutex<()> = Mutex::new(()); -// Use server_name as the credential user to support multiple OAuth servers -fn credential_user(server_name: &str) -> String { - format!("oauth-token-{}", server_name) -} - -/// SQLite keystore file: `/octomind/keystore.db`. -fn keystore_path() -> PathBuf { - let mut dir = dirs::data_dir().unwrap_or_else(|| PathBuf::from("~/.local/share")); - dir.push("octomind"); - dir.push("keystore.db"); - dir -} - -/// Register the db-keystore SQLite store as the process-wide credential store, -/// exactly once. A store registered earlier (e.g. by tests) takes precedence and -/// short-circuits this. The registration result is cached, so a failure surfaces -/// on every call rather than being silently retried. -fn ensure_store() -> Result<()> { - // Honor a pre-registered store (tests inject an isolated one). - if keyring_core::get_default_store().is_some() { - return Ok(()); +/// Plain JSON keystore file: `/keystore.json`, map of server name → +/// [`TokenMetadata`], mode 0600. +fn keystore_path() -> Result { + #[cfg(test)] + { + Ok(tests::test_keystore_path()) + } + #[cfg(not(test))] + { + Ok(crate::directories::get_octomind_data_dir()?.join("keystore.json")) } - - static INIT: OnceLock> = OnceLock::new(); - INIT.get_or_init(|| { - let path = keystore_path(); - let path_str = path.to_string_lossy().into_owned(); - let modifiers = HashMap::from([("path", path_str.as_str())]); - let store = db_keystore::DbKeyStore::new_with_modifiers(&modifiers) - .map_err(|e| format!("failed to open keystore at {}: {e}", path.display()))?; - keyring_core::set_default_store(store); - // Restrict the keystore directory so other users can't read the db file. - harden_dir(path.parent()); - Ok(()) - }) - .clone() - .map_err(|e| anyhow!(e)) } -#[cfg(unix)] -fn harden_dir(dir: Option<&Path>) { - use std::os::unix::fs::PermissionsExt; - if let Some(dir) = dir { - let _ = std::fs::set_permissions(dir, std::fs::Permissions::from_mode(0o700)); +fn read_all(path: &Path) -> Result, TokenStoreError> { + match std::fs::read_to_string(path) { + // A corrupt file surfaces as SerializationError — it must not silently + // degrade into an endless re-auth loop. + Ok(json) => Ok(serde_json::from_str(&json)?), + // No file yet — not an error, just no tokens stored. + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(HashMap::new()), + Err(e) => Err(TokenStoreError::CredentialStoreError(anyhow!( + "failed to read keystore {}: {e}", + path.display() + ))), } } -#[cfg(not(unix))] -fn harden_dir(_dir: Option<&Path>) {} -/// Build a credential entry for a server, ensuring the store is registered. -fn entry(server_name: &str) -> Result { - ensure_store()?; - Entry::new(CREDENTIAL_SERVICE, &credential_user(server_name)) - .map_err(|e| anyhow!("keyring entry error: {e}")) +/// Atomically replace the keystore: write a private (0600) temp file in the +/// same directory, then rename over the target. Rename is atomic on POSIX and +/// on NFS, so readers never observe a partial file. +fn write_all(path: &Path, tokens: &HashMap) -> Result<()> { + let json = serde_json::to_string_pretty(tokens)?; + let dir = path.parent().context("keystore path has no parent")?; + std::fs::create_dir_all(dir)?; + let tmp = dir.join(format!(".keystore.{}.tmp", std::process::id())); + + let mut opts = std::fs::OpenOptions::new(); + opts.write(true).create_new(true); + #[cfg(unix)] + { + use std::os::unix::fs::OpenOptionsExt; + opts.mode(0o600); + } + // create_new never follows a pre-existing symlink; a leftover temp file + // from a crashed process is removed first. + let _ = std::fs::remove_file(&tmp); + let mut file = opts + .open(&tmp) + .with_context(|| format!("failed to create {}", tmp.display()))?; + file.write_all(json.as_bytes())?; + file.sync_all()?; + drop(file); + std::fs::rename(&tmp, path) + .with_context(|| format!("failed to replace keystore {}", path.display()))?; + Ok(()) } pub async fn save_token(server_name: &str, metadata: &TokenMetadata) -> Result<()> { - let json = serde_json::to_string(metadata).map_err(TokenStoreError::SerializationError)?; crate::log_debug!( "🔍 SAVE_TOKEN: server_name='{}', token_prefix='{}...'", server_name, metadata.access_token.chars().take(10).collect::() ); - entry(server_name)? - .set_password(&json) - .map_err(|e| anyhow!("failed to save token: {e}"))?; + let path = keystore_path()?; + let _guard = FILE_LOCK.lock().unwrap(); + let mut tokens = read_all(&path)?; + tokens.insert(server_name.to_string(), metadata.clone()); + write_all(&path, &tokens)?; crate::log_debug!("✅ SAVE_TOKEN: stored token for server '{}'", server_name); Ok(()) } pub async fn load_token(server_name: &str) -> TokenResult { - crate::log_debug!( - "🔍 LOAD_TOKEN: server_name='{}', credential_user='{}'", - server_name, - credential_user(server_name) - ); - match entry(server_name)?.get_password() { - Ok(json) => { - let metadata: TokenMetadata = serde_json::from_str(&json)?; + let path = keystore_path().map_err(TokenStoreError::CredentialStoreError)?; + match read_all(&path)?.get(server_name).cloned() { + Some(metadata) => { crate::log_debug!( - "✅ LOAD_TOKEN: loaded token, token_prefix='{}...'", + "✅ LOAD_TOKEN: loaded token for '{}', token_prefix='{}...'", + server_name, metadata.access_token.chars().take(10).collect::() ); Ok(Some(metadata)) } - // No stored credential for this server — not an error, just unauthenticated. - Err(keyring_core::Error::NoEntry) => { + None => { crate::log_debug!("LOAD_TOKEN: no token stored for server '{}'", server_name); Ok(None) } - // A genuine store failure (corruption, no access) must surface, not silently - // degrade into an endless re-auth loop. - Err(e) => Err(TokenStoreError::CredentialStoreError(anyhow!( - "failed to load token for '{server_name}': {e}" - ))), } } @@ -153,9 +148,11 @@ pub async fn clear_token( } } - match entry(server_name)?.delete_credential() { - Ok(()) | Err(keyring_core::Error::NoEntry) => {} - Err(e) => crate::log_debug!("clear_token: delete failed for '{}': {}", server_name, e), + let path = keystore_path()?; + let _guard = FILE_LOCK.lock().unwrap(); + let mut tokens = read_all(&path)?; + if tokens.remove(server_name).is_some() { + write_all(&path, &tokens)?; } tracing::debug!("Cleared OAuth token for server: {}", server_name); @@ -243,26 +240,16 @@ async fn revoke_token( #[cfg(test)] mod tests { use super::*; - use std::sync::Once; - // Register an isolated temp-file keystore as the process-wide store, once. - // File-backed (not :memory:) so it survives across separate store operations. - static TEST_STORE: Once = Once::new(); - fn init_test_store() { - TEST_STORE.call_once(|| { - let path = std::env::temp_dir() - .join(format!("octomind-keystore-test-{}", std::process::id())) - .join("keystore.db"); - let path_str = path.to_string_lossy().into_owned(); - let modifiers = HashMap::from([("path", path_str.as_str())]); - let store = db_keystore::DbKeyStore::new_with_modifiers(&modifiers).unwrap(); - keyring_core::set_default_store(store); - }); + // Isolated per-process keystore file so tests never touch the real one. + pub(super) fn test_keystore_path() -> PathBuf { + std::env::temp_dir() + .join(format!("octomind-keystore-test-{}", std::process::id())) + .join("keystore.json") } #[tokio::test] async fn save_load_clear_roundtrip() { - init_test_store(); let server = "test-roundtrip"; let meta = TokenMetadata { server_name: server.to_string(), @@ -281,7 +268,6 @@ mod tests { #[tokio::test] async fn load_missing_is_none() { - init_test_store(); assert_eq!(load_token("never-saved-server").await.unwrap(), None); } } diff --git a/src/session/inject_listener.rs b/src/session/inject_listener.rs index 35f9b567..22c57154 100644 --- a/src/session/inject_listener.rs +++ b/src/session/inject_listener.rs @@ -14,8 +14,9 @@ //! Unix Domain Socket listener for external message injection. //! -//! Each running session binds a UDS at `~/.local/share/octomind/run/.sock` -//! and writes its PID to `~/.local/share/octomind/run/.pid`. +//! Each running session binds a UDS at `/.sock` and writes its +//! PID to `/.pid`, where the run dir is `$XDG_RUNTIME_DIR/octomind` +//! or `/octomind-` (see `directories::get_run_dir`). //! //! The `octomind send` command connects to this socket, sends a UTF-8 message, //! shuts down the write half, and reads back `"ok\n"` or `"error: ...\n"`.