mermaid_cli/cli/
commands.rs1use anyhow::Result;
2
3use crate::{
4 app::{get_config_dir, init_config, load_config},
5 models::ModelFactory,
6 ollama::{is_installed as is_ollama_installed, list_models_async as get_ollama_models},
7};
8
9use super::Commands;
10
11pub async fn handle_command(command: &Commands) -> Result<bool> {
15 match command {
16 Commands::Init => {
17 println!("Initializing Mermaid configuration...");
18 init_config()?;
19 println!("Configuration initialized successfully!");
20 Ok(true)
21 },
22 Commands::List => {
23 list_models().await?;
24 Ok(true)
25 },
26 Commands::Version => {
27 show_version();
28 Ok(true)
29 },
30 Commands::Status => {
31 show_status().await?;
32 Ok(true)
33 },
34 Commands::Add { name } => {
35 crate::mcp::add_server(name).await?;
36 Ok(true)
37 },
38 Commands::Remove { name } => {
39 crate::mcp::remove_server(name).await?;
40 Ok(true)
41 },
42 Commands::Mcp => {
43 show_mcp_servers();
44 Ok(true)
45 },
46 Commands::Chat => Ok(false), Commands::Run { .. } => Ok(false), }
49}
50
51pub async fn list_models() -> Result<()> {
53 let models = ModelFactory::list_all_models().await?;
54
55 if models.is_empty() {
56 println!("No models found across any backends");
57 } else {
58 println!("Available models:");
59 for model in models {
60 println!(" - {}", model);
61 }
62 }
63 Ok(())
64}
65
66pub fn show_version() {
68 println!("Mermaid v{}", env!("CARGO_PKG_VERSION"));
69 println!(" An open-source, model-agnostic AI pair programmer");
70}
71
72fn show_mcp_servers() {
74 let config = load_config().unwrap_or_default();
75
76 if config.mcp_servers.is_empty() {
77 println!("No MCP servers configured.\n");
78 println!("Add one with: mermaid add <name>");
79 println!("Examples:");
80 println!(" mermaid add context7 # Library documentation");
81 println!(" mermaid add github # GitHub API integration");
82 println!(" mermaid add playwright # Browser automation");
83 println!(" mermaid add memory # Persistent knowledge graph");
84 return;
85 }
86
87 println!("Configured MCP servers:\n");
88 for (name, server_cfg) in &config.mcp_servers {
89 let package = server_cfg
90 .args
91 .iter()
92 .find(|a| !a.starts_with('-'))
93 .unwrap_or(&server_cfg.command);
94 let env_keys: Vec<&String> = server_cfg.env.keys().collect();
95 let env_display = if env_keys.is_empty() {
96 String::new()
97 } else {
98 format!(" (env: {})", env_keys.iter().map(|k| k.as_str()).collect::<Vec<_>>().join(", "))
99 };
100 println!(" {} — {}{}", name, package, env_display);
101 }
102 println!("\nManage with: mermaid add <name> / mermaid remove <name>");
103}
104
105async fn show_status() -> Result<()> {
107 println!("Mermaid Status:");
108 println!();
109
110 let status_config = load_config().unwrap_or_default();
112 let factory = ModelFactory::from_config(&status_config);
113 let backends = factory.available_providers_pub().await;
114 if backends.is_empty() {
115 println!(" [WARNING] Backends: None available");
116 } else {
117 println!(" [OK] Backends: {}", backends.join(", "));
118 }
119
120 if is_ollama_installed() {
122 let models = get_ollama_models().await.unwrap_or_default();
123 if models.is_empty() {
124 println!(" [WARNING] Ollama: Installed (no models)");
125 } else {
126 println!(" [OK] Ollama: Running ({} models installed)", models.len());
127 for model in models.iter().take(3) {
128 println!(" - {}", model);
129 }
130 if models.len() > 3 {
131 println!(" ... and {} more", models.len() - 3);
132 }
133 }
134 } else {
135 println!(" [ERROR] Ollama: Not installed");
136 }
137
138 if let Ok(config_dir) = get_config_dir() {
140 let config_path = config_dir.join("config.toml");
141 if config_path.exists() {
142 println!(" [OK] Configuration: {}", config_path.display());
143 } else {
144 println!(" [WARNING] Configuration: Not found (using defaults)");
145 }
146 }
147
148 if let Ok(cfg) = load_config() {
150 if cfg.mcp_servers.is_empty() {
151 println!(" [INFO] MCP Servers: None configured (use 'mermaid add <name>')");
152 } else {
153 println!(
154 " [OK] MCP Servers: {} configured",
155 cfg.mcp_servers.len()
156 );
157 for (name, server_cfg) in &cfg.mcp_servers {
158 println!(
159 " - {} ({})",
160 name,
161 server_cfg.args.get(1).unwrap_or(&server_cfg.command)
162 );
163 }
164 }
165 }
166
167 println!("\n Environment:");
169 if std::env::var("OPENROUTER_API_KEY").is_ok() {
170 println!(" - OPENROUTER_API_KEY: Set");
171 }
172 if std::env::var("OLLAMA_API_KEY").is_ok() {
173 println!(" - OLLAMA_API_KEY: Set (for Ollama Cloud)");
174 }
175
176 println!();
177 Ok(())
178}