feat: make cwd a required field of Config so we stop assuming std::env::current_dir() in a session (#800)

In order to expose Codex via an MCP server, I realized that we should be
taking `cwd` as a parameter rather than assuming
`std::env::current_dir()` as the `cwd`. Specifically, the user may want
to start a session in a directory other than the one where the MCP
server has been started.

This PR makes `cwd: PathBuf` a required field of `Session` and threads
it all the way through, though I think there is still an issue with not
honoring `workdir` for `apply_patch`, which is something we also had to
fix in the TypeScript version: https://github.com/openai/codex/pull/556.

This also adds `-C`/`--cd` to change the cwd via the command line.

To test, I ran:

```
cargo run --bin codex -- exec -C /tmp 'show the output of ls'
```

and verified it showed the contents of my `/tmp` folder instead of
`$PWD`.
This commit is contained in:
Michael Bolin
2025-05-04 10:57:12 -07:00
committed by GitHub
parent 4b61fb8bab
commit 421e159888
18 changed files with 210 additions and 102 deletions

View File

@@ -18,7 +18,8 @@ pub fn run_landlock(command: Vec<String>, sandbox_policy: SandboxPolicy) -> anyh
// Spawn a new thread and apply the sandbox policies there.
let handle = std::thread::spawn(move || -> anyhow::Result<ExitStatus> {
codex_core::linux::apply_sandbox_policy_to_current_thread(sandbox_policy)?;
let cwd = std::env::current_dir()?;
codex_core::linux::apply_sandbox_policy_to_current_thread(sandbox_policy, &cwd)?;
let status = Command::new(&command[0]).args(&command[1..]).status()?;
Ok(status)
});

View File

@@ -5,7 +5,8 @@ pub async fn run_seatbelt(
command: Vec<String>,
sandbox_policy: SandboxPolicy,
) -> anyhow::Result<()> {
let seatbelt_command = create_seatbelt_command(command, &sandbox_policy);
let cwd = std::env::current_dir().expect("failed to get cwd");
let seatbelt_command = create_seatbelt_command(command, &sandbox_policy, &cwd);
let status = tokio::process::Command::new(seatbelt_command[0].clone())
.args(&seatbelt_command[1..])
.spawn()