@@ -532,10 +532,29 @@ function openNote(repoId, btn) {
532532 panel . querySelector ( '.lc-note-save' ) ?. addEventListener ( 'click' , saveNote ) ;
533533}
534534
535- function openRow ( repoId ) {
535+ // Forward path (library → output). Before opening a fresh output tab, focus an
536+ // already-open output tab for the same repo so re-clicking a card round-trips
537+ // instead of orphaning duplicate analysis tabs. Output tabs set their title to
538+ // `… {repoId} — RepoLens` (output-tab.js), which is what we match on — the random
539+ // session key never reaches the URL, so the title is the only stable repo signal.
540+ async function focusExistingOutputTab ( repoId ) {
541+ try {
542+ const tabs = await chrome . tabs . query ( { url : chrome . runtime . getURL ( 'output-tab.html' ) + '*' } ) ;
543+ const existing = tabs . find ( ( t ) => typeof t . title === 'string' && t . title . includes ( `${ repoId } — RepoLens` ) ) ;
544+ if ( ! existing ) return false ;
545+ await chrome . tabs . update ( existing . id , { active : true } ) ;
546+ await chrome . windows . update ( existing . windowId , { focused : true } ) ;
547+ return true ;
548+ } catch {
549+ return false ;
550+ }
551+ }
552+
553+ async function openRow ( repoId ) {
536554 const cached = cacheByRepo . get ( repoId ) ;
537- if ( cached ) openCachedAnalysis ( cached ) ;
538- else openSource ( repoId ) ;
555+ if ( ! cached ) { openSource ( repoId ) ; return ; }
556+ if ( await focusExistingOutputTab ( repoId ) ) return ;
557+ openCachedAnalysis ( cached ) ;
539558}
540559
541560function openSource ( repoId ) {
0 commit comments