@@ -35,6 +35,15 @@ export function showSidebarContent(d, fromHover = false) {
3535 if ( ( d . prompts && typeof d . prompts === 'object' && Object . keys ( d . prompts ) . length > 0 ) || ( d . artifacts_json && typeof d . artifacts_json === 'object' && Object . keys ( d . artifacts_json ) . length > 0 ) ) tabNames . push ( 'Prompts' ) ;
3636 const children = allNodeData . filter ( n => n . parent_id === d . id ) ;
3737 if ( children . length > 0 ) tabNames . push ( 'Children' ) ;
38+
39+ // --- CLONES TAB LOGIC ---
40+ function getBaseId ( id ) {
41+ return id . includes ( '-copy' ) ? id . split ( '-copy' ) [ 0 ] : id ;
42+ }
43+ const baseId = getBaseId ( d . id ) ;
44+ const clones = allNodeData . filter ( n => getBaseId ( n . id ) === baseId && n . id !== d . id ) ;
45+ if ( clones . length > 0 ) tabNames . push ( 'Clones' ) ;
46+
3847 let activeTab = lastSidebarTab && tabNames . includes ( lastSidebarTab ) ? lastSidebarTab : tabNames [ 0 ] ;
3948
4049 // Helper to render tab content
@@ -99,6 +108,13 @@ export function showSidebarContent(d, fromHover = false) {
99108 } ) . join ( '' ) +
100109 `</ul></div>` ;
101110 }
111+ if ( tabName === 'Clones' ) {
112+ return `<div><ul style='margin:0.5em 0 0 1em;padding:0;'>` +
113+ clones . map ( clone =>
114+ `<li style='margin-bottom:0.3em;'><a href="#" class="clone-link" data-clone="${ clone . id } ">${ clone . id } </a></li>`
115+ ) . join ( '' ) +
116+ `</ul></div>` ;
117+ }
102118 return '' ;
103119 }
104120
@@ -178,6 +194,25 @@ export function showSidebarContent(d, fromHover = false) {
178194 }
179195 } ;
180196 } ) ;
197+ document . querySelectorAll ( '.clone-link' ) . forEach ( link => {
198+ link . onclick = function ( e ) {
199+ e . preventDefault ( ) ;
200+ const cloneNode = allNodeData . find ( n => n . id == link . dataset . clone ) ;
201+ if ( cloneNode ) {
202+ window . _lastSelectedNodeData = cloneNode ;
203+ const perfTabBtn = document . getElementById ( 'tab-performance' ) ;
204+ const perfTabView = document . getElementById ( 'view-performance' ) ;
205+ if ( ( perfTabBtn && perfTabBtn . classList . contains ( 'active' ) ) || ( perfTabView && perfTabView . classList . contains ( 'active' ) ) ) {
206+ import ( './performance.js' ) . then ( mod => {
207+ mod . selectPerformanceNodeById ( cloneNode . id ) ;
208+ showSidebar ( ) ;
209+ } ) ;
210+ } else {
211+ scrollAndSelectNodeById ( cloneNode . id ) ;
212+ }
213+ }
214+ } ;
215+ } ) ;
181216 } , 0 ) ;
182217 } ;
183218 } ) ;
@@ -204,6 +239,25 @@ export function showSidebarContent(d, fromHover = false) {
204239 }
205240 } ;
206241 } ) ;
242+ document . querySelectorAll ( '.clone-link' ) . forEach ( link => {
243+ link . onclick = function ( e ) {
244+ e . preventDefault ( ) ;
245+ const cloneNode = allNodeData . find ( n => n . id == link . dataset . clone ) ;
246+ if ( cloneNode ) {
247+ window . _lastSelectedNodeData = cloneNode ;
248+ const perfTabBtn = document . getElementById ( 'tab-performance' ) ;
249+ const perfTabView = document . getElementById ( 'view-performance' ) ;
250+ if ( ( perfTabBtn && perfTabBtn . classList . contains ( 'active' ) ) || ( perfTabView && perfTabView . classList . contains ( 'active' ) ) ) {
251+ import ( './performance.js' ) . then ( mod => {
252+ mod . selectPerformanceNodeById ( cloneNode . id ) ;
253+ showSidebar ( ) ;
254+ } ) ;
255+ } else {
256+ scrollAndSelectNodeById ( cloneNode . id ) ;
257+ }
258+ }
259+ } ;
260+ } ) ;
207261 } , 0 ) ;
208262 const closeBtnEl = document . getElementById ( 'sidebar-close-btn' ) ;
209263 if ( closeBtnEl ) closeBtnEl . onclick = function ( ) {
0 commit comments