@@ -254,11 +254,13 @@ def draw_sessions(
254254
255255def draw_details (
256256 win , y : int , x : int , width : int , height : int ,
257- session : dict | None , tool_calls : list [dict ], patterns : list [dict ]
257+ session : dict | None , tool_calls : list [dict ], patterns : list [dict ],
258+ analysis = None ,
258259) -> None :
259260 """Draw the session details panel.
260261
261- Shows detailed info about the currently selected session.
262+ Shows detailed info about the currently selected session,
263+ including outcome grade, commits, tests, and collaboration.
262264 """
263265 draw_box (win , y , x , height , width , "Details" )
264266
@@ -277,9 +279,52 @@ def add_line(label: str, value: str, value_attr: int = 0) -> None:
277279 safe_addstr (win , y + 1 + row , x + 3 + len (label ) + 2 , value , value_attr or dim_attr ())
278280 row += 1
279281
280- grade = session .get ("grade" , "?" ) or "?"
281- score = session .get ("score" , 0 ) or 0
282- add_line ("Grade" , f"{ grade } ({ score } /100)" , grade_color (grade ))
282+ def add_raw (text : str , attr : int = 0 ) -> None :
283+ nonlocal row
284+ if row >= available_rows :
285+ return
286+ safe_addstr (win , y + 1 + row , x + 3 , truncate (text , width - 6 ), attr or dim_attr ())
287+ row += 1
288+
289+ # Outcome + Process grades side by side (if analysis available)
290+ if analysis and hasattr (analysis , "outcome" ) and analysis .outcome :
291+ o = analysis .outcome
292+ p_grade = session .get ("grade" , "?" ) or "?"
293+ p_score = session .get ("score" , 0 ) or 0
294+ o_grade = o .grade or "N/A"
295+ o_score = o .score if o .score is not None else 0
296+
297+ # Outcome grade
298+ label = "Outcome"
299+ safe_addstr (win , y + 1 + row , x + 3 , f"{ label } : " , dim_attr ())
300+ o_str = f"{ o_grade } ({ o_score } /100)" if o_grade != "N/A" else "N/A"
301+ safe_addstr (win , y + 1 + row , x + 3 + len (label ) + 2 , o_str , grade_color (o_grade ))
302+ # Process grade on same line
303+ sep_x = x + 3 + len (label ) + 2 + len (o_str ) + 2
304+ if sep_x + 20 < x + width :
305+ safe_addstr (win , y + 1 + row , sep_x , "Process: " , dim_attr ())
306+ safe_addstr (win , y + 1 + row , sep_x + 9 , f"{ p_grade } ({ p_score } /100)" , grade_color (p_grade ))
307+ row += 1
308+
309+ # Commits
310+ if o .commit_count > 0 :
311+ style = f" ({ o .commit_style } )" if o .commit_style and o .commit_style != "none" else ""
312+ add_line ("Commits" , f"{ o .commit_count } { style } " , curses .color_pair (1 ))
313+
314+ # Tests
315+ if o .test_snapshots :
316+ last = o .test_snapshots [- 1 ]
317+ passed = getattr (last , "passed" , 0 ) or 0
318+ failed = getattr (last , "failed" , 0 ) or 0
319+ if failed > 0 :
320+ add_line ("Tests" , f"{ passed } pass, { failed } FAIL" , curses .color_pair (4 ))
321+ else :
322+ add_line ("Tests" , f"{ passed } passing" , curses .color_pair (1 ))
323+ else :
324+ # Fallback: just process grade
325+ grade = session .get ("grade" , "?" ) or "?"
326+ score = session .get ("score" , 0 ) or 0
327+ add_line ("Grade" , f"{ grade } ({ score } /100)" , grade_color (grade ))
283328
284329 duration = session .get ("duration_minutes" )
285330 if duration is not None :
@@ -307,14 +352,22 @@ def add_line(label: str, value: str, value_attr: int = 0) -> None:
307352 if files_touched :
308353 add_line ("Files" , f"{ len (files_touched )} touched" )
309354
310- # Model
311- model = session .get ("model" )
312- if model :
313- add_line ("Model" , truncate (model , width - 12 ))
355+ # Collaboration (if analysis available)
356+ if analysis and hasattr (analysis , "collaboration" ) and analysis .collaboration :
357+ c = analysis .collaboration
358+ if c .human_turns >= 2 and c .archetype :
359+ if row < available_rows :
360+ row += 1 # blank line
361+ arch_color = curses .color_pair (1 ) if c .archetype == "Partnership" else (
362+ curses .color_pair (4 ) if c .archetype in ("Spec Dump" , "Micromanager" ) else dim_attr ()
363+ )
364+ add_line ("Collab" , f"{ c .archetype } ({ c .score } /100)" , arch_color )
365+ corr = f"{ c .corrections } c" if c .corrections else "0c"
366+ aff = f"{ c .affirmations } a" if c .affirmations else "0a"
367+ add_raw (f" { corr } { aff } ~{ c .avg_words_per_turn :.0f} words/turn" , dim_attr ())
314368
315369 # Patterns
316370 if patterns :
317- # Count by type
318371 pattern_counts : dict [str , int ] = {}
319372 for p in patterns :
320373 pt = p .get ("type" , "unknown" )
@@ -328,9 +381,6 @@ def add_line(label: str, value: str, value_attr: int = 0) -> None:
328381 break
329382 safe_addstr (win , y + 1 + row , x + 3 , f" { pt } ({ cnt } )" , curses .color_pair (3 ))
330383 row += 1
331- elif row < available_rows :
332- row += 1
333- safe_addstr (win , y + 1 + row , x + 3 , "No patterns" , curses .color_pair (1 ))
334384
335385 # Session ID at the bottom if space permits
336386 if row + 1 < available_rows :
0 commit comments