@@ -177,8 +177,8 @@ interface Bar {
177177 summary : BarSummary ;
178178 /** Tooltip shown on hover (e.g. pipeline status explanation). */
179179 tooltip ?: string ;
180- /** When true , render a "Create PR" control instead of the status label. */
181- showRunAction ?: boolean ;
180+ /** When set , render a run-action button with this label instead of (or alongside) the status label. */
181+ runActionLabel ?: string ;
182182}
183183
184184interface ReportTaskLogsProps {
@@ -213,8 +213,10 @@ export function ReportTaskLogs({
213213 // Build the stacked bars we'll render. We always surface the research bar
214214 // (using a pending/unavailable placeholder if no research task exists yet).
215215 // For `ready` reports without an implementation task yet, we still show the
216- // implementation row ("Not started"); the Create PR control only appears when
217- // the parent passes `onRunInCloud` (ready + actionable).
216+ // implementation row ("Not started"); the run-action control only appears
217+ // when the parent passes `onRunInCloud`. For `pending_input` reports, we
218+ // surface the control as "Provide input for PR" so the user can supply the
219+ // additional context the agent is waiting on.
218220 const bars : Bar [ ] = [ ] ;
219221
220222 if ( researchTask ) {
@@ -236,13 +238,21 @@ export function ReportTaskLogs({
236238 } ) ;
237239 }
238240
241+ const isPendingInput = reportStatus === "pending_input" ;
242+ const runActionLabel = onRunInCloud
243+ ? isPendingInput
244+ ? "Provide input for PR"
245+ : "Create PR"
246+ : undefined ;
247+
239248 if ( implementationTask ) {
240249 bars . push ( {
241250 relationship : "implementation" ,
242251 task : implementationTask ,
243252 summary : getTaskStatusSummary ( implementationTask ) ,
253+ runActionLabel : isPendingInput ? runActionLabel : undefined ,
244254 } ) ;
245- } else if ( reportStatus === "ready" ) {
255+ } else if ( reportStatus === "ready" || isPendingInput ) {
246256 bars . push ( {
247257 relationship : "implementation" ,
248258 task : null ,
@@ -251,7 +261,7 @@ export function ReportTaskLogs({
251261 color : "var(--gray-9)" ,
252262 icon : < DotOutlineIcon size = { 14 } /> ,
253263 } ,
254- showRunAction : ! ! onRunInCloud ,
264+ runActionLabel ,
255265 } ) ;
256266 }
257267
@@ -262,7 +272,8 @@ export function ReportTaskLogs({
262272 tasks . length > 0 ||
263273 reportStatus === "candidate" ||
264274 reportStatus === "in_progress" ||
265- reportStatus === "ready" ;
275+ reportStatus === "ready" ||
276+ isPendingInput ;
266277
267278 if ( ! showBar ) {
268279 return null ;
@@ -318,30 +329,42 @@ export function ReportTaskLogs({
318329 { /* Stacked header bars — one per task relationship. */ }
319330 < div className = "shrink-0" style = { { pointerEvents : "auto" } } >
320331 { bars . map ( ( bar , index ) => {
321- const { relationship, task, summary, tooltip, showRunAction } = bar ;
332+ const { relationship, task, summary, tooltip, runActionLabel } =
333+ bar ;
334+ const showRunAction = ! ! runActionLabel ;
322335 const isExpanded = expanded === relationship ;
323336 const isInteractive = ! ! task ;
337+ // When we have both an expandable task and a run button, the outer
338+ // element becomes a <div role="button"> so we can legally nest the
339+ // run button inside. Without a task, there's nothing to expand; the
340+ // run button becomes the sole interactive control.
341+ const hideStatusLabel = showRunAction && ! task ;
324342
325343 const rowClassName = [
326344 "flex w-full items-center gap-2 bg-transparent px-3 py-2 text-left transition-colors" ,
327345 index > 0 ? "border-gray-5 border-t" : "" ,
328- showRunAction
329- ? "cursor-default "
330- : isInteractive
331- ? "cursor-pointer hover:bg-gray-2 "
346+ isInteractive
347+ ? "cursor-pointer hover:bg-gray-2 "
348+ : showRunAction
349+ ? "cursor-default "
332350 : "cursor-default opacity-70" ,
333351 isExpanded && isInteractive ? "bg-gray-2" : "" ,
334352 ]
335353 . filter ( Boolean )
336354 . join ( " " ) ;
337355
356+ const toggleExpand = ( ) =>
357+ setExpanded ( ( curr ) =>
358+ curr === relationship ? null : relationship ,
359+ ) ;
360+
338361 const rowInner = (
339362 < >
340363 < span style = { { color : summary . color } } > { summary . icon } </ span >
341364 < Text size = "1" weight = "medium" className = "text-[12px]" >
342365 { RELATIONSHIP_LABELS [ relationship ] }
343366 </ Text >
344- { showRunAction ? (
367+ { hideStatusLabel ? (
345368 < span className = "flex-1" />
346369 ) : (
347370 < Text
@@ -363,10 +386,10 @@ export function ReportTaskLogs({
363386 } }
364387 >
365388 < Cloud size = { 12 } />
366- Create PR
389+ { runActionLabel }
367390 </ Button >
368391 ) }
369- { isInteractive && ! showRunAction && (
392+ { isInteractive && (
370393 < span
371394 className = "inline-flex text-gray-9"
372395 style = { {
@@ -380,30 +403,48 @@ export function ReportTaskLogs({
380403 </ >
381404 ) ;
382405
383- const row =
384- isInteractive && ! showRunAction ? (
385- < button
406+ const row = isInteractive ? (
407+ showRunAction ? (
408+ // biome-ignore lint/a11y/useSemanticElements: a <button> can't contain the nested run-action <button>
409+ // biome-ignore lint/a11y/useKeyWithClickEvents: keyboard handled via onKeyDown
410+ // biome-ignore lint/a11y/noStaticElementInteractions: role="button" makes this interactive
411+ < div
386412 key = { relationship }
387- type = "button"
388- onClick = { ( ) =>
389- setExpanded ( ( curr ) =>
390- curr === relationship ? null : relationship ,
391- )
392- }
413+ role = "button"
414+ tabIndex = { 0 }
415+ onClick = { toggleExpand }
416+ onKeyDown = { ( e ) => {
417+ if ( e . target !== e . currentTarget ) return ;
418+ if ( e . key === "Enter" || e . key === " " ) {
419+ e . preventDefault ( ) ;
420+ toggleExpand ( ) ;
421+ }
422+ } }
393423 className = { rowClassName }
394424 style = { { height : BAR_HEIGHT } }
395425 >
396426 { rowInner }
397- </ button >
427+ </ div >
398428 ) : (
399- < div
429+ < button
400430 key = { relationship }
431+ type = "button"
432+ onClick = { toggleExpand }
401433 className = { rowClassName }
402434 style = { { height : BAR_HEIGHT } }
403435 >
404436 { rowInner }
405- </ div >
406- ) ;
437+ </ button >
438+ )
439+ ) : (
440+ < div
441+ key = { relationship }
442+ className = { rowClassName }
443+ style = { { height : BAR_HEIGHT } }
444+ >
445+ { rowInner }
446+ </ div >
447+ ) ;
407448
408449 return tooltip ? (
409450 < Tooltip key = { relationship } content = { tooltip } >
0 commit comments