Add a startup deprecation warning for custom prompts (#15076)

## Summary
- detect custom prompts in `$CODEX_HOME/prompts` during TUI startup
- show a deprecation notice only when prompts are present, with guidance
to use `$skill-creator`
- add TUI tests and snapshot coverage for present, missing, and empty
prompts directories

## Testing
- Manually tested
This commit is contained in:
Eric Traut 2026-03-18 15:21:30 -06:00 committed by GitHub
parent 5cada46ddf
commit e5de13644d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 90 additions and 0 deletions

View file

@ -285,6 +285,32 @@ fn emit_missing_system_bwrap_warning(app_event_tx: &AppEventSender) {
)));
}
async fn emit_custom_prompt_deprecation_notice(app_event_tx: &AppEventSender, codex_home: &Path) {
let prompts_dir = codex_home.join("prompts");
let prompt_count = codex_core::custom_prompts::discover_prompts_in(&prompts_dir)
.await
.len();
if prompt_count == 0 {
return;
}
let prompt_label = if prompt_count == 1 {
"prompt"
} else {
"prompts"
};
let details = format!(
"Detected {prompt_count} custom {prompt_label} in `$CODEX_HOME/prompts`. Use the `$skill-creator` skill to convert each custom prompt into a skill."
);
app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(
history_cell::new_deprecation_notice(
"Custom prompts are deprecated and will soon be removed.".to_string(),
Some(details),
),
)));
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct SessionSummary {
usage_line: String,
@ -1974,6 +2000,7 @@ impl App {
let app_event_tx = AppEventSender::new(app_event_tx);
emit_project_config_warnings(&app_event_tx, &config);
emit_missing_system_bwrap_warning(&app_event_tx);
emit_custom_prompt_deprecation_notice(&app_event_tx, &config.codex_home).await;
tui.set_notification_method(config.tui_notification_method);
let harness_overrides =
@ -4324,6 +4351,62 @@ mod tests {
);
}
fn render_history_cell(cell: &dyn HistoryCell, width: u16) -> String {
cell.display_lines(width)
.into_iter()
.map(|line| line.to_string())
.collect::<Vec<_>>()
.join("\n")
}
#[tokio::test]
async fn startup_custom_prompt_deprecation_notice_emits_when_prompts_exist() -> Result<()> {
let codex_home = tempdir()?;
let prompts_dir = codex_home.path().join("prompts");
std::fs::create_dir_all(&prompts_dir)?;
std::fs::write(prompts_dir.join("review.md"), "# Review\n")?;
let (tx_raw, mut rx) = unbounded_channel();
let app_event_tx = AppEventSender::new(tx_raw);
emit_custom_prompt_deprecation_notice(&app_event_tx, codex_home.path()).await;
let cell = match rx.try_recv() {
Ok(AppEvent::InsertHistoryCell(cell)) => cell,
other => panic!("expected InsertHistoryCell event, got {other:?}"),
};
let rendered = render_history_cell(cell.as_ref(), 120);
assert_snapshot!("startup_custom_prompt_deprecation_notice", rendered);
assert!(rx.try_recv().is_err(), "expected only one startup notice");
Ok(())
}
#[tokio::test]
async fn startup_custom_prompt_deprecation_notice_skips_missing_prompts_dir() -> Result<()> {
let codex_home = tempdir()?;
let (tx_raw, mut rx) = unbounded_channel();
let app_event_tx = AppEventSender::new(tx_raw);
emit_custom_prompt_deprecation_notice(&app_event_tx, codex_home.path()).await;
assert!(rx.try_recv().is_err(), "expected no startup notice");
Ok(())
}
#[tokio::test]
async fn startup_custom_prompt_deprecation_notice_skips_empty_prompts_dir() -> Result<()> {
let codex_home = tempdir()?;
std::fs::create_dir_all(codex_home.path().join("prompts"))?;
let (tx_raw, mut rx) = unbounded_channel();
let app_event_tx = AppEventSender::new(tx_raw);
emit_custom_prompt_deprecation_notice(&app_event_tx, codex_home.path()).await;
assert!(rx.try_recv().is_err(), "expected no startup notice");
Ok(())
}
#[test]
fn startup_waiting_gate_not_applied_for_resume_or_fork_session_selection() {
let wait_for_resume = App::should_wait_for_initial_session(&SessionSelection::Resume(

View file

@ -0,0 +1,7 @@
---
source: tui/src/app.rs
expression: rendered
---
⚠ Custom prompts are deprecated and will soon be removed.
Detected 1 custom prompt in `$CODEX_HOME/prompts`. Use the `$skill-creator` skill to convert each custom prompt into
a skill.