@@ -28,7 +28,9 @@ import {
2828 GlobeIcon ,
2929 HammerIcon ,
3030 Loader2Icon ,
31+ ListIcon ,
3132 type LucideIcon ,
33+ MessageSquareTextIcon ,
3234 PlugIcon ,
3335 SearchIcon ,
3436 SquarePenIcon ,
@@ -839,7 +841,53 @@ function workEntryPreview(
839841 : `${ shortenToolSummary ( firstPath ) } +${ workEntry . changedFiles ! . length - 1 } more` ;
840842}
841843
844+ /** Check if a tool name refers to a review comment MCP tool. */
845+ function isReviewCommentTool ( toolName ?: string ) : boolean {
846+ if ( ! toolName ) return false ;
847+ const lower = toolName . toLowerCase ( ) ;
848+ return lower . includes ( "review_comment" ) || lower . includes ( "review-comment" ) ;
849+ }
850+
851+ /** Extract review comment severity from the detail/command JSON preview. */
852+ function extractReviewSeverity (
853+ workEntry : Pick < TimelineWorkEntry , "detail" | "command" > ,
854+ ) : "info" | "suggestion" | "issue" | "blocker" | null {
855+ const text = workEntry . detail || workEntry . command || "" ;
856+ const match = text . match ( / " s e v e r i t y " \s * : \s * " ( i n f o | s u g g e s t i o n | i s s u e | b l o c k e r ) " / ) ;
857+ return ( match ?. [ 1 ] as "info" | "suggestion" | "issue" | "blocker" ) ?? null ;
858+ }
859+
860+ /** Severity-based color class for review comment icons. */
861+ function reviewSeverityClass ( severity : "info" | "suggestion" | "issue" | "blocker" | null ) : string {
862+ switch ( severity ) {
863+ case "blocker" :
864+ return "text-rose-400" ;
865+ case "issue" :
866+ return "text-orange-400" ;
867+ case "suggestion" :
868+ return "text-blue-400" ;
869+ case "info" :
870+ return "text-muted-foreground/60" ;
871+ default :
872+ return "text-muted-foreground/50" ;
873+ }
874+ }
875+
876+ function reviewCommentIcon (
877+ toolName ?: string ,
878+ ) : { icon : LucideIcon ; isReview : true } | { isReview : false } {
879+ if ( ! isReviewCommentTool ( toolName ) ) return { isReview : false } ;
880+ const lower = toolName ! . toLowerCase ( ) ;
881+ if ( lower . includes ( "list" ) ) return { icon : ListIcon , isReview : true } ;
882+ if ( lower . includes ( "update" ) ) return { icon : MessageSquareTextIcon , isReview : true } ;
883+ return { icon : MessageSquareTextIcon , isReview : true } ;
884+ }
885+
842886function workEntryIcon ( workEntry : TimelineWorkEntry ) : LucideIcon {
887+ // Review comment MCP tools get a dedicated icon
888+ const review = reviewCommentIcon ( workEntry . toolName ) ;
889+ if ( review . isReview ) return review . icon ;
890+
843891 // Match by tool name first for precise icons
844892 switch ( workEntry . toolName ) {
845893 case "Bash" :
@@ -1000,12 +1048,15 @@ const SimpleWorkEntryRow = memo(function SimpleWorkEntryRow(props: {
10001048 const hasChangedFiles = ( workEntry . changedFiles ?. length ?? 0 ) > 0 ;
10011049 const previewIsChangedFiles = hasChangedFiles && ! workEntry . command && ! workEntry . detail ;
10021050
1051+ // Review comment tools get severity-based icon coloring
1052+ const isReview = isReviewCommentTool ( workEntry . toolName ) ;
1053+ const severity = isReview ? extractReviewSeverity ( workEntry ) : null ;
1054+ const iconClassName = isReview ? reviewSeverityClass ( severity ) : iconConfig . className ;
1055+
10031056 return (
10041057 < div className = "rounded-lg px-1 py-1" >
10051058 < div className = "flex items-center gap-2 transition-[opacity,translate] duration-200" >
1006- < span
1007- className = { cn ( "flex size-5 shrink-0 items-center justify-center" , iconConfig . className ) }
1008- >
1059+ < span className = { cn ( "flex size-5 shrink-0 items-center justify-center" , iconClassName ) } >
10091060 < EntryIcon className = "size-3" />
10101061 </ span >
10111062 < div className = "min-w-0 flex-1 overflow-hidden" >
0 commit comments