11use anyhow:: Result ;
2+ use atty:: Stream ;
23use clap:: { Parser , Subcommand } ;
34use codegraph_core:: GraphStore ;
45use codegraph_mcp:: { IndexerConfig , ProcessManager , ProjectIndexer } ;
56use colored:: * ;
7+ use indicatif:: { MultiProgress , ProgressBar , ProgressStyle } ;
68use rmcp:: { transport:: stdio, ServiceExt } ;
79use std:: path:: PathBuf ;
810use tracing:: info;
9- use tracing_subscriber;
11+ use tracing_indicatif:: IndicatifLayer ;
12+ use tracing_subscriber:: { layer:: SubscriberExt , util:: SubscriberInitExt , Registry } ;
1013
1114#[ derive( Parser ) ]
1215#[ command(
@@ -432,15 +435,10 @@ enum StatsFormat {
432435async fn main ( ) -> Result < ( ) > {
433436 let cli = Cli :: parse ( ) ;
434437
435- // Initialize logging
436438 let log_level = if cli. verbose { "debug" } else { "info" } ;
437- tracing_subscriber:: fmt ( )
438- . with_env_filter ( std:: env:: var ( "RUST_LOG" ) . unwrap_or_else ( |_| log_level. to_string ( ) ) )
439- . init ( ) ;
440439
441440 // Load configuration if provided
442441 if let Some ( config_path) = & cli. config {
443- info ! ( "Loading configuration from: {:?}" , config_path) ;
444442 // TODO: Load and merge configuration
445443 }
446444
@@ -705,33 +703,34 @@ async fn handle_start(
705703
706704 match transport {
707705 TransportType :: Stdio { buffer_size : _ } => {
708- // For STDIO transport, reconfigure tracing to use stderr only
709- tracing_subscriber:: fmt ( )
710- . with_writer ( std:: io:: stderr)
711- . with_env_filter ( tracing_subscriber:: EnvFilter :: from_default_env ( ) )
712- . try_init ( )
713- . ok ( ) ; // Ignore if already initialized
714-
715- eprintln ! (
716- "{}" ,
717- "Starting CodeGraph MCP Server with 100% Official SDK..."
718- . green( )
719- . bold( )
720- ) ;
706+ if atty:: is ( Stream :: Stderr ) {
707+ eprintln ! (
708+ "{}" ,
709+ "Starting CodeGraph MCP Server with 100% Official SDK..."
710+ . green( )
711+ . bold( )
712+ ) ;
713+ }
721714
722715 // Create and initialize the revolutionary CodeGraph server with official SDK
723716 let mut server = codegraph_mcp:: official_server:: CodeGraphMCPServer :: new ( ) ;
724717 server. initialize_qwen ( ) . await ;
725718
726- eprintln ! ( "✅ Revolutionary CodeGraph MCP server ready with 100% protocol compliance" ) ;
719+ if atty:: is ( Stream :: Stderr ) {
720+ eprintln ! ( "✅ Revolutionary CodeGraph MCP server ready with 100% protocol compliance" ) ;
721+ }
727722
728723 // Use official rmcp STDIO transport for perfect compliance
729724 let service = server. serve ( rmcp:: transport:: stdio ( ) ) . await . map_err ( |e| {
730- eprintln ! ( "❌ Failed to start official MCP server: {}" , e) ;
725+ if atty:: is ( Stream :: Stderr ) {
726+ eprintln ! ( "❌ Failed to start official MCP server: {}" , e) ;
727+ }
731728 anyhow:: anyhow!( "MCP server startup failed: {}" , e)
732729 } ) ?;
733730
734- eprintln ! ( "🚀 Official MCP server started with revolutionary capabilities" ) ;
731+ if atty:: is ( Stream :: Stderr ) {
732+ eprintln ! ( "🚀 Official MCP server started with revolutionary capabilities" ) ;
733+ }
735734
736735 // Wait for the server to complete
737736 service
@@ -790,16 +789,23 @@ async fn handle_start(
790789}
791790
792791async fn handle_stop ( pid_file : Option < PathBuf > , force : bool ) -> Result < ( ) > {
793- println ! ( "{}" , "Stopping CodeGraph MCP Server..." . yellow( ) . bold( ) ) ;
792+ if atty:: is ( Stream :: Stdout ) {
793+ println ! ( "{}" , "Stopping CodeGraph MCP Server..." . yellow( ) . bold( ) ) ;
794+ }
794795
795796 let manager = ProcessManager :: new ( ) ;
796797
797798 if force {
798- println ! ( "Force stopping server" ) ;
799+ if atty:: is ( Stream :: Stdout ) {
800+ println ! ( "Force stopping server" ) ;
801+ }
799802 }
800803
801804 manager. stop_server ( pid_file, force) . await ?;
802- println ! ( "✓ Server stopped" ) ;
805+
806+ if atty:: is ( Stream :: Stdout ) {
807+ println ! ( "✓ Server stopped" ) ;
808+ }
803809
804810 Ok ( ( ) )
805811}
@@ -856,45 +862,33 @@ async fn handle_index(
856862 device : Option < String > ,
857863 max_seq_len : usize ,
858864) -> Result < ( ) > {
859- println ! ( "{}" , format!( "Indexing project: {:?}" , path) . cyan( ) . bold( ) ) ;
865+ let indicatif_layer = IndicatifLayer :: new ( ) ;
866+ let multi_progress = indicatif_layer. get_progress_bar ( ) ;
860867
861- if let Some ( langs ) = & languages {
862- println ! ( "Languages: {}" , langs . join ( ", " ) ) ;
863- }
868+ let subscriber = Registry :: default ( )
869+ . with ( tracing_subscriber :: filter :: EnvFilter :: from_default_env ( ) )
870+ . with ( indicatif_layer ) ;
864871
865- if recursive {
866- println ! ( "Recursive indexing enabled" ) ;
867- }
872+ tracing:: subscriber:: set_global_default ( subscriber) . ok ( ) ;
873+
874+ let h_style = ProgressStyle :: with_template ( "{spinner:.blue} {msg}" )
875+ . unwrap ( )
876+ . tick_chars ( "⠁⠂⠄⡀⢀⠠⠐⠈ " ) ;
877+
878+ let header_pb = multi_progress. add ( ProgressBar :: new ( 1 ) ) ;
879+ header_pb. set_style ( h_style) ;
880+ header_pb. set_message ( format ! ( "Indexing project: {}" , path. to_string_lossy( ) ) ) ;
868881
869882 // Memory-aware optimization for high-memory systems
870883 let available_memory_gb = estimate_available_memory_gb ( ) ;
871884 let ( optimized_batch_size, optimized_workers) =
872885 optimize_for_memory ( available_memory_gb, batch_size, workers) ;
873886
874- println ! ( "Workers: {} → {} (optimized)" , workers, optimized_workers) ;
875- println ! (
876- "Batch size: {} → {} (optimized)" ,
877- batch_size, optimized_batch_size
878- ) ;
879-
880887 if available_memory_gb >= 64 {
881- println ! (
882- "{}" ,
883- format!(
884- "🚀 High-memory system detected ({}GB) - performance optimized!" ,
885- available_memory_gb
886- )
887- . green( )
888- . bold( )
889- ) ;
890- println ! (
891- "{}" ,
892- format!(
893- "💾 Memory capacity: ~{} embeddings per batch" ,
894- optimized_batch_size
895- )
896- . cyan( )
897- ) ;
888+ multi_progress. println ( format ! (
889+ "🚀 High-memory system detected ({}GB) - performance optimized!" ,
890+ available_memory_gb
891+ ) ) ?;
898892 }
899893
900894 // Configure indexer
@@ -914,10 +908,15 @@ async fn handle_index(
914908 } ;
915909
916910 // Create indexer
917- let mut indexer = ProjectIndexer :: new ( config) . await ?;
911+ let mut indexer = ProjectIndexer :: new ( config, multi_progress. clone ( ) ) . await ?;
912+
913+ let start_time = std:: time:: Instant :: now ( ) ;
918914
919915 // Perform indexing
920916 let stats = indexer. index_project ( & path) . await ?;
917+ let elapsed = start_time. elapsed ( ) ;
918+
919+ header_pb. finish_with_message ( "✔ Indexing complete" . to_string ( ) ) ;
921920
922921 println ! ( ) ;
923922 println ! ( "{}" , "🎉 INDEXING COMPLETE!" . green( ) . bold( ) ) ;
@@ -927,37 +926,35 @@ async fn handle_index(
927926 println ! ( "{}" , "📊 Performance Summary" . cyan( ) . bold( ) ) ;
928927 println ! ( "┌─────────────────────────────────────────────────┐" ) ;
929928 println ! (
930- "│ 📄 Files: {} indexed │" ,
931- format!( "{:>6}" , stats. files) . yellow( )
932- ) ;
933- println ! (
934- "│ 📝 Lines: {} processed │" ,
935- format!( "{:>6}" , stats. lines) . yellow( )
936- ) ;
937- println ! (
938- "│ 🔧 Functions: {} extracted │" ,
939- format!( "{:>6}" , stats. functions) . green( )
929+ "│ ⏱️ Total time: {:<33} │" ,
930+ format!( "{:.2?}" , elapsed) . green( )
940931 ) ;
941932 println ! (
942- "│ 🏗️ Classes : {} extracted │" ,
943- format!( "{:>6} " , stats. classes ) . green ( )
933+ "│ ⚡ Throughput : {:<33} │" ,
934+ format!( "{:.2} files/sec " , stats. files as f64 / elapsed . as_secs_f64 ( ) ) . yellow ( )
944935 ) ;
936+ println ! ( "├─────────────────────────────────────────────────┤" ) ;
945937 println ! (
946- "│ 📦 Structs: {} extracted │" ,
947- format!( "{:>6}" , stats. structs) . green( )
938+ "│ 📄 Files: {} indexed, {} skipped {:<13} │" ,
939+ format!( "{:>6}" , stats. files) . yellow( ) ,
940+ format!( "{:>4}" , stats. skipped) . yellow( ) ,
941+ ""
948942 ) ;
949943 println ! (
950- "│ 🎯 Traits: {} extracted │" ,
951- format!( "{:>6}" , stats. traits) . green( )
944+ "│ 📝 Lines: {} processed {:<24} │" ,
945+ format!( "{:>6}" , stats. lines) . yellow( ) ,
946+ ""
952947 ) ;
953948 println ! (
954- "│ 💾 Embeddings: {} generated │" ,
955- format!( "{:>6}" , stats. embeddings) . cyan( )
949+ "│ 💾 Embeddings: {} generated {:<20} │" ,
950+ format!( "{:>6}" , stats. embeddings) . cyan( ) ,
951+ ""
956952 ) ;
957953 if stats. errors > 0 {
958954 println ! (
959- "│ ❌ Errors: {} encountered │" ,
960- format!( "{:>6}" , stats. errors) . red( )
955+ "│ ❌ Errors: {} encountered {:<24} │" ,
956+ format!( "{:>6}" , stats. errors) . red( ) ,
957+ ""
961958 ) ;
962959 }
963960 println ! ( "└─────────────────────────────────────────────────┘" ) ;
0 commit comments