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