Skip to content

Commit ef7661a

Browse files
authored
Merge pull request #24 from zhanglinqian/fix/issue-23-color-coded-output
Fix issue #23: Add color-coded output to CLI scan results
2 parents 4531543 + 62c0a2c commit ef7661a

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

src/ai_bom/reporters/cli_reporter.py

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,38 @@
1010
from rich.table import Table
1111
from rich.text import Text
1212

13-
from ai_bom.models import ScanResult
13+
from ai_bom.models import ComponentType, ScanResult
1414
from 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+
1745
class 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

Comments
 (0)