1pub fn error_message(message: &str) {
2 eprintln!();
3 eprintln!("============================================");
4 eprintln!(" ERROR");
5 eprintln!("============================================");
6 eprintln!();
7 eprintln!(" {}", message);
8 println!();
9}
10
11pub fn model_select_prompt(models: &[String]) -> String {
12 use inquire::Select;
13
14 let mut options: Vec<String> = vec!["[ Type Manual Model ID... ]".to_string()];
15 options.extend(models.iter().cloned());
16
17 let sel = Select::new("Select model (type to search):", options)
18 .with_page_size(20)
19 .prompt()
20 .expect("User cancelled");
21
22 sel
23}
24
25pub fn manual_model_prompt() -> String {
26 inquire::Text::new("Enter model ID manually (e.g. anthropic/claude-3-haiku):")
27 .prompt()
28 .expect("User cancelled")
29}
30
31pub fn save_confirmation() {
32 println!();
33 println!("Configuration saved!");
34 println!();
35}
36
37pub fn fetching_models_message() {
38 print!("Fetching model list from OpenRouter...");
39 std::io::Write::flush(&mut std::io::stdout()).ok();
40}
41
42pub fn models_loaded(count: usize) {
43 println!(" done! {} models found.", count);
44 println!("Type to search...");
45 println!();
46}
47
48pub fn rate_limited_message() {
49 error_message("Too many requests. Please wait a moment and try again.");
50}
51
52pub fn prompt_model_switch(model_name: &str) -> Result<bool, ()> {
53 println!();
54 println!("❌ Oops! API Error");
55 println!("The provider rejected the request for the '{}' model.", model_name);
56 println!();
57 inquire::Confirm::new("Do you want to change the AI model now?")
58 .with_default(true)
59 .prompt()
60 .map_err(|_| ())
61}
62
63pub fn confirm_large_diff(size: usize) -> Result<bool, ()> {
64 println!();
65 println!("⚠️ Diff too large ({} characters).", size);
66 println!();
67 println!("Committing with such a large diff is a Git anti-pattern:");
68 println!("- You may have staged files that shouldn't be there (lock files, dist/)");
69 println!("- Better to split into smaller commits per feature");
70 println!();
71 inquire::Confirm::new("Continue anyway?")
72 .with_default(false)
73 .prompt()
74 .map_err(|_| ())
75}
76
77pub fn print_unstaged_files(files: &[crate::preflight::UnstagedFile]) {
78 println!("⚠️ No files staged for commit.");
79 println!();
80 println!("Changed files that are not staged:");
81 for file in files {
82 println!(" {} {}", file.status, file.path);
83 }
84 println!();
85}
86
87pub fn prompt_git_add() -> bool {
88 inquire::Confirm::new("Do you want to run 'git add .' now?")
89 .with_default(true)
90 .prompt()
91 .unwrap_or(false)
92}