12 Commits

Author SHA1 Message Date
github-actions[bot] 040dad05d2 chore: bump Cargo.toml to 0.7.3
CI / All (ubuntu-latest) (push) Failing after 24s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-24 18:20:20 +00:00
github-actions[bot] 1ba38860f2 bump: version 0.7.2 → 0.7.3 [skip ci] 2026-06-24 18:20:16 +00:00
Dark-Alex-17 84ec5fe7b8 fix: apply bootstrapping of functions at startup to fix edge case
CI / All (ubuntu-latest) (push) Failing after 24s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-24 12:13:55 -06:00
github-actions[bot] 1684788fe6 bump: version 0.7.1 → 0.7.2 [skip ci] 2026-06-19 18:51:49 +00:00
Dark-Alex-17 4b7e242998 fix: usql version upgrade
CI / All (ubuntu-latest) (push) Failing after 24s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-19 12:45:41 -06:00
github-actions[bot] f69aba2dd8 chore: bump Cargo.toml to 0.7.1
CI / All (ubuntu-latest) (push) Failing after 25s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-19 18:04:58 +00:00
github-actions[bot] c3487ecd0e bump: version 0.7.0 → 0.7.1 [skip ci] 2026-06-19 18:04:56 +00:00
Dark-Alex-17 db75391fb6 Merge branch 'main' of github.com:Dark-Alex-17/coyote
CI / All (ubuntu-latest) (push) Failing after 24s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-19 11:44:28 -06:00
Dark-Alex-17 e3815af69b fix: sbx mixins must be passed in directories, not as files and the files must be named spec.yaml per new sbx version
CI / All (ubuntu-latest) (push) Failing after 25s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-19 11:44:16 -06:00
github-actions[bot] 66a485f924 chore: bump Cargo.toml to 0.7.0 2026-06-18 22:40:24 +00:00
github-actions[bot] 49d7204f89 bump: version 0.6.0 → 0.7.0 [skip ci] 2026-06-18 22:40:19 +00:00
Dark-Alex-17 bbcae1fc2b feat: added configurable cache path via the COYOTE_CACHE_PATH environment variable
CI / All (ubuntu-latest) (push) Failing after 24s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled
2026-06-18 16:30:24 -06:00
9 changed files with 421 additions and 84 deletions
+19
View File
@@ -1,7 +1,26 @@
## v0.7.3 (2026-06-24)
### Fix
- apply bootstrapping of functions at startup to fix edge case
## v0.7.2 (2026-06-19)
### Fix
- usql version upgrade
## v0.7.1 (2026-06-19)
### Fix
- sbx mixins must be passed in directories, not as files and the files must be named spec.yaml per new sbx version
## v0.7.0 (2026-06-18) ## v0.7.0 (2026-06-18)
### Feat ### Feat
- added configurable cache path via the COYOTE_CACHE_PATH environment variable
- added a memory option to .set tab completions - added a memory option to .set tab completions
- Added a diagnostic .info tools subcommand to make it easier to see what tools are enabled in all contexts - Added a diagnostic .info tools subcommand to make it easier to see what tools are enabled in all contexts
- Added additional info outputs for enabled skills and sbx directories - Added additional info outputs for enabled skills and sbx directories
Generated
+104 -65
View File
@@ -566,7 +566,7 @@ dependencies = [
"hyper-util", "hyper-util",
"pin-project-lite", "pin-project-lite",
"rustls 0.21.12", "rustls 0.21.12",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-native-certs", "rustls-native-certs",
"rustls-pki-types", "rustls-pki-types",
"tokio", "tokio",
@@ -893,7 +893,7 @@ version = "0.72.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"cexpr", "cexpr",
"clang-sys", "clang-sys",
"itertools 0.13.0", "itertools 0.13.0",
@@ -922,6 +922,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.13.0" version = "2.13.0"
@@ -1060,9 +1066,9 @@ checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.64" version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -1104,9 +1110,9 @@ dependencies = [
[[package]] [[package]]
name = "chacha20" name = "chacha20"
version = "0.10.0" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures 0.3.0", "cpufeatures 0.3.0",
@@ -1402,7 +1408,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "coyote-ai" name = "coyote-ai"
version = "0.7.0" version = "0.7.3"
dependencies = [ dependencies = [
"ansi_colours", "ansi_colours",
"anyhow", "anyhow",
@@ -1414,7 +1420,7 @@ dependencies = [
"aws-smithy-types", "aws-smithy-types",
"base64", "base64",
"bincode 2.0.1", "bincode 2.0.1",
"bitflags", "bitflags 2.13.0",
"bm25", "bm25",
"bytes", "bytes",
"chrono", "chrono",
@@ -1556,7 +1562,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"crossterm_winapi", "crossterm_winapi",
"derive_more 2.1.1", "derive_more 2.1.1",
"document-features", "document-features",
@@ -1727,6 +1733,38 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "defmt"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f"
dependencies = [
"bitflags 1.3.2",
"defmt-macros",
]
[[package]]
name = "defmt-macros"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b"
dependencies = [
"defmt-parser",
"proc-macro-error2",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "defmt-parser"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
dependencies = [
"thiserror 2.0.18",
]
[[package]] [[package]]
name = "der" name = "der"
version = "0.7.10" version = "0.7.10"
@@ -1872,7 +1910,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
] ]
@@ -2814,7 +2852,7 @@ dependencies = [
"http 1.4.2", "http 1.4.2",
"hyper 1.10.1", "hyper 1.10.1",
"hyper-util", "hyper-util",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-native-certs", "rustls-native-certs",
"tokio", "tokio",
"tokio-rustls 0.26.4", "tokio-rustls 0.26.4",
@@ -3066,7 +3104,7 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6654738b8024300cf062d04a1c13c10c8e2cea598ec1c47dc9b6641159429756" checksum = "6654738b8024300cf062d04a1c13c10c8e2cea598ec1c47dc9b6641159429756"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"crossterm", "crossterm",
"dyn-clone", "dyn-clone",
"fuzzy-matcher", "fuzzy-matcher",
@@ -3151,10 +3189,11 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]] [[package]]
name = "jiff" name = "jiff"
version = "0.2.28" version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46"
dependencies = [ dependencies = [
"defmt",
"jiff-static", "jiff-static",
"log", "log",
"portable-atomic", "portable-atomic",
@@ -3164,9 +3203,9 @@ dependencies = [
[[package]] [[package]]
name = "jiff-static" name = "jiff-static"
version = "0.2.28" version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3342,9 +3381,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.32" version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
dependencies = [ dependencies = [
"serde_core", "serde_core",
] ]
@@ -3518,7 +3557,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ecce9d566cb9234ae3db9e249c8b55665feaaf32b0859ff1e27e310d2beb3d8" checksum = "4ecce9d566cb9234ae3db9e249c8b55665feaaf32b0859ff1e27e310d2beb3d8"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"combine", "combine",
"libc", "libc",
"mach2", "mach2",
@@ -3570,7 +3609,7 @@ version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"cfg-if", "cfg-if",
"cfg_aliases", "cfg_aliases",
"libc", "libc",
@@ -3582,7 +3621,7 @@ version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"cfg-if", "cfg-if",
"cfg_aliases", "cfg_aliases",
"libc", "libc",
@@ -3684,7 +3723,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
"objc2-core-graphics", "objc2-core-graphics",
"objc2-foundation", "objc2-foundation",
@@ -3696,7 +3735,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
"objc2-foundation", "objc2-foundation",
] ]
@@ -3717,7 +3756,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"dispatch2", "dispatch2",
"objc2", "objc2",
] ]
@@ -3728,7 +3767,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"dispatch2", "dispatch2",
"objc2", "objc2",
"objc2-core-foundation", "objc2-core-foundation",
@@ -3761,7 +3800,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-core-graphics", "objc2-core-graphics",
@@ -3779,7 +3818,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"block2", "block2",
"libc", "libc",
"objc2", "objc2",
@@ -3802,7 +3841,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
"objc2-core-foundation", "objc2-core-foundation",
] ]
@@ -3813,7 +3852,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"objc2", "objc2",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
@@ -3825,7 +3864,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"block2", "block2",
"objc2", "objc2",
"objc2-cloud-kit", "objc2-cloud-kit",
@@ -3877,7 +3916,7 @@ version = "6.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2" checksum = "0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"libc", "libc",
"once_cell", "once_cell",
"onig_sys", "onig_sys",
@@ -3916,7 +3955,7 @@ version = "0.10.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"cfg-if", "cfg-if",
"foreign-types", "foreign-types",
"libc", "libc",
@@ -4392,9 +4431,9 @@ dependencies = [
[[package]] [[package]]
name = "quinn" name = "quinn"
version = "0.11.9" version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
dependencies = [ dependencies = [
"bytes", "bytes",
"cfg_aliases", "cfg_aliases",
@@ -4402,7 +4441,7 @@ dependencies = [
"quinn-proto", "quinn-proto",
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash",
"rustls 0.23.40", "rustls 0.23.41",
"socket2 0.6.4", "socket2 0.6.4",
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
@@ -4412,9 +4451,9 @@ dependencies = [
[[package]] [[package]]
name = "quinn-proto" name = "quinn-proto"
version = "0.11.14" version = "0.11.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e"
dependencies = [ dependencies = [
"aws-lc-rs", "aws-lc-rs",
"bytes", "bytes",
@@ -4423,7 +4462,7 @@ dependencies = [
"rand 0.9.4", "rand 0.9.4",
"ring", "ring",
"rustc-hash", "rustc-hash",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-pki-types", "rustls-pki-types",
"slab", "slab",
"thiserror 2.0.18", "thiserror 2.0.18",
@@ -4448,9 +4487,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.45" version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@@ -4492,7 +4531,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
dependencies = [ dependencies = [
"chacha20 0.10.0", "chacha20 0.10.1",
"getrandom 0.4.3", "getrandom 0.4.3",
"rand_core 0.10.1", "rand_core 0.10.1",
] ]
@@ -4557,7 +4596,7 @@ version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
] ]
[[package]] [[package]]
@@ -4669,7 +4708,7 @@ dependencies = [
"native-tls", "native-tls",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-native-certs", "rustls-native-certs",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
@@ -4716,7 +4755,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"quinn", "quinn",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-pki-types", "rustls-pki-types",
"rustls-platform-verifier", "rustls-platform-verifier",
"serde", "serde",
@@ -4762,9 +4801,9 @@ dependencies = [
[[package]] [[package]]
name = "rmcp" name = "rmcp"
version = "1.7.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0810a9f717d9828f475fe1f629f4c305c8464b7f496c3a854b58d29e65f4058e" checksum = "1d1f571c72940a19d9532fe52dbea8bc9912bf1d766c2970bb824056b86f3f59"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64", "base64",
@@ -4789,9 +4828,9 @@ dependencies = [
[[package]] [[package]]
name = "rmcp-macros" name = "rmcp-macros"
version = "1.7.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aefac48c364756e97f04c0401ba3231e8607882c7c1d92da0437dc16307904d" checksum = "1aad0035b69380782d78ea95b508327e6deaa2235909053e596eea8f27b5e1d5"
dependencies = [ dependencies = [
"darling 0.23.0", "darling 0.23.0",
"proc-macro2", "proc-macro2",
@@ -4898,7 +4937,7 @@ version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
@@ -4919,9 +4958,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.23.40" version = "0.23.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f"
dependencies = [ dependencies = [
"aws-lc-rs", "aws-lc-rs",
"log", "log",
@@ -4966,7 +5005,7 @@ dependencies = [
"jni", "jni",
"log", "log",
"once_cell", "once_cell",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-native-certs", "rustls-native-certs",
"rustls-platform-verifier-android", "rustls-platform-verifier-android",
"rustls-webpki 0.103.13", "rustls-webpki 0.103.13",
@@ -5129,7 +5168,7 @@ version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"core-foundation", "core-foundation",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
@@ -5152,7 +5191,7 @@ version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"cssparser", "cssparser",
"derive_more 0.99.20", "derive_more 0.99.20",
"fxhash", "fxhash",
@@ -5759,7 +5798,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc" checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"byteorder", "byteorder",
"enum-as-inner", "enum-as-inner",
"libc", "libc",
@@ -6042,7 +6081,7 @@ version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [ dependencies = [
"rustls 0.23.40", "rustls 0.23.41",
"tokio", "tokio",
] ]
@@ -6165,7 +6204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
dependencies = [ dependencies = [
"async-compression", "async-compression",
"bitflags", "bitflags 2.13.0",
"bytes", "bytes",
"futures-core", "futures-core",
"futures-util", "futures-util",
@@ -6438,7 +6477,7 @@ dependencies = [
"flate2", "flate2",
"log", "log",
"percent-encoding", "percent-encoding",
"rustls 0.23.40", "rustls 0.23.41",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
"serde_json", "serde_json",
@@ -6704,7 +6743,7 @@ version = "0.31.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"rustix", "rustix",
"wayland-backend", "wayland-backend",
"wayland-scanner", "wayland-scanner",
@@ -6712,11 +6751,11 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols" name = "wayland-protocols"
version = "0.32.12" version = "0.32.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"wayland-backend", "wayland-backend",
"wayland-client", "wayland-client",
"wayland-scanner", "wayland-scanner",
@@ -6728,7 +6767,7 @@ version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.13.0",
"wayland-backend", "wayland-backend",
"wayland-client", "wayland-client",
"wayland-protocols", "wayland-protocols",
@@ -7411,9 +7450,9 @@ dependencies = [
[[package]] [[package]]
name = "zlib-rs" name = "zlib-rs"
version = "0.6.3" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" checksum = "977347db8caa080403f6b6b7c1cda9479a8e869316f7e13a59b19076a40f94e3"
[[package]] [[package]]
name = "zmij" name = "zmij"
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "coyote-ai" name = "coyote-ai"
version = "0.7.0" version = "0.7.3"
edition = "2024" edition = "2024"
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"] authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
description = "An all-in-one, batteries included LLM CLI Tool" description = "An all-in-one, batteries included LLM CLI Tool"
+6 -5
View File
@@ -257,17 +257,18 @@ commands:
description: Install uv (required for Python-based custom tools) description: Install uv (required for Python-based custom tools)
- command: | - command: |
set -euo pipefail set -euo pipefail
USQL_VERSION="0.19.20" USQL_VERSION=$(curl -sSL https://api.github.com/repos/xo/usql/releases/latest | jq -r .tag_name | sed 's/^v//')
ARCH=$(uname -m) ARCH=$(uname -m)
case "$ARCH" in case "$ARCH" in
x86_64) USQL_ARCH=amd64 ;; x86_64) USQL_ARCH=amd64 ;;
aarch64) USQL_ARCH=arm64 ;; aarch64) USQL_ARCH=arm64 ;;
*) echo "Unsupported arch for usql install: $ARCH" >&2; exit 1 ;; *) echo "Unsupported arch for usql install: $ARCH" >&2; exit 1 ;;
esac esac
curl -sSL "https://github.com/xo/usql/releases/download/v${USQL_VERSION}/usql_static-${USQL_VERSION}-linux-${USQL_ARCH}.tar.bz2" -o /tmp/usql.tar.bz2 TMPDIR=$(mktemp -d)
sudo tar -xjf /tmp/usql.tar.bz2 -C /usr/local/bin trap 'rm -rf "$TMPDIR"' EXIT
sudo chmod +x /usr/local/bin/usql curl -sSL "https://github.com/xo/usql/releases/download/v${USQL_VERSION}/usql_static-${USQL_VERSION}-linux-${USQL_ARCH}.tar.bz2" -o "$TMPDIR/usql.tar.bz2"
rm -f /tmp/usql.tar.bz2 tar -xjf "$TMPDIR/usql.tar.bz2" -C "$TMPDIR"
sudo install -m 0755 "$TMPDIR/usql_static" /usr/local/bin/usql
user: "1000" user: "1000"
description: Install the usql universal SQL CLI (used by the built-in sql agent and execute_sql_code tool) description: Install the usql universal SQL CLI (used by the built-in sql agent and execute_sql_code tool)
- command: | - command: |
+1
View File
@@ -147,6 +147,7 @@ const SBX_KIT_DIR_NAME: &str = "sbx-kit";
const SBX_KIT_HASH_FILE: &str = "kit.sha256"; const SBX_KIT_HASH_FILE: &str = "kit.sha256";
const SBX_MIXIN_FILE_NAME: &str = "sbx-mixin.yaml"; const SBX_MIXIN_FILE_NAME: &str = "sbx-mixin.yaml";
const SBX_VAULT_MIXINS_DIR_NAME: &str = "sbx-vault-mixins"; const SBX_VAULT_MIXINS_DIR_NAME: &str = "sbx-vault-mixins";
const SBX_MIXIN_KITS_DIR_NAME: &str = "sbx-mixin-kits";
const GIT_DIR_NAME: &str = ".git"; const GIT_DIR_NAME: &str = ".git";
const GITIGNORE_FILE_NAME: &str = ".gitignore"; const GITIGNORE_FILE_NAME: &str = ".gitignore";
const DEFAULT_VISIBLE_TOOLS: [&str; 18] = [ const DEFAULT_VISIBLE_TOOLS: [&str; 18] = [
+14 -4
View File
@@ -4,8 +4,8 @@ use super::{
ENV_FILE_NAME, FUNCTIONS_BIN_DIR_NAME, FUNCTIONS_DIR_NAME, GLOBAL_TOOLS_DIR_NAME, ENV_FILE_NAME, FUNCTIONS_BIN_DIR_NAME, FUNCTIONS_DIR_NAME, GLOBAL_TOOLS_DIR_NAME,
GLOBAL_TOOLS_UTILS_DIR_NAME, MACROS_DIR_NAME, MCP_FILE_NAME, MEMORY_DIR_NAME, GLOBAL_TOOLS_UTILS_DIR_NAME, MACROS_DIR_NAME, MCP_FILE_NAME, MEMORY_DIR_NAME,
MEMORY_INDEX_FILE_NAME, ModelsOverride, RAGS_DIR_NAME, ROLES_DIR_NAME, SBX_KIT_DIR_NAME, MEMORY_INDEX_FILE_NAME, ModelsOverride, RAGS_DIR_NAME, ROLES_DIR_NAME, SBX_KIT_DIR_NAME,
SBX_KIT_HASH_FILE, SBX_MIXIN_FILE_NAME, SBX_VAULT_MIXINS_DIR_NAME, SKILLS_DIR_NAME, SBX_KIT_HASH_FILE, SBX_MIXIN_FILE_NAME, SBX_MIXIN_KITS_DIR_NAME, SBX_VAULT_MIXINS_DIR_NAME,
WORKSPACE_MEMORY_DIR_NAME, SKILLS_DIR_NAME, WORKSPACE_MEMORY_DIR_NAME,
}; };
use crate::client::ProviderModels; use crate::client::ProviderModels;
use crate::utils::{get_env_name, list_file_names, normalize_env_name}; use crate::utils::{get_env_name, list_file_names, normalize_env_name};
@@ -33,8 +33,14 @@ pub fn local_path(name: &str) -> PathBuf {
} }
pub fn cache_path() -> PathBuf { pub fn cache_path() -> PathBuf {
let base_dir = dirs::cache_dir().unwrap_or_else(env::temp_dir); if let Ok(v) = env::var(get_env_name("cache_dir")) {
base_dir.join(env!("CARGO_CRATE_NAME")) PathBuf::from(v)
} else if let Ok(v) = env::var("XDG_CACHE_HOME") {
PathBuf::from(v).join(env!("CARGO_CRATE_NAME"))
} else {
let base_dir = dirs::cache_dir().unwrap_or_else(env::temp_dir);
base_dir.join(env!("CARGO_CRATE_NAME"))
}
} }
pub fn sandbox_kit_override() -> Option<PathBuf> { pub fn sandbox_kit_override() -> Option<PathBuf> {
@@ -148,6 +154,10 @@ pub fn sbx_vault_mixins_hash_file() -> PathBuf {
sbx_vault_mixins_dir().join(SBX_KIT_HASH_FILE) sbx_vault_mixins_dir().join(SBX_KIT_HASH_FILE)
} }
pub fn sbx_mixin_kits_dir() -> PathBuf {
cache_path().join(SBX_MIXIN_KITS_DIR_NAME)
}
pub fn config_file() -> PathBuf { pub fn config_file() -> PathBuf {
match env::var(get_env_name("config_file")) { match env::var(get_env_name("config_file")) {
Ok(value) => PathBuf::from(value), Ok(value) => PathBuf::from(value),
+4 -1
View File
@@ -137,7 +137,10 @@ async fn main() -> Result<()> {
) )
.await?, .await?,
); );
let ctx = RequestContext::bootstrap(app_state, working_mode, info_flag)?; let mut ctx = RequestContext::bootstrap(app_state, working_mode, info_flag)?;
let app_config = Arc::clone(&ctx.app.config);
ctx.bootstrap_tools(&app_config, start_mcp_servers, abort_signal.clone())
.await?;
{ {
let app = &*ctx.app.config; let app = &*ctx.app.config;
+205
View File
@@ -1,13 +1,16 @@
use std::env; use std::env;
use std::fs;
use std::fs::{read_dir, read_to_string}; use std::fs::{read_dir, read_to_string};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use serde_yaml::Value; use serde_yaml::Value;
use sha2::{Digest, Sha256};
use crate::config::paths; use crate::config::paths;
const SBX_MIXIN_FILE_NAME: &str = "sbx-mixin.yaml"; const SBX_MIXIN_FILE_NAME: &str = "sbx-mixin.yaml";
const KIT_SPEC_FILE_NAME: &str = "spec.yaml";
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DiscoveredMixin { pub struct DiscoveredMixin {
@@ -17,6 +20,46 @@ pub struct DiscoveredMixin {
pub domain_count: usize, pub domain_count: usize,
} }
impl DiscoveredMixin {
pub fn kit_path(&self) -> Result<PathBuf> {
if self.path.is_dir() {
return Ok(self.path.clone());
}
wrap_mixin_as_kit(&self.path)
}
}
pub fn wrap_mixin_as_kit(mixin_path: &Path) -> Result<PathBuf> {
let bytes = fs::read(mixin_path)
.with_context(|| format!("Failed to read sbx mixin {}", mixin_path.display()))?;
let mut hasher = Sha256::new();
hasher.update(&bytes);
let hash = format!("{:x}", hasher.finalize());
let kit_dir = paths::sbx_mixin_kits_dir().join(&hash);
let spec_path = kit_dir.join(KIT_SPEC_FILE_NAME);
if let Ok(existing) = fs::read(&spec_path)
&& existing == bytes
{
return Ok(kit_dir);
}
fs::create_dir_all(&kit_dir)
.with_context(|| format!("Failed to create mixin kit dir {}", kit_dir.display()))?;
fs::write(&spec_path, &bytes)
.with_context(|| format!("Failed to write {}", spec_path.display()))?;
debug!(
"Wrapped mixin {} as kit at {}",
mixin_path.display(),
kit_dir.display()
);
Ok(kit_dir)
}
pub fn discover() -> Result<Vec<DiscoveredMixin>> { pub fn discover() -> Result<Vec<DiscoveredMixin>> {
let mut out = Vec::new(); let mut out = Vec::new();
@@ -234,4 +277,166 @@ network:
let found = collect_subdir_mixins(&absent); let found = collect_subdir_mixins(&absent);
assert!(found.is_empty()); assert!(found.is_empty());
} }
mod wrap_as_kit {
use super::*;
use serial_test::serial;
use std::ffi::OsString;
struct TestCacheDirGuard {
key: String,
previous: Option<OsString>,
path: PathBuf,
}
impl TestCacheDirGuard {
fn new() -> Self {
let key = crate::utils::get_env_name("cache_dir");
let previous = env::var_os(&key);
let nanos = time::SystemTime::now()
.duration_since(time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let path = env::temp_dir().join(format!("coyote-mixin-wrap-cache-{nanos}"));
fs::create_dir_all(&path).unwrap();
unsafe {
env::set_var(&key, &path);
}
Self {
key,
previous,
path,
}
}
}
impl Drop for TestCacheDirGuard {
fn drop(&mut self) {
unsafe {
match &self.previous {
Some(v) => env::set_var(&self.key, v),
None => env::remove_var(&self.key),
}
}
let _ = fs::remove_dir_all(&self.path);
}
}
fn write_mixin(name: &str, content: &str) -> PathBuf {
let root = unique_root(&format!("wrap-src-{name}"));
let path = root.join("sbx-mixin.yaml");
fs::write(&path, content).unwrap();
path
}
#[test]
#[serial]
fn wrap_mixin_as_kit_creates_spec_yaml_with_original_content() {
let _guard = TestCacheDirGuard::new();
let content = "schemaVersion: \"1\"\nkind: mixin\nname: probe\n";
let mixin = write_mixin("content", content);
let kit_dir = wrap_mixin_as_kit(&mixin).unwrap();
let spec = kit_dir.join("spec.yaml");
assert!(spec.exists(), "spec.yaml must exist in wrapped kit dir");
assert_eq!(fs::read_to_string(&spec).unwrap(), content);
}
#[test]
#[serial]
fn wrap_mixin_as_kit_is_deterministic_for_identical_content() {
let _guard = TestCacheDirGuard::new();
let content = "schemaVersion: \"1\"\nkind: mixin\nname: probe\n";
let mixin_one = write_mixin("dedup-1", content);
let mixin_two = write_mixin("dedup-2", content);
let kit_a = wrap_mixin_as_kit(&mixin_one).unwrap();
let kit_b = wrap_mixin_as_kit(&mixin_two).unwrap();
assert_eq!(
kit_a, kit_b,
"same content should share the same content-addressed kit dir"
);
}
#[test]
#[serial]
fn wrap_mixin_as_kit_different_content_yields_different_dirs() {
let _guard = TestCacheDirGuard::new();
let mixin_a = write_mixin("diff-a", "kind: mixin\nname: a\n");
let mixin_b = write_mixin("diff-b", "kind: mixin\nname: b\n");
let kit_a = wrap_mixin_as_kit(&mixin_a).unwrap();
let kit_b = wrap_mixin_as_kit(&mixin_b).unwrap();
assert_ne!(
kit_a, kit_b,
"different content must hash to different kit dirs"
);
}
#[test]
#[serial]
fn wrap_mixin_as_kit_is_idempotent_on_cache_hit() {
let _guard = TestCacheDirGuard::new();
let mixin = write_mixin("idempotent", "kind: mixin\nname: probe\n");
let kit_first = wrap_mixin_as_kit(&mixin).unwrap();
let spec = kit_first.join("spec.yaml");
let mtime_first = fs::metadata(&spec).unwrap().modified().unwrap();
std::thread::sleep(std::time::Duration::from_millis(10));
let kit_second = wrap_mixin_as_kit(&mixin).unwrap();
let mtime_second = fs::metadata(kit_second.join("spec.yaml"))
.unwrap()
.modified()
.unwrap();
assert_eq!(kit_first, kit_second);
assert_eq!(
mtime_first, mtime_second,
"cache hit must not rewrite spec.yaml"
);
}
#[test]
#[serial]
fn kit_path_passes_through_existing_directory() {
let _guard = TestCacheDirGuard::new();
let dir = unique_root("kit-path-dir-passthrough");
let m = DiscoveredMixin {
path: dir.clone(),
label: "vault".into(),
install_count: 1,
domain_count: 1,
};
assert_eq!(m.kit_path().unwrap(), dir);
}
#[test]
#[serial]
fn kit_path_wraps_file_into_kit_dir() {
let _guard = TestCacheDirGuard::new();
let mixin = write_mixin("kit-path-wrap", "kind: mixin\nname: probe\n");
let m = DiscoveredMixin {
path: mixin.clone(),
label: mixin.display().to_string(),
install_count: 0,
domain_count: 0,
};
let wrapped = m.kit_path().unwrap();
assert!(wrapped.is_dir(), "kit_path of a file should be a directory");
assert!(wrapped.join("spec.yaml").exists());
assert_ne!(
wrapped, mixin,
"kit_path should not return the original file path"
);
}
}
} }
+67 -8
View File
@@ -347,12 +347,13 @@ fn build_create_args(
]; ];
for mixin in mixins { for mixin in mixins {
let mixin_str = mixin let mixin_kit = mixin.kit_path()?;
.path let mixin_str = mixin_kit
.to_str() .to_str()
.ok_or_else(|| anyhow!("Mixin path is not valid UTF-8: {}", mixin.path.display()))?; .ok_or_else(|| anyhow!("Mixin kit path is not valid UTF-8: {}", mixin_kit.display()))?
.to_string();
args.push("--kit".to_string()); args.push("--kit".to_string());
args.push(mixin_str.to_string()); args.push(mixin_str);
} }
args.push(SANDBOX_AGENT.to_string()); args.push(SANDBOX_AGENT.to_string());
@@ -590,15 +591,24 @@ mod tests {
#[test] #[test]
fn build_create_args_emits_base_kit_before_mixins() { fn build_create_args_emits_base_kit_before_mixins() {
let kit = PathBuf::from("/cache/sbx-kit"); let kit = PathBuf::from("/cache/sbx-kit");
let unique = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let dir_a = env::temp_dir().join(format!("coyote-mixin-a-{unique}"));
let dir_b = env::temp_dir().join(format!("coyote-mixin-b-{unique}"));
fs::create_dir_all(&dir_a).unwrap();
fs::create_dir_all(&dir_b).unwrap();
let mixins = vec![ let mixins = vec![
DiscoveredMixin { DiscoveredMixin {
path: PathBuf::from("/cfg/sbx-mixin.yaml"), path: dir_a.clone(),
label: "user".into(), label: "user".into(),
install_count: 0, install_count: 0,
domain_count: 0, domain_count: 0,
}, },
DiscoveredMixin { DiscoveredMixin {
path: PathBuf::from("/cfg/agents/sql/sbx-mixin.yaml"), path: dir_b.clone(),
label: "sql".into(), label: "sql".into(),
install_count: 0, install_count: 0,
domain_count: 0, domain_count: 0,
@@ -614,15 +624,18 @@ mod tests {
"--kit".to_string(), "--kit".to_string(),
"/cache/sbx-kit".to_string(), "/cache/sbx-kit".to_string(),
"--kit".to_string(), "--kit".to_string(),
"/cfg/sbx-mixin.yaml".to_string(), dir_a.display().to_string(),
"--kit".to_string(), "--kit".to_string(),
"/cfg/agents/sql/sbx-mixin.yaml".to_string(), dir_b.display().to_string(),
"coyote".to_string(), "coyote".to_string(),
"--name".to_string(), "--name".to_string(),
"my-box".to_string(), "my-box".to_string(),
".".to_string(), ".".to_string(),
] ]
); );
let _ = fs::remove_dir_all(&dir_a);
let _ = fs::remove_dir_all(&dir_b);
} }
#[test] #[test]
@@ -645,6 +658,7 @@ mod tests {
mod vault_mixins { mod vault_mixins {
use super::*; use super::*;
use crate::utils::get_env_name;
use gman::providers::aws_secrets_manager::AwsSecretsManagerProvider; use gman::providers::aws_secrets_manager::AwsSecretsManagerProvider;
use gman::providers::azure_key_vault::AzureKeyVaultProvider; use gman::providers::azure_key_vault::AzureKeyVaultProvider;
use gman::providers::gcp_secret_manager::GcpSecretManagerProvider; use gman::providers::gcp_secret_manager::GcpSecretManagerProvider;
@@ -652,6 +666,46 @@ mod tests {
use gman::providers::local::LocalProvider; use gman::providers::local::LocalProvider;
use gman::providers::one_password::OnePasswordProvider; use gman::providers::one_password::OnePasswordProvider;
use serial_test::serial; use serial_test::serial;
use std::time::{SystemTime, UNIX_EPOCH};
struct TestCacheDirGuard {
key: String,
previous: Option<std::ffi::OsString>,
path: PathBuf,
}
impl TestCacheDirGuard {
fn new() -> Self {
let key = get_env_name("cache_dir");
let previous = env::var_os(&key);
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let path = env::temp_dir().join(format!("coyote-sandbox-vault-tests-{unique}"));
fs::create_dir_all(&path).unwrap();
unsafe {
env::set_var(&key, &path);
}
Self {
key,
previous,
path,
}
}
}
impl Drop for TestCacheDirGuard {
fn drop(&mut self) {
unsafe {
match &self.previous {
Some(v) => env::set_var(&self.key, v),
None => env::remove_var(&self.key),
}
}
let _ = fs::remove_dir_all(&self.path);
}
}
#[test] #[test]
fn returns_none_for_local() { fn returns_none_for_local() {
@@ -664,6 +718,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn returns_some_for_aws() { fn returns_some_for_aws() {
let _guard = TestCacheDirGuard::new();
let p = SupportedProvider::AwsSecretsManager { let p = SupportedProvider::AwsSecretsManager {
provider_def: AwsSecretsManagerProvider { provider_def: AwsSecretsManagerProvider {
aws_profile: None, aws_profile: None,
@@ -680,6 +735,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn returns_some_for_gcp() { fn returns_some_for_gcp() {
let _guard = TestCacheDirGuard::new();
let p = SupportedProvider::GcpSecretManager { let p = SupportedProvider::GcpSecretManager {
provider_def: GcpSecretManagerProvider { provider_def: GcpSecretManagerProvider {
gcp_project_id: None, gcp_project_id: None,
@@ -695,6 +751,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn returns_some_for_one_password() { fn returns_some_for_one_password() {
let _guard = TestCacheDirGuard::new();
let p = SupportedProvider::OnePassword { let p = SupportedProvider::OnePassword {
provider_def: OnePasswordProvider { provider_def: OnePasswordProvider {
vault: None, vault: None,
@@ -711,6 +768,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn returns_some_for_azure() { fn returns_some_for_azure() {
let _guard = TestCacheDirGuard::new();
let p = SupportedProvider::AzureKeyVault { let p = SupportedProvider::AzureKeyVault {
provider_def: AzureKeyVaultProvider { vault_name: None }, provider_def: AzureKeyVaultProvider { vault_name: None },
}; };
@@ -724,6 +782,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn returns_some_for_gopass() { fn returns_some_for_gopass() {
let _guard = TestCacheDirGuard::new();
let p = SupportedProvider::Gopass { let p = SupportedProvider::Gopass {
provider_def: GopassProvider { store: None }, provider_def: GopassProvider { store: None },
}; };