@@ -223,6 +223,10 @@ async fn review_command(
223223 info ! ( "Skipping excluded file: {}" , diff. file_path. display( ) ) ;
224224 continue ;
225225 }
226+ if diff. is_binary || diff. hunks . is_empty ( ) {
227+ info ! ( "Skipping non-text diff: {}" , diff. file_path. display( ) ) ;
228+ continue ;
229+ }
226230
227231 let mut context_chunks = context_fetcher. fetch_context_for_file (
228232 & diff. file_path ,
@@ -692,6 +696,10 @@ async fn review_diff_content_raw(
692696 info ! ( "Skipping excluded file: {}" , diff. file_path. display( ) ) ;
693697 continue ;
694698 }
699+ if diff. is_binary || diff. hunks . is_empty ( ) {
700+ info ! ( "Skipping non-text diff: {}" , diff. file_path. display( ) ) ;
701+ continue ;
702+ }
695703
696704 let mut context_chunks = context_fetcher. fetch_context_for_file (
697705 & diff. file_path ,
@@ -785,7 +793,9 @@ async fn review_diff_content_raw(
785793
786794fn parse_llm_response ( content : & str , file_path : & PathBuf ) -> Result < Vec < core:: comment:: RawComment > > {
787795 let mut comments = Vec :: new ( ) ;
788- let line_pattern = regex:: Regex :: new ( r"(?i)line\s+(\d+):\s*(.+)" ) ?;
796+ static LINE_PATTERN : Lazy < Regex > = Lazy :: new ( || {
797+ Regex :: new ( r"(?i)line\s+(\d+):\s*(.+)" ) . unwrap ( )
798+ } ) ;
789799
790800 for line in content. lines ( ) {
791801 let trimmed = line. trim ( ) ;
@@ -801,7 +811,7 @@ fn parse_llm_response(content: &str, file_path: &PathBuf) -> Result<Vec<core::co
801811 continue ;
802812 }
803813
804- if let Some ( caps) = line_pattern . captures ( line) {
814+ if let Some ( caps) = LINE_PATTERN . captures ( line) {
805815 let line_number: usize = caps. get ( 1 ) . unwrap ( ) . as_str ( ) . parse ( ) ?;
806816 let comment_text = caps. get ( 2 ) . unwrap ( ) . as_str ( ) . trim ( ) ;
807817
@@ -867,6 +877,9 @@ fn format_as_patch(comments: &[core::Comment]) -> String {
867877 comment. severity,
868878 comment. content
869879 ) ) ;
880+ if let Some ( suggestion) = & comment. suggestion {
881+ output. push_str ( & format ! ( "# Suggestion: {}\n " , suggestion) ) ;
882+ }
870883 }
871884 output
872885}
@@ -886,8 +899,13 @@ fn format_as_markdown(comments: &[core::Comment]) -> String {
886899
887900 // Severity breakdown
888901 output. push_str ( "### Issues by Severity\n \n " ) ;
889- for ( severity, count) in & summary. by_severity {
890- let emoji = match severity. as_str ( ) {
902+ let severity_order = [ "Error" , "Warning" , "Info" , "Suggestion" ] ;
903+ for severity in severity_order {
904+ let count = summary. by_severity . get ( severity) . copied ( ) . unwrap_or ( 0 ) ;
905+ if count == 0 {
906+ continue ;
907+ }
908+ let emoji = match severity {
891909 "Error" => "🔴" ,
892910 "Warning" => "🟡" ,
893911 "Info" => "🔵" ,
@@ -900,8 +918,23 @@ fn format_as_markdown(comments: &[core::Comment]) -> String {
900918
901919 // Category breakdown
902920 output. push_str ( "### Issues by Category\n \n " ) ;
903- for ( category, count) in & summary. by_category {
904- let emoji = match category. as_str ( ) {
921+ let category_order = [
922+ "Security" ,
923+ "Performance" ,
924+ "Bug" ,
925+ "Maintainability" ,
926+ "Testing" ,
927+ "Style" ,
928+ "Documentation" ,
929+ "Architecture" ,
930+ "BestPractice" ,
931+ ] ;
932+ for category in category_order {
933+ let count = summary. by_category . get ( category) . copied ( ) . unwrap_or ( 0 ) ;
934+ if count == 0 {
935+ continue ;
936+ }
937+ let emoji = match category {
905938 "Security" => "🔒" ,
906939 "Performance" => "⚡" ,
907940 "Bug" => "🐛" ,
@@ -1036,6 +1069,10 @@ async fn smart_review_command(
10361069 info ! ( "Skipping excluded file: {}" , diff. file_path. display( ) ) ;
10371070 continue ;
10381071 }
1072+ if diff. is_binary || diff. hunks . is_empty ( ) {
1073+ info ! ( "Skipping non-text diff: {}" , diff. file_path. display( ) ) ;
1074+ continue ;
1075+ }
10391076
10401077 let mut context_chunks = context_fetcher. fetch_context_for_file (
10411078 & diff. file_path ,
@@ -1443,15 +1480,16 @@ fn format_detailed_comment(comment: &core::Comment) -> String {
14431480 comment. category
14441481 ) ) ;
14451482
1446- output. push_str ( & format ! ( "**Confidence:** {:.0}% | " , comment. confidence * 100.0 ) ) ;
1447- if !comment. tags . is_empty ( ) {
1448- output. push_str ( "**Tags:** " ) ;
1483+ if comment. tags . is_empty ( ) {
1484+ output. push_str ( & format ! ( "**Confidence:** {:.0}%\n \n " , comment. confidence * 100.0 ) ) ;
1485+ } else {
1486+ output. push_str ( & format ! ( "**Confidence:** {:.0}% | **Tags:** " , comment. confidence * 100.0 ) ) ;
14491487 for ( i, tag) in comment. tags . iter ( ) . enumerate ( ) {
14501488 if i > 0 { output. push_str ( ", " ) ; }
14511489 output. push_str ( & format ! ( "`{}`" , tag) ) ;
14521490 }
1491+ output. push_str ( "\n \n " ) ;
14531492 }
1454- output. push_str ( "\n \n " ) ;
14551493
14561494 output. push_str ( & format ! ( "{}\n \n " , comment. content) ) ;
14571495
0 commit comments