foundry_mcp/cli/commands/
list_projects.rs1use crate::cli::args::ListProjectsArgs;
4use crate::core::project;
5use crate::types::responses::{FoundryResponse, ListProjectsResponse, ProjectInfo};
6use crate::utils::formatting::format_count;
7use crate::utils::response::build_success_response;
8use anyhow::{Context, Result};
9
10pub async fn execute(_args: ListProjectsArgs) -> Result<FoundryResponse<ListProjectsResponse>> {
11 let project_metadata_list =
13 project::list_projects().context("Failed to list projects from foundry directory")?;
14
15 let projects: Vec<ProjectInfo> = project_metadata_list
17 .into_iter()
18 .map(|metadata| {
19 let project_path = project::get_project_path(&metadata.name)
20 .map(|p| p.to_string_lossy().to_string())
21 .unwrap_or_else(|_| "Unknown".to_string());
22
23 ProjectInfo {
24 name: metadata.name,
25 created_at: metadata.created_at,
26 spec_count: metadata.spec_count,
27 path: project_path,
28 }
29 })
30 .collect();
31
32 let response_data = ListProjectsResponse { projects };
33
34 let (next_steps, workflow_hints) = if response_data.projects.is_empty() {
36 (
37 vec![
38 "No projects found in foundry directory - ready for project creation".to_string(),
39 "You can create your first project with: foundry mcp create-project".to_string(),
40 ],
41 vec![
42 "You can use 'foundry mcp get-foundry-help workflows' for getting started guidance"
43 .to_string(),
44 "Projects are stored in ~/.foundry/ directory for easy access".to_string(),
45 ],
46 )
47 } else {
48 let project_count = response_data.projects.len();
49 (
50 vec![
51 format_count(project_count, "project", "projects"),
52 "You can use 'foundry mcp create-spec <project_name> <feature_name>' to add specifications"
53 .to_string(),
54 "You can use 'foundry mcp load-spec <project_name>' to view existing specifications"
55 .to_string(),
56 ],
57 vec![
58 "Each project can contain multiple timestamped specifications for organized development".to_string(),
59 "You can use 'foundry mcp analyze-project' to add project analysis to existing codebases"
60 .to_string(),
61 ],
62 )
63 };
64
65 Ok(build_success_response(
66 response_data,
67 next_steps,
68 workflow_hints,
69 ))
70}