1use crate::config::Config;
2
3pub mod claude_compat;
4pub mod enterprise;
5pub mod migration;
6pub mod setup_agent;
7pub mod wizard;
8pub mod zero_question;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
13pub enum UserMode {
14 Beginner,
15 Expert,
16}
17
18impl Default for UserMode {
19 fn default() -> Self {
20 UserMode::Beginner
21 }
22}
23
24pub struct Onboarding {
27 pub mode: UserMode,
28 pub lessons: Vec<Lesson>,
29}
30
31#[derive(Debug, Clone)]
32pub struct Lesson {
33 pub id: String,
34 pub title: String,
35 pub description: String,
36 pub command: String,
37 pub expected_output: String,
38}
39
40impl Default for Onboarding {
41 fn default() -> Self {
42 Self {
43 mode: UserMode::Beginner,
44 lessons: default_lessons(),
45 }
46 }
47}
48
49fn default_lessons() -> Vec<Lesson> {
50 vec![
51 Lesson {
52 id: "run".into(),
53 title: "Your First Run".into(),
54 description: "Execute a simple task and see Sparrow in action.".into(),
55 command: r#"run "Create a file called hello.txt with 'Hello Sparrow' inside""#.into(),
56 expected_output: "file created".into(),
57 },
58 Lesson {
59 id: "swarm".into(),
60 title: "The Swarm".into(),
61 description: "See Planner → Coder → Verifier work together.".into(),
62 command: r#"swarm "Add a comment to hello.txt explaining what it contains""#.into(),
63 expected_output: "Planner → Coder → Verifier".into(),
64 },
65 Lesson {
66 id: "autonomy".into(),
67 title: "Autonomy Dial".into(),
68 description: "Understand how Sparrow keeps you safe with graduated trust.".into(),
69 command: r#"run "Read hello.txt" --autonomy supervised"#.into(),
70 expected_output: "autonomy gate".into(),
71 },
72 Lesson {
73 id: "skills".into(),
74 title: "Self-Improving Skills".into(),
75 description: "Sparrow learns from experience and gets better over time.".into(),
76 command: "skills list".into(),
77 expected_output: "skill library".into(),
78 },
79 Lesson {
80 id: "gateway".into(),
81 title: "Everywhere You Are".into(),
82 description: "Continue your session from Telegram, Discord, or Slack.".into(),
83 command: "gateway status".into(),
84 expected_output: "messaging surfaces".into(),
85 },
86 ]
87}
88
89impl Onboarding {
90 pub fn run_interactive(&self) -> anyhow::Result<()> {
92 use std::io::{self, BufRead};
93
94 println!("═══ SPARROW LEARN ═══");
95 println!("5 interactive lessons to master Sparrow.\n");
96
97 for (i, lesson) in self.lessons.iter().enumerate() {
98 println!(
99 "── Lesson {}/{} : {} ──",
100 i + 1,
101 self.lessons.len(),
102 lesson.title
103 );
104 println!("{}", lesson.description);
105 println!("\n sparrow {}", lesson.command);
106 println!("\nPress Enter to continue...");
107 io::stdin().lock().lines().next();
108 println!();
109 }
110
111 println!("═══ All lessons complete! ═══");
112 println!("Try: sparrow run 'your own task'");
113 println!("Help: sparrow --help\n");
114 Ok(())
115 }
116
117 pub fn detect_mode(config: &Config) -> UserMode {
119 if config.defaults.autonomy == crate::event::AutonomyLevel::Supervised {
120 UserMode::Beginner
121 } else {
122 UserMode::Expert
123 }
124 }
125
126 pub fn friendly_error(error_type: &str, context: &str) -> String {
128 match error_type {
129 "no_provider" => format!(
130 "No API key configured.\n→ Run: sparrow auth add <provider>\n→ Or: sparrow setup\n→ Or set env: {}_API_KEY",
131 context.to_uppercase()
132 ),
133 "no_model" => format!(
134 "Model '{}' not available.\n→ List models: sparrow model --list\n→ Add one: edit ~/.config/sparrow/config.toml",
135 context
136 ),
137 "budget" => format!(
138 "Budget limit reached (${}).\n→ Increase: sparrow run --budget <amount>\n→ Or edit: config.toml [budget]",
139 context
140 ),
141 "sandbox" => format!(
142 "Operation blocked by sandbox: {}\n→ Check: sparrow doctor\n→ Change: config.toml [defaults] sandbox",
143 context
144 ),
145 "permission" => format!(
146 "Permission denied: {}\n→ In Supervised mode, mutating actions require approval.\n→ Use: --autonomy trusted\n→ Or: sparrow config --edit",
147 context
148 ),
149 _ => format!(
150 "Error: {}\n→ Run diagnostics: sparrow doctor\n→ Get help: sparrow --help\n→ Docs: https://github.com/ucav/Sparrow",
151 context
152 ),
153 }
154 }
155
156 pub fn examples_gallery() -> Vec<(&'static str, &'static str)> {
158 vec![
159 ("run \"fix the failing auth test\"", "Fix a bug"),
160 ("run \"add a /health endpoint to the API\"", "Add a feature"),
161 ("run \"explain this codebase\" --local", "Analyze offline"),
162 ("swarm \"refactor the rate limiter\"", "Swarm review"),
163 (
164 "schedule \"run tests\" --cron \"0 */6 * * *\"",
165 "Schedule checks",
166 ),
167 ("skills list", "See learned skills"),
168 ("checkpoint list", "View safety net"),
169 ("replay <id>", "Replay any run"),
170 ]
171 }
172}