diff --git a/Cargo.lock b/Cargo.lock
index cd891573..a43528a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,16 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "Inflector"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+dependencies = [
+ "lazy_static",
+ "regex",
+]
+
[[package]]
name = "adler2"
version = "2.0.1"
@@ -48,7 +58,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d176a10d4cb06e0262a738c3c5bf21ff0968db13a666e31cbca94a3d3d72e7c"
dependencies = [
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -58,7 +68,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c290bfa00c6b52339db66f8e9cf711d5f08530800529f7d619ff24d6cba253d0"
dependencies = [
"anyhow",
- "derive_more",
+ "derive_more 2.1.1",
"schemars 1.2.1",
"serde",
"serde_json",
@@ -90,6 +100,30 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "allocative"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8cf9afc79c83d514444b55df3935d317da54b1ce3b17a133c646889cc260de8"
+dependencies = [
+ "allocative_derive",
+ "bumpalo",
+ "ctor 1.0.9",
+ "hashbrown 0.16.1",
+ "num-bigint",
+]
+
+[[package]]
+name = "allocative_derive"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "614043c56c1173b800acb007b81fd0cbc0a0d7d717b71ba705fc2230d0760a23"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "allocator-api2"
version = "0.2.21"
@@ -122,6 +156,15 @@ dependencies = [
"rayon",
]
+[[package]]
+name = "annotate-snippets"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e"
+dependencies = [
+ "unicode-width 0.1.14",
+]
+
[[package]]
name = "ansi-to-tui"
version = "7.0.0"
@@ -349,7 +392,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -389,7 +432,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -406,7 +449,22 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "atomic"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
+
+[[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
]
[[package]]
@@ -428,6 +486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00"
dependencies = [
"aws-lc-sys",
+ "untrusted 0.7.1",
"zeroize",
]
@@ -513,6 +572,18 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+[[package]]
+name = "base64ct"
+version = "1.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
+
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+
[[package]]
name = "bincode"
version = "1.3.3"
@@ -522,6 +593,21 @@ dependencies = [
"serde",
]
+[[package]]
+name = "bit-set"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
+
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -536,16 +622,17 @@ checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "blake3"
-version = "1.8.5"
+version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce"
+checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0"
dependencies = [
"arrayref",
"arrayvec",
"cc",
"cfg-if 1.0.4",
"constant_time_eq",
- "cpufeatures 0.3.0",
+ "digest 0.10.7",
+ "rayon-core",
]
[[package]]
@@ -624,7 +711,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -668,6 +755,20 @@ name = "bytemuck"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
+dependencies = [
+ "bytemuck_derive",
+]
+
+[[package]]
+name = "bytemuck_derive"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
[[package]]
name = "byteorder"
@@ -711,7 +812,7 @@ dependencies = [
"darling 0.20.11",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -840,7 +941,7 @@ dependencies = [
"anstream",
"anstyle",
"clap_lex",
- "strsim",
+ "strsim 0.11.1",
]
[[package]]
@@ -852,7 +953,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -879,6 +980,45 @@ dependencies = [
"cc",
]
+[[package]]
+name = "cmp_any"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21"
+
+[[package]]
+name = "cmpv2"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "961b955a666e25ee5a1091d219128d6e6401e3dab84efb1a2bf6b4035d797b39"
+dependencies = [
+ "crmf",
+ "der",
+ "spki",
+ "x509-cert",
+]
+
+[[package]]
+name = "cms"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730"
+dependencies = [
+ "const-oid 0.9.6",
+ "der",
+ "spki",
+ "x509-cert",
+]
+
+[[package]]
+name = "cobs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
+dependencies = [
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "colorchoice"
version = "1.0.5"
@@ -1016,6 +1156,12 @@ dependencies = [
"tracing-subscriber",
]
+[[package]]
+name = "const-oid"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+
[[package]]
name = "const-oid"
version = "0.10.2"
@@ -1039,9 +1185,18 @@ dependencies = [
[[package]]
name = "constant_time_eq"
-version = "0.4.2"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
+
+[[package]]
+name = "convert_case"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
+checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
+dependencies = [
+ "unicode-segmentation",
+]
[[package]]
name = "convert_case"
@@ -1115,6 +1270,21 @@ dependencies = [
"libc",
]
+[[package]]
+name = "crc"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853"
+
[[package]]
name = "crc32fast"
version = "1.5.0"
@@ -1124,6 +1294,24 @@ dependencies = [
"cfg-if 1.0.4",
]
+[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
+name = "crmf"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36fe21b96d5b87f5de4b5b7202ec41c00110ac817ce6728fe75fb2fe5962ed92"
+dependencies = [
+ "cms",
+ "der",
+ "spki",
+ "x509-cert",
+]
+
[[package]]
name = "crossbeam-channel"
version = "0.5.15"
@@ -1239,6 +1427,16 @@ dependencies = [
"dtor",
]
+[[package]]
+name = "ctor"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a394189d59f9befacce833f337f7b1eca5e9a91221bcdd4d28e0114d96e597b3"
+dependencies = [
+ "link-section",
+ "linktime-proc-macro",
+]
+
[[package]]
name = "ctor-proc-macro"
version = "0.0.7"
@@ -1275,8 +1473,8 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "strsim",
- "syn",
+ "strsim 0.11.1",
+ "syn 2.0.117",
]
[[package]]
@@ -1288,8 +1486,8 @@ dependencies = [
"ident_case",
"proc-macro2",
"quote",
- "strsim",
- "syn",
+ "strsim 0.11.1",
+ "syn 2.0.117",
]
[[package]]
@@ -1300,7 +1498,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core 0.20.11",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1311,7 +1509,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
dependencies = [
"darling_core 0.23.0",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1323,6 +1521,20 @@ dependencies = [
"serde",
]
+[[package]]
+name = "dashmap"
+version = "6.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c"
+dependencies = [
+ "cfg-if 1.0.4",
+ "crossbeam-utils",
+ "hashbrown 0.14.5",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core",
+]
+
[[package]]
name = "data-encoding"
version = "2.11.0"
@@ -1358,6 +1570,41 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "debugserver-types"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bf6834a70ed14e8e4e41882df27190bea150f1f6ecf461f1033f8739cd8af4a"
+dependencies = [
+ "schemafy",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "der"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
+dependencies = [
+ "const-oid 0.9.6",
+ "der_derive",
+ "flagset",
+ "pem-rfc7468",
+ "zeroize",
+]
+
+[[package]]
+name = "der_derive"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "deranged"
version = "0.5.8"
@@ -1367,6 +1614,17 @@ dependencies = [
"serde_core",
]
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
[[package]]
name = "derive_builder"
version = "0.20.2"
@@ -1385,7 +1643,7 @@ dependencies = [
"darling 0.20.11",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1395,7 +1653,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "derive_more"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
+dependencies = [
+ "derive_more-impl 1.0.0",
]
[[package]]
@@ -1404,7 +1671,20 @@ version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
dependencies = [
- "derive_more-impl",
+ "derive_more-impl 2.1.1",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
+dependencies = [
+ "convert_case 0.6.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+ "unicode-xid",
]
[[package]]
@@ -1413,11 +1693,11 @@ 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",
- "syn",
+ "syn 2.0.117",
"unicode-xid",
]
@@ -1435,6 +1715,7 @@ dependencies = [
"clap",
"console-subscriber",
"devo-core",
+ "devo-linux-sandbox",
"devo-server",
"devo-util-paths",
"dotenvy",
@@ -1464,6 +1745,7 @@ dependencies = [
"devo-tasks",
"devo-tui",
"devo-util-paths",
+ "devo-windows-sandbox",
"futures",
"pretty_assertions",
"serde",
@@ -1570,14 +1852,17 @@ dependencies = [
"chrono",
"devo-code-search",
"devo-config",
+ "devo-execpolicy",
"devo-network-proxy",
"devo-protocol",
"devo-provider",
"devo-safety",
+ "devo-sandbox",
"devo-skills",
"devo-tools",
"devo-util-paths",
"devo-util-process",
+ "devo-windows-sandbox",
"diffy",
"futures",
"iana-time-zone",
@@ -1603,6 +1888,23 @@ dependencies = [
"uuid",
]
+[[package]]
+name = "devo-execpolicy"
+version = "0.1.30"
+dependencies = [
+ "anyhow",
+ "clap",
+ "devo-util-paths",
+ "multimap",
+ "pretty_assertions",
+ "serde",
+ "serde_json",
+ "shlex 1.3.0",
+ "starlark",
+ "tempfile",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "devo-file-search"
version = "0.1.30"
@@ -1627,6 +1929,18 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "devo-linux-sandbox"
+version = "0.1.30"
+dependencies = [
+ "anyhow",
+ "clap",
+ "devo-sandbox",
+ "libc",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "devo-mcp"
version = "0.1.30"
@@ -1669,6 +1983,7 @@ dependencies = [
"strum 0.27.2",
"strum_macros 0.28.0",
"thiserror 2.0.18",
+ "tracing",
"ts-rs",
"uuid",
]
@@ -1733,6 +2048,9 @@ name = "devo-safety"
version = "0.1.30"
dependencies = [
"async-trait",
+ "devo-config",
+ "devo-util-shell-command",
+ "globset",
"pretty_assertions",
"regex",
"serde",
@@ -1740,6 +2058,47 @@ dependencies = [
"smol_str 0.3.2",
"thiserror 2.0.18",
"tokio",
+ "tracing",
+ "tree-sitter",
+ "url",
+]
+
+[[package]]
+name = "devo-sandbox"
+version = "0.1.30"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "devo-util-paths",
+ "devo-windows-sandbox",
+ "dirs",
+ "dunce",
+ "globset",
+ "ignore",
+ "libc",
+ "nono",
+ "pretty_assertions",
+ "regex",
+ "serde",
+ "serde_json",
+ "serial_test",
+ "sha2 0.10.9",
+ "thiserror 2.0.18",
+ "toml",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "devo-sandbox-network-proxy"
+version = "0.1.30"
+dependencies = [
+ "anyhow",
+ "devo-sandbox",
+ "pretty_assertions",
+ "tokio",
+ "tokio-util",
+ "tracing",
]
[[package]]
@@ -1754,11 +2113,14 @@ dependencies = [
"devo-client",
"devo-code-search",
"devo-core",
+ "devo-execpolicy",
"devo-file-search",
"devo-mcp",
"devo-protocol",
"devo-provider",
"devo-safety",
+ "devo-sandbox",
+ "devo-sandbox-network-proxy",
"devo-util-fuzzy",
"devo-util-git",
"devo-util-paths",
@@ -1771,6 +2133,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.9",
+ "shlex 1.3.0",
"smol_str 0.3.2",
"tempfile",
"thiserror 2.0.18",
@@ -1841,11 +2204,12 @@ dependencies = [
"base64 0.22.1",
"chrono",
"crossterm",
- "derive_more",
+ "derive_more 2.1.1",
"devo-client",
"devo-core",
"devo-protocol",
"devo-provider",
+ "devo-sandbox",
"devo-server",
"devo-util-fuzzy",
"devo-util-git",
@@ -1875,7 +2239,7 @@ dependencies = [
"supports-color",
"syntect",
"tempfile",
- "textwrap",
+ "textwrap 0.16.2",
"tokio",
"tokio-stream",
"tokio-util",
@@ -1934,6 +2298,7 @@ name = "devo-util-process"
version = "0.1.30"
dependencies = [
"anyhow",
+ "devo-sandbox",
"filedescriptor",
"lazy_static",
"libc",
@@ -1966,8 +2331,39 @@ dependencies = [
]
[[package]]
-name = "diff"
-version = "0.1.13"
+name = "devo-windows-sandbox"
+version = "0.1.30"
+dependencies = [
+ "anyhow",
+ "base64 0.22.1",
+ "chrono",
+ "devo-util-paths",
+ "dirs-next",
+ "dunce",
+ "filedescriptor",
+ "glob",
+ "globset",
+ "lazy_static",
+ "log",
+ "pretty_assertions",
+ "rand 0.8.6",
+ "serde",
+ "serde_json",
+ "shared_library",
+ "strum 0.27.2",
+ "strum_macros 0.28.0",
+ "tempfile",
+ "tokio",
+ "tracing",
+ "tracing-appender",
+ "winapi",
+ "windows 0.58.0",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "diff"
+version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
@@ -1998,7 +2394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
dependencies = [
"block-buffer 0.12.1",
- "const-oid",
+ "const-oid 0.10.2",
"crypto-common 0.2.2",
]
@@ -2011,6 +2407,16 @@ dependencies = [
"dirs-sys",
]
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if 1.0.4",
+ "dirs-sys-next",
+]
+
[[package]]
name = "dirs-sys"
version = "0.5.0"
@@ -2019,10 +2425,21 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
- "redox_users",
+ "redox_users 0.5.2",
"windows-sys 0.61.2",
]
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users 0.4.6",
+ "winapi",
+]
+
[[package]]
name = "dispatch2"
version = "0.3.1"
@@ -2033,6 +2450,16 @@ dependencies = [
"objc2",
]
+[[package]]
+name = "display_container"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a110a75c96bedec8e65823dea00a1d710288b7a369d95fd8a0f5127639466fa"
+dependencies = [
+ "either",
+ "indenter",
+]
+
[[package]]
name = "displaydoc"
version = "0.2.6"
@@ -2041,7 +2468,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2077,6 +2504,26 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+[[package]]
+name = "dupe"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed2bc011db9c93fbc2b6cdb341a53737a55bafb46dbb74cf6764fc33a2fbf9c"
+dependencies = [
+ "dupe_derive",
+]
+
+[[package]]
+name = "dupe_derive"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83e195b4945e88836d826124af44fdcb262ec01ef94d44f14f4fb5103f19892a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "dyn-clone"
version = "1.0.20"
@@ -2089,6 +2536,18 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+[[package]]
+name = "embedded-io"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
[[package]]
name = "encode_unicode"
version = "1.0.0"
@@ -2110,6 +2569,12 @@ version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
+[[package]]
+name = "endian-type"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
+
[[package]]
name = "enum-as-inner"
version = "0.6.1"
@@ -2119,7 +2584,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2140,7 +2605,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2172,6 +2637,26 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+[[package]]
+name = "erased-serde"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "erased-serde"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec"
+dependencies = [
+ "serde",
+ "serde_core",
+ "typeid",
+]
+
[[package]]
name = "errno"
version = "0.3.14"
@@ -2241,6 +2726,17 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
+[[package]]
+name = "fancy-regex"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f"
+dependencies = [
+ "bit-set",
+ "regex-automata",
+ "regex-syntax",
+]
+
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -2253,6 +2749,17 @@ version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a"
+[[package]]
+name = "fd-lock"
+version = "4.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78"
+dependencies = [
+ "cfg-if 1.0.4",
+ "rustix 1.1.4",
+ "windows-sys 0.59.0",
+]
+
[[package]]
name = "fdeflate"
version = "0.3.7"
@@ -2285,6 +2792,12 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
+[[package]]
+name = "flagset"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe"
+
[[package]]
name = "flate2"
version = "1.1.9"
@@ -2295,6 +2808,15 @@ dependencies = [
"miniz_oxide",
]
+[[package]]
+name = "fluent-uri"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -2307,6 +2829,12 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
+[[package]]
+name = "foldhash"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
+
[[package]]
name = "form_urlencoded"
version = "1.2.2"
@@ -2423,7 +2951,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2568,9 +3096,15 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
+[[package]]
+name = "glob"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
+
[[package]]
name = "globset"
version = "0.4.18"
@@ -2614,12 +3148,27 @@ dependencies = [
"zerocopy",
]
+[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -2628,7 +3177,18 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
- "foldhash",
+ "foldhash 0.1.5",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash 0.2.0",
]
[[package]]
@@ -2665,6 +3225,20 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0049b265b7f201ca9ab25475b22b47fe444060126a51abe00f77d986fc5cc52e"
+[[package]]
+name = "heapless"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "serde",
+ "spin",
+ "stable_deref_trait",
+]
+
[[package]]
name = "heck"
version = "0.5.0"
@@ -2774,6 +3348,15 @@ dependencies = [
"serde",
]
+[[package]]
+name = "home"
+version = "0.5.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "http"
version = "1.4.2"
@@ -2923,7 +3506,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
- "windows-core",
+ "windows-core 0.62.2",
]
[[package]]
@@ -3098,6 +3681,12 @@ dependencies = [
"quote",
]
+[[package]]
+name = "indenter"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
+
[[package]]
name = "indexmap"
version = "1.9.3"
@@ -3195,7 +3784,16 @@ dependencies = [
"indoc",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "inventory"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b"
+dependencies = [
+ "rustversion",
]
[[package]]
@@ -3261,7 +3859,7 @@ checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3291,7 +3889,7 @@ dependencies = [
"quote",
"rustc_version",
"simd_cesu8",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3310,7 +3908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3400,6 +3998,17 @@ dependencies = [
"libc",
]
+[[package]]
+name = "landlock"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "635839550ae8b90d9fd2571460a6645dc0aec070225956ca7a2831ed31d2795d"
+dependencies = [
+ "enumflags2",
+ "libc",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -3447,12 +4056,24 @@ dependencies = [
"vcpkg",
]
+[[package]]
+name = "link-section"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e333fe507b738576d6da5bb3f1a7d7a1c80307ed9ef31624c057d844c19c93e9"
+
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+[[package]]
+name = "linktime-proc-macro"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c7b0a3383c2a1002d11349c92c85a666a5fb679e96c79d782cf0dbe557fd6ee"
+
[[package]]
name = "linux-keyutils"
version = "0.2.5"
@@ -3490,12 +4111,56 @@ dependencies = [
"scopeguard",
]
+[[package]]
+name = "lock_free_hashtable"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebf3631712f5b790675292ff827af269f5d9f920c920b77dc41d0485e3719612"
+dependencies = [
+ "atomic",
+ "parking_lot",
+]
+
[[package]]
name = "log"
version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
+[[package]]
+name = "logos"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154"
+dependencies = [
+ "logos-derive",
+]
+
+[[package]]
+name = "logos-codegen"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "192a3a2b90b0c05b27a0b2c43eecdb7c415e29243acc3f89cc8247a5b693045c"
+dependencies = [
+ "beef",
+ "fnv",
+ "lazy_static",
+ "proc-macro2",
+ "quote",
+ "regex-syntax",
+ "rustc_version",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "logos-derive"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470"
+dependencies = [
+ "logos-codegen",
+]
+
[[package]]
name = "lru"
version = "0.12.5"
@@ -3511,6 +4176,19 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
+[[package]]
+name = "lsp-types"
+version = "0.97.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071"
+dependencies = [
+ "bitflags 1.3.2",
+ "fluent-uri",
+ "serde",
+ "serde_json",
+ "serde_repr",
+]
+
[[package]]
name = "lz4_flex"
version = "0.13.1"
@@ -3545,6 +4223,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30"
+[[package]]
+name = "maplit"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
+
[[package]]
name = "matchers"
version = "0.2.0"
@@ -3679,7 +4363,7 @@ checksum = "e4db6d5580af57bf992f59068d4ea26fd518574ff48d7639b255a36f9de6e7e9"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3698,6 +4382,15 @@ dependencies = [
"pxfm",
]
+[[package]]
+name = "multimap"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "ndarray"
version = "0.16.1"
@@ -3719,6 +4412,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
+[[package]]
+name = "nibble_vec"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
+dependencies = [
+ "smallvec",
+]
+
[[package]]
name = "nix"
version = "0.28.0"
@@ -3787,6 +4489,35 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "nono"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae7eb523cc2036e9ad6527411c3da5dc2172dc454cc3447a03b910420a39bfee"
+dependencies = [
+ "der",
+ "getrandom 0.4.2",
+ "globset",
+ "ignore",
+ "landlock",
+ "libc",
+ "nix 0.31.3",
+ "prettyplease",
+ "regress",
+ "serde",
+ "serde_json",
+ "sha2 0.11.0",
+ "sigstore-trust-root",
+ "sigstore-verify",
+ "syn 2.0.117",
+ "thiserror 2.0.18",
+ "tracing",
+ "typify",
+ "walkdir",
+ "x509-cert",
+ "zeroize",
+]
+
[[package]]
name = "notify"
version = "8.2.0"
@@ -3873,6 +4604,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
+ "serde",
]
[[package]]
@@ -4139,6 +4871,53 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "pagable"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3658968938a4d1eaa1987e69dcd84b01fb067c5b3416dccc8d71373b6ded6821"
+dependencies = [
+ "allocative",
+ "anyhow",
+ "async-trait",
+ "blake3",
+ "bytemuck",
+ "dashmap",
+ "dupe",
+ "either",
+ "erased-serde 0.4.10",
+ "fancy-regex",
+ "indexmap 2.14.0",
+ "inventory",
+ "num-bigint",
+ "once_cell",
+ "pagable_derive",
+ "parking_lot",
+ "postcard",
+ "regex",
+ "sequence_trie",
+ "serde",
+ "serde_json",
+ "smallvec",
+ "sorted_vector_map",
+ "static_assertions",
+ "static_interner",
+ "strong_hash",
+ "take_mut",
+ "triomphe",
+]
+
+[[package]]
+name = "pagable_derive"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "838d17166587914f4e99353766c29160462b681511f08679545a0d07a0dc9415"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "parking"
version = "2.2.1"
@@ -4186,6 +4965,25 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
+[[package]]
+name = "pem"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
+dependencies = [
+ "base64 0.22.1",
+ "serde_core",
+]
+
+[[package]]
+name = "pem-rfc7468"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
+dependencies = [
+ "base64ct",
+]
+
[[package]]
name = "percent-encoding"
version = "2.3.2"
@@ -4220,7 +5018,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4322,6 +5120,20 @@ dependencies = [
"winreg",
]
+[[package]]
+name = "postcard"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
+dependencies = [
+ "cobs",
+ "crc",
+ "embedded-io 0.4.0",
+ "embedded-io 0.6.1",
+ "heapless",
+ "serde",
+]
+
[[package]]
name = "potential_utf"
version = "0.1.5"
@@ -4363,7 +5175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4418,7 +5230,7 @@ dependencies = [
"itertools 0.14.0",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4479,6 +5291,17 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "quickcheck"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95c589f335db0f6aaa168a7cd27b1fc6920f5e1470c804f814d9cd6e62a0f70b"
+dependencies = [
+ "env_logger",
+ "log",
+ "rand 0.10.1",
+]
+
[[package]]
name = "quinn"
version = "0.11.9"
@@ -4556,6 +5379,16 @@ version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+[[package]]
+name = "radix_trie"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
+dependencies = [
+ "endian-type",
+ "nibble_vec",
+]
+
[[package]]
name = "rand"
version = "0.8.6"
@@ -4716,6 +5549,17 @@ dependencies = [
"bitflags 2.13.0",
]
+[[package]]
+name = "redox_users"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+dependencies = [
+ "getrandom 0.2.17",
+ "libredox",
+ "thiserror 1.0.69",
+]
+
[[package]]
name = "redox_users"
version = "0.5.2"
@@ -4744,7 +5588,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4782,6 +5626,16 @@ version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+[[package]]
+name = "regress"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "158a764437582235e3501f683b93a0a6f8d825d04a789dbe5ed30b8799b8908a"
+dependencies = [
+ "hashbrown 0.16.1",
+ "memchr",
+]
+
[[package]]
name = "reqwest"
version = "0.12.28"
@@ -4909,7 +5763,7 @@ dependencies = [
"cfg-if 1.0.4",
"getrandom 0.2.17",
"libc",
- "untrusted",
+ "untrusted 0.9.0",
"windows-sys 0.52.0",
]
@@ -4959,7 +5813,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_json",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5100,7 +5954,7 @@ dependencies = [
"aws-lc-rs",
"ring",
"rustls-pki-types",
- "untrusted",
+ "untrusted 0.9.0",
]
[[package]]
@@ -5109,12 +5963,40 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+[[package]]
+name = "rustyline"
+version = "14.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63"
+dependencies = [
+ "bitflags 2.13.0",
+ "cfg-if 1.0.4",
+ "clipboard-win",
+ "fd-lock",
+ "home",
+ "libc",
+ "log",
+ "memchr",
+ "nix 0.28.0",
+ "radix_trie",
+ "unicode-segmentation",
+ "unicode-width 0.1.14",
+ "utf8parse",
+ "windows-sys 0.52.0",
+]
+
[[package]]
name = "ryu"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
+[[package]]
+name = "ryu-js"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04d056b875a9d2e6cb9a61d127afee9ac5999b9f87bcb32079d1318e505be714"
+
[[package]]
name = "safe-transmute"
version = "0.11.3"
@@ -5149,6 +6031,48 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "schemafy"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8aea5ba40287dae331f2c48b64dbc8138541f5e97ee8793caa7948c1f31d86d5"
+dependencies = [
+ "Inflector",
+ "schemafy_core",
+ "schemafy_lib",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "serde_repr",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "schemafy_core"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41781ae092f4fd52c9287efb74456aea0d3b90032d2ecad272bd14dbbcb0511b"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "schemafy_lib"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e953db32579999ca98c451d80801b6f6a7ecba6127196c5387ec0774c528befa"
+dependencies = [
+ "Inflector",
+ "proc-macro2",
+ "quote",
+ "schemafy_core",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "syn 1.0.109",
+]
+
[[package]]
name = "schemars"
version = "0.8.22"
@@ -5199,7 +6123,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5211,7 +6135,7 @@ dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5280,6 +6204,16 @@ name = "semver"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+dependencies = [
+ "serde",
+ "serde_core",
+]
+
+[[package]]
+name = "sequence_trie"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ee22067b7ccd072eeb64454b9c6e1b33b61cd0d49e895fd48676a184580e0c3"
[[package]]
name = "serde"
@@ -5308,7 +6242,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5319,7 +6253,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5336,6 +6270,17 @@ dependencies = [
"zmij",
]
+[[package]]
+name = "serde_json_canonicalizer"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe52319a927259afbfa5180c5157cd8167edfd3e8c254f9558c7fef44c5649f2"
+dependencies = [
+ "ryu-js",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "serde_path_to_error"
version = "0.1.20"
@@ -5355,7 +6300,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5367,6 +6312,18 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_tokenstream"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7c49585c52c01f13c5c2ebb333f14f6885d76daa768d8a037d28017ec538c69"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.117",
+]
+
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -5408,7 +6365,7 @@ dependencies = [
"darling 0.23.0",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5457,7 +6414,7 @@ checksum = "94e153fc76e1c6a068703d6d29c508a0b15c061c4b7e43da59cc097bc342673c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5573,13 +6530,182 @@ dependencies = [
]
[[package]]
-name = "signal-hook-registry"
-version = "1.4.8"
+name = "signal-hook-registry"
+version = "1.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+dependencies = [
+ "errno",
+ "libc",
+]
+
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "sigstore-bundle"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e7dc53c8a941858d01479622dbb7650aaa2ee0ca1fb58fb6cdddbfc3064abbb"
+dependencies = [
+ "base64 0.22.1",
+ "hex",
+ "serde",
+ "serde_json",
+ "sigstore-crypto",
+ "sigstore-merkle",
+ "sigstore-rekor",
+ "sigstore-tsa",
+ "sigstore-types",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "sigstore-crypto"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da90c3d9af638898a5fdc347479b18f950bb0dde11ecf2244f94cd28135da53b"
+dependencies = [
+ "aws-lc-rs",
+ "base64 0.22.1",
+ "const-oid 0.9.6",
+ "der",
+ "digest 0.10.7",
+ "pem",
+ "rand_core 0.10.1",
+ "sha2 0.10.9",
+ "signature",
+ "sigstore-types",
+ "spki",
+ "thiserror 2.0.18",
+ "tracing",
+ "x509-cert",
+]
+
+[[package]]
+name = "sigstore-merkle"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c0d53558825c77716855c13794306fff766854c1bf92948e77d7890da3f2455"
+dependencies = [
+ "base64 0.22.1",
+ "hex",
+ "sigstore-crypto",
+ "sigstore-types",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "sigstore-rekor"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "641fdaaa40d0cd6e249cf1671c2240beff1a3ece578062cf43e750779e8db2b3"
+dependencies = [
+ "base64 0.22.1",
+ "hex",
+ "reqwest 0.13.4",
+ "serde",
+ "serde_json",
+ "sigstore-crypto",
+ "sigstore-merkle",
+ "sigstore-types",
+ "thiserror 2.0.18",
+ "url",
+]
+
+[[package]]
+name = "sigstore-trust-root"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee8762a4813252faffdf6f7e2040213078eb2482fbc351381134f3fc60c1be9c"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "sigstore-crypto",
+ "sigstore-types",
+ "thiserror 2.0.18",
+ "x509-cert",
+]
+
+[[package]]
+name = "sigstore-tsa"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bc86c8abc1ece6832236e7e34e9baebb5d4d40490c0332b814a0d8624ca7255"
+dependencies = [
+ "aws-lc-rs",
+ "base64 0.22.1",
+ "chrono",
+ "cmpv2",
+ "cms",
+ "const-oid 0.9.6",
+ "der",
+ "hex",
+ "rand 0.10.1",
+ "reqwest 0.13.4",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "sigstore-crypto",
+ "sigstore-types",
+ "thiserror 2.0.18",
+ "tracing",
+ "x509-cert",
+ "x509-tsp",
+]
+
+[[package]]
+name = "sigstore-types"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8d870c9bcfdf83396ac2bd2d6a23c5d09ec02cc9fda50fa1cbb3dd71a9bee53"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "pem",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "sigstore-verify"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
+checksum = "6d751d608afd334fb9d8c037ad9efef69f1954494eff99cd79a0a6fc8af34ccb"
dependencies = [
- "errno",
- "libc",
+ "base64 0.22.1",
+ "chrono",
+ "cms",
+ "const-oid 0.9.6",
+ "hex",
+ "pem",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "serde",
+ "serde_json",
+ "serde_json_canonicalizer",
+ "sigstore-bundle",
+ "sigstore-crypto",
+ "sigstore-merkle",
+ "sigstore-rekor",
+ "sigstore-trust-root",
+ "sigstore-tsa",
+ "sigstore-types",
+ "thiserror 2.0.18",
+ "tls_codec",
+ "tracing",
+ "x509-cert",
]
[[package]]
@@ -5657,6 +6783,35 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "sorted_vector_map"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94bf565ee1681b4473aa5a9d71d807347c28021bd1d8947cb626b02f42a0141f"
+dependencies = [
+ "itertools 0.14.0",
+ "quickcheck",
+]
+
+[[package]]
+name = "spin"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
[[package]]
name = "spm_precompiled"
version = "0.1.4"
@@ -5688,12 +6843,118 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+[[package]]
+name = "starlark"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9062e866918dc4c9701c98ac99f7f4fa9e4b3b4edce306e147393bc75458c4fc"
+dependencies = [
+ "allocative",
+ "anyhow",
+ "blake3",
+ "bumpalo",
+ "cmp_any",
+ "dashmap",
+ "debugserver-types",
+ "derivative",
+ "derive_more 1.0.0",
+ "display_container",
+ "dupe",
+ "either",
+ "erased-serde 0.3.31",
+ "hashbrown 0.16.1",
+ "indexmap 2.14.0",
+ "inventory",
+ "itertools 0.14.0",
+ "maplit",
+ "memoffset",
+ "num-bigint",
+ "num-traits",
+ "once_cell",
+ "pagable",
+ "paste",
+ "ref-cast",
+ "regex",
+ "rustyline",
+ "serde",
+ "serde_json",
+ "starlark_derive",
+ "starlark_map",
+ "starlark_syntax",
+ "static_assertions",
+ "strong_hash",
+ "strsim 0.10.0",
+ "textwrap 0.11.0",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "starlark_derive"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "797e235eb70936bfa14fabf490bf7453e6f0caaf6b9c56fe4c9aff02aee7e66d"
+dependencies = [
+ "dupe",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "starlark_map"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "234877898fd216af93b2f5798b08cbbdc1a2e8f16a622a258b1db23a61a1c4ba"
+dependencies = [
+ "allocative",
+ "dupe",
+ "equivalent",
+ "fxhash",
+ "hashbrown 0.16.1",
+ "pagable",
+ "serde",
+ "strong_hash",
+]
+
+[[package]]
+name = "starlark_syntax"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7492c571c531e68099c911cfd909d32659f1cc0910cf3adee9fce66e39d21f14"
+dependencies = [
+ "allocative",
+ "annotate-snippets",
+ "anyhow",
+ "derivative",
+ "derive_more 1.0.0",
+ "dupe",
+ "logos",
+ "lsp-types",
+ "memchr",
+ "num-bigint",
+ "num-traits",
+ "once_cell",
+ "pagable",
+ "starlark_map",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+[[package]]
+name = "static_interner"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0a72d2480db611b8ee9287b4a2e0adc63c4d7fdd647d2a1a65d529fc234fd16"
+dependencies = [
+ "equivalent",
+ "lock_free_hashtable",
+]
+
[[package]]
name = "statrs"
version = "0.18.0"
@@ -5719,6 +6980,32 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
+[[package]]
+name = "strong_hash"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0831334aea34390b6b6ec7af0a27f9ee6324ad3a69463e6b240d83d6b7bce9c9"
+dependencies = [
+ "ref-cast",
+ "strong_hash_derive",
+]
+
+[[package]]
+name = "strong_hash_derive"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace6b48b7c4383a39bd3b966cca41bc999003aab9f690a2f355525c924296928"
+dependencies = [
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
[[package]]
name = "strsim"
version = "0.11.1"
@@ -5759,7 +7046,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5771,7 +7058,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5795,6 +7082,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.117"
@@ -5823,7 +7121,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5896,6 +7194,12 @@ dependencies = [
"libc",
]
+[[package]]
+name = "take_mut"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
+
[[package]]
name = "tempfile"
version = "3.27.0"
@@ -5918,6 +7222,15 @@ dependencies = [
"winapi-util",
]
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width 0.1.14",
+]
+
[[package]]
name = "textwrap"
version = "0.16.2"
@@ -5955,7 +7268,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -5966,7 +7279,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6059,6 +7372,27 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+[[package]]
+name = "tls_codec"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b"
+dependencies = [
+ "tls_codec_derive",
+ "zeroize",
+]
+
+[[package]]
+name = "tls_codec_derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
[[package]]
name = "tokenizers"
version = "0.21.4"
@@ -6119,7 +7453,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6374,7 +7708,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -6710,6 +8044,16 @@ dependencies = [
"petgraph",
]
+[[package]]
+name = "triomphe"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+]
+
[[package]]
name = "try-lock"
version = "0.2.5"
@@ -6738,7 +8082,7 @@ checksum = "38d90eea51bc7988ef9e674bf80a85ba6804739e535e9cab48e4bb34a8b652aa"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"termcolor",
]
@@ -6776,6 +8120,12 @@ version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c"
+[[package]]
+name = "typeid"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
+
[[package]]
name = "typenum"
version = "1.20.1"
@@ -6788,6 +8138,53 @@ version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "214ca0b2191785cbc06209b9ca1861e048e39b5ba33574b3cedd58363d5bb5f6"
+[[package]]
+name = "typify"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc0b89f47309feaeb23c4509c15c9a04234f7deccef6f96c3bfe95319819a304"
+dependencies = [
+ "typify-impl",
+ "typify-macro",
+]
+
+[[package]]
+name = "typify-impl"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7b026f540b148b81043c720889dbb942b08659aa8a43f624ac4f04dbfc1861"
+dependencies = [
+ "heck",
+ "log",
+ "proc-macro2",
+ "quote",
+ "regress",
+ "schemars 0.8.22",
+ "semver",
+ "serde",
+ "serde_json",
+ "syn 2.0.117",
+ "thiserror 2.0.18",
+ "unicode-ident",
+]
+
+[[package]]
+name = "typify-macro"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39ed96c57f06ae0839416b986921a98f18b220da63bbb243a8570a00c8492183"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "schemars 0.8.22",
+ "semver",
+ "serde",
+ "serde_json",
+ "serde_tokenstream",
+ "syn 2.0.117",
+ "typify-impl",
+]
+
[[package]]
name = "uds_windows"
version = "1.1.0"
@@ -6873,6 +8270,12 @@ version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
[[package]]
name = "untrusted"
version = "0.9.0"
@@ -7070,7 +8473,7 @@ dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wasm-bindgen-shared",
]
@@ -7341,6 +8744,16 @@ dependencies = [
"windows-targets 0.48.5",
]
+[[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"
version = "0.62.2"
@@ -7348,7 +8761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
dependencies = [
"windows-collections",
- "windows-core",
+ "windows-core 0.62.2",
"windows-future",
"windows-numerics",
]
@@ -7359,7 +8772,20 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
dependencies = [
- "windows-core",
+ "windows-core 0.62.2",
+]
+
+[[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]]
@@ -7368,11 +8794,11 @@ 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]]
@@ -7381,11 +8807,22 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
dependencies = [
- "windows-core",
+ "windows-core 0.62.2",
"windows-link",
"windows-threading",
]
+[[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.117",
+]
+
[[package]]
name = "windows-implement"
version = "0.60.2"
@@ -7394,7 +8831,18 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
+]
+
+[[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.117",
]
[[package]]
@@ -7405,7 +8853,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -7420,7 +8868,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
dependencies = [
- "windows-core",
+ "windows-core 0.62.2",
"windows-link",
]
@@ -7431,8 +8879,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]]
@@ -7444,6 +8901,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"
@@ -7747,7 +9214,7 @@ dependencies = [
"heck",
"indexmap 2.14.0",
"prettyplease",
- "syn",
+ "syn 2.0.117",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
@@ -7763,7 +9230,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wit-bindgen-core",
"wit-bindgen-rust",
]
@@ -7846,6 +9313,31 @@ version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
+[[package]]
+name = "x509-cert"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94"
+dependencies = [
+ "const-oid 0.9.6",
+ "der",
+ "sha1",
+ "signature",
+ "spki",
+ "tls_codec",
+]
+
+[[package]]
+name = "x509-tsp"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5ceece934a21607055b7ac5c25adb56a2ff559804b10705dc674d1d838c15e1"
+dependencies = [
+ "cmpv2",
+ "cms",
+ "der",
+]
+
[[package]]
name = "xdg-home"
version = "1.3.0"
@@ -7976,7 +9468,7 @@ dependencies = [
"chrono",
"colored 3.1.1",
"const-str",
- "ctor",
+ "ctor 0.6.3",
"dirs",
"futures",
"git-version",
@@ -8037,7 +9529,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
@@ -8088,7 +9580,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"zvariant_utils",
]
@@ -8120,7 +9612,7 @@ checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8140,7 +9632,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
@@ -8161,7 +9653,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8194,7 +9686,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -8240,7 +9732,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"zvariant_utils",
]
@@ -8252,5 +9744,5 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
diff --git a/Cargo.toml b/Cargo.toml
index 572d92ec..81a677bc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,9 +2,14 @@
members = [
"crates/core",
"crates/code-search",
+ "crates/execpolicy",
"crates/tools",
"crates/provider",
"crates/safety",
+ "crates/sandbox",
+ "crates/linux-sandbox",
+ "crates/sandbox-network-proxy",
+ "crates/windows-sandbox",
"crates/tasks",
"crates/mcp",
"crates/network-proxy",
@@ -57,6 +62,7 @@ devo-client = { path = "crates/client" }
devo-code-search = { path = "crates/code-search" }
devo-config = { path = "crates/config" }
devo-core = { path = "crates/core" }
+devo-execpolicy = { path = "crates/execpolicy" }
devo-file-search = { path = "crates/file-search" }
devo-keyring-store = { path = "crates/keyring-store" }
devo-mcp = { path = "crates/mcp" }
@@ -65,6 +71,10 @@ devo-protocol = { path = "crates/protocol" }
devo-provider = { path = "crates/provider" }
devo-rmcp-client = { path = "crates/rmcp-client" }
devo-safety = { path = "crates/safety" }
+devo-sandbox = { path = "crates/sandbox" }
+devo-linux-sandbox = { path = "crates/linux-sandbox" }
+devo-sandbox-network-proxy = { path = "crates/sandbox-network-proxy" }
+devo-windows-sandbox = { path = "crates/windows-sandbox" }
devo-server = { path = "crates/server" }
devo-skills = { path = "crates/skills" }
devo-tasks = { path = "crates/tasks" }
@@ -77,8 +87,10 @@ devo-util-process = { path = "crates/utils/process" }
devo-util-shell-command = { path = "crates/utils/shell-command" }
diffy = "0.4.2"
dirs = "6"
+dunce = "1"
fs2 = "0.4"
futures = { version = "0.3", default-features = false }
+globset = "0.4"
hf-hub = { version = "1.0.0-rc.1", features = ["blocking", "rustls-tls"] }
hnsw_rs = "0.3.4"
iana-time-zone = "0.1.65"
@@ -90,8 +102,10 @@ itertools = "0.14.0"
keyring = { version = "3.6", default-features = false }
lazy_static = "1"
libc = "0.2.182"
+multimap = "0.10.1"
model2vec = "0.3.0"
notify = "8.2.0"
+nono = { version = "=0.53.0", default-features = false }
nucleo = { git = "https://github.com/helix-editor/nucleo.git", rev = "4253de9faabb4e5c6d81d946a5e35a90f87347ee" }
once_cell = "1.20.2"
pathdiff = "0.2"
@@ -120,6 +134,7 @@ serial_test = "3.2.0"
sha2 = "0.10"
shlex = "1.3.0"
smol_str = { version = "0.3", features = ["serde"] }
+starlark = { version = "0.14.2", default-features = false }
strum = "0.27.2"
strum_macros = "0.28.0"
supports-color = "3.0.2"
diff --git a/README.ja.md b/README.ja.md
index 2845b901..c55d0115 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -83,7 +83,7 @@ Desktop 体験、terminal workflow、ランタイムの動作、ワークスペ
-
+
Devo の組み込みモデルカタログには、Qwen、Kimi、MiniMax、GLM、DeepSeek の検証済みモデル定義が含まれています。
diff --git a/README.md b/README.md
index ac7f00c6..99417e77 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ runtime behavior, and workspace execution under your control.
-
+
Devo's built-in model catalog includes tested model definitions for Qwen, Kimi,
diff --git a/README.ru.md b/README.ru.md
index 11aba066..3005abd7 100644
--- a/README.ru.md
+++ b/README.ru.md
@@ -90,7 +90,7 @@ Devo предназначен для команд, которым нужен cod
-
+
Встроенный каталог моделей Devo содержит проверенные определения моделей для
diff --git a/README.zh-Hans.md b/README.zh-Hans.md
index 11d04c10..0dbe9061 100644
--- a/README.zh-Hans.md
+++ b/README.zh-Hans.md
@@ -77,7 +77,7 @@ Desktop 体验、终端工作流以及工作区执行边界的团队。
-
+
Devo 的内置模型目录包含 Qwen、Kimi、MiniMax、GLM 和 DeepSeek 的已测试模型定义。
diff --git a/README.zh-Hant.md b/README.zh-Hant.md
index 6eda75e1..97d29e40 100644
--- a/README.zh-Hant.md
+++ b/README.zh-Hant.md
@@ -77,7 +77,7 @@ Desktop 體驗、終端機工作流以及工作區執行邊界的團隊。
-
+
Devo 的內建模型目錄包含 Qwen、Kimi、MiniMax、GLM 和 DeepSeek 的已測試模型定義。
diff --git a/apps/desktop/src/main/tray-menu.test.ts b/apps/desktop/src/main/tray-menu.test.ts
index d0e63d89..d6b61692 100644
--- a/apps/desktop/src/main/tray-menu.test.ts
+++ b/apps/desktop/src/main/tray-menu.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, test } from "bun:test"
import type { MenuItemConstructorOptions } from "electron"
-import { buildCodexStyleTrayMenuTemplate } from "./tray-menu"
+import { buildDevoTrayMenuTemplate } from "./tray-menu"
function menuShape(items: MenuItemConstructorOptions[]): unknown[] {
return items.map((item) => ({
@@ -13,8 +13,8 @@ function menuShape(items: MenuItemConstructorOptions[]): unknown[] {
}))
}
-describe("buildCodexStyleTrayMenuTemplate", () => {
- test("builds a Codex-style tray menu with running, recent, usage, and actions", () => {
+describe("buildDevoTrayMenuTemplate", () => {
+ test("builds a Devo tray menu with running, recent, usage, and actions", () => {
const liveSessions = new Map([
[
"s1",
@@ -74,7 +74,7 @@ describe("buildCodexStyleTrayMenuTemplate", () => {
},
]
- const template = buildCodexStyleTrayMenuTemplate({
+ const template = buildDevoTrayMenuTemplate({
liveSessions,
discovery: {
projects: [],
diff --git a/apps/desktop/src/main/tray-menu.ts b/apps/desktop/src/main/tray-menu.ts
index ce6ea005..c1807004 100644
--- a/apps/desktop/src/main/tray-menu.ts
+++ b/apps/desktop/src/main/tray-menu.ts
@@ -11,7 +11,7 @@ export interface DiscoveryCache {
sessions: Session[]
}
-export interface CodexStyleTrayMenuOptions {
+export interface DevoTrayMenuOptions {
liveSessions: ReadonlyMap
discovery: DiscoveryCache | null
pendingCount: number
@@ -40,8 +40,8 @@ interface UsageSummary {
cacheReadTokens: number
}
-export function buildCodexStyleTrayMenuTemplate(
- options: CodexStyleTrayMenuOptions,
+export function buildDevoTrayMenuTemplate(
+ options: DevoTrayMenuOptions,
): MenuItemConstructorOptions[] {
const template: MenuItemConstructorOptions[] = []
diff --git a/apps/desktop/src/main/tray.ts b/apps/desktop/src/main/tray.ts
index 69b93b1d..f6afff87 100644
--- a/apps/desktop/src/main/tray.ts
+++ b/apps/desktop/src/main/tray.ts
@@ -23,7 +23,7 @@ import {
type SessionState,
} from "./notification-watcher"
import { getAcpTransport, getServerUrl, onServerReady } from "./devo-manager"
-import { buildCodexStyleTrayMenuTemplate, type DiscoveryCache } from "./tray-menu"
+import { buildDevoTrayMenuTemplate, type DiscoveryCache } from "./tray-menu"
const log = createLogger("tray")
@@ -182,7 +182,7 @@ function rebuildMenu(): void {
const liveSessions = getSessionStates()
const pendingCount = getPendingCount()
- const template = buildCodexStyleTrayMenuTemplate({
+ const template = buildDevoTrayMenuTemplate({
liveSessions,
discovery: discoveryCache,
pendingCount,
diff --git a/apps/desktop/src/renderer/atoms/derived/session-metrics.ts b/apps/desktop/src/renderer/atoms/derived/session-metrics.ts
index 5e5a797b..5c885b12 100644
--- a/apps/desktop/src/renderer/atoms/derived/session-metrics.ts
+++ b/apps/desktop/src/renderer/atoms/derived/session-metrics.ts
@@ -7,7 +7,7 @@
*/
import { atom } from "jotai"
import { atomFamily } from "jotai-family"
-import { getToolCategory } from "../../components/chat/tool-card"
+import { getToolCategory } from "../../components/chat/tool-category"
import {
computeSessionMetricsExtended,
formatCost,
diff --git a/apps/desktop/src/renderer/components/chat/chat-tool-call.test.ts b/apps/desktop/src/renderer/components/chat/chat-tool-call.test.ts
index 68680ad8..2c90923a 100644
--- a/apps/desktop/src/renderer/components/chat/chat-tool-call.test.ts
+++ b/apps/desktop/src/renderer/components/chat/chat-tool-call.test.ts
@@ -1,48 +1,67 @@
import { readFileSync } from "node:fs"
import { describe, expect, test } from "bun:test"
-import { getToolDuration, getToolSubtitle, shouldDefaultOpen } from "./chat-tool-call"
+import { buildBashTerminalOutput, getToolSubtitle, stripShellEnvelope } from "./chat-tool-call"
const elapsedHookSource = readFileSync(new URL("../../hooks/use-elapsed-time.ts", import.meta.url), "utf8")
const chatToolCallSource = readFileSync(new URL("./chat-tool-call.tsx", import.meta.url), "utf8")
const rendererCssSource = readFileSync(new URL("../../index.css", import.meta.url), "utf8")
-describe("shouldDefaultOpen", () => {
- test("keeps all tool output collapsed by default", () => {
+describe("buildBashTerminalOutput", () => {
+ test("joins command and output into a single terminal block", () => {
expect({
- bash: shouldDefaultOpen("bash", "completed"),
- read: shouldDefaultOpen("read", "completed"),
- bashError: shouldDefaultOpen("bash", "error"),
- readError: shouldDefaultOpen("read", "error"),
- unknown: shouldDefaultOpen("unknown", "error"),
+ plain: buildBashTerminalOutput("bun test", "ok\nDone", undefined),
+ echoed: buildBashTerminalOutput("bun test", "$ bun test\nok", undefined),
+ errorPreferred: buildBashTerminalOutput("bun test", "partial", "boom"),
+ pending: buildBashTerminalOutput("bun test", undefined, undefined),
+ noCommand: buildBashTerminalOutput(undefined, "plain output", undefined),
}).toEqual({
- bash: false,
- read: false,
- bashError: false,
- readError: false,
- unknown: false,
+ plain: "$ bun test\nok\nDone",
+ echoed: "$ bun test\nok",
+ errorPreferred: "$ bun test\nboom",
+ pending: "$ bun test",
+ noCommand: "plain output",
})
})
-})
-describe("getToolDuration", () => {
- test("uses SDK tool state start and end timestamps", () => {
- expect(
- getToolDuration({
- id: "tool-1",
- type: "tool",
- state: { status: "completed", time: { start: 1_000, end: 3_500 } },
- } as any),
- ).toBe("2s")
+ test("truncates very long output", () => {
+ const truncated = buildBashTerminalOutput(undefined, "x".repeat(6000), undefined)
+ expect({
+ endsWithMarker: truncated.endsWith("... (truncated)"),
+ length: truncated.length,
+ }).toEqual({
+ endsWithMarker: true,
+ length: 5000 + "\n... (truncated)".length,
+ })
})
+})
- test("clamps reversed timestamps instead of showing negative durations", () => {
- expect(
- getToolDuration({
- id: "tool-1",
- type: "tool",
- state: { status: "completed", time: { start: 3_500, end: 1_000 } },
- } as any),
- ).toBe("0ms")
+describe("stripShellEnvelope", () => {
+ test("strips the shell result envelope from tool output", () => {
+ const envelope = JSON.stringify({
+ output: "",
+ command: "ls",
+ exit: 0,
+ description: "List files",
+ cwd: "/repo",
+ yield_time_ms: 1000,
+ })
+ expect({
+ envelopeOnly: stripShellEnvelope(envelope),
+ stdoutPlusEnvelope: stripShellEnvelope(`hello\nworld\n${envelope}`),
+ plainOutput: stripShellEnvelope("just text"),
+ otherJson: stripShellEnvelope('{"foo": 1}'),
+ envelopeWithOutput: stripShellEnvelope(
+ JSON.stringify({ output: "files", command: "ls", exit: 0 }),
+ ),
+ cmdEnvelope: stripShellEnvelope(JSON.stringify({ output: "ok", cmd: "ls", exit: 0 })),
+ }).toEqual({
+ envelopeOnly: "",
+ stdoutPlusEnvelope: "hello\nworld",
+ plainOutput: "just text",
+ otherJson: '{"foo": 1}',
+ envelopeWithOutput: "files",
+ cmdEnvelope: "ok",
+ })
})
})
@@ -140,3 +159,16 @@ describe("useToolElapsedTime source", () => {
})
})
})
+
+
+describe("ChatToolCall memo comparison", () => {
+ test("re-renders when the controlled open state changes so rows can expand", () => {
+ expect({
+ comparesOpen: chatToolCallSource.includes("prev.open !== next.open"),
+ comparesTurnError: chatToolCallSource.includes("prev.turnHasError !== next.turnHasError"),
+ }).toEqual({
+ comparesOpen: true,
+ comparesTurnError: true,
+ })
+ })
+})
diff --git a/apps/desktop/src/renderer/components/chat/chat-tool-call.tsx b/apps/desktop/src/renderer/components/chat/chat-tool-call.tsx
index 696d59bc..3001d557 100644
--- a/apps/desktop/src/renderer/components/chat/chat-tool-call.tsx
+++ b/apps/desktop/src/renderer/components/chat/chat-tool-call.tsx
@@ -7,13 +7,7 @@ import {
CodeBlockTitle,
} from "@devo/ui/components/ai-elements/code-block"
import { Diff, DiffContent } from "@devo/ui/components/ai-elements/diff"
-import {
- Terminal,
- TerminalContent,
- TerminalCopyButton,
- TerminalHeader,
- TerminalTitle,
-} from "@devo/ui/components/ai-elements/terminal"
+import { Terminal, TerminalContent } from "@devo/ui/components/ai-elements/terminal"
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from "@devo/ui/components/dialog"
import { cn } from "@devo/ui/lib/utils"
@@ -45,7 +39,7 @@ import { viewFileInDiffPanelAtom } from "../../atoms/ui"
import { detectContentLanguage, detectLanguage, prettyPrintJson } from "../../lib/language"
import type { FilePart, ToolPart, ToolStateCompleted } from "../../lib/types"
import { SubAgentCard } from "./sub-agent-card"
-import type { ToolCategory } from "./tool-card"
+import type { ToolCategory } from "./tool-category"
import {
TranscriptDisclosure,
TranscriptDisclosureContent,
@@ -71,23 +65,63 @@ function truncateOutput(output: string, max = MAX_OUTPUT_LENGTH): string {
return `${output.slice(0, max)}\n... (truncated)`
}
+/** Shell-family tools that share the command/terminal display. */
+const SHELL_TOOLS: ReadonlySet = new Set(["bash", "shell_command", "exec_command"])
+
+/**
+ * The shell tool's result text is `\n`, where the
+ * envelope carries display metadata ({output, command, exit, description,
+ * cwd, yield_time_ms}). Strip it so the terminal shows only real command
+ * output; the command and description already appear in the tool row itself.
+ */
+export function stripShellEnvelope(output: string): string {
+ const parseEnvelope = (text: string): { body?: string } | undefined => {
+ try {
+ const parsed = JSON.parse(text)
+ if (
+ parsed &&
+ typeof parsed === "object" &&
+ typeof parsed.exit === "number" &&
+ (typeof parsed.command === "string" || typeof parsed.cmd === "string")
+ ) {
+ return { body: typeof parsed.output === "string" ? parsed.output : undefined }
+ }
+ } catch {
+ // Not JSON — ordinary command output.
+ }
+ return undefined
+ }
+
+ const trimmed = output.trim()
+ // The output IS the envelope (the command produced no stdout).
+ if (trimmed.startsWith("{")) {
+ const whole = parseEnvelope(trimmed)
+ if (whole) return whole.body ?? ""
+ }
+ // Stdout followed by the envelope JSON (they are joined with "\n").
+ const separator = output.lastIndexOf("\n{")
+ if (separator !== -1) {
+ const tail = parseEnvelope(output.slice(separator + 1).trim())
+ if (tail) return output.slice(0, separator).trimEnd()
+ }
+ return output
+}
+
// ============================================================
-// Read output parsing — strip cat -n prefixes and tags
+// Read output parsing — strip wrapper tags, keep original line numbers
// ============================================================
-/** Pre-compiled regex for line-number formats (hoisted to avoid re-creation per call) */
-const LINE_NUM_REGEX = /^\s*(\d+)[|:\t]\s?(.*)$/
-
/**
* Parses output from various read tools.
* Handles:
* 1. Claude Code's `cat -n` format: 00001| content
* 2. Devo's XML-wrapped format: ...1: content
*
- * This function strips the wrapper tags, removes the line-number
- * prefixes, and returns the clean content + the starting line number.
+ * Strips the wrapper tags and trailing metadata lines, but keeps the
+ * content's own line-number prefixes — the read output already carries
+ * line numbers, so the UI must not add another gutter of its own.
*/
-function parseReadOutput(raw: string): { content: string; startLine: number } {
+function parseReadOutput(raw: string): string {
let text = raw
// 1. Strip Devo XML-style tags
@@ -113,28 +147,7 @@ function parseReadOutput(raw: string): { content: string; startLine: number } {
text = text.replace(/\n?\s*\(File has more lines[^)]*\)\s*$/, "")
text = text.replace(/\n?\s*\(Output truncated[^)]*\)\s*$/, "")
- const lines = text.split("\n")
- // If first line has a line number, use it as startLine
- const firstMatch = lines[0]?.match(LINE_NUM_REGEX)
-
- if (!firstMatch) {
- return { content: text, startLine: 1 }
- }
-
- const startLine = Number.parseInt(firstMatch[1], 10)
- const stripped: string[] = []
-
- for (const line of lines) {
- const match = line.match(LINE_NUM_REGEX)
- if (match) {
- stripped.push(match[2])
- } else {
- // Lines without prefix (e.g. blank lines) — keep as-is
- stripped.push(line)
- }
- }
-
- return { content: stripped.join("\n"), startLine }
+ return text
}
// ============================================================
@@ -186,6 +199,8 @@ export function getToolInfo(tool: string): {
case "webfetch":
return { icon: GlobeIcon, title: "Fetch" }
case "bash":
+ case "shell_command":
+ case "exec_command":
return { icon: TerminalIcon, title: "Shell" }
case "edit":
return { icon: EditIcon, title: "Edit" }
@@ -241,6 +256,8 @@ function getPendingLabel(tool: string): string {
case "apply_patch":
return "Preparing patch..."
case "bash":
+ case "shell_command":
+ case "exec_command":
return "Preparing command..."
case "read":
return "Preparing read..."
@@ -294,11 +311,14 @@ export function getToolSubtitle(
extractFromRaw(state, "pattern", "path")
break
case "bash":
+ case "shell_command":
+ case "exec_command":
subtitle =
title ??
(input.description as string) ??
(input.command as string) ??
- extractFromRaw(state, "command", "description")
+ (input.cmd as string) ??
+ extractFromRaw(state, "command", "cmd", "description")
break
case "edit":
subtitle =
@@ -394,27 +414,38 @@ function formatInputParams(input: Record): string | undefined {
return `[${parts.join(", ")}]`
}
-/** Compute completed tool duration from the SDK tool-state timestamps. */
-export function getToolDuration(part: ToolPart): string | undefined {
- const state = part.state
- if (state.status === "completed" || state.status === "error") {
- const ms = Math.max(0, state.time.end - state.time.start)
- if (ms < 1000) return `${ms}ms`
- const seconds = Math.floor(ms / 1000)
- if (seconds < 60) return `${seconds}s`
- const minutes = Math.floor(seconds / 60)
- const remainingSeconds = seconds % 60
- return `${minutes}m ${remainingSeconds}s`
- }
- return undefined
-}
-
// ============================================================
// Tool-specific content renderers
// ============================================================
/**
- * Bash tool: shows command with syntax highlighting + ANSI-colored terminal output.
+ * Builds the text of the single terminal block shown for a bash tool call:
+ * the command as its first line, followed by the (cleaned) output.
+ *
+ * The SDK output often echoes the command as the first line (e.g.
+ * "$ command\n..."). Since we prepend the command ourselves, strip the
+ * duplicate before joining.
+ */
+export function buildBashTerminalOutput(
+ command: string | undefined,
+ output: string | undefined,
+ error: string | undefined,
+): string {
+ let body = stripShellEnvelope(error ?? output ?? "")
+ if (command) {
+ const prefix = `$ ${command}`
+ if (body.startsWith(prefix)) {
+ body = body.slice(prefix.length).replace(/^\r?\n/, "")
+ }
+ }
+ body = truncateOutput(body)
+ if (!command) return body
+ return body ? `$ ${command}\n${body}` : `$ ${command}`
+}
+
+/**
+ * Bash tool: one terminal block — command on the first line, ANSI-colored
+ * output below. No separate command code block or "Output" header.
*
* During `running` state the server streams incremental output via
* `state.metadata.output` (accumulated string, updated on every stdout/stderr
@@ -422,7 +453,9 @@ export function getToolDuration(part: ToolPart): string | undefined {
* behaviour of the Devo TUI and web UI.
*/
function BashContent({ part }: { part: ToolPart }) {
- const command = part.state.input?.command as string | undefined
+ const command =
+ (part.state.input?.command as string | undefined) ??
+ (part.state.input?.cmd as string | undefined)
// During "running", live output arrives in state.metadata.output.
// After completion it moves to state.output.
@@ -434,68 +467,27 @@ function BashContent({ part }: { part: ToolPart }) {
const error = part.state.status === "error" ? (part.state as { error: string }).error : undefined
const isStreaming = part.state.status === "running"
- const displayOutput = useMemo(() => {
- if (error) return error
- if (!output) return ""
- let cleaned = output
- // The SDK output often echoes the command as the first line (e.g. "$ command\n...").
- // Since we already render the command in a separate CodeBlock above, strip the duplicate.
- if (command) {
- const prefix = `$ ${command}`
- if (cleaned.startsWith(prefix)) {
- cleaned = cleaned.slice(prefix.length).replace(/^\r?\n/, "")
- }
- }
- return truncateOutput(cleaned)
- }, [output, error, command])
-
- // If there's meaningful output, show a terminal view with ANSI support
- if (displayOutput || isStreaming) {
- return (
-
- {command && (
-
-
-
- )}
-
-
- Output
-
-
-
-
-
- )
- }
+ const terminalOutput = useMemo(
+ () => buildBashTerminalOutput(command, output, error),
+ [command, output, error],
+ )
- // Command only (no output yet)
- if (command) {
- return (
-
-
-
- )
- }
+ if (!terminalOutput && !isStreaming) return null
- return null
+ return (
+
+
+
+ )
}
/**
* Edit tool: shows inline diff of oldString → newString with syntax highlighting.
- * No inner headers — diff stats are shown in the ToolCard trailing area.
+ * No inner headers — diff stats are shown in the tool row's trailing area.
*/
function EditDiffContent({ part }: { part: ToolPart }) {
const filePath = (part.state.input?.filePath as string) ?? (part.state.input?.path as string)
@@ -535,7 +527,7 @@ function EditDiffContent({ part }: { part: ToolPart }) {
/**
* Write tool: shows syntax-highlighted file content being written.
- * No inner header — the ToolCard header already shows the filename.
+ * No inner header — the tool row header already shows the filename.
*/
function WriteContent({ part }: { part: ToolPart }) {
const filePath = (part.state.input?.filePath as string) ?? (part.state.input?.path as string)
@@ -575,7 +567,7 @@ function WriteContent({ part }: { part: ToolPart }) {
/**
* Apply patch tool: shows diff in patch mode.
- * No inner header — the ToolCard header identifies this as a patch.
+ * No inner header — the tool row header identifies this as a patch.
*/
function PatchContent({ part }: { part: ToolPart }) {
const output = part.state.status === "completed" ? part.state.output : undefined
@@ -618,7 +610,8 @@ function PatchContent({ part }: { part: ToolPart }) {
/**
* Read tool: shows syntax-highlighted file contents.
- * Strips cat -n prefixes and tags, preserves original line numbers.
+ * Strips wrapper tags but keeps the read output's own line numbers —
+ * the code block renders no line-number gutter of its own.
*/
function ReadContent({ part }: { part: ToolPart }) {
const filePath = (part.state.input?.filePath as string) ?? (part.state.input?.path as string)
@@ -630,25 +623,16 @@ function ReadContent({ part }: { part: ToolPart }) {
const language = (detectLanguage(filePath) ?? "text") as BundledLanguage
- // Parse out cat -n line numbers and wrapper
- const { content: cleanContent, startLine } = parseReadOutput(output)
- const displayContent = truncateOutput(cleanContent)
+ // No inner header — the tool row header already shows the filename.
+ const displayContent = truncateOutput(parseReadOutput(output))
- // No inner header — the ToolCard header already shows the filename.
- // Just the code block with correct line number offset.
return (
-
+
)
}
@@ -838,6 +822,26 @@ function GenericContent({ part }: { part: ToolPart }) {
// Tool group summaries
// ============================================================
+/**
+ * Verb for an explore tool group: specific when every tool in the group is
+ * the same kind (e.g. a run of greps reads "Searched", not "Read").
+ */
+function exploreGroupVerb(tools: ToolPart[]): string {
+ const first = tools[0]?.tool
+ if (!first || !tools.every((t) => t.tool === first)) return "Explored"
+ switch (first) {
+ case "read":
+ return "Read"
+ case "grep":
+ case "glob":
+ return "Searched"
+ case "list":
+ return "Listed"
+ default:
+ return "Explored"
+ }
+}
+
export function describeToolGroup(
category: ToolCategory,
tools: ToolPart[],
@@ -857,7 +861,7 @@ export function describeToolGroup(
if (details.length > 0) {
switch (category) {
case "explore":
- return count === 1 ? `Read ${details[0]}` : `Read ${details.join(", ")}`
+ return `${exploreGroupVerb(tools)} ${count === 1 ? details[0] : details.join(", ")}`
case "edit":
return count === 1 ? `Edited ${details[0]}` : `Edited ${details.join(", ")}`
case "run":
@@ -877,8 +881,10 @@ export function describeToolGroup(
}
switch (category) {
- case "explore":
- return `Explored ${count} files`
+ case "explore": {
+ const verb = exploreGroupVerb(tools)
+ return `${verb} ${count} ${verb === "Searched" ? "patterns" : "files"}`
+ }
case "edit":
return `Edited ${count} files`
case "run":
@@ -904,22 +910,12 @@ export function isGroupError(tools: ToolPart[]): boolean {
return tools.some((t) => t.state.status === "error")
}
-// ============================================================
-// Smart defaults: which tools should be open by default
-// ============================================================
-
-/**
- * Returns whether a tool should default to expanded in the active turn.
- */
-export function shouldDefaultOpen(_tool: string, _status: string): boolean {
- return false
-}
/**
* Returns whether a tool has expandable content.
*/
function hasExpandableContent(part: ToolPart): boolean {
const { tool, state } = part
- // Task uses SubAgentCard, not ToolCard
+ // Task uses SubAgentCard, not a tool row
if (tool === "task") return false
// Todowrite has expandable todo items
if (tool === "todowrite" || tool === "todoread") {
@@ -940,8 +936,8 @@ function hasExpandableContent(part: ToolPart): boolean {
// If there's output or error, there's content
if (state.status === "completed" && state.output) return true
if (state.status === "error") return true
- // Bash always has content (the command at least)
- if (tool === "bash") return true
+ // Shell tools always have content (the command at least)
+ if (SHELL_TOOLS.has(tool)) return true
return false
}
@@ -952,7 +948,7 @@ function getToolContent(part: ToolPart): ReactNode {
const error = part.state.status === "error" ? (part.state as { error: string }).error : undefined
if (
error &&
- part.tool !== "bash" &&
+ !SHELL_TOOLS.has(part.tool) &&
part.tool !== "edit" &&
part.tool !== "write" &&
part.tool !== "read" &&
@@ -963,6 +959,8 @@ function getToolContent(part: ToolPart): ReactNode {
switch (part.tool) {
case "bash":
+ case "shell_command":
+ case "exec_command":
return
case "edit":
return
@@ -992,8 +990,6 @@ function getToolContent(part: ToolPart): ReactNode {
interface ChatToolCallProps {
part: ToolPart
- /** Whether this tool is in the active (last) turn */
- isActiveTurn?: boolean
/** Whether the turn containing this tool has an error (enables delete action) */
turnHasError?: boolean
/** Delete this tool part (for error recovery) */
@@ -1038,13 +1034,12 @@ function areToolPartsEqual(a: ToolPart, b: ToolPart): boolean {
}
/**
- * Renders a single tool call as a ToolCard with tool-specific content,
- * or as a SubAgentCard for sub-agent tasks.
+ * Renders a single tool call as a unified disclosure row with tool-specific
+ * content, or as a SubAgentCard for sub-agent tasks.
*/
export const ChatToolCall = memo(
function ChatToolCall({
part,
- isActiveTurn = false,
turnHasError = false,
onDelete,
projectRoot,
@@ -1082,7 +1077,7 @@ export const ChatToolCall = memo(
const status = part.state.status as "running" | "error" | "completed" | "pending"
- // Build trailing element: diff stats + "view diff" button, or a running spinner.
+ // Build trailing element: diff stats, or a running spinner.
const trailingElement = useMemo(() => {
const parts: ReactNode[] = []
@@ -1115,29 +1110,6 @@ export const ChatToolCall = memo(
return {parts}
}, [diffStats, status])
- // Combine trailing element with "View diff" button for edit-category tools
- const combinedTrailing = useMemo(() => {
- if (!editFilePath || status !== "completed") return trailingElement
- const viewButton = (
-
- )
- if (!trailingElement) return viewButton
- return (
-
- {trailingElement}
- {viewButton}
-
- )
- }, [editFilePath, status, trailingElement, handleViewDiff])
-
// When the turn has an error, add a delete button so the user can
// surgically remove a problematic tool part and continue the conversation.
const handleDelete = useCallback(
@@ -1149,7 +1121,7 @@ export const ChatToolCall = memo(
)
const finalTrailing = useMemo(() => {
- if (!turnHasError || !onDelete) return combinedTrailing
+ if (!turnHasError || !onDelete) return trailingElement
const deleteButton = (
)
- if (!combinedTrailing) return deleteButton
+ if (!trailingElement) return deleteButton
return (
- {combinedTrailing}
+ {trailingElement}
{deleteButton}
)
- }, [turnHasError, onDelete, combinedTrailing, handleDelete])
+ }, [turnHasError, onDelete, trailingElement, handleDelete])
// Skip rendering todoread parts without output
if (part.tool === "todoread" && part.state.status !== "completed") return null
@@ -1178,12 +1150,11 @@ export const ChatToolCall = memo(
return
}
- // --- All other tools (including todos): ToolCard ---
+ // --- All other tools (including todos): unified tool row ---
const { icon: Icon, title } = getToolInfo(part.tool)
const subtitle = getToolSubtitle(part, { projectRoot })
const hasContent = hasExpandableContent(part)
- const defaultOpen =
- defaultOpenProp ?? (isActiveTurn ? shouldDefaultOpen(part.tool, status) : false)
+ const defaultOpen = defaultOpenProp ?? false
const isRunning = status === "running" || status === "pending"
// Extract attachments
@@ -1201,10 +1172,13 @@ export const ChatToolCall = memo(
{title}
)
+ // Completed edit-category tools can jump to the diff panel; the action
+ // lives at the top of the expanded content so the row trailing stays lean.
+ const showViewDiff = editFilePath != null && status === "completed"
+
return (
{hasContent && (
-
+
+ {showViewDiff && (
+
+
+
+ )}
{getToolContent(part)}
)}
@@ -1236,10 +1223,12 @@ export const ChatToolCall = memo(
},
(prev, next) => {
if (!areToolPartsEqual(prev.part, next.part)) return false
- if (prev.isActiveTurn !== next.isActiveTurn) return false
+ // open is controlled by the parent timeline (expandedRowIds); without this
+ // comparison the memo blocks the re-render and the row can never expand.
+ if (prev.open !== next.open) return false
if (prev.turnHasError !== next.turnHasError) return false
if (prev.projectRoot !== next.projectRoot) return false
- // onDelete is a callback ref - skip reference comparison to avoid
+ // onDelete/onOpenChange are callback refs - skip reference comparison to avoid
// re-renders from parent creating new closures
return true
},
diff --git a/apps/desktop/src/renderer/components/chat/chat-turn.test.ts b/apps/desktop/src/renderer/components/chat/chat-turn.test.ts
index 0cb61cad..f7106221 100644
--- a/apps/desktop/src/renderer/components/chat/chat-turn.test.ts
+++ b/apps/desktop/src/renderer/components/chat/chat-turn.test.ts
@@ -139,7 +139,7 @@ describe("ChatTurnComponent transcript controls", () => {
expect({
definesWorkingStrip: source.includes("function WorkingTurnStatusStrip"),
- usesWorkingForCopy: source.includes('Working for "'),
+ usesWorkingForCopy: source.includes("Working for {display}"),
reusesTurnDuration: source.includes(
"computeTurnWorkTime(turn, { active: true })",
),
diff --git a/apps/desktop/src/renderer/components/chat/chat-turn.tsx b/apps/desktop/src/renderer/components/chat/chat-turn.tsx
index ba186b18..6a2919a0 100644
--- a/apps/desktop/src/renderer/components/chat/chat-turn.tsx
+++ b/apps/desktop/src/renderer/components/chat/chat-turn.tsx
@@ -583,10 +583,10 @@ function CompletedTurnProcessDisclosure({
* Renders a single turn: user message + assistant response.
*
* Two modes based on turn state:
- * - **Active turn** (last + working): tool calls are individually rendered with
- * per-tool ToolCards, smart default expand/collapse, and live activity.
- * - **Completed turn**: icon-pill summary bar with one-click expand to show
- * individual tools. Response text is always visible.
+ * - **Active turn** (last + working): the process timeline streams live —
+ * interleaved thoughts, unified tool rows, and text.
+ * - **Completed turn**: the process collapses behind a "Worked for ..."
+ * disclosure; the final response text is always visible.
*
* Display mode preference (default/verbose) modifies behavior:
* - default: interleaved text + grouped tool summaries as collapsible rows.
@@ -710,8 +710,6 @@ export const ChatTurnComponent = memo(
return ""
}, [turn.assistantMessages])
- // Determine if tools should be shown individually (active turn behavior)
- const isActiveTurn = working
const showVerboseTools = displayMode === "verbose"
const textAlreadyInline =
@@ -812,7 +810,6 @@ export const ChatTurnComponent = memo(
+
-
+
{tools.map((tool) => (
@@ -82,7 +74,6 @@ export interface ProcessTimelineViewProps {
items: ProcessTimelineItem[]
orderedParts: ProcessTimelineInput[]
working: boolean
- isActiveTurn: boolean
projectRoot?: string | null
defaultExpandAll?: boolean
expandedRowIds?: Set
@@ -96,7 +87,6 @@ export const ProcessTimelineView = memo(function ProcessTimelineView({
items,
orderedParts,
working,
- isActiveTurn,
projectRoot,
defaultExpandAll = false,
expandedRowIds,
@@ -144,7 +134,6 @@ export const ProcessTimelineView = memo(function ProcessTimelineView({
onToggleRow(rowId, open) : undefined}
open={expandedRowIds ? expandedRowIds.has(rowId) : undefined}
projectRoot={projectRoot}
diff --git a/apps/desktop/src/renderer/components/chat/process-timeline.ts b/apps/desktop/src/renderer/components/chat/process-timeline.ts
index 3b317e2d..21e41818 100644
--- a/apps/desktop/src/renderer/components/chat/process-timeline.ts
+++ b/apps/desktop/src/renderer/components/chat/process-timeline.ts
@@ -1,5 +1,5 @@
import type { ReasoningPart, ToolPart } from "../../lib/types"
-import { getToolCategory, type ToolCategory } from "./tool-card"
+import { getToolCategory, type ToolCategory } from "./tool-category"
export type ProcessTimelineInput =
| { kind: "tool"; part: ToolPart }
diff --git a/apps/desktop/src/renderer/components/chat/sub-agent-card.tsx b/apps/desktop/src/renderer/components/chat/sub-agent-card.tsx
index b8d12adb..39e92145 100644
--- a/apps/desktop/src/renderer/components/chat/sub-agent-card.tsx
+++ b/apps/desktop/src/renderer/components/chat/sub-agent-card.tsx
@@ -20,7 +20,7 @@ import { appStore } from "../../atoms/store"
import { getStreamingPartsForSession, streamingVersionFamily } from "../../atoms/streaming"
import { useToolElapsedTime } from "../../hooks/use-elapsed-time"
import type { ToolPart, ToolState } from "../../lib/types"
-import { getToolDuration, getToolInfo, getToolSubtitle } from "./chat-tool-call"
+import { getToolInfo, getToolSubtitle } from "./chat-tool-call"
// ============================================================
// Collapse state for three-tier agent card
@@ -180,8 +180,7 @@ export const SubAgentCard = memo(function SubAgentCard({ part: propPart }: SubAg
setCollapseState("summary")
}, [])
- // ── Duration ───────────────────────────────────────────────
- const duration = getToolDuration(part)
+ // ── Elapsed time (live, while running) ─────────────────────
const elapsedTime = useToolElapsedTime(part)
// Access child session data from the store.
@@ -297,15 +296,16 @@ export const SubAgentCard = memo(function SubAgentCard({ part: propPart }: SubAg
return (
-
+
-
+
{/* Waiting indicator: shown when sub-agent has a pending permission or question */}
{childIsWaiting && childHasPendingPermission && (
@@ -340,9 +339,6 @@ export const SubAgentCard = memo(function SubAgentCard({ part: propPart }: SubAg
)}
{isRunning && !childIsWaiting && }
{childIsWaiting && }
- {!isRunning && duration && (
- {duration}
- )}
{sessionId && (