intelli_shell/process/
fix.rs1use std::time::Duration;
2
3use indicatif::{ProgressBar, ProgressStyle};
4
5use super::{Process, ProcessOutput};
6use crate::{
7 ai::CommandFix,
8 cli::CommandFixProcess,
9 config::Config,
10 errors::AppError,
11 format_error,
12 service::{AiFixProgress, IntelliShellService},
13 widgets::SPINNER_CHARS,
14};
15
16impl Process for CommandFixProcess {
17 async fn execute(self, config: Config, service: IntelliShellService) -> color_eyre::Result<ProcessOutput> {
18 let pb = ProgressBar::new_spinner();
20 pb.set_style(
21 ProgressStyle::with_template("{spinner:.blue} {wide_msg}")
22 .unwrap()
23 .tick_strings(&SPINNER_CHARS),
24 );
25
26 let on_progress = |progress: AiFixProgress| match progress {
28 AiFixProgress::Thinking => {
30 eprintln!("\n────────────────────────────────────────────────────────────────────────────────\n");
32 pb.enable_steady_tick(Duration::from_millis(100));
34 pb.set_message("Thinking ...");
35 }
36 };
37
38 let res = service
40 .fix_command(&self.command, self.history.as_deref(), on_progress)
41 .await;
42
43 pb.finish_and_clear();
45
46 match res {
48 Ok(None) => Ok(ProcessOutput::success()),
49 Ok(Some(CommandFix {
50 summary,
51 diagnosis,
52 proposal,
53 fixed_command,
54 })) => {
55 let mut msg = format!(
56 r"🧠 IntelliShell Diagnosis
57
58❌ {summary}
59{}
60
61✨ Fix
62{}
63",
64 config.theme.secondary.apply(diagnosis),
65 config.theme.secondary.apply(proposal)
66 );
67 let mut out = ProcessOutput::success();
68 if !fixed_command.trim().is_empty() {
69 msg += "\nSuggested Command 👉";
70 out = out.stdout(&fixed_command).fileout(fixed_command);
71 }
72 Ok(out.stderr(msg))
73 }
74 Err(AppError::UserFacing(err)) => Ok(ProcessOutput::fail().stderr(format_error!(config.theme, "{err}"))),
75 Err(AppError::Unexpected(report)) => Err(report),
76 }
77 }
78}