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
run: pnpm install
- uses: dtolnay/rust-toolchain@1.87
- uses: dtolnay/rust-toolchain@1.88
with:
targets: x86_64-unknown-linux-gnu
components: clippy

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
FROM node:20-slim
FROM node:22-slim
ARG 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]
anyhow = "1"
serde_json = "1.0.110"
similar = "2.7.0"
thiserror = "2.0.12"
tree-sitter = "0.25.3"
tree-sitter-bash = "0.23.3"
tree-sitter-bash = "0.25.0"
[dev-dependencies]
pretty_assertions = "1.4.1"

View File

@@ -633,7 +633,7 @@ mod tests {
/// Helper to construct a patch with the given body.
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> {
@@ -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]
clap = { version = "4", features = ["derive", "wrap_help"], optional = true }
codex-core = { path = "../core" }
toml = { version = "0.8", optional = true }
toml = { version = "0.9", optional = true }
serde = { version = "1", optional = true }
[features]

View File

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

View File

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

View File

@@ -37,7 +37,7 @@ pub struct 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];
if let Some(ref user) = self.user_instructions {
sections.push(user);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,7 +19,7 @@ anyhow = "1"
starlark = "0.13.0"
allocative = "0.3.3"
clap = { version = "4", features = ["derive"] }
derive_more = { version = "1", features = ["display"] }
derive_more = { version = "2", features = ["display"] }
env_logger = "0.11.5"
log = "0.4"
multimap = "0.10.0"
@@ -28,4 +28,6 @@ regex-lite = "0.1"
serde = { version = "1.0.194", features = ["derive"] }
serde_json = "1.0.110"
serde_with = { version = "3", features = ["macros"] }
[dev-dependencies]
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 {
write!(f, "{}", self.program)?;
for arg in &self.args {
write!(f, " {}", arg)?;
write!(f, " {arg}")?;
}
Ok(())
}

View File

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

View File

@@ -63,7 +63,7 @@ impl Policy {
arg: arg.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) {
info!("adding program spec: {:?}", program_spec);
info!("adding program spec: {program_spec:?}");
let name = program_spec.program.clone();
let mut programs = self.programs.borrow_mut();
programs.insert(name.clone(), program_spec);

View File

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

View File

@@ -43,12 +43,12 @@ impl Reporter for StdioReporter {
match indices_iter.peek() {
Some(next) if **next == i as u32 => {
// 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
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_path = tmpfile.path().to_string_lossy();
run_cmd(
&["bash", "-lc", &format!("echo blah > {}", tmpfile_path)],
&["bash", "-lc", &format!("echo blah > {tmpfile_path}")],
&[],
SHORT_TIMEOUT_MS,
)
@@ -158,7 +158,7 @@ async fn assert_network_blocked(cmd: &[&str]) {
(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 exit_code == 0 {
panic!(
"Network sandbox FAILED - {:?} exited 0\nstdout:\n{}\nstderr:\n{}",
cmd, stdout, stderr
);
panic!("Network sandbox FAILED - {cmd:?} exited 0\nstdout:\n{stdout}\nstderr:\n{stderr}",);
}
}

View File

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

View File

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

View File

@@ -54,7 +54,7 @@ tokio = { version = "1", features = [
tracing = { version = "0.1.41", features = ["log"] }
tracing-appender = "0.2.3"
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-textarea = "0.7.0"
unicode-segmentation = "1.12.0"

View File

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

View File

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

View File

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

View File

@@ -53,7 +53,7 @@ where
impl Visit for Visitor<'_> {
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);
if let Some((truncate_byte_index, _)) = truncate_graphemes.nth(max_graphemes - 3) {
let truncated = &text[..truncate_byte_index];
format!("{}...", truncated)
format!("{truncated}...")
} else {
text.to_string()
}