checkpoint-cli 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -79,1194 +79,6 @@ function requireAuth() {
79
79
  process.exit(1);
80
80
  }
81
81
  }
82
- /* ── Checkpoint Tracking Script (injected into HTML responses) ── */
83
- function trackingScript() {
84
- return `
85
- <script data-checkpoint-script="1">
86
- (function(){
87
- var lastPath='';
88
- var pickMode=false;
89
- var pickClickHandler=null;
90
- var pickEscHandler=null;
91
- var pickMoveHandler=null;
92
- var pickInspectBox=null;
93
- var pickInspectLabel=null;
94
- var pickPointerDownHandler=null;
95
- var pickHoverRaf=0;
96
- var pickLastMouseX=0;
97
- var pickLastMouseY=0;
98
-
99
- function getMetrics(){
100
- var de=document.documentElement;
101
- return {
102
- scrollX:window.scrollX||window.pageXOffset||0,
103
- scrollY:window.scrollY||window.pageYOffset||0,
104
- docWidth:de.scrollWidth||0,
105
- docHeight:de.scrollHeight||0,
106
- viewWidth:de.clientWidth||window.innerWidth||0,
107
- viewHeight:de.clientHeight||window.innerHeight||0
108
- };
109
- }
110
-
111
- function clampPercent(v){
112
- if(v<0) return 0;
113
- if(v>100) return 100;
114
- return v;
115
- }
116
-
117
- function cssEscape(value){
118
- try{
119
- if(window.CSS&&typeof window.CSS.escape==='function'){
120
- return window.CSS.escape(value);
121
- }
122
- }catch(e){}
123
- return String(value).replace(/[^a-zA-Z0-9_-]/g,'\\\\$&');
124
- }
125
-
126
- function shortText(value){
127
- if(!value) return '';
128
- return String(value).replace(/\\s+/g,' ').trim().slice(0,120);
129
- }
130
-
131
- function getFileLeaf(path){
132
- if(!path) return '';
133
- try{
134
- var raw=String(path);
135
- var parts=raw.split(/[\\\\/]/);
136
- return parts[parts.length-1]||raw;
137
- }catch(e){}
138
- return '';
139
- }
140
-
141
- function getInspectElementLabel(el){
142
- if(!el||!el.tagName) return '(unknown)';
143
- var tag=String(el.tagName).toLowerCase();
144
- var id=el.id?('#'+el.id):'';
145
- var classes='';
146
- try{
147
- var cls=(el.className&&typeof el.className==='string')
148
- ? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,3)
149
- : [];
150
- if(cls.length>0){
151
- classes='.'+cls.join('.');
152
- }
153
- }catch(e){}
154
- return shortText(tag+id+classes);
155
- }
156
-
157
- function ensurePickInspectUi(){
158
- if(!document.body) return;
159
- if(!pickInspectBox){
160
- pickInspectBox=document.createElement('div');
161
- pickInspectBox.setAttribute('data-checkpoint-inspect','box');
162
- pickInspectBox.style.position='fixed';
163
- pickInspectBox.style.left='0';
164
- pickInspectBox.style.top='0';
165
- pickInspectBox.style.width='0';
166
- pickInspectBox.style.height='0';
167
- pickInspectBox.style.border='2px solid #6366f1';
168
- pickInspectBox.style.background='rgba(99,102,241,0.12)';
169
- pickInspectBox.style.boxSizing='border-box';
170
- pickInspectBox.style.borderRadius='4px';
171
- pickInspectBox.style.pointerEvents='none';
172
- pickInspectBox.style.zIndex='2147483646';
173
- pickInspectBox.style.display='none';
174
- document.body.appendChild(pickInspectBox);
175
- }
176
- if(!pickInspectLabel){
177
- pickInspectLabel=document.createElement('div');
178
- pickInspectLabel.setAttribute('data-checkpoint-inspect','label');
179
- pickInspectLabel.style.position='fixed';
180
- pickInspectLabel.style.left='0';
181
- pickInspectLabel.style.top='0';
182
- pickInspectLabel.style.maxWidth='380px';
183
- pickInspectLabel.style.padding='6px 8px';
184
- pickInspectLabel.style.borderRadius='8px';
185
- pickInspectLabel.style.border='1px solid rgba(148,163,184,0.45)';
186
- pickInspectLabel.style.background='rgba(15,23,42,0.96)';
187
- pickInspectLabel.style.color='#e2e8f0';
188
- pickInspectLabel.style.font='12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace';
189
- pickInspectLabel.style.whiteSpace='pre-line';
190
- pickInspectLabel.style.wordBreak='break-word';
191
- pickInspectLabel.style.pointerEvents='none';
192
- pickInspectLabel.style.zIndex='2147483647';
193
- pickInspectLabel.style.display='none';
194
- pickInspectLabel.style.boxShadow='0 6px 20px rgba(0,0,0,0.35)';
195
- document.body.appendChild(pickInspectLabel);
196
- }
197
- }
198
-
199
- function hidePickInspectUi(){
200
- if(pickInspectBox) pickInspectBox.style.display='none';
201
- if(pickInspectLabel) pickInspectLabel.style.display='none';
202
- }
203
-
204
- function renderPickInspect(target,mouseX,mouseY){
205
- ensurePickInspectUi();
206
- if(!pickInspectBox||!pickInspectLabel||!target||target.nodeType!==1){
207
- hidePickInspectUi();
208
- return;
209
- }
210
- var sourceTarget=findBestSourceAnchorTarget(target);
211
- var anchorEl=sourceTarget.element||target;
212
- var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl);
213
- var rect=target.getBoundingClientRect?target.getBoundingClientRect():null;
214
- if(!rect||rect.width<1||rect.height<1){
215
- hidePickInspectUi();
216
- return;
217
- }
218
-
219
- pickInspectBox.style.display='block';
220
- pickInspectBox.style.left=Math.max(0,rect.left)+'px';
221
- pickInspectBox.style.top=Math.max(0,rect.top)+'px';
222
- pickInspectBox.style.width=Math.max(1,rect.width)+'px';
223
- pickInspectBox.style.height=Math.max(1,rect.height)+'px';
224
-
225
- var primary=getInspectElementLabel(anchorEl);
226
- var sourceLabel='(no source metadata)';
227
- if(sourceAnchor){
228
- var leaf=getFileLeaf(sourceAnchor.source_file);
229
- if(leaf&&typeof sourceAnchor.source_line==='number'){
230
- sourceLabel=leaf+':'+sourceAnchor.source_line;
231
- }else if(leaf){
232
- sourceLabel=leaf;
233
- }else if(sourceAnchor.component_name){
234
- sourceLabel=sourceAnchor.component_name;
235
- }
236
- if(sourceAnchor.explicit_id){
237
- sourceLabel=sourceLabel+' · #'+sourceAnchor.explicit_id;
238
- }
239
- }
240
- pickInspectLabel.textContent=primary+'\\n'+sourceLabel;
241
- pickInspectLabel.style.display='block';
242
-
243
- var viewW=window.innerWidth||document.documentElement.clientWidth||0;
244
- var viewH=window.innerHeight||document.documentElement.clientHeight||0;
245
- var labelRect=pickInspectLabel.getBoundingClientRect();
246
- var left=mouseX+14;
247
- var top=mouseY+14;
248
- if(left+labelRect.width>viewW-8){
249
- left=Math.max(8,mouseX-labelRect.width-14);
250
- }
251
- if(top+labelRect.height>viewH-8){
252
- top=Math.max(8,mouseY-labelRect.height-14);
253
- }
254
- pickInspectLabel.style.left=left+'px';
255
- pickInspectLabel.style.top=top+'px';
256
- }
257
-
258
- function getEventElement(ev){
259
- if(!ev) return null;
260
- try{
261
- if(typeof ev.composedPath==='function'){
262
- var path=ev.composedPath();
263
- if(path&&path.length>0){
264
- var first=path[0];
265
- if(first&&first.nodeType===1) return first;
266
- if(first&&first.nodeType===3&&first.parentElement) return first.parentElement;
267
- }
268
- }
269
- }catch(e){}
270
- var target=ev.target||null;
271
- if(target&&target.nodeType===1){
272
- return target;
273
- }
274
- if(target&&target.nodeType===3&&target.parentElement){
275
- return target.parentElement;
276
- }
277
- try{
278
- if(typeof ev.clientX==='number'&&typeof ev.clientY==='number'&&document.elementFromPoint){
279
- var node=document.elementFromPoint(ev.clientX,ev.clientY);
280
- if(node&&node.nodeType===1){
281
- return node;
282
- }
283
- }
284
- }catch(e){}
285
- return null;
286
- }
287
-
288
- function getElementAtPoint(x,y){
289
- try{
290
- if(typeof x==='number'&&typeof y==='number'&&document.elementFromPoint){
291
- var node=document.elementFromPoint(x,y);
292
- if(node&&node.nodeType===1){
293
- return node;
294
- }
295
- }
296
- }catch(e){}
297
- return null;
298
- }
299
-
300
- function elementSelector(el){
301
- if(!el||!el.tagName) return '';
302
- var tag=el.tagName.toLowerCase();
303
- if(el.id) return '#'+cssEscape(el.id);
304
- var cls=(el.className&&typeof el.className==='string')
305
- ? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,3)
306
- : [];
307
- if(cls.length>0) return tag+'.'+cls.map(cssEscape).join('.');
308
- return tag;
309
- }
310
-
311
- function getSelectorChain(el){
312
- var out=[];
313
- var seen={};
314
- function push(selector,score){
315
- if(!selector||seen[selector]) return;
316
- seen[selector]=true;
317
- out.push({selector:selector,score:score});
318
- }
319
- var current=el;
320
- var depth=0;
321
- while(current&&current.nodeType===1&&depth<5){
322
- var sel=elementSelector(current);
323
- if(sel){
324
- var score=Math.max(0.2,1-(depth*0.18));
325
- push(sel,score);
326
- }
327
- if(current.parentElement){
328
- var parentSel=elementSelector(current.parentElement);
329
- if(parentSel&&sel){
330
- push(parentSel+' > '+sel,Math.max(0.2,0.88-(depth*0.15)));
331
- }
332
- }
333
- current=current.parentElement;
334
- depth++;
335
- }
336
- return out.slice(0,10);
337
- }
338
-
339
- function getSiblingPath(el){
340
- var path=[];
341
- var current=el;
342
- var steps=0;
343
- while(current&&current.parentElement&&steps<8){
344
- var parent=current.parentElement;
345
- var index=0;
346
- var children=parent.children;
347
- for(var i=0;i<children.length;i++){
348
- if(children[i]===current){
349
- index=i;
350
- break;
351
- }
352
- }
353
- path.unshift(index);
354
- current=parent;
355
- steps++;
356
- }
357
- return path;
358
- }
359
-
360
- function getDomFingerprint(el){
361
- if(!el||!el.tagName) return null;
362
- var classes=(el.className&&typeof el.className==='string')
363
- ? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,6)
364
- : [];
365
- return {
366
- tag:el.tagName.toLowerCase(),
367
- id:el.id||null,
368
- classes:classes,
369
- sibling_path:getSiblingPath(el)
370
- };
371
- }
372
-
373
- function getContainerHint(el){
374
- if(!el||typeof el.closest!=='function') return null;
375
- var container=el.closest('main,article,section,form,nav,[role="main"],[data-testid],[id]');
376
- if(!container||!container.tagName) return null;
377
- var classes=(container.className&&typeof container.className==='string')
378
- ? container.className.trim().split(/\\s+/).filter(Boolean).slice(0,4)
379
- : [];
380
- return {
381
- selector:elementSelector(container),
382
- tag:container.tagName.toLowerCase(),
383
- id:container.id||null,
384
- classes:classes
385
- };
386
- }
387
-
388
- function parseZIndex(value){
389
- var n=parseInt(String(value||''),10);
390
- return isNaN(n)?0:n;
391
- }
392
-
393
- function detectTransientKind(el){
394
- if(!el||!el.tagName) return 'unknown';
395
- try{
396
- var role=(el.getAttribute&&el.getAttribute('role')||'').toLowerCase();
397
- var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
398
- var id=(el.id||'').toLowerCase();
399
- var label=(role+' '+classes+' '+id).trim();
400
- if(role==='dialog'||el.getAttribute('aria-modal')==='true'||label.indexOf('modal')>=0||label.indexOf('dialog')>=0){
401
- return 'dialog';
402
- }
403
- if(label.indexOf('drawer')>=0||label.indexOf('sheet')>=0||label.indexOf('sidebar')>=0){
404
- return 'drawer';
405
- }
406
- if(label.indexOf('popover')>=0) return 'popover';
407
- if(role==='menu'||label.indexOf('menu')>=0||label.indexOf('dropdown')>=0) return 'menu';
408
- if(role==='tooltip'||label.indexOf('tooltip')>=0) return 'tooltip';
409
- }catch(e){}
410
- return 'unknown';
411
- }
412
-
413
- function isTransientRootCandidate(el){
414
- if(!el||!el.tagName) return false;
415
- try{
416
- var role=(el.getAttribute&&el.getAttribute('role')||'').toLowerCase();
417
- var ariaModal=(el.getAttribute&&el.getAttribute('aria-modal')||'').toLowerCase();
418
- var dataState=(el.getAttribute&&el.getAttribute('data-state')||'').toLowerCase();
419
- var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
420
- var id=(el.id||'').toLowerCase();
421
- var style=window.getComputedStyle?window.getComputedStyle(el):null;
422
- var position=style?style.position:'';
423
- var zIndex=parseZIndex(style?style.zIndex:0);
424
- if(role==='dialog'||role==='menu'||role==='tooltip') return true;
425
- if(ariaModal==='true') return true;
426
- if(dataState==='open'&&(classes.indexOf('modal')>=0||classes.indexOf('popover')>=0||classes.indexOf('drawer')>=0)) return true;
427
- if(classes.indexOf('modal')>=0||classes.indexOf('dialog')>=0||classes.indexOf('drawer')>=0||classes.indexOf('popover')>=0||classes.indexOf('tooltip')>=0||classes.indexOf('dropdown')>=0) return true;
428
- if(id.indexOf('modal')>=0||id.indexOf('dialog')>=0||id.indexOf('drawer')>=0||id.indexOf('popover')>=0) return true;
429
- if((position==='fixed'||position==='sticky')&&zIndex>=100) return true;
430
- }catch(e){}
431
- return false;
432
- }
433
-
434
- function isLikelyPortaled(el){
435
- if(!el||!el.parentElement) return false;
436
- try{
437
- var root=el;
438
- var steps=0;
439
- while(root&&root.parentElement&&steps<8){
440
- root=root.parentElement;
441
- steps++;
442
- }
443
- if(!root||!root.parentElement) return false;
444
- if(root===document.body) return true;
445
- if(el.parentElement===document.body) return true;
446
- if(el.parentElement&&el.parentElement.id&&String(el.parentElement.id).toLowerCase().indexOf('portal')>=0) return true;
447
- var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
448
- if(classes.indexOf('portal')>=0) return true;
449
- }catch(e){}
450
- return false;
451
- }
452
-
453
- function getOpenerCandidates(){
454
- var out=[];
455
- var seen={};
456
- var selectors=[
457
- '[aria-haspopup=\"dialog\"]',
458
- '[aria-controls]',
459
- '[data-modal-trigger]',
460
- '[data-dialog-trigger]',
461
- 'button',
462
- '[role=\"button\"]',
463
- 'a'
464
- ];
465
- for(var s=0;s<selectors.length;s++){
466
- var selector=selectors[s];
467
- try{
468
- var nodes=document.querySelectorAll(selector);
469
- for(var i=0;i<nodes.length&&out.length<8;i++){
470
- var node=nodes[i];
471
- if(!node||node.nodeType!==1) continue;
472
- var sel=elementSelector(node);
473
- if(!sel||seen[sel]) continue;
474
- seen[sel]=true;
475
- var score=0.3;
476
- var label=(node.getAttribute&&node.getAttribute('aria-label')||'').toLowerCase();
477
- var text=shortText(node.textContent).toLowerCase();
478
- if(label.indexOf('setting')>=0||text.indexOf('setting')>=0) score=0.9;
479
- else if(label.indexOf('open')>=0||text.indexOf('open')>=0) score=0.7;
480
- out.push({selector:sel,score:score});
481
- }
482
- }catch(e){}
483
- }
484
- out.sort(function(a,b){ return b.score-a.score; });
485
- return out.slice(0,6);
486
- }
487
-
488
- function getTransientContext(el){
489
- if(!el||typeof el.closest!=='function') return null;
490
- var current=el;
491
- var depth=0;
492
- while(current&&current.nodeType===1&&depth<8){
493
- if(isTransientRootCandidate(current)){
494
- var style=window.getComputedStyle?window.getComputedStyle(current):null;
495
- return {
496
- kind:detectTransientKind(current),
497
- root_selector_chain:getSelectorChain(current),
498
- root_fingerprint:getDomFingerprint(current),
499
- is_portaled:isLikelyPortaled(current),
500
- z_index:parseZIndex(style?style.zIndex:0),
501
- is_fixed:style?style.position==='fixed':false,
502
- opener_candidates:getOpenerCandidates()
503
- };
504
- }
505
- current=current.parentElement;
506
- depth++;
507
- }
508
- return null;
509
- }
510
-
511
- function getVisibleText(node){
512
- try{
513
- if(!node||!node.textContent) return '';
514
- return shortText(String(node.textContent).replace(/\\s+/g,' ').trim()).toLowerCase();
515
- }catch(e){}
516
- return '';
517
- }
518
-
519
- function getSourceDebugInfo(fiber){
520
- var current=fiber;
521
- var steps=0;
522
- while(current&&steps<24){
523
- if(current._debugSource){
524
- return current._debugSource;
525
- }
526
- current=current.return||null;
527
- steps++;
528
- }
529
- return null;
530
- }
531
-
532
- function buildCoordFallback(clientX,clientY,metrics){
533
- var safeViewW=metrics.viewWidth||1;
534
- var safeViewH=metrics.viewHeight||1;
535
- var docX=clientX+metrics.scrollX;
536
- var docY=clientY+metrics.scrollY;
537
- return {
538
- x_percent:clampPercent((clientX/safeViewW)*100),
539
- y_percent:clampPercent((clientY/safeViewH)*100),
540
- scroll_x:metrics.scrollX,
541
- scroll_y:metrics.scrollY,
542
- viewport_width:safeViewW,
543
- viewport_height:safeViewH,
544
- doc_width:metrics.docWidth||safeViewW,
545
- doc_height:metrics.docHeight||safeViewH,
546
- doc_x_percent:clampPercent((docX/(metrics.docWidth||safeViewW))*100),
547
- doc_y_percent:clampPercent((docY/(metrics.docHeight||safeViewH))*100)
548
- };
549
- }
550
-
551
- function buildAnchorPayload(el,clientX,clientY){
552
- var sourceTarget=findBestSourceAnchorTarget(el);
553
- var anchorEl=sourceTarget.element||el;
554
- var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl)||null;
555
- var metrics=getMetrics();
556
- var textSelf='';
557
- var textParent='';
558
- try{
559
- textSelf=shortText(el&&el.textContent);
560
- textParent=shortText(el&&el.parentElement&&el.parentElement.textContent);
561
- }catch(e){}
562
- var fallback=buildCoordFallback(clientX,clientY,metrics);
563
- try{
564
- var rect=anchorEl&&anchorEl.getBoundingClientRect?anchorEl.getBoundingClientRect():null;
565
- if(rect){
566
- var safeW=Math.max(1,rect.width||1);
567
- var safeH=Math.max(1,rect.height||1);
568
- fallback.element_x_percent=clampPercent(((clientX-rect.left)/safeW)*100);
569
- fallback.element_y_percent=clampPercent(((clientY-rect.top)/safeH)*100);
570
- }
571
- }catch(e){}
572
- return {
573
- selector_chain:[],
574
- dom_fingerprint:null,
575
- text_context:{
576
- self:textSelf,
577
- parent:textParent
578
- },
579
- container_hint:null,
580
- transient_context:getTransientContext(el),
581
- source_anchor:sourceAnchor,
582
- coord_fallback:fallback
583
- };
584
- }
585
-
586
- function getTargetDocPoint(payload,metrics){
587
- var fallback=payload&&payload.coord_fallback;
588
- if(!fallback||typeof fallback!=='object') return null;
589
- var docW=(typeof fallback.doc_width==='number'&&fallback.doc_width>0)
590
- ? fallback.doc_width
591
- : (metrics.docWidth||metrics.viewWidth||1);
592
- var docH=(typeof fallback.doc_height==='number'&&fallback.doc_height>0)
593
- ? fallback.doc_height
594
- : (metrics.docHeight||metrics.viewHeight||1);
595
- if(typeof fallback.doc_x_percent==='number'&&typeof fallback.doc_y_percent==='number'){
596
- return {
597
- x:(fallback.doc_x_percent/100)*docW,
598
- y:(fallback.doc_y_percent/100)*docH
599
- };
600
- }
601
- if(typeof fallback.x_percent==='number'&&typeof fallback.y_percent==='number'){
602
- var viewW=(typeof fallback.viewport_width==='number'&&fallback.viewport_width>0)
603
- ? fallback.viewport_width
604
- : (metrics.viewWidth||1);
605
- var viewH=(typeof fallback.viewport_height==='number'&&fallback.viewport_height>0)
606
- ? fallback.viewport_height
607
- : (metrics.viewHeight||1);
608
- var scrollX=typeof fallback.scroll_x==='number'?fallback.scroll_x:metrics.scrollX;
609
- var scrollY=typeof fallback.scroll_y==='number'?fallback.scroll_y:metrics.scrollY;
610
- return {
611
- x:(fallback.x_percent/100)*viewW+scrollX,
612
- y:(fallback.y_percent/100)*viewH+scrollY
613
- };
614
- }
615
- return null;
616
- }
617
-
618
- function getAnchorClientPoint(el,payload){
619
- var rect=el.getBoundingClientRect();
620
- var safeW=Math.max(2,rect.width||2);
621
- var safeH=Math.max(2,rect.height||2);
622
- var relX=0.5;
623
- var relY=0.5;
624
- var fallback=payload&&payload.coord_fallback;
625
- if(fallback&&typeof fallback.element_x_percent==='number'){
626
- relX=clampPercent(fallback.element_x_percent)/100;
627
- }
628
- if(fallback&&typeof fallback.element_y_percent==='number'){
629
- relY=clampPercent(fallback.element_y_percent)/100;
630
- }
631
- return {
632
- clientX:rect.left+Math.max(1,Math.min(safeW-1,safeW*relX)),
633
- clientY:rect.top+Math.max(1,Math.min(safeH-1,safeH*relY))
634
- };
635
- }
636
-
637
- function siblingPathDistance(el,path){
638
- if(!Array.isArray(path)||path.length===0) return 0;
639
- var current=getSiblingPath(el);
640
- var maxLen=Math.max(current.length,path.length);
641
- var dist=Math.abs(current.length-path.length)*5;
642
- var cOffset=maxLen-current.length;
643
- var pOffset=maxLen-path.length;
644
- for(var i=0;i<maxLen;i++){
645
- var cVal=current[i-cOffset];
646
- var pVal=path[i-pOffset];
647
- if(typeof cVal==='number'&&typeof pVal==='number'){
648
- dist+=Math.abs(cVal-pVal);
649
- }else{
650
- dist+=2;
651
- }
652
- }
653
- return dist;
654
- }
655
-
656
- function getReactFiberNode(el){
657
- if(!el||typeof el!=='object') return null;
658
- try{
659
- var keys=Object.keys(el);
660
- for(var i=0;i<keys.length;i++){
661
- var key=keys[i];
662
- if(key.indexOf('__reactFiber$')===0||key.indexOf('__reactInternalInstance$')===0){
663
- return el[key];
664
- }
665
- }
666
- }catch(e){}
667
- return null;
668
- }
669
-
670
- function getReactFiberName(fiber){
671
- try{
672
- if(!fiber) return '';
673
- var t=fiber.type||fiber.elementType;
674
- if(typeof t==='string') return t;
675
- if(t&&typeof t.displayName==='string'&&t.displayName) return t.displayName;
676
- if(t&&typeof t.name==='string'&&t.name) return t.name;
677
- }catch(e){}
678
- return '';
679
- }
680
-
681
- function getReactOwnerPath(el){
682
- var fiber=getReactFiberNode(el);
683
- if(!fiber) return [];
684
- var path=[];
685
- var current=fiber;
686
- var steps=0;
687
- while(current&&steps<24){
688
- var name=getReactFiberName(current);
689
- if(name){
690
- var keyVal=current.key!=null?String(current.key):'';
691
- path.push(keyVal?name+'#'+keyVal:name);
692
- }
693
- current=current.return||null;
694
- steps++;
695
- }
696
- path.reverse();
697
- if(path.length>12){
698
- path=path.slice(path.length-12);
699
- }
700
- return path;
701
- }
702
-
703
- function getExplicitAnchorId(el){
704
- if(!el||typeof el.closest!=='function') return '';
705
- var holder=el.closest('[data-checkpoint-anchor]');
706
- if(!holder||!holder.getAttribute) return '';
707
- return holder.getAttribute('data-checkpoint-anchor')||'';
708
- }
709
-
710
- function getSourceAnchor(el){
711
- var fiber=getReactFiberNode(el);
712
- var ownerPath=getReactOwnerPath(el);
713
- var source=getSourceDebugInfo(fiber);
714
- var component=getReactFiberName(fiber);
715
- var explicitId=getExplicitAnchorId(el);
716
- var reactKey=fiber&&fiber.key!=null?String(fiber.key):'';
717
- var hasData=!!(explicitId||component||ownerPath.length>0||source||reactKey);
718
- if(!hasData) return null;
719
- return {
720
- explicit_id:explicitId||undefined,
721
- component_name:component||undefined,
722
- owner_path:ownerPath,
723
- source_file:source&&source.fileName?String(source.fileName):undefined,
724
- source_line:source&&typeof source.lineNumber==='number'?source.lineNumber:undefined,
725
- source_column:source&&typeof source.columnNumber==='number'?source.columnNumber:undefined,
726
- react_key:reactKey||undefined,
727
- host_tag:el&&el.tagName?String(el.tagName).toLowerCase():undefined
728
- };
729
- }
730
-
731
- function getSourceAnchorStrength(anchor){
732
- if(!anchor||typeof anchor!=='object') return 0;
733
- var score=0;
734
- if(anchor.explicit_id) score+=2000;
735
- if(anchor.react_key) score+=400;
736
- if(anchor.source_file) score+=420;
737
- if(typeof anchor.source_line==='number') score+=260;
738
- if(anchor.component_name) score+=160;
739
- if(Array.isArray(anchor.owner_path)&&anchor.owner_path.length>0){
740
- score+=Math.min(220,anchor.owner_path.length*28);
741
- }
742
- return score;
743
- }
744
-
745
- function findBestSourceAnchorTarget(el){
746
- if(!el||el.nodeType!==1) return { element:el, sourceAnchor:null };
747
- var current=el;
748
- var bestEl=el;
749
- var bestAnchor=null;
750
- var bestScore=0;
751
- var depth=0;
752
- while(current&&current.nodeType===1&&depth<12){
753
- var anchor=getSourceAnchor(current);
754
- var score=getSourceAnchorStrength(anchor);
755
- if(score>bestScore){
756
- bestScore=score;
757
- bestAnchor=anchor;
758
- bestEl=current;
759
- }
760
- if(anchor&&anchor.explicit_id){
761
- return { element:current, sourceAnchor:anchor };
762
- }
763
- current=current.parentElement;
764
- depth++;
765
- }
766
- return { element:bestEl, sourceAnchor:bestAnchor };
767
- }
768
-
769
- function ownerPathSuffixMatches(current,expected){
770
- if(!Array.isArray(current)||!Array.isArray(expected)||current.length===0||expected.length===0) return 0;
771
- var i=current.length-1;
772
- var j=expected.length-1;
773
- var matches=0;
774
- while(i>=0&&j>=0){
775
- if(current[i]!==expected[j]) break;
776
- matches++;
777
- i--;
778
- j--;
779
- }
780
- return matches;
781
- }
782
-
783
- function sourceMatchScore(node,sourceAnchor){
784
- if(!sourceAnchor||typeof sourceAnchor!=='object') return 0;
785
- var score=0;
786
- var explicit=getExplicitAnchorId(node);
787
- if(sourceAnchor.explicit_id){
788
- if(explicit===sourceAnchor.explicit_id) score+=1400;
789
- else if(explicit) score-=300;
790
- }
791
- var fiber=getReactFiberNode(node);
792
- if(fiber){
793
- var component=getReactFiberName(fiber);
794
- if(sourceAnchor.component_name&&component===sourceAnchor.component_name){
795
- score+=180;
796
- }
797
- if(sourceAnchor.react_key&&fiber.key!=null&&String(fiber.key)===sourceAnchor.react_key){
798
- score+=260;
799
- }
800
- var currentPath=getReactOwnerPath(node);
801
- var suffix=ownerPathSuffixMatches(currentPath,sourceAnchor.owner_path);
802
- if(suffix>0){
803
- score+=suffix*80;
804
- }
805
- var source=getSourceDebugInfo(fiber);
806
- if(source&&sourceAnchor.source_file){
807
- var currentFile=String(source.fileName||'');
808
- var targetFile=String(sourceAnchor.source_file||'');
809
- if(currentFile===targetFile){
810
- score+=260;
811
- if(typeof sourceAnchor.source_line==='number'&&source.lineNumber===sourceAnchor.source_line){
812
- score+=280;
813
- }
814
- if(typeof sourceAnchor.source_column==='number'&&source.columnNumber===sourceAnchor.source_column){
815
- score+=60;
816
- }
817
- }
818
- }
819
- }
820
- if(sourceAnchor.host_tag&&node&&node.tagName&&String(node.tagName).toLowerCase()===sourceAnchor.host_tag){
821
- score+=35;
822
- }
823
- return score;
824
- }
825
-
826
- function textMatchScore(node,payload){
827
- if(!payload||!payload.text_context) return 0;
828
- var tc=payload.text_context;
829
- var selfText=getVisibleText(node);
830
- var parentText=node.parentElement?getVisibleText(node.parentElement):'';
831
- var bonus=0;
832
- if(tc.self&&selfText&&tc.self.length>2){
833
- if(selfText===tc.self.toLowerCase()) bonus+=200;
834
- else if(selfText.indexOf(tc.self.toLowerCase())>=0||tc.self.toLowerCase().indexOf(selfText)>=0) bonus+=80;
835
- }
836
- if(tc.parent&&parentText&&tc.parent.length>2){
837
- if(parentText===tc.parent.toLowerCase()) bonus+=100;
838
- else if(parentText.indexOf(tc.parent.toLowerCase())>=0||tc.parent.toLowerCase().indexOf(parentText)>=0) bonus+=40;
839
- }
840
- return bonus;
841
- }
842
-
843
- function pickBestElement(nodes,payload,metrics,fingerprintPath){
844
- if(!nodes||nodes.length===0) return { element:null, bestScore:Infinity };
845
- var target=getTargetDocPoint(payload,metrics);
846
- var best=null;
847
- var bestScore=Infinity;
848
- for(var i=0;i<nodes.length;i++){
849
- var node=nodes[i];
850
- if(!node||node.nodeType!==1) continue;
851
- var anchorPoint=getAnchorClientPoint(node,payload);
852
- var docX=anchorPoint.clientX+metrics.scrollX;
853
- var docY=anchorPoint.clientY+metrics.scrollY;
854
- var score=0;
855
- if(target){
856
- var dx=docX-target.x;
857
- var dy=docY-target.y;
858
- score+=Math.sqrt(dx*dx+dy*dy);
859
- }
860
- if(Array.isArray(fingerprintPath)&&fingerprintPath.length>0){
861
- score+=siblingPathDistance(node,fingerprintPath)*40;
862
- }
863
- var tBonus=textMatchScore(node,payload);
864
- score=Math.max(0,score-tBonus);
865
- if(score<bestScore){
866
- best=node;
867
- bestScore=score;
868
- }
869
- }
870
- if(!best) return { element:null, bestScore:Infinity };
871
- return { element:best, bestScore:bestScore };
872
- }
873
-
874
- function querySelectorAllSafe(scope,selector){
875
- if(!scope||!selector) return [];
876
- try{
877
- var nodeList=scope.querySelectorAll(selector);
878
- return nodeList?Array.prototype.slice.call(nodeList):[];
879
- }catch(e){}
880
- return [];
881
- }
882
-
883
- function resolveFromFingerprint(fingerprint,payload,metrics,scope){
884
- if(!fingerprint) return { element:null, bestScore:Infinity };
885
- var searchScope=scope||document;
886
- if(fingerprint.id){
887
- var byId=searchScope.getElementById?searchScope.getElementById(fingerprint.id):null;
888
- if(!byId&&searchScope.querySelector){
889
- try{ byId=searchScope.querySelector('#'+cssEscape(fingerprint.id)); }catch(e){}
890
- }
891
- if(byId) return { element:byId, bestScore:0 };
892
- }
893
- var tag=fingerprint.tag||'*';
894
- var selector=tag;
895
- if(Array.isArray(fingerprint.classes)&&fingerprint.classes.length>0){
896
- selector+= '.'+fingerprint.classes.map(cssEscape).join('.');
897
- }
898
- var nodes=querySelectorAllSafe(searchScope,selector);
899
- return pickBestElement(nodes,payload,metrics,fingerprint.sibling_path);
900
- }
901
-
902
- function resolveFromSourceAnchor(sourceAnchor,payload,metrics,scope){
903
- if(!sourceAnchor||typeof sourceAnchor!=='object'){
904
- return { element:null, score:0 };
905
- }
906
- var searchScope=scope||document;
907
- var best=null;
908
- var bestScore=0;
909
- var target=getTargetDocPoint(payload,metrics);
910
-
911
- function consider(nodes){
912
- for(var i=0;i<nodes.length;i++){
913
- var node=nodes[i];
914
- if(!node||node.nodeType!==1) continue;
915
- var score=sourceMatchScore(node,sourceAnchor);
916
- if(score<=0) continue;
917
- if(target){
918
- var point=getAnchorClientPoint(node,payload);
919
- var dx=(point.clientX+metrics.scrollX)-target.x;
920
- var dy=(point.clientY+metrics.scrollY)-target.y;
921
- var dist=Math.sqrt(dx*dx+dy*dy);
922
- score-=Math.min(280,dist*0.7);
923
- }
924
- if(score>bestScore){
925
- best=node;
926
- bestScore=score;
927
- }
928
- }
929
- }
930
-
931
- if(sourceAnchor.explicit_id){
932
- var explicitNodes=querySelectorAllSafe(searchScope,'[data-checkpoint-anchor=\"'+cssEscape(sourceAnchor.explicit_id)+'\"]');
933
- consider(explicitNodes);
934
- if(!best&&searchScope!==document){
935
- consider(querySelectorAllSafe(document,'[data-checkpoint-anchor=\"'+cssEscape(sourceAnchor.explicit_id)+'\"]'));
936
- }
937
- if(best){
938
- return { element:best, score:bestScore };
939
- }
940
- }
941
-
942
- var tag=sourceAnchor.host_tag||((payload.dom_fingerprint&&payload.dom_fingerprint.tag)||'*');
943
- var nodes=querySelectorAllSafe(searchScope,tag);
944
- if(nodes.length>1800){
945
- nodes=nodes.slice(0,1800);
946
- }
947
- consider(nodes);
948
- if(!best&&searchScope!==document){
949
- var docNodes=querySelectorAllSafe(document,tag);
950
- if(docNodes.length>1800){
951
- docNodes=docNodes.slice(0,1800);
952
- }
953
- consider(docNodes);
954
- }
955
- var minScore=160;
956
- if(sourceAnchor.explicit_id) minScore=900;
957
- else if(sourceAnchor.source_file) minScore=260;
958
- if(bestScore<minScore){
959
- return { element:null, score:bestScore };
960
- }
961
- return { element:best, score:bestScore };
962
- }
963
-
964
- function isStrongContainerHint(hint){
965
- if(!hint||typeof hint!=='object') return false;
966
- if(typeof hint.id==='string'&&hint.id.length>0) return true;
967
- if(typeof hint.selector==='string'){
968
- if(hint.selector.indexOf('#')===0) return true;
969
- if(hint.selector.indexOf('[data-testid')>=0) return true;
970
- if(hint.selector.indexOf('[role=')>=0) return true;
971
- }
972
- return false;
973
- }
974
-
975
- function resolveTransientRoot(payload,metrics){
976
- var transient=payload&&payload.transient_context;
977
- if(!transient||typeof transient!=='object') return null;
978
- var root=null;
979
- if(Array.isArray(transient.root_selector_chain)){
980
- for(var i=0;i<transient.root_selector_chain.length;i++){
981
- var candidate=transient.root_selector_chain[i];
982
- if(!candidate||typeof candidate.selector!=='string') continue;
983
- var nodes=querySelectorAllSafe(document,candidate.selector);
984
- var rootMatch=pickBestElement(nodes,payload,metrics,transient.root_fingerprint&&transient.root_fingerprint.sibling_path);
985
- root=rootMatch.element;
986
- if(root) return root;
987
- }
988
- }
989
- root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document).element;
990
- return root;
991
- }
992
-
993
- function resolveAnchor(payload){
994
- if(!payload||typeof payload!=='object') return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
995
- var metrics=getMetrics();
996
- var transientRoot=null;
997
- var hasTransientContext=!!(payload.transient_context&&typeof payload.transient_context==='object');
998
- if(hasTransientContext){
999
- transientRoot=resolveTransientRoot(payload,metrics);
1000
- if(!transientRoot){
1001
- return {coordFallback:null,strategy:'transient_missing',matchedSelector:null,status:'transient_missing'};
1002
- }
1003
- }
1004
-
1005
- if(!payload.source_anchor){
1006
- if(payload.coord_fallback){
1007
- return {
1008
- coordFallback:payload.coord_fallback,
1009
- strategy:'fallback',
1010
- matchedSelector:'legacy_coord_fallback',
1011
- status:'fallback_only'
1012
- };
1013
- }
1014
- return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
1015
- }
1016
-
1017
- var sourceScope=transientRoot||document;
1018
- var sourceMatch=resolveFromSourceAnchor(payload.source_anchor,payload,metrics,sourceScope);
1019
- if(!sourceMatch||!sourceMatch.element){
1020
- return {coordFallback:null,strategy:'fallback',matchedSelector:'source_anchor_miss',status:'fallback_only'};
1021
- }
1022
- var point=getAnchorClientPoint(sourceMatch.element,payload);
1023
- var clientX=point.clientX;
1024
- var clientY=point.clientY;
1025
- return {
1026
- coordFallback:buildCoordFallback(clientX,clientY,metrics),
1027
- strategy:'source',
1028
- matchedSelector:'source_anchor',
1029
- status:'resolved'
1030
- };
1031
- }
1032
-
1033
- function setPickMode(enabled){
1034
- var next=!!enabled;
1035
- if(pickMode===next) return;
1036
- pickMode=next;
1037
- document.documentElement.style.cursor=pickMode?'crosshair':'';
1038
- if(document.body){
1039
- document.body.style.cursor=pickMode?'crosshair':'';
1040
- }
1041
- if(!pickMode){
1042
- if(pickClickHandler){
1043
- window.removeEventListener('click',pickClickHandler,true);
1044
- pickClickHandler=null;
1045
- }
1046
- if(pickPointerDownHandler){
1047
- window.removeEventListener('pointerdown',pickPointerDownHandler,true);
1048
- pickPointerDownHandler=null;
1049
- }
1050
- if(pickMoveHandler){
1051
- document.removeEventListener('mousemove',pickMoveHandler,true);
1052
- pickMoveHandler=null;
1053
- }
1054
- if(pickEscHandler){
1055
- window.removeEventListener('keydown',pickEscHandler,true);
1056
- pickEscHandler=null;
1057
- }
1058
- if(pickHoverRaf){
1059
- cancelAnimationFrame(pickHoverRaf);
1060
- pickHoverRaf=0;
1061
- }
1062
- hidePickInspectUi();
1063
- return;
1064
- }
1065
- pickMoveHandler=function(ev){
1066
- if(!pickMode) return;
1067
- pickLastMouseX=ev.clientX;
1068
- pickLastMouseY=ev.clientY;
1069
- if(pickHoverRaf) return;
1070
- pickHoverRaf=requestAnimationFrame(function(){
1071
- pickHoverRaf=0;
1072
- var target=getElementAtPoint(pickLastMouseX,pickLastMouseY)||getEventElement(ev);
1073
- renderPickInspect(target,pickLastMouseX,pickLastMouseY);
1074
- });
1075
- };
1076
- pickPointerDownHandler=function(ev){
1077
- if(!pickMode) return;
1078
- var target=getElementAtPoint(ev.clientX,ev.clientY)||getEventElement(ev);
1079
- if(!target) return;
1080
- ev.preventDefault();
1081
- ev.stopPropagation();
1082
- if(typeof ev.stopImmediatePropagation==='function'){
1083
- ev.stopImmediatePropagation();
1084
- }
1085
- try{
1086
- var payload=buildAnchorPayload(target,ev.clientX,ev.clientY);
1087
- window.parent.postMessage({
1088
- type:'checkpoint:pickResult',
1089
- path:location.pathname+location.search+location.hash,
1090
- anchorPayload:payload,
1091
- point:{
1092
- xPercent:payload.coord_fallback&&typeof payload.coord_fallback.x_percent==='number'?payload.coord_fallback.x_percent:50,
1093
- yPercent:payload.coord_fallback&&typeof payload.coord_fallback.y_percent==='number'?payload.coord_fallback.y_percent:50,
1094
- scrollY:payload.coord_fallback&&typeof payload.coord_fallback.scroll_y==='number'?payload.coord_fallback.scroll_y:0,
1095
- viewHeight:payload.coord_fallback&&typeof payload.coord_fallback.viewport_height==='number'?payload.coord_fallback.viewport_height:0
1096
- }
1097
- },'*');
1098
- }catch(e){}
1099
- setPickMode(false);
1100
- };
1101
- pickClickHandler=function(ev){
1102
- try{
1103
- if(!pickMode) return;
1104
- ev.preventDefault();
1105
- ev.stopPropagation();
1106
- if(typeof ev.stopImmediatePropagation==='function'){
1107
- ev.stopImmediatePropagation();
1108
- }
1109
- var target=getEventElement(ev);
1110
- if(!target) return;
1111
- var payload=buildAnchorPayload(target,ev.clientX,ev.clientY);
1112
- window.parent.postMessage({
1113
- type:'checkpoint:pickResult',
1114
- path:location.pathname+location.search+location.hash,
1115
- anchorPayload:payload,
1116
- point:{
1117
- xPercent:payload.coord_fallback&&typeof payload.coord_fallback.x_percent==='number'?payload.coord_fallback.x_percent:50,
1118
- yPercent:payload.coord_fallback&&typeof payload.coord_fallback.y_percent==='number'?payload.coord_fallback.y_percent:50,
1119
- scrollY:payload.coord_fallback&&typeof payload.coord_fallback.scroll_y==='number'?payload.coord_fallback.scroll_y:0,
1120
- viewHeight:payload.coord_fallback&&typeof payload.coord_fallback.viewport_height==='number'?payload.coord_fallback.viewport_height:0
1121
- }
1122
- },'*');
1123
- }catch(e){}
1124
- setPickMode(false);
1125
- };
1126
- pickEscHandler=function(ev){
1127
- if(ev.key==='Escape'){
1128
- setPickMode(false);
1129
- }
1130
- };
1131
- document.addEventListener('mousemove',pickMoveHandler,true);
1132
- window.addEventListener('pointerdown',pickPointerDownHandler,true);
1133
- window.addEventListener('click',pickClickHandler,true);
1134
- window.addEventListener('keydown',pickEscHandler,true);
1135
- }
1136
-
1137
- function reportNav(){
1138
- try{
1139
- var p=location.pathname+location.search+location.hash;
1140
- if(p!==lastPath){
1141
- lastPath=p;
1142
- window.parent.postMessage({
1143
- type:'checkpoint:navigate',
1144
- path:p
1145
- },'*');
1146
- reportScroll();
1147
- }
1148
- }catch(e){}
1149
- }
1150
- var scrollTick=false;
1151
- function reportScroll(){
1152
- try{
1153
- var metrics=getMetrics();
1154
- window.parent.postMessage({
1155
- type:'checkpoint:scroll',
1156
- scrollX:metrics.scrollX,
1157
- scrollY:metrics.scrollY,
1158
- docWidth:metrics.docWidth,
1159
- docHeight:metrics.docHeight,
1160
- viewWidth:metrics.viewWidth,
1161
- viewHeight:metrics.viewHeight
1162
- },'*');
1163
- }catch(e){}
1164
- }
1165
- function onScroll(){
1166
- if(!scrollTick){
1167
- scrollTick=true;
1168
- requestAnimationFrame(function(){
1169
- reportScroll();
1170
- scrollTick=false;
1171
- });
1172
- }
1173
- }
1174
-
1175
- var mutationTick=false;
1176
- function reportDomMutation(reason){
1177
- try{
1178
- window.parent.postMessage({
1179
- type:'checkpoint:domMutation',
1180
- reason:reason||'mutation',
1181
- path:location.pathname+location.search+location.hash
1182
- },'*');
1183
- }catch(e){}
1184
- }
1185
-
1186
- function onMutation(){
1187
- if(mutationTick) return;
1188
- mutationTick=true;
1189
- requestAnimationFrame(function(){
1190
- mutationTick=false;
1191
- reportScroll();
1192
- reportDomMutation('mutation');
1193
- });
1194
- }
1195
-
1196
- function setupMutationObserver(){
1197
- try{
1198
- if(!window.MutationObserver||!document.documentElement) return;
1199
- var observer=new MutationObserver(function(mutations){
1200
- for(var i=0;i<mutations.length;i++){
1201
- var m=mutations[i];
1202
- if(m.type==='childList'){
1203
- if((m.addedNodes&&m.addedNodes.length>0)||(m.removedNodes&&m.removedNodes.length>0)){
1204
- onMutation();
1205
- return;
1206
- }
1207
- }
1208
- if(m.type==='attributes'){
1209
- onMutation();
1210
- return;
1211
- }
1212
- }
1213
- });
1214
- observer.observe(document.documentElement,{
1215
- childList:true,
1216
- subtree:true,
1217
- attributes:true,
1218
- attributeFilter:['class','style','aria-hidden','aria-modal','data-state','open']
1219
- });
1220
- window.addEventListener('beforeunload',function(){ try{observer.disconnect();}catch(e){}; });
1221
- }catch(e){}
1222
- }
1223
-
1224
- reportNav();
1225
- reportScroll();
1226
- setupMutationObserver();
1227
- var _ps=history.pushState,_rs=history.replaceState;
1228
- history.pushState=function(){_ps.apply(this,arguments);reportNav();};
1229
- history.replaceState=function(){_rs.apply(this,arguments);reportNav();};
1230
- window.addEventListener('popstate',reportNav);
1231
- window.addEventListener('hashchange',reportNav);
1232
- window.addEventListener('scroll',onScroll,{passive:true});
1233
- document.addEventListener('scroll',onScroll,true);
1234
- window.addEventListener('resize',reportScroll);
1235
- window.addEventListener('message',function(e){
1236
- try{
1237
- if(e.data&&e.data.type==='checkpoint:scrollTo'&&typeof e.data.y==='number'){
1238
- window.scrollTo({top:e.data.y,behavior:'smooth'});
1239
- }
1240
- if(e.data&&e.data.type==='checkpoint:pickMode'){
1241
- setPickMode(!!e.data.enabled);
1242
- }
1243
- if(e.data&&e.data.type==='checkpoint:resolveAnchors'&&Array.isArray(e.data.items)){
1244
- var positions=[];
1245
- for(var i=0;i<e.data.items.length;i++){
1246
- var item=e.data.items[i];
1247
- if(!item||typeof item.id!=='string') continue;
1248
- var result=resolveAnchor(item.anchorPayload);
1249
- positions.push({
1250
- id:item.id,
1251
- found:!!result.coordFallback,
1252
- status:result.status||'none',
1253
- strategy:result.strategy,
1254
- matchedSelector:result.matchedSelector,
1255
- coordFallback:result.coordFallback||null
1256
- });
1257
- }
1258
- window.parent.postMessage({
1259
- type:'checkpoint:anchorsResolved',
1260
- path:location.pathname+location.search+location.hash,
1261
- positions:positions
1262
- },'*');
1263
- }
1264
- }catch(ex){}
1265
- });
1266
- setInterval(reportNav,500);
1267
- })();
1268
- </script>`.trim();
1269
- }
1270
82
  /* ── Injection Proxy ── */
1271
83
  function startInjectionProxy(targetPort) {
1272
84
  const scriptBody = (0, tracking_script_minimal_js_1.buildMinimalTrackingScript)().replace(/<\/script/gi, '<\\/script');
@@ -1606,7 +418,7 @@ const program = new commander_1.Command();
1606
418
  program
1607
419
  .name('checkpoint')
1608
420
  .description('Share your localhost with reviewers — get visual feedback directly on the page')
1609
- .version('0.3.7');
421
+ .version('0.3.9');
1610
422
  // ── checkpoint login ──
1611
423
  program
1612
424
  .command('login')
@@ -190,6 +190,15 @@ function buildMinimalTrackingScript() {
190
190
  return score;
191
191
  }
192
192
 
193
+ function hasOwnerPathKey(anchor){
194
+ if(!anchor||!Array.isArray(anchor.owner_path)) return false;
195
+ for(var i=0;i<anchor.owner_path.length;i++){
196
+ var part=anchor.owner_path[i];
197
+ if(typeof part==='string'&&part.indexOf('#')>0) return true;
198
+ }
199
+ return false;
200
+ }
201
+
193
202
  function findBestAnchorableElement(el){
194
203
  if(!el||el.nodeType!==1) return { element:el, sourceAnchor:null };
195
204
  var current=el;
@@ -208,6 +217,10 @@ function buildMinimalTrackingScript() {
208
217
  if(anchor&&anchor.explicit_id){
209
218
  return { element:current, sourceAnchor:anchor };
210
219
  }
220
+ // Prefer keyed instances in repeated lists/grids.
221
+ if(anchor&&(anchor.react_key||hasOwnerPathKey(anchor))){
222
+ return { element:current, sourceAnchor:anchor };
223
+ }
211
224
  current=current.parentElement;
212
225
  depth++;
213
226
  }
@@ -221,7 +234,7 @@ function buildMinimalTrackingScript() {
221
234
  var score=0;
222
235
  while(i>=0&&j>=0){
223
236
  if(current[i]!==expected[j]) break;
224
- score+=100;
237
+ score+=(String(expected[j]).indexOf('#')>0?180:100);
225
238
  i--;
226
239
  j--;
227
240
  }
@@ -471,10 +484,10 @@ function buildMinimalTrackingScript() {
471
484
  inspectBox.style.top='0';
472
485
  inspectBox.style.width='0';
473
486
  inspectBox.style.height='0';
474
- inspectBox.style.border='2px solid #6366f1';
475
- inspectBox.style.background='rgba(99,102,241,0.12)';
476
- inspectBox.style.boxSizing='border-box';
477
- inspectBox.style.borderRadius='4px';
487
+ inspectBox.style.border='2px solid #F26522';
488
+ inspectBox.style.background='rgba(242,101,34,0.12)';
489
+ inspectBox.style.boxSizing='border-box';
490
+ inspectBox.style.borderRadius='0';
478
491
  inspectBox.style.pointerEvents='none';
479
492
  inspectBox.style.zIndex='2147483646';
480
493
  inspectBox.style.display='none';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "checkpoint-cli",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "Share your localhost with reviewers — get visual feedback directly on the page",
5
5
  "keywords": [
6
6
  "checkpoint",