chore(rs): update dependencies (#1494)

### Chores
- Update cargo dependencies
- Remove unused cargo dependencies
- Fix clippy warnings
- Update Dockerfile (package.json requires node 22)
- Let Dependabot update bun, cargo, devcontainers, docker,
github-actions, npm (nix still not supported)

### TODO
- Upgrade dependencies with breaking changes

```shell
$ cargo update --verbose
   Unchanged crossterm v0.28.1 (available: v0.29.0)
   Unchanged schemars v0.8.22 (available: v1.0.4)
```
This commit is contained in:
Rene Leonhardt
2025-07-10 20:08:16 +02:00
committed by GitHub
parent 3a23a86f4b
commit 82b0cebe8b
36 changed files with 673 additions and 615 deletions

32
.github/dependabot.yaml vendored Normal file
View File

@@ -0,0 +1,32 @@
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#package-ecosystem-
version: 2
updates:
- package-ecosystem: bun
directory: .github/actions/codex
schedule:
interval: weekly
- package-ecosystem: cargo
directories:
- codex-rs
- codex-rs/*
schedule:
interval: weekly
- package-ecosystem: devcontainers
directory: /
schedule:
interval: weekly
- package-ecosystem: docker
directory: codex-cli
schedule:
interval: weekly
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
- package-ecosystem: npm
directories:
- /
- codex-cli
schedule:
interval: weekly

View File

@@ -70,7 +70,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- uses: dtolnay/rust-toolchain@1.87 - uses: dtolnay/rust-toolchain@1.88
with: with:
targets: x86_64-unknown-linux-gnu targets: x86_64-unknown-linux-gnu
components: clippy components: clippy

View File

@@ -26,7 +26,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.87 - uses: dtolnay/rust-toolchain@1.88
with: with:
components: rustfmt components: rustfmt
- name: cargo fmt - name: cargo fmt
@@ -64,7 +64,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.87 - uses: dtolnay/rust-toolchain@1.88
with: with:
targets: ${{ matrix.target }} targets: ${{ matrix.target }}
components: clippy components: clippy

View File

@@ -73,7 +73,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.87 - uses: dtolnay/rust-toolchain@1.88
with: with:
targets: ${{ matrix.target }} targets: ${{ matrix.target }}

View File

@@ -1,4 +1,4 @@
FROM node:20-slim FROM node:22-slim
ARG TZ ARG TZ
ENV TZ="$TZ" ENV TZ="$TZ"

1149
codex-rs/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,11 +12,10 @@ workspace = true
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
serde_json = "1.0.110"
similar = "2.7.0" similar = "2.7.0"
thiserror = "2.0.12" thiserror = "2.0.12"
tree-sitter = "0.25.3" tree-sitter = "0.25.3"
tree-sitter-bash = "0.23.3" tree-sitter-bash = "0.25.0"
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.4.1" pretty_assertions = "1.4.1"

View File

@@ -633,7 +633,7 @@ mod tests {
/// Helper to construct a patch with the given body. /// Helper to construct a patch with the given body.
fn wrap_patch(body: &str) -> String { fn wrap_patch(body: &str) -> String {
format!("*** Begin Patch\n{}\n*** End Patch", body) format!("*** Begin Patch\n{body}\n*** End Patch")
} }
fn strs_to_strings(strs: &[&str]) -> Vec<String> { fn strs_to_strings(strs: &[&str]) -> Vec<String> {
@@ -661,7 +661,7 @@ mod tests {
}] }]
); );
} }
result => panic!("expected MaybeApplyPatch::Body got {:?}", result), result => panic!("expected MaybeApplyPatch::Body got {result:?}"),
} }
} }
@@ -688,7 +688,7 @@ PATCH"#,
}] }]
); );
} }
result => panic!("expected MaybeApplyPatch::Body got {:?}", result), result => panic!("expected MaybeApplyPatch::Body got {result:?}"),
} }
} }

View File

@@ -9,7 +9,7 @@ workspace = true
[dependencies] [dependencies]
clap = { version = "4", features = ["derive", "wrap_help"], optional = true } clap = { version = "4", features = ["derive", "wrap_help"], optional = true }
codex-core = { path = "../core" } codex-core = { path = "../core" }
toml = { version = "0.8", optional = true } toml = { version = "0.9", optional = true }
serde = { version = "1", optional = true } serde = { version = "1", optional = true }
[features] [features]

View File

@@ -20,7 +20,7 @@ pub fn format_duration(duration: Duration) -> String {
fn format_elapsed_millis(millis: i64) -> String { fn format_elapsed_millis(millis: i64) -> String {
if millis < 1000 { if millis < 1000 {
format!("{}ms", millis) format!("{millis}ms")
} else if millis < 60_000 { } else if millis < 60_000 {
format!("{:.2}s", millis as f64 / 1000.0) format!("{:.2}s", millis as f64 / 1000.0)
} else { } else {

View File

@@ -13,26 +13,21 @@ workspace = true
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
async-channel = "2.3.1" async-channel = "2.3.1"
base64 = "0.21" base64 = "0.22"
bytes = "1.10.1" bytes = "1.10.1"
codex-apply-patch = { path = "../apply-patch" } codex-apply-patch = { path = "../apply-patch" }
codex-login = { path = "../login" }
codex-mcp-client = { path = "../mcp-client" } codex-mcp-client = { path = "../mcp-client" }
dirs = "6" dirs = "6"
env-flags = "0.1.1" env-flags = "0.1.1"
eventsource-stream = "0.2.3" eventsource-stream = "0.2.3"
fs2 = "0.4.3" fs2 = "0.4.3"
fs-err = "3.1.0"
futures = "0.3" futures = "0.3"
mcp-types = { path = "../mcp-types" } mcp-types = { path = "../mcp-types" }
mime_guess = "2.0" mime_guess = "2.0"
patch = "0.7"
path-absolutize = "3.1.1"
rand = "0.9" rand = "0.9"
reqwest = { version = "0.12", features = ["json", "stream"] } reqwest = { version = "0.12", features = ["json", "stream"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
strum = "0.27.1"
strum_macros = "0.27.1" strum_macros = "0.27.1"
thiserror = "2.0.12" thiserror = "2.0.12"
time = { version = "0.3", features = ["formatting", "local-offset", "macros"] } time = { version = "0.3", features = ["formatting", "local-offset", "macros"] }
@@ -44,10 +39,10 @@ tokio = { version = "1", features = [
"signal", "signal",
] } ] }
tokio-util = "0.7.14" tokio-util = "0.7.14"
toml = "0.8.20" toml = "0.9.0"
tracing = { version = "0.1.41", features = ["log"] } tracing = { version = "0.1.41", features = ["log"] }
tree-sitter = "0.25.3" tree-sitter = "0.25.3"
tree-sitter-bash = "0.23.3" tree-sitter-bash = "0.25.0"
uuid = { version = "1", features = ["serde", "v4"] } uuid = { version = "1", features = ["serde", "v4"] }
wildmatch = "2.4.0" wildmatch = "2.4.0"

View File

@@ -37,7 +37,7 @@ pub struct Prompt {
} }
impl Prompt { impl Prompt {
pub(crate) fn get_full_instructions(&self, model: &str) -> Cow<str> { pub(crate) fn get_full_instructions(&self, model: &str) -> Cow<'_, str> {
let mut sections: Vec<&str> = vec![BASE_INSTRUCTIONS]; let mut sections: Vec<&str> = vec![BASE_INSTRUCTIONS];
if let Some(ref user) = self.user_instructions { if let Some(ref user) = self.user_instructions {
sections.push(user); sections.push(user);

View File

@@ -1297,7 +1297,7 @@ async fn handle_function_call(
ResponseInputItem::FunctionCallOutput { ResponseInputItem::FunctionCallOutput {
call_id, call_id,
output: FunctionCallOutputPayload { output: FunctionCallOutputPayload {
content: format!("unsupported call: {}", name), content: format!("unsupported call: {name}"),
success: None, success: None,
}, },
} }
@@ -1489,8 +1489,7 @@ async fn handle_sandbox_error(
call_id, call_id,
output: FunctionCallOutputPayload { output: FunctionCallOutputPayload {
content: format!( content: format!(
"failed in sandbox {:?} with execution error: {error}", "failed in sandbox {sandbox_type:?} with execution error: {error}"
sandbox_type
), ),
success: Some(false), success: Some(false),
}, },

View File

@@ -240,8 +240,7 @@ mod tests {
] { ] {
assert!( assert!(
!is_safe_to_call_with_exec(&args), !is_safe_to_call_with_exec(&args),
"expected {:?} to be unsafe", "expected {args:?} to be unsafe"
args
); );
} }
} }

View File

@@ -145,7 +145,7 @@ impl From<Vec<InputItem>> for ResponseInputItem {
.unwrap_or_else(|| "application/octet-stream".to_string()); .unwrap_or_else(|| "application/octet-stream".to_string());
let encoded = base64::engine::general_purpose::STANDARD.encode(bytes); let encoded = base64::engine::general_purpose::STANDARD.encode(bytes);
Some(ContentItem::InputImage { Some(ContentItem::InputImage {
image_url: format!("data:{};base64,{}", mime, encoded), image_url: format!("data:{mime};base64,{encoded}"),
}) })
} }
Err(err) => { Err(err) => {

View File

@@ -46,8 +46,7 @@ impl Match for HasPrevId {
fn sse_completed(id: &str) -> String { fn sse_completed(id: &str) -> String {
format!( format!(
"event: response.completed\n\ "event: response.completed\n\
data: {{\"type\":\"response.completed\",\"response\":{{\"id\":\"{}\",\"output\":[]}}}}\n\n\n", data: {{\"type\":\"response.completed\",\"response\":{{\"id\":\"{id}\",\"output\":[]}}}}\n\n\n"
id
) )
} }

View File

@@ -29,8 +29,7 @@ fn sse_incomplete() -> String {
fn sse_completed(id: &str) -> String { fn sse_completed(id: &str) -> String {
format!( format!(
"event: response.completed\n\ "event: response.completed\n\
data: {{\"type\":\"response.completed\",\"response\":{{\"id\":\"{}\",\"output\":[]}}}}\n\n\n", data: {{\"type\":\"response.completed\",\"response\":{{\"id\":\"{id}\",\"output\":[]}}}}\n\n\n"
id
) )
} }

View File

@@ -25,7 +25,6 @@ codex-common = { path = "../common", features = [
"sandbox_summary", "sandbox_summary",
] } ] }
codex-linux-sandbox = { path = "../linux-sandbox" } codex-linux-sandbox = { path = "../linux-sandbox" }
mcp-types = { path = "../mcp-types" }
owo-colors = "4.2.0" owo-colors = "4.2.0"
serde_json = "1" serde_json = "1"
shlex = "1.3.0" shlex = "1.3.0"

View File

@@ -415,7 +415,7 @@ impl EventProcessor {
{ {
( (
format!(" in {}", format_elapsed(start_time)), format!(" in {}", format_elapsed(start_time)),
format!("apply_patch(auto_approved={})", auto_approved), format!("apply_patch(auto_approved={auto_approved})"),
) )
} else { } else {
(String::new(), format!("apply_patch('{call_id}')")) (String::new(), format!("apply_patch('{call_id}')"))

View File

@@ -19,7 +19,7 @@ anyhow = "1"
starlark = "0.13.0" starlark = "0.13.0"
allocative = "0.3.3" allocative = "0.3.3"
clap = { version = "4", features = ["derive"] } clap = { version = "4", features = ["derive"] }
derive_more = { version = "1", features = ["display"] } derive_more = { version = "2", features = ["display"] }
env_logger = "0.11.5" env_logger = "0.11.5"
log = "0.4" log = "0.4"
multimap = "0.10.0" multimap = "0.10.0"
@@ -28,4 +28,6 @@ regex-lite = "0.1"
serde = { version = "1.0.194", features = ["derive"] } serde = { version = "1.0.194", features = ["derive"] }
serde_json = "1.0.110" serde_json = "1.0.110"
serde_with = { version = "3", features = ["macros"] } serde_with = { version = "3", features = ["macros"] }
[dev-dependencies]
tempfile = "3.13.0" tempfile = "3.13.0"

View File

@@ -21,7 +21,7 @@ impl Display for ExecCall {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.program)?; write!(f, "{}", self.program)?;
for arg in &self.args { for arg in &self.args {
write!(f, " {}", arg)?; write!(f, " {arg}")?;
} }
Ok(()) Ok(())
} }

View File

@@ -89,7 +89,7 @@ fn main() -> Result<()> {
let (output, exit_code) = check_command(&policy, exec, args.require_safe); let (output, exit_code) = check_command(&policy, exec, args.require_safe);
let json = serde_json::to_string(&output)?; let json = serde_json::to_string(&output)?;
println!("{}", json); println!("{json}");
std::process::exit(exit_code); std::process::exit(exit_code);
} }

View File

@@ -63,7 +63,7 @@ impl Policy {
arg: arg.clone(), arg: arg.clone(),
exec_call: exec_call.clone(), exec_call: exec_call.clone(),
}, },
reason: format!("arg `{}` contains forbidden substring", arg), reason: format!("arg `{arg}` contains forbidden substring"),
}); });
} }
} }

View File

@@ -101,7 +101,7 @@ impl PolicyBuilder {
} }
fn add_program_spec(&self, program_spec: ProgramSpec) { fn add_program_spec(&self, program_spec: ProgramSpec) {
info!("adding program spec: {:?}", program_spec); info!("adding program spec: {program_spec:?}");
let name = program_spec.program.clone(); let name = program_spec.program.clone();
let mut programs = self.programs.borrow_mut(); let mut programs = self.programs.borrow_mut();
programs.insert(name.clone(), program_spec); programs.insert(name.clone(), program_spec);

View File

@@ -156,7 +156,7 @@ pub fn run(
let mut override_builder = OverrideBuilder::new(search_directory); let mut override_builder = OverrideBuilder::new(search_directory);
for exclude in exclude { for exclude in exclude {
// The `!` prefix is used to indicate an exclude pattern. // The `!` prefix is used to indicate an exclude pattern.
let exclude_pattern = format!("!{}", exclude); let exclude_pattern = format!("!{exclude}");
override_builder.add(&exclude_pattern)?; override_builder.add(&exclude_pattern)?;
} }
let override_matcher = override_builder.build()?; let override_matcher = override_builder.build()?;

View File

@@ -43,12 +43,12 @@ impl Reporter for StdioReporter {
match indices_iter.peek() { match indices_iter.peek() {
Some(next) if **next == i as u32 => { Some(next) if **next == i as u32 => {
// ANSI escape code for bold: \x1b[1m ... \x1b[0m // ANSI escape code for bold: \x1b[1m ... \x1b[0m
print!("\x1b[1m{}\x1b[0m", c); print!("\x1b[1m{c}\x1b[0m");
// advance the iterator since we've consumed this index // advance the iterator since we've consumed this index
indices_iter.next(); indices_iter.next();
} }
_ => { _ => {
print!("{}", c); print!("{c}");
} }
} }
} }

View File

@@ -81,7 +81,7 @@ async fn test_root_write() {
let tmpfile = NamedTempFile::new().unwrap(); let tmpfile = NamedTempFile::new().unwrap();
let tmpfile_path = tmpfile.path().to_string_lossy(); let tmpfile_path = tmpfile.path().to_string_lossy();
run_cmd( run_cmd(
&["bash", "-lc", &format!("echo blah > {}", tmpfile_path)], &["bash", "-lc", &format!("echo blah > {tmpfile_path}")],
&[], &[],
SHORT_TIMEOUT_MS, SHORT_TIMEOUT_MS,
) )
@@ -158,7 +158,7 @@ async fn assert_network_blocked(cmd: &[&str]) {
(exit_code, stdout, stderr) (exit_code, stdout, stderr)
} }
_ => { _ => {
panic!("expected sandbox denied error, got: {:?}", result); panic!("expected sandbox denied error, got: {result:?}");
} }
}; };
@@ -171,10 +171,7 @@ async fn assert_network_blocked(cmd: &[&str]) {
// If—*and only if*—the command exits 0 we consider the sandbox breached. // If—*and only if*—the command exits 0 we consider the sandbox breached.
if exit_code == 0 { if exit_code == 0 {
panic!( panic!("Network sandbox FAILED - {cmd:?} exited 0\nstdout:\n{stdout}\nstderr:\n{stderr}",);
"Network sandbox FAILED - {:?} exited 0\nstdout:\n{}\nstderr:\n{}",
cmd, stdout, stderr
);
} }
} }

View File

@@ -21,6 +21,3 @@ tokio = { version = "1", features = [
"sync", "sync",
"time", "time",
] } ] }
[dev-dependencies]
pretty_assertions = "1.4.1"

View File

@@ -22,7 +22,7 @@ mcp-types = { path = "../mcp-types" }
schemars = "0.8.22" schemars = "0.8.22"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
toml = "0.8" toml = "0.9"
tracing = { version = "0.1.41", features = ["log"] } tracing = { version = "0.1.41", features = ["log"] }
tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] } tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
tokio = { version = "1", features = [ tokio = { version = "1", features = [

View File

@@ -54,7 +54,7 @@ tokio = { version = "1", features = [
tracing = { version = "0.1.41", features = ["log"] } tracing = { version = "0.1.41", features = ["log"] }
tracing-appender = "0.2.3" tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
tui-input = "0.11.1" tui-input = "0.14.0"
tui-markdown = "0.3.3" tui-markdown = "0.3.3"
tui-textarea = "0.7.0" tui-textarea = "0.7.0"
unicode-segmentation = "1.12.0" unicode-segmentation = "1.12.0"

View File

@@ -678,8 +678,7 @@ mod tests {
let result = ChatComposer::current_at_token(&textarea); let result = ChatComposer::current_at_token(&textarea);
assert_eq!( assert_eq!(
result, expected, result, expected,
"Failed for case: {} - input: '{}', cursor: {}", "Failed for case: {description} - input: '{input}', cursor: {cursor_pos}"
description, input, cursor_pos
); );
} }
} }

View File

@@ -56,7 +56,7 @@ pub(crate) fn get_git_diff() -> io::Result<(bool, String)> {
} }
} }
Ok((true, format!("{}{}", tracked_diff, untracked_diff))) Ok((true, format!("{tracked_diff}{untracked_diff}")))
} }
/// Helper that executes `git` with the given `args` and returns `stdout` as a /// Helper that executes `git` with the given `args` and returns `stdout` as a

View File

@@ -140,7 +140,7 @@ impl HistoryCell {
Line::from(vec![ Line::from(vec![
"OpenAI ".into(), "OpenAI ".into(),
"Codex".bold(), "Codex".bold(),
format!(" v{}", VERSION).into(), format!(" v{VERSION}").into(),
" (research preview)".dim(), " (research preview)".dim(),
]), ]),
Line::from(""), Line::from(""),
@@ -185,7 +185,7 @@ impl HistoryCell {
let lines = vec![ let lines = vec![
Line::from("model changed:".magenta().bold()), Line::from("model changed:".magenta().bold()),
Line::from(format!("requested: {}", config.model)), Line::from(format!("requested: {}", config.model)),
Line::from(format!("used: {}", model)), Line::from(format!("used: {model}")),
Line::from(""), Line::from(""),
]; ];
HistoryCell::SessionInfo { HistoryCell::SessionInfo {
@@ -276,7 +276,7 @@ impl HistoryCell {
} }
let remaining = lines_iter.count(); let remaining = lines_iter.count();
if remaining > 0 { if remaining > 0 {
lines.push(Line::from(format!("... {} additional lines", remaining)).dim()); lines.push(Line::from(format!("... {remaining} additional lines")).dim());
} }
lines.push(Line::from("")); lines.push(Line::from(""));

View File

@@ -216,8 +216,7 @@ fn run_ratatui_app(
fn restore() { fn restore() {
if let Err(err) = tui::restore() { if let Err(err) = tui::restore() {
eprintln!( eprintln!(
"failed to restore terminal. Run `reset` or restart your terminal to recover: {}", "failed to restore terminal. Run `reset` or restart your terminal to recover: {err}"
err
); );
} }
} }

View File

@@ -53,7 +53,7 @@ where
impl Visit for Visitor<'_> { impl Visit for Visitor<'_> {
fn record_debug(&mut self, _field: &Field, value: &dyn std::fmt::Debug) { fn record_debug(&mut self, _field: &Field, value: &dyn std::fmt::Debug) {
let _ = write!(self.buf, " {:?}", value); let _ = write!(self.buf, " {value:?}");
} }
} }

View File

@@ -85,7 +85,7 @@ pub(crate) fn truncate_text(text: &str, max_graphemes: usize) -> String {
let mut truncate_graphemes = text.grapheme_indices(true); let mut truncate_graphemes = text.grapheme_indices(true);
if let Some((truncate_byte_index, _)) = truncate_graphemes.nth(max_graphemes - 3) { if let Some((truncate_byte_index, _)) = truncate_graphemes.nth(max_graphemes - 3) {
let truncated = &text[..truncate_byte_index]; let truncated = &text[..truncate_byte_index];
format!("{}...", truncated) format!("{truncated}...")
} else { } else {
text.to_string() text.to_string()
} }