1010from rich .table import Table
1111from rich .text import Text
1212
13- from ai_bom .models import ScanResult
13+ from ai_bom .models import ComponentType , ScanResult
1414from ai_bom .reporters .base import BaseReporter
1515
1616
17+ def _get_component_type_color (component_type : ComponentType ) -> str :
18+ """Get color for a component type.
19+
20+ Args:
21+ component_type: The component type enum value
22+
23+ Returns:
24+ Rich color string
25+ """
26+ color_map = {
27+ # Models/LLMs: Blue
28+ ComponentType .model : "blue" ,
29+ ComponentType .llm_provider : "bright_blue" ,
30+ # Agents: Green
31+ ComponentType .agent_framework : "green" ,
32+ ComponentType .mcp_client : "bright_green" ,
33+ ComponentType .workflow : "green" ,
34+ # Tools: Yellow
35+ ComponentType .tool : "yellow" ,
36+ ComponentType .mcp_server : "bright_yellow" ,
37+ # Endpoints: Cyan
38+ ComponentType .endpoint : "cyan" ,
39+ # Containers: Magenta
40+ ComponentType .container : "magenta" ,
41+ }
42+ return color_map .get (component_type , "white" )
43+
44+
1745class CLIReporter (BaseReporter ):
1846 """Rich console reporter for interactive terminal output."""
1947
@@ -40,8 +68,14 @@ def render(self, result: ScanResult) -> str:
4068 "" ,
4169 "By Type:" ,
4270 ]
71+ # Color code type counts
4372 for type_name , count in sorted (summary .by_type .items ()):
44- summary_lines .append (f" { type_name } : { count } " )
73+ try :
74+ comp_type = ComponentType (type_name )
75+ color = _get_component_type_color (comp_type )
76+ summary_lines .append (f" [{ color } ]{ type_name } : { count } [/{ color } ]" )
77+ except ValueError :
78+ summary_lines .append (f" { type_name } : { count } " )
4579
4680 summary_lines .append ("" )
4781 summary_lines .append ("By Severity:" )
@@ -106,19 +140,30 @@ def render(self, result: ScanResult) -> str:
106140 else :
107141 risk_style = "green"
108142
143+ # Color code component name based on type
144+ type_color = _get_component_type_color (comp .type )
145+
146+ # Highlight API keys/credentials with red
147+ comp_name_style = type_color
148+ if any (flag in comp .flags for flag in ["hardcoded_api_key" , "hardcoded_credentials" , "api_key_detected" ]):
149+ comp_name_style = "bold red"
150+
109151 location = comp .location .file_path
110152 if comp .location .line_number :
111153 location += f":{ comp .location .line_number } "
112154 # Truncate path
113155 if len (location ) > 35 :
114156 location = "..." + location [- 32 :]
115157
158+ # Color code type column
159+ type_text = Text (comp .type .value , style = type_color )
160+
116161 flags_display = ", " .join (comp .flags [:3 ]) if comp .flags else "-"
117162
118163 table .add_row (
119164 str (i ),
120- comp .name ,
121- comp . type . value ,
165+ Text ( comp .name , style = comp_name_style ) ,
166+ type_text ,
122167 comp .provider ,
123168 location ,
124169 Text (str (risk_score ), style = risk_style ),
0 commit comments