1use crate::llm::client::LLMRequest;
2use crate::llm::{LLMMessage, PromptBuilder, create_client, parse_suggest};
3use crate::system::{get_system_info, load_config};
4use anyhow::Result;
5use arboard::Clipboard;
6use cliclack::{select, spinner};
7
8pub async fn handle_suggest_command(request: &str) -> Result<()> {
9 let config = load_config()?;
10 let client = create_client(&config.llm)?;
11 let system_info = get_system_info();
12 let builder = PromptBuilder::new(system_info.clone());
13
14 let sp = spinner();
15 sp.start("[SUGGEST MODE] Generating commands...");
16
17 let llm_request = LLMRequest {
18 system: builder.build_suggest(),
19 messages: vec![LLMMessage::user(request)],
20 };
21
22 let response = client.generate_with_parser(llm_request, parse_suggest).await?;
23
24 sp.stop("");
25
26 if response.suggestions.is_empty() {
28 println!("\n⚠️ No commands to suggest.\n");
29 return Ok(());
30 }
31
32 let items: Vec<_> = response
34 .suggestions
35 .iter()
36 .map(|s| (s, s.cmd.as_str(), s.description.as_str()))
37 .collect();
38
39 let selected = select("Select a command").items(&items).interact()?;
40
41 copy_to_clipboard(&selected.cmd)?;
43
44 cliclack::outro("✅ Command copied to clipboard, Ctrl+V to paste it!")?;
45
46 Ok(())
47}
48
49fn copy_to_clipboard(text: &str) -> Result<()> {
51 let mut clipboard =
52 Clipboard::new().map_err(|e| anyhow::anyhow!("Failed to initialize clipboard: {}", e))?;
53
54 clipboard
55 .set_text(text)
56 .map_err(|e| anyhow::anyhow!("Failed to copy to clipboard: {}", e))?;
57
58 Ok(())
59}