use crate::storage::{Storage, DeveloperProfile};
use anyhow::Result;
use colored::Colorize;
pub struct QueryCommand;
impl QueryCommand {
pub fn new() -> Self {
Self
}
pub async fn run(&self, query: &str) -> Result<()> {
let storage = Storage::new()?;
let profile = storage.load_profile().await?;
let _knowledge = storage.load_knowledge().await?;
println!("{}", format!("🔍 Query: {}", query).bold().cyan());
println!();
let query_lower = query.to_lowercase();
if query_lower.contains("language") || query_lower.contains("tech") {
self.show_languages(&profile);
}
if query_lower.contains("project") || query_lower.contains("repo") {
self.show_projects(&profile);
}
if query_lower.contains("recent") || query_lower.contains("work") || query_lower.contains("activity") {
self.show_recent_activity(&profile);
}
if query_lower.contains("pattern") || query_lower.contains("style") {
self.show_patterns(&profile);
}
if query_lower.contains("skill") || query_lower.contains("experience") {
self.show_skills(&profile);
}
if query_lower == "query" || query_lower.split_whitespace().count() < 2 {
self.show_general_summary(&profile);
}
Ok(())
}
fn show_languages(&self, profile: &DeveloperProfile) {
println!("{}", "💻 Programming Languages".bold().underline());
if profile.github.primary_languages.is_empty() {
println!(" No language data available yet. Run 'i-self setup' first.");
return;
}
for (lang, percentage) in &profile.github.primary_languages {
let bar = self.create_bar(*percentage, 20);
println!(" {:15} {:6.1}% {}", lang, percentage, bar);
}
println!();
}
fn show_projects(&self, profile: &DeveloperProfile) {
println!("{}", "📁 Recent Projects".bold().underline());
if profile.github.most_active_repos.is_empty() {
println!(" No project data available yet. Run 'i-self setup' first.");
return;
}
for repo in &profile.github.most_active_repos {
let lang = repo.language.as_deref().unwrap_or("Unknown");
println!(" • {:25} ({}) - {} commits in last 30 days",
repo.name.cyan(),
lang.dimmed(),
repo.commits_30d
);
}
println!();
}
fn show_recent_activity(&self, profile: &DeveloperProfile) {
println!("{}", "📊 Recent Activity (30 days)".bold().underline());
println!(" Total commits: {}", profile.github.total_contributions_30d);
println!(" Active repositories: {}", profile.github.most_active_repos.len());
println!(" Recent pull requests: {}", profile.github.recent_prs.len());
if !profile.github.recent_prs.is_empty() {
println!("\n Recent PRs:");
for pr in profile.github.recent_prs.iter().take(5) {
let state_icon = match pr.state.as_str() {
"open" => "🟢",
"merged" => "🟣",
"closed" => "🔴",
_ => "⚪",
};
println!(" {} #{}: {}", state_icon, pr.number, pr.title);
}
}
println!();
}
fn show_patterns(&self, profile: &DeveloperProfile) {
println!("{}", "🎨 Coding Patterns".bold().underline());
if profile.coding_patterns.preferred_languages.is_empty() {
println!(" No pattern data available yet.");
return;
}
println!(" Preferred languages: {}",
profile.coding_patterns.preferred_languages.join(", "));
if let Some(style) = &profile.coding_patterns.code_style.indentation {
println!(" Indentation: {}", style);
}
if let Some(style) = &profile.coding_patterns.commit_patterns.message_style {
println!(" Commit style: {}", style);
}
println!(" Common libraries:");
for (lang, libs) in &profile.coding_patterns.common_libraries {
println!(" {}: {}", lang, libs.join(", "));
}
println!();
}
fn show_skills(&self, profile: &DeveloperProfile) {
println!("{}", "🎯 Skills Profile".bold().underline());
if profile.skills.languages.is_empty() {
println!(" No skills data available yet.");
return;
}
for skill in &profile.skills.languages {
let level = match skill.proficiency {
crate::storage::profile::Proficiency::Beginner => "Beginner",
crate::storage::profile::Proficiency::Intermediate => "Intermediate",
crate::storage::profile::Proficiency::Advanced => "Advanced",
crate::storage::profile::Proficiency::Expert => "Expert",
};
let bar = self.create_bar(skill.proficiency_score * 100.0, 15);
println!(" {:15} {:12} {} ({} years est.)",
skill.name,
level.dimmed(),
bar,
skill.years_experience
);
}
println!();
}
fn show_general_summary(&self, profile: &DeveloperProfile) {
println!("{}", "👤 Developer Profile Summary".bold().underline());
if let Some(name) = &profile.identity.name {
println!(" Name: {}", name);
}
if let Some(github) = &profile.identity.github_username {
println!(" GitHub: @{}", github.cyan());
}
println!(" Repositories: {}", profile.github.total_repositories);
println!(" Last updated: {}", profile.last_updated.format("%Y-%m-%d %H:%M"));
println!("\nTry asking about:");
println!(" • 'What languages do I use?'");
println!(" • 'Show my recent projects'");
println!(" • 'What are my coding patterns?'");
println!(" • 'What are my skills?'");
}
fn create_bar(&self, percentage: f64, width: usize) -> String {
let filled = ((percentage / 100.0) * width as f64) as usize;
let empty = width - filled;
let filled_str = "█".repeat(filled);
let empty_str = "░".repeat(empty);
format!("[{}{}]", filled_str.green(), empty_str)
}
}