fix: skip /init when AGENTS.md already exists (#5242)
This change aborts /init if an AGENTS.md already exists to avoid plainly overwriting it. <img width="581" height="24" alt="Screenshot 2025-10-15 at 9 43 07 PM" src="https://github.com/user-attachments/assets/f8be51f7-dcb1-4f90-8062-18d4e852300a" />
This commit is contained in:
committed by
GitHub
parent
c146585cdb
commit
86ba270926
@@ -7,6 +7,7 @@ use codex_core::config::Config;
|
||||
use codex_core::config_types::Notifications;
|
||||
use codex_core::git_info::current_branch_name;
|
||||
use codex_core::git_info::local_git_branches;
|
||||
use codex_core::project_doc::DEFAULT_PROJECT_DOC_FILENAME;
|
||||
use codex_core::protocol::AgentMessageDeltaEvent;
|
||||
use codex_core::protocol::AgentMessageEvent;
|
||||
use codex_core::protocol::AgentReasoningDeltaEvent;
|
||||
@@ -1130,6 +1131,14 @@ impl ChatWidget {
|
||||
self.app_event_tx.send(AppEvent::NewSession);
|
||||
}
|
||||
SlashCommand::Init => {
|
||||
let init_target = self.config.cwd.join(DEFAULT_PROJECT_DOC_FILENAME);
|
||||
if init_target.exists() {
|
||||
let message = format!(
|
||||
"{DEFAULT_PROJECT_DOC_FILENAME} already exists here. Skipping /init to avoid overwriting it."
|
||||
);
|
||||
self.add_info_message(message, None);
|
||||
return;
|
||||
}
|
||||
const INIT_PROMPT: &str = include_str!("../prompt_for_init_command.md");
|
||||
self.submit_text_message(INIT_PROMPT.to_string());
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use tempfile::NamedTempFile;
|
||||
use tempfile::tempdir;
|
||||
use tokio::sync::mpsc::error::TryRecvError;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
|
||||
@@ -769,6 +770,38 @@ fn review_popup_custom_prompt_action_sends_event() {
|
||||
assert!(found, "expected OpenReviewCustomPrompt event to be sent");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slash_init_skips_when_project_doc_exists() {
|
||||
let (mut chat, mut rx, mut op_rx) = make_chatwidget_manual();
|
||||
let tempdir = tempdir().unwrap();
|
||||
let existing_path = tempdir.path().join(DEFAULT_PROJECT_DOC_FILENAME);
|
||||
std::fs::write(&existing_path, "existing instructions").unwrap();
|
||||
chat.config.cwd = tempdir.path().to_path_buf();
|
||||
|
||||
chat.dispatch_command(SlashCommand::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_PROJECT_DOC_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"
|
||||
);
|
||||
}
|
||||
|
||||
/// The commit picker shows only commit subjects (no timestamps).
|
||||
#[test]
|
||||
fn review_commit_picker_shows_subjects_without_timestamps() {
|
||||
|
||||
Reference in New Issue
Block a user