diff --git a/Cargo.lock b/Cargo.lock index fcb3151..5d4d33a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,50 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.6.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" +dependencies = [ + "crypto-common 0.2.2", + "inout", +] + +[[package]] +name = "aes" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" +dependencies = [ + "cipher", + "cpubits", + "cpufeatures 0.3.0", +] + +[[package]] +name = "aes-gcm" +version = "0.11.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da8c919c118108f144adecad74b425b804ad075580d605d9b33c2d6d1c62a2f8" +dependencies = [ + "aead", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-kw" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ac571010bd60765c56085a4f1d412012a9be2663b1a2f2b19b49318653fd0d" +dependencies = [ + "aes", + "const-oid", +] + [[package]] name = "ahash" version = "0.8.12" @@ -153,6 +197,21 @@ dependencies = [ "equator", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -285,7 +344,7 @@ dependencies = [ "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.59.0", "x11rb", ] @@ -654,12 +713,34 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "base16ct" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "bincode" version = "2.0.1" @@ -720,6 +801,33 @@ dependencies = [ "no_std_io2", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "block-padding" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.5.1" @@ -761,6 +869,27 @@ dependencies = [ "cfg_aliases", ] +[[package]] +name = "brotli" +version = "8.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8119e4516436f5708bbc474a9d395bf12f1b5395e93a92a56e647ac3388c8610" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "built" version = "0.8.0" @@ -862,6 +991,15 @@ dependencies = [ "wayland-client", ] +[[package]] +name = "cbc" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.2.62" @@ -904,6 +1042,17 @@ dependencies = [ "libc", ] +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" version = "0.4.44" @@ -917,6 +1066,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "cipher" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.2", + "inout", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -986,6 +1146,12 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "color_quant" version = "1.1.0" @@ -1038,6 +1204,12 @@ dependencies = [ "syn", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "convert_case" version = "0.10.0" @@ -1047,6 +1219,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "copypasta" version = "0.10.2" @@ -1126,6 +1307,39 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1181,6 +1395,53 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-bigint" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" +dependencies = [ + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "crypto-primes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21f41f23de7d24cdbda7f0c4d9c0351f99a4ceb258ef30e5c1927af8987ffe5a" +dependencies = [ + "crypto-bigint", + "libm", + "rand_core 0.10.1", +] + [[package]] name = "ctor" version = "0.10.1" @@ -1190,12 +1451,58 @@ dependencies = [ "dtor", ] +[[package]] +name = "ctr" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", +] + [[package]] name = "cursor-icon" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +[[package]] +name = "curve25519-dalek" +version = "5.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f359e08ca85e7bd759e1fd933ff2bccd81864c60a8fba0e259c7f822b0924bf" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "curve25519-dalek-derive", + "digest 0.11.3", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dark-light" version = "2.0.0" @@ -1216,6 +1523,29 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" +[[package]] +name = "der" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +dependencies = [ + "const-oid", + "der_derive", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59600e2c2d636fde9b65e99cc6445ac770c63d3628195ff39932b8d6d7409903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_arbitrary" version = "1.4.2" @@ -1242,7 +1572,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ - "convert_case", + "convert_case 0.10.0", "proc-macro2", "quote", "rustc_version", @@ -1261,6 +1591,28 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "const-oid", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "directories" version = "6.0.0" @@ -1300,7 +1652,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1397,12 +1749,73 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b" +[[package]] +name = "ecdsa" +version = "0.17.0-rc.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54fb064faabbee66e1fc8e5c5a9458d4269dc2d8b638fe86a425adb2510d1a96" +dependencies = [ + "der", + "digest 0.11.3", + "elliptic-curve", + "rfc6979", + "signature", + "zeroize", +] + +[[package]] +name = "ed25519" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "3.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.10.1", + "serde", + "sha2 0.11.0", + "signature", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "elliptic-curve" +version = "0.14.0-rc.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "102d3643d30dd8b559613c5cced68317199597fffb278cdc88daa2ef7fafc935" +dependencies = [ + "base16ct", + "crypto-bigint", + "crypto-common 0.2.2", + "digest 0.11.3", + "ff", + "group", + "hkdf", + "hybrid-array", + "pkcs8", + "rand_core 0.10.1", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "endi" version = "1.1.1" @@ -1463,7 +1876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1577,13 +1990,29 @@ dependencies = [ ] [[package]] -name = "field-offset" -version = "0.3.6" +name = "ff" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "memoffset", - "rustc_version", + "rand_core 0.10.1", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" + +[[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]] @@ -1618,6 +2047,15 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +[[package]] +name = "float-cmp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" +dependencies = [ + "num-traits", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1852,6 +2290,16 @@ dependencies = [ "libc", ] +[[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 = "gethostname" version = "1.1.0" @@ -1907,10 +2355,20 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.1", "wasip2", "wasip3", ] +[[package]] +name = "ghash" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" +dependencies = [ + "polyval", +] + [[package]] name = "gif" version = "0.14.2" @@ -2051,6 +2509,36 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" +[[package]] +name = "group" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" +dependencies = [ + "ff", + "rand_core 0.10.1", + "subtle", +] + +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.7.1" @@ -2062,6 +2550,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "halfbrown" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed2f2edad8a14c8186b847909a41fbb9c3eafa44f88bd891114ed5019da09" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "harfrust" version = "0.5.2" @@ -2109,6 +2606,11 @@ name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -2143,6 +2645,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f7685beb53fc20efc2605f32f5d51e9ba18b8ef237961d1760169d2290d3bee" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "high-beam" version = "0.3.1" @@ -2157,6 +2669,23 @@ dependencies = [ "freedesktop-icons", "global-hotkey", "image", + "llrt_abort", + "llrt_buffer", + "llrt_child_process", + "llrt_crypto", + "llrt_exceptions", + "llrt_fetch", + "llrt_fs", + "llrt_intl", + "llrt_os", + "llrt_path", + "llrt_process", + "llrt_stream_web", + "llrt_string_decoder", + "llrt_temporal", + "llrt_url", + "llrt_util", + "llrt_zlib", "nucleo-matcher", "objc2 0.5.2", "objc2-app-kit 0.2.2", @@ -2184,6 +2713,33 @@ dependencies = [ "zip", ] +[[package]] +name = "hkdf" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "htmlparser" version = "0.2.1" @@ -2229,6 +2785,17 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" version = "1.9.0" @@ -2239,6 +2806,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -2569,7 +3137,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] @@ -2808,6 +3376,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "block-padding", + "hybrid-array", +] + [[package]] name = "input" version = "0.9.1" @@ -2913,6 +3491,47 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jiff" +version = "0.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link 0.2.1", +] + +[[package]] +name = "jiff-static" +version = "0.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "jni" version = "0.22.4" @@ -2993,6 +3612,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "junction" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "160f2eade097f30263b548aae5deb12ad349c909baa710fa24b92c9090b2e006" +dependencies = [ + "scopeguard", + "windows-sys 0.59.0", +] + [[package]] name = "keyboard-types" version = "0.7.0" @@ -3159,6 +3788,454 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +[[package]] +name = "llrt_abort" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_async_hooks", + "llrt_events", + "llrt_exceptions", + "llrt_timers", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_async_hooks" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_hooking", + "llrt_utils", + "rquickjs", + "tracing", +] + +[[package]] +name = "llrt_buffer" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "llrt_encoding", + "llrt_stream_web", + "llrt_utils", + "rquickjs", + "ryu", +] + +[[package]] +name = "llrt_build" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "llrt_child_process" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "libc", + "llrt_buffer", + "llrt_context", + "llrt_events", + "llrt_stream", + "llrt_utils", + "rquickjs", + "tokio", +] + +[[package]] +name = "llrt_compression" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "brotli", + "flate2", + "zstd", +] + +[[package]] +name = "llrt_context" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_build", + "llrt_utils", + "rquickjs", + "tokio", + "tracing", +] + +[[package]] +name = "llrt_crypto" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "aes", + "aes-gcm", + "aes-kw", + "cbc", + "const-oid", + "crc32c", + "crc32fast", + "ctr", + "der", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "hkdf", + "hmac", + "llrt_buffer", + "llrt_context", + "llrt_encoding", + "llrt_json", + "llrt_utils", + "md-5", + "once_cell", + "p256", + "p384", + "p521", + "pbkdf2", + "pkcs8", + "rand 0.10.1", + "rquickjs", + "rsa", + "sha1", + "spki", + "x25519-dalek", +] + +[[package]] +name = "llrt_dns_cache" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "hyper-util", + "llrt_context", + "llrt_utils", + "quick_cache", + "tokio", + "tower-service", +] + +[[package]] +name = "llrt_encoding" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "base64-simd", + "hex-simd", + "llrt_build", + "memchr", + "phf", +] + +[[package]] +name = "llrt_events" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_utils", + "rquickjs", + "tracing", +] + +[[package]] +name = "llrt_exceptions" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_fetch" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "bytes", + "either", + "http-body", + "http-body-util", + "hyper", + "itoa", + "llrt_abort", + "llrt_buffer", + "llrt_compression", + "llrt_context", + "llrt_encoding", + "llrt_http", + "llrt_json", + "llrt_stream_web", + "llrt_url", + "llrt_utils", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rand 0.10.1", + "rquickjs", + "sha2 0.10.9", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "llrt_fs" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "either", + "junction", + "llrt_buffer", + "llrt_encoding", + "llrt_path", + "llrt_utils", + "rand 0.10.1", + "rquickjs", + "tokio", +] + +[[package]] +name = "llrt_hooking" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_utils", + "once_cell", + "rquickjs", +] + +[[package]] +name = "llrt_http" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "llrt_dns_cache", + "llrt_tls", + "llrt_utils", + "once_cell", + "rquickjs", + "rustls", +] + +[[package]] +name = "llrt_intl" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "jiff", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_json" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "llrt_build", + "llrt_utils", + "rquickjs", + "ryu", + "simd-json", +] + +[[package]] +name = "llrt_logging" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "llrt_context", + "llrt_encoding", + "llrt_json", + "llrt_numbers", + "llrt_utils", + "rquickjs", + "ryu", +] + +[[package]] +name = "llrt_numbers" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "itoa", + "llrt_utils", + "rquickjs", + "ryu", +] + +[[package]] +name = "llrt_os" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "home", + "libc", + "llrt_utils", + "num_cpus", + "once_cell", + "rquickjs", + "sysinfo", + "users", + "whoami", + "windows-registry", + "windows-result 0.4.1", + "windows-version", +] + +[[package]] +name = "llrt_path" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_utils", + "memchr", + "rquickjs", +] + +[[package]] +name = "llrt_process" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "libc", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_stream" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_buffer", + "llrt_context", + "llrt_events", + "llrt_utils", + "rquickjs", + "tokio", +] + +[[package]] +name = "llrt_stream_web" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_abort", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_string_decoder" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_buffer", + "llrt_encoding", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_temporal" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "jiff", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_timers" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_context", + "llrt_hooking", + "llrt_utils", + "once_cell", + "rquickjs", + "tokio", +] + +[[package]] +name = "llrt_tls" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "once_cell", + "rustls", + "tracing", + "webpki-roots", +] + +[[package]] +name = "llrt_url" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_utils", + "rquickjs", + "url", +] + +[[package]] +name = "llrt_util" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_context", + "llrt_encoding", + "llrt_logging", + "llrt_utils", + "rquickjs", +] + +[[package]] +name = "llrt_utils" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "libc", + "llrt_build", + "memchr", + "rquickjs", + "simdutf8", + "tokio", + "tracing", + "windows-sys 0.61.2", +] + +[[package]] +name = "llrt_zlib" +version = "0.8.1-beta" +source = "git+https://github.com/awslabs/llrt?rev=5af6d48ee7258cb222d7b3081276d297606afc05#5af6d48ee7258cb222d7b3081276d297606afc05" +dependencies = [ + "llrt_buffer", + "llrt_compression", + "llrt_context", + "llrt_utils", + "rquickjs", +] + [[package]] name = "lock_api" version = "0.4.14" @@ -3252,6 +4329,16 @@ dependencies = [ "rayon", ] +[[package]] +name = "md-5" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" +dependencies = [ + "cfg-if", + "digest 0.11.3", +] + [[package]] name = "memchr" version = "2.8.0" @@ -3420,6 +4507,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + [[package]] name = "nucleo-matcher" version = "0.3.1" @@ -3481,6 +4577,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi 0.5.2", + "libc", +] + [[package]] name = "num_enum" version = "0.7.6" @@ -3737,6 +4843,16 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "objc2-io-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" +dependencies = [ + "libc", + "objc2-core-foundation", +] + [[package]] name = "objc2-io-surface" version = "0.3.2" @@ -3931,6 +5047,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -3940,6 +5062,47 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "p256" +version = "0.14.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41adc63effe99d48837a8cc0e6d7a77e32ae6a07f6000df466178dbc2193093e" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primefield", + "primeorder", + "sha2 0.11.0", +] + +[[package]] +name = "p384" +version = "0.14.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd5333afa5ae0347f39e6a0f2c9c155da431583fd71fe5555bd0521b4ccaf02" +dependencies = [ + "ecdsa", + "elliptic-curve", + "fiat-crypto", + "primefield", + "primeorder", + "sha2 0.11.0", +] + +[[package]] +name = "p521" +version = "0.14.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3a5297f53dc16d35909060ba3032cff7867e8809f01e273ff325579d5f0ceae" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primefield", + "primeorder", + "sha2 0.11.0", +] + [[package]] name = "parking" version = "2.2.1" @@ -4021,10 +5184,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "pbkdf2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" +dependencies = [ + "digest 0.11.3", +] + +[[package]] +name = "pem-rfc7468" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] [[package]] name = "pico-args" @@ -4081,6 +5304,26 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs1" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.33" @@ -4142,6 +5385,17 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "polyval" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede" +dependencies = [ + "cpubits", + "cpufeatures 0.3.0", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -4151,6 +5405,15 @@ dependencies = [ "critical-section", ] +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + [[package]] name = "potential_utf" version = "0.1.5" @@ -4181,6 +5444,29 @@ dependencies = [ "syn", ] +[[package]] +name = "primefield" +version = "0.14.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f845ec3240cd5ed5e1e31cf3ff633a5bf47c698dc4092ba9e767415b3d393406" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d2793f22b9b6fd11ef3ac1d59bf003c2573593e4968702341605c2748fd90bf" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -4268,6 +5554,16 @@ dependencies = [ "serde", ] +[[package]] +name = "quick_cache" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c821816e9b928e20e92ed59bb3ac4aab321d16ca2316871c9fe7ca739cd477" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + [[package]] name = "quinn" version = "0.11.9" @@ -4320,7 +5616,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -4365,6 +5661,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -4403,6 +5710,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rav1e" version = "0.8.1" @@ -4551,6 +5864,26 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.12.3" @@ -4644,6 +5977,16 @@ dependencies = [ "zune-jpeg", ] +[[package]] +name = "rfc6979" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5236ce872cac07e0fb3969b0cbf468c7d2f37d432f1b627dcb7b8d34563fb0c3" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "rgb" version = "0.8.53" @@ -4690,33 +6033,35 @@ dependencies = [ [[package]] name = "rquickjs" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50dc6d6c587c339edb4769cf705867497a2baf0eca8b4645fa6ecd22f02c77a" +checksum = "c0688f8b0192998cca685adefdfad3483da295fa40a0ec406b4c14ecd729e858" dependencies = [ + "either", "rquickjs-core", "rquickjs-macro", ] [[package]] name = "rquickjs-core" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8bf7840285c321c3ab20e752a9afb95548c75cd7f4632a0627cea3507e310c1" +checksum = "2fee8c5383f0cfda3b980a80ca4520e726e09b593c59562f579daa51b6c20411" dependencies = [ "async-lock", - "hashbrown 0.16.1", + "either", + "hashbrown 0.17.1", "relative-path", "rquickjs-sys", ] [[package]] name = "rquickjs-macro" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7106215ff41a5677b104906a13e1a440b880f4b6362b5dc4f3978c267fad2b80" +checksum = "04e6cf4b6e695b526cb430a6f445d3ccb9908696b99f1c1f8a1480af38bed5e6" dependencies = [ - "convert_case", + "convert_case 0.11.0", "fnv", "ident_case", "indexmap", @@ -4729,13 +6074,32 @@ dependencies = [ [[package]] name = "rquickjs-sys" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27344601ef27460e82d6a4e1ecb9e7e99f518122095f3c51296da8e9be2b9d83" +checksum = "698077537c286a169de8693b216672bcef148bf2e2e112ebf50758c68e9afa09" dependencies = [ "cc", ] +[[package]] +name = "rsa" +version = "0.10.0-rc.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b2aa4ba0d89f73d1e332df05be0eeab8840351c36ca5654341dfdb57bb3caf" +dependencies = [ + "const-oid", + "crypto-bigint", + "crypto-primes", + "digest 0.11.3", + "pkcs1", + "pkcs8", + "rand_core 0.10.1", + "sha2 0.11.0", + "signature", + "spki", + "zeroize", +] + [[package]] name = "rspolib" version = "0.1.2" @@ -4817,7 +6181,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -4925,6 +6289,20 @@ dependencies = [ "tiny-skia 0.11.4", ] +[[package]] +name = "sec1" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" +dependencies = [ + "base16ct", + "ctutils", + "der", + "hybrid-array", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "1.0.28" @@ -5015,6 +6393,49 @@ dependencies = [ "serde", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -5040,12 +6461,34 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "digest 0.11.3", + "rand_core 0.10.1", +] + [[package]] name = "simd-adler32" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd-json" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4255126f310d2ba20048db6321c81ab376f6a6735608bf11f0785c41f01f64e3" +dependencies = [ + "halfbrown", + "ref-cast", + "simdutf8", + "value-trait", +] + [[package]] name = "simd_cesu8" version = "1.1.1" @@ -5345,6 +6788,16 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "spki" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -5363,7 +6816,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" dependencies = [ - "float-cmp", + "float-cmp 0.9.0", ] [[package]] @@ -5463,6 +6916,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "sysinfo" +version = "0.39.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21d0d938c10fcda3e897e28aaddf4ab462375d411f4378cd63b1c945f69aba96" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows 0.62.2", +] + [[package]] name = "taffy" version = "0.9.2" @@ -5496,7 +6963,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5928,6 +7395,12 @@ dependencies = [ "serde", ] +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + [[package]] name = "udev" version = "0.9.3" @@ -6023,6 +7496,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" +dependencies = [ + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -6048,6 +7531,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "users" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032" +dependencies = [ + "libc", +] + [[package]] name = "usvg" version = "0.47.0" @@ -6116,6 +7608,18 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" +[[package]] +name = "value-trait" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e80f0c733af0720a501b3905d22e2f97662d8eacfe082a75ed7ffb5ab08cb59" +dependencies = [ + "float-cmp 0.10.0", + "halfbrown", + "itoa", + "ryu", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -6128,6 +7632,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "vtable" version = "0.4.0" @@ -6469,15 +7979,43 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +[[package]] +name = "whoami" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +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", + "windows-sys 0.48.0", ] +[[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.61.3" @@ -6623,6 +8161,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -6770,6 +8319,15 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -7143,6 +8701,17 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" +[[package]] +name = "x25519-dalek" +version = "3.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17b575e04fcdb37e5509a85a14ff08116678a1c9724befb8b571db742dbdbb0" +dependencies = [ + "curve25519-dalek", + "rand_core 0.10.1", + "zeroize", +] + [[package]] name = "xattr" version = "1.6.1" @@ -7473,6 +9042,34 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "zune-core" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 87a8b03..fd4d82f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -167,7 +167,47 @@ serde_json = "1" # function* query()` without manual job-queue pumping # * `macro` — `#[rquickjs::module]` ergonomics for host modules # * `parallel` — required by `futures` for Send-able runtime handles -rquickjs = { version = "0.11", features = ["loader", "futures", "macro", "parallel"] } +rquickjs = { version = "0.12", features = ["loader", "futures", "macro", "parallel"] } + +# LLRT modules (AWS) supply the Node/Web API surface for the plugin +# runtime: node:path, node:fs, URL/URLSearchParams, Buffer, TextEncoder/ +# TextDecoder, AbortController/AbortSignal, DOMException, streams, fetch. +# Not published to crates.io; pinned to a rev of the llrt monorepo — keep +# every crate on the SAME rev (they share types across workspace-internal +# deps). llrt_timers is deliberately absent: its process-global timer table +# is keyed by raw runtime pointer and never deregistered, which leaks and +# aliases under our one-runtime-per-plugin + reload model. +# +# llrt_abort: its AbortSignal.timeout backend is forced to `sleep-timers` +# by feature unification (llrt_fetch depends on it with defaults), which +# routes into llrt_timers' unsound global table — the host replaces the +# static with a setTimeout-based impl at install (sdk/js/abort_timeout_patch.js). +# llrt_fetch: `compression-rust` swaps brotli/gzip/deflate to Rust impls; +# zstd has no pure-Rust impl and stays a C dep either way. `tls-ring` +# matches the rustls provider reqwest already links so the process has one +# CryptoProvider. +llrt_abort = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_buffer = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +# Gated behind the `subprocess` capability. child_process builds its stdio +# on llrt_stream's Rust stream constructors directly (no node:stream needed) +# and uses the Buffer global; process reads the daemon's real environment. +llrt_child_process = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_crypto = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_exceptions = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_fetch = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05", default-features = false, features = ["http1", "http2", "compression-rust", "webpki-roots", "tls-ring"] } +llrt_fs = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_intl = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_os = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_path = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_process = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_stream_web = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_string_decoder = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_temporal = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_url = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +llrt_util = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05" } +# compression-rust (not the default compression-c): keep the tree C-free, +# sharing llrt_fetch's backend choice. +llrt_zlib = { git = "https://github.com/awslabs/llrt", rev = "5af6d48ee7258cb222d7b3081276d297606afc05", default-features = false, features = ["compression-rust"] } # Single-threaded tokio drives the AsyncRuntime per query. tokio = { version = "1", features = ["rt", "macros", "time", "sync", "process", "io-util"] } diff --git a/docs/internals.md b/docs/internals.md index c53c017..8822916 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -16,7 +16,7 @@ see [plugin-authoring.md](./plugin-authoring.md) and |---|---|---| | Language | Rust (edition 2024) | Native binary, no GC, mature ecosystem for the pieces we need | | UI toolkit | Slint | Declarative `.slint` files with runtime-bound properties (good fit for theme tokens); winit windowing | -| Plugin runtime | rquickjs (QuickJS binding) | ~1 MB embed, pure ECMAScript (not Node), per-context memory caps, interrupt hooks for timeouts | +| Plugin runtime | rquickjs (QuickJS binding) + llrt module crates | ~1 MB embed, per-context memory caps, interrupt hooks for timeouts; the llrt crates supply the Node/Web API surface (`fetch`, `node:path`, `node:fs`, `URL`, web-streams, …) on top of bare QuickJS | | Persistence | SQLite via `rusqlite` | Frecency + query history; schemas versioned with `rusqlite_migration`. Boring, reliable. | | Global hotkey | `global-hotkey` (macOS); CLI `--open` (Linux) | Wayland has no portable global-hotkey API; punt to the WM. | @@ -30,7 +30,7 @@ fire-and-forget housekeeping. run here; other threads route through `slint::invoke_from_event_loop`. - **`highbeam-plugin-runtime`**: single-threaded tokio runtime that owns every loaded `LoadedPlugin` (rquickjs `AsyncContext`). Plugins - live here because rquickjs futures are `!Send` across `async_with!` + live here because rquickjs futures are `!Send` across `async_with` under the `parallel` feature, so they can't cross threads. - **`highbeam-ipc`**: blocks on the unix socket; hops back to the Slint thread to show the window. @@ -49,12 +49,17 @@ write paths. - On every keystroke (post-debounce), the host calls `cancel.cancel()` on the previous dispatch token, which both fires JS-side `AbortSignal` listeners and sets the rquickjs interrupt flag. -- All host APIs that do I/O (`http.get`, `fs.readDir`, `system.exec`, - etc.) accept an optional `signal` and honor it. +- I/O honors `AbortSignal`: `fetch` takes `init.signal`, the host APIs + (`fs.readDir`, `system.exec`, etc.) take an optional `signal`. The host + also injects a 30 s default timeout into every `fetch` via an + `AbortSignal`, which an explicit caller signal still overrides on abort. - CPU-bound plugins that block synchronously can't be cancelled gracefully. The per-plugin `timeoutMs` is the hard kill via the rquickjs interrupt hook. The watchdog runs on the blocking thread pool so a `while(true){}` JS body can't starve it. +- `setTimeout` is a host polyfill, not llrt's `llrt_timers`: that crate + keys its timer state on a process-global runtime pointer, which is unsound + under high-beam's one-runtime-per-plugin model. ## Frecency @@ -204,12 +209,16 @@ Considered seriously. Rejected because: a load-bearing reason, the DX cost is too high. - Polyglot plugins are a feature we don't need. -## Why not Node compat +## Why not full Node compat -Considered. Rejected because once `import 'fs'` works, plugin authors -reach for npm and we're back to the bundle problem that motivated -rejecting Electron. The whole point of single-file plugins is to make -that impossible. +Full npm-style Node compat was rejected: once arbitrary `require`/npm +resolution works, plugin authors reach for the registry and we're back to +the bundle problem that motivated rejecting Electron. The whole point of +single-file plugins is to make that impossible. -Plugins import from `highbeam:*` modules only. The host loader -rejects every other specifier. +The loader allowlist is `highbeam:*` plus a curated set of bare `node:*` +built-ins (`node:path`, `node:fs`, `node:fs/promises` today, all backed by +llrt crates). Bare specifiers (`import 'fs'`, `import 'lodash'`) and +unsupported `node:*` names are rejected. There is no `node_modules` +resolution, so a `node:*` import can only ever resolve to a built-in the +host vetted, never to an npm package. diff --git a/docs/plugin-authoring.md b/docs/plugin-authoring.md index 8541c47..26cee3f 100644 --- a/docs/plugin-authoring.md +++ b/docs/plugin-authoring.md @@ -136,39 +136,65 @@ type Result = { }; ``` -Plugins can `import` only from the `highbeam:*` scheme. `import 'fs'`, -`import 'lodash'`, etc. are rejected at load time. +Plugins can `import` from the `highbeam:*` scheme and from the supported +`node:*` built-ins (`node:path`, `node:fs`, `node:fs/promises`, `node:os`, +`node:zlib`, `node:string_decoder`, `node:child_process`). Every other +specifier (`import 'lodash'`, `import 'node:net'`, …) is rejected at load +time. ## Capabilities at a glance | Capability | Grants | |------------------------|-----------------------------------------------------| | `actions` | `highbeam:actions` | -| `http` | `highbeam:http.get` / `.post` | +| `http` | global `fetch` (+ `Headers` / `Request` / `Response` / `FormData`) | | `clipboard.read` | `highbeam:clipboard.read` | | `clipboard.write` | `highbeam:clipboard.write` | | `fs.read` | `highbeam:fs.readDir` / `.readFile` / `.readText` | | `fs.cache` | `highbeam:fs.readCache` / `.writeCache` | +| `fs` | full filesystem: `node:fs` / `node:fs/promises` + all `highbeam:fs.*` | +| `subprocess` | spawn programs (`node:child_process`) + the `process` global | | `icons` | `highbeam:icons.forPath` | | `system.exec` | `highbeam:system.exec` | | `system.applescript` | `highbeam:system.applescript` | -`highbeam:match`, `highbeam:platform`, and `highbeam:settings` are uncapped -— no declaration required. See [sdk-reference.md](./sdk-reference.md) for -per-function behavior, signatures, and examples. +`highbeam:match`, `highbeam:settings`, `node:path`, +`node:os`, `node:string_decoder`, and `node:zlib` are uncapped — no +declaration required. `fs` is the broad "read and write any file your user +can" grant; prefer the scoped `fs.read` / `fs.cache` when they suffice. See +[sdk-reference.md](./sdk-reference.md) for per-function behavior, signatures, +and examples. ## Runtime globals -The runtime is bare `QuickJS` plus exactly these host-installed globals — no -other Web APIs exist (`fetch`, `URLSearchParams`, `crypto`, …): +The runtime is QuickJS (via rquickjs) with the llrt module crates layered on +top for the Node and Web API surface. Always-on globals, no capability and no +import: - `console.log/info/warn/error/debug` — see below. - `setTimeout` — awaitable; `clearTimeout` / `clearInterval` are no-ops. -- `AbortController` / `AbortSignal` — the signal passed to `query()` is one. -- `TextEncoder` / `TextDecoder` — UTF-8 only. Constructing `TextDecoder` - with any other encoding throws `RangeError`; invalid byte sequences - decode to U+FFFD. The main consumer is `fs.readCache`, which returns a - `Uint8Array`. +- `URL` / `URLSearchParams`. +- `Buffer`, `Blob`, `File`. +- `TextEncoder` / `TextDecoder`: multi-encoding (utf-8, utf-16le, utf-16be, + windows-1252), with BOM handling; invalid byte sequences decode to U+FFFD. +- `ReadableStream` and the rest of the web-streams family. +- `DOMException`. +- `AbortController` / `AbortSignal`: the signal passed to `query()` is one. + `AbortSignal.timeout(ms)`, `AbortSignal.any([...])`, + `AbortSignal.abort(reason)` all work; `signal.reason` is a `DOMException` + and `signal.throwIfAborted()` throws it. +- `crypto`: WebCrypto (`getRandomValues`, `randomUUID`, `subtle.*`) plus the + node-style `randomBytes` / `createHash` / `createHmac` helpers. +- `Temporal`: the full Temporal surface (`Now`, `PlainDate`, `Instant`, …). +- `Intl`: partial — `DateTimeFormat` and `supportedValuesOf` only, no + `NumberFormat` / `Collator`. + +`fetch` (with `Headers` / `Request` / `Response` / `FormData`) is gated on +the `http` capability rather than always-on, and the `process` global is +gated on `subprocess`. The `node:path`, `node:os`, `node:zlib`, +`node:string_decoder`, `node:fs`, `node:fs/promises`, and +`node:child_process` modules are imported, not globals (see +[sdk-reference.md](./sdk-reference.md#nodepath)). ## Console + logging @@ -197,6 +223,7 @@ Hand-written `.d.ts` files live in `sdk/highbeam/`. A minimal "moduleResolution": "node", "strict": true, "outDir": ".", + "types": ["node"], "paths": { "highbeam:*": ["./node_modules/@high-beam/sdk/*"] } @@ -206,8 +233,14 @@ Hand-written `.d.ts` files live in `sdk/highbeam/`. A minimal ``` `npm install --save-dev /sdk/highbeam` (or symlink it) -to pull the ambient types in. Compiled `plugin.js` keeps the bare -`highbeam:*` specifiers — TypeScript only needs the types at compile time. +to pull the ambient `highbeam:*` types in. Compiled `plugin.js` keeps the +bare `highbeam:*` specifiers — TypeScript only needs the types at compile +time. + +Types for the `node:*` modules come from `@types/node` +(`npm install --save-dev @types/node`, hence `"types": ["node"]` above); the +SDK no longer ships an `http.d.ts`. The `fetch` / `Response` / +`AbortSignal` / `AbortController` shapes are in the SDK's `types.d.ts`. `plugins/echo-ts` has a full working setup. @@ -322,4 +355,4 @@ as a starting point: - `dnd` — bundled `5eSpells.json`, `match.fuzzy` ranking, `openUrl`. - `app-launcher` — `fs.readDir`, `icons.forPath`, `match.fuzzy`, cross-platform Spotlight equivalent. -- `xkcd` — HTTP + `fs.cache`-backed title index, fuzzy search. +- `xkcd` — `fetch` + `fs.cache`-backed title index, fuzzy search. diff --git a/docs/plugin-cookbook.md b/docs/plugin-cookbook.md index 7718377..dba6877 100644 --- a/docs/plugin-cookbook.md +++ b/docs/plugin-cookbook.md @@ -221,14 +221,14 @@ Manifest: Real plugin: `plugins/xkcd` builds a title index lazily and refreshes on a 24h TTL. -## HTTP request with timeout and abort +## fetch with timeout and abort -Use this when fetching from a remote API. Propagate the host's `signal` so -the next keystroke cancels the in-flight request. +Use this when fetching from a remote API. Compose the host's `signal` with a +per-request timeout so the next keystroke cancels the in-flight request and a +slow server can't hang the query. ```js import { openUrl } from 'highbeam:actions'; -import { get } from 'highbeam:http'; const TRIGGER = /^pkg\s+(.+)$/i; @@ -240,18 +240,18 @@ export async function* query(input, signal) { let res; try { - res = await get( + res = await fetch( `https://registry.example.com/search?q=${encodeURIComponent(term)}`, - { signal, timeoutMs: 3000 }, + { signal: AbortSignal.any([signal, AbortSignal.timeout(3000)]) }, ); } catch (err) { // Aborted, timed out, or transport failure — render nothing. - if (err.name === 'AbortError') return; + if (err.name === 'AbortError' || err.name === 'TimeoutError') return; throw err; } if (!res.ok) return; - const body = res.json(); + const body = await res.json(); for (const pkg of body.results ?? []) { if (signal.aborted) return; yield { @@ -266,18 +266,21 @@ export async function* query(input, signal) { Notes: -- Pass `signal` into `get`/`post` so the abort cascades from "user typed - another keystroke" into the reqwest future. -- `timeoutMs: 3000` overrides the 30 s default for this call. Pick - aggressively — autocomplete UI feels bad waiting 30 seconds for a - failing fetch. -- Catch `AbortError` and return silently; that's the cancellation path. +- `AbortSignal.any([signal, AbortSignal.timeout(3000)])` aborts on either the + keystroke signal or a 3 s timeout, whichever fires first. Without a timeout + signal, the host's 30 s default still applies. Pick aggressively; + autocomplete UI feels bad waiting 30 seconds for a failing fetch. +- Pass the host `signal` so the abort cascades from "user typed another + keystroke" into the request. +- Catch `AbortError` / `TimeoutError` and return silently; that's the + cancellation path. +- `await res.json()` (the body readers are async). - Check `signal.aborted` between yields if you produce many rows after a slow await; otherwise the next keystroke's rows can interleave with this one's. - The plugin must declare the `http` capability. -Real plugin: `plugins/xkcd` (HTTP + abort + cache). +Real plugin: `plugins/xkcd` (fetch + abort + cache). ## Cross-platform behavior @@ -285,11 +288,11 @@ Use this when the plugin's data sources differ between macOS and Linux — e.g. app discovery via `.app` bundles vs `.desktop` files. ```js -import { isMacOS, isLinux } from 'highbeam:platform'; +import os from 'node:os'; async function collectApps() { - if (isMacOS()) return collectMacApps(); - if (isLinux()) return collectLinuxApps(); + if (os.platform() === 'darwin') return collectMacApps(); + if (os.platform() === 'linux') return collectLinuxApps(); return []; } @@ -309,7 +312,7 @@ immediately on non-macOS rather than throwing: ```js import { applescript } from 'highbeam:system'; -// Resolves to null on Linux; no isMacOS() check needed. +// Resolves to null on Linux; no platform check needed. const result = await applescript('tell application "Finder" to get name'); ``` @@ -326,8 +329,8 @@ where it can't work at all: The host won't even load it on Linux. `platforms` absent loads everywhere; empty `[]` shelves the plugin entirely (never loads). -Real plugin: `plugins/app-launcher` (`isMacOS()` / `isLinux()` to -branch between `.app` and `.desktop` discovery). +Real plugin: `plugins/app-launcher` (`os.platform() === 'darwin'` / +`=== 'linux'` to branch between `.app` and `.desktop` discovery). ## Read user-editable options via `highbeam:settings` @@ -439,33 +442,31 @@ test('uses the user-set username', async () => { The SDK stubs are `vi.fn()`s that return `undefined` by default, so any unmocked `get*` call falls back to the plugin's `?? default` branch. -Mocking `http.get` per-test: +Mocking `fetch` per-test (it's a global, so stub `globalThis.fetch` rather +than a module import): ```js import { vi } from 'vitest'; -import { get } from 'highbeam:http'; - -vi.mocked(get).mockResolvedValueOnce({ - status: 200, - statusText: 'OK', - headers: {}, - body: JSON.stringify({ result: 'ok' }), - ok: true, - json() { return { result: 'ok' }; }, - text() { return this.body; }, -}); + +vi.stubGlobal('fetch', vi.fn().mockResolvedValueOnce( + new Response(JSON.stringify({ result: 'ok' }), { + status: 200, + headers: { 'content-type': 'application/json' }, + }), +)); ``` +`Response` exists in Node 18+ (and under vitest), so the real class works in +tests. Call `vi.unstubAllGlobals()` in `afterEach` to restore. + Resetting a plugin's module-level cache between tests: ```js async function loadPlugin() { vi.resetModules(); - const http = await import('highbeam:http'); - vi.mocked(http.get).mockReset(); - vi.mocked(http.get).mockResolvedValue(/* default */); + vi.stubGlobal('fetch', vi.fn().mockResolvedValue(/* default Response */)); const plugin = await import('./plugin.js'); - return { plugin, http }; + return { plugin }; } ``` @@ -474,9 +475,18 @@ Notes: - `highbeam:actions` is not a mock — the stub returns the same plain objects the host does, so `expect(action).toEqual({ kind: 'copy', text: '...' })` works straight out. -- `highbeam:platform` is real (reads `process.platform` and friends), so - `isMacOS()` reflects the test host. Stub it explicitly when you need - cross-platform coverage. +- `node:os` is real, so `os.platform()` reflects the test host. Mock the + whole module to drive platform detection per test (ESM namespaces are + frozen, so replacing the module beats `spyOn`): + + ```js + vi.mock('node:os', () => { + const platform = vi.fn(() => 'darwin'); + return { default: { platform }, platform }; + }); + // later: vi.mocked((await import('node:os')).default.platform) + // .mockReturnValue('linux'); + ``` - `highbeam:match` is a faithful port of the host matcher. Order and highlight ranges agree with `nucleo-matcher` on realistic input. - `vi.resetModules()` clears the plugin's module-level cache between @@ -485,7 +495,7 @@ Notes: Real test suites: `plugins/http-codes/http-codes.test.js` (mocking `fs.readText`), `plugins/xkcd/xkcd.test.js` -(mocking `http.get` + `fs.readCache` + `vi.resetModules`). +(stubbing `fetch` + mocking `fs.readCache` + `vi.resetModules`). ## Stream results vs return all at once @@ -678,7 +688,8 @@ methods: { this.loadCtrl = new AbortController(); this.loading = true; try { - this.data = await http.getJson(this.url, { signal: this.loadCtrl.signal }); + const res = await fetch(this.url, { signal: this.loadCtrl.signal }); + this.data = await res.json(); } catch (err) { if (err.name !== 'AbortError') this.err = err; } @@ -739,19 +750,20 @@ dropped (logged once at INFO in `plugin.log`). ## Show a remote image inside a view `Image({ src })` accepts a `data:` URI only — the same rule as -`Result.icon`. Plugins fetch via `highbeam:http` and base64-encode the -body themselves. Watch the size: a 5 MB JPEG base64-encodes to ~7 MB of -JS string, which blows the default 32 MB `memoryMb` cap. +`Result.icon`. Plugins fetch with `fetch` and base64-encode the body +themselves (`Buffer` is an always-on global). Watch the size: a 5 MB JPEG +base64-encodes to ~7 MB of JS string, which blows the default 32 MB +`memoryMb` cap. ```js -import { http } from 'highbeam:http'; import { Heading, Image, Spinner } from 'highbeam:view'; const Photo = { setup: (props) => ({ src: null, title: props.title }), async mounted({ signal }) { - const bytes = await http.getBytes(this.props.src, { signal }); - this.src = `data:image/jpeg;base64,${bytes.base64}`; + const res = await fetch(this.props.src, { signal }); + const base64 = Buffer.from(await res.arrayBuffer()).toString('base64'); + this.src = `data:image/jpeg;base64,${base64}`; }, render() { if (!this.src) return { body: [Spinner({ label: 'Loading image…' })] }; diff --git a/docs/plugin-tutorial.md b/docs/plugin-tutorial.md index a67cb11..fd6cc25 100644 --- a/docs/plugin-tutorial.md +++ b/docs/plugin-tutorial.md @@ -332,9 +332,9 @@ npm test vitest watches by default; `vitest run` runs once and exits. The iteration loop is now: edit `plugin.js`, save, vitest re-runs in <100ms. -SDK modules with side effects (`highbeam:http`, `highbeam:clipboard`, -`highbeam:fs`, `highbeam:system`, `highbeam:icons`) ship as `vi.fn()`s so you -can spy and override per-call: +SDK modules with side effects (`highbeam:clipboard`, `highbeam:fs`, +`highbeam:system`, `highbeam:icons`) ship as `vi.fn()`s so you can spy and +override per-call: ```js import { readText } from 'highbeam:fs'; diff --git a/docs/sdk-reference.md b/docs/sdk-reference.md index 1531cf0..55d067d 100644 --- a/docs/sdk-reference.md +++ b/docs/sdk-reference.md @@ -11,8 +11,11 @@ build), [plugin-cookbook.md](./plugin-cookbook.md) (recipes), ## Conventions -- Every module is imported under the `highbeam:` scheme. `import 'fs'`, - `import 'lodash'`, etc. are rejected at load time. +- Modules are imported under the `highbeam:` scheme, or the `node:` scheme + for the supported Node built-ins (`node:path`, `node:fs`, + `node:fs/promises`, `node:os`, `node:zlib`, `node:string_decoder`, + `node:child_process`). Anything else (`import 'fs'`, `import 'lodash'`, + `import 'node:net'`) is rejected at load time. - A module loads when the plugin declares *any* capability the module recognises. Functions within the module may gate themselves further — e.g. `highbeam:clipboard` loads on either `clipboard.read` or `clipboard.write`, @@ -58,28 +61,12 @@ type Action = | { kind: 'closeView' } | { kind: 'noop' }; // inert row — Enter just dismisses the launcher -interface HttpResponse { - status: number; - statusText: string; - headers: Record; - body: string; - ok: boolean; // status in 200..=299 - json(): unknown; // throws on parse failure - text(): string; // alias for body -} - -interface HttpOpts { - headers?: Record; - signal?: AbortSignal; - timeoutMs?: number; // per-request override of default 30s -} - interface AbortSignal { readonly aborted: boolean; - readonly reason?: unknown; + readonly reason: unknown; // a DOMException once aborted addEventListener(type: 'abort', listener: () => void): void; removeEventListener(type: 'abort', listener: () => void): void; - throwIfAborted(): void; + throwIfAborted(): void; // throws signal.reason if aborted } interface AbortController { @@ -166,77 +153,61 @@ selected. - Linux: best-effort `xdg-open `; no selection (the freedesktop spec doesn't have a portable equivalent). -## `highbeam:http` - -Async HTTP client. Built on a shared reqwest client. +## `fetch` -```js -import { get, post, put, patch } from 'highbeam:http'; -// `delete` is a JS reserved word — rename on import, or use the -// namespace form: `import * as http from 'highbeam:http';`. -import { delete as del } from 'highbeam:http'; -``` +Standard WHATWG `fetch`. No import: declaring the `http` capability installs +it (and `Headers`, `Request`, `Response`, `FormData`) as a global. Real +classes, binary bodies, and a `ReadableStream` on `response.body`. **Capability:** `http`. -### `get(url: string, opts?: HttpOpts): Promise` - ```js -const res = await get('https://xkcd.com/info.0.json', { signal }); +const res = await fetch('https://xkcd.com/info.0.json', { signal }); if (!res.ok) throw new Error(`HTTP ${res.status}`); -const data = res.json(); +const data = await res.json(); ``` -Resolves to an `HttpResponse` regardless of HTTP status. Check `.ok` or -`.status` to detect errors. Non-2xx does not throw. - -### `post(url: string, body?: string | object, opts?: HttpOpts): Promise` -### `put(url: string, body?: string | object, opts?: HttpOpts): Promise` -### `patch(url: string, body?: string | object, opts?: HttpOpts): Promise` -### `delete(url: string, body?: string | object, opts?: HttpOpts): Promise` +`fetch(input, init?)` takes a URL string or `Request` and the usual `init` +(`method`, `headers`, `body`, `signal`, …). `body` accepts a string, +`Uint8Array`/`ArrayBuffer`, `Blob`, `FormData`, or `URLSearchParams`. The +`Response` exposes `.ok`, `.status`, `.statusText`, `.headers`, and the +async readers `.json()`, `.text()`, `.arrayBuffer()`, `.blob()`, plus a +`.body` `ReadableStream`. ```js -const res = await post('https://api.example.com/items', { name: 'x' }, { - headers: { 'authorization': 'bearer ...' }, - timeoutMs: 5000, +const res = await fetch('https://api.example.com/items', { + method: 'POST', + headers: { 'authorization': 'bearer ...', 'content-type': 'application/json' }, + body: JSON.stringify({ name: 'x' }), signal, }); ``` -All four share the same shape — verbatim string body, JSON-stringified -object body, or no body. `body` semantics: - -- `undefined` — empty body, no `Content-Type` set. -- `string` — sent verbatim, no `Content-Type` set. -- `object` — JSON-stringified, `Content-Type: application/json` injected. - -`delete` is exposed under its conventional name on the module; consumers -must rename on import to dodge the JS reserved word (see the import block -above). - ### Behavior notes -- Default timeout is 30 s. Override per request via `opts.timeoutMs`. -- Cancellation: pass an `AbortSignal` via `opts.signal`. The signal the host - hands to `query(input, signal)` is the one to propagate — aborting it - cascades into the in-flight reqwest future when the user types another - keystroke. -- `HttpResponse.body` is decoded as UTF-8. Binary bodies are post-v1. -- `HttpResponse.json()` throws on parse failure; wrap in `try/catch` if the - server is allowed to return non-JSON. -- `HttpResponse.headers` keys are lowercased. +- Every fetch gets a 30 s timeout, injected host-side by joining your + `signal` (if any) with a deadline via `AbortSignal.any`. Your own signal + can abort sooner (`AbortSignal.timeout(5000)`, a keystroke cancel) but + cannot extend past the 30 s ceiling. +- Cancellation: pass an `AbortSignal` via `init.signal`. The signal the host + hands to `query(input, signal)` is the one to propagate, so the next + keystroke cancels the in-flight request. +- The body readers (`.json()`, `.text()`, `.arrayBuffer()`, `.blob()`) are + async. There is no transfer cap; a response body is bounded by the + plugin's `memoryMb`. +- A non-2xx status resolves normally (check `.ok` / `.status`). `fetch` + rejects only on transport failure or abort. ### Example ```js import { openUrl } from 'highbeam:actions'; -import { get } from 'highbeam:http'; export async function* query(input, signal) { if (!/^xkcd latest$/i.test(input)) return; - const res = await get('https://xkcd.com/info.0.json', { signal }); + const res = await fetch('https://xkcd.com/info.0.json', { signal }); if (!res.ok) return; - const comic = res.json(); + const comic = await res.json(); yield { key: `xkcd-${comic.num}`, title: `${comic.num}: ${comic.title}`, @@ -246,7 +217,20 @@ export async function* query(input, signal) { } ``` -See `plugins/xkcd` for a full HTTP-driven plugin with caching. +See `plugins/xkcd` for a full fetch-driven plugin with caching. + +### Migrating from `highbeam:http` + +The `highbeam:http` module is gone. Translate calls to `fetch`: + +- `get(url, opts)` → `fetch(url, opts)`. +- `post(url, body, opts)` → `fetch(url, { method: 'POST', body, ...opts })`. + An object body is no longer JSON-stringified for you: call + `JSON.stringify(body)` and set `content-type: application/json` yourself. +- `res.json()` / `res.text()` are now async: `await res.json()`. +- The `timeoutMs` option is gone. Use `AbortSignal.timeout(ms)` (composed + with the host signal via `AbortSignal.any` when you also want + keystroke cancellation). ## `highbeam:clipboard` @@ -292,7 +276,9 @@ import { readDir, readFile, readText, readCache, writeCache, basename } from 'hi **Capabilities:** `fs.read` for the file readers, `fs.cache` for the cache helpers. Both can be declared independently. `basename` is a pure string -helper available with either. +helper available with either. Declaring the broad `fs` capability (full +filesystem access, see [`node:fs`](#nodefs--nodefspromises)) unlocks every +helper here too, without naming `fs.read` / `fs.cache` separately. Relative paths passed to `readDir` / `readFile` / `readText` resolve against the plugin's own directory, so `readText('./bundled.json')` works regardless @@ -488,46 +474,6 @@ Notes: See `plugins/dnd` and `plugins/app-launcher` for typical usage (fuzzy-rank a bundled list and map scores onto `weight`). -## `highbeam:platform` - -Host metadata. Always importable. - -```js -import { os, arch, version, isMacOS, isLinux } from 'highbeam:platform'; -``` - -**Capability:** none. - -### `os: 'macos' | 'linux'` - -OS identifier, matching the host's `std::env::consts::OS`. - -### `arch: string` - -CPU architecture. Common values: `x86_64`, `aarch64`. - -### `version: string` - -OS version. Best-effort: - -- macOS: `sw_vers -productVersion` (e.g. `14.4.1`). -- Linux: `uname -r` (kernel release). - -Returns `"unknown"` if detection fails. Never throws. - -### `isMacOS(): boolean` / `isLinux(): boolean` - -```js -if (isMacOS()) { - // mac-specific path -} else if (isLinux()) { - // linux-specific path -} -``` - -Convenience wrappers over `os === 'macos'` / `os === 'linux'`. Use these in -preference to manual comparisons — the intent is clearer at the call site. - ## `highbeam:settings` Read this plugin's own option values. The host scopes per plugin internally, @@ -643,27 +589,199 @@ On macOS: runs via `osascript -e