mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
fix(exec): store project roots in config
This commit is contained in:
@@ -2854,7 +2854,7 @@ async fn add_dir_override_extends_workspace_writable_roots() -> std::io::Result<
|
||||
std::fs::create_dir_all(&backend)?;
|
||||
|
||||
let overrides = ConfigOverrides {
|
||||
cwd: Some(frontend),
|
||||
cwd: Some(frontend.clone()),
|
||||
sandbox_mode: Some(SandboxMode::WorkspaceWrite),
|
||||
additional_writable_roots: vec![PathBuf::from("../backend"), backend.clone()],
|
||||
..Default::default()
|
||||
@@ -2868,6 +2868,14 @@ async fn add_dir_override_extends_workspace_writable_roots() -> std::io::Result<
|
||||
.await?;
|
||||
|
||||
let expected_backend = backend.abs();
|
||||
assert_eq!(
|
||||
config.project_roots,
|
||||
vec![
|
||||
frontend.abs(),
|
||||
expected_backend.clone(),
|
||||
expected_backend.clone()
|
||||
]
|
||||
);
|
||||
if cfg!(target_os = "windows") {
|
||||
match &config.legacy_sandbox_policy() {
|
||||
SandboxPolicy::ReadOnly { .. } => {}
|
||||
@@ -6366,6 +6374,7 @@ async fn test_precedence_fixture_with_o3_profile() -> std::io::Result<()> {
|
||||
user_instructions: None,
|
||||
notify: None,
|
||||
cwd: fixture.cwd(),
|
||||
project_roots: vec![fixture.cwd()],
|
||||
cli_auth_credentials_store_mode: Default::default(),
|
||||
mcp_servers: Constrained::allow_any(HashMap::new()),
|
||||
mcp_oauth_credentials_store_mode: resolve_mcp_oauth_credentials_store_mode(
|
||||
@@ -6568,6 +6577,7 @@ async fn test_precedence_fixture_with_gpt3_profile() -> std::io::Result<()> {
|
||||
user_instructions: None,
|
||||
notify: None,
|
||||
cwd: fixture.cwd(),
|
||||
project_roots: vec![fixture.cwd()],
|
||||
cli_auth_credentials_store_mode: Default::default(),
|
||||
mcp_servers: Constrained::allow_any(HashMap::new()),
|
||||
mcp_oauth_credentials_store_mode: resolve_mcp_oauth_credentials_store_mode(
|
||||
@@ -6724,6 +6734,7 @@ async fn test_precedence_fixture_with_zdr_profile() -> std::io::Result<()> {
|
||||
user_instructions: None,
|
||||
notify: None,
|
||||
cwd: fixture.cwd(),
|
||||
project_roots: vec![fixture.cwd()],
|
||||
cli_auth_credentials_store_mode: Default::default(),
|
||||
mcp_servers: Constrained::allow_any(HashMap::new()),
|
||||
mcp_oauth_credentials_store_mode: resolve_mcp_oauth_credentials_store_mode(
|
||||
@@ -6865,6 +6876,7 @@ async fn test_precedence_fixture_with_gpt5_profile() -> std::io::Result<()> {
|
||||
user_instructions: None,
|
||||
notify: None,
|
||||
cwd: fixture.cwd(),
|
||||
project_roots: vec![fixture.cwd()],
|
||||
cli_auth_credentials_store_mode: Default::default(),
|
||||
mcp_servers: Constrained::allow_any(HashMap::new()),
|
||||
mcp_oauth_credentials_store_mode: resolve_mcp_oauth_credentials_store_mode(
|
||||
|
||||
@@ -561,6 +561,11 @@ pub struct Config {
|
||||
/// layer are resolved against this path.
|
||||
pub cwd: AbsolutePathBuf,
|
||||
|
||||
/// Absolute project roots for the session. This is the cwd plus any
|
||||
/// user-requested additional roots, before implicit writable roots are
|
||||
/// added to the effective permission profile.
|
||||
pub project_roots: Vec<AbsolutePathBuf>,
|
||||
|
||||
/// Preferred store for CLI auth credentials.
|
||||
/// file (default): Use a file in the Codex home directory.
|
||||
/// keyring: Use an OS-specific keyring service.
|
||||
@@ -2950,6 +2955,9 @@ impl Config {
|
||||
.value
|
||||
.set(effective_permission_profile)
|
||||
.map_err(std::io::Error::from)?;
|
||||
let project_roots = std::iter::once(resolved_cwd.clone())
|
||||
.chain(requested_additional_writable_roots.iter().cloned())
|
||||
.collect::<Vec<_>>();
|
||||
let config = Self {
|
||||
model,
|
||||
service_tier,
|
||||
@@ -2959,6 +2967,7 @@ impl Config {
|
||||
model_provider_id,
|
||||
model_provider,
|
||||
cwd: resolved_cwd,
|
||||
project_roots,
|
||||
startup_warnings,
|
||||
permissions: Permissions {
|
||||
approval_policy: constrained_approval_policy.value,
|
||||
|
||||
@@ -207,7 +207,6 @@ struct ExecRunArgs {
|
||||
oss: bool,
|
||||
output_schema_path: Option<PathBuf>,
|
||||
prompt: Option<String>,
|
||||
project_roots: Option<Vec<AbsolutePathBuf>>,
|
||||
skip_git_repo_check: bool,
|
||||
stderr_with_ansi: bool,
|
||||
}
|
||||
@@ -305,15 +304,6 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
|
||||
}
|
||||
None => AbsolutePathBuf::current_dir()?,
|
||||
};
|
||||
let project_roots =
|
||||
(!add_dir.is_empty()).then(|| {
|
||||
std::iter::once(config_cwd.clone())
|
||||
.chain(add_dir.iter().cloned().map(|path| {
|
||||
AbsolutePathBuf::resolve_path_against_base(path, config_cwd.as_path())
|
||||
}))
|
||||
.collect()
|
||||
});
|
||||
|
||||
// we load config.toml here to determine project state.
|
||||
#[allow(clippy::print_stderr)]
|
||||
let codex_home = match find_codex_home() {
|
||||
@@ -550,7 +540,6 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
|
||||
oss,
|
||||
output_schema_path,
|
||||
prompt,
|
||||
project_roots,
|
||||
skip_git_repo_check,
|
||||
stderr_with_ansi,
|
||||
})
|
||||
@@ -573,11 +562,9 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
oss,
|
||||
output_schema_path,
|
||||
prompt,
|
||||
project_roots,
|
||||
skip_git_repo_check,
|
||||
stderr_with_ansi,
|
||||
} = args;
|
||||
let project_roots = project_roots.as_deref();
|
||||
|
||||
let mut event_processor: Box<dyn EventProcessor> = match json_mode {
|
||||
true => Box::new(EventProcessorWithJsonOutput::new(last_message_file.clone())),
|
||||
@@ -697,7 +684,7 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
&client,
|
||||
ClientRequest::ThreadResume {
|
||||
request_id: request_ids.next(),
|
||||
params: thread_resume_params_from_config(&config, thread_id, project_roots),
|
||||
params: thread_resume_params_from_config(&config, thread_id),
|
||||
},
|
||||
"thread/resume",
|
||||
)
|
||||
@@ -712,7 +699,7 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
&client,
|
||||
ClientRequest::ThreadStart {
|
||||
request_id: request_ids.next(),
|
||||
params: thread_start_params_from_config(&config, project_roots),
|
||||
params: thread_start_params_from_config(&config),
|
||||
},
|
||||
"thread/start",
|
||||
)
|
||||
@@ -728,7 +715,7 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
&client,
|
||||
ClientRequest::ThreadStart {
|
||||
request_id: request_ids.next(),
|
||||
params: thread_start_params_from_config(&config, project_roots),
|
||||
params: thread_start_params_from_config(&config),
|
||||
},
|
||||
"thread/start",
|
||||
)
|
||||
@@ -941,10 +928,7 @@ async fn run_exec_session(args: ExecRunArgs) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn thread_start_params_from_config(
|
||||
config: &Config,
|
||||
project_roots: Option<&[AbsolutePathBuf]>,
|
||||
) -> ThreadStartParams {
|
||||
fn thread_start_params_from_config(config: &Config) -> ThreadStartParams {
|
||||
let permissions = permissions_selection_from_config(config);
|
||||
let sandbox = permissions.is_none().then(|| {
|
||||
sandbox_mode_from_permission_profile(
|
||||
@@ -960,18 +944,14 @@ fn thread_start_params_from_config(
|
||||
approvals_reviewer: approvals_reviewer_override_from_config(config),
|
||||
sandbox: sandbox.flatten(),
|
||||
permissions,
|
||||
project_roots: project_roots.map(<[AbsolutePathBuf]>::to_vec),
|
||||
project_roots: Some(config.project_roots.clone()),
|
||||
config: config_request_overrides_from_config(config),
|
||||
ephemeral: Some(config.ephemeral),
|
||||
..ThreadStartParams::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn thread_resume_params_from_config(
|
||||
config: &Config,
|
||||
thread_id: String,
|
||||
project_roots: Option<&[AbsolutePathBuf]>,
|
||||
) -> ThreadResumeParams {
|
||||
fn thread_resume_params_from_config(config: &Config, thread_id: String) -> ThreadResumeParams {
|
||||
let permissions = permissions_selection_from_config(config);
|
||||
let sandbox = permissions.is_none().then(|| {
|
||||
sandbox_mode_from_permission_profile(
|
||||
@@ -988,7 +968,7 @@ fn thread_resume_params_from_config(
|
||||
approvals_reviewer: approvals_reviewer_override_from_config(config),
|
||||
sandbox: sandbox.flatten(),
|
||||
permissions,
|
||||
project_roots: project_roots.map(<[AbsolutePathBuf]>::to_vec),
|
||||
project_roots: Some(config.project_roots.clone()),
|
||||
config: config_request_overrides_from_config(config),
|
||||
..ThreadResumeParams::default()
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ async fn thread_start_params_include_review_policy_when_review_policy_is_manual_
|
||||
.await
|
||||
.expect("build config with manual-only review policy");
|
||||
|
||||
let params = thread_start_params_from_config(&config, /*project_roots*/ None);
|
||||
let params = thread_start_params_from_config(&config);
|
||||
|
||||
assert_eq!(
|
||||
params.approvals_reviewer,
|
||||
@@ -383,7 +383,7 @@ async fn thread_start_params_include_review_policy_when_auto_review_is_enabled()
|
||||
.await
|
||||
.expect("build config with guardian review policy");
|
||||
|
||||
let params = thread_start_params_from_config(&config, /*project_roots*/ None);
|
||||
let params = thread_start_params_from_config(&config);
|
||||
|
||||
assert_eq!(
|
||||
params.approvals_reviewer,
|
||||
@@ -400,6 +400,7 @@ async fn thread_lifecycle_params_include_legacy_sandbox_when_no_active_profile()
|
||||
.codex_home(codex_home.path().to_path_buf())
|
||||
.harness_overrides(ConfigOverrides {
|
||||
sandbox_mode: Some(SandboxMode::WorkspaceWrite),
|
||||
additional_writable_roots: vec![extra.clone().into_path_buf()],
|
||||
..Default::default()
|
||||
})
|
||||
.fallback_cwd(Some(cwd.path().to_path_buf()))
|
||||
@@ -412,11 +413,11 @@ async fn thread_lifecycle_params_include_legacy_sandbox_when_no_active_profile()
|
||||
config.cwd.as_path(),
|
||||
);
|
||||
|
||||
let start_params = thread_start_params_from_config(&config, Some(&project_roots));
|
||||
let resume_params =
|
||||
thread_resume_params_from_config(&config, "thread-id".to_string(), Some(&project_roots));
|
||||
let start_params = thread_start_params_from_config(&config);
|
||||
let resume_params = thread_resume_params_from_config(&config, "thread-id".to_string());
|
||||
|
||||
assert_eq!(config.permissions.active_permission_profile(), None);
|
||||
assert_eq!(config.project_roots, project_roots);
|
||||
assert_eq!(start_params.sandbox, expected_sandbox);
|
||||
assert_eq!(start_params.permissions, None);
|
||||
assert_eq!(start_params.project_roots, Some(project_roots.clone()));
|
||||
|
||||
Reference in New Issue
Block a user