@@ -372,7 +372,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
372372 let safeCodeHashes = { } ;
373373 let serverAvailable = false ;
374374 let maximizedEditor = null ;
375- let debugTraceActive = false , debugDecorations = [ ] , lastDebugHash = null , lastDebugTrace = null ;
375+ let debugTraceActive = false , debugDecorations = [ ] , debugTraceIdx = 0 ;
376376
377377 let isManuallyCollapsed = false ;
378378
@@ -433,6 +433,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
433433 if ( e . key === 'Escape' && ttsEnabled ) { speechSynthesis . cancel ( ) ; }
434434 if ( e . key === 'Escape' && testGenTimer ) { e . preventDefault ( ) ; cancelTestGen ( ) ; return ; }
435435 if ( e . key === 'Escape' && debugTraceActive ) { e . preventDefault ( ) ; closeDebugTrace ( ) ; return ; }
436+ if ( debugTraceActive && ( e . key === 'ArrowDown' || e . key === 'ArrowUp' ) ) { e . preventDefault ( ) ; stepDebugTrace ( e . key === 'ArrowDown' ? 1 : - 1 ) ; return ; }
436437 if ( e . key === 'Escape' && maximizedEditor ) { toggleMaximize ( maximizedEditor ) ; }
437438 } ) ;
438439
@@ -616,7 +617,6 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
616617 function selectTab ( id ) {
617618 cancelTestGen ( ) ;
618619 closeDebugTrace ( ) ;
619- lastDebugHash = null ; lastDebugTrace = null ;
620620 activeTabId = id ;
621621 genMgr . clearAll ( ) ;
622622
@@ -676,6 +676,11 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
676676 term . style . color = tabs [ id ] . terminalColor || '#10b981' ;
677677 renderTermTable ( tabs [ id ] . terminalTable ) ;
678678
679+ // Restore debug trace if present
680+ if ( tabs [ id ] . debugTrace && tabs [ id ] . debugTrace . length ) {
681+ showDebugTrace ( tabs [ id ] . debugTrace , id ) ;
682+ }
683+
679684 renderTabs ( ) ;
680685 setView ( 'workbook' ) ;
681686 applyDescDock ( ) ;
@@ -739,7 +744,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
739744 if ( d . error ) throw new Error ( d . error ) ;
740745 return d . text ;
741746 }
742- const res = await fetch ( `https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-latest :generateContent?key=${ key } ` , {
747+ const res = await fetch ( `https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1- flash-lite-preview :generateContent?key=${ key } ` , {
743748 method :'POST' , headers :{ 'Content-Type' :'application/json' } ,
744749 body :JSON . stringify ( { contents :[ { parts :[ { text :prompt } ] } ] } )
745750 } ) ;
@@ -1785,9 +1790,9 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
17851790 if ( lang !== 'javascript' ) { termDone ( '[DEBUG] Only JavaScript supported for trace debugging.' , '#facc15' , tabId ) ; return ; }
17861791 const hash = await md5 ( code ) ;
17871792 // Reuse cached trace if code unchanged
1788- if ( hash === lastDebugHash && lastDebugTrace && lastDebugTrace . length ) {
1789- showDebugTrace ( lastDebugTrace , tabId ) ;
1790- termDone ( `>>> Debug trace (cached): ${ lastDebugTrace . length } steps.` , '#10b981' , tabId ) ;
1793+ if ( hash === tabs [ tabId ] . debugHash && tabs [ tabId ] . debugTrace ? .length ) {
1794+ showDebugTrace ( tabs [ tabId ] . debugTrace , tabId ) ;
1795+ termDone ( `>>> Debug trace (cached): ${ tabs [ tabId ] . debugTrace . length } steps.` , '#10b981' , tabId ) ;
17911796 return ;
17921797 }
17931798 const codeLines = code . split ( '\n' ) ;
@@ -1818,8 +1823,9 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
18181823 termSpinner ( 'Running instrumented code...' , tabId ) ;
18191824 const result = await runDebugSandbox ( instrumented ) ;
18201825 if ( result . traceData && result . traceData . length ) {
1821- lastDebugHash = hash ;
1822- lastDebugTrace = result . traceData ;
1826+ tabs [ tabId ] . debugHash = hash ;
1827+ tabs [ tabId ] . debugTrace = result . traceData ;
1828+ triggerSave ( ) ;
18231829 showDebugTrace ( result . traceData , tabId ) ;
18241830 termDone ( result . output || `>>> Debug trace: ${ result . traceData . length } steps captured.` , '#10b981' , tabId ) ;
18251831 } else {
@@ -1871,6 +1877,7 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
18711877 const panel = document . getElementById ( 'debugTracePanel' ) ;
18721878 if ( ! panel || ! data || ! data . length ) return ;
18731879 debugTraceActive = true ;
1880+ debugTraceIdx = 0 ;
18741881 panel . style . display = 'block' ;
18751882 panel . style . flex = '1' ;
18761883 // Build table — hide _srcLine from display but keep as data attr
@@ -1889,19 +1896,31 @@ <h3 class="text-xl font-black text-white mb-6 tracking-tighter italic">OPEN NEW
18891896 } ) ;
18901897 html += '</tbody></table>' ;
18911898 panel . innerHTML = html ;
1892- // Auto-highlight first row
1893- const firstRow = panel . querySelector ( 'tr[data-srcline]' ) ;
1899+ const firstRow = panel . querySelector ( 'tr[data-idx="0"]' ) ;
18941900 if ( firstRow ) highlightTraceLine ( parseInt ( firstRow . dataset . srcline ) || 0 , firstRow ) ;
18951901 setTimeout ( ( ) => { const ed = editors [ `${ tabId } _code` ] ; if ( ed && ed . layout ) ed . layout ( ) ; } , 50 ) ;
18961902 }
18971903
1904+ function stepDebugTrace ( dir ) {
1905+ const panel = document . getElementById ( 'debugTracePanel' ) ;
1906+ if ( ! panel ) return ;
1907+ const rows = panel . querySelectorAll ( 'tr[data-idx]' ) ;
1908+ if ( ! rows . length ) return ;
1909+ debugTraceIdx = Math . max ( 0 , Math . min ( rows . length - 1 , debugTraceIdx + dir ) ) ;
1910+ const row = rows [ debugTraceIdx ] ;
1911+ highlightTraceLine ( parseInt ( row . dataset . srcline ) || 0 , row ) ;
1912+ row . scrollIntoView ( { block : 'nearest' } ) ;
1913+ }
1914+
18981915 function highlightTraceLine ( srcLine , rowEl ) {
18991916 const ed = editors [ `${ activeTabId } _code` ] ;
19001917 if ( ! ed ) return ;
1901- // Highlight row in table
19021918 const panel = document . getElementById ( 'debugTracePanel' ) ;
19031919 panel . querySelectorAll ( 'tr.trace-active' ) . forEach ( r => r . classList . remove ( 'trace-active' ) ) ;
1904- if ( rowEl ) rowEl . classList . add ( 'trace-active' ) ;
1920+ if ( rowEl ) {
1921+ rowEl . classList . add ( 'trace-active' ) ;
1922+ debugTraceIdx = parseInt ( rowEl . dataset . idx ) || 0 ;
1923+ }
19051924 // Highlight line in editor
19061925 if ( srcLine > 0 ) {
19071926 debugDecorations = ed . deltaDecorations ( debugDecorations , [
0 commit comments