diff --git a/Cargo.lock b/Cargo.lock index 70c9f31..e788c0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,16 @@ 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", + "generic-array", +] + [[package]] name = "ahash" version = "0.8.12" @@ -134,7 +144,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -189,7 +199,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -200,7 +210,30 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", +] + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", ] [[package]] @@ -283,7 +316,7 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", - "itoa", + "itoa 1.0.18", "matchit", "memchr", "mime", @@ -331,7 +364,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -377,6 +410,12 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.13.0" @@ -395,6 +434,12 @@ dependencies = [ "no_std_io2", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -440,6 +485,31 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.13.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "castaway" version = "0.2.4" @@ -461,6 +531,22 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.4" @@ -473,6 +559,30 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.45" @@ -487,6 +597,17 @@ 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", + "inout", + "zeroize", +] + [[package]] name = "clap" version = "4.6.1" @@ -515,10 +636,10 @@ version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -527,6 +648,35 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cocoa" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c" +dependencies = [ + "bitflags 2.13.0", + "block", + "cocoa-foundation", + "core-foundation 0.10.1", + "core-graphics", + "foreign-types 0.5.0", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" +dependencies = [ + "bitflags 2.13.0", + "block", + "core-foundation 0.10.1", + "core-graphics-types", + "objc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -539,6 +689,16 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compact_str" version = "0.9.1" @@ -547,7 +707,7 @@ checksum = "9dfdd1c2274d9aa354115b09dc9a901d6c5576818cdf70d14cae2bdb47df00ab" dependencies = [ "castaway", "cfg-if", - "itoa", + "itoa 1.0.18", "rustversion", "ryu", "serde", @@ -587,7 +747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" dependencies = [ "async-trait", - "convert_case", + "convert_case 0.6.0", "json5", "nom 7.1.3", "pathdiff", @@ -638,6 +798,12 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "convert_case" version = "0.6.0" @@ -673,6 +839,30 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.10.1", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.10.1", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -762,9 +952,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.118", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -789,7 +1007,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -813,7 +1031,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 2.0.118", ] [[package]] @@ -824,7 +1042,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -836,6 +1054,27 @@ dependencies = [ "serde", ] +[[package]] +name = "dbus" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "dbus-secret-service" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "708b509edf7889e53d7efb0ffadd994cc6c2345ccb62f55cfd6b0682165e4fa6" +dependencies = [ + "dbus", + "zeroize", +] + [[package]] name = "der" version = "0.7.10" @@ -871,7 +1110,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -881,7 +1120,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn", + "syn 2.0.118", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.118", ] [[package]] @@ -917,6 +1169,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + [[package]] name = "displaydoc" version = "0.2.6" @@ -925,7 +1183,30 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", +] + +[[package]] +name = "dlopen2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -943,6 +1224,33 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "ed25519" version = "2.2.3" @@ -1008,7 +1316,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1114,6 +1422,16 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + [[package]] name = "filetime" version = "0.2.29" @@ -1169,7 +1487,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -1178,6 +1517,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -1187,6 +1532,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + [[package]] name = "futures-channel" version = "0.3.32" @@ -1239,7 +1594,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1271,62 +1626,323 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "typenum", - "version_check", + "byteorder", ] [[package]] -name = "getrandom" -version = "0.2.17" +name = "gdk" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" dependencies = [ - "cfg-if", - "js-sys", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", "libc", - "wasi", - "wasm-bindgen", + "pango", ] [[package]] -name = "getrandom" -version = "0.3.4" +name = "gdk-pixbuf" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" dependencies = [ - "cfg-if", - "js-sys", + "gdk-pixbuf-sys", + "gio", + "glib", "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", + "once_cell", ] [[package]] -name = "getrandom" -version = "0.4.3" +name = "gdk-pixbuf-sys" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" dependencies = [ - "cfg-if", + "gio-sys", + "glib-sys", + "gobject-sys", "libc", - "r-efi 6.0.0", + "system-deps", ] [[package]] -name = "gif" -version = "0.14.2" +name = "gdk-sys" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" dependencies = [ - "color_quant", - "weezl", -] + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + +[[package]] +name = "gif" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.13.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.118", +] [[package]] name = "h2" @@ -1409,6 +2025,12 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" @@ -1469,6 +2091,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "http" version = "1.4.2" @@ -1476,7 +2112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", - "itoa", + "itoa 1.0.18", ] [[package]] @@ -1529,7 +2165,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", + "itoa 1.0.18", "pin-project-lite", "smallvec", "tokio", @@ -1618,7 +2254,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.2", ] [[package]] @@ -1812,6 +2448,24 @@ 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 = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + [[package]] name = "interpolate_name" version = "0.2.4" @@ -1820,7 +2474,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -1844,12 +2498,85 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.118", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -1897,6 +2624,34 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "keyring" +version = "3.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" +dependencies = [ + "byteorder", + "dbus-secret-service", + "log", + "security-framework 2.11.1", + "security-framework 3.7.0", + "windows-sys 0.60.2", + "zeroize", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1918,6 +2673,15 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + [[package]] name = "libfuzzer-sys" version = "0.4.13" @@ -1940,7 +2704,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags", + "bitflags 2.13.0", "libc", "plain", "redox_syscall 0.8.1", @@ -1999,6 +2763,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + [[package]] name = "macro_rules_attribute" version = "0.2.2" @@ -2015,6 +2785,29 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + [[package]] name = "matchers" version = "0.2.0" @@ -2024,6 +2817,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + [[package]] name = "matchit" version = "0.7.3" @@ -2072,6 +2871,30 @@ version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +[[package]] +name = "memmesh-desktop" +version = "0.1.2" +dependencies = [ + "anyhow", + "memory-core", + "memory-embed", + "memory-server", + "memory-storage", + "tao", + "tokio", + "tracing-subscriber", + "wry", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "memory-audit" version = "0.1.2" @@ -2101,12 +2924,13 @@ dependencies = [ "memory-server", "memory-storage", "memory-sync", + "rpassword", "serde", "serde_json", "serde_yaml", "tokio", "toml", - "toml_edit", + "toml_edit 0.22.27", "tracing", "tracing-appender", "tracing-subscriber", @@ -2240,10 +3064,13 @@ version = "0.1.2" dependencies = [ "anyhow", "async-trait", + "chacha20poly1305", "chrono", + "keyring", "memory-core", "memory-embed", "once_cell", + "rand 0.8.6", "regex", "serde", "serde_json", @@ -2252,6 +3079,7 @@ dependencies = [ "tokio", "tracing", "uuid", + "zeroize", ] [[package]] @@ -2300,7 +3128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -2323,7 +3151,7 @@ checksum = "e4db6d5580af57bf992f59068d4ea26fd518574ff48d7639b255a36f9de6e7e9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2348,7 +3176,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 3.7.0", "security-framework-sys", "tempfile", ] @@ -2368,6 +3196,36 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.0", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -2383,6 +3241,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nom" version = "7.1.3" @@ -2466,7 +3330,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2510,12 +3374,62 @@ dependencies = [ "libm", ] +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "number_prefix" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -2534,7 +3448,7 @@ version = "6.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2" dependencies = [ - "bitflags", + "bitflags 2.13.0", "libc", "once_cell", "onig_sys", @@ -2550,15 +3464,21 @@ 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 = "openssl" version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ - "bitflags", + "bitflags 2.13.0", "cfg-if", - "foreign-types", + "foreign-types 0.3.2", "libc", "openssl-macros", "openssl-sys", @@ -2572,7 +3492,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2633,6 +3553,31 @@ dependencies = [ "ureq", ] +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "parking" version = "2.2.1" @@ -2694,58 +3639,169 @@ dependencies = [ name = "pem-rfc7468" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "base64ct", + "phf_shared 0.10.0", + "rand 0.8.6", ] [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "phf_generator" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.6", +] [[package]] -name = "pest" -version = "2.8.6" +name = "phf_macros" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" dependencies = [ - "memchr", - "ucd-trie", + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "pest_derive" -version = "2.8.6" +name = "phf_shared" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ - "pest", - "pest_generator", + "siphasher 0.3.11", ] [[package]] -name = "pest_generator" -version = "2.8.6" +name = "phf_shared" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", + "siphasher 0.3.11", ] [[package]] -name = "pest_meta" -version = "2.8.6" +name = "phf_shared" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "pest", - "sha2", + "siphasher 1.0.3", ] [[package]] @@ -2765,7 +3821,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2813,13 +3869,24 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -2859,6 +3926,70 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.13+spec-1.1.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.106" @@ -2884,7 +4015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -2907,7 +4038,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3007,6 +4138,20 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + [[package]] name = "rand" version = "0.8.6" @@ -3028,6 +4173,16 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -3048,6 +4203,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -3066,6 +4230,24 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "rav1e" version = "0.8.1" @@ -3116,6 +4298,12 @@ dependencies = [ "rgb", ] +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + [[package]] name = "rawpointer" version = "0.2.1" @@ -3159,7 +4347,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.0", ] [[package]] @@ -3168,7 +4356,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ - "bitflags", + "bitflags 2.13.0", ] [[package]] @@ -3285,11 +4473,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags", + "bitflags 2.13.0", "serde", "serde_derive", ] +[[package]] +name = "rpassword" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da316a15f47e3d053de9cb2c439650bd8fa4aaeb9365f2e5f27f492ff73c196" +dependencies = [ + "libc", + "rtoolbox", + "windows-sys 0.61.2", +] + [[package]] name = "rsa" version = "0.9.10" @@ -3310,6 +4509,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rtoolbox" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50a0e551c1e27e1731aba276dbeaeac73f53c7cd34d1bda485d02bd1e0f36844" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "rust-ini" version = "0.20.0" @@ -3341,7 +4550,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys", @@ -3396,6 +4605,15 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.29" @@ -3411,13 +4629,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.13.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework" version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.13.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -3434,6 +4665,26 @@ dependencies = [ "libc", ] +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + [[package]] name = "semver" version = "1.0.28" @@ -3467,7 +4718,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3476,7 +4727,7 @@ version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ - "itoa", + "itoa 1.0.18", "memchr", "serde", "serde_core", @@ -3489,7 +4740,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ - "itoa", + "itoa 1.0.18", "serde", "serde_core", ] @@ -3510,7 +4761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa", + "itoa 1.0.18", "ryu", "serde", ] @@ -3522,12 +4773,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap 2.14.0", - "itoa", + "itoa 1.0.18", "ryu", "serde", "unsafe-libyaml", ] +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + [[package]] name = "sha1" version = "0.10.6" @@ -3612,6 +4873,18 @@ dependencies = [ "time", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[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" @@ -3658,6 +4931,32 @@ dependencies = [ "winapi", ] +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "spin" version = "0.9.8" @@ -3751,7 +5050,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn", + "syn 2.0.118", ] [[package]] @@ -3762,7 +5061,7 @@ checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck", + "heck 0.5.0", "hex", "once_cell", "proc-macro2", @@ -3774,7 +5073,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn", + "syn 2.0.118", "tokio", "url", ] @@ -3788,7 +5087,7 @@ dependencies = [ "atoi", "base64 0.22.1", "bigdecimal", - "bitflags", + "bitflags 2.13.0", "byteorder", "bytes", "chrono", @@ -3804,7 +5103,7 @@ dependencies = [ "hex", "hkdf", "hmac", - "itoa", + "itoa 1.0.18", "log", "md-5", "memchr", @@ -3833,7 +5132,7 @@ dependencies = [ "atoi", "base64 0.22.1", "bigdecimal", - "bitflags", + "bitflags 2.13.0", "byteorder", "chrono", "crc", @@ -3846,7 +5145,7 @@ dependencies = [ "hkdf", "hmac", "home", - "itoa", + "itoa 1.0.18", "log", "md-5", "memchr", @@ -3903,6 +5202,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + [[package]] name = "stringprep" version = "0.1.5" @@ -3932,6 +5256,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.118" @@ -3943,6 +5278,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -3960,7 +5306,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -3969,7 +5315,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" dependencies = [ - "bitflags", + "bitflags 2.13.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3984,6 +5330,69 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.30.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da" +dependencies = [ + "bitflags 2.13.0", + "cocoa", + "core-foundation 0.10.1", + "core-graphics", + "crossbeam-channel", + "dispatch", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "raw-window-handle", + "scopeguard", + "tao-macros", + "unicode-segmentation", + "url", + "windows", + "windows-core 0.58.0", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7eeb6d99155545da6150a1795945f16ac9c178deb2a5f2e74d776107bd5849" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "tar" version = "0.4.46" @@ -3995,6 +5404,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.27.0" @@ -4008,6 +5423,23 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + [[package]] name = "thiserror" version = "1.0.69" @@ -4034,7 +5466,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4045,7 +5477,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4193,7 +5625,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4248,8 +5680,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -4261,6 +5693,37 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -4270,9 +5733,30 @@ dependencies = [ "indexmap 2.14.0", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.15", +] + +[[package]] +name = "toml_edit" +version = "0.25.13+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.4", +] + +[[package]] +name = "toml_parser" +version = "1.1.3+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" +dependencies = [ + "winnow 1.0.4", ] [[package]] @@ -4353,7 +5837,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "bitflags", + "bitflags 2.13.0", "bytes", "http", "http-body", @@ -4371,7 +5855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", - "bitflags", + "bitflags 2.13.0", "bytes", "futures-core", "futures-util", @@ -4432,7 +5916,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4559,6 +6043,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -4603,6 +6097,12 @@ dependencies = [ "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -4650,12 +6150,28 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -4665,6 +6181,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -4728,7 +6250,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.118", "wasm-bindgen-shared", ] @@ -4774,6 +6296,50 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webkit2gtk" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + [[package]] name = "webpki-roots" version = "0.26.11" @@ -4792,6 +6358,42 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webview2-com" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f61ff3d9d0ee4efcb461b14eb3acfda2702d10dc329f339303fc3e57215ae2c" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core 0.58.0", + "windows-implement 0.58.0", + "windows-interface 0.58.0", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "webview2-com-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886" +dependencies = [ + "thiserror 1.0.69", + "windows", + "windows-core 0.58.0", +] + [[package]] name = "weezl" version = "0.1.12" @@ -4824,23 +6426,66 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link", - "windows-result", - "windows-strings", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -4851,7 +6496,18 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", ] [[package]] @@ -4862,7 +6518,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -4878,8 +6534,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ "windows-link", - "windows-result", - "windows-strings", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -4891,6 +6556,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.5.1" @@ -4900,6 +6575,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -4945,6 +6629,21 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -4993,6 +6692,21 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5011,6 +6725,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5029,6 +6749,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5059,6 +6785,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5077,6 +6809,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5095,6 +6833,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5113,6 +6857,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5131,6 +6881,15 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.7.15" @@ -5140,6 +6899,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.57.1" @@ -5152,6 +6920,67 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +[[package]] +name = "wry" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0099a336829fbf54c26b5f620c68980ebbe37196772aeaf6118df4931b5cb0" +dependencies = [ + "base64 0.22.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "objc", + "objc_id", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 1.0.69", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core 0.58.0", + "windows-version", + "x11-dl", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + [[package]] name = "xattr" version = "1.6.1" @@ -5198,7 +7027,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", "synstructure", ] @@ -5219,7 +7048,7 @@ checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] @@ -5239,7 +7068,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", "synstructure", ] @@ -5248,6 +7077,20 @@ name = "zeroize" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] [[package]] name = "zerotrie" @@ -5279,7 +7122,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.118", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8058298..d291078 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "crates/license", "crates/eval", "crates/cli", + "crates/desktop", ] [workspace.package] @@ -37,6 +38,12 @@ futures = "0.3" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } tracing-appender = "0.2" +# Secrets vault (encrypted credential storage) +chacha20poly1305 = "0.10" +keyring = { version = "3", features = ["apple-native", "sync-secret-service", "windows-native"] } +zeroize = "1" +rand = "0.8" +rpassword = "7" # Serialization serde = { version = "1", features = ["derive"] } diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 2050dbc..e502608 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -33,6 +33,7 @@ tracing-appender.workspace = true serde.workspace = true serde_json.workspace = true serde_yaml.workspace = true +rpassword.workspace = true uuid.workspace = true chrono.workspace = true toml.workspace = true diff --git a/crates/cli/src/installer.rs b/crates/cli/src/installer.rs index 71cfb3e..b5b3ceb 100644 --- a/crates/cli/src/installer.rs +++ b/crates/cli/src/installer.rs @@ -305,36 +305,67 @@ fn install_claude_code_hook(settings_path: &Path, binary: &Path) -> Result<()> { bail!("{}::hooks is not an object", settings_path.display()); } let hooks_obj = hooks.as_object_mut().unwrap(); + let bin = binary.to_string_lossy(); - // Our hook entry — matcher "*" catches every prompt. Command runs - // synchronously (Claude Code waits for it), reads the prompt from - // stdin, and is heuristic-only so finishes in <50ms even on a cold - // start. We pipe stderr to /dev/null to keep Claude Code's output - // clean if extraction fails. - let our_hook = serde_json::json!({ + // 1. CAPTURE — UserPromptSubmit: pipe every prompt into the engine. + // matcher "*" catches every prompt; runs synchronously (Claude Code + // waits), heuristic-only so it finishes in <50ms even cold. stderr is + // dropped so a failure never dirties Claude Code's output. + let observe_hook = serde_json::json!({ "matcher": "*", - "hooks": [ - { - "type": "command", - "command": format!( - "{} observe --role user --json 2>/dev/null || true", - binary.to_string_lossy(), - ) - } - ] + "hooks": [ { + "type": "command", + "command": format!("{bin} observe --role user --json 2>/dev/null || true"), + } ] + }); + upsert_owned_hook(hooks_obj, "UserPromptSubmit", observe_hook, "memmesh observe")?; + + // 2. RECALL — SessionStart: inject relevant memories into context at the + // start of each session. The hook's stdout is added to the session + // context, so `search --format claude-context` surfaces the memory + // block automatically (no dependency on the model choosing to search). + let recall_hook = serde_json::json!({ + "hooks": [ { + "type": "command", + "command": format!("{bin} search --format claude-context --limit 30 2>/dev/null || true"), + } ] + }); + upsert_owned_hook(hooks_obj, "SessionStart", recall_hook, "memmesh search")?; + + // 3. ENFORCE — PreToolUse secret-guard on Bash: block a command that + // carries a live credential and redirect it to the vault. Deterministic + // enforcement the advisory skill can't guarantee — secrets can't reach a + // shell command or the transcript. Fast (regex only, no engine init). + let guard_hook = serde_json::json!({ + "matcher": "Bash", + "hooks": [ { + "type": "command", + "command": format!("{bin} hook secret-guard"), + } ] }); + upsert_owned_hook(hooks_obj, "PreToolUse", guard_hook, "hook secret-guard")?; + + let serialized = serde_json::to_string_pretty(&doc)?; + std::fs::write(settings_path, serialized)?; + Ok(()) +} - // Append-or-replace logic: if there's already a hooks block we own - // (matcher "*" with a command containing "memmesh observe"), - // replace it; otherwise append to the array so other hooks survive. - let event = hooks_obj - .entry("UserPromptSubmit".to_string()) +/// Append-or-replace a hook we own under `event`, identified by `marker` +/// appearing in one of its command strings. Other vendors' hooks are left +/// untouched, and re-running install replaces our entry rather than +/// duplicating it. +fn upsert_owned_hook( + hooks_obj: &mut serde_json::Map, + event: &str, + our_hook: serde_json::Value, + marker: &str, +) -> Result<()> { + let ev = hooks_obj + .entry(event.to_string()) .or_insert_with(|| serde_json::json!([])); - let arr = event + let arr = ev .as_array_mut() - .ok_or_else(|| anyhow!("hooks.UserPromptSubmit is not an array"))?; - - let mut replaced = false; + .ok_or_else(|| anyhow!("hooks.{event} is not an array"))?; for entry in arr.iter_mut() { let is_ours = entry .get("hooks") @@ -343,22 +374,16 @@ fn install_claude_code_hook(settings_path: &Path, binary: &Path) -> Result<()> { hs.iter().any(|h| { h.get("command") .and_then(|c| c.as_str()) - .is_some_and(|s| s.contains("memmesh observe")) + .is_some_and(|s| s.contains(marker)) }) }) .unwrap_or(false); if is_ours { - *entry = our_hook.clone(); - replaced = true; - break; + *entry = our_hook; + return Ok(()); } } - if !replaced { - arr.push(our_hook); - } - - let serialized = serde_json::to_string_pretty(&doc)?; - std::fs::write(settings_path, serialized)?; + arr.push(our_hook); Ok(()) } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index d2a5b6d..40cee3b 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -206,6 +206,13 @@ enum Cmd { http: String, }, + /// Internal hooks for AI-tool integration (wired by `install`). Reads a + /// tool's hook JSON on stdin. Not meant to be called by hand. + Hook { + #[command(subcommand)] + action: HookAction, + }, + /// Launch the local web console: starts the REST API, serves the /// memory management UI, and opens it in your browser. One command to /// see engine status, browse memories, tail logs, and tweak config. @@ -218,6 +225,30 @@ enum Cmd { no_open: bool, }, + /// Start a REMOTE MCP server over Streamable HTTP for web chats + /// (ChatGPT + Claude.ai custom connectors), which can't use a local + /// stdio server. Unlike `mcp` (stdio) and `console` (loopback, no auth), + /// this is meant to be exposed publicly via a tunnel, so it REQUIRES a + /// bearer token. Pass --token or set MEMMESH_MCP_TOKEN; if neither is + /// set, a random token is generated and printed. + ServeMcp { + /// Address to bind. Default 127.0.0.1:7899 (put a tunnel in front). + #[arg(long, default_value = "127.0.0.1:7899")] + http: String, + /// Bearer token clients must send. Auto-generated if omitted. + #[arg(long, env = "MEMMESH_MCP_TOKEN")] + token: Option, + }, + + /// Encrypted secrets vault. Store credentials the AI can *reference* but + /// never read — values are entered here (never in chat), sealed with the + /// OS-keychain-backed master key, and used via execute-through-vault so + /// plaintext never reaches the model. + Secret { + #[command(subcommand)] + action: SecretAction, + }, + /// Manage the agent teaching skill (markdown that tells the AI when /// and how to use the memory tools). Skill { @@ -435,6 +466,41 @@ enum ConfigAction { ClearSync, } +#[derive(Subcommand)] +enum SecretAction { + /// Store (or replace) a secret. Prompts for the value on a hidden line — + /// it is never passed as an argument or echoed. + Set { + /// Reference name, e.g. `aws-prod`. Used as `{{memmesh:aws-prod}}`. + name: String, + #[arg(long, help = "Category, e.g. aws / openai / db / password")] + kind: Option, + #[arg(long, help = "Non-secret note shown in listings")] + desc: Option, + }, + /// List stored secrets (names, kinds, descriptions) — never values. + List { + #[arg(long)] + json: bool, + }, + /// Remove a secret. + Rm { name: String }, + /// Execute-through-vault: run a command with `{{memmesh:NAME}}` references + /// resolved in-process. Output is returned with secret values scrubbed. + Run { + /// The command to run (quote it). e.g. "aws s3 ls --profile {{memmesh:aws-prod}}" + command: String, + }, +} + +#[derive(Subcommand)] +enum HookAction { + /// PreToolUse guard: block a tool command that carries a live credential, + /// redirecting it to the vault. Reads the tool's PreToolUse JSON on stdin; + /// exit 2 (with a reason on stderr) blocks the call. + SecretGuard, +} + #[derive(Subcommand)] enum SkillAction { /// Print the skill markdown to stdout. @@ -461,6 +527,13 @@ const SKILL_MD: &str = include_str!("../../../skills/memmesh/SKILL.md"); async fn main() -> Result<()> { let cli = Cli::parse(); + // Hooks run on EVERY tool call (e.g. Claude Code PreToolUse before every + // Bash command), so handle them here — before tracing / license / store + // setup — to keep them fast and side-effect-free. + if let Cmd::Hook { action } = &cli.cmd { + return run_hook(action); + } + // Hold the log-file guard for the whole process so buffered log lines // flush on exit. Dropping it early would truncate the tail of the log. let _log_guard = init_tracing(&cli.log)?; @@ -505,6 +578,9 @@ async fn main() -> Result<()> { /// `main` selected. Monomorphized once per backend. async fn run(store: Arc, cli: Cli, license: License) -> Result<()> { match cli.cmd { + // Hooks are dispatched in main() before engine setup. + Cmd::Hook { .. } => unreachable!("hook handled before dispatch"), + Cmd::Migrate => { let version = store.migrate().await?; println!("schema version: {version}"); @@ -583,9 +659,26 @@ async fn run(store: Arc, cli: Cli, license: License) -> Result<() use std::io::Read; let mut buf = String::new(); std::io::stdin().read_to_string(&mut buf)?; - buf + // AI-tool hooks (Claude Code's UserPromptSubmit, etc.) deliver + // their input as a JSON envelope on stdin, not the raw prompt — + // e.g. {"hook_event_name":"UserPromptSubmit","prompt":"…"}. + // Observing the wrapper JSON extracts nothing, so pull the + // actual prompt out when we recognize that shape. + extract_hook_prompt(&buf).unwrap_or(buf) } }; + // Drop harness/tool noise before it ever reaches the engine. + // task-notifications, system-reminders, and command wrappers are + // machine chatter, not things worth remembering — capturing them + // pollutes recall and buries the real memories. + if is_noise(&text) { + if json { + println!("{}", serde_json::json!({"saved": [], "candidateCount": 0, "skipped": "noise"})); + } else { + println!("observed: 0 saved (filtered harness noise)"); + } + return Ok(()); + } let role_parsed = match role.as_str() { "user" => Some(memory_core::extraction::ObserveRole::User), "assistant" => Some(memory_core::extraction::ObserveRole::Assistant), @@ -648,7 +741,7 @@ async fn run(store: Arc, cli: Cli, license: License) -> Result<() }; // Hybrid semantic + lexical + recency ranking. Falls back to the // lexical substring path automatically when embeddings are off. - let rows = memory_storage::search::search( + let mut rows = memory_storage::search::search( store.as_ref(), &filter, query.as_deref(), @@ -656,6 +749,18 @@ async fn run(store: Arc, cli: Cli, license: License) -> Result<() offset, ) .await?; + // For session-start injection (claude-context, typically no query) + // lead with the highest-value memories — facts / rules / preferences + // (importance ~8) before raw conversational observations (~3) — so + // the model sees signal first instead of recency-ordered chatter. + if format == "claude-context" { + rows.sort_by(|a, b| { + b.importance + .partial_cmp(&a.importance) + .unwrap_or(std::cmp::Ordering::Equal) + .then_with(|| b.created.cmp(&a.created)) + }); + } match format.as_str() { "json" => println!("{}", serde_json::to_string_pretty(&rows)?), "claude-context" => { @@ -788,6 +893,28 @@ async fn run(store: Arc, cli: Cli, license: License) -> Result<() memory_server::serve_http(store, &http).await?; } + Cmd::ServeMcp { http, token } => { + let token = token.unwrap_or_else(|| { + uuid::Uuid::new_v4().to_string().replace('-', "") + }); + let url = format!("http://{http}/mcp"); + println!(); + println!(" MemMesh remote MCP (Streamable HTTP)"); + println!(" ────────────────────────────────────"); + println!(" engine : {}", cli.db); + println!(" url : {url}"); + println!(" token : {token}"); + println!(); + println!(" Expose it publicly with a tunnel, e.g.:"); + println!(" cloudflared tunnel --url http://{http}"); + println!(" then register the resulting https URL + '/mcp' as a custom"); + println!(" connector in ChatGPT / Claude.ai, with header:"); + println!(" Authorization: Bearer {token}"); + println!(); + tracing::info!(db = %cli.db, addr = %http, "starting remote MCP server"); + memory_server::serve_mcp_http(store, license, &http, token).await?; + } + Cmd::Sync { skip_token_check } => { let cfg = memory_core::config::Config::load_or_default(); let sync_cfg = cfg.sync.clone().ok_or_else(|| { @@ -839,6 +966,70 @@ async fn run(store: Arc, cli: Cli, license: License) -> Result<() } } + Cmd::Secret { action } => { + use memory_storage::vault::Vault; + let vault = Vault::open(&Vault::default_path()) + .await + .context("opening secrets vault")?; + match action { + SecretAction::Set { name, kind, desc } => { + // Hidden TTY prompt for humans; fall back to reading a line + // from stdin when there's no terminal (piped / automation). + let value = match rpassword::prompt_password(format!("Value for '{name}' (hidden): ")) { + Ok(v) => v, + Err(_) => { + use std::io::BufRead; + let mut line = String::new(); + std::io::stdin().lock().read_line(&mut line)?; + line.trim_end_matches(['\n', '\r']).to_string() + } + }; + if value.is_empty() { + return Err(anyhow!("empty value — nothing stored")); + } + vault + .set(&name, &value, kind.as_deref(), desc.as_deref(), Some("user"), None) + .await?; + println!("stored secret '{name}' (reference it as {{{{memmesh:{name}}}}})"); + } + SecretAction::List { json } => { + let secrets = vault.list().await?; + if json { + println!("{}", serde_json::to_string_pretty(&secrets)?); + } else if secrets.is_empty() { + println!("no secrets stored. Add one with `memmesh secret set `."); + } else { + for s in &secrets { + println!( + " {}{}{}", + s.name, + s.kind.as_deref().map(|k| format!(" [{k}]")).unwrap_or_default(), + s.description.as_deref().map(|d| format!(" — {d}")).unwrap_or_default(), + ); + } + } + } + SecretAction::Rm { name } => { + if vault.delete(&name).await? { + println!("removed '{name}'"); + } else { + eprintln!("no secret named '{name}'"); + std::process::exit(2); + } + } + SecretAction::Run { command } => { + let r = vault.run(&command).await?; + if !r.stdout.is_empty() { + print!("{}", r.stdout); + } + if !r.stderr.is_empty() { + eprint!("{}", r.stderr); + } + std::process::exit(r.exit_code); + } + } + } + Cmd::Skill { action } => match action { SkillAction::Print => { print!("{SKILL_MD}"); @@ -1332,6 +1523,88 @@ fn detect_git_project() -> Option { Some(last.to_string()) } +/// Handle an AI-tool integration hook. Fast, synchronous, no engine init. +fn run_hook(action: &HookAction) -> Result<()> { + match action { + HookAction::SecretGuard => secret_guard(), + } +} + +/// PreToolUse secret guard. Reads the tool's hook JSON on stdin, scans the +/// command it's about to run, and BLOCKS (exit 2) if it carries a live +/// credential — redirecting the user/agent to the vault. This is the +/// deterministic enforcement the advisory skill can't guarantee: a secret +/// physically cannot reach a shell command or the transcript. +fn secret_guard() -> Result<()> { + use std::io::Read; + let mut buf = String::new(); + std::io::stdin().read_to_string(&mut buf).ok(); + + // Pull the command out of the hook envelope; fall back to the whole + // payload so we still scan if the shape is unfamiliar. + let scanned: String = serde_json::from_str::(&buf) + .ok() + .and_then(|v| { + v.get("tool_input") + .and_then(|ti| ti.get("command").or_else(|| ti.get("script"))) + .and_then(|c| c.as_str()) + .map(|s| s.to_string()) + }) + .unwrap_or(buf); + + if memory_core::extraction::contains_secret(&scanned) { + eprintln!( + "⛔ memmesh secret-guard: this command appears to contain a live credential.\n\ + Never put secrets in a command or the transcript. Store it in the vault instead:\n\ + • run `memmesh secret set ` (or open http://127.0.0.1:7878/?tab=vault&add=)\n\ + then reference it as {{{{memmesh:}}}} and run via the memory_secret_run tool." + ); + std::process::exit(2); + } + Ok(()) +} + +/// AI-tool hooks pipe a JSON envelope to stdin rather than the raw prompt. +/// Claude Code's `UserPromptSubmit` sends +/// `{"hook_event_name":"UserPromptSubmit","prompt":"…","session_id":…,…}`. +/// Detect that envelope and return the inner prompt so `observe` runs on the +/// user's text, not the wrapper. Returns `None` for plain text (observe as-is) +/// — a bare prompt won't parse as a JSON object with these hook markers. +fn extract_hook_prompt(raw: &str) -> Option { + let v: serde_json::Value = serde_json::from_str(raw.trim()).ok()?; + let obj = v.as_object()?; + let is_hook_envelope = obj.contains_key("hook_event_name") + || obj.contains_key("session_id") + || obj.contains_key("transcript_path"); + if !is_hook_envelope { + return None; + } + obj.get("prompt") + .and_then(|p| p.as_str()) + .filter(|s| !s.trim().is_empty()) + .map(|s| s.to_string()) +} + +/// True for machine/harness chatter that should never be remembered: +/// task-notification and system-reminder blocks injected by the AI tool, +/// command wrappers, and empty input. These arrive through the same hook +/// path as real prompts but carry no durable user intent. +fn is_noise(text: &str) -> bool { + let t = text.trim_start(); + if t.is_empty() { + return true; + } + const NOISE_PREFIXES: &[&str] = &[ + " String { std::env::var("USER") .or_else(|_| std::env::var("USERNAME")) diff --git a/crates/core/src/extraction.rs b/crates/core/src/extraction.rs index f9c78e9..5a3e1f4 100644 --- a/crates/core/src/extraction.rs +++ b/crates/core/src/extraction.rs @@ -69,6 +69,13 @@ pub fn extract(text: &str, ctx: &ObserveContext) -> Vec { let mut out = Vec::new(); for line in segment(text) { + // SAFETY NET: never persist a line that looks like it carries a live + // credential. Secrets belong in the encrypted vault (entered by the + // user out-of-band), never in the plaintext memory store — and never + // in the context we later inject back. Drop the whole line. + if contains_secret(&line) { + continue; + } if let Some(m) = extract_line(&line, ctx) { out.push(m); } @@ -82,7 +89,7 @@ pub fn extract(text: &str, ctx: &ObserveContext) -> Vec { // (third-person, questions aside, arbitrary facts) matches nothing, so // without this the store stays empty. Hosted LLM extraction refines these // into typed facts; locally we at least never lose them. - if out.is_empty() { + if out.is_empty() && !contains_secret(text) { if let Some(m) = fallback_observation(text) { out.push(m); } @@ -91,6 +98,34 @@ pub fn extract(text: &str, ctx: &ObserveContext) -> Vec { out } +/// Regexes for common live credentials. Precision-first: these match +/// high-signal token shapes and `key = value` secret assignments, not every +/// mention of the word "password". Used only as a safety net so a pasted +/// credential never lands in the plaintext memory store. +static SECRET_PATTERNS: Lazy> = Lazy::new(|| { + [ + r"AKIA[0-9A-Z]{16}", // AWS access key id + r"ASIA[0-9A-Z]{16}", // AWS temp key id + r"sk-ant-[A-Za-z0-9_\-]{20,}", // Anthropic + r"sk-[A-Za-z0-9]{20,}", // OpenAI-style + r"gh[opsu]_[A-Za-z0-9]{30,}", // GitHub tokens + r"xox[baprs]-[A-Za-z0-9-]{10,}", // Slack + r"AIza[0-9A-Za-z\-_]{35}", // Google API key + r"-----BEGIN [A-Z ]*PRIVATE KEY-----", // PEM private key + r"eyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}", // JWT + r"(?i)(password|passwd|pwd|api[_-]?key|secret|token|bearer)\s*[:=]\s*\S{6,}", + r"(?i)(postgres(ql)?|mysql|mongodb(\+srv)?|redis|amqp)://[^:\s/]+:[^@\s]+@", // DSN with creds + ] + .iter() + .map(|p| Regex::new(p).expect("invalid secret regex")) + .collect() +}); + +/// True if the text appears to contain a live credential. +pub fn contains_secret(text: &str) -> bool { + SECRET_PATTERNS.iter().any(|re| re.is_match(text)) +} + /// Keep substantive input that matched no structured rule as a raw /// `observation`. Filters out questions, code/commands, and short fragments so /// the store fills with statements rather than chatter or one-word acks. @@ -428,6 +463,76 @@ static RULES: Lazy> = Lazy::new(|| { Low, "explicit-remember", ), + // Ideas / aspirations — softer, forward-looking language the user + // muses about ("we should…", "what if we…", "might want to…"). Kept + // LOWER priority than facts/decisions/rules so those still win; this + // block upgrades what would otherwise be a low-value raw observation + // into a first-class, listable `idea`. Non-anchored `\b…` variants + // catch the cue mid-sentence (e.g. "…app we might want to do X"). + ( + r"^idea[:\-] ", + "idea", + Project, + 6.0, + Low, + "explicit-idea", + ), + ( + r"\b(one|another|quick|random|cool) idea\b", + "idea", + Project, + 6.0, + Low, + "explicit-idea", + ), + ( + r"^what if we ", + "idea", + Project, + 6.0, + Low, + "idea-what-if", + ), + ( + r"\bwe (might|may) want to ", + "idea", + Project, + 6.0, + Low, + "idea-aspiration", + ), + ( + r"\b(i'?m|we'?re) thinking (we|that|about|maybe) ", + "idea", + Project, + 6.0, + Low, + "idea-thinking", + ), + ( + r"\bwe (should|could|ought to) ", + "idea", + Project, + 5.0, + Low, + "idea-suggestion", + ), + ( + r"\bit would be (nice|good|great|cool|helpful|useful) (to|if) ", + "idea", + Project, + 5.0, + Low, + "idea-wish", + ), + ( + r"\b(eventually|someday|down the road|at some point) we ", + "idea", + Project, + 5.0, + Low, + "idea-future", + ), ]; rules diff --git a/crates/desktop/Cargo.toml b/crates/desktop/Cargo.toml new file mode 100644 index 0000000..31ed582 --- /dev/null +++ b/crates/desktop/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "memmesh-desktop" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +publish = false + +[[bin]] +name = "memmesh-desktop" +path = "src/main.rs" + +[dependencies] +# The engine + console, embedded in-process — the desktop IS the Rust app. +memory-core.workspace = true +memory-embed = { workspace = true, features = ["fastembed"] } +memory-storage.workspace = true +memory-server.workspace = true +anyhow.workspace = true +tokio.workspace = true +tracing-subscriber.workspace = true +# Native window + system webview (no browser, no Tauri CLI, no Node). +tao = "0.30" +wry = "0.45" diff --git a/crates/desktop/src/main.rs b/crates/desktop/src/main.rs new file mode 100644 index 0000000..285c945 --- /dev/null +++ b/crates/desktop/src/main.rs @@ -0,0 +1,96 @@ +// Copyright 2026 Thinkfleet AI, LLC Licensed under the Apache License, Version 2.0. + +//! MemMesh Desktop — the Rust engine + the console UI in one native app. +//! +//! No browser, no Node, no Tauri CLI: the engine (`memory-server`) runs +//! in-process on a background tokio runtime, and a system webview (`wry`) +//! renders the same console UI the OSS `memmesh console` serves. One binary +//! that is the whole product. + +use anyhow::Result; +use memory_storage::Storage; +use std::net::{SocketAddr, TcpStream}; +use std::sync::Arc; +use std::time::Duration; + +const ADDR: &str = "127.0.0.1:7878"; + +fn main() -> Result<()> { + tracing_subscriber::fmt().with_writer(std::io::stderr).init(); + + // The engine + console HTTP server run on their own tokio runtime in a + // background thread — the native event loop must own the main thread. + std::thread::spawn(|| { + let rt = tokio::runtime::Runtime::new().expect("tokio runtime"); + if let Err(e) = rt.block_on(run_engine()) { + eprintln!("memmesh-desktop: engine failed: {e}"); + } + }); + + // Wait for the server to bind before pointing the webview at it. + wait_for_server(ADDR); + + run_window() +} + +/// Open the SQLite store, migrate, and serve the console REST API + UI. +async fn run_engine() -> Result<()> { + let db = default_db_path(); + let url = format!("sqlite://{db}?mode=rwc"); + let store = memory_storage::sqlite::SqliteStore::connect(&url).await?; + store.migrate().await?; + memory_server::serve_http(Arc::new(store), ADDR).await +} + +fn run_window() -> Result<()> { + use tao::{ + dpi::LogicalSize, + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, + }; + use wry::WebViewBuilder; + + let event_loop = EventLoop::new(); + let window = WindowBuilder::new() + .with_title("MemMesh") + .with_inner_size(LogicalSize::new(1220.0, 840.0)) + .with_min_inner_size(LogicalSize::new(760.0, 560.0)) + .build(&event_loop)?; + + let _webview = WebViewBuilder::new(&window) + .with_url(format!("http://{ADDR}")) + .build()?; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + if let Event::WindowEvent { + event: WindowEvent::CloseRequested, + .. + } = event + { + *control_flow = ControlFlow::Exit; + } + }); +} + +fn default_db_path() -> String { + if let Some(home) = std::env::var_os("HOME") { + let dir = std::path::Path::new(&home).join(".memmesh"); + std::fs::create_dir_all(&dir).ok(); + return dir.join("memory.db").to_string_lossy().to_string(); + } + "./memory.db".to_string() +} + +/// Poll the console port for readiness (embedding-model load can take a few +/// seconds on cold start). +fn wait_for_server(addr: &str) { + let sa: SocketAddr = addr.parse().expect("valid addr"); + for _ in 0..60 { + if TcpStream::connect_timeout(&sa, Duration::from_millis(200)).is_ok() { + return; + } + std::thread::sleep(Duration::from_millis(400)); + } +} diff --git a/crates/mcp/src/lib.rs b/crates/mcp/src/lib.rs index 27c8712..a0e1c05 100644 --- a/crates/mcp/src/lib.rs +++ b/crates/mcp/src/lib.rs @@ -123,6 +123,22 @@ pub async fn run_stdio(storage: Arc, license: License) -> Result< Ok(()) } +/// Handle a single JSON-RPC message (raw string) and return the serialized +/// response value, or `None` for notifications (which get no response). Shared +/// by the stdio loop and the Streamable-HTTP transport in `memory-server`. +pub async fn handle_message( + message: &str, + storage: &S, + license: &License, +) -> Option { + handle_line(message, storage, license).await.map(|resp| { + serde_json::to_value(resp).unwrap_or_else(|e| { + json!({ "jsonrpc": "2.0", "id": null, + "error": { "code": -32603, "message": e.to_string() } }) + }) + }) +} + // Both early-return blocks below check id-presence and need readable control // flow with side effects (tracing). The clippy `?` rewrite hides intent. #[allow(clippy::question_mark)] @@ -165,17 +181,30 @@ async fn handle_line( } let response = match req.method.as_str() { - "initialize" => JsonRpcResponse::ok( - req.id, - json!({ - "protocolVersion": PROTOCOL_VERSION, - "capabilities": { "tools": {} }, - "serverInfo": { - "name": SERVER_NAME, - "version": SERVER_VERSION, - } - }), - ), + "initialize" => { + // Echo the client's requested protocol version when present. stdio + // clients (Claude Code) send 2024-11-05; Streamable-HTTP clients + // (ChatGPT / Claude.ai connectors) negotiate newer revisions + // (2025-03-26 / 2025-06-18). Our tool surface is compatible across + // all of them, so echoing avoids a version-mismatch rejection. + let negotiated = req + .params + .get("protocolVersion") + .and_then(|v| v.as_str()) + .unwrap_or(PROTOCOL_VERSION) + .to_string(); + JsonRpcResponse::ok( + req.id, + json!({ + "protocolVersion": negotiated, + "capabilities": { "tools": {} }, + "serverInfo": { + "name": SERVER_NAME, + "version": SERVER_VERSION, + } + }), + ) + } "tools/list" => JsonRpcResponse::ok(req.id, json!({ "tools": tool_definitions() })), @@ -373,6 +402,35 @@ fn tool_definitions() -> serde_json::Value { "dryRun": { "type": "boolean", "default": false, "description": "Preview collapses without writing." } } } + }, + { + "name": "memory_secret_list", + "description": "List the names/kinds/descriptions of credentials in the encrypted vault. NEVER returns values — you cannot read a secret, only reference it. Use before secret_run to see what's available.", + "inputSchema": { "type": "object", "properties": {} } + }, + { + "name": "memory_secret_request", + "description": "Check whether a credential is available and, if not, get a link that prompts the USER to add it in the vault. Call this when you need a credential (API key, password, token…). Returns status only — never a value. Pass `kind` so the vault shows the right entry form for that credential. If missing, relay the returned link (or `memmesh secret set `); NEVER ask the user to paste a secret into the chat.", + "inputSchema": { + "type": "object", + "required": ["name"], + "properties": { + "name": { "type": "string", "description": "Reference name, e.g. 'aws-prod'." }, + "kind": { "type": "string", "enum": ["api_key","password","basic_auth","oauth2","connection_string","ssh_key","token","custom"], "description": "What kind of credential this is, so the vault renders the matching form (single value, username+password, DSN, key, etc.). Multi-field kinds are referenced field-wise as {{memmesh:NAME|field}}." }, + "purpose": { "type": "string", "description": "Why you need it (shown to the user)." } + } + } + }, + { + "name": "memory_secret_run", + "description": "Execute-through-vault: run a shell command that references vault secrets as {{memmesh:NAME}} placeholders. The engine substitutes the real values IN ITS OWN PROCESS, runs the command, and returns stdout/stderr with every secret value scrubbed to [redacted]. This is the ONLY way to use a secret — you never receive the plaintext. Example command: \"aws s3 ls --profile {{memmesh:aws-prod}}\".", + "inputSchema": { + "type": "object", + "required": ["command"], + "properties": { + "command": { "type": "string", "description": "Shell command containing {{memmesh:NAME}} references." } + } + } } ]) } @@ -540,10 +598,74 @@ async fn handle_tool_call( Ok(text_result(&summary)) } + // ── Secrets vault (the AI references, never reads) ────────── + "memory_secret_list" => { + let vault = open_vault().await?; + let secrets = vault.list().await?; + Ok(text_result(&serde_json::to_string_pretty(&secrets)?)) + } + + "memory_secret_request" => { + let name = args.get("name").and_then(|v| v.as_str()).unwrap_or_default(); + if name.is_empty() { + return Ok(text_result("error: 'name' is required")); + } + let purpose = args.get("purpose").and_then(|v| v.as_str()).unwrap_or("(unspecified)"); + let vault = open_vault().await?; + if vault.exists(name).await? { + Ok(text_result(&format!( + "Secret '{name}' is available. Use it by calling memory_secret_run with \ + {{{{memmesh:{name}}}}} in the command — you will never see its value." + ))) + } else { + let purpose_enc = purpose.replace(' ', "%20"); + // Optional credential kind so the vault shows the right form + // (api_key / password / basic_auth / oauth2 / connection_string / + // ssh_key / token / custom). + let kind = args.get("kind").and_then(|v| v.as_str()).unwrap_or(""); + let kind_param = if kind.is_empty() { + String::new() + } else { + format!("&kind={}", kind.replace(' ', "%20")) + }; + Ok(text_result(&format!( + "Secret '{name}' is NOT set (purpose: {purpose}). Prompt the user to enter it \ + securely — DO NOT ask them to paste the value into the chat. Give them this \ + one-click link, which opens the memmesh console's Vault tab with a focused \ + entry form (fields matched to the credential kind, name pre-filled):\n\n http://127.0.0.1:7878/?tab=vault&add={name}&purpose={purpose_enc}{kind_param}\n\n\ + Or they can run `memmesh secret set {name}`. Once they've added it, retry \ + using {{{{memmesh:{name}}}}} via memory_secret_run." + ))) + } + } + + "memory_secret_run" => { + let command = args.get("command").and_then(|v| v.as_str()).unwrap_or_default(); + if command.is_empty() { + return Ok(text_result("error: 'command' is required")); + } + let vault = open_vault().await?; + match vault.run(command).await { + Ok(r) => Ok(text_result(&serde_json::to_string_pretty(&serde_json::json!({ + "exitCode": r.exit_code, + "stdout": r.stdout, + "stderr": r.stderr, + "usedSecrets": r.used, + "note": "secret values are scrubbed from this output", + }))?)), + Err(e) => Ok(text_result(&format!("secret_run failed: {e}"))), + } + } + other => anyhow::bail!("unknown tool: {other}"), } } +/// Open the encrypted secrets vault (its own store + keychain-backed key). +async fn open_vault() -> anyhow::Result { + memory_storage::vault::Vault::open(&memory_storage::vault::Vault::default_path()).await +} + // ─── Extraction tools (PR F) ───────────────────────────────────────── // // Two-step protocol: extract_pending hands raw text + a deterministic diff --git a/crates/server/src/http.rs b/crates/server/src/http.rs index 683faff..3b563c4 100644 --- a/crates/server/src/http.rs +++ b/crates/server/src/http.rs @@ -33,7 +33,7 @@ use axum::{ extract::{Path, Query, State}, http::StatusCode, response::{Html, IntoResponse, Json}, - routing::{get, post}, + routing::{delete, get, post}, Router, }; use memory_core::{ @@ -743,6 +743,78 @@ async fn get_bindings(State(s): State>) -> axum::respons } } +// ── /vault (encrypted secrets — the console entry point) ──── + +async fn open_vault_or_err() -> Result { + memory_storage::vault::Vault::open(&memory_storage::vault::Vault::default_path()) + .await + .map_err(|e| err("vault_open", StatusCode::INTERNAL_SERVER_ERROR, e.to_string())) +} + +async fn get_vault() -> axum::response::Response { + let vault = match open_vault_or_err().await { + Ok(v) => v, + Err(r) => return r, + }; + match vault.list().await { + Ok(list) => Json(list).into_response(), + Err(e) => err("vault", StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + } +} + +#[derive(Deserialize)] +struct AddSecretBody { + name: String, + value: String, + kind: Option, + description: Option, +} + +async fn add_vault(Json(b): Json) -> axum::response::Response { + if b.name.trim().is_empty() || b.value.is_empty() { + return err("bad_request", StatusCode::BAD_REQUEST, "name and value are required"); + } + let vault = match open_vault_or_err().await { + Ok(v) => v, + Err(r) => return r, + }; + match vault + .set(b.name.trim(), &b.value, b.kind.as_deref(), b.description.as_deref(), Some("user"), None) + .await + { + Ok(()) => Json(json!({ "ok": true, "name": b.name.trim() })).into_response(), + Err(e) => err("vault_write", StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + } +} + +/// Reveal a secret's plaintext to the **human** at the loopback console (for +/// copy/paste of their own credential). Deliberately NOT exposed to the AI — +/// there is no MCP equivalent; the model only ever gets scrubbed `secret_run` +/// output. +async fn reveal_vault(Path(name): Path) -> axum::response::Response { + let vault = match open_vault_or_err().await { + Ok(v) => v, + Err(r) => return r, + }; + match vault.reveal(&name).await { + Ok(Some(value)) => Json(json!({ "name": name, "value": value })).into_response(), + Ok(None) => err("not_found", StatusCode::NOT_FOUND, name), + Err(e) => err("vault_reveal", StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + } +} + +async fn delete_vault(Path(name): Path) -> axum::response::Response { + let vault = match open_vault_or_err().await { + Ok(v) => v, + Err(r) => return r, + }; + match vault.delete(&name).await { + Ok(true) => Json(json!({ "ok": true })).into_response(), + Ok(false) => err("not_found", StatusCode::NOT_FOUND, name), + Err(e) => err("vault_delete", StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + } +} + // ── Public entrypoint ─────────────────────────────────────── /// Build the HTTP router. Caller owns binding + serving so the same router @@ -767,6 +839,9 @@ pub fn router(storage: Arc) -> Router { .route("/sync", get(get_sync)) .route("/sync/run", post(run_sync)) .route("/bindings", get(get_bindings)) + .route("/vault", get(get_vault).post(add_vault)) + .route("/vault/:name", delete(delete_vault)) + .route("/vault/:name/reveal", get(reveal_vault)) .route("/database", get(get_database).put(put_database)) .route("/database/test", post(test_database)) .route("/database/copy", post(copy_database)) diff --git a/crates/server/src/lib.rs b/crates/server/src/lib.rs index 5178b24..49e052b 100644 --- a/crates/server/src/lib.rs +++ b/crates/server/src/lib.rs @@ -12,12 +12,25 @@ //! - gRPC server lands in v1.1 alongside the sync engine. mod http; +mod mcp_http; use anyhow::Result; use memory_license::License; use memory_storage::Storage; use std::sync::Arc; +/// Run the remote MCP server over Streamable HTTP (for ChatGPT / Claude.ai +/// custom connectors). Requires a bearer `token` on every request; meant to +/// be exposed publicly via a tunnel. Binds `addr` and blocks until cancelled. +pub async fn serve_mcp_http( + storage: Arc, + license: License, + addr: &str, + token: String, +) -> Result<()> { + mcp_http::serve_mcp_http(storage, license, addr, token).await +} + /// Run the MCP stdio server, dispatching tool calls to the given storage /// backend. `license` gates every write-path tool so callers can't grow /// memory past their plan's cap. Blocks until stdin closes. diff --git a/crates/server/src/mcp_http.rs b/crates/server/src/mcp_http.rs new file mode 100644 index 0000000..83fe898 --- /dev/null +++ b/crates/server/src/mcp_http.rs @@ -0,0 +1,104 @@ +// Copyright 2026 Thinkfleet AI, LLC Licensed under the Apache License, Version 2.0. + +//! Remote MCP server over **Streamable HTTP** — the transport ChatGPT and +//! Claude.ai custom connectors require (a local stdio server can't be +//! registered directly). This is deliberately separate from the loopback +//! console (`http.rs`, no auth): the remote MCP endpoint is meant to be +//! exposed publicly via a tunnel, so it **requires a bearer token** on every +//! request. +//! +//! Endpoints: +//! POST /mcp — one JSON-RPC message per request; returns the JSON-RPC +//! response as `application/json`, or `202` for +//! notifications. Requires `Authorization: Bearer `. +//! GET /mcp — 405 (we don't do server-initiated SSE streams). +//! GET /health — unauthed liveness for tunnel/uptime checks. +//! +//! Stateless: no `Mcp-Session-Id` is issued — every request is handled +//! independently, which the MCP spec permits and our tools allow. + +use axum::{ + extract::State, + http::{HeaderMap, StatusCode}, + response::{IntoResponse, Json}, + routing::{get, post}, + Router, +}; +use memory_license::License; +use memory_storage::Storage; +use serde_json::json; +use std::sync::Arc; + +struct McpState { + storage: Arc, + license: Arc, + token: Arc, +} + +impl Clone for McpState { + fn clone(&self) -> Self { + Self { + storage: self.storage.clone(), + license: self.license.clone(), + token: self.token.clone(), + } + } +} + +fn authorized(headers: &HeaderMap, token: &str) -> bool { + headers + .get(axum::http::header::AUTHORIZATION) + .and_then(|h| h.to_str().ok()) + .map(|h| h.strip_prefix("Bearer ").unwrap_or(h).trim() == token) + .unwrap_or(false) +} + +async fn mcp_post( + State(st): State>, + headers: HeaderMap, + body: String, +) -> axum::response::Response { + if !authorized(&headers, &st.token) { + return ( + StatusCode::UNAUTHORIZED, + Json(json!({ "error": "unauthorized — send Authorization: Bearer " })), + ) + .into_response(); + } + match memory_mcp::handle_message(&body, st.storage.as_ref(), &st.license).await { + // Request → JSON-RPC response as application/json. + Some(value) => (StatusCode::OK, Json(value)).into_response(), + // Notification → no body, per JSON-RPC / MCP. + None => StatusCode::ACCEPTED.into_response(), + } +} + +/// Serve the remote MCP endpoint on `addr`, gated by `token`. Blocks until +/// cancelled. +pub async fn serve_mcp_http( + storage: Arc, + license: License, + addr: &str, + token: String, +) -> anyhow::Result<()> { + let state = McpState { + storage, + license: Arc::new(license), + token: Arc::new(token), + }; + let app = Router::new() + .route( + "/mcp", + post(mcp_post::).get(|| async { StatusCode::METHOD_NOT_ALLOWED }), + ) + .route( + "/health", + get(|| async { Json(json!({ "name": "memmesh-mcp", "status": "ok" })) }), + ) + .with_state(state); + + let listener = tokio::net::TcpListener::bind(addr).await?; + tracing::info!(addr = %addr, "remote MCP (Streamable HTTP) server listening"); + axum::serve(listener, app).await?; + Ok(()) +} diff --git a/crates/server/src/ui/index.html b/crates/server/src/ui/index.html index 8e6a522..641b8b6 100644 --- a/crates/server/src/ui/index.html +++ b/crates/server/src/ui/index.html @@ -102,6 +102,26 @@ .covbar { background: var(--panel-2); border-radius: 6px; height: 14px; overflow: hidden; } .covbar span { display: block; height: 100%; background: var(--ok); } .cov #covText { margin-top: 6px; } + .reveal-box { margin-top: 8px; } + .secret-val { font-family: var(--mono); font-size: 12px; background: var(--panel-2); border: 1px dashed var(--warn); color: var(--fg); padding: 5px 9px; border-radius: 6px; word-break: break-all; user-select: all; display: inline-block; } + /* Focused credential-request card (the AI-prompt landing) */ + .reqcard { background: var(--panel); border: 1px solid var(--accent); border-radius: 14px; padding: 22px 24px; margin-bottom: 20px; max-width: 560px; box-shadow: 0 8px 30px color-mix(in srgb, var(--accent) 14%, transparent); } + .reqhead { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 18px; } + .reqicon { font-size: 26px; line-height: 1; } + .reqtitle { font-size: 17px; font-weight: 700; } + .reqsub { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.45; } + .fieldlabel { display: block; font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; margin: 12px 0 5px; } + .fieldlabel input { display: block; width: 100%; margin-top: 5px; text-transform: none; letter-spacing: 0; font-weight: 400; } + .reqname { font-family: var(--mono); font-size: 15px; font-weight: 600; color: var(--accent); background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; padding: 9px 12px; } + .reqkind { font-family: system-ui, sans-serif; font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; margin-left: 6px; } + .valrow { display: flex; gap: 8px; align-items: stretch; } + .valrow input { flex: 1; font-family: var(--mono); } + .iconbtn { flex: none; min-width: 52px; } + .reqactions { display: flex; gap: 10px; align-items: center; margin-top: 18px; } + .reqcard.saved { border-color: var(--ok); box-shadow: 0 8px 30px color-mix(in srgb, var(--ok) 16%, transparent); } + details.addsecret { padding: 14px 16px; } + details.addsecret summary { cursor: pointer; font-weight: 600; color: var(--fg); font-size: 13px; } + .formgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin-top: 10px; } .pg { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; } .pgcol .item { padding: 9px 11px; } @media (max-width: 720px) { .pg { grid-template-columns: 1fr; } } @@ -119,6 +139,8 @@ + + @@ -193,6 +215,58 @@

   
 
+  
+  
+
+  
+  
+