diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index be85977a55..48e1523cb7 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1088,7 +1088,7 @@ "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4_wxc_common": "{\"dependencies\":[{\"name\":\"base64\",\"req\":\"0.22\"},{\"name\":\"cidr\",\"req\":\"0.3.2\"},{\"name\":\"getrandom\",\"req\":\"0.2\"},{\"default_features\":true,\"features\":[],\"name\":\"mxc_config_contract\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"mxc_schema_support\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"mxc_telemetry\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"nanvix_common\",\"optional\":true},{\"name\":\"schemars\",\"optional\":true,\"req\":\"0.8\"},{\"name\":\"semver\",\"req\":\"1\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":false,\"req\":\"1\"},{\"features\":[\"raw_value\"],\"name\":\"serde_json\",\"req\":\"1\"},{\"name\":\"serde_path_to_error\",\"req\":\"0.1\"},{\"name\":\"thiserror\",\"req\":\"2\"},{\"name\":\"unicode-general-category\",\"req\":\"1\"},{\"name\":\"url\",\"req\":\"2\"},{\"default_features\":true,\"features\":[\"v4\"],\"name\":\"uuid\",\"optional\":true,\"req\":\"1\"},{\"name\":\"widestring\",\"req\":\"1\",\"target\":\"cfg(target_os = \\\"windows\\\")\"},{\"default_features\":true,\"features\":[\"Win32_Foundation\",\"Win32_Globalization\",\"Win32_NetworkManagement_WindowsFirewall\",\"Win32_Networking_WinSock\",\"Win32_Security\",\"Win32_Security_Authorization\",\"Win32_Security_Credentials\",\"Win32_Security_Isolation\",\"Win32_Storage_FileSystem\",\"Win32_System_Com\",\"Win32_System_Console\",\"Win32_System_Diagnostics_Debug\",\"Win32_System_Diagnostics_Etw\",\"Win32_System_Diagnostics_ToolHelp\",\"Win32_System_Environment\",\"Win32_System_IO\",\"Win32_System_JobObjects\",\"Win32_System_LibraryLoader\",\"Win32_System_Memory\",\"Win32_System_Ole\",\"Win32_System_Pipes\",\"Win32_System_ProcessStatus\",\"Win32_System_Registry\",\"Win32_System_SystemInformation\",\"Win32_System_SystemServices\",\"Win32_System_Threading\",\"Win32_System_Time\",\"Win32_System_Variant\",\"Win32_System_WindowsProgramming\",\"Win32_UI_Shell\"],\"name\":\"windows\",\"optional\":false,\"req\":\"0.62\",\"target\":\"cfg(target_os = \\\"windows\\\")\"},{\"name\":\"windows-core\",\"req\":\"0.62\",\"target\":\"cfg(target_os = \\\"windows\\\")\"},{\"name\":\"winreg\",\"req\":\"0.55\",\"target\":\"cfg(target_os = \\\"windows\\\")\"},{\"name\":\"libc\",\"req\":\"0.2\",\"target\":\"cfg(unix)\"}],\"features\":{\"microvm\":[\"dep:nanvix_common\",\"dep:uuid\"],\"schema-gen\":[\"dep:mxc_schema_support\",\"dep:schemars\"]},\"strip_prefix\":\"core/wxc_common\"}", "git+https://github.com/modelcontextprotocol/rust-sdk?rev=3e636cab26c013eca5131103c03d20237f12c4df#3e636cab26c013eca5131103c03d20237f12c4df_rmcp": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"async-trait\",\"optional\":true,\"req\":\"0.1.89\"},{\"default_features\":true,\"features\":[],\"name\":\"base64\",\"optional\":true,\"req\":\"0.23\"},{\"default_features\":true,\"features\":[],\"name\":\"bytes\",\"optional\":true,\"req\":\"1\"},{\"name\":\"futures\",\"req\":\"0.3\"},{\"default_features\":true,\"features\":[],\"name\":\"hmac\",\"optional\":true,\"req\":\"0.13\"},{\"default_features\":true,\"features\":[],\"name\":\"http\",\"optional\":true,\"req\":\"1\"},{\"default_features\":true,\"features\":[],\"name\":\"http-body\",\"optional\":true,\"req\":\"1\"},{\"default_features\":true,\"features\":[],\"name\":\"http-body-util\",\"optional\":true,\"req\":\"0.1\"},{\"default_features\":true,\"features\":[\"client\",\"http1\"],\"name\":\"hyper\",\"optional\":true,\"req\":\"1\"},{\"default_features\":true,\"features\":[\"tokio\"],\"name\":\"hyper-util\",\"optional\":true,\"req\":\"0.1\"},{\"default_features\":true,\"features\":[\"serde\"],\"name\":\"indexmap\",\"optional\":false,\"req\":\"2\"},{\"default_features\":true,\"features\":[\"aws_lc_rs\"],\"name\":\"jsonwebtoken\",\"optional\":true,\"req\":\"11\"},{\"default_features\":false,\"features\":[],\"name\":\"oauth2\",\"optional\":true,\"req\":\"5.0\"},{\"default_features\":true,\"features\":[],\"name\":\"pastey\",\"optional\":true,\"req\":\"0.2.0\"},{\"name\":\"pin-project-lite\",\"req\":\"0.2\"},{\"default_features\":true,\"features\":[\"tokio1\"],\"name\":\"process-wrap\",\"optional\":true,\"req\":\"10.0\"},{\"default_features\":true,\"features\":[],\"name\":\"rand\",\"optional\":true,\"req\":\"0.10\"},{\"default_features\":false,\"features\":[\"json\",\"stream\"],\"name\":\"reqwest\",\"optional\":true,\"req\":\"0.13.2\"},{\"default_features\":true,\"features\":[],\"name\":\"rmcp-macros\",\"optional\":true,\"req\":\"3.3.0\"},{\"default_features\":true,\"features\":[\"chrono04\"],\"name\":\"schemars\",\"optional\":true,\"req\":\"1.0\"},{\"default_features\":true,\"features\":[\"derive\",\"rc\"],\"name\":\"serde\",\"optional\":false,\"req\":\"1.0\"},{\"name\":\"serde_json\",\"req\":\"1.0\"},{\"default_features\":true,\"features\":[],\"name\":\"sha2\",\"optional\":true,\"req\":\"0.11\"},{\"default_features\":true,\"features\":[],\"name\":\"sse-stream\",\"optional\":true,\"req\":\"0.2.4\"},{\"name\":\"thiserror\",\"req\":\"2\"},{\"default_features\":true,\"features\":[\"sync\",\"macros\",\"rt\",\"time\"],\"name\":\"tokio\",\"optional\":false,\"req\":\"1\"},{\"default_features\":true,\"features\":[],\"name\":\"tokio-stream\",\"optional\":true,\"req\":\"0.1\"},{\"default_features\":true,\"features\":[],\"name\":\"tokio-util\",\"optional\":false,\"req\":\"0.7\"},{\"default_features\":true,\"features\":[],\"name\":\"tower-service\",\"optional\":true,\"req\":\"0.3\"},{\"default_features\":true,\"features\":[],\"name\":\"tracing\",\"optional\":false,\"req\":\"0.1\"},{\"default_features\":true,\"features\":[],\"name\":\"url\",\"optional\":true,\"req\":\"2.4\"},{\"default_features\":true,\"features\":[\"v4\"],\"name\":\"uuid\",\"optional\":true,\"req\":\"1\"},{\"default_features\":true,\"features\":[],\"name\":\"which\",\"optional\":true,\"req\":\"8\"},{\"default_features\":true,\"features\":[],\"name\":\"zeroize\",\"optional\":true,\"req\":\"1\"},{\"default_features\":false,\"features\":[\"serde\",\"clock\",\"std\",\"oldtime\"],\"name\":\"chrono\",\"optional\":false,\"req\":\"0.4.38\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"features\":[\"serde\",\"now\"],\"name\":\"chrono\",\"optional\":false,\"req\":\"0.4.38\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"}],\"features\":{\"__reqwest\":[\"dep:reqwest\"],\"auth\":[\"dep:async-trait\",\"dep:oauth2\",\"__reqwest\",\"dep:url\"],\"auth-client-credentials-jwt\":[\"auth\",\"dep:jsonwebtoken\",\"uuid\"],\"auth-enterprise-managed\":[\"auth\",\"base64\"],\"client\":[\"dep:tokio-stream\"],\"client-side-sse\":[\"dep:sse-stream\",\"dep:http\",\"dep:bytes\",\"base64\"],\"default\":[\"base64\",\"macros\",\"server\"],\"elicitation\":[\"dep:url\"],\"local\":[\"rmcp-macros?/local\"],\"macros\":[\"dep:rmcp-macros\",\"dep:pastey\"],\"request-state\":[\"dep:hmac\",\"dep:sha2\",\"dep:zeroize\",\"base64\"],\"reqwest\":[\"__reqwest\",\"reqwest?/rustls\"],\"reqwest-native-tls\":[\"__reqwest\",\"reqwest?/native-tls\"],\"reqwest-tls-no-provider\":[\"__reqwest\",\"reqwest?/rustls-no-provider\"],\"schemars\":[\"dep:schemars\"],\"server\":[\"transport-async-rw\",\"schemars\",\"dep:pastey\",\"uuid\"],\"server-side-http\":[\"uuid\",\"dep:rand\",\"dep:tokio-stream\",\"dep:http\",\"dep:http-body\",\"dep:http-body-util\",\"dep:bytes\",\"dep:sse-stream\",\"tower\",\"base64\"],\"tower\":[\"dep:tower-service\"],\"transport-async-rw\":[\"tokio/io-util\",\"tokio-util/codec\"],\"transport-child-process\":[\"transport-async-rw\",\"tokio/process\",\"dep:process-wrap\"],\"transport-io\":[\"transport-async-rw\",\"tokio/io-std\"],\"transport-streamable-http-client\":[\"client-side-sse\",\"transport-worker\"],\"transport-streamable-http-client-reqwest\":[\"transport-streamable-http-client\",\"__reqwest\"],\"transport-streamable-http-client-unix-socket\":[\"transport-streamable-http-client\",\"dep:hyper\",\"dep:hyper-util\",\"dep:http-body-util\",\"dep:http\",\"dep:bytes\",\"tokio/net\"],\"transport-streamable-http-server\":[\"transport-streamable-http-server-session\",\"server-side-http\",\"transport-worker\"],\"transport-streamable-http-server-session\":[\"transport-async-rw\",\"dep:async-trait\",\"dep:tokio-stream\"],\"transport-worker\":[\"dep:tokio-stream\"],\"which-command\":[\"transport-child-process\",\"dep:which\"]},\"strip_prefix\":\"./crates/rmcp\"}", "git+https://github.com/modelcontextprotocol/rust-sdk?rev=3e636cab26c013eca5131103c03d20237f12c4df#3e636cab26c013eca5131103c03d20237f12c4df_rmcp-macros": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"darling\",\"optional\":false,\"req\":\"0.24\"},{\"name\":\"proc-macro2\",\"req\":\"1\"},{\"name\":\"quote\",\"req\":\"1\"},{\"name\":\"serde_json\",\"req\":\"1.0\"},{\"default_features\":true,\"features\":[\"full\"],\"name\":\"syn\",\"optional\":false,\"req\":\"3\"}],\"features\":{\"local\":[]},\"strip_prefix\":\"./crates/rmcp-macros\"}", - "git+https://github.com/openai-oss-forks/crossterm?rev=efa177859fd9623d57b9fe7ae9bf491ae1ac6ec4#efa177859fd9623d57b9fe7ae9bf491ae1ac6ec4_crossterm": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"base64\",\"optional\":true,\"req\":\"0.22\"},{\"default_features\":true,\"features\":[],\"name\":\"bitflags\",\"optional\":false,\"req\":\"2.9\"},{\"default_features\":true,\"features\":[\"is_variant\"],\"name\":\"derive_more\",\"optional\":true,\"req\":\"2.0.0\"},{\"name\":\"document-features\",\"req\":\"0.2.11\"},{\"default_features\":false,\"features\":[],\"name\":\"futures-core\",\"optional\":true,\"req\":\"0.3\"},{\"name\":\"parking_lot\",\"req\":\"0.12\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"1.0\"},{\"default_features\":true,\"features\":[],\"name\":\"filedescriptor\",\"optional\":true,\"req\":\"0.8\",\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[],\"name\":\"libc\",\"optional\":true,\"req\":\"0.2\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"os-poll\"],\"name\":\"mio\",\"optional\":true,\"req\":\"1.0\",\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[\"std\",\"stdio\",\"termios\"],\"name\":\"rustix\",\"optional\":false,\"req\":\"1\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"signal-hook\",\"optional\":true,\"req\":\"0.3.17\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"support-v1_0\"],\"name\":\"signal-hook-mio\",\"optional\":true,\"req\":\"0.2.4\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm_winapi\",\"optional\":true,\"req\":\"0.9.1\",\"target\":\"cfg(windows)\"},{\"default_features\":true,\"features\":[\"winuser\",\"winerror\"],\"name\":\"winapi\",\"optional\":true,\"req\":\"0.3.9\",\"target\":\"cfg(windows)\"}],\"features\":{\"bracketed-paste\":[],\"default\":[\"bracketed-paste\",\"events\",\"windows\",\"derive-more\"],\"derive-more\":[\"dep:derive_more\"],\"event-stream\":[\"dep:futures-core\",\"events\"],\"events\":[\"dep:mio\",\"dep:signal-hook\",\"dep:signal-hook-mio\"],\"osc52\":[\"dep:base64\"],\"serde\":[\"dep:serde\",\"bitflags/serde\"],\"use-dev-tty\":[\"filedescriptor\",\"rustix/process\"],\"windows\":[\"dep:winapi\",\"dep:crossterm_winapi\"]},\"strip_prefix\":\"\"}", + "git+https://github.com/openai-oss-forks/crossterm?rev=ed1cdab335221515706178d68495bba2aed1924f#ed1cdab335221515706178d68495bba2aed1924f_crossterm": "{\"dependencies\":[{\"default_features\":true,\"features\":[],\"name\":\"base64\",\"optional\":true,\"req\":\"0.23\"},{\"default_features\":true,\"features\":[],\"name\":\"bitflags\",\"optional\":false,\"req\":\"2.9\"},{\"default_features\":true,\"features\":[\"is_variant\"],\"name\":\"derive_more\",\"optional\":true,\"req\":\"2.0.0\"},{\"default_features\":true,\"features\":[],\"name\":\"document-features\",\"optional\":true,\"req\":\"0.2.11\"},{\"default_features\":false,\"features\":[],\"name\":\"futures-core\",\"optional\":true,\"req\":\"0.3.31\"},{\"name\":\"parking_lot\",\"req\":\"0.12.1\"},{\"default_features\":true,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"1.0.103\"},{\"default_features\":true,\"features\":[],\"name\":\"filedescriptor\",\"optional\":true,\"req\":\"0.8\",\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[],\"name\":\"libc\",\"optional\":true,\"req\":\"0.2.168\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"os-poll\"],\"name\":\"mio\",\"optional\":true,\"req\":\"1.0.1\",\"target\":\"cfg(unix)\"},{\"default_features\":false,\"features\":[\"std\",\"stdio\",\"termios\"],\"name\":\"rustix\",\"optional\":false,\"req\":\"1\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"signal-hook\",\"optional\":true,\"req\":\"0.3.17\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[\"support-v1_0\"],\"name\":\"signal-hook-mio\",\"optional\":true,\"req\":\"0.2.4\",\"target\":\"cfg(unix)\"},{\"default_features\":true,\"features\":[],\"name\":\"crossterm_winapi\",\"optional\":true,\"req\":\"0.9.1\",\"target\":\"cfg(windows)\"},{\"default_features\":true,\"features\":[\"winuser\",\"winerror\"],\"name\":\"winapi\",\"optional\":true,\"req\":\"0.3.9\",\"target\":\"cfg(windows)\"}],\"features\":{\"bracketed-paste\":[],\"default\":[\"bracketed-paste\",\"derive-more\",\"events\",\"windows\"],\"derive-more\":[\"dep:derive_more\"],\"document-features\":[\"dep:document-features\"],\"event-stream\":[\"dep:futures-core\",\"events\"],\"events\":[\"dep:mio\",\"dep:signal-hook\",\"dep:signal-hook-mio\"],\"osc52\":[\"dep:base64\"],\"serde\":[\"dep:serde\",\"bitflags/serde\"],\"use-dev-tty\":[\"filedescriptor\",\"rustix/process\"],\"windows\":[\"dep:winapi\",\"dep:crossterm_winapi\"]},\"strip_prefix\":\"\"}", "git+https://github.com/openai-oss-forks/tokio-tungstenite?rev=0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186#0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186_tokio-tungstenite": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"optional\":false},{\"name\":\"log\"},{\"default_features\":true,\"features\":[],\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\"},{\"default_features\":false,\"features\":[],\"name\":\"rustls\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-native-certs\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-pki-types\",\"optional\":true},{\"default_features\":false,\"features\":[\"io-util\"],\"name\":\"tokio\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"tokio-native-tls\",\"optional\":true},{\"default_features\":false,\"features\":[],\"name\":\"tokio-rustls\",\"optional\":true},{\"default_features\":false,\"features\":[],\"name\":\"tungstenite\",\"optional\":false},{\"default_features\":true,\"features\":[],\"name\":\"webpki-roots\",\"optional\":true}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\",\"tokio-rustls\",\"stream\",\"tungstenite/__rustls-tls\",\"handshake\"],\"connect\":[\"stream\",\"tokio/net\",\"tokio/time\",\"handshake\"],\"default\":[\"connect\",\"handshake\"],\"handshake\":[\"tungstenite/handshake\"],\"native-tls\":[\"native-tls-crate\",\"tokio-native-tls\",\"stream\",\"tungstenite/native-tls\",\"handshake\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\",\"tungstenite/native-tls-vendored\"],\"proxy\":[\"tungstenite/proxy\",\"tokio/net\",\"handshake\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"stream\":[],\"url\":[\"tungstenite/url\"]},\"strip_prefix\":\"\"}", "git+https://github.com/openai-oss-forks/tungstenite-rs?rev=4fffad30fe373adbdcffab9545e9e9bf4f2fc19f#4fffad30fe373adbdcffab9545e9e9bf4f2fc19f_tungstenite": "{\"dependencies\":[{\"name\":\"bytes\"},{\"default_features\":true,\"features\":[],\"name\":\"data-encoding\",\"optional\":true},{\"default_features\":false,\"features\":[\"zlib-rs\"],\"name\":\"flate2\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"headers\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"http\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"httparse\",\"optional\":true},{\"name\":\"log\"},{\"default_features\":true,\"features\":[],\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\"},{\"name\":\"rand\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-native-certs\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"rustls-pki-types\",\"optional\":true},{\"default_features\":true,\"features\":[],\"name\":\"sha1\",\"optional\":true},{\"name\":\"thiserror\"},{\"default_features\":true,\"features\":[],\"name\":\"url\",\"optional\":true},{\"name\":\"utf-8\"},{\"default_features\":true,\"features\":[],\"name\":\"webpki-roots\",\"optional\":true}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\"],\"default\":[\"handshake\"],\"deflate\":[\"headers\",\"flate2\"],\"handshake\":[\"data-encoding\",\"headers\",\"httparse\",\"sha1\"],\"headers\":[\"http\",\"dep:headers\"],\"native-tls\":[\"native-tls-crate\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\"],\"proxy\":[\"handshake\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"url\":[\"dep:url\"]},\"strip_prefix\":\"\"}", "git+https://github.com/rust-lang/rust-clippy?rev=21baba9c10c5d179915cae82e6247bc2337872fb#21baba9c10c5d179915cae82e6247bc2337872fb_clippy_utils": "{\"dependencies\":[{\"default_features\":false,\"features\":[],\"name\":\"arrayvec\",\"optional\":false,\"req\":\"0.7\"},{\"name\":\"itertools\",\"req\":\"0.15\"},{\"name\":\"rustc_apfloat\",\"req\":\"0.2.0\"}],\"features\":{},\"strip_prefix\":\"clippy_utils\"}", diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index e7c700939b..295d1f826b 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -254,7 +254,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -265,7 +265,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -5827,12 +5827,11 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" version = "0.29.0" -source = "git+https://github.com/openai-oss-forks/crossterm?rev=efa177859fd9623d57b9fe7ae9bf491ae1ac6ec4#efa177859fd9623d57b9fe7ae9bf491ae1ac6ec4" +source = "git+https://github.com/openai-oss-forks/crossterm?rev=ed1cdab335221515706178d68495bba2aed1924f#ed1cdab335221515706178d68495bba2aed1924f" dependencies = [ "bitflags 2.13.1", "crossterm_winapi", "derive_more 2.1.1", - "document-features", "futures-core", "mio", "parking_lot", @@ -6497,7 +6496,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6854,7 +6853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7504,7 +7503,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -9617,7 +9616,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -9683,7 +9682,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -10592,7 +10591,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -11309,7 +11308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -12242,7 +12241,7 @@ dependencies = [ "libc", "log", "socket2 0.6.3", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -13545,7 +13544,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -13604,7 +13603,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -14428,7 +14427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -15258,7 +15257,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -15314,7 +15313,7 @@ dependencies = [ "parking_lot", "rustix 1.1.4", "signal-hook", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -17065,7 +17064,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 2dd0e130f1..ce7ed1f34d 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -643,7 +643,7 @@ opt-level = 0 [patch.crates-io] # Uncomment to debug local changes. # ratatui = { path = "../../ratatui" } -crossterm = { git = "https://github.com/openai-oss-forks/crossterm", rev = "efa177859fd9623d57b9fe7ae9bf491ae1ac6ec4" } +crossterm = { git = "https://github.com/openai-oss-forks/crossterm", rev = "ed1cdab335221515706178d68495bba2aed1924f" } tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "0e5b2d73aa18dd9f0a50ee9ff199d5aef7594186" } tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "4fffad30fe373adbdcffab9545e9e9bf4f2fc19f" } diff --git a/codex-rs/tui/src/tui.rs b/codex-rs/tui/src/tui.rs index 69abbb388e..9f49da4adb 100644 --- a/codex-rs/tui/src/tui.rs +++ b/codex-rs/tui/src/tui.rs @@ -90,6 +90,8 @@ pub(crate) mod test_support; mod tmux; #[cfg(any(windows, test))] mod windows_console; +#[cfg(any(windows, test))] +mod windows_key_sequence; /// Target frame interval for UI redraw scheduling. pub(crate) const TARGET_FRAME_INTERVAL: Duration = frame_rate_limiter::MIN_FRAME_INTERVAL; diff --git a/codex-rs/tui/src/tui/event_stream.rs b/codex-rs/tui/src/tui/event_stream.rs index 35afa4bfbb..3ed439eec6 100644 --- a/codex-rs/tui/src/tui/event_stream.rs +++ b/codex-rs/tui/src/tui/event_stream.rs @@ -125,11 +125,22 @@ impl EventBroker { } /// Real crossterm-backed event source. -pub struct CrosstermEventSource(pub crossterm::event::EventStream); +pub struct CrosstermEventSource { + #[cfg(not(windows))] + events: crossterm::event::EventStream, + #[cfg(windows)] + events: super::windows_key_sequence::WindowsKeySequence, +} impl Default for CrosstermEventSource { fn default() -> Self { - Self(crossterm::event::EventStream::new()) + let events = crossterm::event::EventStream::new(); + Self { + #[cfg(not(windows))] + events, + #[cfg(windows)] + events: super::windows_key_sequence::WindowsKeySequence::new(events), + } } } @@ -140,7 +151,7 @@ impl EventSource for CrosstermEventSource { #[cfg(windows)] let _ = super::windows_console::ensure_input_record_mode(); - let result = Pin::new(&mut self.get_mut().0).poll_next(cx); + let result = Pin::new(&mut self.get_mut().events).poll_next(cx); // EventStream starts its blocking reader before returning Pending, so reassert the mode // after that transition as well. diff --git a/codex-rs/tui/src/tui/snapshots/codex_tui__tui__windows_key_sequence__tests__windows_mapped_shift_enter.snap b/codex-rs/tui/src/tui/snapshots/codex_tui__tui__windows_key_sequence__tests__windows_mapped_shift_enter.snap new file mode 100644 index 0000000000..6f074244f4 --- /dev/null +++ b/codex-rs/tui/src/tui/snapshots/codex_tui__tui__windows_key_sequence__tests__windows_mapped_shift_enter.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/tui/windows_key_sequence_tests.rs +assertion_line: 188 +expression: terminal.backend() +--- +" " +"› first line " +" " +" second line [13;2u " +" " +" " +" " +" " +" 100% context left " diff --git a/codex-rs/tui/src/tui/windows_key_sequence.rs b/codex-rs/tui/src/tui/windows_key_sequence.rs new file mode 100644 index 0000000000..50981ea337 --- /dev/null +++ b/codex-rs/tui/src/tui/windows_key_sequence.rs @@ -0,0 +1,157 @@ +//! Decode Windows Terminal's explicit CSI-u Shift+Enter mapping from console key events. +//! +//! Crossterm's Win32 backend delivers `sendInput` as individual keys. Only the complete +//! ESC-prefixed sequence is recognized; plain text and paste events are never scanned. +//! A fixed deadline bounds waiting for input; already-ready keys may complete a candidate. +//! Failed prefixes are replayed unchanged. +//! State belongs to the event source so dropping it on terminal handoff drops partial input. + +use std::collections::VecDeque; +use std::future::Future; +use std::pin::Pin; +use std::task::Context; +use std::task::Poll; +use std::time::Duration; + +use crossterm::event::Event; +use crossterm::event::KeyCode; +use crossterm::event::KeyEvent; +use crossterm::event::KeyEventKind; +use crossterm::event::KeyModifiers; +use tokio::time::Sleep; +use tokio_stream::Stream; + +use super::event_stream::EventResult; + +const SEQUENCE: [KeyCode; 7] = [ + KeyCode::Esc, + KeyCode::Char('['), + KeyCode::Char('1'), + KeyCode::Char('3'), + KeyCode::Char(';'), + KeyCode::Char('2'), + KeyCode::Char('u'), +]; +const SEQUENCE_TIMEOUT: Duration = Duration::from_millis(/*millis*/ 50); + +pub(super) struct WindowsKeySequence { + inner: S, + // At most one press and one release per sequence character. + pending: Vec, + next: usize, + deadline: Option>>, + ready: VecDeque, + final_release: Option, +} + +impl WindowsKeySequence { + pub(super) fn new(inner: S) -> Self { + Self { + inner, + pending: Vec::new(), + next: 0, + deadline: None, + ready: VecDeque::new(), + final_release: None, + } + } + + fn flush(&mut self) { + self.ready + .extend(self.pending.drain(..).map(|key| Ok(Event::Key(key)))); + self.next = 0; + self.deadline = None; + } + + fn accept(&mut self, event: Event) { + if let Some(release) = self.final_release.take() + && event == Event::Key(release) + { + return; + } + if let Event::Key(key) = event { + if let Some(previous) = self.pending.last() + && previous.kind == KeyEventKind::Press + && key + == (KeyEvent { + kind: KeyEventKind::Release, + ..*previous + }) + { + self.pending.push(key); + return; + } + if key.code == SEQUENCE[self.next] + && key.modifiers.is_empty() + && key.kind == KeyEventKind::Press + { + if self.pending.is_empty() { + self.deadline = Some(Box::pin(tokio::time::sleep(SEQUENCE_TIMEOUT))); + } + self.pending.push(key); + self.next += 1; + if self.next == SEQUENCE.len() { + self.pending.clear(); + self.next = 0; + self.deadline = None; + self.final_release = Some(KeyEvent { + kind: KeyEventKind::Release, + ..key + }); + self.ready.push_back(Ok(Event::Key(KeyEvent::new( + KeyCode::Enter, + KeyModifiers::SHIFT, + )))); + } + return; + } + } + self.flush(); + // A mismatching Escape may start the next sequence after replaying the failed one. + if matches!(event, Event::Key(key) if key == KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)) + { + self.accept(event); + } else { + self.ready.push_back(Ok(event)); + } + } +} + +impl + Unpin> Stream for WindowsKeySequence { + type Item = EventResult; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.get_mut(); + loop { + if let Some(event) = this.ready.pop_front() { + return Poll::Ready(Some(event)); + } + // Each ready key advances the finite candidate or produces output, so this + // cannot drain indefinitely. Prefer queued input over an elapsed deadline. + match Pin::new(&mut this.inner).poll_next(cx) { + Poll::Ready(Some(Ok(event))) => this.accept(event), + Poll::Ready(Some(Err(error))) => { + this.flush(); + this.ready.push_back(Err(error)); + } + Poll::Ready(None) => { + this.flush(); + return Poll::Ready(this.ready.pop_front()); + } + Poll::Pending => { + if let Some(deadline) = &mut this.deadline + && deadline.as_mut().poll(cx).is_ready() + { + this.flush(); + continue; + } + return Poll::Pending; + } + } + } + } +} + +#[cfg(test)] +#[path = "windows_key_sequence_tests.rs"] +mod tests; diff --git a/codex-rs/tui/src/tui/windows_key_sequence_tests.rs b/codex-rs/tui/src/tui/windows_key_sequence_tests.rs new file mode 100644 index 0000000000..b6c77597b2 --- /dev/null +++ b/codex-rs/tui/src/tui/windows_key_sequence_tests.rs @@ -0,0 +1,230 @@ +use super::*; +use futures::FutureExt; +use pretty_assertions::assert_eq; +use tokio_stream::StreamExt; +use tokio_stream::wrappers::UnboundedReceiverStream; + +fn keys(text: &str) -> Vec { + text.chars() + .map(|ch| { + Event::Key(KeyEvent::new( + if ch == '\u{1b}' { + KeyCode::Esc + } else { + KeyCode::Char(ch) + }, + KeyModifiers::NONE, + )) + }) + .collect() +} + +async fn decoded(events: Vec) -> Vec { + WindowsKeySequence::new(tokio_stream::iter(events.into_iter().map(Ok))) + .map(Result::unwrap) + .collect() + .await +} + +#[tokio::test] +async fn repeated_mappings_decode_with_or_without_key_releases() { + let expected = Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)); + let presses = keys("\u{1b}[13;2u\u{1b}[13;2u"); + assert_eq!(decoded(presses.clone()).await, vec![expected.clone(); 2]); + let records = presses + .into_iter() + .flat_map(|event| { + let Event::Key(key) = event else { + unreachable!() + }; + [ + Event::Key(key), + Event::Key(KeyEvent { + kind: KeyEventKind::Release, + ..key + }), + ] + }) + .collect(); + assert_eq!(decoded(records).await, vec![expected; 2]); +} + +#[tokio::test(start_paused = true)] +async fn fragmented_mapping_waits_without_leaking_escape() { + let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); + let mut stream = WindowsKeySequence::new(UnboundedReceiverStream::new(rx)); + let events = keys("\u{1b}[13;2u"); + for event in &events[..6] { + tx.send(Ok(event.clone())).unwrap(); + assert!(stream.next().now_or_never().is_none()); + tokio::time::advance(Duration::from_millis(/*millis*/ 5)).await; + } + tx.send(Ok(events[6].clone())).unwrap(); + assert_eq!( + stream.next().await.unwrap().unwrap(), + Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)) + ); +} + +#[tokio::test(start_paused = true)] +async fn delayed_poll_consumes_queued_suffix_without_waiting_for_more_input() { + for suffix in ["[13;2u", "[13;"] { + let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); + let mut stream = WindowsKeySequence::new(UnboundedReceiverStream::new(rx)); + tx.send(Ok(keys("\u{1b}")[0].clone())).unwrap(); + assert!(stream.next().now_or_never().is_none()); + for event in keys(suffix) { + tx.send(Ok(event)).unwrap(); + } + tokio::time::advance(SEQUENCE_TIMEOUT).await; + let expected = if suffix.ends_with('u') { + vec![Event::Key(KeyEvent::new( + KeyCode::Enter, + KeyModifiers::SHIFT, + ))] + } else { + keys("\u{1b}[13;") + }; + for event in expected { + assert_eq!( + stream.next().now_or_never().unwrap().unwrap().unwrap(), + event + ); + } + assert!(stream.next().now_or_never().is_none()); + } +} + +#[tokio::test] +async fn continuously_ready_mappings_yield_one_newline_at_a_time() { + let events = keys("\u{1b}[13;2u").into_iter().cycle(); + let mut stream = WindowsKeySequence::new(tokio_stream::iter(events.map(Ok))); + for _ in 0..2 { + assert_eq!( + stream.next().now_or_never().unwrap().unwrap().unwrap(), + Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)) + ); + } +} + +#[tokio::test(start_paused = true)] +async fn standalone_escape_and_partial_prefix_wake_at_fixed_deadline() { + for text in ["\u{1b}", "\u{1b}[13;"] { + let events = keys(text); + let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); + let mut stream = WindowsKeySequence::new(UnboundedReceiverStream::new(rx)); + tx.send(Ok(events[0].clone())).unwrap(); + assert!(stream.next().now_or_never().is_none()); + tokio::time::advance(Duration::from_millis(/*millis*/ 40)).await; + for event in &events[1..] { + tx.send(Ok(event.clone())).unwrap(); + } + assert!(stream.next().now_or_never().is_none()); + // next() must be woken by the original deadline, without another input event. + let start = tokio::time::Instant::now(); + assert_eq!(stream.next().await.unwrap().unwrap(), events[0]); + assert_eq!(start.elapsed(), Duration::from_millis(/*millis*/ 10)); + for event in &events[1..] { + assert_eq!(stream.next().await.unwrap().unwrap(), *event); + } + drop(tx); + assert!(stream.next().await.is_none()); + } +} + +#[tokio::test] +async fn literal_text_paste_native_keys_and_failed_prefixes_are_unchanged() { + let mut events = keys("literal [13;2u\u{1b}[13;3u\u{1b}[x"); + events.extend([ + Event::Paste("literal \u{1b}[13;2u".to_string()), + Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)), + Event::Key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT)), + Event::Key(KeyEvent::new(KeyCode::Char('j'), KeyModifiers::CONTROL)), + Event::Key(KeyEvent::new_with_kind( + KeyCode::Char('x'), + KeyModifiers::NONE, + KeyEventKind::Repeat, + )), + Event::Key(KeyEvent::new_with_kind( + KeyCode::Esc, + KeyModifiers::NONE, + KeyEventKind::Release, + )), + ]); + assert_eq!(decoded(events.clone()).await, events); + for interrupt in [ + Event::Resize(80, 24), + Event::FocusLost, + Event::Paste("[13;2u".to_string()), + ] { + let mut events = keys("\u{1b}["); + events.push(interrupt); + events.extend(keys("13;2u")); + assert_eq!(decoded(events.clone()).await, events); + } +} + +#[tokio::test] +async fn mismatch_can_start_another_mapping_and_eof_replays_partial_input() { + let mut expected = keys("\u{1b}[1"); + expected.push(Event::Key(KeyEvent::new( + KeyCode::Enter, + KeyModifiers::SHIFT, + ))); + expected.extend(keys("\u{1b}[")); + assert_eq!(decoded(keys("\u{1b}[1\u{1b}[13;2u\u{1b}[")).await, expected); +} + +#[tokio::test] +async fn errors_follow_pending_input_and_do_not_keep_partial_state() { + let mut events: Vec<_> = keys("\u{1b}[").into_iter().map(Ok).collect(); + events.push(Err(std::io::Error::other("input failed"))); + events.extend(keys("13;2u").into_iter().map(Ok)); + let mut stream = WindowsKeySequence::new(tokio_stream::iter(events)); + for event in keys("\u{1b}[") { + assert_eq!(stream.next().await.unwrap().unwrap(), event); + } + assert_eq!( + stream.next().await.unwrap().unwrap_err().to_string(), + "input failed" + ); + assert_eq!( + stream.map(Result::unwrap).collect::>().await, + keys("13;2u") + ); +} + +#[tokio::test] +async fn mapped_shift_enter_renders_newlines_in_the_composer() { + use crate::app_event::AppEvent; + use crate::app_event_sender::AppEventSender; + use crate::bottom_pane::ChatComposer; + use crate::bottom_pane::InputResult; + use crate::render::renderable::Renderable; + use ratatui::Terminal; + use ratatui::backend::TestBackend; + + let (tx, _rx) = tokio::sync::mpsc::unbounded_channel::(); + let mut composer = ChatComposer::new( + /*has_input_focus*/ true, + AppEventSender::new(tx), + /*enhanced_keys_supported*/ false, + "Ask Codex to do anything".to_string(), + /*disable_paste_burst*/ true, + ); + for event in decoded(keys("first line\u{1b}[13;2u\u{1b}[13;2usecond line [13;2u")).await { + let Event::Key(key) = event else { + unreachable!() + }; + assert!(matches!( + composer.handle_key_event(key).0, + InputResult::None + )); + } + assert_eq!(composer.current_text(), "first line\n\nsecond line [13;2u"); + let mut terminal = Terminal::new(TestBackend::new(/*width*/ 60, /*height*/ 9)).unwrap(); + terminal + .draw(|frame| composer.render(frame.area(), frame.buffer_mut())) + .unwrap(); + insta::assert_snapshot!("windows_mapped_shift_enter", terminal.backend()); +}