Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions codex-rs/app-server-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,9 @@ pub use crate::remote::RemoteAppServerEndpoint;
/// module exists so clients can remove a direct `codex-core` dependency
/// while legacy startup/config paths are migrated to RPCs.
pub mod legacy_core {
pub use codex_core::DEFAULT_AGENTS_MD_FILENAME;
pub use codex_core::LOCAL_AGENTS_MD_FILENAME;
pub use codex_core::McpManager;
pub use codex_core::check_execpolicy_for_warnings;
pub use codex_core::format_exec_policy_error_with_source;
pub use codex_core::grant_read_root_non_elevated;
pub use codex_core::web_search_detail;

pub mod config {
pub use codex_core::config::*;
Expand All @@ -86,10 +82,6 @@ pub mod legacy_core {
}
}

pub mod connectors {
pub use codex_core::connectors::*;
}

pub mod otel_init {
pub use codex_core::otel_init::*;
}
Expand All @@ -98,22 +90,10 @@ pub mod legacy_core {
pub use codex_core::personality_migration::*;
}

pub mod review_format {
pub use codex_core::review_format::*;
}

pub mod review_prompts {
pub use codex_core::review_prompts::*;
}

pub mod test_support {
pub use codex_core::test_support::*;
}

pub mod util {
pub use codex_core::util::*;
}

pub mod windows_sandbox {
pub use codex_core::windows_sandbox::*;
}
Expand Down
1 change: 1 addition & 0 deletions codex-rs/tui/prompt_for_init_command.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Generate a file named AGENTS.md that serves as a contributor guide for this repository.
Before writing, check whether AGENTS.md already exists in the current working directory. If it does, do not overwrite or modify it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 Badge Add integration coverage for /init behavior

Under AGENTS.md Test authoring guidance, agent-logic changes need integration coverage. This line changes /init model behavior by requiring an existing-AGENTS.md check before writing, but the diff only verifies that the TUI queues the prompt, so regressions in the actual agent behavior can still pass. Please add an integration test for existing-AGENTS.md handling.

Useful? React with 👍 / 👎.

Your goal is to produce a clear, concise, and well-structured document with descriptive headings and actionable explanations for each section.
Follow the outline below, but adapt as needed — add sections if relevant, and omit those that do not apply to this project.

Expand Down
6 changes: 5 additions & 1 deletion codex-rs/tui/src/chatwidget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ use crate::bottom_pane::TerminalTitleItem;
use crate::bottom_pane::TerminalTitleSetupView;
use crate::diff_model::FileChange;
use crate::git_action_directives::parse_assistant_markdown;
use crate::legacy_core::DEFAULT_AGENTS_MD_FILENAME;
use crate::legacy_core::config::Config;
use crate::legacy_core::config::Constrained;
use crate::legacy_core::config::ConstraintResult;
Expand Down Expand Up @@ -257,6 +256,11 @@ fn queued_message_edit_hint_binding(
.or_else(|| bindings.first().copied())
}

fn normalize_thread_name(name: &str) -> Option<String> {
let trimmed = name.trim();
(!trimmed.is_empty()).then(|| trimmed.to_string())
}

use crate::app_event::AppEvent;
use crate::app_event::ExitMode;
use crate::app_event::PermissionProfileSelection;
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/tui/src/chatwidget/interaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ impl ChatWidget {
/*initial_text*/ existing_name.unwrap_or_default().to_string(),
/*context_label*/ None,
Box::new(move |name: String| {
let Some(name) = crate::legacy_core::util::normalize_thread_name(&name) else {
let Some(name) = normalize_thread_name(&name) else {
tx.send(AppEvent::InsertHistoryCell(Box::new(
history_cell::new_error_event("Thread name cannot be empty.".to_string()),
)));
Expand Down
10 changes: 1 addition & 9 deletions codex-rs/tui/src/chatwidget/slash_dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,6 @@ impl ChatWidget {
.send(AppEvent::OpenDesktopThread { thread_id });
}
SlashCommand::Init => {
let init_target = self.config.cwd.join(DEFAULT_AGENTS_MD_FILENAME);
if init_target.exists() {
let message = format!(
"{DEFAULT_AGENTS_MD_FILENAME} already exists here. Skipping /init to avoid overwriting it."
);
self.add_info_message(message, /*hint*/ None);
return;
}
const INIT_PROMPT: &str = include_str!("../../prompt_for_init_command.md");
self.submit_user_message(INIT_PROMPT.to_string().into());
Comment thread
etraut-openai marked this conversation as resolved.
}
Expand Down Expand Up @@ -662,7 +654,7 @@ impl ChatWidget {
}
self.session_telemetry
.counter("codex.thread.rename", /*inc*/ 1, &[]);
let Some(name) = crate::legacy_core::util::normalize_thread_name(&args) else {
let Some(name) = normalize_thread_name(&args) else {
self.add_error_message("Thread name cannot be empty.".to_string());
return;
};
Expand Down
31 changes: 5 additions & 26 deletions codex-rs/tui/src/chatwidget/tests/slash_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,35 +565,14 @@ async fn ctrl_d_with_modal_open_does_not_quit() {
}

#[tokio::test]
async fn slash_init_skips_when_project_doc_exists() {
let (mut chat, mut rx, mut op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
let tempdir = tempdir().unwrap();
let existing_path = tempdir.path().join(DEFAULT_AGENTS_MD_FILENAME);
std::fs::write(&existing_path, "existing instructions").unwrap();
chat.config.cwd = tempdir.path().to_path_buf().abs();
async fn slash_init_does_not_depend_on_loaded_instruction_sources() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;
chat.instruction_source_paths = vec![chat.config.cwd.join("project-instructions.md")];

submit_composer_text(&mut chat, "/init");

match op_rx.try_recv() {
Err(TryRecvError::Empty) => {}
other => panic!("expected no Codex op to be sent, got {other:?}"),
}

let cells = drain_insert_history(&mut rx);
assert_eq!(cells.len(), 1, "expected one info message");
let rendered = lines_to_single_string(&cells[0]);
assert!(
rendered.contains(DEFAULT_AGENTS_MD_FILENAME),
"info message should mention the existing file: {rendered:?}"
);
assert!(
rendered.contains("Skipping /init"),
"info message should explain why /init was skipped: {rendered:?}"
);
assert_eq!(
std::fs::read_to_string(existing_path).unwrap(),
"existing instructions"
);
assert_eq!(chat.input_queue.queued_user_messages.len(), 1);
assert!(drain_insert_history(&mut rx).is_empty());
assert_eq!(recall_latest_after_clearing(&mut chat), "/init");
}

Expand Down
12 changes: 5 additions & 7 deletions codex-rs/tui/src/status/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,6 @@ fn title_case(s: &str) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::legacy_core::DEFAULT_AGENTS_MD_FILENAME;
use crate::legacy_core::LOCAL_AGENTS_MD_FILENAME;
use crate::legacy_core::config::ConfigBuilder;
use codex_utils_absolute_path::test_support::PathBufExt;
use pretty_assertions::assert_eq;
Expand Down Expand Up @@ -227,7 +225,7 @@ mod tests {
async fn compose_agents_summary_includes_global_agents_path() {
let codex_home = TempDir::new().expect("temp codex home");
let cwd = TempDir::new().expect("temp cwd");
let global_agents_path = codex_home.path().join(DEFAULT_AGENTS_MD_FILENAME);
let global_agents_path = codex_home.path().join("global.md");
let config = test_config(&codex_home, &cwd).await;

assert_eq!(
Expand All @@ -240,7 +238,7 @@ mod tests {
async fn compose_agents_summary_names_global_agents_override() {
let codex_home = TempDir::new().expect("temp codex home");
let cwd = TempDir::new().expect("temp cwd");
let override_path = codex_home.path().join(LOCAL_AGENTS_MD_FILENAME);
let override_path = codex_home.path().join("override.md");
let config = test_config(&codex_home, &cwd).await;

assert_eq!(
Expand All @@ -253,8 +251,8 @@ mod tests {
async fn compose_agents_summary_orders_global_before_project_agents() {
let codex_home = TempDir::new().expect("temp codex home");
let cwd = TempDir::new().expect("temp cwd");
let global_agents_path = codex_home.path().join(DEFAULT_AGENTS_MD_FILENAME);
let project_agents_path = cwd.path().join(DEFAULT_AGENTS_MD_FILENAME);
let global_agents_path = codex_home.path().join("global.md");
let project_agents_path = cwd.path().join("project.md");
let config = test_config(&codex_home, &cwd).await;

let summary = compose_agents_summary(
Expand All @@ -270,7 +268,7 @@ mod tests {
Some(format_directory_display(&global_agents_path, /*max_width*/ None).as_str())
);
let project_path = paths.next().expect("project agents path");
assert!(project_path.ends_with(DEFAULT_AGENTS_MD_FILENAME));
assert!(project_path.ends_with("project.md"));
assert_eq!(paths.next(), None);
}
}
Loading