@xbrowser/cli 1.18.2 → 1.19.0

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/cli.js CHANGED
@@ -72,7 +72,7 @@ import {
72
72
  setActivePage,
73
73
  sleep,
74
74
  wheelDelta
75
- } from "./chunk-7SDM4EA4.js";
75
+ } from "./chunk-KLXLNQI5.js";
76
76
  import "./chunk-3KZ34AUC.js";
77
77
  import {
78
78
  errMsg
@@ -203,8 +203,8 @@ function asZodSchema(value) {
203
203
 
204
204
  // src/executor.ts
205
205
  import {
206
- ok as ok28,
207
- fail as fail13,
206
+ ok as ok30,
207
+ fail as fail15,
208
208
  isCommandResult,
209
209
  CompositeStorage as CompositeStorage2,
210
210
  TipCollector as TipCollector2,
@@ -6362,6 +6362,709 @@ function describeSelector(strategy, value, name) {
6362
6362
  }
6363
6363
  }
6364
6364
 
6365
+ // src/commands/visual-tag.ts
6366
+ import { z as z29 } from "zod";
6367
+ import { ok as ok28, fail as fail13 } from "@dyyz1993/xcli-core";
6368
+ var SAFE_SET = "ahjkmnprtw3479".split("");
6369
+ var TAG_SCRIPT = `
6370
+ (function() {
6371
+ // \u6E05\u9664\u65E7\u6807\u6CE8
6372
+ var old = document.getElementById('__xb-tag-overlay');
6373
+ if (old) old.remove();
6374
+ window.__xbTagMap = {};
6375
+
6376
+ var SAFE_SET = ${JSON.stringify(SAFE_SET)};
6377
+ function genId(idx) {
6378
+ var base = SAFE_SET.length;
6379
+ if (idx < base * base) return SAFE_SET[Math.floor(idx / base)] + SAFE_SET[idx % base];
6380
+ var i = idx - base * base;
6381
+ return SAFE_SET[Math.floor(i / (base * base))] + SAFE_SET[Math.floor(i / base) % base] + SAFE_SET[i % base];
6382
+ }
6383
+
6384
+ // \u627E\u6240\u6709\u53EF\u4EA4\u4E92\u5143\u7D20
6385
+ var els = [];
6386
+ var all = document.querySelectorAll('button, a[href], input, select, textarea, [onclick], [role="button"], [contenteditable], [class*="btn"], [class*="button"], [class*="link"]');
6387
+ for (var i = 0; i < all.length && els.length < 200; i++) {
6388
+ var el = all[i];
6389
+ var r = el.getBoundingClientRect();
6390
+ if (r.width < 10 || r.height < 10) continue;
6391
+ if (r.x < 0 || r.y < 0 || r.x + r.width > window.innerWidth || r.y + r.height > window.innerHeight + 100) continue;
6392
+ var style = getComputedStyle(el);
6393
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6394
+ els.push({ el: el, rect: r });
6395
+ }
6396
+
6397
+ // \u521B\u5EFA\u53E0\u52A0 Canvas
6398
+ var canvas = document.createElement('canvas');
6399
+ canvas.id = '__xb-tag-overlay';
6400
+ canvas.width = window.innerWidth;
6401
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6402
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6403
+ document.body.appendChild(canvas);
6404
+ var ctx = canvas.getContext('2d');
6405
+
6406
+ // \u7ED8\u5236\u6807\u7B7E
6407
+ for (var j = 0; j < els.length; j++) {
6408
+ var item = els[j];
6409
+ var id = genId(j);
6410
+ var x = item.rect.x;
6411
+ var y = item.rect.y;
6412
+
6413
+ // \u6807\u7B7E\u6846\uFF1A\u9AD8\u5BF9\u6BD4\uFF08\u9EC4\u5E95\u9ED1\u5B57\uFF09
6414
+ ctx.fillStyle = '#FFD700';
6415
+ ctx.fillRect(x - 2, y - 16, id.length * 8 + 8, 16);
6416
+ ctx.strokeStyle = '#000';
6417
+ ctx.lineWidth = 1.5;
6418
+ ctx.strokeRect(x - 2, y - 16, id.length * 8 + 8, 16);
6419
+ ctx.fillStyle = '#000';
6420
+ ctx.font = 'bold 12px monospace';
6421
+ ctx.fillText(id, x + 2, y - 5);
6422
+
6423
+ // \u5143\u7D20\u8F6E\u5ED3
6424
+ ctx.strokeStyle = '#FF0000';
6425
+ ctx.lineWidth = 1.5;
6426
+ ctx.strokeRect(x, y, item.rect.width, item.rect.height);
6427
+
6428
+ // \u5B58\u50A8 ID \u2192 \u5143\u7D20\u6620\u5C04
6429
+ window.__xbTagMap[id] = {
6430
+ tagName: item.el.tagName,
6431
+ text: (item.el.textContent || '').trim().slice(0, 50),
6432
+ rect: { x: x, y: y, w: item.rect.width, h: item.rect.height },
6433
+ selector: (function(e) {
6434
+ if (e.id) return '#' + e.id;
6435
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6436
+ // \u751F\u6210 nth-child \u9009\u62E9\u5668
6437
+ var path = [];
6438
+ var node = e;
6439
+ while (node && node !== document.body) {
6440
+ var idx = 1;
6441
+ var sib = node.previousElementSibling;
6442
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6443
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6444
+ node = node.parentElement;
6445
+ }
6446
+ return path.join(' > ');
6447
+ })(item.el)
6448
+ };
6449
+ }
6450
+
6451
+ return JSON.stringify({ tagged: els.length, overlay: true });
6452
+ })()
6453
+ `;
6454
+ var visualTagCommand = registerCommand({
6455
+ name: "visual-tag",
6456
+ description: "\u5728\u9875\u9762\u4E0A\u7ED9\u53EF\u4EA4\u4E92\u5143\u7D20\u53E0\u52A0\u9632\u6DF7\u6DC6\u77ED ID \u6807\u7B7E\uFF08\u89C6\u89C9\u5B9A\u4F4D\u7528\uFF09",
6457
+ scope: "page",
6458
+ parameters: z29.object({
6459
+ action: z29.enum(["tag", "lookup", "clear", "list"]),
6460
+ id: z29.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6461
+ }),
6462
+ result: z29.object({
6463
+ action: z29.string(),
6464
+ tagged: z29.number().optional(),
6465
+ id: z29.string().optional(),
6466
+ element: z29.record(z29.unknown()).optional()
6467
+ }),
6468
+ handler: async (p, ctx) => {
6469
+ switch (p.action) {
6470
+ case "tag": {
6471
+ const result = await ctx.page.evaluate(TAG_SCRIPT);
6472
+ const parsed = JSON.parse(result);
6473
+ return ok28({ action: "tag", tagged: parsed.tagged });
6474
+ }
6475
+ case "lookup": {
6476
+ if (!p.id) return fail13("lookup \u9700\u8981 --id \u53C2\u6570");
6477
+ const result = await ctx.page.evaluate(
6478
+ `(function() { var m = window.__xbTagMap; if (!m) return JSON.stringify({err:'no-map'}); var e = m[${JSON.stringify(p.id)}]; return e ? JSON.stringify(e) : JSON.stringify({err:'not-found'}); })()`
6479
+ );
6480
+ const parsed = JSON.parse(result);
6481
+ if (parsed.err) return fail13(`ID ${p.id}: ${parsed.err}`);
6482
+ return ok28({ action: "lookup", id: p.id, element: parsed });
6483
+ }
6484
+ case "list": {
6485
+ const result = await ctx.page.evaluate(
6486
+ `(function() { var m = window.__xbTagMap; if (!m) return '{}'; var out = {}; for (var k in m) { out[k] = m[k].text || m[k].tagName; } return JSON.stringify(out); })()`
6487
+ );
6488
+ return ok28({ action: "list", element: JSON.parse(result) });
6489
+ }
6490
+ case "clear": {
6491
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6492
+ return ok28({ action: "clear" });
6493
+ }
6494
+ }
6495
+ }
6496
+ });
6497
+
6498
+ // src/commands/visual-tag-v2.ts
6499
+ import { z as z30 } from "zod";
6500
+ import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6501
+ var SAFE_SET2 = "ahjkmnprtw3479".split("");
6502
+ var TAG_V2_SCRIPT = `
6503
+ (function() {
6504
+ var old = document.getElementById('__xb-tag-overlay');
6505
+ if (old) old.remove();
6506
+ window.__xbTagMap = {};
6507
+ window.__xbTagStats = {};
6508
+
6509
+ var SAFE_SET = ${JSON.stringify(SAFE_SET2)};
6510
+ var TYPE_PREFIX = { click:'k', input:'n', img:'m', list:'h', count:'p', text:'t' };
6511
+ function genId(prefix, idx) {
6512
+ var base = SAFE_SET.length;
6513
+ var suffix = SAFE_SET[Math.floor(idx / base) % base] + SAFE_SET[idx % base];
6514
+ return prefix + suffix;
6515
+ }
6516
+
6517
+ var counters = { click: 0, input: 0, img: 0, list: 0, count: 0, text: 0 };
6518
+
6519
+ var canvas = document.createElement('canvas');
6520
+ canvas.id = '__xb-tag-overlay';
6521
+ canvas.width = window.innerWidth;
6522
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6523
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6524
+ document.body.appendChild(canvas);
6525
+ var ctx = canvas.getContext('2d');
6526
+
6527
+ function classifyElement(el) {
6528
+ var tag = el.tagName;
6529
+ var text = (el.textContent || '').trim();
6530
+ var cls = el.className || '';
6531
+
6532
+ // \u4F18\u5148\u7EA71\uFF1A\u6570\u5B57/\u8BA1\u6570\u5668\u2014\u2014\u5148\u4E8E\u5217\u8868\uFF08S129 \u9057\u7559\u95EE\u9898\u4FEE\u590D\uFF09
6533
+ var hasOnlySvgChildren = true;
6534
+ for (var ci = 0; ci < el.children.length; ci++) {
6535
+ if (el.children[ci].tagName.toUpperCase() !== 'SVG' && el.children[ci].tagName.toUpperCase() !== 'PATH' && el.children[ci].tagName.toUpperCase() !== 'SPAN') { hasOnlySvgChildren = false; break; }
6536
+ }
6537
+ if ((el.children.length === 0 || hasOnlySvgChildren) && text.length > 0 && text.length < 25) {
6538
+ var numMatch = /^[0-9]/.test(text) && text.length < 20;
6539
+ if (numMatch) return 'count';
6540
+ }
6541
+ // \u4F18\u5148\u7EA71.5\uFF1Aclass \u542B count/num/like/star/fork \u7684\u5BB9\u5668
6542
+ if (/count|num\b|like|star|fork|rating|badge/i.test(cls) && el.children.length <= 2) return 'count';
6543
+
6544
+ // \u4F18\u5148\u7EA72\uFF1A\u8F93\u5165\u6846
6545
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' ||
6546
+ el.getAttribute('contenteditable')) return 'input';
6547
+
6548
+ // \u4F18\u5148\u7EA73\uFF1A\u53EF\u70B9\u51FB\uFF08v3 \u6269\u5BBD\uFF1Adata-target/onclick/tab/menu/nav/link class\uFF09
6549
+ if (tag === 'BUTTON' || (el.getAttribute('role') === 'button') ||
6550
+ (tag === 'A' && el.getAttribute('href')) ||
6551
+ el.hasAttribute('onclick') || el.hasAttribute('data-target') ||
6552
+ /btn|button|click|action|tab\b|menu|nav\b|link\b/i.test(cls)) return 'click';
6553
+
6554
+ // \u4F18\u5148\u7EA74\uFF1A\u56FE\u7247\uFF08v3\uFF1A\u542B SVG \u56FE\u6807\uFF09
6555
+ if (tag === 'IMG' || (tag === 'SVG') ||
6556
+ (el.querySelector && el.querySelector('img,svg') &&
6557
+ el.children.length <= 2 && !text)) return 'img';
6558
+
6559
+ // \u4F18\u5148\u7EA74.5\uFF1A\u8868\u683C\u5355\u5143\u683C
6560
+ if (tag === 'TD' || tag === 'TH') return 'list';
6561
+
6562
+ // \u4F18\u5148\u7EA75\uFF1A\u5217\u8868\uFF08v3\uFF1A\u52A0 card\uFF09
6563
+ if (tag === 'UL' || tag === 'OL' || tag === 'LI' ||
6564
+ /list|item|feed|timeline|card/i.test(cls)) return 'list';
6565
+
6566
+ // \u4F18\u5148\u7EA76\uFF1A\u6587\u672C
6567
+ if (text.length > 20) return 'text';
6568
+ return null;
6569
+ }
6570
+
6571
+ var COLORS = {
6572
+ click: { stroke: '#FF0000', fill: '#FFD700' }, // \u7EA2+\u9EC4
6573
+ input: { stroke: '#0000FF', fill: '#ADD8E6' }, // \u84DD
6574
+ img: { stroke: '#00AA00', fill: '#90EE90' }, // \u7EFF
6575
+ list: { stroke: '#FFAA00', fill: '#FFE4B5' }, // \u6A59\u9EC4
6576
+ count: { stroke: '#9900CC', fill: '#E0B0FF' }, // \u7D2B
6577
+ text: { stroke: '#FF8C00', fill: '#FFECD2' }, // \u6A59
6578
+ };
6579
+
6580
+ var all = document.querySelectorAll('button, a[href], td, th, input, select, textarea, img, ul, ol, li, svg, [onclick], [role="button"], [contenteditable], [aria-label], [data-target], [class*="btn"], [class*="list"], [class*="item"], [class*="count"], [class*="num"], [class*="like"], [class*="comment"], [class*="stat"], [class*="card"], [class*="tab"], [class*="menu"], [class*="nav"], [class*="link"], [class*="Link"], [class*="Card"]');
6581
+
6582
+ for (var i = 0; i < all.length && i < 3000; i++) {
6583
+ var el = all[i];
6584
+ var r = el.getBoundingClientRect();
6585
+ if (r.width < 8 || r.height < 8) continue;
6586
+ if (r.x < -50 || r.y < -50 || r.x > window.innerWidth || r.y > window.innerHeight + 200) continue;
6587
+ var style = getComputedStyle(el);
6588
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6589
+
6590
+ var type = classifyElement(el);
6591
+ if (!type) continue;
6592
+
6593
+ var id = genId(TYPE_PREFIX[type] || 't', counters[type]);
6594
+ counters[type]++;
6595
+ var colors = COLORS[type];
6596
+
6597
+ // \u6807\u7B7E
6598
+ ctx.fillStyle = colors.fill;
6599
+ ctx.fillRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6600
+ ctx.strokeStyle = '#000';
6601
+ ctx.lineWidth = 1;
6602
+ ctx.strokeRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6603
+ ctx.fillStyle = '#000';
6604
+ ctx.font = 'bold 11px monospace';
6605
+ ctx.fillText(id, r.x + 1, r.y - 4);
6606
+
6607
+ // \u5143\u7D20\u6846\uFF08\u5206\u8272\uFF09
6608
+ ctx.strokeStyle = colors.stroke;
6609
+ ctx.lineWidth = 1.5;
6610
+ ctx.strokeRect(r.x, r.y, r.width, r.height);
6611
+
6612
+ // v4\uFF1A\u67E5\u7236\u7EA7\u6807\u6CE8 ID\uFF08\u5D4C\u5957\u5173\u7CFB\uFF09
6613
+ var parentId = null;
6614
+ var parentNode = el.parentElement;
6615
+ while (parentNode && parentNode !== document.body) {
6616
+ for (var pk in window.__xbTagMap) {
6617
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
6618
+ }
6619
+ if (parentId) break;
6620
+ parentNode = parentNode.parentElement;
6621
+ }
6622
+
6623
+ // v6\uFF1A\u8868\u5355\u8BED\u4E49\u2014\u2014\u8BC6\u522B input \u7684\u5173\u8054 label
6624
+ var formLabel = null;
6625
+ if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT') {
6626
+ var inputId = el.id;
6627
+ if (inputId) {
6628
+ var lbl = document.querySelector('label[for="' + inputId + '"]');
6629
+ if (lbl) formLabel = lbl.textContent.trim();
6630
+ }
6631
+ if (!formLabel) {
6632
+ var aria = el.getAttribute('aria-label');
6633
+ if (aria) formLabel = aria;
6634
+ }
6635
+ if (!formLabel) {
6636
+ var ph = el.getAttribute('placeholder');
6637
+ if (ph) formLabel = '(placeholder) ' + ph;
6638
+ }
6639
+ if (!formLabel) {
6640
+ var parentLbl = el.closest('label');
6641
+ if (parentLbl) formLabel = parentLbl.textContent.trim().slice(0, 30);
6642
+ }
6643
+ if (!formLabel) {
6644
+ var prev = el.previousElementSibling;
6645
+ if (prev && (prev.tagName === 'LABEL' || prev.tagName === 'SPAN' || prev.tagName === 'DIV') && prev.textContent.trim()) {
6646
+ formLabel = '(adjacent) ' + prev.textContent.trim().slice(0, 30);
6647
+ }
6648
+ }
6649
+ }
6650
+
6651
+ // v7\uFF1A\u8868\u683C\u8BED\u4E49\u2014\u2014\u5355\u5143\u683C \u2192 \u5217\u540D + \u884C\u53F7
6652
+ var tableInfo = null;
6653
+ if (el.tagName === 'TD' || el.tagName === 'TH') {
6654
+ var table = el.closest('table');
6655
+ if (table) {
6656
+ var row = el.closest('tr');
6657
+ var cellIndex = el.cellIndex;
6658
+ var rowIndex = row ? row.rowIndex : -1;
6659
+ // \u627E\u8868\u5934\uFF08thead \u7684 th \u6216\u7B2C\u4E00\u884C\u7684 th\uFF09
6660
+ var header = table.querySelector('thead th:nth-child(' + (cellIndex + 1) + ')') ||
6661
+ table.querySelector('tr:first-child th:nth-child(' + (cellIndex + 1) + ')');
6662
+ var colName = header ? header.textContent.trim() : 'col-' + (cellIndex + 1);
6663
+ tableInfo = { col: colName, colIndex: cellIndex, rowIndex: rowIndex, value: el.textContent.trim().slice(0, 20) };
6664
+ }
6665
+ }
6666
+
6667
+ window.__xbTagMap[id] = {
6668
+ type: type,
6669
+ parent: parentId,
6670
+ _el: el,
6671
+ formLabel: formLabel,
6672
+ table: tableInfo,
6673
+ tagName: el.tagName,
6674
+ text: (el.textContent || '').trim().slice(0, 40),
6675
+ num: (el.textContent || '').trim().match(/[\\d,.]+/)?.[0] || null,
6676
+ rect: { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) },
6677
+ selector: (function(e) {
6678
+ if (e.id) return '#' + e.id;
6679
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6680
+ var path = [];
6681
+ var node = e;
6682
+ while (node && node !== document.body) {
6683
+ var idx = 1;
6684
+ var sib = node.previousElementSibling;
6685
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6686
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6687
+ node = node.parentElement;
6688
+ }
6689
+ return path.join(' > ');
6690
+ })(el)
6691
+ };
6692
+ }
6693
+
6694
+ // v9\uFF1A\u8DE8 frame \u6807\u6CE8\u2014\u2014\u9012\u5F52\u5904\u7406\u540C\u6E90 iframe \u5185\u7684\u5143\u7D20
6695
+ function tagFrame(doc, offsetX, offsetY) {
6696
+ var frameAll = doc.querySelectorAll('button, a[href], input, select, textarea, img, [onclick], [role=button], [contenteditable], [aria-label]');
6697
+ for (var fi = 0; fi < frameAll.length && fi < 100; fi++) {
6698
+ var fel = frameAll[fi];
6699
+ var fr = fel.getBoundingClientRect();
6700
+ if (fr.width < 8 || fr.height < 8) continue;
6701
+ var fType = classifyElement(fel);
6702
+ if (!fType) continue;
6703
+ var fId = genId(TYPE_PREFIX[fType] || 't', counters[fType]);
6704
+ counters[fType]++;
6705
+ var fColors = COLORS[fType];
6706
+ // \u5750\u6807\u504F\u79FB\u5230\u4E3B\u6587\u6863 Canvas\uFF08iframe \u5728\u4E3B\u6587\u6863\u4E2D\u7684\u4F4D\u7F6E + \u5143\u7D20\u5728 iframe \u4E2D\u7684\u4F4D\u7F6E\uFF09
6707
+ var fx = fr.x + offsetX, fy = fr.y + offsetY;
6708
+ ctx.fillStyle = fColors.fill;
6709
+ ctx.fillRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
6710
+ ctx.strokeStyle = '#000'; ctx.lineWidth = 1;
6711
+ ctx.strokeRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
6712
+ ctx.fillStyle = '#000'; ctx.font = 'bold 11px monospace';
6713
+ ctx.fillText(fId, fx + 1, fy - 4);
6714
+ ctx.strokeStyle = fColors.stroke; ctx.lineWidth = 1.5;
6715
+ ctx.strokeRect(fx, fy, fr.width, fr.height);
6716
+ window.__xbTagMap[fId] = {
6717
+ type: fType, tagName: fel.tagName,
6718
+ text: (fel.textContent||'').trim().slice(0,40),
6719
+ num: (fel.textContent||'').trim().match(/[0-9,.]+/)?.[0] || null,
6720
+ formLabel: (fel.getAttribute('aria-label')||fel.getAttribute('placeholder')||'').slice(0,30) || null,
6721
+ frame: 'iframe',
6722
+ _el: fel,
6723
+ rect: {x:Math.round(fx),y:Math.round(fy),w:Math.round(fr.width),h:Math.round(fr.height)},
6724
+ selector: (function(e){return e.id?'#'+e.id:e.tagName.toLowerCase()}) (fel)
6725
+ };
6726
+ }
6727
+ // \u9012\u5F52\u5904\u7406\u5D4C\u5957 iframe
6728
+ var nestedFrames = doc.querySelectorAll('iframe');
6729
+ for (var nf = 0; nf < nestedFrames.length; nf++) {
6730
+ try {
6731
+ var nestedDoc = nestedFrames[nf].contentDocument;
6732
+ if (!nestedDoc) continue;
6733
+ var nestedRect = nestedFrames[nf].getBoundingClientRect();
6734
+ tagFrame(nestedDoc, nestedRect.x, nestedRect.y);
6735
+ } catch(e) { /* \u8DE8\u57DF iframe \u8DF3\u8FC7 */ }
6736
+ }
6737
+ }
6738
+ // \u904D\u5386\u4E3B\u6587\u6863\u7684\u6240\u6709\u540C\u6E90 iframe
6739
+ var mainFrames = document.querySelectorAll('iframe');
6740
+ for (var mf = 0; mf < mainFrames.length; mf++) {
6741
+ try {
6742
+ var mDoc = mainFrames[mf].contentDocument;
6743
+ if (!mDoc) continue;
6744
+ var mRect = mainFrames[mf].getBoundingClientRect();
6745
+ tagFrame(mDoc, mRect.x, mRect.y);
6746
+ } catch(e) { /* \u8DE8\u57DF\u8DF3\u8FC7 */ }
6747
+ }
6748
+
6749
+ // v8\uFF1A\u52A8\u6001\u6807\u6CE8\u2014\u2014MutationObserver \u76D1\u542C\u65B0\u5143\u7D20\uFF0C\u81EA\u52A8\u8865\u5145\u6807\u6CE8
6750
+ if (window.__xbTagObserver) { window.__xbTagObserver.disconnect(); }
6751
+ window.__xbTagObserver = new MutationObserver(function(mutations) {
6752
+ var needsRetag = false;
6753
+ for (var mi = 0; mi < mutations.length; mi++) {
6754
+ if (mutations[mi].addedNodes.length > 0) { needsRetag = true; break; }
6755
+ }
6756
+ if (!needsRetag) return;
6757
+ // v8.1\uFF1A\u6E05\u7406\u88AB\u79FB\u9664\u5143\u7D20\u7684\u6807\u6CE8\uFF08\u6B7B\u6807\u6CE8\u4F1A\u7559\u5728 Canvas \u4E0A\uFF09
6758
+ for (var ri = 0; ri < mutations.length; ri++) {
6759
+ var removed = mutations[ri].removedNodes;
6760
+ for (var rj = 0; rj < removed.length; rj++) {
6761
+ var removedNode = removed[rj];
6762
+ if (!removedNode.tagName) continue;
6763
+ for (var rk in window.__xbTagMap) {
6764
+ var entry = window.__xbTagMap[rk];
6765
+ if (entry._el === removedNode || (entry._el && removedNode.contains && removedNode.contains(entry._el))) {
6766
+ delete window.__xbTagMap[rk];
6767
+ window.__xbTagStats.total--;
6768
+ }
6769
+ }
6770
+ }
6771
+ }
6772
+ // \u9632\u6296\uFF1A300ms \u5185\u7684\u8FDE\u7EED\u53D8\u5316\u53EA\u89E6\u53D1\u4E00\u6B21\u91CD\u6807\u6CE8
6773
+ clearTimeout(window.__xbTagRetagTimer);
6774
+ window.__xbTagRetagTimer = setTimeout(function() {
6775
+ // \u53EA\u6807\u6CE8\u65B0\u589E\u7684\u53EF\u89C1\u5143\u7D20\uFF08\u4E0D\u91CD\u753B\u6574\u4E2A Canvas\uFF09
6776
+ var ctx2 = document.getElementById('__xb-tag-overlay');
6777
+ if (!ctx2) return;
6778
+ var canvas2 = ctx2.getContext('2d');
6779
+ for (var ni = 0; ni < mutations.length; ni++) {
6780
+ var nodes = mutations[ni].addedNodes;
6781
+ for (var nj = 0; nj < nodes.length; nj++) {
6782
+ var node = nodes[nj];
6783
+ if (!node.getBoundingClientRect) continue;
6784
+ var r = node.getBoundingClientRect();
6785
+ if (r.width < 8 || r.height < 8) continue;
6786
+ // \u5206\u7C7B\u5E76\u6807\u6CE8
6787
+ var newType = classifyElement(node);
6788
+ if (!newType) continue;
6789
+ var newId = genId(TYPE_PREFIX[newType] || 't', counters[newType]);
6790
+ counters[newType]++;
6791
+ var colors = COLORS[newType];
6792
+ canvas2.fillStyle = colors.fill;
6793
+ canvas2.fillRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
6794
+ canvas2.strokeStyle = '#000';
6795
+ canvas2.lineWidth = 1;
6796
+ canvas2.strokeRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
6797
+ canvas2.fillStyle = '#000';
6798
+ canvas2.font = 'bold 11px monospace';
6799
+ canvas2.fillText(newId, r.x + 1, r.y - 4);
6800
+ canvas2.strokeStyle = colors.stroke;
6801
+ canvas2.lineWidth = 1.5;
6802
+ canvas2.strokeRect(r.x, r.y, r.width, r.height);
6803
+ // \u5B58\u6620\u5C04
6804
+ var parentId = null;
6805
+ var parentNode = node.parentElement;
6806
+ while (parentNode && parentNode !== document.body) {
6807
+ for (var pk in window.__xbTagMap) {
6808
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
6809
+ }
6810
+ if (parentId) break;
6811
+ parentNode = parentNode.parentElement;
6812
+ }
6813
+ window.__xbTagMap[newId] = { type: newType, tagName: node.tagName, text: (node.textContent||'').trim().slice(0,40), parent: parentId, _el: node, rect: {x:Math.round(r.x),y:Math.round(r.y),w:Math.round(r.width),h:Math.round(r.height)} };
6814
+ window.__xbTagStats.total++;
6815
+ }
6816
+ }
6817
+ // \u66F4\u65B0 serializable
6818
+ var ser = {};
6819
+ for (var sk2 in window.__xbTagMap) {
6820
+ var item = {};
6821
+ for (var key in window.__xbTagMap[sk2]) { if (key !== '_el') item[key] = window.__xbTagMap[sk2][key]; }
6822
+ ser[sk2] = item;
6823
+ }
6824
+ window.__xbTagSerializable = ser;
6825
+ }, 300);
6826
+ });
6827
+ window.__xbTagObserver.observe(document.body, { childList: true, subtree: true });
6828
+
6829
+ // v4\uFF1A\u751F\u6210\u53EF\u5E8F\u5217\u5316\u7248\u672C\uFF08\u53BB\u6389 _el DOM \u5F15\u7528\uFF09
6830
+ var serializable = {};
6831
+ for (var sk in window.__xbTagMap) {
6832
+ var item = {};
6833
+ for (var key in window.__xbTagMap[sk]) {
6834
+ if (key !== '_el') item[key] = window.__xbTagMap[sk][key];
6835
+ }
6836
+ serializable[sk] = item;
6837
+ }
6838
+ window.__xbTagSerializable = serializable;
6839
+ window.__xbTagStats = { total: Object.keys(window.__xbTagMap).length, byType: counters };
6840
+ return JSON.stringify(window.__xbTagStats);
6841
+ })()
6842
+ `;
6843
+ var visualTagV2Command = registerCommand({
6844
+ name: "visual-tag-v2",
6845
+ description: "\u5206\u8272\u6807\u6CE8\u9875\u9762\u5143\u7D20\uFF08\u7EA2=\u53EF\u70B9\u51FB \u84DD=\u8F93\u5165 \u7EFF=\u56FE\u7247 \u9EC4=\u5217\u8868 \u7D2B=\u6570\u5B57 \u6A59=\u6587\u672C\uFF09",
6846
+ scope: "page",
6847
+ parameters: z30.object({
6848
+ action: z30.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6849
+ id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6850
+ query: z30.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6851
+ type: z30.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6852
+ "interact-action": z30.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6853
+ value: z30.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6854
+ }),
6855
+ result: z30.object({
6856
+ action: z30.string(),
6857
+ total: z30.number().optional(),
6858
+ byType: z30.record(z30.number()).optional(),
6859
+ element: z30.record(z30.unknown()).optional()
6860
+ }),
6861
+ handler: async (p, ctx) => {
6862
+ switch (p.action) {
6863
+ case "tag": {
6864
+ const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6865
+ const parsed = JSON.parse(result);
6866
+ return ok29({ action: "tag", total: parsed.total, byType: parsed.byType });
6867
+ }
6868
+ case "lookup": {
6869
+ if (!p.id) return fail14("lookup \u9700\u8981 --id");
6870
+ const result = await ctx.page.evaluate(
6871
+ `(function(){var m=window.__xbTagMap;if(!m)return JSON.stringify({err:'no-map'});var e=m[${JSON.stringify(p.id)}];return e?JSON.stringify(e):JSON.stringify({err:'not-found'})})()`
6872
+ );
6873
+ const parsed = JSON.parse(result);
6874
+ if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6875
+ return ok29({ action: "lookup", id: p.id, element: parsed });
6876
+ }
6877
+ case "by-type": {
6878
+ const result = await ctx.page.evaluate(
6879
+ `(function(){var m=window.__xbTagMap;if(!m)return'{}';var out={};for(var k in m){if(!${JSON.stringify(p.type || "")}||m[k].type===${JSON.stringify(p.type || "")}){out[k]={type:m[k].type,text:m[k].text,num:m[k].num,label:m[k].formLabel}}}return JSON.stringify(out)})()`
6880
+ );
6881
+ return ok29({ action: "by-type", element: JSON.parse(result) });
6882
+ }
6883
+ case "find": {
6884
+ const query = p.query;
6885
+ if (!query) return fail14('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6886
+ const result = await ctx.page.evaluate(
6887
+ `(function(){
6888
+ var map = window.__xbTagSerializable;
6889
+ if (!map) return JSON.stringify({err:'no-map'});
6890
+ var query = ${JSON.stringify(query)};
6891
+ var results = [];
6892
+ // 1) \u76F4\u63A5\u6587\u672C\u5339\u914D
6893
+ for (var id in map) {
6894
+ var e = map[id];
6895
+ var text = (e.text || '').toLowerCase();
6896
+ var q = query.toLowerCase();
6897
+ if (text.includes(q)) {
6898
+ results.push({id:id, type:e.type, text:e.text, num:e.num, parent:e.parent, reason:'text-match'});
6899
+ }
6900
+ }
6901
+ // 2) \u7C7B\u578B\u5339\u914D\uFF08query \u542B"\u6309\u94AE"/"\u94FE\u63A5"/"\u56FE\u7247"/"\u6570\u5B57"\u7B49\uFF09
6902
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u94FE\u63A5:'click', \u56FE\u7247:'img', image:'img',
6903
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', list:'list', \u5361\u7247:'list', card:'list',
6904
+ \u6570\u5B57:'count', count:'count', \u8BA1\u6570:'count', \u6587\u672C:'text'};
6905
+ for (var tk in typeMap) {
6906
+ if (query.toLowerCase().includes(tk)) {
6907
+ for (var id2 in map) {
6908
+ if (map[id2].type === typeMap[tk]) {
6909
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, parent:map[id2].parent, reason:'type-match:'+tk});
6910
+ }
6911
+ }
6912
+ }
6913
+ }
6914
+ // 3) \u6570\u5B57\u5339\u914D\uFF08query \u542B\u6570\u5B57\uFF09
6915
+ var numMatch = query.match(/([0-9,.]+)/);
6916
+ if (numMatch && map) {
6917
+ var target = parseFloat(numMatch[1].replace(/,/g,''));
6918
+ for (var id3 in map) {
6919
+ if (map[id3].num && parseFloat(map[id3].num.replace(/,/g,'')) === target) {
6920
+ results.push({id:id3, type:map[id3].type, text:map[id3].text, num:map[id3].num, parent:map[id3].parent, reason:'num-match'});
6921
+ }
6922
+ }
6923
+ }
6924
+ return JSON.stringify({total:results.length, results:results.slice(0,20)});
6925
+ })()`
6926
+ );
6927
+ return ok29({ action: "find", query, element: JSON.parse(result) });
6928
+ }
6929
+ case "stats": {
6930
+ const result = await ctx.page.evaluate(
6931
+ `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6932
+ );
6933
+ return ok29({ action: "stats", element: JSON.parse(result) });
6934
+ }
6935
+ case "interact": {
6936
+ const query = p.query;
6937
+ const pAny = p;
6938
+ const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6939
+ const value = pAny.value;
6940
+ if (!query) return fail14("interact \u9700\u8981 --query \u53C2\u6570");
6941
+ if (!action) return fail14("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6942
+ const findResult = await ctx.page.evaluate(
6943
+ `(function(){
6944
+ var map = window.__xbTagSerializable;
6945
+ if (!map) return JSON.stringify({err:'no-map'});
6946
+ var query = ${JSON.stringify(query)};
6947
+ var results = [];
6948
+ for (var id in map) {
6949
+ var e = map[id];
6950
+ var text = (e.text || '').toLowerCase();
6951
+ if (text.includes(query.toLowerCase())) {
6952
+ results.push({id:id, type:e.type, text:e.text, num:e.num, label:e.formLabel});
6953
+ }
6954
+ }
6955
+ // \u7C7B\u578B\u5339\u914D
6956
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u56FE\u7247:'img', image:'img',
6957
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', \u6570\u5B57:'count', count:'count'};
6958
+ for (var tk in typeMap) {
6959
+ if (query.toLowerCase().includes(tk)) {
6960
+ for (var id2 in map) {
6961
+ if (map[id2].type === typeMap[tk]) {
6962
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, label:map[id2].formLabel});
6963
+ }
6964
+ }
6965
+ }
6966
+ }
6967
+ return JSON.stringify({total:results.length, results:results.slice(0,10)});
6968
+ })()`
6969
+ );
6970
+ const parsed = JSON.parse(findResult);
6971
+ if (parsed.err) return fail14(parsed.err);
6972
+ if (!parsed.total || !parsed.results?.length) return fail14(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
6973
+ const target = parsed.results[0];
6974
+ if (action === "read") {
6975
+ return ok29({ action: "interact", query, target, result: { read: target.text || target.label } });
6976
+ }
6977
+ if (action === "click") {
6978
+ const el = await ctx.page.evaluate(
6979
+ `(function(){
6980
+ var map = window.__xbTagMap;
6981
+ if (!map) return null;
6982
+ var entry = map[${JSON.stringify(target.id)}];
6983
+ if (!entry || !entry._el) return null;
6984
+ var r = entry._el.getBoundingClientRect();
6985
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
6986
+ })()`
6987
+ );
6988
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
6989
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
6990
+ return ok29({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
6991
+ }
6992
+ if (action === "fill") {
6993
+ if (!value) return fail14("fill \u9700\u8981 --value \u53C2\u6570");
6994
+ const el = await ctx.page.evaluate(
6995
+ `(function(){
6996
+ var map = window.__xbTagMap;
6997
+ if (!map) return null;
6998
+ var entry = map[${JSON.stringify(target.id)}];
6999
+ if (!entry || !entry._el) return null;
7000
+ var r = entry._el.getBoundingClientRect();
7001
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7002
+ })()`
7003
+ );
7004
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7005
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7006
+ await ctx.page.keyboard.type(value, { stealth: true });
7007
+ return ok29({ action: "interact", query, target, result: { filled: true, value } });
7008
+ }
7009
+ return fail14(`\u672A\u77E5 action: ${action}`);
7010
+ }
7011
+ case "export": {
7012
+ const result = await ctx.page.evaluate(
7013
+ `(function(){
7014
+ var map = window.__xbTagSerializable;
7015
+ if (!map) return JSON.stringify({err:'no-map'});
7016
+ // \u6309 type \u5206\u7EC4\u7EDF\u8BA1
7017
+ var byType = {};
7018
+ for (var id in map) {
7019
+ var t = map[id].type || 'unknown';
7020
+ byType[t] = (byType[t] || 0) + 1;
7021
+ }
7022
+ // \u6784\u5EFA\u5C42\u7EA7\u6811\uFF08parent \u2192 children\uFF09
7023
+ var tree = {};
7024
+ var roots = [];
7025
+ for (var id2 in map) {
7026
+ var parent = map[id2].parent;
7027
+ if (parent && map[parent]) {
7028
+ if (!tree[parent]) tree[parent] = [];
7029
+ tree[parent].push(id2);
7030
+ } else {
7031
+ roots.push(id2);
7032
+ }
7033
+ }
7034
+ // elements \u5BFC\u51FA\u6458\u8981\uFF08\u5B8C\u6574 DOM \u6620\u5C04\u592A\u5927\uFF0C\u53EA\u5BFC\u6838\u5FC3\u5B57\u6BB5\uFF09
7035
+ var elementsOut = {};
7036
+ for (var id3 in map) {
7037
+ elementsOut[id3] = {
7038
+ type: map[id3].type,
7039
+ text: (map[id3].text || '').slice(0, 20),
7040
+ num: map[id3].num,
7041
+ label: map[id3].formLabel,
7042
+ frame: map[id3].frame,
7043
+ parent: map[id3].parent,
7044
+ table: map[id3].table ? {col: map[id3].table.col, row: map[id3].table.rowIndex} : null
7045
+ };
7046
+ }
7047
+ return JSON.stringify({
7048
+ total: Object.keys(map).length,
7049
+ byType: byType,
7050
+ rootIds: roots.slice(0, 20),
7051
+ hierarchy: Object.keys(tree).slice(0, 50).reduce(function(acc, k) { acc[k] = tree[k]; return acc; }, {}),
7052
+ elements: elementsOut
7053
+ });
7054
+ })()`
7055
+ );
7056
+ const parsed = JSON.parse(result);
7057
+ if (parsed.err) return fail14(String(parsed.err));
7058
+ return ok29({ action: "export", element: parsed });
7059
+ }
7060
+ case "clear": {
7061
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7062
+ return ok29({ action: "clear" });
7063
+ }
7064
+ }
7065
+ }
7066
+ });
7067
+
6365
7068
  // src/context.ts
6366
7069
  function attachDetectAntiBot(ctx) {
6367
7070
  ctx.detectAntiBot = async (page, config) => {
@@ -7468,7 +8171,7 @@ async function guardCheck(commandName) {
7468
8171
  }
7469
8172
  }
7470
8173
  function errorResult(message) {
7471
- return { ...fail13(message), duration: 0 };
8174
+ return { ...fail15(message), duration: 0 };
7472
8175
  }
7473
8176
  function tipsToMessages(tips) {
7474
8177
  if (!tips || tips.length === 0) return [];
@@ -7545,7 +8248,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7545
8248
  }
7546
8249
  let targetPageOverride = null;
7547
8250
  if (_target && extraOpts?.cdpEndpoint) {
7548
- const { findTargetPage } = await import("./browser-BEERPZPB.js");
8251
+ const { findTargetPage } = await import("./browser-6LH6KJSW.js");
7549
8252
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7550
8253
  if (!targetPageOverride) {
7551
8254
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -7741,7 +8444,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7741
8444
  timestamp: start
7742
8445
  });
7743
8446
  if (isSuccess) {
7744
- return { ...ok28(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8447
+ return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
7745
8448
  }
7746
8449
  return { success: false, data: raw.data, message: raw.message, tips: mergedOrRaw, duration, ...hookOutputs ? { hookOutputs } : {} };
7747
8450
  }
@@ -7755,7 +8458,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7755
8458
  duration,
7756
8459
  timestamp: start
7757
8460
  });
7758
- return { ...ok28(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8461
+ return { ...ok30(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
7759
8462
  } catch (err) {
7760
8463
  const end = Date.now();
7761
8464
  const duration = end - start;
@@ -7800,7 +8503,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7800
8503
  duration,
7801
8504
  timestamp: start
7802
8505
  });
7803
- return { ...fail13(errorMessage), duration };
8506
+ return { ...fail15(errorMessage), duration };
7804
8507
  } finally {
7805
8508
  }
7806
8509
  }
@@ -7844,7 +8547,7 @@ async function executeChain(input, options) {
7844
8547
  results.push({
7845
8548
  command: cmdName,
7846
8549
  raw: cmdStr,
7847
- ...fail13(`Plugin "${cmdName}" requires a sub-command`),
8550
+ ...fail15(`Plugin "${cmdName}" requires a sub-command`),
7848
8551
  duration: 0
7849
8552
  });
7850
8553
  if (type === "and") {
@@ -7863,7 +8566,7 @@ async function executeChain(input, options) {
7863
8566
  results.push({
7864
8567
  command: cmdName,
7865
8568
  raw: cmdStr,
7866
- ...fail13(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8569
+ ...fail15(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
7867
8570
  duration: 0
7868
8571
  });
7869
8572
  if (type === "and") {
@@ -7967,7 +8670,7 @@ async function executeChain(input, options) {
7967
8670
  results.push({
7968
8671
  command: `${cmdName} ${subCommand}`,
7969
8672
  raw: cmdStr,
7970
- ...ok28(data),
8673
+ ...ok30(data),
7971
8674
  duration: duration2,
7972
8675
  ...hookOutputs ? { hookOutputs } : {}
7973
8676
  });
@@ -7995,7 +8698,7 @@ async function executeChain(input, options) {
7995
8698
  results.push({
7996
8699
  command: `${cmdName} ${subCommand}`,
7997
8700
  raw: cmdStr,
7998
- ...fail13(errorMessage),
8701
+ ...fail15(errorMessage),
7999
8702
  duration: duration2
8000
8703
  });
8001
8704
  if (type === "and") {
@@ -10189,6 +10892,7 @@ var HTML_TAGS = /* @__PURE__ */ new Set([
10189
10892
  var SELECTOR_DSL_PREFIXES = /^(text=|popup-text=|xpath=|role=|css=|chain=)/;
10190
10893
  function normalizeSelector(input) {
10191
10894
  if (!input) return input;
10895
+ if (typeof input !== "string") input = String(input);
10192
10896
  if (/^[#\.\[\:\/]/.test(input)) return input;
10193
10897
  if (input === "*") return input;
10194
10898
  if (SELECTOR_DSL_PREFIXES.test(input)) return input;
@@ -13224,6 +13928,12 @@ function findEvalStart(argv) {
13224
13928
  async function handleEvalScript(parts, argv) {
13225
13929
  const cdpEndpoint = extractCdpFromArgv(argv);
13226
13930
  const sessionName = extractSessionNameFromArgv(argv);
13931
+ if (parts[0] === "--script-b64" && parts[1]) {
13932
+ const chainResult2 = await executeChain(`eval --script-b64 ${parts[1]}`, { cdpEndpoint, sessionName });
13933
+ printChainResult(chainResult2);
13934
+ if (!chainResult2.success) throw new Error("Command failed");
13935
+ return;
13936
+ }
13227
13937
  let frame;
13228
13938
  const scriptLines = [];
13229
13939
  for (let i = 0; i < parts.length; i++) {
@@ -13723,7 +14433,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
13723
14433
  const targetPage = pages[cmdTabIndex];
13724
14434
  await targetPage.bringToFront().catch(() => {
13725
14435
  });
13726
- const { setActivePage: setActivePage2 } = await import("./browser-BEERPZPB.js");
14436
+ const { setActivePage: setActivePage2 } = await import("./browser-6LH6KJSW.js");
13727
14437
  setActivePage2(session, targetPage);
13728
14438
  }
13729
14439
  }
@@ -13999,7 +14709,7 @@ async function main() {
13999
14709
  const command = process.argv[2];
14000
14710
  const isLongRunning = command === "preview" || command === "serve";
14001
14711
  if (!isLongRunning) {
14002
- const { ensureProcessCanExit } = await import("./browser-BEERPZPB.js");
14712
+ const { ensureProcessCanExit } = await import("./browser-6LH6KJSW.js");
14003
14713
  await ensureProcessCanExit().catch(() => {
14004
14714
  });
14005
14715
  process.exit(process.exitCode || exitCode);