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:
@@ -52,6 +52,11 @@ pub struct Config {
|
||||
///
|
||||
/// If unset the feature is disabled.
|
||||
pub notify: Option<Vec<String>>,
|
||||
|
||||
/// The directory that should be treated as the current working directory
|
||||
/// for the session. All relative paths inside the business-logic layer are
|
||||
/// resolved against this path.
|
||||
pub cwd: PathBuf,
|
||||
}
|
||||
|
||||
/// Base config deserialized from ~/.codex/config.toml.
|
||||
@@ -135,6 +140,7 @@ where
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct ConfigOverrides {
|
||||
pub model: Option<String>,
|
||||
pub cwd: Option<PathBuf>,
|
||||
pub approval_policy: Option<AskForApproval>,
|
||||
pub sandbox_policy: Option<SandboxPolicy>,
|
||||
pub disable_response_storage: Option<bool>,
|
||||
@@ -158,6 +164,7 @@ impl Config {
|
||||
// Destructure ConfigOverrides fully to ensure all overrides are applied.
|
||||
let ConfigOverrides {
|
||||
model,
|
||||
cwd,
|
||||
approval_policy,
|
||||
sandbox_policy,
|
||||
disable_response_storage,
|
||||
@@ -180,6 +187,23 @@ impl Config {
|
||||
|
||||
Self {
|
||||
model: model.or(cfg.model).unwrap_or_else(default_model),
|
||||
cwd: cwd.map_or_else(
|
||||
|| {
|
||||
tracing::info!("cwd not set, using current dir");
|
||||
std::env::current_dir().expect("cannot determine current dir")
|
||||
},
|
||||
|p| {
|
||||
if p.is_absolute() {
|
||||
p
|
||||
} else {
|
||||
// Resolve relative paths against the current working directory.
|
||||
tracing::info!("cwd is relative, resolving against current dir");
|
||||
let mut cwd = std::env::current_dir().expect("cannot determine cwd");
|
||||
cwd.push(p);
|
||||
cwd
|
||||
}
|
||||
},
|
||||
),
|
||||
approval_policy: approval_policy
|
||||
.or(cfg.approval_policy)
|
||||
.unwrap_or_else(AskForApproval::default),
|
||||
|
||||
Reference in New Issue
Block a user