@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.
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  resolveLaunchOpts,
19
19
  saveSessionDiskMeta,
20
20
  setActivePage
21
- } from "./chunk-MTNVT2T7.js";
21
+ } from "./chunk-76EKW7YJ.js";
22
22
  import {
23
23
  detectAntiBot,
24
24
  formatDetectionMessage
@@ -86,7 +86,7 @@ import {
86
86
  rand,
87
87
  sleep,
88
88
  wheelDelta
89
- } from "./chunk-LL37GYPP.js";
89
+ } from "./chunk-FDU5BCPV.js";
90
90
  import "./chunk-3KZ34AUC.js";
91
91
  import {
92
92
  errMsg
@@ -124,8 +124,8 @@ import {
124
124
 
125
125
  // src/executor.ts
126
126
  import {
127
- ok as ok28,
128
- fail as fail13,
127
+ ok as ok30,
128
+ fail as fail15,
129
129
  isCommandResult,
130
130
  CompositeStorage as CompositeStorage2,
131
131
  TipCollector as TipCollector2,
@@ -6673,6 +6673,709 @@ function describeSelector(strategy, value, name) {
6673
6673
  }
6674
6674
  }
6675
6675
 
6676
+ // src/commands/visual-tag.ts
6677
+ import { z as z29 } from "zod";
6678
+ import { ok as ok28, fail as fail13 } from "@dyyz1993/xcli-core";
6679
+ var SAFE_SET = "ahjkmnprtw3479".split("");
6680
+ var TAG_SCRIPT = `
6681
+ (function() {
6682
+ // \u6E05\u9664\u65E7\u6807\u6CE8
6683
+ var old = document.getElementById('__xb-tag-overlay');
6684
+ if (old) old.remove();
6685
+ window.__xbTagMap = {};
6686
+
6687
+ var SAFE_SET = ${JSON.stringify(SAFE_SET)};
6688
+ function genId(idx) {
6689
+ var base = SAFE_SET.length;
6690
+ if (idx < base * base) return SAFE_SET[Math.floor(idx / base)] + SAFE_SET[idx % base];
6691
+ var i = idx - base * base;
6692
+ return SAFE_SET[Math.floor(i / (base * base))] + SAFE_SET[Math.floor(i / base) % base] + SAFE_SET[i % base];
6693
+ }
6694
+
6695
+ // \u627E\u6240\u6709\u53EF\u4EA4\u4E92\u5143\u7D20
6696
+ var els = [];
6697
+ var all = document.querySelectorAll('button, a[href], input, select, textarea, [onclick], [role="button"], [contenteditable], [class*="btn"], [class*="button"], [class*="link"]');
6698
+ for (var i = 0; i < all.length && els.length < 200; i++) {
6699
+ var el = all[i];
6700
+ var r = el.getBoundingClientRect();
6701
+ if (r.width < 10 || r.height < 10) continue;
6702
+ if (r.x < 0 || r.y < 0 || r.x + r.width > window.innerWidth || r.y + r.height > window.innerHeight + 100) continue;
6703
+ var style = getComputedStyle(el);
6704
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6705
+ els.push({ el: el, rect: r });
6706
+ }
6707
+
6708
+ // \u521B\u5EFA\u53E0\u52A0 Canvas
6709
+ var canvas = document.createElement('canvas');
6710
+ canvas.id = '__xb-tag-overlay';
6711
+ canvas.width = window.innerWidth;
6712
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6713
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6714
+ document.body.appendChild(canvas);
6715
+ var ctx = canvas.getContext('2d');
6716
+
6717
+ // \u7ED8\u5236\u6807\u7B7E
6718
+ for (var j = 0; j < els.length; j++) {
6719
+ var item = els[j];
6720
+ var id = genId(j);
6721
+ var x = item.rect.x;
6722
+ var y = item.rect.y;
6723
+
6724
+ // \u6807\u7B7E\u6846\uFF1A\u9AD8\u5BF9\u6BD4\uFF08\u9EC4\u5E95\u9ED1\u5B57\uFF09
6725
+ ctx.fillStyle = '#FFD700';
6726
+ ctx.fillRect(x - 2, y - 16, id.length * 8 + 8, 16);
6727
+ ctx.strokeStyle = '#000';
6728
+ ctx.lineWidth = 1.5;
6729
+ ctx.strokeRect(x - 2, y - 16, id.length * 8 + 8, 16);
6730
+ ctx.fillStyle = '#000';
6731
+ ctx.font = 'bold 12px monospace';
6732
+ ctx.fillText(id, x + 2, y - 5);
6733
+
6734
+ // \u5143\u7D20\u8F6E\u5ED3
6735
+ ctx.strokeStyle = '#FF0000';
6736
+ ctx.lineWidth = 1.5;
6737
+ ctx.strokeRect(x, y, item.rect.width, item.rect.height);
6738
+
6739
+ // \u5B58\u50A8 ID \u2192 \u5143\u7D20\u6620\u5C04
6740
+ window.__xbTagMap[id] = {
6741
+ tagName: item.el.tagName,
6742
+ text: (item.el.textContent || '').trim().slice(0, 50),
6743
+ rect: { x: x, y: y, w: item.rect.width, h: item.rect.height },
6744
+ selector: (function(e) {
6745
+ if (e.id) return '#' + e.id;
6746
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6747
+ // \u751F\u6210 nth-child \u9009\u62E9\u5668
6748
+ var path = [];
6749
+ var node = e;
6750
+ while (node && node !== document.body) {
6751
+ var idx = 1;
6752
+ var sib = node.previousElementSibling;
6753
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6754
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6755
+ node = node.parentElement;
6756
+ }
6757
+ return path.join(' > ');
6758
+ })(item.el)
6759
+ };
6760
+ }
6761
+
6762
+ return JSON.stringify({ tagged: els.length, overlay: true });
6763
+ })()
6764
+ `;
6765
+ var visualTagCommand = registerCommand({
6766
+ name: "visual-tag",
6767
+ 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",
6768
+ scope: "page",
6769
+ parameters: z29.object({
6770
+ action: z29.enum(["tag", "lookup", "clear", "list"]),
6771
+ id: z29.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6772
+ }),
6773
+ result: z29.object({
6774
+ action: z29.string(),
6775
+ tagged: z29.number().optional(),
6776
+ id: z29.string().optional(),
6777
+ element: z29.record(z29.unknown()).optional()
6778
+ }),
6779
+ handler: async (p, ctx) => {
6780
+ switch (p.action) {
6781
+ case "tag": {
6782
+ const result = await ctx.page.evaluate(TAG_SCRIPT);
6783
+ const parsed = JSON.parse(result);
6784
+ return ok28({ action: "tag", tagged: parsed.tagged });
6785
+ }
6786
+ case "lookup": {
6787
+ if (!p.id) return fail13("lookup \u9700\u8981 --id \u53C2\u6570");
6788
+ const result = await ctx.page.evaluate(
6789
+ `(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'}); })()`
6790
+ );
6791
+ const parsed = JSON.parse(result);
6792
+ if (parsed.err) return fail13(`ID ${p.id}: ${parsed.err}`);
6793
+ return ok28({ action: "lookup", id: p.id, element: parsed });
6794
+ }
6795
+ case "list": {
6796
+ const result = await ctx.page.evaluate(
6797
+ `(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); })()`
6798
+ );
6799
+ return ok28({ action: "list", element: JSON.parse(result) });
6800
+ }
6801
+ case "clear": {
6802
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6803
+ return ok28({ action: "clear" });
6804
+ }
6805
+ }
6806
+ }
6807
+ });
6808
+
6809
+ // src/commands/visual-tag-v2.ts
6810
+ import { z as z30 } from "zod";
6811
+ import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6812
+ var SAFE_SET2 = "ahjkmnprtw3479".split("");
6813
+ var TAG_V2_SCRIPT = `
6814
+ (function() {
6815
+ var old = document.getElementById('__xb-tag-overlay');
6816
+ if (old) old.remove();
6817
+ window.__xbTagMap = {};
6818
+ window.__xbTagStats = {};
6819
+
6820
+ var SAFE_SET = ${JSON.stringify(SAFE_SET2)};
6821
+ var TYPE_PREFIX = { click:'k', input:'n', img:'m', list:'h', count:'p', text:'t' };
6822
+ function genId(prefix, idx) {
6823
+ var base = SAFE_SET.length;
6824
+ var suffix = SAFE_SET[Math.floor(idx / base) % base] + SAFE_SET[idx % base];
6825
+ return prefix + suffix;
6826
+ }
6827
+
6828
+ var counters = { click: 0, input: 0, img: 0, list: 0, count: 0, text: 0 };
6829
+
6830
+ var canvas = document.createElement('canvas');
6831
+ canvas.id = '__xb-tag-overlay';
6832
+ canvas.width = window.innerWidth;
6833
+ canvas.height = Math.max(window.innerHeight, document.documentElement.scrollHeight);
6834
+ canvas.style.cssText = 'position:fixed;top:0;left:0;pointer-events:none;z-index:999999;';
6835
+ document.body.appendChild(canvas);
6836
+ var ctx = canvas.getContext('2d');
6837
+
6838
+ function classifyElement(el) {
6839
+ var tag = el.tagName;
6840
+ var text = (el.textContent || '').trim();
6841
+ var cls = el.className || '';
6842
+
6843
+ // \u4F18\u5148\u7EA71\uFF1A\u6570\u5B57/\u8BA1\u6570\u5668\u2014\u2014\u5148\u4E8E\u5217\u8868\uFF08S129 \u9057\u7559\u95EE\u9898\u4FEE\u590D\uFF09
6844
+ var hasOnlySvgChildren = true;
6845
+ for (var ci = 0; ci < el.children.length; ci++) {
6846
+ if (el.children[ci].tagName.toUpperCase() !== 'SVG' && el.children[ci].tagName.toUpperCase() !== 'PATH' && el.children[ci].tagName.toUpperCase() !== 'SPAN') { hasOnlySvgChildren = false; break; }
6847
+ }
6848
+ if ((el.children.length === 0 || hasOnlySvgChildren) && text.length > 0 && text.length < 25) {
6849
+ var numMatch = /^[0-9]/.test(text) && text.length < 20;
6850
+ if (numMatch) return 'count';
6851
+ }
6852
+ // \u4F18\u5148\u7EA71.5\uFF1Aclass \u542B count/num/like/star/fork \u7684\u5BB9\u5668
6853
+ if (/count|num\b|like|star|fork|rating|badge/i.test(cls) && el.children.length <= 2) return 'count';
6854
+
6855
+ // \u4F18\u5148\u7EA72\uFF1A\u8F93\u5165\u6846
6856
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' ||
6857
+ el.getAttribute('contenteditable')) return 'input';
6858
+
6859
+ // \u4F18\u5148\u7EA73\uFF1A\u53EF\u70B9\u51FB\uFF08v3 \u6269\u5BBD\uFF1Adata-target/onclick/tab/menu/nav/link class\uFF09
6860
+ if (tag === 'BUTTON' || (el.getAttribute('role') === 'button') ||
6861
+ (tag === 'A' && el.getAttribute('href')) ||
6862
+ el.hasAttribute('onclick') || el.hasAttribute('data-target') ||
6863
+ /btn|button|click|action|tab\b|menu|nav\b|link\b/i.test(cls)) return 'click';
6864
+
6865
+ // \u4F18\u5148\u7EA74\uFF1A\u56FE\u7247\uFF08v3\uFF1A\u542B SVG \u56FE\u6807\uFF09
6866
+ if (tag === 'IMG' || (tag === 'SVG') ||
6867
+ (el.querySelector && el.querySelector('img,svg') &&
6868
+ el.children.length <= 2 && !text)) return 'img';
6869
+
6870
+ // \u4F18\u5148\u7EA74.5\uFF1A\u8868\u683C\u5355\u5143\u683C
6871
+ if (tag === 'TD' || tag === 'TH') return 'list';
6872
+
6873
+ // \u4F18\u5148\u7EA75\uFF1A\u5217\u8868\uFF08v3\uFF1A\u52A0 card\uFF09
6874
+ if (tag === 'UL' || tag === 'OL' || tag === 'LI' ||
6875
+ /list|item|feed|timeline|card/i.test(cls)) return 'list';
6876
+
6877
+ // \u4F18\u5148\u7EA76\uFF1A\u6587\u672C
6878
+ if (text.length > 20) return 'text';
6879
+ return null;
6880
+ }
6881
+
6882
+ var COLORS = {
6883
+ click: { stroke: '#FF0000', fill: '#FFD700' }, // \u7EA2+\u9EC4
6884
+ input: { stroke: '#0000FF', fill: '#ADD8E6' }, // \u84DD
6885
+ img: { stroke: '#00AA00', fill: '#90EE90' }, // \u7EFF
6886
+ list: { stroke: '#FFAA00', fill: '#FFE4B5' }, // \u6A59\u9EC4
6887
+ count: { stroke: '#9900CC', fill: '#E0B0FF' }, // \u7D2B
6888
+ text: { stroke: '#FF8C00', fill: '#FFECD2' }, // \u6A59
6889
+ };
6890
+
6891
+ 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"]');
6892
+
6893
+ for (var i = 0; i < all.length && i < 3000; i++) {
6894
+ var el = all[i];
6895
+ var r = el.getBoundingClientRect();
6896
+ if (r.width < 8 || r.height < 8) continue;
6897
+ if (r.x < -50 || r.y < -50 || r.x > window.innerWidth || r.y > window.innerHeight + 200) continue;
6898
+ var style = getComputedStyle(el);
6899
+ if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
6900
+
6901
+ var type = classifyElement(el);
6902
+ if (!type) continue;
6903
+
6904
+ var id = genId(TYPE_PREFIX[type] || 't', counters[type]);
6905
+ counters[type]++;
6906
+ var colors = COLORS[type];
6907
+
6908
+ // \u6807\u7B7E
6909
+ ctx.fillStyle = colors.fill;
6910
+ ctx.fillRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6911
+ ctx.strokeStyle = '#000';
6912
+ ctx.lineWidth = 1;
6913
+ ctx.strokeRect(r.x - 2, r.y - 14, id.length * 7 + 6, 14);
6914
+ ctx.fillStyle = '#000';
6915
+ ctx.font = 'bold 11px monospace';
6916
+ ctx.fillText(id, r.x + 1, r.y - 4);
6917
+
6918
+ // \u5143\u7D20\u6846\uFF08\u5206\u8272\uFF09
6919
+ ctx.strokeStyle = colors.stroke;
6920
+ ctx.lineWidth = 1.5;
6921
+ ctx.strokeRect(r.x, r.y, r.width, r.height);
6922
+
6923
+ // v4\uFF1A\u67E5\u7236\u7EA7\u6807\u6CE8 ID\uFF08\u5D4C\u5957\u5173\u7CFB\uFF09
6924
+ var parentId = null;
6925
+ var parentNode = el.parentElement;
6926
+ while (parentNode && parentNode !== document.body) {
6927
+ for (var pk in window.__xbTagMap) {
6928
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
6929
+ }
6930
+ if (parentId) break;
6931
+ parentNode = parentNode.parentElement;
6932
+ }
6933
+
6934
+ // v6\uFF1A\u8868\u5355\u8BED\u4E49\u2014\u2014\u8BC6\u522B input \u7684\u5173\u8054 label
6935
+ var formLabel = null;
6936
+ if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT') {
6937
+ var inputId = el.id;
6938
+ if (inputId) {
6939
+ var lbl = document.querySelector('label[for="' + inputId + '"]');
6940
+ if (lbl) formLabel = lbl.textContent.trim();
6941
+ }
6942
+ if (!formLabel) {
6943
+ var aria = el.getAttribute('aria-label');
6944
+ if (aria) formLabel = aria;
6945
+ }
6946
+ if (!formLabel) {
6947
+ var ph = el.getAttribute('placeholder');
6948
+ if (ph) formLabel = '(placeholder) ' + ph;
6949
+ }
6950
+ if (!formLabel) {
6951
+ var parentLbl = el.closest('label');
6952
+ if (parentLbl) formLabel = parentLbl.textContent.trim().slice(0, 30);
6953
+ }
6954
+ if (!formLabel) {
6955
+ var prev = el.previousElementSibling;
6956
+ if (prev && (prev.tagName === 'LABEL' || prev.tagName === 'SPAN' || prev.tagName === 'DIV') && prev.textContent.trim()) {
6957
+ formLabel = '(adjacent) ' + prev.textContent.trim().slice(0, 30);
6958
+ }
6959
+ }
6960
+ }
6961
+
6962
+ // v7\uFF1A\u8868\u683C\u8BED\u4E49\u2014\u2014\u5355\u5143\u683C \u2192 \u5217\u540D + \u884C\u53F7
6963
+ var tableInfo = null;
6964
+ if (el.tagName === 'TD' || el.tagName === 'TH') {
6965
+ var table = el.closest('table');
6966
+ if (table) {
6967
+ var row = el.closest('tr');
6968
+ var cellIndex = el.cellIndex;
6969
+ var rowIndex = row ? row.rowIndex : -1;
6970
+ // \u627E\u8868\u5934\uFF08thead \u7684 th \u6216\u7B2C\u4E00\u884C\u7684 th\uFF09
6971
+ var header = table.querySelector('thead th:nth-child(' + (cellIndex + 1) + ')') ||
6972
+ table.querySelector('tr:first-child th:nth-child(' + (cellIndex + 1) + ')');
6973
+ var colName = header ? header.textContent.trim() : 'col-' + (cellIndex + 1);
6974
+ tableInfo = { col: colName, colIndex: cellIndex, rowIndex: rowIndex, value: el.textContent.trim().slice(0, 20) };
6975
+ }
6976
+ }
6977
+
6978
+ window.__xbTagMap[id] = {
6979
+ type: type,
6980
+ parent: parentId,
6981
+ _el: el,
6982
+ formLabel: formLabel,
6983
+ table: tableInfo,
6984
+ tagName: el.tagName,
6985
+ text: (el.textContent || '').trim().slice(0, 40),
6986
+ num: (el.textContent || '').trim().match(/[\\d,.]+/)?.[0] || null,
6987
+ rect: { x: Math.round(r.x), y: Math.round(r.y), w: Math.round(r.width), h: Math.round(r.height) },
6988
+ selector: (function(e) {
6989
+ if (e.id) return '#' + e.id;
6990
+ if (e.getAttribute('data-testid')) return '[data-testid="' + e.getAttribute('data-testid') + '"]';
6991
+ var path = [];
6992
+ var node = e;
6993
+ while (node && node !== document.body) {
6994
+ var idx = 1;
6995
+ var sib = node.previousElementSibling;
6996
+ while (sib) { if (sib.tagName === node.tagName) idx++; sib = sib.previousElementSibling; }
6997
+ path.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + idx + ')');
6998
+ node = node.parentElement;
6999
+ }
7000
+ return path.join(' > ');
7001
+ })(el)
7002
+ };
7003
+ }
7004
+
7005
+ // v9\uFF1A\u8DE8 frame \u6807\u6CE8\u2014\u2014\u9012\u5F52\u5904\u7406\u540C\u6E90 iframe \u5185\u7684\u5143\u7D20
7006
+ function tagFrame(doc, offsetX, offsetY) {
7007
+ var frameAll = doc.querySelectorAll('button, a[href], input, select, textarea, img, [onclick], [role=button], [contenteditable], [aria-label]');
7008
+ for (var fi = 0; fi < frameAll.length && fi < 100; fi++) {
7009
+ var fel = frameAll[fi];
7010
+ var fr = fel.getBoundingClientRect();
7011
+ if (fr.width < 8 || fr.height < 8) continue;
7012
+ var fType = classifyElement(fel);
7013
+ if (!fType) continue;
7014
+ var fId = genId(TYPE_PREFIX[fType] || 't', counters[fType]);
7015
+ counters[fType]++;
7016
+ var fColors = COLORS[fType];
7017
+ // \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
7018
+ var fx = fr.x + offsetX, fy = fr.y + offsetY;
7019
+ ctx.fillStyle = fColors.fill;
7020
+ ctx.fillRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
7021
+ ctx.strokeStyle = '#000'; ctx.lineWidth = 1;
7022
+ ctx.strokeRect(fx - 2, fy - 14, fId.length * 7 + 6, 14);
7023
+ ctx.fillStyle = '#000'; ctx.font = 'bold 11px monospace';
7024
+ ctx.fillText(fId, fx + 1, fy - 4);
7025
+ ctx.strokeStyle = fColors.stroke; ctx.lineWidth = 1.5;
7026
+ ctx.strokeRect(fx, fy, fr.width, fr.height);
7027
+ window.__xbTagMap[fId] = {
7028
+ type: fType, tagName: fel.tagName,
7029
+ text: (fel.textContent||'').trim().slice(0,40),
7030
+ num: (fel.textContent||'').trim().match(/[0-9,.]+/)?.[0] || null,
7031
+ formLabel: (fel.getAttribute('aria-label')||fel.getAttribute('placeholder')||'').slice(0,30) || null,
7032
+ frame: 'iframe',
7033
+ _el: fel,
7034
+ rect: {x:Math.round(fx),y:Math.round(fy),w:Math.round(fr.width),h:Math.round(fr.height)},
7035
+ selector: (function(e){return e.id?'#'+e.id:e.tagName.toLowerCase()}) (fel)
7036
+ };
7037
+ }
7038
+ // \u9012\u5F52\u5904\u7406\u5D4C\u5957 iframe
7039
+ var nestedFrames = doc.querySelectorAll('iframe');
7040
+ for (var nf = 0; nf < nestedFrames.length; nf++) {
7041
+ try {
7042
+ var nestedDoc = nestedFrames[nf].contentDocument;
7043
+ if (!nestedDoc) continue;
7044
+ var nestedRect = nestedFrames[nf].getBoundingClientRect();
7045
+ tagFrame(nestedDoc, nestedRect.x, nestedRect.y);
7046
+ } catch(e) { /* \u8DE8\u57DF iframe \u8DF3\u8FC7 */ }
7047
+ }
7048
+ }
7049
+ // \u904D\u5386\u4E3B\u6587\u6863\u7684\u6240\u6709\u540C\u6E90 iframe
7050
+ var mainFrames = document.querySelectorAll('iframe');
7051
+ for (var mf = 0; mf < mainFrames.length; mf++) {
7052
+ try {
7053
+ var mDoc = mainFrames[mf].contentDocument;
7054
+ if (!mDoc) continue;
7055
+ var mRect = mainFrames[mf].getBoundingClientRect();
7056
+ tagFrame(mDoc, mRect.x, mRect.y);
7057
+ } catch(e) { /* \u8DE8\u57DF\u8DF3\u8FC7 */ }
7058
+ }
7059
+
7060
+ // v8\uFF1A\u52A8\u6001\u6807\u6CE8\u2014\u2014MutationObserver \u76D1\u542C\u65B0\u5143\u7D20\uFF0C\u81EA\u52A8\u8865\u5145\u6807\u6CE8
7061
+ if (window.__xbTagObserver) { window.__xbTagObserver.disconnect(); }
7062
+ window.__xbTagObserver = new MutationObserver(function(mutations) {
7063
+ var needsRetag = false;
7064
+ for (var mi = 0; mi < mutations.length; mi++) {
7065
+ if (mutations[mi].addedNodes.length > 0) { needsRetag = true; break; }
7066
+ }
7067
+ if (!needsRetag) return;
7068
+ // v8.1\uFF1A\u6E05\u7406\u88AB\u79FB\u9664\u5143\u7D20\u7684\u6807\u6CE8\uFF08\u6B7B\u6807\u6CE8\u4F1A\u7559\u5728 Canvas \u4E0A\uFF09
7069
+ for (var ri = 0; ri < mutations.length; ri++) {
7070
+ var removed = mutations[ri].removedNodes;
7071
+ for (var rj = 0; rj < removed.length; rj++) {
7072
+ var removedNode = removed[rj];
7073
+ if (!removedNode.tagName) continue;
7074
+ for (var rk in window.__xbTagMap) {
7075
+ var entry = window.__xbTagMap[rk];
7076
+ if (entry._el === removedNode || (entry._el && removedNode.contains && removedNode.contains(entry._el))) {
7077
+ delete window.__xbTagMap[rk];
7078
+ window.__xbTagStats.total--;
7079
+ }
7080
+ }
7081
+ }
7082
+ }
7083
+ // \u9632\u6296\uFF1A300ms \u5185\u7684\u8FDE\u7EED\u53D8\u5316\u53EA\u89E6\u53D1\u4E00\u6B21\u91CD\u6807\u6CE8
7084
+ clearTimeout(window.__xbTagRetagTimer);
7085
+ window.__xbTagRetagTimer = setTimeout(function() {
7086
+ // \u53EA\u6807\u6CE8\u65B0\u589E\u7684\u53EF\u89C1\u5143\u7D20\uFF08\u4E0D\u91CD\u753B\u6574\u4E2A Canvas\uFF09
7087
+ var ctx2 = document.getElementById('__xb-tag-overlay');
7088
+ if (!ctx2) return;
7089
+ var canvas2 = ctx2.getContext('2d');
7090
+ for (var ni = 0; ni < mutations.length; ni++) {
7091
+ var nodes = mutations[ni].addedNodes;
7092
+ for (var nj = 0; nj < nodes.length; nj++) {
7093
+ var node = nodes[nj];
7094
+ if (!node.getBoundingClientRect) continue;
7095
+ var r = node.getBoundingClientRect();
7096
+ if (r.width < 8 || r.height < 8) continue;
7097
+ // \u5206\u7C7B\u5E76\u6807\u6CE8
7098
+ var newType = classifyElement(node);
7099
+ if (!newType) continue;
7100
+ var newId = genId(TYPE_PREFIX[newType] || 't', counters[newType]);
7101
+ counters[newType]++;
7102
+ var colors = COLORS[newType];
7103
+ canvas2.fillStyle = colors.fill;
7104
+ canvas2.fillRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
7105
+ canvas2.strokeStyle = '#000';
7106
+ canvas2.lineWidth = 1;
7107
+ canvas2.strokeRect(r.x - 2, r.y - 14, newId.length * 7 + 6, 14);
7108
+ canvas2.fillStyle = '#000';
7109
+ canvas2.font = 'bold 11px monospace';
7110
+ canvas2.fillText(newId, r.x + 1, r.y - 4);
7111
+ canvas2.strokeStyle = colors.stroke;
7112
+ canvas2.lineWidth = 1.5;
7113
+ canvas2.strokeRect(r.x, r.y, r.width, r.height);
7114
+ // \u5B58\u6620\u5C04
7115
+ var parentId = null;
7116
+ var parentNode = node.parentElement;
7117
+ while (parentNode && parentNode !== document.body) {
7118
+ for (var pk in window.__xbTagMap) {
7119
+ if (window.__xbTagMap[pk]._el === parentNode) { parentId = pk; break; }
7120
+ }
7121
+ if (parentId) break;
7122
+ parentNode = parentNode.parentElement;
7123
+ }
7124
+ 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)} };
7125
+ window.__xbTagStats.total++;
7126
+ }
7127
+ }
7128
+ // \u66F4\u65B0 serializable
7129
+ var ser = {};
7130
+ for (var sk2 in window.__xbTagMap) {
7131
+ var item = {};
7132
+ for (var key in window.__xbTagMap[sk2]) { if (key !== '_el') item[key] = window.__xbTagMap[sk2][key]; }
7133
+ ser[sk2] = item;
7134
+ }
7135
+ window.__xbTagSerializable = ser;
7136
+ }, 300);
7137
+ });
7138
+ window.__xbTagObserver.observe(document.body, { childList: true, subtree: true });
7139
+
7140
+ // v4\uFF1A\u751F\u6210\u53EF\u5E8F\u5217\u5316\u7248\u672C\uFF08\u53BB\u6389 _el DOM \u5F15\u7528\uFF09
7141
+ var serializable = {};
7142
+ for (var sk in window.__xbTagMap) {
7143
+ var item = {};
7144
+ for (var key in window.__xbTagMap[sk]) {
7145
+ if (key !== '_el') item[key] = window.__xbTagMap[sk][key];
7146
+ }
7147
+ serializable[sk] = item;
7148
+ }
7149
+ window.__xbTagSerializable = serializable;
7150
+ window.__xbTagStats = { total: Object.keys(window.__xbTagMap).length, byType: counters };
7151
+ return JSON.stringify(window.__xbTagStats);
7152
+ })()
7153
+ `;
7154
+ var visualTagV2Command = registerCommand({
7155
+ name: "visual-tag-v2",
7156
+ 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",
7157
+ scope: "page",
7158
+ parameters: z30.object({
7159
+ action: z30.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
7160
+ id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
7161
+ query: z30.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
7162
+ type: z30.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
7163
+ "interact-action": z30.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
7164
+ value: z30.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
7165
+ }),
7166
+ result: z30.object({
7167
+ action: z30.string(),
7168
+ total: z30.number().optional(),
7169
+ byType: z30.record(z30.number()).optional(),
7170
+ element: z30.record(z30.unknown()).optional()
7171
+ }),
7172
+ handler: async (p, ctx) => {
7173
+ switch (p.action) {
7174
+ case "tag": {
7175
+ const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
7176
+ const parsed = JSON.parse(result);
7177
+ return ok29({ action: "tag", total: parsed.total, byType: parsed.byType });
7178
+ }
7179
+ case "lookup": {
7180
+ if (!p.id) return fail14("lookup \u9700\u8981 --id");
7181
+ const result = await ctx.page.evaluate(
7182
+ `(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'})})()`
7183
+ );
7184
+ const parsed = JSON.parse(result);
7185
+ if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
7186
+ return ok29({ action: "lookup", id: p.id, element: parsed });
7187
+ }
7188
+ case "by-type": {
7189
+ const result = await ctx.page.evaluate(
7190
+ `(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)})()`
7191
+ );
7192
+ return ok29({ action: "by-type", element: JSON.parse(result) });
7193
+ }
7194
+ case "find": {
7195
+ const query = p.query;
7196
+ if (!query) return fail14('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
7197
+ const result = await ctx.page.evaluate(
7198
+ `(function(){
7199
+ var map = window.__xbTagSerializable;
7200
+ if (!map) return JSON.stringify({err:'no-map'});
7201
+ var query = ${JSON.stringify(query)};
7202
+ var results = [];
7203
+ // 1) \u76F4\u63A5\u6587\u672C\u5339\u914D
7204
+ for (var id in map) {
7205
+ var e = map[id];
7206
+ var text = (e.text || '').toLowerCase();
7207
+ var q = query.toLowerCase();
7208
+ if (text.includes(q)) {
7209
+ results.push({id:id, type:e.type, text:e.text, num:e.num, parent:e.parent, reason:'text-match'});
7210
+ }
7211
+ }
7212
+ // 2) \u7C7B\u578B\u5339\u914D\uFF08query \u542B"\u6309\u94AE"/"\u94FE\u63A5"/"\u56FE\u7247"/"\u6570\u5B57"\u7B49\uFF09
7213
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u94FE\u63A5:'click', \u56FE\u7247:'img', image:'img',
7214
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', list:'list', \u5361\u7247:'list', card:'list',
7215
+ \u6570\u5B57:'count', count:'count', \u8BA1\u6570:'count', \u6587\u672C:'text'};
7216
+ for (var tk in typeMap) {
7217
+ if (query.toLowerCase().includes(tk)) {
7218
+ for (var id2 in map) {
7219
+ if (map[id2].type === typeMap[tk]) {
7220
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, parent:map[id2].parent, reason:'type-match:'+tk});
7221
+ }
7222
+ }
7223
+ }
7224
+ }
7225
+ // 3) \u6570\u5B57\u5339\u914D\uFF08query \u542B\u6570\u5B57\uFF09
7226
+ var numMatch = query.match(/([0-9,.]+)/);
7227
+ if (numMatch && map) {
7228
+ var target = parseFloat(numMatch[1].replace(/,/g,''));
7229
+ for (var id3 in map) {
7230
+ if (map[id3].num && parseFloat(map[id3].num.replace(/,/g,'')) === target) {
7231
+ results.push({id:id3, type:map[id3].type, text:map[id3].text, num:map[id3].num, parent:map[id3].parent, reason:'num-match'});
7232
+ }
7233
+ }
7234
+ }
7235
+ return JSON.stringify({total:results.length, results:results.slice(0,20)});
7236
+ })()`
7237
+ );
7238
+ return ok29({ action: "find", query, element: JSON.parse(result) });
7239
+ }
7240
+ case "stats": {
7241
+ const result = await ctx.page.evaluate(
7242
+ `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
7243
+ );
7244
+ return ok29({ action: "stats", element: JSON.parse(result) });
7245
+ }
7246
+ case "interact": {
7247
+ const query = p.query;
7248
+ const pAny = p;
7249
+ const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
7250
+ const value = pAny.value;
7251
+ if (!query) return fail14("interact \u9700\u8981 --query \u53C2\u6570");
7252
+ if (!action) return fail14("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
7253
+ const findResult = await ctx.page.evaluate(
7254
+ `(function(){
7255
+ var map = window.__xbTagSerializable;
7256
+ if (!map) return JSON.stringify({err:'no-map'});
7257
+ var query = ${JSON.stringify(query)};
7258
+ var results = [];
7259
+ for (var id in map) {
7260
+ var e = map[id];
7261
+ var text = (e.text || '').toLowerCase();
7262
+ if (text.includes(query.toLowerCase())) {
7263
+ results.push({id:id, type:e.type, text:e.text, num:e.num, label:e.formLabel});
7264
+ }
7265
+ }
7266
+ // \u7C7B\u578B\u5339\u914D
7267
+ var typeMap = {button:'click', link:'click', \u6309\u94AE:'click', \u56FE\u7247:'img', image:'img',
7268
+ \u8F93\u5165:'input', input:'input', \u5217\u8868:'list', \u6570\u5B57:'count', count:'count'};
7269
+ for (var tk in typeMap) {
7270
+ if (query.toLowerCase().includes(tk)) {
7271
+ for (var id2 in map) {
7272
+ if (map[id2].type === typeMap[tk]) {
7273
+ results.push({id:id2, type:map[id2].type, text:map[id2].text, num:map[id2].num, label:map[id2].formLabel});
7274
+ }
7275
+ }
7276
+ }
7277
+ }
7278
+ return JSON.stringify({total:results.length, results:results.slice(0,10)});
7279
+ })()`
7280
+ );
7281
+ const parsed = JSON.parse(findResult);
7282
+ if (parsed.err) return fail14(parsed.err);
7283
+ if (!parsed.total || !parsed.results?.length) return fail14(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7284
+ const target = parsed.results[0];
7285
+ if (action === "read") {
7286
+ return ok29({ action: "interact", query, target, result: { read: target.text || target.label } });
7287
+ }
7288
+ if (action === "click") {
7289
+ const el = await ctx.page.evaluate(
7290
+ `(function(){
7291
+ var map = window.__xbTagMap;
7292
+ if (!map) return null;
7293
+ var entry = map[${JSON.stringify(target.id)}];
7294
+ if (!entry || !entry._el) return null;
7295
+ var r = entry._el.getBoundingClientRect();
7296
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7297
+ })()`
7298
+ );
7299
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7300
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7301
+ return ok29({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7302
+ }
7303
+ if (action === "fill") {
7304
+ if (!value) return fail14("fill \u9700\u8981 --value \u53C2\u6570");
7305
+ const el = await ctx.page.evaluate(
7306
+ `(function(){
7307
+ var map = window.__xbTagMap;
7308
+ if (!map) return null;
7309
+ var entry = map[${JSON.stringify(target.id)}];
7310
+ if (!entry || !entry._el) return null;
7311
+ var r = entry._el.getBoundingClientRect();
7312
+ return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7313
+ })()`
7314
+ );
7315
+ if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7316
+ await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7317
+ await ctx.page.keyboard.type(value, { stealth: true });
7318
+ return ok29({ action: "interact", query, target, result: { filled: true, value } });
7319
+ }
7320
+ return fail14(`\u672A\u77E5 action: ${action}`);
7321
+ }
7322
+ case "export": {
7323
+ const result = await ctx.page.evaluate(
7324
+ `(function(){
7325
+ var map = window.__xbTagSerializable;
7326
+ if (!map) return JSON.stringify({err:'no-map'});
7327
+ // \u6309 type \u5206\u7EC4\u7EDF\u8BA1
7328
+ var byType = {};
7329
+ for (var id in map) {
7330
+ var t = map[id].type || 'unknown';
7331
+ byType[t] = (byType[t] || 0) + 1;
7332
+ }
7333
+ // \u6784\u5EFA\u5C42\u7EA7\u6811\uFF08parent \u2192 children\uFF09
7334
+ var tree = {};
7335
+ var roots = [];
7336
+ for (var id2 in map) {
7337
+ var parent = map[id2].parent;
7338
+ if (parent && map[parent]) {
7339
+ if (!tree[parent]) tree[parent] = [];
7340
+ tree[parent].push(id2);
7341
+ } else {
7342
+ roots.push(id2);
7343
+ }
7344
+ }
7345
+ // elements \u5BFC\u51FA\u6458\u8981\uFF08\u5B8C\u6574 DOM \u6620\u5C04\u592A\u5927\uFF0C\u53EA\u5BFC\u6838\u5FC3\u5B57\u6BB5\uFF09
7346
+ var elementsOut = {};
7347
+ for (var id3 in map) {
7348
+ elementsOut[id3] = {
7349
+ type: map[id3].type,
7350
+ text: (map[id3].text || '').slice(0, 20),
7351
+ num: map[id3].num,
7352
+ label: map[id3].formLabel,
7353
+ frame: map[id3].frame,
7354
+ parent: map[id3].parent,
7355
+ table: map[id3].table ? {col: map[id3].table.col, row: map[id3].table.rowIndex} : null
7356
+ };
7357
+ }
7358
+ return JSON.stringify({
7359
+ total: Object.keys(map).length,
7360
+ byType: byType,
7361
+ rootIds: roots.slice(0, 20),
7362
+ hierarchy: Object.keys(tree).slice(0, 50).reduce(function(acc, k) { acc[k] = tree[k]; return acc; }, {}),
7363
+ elements: elementsOut
7364
+ });
7365
+ })()`
7366
+ );
7367
+ const parsed = JSON.parse(result);
7368
+ if (parsed.err) return fail14(String(parsed.err));
7369
+ return ok29({ action: "export", element: parsed });
7370
+ }
7371
+ case "clear": {
7372
+ await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7373
+ return ok29({ action: "clear" });
7374
+ }
7375
+ }
7376
+ }
7377
+ });
7378
+
6676
7379
  // src/context.ts
6677
7380
  function checkBrowserScope(scope, ctx) {
6678
7381
  switch (scope) {
@@ -7816,7 +8519,7 @@ async function guardCheck(commandName) {
7816
8519
  }
7817
8520
  }
7818
8521
  function errorResult(message) {
7819
- return { ...fail13(message), duration: 0 };
8522
+ return { ...fail15(message), duration: 0 };
7820
8523
  }
7821
8524
  function tipsToMessages(tips) {
7822
8525
  if (!tips || tips.length === 0) return [];
@@ -7896,7 +8599,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7896
8599
  }
7897
8600
  let targetPageOverride = null;
7898
8601
  if (_target && extraOpts?.cdpEndpoint) {
7899
- const { findTargetPage } = await import("./browser-TFFGGXOA.js");
8602
+ const { findTargetPage } = await import("./browser-NVC7MTML.js");
7900
8603
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7901
8604
  if (!targetPageOverride) {
7902
8605
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8092,7 +8795,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8092
8795
  timestamp: start
8093
8796
  });
8094
8797
  if (isSuccess) {
8095
- return { ...ok28(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8798
+ return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8096
8799
  }
8097
8800
  return { success: false, data: raw.data, message: raw.message, tips: mergedOrRaw, duration, ...hookOutputs ? { hookOutputs } : {} };
8098
8801
  }
@@ -8106,7 +8809,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8106
8809
  duration,
8107
8810
  timestamp: start
8108
8811
  });
8109
- return { ...ok28(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8812
+ return { ...ok30(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8110
8813
  } catch (err) {
8111
8814
  const end = Date.now();
8112
8815
  const duration = end - start;
@@ -8151,7 +8854,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8151
8854
  duration,
8152
8855
  timestamp: start
8153
8856
  });
8154
- return { ...fail13(errorMessage), duration };
8857
+ return { ...fail15(errorMessage), duration };
8155
8858
  } finally {
8156
8859
  }
8157
8860
  }
@@ -8195,7 +8898,7 @@ async function executeChain(input, options) {
8195
8898
  results.push({
8196
8899
  command: cmdName,
8197
8900
  raw: cmdStr,
8198
- ...fail13(`Plugin "${cmdName}" requires a sub-command`),
8901
+ ...fail15(`Plugin "${cmdName}" requires a sub-command`),
8199
8902
  duration: 0
8200
8903
  });
8201
8904
  if (type === "and") {
@@ -8214,7 +8917,7 @@ async function executeChain(input, options) {
8214
8917
  results.push({
8215
8918
  command: cmdName,
8216
8919
  raw: cmdStr,
8217
- ...fail13(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8920
+ ...fail15(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8218
8921
  duration: 0
8219
8922
  });
8220
8923
  if (type === "and") {
@@ -8318,7 +9021,7 @@ async function executeChain(input, options) {
8318
9021
  results.push({
8319
9022
  command: `${cmdName} ${subCommand}`,
8320
9023
  raw: cmdStr,
8321
- ...ok28(data),
9024
+ ...ok30(data),
8322
9025
  duration: duration2,
8323
9026
  ...hookOutputs ? { hookOutputs } : {}
8324
9027
  });
@@ -8346,7 +9049,7 @@ async function executeChain(input, options) {
8346
9049
  results.push({
8347
9050
  command: `${cmdName} ${subCommand}`,
8348
9051
  raw: cmdStr,
8349
- ...fail13(errorMessage),
9052
+ ...fail15(errorMessage),
8350
9053
  duration: duration2
8351
9054
  });
8352
9055
  if (type === "and") {
@@ -10578,6 +11281,7 @@ var HTML_TAGS = /* @__PURE__ */ new Set([
10578
11281
  var SELECTOR_DSL_PREFIXES = /^(text=|popup-text=|xpath=|role=|css=|chain=)/;
10579
11282
  function normalizeSelector(input) {
10580
11283
  if (!input) return input;
11284
+ if (typeof input !== "string") input = String(input);
10581
11285
  if (/^[#\.\[\:\/]/.test(input)) return input;
10582
11286
  if (input === "*") return input;
10583
11287
  if (SELECTOR_DSL_PREFIXES.test(input)) return input;
@@ -13613,6 +14317,12 @@ function findEvalStart(argv) {
13613
14317
  async function handleEvalScript(parts, argv) {
13614
14318
  const cdpEndpoint = extractCdpFromArgv(argv);
13615
14319
  const sessionName = extractSessionNameFromArgv(argv);
14320
+ if (parts[0] === "--script-b64" && parts[1]) {
14321
+ const chainResult2 = await executeChain(`eval --script-b64 ${parts[1]}`, { cdpEndpoint, sessionName });
14322
+ printChainResult(chainResult2);
14323
+ if (!chainResult2.success) throw new Error("Command failed");
14324
+ return;
14325
+ }
13616
14326
  let frame;
13617
14327
  const scriptLines = [];
13618
14328
  for (let i = 0; i < parts.length; i++) {
@@ -14112,7 +14822,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
14112
14822
  const targetPage = pages[cmdTabIndex];
14113
14823
  await targetPage.bringToFront().catch(() => {
14114
14824
  });
14115
- const { setActivePage: setActivePage2 } = await import("./browser-TFFGGXOA.js");
14825
+ const { setActivePage: setActivePage2 } = await import("./browser-NVC7MTML.js");
14116
14826
  setActivePage2(session, targetPage);
14117
14827
  }
14118
14828
  }
@@ -17285,7 +17995,7 @@ var DataCollector = class {
17285
17995
  return results;
17286
17996
  }
17287
17997
  async createBrowserContext() {
17288
- const { launch } = await import("./cdp-driver-KT6HL33W.js");
17998
+ const { launch } = await import("./cdp-driver-QYFA4QTP.js");
17289
17999
  const { browser } = await launch({
17290
18000
  headless: true,
17291
18001
  args: ["--no-sandbox", "--disable-setuid-sandbox"]