From 4c673086bc5b4b04ac859d3ec06632cb0ce70724 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Tue, 13 Jan 2026 15:39:34 -0800 Subject: [PATCH 1/2] fix: integration test for #9011 (#9166) Adds an integration test for the new behavior introduced in https://github.com/openai/codex/pull/9011. The work to create the test setup was substantial enough that I thought it merited a separate PR. This integration test spawns `codex` in TUI mode, which requires spawning a PTY to run successfully, so I had to introduce quite a bit of scaffolding in `run_codex_cli()`. I was surprised to discover that we have not done this in our codebase before, so perhaps this should get moved to a common location so it can be reused. The test itself verifies that a malformed `rules` in `$CODEX_HOME` prints a human-readable error message and exits nonzero. --- codex-rs/Cargo.lock | 6 + codex-rs/Cargo.toml | 1 + codex-rs/tui/BUILD.bazel | 3 + codex-rs/tui/Cargo.toml | 3 + codex-rs/tui/tests/all.rs | 3 + codex-rs/tui/tests/suite/mod.rs | 1 + .../tui/tests/suite/no_panic_on_startup.rs | 119 ++++++++++++++++++ codex-rs/tui2/BUILD.bazel | 3 + codex-rs/tui2/Cargo.toml | 3 + codex-rs/tui2/tests/all.rs | 3 + codex-rs/tui2/tests/suite/mod.rs | 1 + .../tui2/tests/suite/no_panic_on_startup.rs | 119 ++++++++++++++++++ 12 files changed, 265 insertions(+) create mode 100644 codex-rs/tui/tests/suite/no_panic_on_startup.rs create mode 100644 codex-rs/tui2/tests/suite/no_panic_on_startup.rs diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 4bec499894..aeb32f967a 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -1746,6 +1746,7 @@ dependencies = [ "codex-app-server-protocol", "codex-arg0", "codex-backend-client", + "codex-cli", "codex-common", "codex-core", "codex-feedback", @@ -1753,6 +1754,8 @@ dependencies = [ "codex-login", "codex-protocol", "codex-utils-absolute-path", + "codex-utils-cargo-bin", + "codex-utils-pty", "codex-windows-sandbox", "color-eyre", "crossterm", @@ -1818,6 +1821,7 @@ dependencies = [ "codex-app-server-protocol", "codex-arg0", "codex-backend-client", + "codex-cli", "codex-common", "codex-core", "codex-feedback", @@ -1826,6 +1830,8 @@ dependencies = [ "codex-protocol", "codex-tui", "codex-utils-absolute-path", + "codex-utils-cargo-bin", + "codex-utils-pty", "codex-windows-sandbox", "color-eyre", "crossterm", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 8699385bbf..33a664e06d 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -71,6 +71,7 @@ codex-arg0 = { path = "arg0" } codex-async-utils = { path = "async-utils" } codex-backend-client = { path = "backend-client" } codex-chatgpt = { path = "chatgpt" } +codex-cli = { path = "cli"} codex-client = { path = "codex-client" } codex-common = { path = "common" } codex-core = { path = "core" } diff --git a/codex-rs/tui/BUILD.bazel b/codex-rs/tui/BUILD.bazel index afd7a6bc0a..1400b7cf4e 100644 --- a/codex-rs/tui/BUILD.bazel +++ b/codex-rs/tui/BUILD.bazel @@ -14,4 +14,7 @@ codex_rust_crate( ), test_data_extra = glob(["src/**/snapshots/**"]), integration_compile_data_extra = ["src/test_backend.rs"], + extra_binaries = [ + "//codex-rs/cli:codex", + ], ) diff --git a/codex-rs/tui/Cargo.toml b/codex-rs/tui/Cargo.toml index 3248c7377c..9b7782edf2 100644 --- a/codex-rs/tui/Cargo.toml +++ b/codex-rs/tui/Cargo.toml @@ -113,7 +113,10 @@ arboard = { workspace = true } [dev-dependencies] +codex-cli = { workspace = true } codex-core = { workspace = true, features = ["test-support"] } +codex-utils-cargo-bin = { workspace = true } +codex-utils-pty = { workspace = true } assert_matches = { workspace = true } chrono = { workspace = true, features = ["serde"] } insta = { workspace = true } diff --git a/codex-rs/tui/tests/all.rs b/codex-rs/tui/tests/all.rs index beb7960879..91de618f68 100644 --- a/codex-rs/tui/tests/all.rs +++ b/codex-rs/tui/tests/all.rs @@ -3,4 +3,7 @@ #[cfg(feature = "vt100-tests")] mod test_backend; +#[allow(unused_imports)] +use codex_cli as _; // Keep dev-dep for cargo-shear; tests spawn the codex binary. + mod suite; diff --git a/codex-rs/tui/tests/suite/mod.rs b/codex-rs/tui/tests/suite/mod.rs index 944e338769..9a8b9a1c4e 100644 --- a/codex-rs/tui/tests/suite/mod.rs +++ b/codex-rs/tui/tests/suite/mod.rs @@ -1,4 +1,5 @@ // Aggregates all former standalone integration tests as modules. +mod no_panic_on_startup; mod status_indicator; mod vt100_history; mod vt100_live_commit; diff --git a/codex-rs/tui/tests/suite/no_panic_on_startup.rs b/codex-rs/tui/tests/suite/no_panic_on_startup.rs new file mode 100644 index 0000000000..e9cd55ef38 --- /dev/null +++ b/codex-rs/tui/tests/suite/no_panic_on_startup.rs @@ -0,0 +1,119 @@ +use std::collections::HashMap; +use std::path::Path; +use std::time::Duration; +use tokio::select; +use tokio::time::timeout; + +/// Regression test for https://github.com/openai/codex/issues/8803. +#[tokio::test] +async fn malformed_rules_should_not_panic() -> anyhow::Result<()> { + // run_codex_cli() does not work on Windows due to PTY limitations. + if cfg!(windows) { + return Ok(()); + } + + let tmp = tempfile::tempdir()?; + let codex_home = tmp.path(); + std::fs::write( + codex_home.join("rules"), + "rules should be a directory not a file", + )?; + + // TODO(mbolin): Figure out why using a temp dir as the cwd causes this test + // to hang. + let cwd = std::env::current_dir()?; + let config_contents = format!( + r#" +# Pick a local provider so the CLI doesn't prompt for OpenAI auth in this test. +model_provider = "ollama" + +[projects] +"{cwd}" = {{ trust_level = "trusted" }} +"#, + cwd = cwd.display() + ); + std::fs::write(codex_home.join("config.toml"), config_contents)?; + + let CodexCliOutput { exit_code, output } = run_codex_cli(codex_home, cwd).await?; + assert_eq!(1, exit_code, "Codex CLI should exit nonzero."); + assert!( + output.contains("ERROR: Failed to initialize codex:"), + "expected startup error in output, got: {output}" + ); + assert!( + output.contains("failed to read execpolicy files"), + "expected execpolicy read error in output, got: {output}" + ); + Ok(()) +} + +struct CodexCliOutput { + exit_code: i32, + output: String, +} + +async fn run_codex_cli( + codex_home: impl AsRef, + cwd: impl AsRef, +) -> anyhow::Result { + let codex_cli = codex_utils_cargo_bin::cargo_bin("codex")?; + let mut env = HashMap::new(); + env.insert( + "CODEX_HOME".to_string(), + codex_home.as_ref().display().to_string(), + ); + + let args = vec!["-c".to_string(), "analytics_enabled=false".to_string()]; + let spawned = codex_utils_pty::spawn_pty_process( + codex_cli.to_string_lossy().as_ref(), + &args, + cwd.as_ref(), + &env, + &None, + ) + .await?; + let mut output = Vec::new(); + let mut output_rx = spawned.output_rx; + let mut exit_rx = spawned.exit_rx; + let writer_tx = spawned.session.writer_sender(); + let exit_code_result = timeout(Duration::from_secs(10), async { + // Read PTY output until the process exits while replying to cursor + // position queries so the TUI can initialize without a real terminal. + loop { + select! { + result = output_rx.recv() => match result { + Ok(chunk) => { + // The TUI asks for the cursor position via ESC[6n. + // Respond with a valid position to unblock startup. + if chunk.windows(4).any(|window| window == b"\x1b[6n") { + let _ = writer_tx.send(b"\x1b[1;1R".to_vec()).await; + } + output.extend_from_slice(&chunk); + } + Err(tokio::sync::broadcast::error::RecvError::Closed) => break exit_rx.await, + Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {} + }, + result = &mut exit_rx => break result, + } + } + }) + .await; + let exit_code = match exit_code_result { + Ok(Ok(code)) => code, + Ok(Err(err)) => return Err(err.into()), + Err(_) => { + spawned.session.terminate(); + anyhow::bail!("timed out waiting for codex CLI to exit"); + } + }; + // Drain any output that raced with the exit notification. + while let Ok(chunk) = output_rx.try_recv() { + output.extend_from_slice(&chunk); + } + + let output = String::from_utf8_lossy(&output); + Ok(CodexCliOutput { + exit_code, + output: output.to_string(), + }) +} diff --git a/codex-rs/tui2/BUILD.bazel b/codex-rs/tui2/BUILD.bazel index b21dcc6b12..70c977b6a3 100644 --- a/codex-rs/tui2/BUILD.bazel +++ b/codex-rs/tui2/BUILD.bazel @@ -14,4 +14,7 @@ codex_rust_crate( ), test_data_extra = glob(["src/**/snapshots/**"]), integration_compile_data_extra = ["src/test_backend.rs"], + extra_binaries = [ + "//codex-rs/cli:codex", + ], ) diff --git a/codex-rs/tui2/Cargo.toml b/codex-rs/tui2/Cargo.toml index 3108e5561e..391d216999 100644 --- a/codex-rs/tui2/Cargo.toml +++ b/codex-rs/tui2/Cargo.toml @@ -109,7 +109,10 @@ arboard = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } +codex-cli = { workspace = true } codex-core = { workspace = true, features = ["test-support"] } +codex-utils-cargo-bin = { workspace = true } +codex-utils-pty = { workspace = true } chrono = { workspace = true, features = ["serde"] } insta = { workspace = true } pretty_assertions = { workspace = true } diff --git a/codex-rs/tui2/tests/all.rs b/codex-rs/tui2/tests/all.rs index beb7960879..91de618f68 100644 --- a/codex-rs/tui2/tests/all.rs +++ b/codex-rs/tui2/tests/all.rs @@ -3,4 +3,7 @@ #[cfg(feature = "vt100-tests")] mod test_backend; +#[allow(unused_imports)] +use codex_cli as _; // Keep dev-dep for cargo-shear; tests spawn the codex binary. + mod suite; diff --git a/codex-rs/tui2/tests/suite/mod.rs b/codex-rs/tui2/tests/suite/mod.rs index 944e338769..9a8b9a1c4e 100644 --- a/codex-rs/tui2/tests/suite/mod.rs +++ b/codex-rs/tui2/tests/suite/mod.rs @@ -1,4 +1,5 @@ // Aggregates all former standalone integration tests as modules. +mod no_panic_on_startup; mod status_indicator; mod vt100_history; mod vt100_live_commit; diff --git a/codex-rs/tui2/tests/suite/no_panic_on_startup.rs b/codex-rs/tui2/tests/suite/no_panic_on_startup.rs new file mode 100644 index 0000000000..e9cd55ef38 --- /dev/null +++ b/codex-rs/tui2/tests/suite/no_panic_on_startup.rs @@ -0,0 +1,119 @@ +use std::collections::HashMap; +use std::path::Path; +use std::time::Duration; +use tokio::select; +use tokio::time::timeout; + +/// Regression test for https://github.com/openai/codex/issues/8803. +#[tokio::test] +async fn malformed_rules_should_not_panic() -> anyhow::Result<()> { + // run_codex_cli() does not work on Windows due to PTY limitations. + if cfg!(windows) { + return Ok(()); + } + + let tmp = tempfile::tempdir()?; + let codex_home = tmp.path(); + std::fs::write( + codex_home.join("rules"), + "rules should be a directory not a file", + )?; + + // TODO(mbolin): Figure out why using a temp dir as the cwd causes this test + // to hang. + let cwd = std::env::current_dir()?; + let config_contents = format!( + r#" +# Pick a local provider so the CLI doesn't prompt for OpenAI auth in this test. +model_provider = "ollama" + +[projects] +"{cwd}" = {{ trust_level = "trusted" }} +"#, + cwd = cwd.display() + ); + std::fs::write(codex_home.join("config.toml"), config_contents)?; + + let CodexCliOutput { exit_code, output } = run_codex_cli(codex_home, cwd).await?; + assert_eq!(1, exit_code, "Codex CLI should exit nonzero."); + assert!( + output.contains("ERROR: Failed to initialize codex:"), + "expected startup error in output, got: {output}" + ); + assert!( + output.contains("failed to read execpolicy files"), + "expected execpolicy read error in output, got: {output}" + ); + Ok(()) +} + +struct CodexCliOutput { + exit_code: i32, + output: String, +} + +async fn run_codex_cli( + codex_home: impl AsRef, + cwd: impl AsRef, +) -> anyhow::Result { + let codex_cli = codex_utils_cargo_bin::cargo_bin("codex")?; + let mut env = HashMap::new(); + env.insert( + "CODEX_HOME".to_string(), + codex_home.as_ref().display().to_string(), + ); + + let args = vec!["-c".to_string(), "analytics_enabled=false".to_string()]; + let spawned = codex_utils_pty::spawn_pty_process( + codex_cli.to_string_lossy().as_ref(), + &args, + cwd.as_ref(), + &env, + &None, + ) + .await?; + let mut output = Vec::new(); + let mut output_rx = spawned.output_rx; + let mut exit_rx = spawned.exit_rx; + let writer_tx = spawned.session.writer_sender(); + let exit_code_result = timeout(Duration::from_secs(10), async { + // Read PTY output until the process exits while replying to cursor + // position queries so the TUI can initialize without a real terminal. + loop { + select! { + result = output_rx.recv() => match result { + Ok(chunk) => { + // The TUI asks for the cursor position via ESC[6n. + // Respond with a valid position to unblock startup. + if chunk.windows(4).any(|window| window == b"\x1b[6n") { + let _ = writer_tx.send(b"\x1b[1;1R".to_vec()).await; + } + output.extend_from_slice(&chunk); + } + Err(tokio::sync::broadcast::error::RecvError::Closed) => break exit_rx.await, + Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {} + }, + result = &mut exit_rx => break result, + } + } + }) + .await; + let exit_code = match exit_code_result { + Ok(Ok(code)) => code, + Ok(Err(err)) => return Err(err.into()), + Err(_) => { + spawned.session.terminate(); + anyhow::bail!("timed out waiting for codex CLI to exit"); + } + }; + // Drain any output that raced with the exit notification. + while let Ok(chunk) = output_rx.try_recv() { + output.extend_from_slice(&chunk); + } + + let output = String::from_utf8_lossy(&output); + Ok(CodexCliOutput { + exit_code, + output: output.to_string(), + }) +} From 7a2f62edb8b216558c9b981982214b73c94f248b Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Tue, 13 Jan 2026 15:52:08 -0800 Subject: [PATCH 2/2] feat: add bazel-codex entry to justfile --- MODULE.bazel.lock | 3 +++ justfile | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 5a89f1a686..7a7f9ce498 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -451,6 +451,7 @@ "darling_macro_0.20.11": "{\"dependencies\":[{\"name\":\"darling_core\",\"req\":\"=0.20.11\"},{\"name\":\"quote\",\"req\":\"^1.0.18\"},{\"name\":\"syn\",\"req\":\"^2.0.15\"}],\"features\":{}}", "darling_macro_0.21.3": "{\"dependencies\":[{\"name\":\"darling_core\",\"req\":\"=0.21.3\"},{\"name\":\"quote\",\"req\":\"^1.0.18\"},{\"name\":\"syn\",\"req\":\"^2.0.15\"}],\"features\":{}}", "darling_macro_0.23.0": "{\"dependencies\":[{\"name\":\"darling_core\",\"req\":\"=0.23.0\"},{\"name\":\"quote\",\"req\":\"^1.0.18\"},{\"name\":\"syn\",\"req\":\"^2.0.15\"}],\"features\":{}}", + "data-encoding_2.10.0": "{\"dependencies\":[],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", "dbus-secret-service_4.1.0": "{\"dependencies\":[{\"name\":\"aes\",\"optional\":true,\"req\":\"^0.8\"},{\"features\":[\"std\"],\"name\":\"block-padding\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"block-padding\",\"alloc\"],\"name\":\"cbc\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"dbus\",\"req\":\"^0.9\"},{\"name\":\"fastrand\",\"optional\":true,\"req\":\"^2.3\"},{\"name\":\"hkdf\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"num\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"openssl\",\"optional\":true,\"req\":\"^0.10.55\"},{\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10\"},{\"features\":[\"derive\"],\"name\":\"zeroize\",\"req\":\"^1.8\"}],\"features\":{\"crypto-openssl\":[\"dep:fastrand\",\"dep:num\",\"dep:once_cell\",\"dep:openssl\"],\"crypto-rust\":[\"dep:aes\",\"dep:block-padding\",\"dep:cbc\",\"dep:fastrand\",\"dep:hkdf\",\"dep:num\",\"dep:once_cell\",\"dep:sha2\"],\"vendored\":[\"dbus/vendored\",\"openssl?/vendored\"]}}", "dbus_0.9.9": "{\"dependencies\":[{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"futures-executor\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"libc\",\"req\":\"^0.2.66\"},{\"name\":\"libdbus-sys\",\"req\":\"^0.2.6\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"},{\"features\":[\"Win32_Networking_WinSock\"],\"name\":\"windows-sys\",\"req\":\"^0.59.0\",\"target\":\"cfg(windows)\"}],\"features\":{\"futures\":[\"futures-util\",\"futures-channel\"],\"no-string-validation\":[],\"stdfd\":[],\"vendored\":[\"libdbus-sys/vendored\"]}}", "deadpool-runtime_0.1.4": "{\"dependencies\":[{\"features\":[\"unstable\"],\"name\":\"async-std_1\",\"optional\":true,\"package\":\"async-std\",\"req\":\"^1.0\"},{\"features\":[\"time\",\"rt\"],\"name\":\"tokio_1\",\"optional\":true,\"package\":\"tokio\",\"req\":\"^1.0\"}],\"features\":{}}", @@ -906,6 +907,7 @@ "tokio-rustls_0.26.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"argh\",\"req\":\"^0.1.1\"},{\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.1\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1.1\"},{\"features\":[\"pem\"],\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.13\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"rustls\",\"req\":\"^0.23.22\"},{\"name\":\"tokio\",\"req\":\"^1.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^0.26\"}],\"features\":{\"aws-lc-rs\":[\"aws_lc_rs\"],\"aws_lc_rs\":[\"rustls/aws_lc_rs\"],\"default\":[\"logging\",\"tls12\",\"aws_lc_rs\"],\"early-data\":[],\"fips\":[\"rustls/fips\"],\"logging\":[\"rustls/logging\"],\"ring\":[\"rustls/ring\"],\"tls12\":[\"rustls/tls12\"]}}", "tokio-stream_0.1.18": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.15.0\"},{\"features\":[\"full\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tokio-util\",\"optional\":true,\"req\":\"^0.7.0\"}],\"features\":{\"default\":[\"time\"],\"fs\":[\"tokio/fs\"],\"full\":[\"time\",\"net\",\"io-util\",\"fs\",\"sync\",\"signal\"],\"io-util\":[\"tokio/io-util\"],\"net\":[\"tokio/net\"],\"signal\":[\"tokio/signal\"],\"sync\":[\"tokio/sync\",\"tokio-util\"],\"time\":[\"tokio/time\"]}}", "tokio-test_0.4.4": "{\"dependencies\":[{\"name\":\"async-stream\",\"req\":\"^0.3.3\"},{\"name\":\"bytes\",\"req\":\"^1.0.0\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.0\"},{\"features\":[\"rt\",\"sync\",\"time\",\"test-util\"],\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.2.0\"},{\"name\":\"tokio-stream\",\"req\":\"^0.1.1\"}],\"features\":{}}", + "tokio-tungstenite_0.21.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.0\"},{\"kind\":\"dev\",\"name\":\"futures-channel\",\"req\":\"^0.3.28\"},{\"default_features\":false,\"features\":[\"sink\",\"std\"],\"name\":\"futures-util\",\"req\":\"^0.3.28\"},{\"default_features\":false,\"features\":[\"http1\",\"server\",\"tcp\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^0.14.25\"},{\"name\":\"log\",\"req\":\"^0.4.17\"},{\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\",\"req\":\"^0.2.11\"},{\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.22.0\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.7.0\"},{\"name\":\"rustls-pki-types\",\"optional\":true,\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"io-util\"],\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"features\":[\"io-std\",\"macros\",\"net\",\"rt-multi-thread\",\"time\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.27.0\"},{\"name\":\"tokio-native-tls\",\"optional\":true,\"req\":\"^0.3.1\"},{\"name\":\"tokio-rustls\",\"optional\":true,\"req\":\"^0.25.0\"},{\"default_features\":false,\"name\":\"tungstenite\",\"req\":\"^0.21.0\"},{\"kind\":\"dev\",\"name\":\"url\",\"req\":\"^2.3.1\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^0.26.0\"}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\",\"tokio-rustls\",\"stream\",\"tungstenite/__rustls-tls\",\"handshake\"],\"connect\":[\"stream\",\"tokio/net\",\"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\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"],\"stream\":[]}}", "tokio-util_0.7.18": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3.0\"},{\"name\":\"bytes\",\"req\":\"^1.5.0\"},{\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"name\":\"futures-core\",\"req\":\"^0.3.0\"},{\"name\":\"futures-io\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"futures-sink\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-test\",\"req\":\"^0.3.5\"},{\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15.0\"},{\"features\":[\"futures\",\"checkpoint\"],\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"name\":\"slab\",\"optional\":true,\"req\":\"^0.4.4\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1.44.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\"}],\"features\":{\"__docs_rs\":[\"futures-util\"],\"codec\":[],\"compat\":[\"futures-io\"],\"default\":[],\"full\":[\"codec\",\"compat\",\"io-util\",\"time\",\"net\",\"rt\",\"join-map\"],\"io\":[],\"io-util\":[\"io\",\"tokio/rt\",\"tokio/io-util\"],\"join-map\":[\"rt\",\"hashbrown\"],\"net\":[\"tokio/net\"],\"rt\":[\"tokio/rt\",\"tokio/sync\",\"futures-util\"],\"time\":[\"tokio/time\",\"slab\"]}}", "tokio_1.48.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"async-stream\",\"req\":\"^0.3\"},{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.58\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1.2.1\"},{\"features\":[\"async-await\"],\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"futures-concurrency\",\"req\":\"^7.6.3\"},{\"default_features\":false,\"name\":\"io-uring\",\"optional\":true,\"req\":\"^0.7.6\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.168\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.168\",\"target\":\"cfg(unix)\"},{\"features\":[\"futures\",\"checkpoint\"],\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"default_features\":false,\"name\":\"mio\",\"optional\":true,\"req\":\"^1.0.1\"},{\"default_features\":false,\"features\":[\"os-poll\",\"os-ext\"],\"name\":\"mio\",\"optional\":true,\"req\":\"^1.0.1\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"features\":[\"tokio\"],\"kind\":\"dev\",\"name\":\"mio-aio\",\"req\":\"^1\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"mockall\",\"req\":\"^0.13.0\"},{\"default_features\":false,\"features\":[\"aio\",\"fs\",\"socket\"],\"kind\":\"dev\",\"name\":\"nix\",\"req\":\"^0.29.0\",\"target\":\"cfg(unix)\"},{\"name\":\"parking_lot\",\"optional\":true,\"req\":\"^0.12.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"name\":\"signal-hook-registry\",\"optional\":true,\"req\":\"^1.1.1\",\"target\":\"cfg(unix)\"},{\"name\":\"slab\",\"optional\":true,\"req\":\"^0.4.9\",\"target\":\"cfg(all(tokio_unstable, target_os = \\\"linux\\\"))\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.6.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\",\"target\":\"cfg(not(target_family = \\\"wasm\\\"))\"},{\"name\":\"tokio-macros\",\"optional\":true,\"req\":\"~2.6.0\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.0\"},{\"features\":[\"rt\"],\"kind\":\"dev\",\"name\":\"tokio-util\",\"req\":\"^0.7\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.29\",\"target\":\"cfg(tokio_unstable)\"},{\"kind\":\"dev\",\"name\":\"tracing-mock\",\"req\":\"=0.1.0-beta.1\",\"target\":\"cfg(all(tokio_unstable, target_has_atomic = \\\"64\\\"))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.0\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(target_os = \\\"wasi\\\")))\"},{\"name\":\"windows-sys\",\"optional\":true,\"req\":\"^0.61\",\"target\":\"cfg(windows)\"},{\"features\":[\"Win32_Foundation\",\"Win32_Security_Authorization\"],\"kind\":\"dev\",\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[],\"fs\":[],\"full\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"process\",\"rt\",\"rt-multi-thread\",\"signal\",\"sync\",\"time\"],\"io-std\":[],\"io-uring\":[\"dep:io-uring\",\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"dep:slab\"],\"io-util\":[\"bytes\"],\"macros\":[\"tokio-macros\"],\"net\":[\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"socket2\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_Security\",\"windows-sys/Win32_Storage_FileSystem\",\"windows-sys/Win32_System_Pipes\",\"windows-sys/Win32_System_SystemServices\"],\"process\":[\"bytes\",\"libc\",\"mio/os-poll\",\"mio/os-ext\",\"mio/net\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Threading\",\"windows-sys/Win32_System_WindowsProgramming\"],\"rt\":[],\"rt-multi-thread\":[\"rt\"],\"signal\":[\"libc\",\"mio/os-poll\",\"mio/net\",\"mio/os-ext\",\"signal-hook-registry\",\"windows-sys/Win32_Foundation\",\"windows-sys/Win32_System_Console\"],\"sync\":[],\"taskdump\":[\"dep:backtrace\"],\"test-util\":[\"rt\",\"sync\",\"time\"],\"time\":[]}}", "toml_0.5.11": "{\"dependencies\":[{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde\",\"req\":\"^1.0.97\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{\"default\":[],\"preserve_order\":[\"indexmap\"]}}", @@ -940,6 +942,7 @@ "ts-rs-macros_11.1.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\",\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2.0.28\"},{\"name\":\"termcolor\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"no-serde-warnings\":[],\"serde-compat\":[\"termcolor\"]}}", "ts-rs_11.1.0": "{\"dependencies\":[{\"features\":[\"serde\"],\"name\":\"bigdecimal\",\"optional\":true,\"req\":\">=0.0.13, <0.5\"},{\"name\":\"bson\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4\"},{\"name\":\"dprint-plugin-typescript\",\"optional\":true,\"req\":\"=0.95\"},{\"name\":\"heapless\",\"optional\":true,\"req\":\">=0.7, <0.9\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"ordered-float\",\"optional\":true,\"req\":\">=3, <6\"},{\"name\":\"semver\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"name\":\"smol_str\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"thiserror\",\"req\":\"^2\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"sync\",\"rt\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.40\"},{\"name\":\"ts-rs-macros\",\"req\":\"=11.1.0\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"uuid\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"bigdecimal-impl\":[\"bigdecimal\"],\"bson-uuid-impl\":[\"bson\"],\"bytes-impl\":[\"bytes\"],\"chrono-impl\":[\"chrono\"],\"default\":[\"serde-compat\"],\"format\":[\"dprint-plugin-typescript\"],\"heapless-impl\":[\"heapless\"],\"import-esm\":[],\"indexmap-impl\":[\"indexmap\"],\"no-serde-warnings\":[\"ts-rs-macros/no-serde-warnings\"],\"ordered-float-impl\":[\"ordered-float\"],\"semver-impl\":[\"semver\"],\"serde-compat\":[\"ts-rs-macros/serde-compat\"],\"serde-json-impl\":[\"serde_json\"],\"smol_str-impl\":[\"smol_str\"],\"tokio-impl\":[\"tokio\"],\"url-impl\":[\"url\"],\"uuid-impl\":[\"uuid\"]}}", "tui-scrollbar_0.2.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"color-eyre\",\"req\":\"^0.6\"},{\"name\":\"crossterm_0_28\",\"optional\":true,\"package\":\"crossterm\",\"req\":\"^0.28\"},{\"name\":\"crossterm_0_29\",\"optional\":true,\"package\":\"crossterm\",\"req\":\"^0.29\"},{\"name\":\"document-features\",\"req\":\"^0.2.11\"},{\"kind\":\"dev\",\"name\":\"ratatui\",\"req\":\"^0.30.0\"},{\"name\":\"ratatui-core\",\"req\":\"^0.1\"}],\"features\":{\"crossterm\":[\"crossterm_0_29\"],\"crossterm_0_28\":[\"dep:crossterm_0_28\"],\"crossterm_0_29\":[\"dep:crossterm_0_29\"],\"default\":[]}}", + "tungstenite_0.21.0": "{\"dependencies\":[{\"name\":\"byteorder\",\"req\":\"^1.3.2\"},{\"name\":\"bytes\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5.0\"},{\"name\":\"data-encoding\",\"optional\":true,\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.0\"},{\"name\":\"http\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"httparse\",\"optional\":true,\"req\":\"^1.3.4\"},{\"kind\":\"dev\",\"name\":\"input_buffer\",\"req\":\"^0.5.0\"},{\"name\":\"log\",\"req\":\"^0.4.8\"},{\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\",\"req\":\"^0.2.3\"},{\"name\":\"rand\",\"req\":\"^0.8.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.4\"},{\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.22.0\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.7.0\"},{\"name\":\"rustls-pki-types\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"sha1\",\"optional\":true,\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.5.5\"},{\"name\":\"thiserror\",\"req\":\"^1.0.23\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2.1.0\"},{\"name\":\"utf-8\",\"req\":\"^0.7.5\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^0.26\"}],\"features\":{\"__rustls-tls\":[\"rustls\",\"rustls-pki-types\"],\"default\":[\"handshake\"],\"handshake\":[\"data-encoding\",\"http\",\"httparse\",\"sha1\",\"url\"],\"native-tls\":[\"native-tls-crate\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate/vendored\"],\"rustls-tls-native-roots\":[\"__rustls-tls\",\"rustls-native-certs\"],\"rustls-tls-webpki-roots\":[\"__rustls-tls\",\"webpki-roots\"]}}", "typenum_1.18.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"scale-info\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"const-generics\":[],\"force_unix_path_separator\":[],\"i128\":[],\"no_std\":[],\"scale_info\":[\"scale-info/derive\"],\"strict\":[]}}", "uds_windows_1.1.0": "{\"dependencies\":[{\"name\":\"memoffset\",\"req\":\"^0.9.0\"},{\"name\":\"tempfile\",\"req\":\"^3\",\"target\":\"cfg(windows)\"},{\"features\":[\"winsock2\",\"ws2def\",\"minwinbase\",\"ntdef\",\"processthreadsapi\",\"handleapi\",\"ws2tcpip\",\"winbase\"],\"name\":\"winapi\",\"req\":\"^0.3.9\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "uname_0.1.1": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2\"}],\"features\":{}}", diff --git a/justfile b/justfile index 64f470ca7a..891d761e89 100644 --- a/justfile +++ b/justfile @@ -44,6 +44,10 @@ install: test: cargo nextest run --no-fail-fast +# Run Codex from source using Bazel +bazel-codex *args: + bazel run //codex-rs/cli:codex -- --cd "$PWD" "$@" + bazel-test: bazel test //... --keep_going