diff --git a/crates/g3-cli/src/completion.rs b/crates/g3-cli/src/completion.rs index ac46847..722d47e 100644 --- a/crates/g3-cli/src/completion.rs +++ b/crates/g3-cli/src/completion.rs @@ -336,6 +336,13 @@ impl Highlighter for G3Helper { prompt: &'p str, _default: bool, ) -> std::borrow::Cow<'b, str> { + // Plan mode prompt: colorize "[plan mode]" in magenta + if prompt.contains("[plan mode]") { + return std::borrow::Cow::Owned( + prompt.replace("[plan mode]", "\x1b[35m[plan mode]\x1b[0m") + ); + } + // If prompt contains " | ", colorize from "|" to ">" in blue if let Some(pipe_pos) = prompt.find(" | ") { if let Some(gt_pos) = prompt.rfind('>') { @@ -550,7 +557,29 @@ mod tests { let (_, completions) = helper.complete(line, pos, &ctx).unwrap(); assert_eq!(completions.len(), 0, "Non-matching prefix should return empty"); } - + + #[test] + fn test_highlight_prompt_plan_mode() { + let helper = G3Helper::new(); + + // Plan mode prompt should be colorized with magenta + let prompt = " [plan mode] >> "; + let highlighted = helper.highlight_prompt(prompt, false); + assert!(highlighted.contains("\x1b[35m"), "Plan mode should use magenta color"); + assert!(highlighted.contains("[plan mode]"), "Should contain [plan mode] text"); + assert!(highlighted.contains("\x1b[0m"), "Should reset color"); + } + + #[test] + fn test_highlight_prompt_normal_unchanged() { + let helper = G3Helper::new(); + + // Normal prompt without project should be unchanged + let prompt = "g3> "; + let highlighted = helper.highlight_prompt(prompt, false); + assert_eq!(highlighted.as_ref(), prompt, "Normal prompt should be unchanged"); + } + #[test] fn test_resume_completion_graceful_no_panic() { let helper = G3Helper::new(); diff --git a/crates/g3-cli/src/interactive.rs b/crates/g3-cli/src/interactive.rs index 3fa904a..4d9c2bd 100644 --- a/crates/g3-cli/src/interactive.rs +++ b/crates/g3-cli/src/interactive.rs @@ -23,7 +23,7 @@ use crate::task_execution::execute_task_with_retry; use crate::utils::display_context_progress; /// Plan mode prompt string. -const PLAN_MODE_PROMPT: &str = " >> "; +const PLAN_MODE_PROMPT: &str = " [plan mode] >> "; /// Build the interactive prompt string. /// @@ -482,16 +482,16 @@ mod tests { #[test] fn test_build_prompt_plan_mode() { let prompt = build_prompt(false, true, None, &None); - assert_eq!(prompt, " >> "); + assert_eq!(prompt, " [plan mode] >> "); // Plan mode takes precedence over agent name let prompt = build_prompt(false, true, Some("butler"), &None); - assert_eq!(prompt, " >> "); + assert_eq!(prompt, " [plan mode] >> "); // Plan mode takes precedence over project let project = Some(create_test_project("myapp")); let prompt = build_prompt(false, true, None, &project); - assert_eq!(prompt, " >> "); + assert_eq!(prompt, " [plan mode] >> "); } #[test]