@xbrowser/cli 1.18.2 → 1.20.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.
@@ -34,13 +34,13 @@ import {
34
34
  resolveLaunchOpts,
35
35
  saveSessionDiskMeta,
36
36
  setActivePage
37
- } from "./chunk-NA7IP6PO.js";
37
+ } from "./chunk-75TLPVVZ.js";
38
38
  import {
39
39
  createRuleEngine,
40
40
  rand,
41
41
  sleep,
42
42
  wheelDelta
43
- } from "./chunk-DVKIL7H6.js";
43
+ } from "./chunk-UYEJ66VX.js";
44
44
  import {
45
45
  queryJS
46
46
  } from "./chunk-3FWLW7FS.js";
@@ -69,8 +69,8 @@ import {
69
69
 
70
70
  // src/executor.ts
71
71
  import {
72
- ok as ok28,
73
- fail as fail13,
72
+ ok as ok30,
73
+ fail as fail15,
74
74
  isCommandResult,
75
75
  CompositeStorage as CompositeStorage2,
76
76
  TipCollector as TipCollector2,
@@ -6322,6 +6322,709 @@ function describeSelector(strategy, value, name) {
6322
6322
  }
6323
6323
  }
6324
6324
 
6325
+ // src/commands/visual-tag.ts
6326
+ import { z as z29 } from "zod";
6327
+ import { ok as ok28, fail as fail13 } from "@dyyz1993/xcli-core";
6328
+ var SAFE_SET = "ahjkmnprtw3479".split("");
6329
+ var TAG_SCRIPT = `
6330
+ (function() {
6331
+ // \u6E05\u9664\u65E7\u6807\u6CE8
6332
+ var old = document.getElementById('__xb-tag-overlay');
6333
+ if (old) old.remove();
6334
+ window.__xbTagMap = {};
6335
+
6336
+ var SAFE_SET = ${JSON.stringify(SAFE_SET)};
6337
+ function genId(idx) {
6338
+ var base = SAFE_SET.length;
6339
+ if (idx < base * base) return SAFE_SET[Math.floor(idx / base)] + SAFE_SET[idx % base];
6340
+ var i = idx - base * base;
6341
+ return SAFE_SET[Math.floor(i / (base * base))] + SAFE_SET[Math.floor(i / base) % base] + SAFE_SET[i % base];
6342
+ }
6343
+
6344
+ // \u627E\u6240\u6709\u53EF\u4EA4\u4E92\u5143\u7D20
6345
+ var els = [];
6346
+ var all = document.querySelectorAll('button, a[href], input, select, textarea, [onclick], [role="button"], [contenteditable], [class*="btn"], [class*="button"], [class*="link"]');
6347
+ for (var i = 0; i < all.length && els.length < 200; i++) {
6348
+ var el = all[i];
6349
+ var r = el.getBoundingClientRect();
6350
+ if (r.width < 10 || r.height < 10) continue;
6351
+ if (r.x < 0 || r.y < 0 || r.x + r.width > window.innerWidth || r.y + r.height > window.innerHeight + 100) continue;
6352
+ var style = getComputedStyle(el);
6353
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6354
+ els.push({ el: el, rect: r });
6355
+ }
6356
+
6357
+ // \u521B\u5EFA\u53E0\u52A0 Canvas
6358
+ var canvas = document.createElement('canvas');
6359
+ canvas.id = '__xb-tag-overlay';
6360
+ canvas.width = window.innerWidth;
6361
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6362
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6363
+ document.body.appendChild(canvas);
6364
+ var ctx = canvas.getContext('2d');
6365
+
6366
+ // \u7ED8\u5236\u6807\u7B7E
6367
+ for (var j = 0; j < els.length; j++) {
6368
+ var item = els[j];
6369
+ var id = genId(j);
6370
+ var x = item.rect.x;
6371
+ var y = item.rect.y;
6372
+
6373
+ // \u6807\u7B7E\u6846\uFF1A\u9AD8\u5BF9\u6BD4\uFF08\u9EC4\u5E95\u9ED1\u5B57\uFF09
6374
+ ctx.fillStyle = '#FFD700';
6375
+ ctx.fillRect(x - 2, y - 16, id.length * 8 + 8, 16);
6376
+ ctx.strokeStyle = '#000';
6377
+ ctx.lineWidth = 1.5;
6378
+ ctx.strokeRect(x - 2, y - 16, id.length * 8 + 8, 16);
6379
+ ctx.fillStyle = '#000';
6380
+ ctx.font = 'bold 12px monospace';
6381
+ ctx.fillText(id, x + 2, y - 5);
6382
+
6383
+ // \u5143\u7D20\u8F6E\u5ED3
6384
+ ctx.strokeStyle = '#FF0000';
6385
+ ctx.lineWidth = 1.5;
6386
+ ctx.strokeRect(x, y, item.rect.width, item.rect.height);
6387
+
6388
+ // \u5B58\u50A8 ID \u2192 \u5143\u7D20\u6620\u5C04
6389
+ window.__xbTagMap[id] = {
6390
+ tagName: item.el.tagName,
6391
+ text: (item.el.textContent || '').trim().slice(0, 50),
6392
+ rect: { x: x, y: y, w: item.rect.width, h: item.rect.height },
6393
+ selector: (function(e) {
6394
+ if (e.id) return '#' + e.id;
6395
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6396
+ // \u751F\u6210 nth-child \u9009\u62E9\u5668
6397
+ var path = [];
6398
+ var node = e;
6399
+ while (node && node !== document.body) {
6400
+ var idx = 1;
6401
+ var sib = node.previousElementSibling;
6402
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6403
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6404
+ node = node.parentElement;
6405
+ }
6406
+ return path.join(' > ');
6407
+ })(item.el)
6408
+ };
6409
+ }
6410
+
6411
+ return JSON.stringify({ tagged: els.length, overlay: true });
6412
+ })()
6413
+ `;
6414
+ var visualTagCommand = registerCommand({
6415
+ name: "visual-tag",
6416
+ 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",
6417
+ scope: "page",
6418
+ parameters: z29.object({
6419
+ action: z29.enum(["tag", "lookup", "clear", "list"]),
6420
+ id: z29.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6421
+ }),
6422
+ result: z29.object({
6423
+ action: z29.string(),
6424
+ tagged: z29.number().optional(),
6425
+ id: z29.string().optional(),
6426
+ element: z29.record(z29.unknown()).optional()
6427
+ }),
6428
+ handler: async (p, ctx) => {
6429
+ switch (p.action) {
6430
+ case "tag": {
6431
+ const result = await ctx.page.evaluate(TAG_SCRIPT);
6432
+ const parsed = JSON.parse(result);
6433
+ return ok28({ action: "tag", tagged: parsed.tagged });
6434
+ }
6435
+ case "lookup": {
6436
+ if (!p.id) return fail13("lookup \u9700\u8981 --id \u53C2\u6570");
6437
+ const result = await ctx.page.evaluate(
6438
+ `(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'}); })()`
6439
+ );
6440
+ const parsed = JSON.parse(result);
6441
+ if (parsed.err) return fail13(`ID ${p.id}: ${parsed.err}`);
6442
+ return ok28({ action: "lookup", id: p.id, element: parsed });
6443
+ }
6444
+ case "list": {
6445
+ const result = await ctx.page.evaluate(
6446
+ `(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); })()`
6447
+ );
6448
+ return ok28({ action: "list", element: JSON.parse(result) });
6449
+ }
6450
+ case "clear": {
6451
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6452
+ return ok28({ action: "clear" });
6453
+ }
6454
+ }
6455
+ }
6456
+ });
6457
+
6458
+ // src/commands/visual-tag-v2.ts
6459
+ import { z as z30 } from "zod";
6460
+ import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6461
+ var SAFE_SET2 = "ahjkmnprtw3479".split("");
6462
+ var TAG_V2_SCRIPT = `
6463
+ (function() {
6464
+ var old = document.getElementById('__xb-tag-overlay');
6465
+ if (old) old.remove();
6466
+ window.__xbTagMap = {};
6467
+ window.__xbTagStats = {};
6468
+
6469
+ var SAFE_SET = ${JSON.stringify(SAFE_SET2)};
6470
+ var TYPE_PREFIX = { click:'k', input:'n', img:'m', list:'h', count:'p', text:'t' };
6471
+ function genId(prefix, idx) {
6472
+ var base = SAFE_SET.length;
6473
+ var suffix = SAFE_SET[Math.floor(idx / base) % base] + SAFE_SET[idx % base];
6474
+ return prefix + suffix;
6475
+ }
6476
+
6477
+ var counters = { click: 0, input: 0, img: 0, list: 0, count: 0, text: 0 };
6478
+
6479
+ var canvas = document.createElement('canvas');
6480
+ canvas.id = '__xb-tag-overlay';
6481
+ canvas.width = window.innerWidth;
6482
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6483
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6484
+ document.body.appendChild(canvas);
6485
+ var ctx = canvas.getContext('2d');
6486
+
6487
+ function classifyElement(el) {
6488
+ var tag = el.tagName;
6489
+ var text = (el.textContent || '').trim();
6490
+ var cls = el.className || '';
6491
+
6492
+ // \u4F18\u5148\u7EA71\uFF1A\u6570\u5B57/\u8BA1\u6570\u5668\u2014\u2014\u5148\u4E8E\u5217\u8868\uFF08S129 \u9057\u7559\u95EE\u9898\u4FEE\u590D\uFF09
6493
+ var hasOnlySvgChildren = true;
6494
+ for (var ci = 0; ci < el.children.length; ci++) {
6495
+ if (el.children[ci].tagName.toUpperCase() !== 'SVG' && el.children[ci].tagName.toUpperCase() !== 'PATH' && el.children[ci].tagName.toUpperCase() !== 'SPAN') { hasOnlySvgChildren = false; break; }
6496
+ }
6497
+ if ((el.children.length === 0 || hasOnlySvgChildren) && text.length > 0 && text.length < 25) {
6498
+ var numMatch = /^[0-9]/.test(text) && text.length < 20;
6499
+ if (numMatch) return 'count';
6500
+ }
6501
+ // \u4F18\u5148\u7EA71.5\uFF1Aclass \u542B count/num/like/star/fork \u7684\u5BB9\u5668
6502
+ if (/count|num\b|like|star|fork|rating|badge/i.test(cls) && el.children.length <= 2) return 'count';
6503
+
6504
+ // \u4F18\u5148\u7EA72\uFF1A\u8F93\u5165\u6846
6505
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' ||
6506
+ el.getAttribute('contenteditable')) return 'input';
6507
+
6508
+ // \u4F18\u5148\u7EA73\uFF1A\u53EF\u70B9\u51FB\uFF08v3 \u6269\u5BBD\uFF1Adata-target/onclick/tab/menu/nav/link class\uFF09
6509
+ if (tag === 'BUTTON' || (el.getAttribute('role') === 'button') ||
6510
+ (tag === 'A' && el.getAttribute('href')) ||
6511
+ el.hasAttribute('onclick') || el.hasAttribute('data-target') ||
6512
+ /btn|button|click|action|tab\b|menu|nav\b|link\b/i.test(cls)) return 'click';
6513
+
6514
+ // \u4F18\u5148\u7EA74\uFF1A\u56FE\u7247\uFF08v3\uFF1A\u542B SVG \u56FE\u6807\uFF09
6515
+ if (tag === 'IMG' || (tag === 'SVG') ||
6516
+ (el.querySelector && el.querySelector('img,svg') &&
6517
+ el.children.length <= 2 && !text)) return 'img';
6518
+
6519
+ // \u4F18\u5148\u7EA74.5\uFF1A\u8868\u683C\u5355\u5143\u683C
6520
+ if (tag === 'TD' || tag === 'TH') return 'list';
6521
+
6522
+ // \u4F18\u5148\u7EA75\uFF1A\u5217\u8868\uFF08v3\uFF1A\u52A0 card\uFF09
6523
+ if (tag === 'UL' || tag === 'OL' || tag === 'LI' ||
6524
+ /list|item|feed|timeline|card/i.test(cls)) return 'list';
6525
+
6526
+ // \u4F18\u5148\u7EA76\uFF1A\u6587\u672C
6527
+ if (text.length > 20) return 'text';
6528
+ return null;
6529
+ }
6530
+
6531
+ var COLORS = {
6532
+ click: { stroke: '#FF0000', fill: '#FFD700' }, // \u7EA2+\u9EC4
6533
+ input: { stroke: '#0000FF', fill: '#ADD8E6' }, // \u84DD
6534
+ img: { stroke: '#00AA00', fill: '#90EE90' }, // \u7EFF
6535
+ list: { stroke: '#FFAA00', fill: '#FFE4B5' }, // \u6A59\u9EC4
6536
+ count: { stroke: '#9900CC', fill: '#E0B0FF' }, // \u7D2B
6537
+ text: { stroke: '#FF8C00', fill: '#FFECD2' }, // \u6A59
6538
+ };
6539
+
6540
+ 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"]');
6541
+
6542
+ for (var i = 0; i < all.length && i < 3000; i++) {
6543
+ var el = all[i];
6544
+ var r = el.getBoundingClientRect();
6545
+ if (r.width < 8 || r.height < 8) continue;
6546
+ if (r.x < -50 || r.y < -50 || r.x > window.innerWidth || r.y > window.innerHeight + 200) continue;
6547
+ var style = getComputedStyle(el);
6548
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6549
+
6550
+ var type = classifyElement(el);
6551
+ if (!type) continue;
6552
+
6553
+ var id = genId(TYPE_PREFIX[type] || 't', counters[type]);
6554
+ counters[type]++;
6555
+ var colors = COLORS[type];
6556
+
6557
+ // \u6807\u7B7E
6558
+ ctx.fillStyle = colors.fill;
6559
+ ctx.fillRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6560
+ ctx.strokeStyle = '#000';
6561
+ ctx.lineWidth = 1;
6562
+ ctx.strokeRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6563
+ ctx.fillStyle = '#000';
6564
+ ctx.font = 'bold 11px monospace';
6565
+ ctx.fillText(id, r.x + 1, r.y - 4);
6566
+
6567
+ // \u5143\u7D20\u6846\uFF08\u5206\u8272\uFF09
6568
+ ctx.strokeStyle = colors.stroke;
6569
+ ctx.lineWidth = 1.5;
6570
+ ctx.strokeRect(r.x, r.y, r.width, r.height);
6571
+
6572
+ // v4\uFF1A\u67E5\u7236\u7EA7\u6807\u6CE8 ID\uFF08\u5D4C\u5957\u5173\u7CFB\uFF09
6573
+ var parentId = null;
6574
+ var parentNode = el.parentElement;
6575
+ while (parentNode && parentNode !== document.body) {
6576
+ for (var pk in window.__xbTagMap) {
6577
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
6578
+ }
6579
+ if (parentId) break;
6580
+ parentNode = parentNode.parentElement;
6581
+ }
6582
+
6583
+ // v6\uFF1A\u8868\u5355\u8BED\u4E49\u2014\u2014\u8BC6\u522B input \u7684\u5173\u8054 label
6584
+ var formLabel = null;
6585
+ if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT') {
6586
+ var inputId = el.id;
6587
+ if (inputId) {
6588
+ var lbl = document.querySelector('label[for="' + inputId + '"]');
6589
+ if (lbl) formLabel = lbl.textContent.trim();
6590
+ }
6591
+ if (!formLabel) {
6592
+ var aria = el.getAttribute('aria-label');
6593
+ if (aria) formLabel = aria;
6594
+ }
6595
+ if (!formLabel) {
6596
+ var ph = el.getAttribute('placeholder');
6597
+ if (ph) formLabel = '(placeholder) ' + ph;
6598
+ }
6599
+ if (!formLabel) {
6600
+ var parentLbl = el.closest('label');
6601
+ if (parentLbl) formLabel = parentLbl.textContent.trim().slice(0, 30);
6602
+ }
6603
+ if (!formLabel) {
6604
+ var prev = el.previousElementSibling;
6605
+ if (prev && (prev.tagName === 'LABEL' || prev.tagName === 'SPAN' || prev.tagName === 'DIV') && prev.textContent.trim()) {
6606
+ formLabel = '(adjacent) ' + prev.textContent.trim().slice(0, 30);
6607
+ }
6608
+ }
6609
+ }
6610
+
6611
+ // v7\uFF1A\u8868\u683C\u8BED\u4E49\u2014\u2014\u5355\u5143\u683C \u2192 \u5217\u540D + \u884C\u53F7
6612
+ var tableInfo = null;
6613
+ if (el.tagName === 'TD' || el.tagName === 'TH') {
6614
+ var table = el.closest('table');
6615
+ if (table) {
6616
+ var row = el.closest('tr');
6617
+ var cellIndex = el.cellIndex;
6618
+ var rowIndex = row ? row.rowIndex : -1;
6619
+ // \u627E\u8868\u5934\uFF08thead \u7684 th \u6216\u7B2C\u4E00\u884C\u7684 th\uFF09
6620
+ var header = table.querySelector('thead th:nth-child(' + (cellIndex + 1) + ')') ||
6621
+ table.querySelector('tr:first-child th:nth-child(' + (cellIndex + 1) + ')');
6622
+ var colName = header ? header.textContent.trim() : 'col-' + (cellIndex + 1);
6623
+ tableInfo = { col: colName, colIndex: cellIndex, rowIndex: rowIndex, value: el.textContent.trim().slice(0, 20) };
6624
+ }
6625
+ }
6626
+
6627
+ window.__xbTagMap[id] = {
6628
+ type: type,
6629
+ parent: parentId,
6630
+ _el: el,
6631
+ formLabel: formLabel,
6632
+ table: tableInfo,
6633
+ tagName: el.tagName,
6634
+ text: (el.textContent || '').trim().slice(0, 40),
6635
+ num: (el.textContent || '').trim().match(/[\\d,.]+/)?.[0] || null,
6636
+ rect: { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) },
6637
+ selector: (function(e) {
6638
+ if (e.id) return '#' + e.id;
6639
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6640
+ var path = [];
6641
+ var node = e;
6642
+ while (node && node !== document.body) {
6643
+ var idx = 1;
6644
+ var sib = node.previousElementSibling;
6645
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6646
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6647
+ node = node.parentElement;
6648
+ }
6649
+ return path.join(' > ');
6650
+ })(el)
6651
+ };
6652
+ }
6653
+
6654
+ // v9\uFF1A\u8DE8 frame \u6807\u6CE8\u2014\u2014\u9012\u5F52\u5904\u7406\u540C\u6E90 iframe \u5185\u7684\u5143\u7D20
6655
+ function tagFrame(doc, offsetX, offsetY) {
6656
+ var frameAll = doc.querySelectorAll('button, a[href], input, select, textarea, img, [onclick], [role=button], [contenteditable], [aria-label]');
6657
+ for (var fi = 0; fi < frameAll.length && fi < 100; fi++) {
6658
+ var fel = frameAll[fi];
6659
+ var fr = fel.getBoundingClientRect();
6660
+ if (fr.width < 8 || fr.height < 8) continue;
6661
+ var fType = classifyElement(fel);
6662
+ if (!fType) continue;
6663
+ var fId = genId(TYPE_PREFIX[fType] || 't', counters[fType]);
6664
+ counters[fType]++;
6665
+ var fColors = COLORS[fType];
6666
+ // \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
6667
+ var fx = fr.x + offsetX, fy = fr.y + offsetY;
6668
+ ctx.fillStyle = fColors.fill;
6669
+ ctx.fillRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
6670
+ ctx.strokeStyle = '#000'; ctx.lineWidth = 1;
6671
+ ctx.strokeRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
6672
+ ctx.fillStyle = '#000'; ctx.font = 'bold 11px monospace';
6673
+ ctx.fillText(fId, fx + 1, fy - 4);
6674
+ ctx.strokeStyle = fColors.stroke; ctx.lineWidth = 1.5;
6675
+ ctx.strokeRect(fx, fy, fr.width, fr.height);
6676
+ window.__xbTagMap[fId] = {
6677
+ type: fType, tagName: fel.tagName,
6678
+ text: (fel.textContent||'').trim().slice(0,40),
6679
+ num: (fel.textContent||'').trim().match(/[0-9,.]+/)?.[0] || null,
6680
+ formLabel: (fel.getAttribute('aria-label')||fel.getAttribute('placeholder')||'').slice(0,30) || null,
6681
+ frame: 'iframe',
6682
+ _el: fel,
6683
+ rect: {x:Math.round(fx),y:Math.round(fy),w:Math.round(fr.width),h:Math.round(fr.height)},
6684
+ selector: (function(e){return e.id?'#'+e.id:e.tagName.toLowerCase()}) (fel)
6685
+ };
6686
+ }
6687
+ // \u9012\u5F52\u5904\u7406\u5D4C\u5957 iframe
6688
+ var nestedFrames = doc.querySelectorAll('iframe');
6689
+ for (var nf = 0; nf < nestedFrames.length; nf++) {
6690
+ try {
6691
+ var nestedDoc = nestedFrames[nf].contentDocument;
6692
+ if (!nestedDoc) continue;
6693
+ var nestedRect = nestedFrames[nf].getBoundingClientRect();
6694
+ tagFrame(nestedDoc, nestedRect.x, nestedRect.y);
6695
+ } catch(e) { /* \u8DE8\u57DF iframe \u8DF3\u8FC7 */ }
6696
+ }
6697
+ }
6698
+ // \u904D\u5386\u4E3B\u6587\u6863\u7684\u6240\u6709\u540C\u6E90 iframe
6699
+ var mainFrames = document.querySelectorAll('iframe');
6700
+ for (var mf = 0; mf < mainFrames.length; mf++) {
6701
+ try {
6702
+ var mDoc = mainFrames[mf].contentDocument;
6703
+ if (!mDoc) continue;
6704
+ var mRect = mainFrames[mf].getBoundingClientRect();
6705
+ tagFrame(mDoc, mRect.x, mRect.y);
6706
+ } catch(e) { /* \u8DE8\u57DF\u8DF3\u8FC7 */ }
6707
+ }
6708
+
6709
+ // v8\uFF1A\u52A8\u6001\u6807\u6CE8\u2014\u2014MutationObserver \u76D1\u542C\u65B0\u5143\u7D20\uFF0C\u81EA\u52A8\u8865\u5145\u6807\u6CE8
6710
+ if (window.__xbTagObserver) { window.__xbTagObserver.disconnect(); }
6711
+ window.__xbTagObserver = new MutationObserver(function(mutations) {
6712
+ var needsRetag = false;
6713
+ for (var mi = 0; mi < mutations.length; mi++) {
6714
+ if (mutations[mi].addedNodes.length > 0) { needsRetag = true; break; }
6715
+ }
6716
+ if (!needsRetag) return;
6717
+ // v8.1\uFF1A\u6E05\u7406\u88AB\u79FB\u9664\u5143\u7D20\u7684\u6807\u6CE8\uFF08\u6B7B\u6807\u6CE8\u4F1A\u7559\u5728 Canvas \u4E0A\uFF09
6718
+ for (var ri = 0; ri < mutations.length; ri++) {
6719
+ var removed = mutations[ri].removedNodes;
6720
+ for (var rj = 0; rj < removed.length; rj++) {
6721
+ var removedNode = removed[rj];
6722
+ if (!removedNode.tagName) continue;
6723
+ for (var rk in window.__xbTagMap) {
6724
+ var entry = window.__xbTagMap[rk];
6725
+ if (entry._el === removedNode || (entry._el && removedNode.contains && removedNode.contains(entry._el))) {
6726
+ delete window.__xbTagMap[rk];
6727
+ window.__xbTagStats.total--;
6728
+ }
6729
+ }
6730
+ }
6731
+ }
6732
+ // \u9632\u6296\uFF1A300ms \u5185\u7684\u8FDE\u7EED\u53D8\u5316\u53EA\u89E6\u53D1\u4E00\u6B21\u91CD\u6807\u6CE8
6733
+ clearTimeout(window.__xbTagRetagTimer);
6734
+ window.__xbTagRetagTimer = setTimeout(function() {
6735
+ // \u53EA\u6807\u6CE8\u65B0\u589E\u7684\u53EF\u89C1\u5143\u7D20\uFF08\u4E0D\u91CD\u753B\u6574\u4E2A Canvas\uFF09
6736
+ var ctx2 = document.getElementById('__xb-tag-overlay');
6737
+ if (!ctx2) return;
6738
+ var canvas2 = ctx2.getContext('2d');
6739
+ for (var ni = 0; ni < mutations.length; ni++) {
6740
+ var nodes = mutations[ni].addedNodes;
6741
+ for (var nj = 0; nj < nodes.length; nj++) {
6742
+ var node = nodes[nj];
6743
+ if (!node.getBoundingClientRect) continue;
6744
+ var r = node.getBoundingClientRect();
6745
+ if (r.width < 8 || r.height < 8) continue;
6746
+ // \u5206\u7C7B\u5E76\u6807\u6CE8
6747
+ var newType = classifyElement(node);
6748
+ if (!newType) continue;
6749
+ var newId = genId(TYPE_PREFIX[newType] || 't', counters[newType]);
6750
+ counters[newType]++;
6751
+ var colors = COLORS[newType];
6752
+ canvas2.fillStyle = colors.fill;
6753
+ canvas2.fillRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
6754
+ canvas2.strokeStyle = '#000';
6755
+ canvas2.lineWidth = 1;
6756
+ canvas2.strokeRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
6757
+ canvas2.fillStyle = '#000';
6758
+ canvas2.font = 'bold 11px monospace';
6759
+ canvas2.fillText(newId, r.x + 1, r.y - 4);
6760
+ canvas2.strokeStyle = colors.stroke;
6761
+ canvas2.lineWidth = 1.5;
6762
+ canvas2.strokeRect(r.x, r.y, r.width, r.height);
6763
+ // \u5B58\u6620\u5C04
6764
+ var parentId = null;
6765
+ var parentNode = node.parentElement;
6766
+ while (parentNode && parentNode !== document.body) {
6767
+ for (var pk in window.__xbTagMap) {
6768
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
6769
+ }
6770
+ if (parentId) break;
6771
+ parentNode = parentNode.parentElement;
6772
+ }
6773
+ 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)} };
6774
+ window.__xbTagStats.total++;
6775
+ }
6776
+ }
6777
+ // \u66F4\u65B0 serializable
6778
+ var ser = {};
6779
+ for (var sk2 in window.__xbTagMap) {
6780
+ var item = {};
6781
+ for (var key in window.__xbTagMap[sk2]) { if (key !== '_el') item[key] = window.__xbTagMap[sk2][key]; }
6782
+ ser[sk2] = item;
6783
+ }
6784
+ window.__xbTagSerializable = ser;
6785
+ }, 300);
6786
+ });
6787
+ window.__xbTagObserver.observe(document.body, { childList: true, subtree: true });
6788
+
6789
+ // v4\uFF1A\u751F\u6210\u53EF\u5E8F\u5217\u5316\u7248\u672C\uFF08\u53BB\u6389 _el DOM \u5F15\u7528\uFF09
6790
+ var serializable = {};
6791
+ for (var sk in window.__xbTagMap) {
6792
+ var item = {};
6793
+ for (var key in window.__xbTagMap[sk]) {
6794
+ if (key !== '_el') item[key] = window.__xbTagMap[sk][key];
6795
+ }
6796
+ serializable[sk] = item;
6797
+ }
6798
+ window.__xbTagSerializable = serializable;
6799
+ window.__xbTagStats = { total: Object.keys(window.__xbTagMap).length, byType: counters };
6800
+ return JSON.stringify(window.__xbTagStats);
6801
+ })()
6802
+ `;
6803
+ var visualTagV2Command = registerCommand({
6804
+ name: "visual-tag-v2",
6805
+ 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",
6806
+ scope: "page",
6807
+ parameters: z30.object({
6808
+ action: z30.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6809
+ id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6810
+ query: z30.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6811
+ type: z30.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6812
+ "interact-action": z30.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6813
+ value: z30.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6814
+ }),
6815
+ result: z30.object({
6816
+ action: z30.string(),
6817
+ total: z30.number().optional(),
6818
+ byType: z30.record(z30.number()).optional(),
6819
+ element: z30.record(z30.unknown()).optional()
6820
+ }),
6821
+ handler: async (p, ctx) => {
6822
+ switch (p.action) {
6823
+ case "tag": {
6824
+ const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6825
+ const parsed = JSON.parse(result);
6826
+ return ok29({ action: "tag", total: parsed.total, byType: parsed.byType });
6827
+ }
6828
+ case "lookup": {
6829
+ if (!p.id) return fail14("lookup \u9700\u8981 --id");
6830
+ const result = await ctx.page.evaluate(
6831
+ `(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'})})()`
6832
+ );
6833
+ const parsed = JSON.parse(result);
6834
+ if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6835
+ return ok29({ action: "lookup", id: p.id, element: parsed });
6836
+ }
6837
+ case "by-type": {
6838
+ const result = await ctx.page.evaluate(
6839
+ `(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)})()`
6840
+ );
6841
+ return ok29({ action: "by-type", element: JSON.parse(result) });
6842
+ }
6843
+ case "find": {
6844
+ const query = p.query;
6845
+ if (!query) return fail14('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6846
+ const result = await ctx.page.evaluate(
6847
+ `(function(){
6848
+ var map = window.__xbTagSerializable;
6849
+ if (!map) return JSON.stringify({err:'no-map'});
6850
+ var query = ${JSON.stringify(query)};
6851
+ var results = [];
6852
+ // 1) \u76F4\u63A5\u6587\u672C\u5339\u914D
6853
+ for (var id in map) {
6854
+ var e = map[id];
6855
+ var text = (e.text || '').toLowerCase();
6856
+ var q = query.toLowerCase();
6857
+ if (text.includes(q)) {
6858
+ results.push({id:id, type:e.type, text:e.text, num:e.num, parent:e.parent, reason:'text-match'});
6859
+ }
6860
+ }
6861
+ // 2) \u7C7B\u578B\u5339\u914D\uFF08query \u542B"\u6309\u94AE"/"\u94FE\u63A5"/"\u56FE\u7247"/"\u6570\u5B57"\u7B49\uFF09
6862
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u94FE\u63A5:'click', \u56FE\u7247:'img', image:'img',
6863
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', list:'list', \u5361\u7247:'list', card:'list',
6864
+ \u6570\u5B57:'count', count:'count', \u8BA1\u6570:'count', \u6587\u672C:'text'};
6865
+ for (var tk in typeMap) {
6866
+ if (query.toLowerCase().includes(tk)) {
6867
+ for (var id2 in map) {
6868
+ if (map[id2].type === typeMap[tk]) {
6869
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, parent:map[id2].parent, reason:'type-match:'+tk});
6870
+ }
6871
+ }
6872
+ }
6873
+ }
6874
+ // 3) \u6570\u5B57\u5339\u914D\uFF08query \u542B\u6570\u5B57\uFF09
6875
+ var numMatch = query.match(/([0-9,.]+)/);
6876
+ if (numMatch && map) {
6877
+ var target = parseFloat(numMatch[1].replace(/,/g,''));
6878
+ for (var id3 in map) {
6879
+ if (map[id3].num && parseFloat(map[id3].num.replace(/,/g,'')) === target) {
6880
+ results.push({id:id3, type:map[id3].type, text:map[id3].text, num:map[id3].num, parent:map[id3].parent, reason:'num-match'});
6881
+ }
6882
+ }
6883
+ }
6884
+ return JSON.stringify({total:results.length, results:results.slice(0,20)});
6885
+ })()`
6886
+ );
6887
+ return ok29({ action: "find", query, element: JSON.parse(result) });
6888
+ }
6889
+ case "stats": {
6890
+ const result = await ctx.page.evaluate(
6891
+ `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6892
+ );
6893
+ return ok29({ action: "stats", element: JSON.parse(result) });
6894
+ }
6895
+ case "interact": {
6896
+ const query = p.query;
6897
+ const pAny = p;
6898
+ const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6899
+ const value = pAny.value;
6900
+ if (!query) return fail14("interact \u9700\u8981 --query \u53C2\u6570");
6901
+ if (!action) return fail14("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6902
+ const findResult = await ctx.page.evaluate(
6903
+ `(function(){
6904
+ var map = window.__xbTagSerializable;
6905
+ if (!map) return JSON.stringify({err:'no-map'});
6906
+ var query = ${JSON.stringify(query)};
6907
+ var results = [];
6908
+ for (var id in map) {
6909
+ var e = map[id];
6910
+ var text = (e.text || '').toLowerCase();
6911
+ if (text.includes(query.toLowerCase())) {
6912
+ results.push({id:id, type:e.type, text:e.text, num:e.num, label:e.formLabel});
6913
+ }
6914
+ }
6915
+ // \u7C7B\u578B\u5339\u914D
6916
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u56FE\u7247:'img', image:'img',
6917
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', \u6570\u5B57:'count', count:'count'};
6918
+ for (var tk in typeMap) {
6919
+ if (query.toLowerCase().includes(tk)) {
6920
+ for (var id2 in map) {
6921
+ if (map[id2].type === typeMap[tk]) {
6922
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, label:map[id2].formLabel});
6923
+ }
6924
+ }
6925
+ }
6926
+ }
6927
+ return JSON.stringify({total:results.length, results:results.slice(0,10)});
6928
+ })()`
6929
+ );
6930
+ const parsed = JSON.parse(findResult);
6931
+ if (parsed.err) return fail14(parsed.err);
6932
+ if (!parsed.total || !parsed.results?.length) return fail14(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
6933
+ const target = parsed.results[0];
6934
+ if (action === "read") {
6935
+ return ok29({ action: "interact", query, target, result: { read: target.text || target.label } });
6936
+ }
6937
+ if (action === "click") {
6938
+ const el = await ctx.page.evaluate(
6939
+ `(function(){
6940
+ var map = window.__xbTagMap;
6941
+ if (!map) return null;
6942
+ var entry = map[${JSON.stringify(target.id)}];
6943
+ if (!entry || !entry._el) return null;
6944
+ var r = entry._el.getBoundingClientRect();
6945
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
6946
+ })()`
6947
+ );
6948
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
6949
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
6950
+ return ok29({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
6951
+ }
6952
+ if (action === "fill") {
6953
+ if (!value) return fail14("fill \u9700\u8981 --value \u53C2\u6570");
6954
+ const el = await ctx.page.evaluate(
6955
+ `(function(){
6956
+ var map = window.__xbTagMap;
6957
+ if (!map) return null;
6958
+ var entry = map[${JSON.stringify(target.id)}];
6959
+ if (!entry || !entry._el) return null;
6960
+ var r = entry._el.getBoundingClientRect();
6961
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
6962
+ })()`
6963
+ );
6964
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
6965
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
6966
+ await ctx.page.keyboard.type(value, { stealth: true });
6967
+ return ok29({ action: "interact", query, target, result: { filled: true, value } });
6968
+ }
6969
+ return fail14(`\u672A\u77E5 action: ${action}`);
6970
+ }
6971
+ case "export": {
6972
+ const result = await ctx.page.evaluate(
6973
+ `(function(){
6974
+ var map = window.__xbTagSerializable;
6975
+ if (!map) return JSON.stringify({err:'no-map'});
6976
+ // \u6309 type \u5206\u7EC4\u7EDF\u8BA1
6977
+ var byType = {};
6978
+ for (var id in map) {
6979
+ var t = map[id].type || 'unknown';
6980
+ byType[t] = (byType[t] || 0) + 1;
6981
+ }
6982
+ // \u6784\u5EFA\u5C42\u7EA7\u6811\uFF08parent \u2192 children\uFF09
6983
+ var tree = {};
6984
+ var roots = [];
6985
+ for (var id2 in map) {
6986
+ var parent = map[id2].parent;
6987
+ if (parent && map[parent]) {
6988
+ if (!tree[parent]) tree[parent] = [];
6989
+ tree[parent].push(id2);
6990
+ } else {
6991
+ roots.push(id2);
6992
+ }
6993
+ }
6994
+ // elements \u5BFC\u51FA\u6458\u8981\uFF08\u5B8C\u6574 DOM \u6620\u5C04\u592A\u5927\uFF0C\u53EA\u5BFC\u6838\u5FC3\u5B57\u6BB5\uFF09
6995
+ var elementsOut = {};
6996
+ for (var id3 in map) {
6997
+ elementsOut[id3] = {
6998
+ type: map[id3].type,
6999
+ text: (map[id3].text || '').slice(0, 20),
7000
+ num: map[id3].num,
7001
+ label: map[id3].formLabel,
7002
+ frame: map[id3].frame,
7003
+ parent: map[id3].parent,
7004
+ table: map[id3].table ? {col: map[id3].table.col, row: map[id3].table.rowIndex} : null
7005
+ };
7006
+ }
7007
+ return JSON.stringify({
7008
+ total: Object.keys(map).length,
7009
+ byType: byType,
7010
+ rootIds: roots.slice(0, 20),
7011
+ hierarchy: Object.keys(tree).slice(0, 50).reduce(function(acc, k) { acc[k] = tree[k]; return acc; }, {}),
7012
+ elements: elementsOut
7013
+ });
7014
+ })()`
7015
+ );
7016
+ const parsed = JSON.parse(result);
7017
+ if (parsed.err) return fail14(String(parsed.err));
7018
+ return ok29({ action: "export", element: parsed });
7019
+ }
7020
+ case "clear": {
7021
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7022
+ return ok29({ action: "clear" });
7023
+ }
7024
+ }
7025
+ }
7026
+ });
7027
+
6325
7028
  // src/context.ts
6326
7029
  function attachDetectAntiBot(ctx) {
6327
7030
  ctx.detectAntiBot = async (page, config) => {
@@ -6986,7 +7689,7 @@ async function guardCheck(commandName) {
6986
7689
  }
6987
7690
  }
6988
7691
  function errorResult(message) {
6989
- return { ...fail13(message), duration: 0 };
7692
+ return { ...fail15(message), duration: 0 };
6990
7693
  }
6991
7694
  function tipsToMessages(tips) {
6992
7695
  if (!tips || tips.length === 0) return [];
@@ -7063,7 +7766,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7063
7766
  }
7064
7767
  let targetPageOverride = null;
7065
7768
  if (_target && extraOpts?.cdpEndpoint) {
7066
- const { findTargetPage } = await import("./browser-AEQS6325.js");
7769
+ const { findTargetPage } = await import("./browser-PBBC7RAV.js");
7067
7770
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7068
7771
  if (!targetPageOverride) {
7069
7772
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -7259,7 +7962,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7259
7962
  timestamp: start
7260
7963
  });
7261
7964
  if (isSuccess) {
7262
- return { ...ok28(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
7965
+ return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
7263
7966
  }
7264
7967
  return { success: false, data: raw.data, message: raw.message, tips: mergedOrRaw, duration, ...hookOutputs ? { hookOutputs } : {} };
7265
7968
  }
@@ -7273,7 +7976,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7273
7976
  duration,
7274
7977
  timestamp: start
7275
7978
  });
7276
- return { ...ok28(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
7979
+ return { ...ok30(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
7277
7980
  } catch (err) {
7278
7981
  const end = Date.now();
7279
7982
  const duration = end - start;
@@ -7318,7 +8021,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7318
8021
  duration,
7319
8022
  timestamp: start
7320
8023
  });
7321
- return { ...fail13(errorMessage), duration };
8024
+ return { ...fail15(errorMessage), duration };
7322
8025
  } finally {
7323
8026
  }
7324
8027
  }
@@ -7362,7 +8065,7 @@ async function executeChain(input, options) {
7362
8065
  results.push({
7363
8066
  command: cmdName,
7364
8067
  raw: cmdStr,
7365
- ...fail13(`Plugin "${cmdName}" requires a sub-command`),
8068
+ ...fail15(`Plugin "${cmdName}" requires a sub-command`),
7366
8069
  duration: 0
7367
8070
  });
7368
8071
  if (type === "and") {
@@ -7381,7 +8084,7 @@ async function executeChain(input, options) {
7381
8084
  results.push({
7382
8085
  command: cmdName,
7383
8086
  raw: cmdStr,
7384
- ...fail13(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8087
+ ...fail15(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
7385
8088
  duration: 0
7386
8089
  });
7387
8090
  if (type === "and") {
@@ -7485,7 +8188,7 @@ async function executeChain(input, options) {
7485
8188
  results.push({
7486
8189
  command: `${cmdName} ${subCommand}`,
7487
8190
  raw: cmdStr,
7488
- ...ok28(data),
8191
+ ...ok30(data),
7489
8192
  duration: duration2,
7490
8193
  ...hookOutputs ? { hookOutputs } : {}
7491
8194
  });
@@ -7513,7 +8216,7 @@ async function executeChain(input, options) {
7513
8216
  results.push({
7514
8217
  command: `${cmdName} ${subCommand}`,
7515
8218
  raw: cmdStr,
7516
- ...fail13(errorMessage),
8219
+ ...fail15(errorMessage),
7517
8220
  duration: duration2
7518
8221
  });
7519
8222
  if (type === "and") {
@@ -8885,7 +9588,7 @@ function createRPCHandler() {
8885
9588
  if (isNewFormat) {
8886
9589
  try {
8887
9590
  const replayErrors = [];
8888
- const { SessionReplayer } = await import("./session-replayer-J4GXUULG.js");
9591
+ const { SessionReplayer } = await import("./session-replayer-SBYJXQZZ.js");
8889
9592
  const replayer = new SessionReplayer({
8890
9593
  page: session.page,
8891
9594
  stepDelay: slowMo * 500,
@@ -8935,10 +9638,10 @@ function createRPCHandler() {
8935
9638
  const errors = Array.isArray(input.errors) ? input.errors : [];
8936
9639
  const eventsPlayed = typeof input.eventsPlayed === "number" ? input.eventsPlayed : 0;
8937
9640
  const totalEvents = typeof input.totalEvents === "number" ? input.totalEvents : eventsPlayed + errors.length;
8938
- const ok29 = input.ok ?? errors.length === 0;
9641
+ const ok31 = input.ok ?? errors.length === 0;
8939
9642
  return {
8940
- ok: ok29,
8941
- success: ok29,
9643
+ ok: ok31,
9644
+ success: ok31,
8942
9645
  duration: typeof input.duration === "number" ? input.duration : 0,
8943
9646
  eventsPlayed,
8944
9647
  totalEvents,
@@ -12060,6 +12763,18 @@ async function main() {
12060
12763
  log(`unhandledRejection: ${msg}`);
12061
12764
  console.error("Daemon unhandledRejection:", msg);
12062
12765
  });
12766
+ try {
12767
+ const bridgeUp = await fetch("http://127.0.0.1:9347/status").then((r) => r.ok).catch(() => false);
12768
+ if (!bridgeUp) {
12769
+ const { spawn } = await import("child_process");
12770
+ const path2 = await import("path");
12771
+ const serverPath = path2.join(process.cwd(), ".xcli", "plugins", "chrome-bridge", "server.mjs");
12772
+ const child = spawn(process.execPath, [serverPath, "9346"], { detached: true, stdio: "ignore" });
12773
+ child.unref();
12774
+ log("chrome-bridge server auto-started (WS:9346/HTTP:9347)");
12775
+ }
12776
+ } catch {
12777
+ }
12063
12778
  setInterval(() => {
12064
12779
  }, 6e4);
12065
12780
  }