@xbrowser/cli 1.24.3 → 1.25.1

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.
@@ -20,12 +20,12 @@ import {
20
20
  resolveLaunchOpts,
21
21
  saveSessionDiskMeta,
22
22
  setActivePage
23
- } from "./chunk-X735U7G7.js";
23
+ } from "./chunk-CRRR4KUO.js";
24
24
  import {
25
25
  rand,
26
26
  sleep,
27
27
  wheelDelta
28
- } from "./chunk-GYB5BOSP.js";
28
+ } from "./chunk-R3F4K2SB.js";
29
29
  import {
30
30
  errMsg
31
31
  } from "./chunk-GDKLH7ZY.js";
@@ -63,8 +63,8 @@ function classifyFailure(message) {
63
63
 
64
64
  // src/executor.ts
65
65
  import {
66
- ok as ok30,
67
- fail as fail15,
66
+ ok as ok31,
67
+ fail as fail16,
68
68
  isCommandResult,
69
69
  CompositeStorage as CompositeStorage2,
70
70
  TipCollector as TipCollector2,
@@ -273,6 +273,9 @@ function getCommand(name) {
273
273
  function getAllCommands() {
274
274
  return Array.from(registry.values());
275
275
  }
276
+ function getCommandNames() {
277
+ return Array.from(registry.keys());
278
+ }
276
279
 
277
280
  // src/utils/ssr-detect.ts
278
281
  var SSR_VARIABLE_TO_FRAMEWORK = {
@@ -1426,37 +1429,109 @@ var uaCommand = registerCommand({
1426
1429
  }
1427
1430
  });
1428
1431
 
1429
- // src/commands/storage.ts
1432
+ // src/commands/preflight.ts
1430
1433
  import { z as z11 } from "zod";
1431
1434
  import { ok as ok11, fail as fail4 } from "@dyyz1993/xcli-core";
1435
+ var preflightCommand = registerCommand({
1436
+ name: "preflight",
1437
+ description: "Pre-flight anti-bot gate: open local detection page and verify stealth posture before any automation task",
1438
+ scope: "page",
1439
+ parameters: z11.object({
1440
+ strict: z11.boolean().optional().describe("\u5931\u8D25\u65F6\u4EE5\u975E\u96F6\u9000\u51FA\u7801\u7ED3\u675F\uFF08\u94FE\u5F0F/CI \u95E8\u7981\u7528\uFF09"),
1441
+ publish: z11.boolean().optional().describe("\u53D1\u5E03\u7C7B\u4EFB\u52A1\u95E8\u7981\uFF1Aheadless \u73AF\u5883\u76F4\u63A5\u5224\u5931\u8D25\uFF08\u9ED8\u8BA4\u7531 XBROWSER_NO_HEADLESS_PUBLISH \u63A7\u5236\uFF09")
1442
+ }),
1443
+ result: z11.object({
1444
+ gate: z11.enum(["pass", "fail"]),
1445
+ failed: z11.array(z11.string()),
1446
+ headless: z11.boolean()
1447
+ }),
1448
+ handler: async (p, ctx) => {
1449
+ const page = ctx.page;
1450
+ const tips = [];
1451
+ const ua = await page.evaluate("navigator.userAgent").catch(() => "");
1452
+ const outerW = await page.evaluate("window.outerWidth").catch(() => 0);
1453
+ const headless = /headless/i.test(ua) || outerW === 0;
1454
+ const publishMode = p.publish || process.env.XBROWSER_NO_HEADLESS_PUBLISH === "1";
1455
+ if (publishMode && headless) {
1456
+ tips.push("\u53D1\u5E03\u7C7B\u4EFB\u52A1\u7981\u7528 headless\uFF08\u98CE\u63A7\u7EA2\u7EBF\uFF09\uFF1A\u63A5\u6709\u5934\u771F\u6D4F\u89C8\u5668\u540E\u91CD\u8BD5");
1457
+ tips.push(' \u6709\u5934 Chrome: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --user-data-dir=~/.xbrowser/chrome-profile-headed --remote-debugging-port=9222');
1458
+ tips.push(" \u7136\u540E\u52A0 --cdp http://localhost:9222");
1459
+ return fail4("PREFLIGHT-FAIL: headless \u4E0D\u5141\u8BB8\u7528\u4E8E\u53D1\u5E03\u7C7B\u4EFB\u52A1\uFF08\u7528 --cdp \u63A5\u6709\u5934 Chrome\uFF09", tips);
1460
+ }
1461
+ let pageUrl = null;
1462
+ try {
1463
+ const { fileURLToPath } = await import("url");
1464
+ const { join: join9, dirname: dirname4 } = await import("path");
1465
+ const { existsSync: existsSync7 } = await import("fs");
1466
+ const here = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
1467
+ const candidates = [
1468
+ join9(dirname4(here), "..", "assets", "preflight.html"),
1469
+ join9(process.cwd(), "assets", "preflight.html")
1470
+ ];
1471
+ pageUrl = candidates.find((c) => existsSync7(c)) || null;
1472
+ } catch {
1473
+ }
1474
+ if (pageUrl) {
1475
+ await page.goto("file://" + pageUrl, { waitUntil: "domcontentloaded", timeout: 15e3 });
1476
+ } else {
1477
+ await page.goto("about:blank");
1478
+ await page.evaluate(`(function(){
1479
+ var fails=[];
1480
+ if(navigator.webdriver!==false)fails.push('webdriver');
1481
+ if(/headless/i.test(navigator.userAgent))fails.push('ua-no-headless');
1482
+ window.__pf=fails.join(',');
1483
+ document.title=fails.length?'PREFLIGHT-FAIL':'PREFLIGHT-PASS';
1484
+ })()`);
1485
+ }
1486
+ await page.waitForTimeout(1200);
1487
+ const result = await page.evaluate(`(function(){
1488
+ var out=document.getElementById('out');
1489
+ return { title: document.title, fails: out ? (out.getAttribute('data-fails')||'') : (window.__pf||'') };
1490
+ })()`).catch(() => ({ title: "PREFLIGHT-FAIL", fails: "evaluate-error" }));
1491
+ const passed = result.title === "PREFLIGHT-PASS";
1492
+ const failed = result.fails ? result.fails.split(",").filter(Boolean) : [];
1493
+ tips.push(`headless=${headless}${publishMode ? "\uFF08publish \u95E8\u7981\u5F00\u542F\uFF09" : ""}`);
1494
+ if (passed) {
1495
+ tips.push("\u9884\u68C0\u901A\u8FC7\uFF1A\u53CD\u722C\u59FF\u6001\u5168\u90E8\u65AD\u8A00\u7EFF\u706F\uFF0C\u53EF\u6267\u884C\u81EA\u52A8\u5316\u4EFB\u52A1");
1496
+ return ok11({ gate: "pass", failed: [], headless }, tips);
1497
+ }
1498
+ tips.push(`\u5931\u8D25\u9879: ${failed.join(", ") || result.title}`);
1499
+ tips.push("\u4FEE\u590D\u6307\u5F15: headless \u73AF\u5883\u63A5\u6709\u5934 Chrome\uFF08--cdp\uFF09\uFF1Bwebdriver \u6CC4\u6F0F\u68C0\u67E5 stealth \u57AB\u7247\uFF08XBROWSER_STEALTH \u4E0D\u4E3A off\uFF09");
1500
+ return fail4(`PREFLIGHT-FAIL: ${failed.join(", ") || result.title}`, tips);
1501
+ }
1502
+ });
1503
+
1504
+ // src/commands/storage.ts
1505
+ import { z as z12 } from "zod";
1506
+ import { ok as ok12, fail as fail5 } from "@dyyz1993/xcli-core";
1432
1507
  var getCookiesCommand = registerCommand({
1433
1508
  name: "get-cookies",
1434
1509
  description: "Get all cookies for the current page",
1435
1510
  scope: "page",
1436
- result: z11.object({
1437
- cookies: z11.array(z11.record(z11.unknown()))
1511
+ result: z12.object({
1512
+ cookies: z12.array(z12.record(z12.unknown()))
1438
1513
  }),
1439
1514
  handler: async (_p, ctx) => {
1440
1515
  const cookies = await ctx.browserContext.cookies();
1441
- return ok11({ cookies });
1516
+ return ok12({ cookies });
1442
1517
  }
1443
1518
  });
1444
1519
  var setCookieCommand = registerCommand({
1445
1520
  name: "set-cookie",
1446
1521
  description: "Set a cookie",
1447
1522
  scope: "page",
1448
- parameters: z11.object({
1449
- name: z11.coerce.string(),
1450
- value: z11.coerce.string(),
1451
- domain: z11.coerce.string().optional(),
1452
- path: z11.coerce.string().optional(),
1453
- url: z11.string().optional().describe("Cookie URL (alternative to domain)"),
1454
- expires: z11.number().optional(),
1455
- httpOnly: z11.boolean().optional(),
1456
- secure: z11.boolean().optional(),
1457
- sameSite: z11.enum(["Strict", "Lax", "None"]).optional()
1523
+ parameters: z12.object({
1524
+ name: z12.coerce.string(),
1525
+ value: z12.coerce.string(),
1526
+ domain: z12.coerce.string().optional(),
1527
+ path: z12.coerce.string().optional(),
1528
+ url: z12.string().optional().describe("Cookie URL (alternative to domain)"),
1529
+ expires: z12.number().optional(),
1530
+ httpOnly: z12.boolean().optional(),
1531
+ secure: z12.boolean().optional(),
1532
+ sameSite: z12.enum(["Strict", "Lax", "None"]).optional()
1458
1533
  }),
1459
- result: z11.object({ name: z11.string() }),
1534
+ result: z12.object({ name: z12.string() }),
1460
1535
  handler: async (p, ctx) => {
1461
1536
  const cookie = { ...p };
1462
1537
  if (!cookie.domain && !cookie.url) {
@@ -1471,38 +1546,38 @@ var setCookieCommand = registerCommand({
1471
1546
  }
1472
1547
  }
1473
1548
  if (!cookie.domain && !cookie.url) {
1474
- return fail4("set-cookie requires --domain or --url, or a non-blank page URL to infer from");
1549
+ return fail5("set-cookie requires --domain or --url, or a non-blank page URL to infer from");
1475
1550
  }
1476
1551
  await ctx.browserContext.addCookies([cookie]);
1477
- return ok11({ name: p.name });
1552
+ return ok12({ name: p.name });
1478
1553
  }
1479
1554
  });
1480
1555
  var clearCookiesCommand = registerCommand({
1481
1556
  name: "clear-cookies",
1482
1557
  description: "Clear all cookies",
1483
1558
  scope: "page",
1484
- result: z11.object({ cleared: z11.boolean() }),
1559
+ result: z12.object({ cleared: z12.boolean() }),
1485
1560
  handler: async (_p, ctx) => {
1486
1561
  await ctx.browserContext.clearCookies();
1487
- return ok11({ cleared: true });
1562
+ return ok12({ cleared: true });
1488
1563
  }
1489
1564
  });
1490
1565
  var getLocalStorageCommand = registerCommand({
1491
1566
  name: "get-local-storage",
1492
1567
  description: "Get localStorage entries",
1493
1568
  scope: "page",
1494
- parameters: z11.object({
1495
- key: z11.string().optional()
1569
+ parameters: z12.object({
1570
+ key: z12.string().optional()
1496
1571
  }),
1497
- result: z11.union([
1498
- z11.object({ key: z11.string(), value: z11.string().nullable() }),
1499
- z11.object({ data: z11.record(z11.string()) })
1572
+ result: z12.union([
1573
+ z12.object({ key: z12.string(), value: z12.string().nullable() }),
1574
+ z12.object({ data: z12.record(z12.string()) })
1500
1575
  ]),
1501
1576
  handler: async (p, ctx) => {
1502
1577
  try {
1503
1578
  if (p.key) {
1504
1579
  const value = await ctx.page.evaluate((k) => localStorage.getItem(k), p.key);
1505
- return ok11({ key: p.key, value });
1580
+ return ok12({ key: p.key, value });
1506
1581
  }
1507
1582
  const data = await ctx.page.evaluate(() => {
1508
1583
  const entries = {};
@@ -1512,9 +1587,9 @@ var getLocalStorageCommand = registerCommand({
1512
1587
  }
1513
1588
  return entries;
1514
1589
  });
1515
- return ok11({ data });
1590
+ return ok12({ data });
1516
1591
  } catch (e) {
1517
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1592
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1518
1593
  }
1519
1594
  }
1520
1595
  });
@@ -1522,11 +1597,11 @@ var setLocalStorageCommand = registerCommand({
1522
1597
  name: "set-local-storage",
1523
1598
  description: "Set a localStorage entry",
1524
1599
  scope: "page",
1525
- parameters: z11.object({
1526
- key: z11.string(),
1527
- value: z11.string()
1600
+ parameters: z12.object({
1601
+ key: z12.string(),
1602
+ value: z12.string()
1528
1603
  }),
1529
- result: z11.object({ key: z11.string() }),
1604
+ result: z12.object({ key: z12.string() }),
1530
1605
  handler: async (p, ctx) => {
1531
1606
  try {
1532
1607
  await ctx.page.evaluate(
@@ -1535,9 +1610,9 @@ var setLocalStorageCommand = registerCommand({
1535
1610
  },
1536
1611
  { key: p.key, value: p.value }
1537
1612
  );
1538
- return ok11({ key: p.key });
1613
+ return ok12({ key: p.key });
1539
1614
  } catch (e) {
1540
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1615
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1541
1616
  }
1542
1617
  }
1543
1618
  });
@@ -1545,20 +1620,20 @@ var clearLocalStorageCommand = registerCommand({
1545
1620
  name: "clear-local-storage",
1546
1621
  description: "Clear all localStorage entries",
1547
1622
  scope: "page",
1548
- result: z11.object({ cleared: z11.boolean() }),
1623
+ result: z12.object({ cleared: z12.boolean() }),
1549
1624
  handler: async (_p, ctx) => {
1550
1625
  try {
1551
1626
  await ctx.page.evaluate(() => localStorage.clear());
1552
- return ok11({ cleared: true });
1627
+ return ok12({ cleared: true });
1553
1628
  } catch (e) {
1554
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1629
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1555
1630
  }
1556
1631
  }
1557
1632
  });
1558
1633
 
1559
1634
  // src/commands/screenshot.ts
1560
- import { z as z12 } from "zod";
1561
- import { ok as ok12, fail as fail5 } from "@dyyz1993/xcli-core";
1635
+ import { z as z13 } from "zod";
1636
+ import { ok as ok13, fail as fail6 } from "@dyyz1993/xcli-core";
1562
1637
  import { writeFileSync, mkdirSync } from "fs";
1563
1638
  import { dirname, join as join4 } from "path";
1564
1639
  function ensureScreenshotsDir() {
@@ -1585,23 +1660,23 @@ var screenshotCommand = registerCommand({
1585
1660
  description: "Take a screenshot of the page or element (auto-saved to the OS temp dir unless --output is given; persistent override: xbrowser config set screenshots.dir <path>)",
1586
1661
  scope: "page",
1587
1662
  selectorParams: ["selector"],
1588
- parameters: z12.object({
1589
- selector: z12.string().optional(),
1590
- type: z12.enum(["png", "jpeg"]).optional(),
1591
- fullPage: z12.boolean().optional(),
1592
- output: z12.string().optional(),
1593
- base64: z12.boolean().optional().describe("Return base64 data instead of file path")
1663
+ parameters: z13.object({
1664
+ selector: z13.string().optional(),
1665
+ type: z13.enum(["png", "jpeg"]).optional(),
1666
+ fullPage: z13.boolean().optional(),
1667
+ output: z13.string().optional(),
1668
+ base64: z13.boolean().optional().describe("Return base64 data instead of file path")
1594
1669
  }),
1595
- result: z12.union([
1596
- z12.object({
1597
- data: z12.string(),
1598
- format: z12.string(),
1599
- size: z12.number()
1670
+ result: z13.union([
1671
+ z13.object({
1672
+ data: z13.string(),
1673
+ format: z13.string(),
1674
+ size: z13.number()
1600
1675
  }),
1601
- z12.object({
1602
- output: z12.string(),
1603
- format: z12.string(),
1604
- size: z12.number()
1676
+ z13.object({
1677
+ output: z13.string(),
1678
+ format: z13.string(),
1679
+ size: z13.number()
1605
1680
  })
1606
1681
  ]),
1607
1682
  handler: async (p, ctx) => {
@@ -1619,21 +1694,21 @@ var screenshotCommand = registerCommand({
1619
1694
  if (p.output) {
1620
1695
  const dirErr = ensureParentDir(p.output);
1621
1696
  if (dirErr) {
1622
- return fail5(`Cannot create directory for --output "${p.output}": ${dirErr}`);
1697
+ return fail6(`Cannot create directory for --output "${p.output}": ${dirErr}`);
1623
1698
  }
1624
1699
  try {
1625
1700
  writeFileSync(p.output, buffer, "binary");
1626
1701
  } catch (err) {
1627
- return fail5(`Failed to write screenshot to "${p.output}": ${err instanceof Error ? err.message : String(err)}`);
1702
+ return fail6(`Failed to write screenshot to "${p.output}": ${err instanceof Error ? err.message : String(err)}`);
1628
1703
  }
1629
- return ok12({
1704
+ return ok13({
1630
1705
  output: p.output,
1631
1706
  format,
1632
1707
  size: buffer.length
1633
1708
  });
1634
1709
  }
1635
1710
  if (p.base64) {
1636
- return ok12({
1711
+ return ok13({
1637
1712
  data: buffer.toString("base64"),
1638
1713
  format,
1639
1714
  size: buffer.length
@@ -1642,7 +1717,7 @@ var screenshotCommand = registerCommand({
1642
1717
  ensureScreenshotsDir();
1643
1718
  const screenshotPath = generateScreenshotPath(format);
1644
1719
  writeFileSync(screenshotPath, buffer, "binary");
1645
- return ok12({
1720
+ return ok13({
1646
1721
  output: screenshotPath,
1647
1722
  format,
1648
1723
  size: buffer.length
@@ -1651,19 +1726,19 @@ var screenshotCommand = registerCommand({
1651
1726
  });
1652
1727
 
1653
1728
  // src/commands/structure.ts
1654
- import { z as z13 } from "zod";
1655
- import { ok as ok13 } from "@dyyz1993/xcli-core";
1729
+ import { z as z14 } from "zod";
1730
+ import { ok as ok14 } from "@dyyz1993/xcli-core";
1656
1731
  var structureCommand = registerCommand({
1657
1732
  name: "structure",
1658
1733
  description: "Get the DOM structure of the page or an element",
1659
1734
  scope: "page",
1660
1735
  selectorParams: ["selector"],
1661
- parameters: z13.object({
1662
- selector: z13.string().optional(),
1663
- depth: z13.number().optional()
1736
+ parameters: z14.object({
1737
+ selector: z14.string().optional(),
1738
+ depth: z14.number().optional()
1664
1739
  }),
1665
- result: z13.object({
1666
- structure: z13.record(z13.unknown())
1740
+ result: z14.object({
1741
+ structure: z14.record(z14.unknown())
1667
1742
  }),
1668
1743
  handler: async (p, ctx) => {
1669
1744
  const structure = await ctx.page.evaluate(
@@ -1695,30 +1770,30 @@ var structureCommand = registerCommand({
1695
1770
  },
1696
1771
  { sel: p.selector || "body", maxDepth: p.depth || 5 }
1697
1772
  );
1698
- return ok13({ structure });
1773
+ return ok14({ structure });
1699
1774
  }
1700
1775
  });
1701
1776
 
1702
1777
  // src/commands/viewport.ts
1703
- import { z as z14 } from "zod";
1704
- import { ok as ok14 } from "@dyyz1993/xcli-core";
1778
+ import { z as z15 } from "zod";
1779
+ import { ok as ok15 } from "@dyyz1993/xcli-core";
1705
1780
  var setViewportCommand = registerCommand({
1706
1781
  name: "set-viewport",
1707
1782
  description: "Set the viewport size and properties",
1708
1783
  scope: "browser",
1709
- parameters: z14.object({
1710
- width: z14.coerce.number(),
1711
- height: z14.coerce.number(),
1712
- deviceScaleFactor: z14.coerce.number().optional(),
1713
- isMobile: z14.boolean().optional(),
1714
- hasTouch: z14.boolean().optional()
1784
+ parameters: z15.object({
1785
+ width: z15.coerce.number(),
1786
+ height: z15.coerce.number(),
1787
+ deviceScaleFactor: z15.coerce.number().optional(),
1788
+ isMobile: z15.boolean().optional(),
1789
+ hasTouch: z15.boolean().optional()
1715
1790
  }),
1716
- result: z14.object({
1717
- width: z14.number(),
1718
- height: z14.number(),
1719
- deviceScaleFactor: z14.number().optional(),
1720
- isMobile: z14.boolean().optional(),
1721
- hasTouch: z14.boolean().optional()
1791
+ result: z15.object({
1792
+ width: z15.number(),
1793
+ height: z15.number(),
1794
+ deviceScaleFactor: z15.number().optional(),
1795
+ isMobile: z15.boolean().optional(),
1796
+ hasTouch: z15.boolean().optional()
1722
1797
  }),
1723
1798
  handler: async (p, ctx) => {
1724
1799
  const viewport = ctx.page.viewportSize();
@@ -1731,7 +1806,7 @@ var setViewportCommand = registerCommand({
1731
1806
  ...p.isMobile !== void 0 && { isMobile: p.isMobile },
1732
1807
  ...p.hasTouch !== void 0 && { hasTouch: p.hasTouch }
1733
1808
  });
1734
- return ok14({
1809
+ return ok15({
1735
1810
  width,
1736
1811
  height,
1737
1812
  ...p.deviceScaleFactor !== void 0 && { deviceScaleFactor: p.deviceScaleFactor },
@@ -1742,17 +1817,17 @@ var setViewportCommand = registerCommand({
1742
1817
  });
1743
1818
 
1744
1819
  // src/commands/frame.ts
1745
- import { z as z15 } from "zod";
1746
- import { ok as ok15, fail as fail6 } from "@dyyz1993/xcli-core";
1820
+ import { z as z16 } from "zod";
1821
+ import { ok as ok16, fail as fail7 } from "@dyyz1993/xcli-core";
1747
1822
  var framesCommand = registerCommand({
1748
1823
  name: "frames",
1749
1824
  description: "List all frames in the current page",
1750
1825
  scope: "page",
1751
- result: z15.object({
1752
- frames: z15.array(z15.object({
1753
- index: z15.number(),
1754
- name: z15.string().nullable(),
1755
- url: z15.string()
1826
+ result: z16.object({
1827
+ frames: z16.array(z16.object({
1828
+ index: z16.number(),
1829
+ name: z16.string().nullable(),
1830
+ url: z16.string()
1756
1831
  }))
1757
1832
  }),
1758
1833
  handler: async (_p, ctx) => {
@@ -1763,21 +1838,21 @@ var framesCommand = registerCommand({
1763
1838
  name: frame.name(),
1764
1839
  url: frame.url()
1765
1840
  }));
1766
- return ok15({ frames: frameList });
1841
+ return ok16({ frames: frameList });
1767
1842
  }
1768
1843
  });
1769
1844
  var frameCommand = registerCommand({
1770
1845
  name: "frame",
1771
1846
  description: "Get frame info by index or name",
1772
1847
  scope: "page",
1773
- parameters: z15.object({
1774
- index: z15.number().int().min(0).optional(),
1775
- name: z15.string().optional()
1848
+ parameters: z16.object({
1849
+ index: z16.number().int().min(0).optional(),
1850
+ name: z16.string().optional()
1776
1851
  }),
1777
- result: z15.object({
1778
- name: z15.string().nullable(),
1779
- url: z15.string(),
1780
- error: z15.string().optional()
1852
+ result: z16.object({
1853
+ name: z16.string().nullable(),
1854
+ url: z16.string(),
1855
+ error: z16.string().optional()
1781
1856
  }),
1782
1857
  handler: async (p, ctx) => {
1783
1858
  const discover = ctx.page.discoverFrames;
@@ -1788,12 +1863,12 @@ var frameCommand = registerCommand({
1788
1863
  } else if (p.name !== void 0) {
1789
1864
  targetFrame = rawFrames.find((f) => f.name() === p.name);
1790
1865
  } else {
1791
- return fail6("Must provide index or name");
1866
+ return fail7("Must provide index or name");
1792
1867
  }
1793
1868
  if (!targetFrame) {
1794
- return fail6("Frame not found");
1869
+ return fail7("Frame not found");
1795
1870
  }
1796
- return ok15({
1871
+ return ok16({
1797
1872
  name: targetFrame.name(),
1798
1873
  url: targetFrame.url()
1799
1874
  });
@@ -1801,27 +1876,27 @@ var frameCommand = registerCommand({
1801
1876
  });
1802
1877
 
1803
1878
  // src/commands/ui-debug.ts
1804
- import { z as z16 } from "zod";
1805
- import { ok as ok16 } from "@dyyz1993/xcli-core";
1879
+ import { z as z17 } from "zod";
1880
+ import { ok as ok17 } from "@dyyz1993/xcli-core";
1806
1881
  var consoleCheckCommand = registerCommand({
1807
1882
  name: "console",
1808
1883
  description: "Collect and analyze browser console messages (errors, warnings, logs)",
1809
1884
  scope: "page",
1810
- parameters: z16.object({
1811
- url: z16.string().optional().describe("URL to navigate first (optional, uses current page if omitted)"),
1812
- duration: z16.number().optional().default(5e3).describe("How long to collect messages (ms)"),
1813
- filter: z16.enum(["all", "error", "warning", "info", "log"]).optional().default("all"),
1814
- includeStackTraces: z16.boolean().optional().default(true)
1885
+ parameters: z17.object({
1886
+ url: z17.string().optional().describe("URL to navigate first (optional, uses current page if omitted)"),
1887
+ duration: z17.number().optional().default(5e3).describe("How long to collect messages (ms)"),
1888
+ filter: z17.enum(["all", "error", "warning", "info", "log"]).optional().default("all"),
1889
+ includeStackTraces: z17.boolean().optional().default(true)
1815
1890
  }),
1816
- result: z16.object({
1817
- url: z16.string(),
1818
- duration: z16.number(),
1819
- total: z16.number(),
1820
- errors: z16.number(),
1821
- warnings: z16.number(),
1822
- messages: z16.array(z16.record(z16.unknown())),
1823
- summary: z16.string(),
1824
- passed: z16.boolean()
1891
+ result: z17.object({
1892
+ url: z17.string(),
1893
+ duration: z17.number(),
1894
+ total: z17.number(),
1895
+ errors: z17.number(),
1896
+ warnings: z17.number(),
1897
+ messages: z17.array(z17.record(z17.unknown())),
1898
+ summary: z17.string(),
1899
+ passed: z17.boolean()
1825
1900
  }),
1826
1901
  handler: async (p, ctx) => {
1827
1902
  const { page } = ctx;
@@ -1903,7 +1978,7 @@ ${a.stack || ""}`;
1903
1978
  const filtered = p.filter === "all" ? messages : messages.filter((m) => m.type === p.filter);
1904
1979
  const errorCount = messages.filter((m) => m.type === "error").length;
1905
1980
  const warnCount = messages.filter((m) => m.type === "warning").length;
1906
- return ok16({
1981
+ return ok17({
1907
1982
  url: page.url(),
1908
1983
  duration: p.duration,
1909
1984
  total: messages.length,
@@ -1919,23 +1994,23 @@ var networkCheckCommand = registerCommand({
1919
1994
  name: "net-debug",
1920
1995
  description: "Monitor and analyze network requests \u2014 capture failed requests, slow responses, status codes",
1921
1996
  scope: "page",
1922
- parameters: z16.object({
1923
- url: z16.string().optional().describe("URL to navigate first"),
1924
- duration: z16.number().optional().default(5e3).describe("How long to monitor (ms)"),
1925
- filter: z16.enum(["all", "failed", "slow", "error", "xhr", "fetch", "document", "stylesheet", "script", "image"]).optional().default("all"),
1926
- slowThreshold: z16.number().optional().default(3e3).describe('Threshold for "slow" requests (ms)')
1997
+ parameters: z17.object({
1998
+ url: z17.string().optional().describe("URL to navigate first"),
1999
+ duration: z17.number().optional().default(5e3).describe("How long to monitor (ms)"),
2000
+ filter: z17.enum(["all", "failed", "slow", "error", "xhr", "fetch", "document", "stylesheet", "script", "image"]).optional().default("all"),
2001
+ slowThreshold: z17.number().optional().default(3e3).describe('Threshold for "slow" requests (ms)')
1927
2002
  }),
1928
- result: z16.object({
1929
- url: z16.string(),
1930
- duration: z16.number(),
1931
- totalRequests: z16.number(),
1932
- failedRequests: z16.number(),
1933
- slowRequests: z16.number(),
1934
- errorRequests: z16.number(),
1935
- totalSizeKB: z16.number(),
1936
- requests: z16.array(z16.record(z16.unknown())),
1937
- summary: z16.string(),
1938
- passed: z16.boolean()
2003
+ result: z17.object({
2004
+ url: z17.string(),
2005
+ duration: z17.number(),
2006
+ totalRequests: z17.number(),
2007
+ failedRequests: z17.number(),
2008
+ slowRequests: z17.number(),
2009
+ errorRequests: z17.number(),
2010
+ totalSizeKB: z17.number(),
2011
+ requests: z17.array(z17.record(z17.unknown())),
2012
+ summary: z17.string(),
2013
+ passed: z17.boolean()
1939
2014
  }),
1940
2015
  handler: async (p, ctx) => {
1941
2016
  const { page } = ctx;
@@ -2017,7 +2092,7 @@ var networkCheckCommand = registerCommand({
2017
2092
  const slowCount = requests.filter((r) => r.duration >= p.slowThreshold).length;
2018
2093
  const errorCount = requests.filter((r) => r.error).length;
2019
2094
  const totalSize = requests.reduce((sum, r) => sum + r.size, 0);
2020
- return ok16({
2095
+ return ok17({
2021
2096
  url: page.url(),
2022
2097
  duration: p.duration,
2023
2098
  totalRequests: requests.length,
@@ -2039,17 +2114,17 @@ var perfCheckCommand = registerCommand({
2039
2114
  name: "perf",
2040
2115
  description: "Audit page performance metrics \u2014 load time, FCP, LCP, CLS, TTFB, resource sizes",
2041
2116
  scope: "page",
2042
- parameters: z16.object({
2043
- url: z16.string().optional().describe("URL to navigate (uses current page if omitted)"),
2044
- iterations: z16.number().optional().default(1).describe("Number of iterations to average")
2117
+ parameters: z17.object({
2118
+ url: z17.string().optional().describe("URL to navigate (uses current page if omitted)"),
2119
+ iterations: z17.number().optional().default(1).describe("Number of iterations to average")
2045
2120
  }),
2046
- result: z16.object({
2047
- url: z16.string(),
2048
- iterations: z16.number(),
2049
- metrics: z16.record(z16.unknown()),
2050
- allIterations: z16.array(z16.record(z16.unknown())).optional(),
2051
- passed: z16.boolean(),
2052
- summary: z16.string()
2121
+ result: z17.object({
2122
+ url: z17.string(),
2123
+ iterations: z17.number(),
2124
+ metrics: z17.record(z17.unknown()),
2125
+ allIterations: z17.array(z17.record(z17.unknown())).optional(),
2126
+ passed: z17.boolean(),
2127
+ summary: z17.string()
2053
2128
  }),
2054
2129
  handler: async (p, ctx) => {
2055
2130
  const { page } = ctx;
@@ -2111,7 +2186,7 @@ var perfCheckCommand = registerCommand({
2111
2186
  if (resourceStats) avg.resourceStats = resourceStats;
2112
2187
  return avg;
2113
2188
  })();
2114
- return ok16({
2189
+ return ok17({
2115
2190
  url: page.url(),
2116
2191
  iterations: p.iterations,
2117
2192
  metrics: avgMetrics,
@@ -2125,23 +2200,23 @@ var healthCheckCommand = registerCommand({
2125
2200
  name: "health",
2126
2201
  description: "Comprehensive page health check \u2014 broken links, missing images, console errors, SEO issues",
2127
2202
  scope: "page",
2128
- parameters: z16.object({
2129
- url: z16.string().optional().describe("URL to check"),
2130
- checkLinks: z16.boolean().optional().default(true).describe("Check for broken links"),
2131
- checkImages: z16.boolean().optional().default(true).describe("Check for missing/broken images"),
2132
- checkMeta: z16.boolean().optional().default(true).describe("Check SEO meta tags"),
2133
- maxLinks: z16.number().optional().default(50).describe("Max links to check")
2203
+ parameters: z17.object({
2204
+ url: z17.string().optional().describe("URL to check"),
2205
+ checkLinks: z17.boolean().optional().default(true).describe("Check for broken links"),
2206
+ checkImages: z17.boolean().optional().default(true).describe("Check for missing/broken images"),
2207
+ checkMeta: z17.boolean().optional().default(true).describe("Check SEO meta tags"),
2208
+ maxLinks: z17.number().optional().default(50).describe("Max links to check")
2134
2209
  }),
2135
- result: z16.object({
2136
- url: z16.string(),
2137
- title: z16.string(),
2138
- passed: z16.boolean(),
2139
- totalIssues: z16.number(),
2140
- errors: z16.number(),
2141
- warnings: z16.number(),
2142
- info: z16.number(),
2143
- issues: z16.array(z16.record(z16.unknown())),
2144
- summary: z16.string()
2210
+ result: z17.object({
2211
+ url: z17.string(),
2212
+ title: z17.string(),
2213
+ passed: z17.boolean(),
2214
+ totalIssues: z17.number(),
2215
+ errors: z17.number(),
2216
+ warnings: z17.number(),
2217
+ info: z17.number(),
2218
+ issues: z17.array(z17.record(z17.unknown())),
2219
+ summary: z17.string()
2145
2220
  }),
2146
2221
  handler: async (p, ctx) => {
2147
2222
  const { page } = ctx;
@@ -2228,7 +2303,7 @@ var healthCheckCommand = registerCommand({
2228
2303
  }, { checkLinks: p.checkLinks, checkImages: p.checkImages, checkMeta: p.checkMeta, maxLinks: p.maxLinks });
2229
2304
  const errors = result.issues.filter((i) => i.severity === "error").length;
2230
2305
  const warnings = result.issues.filter((i) => i.severity === "warning").length;
2231
- return ok16({
2306
+ return ok17({
2232
2307
  url: result.url,
2233
2308
  title: result.title,
2234
2309
  passed: errors === 0,
@@ -2243,8 +2318,8 @@ var healthCheckCommand = registerCommand({
2243
2318
  });
2244
2319
 
2245
2320
  // src/commands/actions.ts
2246
- import { z as z17 } from "zod";
2247
- import { ok as ok17 } from "@dyyz1993/xcli-core";
2321
+ import { z as z18 } from "zod";
2322
+ import { ok as ok18 } from "@dyyz1993/xcli-core";
2248
2323
  import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
2249
2324
  import { join as join5 } from "path";
2250
2325
  function ensureScreenshotsDir2() {
@@ -2256,53 +2331,53 @@ function generateScreenshotPath2(format) {
2256
2331
  const ext = format === "jpeg" ? "jpg" : "png";
2257
2332
  return join5(resolveScreenshotsDir(), `screenshot-${timestamp}-${random}.${ext}`);
2258
2333
  }
2259
- var waitActionSchema = z17.object({
2260
- type: z17.literal("wait"),
2261
- milliseconds: z17.number().positive().optional(),
2262
- selector: z17.string().optional()
2334
+ var waitActionSchema = z18.object({
2335
+ type: z18.literal("wait"),
2336
+ milliseconds: z18.number().positive().optional(),
2337
+ selector: z18.string().optional()
2263
2338
  }).refine(
2264
2339
  (d) => (d.milliseconds !== void 0 || d.selector !== void 0) && !(d.milliseconds !== void 0 && d.selector !== void 0),
2265
2340
  { message: "Either 'milliseconds' or 'selector' must be provided, but not both." }
2266
2341
  );
2267
- var clickActionSchema = z17.object({
2268
- type: z17.literal("click"),
2269
- selector: z17.string(),
2270
- all: z17.boolean().optional()
2342
+ var clickActionSchema = z18.object({
2343
+ type: z18.literal("click"),
2344
+ selector: z18.string(),
2345
+ all: z18.boolean().optional()
2271
2346
  });
2272
- var screenshotActionSchema = z17.object({
2273
- type: z17.literal("screenshot"),
2274
- fullPage: z17.boolean().optional(),
2275
- quality: z17.number().min(1).max(100).optional(),
2276
- viewport: z17.object({ width: z17.number().int().positive(), height: z17.number().int().positive() }).optional(),
2277
- base64: z17.boolean().optional().describe("Return base64 data instead of file path")
2347
+ var screenshotActionSchema = z18.object({
2348
+ type: z18.literal("screenshot"),
2349
+ fullPage: z18.boolean().optional(),
2350
+ quality: z18.number().min(1).max(100).optional(),
2351
+ viewport: z18.object({ width: z18.number().int().positive(), height: z18.number().int().positive() }).optional(),
2352
+ base64: z18.boolean().optional().describe("Return base64 data instead of file path")
2278
2353
  });
2279
- var writeActionSchema = z17.object({
2280
- type: z17.literal("write"),
2281
- text: z17.string()
2354
+ var writeActionSchema = z18.object({
2355
+ type: z18.literal("write"),
2356
+ text: z18.string()
2282
2357
  });
2283
- var pressActionSchema = z17.object({
2284
- type: z17.literal("press"),
2285
- key: z17.string()
2358
+ var pressActionSchema = z18.object({
2359
+ type: z18.literal("press"),
2360
+ key: z18.string()
2286
2361
  });
2287
- var scrollActionSchema = z17.object({
2288
- type: z17.literal("scroll"),
2289
- direction: z17.enum(["up", "down"]).optional(),
2290
- selector: z17.string().optional()
2362
+ var scrollActionSchema = z18.object({
2363
+ type: z18.literal("scroll"),
2364
+ direction: z18.enum(["up", "down"]).optional(),
2365
+ selector: z18.string().optional()
2291
2366
  });
2292
- var scrapeActionSchema = z17.object({
2293
- type: z17.literal("scrape")
2367
+ var scrapeActionSchema = z18.object({
2368
+ type: z18.literal("scrape")
2294
2369
  });
2295
- var executeJavascriptActionSchema = z17.object({
2296
- type: z17.literal("executeJavascript"),
2297
- script: z17.string()
2370
+ var executeJavascriptActionSchema = z18.object({
2371
+ type: z18.literal("executeJavascript"),
2372
+ script: z18.string()
2298
2373
  });
2299
- var pdfActionSchema = z17.object({
2300
- type: z17.literal("pdf"),
2301
- landscape: z17.boolean().optional(),
2302
- scale: z17.number().optional(),
2303
- format: z17.enum(["A0", "A1", "A2", "A3", "A4", "A5", "A6", "Letter", "Legal", "Tabloid", "Ledger"]).optional()
2374
+ var pdfActionSchema = z18.object({
2375
+ type: z18.literal("pdf"),
2376
+ landscape: z18.boolean().optional(),
2377
+ scale: z18.number().optional(),
2378
+ format: z18.enum(["A0", "A1", "A2", "A3", "A4", "A5", "A6", "Letter", "Legal", "Tabloid", "Ledger"]).optional()
2304
2379
  });
2305
- var actionSchema = z17.union([
2380
+ var actionSchema = z18.union([
2306
2381
  waitActionSchema,
2307
2382
  clickActionSchema,
2308
2383
  screenshotActionSchema,
@@ -2393,11 +2468,11 @@ var actionsCommand = registerCommand({
2393
2468
  name: "actions",
2394
2469
  description: "Execute a sequence of actions (wait, click, scroll, screenshot, fill, etc.)",
2395
2470
  scope: "page",
2396
- parameters: z17.object({
2397
- url: z17.string().describe("Starting URL"),
2398
- actions: z17.array(actionSchema).max(MAX_ACTIONS).describe("Array of actions (max 50)"),
2399
- output: z17.enum(["text", "json"]).default("json").describe("Output format: text or json"),
2400
- timeout: z17.number().default(60).describe("Overall timeout in seconds (default: 60)")
2471
+ parameters: z18.object({
2472
+ url: z18.string().describe("Starting URL"),
2473
+ actions: z18.array(actionSchema).max(MAX_ACTIONS).describe("Array of actions (max 50)"),
2474
+ output: z18.enum(["text", "json"]).default("json").describe("Output format: text or json"),
2475
+ timeout: z18.number().default(60).describe("Overall timeout in seconds (default: 60)")
2401
2476
  }),
2402
2477
  handler: async (p, ctx) => {
2403
2478
  await ctx.page.goto(p.url, { waitUntil: "domcontentloaded" });
@@ -2417,14 +2492,14 @@ var actionsCommand = registerCommand({
2417
2492
  const finalUrl = ctx.page.url();
2418
2493
  const timedOut = results.length < p.actions.length;
2419
2494
  if (p.output === "text") {
2420
- return ok17({
2495
+ return ok18({
2421
2496
  title,
2422
2497
  url: finalUrl,
2423
2498
  actions: results.map((r) => JSON.stringify(r)).join("\n"),
2424
2499
  ...timedOut ? { warning: `Timed out after ${p.timeout}s, completed ${results.length}/${p.actions.length} actions` } : {}
2425
2500
  });
2426
2501
  }
2427
- return ok17({
2502
+ return ok18({
2428
2503
  title,
2429
2504
  url: finalUrl,
2430
2505
  results,
@@ -2434,8 +2509,8 @@ var actionsCommand = registerCommand({
2434
2509
  });
2435
2510
 
2436
2511
  // src/commands/scrape.ts
2437
- import { z as z18 } from "zod";
2438
- import { ok as ok18, fail as fail7 } from "@dyyz1993/xcli-core";
2512
+ import { z as z19 } from "zod";
2513
+ import { ok as ok19, fail as fail8 } from "@dyyz1993/xcli-core";
2439
2514
 
2440
2515
  // src/lib/html-to-markdown.ts
2441
2516
  import * as cheerio from "cheerio";
@@ -2820,15 +2895,15 @@ var scrapeCommand = registerCommand({
2820
2895
  description: "Scrape a page and convert to Markdown (with JS rendering)",
2821
2896
  scope: "project",
2822
2897
  selectorParams: ["selector"],
2823
- parameters: z18.object({
2824
- url: z18.string().optional(),
2825
- selector: z18.string().optional(),
2826
- timeout: z18.number().default(3e4),
2827
- format: z18.enum(["markdown", "html", "text"]).default("markdown"),
2828
- onlyMainContent: z18.boolean().default(true),
2829
- retries: z18.number().int().min(0).max(5).optional().default(2).describe("\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 2\uFF09"),
2830
- waitAfterLoad: z18.number().int().optional().default(0).describe("\u9875\u9762\u52A0\u8F7D\u540E\u989D\u5916\u7B49\u5F85\u6BEB\u79D2"),
2831
- mode: z18.enum(["raw", "clean", "compact", "smart"]).default("raw").describe("\u8F93\u51FA\u6A21\u5F0F\uFF1Araw\uFF08\u9ED8\u8BA4\uFF09/ clean\uFF08\u7ED3\u6784\u5316\uFF09/ compact\uFF08\u7CBE\u7B80\uFF09/ smart\uFF08\u7ED3\u6784\u5316\uFF0C\u7559\u7ED9 agent \u589E\u5F3A\uFF09")
2898
+ parameters: z19.object({
2899
+ url: z19.string().optional(),
2900
+ selector: z19.string().optional(),
2901
+ timeout: z19.number().default(3e4),
2902
+ format: z19.enum(["markdown", "html", "text"]).default("markdown"),
2903
+ onlyMainContent: z19.boolean().default(true),
2904
+ retries: z19.number().int().min(0).max(5).optional().default(2).describe("\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 2\uFF09"),
2905
+ waitAfterLoad: z19.number().int().optional().default(0).describe("\u9875\u9762\u52A0\u8F7D\u540E\u989D\u5916\u7B49\u5F85\u6BEB\u79D2"),
2906
+ mode: z19.enum(["raw", "clean", "compact", "smart"]).default("raw").describe("\u8F93\u51FA\u6A21\u5F0F\uFF1Araw\uFF08\u9ED8\u8BA4\uFF09/ clean\uFF08\u7ED3\u6784\u5316\uFF09/ compact\uFF08\u7CBE\u7B80\uFF09/ smart\uFF08\u7ED3\u6784\u5316\uFF0C\u7559\u7ED9 agent \u589E\u5F3A\uFF09")
2832
2907
  }),
2833
2908
  handler: async (p, ctx) => {
2834
2909
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
@@ -2836,7 +2911,7 @@ var scrapeCommand = registerCommand({
2836
2911
  try {
2837
2912
  const targetUrl = p.url || page.url();
2838
2913
  if (!targetUrl || targetUrl === "about:blank") {
2839
- return fail7("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
2914
+ return fail8("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
2840
2915
  }
2841
2916
  let lastError;
2842
2917
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -2906,7 +2981,7 @@ var scrapeCommand = registerCommand({
2906
2981
  } catch {
2907
2982
  }
2908
2983
  if (p.mode === "smart") {
2909
- return ok18(structured);
2984
+ return ok19(structured);
2910
2985
  }
2911
2986
  if (p.mode === "compact") {
2912
2987
  const compactData = structured.tables.length > 0 ? structured.tables.map((t) => ({
@@ -2919,9 +2994,9 @@ var scrapeCommand = registerCommand({
2919
2994
  return compact;
2920
2995
  })
2921
2996
  })) : structured.mainText?.substring(0, 500);
2922
- return ok18({ url: structured.url, title: structured.title, data: compactData });
2997
+ return ok19({ url: structured.url, title: structured.title, data: compactData });
2923
2998
  }
2924
- return ok18(structured);
2999
+ return ok19(structured);
2925
3000
  }
2926
3001
  let content;
2927
3002
  switch (p.format) {
@@ -2980,7 +3055,7 @@ var scrapeCommand = registerCommand({
2980
3055
  content = await page.innerText("body");
2981
3056
  break;
2982
3057
  }
2983
- return ok18({ content, title, url: finalUrl });
3058
+ return ok19({ content, title, url: finalUrl });
2984
3059
  } catch (err) {
2985
3060
  lastError = err instanceof Error ? err : new Error(String(err));
2986
3061
  if (attempt < maxAttempts) {
@@ -2990,20 +3065,20 @@ var scrapeCommand = registerCommand({
2990
3065
  }
2991
3066
  }
2992
3067
  }
2993
- return fail7(`Scrape failed after ${maxAttempts} attempt(s): ${lastError?.message ?? "unknown error"}`);
3068
+ return fail8(`Scrape failed after ${maxAttempts} attempt(s): ${lastError?.message ?? "unknown error"}`);
2994
3069
  } finally {
2995
3070
  await closeEphemeralContext(context);
2996
3071
  }
2997
3072
  },
2998
- result: z18.object({
2999
- url: z18.string(),
3000
- title: z18.string()
3073
+ result: z19.object({
3074
+ url: z19.string(),
3075
+ title: z19.string()
3001
3076
  }).passthrough()
3002
3077
  });
3003
3078
 
3004
3079
  // src/commands/map.ts
3005
- import { z as z19 } from "zod";
3006
- import { ok as ok19, fail as fail8 } from "@dyyz1993/xcli-core";
3080
+ import { z as z20 } from "zod";
3081
+ import { ok as ok20, fail as fail9 } from "@dyyz1993/xcli-core";
3007
3082
 
3008
3083
  // src/utils/url.ts
3009
3084
  var SKIP_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -3238,21 +3313,21 @@ var mapCommand = registerCommand({
3238
3313
  name: "map",
3239
3314
  description: "Discover all URLs on a website via sitemap and page link extraction",
3240
3315
  scope: "project",
3241
- parameters: z19.object({
3242
- url: z19.string().optional(),
3243
- search: z19.string().optional(),
3244
- sitemap: z19.enum(["include", "only"]).optional(),
3245
- includeSubdomains: z19.boolean().optional(),
3246
- allowExternalLinks: z19.boolean().optional().describe("Include links to external domains"),
3247
- limit: z19.number().optional(),
3248
- verbose: z19.boolean().default(false).describe("Show progress feedback")
3316
+ parameters: z20.object({
3317
+ url: z20.string().optional(),
3318
+ search: z20.string().optional(),
3319
+ sitemap: z20.enum(["include", "only"]).optional(),
3320
+ includeSubdomains: z20.boolean().optional(),
3321
+ allowExternalLinks: z20.boolean().optional().describe("Include links to external domains"),
3322
+ limit: z20.number().optional(),
3323
+ verbose: z20.boolean().default(false).describe("Show progress feedback")
3249
3324
  }),
3250
3325
  handler: async (p, ctx) => {
3251
3326
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
3252
3327
  try {
3253
3328
  const targetUrl = p.url || page.url();
3254
3329
  if (!targetUrl || targetUrl === "about:blank") {
3255
- return fail8("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3330
+ return fail9("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3256
3331
  }
3257
3332
  const links = await discoverUrls(page, targetUrl, {
3258
3333
  sitemap: p.sitemap,
@@ -3263,7 +3338,7 @@ var mapCommand = registerCommand({
3263
3338
  verbose: p.verbose
3264
3339
  });
3265
3340
  const linkObjects = links.map((url) => ({ url }));
3266
- return ok19({
3341
+ return ok20({
3267
3342
  links: linkObjects,
3268
3343
  success: true
3269
3344
  });
@@ -3271,15 +3346,15 @@ var mapCommand = registerCommand({
3271
3346
  await closeEphemeralContext(context);
3272
3347
  }
3273
3348
  },
3274
- result: z19.object({
3275
- links: z19.array(z19.object({ url: z19.string() })),
3276
- success: z19.boolean()
3349
+ result: z20.object({
3350
+ links: z20.array(z20.object({ url: z20.string() })),
3351
+ success: z20.boolean()
3277
3352
  })
3278
3353
  });
3279
3354
 
3280
3355
  // src/commands/crawl.ts
3281
- import { z as z20 } from "zod";
3282
- import { ok as ok20 } from "@dyyz1993/xcli-core";
3356
+ import { z as z21 } from "zod";
3357
+ import { ok as ok21 } from "@dyyz1993/xcli-core";
3283
3358
  function stripHashAnchorQuery(url) {
3284
3359
  try {
3285
3360
  const parsed = new URL(url);
@@ -3456,21 +3531,21 @@ var crawlCommand = registerCommand({
3456
3531
  name: "crawl",
3457
3532
  description: "Crawl a website and extract content from all pages",
3458
3533
  scope: "project",
3459
- parameters: z20.object({
3460
- url: z20.string(),
3461
- limit: z20.number().default(10),
3462
- maxDepth: z20.number().default(3),
3463
- includePaths: z20.array(z20.string()).optional(),
3464
- excludePaths: z20.array(z20.string()).optional(),
3465
- allowSubdomains: z20.boolean().default(false),
3466
- allowExternalLinks: z20.boolean().default(false),
3467
- allowBackwardCrawling: z20.boolean().default(false),
3468
- enableSpa: z20.boolean().default(true).describe("Disable to skip SPA route detection"),
3469
- format: z20.enum(["markdown", "html"]).default("markdown"),
3470
- onlyMainContent: z20.boolean().default(true),
3471
- concurrency: z20.number().default(3),
3472
- retries: z20.number().default(2),
3473
- verbose: z20.boolean().default(false)
3534
+ parameters: z21.object({
3535
+ url: z21.string(),
3536
+ limit: z21.number().default(10),
3537
+ maxDepth: z21.number().default(3),
3538
+ includePaths: z21.array(z21.string()).optional(),
3539
+ excludePaths: z21.array(z21.string()).optional(),
3540
+ allowSubdomains: z21.boolean().default(false),
3541
+ allowExternalLinks: z21.boolean().default(false),
3542
+ allowBackwardCrawling: z21.boolean().default(false),
3543
+ enableSpa: z21.boolean().default(true).describe("Disable to skip SPA route detection"),
3544
+ format: z21.enum(["markdown", "html"]).default("markdown"),
3545
+ onlyMainContent: z21.boolean().default(true),
3546
+ concurrency: z21.number().default(3),
3547
+ retries: z21.number().default(2),
3548
+ verbose: z21.boolean().default(false)
3474
3549
  }),
3475
3550
  handler: async (p, ctx) => {
3476
3551
  const startUrl = new URL(p.url);
@@ -3609,7 +3684,7 @@ var crawlCommand = registerCommand({
3609
3684
  if (errorPages.length > 0) {
3610
3685
  response.errors = errorPages;
3611
3686
  }
3612
- return ok20(response);
3687
+ return ok21(response);
3613
3688
  } finally {
3614
3689
  for (const ctx2 of contexts) {
3615
3690
  await ctx2.close().catch(() => {
@@ -3619,15 +3694,15 @@ var crawlCommand = registerCommand({
3619
3694
  } catch (err) {
3620
3695
  const message = err instanceof Error ? err.message : String(err);
3621
3696
  const successPages = results.filter((r) => !isPageError(r));
3622
- return ok20({ pages: successPages, total: successPages.length, success: false, error: message });
3697
+ return ok21({ pages: successPages, total: successPages.length, success: false, error: message });
3623
3698
  }
3624
3699
  }
3625
3700
  });
3626
3701
 
3627
3702
  // src/commands/search.ts
3628
- import { z as z21 } from "zod";
3703
+ import { z as z22 } from "zod";
3629
3704
  import * as cheerio2 from "cheerio";
3630
- import { ok as ok21 } from "@dyyz1993/xcli-core";
3705
+ import { ok as ok22 } from "@dyyz1993/xcli-core";
3631
3706
  function getRecencyParams(recency) {
3632
3707
  const now = Math.floor(Date.now() / 1e3);
3633
3708
  switch (recency) {
@@ -3961,16 +4036,16 @@ var searchCommand = registerCommand({
3961
4036
  name: "search",
3962
4037
  description: "Search the web and extract results with engine fallback",
3963
4038
  scope: "project",
3964
- parameters: z21.object({
3965
- query: z21.string(),
3966
- engine: z21.string().optional(),
3967
- limit: z21.number().default(10),
3968
- full: z21.boolean().default(false),
3969
- format: z21.enum(["markdown", "json", "text"]).default("markdown"),
3970
- timeout: z21.number().default(15e3),
3971
- recency: z21.enum(["hour", "day", "week", "month", "year"]).optional().describe("Filter by time: hour/day/week/month/year"),
3972
- fallback: z21.boolean().default(false).describe("Sequential engine fallback instead of parallel"),
3973
- site: z21.string().optional().describe("Limit results to a specific site (e.g. github.com, v2ex.com)")
4039
+ parameters: z22.object({
4040
+ query: z22.string(),
4041
+ engine: z22.string().optional(),
4042
+ limit: z22.number().default(10),
4043
+ full: z22.boolean().default(false),
4044
+ format: z22.enum(["markdown", "json", "text"]).default("markdown"),
4045
+ timeout: z22.number().default(15e3),
4046
+ recency: z22.enum(["hour", "day", "week", "month", "year"]).optional().describe("Filter by time: hour/day/week/month/year"),
4047
+ fallback: z22.boolean().default(false).describe("Sequential engine fallback instead of parallel"),
4048
+ site: z22.string().optional().describe("Limit results to a specific site (e.g. github.com, v2ex.com)")
3974
4049
  }),
3975
4050
  handler: async (p, ctx) => {
3976
4051
  const { context } = await createEphemeralContext(resolveLaunchOpts(ctx));
@@ -4076,7 +4151,7 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4076
4151
  lines.push(`> ${r.snippet}`);
4077
4152
  lines.push("");
4078
4153
  }
4079
- return ok21({ ...searchResult, content: lines.join("\n") });
4154
+ return ok22({ ...searchResult, content: lines.join("\n") });
4080
4155
  }
4081
4156
  if (p.format === "text") {
4082
4157
  const lines = [`Search: ${searchResult.query} (Engine: ${searchResult.engine}, Total: ${searchResult.total})`, ""];
@@ -4086,9 +4161,9 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4086
4161
  lines.push(` ${r.snippet}`);
4087
4162
  lines.push("");
4088
4163
  }
4089
- return ok21({ ...searchResult, content: lines.join("\n") });
4164
+ return ok22({ ...searchResult, content: lines.join("\n") });
4090
4165
  }
4091
- return ok21(searchResult);
4166
+ return ok22(searchResult);
4092
4167
  } finally {
4093
4168
  await closeEphemeralContext(context);
4094
4169
  }
@@ -4096,8 +4171,8 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4096
4171
  });
4097
4172
 
4098
4173
  // src/commands/network.ts
4099
- import { z as z22 } from "zod";
4100
- import { ok as ok22, fail as fail9 } from "@dyyz1993/xcli-core";
4174
+ import { z as z23 } from "zod";
4175
+ import { ok as ok23, fail as fail10 } from "@dyyz1993/xcli-core";
4101
4176
  function extractPath2(url) {
4102
4177
  try {
4103
4178
  const u = new URL(url);
@@ -4195,19 +4270,19 @@ var networkCommand = registerCommand({
4195
4270
  name: "network",
4196
4271
  description: "Capture and filter network responses from a URL",
4197
4272
  scope: "project",
4198
- parameters: z22.object({
4199
- url: z22.string(),
4200
- filter: z22.string().optional(),
4201
- match: z22.string().optional(),
4202
- search: z22.string().optional().describe("Search within all captured response bodies"),
4203
- console: z22.boolean().default(false),
4204
- timeout: z22.number().default(3e4),
4205
- wait: z22.number().default(3e3),
4206
- limit: z22.number().default(50),
4207
- format: z22.enum(["summary", "json"]).default("summary"),
4208
- ws: z22.boolean().optional().default(false).describe("Only show WebSocket messages"),
4209
- listen: z22.boolean().optional().default(false).describe("\u76D1\u542C\u6A21\u5F0F\uFF1A\u4F7F\u7528\u73B0\u6709 session \u7684 page\uFF0C\u7B49\u5F85\u6307\u5B9A\u65F6\u95F4\u6355\u83B7\u8BF7\u6C42"),
4210
- duration: z22.number().int().optional().default(15e3).describe("\u76D1\u542C\u6A21\u5F0F\u7B49\u5F85\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 15000\uFF09")
4273
+ parameters: z23.object({
4274
+ url: z23.string(),
4275
+ filter: z23.string().optional(),
4276
+ match: z23.string().optional(),
4277
+ search: z23.string().optional().describe("Search within all captured response bodies"),
4278
+ console: z23.boolean().default(false),
4279
+ timeout: z23.number().default(3e4),
4280
+ wait: z23.number().default(3e3),
4281
+ limit: z23.number().default(50),
4282
+ format: z23.enum(["summary", "json"]).default("summary"),
4283
+ ws: z23.boolean().optional().default(false).describe("Only show WebSocket messages"),
4284
+ listen: z23.boolean().optional().default(false).describe("\u76D1\u542C\u6A21\u5F0F\uFF1A\u4F7F\u7528\u73B0\u6709 session \u7684 page\uFF0C\u7B49\u5F85\u6307\u5B9A\u65F6\u95F4\u6355\u83B7\u8BF7\u6C42"),
4285
+ duration: z23.number().int().optional().default(15e3).describe("\u76D1\u542C\u6A21\u5F0F\u7B49\u5F85\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 15000\uFF09")
4211
4286
  }),
4212
4287
  handler: async (p, ctx) => {
4213
4288
  const startTime = Date.now();
@@ -4262,7 +4337,7 @@ var networkCommand = registerCommand({
4262
4337
  };
4263
4338
  if (p.listen) {
4264
4339
  const page2 = ctx.page;
4265
- if (!page2) return fail9("No active page. Use --cdp to connect first.");
4340
+ if (!page2) return fail10("No active page. Use --cdp to connect first.");
4266
4341
  const captures = [];
4267
4342
  const consoleMessages = [];
4268
4343
  const wsCaptures = [];
@@ -4289,7 +4364,7 @@ var networkCommand = registerCommand({
4289
4364
  page2.off("response", handler);
4290
4365
  const duration = Date.now() - startTime;
4291
4366
  if (p.ws && wsCaptures.length > 0) {
4292
- return ok22({
4367
+ return ok23({
4293
4368
  url: "[listen mode]",
4294
4369
  duration,
4295
4370
  total: captures.length,
@@ -4303,9 +4378,9 @@ var networkCommand = registerCommand({
4303
4378
  });
4304
4379
  }
4305
4380
  if (p.format === "json") {
4306
- return ok22(buildJsonOutput("[listen mode]", captures, consoleMessages, captures.length, wsCaptures));
4381
+ return ok23(buildJsonOutput("[listen mode]", captures, consoleMessages, captures.length, wsCaptures));
4307
4382
  }
4308
- return ok22(buildSummaryOutput("[listen mode]", duration, captures, consoleMessages, captures.length, wsCaptures));
4383
+ return ok23(buildSummaryOutput("[listen mode]", duration, captures, consoleMessages, captures.length, wsCaptures));
4309
4384
  }
4310
4385
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
4311
4386
  try {
@@ -4360,7 +4435,7 @@ var networkCommand = registerCommand({
4360
4435
  }
4361
4436
  const duration = Date.now() - startTime;
4362
4437
  if (p.ws && wsCaptures.length > 0) {
4363
- return ok22({
4438
+ return ok23({
4364
4439
  url: p.url,
4365
4440
  duration,
4366
4441
  total: captures.length,
@@ -4374,9 +4449,9 @@ var networkCommand = registerCommand({
4374
4449
  });
4375
4450
  }
4376
4451
  if (p.format === "json") {
4377
- return ok22(buildJsonOutput(p.url, results, consoleMessages, totalCount, wsCaptures, searchResults));
4452
+ return ok23(buildJsonOutput(p.url, results, consoleMessages, totalCount, wsCaptures, searchResults));
4378
4453
  }
4379
- return ok22(buildSummaryOutput(p.url, duration, results, consoleMessages, totalCount, wsCaptures));
4454
+ return ok23(buildSummaryOutput(p.url, duration, results, consoleMessages, totalCount, wsCaptures));
4380
4455
  } finally {
4381
4456
  await closeEphemeralContext(context);
4382
4457
  }
@@ -4384,7 +4459,7 @@ var networkCommand = registerCommand({
4384
4459
  });
4385
4460
 
4386
4461
  // src/commands/ai-search-engines.ts
4387
- import { z as z23 } from "zod";
4462
+ import { z as z24 } from "zod";
4388
4463
  var ENGINE_CONFIGS = {
4389
4464
  deepseek: {
4390
4465
  key: "deepseek",
@@ -4638,11 +4713,11 @@ var ENGINE_CONFIGS = {
4638
4713
  }
4639
4714
  };
4640
4715
  var ALL_ENGINE_KEYS = Object.keys(ENGINE_CONFIGS);
4641
- var ENGINE_KEY_ENUM = z23.enum(ALL_ENGINE_KEYS);
4716
+ var ENGINE_KEY_ENUM = z24.enum(ALL_ENGINE_KEYS);
4642
4717
 
4643
4718
  // src/commands/snapshot.ts
4644
- import { z as z24 } from "zod";
4645
- import { ok as ok23, fail as fail10, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
4719
+ import { z as z25 } from "zod";
4720
+ import { ok as ok24, fail as fail11, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
4646
4721
 
4647
4722
  // src/runtime/ref-store.ts
4648
4723
  var sessions = /* @__PURE__ */ new Map();
@@ -5554,24 +5629,24 @@ var snapshotCommand = registerCommand({
5554
5629
  description: "Capture a quick page state snapshot \u2014 aria tree, visible text, or DOM summary",
5555
5630
  scope: "page",
5556
5631
  selectorParams: ["selector"],
5557
- parameters: z24.object({
5558
- type: z24.enum(["aria", "text", "dom", "all"]).default("aria").describe("Snapshot type: aria (accessibility tree), text (visible text), dom (element summary), all (combined)"),
5559
- selector: z24.string().optional().describe("Scope to a specific element"),
5560
- depth: z24.number().optional().default(6).describe("Max depth for DOM/aria tree"),
5561
- interactive: z24.boolean().optional().default(false).describe("Return interactive agent refs only"),
5562
- interactiveOnly: z24.boolean().optional().default(false).describe("Alias for interactive"),
5563
- i: z24.boolean().optional().default(false).describe("Short alias for interactive"),
5564
- compact: z24.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5565
- c: z24.boolean().optional().default(false).describe("Short alias for compact"),
5566
- selectors: z24.boolean().optional().default(false).describe("Include ref to CSS selector map"),
5567
- all: z24.boolean().optional().default(false).describe("Include hidden interactive targets when using interactive snapshot")
5632
+ parameters: z25.object({
5633
+ type: z25.enum(["aria", "text", "dom", "all"]).default("aria").describe("Snapshot type: aria (accessibility tree), text (visible text), dom (element summary), all (combined)"),
5634
+ selector: z25.string().optional().describe("Scope to a specific element"),
5635
+ depth: z25.number().optional().default(6).describe("Max depth for DOM/aria tree"),
5636
+ interactive: z25.boolean().optional().default(false).describe("Return interactive agent refs only"),
5637
+ interactiveOnly: z25.boolean().optional().default(false).describe("Alias for interactive"),
5638
+ i: z25.boolean().optional().default(false).describe("Short alias for interactive"),
5639
+ compact: z25.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5640
+ c: z25.boolean().optional().default(false).describe("Short alias for compact"),
5641
+ selectors: z25.boolean().optional().default(false).describe("Include ref to CSS selector map"),
5642
+ all: z25.boolean().optional().default(false).describe("Include hidden interactive targets when using interactive snapshot")
5568
5643
  }),
5569
- result: z24.object({
5570
- url: z24.string(),
5571
- title: z24.string(),
5572
- aria: z24.string().optional(),
5573
- text: z24.string().optional(),
5574
- dom: z24.record(z24.unknown()).optional()
5644
+ result: z25.object({
5645
+ url: z25.string(),
5646
+ title: z25.string(),
5647
+ aria: z25.string().optional(),
5648
+ text: z25.string().optional(),
5649
+ dom: z25.record(z25.unknown()).optional()
5575
5650
  }),
5576
5651
  handler: async (p, ctx) => {
5577
5652
  const page = ctx.page;
@@ -5585,7 +5660,7 @@ var snapshotCommand = registerCommand({
5585
5660
  if (p.compact || p.c || p.interactive || p.interactiveOnly || p.i) {
5586
5661
  observation.compact = formatObservationCompact(observation, { selectors: p.selectors });
5587
5662
  }
5588
- return ok23(observation, normalizeTips3([
5663
+ return ok24(observation, normalizeTips3([
5589
5664
  `refs refreshed for ${observation.targets.length} targets; use click @e1 or fill @e2 "text"`
5590
5665
  ]));
5591
5666
  }
@@ -5593,15 +5668,15 @@ var snapshotCommand = registerCommand({
5593
5668
  const aria = await captureAriaSnapshot(page, p.selector, p.depth);
5594
5669
  const tips = await buildRefTips(page, aria);
5595
5670
  persistSemantics(url, aria);
5596
- return ok23({ url, title, aria }, normalizeTips3(tips));
5671
+ return ok24({ url, title, aria }, normalizeTips3(tips));
5597
5672
  }
5598
5673
  if (p.type === "text") {
5599
5674
  const text = await captureTextSnapshot(page, p.selector);
5600
- return ok23({ url, title, text });
5675
+ return ok24({ url, title, text });
5601
5676
  }
5602
5677
  if (p.type === "dom") {
5603
5678
  const dom = await captureDomSnapshot(page, p.selector, p.depth ?? 6);
5604
- return ok23({ url, title, dom });
5679
+ return ok24({ url, title, dom });
5605
5680
  }
5606
5681
  if (p.type === "all") {
5607
5682
  const [aria, text, dom] = await Promise.all([
@@ -5611,9 +5686,9 @@ var snapshotCommand = registerCommand({
5611
5686
  ]);
5612
5687
  const tips = await buildRefTips(page, aria);
5613
5688
  persistSemantics(url, aria);
5614
- return ok23({ url, title, aria, text, dom }, normalizeTips3(tips));
5689
+ return ok24({ url, title, aria, text, dom }, normalizeTips3(tips));
5615
5690
  }
5616
- return fail10(`Unknown snapshot type: ${p.type}`);
5691
+ return fail11(`Unknown snapshot type: ${p.type}`);
5617
5692
  }
5618
5693
  });
5619
5694
  function persistSemantics(url, aria) {
@@ -5690,22 +5765,22 @@ async function captureDomSnapshot(page, selector, maxDepth) {
5690
5765
  }
5691
5766
 
5692
5767
  // src/commands/agent.ts
5693
- import { z as z25 } from "zod";
5694
- import { ok as ok24, normalizeTips as normalizeTips4 } from "@dyyz1993/xcli-core";
5768
+ import { z as z26 } from "zod";
5769
+ import { ok as ok25, normalizeTips as normalizeTips4 } from "@dyyz1993/xcli-core";
5695
5770
  var observeCommand = registerCommand({
5696
5771
  name: "observe",
5697
5772
  description: "Observe the current page as structured agent targets with session refs",
5698
5773
  scope: "page",
5699
- parameters: z25.object({
5700
- includeHidden: z25.boolean().optional().default(false).describe("Include hidden elements in the target list"),
5701
- limit: z25.number().int().positive().max(300).optional().default(80).describe("Maximum number of targets to return"),
5702
- compact: z25.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5703
- selectors: z25.boolean().optional().default(false).describe("Include ref to stable CSS selector map")
5774
+ parameters: z26.object({
5775
+ includeHidden: z26.boolean().optional().default(false).describe("Include hidden elements in the target list"),
5776
+ limit: z26.number().int().positive().max(300).optional().default(80).describe("Maximum number of targets to return"),
5777
+ compact: z26.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5778
+ selectors: z26.boolean().optional().default(false).describe("Include ref to stable CSS selector map")
5704
5779
  }),
5705
- result: z25.object({
5706
- targets: z25.array(z25.record(z25.unknown())),
5707
- selectors: z25.record(z25.unknown()).optional(),
5708
- compact: z25.string().optional()
5780
+ result: z26.object({
5781
+ targets: z26.array(z26.record(z26.unknown())),
5782
+ selectors: z26.record(z26.unknown()).optional(),
5783
+ compact: z26.string().optional()
5709
5784
  }).passthrough(),
5710
5785
  handler: async (p, ctx) => {
5711
5786
  const observation = await observePage(ctx.page, ctx.sessionId, {
@@ -5714,7 +5789,7 @@ var observeCommand = registerCommand({
5714
5789
  });
5715
5790
  if (p.selectors) observation.selectors = buildSelectorMap(observation);
5716
5791
  if (p.compact) observation.compact = formatObservationCompact(observation, { selectors: p.selectors });
5717
- return ok24(observation, normalizeTips4([
5792
+ return ok25(observation, normalizeTips4([
5718
5793
  `refs refreshed for ${observation.targets.length} targets; use act --ref @e1 --action click or click @e1`
5719
5794
  ]));
5720
5795
  }
@@ -5724,14 +5799,14 @@ var actCommand = registerCommand({
5724
5799
  description: "Perform an agent action using an observe ref or explicit selector",
5725
5800
  scope: "element",
5726
5801
  selectorParams: ["selector"],
5727
- parameters: z25.object({
5728
- action: z25.enum(["click", "fill", "type", "press", "select", "check", "hover"]).default("click"),
5729
- ref: z25.string().optional().describe("Session-scoped ref returned by observe, such as e1"),
5730
- selector: z25.string().optional().describe("CSS selector fallback when no ref is available"),
5731
- value: z25.string().optional().describe("Value for fill/type/select"),
5732
- key: z25.string().optional().describe("Key for press"),
5733
- force: z25.boolean().optional().default(false).describe("Bypass actionability checks"),
5734
- timeout: z25.number().optional().default(1e4).describe("Playwright action timeout in milliseconds")
5802
+ parameters: z26.object({
5803
+ action: z26.enum(["click", "fill", "type", "press", "select", "check", "hover"]).default("click"),
5804
+ ref: z26.string().optional().describe("Session-scoped ref returned by observe, such as e1"),
5805
+ selector: z26.string().optional().describe("CSS selector fallback when no ref is available"),
5806
+ value: z26.string().optional().describe("Value for fill/type/select"),
5807
+ key: z26.string().optional().describe("Key for press"),
5808
+ force: z26.boolean().optional().default(false).describe("Bypass actionability checks"),
5809
+ timeout: z26.number().optional().default(1e4).describe("Playwright action timeout in milliseconds")
5735
5810
  }).refine((p) => !!p.ref || !!p.selector, {
5736
5811
  message: "Either ref or selector is required"
5737
5812
  }),
@@ -5745,7 +5820,7 @@ var actCommand = registerCommand({
5745
5820
  tips: normalizeTips4(result.stale ? ["run observe again to refresh refs"] : [])
5746
5821
  };
5747
5822
  }
5748
- return ok24(result, normalizeTips4(result.stale ? ["ref screen hash changed; run observe if the next action is uncertain"] : []));
5823
+ return ok25(result, normalizeTips4(result.stale ? ["ref screen hash changed; run observe if the next action is uncertain"] : []));
5749
5824
  }
5750
5825
  });
5751
5826
  var waitForCommand = registerCommand({
@@ -5753,16 +5828,16 @@ var waitForCommand = registerCommand({
5753
5828
  description: "Wait for agent predicates such as text, URL, load state, selector state, or screen hash changes",
5754
5829
  scope: "page",
5755
5830
  selectorParams: ["selector"],
5756
- parameters: z25.object({
5757
- selector: z25.string().optional().describe("CSS selector or observe ref to wait for"),
5758
- state: z25.enum(["attached", "detached", "visible", "hidden"]).optional().default("visible"),
5759
- text: z25.string().optional().describe("Visible text to wait for"),
5760
- url: z25.string().optional().describe("URL substring or glob pattern to wait for"),
5761
- load: z25.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("Load state to wait for"),
5762
- fn: z25.string().optional().describe("JavaScript predicate to wait for"),
5763
- screenHashChanged: z25.string().optional().describe("Previous screenHash from observe"),
5764
- timeout: z25.number().optional().default(3e4),
5765
- pollInterval: z25.number().optional().default(200)
5831
+ parameters: z26.object({
5832
+ selector: z26.string().optional().describe("CSS selector or observe ref to wait for"),
5833
+ state: z26.enum(["attached", "detached", "visible", "hidden"]).optional().default("visible"),
5834
+ text: z26.string().optional().describe("Visible text to wait for"),
5835
+ url: z26.string().optional().describe("URL substring or glob pattern to wait for"),
5836
+ load: z26.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("Load state to wait for"),
5837
+ fn: z26.string().optional().describe("JavaScript predicate to wait for"),
5838
+ screenHashChanged: z26.string().optional().describe("Previous screenHash from observe"),
5839
+ timeout: z26.number().optional().default(3e4),
5840
+ pollInterval: z26.number().optional().default(200)
5766
5841
  }).refine((p) => [p.selector, p.text, p.url, p.load, p.fn, p.screenHashChanged].filter(Boolean).length === 1, {
5767
5842
  message: "Provide exactly one wait predicate: selector, text, url, load, fn, or screenHashChanged"
5768
5843
  }),
@@ -5776,30 +5851,30 @@ var waitForCommand = registerCommand({
5776
5851
  tips: []
5777
5852
  };
5778
5853
  }
5779
- return ok24(result);
5854
+ return ok25(result);
5780
5855
  }
5781
5856
  });
5782
5857
 
5783
5858
  // src/commands/tab.ts
5784
- import { z as z26 } from "zod";
5785
- import { ok as ok25, fail as fail11 } from "@dyyz1993/xcli-core";
5786
- var TabParams = z26.object({
5787
- subcommand: z26.enum(["list", "new", "close", "switch"]),
5788
- url: z26.string().optional(),
5789
- index: z26.number().int().min(0).optional()
5859
+ import { z as z27 } from "zod";
5860
+ import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
5861
+ var TabParams = z27.object({
5862
+ subcommand: z27.enum(["list", "new", "close", "switch"]),
5863
+ url: z27.string().optional(),
5864
+ index: z27.number().int().min(0).optional()
5790
5865
  });
5791
5866
  var tabCommand = registerCommand({
5792
5867
  name: "tab",
5793
5868
  description: "Manage browser tabs: list, new, close, switch",
5794
5869
  scope: "page",
5795
5870
  parameters: TabParams,
5796
- result: z26.object({
5797
- success: z26.boolean(),
5798
- data: z26.unknown()
5871
+ result: z27.object({
5872
+ success: z27.boolean(),
5873
+ data: z27.unknown()
5799
5874
  }),
5800
5875
  handler: async (p, ctx) => {
5801
5876
  if (!ctx.browserContext) {
5802
- return fail11("No browser context available. Use --cdp to connect to a browser first.");
5877
+ return fail12("No browser context available. Use --cdp to connect to a browser first.");
5803
5878
  }
5804
5879
  const pages = ctx.browserContext.pages();
5805
5880
  switch (p.subcommand) {
@@ -5812,7 +5887,7 @@ var tabCommand = registerCommand({
5812
5887
  case "switch":
5813
5888
  return handleSwitch(p, pages, ctx);
5814
5889
  default:
5815
- return fail11(`Unknown subcommand: ${p.subcommand}`);
5890
+ return fail12(`Unknown subcommand: ${p.subcommand}`);
5816
5891
  }
5817
5892
  }
5818
5893
  });
@@ -5827,7 +5902,7 @@ async function handleList(pages, ctx) {
5827
5902
  if (isActive) activeIndex = i;
5828
5903
  tabs.push({ index: i, url, title, active: isActive });
5829
5904
  }
5830
- return ok25({ tabs, total: tabs.length, activeIndex });
5905
+ return ok26({ tabs, total: tabs.length, activeIndex });
5831
5906
  }
5832
5907
  async function handleNew(p, _pages, ctx) {
5833
5908
  const newPage = await ctx.browserContext.newPage();
@@ -5855,7 +5930,7 @@ async function handleNew(p, _pages, ctx) {
5855
5930
  const title = await newPage.title().catch(() => "");
5856
5931
  const allPages = ctx.browserContext.pages();
5857
5932
  const newIndex = allPages.indexOf(newPage);
5858
- return ok25({
5933
+ return ok26({
5859
5934
  index: newIndex >= 0 ? newIndex : allPages.length - 1,
5860
5935
  url: newPage.url(),
5861
5936
  title,
@@ -5866,11 +5941,11 @@ async function handleNew(p, _pages, ctx) {
5866
5941
  async function handleClose(p, ctx) {
5867
5942
  const currentPages = ctx.browserContext.pages();
5868
5943
  if (currentPages.length <= 1) {
5869
- return fail11("Cannot close the last remaining tab");
5944
+ return fail12("Cannot close the last remaining tab");
5870
5945
  }
5871
5946
  const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
5872
5947
  if (closeIndex < 0 || closeIndex >= currentPages.length) {
5873
- return fail11(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
5948
+ return fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
5874
5949
  }
5875
5950
  const pageToClose = currentPages[closeIndex];
5876
5951
  const isActivePage = pageToClose === ctx.page;
@@ -5885,7 +5960,7 @@ async function handleClose(p, ctx) {
5885
5960
  }
5886
5961
  ctx.page = newActivePage;
5887
5962
  }
5888
- return ok25({
5963
+ return ok26({
5889
5964
  closedIndex: closeIndex,
5890
5965
  total: remainingPages.length,
5891
5966
  activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
@@ -5893,10 +5968,10 @@ async function handleClose(p, ctx) {
5893
5968
  }
5894
5969
  async function handleSwitch(p, pages, ctx) {
5895
5970
  if (p.index === void 0) {
5896
- return fail11("Parameter --index is required for switch subcommand");
5971
+ return fail12("Parameter --index is required for switch subcommand");
5897
5972
  }
5898
5973
  if (p.index < 0 || p.index >= pages.length) {
5899
- return fail11(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
5974
+ return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
5900
5975
  }
5901
5976
  const targetPage = pages[p.index];
5902
5977
  await targetPage.bringToFront().catch(() => {
@@ -5918,7 +5993,7 @@ async function handleSwitch(p, pages, ctx) {
5918
5993
  }
5919
5994
  ctx.page = targetPage;
5920
5995
  const title = await targetPage.title().catch(() => "");
5921
- return ok25({
5996
+ return ok26({
5922
5997
  index: p.index,
5923
5998
  url: targetPage.url(),
5924
5999
  title,
@@ -5927,8 +6002,8 @@ async function handleSwitch(p, pages, ctx) {
5927
6002
  }
5928
6003
 
5929
6004
  // src/commands/addinitscript.ts
5930
- import { z as z27 } from "zod";
5931
- import { ok as ok26 } from "@dyyz1993/xcli-core";
6005
+ import { z as z28 } from "zod";
6006
+ import { ok as ok27 } from "@dyyz1993/xcli-core";
5932
6007
  import { readFileSync as readFileSync4 } from "fs";
5933
6008
 
5934
6009
  // src/chain-parser.ts
@@ -6069,14 +6144,14 @@ registerCommandDefinition("tab", ["subcommand"]);
6069
6144
  registerCommandDefinition("mouse", ["action", "x", "y"]);
6070
6145
 
6071
6146
  // src/commands/addinitscript.ts
6072
- var InitScriptParams = z27.object({
6073
- script: z27.string().optional(),
6074
- file: z27.string().optional(),
6075
- stdin: z27.boolean().optional(),
6076
- name: z27.string().optional(),
6077
- list: z27.boolean().optional(),
6078
- remove: z27.union([z27.string(), z27.boolean()]).optional(),
6079
- base64: z27.string().optional()
6147
+ var InitScriptParams = z28.object({
6148
+ script: z28.string().optional(),
6149
+ file: z28.string().optional(),
6150
+ stdin: z28.boolean().optional(),
6151
+ name: z28.string().optional(),
6152
+ list: z28.boolean().optional(),
6153
+ remove: z28.union([z28.string(), z28.boolean()]).optional(),
6154
+ base64: z28.string().optional()
6080
6155
  });
6081
6156
  var registeredScripts = /* @__PURE__ */ new Map();
6082
6157
  function resolveScriptContent(params) {
@@ -6110,14 +6185,14 @@ var addInitScriptCommand = registerCommand({
6110
6185
  description: "Add an initialization script that runs on every page load",
6111
6186
  scope: "page",
6112
6187
  parameters: InitScriptParams,
6113
- result: z27.object({
6114
- scripts: z27.array(z27.object({ name: z27.string(), size: z27.number(), preview: z27.string() })).optional(),
6115
- removed: z27.string().optional(),
6116
- existed: z27.boolean().optional(),
6117
- error: z27.string().optional(),
6118
- registered: z27.string().optional(),
6119
- hint: z27.string().optional(),
6120
- executedImmediately: z27.boolean().optional()
6188
+ result: z28.object({
6189
+ scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6190
+ removed: z28.string().optional(),
6191
+ existed: z28.boolean().optional(),
6192
+ error: z28.string().optional(),
6193
+ registered: z28.string().optional(),
6194
+ hint: z28.string().optional(),
6195
+ executedImmediately: z28.boolean().optional()
6121
6196
  }).passthrough(),
6122
6197
  handler: async (params, ctx) => {
6123
6198
  if (params.list) {
@@ -6126,20 +6201,20 @@ var addInitScriptCommand = registerCommand({
6126
6201
  size: content2.length,
6127
6202
  preview: content2.slice(0, 80)
6128
6203
  }));
6129
- return ok26({ scripts });
6204
+ return ok27({ scripts });
6130
6205
  }
6131
6206
  if (params.remove && typeof params.remove === "string") {
6132
6207
  const existed = registeredScripts.delete(params.remove);
6133
- return ok26({ removed: params.remove, existed });
6208
+ return ok27({ removed: params.remove, existed });
6134
6209
  }
6135
6210
  const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
6136
6211
  if (removeTarget && !resolveScriptContent(params)) {
6137
6212
  const existed = registeredScripts.delete(removeTarget);
6138
- return ok26({ removed: removeTarget, existed });
6213
+ return ok27({ removed: removeTarget, existed });
6139
6214
  }
6140
6215
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6141
6216
  if (!content) {
6142
- return ok26({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6217
+ return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6143
6218
  }
6144
6219
  const scriptName = params.name ?? `script-${Date.now()}`;
6145
6220
  registeredScripts.set(scriptName, content);
@@ -6147,45 +6222,45 @@ var addInitScriptCommand = registerCommand({
6147
6222
  try {
6148
6223
  await ctx.page.evaluate(content);
6149
6224
  } catch {
6150
- return ok26({
6225
+ return ok27({
6151
6226
  registered: scriptName,
6152
6227
  hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
6153
6228
  });
6154
6229
  }
6155
- return ok26({ registered: scriptName, executedImmediately: true });
6230
+ return ok27({ registered: scriptName, executedImmediately: true });
6156
6231
  }
6157
6232
  });
6158
6233
  registerCommandDefinition("addinitscript", ["script"]);
6159
6234
 
6160
6235
  // src/commands/find.ts
6161
- import { z as z28 } from "zod";
6162
- import { ok as ok27, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6163
- var actionSchema2 = z28.enum(["click", "fill", "type", "select", "hover", "check"]);
6236
+ import { z as z29 } from "zod";
6237
+ import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6238
+ var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
6164
6239
  var findCommand = registerCommand({
6165
6240
  name: "find",
6166
6241
  description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
6167
6242
  scope: "page",
6168
- parameters: z28.object({
6169
- strategy: z28.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6170
- value: z28.string(),
6171
- name: z28.string().optional(),
6172
- exact: z28.boolean().optional().default(false),
6173
- operation: z28.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6243
+ parameters: z29.object({
6244
+ strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6245
+ value: z29.string(),
6246
+ name: z29.string().optional(),
6247
+ exact: z29.boolean().optional().default(false),
6248
+ operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6174
6249
  action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
6175
- actionValue: z28.string().optional().describe("Value for fill/type/select when using action"),
6176
- index: z28.number().int().optional().describe("Index for nth strategy"),
6177
- click: z28.boolean().optional().default(false),
6178
- fill: z28.string().optional(),
6179
- type: z28.string().optional(),
6180
- select: z28.string().optional(),
6181
- hover: z28.boolean().optional().default(false),
6182
- check: z28.boolean().optional().default(false),
6183
- timeout: z28.number().optional().default(1e4)
6250
+ actionValue: z29.string().optional().describe("Value for fill/type/select when using action"),
6251
+ index: z29.number().int().optional().describe("Index for nth strategy"),
6252
+ click: z29.boolean().optional().default(false),
6253
+ fill: z29.string().optional(),
6254
+ type: z29.string().optional(),
6255
+ select: z29.string().optional(),
6256
+ hover: z29.boolean().optional().default(false),
6257
+ check: z29.boolean().optional().default(false),
6258
+ timeout: z29.number().optional().default(1e4)
6184
6259
  }),
6185
- result: z28.object({
6186
- matched: z28.number(),
6187
- selector: z28.string(),
6188
- action: z28.string().optional()
6260
+ result: z29.object({
6261
+ matched: z29.number(),
6262
+ selector: z29.string(),
6263
+ action: z29.string().optional()
6189
6264
  }),
6190
6265
  handler: async (p, ctx) => {
6191
6266
  const page = ctx.page;
@@ -6200,7 +6275,7 @@ var findCommand = registerCommand({
6200
6275
  });
6201
6276
  const count = await locator.count();
6202
6277
  if (count === 0) {
6203
- return fail12(`No element found with ${p.strategy}="${p.value}"`);
6278
+ return fail13(`No element found with ${p.strategy}="${p.value}"`);
6204
6279
  }
6205
6280
  const tips = [];
6206
6281
  const target = selectTarget(locator, p.strategy);
@@ -6212,15 +6287,15 @@ var findCommand = registerCommand({
6212
6287
  await target.click({ timeout: p.timeout, force: true });
6213
6288
  return okWithTips({ matched: count, selector, action: "click" }, tips);
6214
6289
  } else if (actionName === "fill") {
6215
- if (actionValue === void 0) return fail12("find fill requires a value");
6290
+ if (actionValue === void 0) return fail13("find fill requires a value");
6216
6291
  await target.fill(actionValue, { timeout: p.timeout, force: true });
6217
6292
  return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
6218
6293
  } else if (actionName === "type") {
6219
- if (actionValue === void 0) return fail12("find type requires a value");
6294
+ if (actionValue === void 0) return fail13("find type requires a value");
6220
6295
  await target.type(actionValue, { delay: 10, timeout: p.timeout });
6221
6296
  return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
6222
6297
  } else if (actionName === "select") {
6223
- if (actionValue === void 0) return fail12("find select requires a value");
6298
+ if (actionValue === void 0) return fail13("find select requires a value");
6224
6299
  await target.selectOption(actionValue);
6225
6300
  return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
6226
6301
  } else if (actionName === "hover") {
@@ -6234,7 +6309,7 @@ var findCommand = registerCommand({
6234
6309
  }
6235
6310
  });
6236
6311
  function okWithTips(data, tips) {
6237
- const result = ok27(data);
6312
+ const result = ok28(data);
6238
6313
  if (tips.length > 0) result.tips = normalizeTips5(tips);
6239
6314
  return result;
6240
6315
  }
@@ -6333,8 +6408,8 @@ function describeSelector(strategy, value, name) {
6333
6408
  }
6334
6409
 
6335
6410
  // src/commands/visual-tag.ts
6336
- import { z as z29 } from "zod";
6337
- import { ok as ok28, fail as fail13 } from "@dyyz1993/xcli-core";
6411
+ import { z as z30 } from "zod";
6412
+ import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6338
6413
  var SAFE_SET = "ahjkmnprtw3479".split("");
6339
6414
  var TAG_SCRIPT = `
6340
6415
  (function() {
@@ -6425,49 +6500,49 @@ var visualTagCommand = registerCommand({
6425
6500
  name: "visual-tag",
6426
6501
  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",
6427
6502
  scope: "page",
6428
- parameters: z29.object({
6429
- action: z29.enum(["tag", "lookup", "clear", "list"]),
6430
- id: z29.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6503
+ parameters: z30.object({
6504
+ action: z30.enum(["tag", "lookup", "clear", "list"]),
6505
+ id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6431
6506
  }),
6432
- result: z29.object({
6433
- action: z29.string(),
6434
- tagged: z29.number().optional(),
6435
- id: z29.string().optional(),
6436
- element: z29.record(z29.unknown()).optional()
6507
+ result: z30.object({
6508
+ action: z30.string(),
6509
+ tagged: z30.number().optional(),
6510
+ id: z30.string().optional(),
6511
+ element: z30.record(z30.unknown()).optional()
6437
6512
  }),
6438
6513
  handler: async (p, ctx) => {
6439
6514
  switch (p.action) {
6440
6515
  case "tag": {
6441
6516
  const result = await ctx.page.evaluate(TAG_SCRIPT);
6442
6517
  const parsed = JSON.parse(result);
6443
- return ok28({ action: "tag", tagged: parsed.tagged });
6518
+ return ok29({ action: "tag", tagged: parsed.tagged });
6444
6519
  }
6445
6520
  case "lookup": {
6446
- if (!p.id) return fail13("lookup \u9700\u8981 --id \u53C2\u6570");
6521
+ if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
6447
6522
  const result = await ctx.page.evaluate(
6448
6523
  `(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'}); })()`
6449
6524
  );
6450
6525
  const parsed = JSON.parse(result);
6451
- if (parsed.err) return fail13(`ID ${p.id}: ${parsed.err}`);
6452
- return ok28({ action: "lookup", id: p.id, element: parsed });
6526
+ if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6527
+ return ok29({ action: "lookup", id: p.id, element: parsed });
6453
6528
  }
6454
6529
  case "list": {
6455
6530
  const result = await ctx.page.evaluate(
6456
6531
  `(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); })()`
6457
6532
  );
6458
- return ok28({ action: "list", element: JSON.parse(result) });
6533
+ return ok29({ action: "list", element: JSON.parse(result) });
6459
6534
  }
6460
6535
  case "clear": {
6461
6536
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6462
- return ok28({ action: "clear" });
6537
+ return ok29({ action: "clear" });
6463
6538
  }
6464
6539
  }
6465
6540
  }
6466
6541
  });
6467
6542
 
6468
6543
  // src/commands/visual-tag-v2.ts
6469
- import { z as z30 } from "zod";
6470
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6544
+ import { z as z31 } from "zod";
6545
+ import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6471
6546
  var SAFE_SET2 = "ahjkmnprtw3479".split("");
6472
6547
  var TAG_V2_SCRIPT = `
6473
6548
  (function() {
@@ -6814,45 +6889,45 @@ var visualTagV2Command = registerCommand({
6814
6889
  name: "visual-tag-v2",
6815
6890
  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",
6816
6891
  scope: "page",
6817
- parameters: z30.object({
6818
- action: z30.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6819
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6820
- query: z30.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6821
- type: z30.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6822
- "interact-action": z30.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6823
- value: z30.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6892
+ parameters: z31.object({
6893
+ action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6894
+ id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6895
+ query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6896
+ type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6897
+ "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6898
+ value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6824
6899
  }),
6825
- result: z30.object({
6826
- action: z30.string(),
6827
- total: z30.number().optional(),
6828
- byType: z30.record(z30.number()).optional(),
6829
- element: z30.record(z30.unknown()).optional()
6900
+ result: z31.object({
6901
+ action: z31.string(),
6902
+ total: z31.number().optional(),
6903
+ byType: z31.record(z31.number()).optional(),
6904
+ element: z31.record(z31.unknown()).optional()
6830
6905
  }),
6831
6906
  handler: async (p, ctx) => {
6832
6907
  switch (p.action) {
6833
6908
  case "tag": {
6834
6909
  const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6835
6910
  const parsed = JSON.parse(result);
6836
- return ok29({ action: "tag", total: parsed.total, byType: parsed.byType });
6911
+ return ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
6837
6912
  }
6838
6913
  case "lookup": {
6839
- if (!p.id) return fail14("lookup \u9700\u8981 --id");
6914
+ if (!p.id) return fail15("lookup \u9700\u8981 --id");
6840
6915
  const result = await ctx.page.evaluate(
6841
6916
  `(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'})})()`
6842
6917
  );
6843
6918
  const parsed = JSON.parse(result);
6844
- if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6845
- return ok29({ action: "lookup", id: p.id, element: parsed });
6919
+ if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6920
+ return ok30({ action: "lookup", id: p.id, element: parsed });
6846
6921
  }
6847
6922
  case "by-type": {
6848
6923
  const result = await ctx.page.evaluate(
6849
6924
  `(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)})()`
6850
6925
  );
6851
- return ok29({ action: "by-type", element: JSON.parse(result) });
6926
+ return ok30({ action: "by-type", element: JSON.parse(result) });
6852
6927
  }
6853
6928
  case "find": {
6854
6929
  const query = p.query;
6855
- if (!query) return fail14('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6930
+ if (!query) return fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6856
6931
  const result = await ctx.page.evaluate(
6857
6932
  `(function(){
6858
6933
  var map = window.__xbTagSerializable;
@@ -6894,21 +6969,21 @@ var visualTagV2Command = registerCommand({
6894
6969
  return JSON.stringify({total:results.length, results:results.slice(0,20)});
6895
6970
  })()`
6896
6971
  );
6897
- return ok29({ action: "find", query, element: JSON.parse(result) });
6972
+ return ok30({ action: "find", query, element: JSON.parse(result) });
6898
6973
  }
6899
6974
  case "stats": {
6900
6975
  const result = await ctx.page.evaluate(
6901
6976
  `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6902
6977
  );
6903
- return ok29({ action: "stats", element: JSON.parse(result) });
6978
+ return ok30({ action: "stats", element: JSON.parse(result) });
6904
6979
  }
6905
6980
  case "interact": {
6906
6981
  const query = p.query;
6907
6982
  const pAny = p;
6908
6983
  const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6909
6984
  const value = pAny.value;
6910
- if (!query) return fail14("interact \u9700\u8981 --query \u53C2\u6570");
6911
- if (!action) return fail14("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6985
+ if (!query) return fail15("interact \u9700\u8981 --query \u53C2\u6570");
6986
+ if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6912
6987
  const findResult = await ctx.page.evaluate(
6913
6988
  `(function(){
6914
6989
  var map = window.__xbTagSerializable;
@@ -6938,11 +7013,11 @@ var visualTagV2Command = registerCommand({
6938
7013
  })()`
6939
7014
  );
6940
7015
  const parsed = JSON.parse(findResult);
6941
- if (parsed.err) return fail14(parsed.err);
6942
- if (!parsed.total || !parsed.results?.length) return fail14(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7016
+ if (parsed.err) return fail15(parsed.err);
7017
+ if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
6943
7018
  const target = parsed.results[0];
6944
7019
  if (action === "read") {
6945
- return ok29({ action: "interact", query, target, result: { read: target.text || target.label } });
7020
+ return ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
6946
7021
  }
6947
7022
  if (action === "click") {
6948
7023
  const el = await ctx.page.evaluate(
@@ -6955,12 +7030,12 @@ var visualTagV2Command = registerCommand({
6955
7030
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
6956
7031
  })()`
6957
7032
  );
6958
- if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7033
+ if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
6959
7034
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
6960
- return ok29({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7035
+ return ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
6961
7036
  }
6962
7037
  if (action === "fill") {
6963
- if (!value) return fail14("fill \u9700\u8981 --value \u53C2\u6570");
7038
+ if (!value) return fail15("fill \u9700\u8981 --value \u53C2\u6570");
6964
7039
  const el = await ctx.page.evaluate(
6965
7040
  `(function(){
6966
7041
  var map = window.__xbTagMap;
@@ -6971,12 +7046,12 @@ var visualTagV2Command = registerCommand({
6971
7046
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
6972
7047
  })()`
6973
7048
  );
6974
- if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7049
+ if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
6975
7050
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
6976
7051
  await ctx.page.keyboard.type(value, { stealth: true });
6977
- return ok29({ action: "interact", query, target, result: { filled: true, value } });
7052
+ return ok30({ action: "interact", query, target, result: { filled: true, value } });
6978
7053
  }
6979
- return fail14(`\u672A\u77E5 action: ${action}`);
7054
+ return fail15(`\u672A\u77E5 action: ${action}`);
6980
7055
  }
6981
7056
  case "export": {
6982
7057
  const result = await ctx.page.evaluate(
@@ -7024,12 +7099,12 @@ var visualTagV2Command = registerCommand({
7024
7099
  })()`
7025
7100
  );
7026
7101
  const parsed = JSON.parse(result);
7027
- if (parsed.err) return fail14(String(parsed.err));
7028
- return ok29({ action: "export", element: parsed });
7102
+ if (parsed.err) return fail15(String(parsed.err));
7103
+ return ok30({ action: "export", element: parsed });
7029
7104
  }
7030
7105
  case "clear": {
7031
7106
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7032
- return ok29({ action: "clear" });
7107
+ return ok30({ action: "clear" });
7033
7108
  }
7034
7109
  }
7035
7110
  }
@@ -8167,7 +8242,7 @@ async function guardCheck(commandName) {
8167
8242
  }
8168
8243
  }
8169
8244
  function errorResult(message) {
8170
- return { ...fail15(message), duration: 0 };
8245
+ return { ...fail16(message), duration: 0 };
8171
8246
  }
8172
8247
  function tipsToMessages(tips) {
8173
8248
  if (!tips || tips.length === 0) return [];
@@ -8244,7 +8319,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8244
8319
  }
8245
8320
  let targetPageOverride = null;
8246
8321
  if (_target && extraOpts?.cdpEndpoint) {
8247
- const { findTargetPage } = await import("./browser-I3EZY3FL.js");
8322
+ const { findTargetPage } = await import("./browser-FIEYZRSV.js");
8248
8323
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8249
8324
  if (!targetPageOverride) {
8250
8325
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8440,7 +8515,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8440
8515
  timestamp: start
8441
8516
  });
8442
8517
  if (isSuccess) {
8443
- return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8518
+ return { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8444
8519
  }
8445
8520
  const fc = classifyFailure(raw.message);
8446
8521
  return {
@@ -8463,7 +8538,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8463
8538
  duration,
8464
8539
  timestamp: start
8465
8540
  });
8466
- return { ...ok30(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8541
+ return { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8467
8542
  } catch (err) {
8468
8543
  const end = Date.now();
8469
8544
  const duration = end - start;
@@ -8508,7 +8583,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8508
8583
  duration,
8509
8584
  timestamp: start
8510
8585
  });
8511
- return { ...fail15(errorMessage), duration };
8586
+ return { ...fail16(errorMessage), duration };
8512
8587
  } finally {
8513
8588
  }
8514
8589
  }
@@ -8553,7 +8628,7 @@ async function executeChain(input, options) {
8553
8628
  results.push({
8554
8629
  command: cmdName,
8555
8630
  raw: cmdStr,
8556
- ...fail15(`Plugin "${cmdName}" requires a sub-command`),
8631
+ ...fail16(`Plugin "${cmdName}" requires a sub-command`),
8557
8632
  duration: 0
8558
8633
  });
8559
8634
  if (type === "and") {
@@ -8572,7 +8647,7 @@ async function executeChain(input, options) {
8572
8647
  results.push({
8573
8648
  command: cmdName,
8574
8649
  raw: cmdStr,
8575
- ...fail15(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8650
+ ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8576
8651
  duration: 0
8577
8652
  });
8578
8653
  if (type === "and") {
@@ -8684,7 +8759,7 @@ async function executeChain(input, options) {
8684
8759
  results.push({
8685
8760
  command: `${cmdName} ${subCommand}`,
8686
8761
  raw: cmdStr,
8687
- ...ok30(data),
8762
+ ...ok31(data),
8688
8763
  duration: duration2,
8689
8764
  ...hookOutputs ? { hookOutputs } : {}
8690
8765
  });
@@ -8712,7 +8787,7 @@ async function executeChain(input, options) {
8712
8787
  results.push({
8713
8788
  command: `${cmdName} ${subCommand}`,
8714
8789
  raw: cmdStr,
8715
- ...fail15(errorMessage),
8790
+ ...fail16(errorMessage),
8716
8791
  duration: duration2
8717
8792
  });
8718
8793
  if (type === "and") {
@@ -8792,6 +8867,7 @@ export {
8792
8867
  createStubContext,
8793
8868
  getCommand,
8794
8869
  getAllCommands,
8870
+ getCommandNames,
8795
8871
  attachDetectAntiBot,
8796
8872
  readJsonFile,
8797
8873
  PluginMetadataParser,