@xbrowser/cli 1.24.2 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1781,37 +1781,109 @@ var uaCommand = registerCommand({
1781
1781
  }
1782
1782
  });
1783
1783
 
1784
- // src/commands/storage.ts
1784
+ // src/commands/preflight.ts
1785
1785
  import { z as z11 } from "zod";
1786
1786
  import { ok as ok11, fail as fail4 } from "@dyyz1993/xcli-core";
1787
+ var preflightCommand = registerCommand({
1788
+ name: "preflight",
1789
+ description: "Pre-flight anti-bot gate: open local detection page and verify stealth posture before any automation task",
1790
+ scope: "page",
1791
+ parameters: z11.object({
1792
+ strict: z11.boolean().optional().describe("\u5931\u8D25\u65F6\u4EE5\u975E\u96F6\u9000\u51FA\u7801\u7ED3\u675F\uFF08\u94FE\u5F0F/CI \u95E8\u7981\u7528\uFF09"),
1793
+ 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")
1794
+ }),
1795
+ result: z11.object({
1796
+ gate: z11.enum(["pass", "fail"]),
1797
+ failed: z11.array(z11.string()),
1798
+ headless: z11.boolean()
1799
+ }),
1800
+ handler: async (p, ctx) => {
1801
+ const page = ctx.page;
1802
+ const tips = [];
1803
+ const ua = await page.evaluate("navigator.userAgent").catch(() => "");
1804
+ const outerW = await page.evaluate("window.outerWidth").catch(() => 0);
1805
+ const headless = /headless/i.test(ua) || outerW === 0;
1806
+ const publishMode = p.publish || process.env.XBROWSER_NO_HEADLESS_PUBLISH === "1";
1807
+ if (publishMode && headless) {
1808
+ 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");
1809
+ tips.push(' \u6709\u5934 Chrome: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --user-data-dir=~/.xbrowser/chrome-profile-headed --remote-debugging-port=9222');
1810
+ tips.push(" \u7136\u540E\u52A0 --cdp http://localhost:9222");
1811
+ return fail4("PREFLIGHT-FAIL: headless \u4E0D\u5141\u8BB8\u7528\u4E8E\u53D1\u5E03\u7C7B\u4EFB\u52A1\uFF08\u7528 --cdp \u63A5\u6709\u5934 Chrome\uFF09", tips);
1812
+ }
1813
+ let pageUrl = null;
1814
+ try {
1815
+ const { fileURLToPath } = await import("url");
1816
+ const { join: join9, dirname: dirname4 } = await import("path");
1817
+ const { existsSync: existsSync7 } = await import("fs");
1818
+ const here = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
1819
+ const candidates = [
1820
+ join9(dirname4(here), "..", "assets", "preflight.html"),
1821
+ join9(process.cwd(), "assets", "preflight.html")
1822
+ ];
1823
+ pageUrl = candidates.find((c) => existsSync7(c)) || null;
1824
+ } catch {
1825
+ }
1826
+ if (pageUrl) {
1827
+ await page.goto("file://" + pageUrl, { waitUntil: "domcontentloaded", timeout: 15e3 });
1828
+ } else {
1829
+ await page.goto("about:blank");
1830
+ await page.evaluate(`(function(){
1831
+ var fails=[];
1832
+ if(navigator.webdriver!==false)fails.push('webdriver');
1833
+ if(/headless/i.test(navigator.userAgent))fails.push('ua-no-headless');
1834
+ window.__pf=fails.join(',');
1835
+ document.title=fails.length?'PREFLIGHT-FAIL':'PREFLIGHT-PASS';
1836
+ })()`);
1837
+ }
1838
+ await page.waitForTimeout(1200);
1839
+ const result = await page.evaluate(`(function(){
1840
+ var out=document.getElementById('out');
1841
+ return { title: document.title, fails: out ? (out.getAttribute('data-fails')||'') : (window.__pf||'') };
1842
+ })()`).catch(() => ({ title: "PREFLIGHT-FAIL", fails: "evaluate-error" }));
1843
+ const passed = result.title === "PREFLIGHT-PASS";
1844
+ const failed = result.fails ? result.fails.split(",").filter(Boolean) : [];
1845
+ tips.push(`headless=${headless}${publishMode ? "\uFF08publish \u95E8\u7981\u5F00\u542F\uFF09" : ""}`);
1846
+ if (passed) {
1847
+ 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");
1848
+ return ok11({ gate: "pass", failed: [], headless }, tips);
1849
+ }
1850
+ tips.push(`\u5931\u8D25\u9879: ${failed.join(", ") || result.title}`);
1851
+ 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");
1852
+ return fail4(`PREFLIGHT-FAIL: ${failed.join(", ") || result.title}`, tips);
1853
+ }
1854
+ });
1855
+
1856
+ // src/commands/storage.ts
1857
+ import { z as z12 } from "zod";
1858
+ import { ok as ok12, fail as fail5 } from "@dyyz1993/xcli-core";
1787
1859
  var getCookiesCommand = registerCommand({
1788
1860
  name: "get-cookies",
1789
1861
  description: "Get all cookies for the current page",
1790
1862
  scope: "page",
1791
- result: z11.object({
1792
- cookies: z11.array(z11.record(z11.unknown()))
1863
+ result: z12.object({
1864
+ cookies: z12.array(z12.record(z12.unknown()))
1793
1865
  }),
1794
1866
  handler: async (_p, ctx) => {
1795
1867
  const cookies = await ctx.browserContext.cookies();
1796
- return ok11({ cookies });
1868
+ return ok12({ cookies });
1797
1869
  }
1798
1870
  });
1799
1871
  var setCookieCommand = registerCommand({
1800
1872
  name: "set-cookie",
1801
1873
  description: "Set a cookie",
1802
1874
  scope: "page",
1803
- parameters: z11.object({
1804
- name: z11.coerce.string(),
1805
- value: z11.coerce.string(),
1806
- domain: z11.coerce.string().optional(),
1807
- path: z11.coerce.string().optional(),
1808
- url: z11.string().optional().describe("Cookie URL (alternative to domain)"),
1809
- expires: z11.number().optional(),
1810
- httpOnly: z11.boolean().optional(),
1811
- secure: z11.boolean().optional(),
1812
- sameSite: z11.enum(["Strict", "Lax", "None"]).optional()
1875
+ parameters: z12.object({
1876
+ name: z12.coerce.string(),
1877
+ value: z12.coerce.string(),
1878
+ domain: z12.coerce.string().optional(),
1879
+ path: z12.coerce.string().optional(),
1880
+ url: z12.string().optional().describe("Cookie URL (alternative to domain)"),
1881
+ expires: z12.number().optional(),
1882
+ httpOnly: z12.boolean().optional(),
1883
+ secure: z12.boolean().optional(),
1884
+ sameSite: z12.enum(["Strict", "Lax", "None"]).optional()
1813
1885
  }),
1814
- result: z11.object({ name: z11.string() }),
1886
+ result: z12.object({ name: z12.string() }),
1815
1887
  handler: async (p, ctx) => {
1816
1888
  const cookie = { ...p };
1817
1889
  if (!cookie.domain && !cookie.url) {
@@ -1826,38 +1898,38 @@ var setCookieCommand = registerCommand({
1826
1898
  }
1827
1899
  }
1828
1900
  if (!cookie.domain && !cookie.url) {
1829
- return fail4("set-cookie requires --domain or --url, or a non-blank page URL to infer from");
1901
+ return fail5("set-cookie requires --domain or --url, or a non-blank page URL to infer from");
1830
1902
  }
1831
1903
  await ctx.browserContext.addCookies([cookie]);
1832
- return ok11({ name: p.name });
1904
+ return ok12({ name: p.name });
1833
1905
  }
1834
1906
  });
1835
1907
  var clearCookiesCommand = registerCommand({
1836
1908
  name: "clear-cookies",
1837
1909
  description: "Clear all cookies",
1838
1910
  scope: "page",
1839
- result: z11.object({ cleared: z11.boolean() }),
1911
+ result: z12.object({ cleared: z12.boolean() }),
1840
1912
  handler: async (_p, ctx) => {
1841
1913
  await ctx.browserContext.clearCookies();
1842
- return ok11({ cleared: true });
1914
+ return ok12({ cleared: true });
1843
1915
  }
1844
1916
  });
1845
1917
  var getLocalStorageCommand = registerCommand({
1846
1918
  name: "get-local-storage",
1847
1919
  description: "Get localStorage entries",
1848
1920
  scope: "page",
1849
- parameters: z11.object({
1850
- key: z11.string().optional()
1921
+ parameters: z12.object({
1922
+ key: z12.string().optional()
1851
1923
  }),
1852
- result: z11.union([
1853
- z11.object({ key: z11.string(), value: z11.string().nullable() }),
1854
- z11.object({ data: z11.record(z11.string()) })
1924
+ result: z12.union([
1925
+ z12.object({ key: z12.string(), value: z12.string().nullable() }),
1926
+ z12.object({ data: z12.record(z12.string()) })
1855
1927
  ]),
1856
1928
  handler: async (p, ctx) => {
1857
1929
  try {
1858
1930
  if (p.key) {
1859
1931
  const value = await ctx.page.evaluate((k) => localStorage.getItem(k), p.key);
1860
- return ok11({ key: p.key, value });
1932
+ return ok12({ key: p.key, value });
1861
1933
  }
1862
1934
  const data = await ctx.page.evaluate(() => {
1863
1935
  const entries = {};
@@ -1867,9 +1939,9 @@ var getLocalStorageCommand = registerCommand({
1867
1939
  }
1868
1940
  return entries;
1869
1941
  });
1870
- return ok11({ data });
1942
+ return ok12({ data });
1871
1943
  } catch (e) {
1872
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1944
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1873
1945
  }
1874
1946
  }
1875
1947
  });
@@ -1877,11 +1949,11 @@ var setLocalStorageCommand = registerCommand({
1877
1949
  name: "set-local-storage",
1878
1950
  description: "Set a localStorage entry",
1879
1951
  scope: "page",
1880
- parameters: z11.object({
1881
- key: z11.string(),
1882
- value: z11.string()
1952
+ parameters: z12.object({
1953
+ key: z12.string(),
1954
+ value: z12.string()
1883
1955
  }),
1884
- result: z11.object({ key: z11.string() }),
1956
+ result: z12.object({ key: z12.string() }),
1885
1957
  handler: async (p, ctx) => {
1886
1958
  try {
1887
1959
  await ctx.page.evaluate(
@@ -1890,9 +1962,9 @@ var setLocalStorageCommand = registerCommand({
1890
1962
  },
1891
1963
  { key: p.key, value: p.value }
1892
1964
  );
1893
- return ok11({ key: p.key });
1965
+ return ok12({ key: p.key });
1894
1966
  } catch (e) {
1895
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1967
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1896
1968
  }
1897
1969
  }
1898
1970
  });
@@ -1900,20 +1972,20 @@ var clearLocalStorageCommand = registerCommand({
1900
1972
  name: "clear-local-storage",
1901
1973
  description: "Clear all localStorage entries",
1902
1974
  scope: "page",
1903
- result: z11.object({ cleared: z11.boolean() }),
1975
+ result: z12.object({ cleared: z12.boolean() }),
1904
1976
  handler: async (_p, ctx) => {
1905
1977
  try {
1906
1978
  await ctx.page.evaluate(() => localStorage.clear());
1907
- return ok11({ cleared: true });
1979
+ return ok12({ cleared: true });
1908
1980
  } catch (e) {
1909
- return fail4(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1981
+ return fail5(`localStorage not accessible on this page: ${e instanceof Error ? e.message : String(e)}`);
1910
1982
  }
1911
1983
  }
1912
1984
  });
1913
1985
 
1914
1986
  // src/commands/screenshot.ts
1915
- import { z as z12 } from "zod";
1916
- import { ok as ok12, fail as fail5 } from "@dyyz1993/xcli-core";
1987
+ import { z as z13 } from "zod";
1988
+ import { ok as ok13, fail as fail6 } from "@dyyz1993/xcli-core";
1917
1989
  import { writeFileSync, mkdirSync } from "fs";
1918
1990
  import { dirname, join as join3 } from "path";
1919
1991
  function ensureScreenshotsDir() {
@@ -1940,23 +2012,23 @@ var screenshotCommand = registerCommand({
1940
2012
  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>)",
1941
2013
  scope: "page",
1942
2014
  selectorParams: ["selector"],
1943
- parameters: z12.object({
1944
- selector: z12.string().optional(),
1945
- type: z12.enum(["png", "jpeg"]).optional(),
1946
- fullPage: z12.boolean().optional(),
1947
- output: z12.string().optional(),
1948
- base64: z12.boolean().optional().describe("Return base64 data instead of file path")
2015
+ parameters: z13.object({
2016
+ selector: z13.string().optional(),
2017
+ type: z13.enum(["png", "jpeg"]).optional(),
2018
+ fullPage: z13.boolean().optional(),
2019
+ output: z13.string().optional(),
2020
+ base64: z13.boolean().optional().describe("Return base64 data instead of file path")
1949
2021
  }),
1950
- result: z12.union([
1951
- z12.object({
1952
- data: z12.string(),
1953
- format: z12.string(),
1954
- size: z12.number()
2022
+ result: z13.union([
2023
+ z13.object({
2024
+ data: z13.string(),
2025
+ format: z13.string(),
2026
+ size: z13.number()
1955
2027
  }),
1956
- z12.object({
1957
- output: z12.string(),
1958
- format: z12.string(),
1959
- size: z12.number()
2028
+ z13.object({
2029
+ output: z13.string(),
2030
+ format: z13.string(),
2031
+ size: z13.number()
1960
2032
  })
1961
2033
  ]),
1962
2034
  handler: async (p, ctx) => {
@@ -1974,21 +2046,21 @@ var screenshotCommand = registerCommand({
1974
2046
  if (p.output) {
1975
2047
  const dirErr = ensureParentDir(p.output);
1976
2048
  if (dirErr) {
1977
- return fail5(`Cannot create directory for --output "${p.output}": ${dirErr}`);
2049
+ return fail6(`Cannot create directory for --output "${p.output}": ${dirErr}`);
1978
2050
  }
1979
2051
  try {
1980
2052
  writeFileSync(p.output, buffer, "binary");
1981
2053
  } catch (err) {
1982
- return fail5(`Failed to write screenshot to "${p.output}": ${err instanceof Error ? err.message : String(err)}`);
2054
+ return fail6(`Failed to write screenshot to "${p.output}": ${err instanceof Error ? err.message : String(err)}`);
1983
2055
  }
1984
- return ok12({
2056
+ return ok13({
1985
2057
  output: p.output,
1986
2058
  format,
1987
2059
  size: buffer.length
1988
2060
  });
1989
2061
  }
1990
2062
  if (p.base64) {
1991
- return ok12({
2063
+ return ok13({
1992
2064
  data: buffer.toString("base64"),
1993
2065
  format,
1994
2066
  size: buffer.length
@@ -1997,7 +2069,7 @@ var screenshotCommand = registerCommand({
1997
2069
  ensureScreenshotsDir();
1998
2070
  const screenshotPath = generateScreenshotPath(format);
1999
2071
  writeFileSync(screenshotPath, buffer, "binary");
2000
- return ok12({
2072
+ return ok13({
2001
2073
  output: screenshotPath,
2002
2074
  format,
2003
2075
  size: buffer.length
@@ -2006,19 +2078,19 @@ var screenshotCommand = registerCommand({
2006
2078
  });
2007
2079
 
2008
2080
  // src/commands/structure.ts
2009
- import { z as z13 } from "zod";
2010
- import { ok as ok13 } from "@dyyz1993/xcli-core";
2081
+ import { z as z14 } from "zod";
2082
+ import { ok as ok14 } from "@dyyz1993/xcli-core";
2011
2083
  var structureCommand = registerCommand({
2012
2084
  name: "structure",
2013
2085
  description: "Get the DOM structure of the page or an element",
2014
2086
  scope: "page",
2015
2087
  selectorParams: ["selector"],
2016
- parameters: z13.object({
2017
- selector: z13.string().optional(),
2018
- depth: z13.number().optional()
2088
+ parameters: z14.object({
2089
+ selector: z14.string().optional(),
2090
+ depth: z14.number().optional()
2019
2091
  }),
2020
- result: z13.object({
2021
- structure: z13.record(z13.unknown())
2092
+ result: z14.object({
2093
+ structure: z14.record(z14.unknown())
2022
2094
  }),
2023
2095
  handler: async (p, ctx) => {
2024
2096
  const structure = await ctx.page.evaluate(
@@ -2050,30 +2122,30 @@ var structureCommand = registerCommand({
2050
2122
  },
2051
2123
  { sel: p.selector || "body", maxDepth: p.depth || 5 }
2052
2124
  );
2053
- return ok13({ structure });
2125
+ return ok14({ structure });
2054
2126
  }
2055
2127
  });
2056
2128
 
2057
2129
  // src/commands/viewport.ts
2058
- import { z as z14 } from "zod";
2059
- import { ok as ok14 } from "@dyyz1993/xcli-core";
2130
+ import { z as z15 } from "zod";
2131
+ import { ok as ok15 } from "@dyyz1993/xcli-core";
2060
2132
  var setViewportCommand = registerCommand({
2061
2133
  name: "set-viewport",
2062
2134
  description: "Set the viewport size and properties",
2063
2135
  scope: "browser",
2064
- parameters: z14.object({
2065
- width: z14.coerce.number(),
2066
- height: z14.coerce.number(),
2067
- deviceScaleFactor: z14.coerce.number().optional(),
2068
- isMobile: z14.boolean().optional(),
2069
- hasTouch: z14.boolean().optional()
2136
+ parameters: z15.object({
2137
+ width: z15.coerce.number(),
2138
+ height: z15.coerce.number(),
2139
+ deviceScaleFactor: z15.coerce.number().optional(),
2140
+ isMobile: z15.boolean().optional(),
2141
+ hasTouch: z15.boolean().optional()
2070
2142
  }),
2071
- result: z14.object({
2072
- width: z14.number(),
2073
- height: z14.number(),
2074
- deviceScaleFactor: z14.number().optional(),
2075
- isMobile: z14.boolean().optional(),
2076
- hasTouch: z14.boolean().optional()
2143
+ result: z15.object({
2144
+ width: z15.number(),
2145
+ height: z15.number(),
2146
+ deviceScaleFactor: z15.number().optional(),
2147
+ isMobile: z15.boolean().optional(),
2148
+ hasTouch: z15.boolean().optional()
2077
2149
  }),
2078
2150
  handler: async (p, ctx) => {
2079
2151
  const viewport = ctx.page.viewportSize();
@@ -2086,7 +2158,7 @@ var setViewportCommand = registerCommand({
2086
2158
  ...p.isMobile !== void 0 && { isMobile: p.isMobile },
2087
2159
  ...p.hasTouch !== void 0 && { hasTouch: p.hasTouch }
2088
2160
  });
2089
- return ok14({
2161
+ return ok15({
2090
2162
  width,
2091
2163
  height,
2092
2164
  ...p.deviceScaleFactor !== void 0 && { deviceScaleFactor: p.deviceScaleFactor },
@@ -2097,17 +2169,17 @@ var setViewportCommand = registerCommand({
2097
2169
  });
2098
2170
 
2099
2171
  // src/commands/frame.ts
2100
- import { z as z15 } from "zod";
2101
- import { ok as ok15, fail as fail6 } from "@dyyz1993/xcli-core";
2172
+ import { z as z16 } from "zod";
2173
+ import { ok as ok16, fail as fail7 } from "@dyyz1993/xcli-core";
2102
2174
  var framesCommand = registerCommand({
2103
2175
  name: "frames",
2104
2176
  description: "List all frames in the current page",
2105
2177
  scope: "page",
2106
- result: z15.object({
2107
- frames: z15.array(z15.object({
2108
- index: z15.number(),
2109
- name: z15.string().nullable(),
2110
- url: z15.string()
2178
+ result: z16.object({
2179
+ frames: z16.array(z16.object({
2180
+ index: z16.number(),
2181
+ name: z16.string().nullable(),
2182
+ url: z16.string()
2111
2183
  }))
2112
2184
  }),
2113
2185
  handler: async (_p, ctx) => {
@@ -2118,21 +2190,21 @@ var framesCommand = registerCommand({
2118
2190
  name: frame.name(),
2119
2191
  url: frame.url()
2120
2192
  }));
2121
- return ok15({ frames: frameList });
2193
+ return ok16({ frames: frameList });
2122
2194
  }
2123
2195
  });
2124
2196
  var frameCommand = registerCommand({
2125
2197
  name: "frame",
2126
2198
  description: "Get frame info by index or name",
2127
2199
  scope: "page",
2128
- parameters: z15.object({
2129
- index: z15.number().int().min(0).optional(),
2130
- name: z15.string().optional()
2200
+ parameters: z16.object({
2201
+ index: z16.number().int().min(0).optional(),
2202
+ name: z16.string().optional()
2131
2203
  }),
2132
- result: z15.object({
2133
- name: z15.string().nullable(),
2134
- url: z15.string(),
2135
- error: z15.string().optional()
2204
+ result: z16.object({
2205
+ name: z16.string().nullable(),
2206
+ url: z16.string(),
2207
+ error: z16.string().optional()
2136
2208
  }),
2137
2209
  handler: async (p, ctx) => {
2138
2210
  const discover = ctx.page.discoverFrames;
@@ -2143,12 +2215,12 @@ var frameCommand = registerCommand({
2143
2215
  } else if (p.name !== void 0) {
2144
2216
  targetFrame = rawFrames.find((f) => f.name() === p.name);
2145
2217
  } else {
2146
- return fail6("Must provide index or name");
2218
+ return fail7("Must provide index or name");
2147
2219
  }
2148
2220
  if (!targetFrame) {
2149
- return fail6("Frame not found");
2221
+ return fail7("Frame not found");
2150
2222
  }
2151
- return ok15({
2223
+ return ok16({
2152
2224
  name: targetFrame.name(),
2153
2225
  url: targetFrame.url()
2154
2226
  });
@@ -2156,27 +2228,27 @@ var frameCommand = registerCommand({
2156
2228
  });
2157
2229
 
2158
2230
  // src/commands/ui-debug.ts
2159
- import { z as z16 } from "zod";
2160
- import { ok as ok16 } from "@dyyz1993/xcli-core";
2231
+ import { z as z17 } from "zod";
2232
+ import { ok as ok17 } from "@dyyz1993/xcli-core";
2161
2233
  var consoleCheckCommand = registerCommand({
2162
2234
  name: "console",
2163
2235
  description: "Collect and analyze browser console messages (errors, warnings, logs)",
2164
2236
  scope: "page",
2165
- parameters: z16.object({
2166
- url: z16.string().optional().describe("URL to navigate first (optional, uses current page if omitted)"),
2167
- duration: z16.number().optional().default(5e3).describe("How long to collect messages (ms)"),
2168
- filter: z16.enum(["all", "error", "warning", "info", "log"]).optional().default("all"),
2169
- includeStackTraces: z16.boolean().optional().default(true)
2237
+ parameters: z17.object({
2238
+ url: z17.string().optional().describe("URL to navigate first (optional, uses current page if omitted)"),
2239
+ duration: z17.number().optional().default(5e3).describe("How long to collect messages (ms)"),
2240
+ filter: z17.enum(["all", "error", "warning", "info", "log"]).optional().default("all"),
2241
+ includeStackTraces: z17.boolean().optional().default(true)
2170
2242
  }),
2171
- result: z16.object({
2172
- url: z16.string(),
2173
- duration: z16.number(),
2174
- total: z16.number(),
2175
- errors: z16.number(),
2176
- warnings: z16.number(),
2177
- messages: z16.array(z16.record(z16.unknown())),
2178
- summary: z16.string(),
2179
- passed: z16.boolean()
2243
+ result: z17.object({
2244
+ url: z17.string(),
2245
+ duration: z17.number(),
2246
+ total: z17.number(),
2247
+ errors: z17.number(),
2248
+ warnings: z17.number(),
2249
+ messages: z17.array(z17.record(z17.unknown())),
2250
+ summary: z17.string(),
2251
+ passed: z17.boolean()
2180
2252
  }),
2181
2253
  handler: async (p, ctx) => {
2182
2254
  const { page } = ctx;
@@ -2258,7 +2330,7 @@ ${a.stack || ""}`;
2258
2330
  const filtered = p.filter === "all" ? messages : messages.filter((m) => m.type === p.filter);
2259
2331
  const errorCount = messages.filter((m) => m.type === "error").length;
2260
2332
  const warnCount = messages.filter((m) => m.type === "warning").length;
2261
- return ok16({
2333
+ return ok17({
2262
2334
  url: page.url(),
2263
2335
  duration: p.duration,
2264
2336
  total: messages.length,
@@ -2274,23 +2346,23 @@ var networkCheckCommand = registerCommand({
2274
2346
  name: "net-debug",
2275
2347
  description: "Monitor and analyze network requests \u2014 capture failed requests, slow responses, status codes",
2276
2348
  scope: "page",
2277
- parameters: z16.object({
2278
- url: z16.string().optional().describe("URL to navigate first"),
2279
- duration: z16.number().optional().default(5e3).describe("How long to monitor (ms)"),
2280
- filter: z16.enum(["all", "failed", "slow", "error", "xhr", "fetch", "document", "stylesheet", "script", "image"]).optional().default("all"),
2281
- slowThreshold: z16.number().optional().default(3e3).describe('Threshold for "slow" requests (ms)')
2349
+ parameters: z17.object({
2350
+ url: z17.string().optional().describe("URL to navigate first"),
2351
+ duration: z17.number().optional().default(5e3).describe("How long to monitor (ms)"),
2352
+ filter: z17.enum(["all", "failed", "slow", "error", "xhr", "fetch", "document", "stylesheet", "script", "image"]).optional().default("all"),
2353
+ slowThreshold: z17.number().optional().default(3e3).describe('Threshold for "slow" requests (ms)')
2282
2354
  }),
2283
- result: z16.object({
2284
- url: z16.string(),
2285
- duration: z16.number(),
2286
- totalRequests: z16.number(),
2287
- failedRequests: z16.number(),
2288
- slowRequests: z16.number(),
2289
- errorRequests: z16.number(),
2290
- totalSizeKB: z16.number(),
2291
- requests: z16.array(z16.record(z16.unknown())),
2292
- summary: z16.string(),
2293
- passed: z16.boolean()
2355
+ result: z17.object({
2356
+ url: z17.string(),
2357
+ duration: z17.number(),
2358
+ totalRequests: z17.number(),
2359
+ failedRequests: z17.number(),
2360
+ slowRequests: z17.number(),
2361
+ errorRequests: z17.number(),
2362
+ totalSizeKB: z17.number(),
2363
+ requests: z17.array(z17.record(z17.unknown())),
2364
+ summary: z17.string(),
2365
+ passed: z17.boolean()
2294
2366
  }),
2295
2367
  handler: async (p, ctx) => {
2296
2368
  const { page } = ctx;
@@ -2372,7 +2444,7 @@ var networkCheckCommand = registerCommand({
2372
2444
  const slowCount = requests.filter((r) => r.duration >= p.slowThreshold).length;
2373
2445
  const errorCount = requests.filter((r) => r.error).length;
2374
2446
  const totalSize = requests.reduce((sum, r) => sum + r.size, 0);
2375
- return ok16({
2447
+ return ok17({
2376
2448
  url: page.url(),
2377
2449
  duration: p.duration,
2378
2450
  totalRequests: requests.length,
@@ -2394,17 +2466,17 @@ var perfCheckCommand = registerCommand({
2394
2466
  name: "perf",
2395
2467
  description: "Audit page performance metrics \u2014 load time, FCP, LCP, CLS, TTFB, resource sizes",
2396
2468
  scope: "page",
2397
- parameters: z16.object({
2398
- url: z16.string().optional().describe("URL to navigate (uses current page if omitted)"),
2399
- iterations: z16.number().optional().default(1).describe("Number of iterations to average")
2469
+ parameters: z17.object({
2470
+ url: z17.string().optional().describe("URL to navigate (uses current page if omitted)"),
2471
+ iterations: z17.number().optional().default(1).describe("Number of iterations to average")
2400
2472
  }),
2401
- result: z16.object({
2402
- url: z16.string(),
2403
- iterations: z16.number(),
2404
- metrics: z16.record(z16.unknown()),
2405
- allIterations: z16.array(z16.record(z16.unknown())).optional(),
2406
- passed: z16.boolean(),
2407
- summary: z16.string()
2473
+ result: z17.object({
2474
+ url: z17.string(),
2475
+ iterations: z17.number(),
2476
+ metrics: z17.record(z17.unknown()),
2477
+ allIterations: z17.array(z17.record(z17.unknown())).optional(),
2478
+ passed: z17.boolean(),
2479
+ summary: z17.string()
2408
2480
  }),
2409
2481
  handler: async (p, ctx) => {
2410
2482
  const { page } = ctx;
@@ -2466,7 +2538,7 @@ var perfCheckCommand = registerCommand({
2466
2538
  if (resourceStats) avg.resourceStats = resourceStats;
2467
2539
  return avg;
2468
2540
  })();
2469
- return ok16({
2541
+ return ok17({
2470
2542
  url: page.url(),
2471
2543
  iterations: p.iterations,
2472
2544
  metrics: avgMetrics,
@@ -2480,23 +2552,23 @@ var healthCheckCommand = registerCommand({
2480
2552
  name: "health",
2481
2553
  description: "Comprehensive page health check \u2014 broken links, missing images, console errors, SEO issues",
2482
2554
  scope: "page",
2483
- parameters: z16.object({
2484
- url: z16.string().optional().describe("URL to check"),
2485
- checkLinks: z16.boolean().optional().default(true).describe("Check for broken links"),
2486
- checkImages: z16.boolean().optional().default(true).describe("Check for missing/broken images"),
2487
- checkMeta: z16.boolean().optional().default(true).describe("Check SEO meta tags"),
2488
- maxLinks: z16.number().optional().default(50).describe("Max links to check")
2555
+ parameters: z17.object({
2556
+ url: z17.string().optional().describe("URL to check"),
2557
+ checkLinks: z17.boolean().optional().default(true).describe("Check for broken links"),
2558
+ checkImages: z17.boolean().optional().default(true).describe("Check for missing/broken images"),
2559
+ checkMeta: z17.boolean().optional().default(true).describe("Check SEO meta tags"),
2560
+ maxLinks: z17.number().optional().default(50).describe("Max links to check")
2489
2561
  }),
2490
- result: z16.object({
2491
- url: z16.string(),
2492
- title: z16.string(),
2493
- passed: z16.boolean(),
2494
- totalIssues: z16.number(),
2495
- errors: z16.number(),
2496
- warnings: z16.number(),
2497
- info: z16.number(),
2498
- issues: z16.array(z16.record(z16.unknown())),
2499
- summary: z16.string()
2562
+ result: z17.object({
2563
+ url: z17.string(),
2564
+ title: z17.string(),
2565
+ passed: z17.boolean(),
2566
+ totalIssues: z17.number(),
2567
+ errors: z17.number(),
2568
+ warnings: z17.number(),
2569
+ info: z17.number(),
2570
+ issues: z17.array(z17.record(z17.unknown())),
2571
+ summary: z17.string()
2500
2572
  }),
2501
2573
  handler: async (p, ctx) => {
2502
2574
  const { page } = ctx;
@@ -2583,7 +2655,7 @@ var healthCheckCommand = registerCommand({
2583
2655
  }, { checkLinks: p.checkLinks, checkImages: p.checkImages, checkMeta: p.checkMeta, maxLinks: p.maxLinks });
2584
2656
  const errors = result.issues.filter((i) => i.severity === "error").length;
2585
2657
  const warnings = result.issues.filter((i) => i.severity === "warning").length;
2586
- return ok16({
2658
+ return ok17({
2587
2659
  url: result.url,
2588
2660
  title: result.title,
2589
2661
  passed: errors === 0,
@@ -2598,8 +2670,8 @@ var healthCheckCommand = registerCommand({
2598
2670
  });
2599
2671
 
2600
2672
  // src/commands/actions.ts
2601
- import { z as z17 } from "zod";
2602
- import { ok as ok17 } from "@dyyz1993/xcli-core";
2673
+ import { z as z18 } from "zod";
2674
+ import { ok as ok18 } from "@dyyz1993/xcli-core";
2603
2675
  import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
2604
2676
  import { join as join4 } from "path";
2605
2677
  function ensureScreenshotsDir2() {
@@ -2611,53 +2683,53 @@ function generateScreenshotPath2(format) {
2611
2683
  const ext = format === "jpeg" ? "jpg" : "png";
2612
2684
  return join4(resolveScreenshotsDir(), `screenshot-${timestamp}-${random}.${ext}`);
2613
2685
  }
2614
- var waitActionSchema = z17.object({
2615
- type: z17.literal("wait"),
2616
- milliseconds: z17.number().positive().optional(),
2617
- selector: z17.string().optional()
2686
+ var waitActionSchema = z18.object({
2687
+ type: z18.literal("wait"),
2688
+ milliseconds: z18.number().positive().optional(),
2689
+ selector: z18.string().optional()
2618
2690
  }).refine(
2619
2691
  (d) => (d.milliseconds !== void 0 || d.selector !== void 0) && !(d.milliseconds !== void 0 && d.selector !== void 0),
2620
2692
  { message: "Either 'milliseconds' or 'selector' must be provided, but not both." }
2621
2693
  );
2622
- var clickActionSchema = z17.object({
2623
- type: z17.literal("click"),
2624
- selector: z17.string(),
2625
- all: z17.boolean().optional()
2694
+ var clickActionSchema = z18.object({
2695
+ type: z18.literal("click"),
2696
+ selector: z18.string(),
2697
+ all: z18.boolean().optional()
2626
2698
  });
2627
- var screenshotActionSchema = z17.object({
2628
- type: z17.literal("screenshot"),
2629
- fullPage: z17.boolean().optional(),
2630
- quality: z17.number().min(1).max(100).optional(),
2631
- viewport: z17.object({ width: z17.number().int().positive(), height: z17.number().int().positive() }).optional(),
2632
- base64: z17.boolean().optional().describe("Return base64 data instead of file path")
2699
+ var screenshotActionSchema = z18.object({
2700
+ type: z18.literal("screenshot"),
2701
+ fullPage: z18.boolean().optional(),
2702
+ quality: z18.number().min(1).max(100).optional(),
2703
+ viewport: z18.object({ width: z18.number().int().positive(), height: z18.number().int().positive() }).optional(),
2704
+ base64: z18.boolean().optional().describe("Return base64 data instead of file path")
2633
2705
  });
2634
- var writeActionSchema = z17.object({
2635
- type: z17.literal("write"),
2636
- text: z17.string()
2706
+ var writeActionSchema = z18.object({
2707
+ type: z18.literal("write"),
2708
+ text: z18.string()
2637
2709
  });
2638
- var pressActionSchema = z17.object({
2639
- type: z17.literal("press"),
2640
- key: z17.string()
2710
+ var pressActionSchema = z18.object({
2711
+ type: z18.literal("press"),
2712
+ key: z18.string()
2641
2713
  });
2642
- var scrollActionSchema = z17.object({
2643
- type: z17.literal("scroll"),
2644
- direction: z17.enum(["up", "down"]).optional(),
2645
- selector: z17.string().optional()
2714
+ var scrollActionSchema = z18.object({
2715
+ type: z18.literal("scroll"),
2716
+ direction: z18.enum(["up", "down"]).optional(),
2717
+ selector: z18.string().optional()
2646
2718
  });
2647
- var scrapeActionSchema = z17.object({
2648
- type: z17.literal("scrape")
2719
+ var scrapeActionSchema = z18.object({
2720
+ type: z18.literal("scrape")
2649
2721
  });
2650
- var executeJavascriptActionSchema = z17.object({
2651
- type: z17.literal("executeJavascript"),
2652
- script: z17.string()
2722
+ var executeJavascriptActionSchema = z18.object({
2723
+ type: z18.literal("executeJavascript"),
2724
+ script: z18.string()
2653
2725
  });
2654
- var pdfActionSchema = z17.object({
2655
- type: z17.literal("pdf"),
2656
- landscape: z17.boolean().optional(),
2657
- scale: z17.number().optional(),
2658
- format: z17.enum(["A0", "A1", "A2", "A3", "A4", "A5", "A6", "Letter", "Legal", "Tabloid", "Ledger"]).optional()
2726
+ var pdfActionSchema = z18.object({
2727
+ type: z18.literal("pdf"),
2728
+ landscape: z18.boolean().optional(),
2729
+ scale: z18.number().optional(),
2730
+ format: z18.enum(["A0", "A1", "A2", "A3", "A4", "A5", "A6", "Letter", "Legal", "Tabloid", "Ledger"]).optional()
2659
2731
  });
2660
- var actionSchema = z17.union([
2732
+ var actionSchema = z18.union([
2661
2733
  waitActionSchema,
2662
2734
  clickActionSchema,
2663
2735
  screenshotActionSchema,
@@ -2748,11 +2820,11 @@ var actionsCommand = registerCommand({
2748
2820
  name: "actions",
2749
2821
  description: "Execute a sequence of actions (wait, click, scroll, screenshot, fill, etc.)",
2750
2822
  scope: "page",
2751
- parameters: z17.object({
2752
- url: z17.string().describe("Starting URL"),
2753
- actions: z17.array(actionSchema).max(MAX_ACTIONS).describe("Array of actions (max 50)"),
2754
- output: z17.enum(["text", "json"]).default("json").describe("Output format: text or json"),
2755
- timeout: z17.number().default(60).describe("Overall timeout in seconds (default: 60)")
2823
+ parameters: z18.object({
2824
+ url: z18.string().describe("Starting URL"),
2825
+ actions: z18.array(actionSchema).max(MAX_ACTIONS).describe("Array of actions (max 50)"),
2826
+ output: z18.enum(["text", "json"]).default("json").describe("Output format: text or json"),
2827
+ timeout: z18.number().default(60).describe("Overall timeout in seconds (default: 60)")
2756
2828
  }),
2757
2829
  handler: async (p, ctx) => {
2758
2830
  await ctx.page.goto(p.url, { waitUntil: "domcontentloaded" });
@@ -2772,14 +2844,14 @@ var actionsCommand = registerCommand({
2772
2844
  const finalUrl = ctx.page.url();
2773
2845
  const timedOut = results.length < p.actions.length;
2774
2846
  if (p.output === "text") {
2775
- return ok17({
2847
+ return ok18({
2776
2848
  title,
2777
2849
  url: finalUrl,
2778
2850
  actions: results.map((r) => JSON.stringify(r)).join("\n"),
2779
2851
  ...timedOut ? { warning: `Timed out after ${p.timeout}s, completed ${results.length}/${p.actions.length} actions` } : {}
2780
2852
  });
2781
2853
  }
2782
- return ok17({
2854
+ return ok18({
2783
2855
  title,
2784
2856
  url: finalUrl,
2785
2857
  results,
@@ -2789,8 +2861,8 @@ var actionsCommand = registerCommand({
2789
2861
  });
2790
2862
 
2791
2863
  // src/commands/scrape.ts
2792
- import { z as z18 } from "zod";
2793
- import { ok as ok18, fail as fail7 } from "@dyyz1993/xcli-core";
2864
+ import { z as z19 } from "zod";
2865
+ import { ok as ok19, fail as fail8 } from "@dyyz1993/xcli-core";
2794
2866
 
2795
2867
  // src/lib/html-to-markdown.ts
2796
2868
  import * as cheerio from "cheerio";
@@ -3175,15 +3247,15 @@ var scrapeCommand = registerCommand({
3175
3247
  description: "Scrape a page and convert to Markdown (with JS rendering)",
3176
3248
  scope: "project",
3177
3249
  selectorParams: ["selector"],
3178
- parameters: z18.object({
3179
- url: z18.string().optional(),
3180
- selector: z18.string().optional(),
3181
- timeout: z18.number().default(3e4),
3182
- format: z18.enum(["markdown", "html", "text"]).default("markdown"),
3183
- onlyMainContent: z18.boolean().default(true),
3184
- retries: z18.number().int().min(0).max(5).optional().default(2).describe("\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 2\uFF09"),
3185
- waitAfterLoad: z18.number().int().optional().default(0).describe("\u9875\u9762\u52A0\u8F7D\u540E\u989D\u5916\u7B49\u5F85\u6BEB\u79D2"),
3186
- 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")
3250
+ parameters: z19.object({
3251
+ url: z19.string().optional(),
3252
+ selector: z19.string().optional(),
3253
+ timeout: z19.number().default(3e4),
3254
+ format: z19.enum(["markdown", "html", "text"]).default("markdown"),
3255
+ onlyMainContent: z19.boolean().default(true),
3256
+ retries: z19.number().int().min(0).max(5).optional().default(2).describe("\u91CD\u8BD5\u6B21\u6570\uFF08\u9ED8\u8BA4 2\uFF09"),
3257
+ waitAfterLoad: z19.number().int().optional().default(0).describe("\u9875\u9762\u52A0\u8F7D\u540E\u989D\u5916\u7B49\u5F85\u6BEB\u79D2"),
3258
+ 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")
3187
3259
  }),
3188
3260
  handler: async (p, ctx) => {
3189
3261
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
@@ -3191,7 +3263,7 @@ var scrapeCommand = registerCommand({
3191
3263
  try {
3192
3264
  const targetUrl = p.url || page.url();
3193
3265
  if (!targetUrl || targetUrl === "about:blank") {
3194
- return fail7("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3266
+ return fail8("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3195
3267
  }
3196
3268
  let lastError;
3197
3269
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -3261,7 +3333,7 @@ var scrapeCommand = registerCommand({
3261
3333
  } catch {
3262
3334
  }
3263
3335
  if (p.mode === "smart") {
3264
- return ok18(structured);
3336
+ return ok19(structured);
3265
3337
  }
3266
3338
  if (p.mode === "compact") {
3267
3339
  const compactData = structured.tables.length > 0 ? structured.tables.map((t) => ({
@@ -3274,9 +3346,9 @@ var scrapeCommand = registerCommand({
3274
3346
  return compact;
3275
3347
  })
3276
3348
  })) : structured.mainText?.substring(0, 500);
3277
- return ok18({ url: structured.url, title: structured.title, data: compactData });
3349
+ return ok19({ url: structured.url, title: structured.title, data: compactData });
3278
3350
  }
3279
- return ok18(structured);
3351
+ return ok19(structured);
3280
3352
  }
3281
3353
  let content;
3282
3354
  switch (p.format) {
@@ -3335,7 +3407,7 @@ var scrapeCommand = registerCommand({
3335
3407
  content = await page.innerText("body");
3336
3408
  break;
3337
3409
  }
3338
- return ok18({ content, title, url: finalUrl });
3410
+ return ok19({ content, title, url: finalUrl });
3339
3411
  } catch (err) {
3340
3412
  lastError = err instanceof Error ? err : new Error(String(err));
3341
3413
  if (attempt < maxAttempts) {
@@ -3345,20 +3417,20 @@ var scrapeCommand = registerCommand({
3345
3417
  }
3346
3418
  }
3347
3419
  }
3348
- return fail7(`Scrape failed after ${maxAttempts} attempt(s): ${lastError?.message ?? "unknown error"}`);
3420
+ return fail8(`Scrape failed after ${maxAttempts} attempt(s): ${lastError?.message ?? "unknown error"}`);
3349
3421
  } finally {
3350
3422
  await closeEphemeralContext(context);
3351
3423
  }
3352
3424
  },
3353
- result: z18.object({
3354
- url: z18.string(),
3355
- title: z18.string()
3425
+ result: z19.object({
3426
+ url: z19.string(),
3427
+ title: z19.string()
3356
3428
  }).passthrough()
3357
3429
  });
3358
3430
 
3359
3431
  // src/commands/map.ts
3360
- import { z as z19 } from "zod";
3361
- import { ok as ok19, fail as fail8 } from "@dyyz1993/xcli-core";
3432
+ import { z as z20 } from "zod";
3433
+ import { ok as ok20, fail as fail9 } from "@dyyz1993/xcli-core";
3362
3434
 
3363
3435
  // src/utils/url.ts
3364
3436
  var SKIP_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -3593,21 +3665,21 @@ var mapCommand = registerCommand({
3593
3665
  name: "map",
3594
3666
  description: "Discover all URLs on a website via sitemap and page link extraction",
3595
3667
  scope: "project",
3596
- parameters: z19.object({
3597
- url: z19.string().optional(),
3598
- search: z19.string().optional(),
3599
- sitemap: z19.enum(["include", "only"]).optional(),
3600
- includeSubdomains: z19.boolean().optional(),
3601
- allowExternalLinks: z19.boolean().optional().describe("Include links to external domains"),
3602
- limit: z19.number().optional(),
3603
- verbose: z19.boolean().default(false).describe("Show progress feedback")
3668
+ parameters: z20.object({
3669
+ url: z20.string().optional(),
3670
+ search: z20.string().optional(),
3671
+ sitemap: z20.enum(["include", "only"]).optional(),
3672
+ includeSubdomains: z20.boolean().optional(),
3673
+ allowExternalLinks: z20.boolean().optional().describe("Include links to external domains"),
3674
+ limit: z20.number().optional(),
3675
+ verbose: z20.boolean().default(false).describe("Show progress feedback")
3604
3676
  }),
3605
3677
  handler: async (p, ctx) => {
3606
3678
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
3607
3679
  try {
3608
3680
  const targetUrl = p.url || page.url();
3609
3681
  if (!targetUrl || targetUrl === "about:blank") {
3610
- return fail8("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3682
+ return fail9("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
3611
3683
  }
3612
3684
  const links = await discoverUrls(page, targetUrl, {
3613
3685
  sitemap: p.sitemap,
@@ -3618,7 +3690,7 @@ var mapCommand = registerCommand({
3618
3690
  verbose: p.verbose
3619
3691
  });
3620
3692
  const linkObjects = links.map((url) => ({ url }));
3621
- return ok19({
3693
+ return ok20({
3622
3694
  links: linkObjects,
3623
3695
  success: true
3624
3696
  });
@@ -3626,15 +3698,15 @@ var mapCommand = registerCommand({
3626
3698
  await closeEphemeralContext(context);
3627
3699
  }
3628
3700
  },
3629
- result: z19.object({
3630
- links: z19.array(z19.object({ url: z19.string() })),
3631
- success: z19.boolean()
3701
+ result: z20.object({
3702
+ links: z20.array(z20.object({ url: z20.string() })),
3703
+ success: z20.boolean()
3632
3704
  })
3633
3705
  });
3634
3706
 
3635
3707
  // src/commands/crawl.ts
3636
- import { z as z20 } from "zod";
3637
- import { ok as ok20 } from "@dyyz1993/xcli-core";
3708
+ import { z as z21 } from "zod";
3709
+ import { ok as ok21 } from "@dyyz1993/xcli-core";
3638
3710
  function stripHashAnchorQuery(url) {
3639
3711
  try {
3640
3712
  const parsed = new URL(url);
@@ -3811,21 +3883,21 @@ var crawlCommand = registerCommand({
3811
3883
  name: "crawl",
3812
3884
  description: "Crawl a website and extract content from all pages",
3813
3885
  scope: "project",
3814
- parameters: z20.object({
3815
- url: z20.string(),
3816
- limit: z20.number().default(10),
3817
- maxDepth: z20.number().default(3),
3818
- includePaths: z20.array(z20.string()).optional(),
3819
- excludePaths: z20.array(z20.string()).optional(),
3820
- allowSubdomains: z20.boolean().default(false),
3821
- allowExternalLinks: z20.boolean().default(false),
3822
- allowBackwardCrawling: z20.boolean().default(false),
3823
- enableSpa: z20.boolean().default(true).describe("Disable to skip SPA route detection"),
3824
- format: z20.enum(["markdown", "html"]).default("markdown"),
3825
- onlyMainContent: z20.boolean().default(true),
3826
- concurrency: z20.number().default(3),
3827
- retries: z20.number().default(2),
3828
- verbose: z20.boolean().default(false)
3886
+ parameters: z21.object({
3887
+ url: z21.string(),
3888
+ limit: z21.number().default(10),
3889
+ maxDepth: z21.number().default(3),
3890
+ includePaths: z21.array(z21.string()).optional(),
3891
+ excludePaths: z21.array(z21.string()).optional(),
3892
+ allowSubdomains: z21.boolean().default(false),
3893
+ allowExternalLinks: z21.boolean().default(false),
3894
+ allowBackwardCrawling: z21.boolean().default(false),
3895
+ enableSpa: z21.boolean().default(true).describe("Disable to skip SPA route detection"),
3896
+ format: z21.enum(["markdown", "html"]).default("markdown"),
3897
+ onlyMainContent: z21.boolean().default(true),
3898
+ concurrency: z21.number().default(3),
3899
+ retries: z21.number().default(2),
3900
+ verbose: z21.boolean().default(false)
3829
3901
  }),
3830
3902
  handler: async (p, ctx) => {
3831
3903
  const startUrl = new URL(p.url);
@@ -3964,7 +4036,7 @@ var crawlCommand = registerCommand({
3964
4036
  if (errorPages.length > 0) {
3965
4037
  response.errors = errorPages;
3966
4038
  }
3967
- return ok20(response);
4039
+ return ok21(response);
3968
4040
  } finally {
3969
4041
  for (const ctx2 of contexts) {
3970
4042
  await ctx2.close().catch(() => {
@@ -3974,15 +4046,15 @@ var crawlCommand = registerCommand({
3974
4046
  } catch (err) {
3975
4047
  const message = err instanceof Error ? err.message : String(err);
3976
4048
  const successPages = results.filter((r) => !isPageError(r));
3977
- return ok20({ pages: successPages, total: successPages.length, success: false, error: message });
4049
+ return ok21({ pages: successPages, total: successPages.length, success: false, error: message });
3978
4050
  }
3979
4051
  }
3980
4052
  });
3981
4053
 
3982
4054
  // src/commands/search.ts
3983
- import { z as z21 } from "zod";
4055
+ import { z as z22 } from "zod";
3984
4056
  import * as cheerio2 from "cheerio";
3985
- import { ok as ok21 } from "@dyyz1993/xcli-core";
4057
+ import { ok as ok22 } from "@dyyz1993/xcli-core";
3986
4058
  function getRecencyParams(recency) {
3987
4059
  const now = Math.floor(Date.now() / 1e3);
3988
4060
  switch (recency) {
@@ -4316,16 +4388,16 @@ var searchCommand = registerCommand({
4316
4388
  name: "search",
4317
4389
  description: "Search the web and extract results with engine fallback",
4318
4390
  scope: "project",
4319
- parameters: z21.object({
4320
- query: z21.string(),
4321
- engine: z21.string().optional(),
4322
- limit: z21.number().default(10),
4323
- full: z21.boolean().default(false),
4324
- format: z21.enum(["markdown", "json", "text"]).default("markdown"),
4325
- timeout: z21.number().default(15e3),
4326
- recency: z21.enum(["hour", "day", "week", "month", "year"]).optional().describe("Filter by time: hour/day/week/month/year"),
4327
- fallback: z21.boolean().default(false).describe("Sequential engine fallback instead of parallel"),
4328
- site: z21.string().optional().describe("Limit results to a specific site (e.g. github.com, v2ex.com)")
4391
+ parameters: z22.object({
4392
+ query: z22.string(),
4393
+ engine: z22.string().optional(),
4394
+ limit: z22.number().default(10),
4395
+ full: z22.boolean().default(false),
4396
+ format: z22.enum(["markdown", "json", "text"]).default("markdown"),
4397
+ timeout: z22.number().default(15e3),
4398
+ recency: z22.enum(["hour", "day", "week", "month", "year"]).optional().describe("Filter by time: hour/day/week/month/year"),
4399
+ fallback: z22.boolean().default(false).describe("Sequential engine fallback instead of parallel"),
4400
+ site: z22.string().optional().describe("Limit results to a specific site (e.g. github.com, v2ex.com)")
4329
4401
  }),
4330
4402
  handler: async (p, ctx) => {
4331
4403
  const { context } = await createEphemeralContext(resolveLaunchOpts(ctx));
@@ -4431,7 +4503,7 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4431
4503
  lines.push(`> ${r.snippet}`);
4432
4504
  lines.push("");
4433
4505
  }
4434
- return ok21({ ...searchResult, content: lines.join("\n") });
4506
+ return ok22({ ...searchResult, content: lines.join("\n") });
4435
4507
  }
4436
4508
  if (p.format === "text") {
4437
4509
  const lines = [`Search: ${searchResult.query} (Engine: ${searchResult.engine}, Total: ${searchResult.total})`, ""];
@@ -4441,9 +4513,9 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4441
4513
  lines.push(` ${r.snippet}`);
4442
4514
  lines.push("");
4443
4515
  }
4444
- return ok21({ ...searchResult, content: lines.join("\n") });
4516
+ return ok22({ ...searchResult, content: lines.join("\n") });
4445
4517
  }
4446
- return ok21(searchResult);
4518
+ return ok22(searchResult);
4447
4519
  } finally {
4448
4520
  await closeEphemeralContext(context);
4449
4521
  }
@@ -4451,8 +4523,8 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
4451
4523
  });
4452
4524
 
4453
4525
  // src/commands/network.ts
4454
- import { z as z22 } from "zod";
4455
- import { ok as ok22, fail as fail9 } from "@dyyz1993/xcli-core";
4526
+ import { z as z23 } from "zod";
4527
+ import { ok as ok23, fail as fail10 } from "@dyyz1993/xcli-core";
4456
4528
  function extractPath2(url) {
4457
4529
  try {
4458
4530
  const u = new URL(url);
@@ -4550,19 +4622,19 @@ var networkCommand = registerCommand({
4550
4622
  name: "network",
4551
4623
  description: "Capture and filter network responses from a URL",
4552
4624
  scope: "project",
4553
- parameters: z22.object({
4554
- url: z22.string(),
4555
- filter: z22.string().optional(),
4556
- match: z22.string().optional(),
4557
- search: z22.string().optional().describe("Search within all captured response bodies"),
4558
- console: z22.boolean().default(false),
4559
- timeout: z22.number().default(3e4),
4560
- wait: z22.number().default(3e3),
4561
- limit: z22.number().default(50),
4562
- format: z22.enum(["summary", "json"]).default("summary"),
4563
- ws: z22.boolean().optional().default(false).describe("Only show WebSocket messages"),
4564
- 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"),
4565
- duration: z22.number().int().optional().default(15e3).describe("\u76D1\u542C\u6A21\u5F0F\u7B49\u5F85\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 15000\uFF09")
4625
+ parameters: z23.object({
4626
+ url: z23.string(),
4627
+ filter: z23.string().optional(),
4628
+ match: z23.string().optional(),
4629
+ search: z23.string().optional().describe("Search within all captured response bodies"),
4630
+ console: z23.boolean().default(false),
4631
+ timeout: z23.number().default(3e4),
4632
+ wait: z23.number().default(3e3),
4633
+ limit: z23.number().default(50),
4634
+ format: z23.enum(["summary", "json"]).default("summary"),
4635
+ ws: z23.boolean().optional().default(false).describe("Only show WebSocket messages"),
4636
+ 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"),
4637
+ duration: z23.number().int().optional().default(15e3).describe("\u76D1\u542C\u6A21\u5F0F\u7B49\u5F85\u65F6\u957F\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 15000\uFF09")
4566
4638
  }),
4567
4639
  handler: async (p, ctx) => {
4568
4640
  const startTime = Date.now();
@@ -4617,7 +4689,7 @@ var networkCommand = registerCommand({
4617
4689
  };
4618
4690
  if (p.listen) {
4619
4691
  const page2 = ctx.page;
4620
- if (!page2) return fail9("No active page. Use --cdp to connect first.");
4692
+ if (!page2) return fail10("No active page. Use --cdp to connect first.");
4621
4693
  const captures = [];
4622
4694
  const consoleMessages = [];
4623
4695
  const wsCaptures = [];
@@ -4644,7 +4716,7 @@ var networkCommand = registerCommand({
4644
4716
  page2.off("response", handler);
4645
4717
  const duration = Date.now() - startTime;
4646
4718
  if (p.ws && wsCaptures.length > 0) {
4647
- return ok22({
4719
+ return ok23({
4648
4720
  url: "[listen mode]",
4649
4721
  duration,
4650
4722
  total: captures.length,
@@ -4658,9 +4730,9 @@ var networkCommand = registerCommand({
4658
4730
  });
4659
4731
  }
4660
4732
  if (p.format === "json") {
4661
- return ok22(buildJsonOutput("[listen mode]", captures, consoleMessages, captures.length, wsCaptures));
4733
+ return ok23(buildJsonOutput("[listen mode]", captures, consoleMessages, captures.length, wsCaptures));
4662
4734
  }
4663
- return ok22(buildSummaryOutput("[listen mode]", duration, captures, consoleMessages, captures.length, wsCaptures));
4735
+ return ok23(buildSummaryOutput("[listen mode]", duration, captures, consoleMessages, captures.length, wsCaptures));
4664
4736
  }
4665
4737
  const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
4666
4738
  try {
@@ -4715,7 +4787,7 @@ var networkCommand = registerCommand({
4715
4787
  }
4716
4788
  const duration = Date.now() - startTime;
4717
4789
  if (p.ws && wsCaptures.length > 0) {
4718
- return ok22({
4790
+ return ok23({
4719
4791
  url: p.url,
4720
4792
  duration,
4721
4793
  total: captures.length,
@@ -4729,9 +4801,9 @@ var networkCommand = registerCommand({
4729
4801
  });
4730
4802
  }
4731
4803
  if (p.format === "json") {
4732
- return ok22(buildJsonOutput(p.url, results, consoleMessages, totalCount, wsCaptures, searchResults));
4804
+ return ok23(buildJsonOutput(p.url, results, consoleMessages, totalCount, wsCaptures, searchResults));
4733
4805
  }
4734
- return ok22(buildSummaryOutput(p.url, duration, results, consoleMessages, totalCount, wsCaptures));
4806
+ return ok23(buildSummaryOutput(p.url, duration, results, consoleMessages, totalCount, wsCaptures));
4735
4807
  } finally {
4736
4808
  await closeEphemeralContext(context);
4737
4809
  }
@@ -4739,7 +4811,7 @@ var networkCommand = registerCommand({
4739
4811
  });
4740
4812
 
4741
4813
  // src/commands/ai-search-engines.ts
4742
- import { z as z23 } from "zod";
4814
+ import { z as z24 } from "zod";
4743
4815
  var ENGINE_CONFIGS = {
4744
4816
  deepseek: {
4745
4817
  key: "deepseek",
@@ -4993,7 +5065,7 @@ var ENGINE_CONFIGS = {
4993
5065
  }
4994
5066
  };
4995
5067
  var ALL_ENGINE_KEYS = Object.keys(ENGINE_CONFIGS);
4996
- var ENGINE_KEY_ENUM = z23.enum(ALL_ENGINE_KEYS);
5068
+ var ENGINE_KEY_ENUM = z24.enum(ALL_ENGINE_KEYS);
4997
5069
  function getEngineConfig(key) {
4998
5070
  return ENGINE_CONFIGS[key];
4999
5071
  }
@@ -5273,8 +5345,8 @@ function parseMarkdownResults(rawText) {
5273
5345
  }
5274
5346
 
5275
5347
  // src/commands/snapshot.ts
5276
- import { z as z24 } from "zod";
5277
- import { ok as ok23, fail as fail10, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
5348
+ import { z as z25 } from "zod";
5349
+ import { ok as ok24, fail as fail11, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
5278
5350
 
5279
5351
  // src/utils/resolve-selector.ts
5280
5352
  function buildElementSelector(el) {
@@ -5755,24 +5827,24 @@ var snapshotCommand = registerCommand({
5755
5827
  description: "Capture a quick page state snapshot \u2014 aria tree, visible text, or DOM summary",
5756
5828
  scope: "page",
5757
5829
  selectorParams: ["selector"],
5758
- parameters: z24.object({
5759
- type: z24.enum(["aria", "text", "dom", "all"]).default("aria").describe("Snapshot type: aria (accessibility tree), text (visible text), dom (element summary), all (combined)"),
5760
- selector: z24.string().optional().describe("Scope to a specific element"),
5761
- depth: z24.number().optional().default(6).describe("Max depth for DOM/aria tree"),
5762
- interactive: z24.boolean().optional().default(false).describe("Return interactive agent refs only"),
5763
- interactiveOnly: z24.boolean().optional().default(false).describe("Alias for interactive"),
5764
- i: z24.boolean().optional().default(false).describe("Short alias for interactive"),
5765
- compact: z24.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5766
- c: z24.boolean().optional().default(false).describe("Short alias for compact"),
5767
- selectors: z24.boolean().optional().default(false).describe("Include ref to CSS selector map"),
5768
- all: z24.boolean().optional().default(false).describe("Include hidden interactive targets when using interactive snapshot")
5830
+ parameters: z25.object({
5831
+ type: z25.enum(["aria", "text", "dom", "all"]).default("aria").describe("Snapshot type: aria (accessibility tree), text (visible text), dom (element summary), all (combined)"),
5832
+ selector: z25.string().optional().describe("Scope to a specific element"),
5833
+ depth: z25.number().optional().default(6).describe("Max depth for DOM/aria tree"),
5834
+ interactive: z25.boolean().optional().default(false).describe("Return interactive agent refs only"),
5835
+ interactiveOnly: z25.boolean().optional().default(false).describe("Alias for interactive"),
5836
+ i: z25.boolean().optional().default(false).describe("Short alias for interactive"),
5837
+ compact: z25.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5838
+ c: z25.boolean().optional().default(false).describe("Short alias for compact"),
5839
+ selectors: z25.boolean().optional().default(false).describe("Include ref to CSS selector map"),
5840
+ all: z25.boolean().optional().default(false).describe("Include hidden interactive targets when using interactive snapshot")
5769
5841
  }),
5770
- result: z24.object({
5771
- url: z24.string(),
5772
- title: z24.string(),
5773
- aria: z24.string().optional(),
5774
- text: z24.string().optional(),
5775
- dom: z24.record(z24.unknown()).optional()
5842
+ result: z25.object({
5843
+ url: z25.string(),
5844
+ title: z25.string(),
5845
+ aria: z25.string().optional(),
5846
+ text: z25.string().optional(),
5847
+ dom: z25.record(z25.unknown()).optional()
5776
5848
  }),
5777
5849
  handler: async (p, ctx) => {
5778
5850
  const page = ctx.page;
@@ -5786,7 +5858,7 @@ var snapshotCommand = registerCommand({
5786
5858
  if (p.compact || p.c || p.interactive || p.interactiveOnly || p.i) {
5787
5859
  observation.compact = formatObservationCompact(observation, { selectors: p.selectors });
5788
5860
  }
5789
- return ok23(observation, normalizeTips3([
5861
+ return ok24(observation, normalizeTips3([
5790
5862
  `refs refreshed for ${observation.targets.length} targets; use click @e1 or fill @e2 "text"`
5791
5863
  ]));
5792
5864
  }
@@ -5794,15 +5866,15 @@ var snapshotCommand = registerCommand({
5794
5866
  const aria = await captureAriaSnapshot(page, p.selector, p.depth);
5795
5867
  const tips = await buildRefTips(page, aria);
5796
5868
  persistSemantics(url, aria);
5797
- return ok23({ url, title, aria }, normalizeTips3(tips));
5869
+ return ok24({ url, title, aria }, normalizeTips3(tips));
5798
5870
  }
5799
5871
  if (p.type === "text") {
5800
5872
  const text = await captureTextSnapshot(page, p.selector);
5801
- return ok23({ url, title, text });
5873
+ return ok24({ url, title, text });
5802
5874
  }
5803
5875
  if (p.type === "dom") {
5804
5876
  const dom = await captureDomSnapshot(page, p.selector, p.depth ?? 6);
5805
- return ok23({ url, title, dom });
5877
+ return ok24({ url, title, dom });
5806
5878
  }
5807
5879
  if (p.type === "all") {
5808
5880
  const [aria, text, dom] = await Promise.all([
@@ -5812,9 +5884,9 @@ var snapshotCommand = registerCommand({
5812
5884
  ]);
5813
5885
  const tips = await buildRefTips(page, aria);
5814
5886
  persistSemantics(url, aria);
5815
- return ok23({ url, title, aria, text, dom }, normalizeTips3(tips));
5887
+ return ok24({ url, title, aria, text, dom }, normalizeTips3(tips));
5816
5888
  }
5817
- return fail10(`Unknown snapshot type: ${p.type}`);
5889
+ return fail11(`Unknown snapshot type: ${p.type}`);
5818
5890
  }
5819
5891
  });
5820
5892
  function persistSemantics(url, aria) {
@@ -5891,22 +5963,22 @@ async function captureDomSnapshot(page, selector, maxDepth) {
5891
5963
  }
5892
5964
 
5893
5965
  // src/commands/agent.ts
5894
- import { z as z25 } from "zod";
5895
- import { ok as ok24, normalizeTips as normalizeTips4 } from "@dyyz1993/xcli-core";
5966
+ import { z as z26 } from "zod";
5967
+ import { ok as ok25, normalizeTips as normalizeTips4 } from "@dyyz1993/xcli-core";
5896
5968
  var observeCommand = registerCommand({
5897
5969
  name: "observe",
5898
5970
  description: "Observe the current page as structured agent targets with session refs",
5899
5971
  scope: "page",
5900
- parameters: z25.object({
5901
- includeHidden: z25.boolean().optional().default(false).describe("Include hidden elements in the target list"),
5902
- limit: z25.number().int().positive().max(300).optional().default(80).describe("Maximum number of targets to return"),
5903
- compact: z25.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5904
- selectors: z25.boolean().optional().default(false).describe("Include ref to stable CSS selector map")
5972
+ parameters: z26.object({
5973
+ includeHidden: z26.boolean().optional().default(false).describe("Include hidden elements in the target list"),
5974
+ limit: z26.number().int().positive().max(300).optional().default(80).describe("Maximum number of targets to return"),
5975
+ compact: z26.boolean().optional().default(false).describe("Include compact xbrowser style snapshot text"),
5976
+ selectors: z26.boolean().optional().default(false).describe("Include ref to stable CSS selector map")
5905
5977
  }),
5906
- result: z25.object({
5907
- targets: z25.array(z25.record(z25.unknown())),
5908
- selectors: z25.record(z25.unknown()).optional(),
5909
- compact: z25.string().optional()
5978
+ result: z26.object({
5979
+ targets: z26.array(z26.record(z26.unknown())),
5980
+ selectors: z26.record(z26.unknown()).optional(),
5981
+ compact: z26.string().optional()
5910
5982
  }).passthrough(),
5911
5983
  handler: async (p, ctx) => {
5912
5984
  const observation = await observePage(ctx.page, ctx.sessionId, {
@@ -5915,7 +5987,7 @@ var observeCommand = registerCommand({
5915
5987
  });
5916
5988
  if (p.selectors) observation.selectors = buildSelectorMap(observation);
5917
5989
  if (p.compact) observation.compact = formatObservationCompact(observation, { selectors: p.selectors });
5918
- return ok24(observation, normalizeTips4([
5990
+ return ok25(observation, normalizeTips4([
5919
5991
  `refs refreshed for ${observation.targets.length} targets; use act --ref @e1 --action click or click @e1`
5920
5992
  ]));
5921
5993
  }
@@ -5925,14 +5997,14 @@ var actCommand = registerCommand({
5925
5997
  description: "Perform an agent action using an observe ref or explicit selector",
5926
5998
  scope: "element",
5927
5999
  selectorParams: ["selector"],
5928
- parameters: z25.object({
5929
- action: z25.enum(["click", "fill", "type", "press", "select", "check", "hover"]).default("click"),
5930
- ref: z25.string().optional().describe("Session-scoped ref returned by observe, such as e1"),
5931
- selector: z25.string().optional().describe("CSS selector fallback when no ref is available"),
5932
- value: z25.string().optional().describe("Value for fill/type/select"),
5933
- key: z25.string().optional().describe("Key for press"),
5934
- force: z25.boolean().optional().default(false).describe("Bypass actionability checks"),
5935
- timeout: z25.number().optional().default(1e4).describe("Playwright action timeout in milliseconds")
6000
+ parameters: z26.object({
6001
+ action: z26.enum(["click", "fill", "type", "press", "select", "check", "hover"]).default("click"),
6002
+ ref: z26.string().optional().describe("Session-scoped ref returned by observe, such as e1"),
6003
+ selector: z26.string().optional().describe("CSS selector fallback when no ref is available"),
6004
+ value: z26.string().optional().describe("Value for fill/type/select"),
6005
+ key: z26.string().optional().describe("Key for press"),
6006
+ force: z26.boolean().optional().default(false).describe("Bypass actionability checks"),
6007
+ timeout: z26.number().optional().default(1e4).describe("Playwright action timeout in milliseconds")
5936
6008
  }).refine((p) => !!p.ref || !!p.selector, {
5937
6009
  message: "Either ref or selector is required"
5938
6010
  }),
@@ -5946,7 +6018,7 @@ var actCommand = registerCommand({
5946
6018
  tips: normalizeTips4(result.stale ? ["run observe again to refresh refs"] : [])
5947
6019
  };
5948
6020
  }
5949
- return ok24(result, normalizeTips4(result.stale ? ["ref screen hash changed; run observe if the next action is uncertain"] : []));
6021
+ return ok25(result, normalizeTips4(result.stale ? ["ref screen hash changed; run observe if the next action is uncertain"] : []));
5950
6022
  }
5951
6023
  });
5952
6024
  var waitForCommand = registerCommand({
@@ -5954,16 +6026,16 @@ var waitForCommand = registerCommand({
5954
6026
  description: "Wait for agent predicates such as text, URL, load state, selector state, or screen hash changes",
5955
6027
  scope: "page",
5956
6028
  selectorParams: ["selector"],
5957
- parameters: z25.object({
5958
- selector: z25.string().optional().describe("CSS selector or observe ref to wait for"),
5959
- state: z25.enum(["attached", "detached", "visible", "hidden"]).optional().default("visible"),
5960
- text: z25.string().optional().describe("Visible text to wait for"),
5961
- url: z25.string().optional().describe("URL substring or glob pattern to wait for"),
5962
- load: z25.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("Load state to wait for"),
5963
- fn: z25.string().optional().describe("JavaScript predicate to wait for"),
5964
- screenHashChanged: z25.string().optional().describe("Previous screenHash from observe"),
5965
- timeout: z25.number().optional().default(3e4),
5966
- pollInterval: z25.number().optional().default(200)
6029
+ parameters: z26.object({
6030
+ selector: z26.string().optional().describe("CSS selector or observe ref to wait for"),
6031
+ state: z26.enum(["attached", "detached", "visible", "hidden"]).optional().default("visible"),
6032
+ text: z26.string().optional().describe("Visible text to wait for"),
6033
+ url: z26.string().optional().describe("URL substring or glob pattern to wait for"),
6034
+ load: z26.enum(["load", "domcontentloaded", "networkidle"]).optional().describe("Load state to wait for"),
6035
+ fn: z26.string().optional().describe("JavaScript predicate to wait for"),
6036
+ screenHashChanged: z26.string().optional().describe("Previous screenHash from observe"),
6037
+ timeout: z26.number().optional().default(3e4),
6038
+ pollInterval: z26.number().optional().default(200)
5967
6039
  }).refine((p) => [p.selector, p.text, p.url, p.load, p.fn, p.screenHashChanged].filter(Boolean).length === 1, {
5968
6040
  message: "Provide exactly one wait predicate: selector, text, url, load, fn, or screenHashChanged"
5969
6041
  }),
@@ -5977,30 +6049,30 @@ var waitForCommand = registerCommand({
5977
6049
  tips: []
5978
6050
  };
5979
6051
  }
5980
- return ok24(result);
6052
+ return ok25(result);
5981
6053
  }
5982
6054
  });
5983
6055
 
5984
6056
  // src/commands/tab.ts
5985
- import { z as z26 } from "zod";
5986
- import { ok as ok25, fail as fail11 } from "@dyyz1993/xcli-core";
5987
- var TabParams = z26.object({
5988
- subcommand: z26.enum(["list", "new", "close", "switch"]),
5989
- url: z26.string().optional(),
5990
- index: z26.number().int().min(0).optional()
6057
+ import { z as z27 } from "zod";
6058
+ import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
6059
+ var TabParams = z27.object({
6060
+ subcommand: z27.enum(["list", "new", "close", "switch"]),
6061
+ url: z27.string().optional(),
6062
+ index: z27.number().int().min(0).optional()
5991
6063
  });
5992
6064
  var tabCommand = registerCommand({
5993
6065
  name: "tab",
5994
6066
  description: "Manage browser tabs: list, new, close, switch",
5995
6067
  scope: "page",
5996
6068
  parameters: TabParams,
5997
- result: z26.object({
5998
- success: z26.boolean(),
5999
- data: z26.unknown()
6069
+ result: z27.object({
6070
+ success: z27.boolean(),
6071
+ data: z27.unknown()
6000
6072
  }),
6001
6073
  handler: async (p, ctx) => {
6002
6074
  if (!ctx.browserContext) {
6003
- return fail11("No browser context available. Use --cdp to connect to a browser first.");
6075
+ return fail12("No browser context available. Use --cdp to connect to a browser first.");
6004
6076
  }
6005
6077
  const pages = ctx.browserContext.pages();
6006
6078
  switch (p.subcommand) {
@@ -6013,7 +6085,7 @@ var tabCommand = registerCommand({
6013
6085
  case "switch":
6014
6086
  return handleSwitch(p, pages, ctx);
6015
6087
  default:
6016
- return fail11(`Unknown subcommand: ${p.subcommand}`);
6088
+ return fail12(`Unknown subcommand: ${p.subcommand}`);
6017
6089
  }
6018
6090
  }
6019
6091
  });
@@ -6028,7 +6100,7 @@ async function handleList(pages, ctx) {
6028
6100
  if (isActive) activeIndex = i;
6029
6101
  tabs.push({ index: i, url, title, active: isActive });
6030
6102
  }
6031
- return ok25({ tabs, total: tabs.length, activeIndex });
6103
+ return ok26({ tabs, total: tabs.length, activeIndex });
6032
6104
  }
6033
6105
  async function handleNew(p, _pages, ctx) {
6034
6106
  const newPage = await ctx.browserContext.newPage();
@@ -6056,7 +6128,7 @@ async function handleNew(p, _pages, ctx) {
6056
6128
  const title = await newPage.title().catch(() => "");
6057
6129
  const allPages = ctx.browserContext.pages();
6058
6130
  const newIndex = allPages.indexOf(newPage);
6059
- return ok25({
6131
+ return ok26({
6060
6132
  index: newIndex >= 0 ? newIndex : allPages.length - 1,
6061
6133
  url: newPage.url(),
6062
6134
  title,
@@ -6067,11 +6139,11 @@ async function handleNew(p, _pages, ctx) {
6067
6139
  async function handleClose(p, ctx) {
6068
6140
  const currentPages = ctx.browserContext.pages();
6069
6141
  if (currentPages.length <= 1) {
6070
- return fail11("Cannot close the last remaining tab");
6142
+ return fail12("Cannot close the last remaining tab");
6071
6143
  }
6072
6144
  const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
6073
6145
  if (closeIndex < 0 || closeIndex >= currentPages.length) {
6074
- return fail11(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6146
+ return fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6075
6147
  }
6076
6148
  const pageToClose = currentPages[closeIndex];
6077
6149
  const isActivePage = pageToClose === ctx.page;
@@ -6086,7 +6158,7 @@ async function handleClose(p, ctx) {
6086
6158
  }
6087
6159
  ctx.page = newActivePage;
6088
6160
  }
6089
- return ok25({
6161
+ return ok26({
6090
6162
  closedIndex: closeIndex,
6091
6163
  total: remainingPages.length,
6092
6164
  activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
@@ -6094,10 +6166,10 @@ async function handleClose(p, ctx) {
6094
6166
  }
6095
6167
  async function handleSwitch(p, pages, ctx) {
6096
6168
  if (p.index === void 0) {
6097
- return fail11("Parameter --index is required for switch subcommand");
6169
+ return fail12("Parameter --index is required for switch subcommand");
6098
6170
  }
6099
6171
  if (p.index < 0 || p.index >= pages.length) {
6100
- return fail11(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6172
+ return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6101
6173
  }
6102
6174
  const targetPage = pages[p.index];
6103
6175
  await targetPage.bringToFront().catch(() => {
@@ -6119,7 +6191,7 @@ async function handleSwitch(p, pages, ctx) {
6119
6191
  }
6120
6192
  ctx.page = targetPage;
6121
6193
  const title = await targetPage.title().catch(() => "");
6122
- return ok25({
6194
+ return ok26({
6123
6195
  index: p.index,
6124
6196
  url: targetPage.url(),
6125
6197
  title,
@@ -6128,17 +6200,17 @@ async function handleSwitch(p, pages, ctx) {
6128
6200
  }
6129
6201
 
6130
6202
  // src/commands/addinitscript.ts
6131
- import { z as z27 } from "zod";
6132
- import { ok as ok26 } from "@dyyz1993/xcli-core";
6203
+ import { z as z28 } from "zod";
6204
+ import { ok as ok27 } from "@dyyz1993/xcli-core";
6133
6205
  import { readFileSync as readFileSync4 } from "fs";
6134
- var InitScriptParams = z27.object({
6135
- script: z27.string().optional(),
6136
- file: z27.string().optional(),
6137
- stdin: z27.boolean().optional(),
6138
- name: z27.string().optional(),
6139
- list: z27.boolean().optional(),
6140
- remove: z27.union([z27.string(), z27.boolean()]).optional(),
6141
- base64: z27.string().optional()
6206
+ var InitScriptParams = z28.object({
6207
+ script: z28.string().optional(),
6208
+ file: z28.string().optional(),
6209
+ stdin: z28.boolean().optional(),
6210
+ name: z28.string().optional(),
6211
+ list: z28.boolean().optional(),
6212
+ remove: z28.union([z28.string(), z28.boolean()]).optional(),
6213
+ base64: z28.string().optional()
6142
6214
  });
6143
6215
  var registeredScripts = /* @__PURE__ */ new Map();
6144
6216
  function resolveScriptContent(params) {
@@ -6172,14 +6244,14 @@ var addInitScriptCommand = registerCommand({
6172
6244
  description: "Add an initialization script that runs on every page load",
6173
6245
  scope: "page",
6174
6246
  parameters: InitScriptParams,
6175
- result: z27.object({
6176
- scripts: z27.array(z27.object({ name: z27.string(), size: z27.number(), preview: z27.string() })).optional(),
6177
- removed: z27.string().optional(),
6178
- existed: z27.boolean().optional(),
6179
- error: z27.string().optional(),
6180
- registered: z27.string().optional(),
6181
- hint: z27.string().optional(),
6182
- executedImmediately: z27.boolean().optional()
6247
+ result: z28.object({
6248
+ scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6249
+ removed: z28.string().optional(),
6250
+ existed: z28.boolean().optional(),
6251
+ error: z28.string().optional(),
6252
+ registered: z28.string().optional(),
6253
+ hint: z28.string().optional(),
6254
+ executedImmediately: z28.boolean().optional()
6183
6255
  }).passthrough(),
6184
6256
  handler: async (params, ctx) => {
6185
6257
  if (params.list) {
@@ -6188,20 +6260,20 @@ var addInitScriptCommand = registerCommand({
6188
6260
  size: content2.length,
6189
6261
  preview: content2.slice(0, 80)
6190
6262
  }));
6191
- return ok26({ scripts });
6263
+ return ok27({ scripts });
6192
6264
  }
6193
6265
  if (params.remove && typeof params.remove === "string") {
6194
6266
  const existed = registeredScripts.delete(params.remove);
6195
- return ok26({ removed: params.remove, existed });
6267
+ return ok27({ removed: params.remove, existed });
6196
6268
  }
6197
6269
  const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
6198
6270
  if (removeTarget && !resolveScriptContent(params)) {
6199
6271
  const existed = registeredScripts.delete(removeTarget);
6200
- return ok26({ removed: removeTarget, existed });
6272
+ return ok27({ removed: removeTarget, existed });
6201
6273
  }
6202
6274
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6203
6275
  if (!content) {
6204
- return ok26({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6276
+ return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6205
6277
  }
6206
6278
  const scriptName = params.name ?? `script-${Date.now()}`;
6207
6279
  registeredScripts.set(scriptName, content);
@@ -6209,45 +6281,45 @@ var addInitScriptCommand = registerCommand({
6209
6281
  try {
6210
6282
  await ctx.page.evaluate(content);
6211
6283
  } catch {
6212
- return ok26({
6284
+ return ok27({
6213
6285
  registered: scriptName,
6214
6286
  hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
6215
6287
  });
6216
6288
  }
6217
- return ok26({ registered: scriptName, executedImmediately: true });
6289
+ return ok27({ registered: scriptName, executedImmediately: true });
6218
6290
  }
6219
6291
  });
6220
6292
  registerCommandDefinition("addinitscript", ["script"]);
6221
6293
 
6222
6294
  // src/commands/find.ts
6223
- import { z as z28 } from "zod";
6224
- import { ok as ok27, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6225
- var actionSchema2 = z28.enum(["click", "fill", "type", "select", "hover", "check"]);
6295
+ import { z as z29 } from "zod";
6296
+ import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6297
+ var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
6226
6298
  var findCommand = registerCommand({
6227
6299
  name: "find",
6228
6300
  description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
6229
6301
  scope: "page",
6230
- parameters: z28.object({
6231
- strategy: z28.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6232
- value: z28.string(),
6233
- name: z28.string().optional(),
6234
- exact: z28.boolean().optional().default(false),
6235
- operation: z28.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6302
+ parameters: z29.object({
6303
+ strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6304
+ value: z29.string(),
6305
+ name: z29.string().optional(),
6306
+ exact: z29.boolean().optional().default(false),
6307
+ operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6236
6308
  action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
6237
- actionValue: z28.string().optional().describe("Value for fill/type/select when using action"),
6238
- index: z28.number().int().optional().describe("Index for nth strategy"),
6239
- click: z28.boolean().optional().default(false),
6240
- fill: z28.string().optional(),
6241
- type: z28.string().optional(),
6242
- select: z28.string().optional(),
6243
- hover: z28.boolean().optional().default(false),
6244
- check: z28.boolean().optional().default(false),
6245
- timeout: z28.number().optional().default(1e4)
6309
+ actionValue: z29.string().optional().describe("Value for fill/type/select when using action"),
6310
+ index: z29.number().int().optional().describe("Index for nth strategy"),
6311
+ click: z29.boolean().optional().default(false),
6312
+ fill: z29.string().optional(),
6313
+ type: z29.string().optional(),
6314
+ select: z29.string().optional(),
6315
+ hover: z29.boolean().optional().default(false),
6316
+ check: z29.boolean().optional().default(false),
6317
+ timeout: z29.number().optional().default(1e4)
6246
6318
  }),
6247
- result: z28.object({
6248
- matched: z28.number(),
6249
- selector: z28.string(),
6250
- action: z28.string().optional()
6319
+ result: z29.object({
6320
+ matched: z29.number(),
6321
+ selector: z29.string(),
6322
+ action: z29.string().optional()
6251
6323
  }),
6252
6324
  handler: async (p, ctx) => {
6253
6325
  const page = ctx.page;
@@ -6262,7 +6334,7 @@ var findCommand = registerCommand({
6262
6334
  });
6263
6335
  const count = await locator.count();
6264
6336
  if (count === 0) {
6265
- return fail12(`No element found with ${p.strategy}="${p.value}"`);
6337
+ return fail13(`No element found with ${p.strategy}="${p.value}"`);
6266
6338
  }
6267
6339
  const tips = [];
6268
6340
  const target = selectTarget(locator, p.strategy);
@@ -6274,15 +6346,15 @@ var findCommand = registerCommand({
6274
6346
  await target.click({ timeout: p.timeout, force: true });
6275
6347
  return okWithTips({ matched: count, selector, action: "click" }, tips);
6276
6348
  } else if (actionName === "fill") {
6277
- if (actionValue === void 0) return fail12("find fill requires a value");
6349
+ if (actionValue === void 0) return fail13("find fill requires a value");
6278
6350
  await target.fill(actionValue, { timeout: p.timeout, force: true });
6279
6351
  return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
6280
6352
  } else if (actionName === "type") {
6281
- if (actionValue === void 0) return fail12("find type requires a value");
6353
+ if (actionValue === void 0) return fail13("find type requires a value");
6282
6354
  await target.type(actionValue, { delay: 10, timeout: p.timeout });
6283
6355
  return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
6284
6356
  } else if (actionName === "select") {
6285
- if (actionValue === void 0) return fail12("find select requires a value");
6357
+ if (actionValue === void 0) return fail13("find select requires a value");
6286
6358
  await target.selectOption(actionValue);
6287
6359
  return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
6288
6360
  } else if (actionName === "hover") {
@@ -6296,7 +6368,7 @@ var findCommand = registerCommand({
6296
6368
  }
6297
6369
  });
6298
6370
  function okWithTips(data, tips) {
6299
- const result = ok27(data);
6371
+ const result = ok28(data);
6300
6372
  if (tips.length > 0) result.tips = normalizeTips5(tips);
6301
6373
  return result;
6302
6374
  }
@@ -6395,8 +6467,8 @@ function describeSelector(strategy, value, name) {
6395
6467
  }
6396
6468
 
6397
6469
  // src/commands/visual-tag.ts
6398
- import { z as z29 } from "zod";
6399
- import { ok as ok28, fail as fail13 } from "@dyyz1993/xcli-core";
6470
+ import { z as z30 } from "zod";
6471
+ import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6400
6472
  var SAFE_SET = "ahjkmnprtw3479".split("");
6401
6473
  var TAG_SCRIPT = `
6402
6474
  (function() {
@@ -6487,49 +6559,49 @@ var visualTagCommand = registerCommand({
6487
6559
  name: "visual-tag",
6488
6560
  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",
6489
6561
  scope: "page",
6490
- parameters: z29.object({
6491
- action: z29.enum(["tag", "lookup", "clear", "list"]),
6492
- id: z29.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6562
+ parameters: z30.object({
6563
+ action: z30.enum(["tag", "lookup", "clear", "list"]),
6564
+ id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6493
6565
  }),
6494
- result: z29.object({
6495
- action: z29.string(),
6496
- tagged: z29.number().optional(),
6497
- id: z29.string().optional(),
6498
- element: z29.record(z29.unknown()).optional()
6566
+ result: z30.object({
6567
+ action: z30.string(),
6568
+ tagged: z30.number().optional(),
6569
+ id: z30.string().optional(),
6570
+ element: z30.record(z30.unknown()).optional()
6499
6571
  }),
6500
6572
  handler: async (p, ctx) => {
6501
6573
  switch (p.action) {
6502
6574
  case "tag": {
6503
6575
  const result = await ctx.page.evaluate(TAG_SCRIPT);
6504
6576
  const parsed = JSON.parse(result);
6505
- return ok28({ action: "tag", tagged: parsed.tagged });
6577
+ return ok29({ action: "tag", tagged: parsed.tagged });
6506
6578
  }
6507
6579
  case "lookup": {
6508
- if (!p.id) return fail13("lookup \u9700\u8981 --id \u53C2\u6570");
6580
+ if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
6509
6581
  const result = await ctx.page.evaluate(
6510
6582
  `(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'}); })()`
6511
6583
  );
6512
6584
  const parsed = JSON.parse(result);
6513
- if (parsed.err) return fail13(`ID ${p.id}: ${parsed.err}`);
6514
- return ok28({ action: "lookup", id: p.id, element: parsed });
6585
+ if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6586
+ return ok29({ action: "lookup", id: p.id, element: parsed });
6515
6587
  }
6516
6588
  case "list": {
6517
6589
  const result = await ctx.page.evaluate(
6518
6590
  `(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); })()`
6519
6591
  );
6520
- return ok28({ action: "list", element: JSON.parse(result) });
6592
+ return ok29({ action: "list", element: JSON.parse(result) });
6521
6593
  }
6522
6594
  case "clear": {
6523
6595
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6524
- return ok28({ action: "clear" });
6596
+ return ok29({ action: "clear" });
6525
6597
  }
6526
6598
  }
6527
6599
  }
6528
6600
  });
6529
6601
 
6530
6602
  // src/commands/visual-tag-v2.ts
6531
- import { z as z30 } from "zod";
6532
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6603
+ import { z as z31 } from "zod";
6604
+ import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6533
6605
  var SAFE_SET2 = "ahjkmnprtw3479".split("");
6534
6606
  var TAG_V2_SCRIPT = `
6535
6607
  (function() {
@@ -6876,45 +6948,45 @@ var visualTagV2Command = registerCommand({
6876
6948
  name: "visual-tag-v2",
6877
6949
  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",
6878
6950
  scope: "page",
6879
- parameters: z30.object({
6880
- action: z30.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6881
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6882
- query: z30.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6883
- type: z30.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6884
- "interact-action": z30.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6885
- value: z30.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6951
+ parameters: z31.object({
6952
+ action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6953
+ id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6954
+ query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6955
+ type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6956
+ "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6957
+ value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6886
6958
  }),
6887
- result: z30.object({
6888
- action: z30.string(),
6889
- total: z30.number().optional(),
6890
- byType: z30.record(z30.number()).optional(),
6891
- element: z30.record(z30.unknown()).optional()
6959
+ result: z31.object({
6960
+ action: z31.string(),
6961
+ total: z31.number().optional(),
6962
+ byType: z31.record(z31.number()).optional(),
6963
+ element: z31.record(z31.unknown()).optional()
6892
6964
  }),
6893
6965
  handler: async (p, ctx) => {
6894
6966
  switch (p.action) {
6895
6967
  case "tag": {
6896
6968
  const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6897
6969
  const parsed = JSON.parse(result);
6898
- return ok29({ action: "tag", total: parsed.total, byType: parsed.byType });
6970
+ return ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
6899
6971
  }
6900
6972
  case "lookup": {
6901
- if (!p.id) return fail14("lookup \u9700\u8981 --id");
6973
+ if (!p.id) return fail15("lookup \u9700\u8981 --id");
6902
6974
  const result = await ctx.page.evaluate(
6903
6975
  `(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'})})()`
6904
6976
  );
6905
6977
  const parsed = JSON.parse(result);
6906
- if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6907
- return ok29({ action: "lookup", id: p.id, element: parsed });
6978
+ if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6979
+ return ok30({ action: "lookup", id: p.id, element: parsed });
6908
6980
  }
6909
6981
  case "by-type": {
6910
6982
  const result = await ctx.page.evaluate(
6911
6983
  `(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)})()`
6912
6984
  );
6913
- return ok29({ action: "by-type", element: JSON.parse(result) });
6985
+ return ok30({ action: "by-type", element: JSON.parse(result) });
6914
6986
  }
6915
6987
  case "find": {
6916
6988
  const query = p.query;
6917
- if (!query) return fail14('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6989
+ if (!query) return fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6918
6990
  const result = await ctx.page.evaluate(
6919
6991
  `(function(){
6920
6992
  var map = window.__xbTagSerializable;
@@ -6956,21 +7028,21 @@ var visualTagV2Command = registerCommand({
6956
7028
  return JSON.stringify({total:results.length, results:results.slice(0,20)});
6957
7029
  })()`
6958
7030
  );
6959
- return ok29({ action: "find", query, element: JSON.parse(result) });
7031
+ return ok30({ action: "find", query, element: JSON.parse(result) });
6960
7032
  }
6961
7033
  case "stats": {
6962
7034
  const result = await ctx.page.evaluate(
6963
7035
  `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6964
7036
  );
6965
- return ok29({ action: "stats", element: JSON.parse(result) });
7037
+ return ok30({ action: "stats", element: JSON.parse(result) });
6966
7038
  }
6967
7039
  case "interact": {
6968
7040
  const query = p.query;
6969
7041
  const pAny = p;
6970
7042
  const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6971
7043
  const value = pAny.value;
6972
- if (!query) return fail14("interact \u9700\u8981 --query \u53C2\u6570");
6973
- if (!action) return fail14("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
7044
+ if (!query) return fail15("interact \u9700\u8981 --query \u53C2\u6570");
7045
+ if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6974
7046
  const findResult = await ctx.page.evaluate(
6975
7047
  `(function(){
6976
7048
  var map = window.__xbTagSerializable;
@@ -7000,11 +7072,11 @@ var visualTagV2Command = registerCommand({
7000
7072
  })()`
7001
7073
  );
7002
7074
  const parsed = JSON.parse(findResult);
7003
- if (parsed.err) return fail14(parsed.err);
7004
- if (!parsed.total || !parsed.results?.length) return fail14(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7075
+ if (parsed.err) return fail15(parsed.err);
7076
+ if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7005
7077
  const target = parsed.results[0];
7006
7078
  if (action === "read") {
7007
- return ok29({ action: "interact", query, target, result: { read: target.text || target.label } });
7079
+ return ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
7008
7080
  }
7009
7081
  if (action === "click") {
7010
7082
  const el = await ctx.page.evaluate(
@@ -7017,12 +7089,12 @@ var visualTagV2Command = registerCommand({
7017
7089
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7018
7090
  })()`
7019
7091
  );
7020
- if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7092
+ if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7021
7093
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7022
- return ok29({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7094
+ return ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7023
7095
  }
7024
7096
  if (action === "fill") {
7025
- if (!value) return fail14("fill \u9700\u8981 --value \u53C2\u6570");
7097
+ if (!value) return fail15("fill \u9700\u8981 --value \u53C2\u6570");
7026
7098
  const el = await ctx.page.evaluate(
7027
7099
  `(function(){
7028
7100
  var map = window.__xbTagMap;
@@ -7033,12 +7105,12 @@ var visualTagV2Command = registerCommand({
7033
7105
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7034
7106
  })()`
7035
7107
  );
7036
- if (!el) return fail14(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7108
+ if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7037
7109
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7038
7110
  await ctx.page.keyboard.type(value, { stealth: true });
7039
- return ok29({ action: "interact", query, target, result: { filled: true, value } });
7111
+ return ok30({ action: "interact", query, target, result: { filled: true, value } });
7040
7112
  }
7041
- return fail14(`\u672A\u77E5 action: ${action}`);
7113
+ return fail15(`\u672A\u77E5 action: ${action}`);
7042
7114
  }
7043
7115
  case "export": {
7044
7116
  const result = await ctx.page.evaluate(
@@ -7086,12 +7158,12 @@ var visualTagV2Command = registerCommand({
7086
7158
  })()`
7087
7159
  );
7088
7160
  const parsed = JSON.parse(result);
7089
- if (parsed.err) return fail14(String(parsed.err));
7090
- return ok29({ action: "export", element: parsed });
7161
+ if (parsed.err) return fail15(String(parsed.err));
7162
+ return ok30({ action: "export", element: parsed });
7091
7163
  }
7092
7164
  case "clear": {
7093
7165
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7094
- return ok29({ action: "clear" });
7166
+ return ok30({ action: "clear" });
7095
7167
  }
7096
7168
  }
7097
7169
  }
@@ -7617,8 +7689,8 @@ function classifyFailure(message) {
7617
7689
 
7618
7690
  // src/executor.ts
7619
7691
  import {
7620
- ok as ok30,
7621
- fail as fail15,
7692
+ ok as ok31,
7693
+ fail as fail16,
7622
7694
  isCommandResult,
7623
7695
  CompositeStorage as CompositeStorage2,
7624
7696
  TipCollector as TipCollector2,
@@ -8484,7 +8556,7 @@ async function guardCheck(commandName) {
8484
8556
  }
8485
8557
  }
8486
8558
  function errorResult(message) {
8487
- return { ...fail15(message), duration: 0 };
8559
+ return { ...fail16(message), duration: 0 };
8488
8560
  }
8489
8561
  function tipsToMessages(tips) {
8490
8562
  if (!tips || tips.length === 0) return [];
@@ -8760,7 +8832,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8760
8832
  timestamp: start
8761
8833
  });
8762
8834
  if (isSuccess) {
8763
- return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8835
+ return { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8764
8836
  }
8765
8837
  const fc = classifyFailure(raw.message);
8766
8838
  return {
@@ -8783,7 +8855,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8783
8855
  duration,
8784
8856
  timestamp: start
8785
8857
  });
8786
- return { ...ok30(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8858
+ return { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8787
8859
  } catch (err) {
8788
8860
  const end = Date.now();
8789
8861
  const duration = end - start;
@@ -8828,7 +8900,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8828
8900
  duration,
8829
8901
  timestamp: start
8830
8902
  });
8831
- return { ...fail15(errorMessage), duration };
8903
+ return { ...fail16(errorMessage), duration };
8832
8904
  } finally {
8833
8905
  }
8834
8906
  }
@@ -8873,7 +8945,7 @@ async function executeChain(input, options) {
8873
8945
  results.push({
8874
8946
  command: cmdName,
8875
8947
  raw: cmdStr,
8876
- ...fail15(`Plugin "${cmdName}" requires a sub-command`),
8948
+ ...fail16(`Plugin "${cmdName}" requires a sub-command`),
8877
8949
  duration: 0
8878
8950
  });
8879
8951
  if (type === "and") {
@@ -8892,7 +8964,7 @@ async function executeChain(input, options) {
8892
8964
  results.push({
8893
8965
  command: cmdName,
8894
8966
  raw: cmdStr,
8895
- ...fail15(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8967
+ ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8896
8968
  duration: 0
8897
8969
  });
8898
8970
  if (type === "and") {
@@ -9004,7 +9076,7 @@ async function executeChain(input, options) {
9004
9076
  results.push({
9005
9077
  command: `${cmdName} ${subCommand}`,
9006
9078
  raw: cmdStr,
9007
- ...ok30(data),
9079
+ ...ok31(data),
9008
9080
  duration: duration2,
9009
9081
  ...hookOutputs ? { hookOutputs } : {}
9010
9082
  });
@@ -9032,7 +9104,7 @@ async function executeChain(input, options) {
9032
9104
  results.push({
9033
9105
  command: `${cmdName} ${subCommand}`,
9034
9106
  raw: cmdStr,
9035
- ...fail15(errorMessage),
9107
+ ...fail16(errorMessage),
9036
9108
  duration: duration2
9037
9109
  });
9038
9110
  if (type === "and") {