@@ -339,6 +339,68 @@ func (sm *sprinklerMonitor) checkAndNotify(prURL string) {
339339 return
340340 }
341341
342+ // Log Turn API response details
343+ prState := ""
344+ prIsMerged := false
345+ if turnData != nil {
346+ prState = turnData .PullRequest .State
347+ prIsMerged = turnData .PullRequest .Merged
348+ }
349+
350+ slog .Info ("[SPRINKLER] Turn API response" ,
351+ "repo" , repo ,
352+ "number" , number ,
353+ "cached" , wasFromCache ,
354+ "state" , prState ,
355+ "merged" , prIsMerged ,
356+ "has_data" , turnData != nil ,
357+ "has_analysis" , turnData != nil && turnData .Analysis .NextAction != nil )
358+
359+ // Skip closed/merged PRs and remove from lists immediately
360+ if prState == "closed" || prIsMerged {
361+ slog .Info ("[SPRINKLER] PR closed/merged, removing from lists" ,
362+ "repo" , repo ,
363+ "number" , number ,
364+ "state" , prState ,
365+ "merged" , prIsMerged ,
366+ "url" , prURL )
367+
368+ // Remove from in-memory lists immediately
369+ sm .app .mu .Lock ()
370+ originalIncoming := len (sm .app .incoming )
371+ originalOutgoing := len (sm .app .outgoing )
372+
373+ // Filter out this PR from incoming
374+ filteredIncoming := make ([]PR , 0 , len (sm .app .incoming ))
375+ for _ , pr := range sm .app .incoming {
376+ if pr .URL != prURL {
377+ filteredIncoming = append (filteredIncoming , pr )
378+ }
379+ }
380+ sm .app .incoming = filteredIncoming
381+
382+ // Filter out this PR from outgoing
383+ filteredOutgoing := make ([]PR , 0 , len (sm .app .outgoing ))
384+ for _ , pr := range sm .app .outgoing {
385+ if pr .URL != prURL {
386+ filteredOutgoing = append (filteredOutgoing , pr )
387+ }
388+ }
389+ sm .app .outgoing = filteredOutgoing
390+ sm .app .mu .Unlock ()
391+
392+ slog .Info ("[SPRINKLER] Removed PR from lists" ,
393+ "url" , prURL ,
394+ "incoming_before" , originalIncoming ,
395+ "incoming_after" , len (sm .app .incoming ),
396+ "outgoing_before" , originalOutgoing ,
397+ "outgoing_after" , len (sm .app .outgoing ))
398+
399+ // Update UI to reflect removal
400+ sm .app .updateMenu (sm .ctx )
401+ return
402+ }
403+
342404 if turnData == nil || turnData .Analysis .NextAction == nil {
343405 slog .Debug ("[SPRINKLER] No turn data available" ,
344406 "repo" , repo ,
@@ -353,7 +415,8 @@ func (sm *sprinklerMonitor) checkAndNotify(prURL string) {
353415 slog .Debug ("[SPRINKLER] No action required for user" ,
354416 "repo" , repo ,
355417 "number" , number ,
356- "user" , user )
418+ "user" , user ,
419+ "state" , prState )
357420 return
358421 }
359422
@@ -366,6 +429,36 @@ func (sm *sprinklerMonitor) checkAndNotify(prURL string) {
366429 return
367430 }
368431
432+ // Check if PR exists in our lists
433+ sm .app .mu .RLock ()
434+ foundIncoming := false
435+ foundOutgoing := false
436+ for i := range sm .app .incoming {
437+ if sm .app .incoming [i ].URL == prURL {
438+ foundIncoming = true
439+ break
440+ }
441+ }
442+ if ! foundIncoming {
443+ for i := range sm .app .outgoing {
444+ if sm .app .outgoing [i ].URL == prURL {
445+ foundOutgoing = true
446+ break
447+ }
448+ }
449+ }
450+ sm .app .mu .RUnlock ()
451+
452+ // If PR not found in our lists, trigger a refresh to fetch it
453+ if ! foundIncoming && ! foundOutgoing {
454+ slog .Info ("[SPRINKLER] New PR detected, triggering refresh" ,
455+ "repo" , repo ,
456+ "number" , number ,
457+ "action" , action .Kind )
458+ go sm .app .updatePRs (sm .ctx )
459+ return // Let the refresh handle everything
460+ }
461+
369462 slog .Info ("[SPRINKLER] Blocking PR detected via event" ,
370463 "repo" , repo ,
371464 "number" , number ,
0 commit comments