@xbrowser/cli 1.21.0 → 1.23.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.
Files changed (43) hide show
  1. package/README.md +21 -3
  2. package/dist/{browser-CNBSH53B.js → browser-BVRFSUXU.js} +3 -2
  3. package/dist/{browser-C2VEOJC2.js → browser-DSYUAE7H.js} +5 -4
  4. package/dist/{browser-VZOOFLAH.js → browser-Q67BJTI2.js} +4 -3
  5. package/dist/{cdp-driver-KFX4A6WR.js → cdp-driver-DC7EIUG5.js} +4 -3
  6. package/dist/{cdp-driver-7Z6ZAT5E.js → cdp-driver-T7D6H2RW.js} +335 -546
  7. package/dist/{cdp-driver-26LGCHXV.js → cdp-driver-WWO2UZDR.js} +3 -2
  8. package/dist/{chunk-Z5RTK4GW.js → chunk-2Q3GQRUP.js} +2 -2
  9. package/dist/{chunk-CLYZPSDR.js → chunk-4OU37CXP.js} +354 -576
  10. package/dist/{chunk-HWWG2ISJ.js → chunk-7OP2ISEY.js} +353 -575
  11. package/dist/{chunk-PIWNMC36.js → chunk-A3MORKYR.js} +1 -1
  12. package/dist/{chunk-3FWLW7FS.js → chunk-A7NEA4PA.js} +39 -1
  13. package/dist/{chunk-OMU63E6J.js → chunk-FBQZ3PVD.js} +5 -8
  14. package/dist/chunk-GYB5BOSP.js +602 -0
  15. package/dist/{chunk-ESJYANQO.js → chunk-IFKJO2UR.js} +360 -582
  16. package/dist/{chunk-NODRQGOK.js → chunk-IR6C24P7.js} +97 -0
  17. package/dist/{chunk-TEXCXIBW.js → chunk-LPW6QS4M.js} +5 -8
  18. package/dist/{chunk-3KZ34AUC.js → chunk-MYH6FIBZ.js} +2 -1
  19. package/dist/{chunk-AVSTNODR.js → chunk-T4WTKBWI.js} +2 -2
  20. package/dist/{chunk-HBHOKZPN.js → chunk-V6KGBU5J.js} +97 -0
  21. package/dist/{chunk-IWVG4XYZ.js → chunk-VCVDILH6.js} +2 -1
  22. package/dist/{chunk-NKW4A74J.js → chunk-XTUAUFL3.js} +5 -8
  23. package/dist/cli.js +497 -252
  24. package/dist/daemon-main.js +25 -19
  25. package/dist/{human-interaction-Y5IDH6LD.js → human-interaction-57VYIR56.js} +1 -1
  26. package/dist/{human-interaction-ZUTR5AC2.js → human-interaction-67K43B4O.js} +1 -1
  27. package/dist/{human-interaction-4YR2N6R6.js → human-interaction-MXST5ZQM.js} +1 -1
  28. package/dist/index.d.ts +52 -4
  29. package/dist/index.js +500 -256
  30. package/dist/keep-awake-M4KJS4B4.js +29 -0
  31. package/dist/{launcher-44STYRJC.js → launcher-IK2FKW6T.js} +1 -1
  32. package/dist/{launcher-EXJHHAUL.js → launcher-LUOMMGZC.js} +1 -1
  33. package/dist/{plugin-singleton-FCNDN3FX.js → plugin-singleton-GJO7EZXB.js} +1 -1
  34. package/dist/{recovery-NXC35EQN.js → recovery-6RI2FE3E.js} +1 -1
  35. package/dist/{recovery-MDWAVXE4.js → recovery-LGY25LIM.js} +1 -1
  36. package/dist/{recovery-L5GLDX4O.js → recovery-LMJW537X.js} +1 -1
  37. package/dist/{session-recorder-SLDBENVF.js → session-recorder-563ISSJK.js} +1 -1
  38. package/dist/{session-recorder-3BEVWHOK.js → session-recorder-GEZVQBKW.js} +1 -1
  39. package/dist/session-replayer-N665T3G5.js +932 -0
  40. package/dist/stealth-2AA2FSNN.js +29 -0
  41. package/dist/stealth-JOXGV34D.js +29 -0
  42. package/package.json +11 -7
  43. package/dist/session-replayer-EVD4HZBB.js +0 -413
@@ -1,6 +1,10 @@
1
+ import {
2
+ detectAntiBot,
3
+ formatDetectionMessage
4
+ } from "./chunk-JKVUFP3G.js";
1
5
  import {
2
6
  getPluginLoader
3
- } from "./chunk-PIWNMC36.js";
7
+ } from "./chunk-A3MORKYR.js";
4
8
  import {
5
9
  version
6
10
  } from "./chunk-43TEMG4U.js";
@@ -19,7 +23,7 @@ import {
19
23
  } from "./chunk-VEDJ5XSQ.js";
20
24
  import {
21
25
  SessionRecorder
22
- } from "./chunk-HBHOKZPN.js";
26
+ } from "./chunk-V6KGBU5J.js";
23
27
  import {
24
28
  closeEphemeralContext,
25
29
  closeSessionByName,
@@ -34,24 +38,22 @@ import {
34
38
  resolveLaunchOpts,
35
39
  saveSessionDiskMeta,
36
40
  setActivePage
37
- } from "./chunk-AVSTNODR.js";
41
+ } from "./chunk-T4WTKBWI.js";
42
+ import {
43
+ createRuleEngine
44
+ } from "./chunk-4OU37CXP.js";
45
+ import {
46
+ queryJS
47
+ } from "./chunk-A7NEA4PA.js";
38
48
  import {
39
- createRuleEngine,
40
49
  rand,
41
50
  sleep,
42
51
  wheelDelta
43
- } from "./chunk-CLYZPSDR.js";
44
- import {
45
- queryJS
46
- } from "./chunk-3FWLW7FS.js";
47
- import "./chunk-3KZ34AUC.js";
52
+ } from "./chunk-GYB5BOSP.js";
53
+ import "./chunk-MYH6FIBZ.js";
48
54
  import {
49
55
  errMsg
50
56
  } from "./chunk-GDKLH7ZY.js";
51
- import {
52
- detectAntiBot,
53
- formatDetectionMessage
54
- } from "./chunk-JKVUFP3G.js";
55
57
  import "./chunk-KFQGP6VL.js";
56
58
 
57
59
  // src/daemon/daemon-main.ts
@@ -7766,7 +7768,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7766
7768
  }
7767
7769
  let targetPageOverride = null;
7768
7770
  if (_target && extraOpts?.cdpEndpoint) {
7769
- const { findTargetPage } = await import("./browser-C2VEOJC2.js");
7771
+ const { findTargetPage } = await import("./browser-DSYUAE7H.js");
7770
7772
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
7771
7773
  if (!targetPageOverride) {
7772
7774
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -7983,7 +7985,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
7983
7985
  const errorMessage = errMsg(err);
7984
7986
  if (session?.page && process.env.XBROWSER_RECOVERY && !extraOpts?._recoveryAttempted) {
7985
7987
  try {
7986
- const { attemptRecovery } = await import("./recovery-MDWAVXE4.js");
7988
+ const { attemptRecovery } = await import("./recovery-LGY25LIM.js");
7987
7989
  const recovery = await attemptRecovery(
7988
7990
  session.page,
7989
7991
  sessionName,
@@ -9023,7 +9025,7 @@ function createRPCHandler() {
9023
9025
  return result;
9024
9026
  } catch (err) {
9025
9027
  const errorMessage = errMsg(err);
9026
- const { attemptRecovery } = await import("./recovery-MDWAVXE4.js");
9028
+ const { attemptRecovery } = await import("./recovery-LGY25LIM.js");
9027
9029
  const recovery = await attemptRecovery(
9028
9030
  session?.page,
9029
9031
  sessionName,
@@ -9190,9 +9192,9 @@ function createRPCHandler() {
9190
9192
  return result;
9191
9193
  }
9192
9194
  async function handlePluginsReload() {
9193
- const { resetPluginLoader } = await import("./plugin-singleton-FCNDN3FX.js");
9195
+ const { resetPluginLoader } = await import("./plugin-singleton-GJO7EZXB.js");
9194
9196
  resetPluginLoader();
9195
- const loader = await import("./plugin-singleton-FCNDN3FX.js").then((m) => m.getPluginLoader());
9197
+ const loader = await import("./plugin-singleton-GJO7EZXB.js").then((m) => m.getPluginLoader());
9196
9198
  const sites = loader.getCore().loader.getSites();
9197
9199
  return { ok: true, plugins: sites.length };
9198
9200
  }
@@ -9588,7 +9590,7 @@ function createRPCHandler() {
9588
9590
  if (isNewFormat) {
9589
9591
  try {
9590
9592
  const replayErrors = [];
9591
- const { SessionReplayer } = await import("./session-replayer-EVD4HZBB.js");
9593
+ const { SessionReplayer } = await import("./session-replayer-N665T3G5.js");
9592
9594
  const replayer = new SessionReplayer({
9593
9595
  page: session.page,
9594
9596
  stepDelay: slowMo * 500,
@@ -9613,6 +9615,8 @@ function createRPCHandler() {
9613
9615
  duration,
9614
9616
  eventsPlayed: result2.success,
9615
9617
  totalEvents: result2.success + result2.failed + result2.skipped,
9618
+ healed: result2.healed,
9619
+ healedDetails: result2.healedDetails,
9616
9620
  errors: replayErrors
9617
9621
  });
9618
9622
  } catch (e) {
@@ -9645,6 +9649,8 @@ function createRPCHandler() {
9645
9649
  duration: typeof input.duration === "number" ? input.duration : 0,
9646
9650
  eventsPlayed,
9647
9651
  totalEvents,
9652
+ healed: typeof input.healed === "number" ? input.healed : 0,
9653
+ healedDetails: Array.isArray(input.healedDetails) ? input.healedDetails : [],
9648
9654
  errors
9649
9655
  };
9650
9656
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HumanInteractionManager
3
- } from "./chunk-NKW4A74J.js";
3
+ } from "./chunk-XTUAUFL3.js";
4
4
  import "./chunk-KFQGP6VL.js";
5
5
  export {
6
6
  HumanInteractionManager
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HumanInteractionManager
3
- } from "./chunk-TEXCXIBW.js";
3
+ } from "./chunk-LPW6QS4M.js";
4
4
  import "./chunk-ZTHE5RBZ.js";
5
5
  import "./chunk-KFQGP6VL.js";
6
6
  export {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HumanInteractionManager
3
- } from "./chunk-OMU63E6J.js";
3
+ } from "./chunk-FBQZ3PVD.js";
4
4
  import "./chunk-HBMEFSTB.js";
5
5
  import "./chunk-KFQGP6VL.js";
6
6
  export {
package/dist/index.d.ts CHANGED
@@ -137,6 +137,12 @@ interface XBContextOptions {
137
137
  ignoreHTTPSErrors?: boolean;
138
138
  /** S194: stealth 伪装配置(UA-CH 档案等)——经 context 传至 page 的注入层 */
139
139
  stealthConfig?: Partial<StealthConfig>;
140
+ /** sup-s9: HTTP Basic/Digest 凭证——Fetch.authRequired 自动 ProvideCredentials;
141
+ * 缺省 CancelAuth(快速失败,不弹认证框不挂起) */
142
+ httpCredentials?: {
143
+ username: string;
144
+ password: string;
145
+ };
140
146
  }
141
147
  interface XBContext {
142
148
  newPage(): Promise<XBPage>;
@@ -270,6 +276,8 @@ interface XBPage {
270
276
  width: number;
271
277
  height: number;
272
278
  }): Promise<void>;
279
+ /** env-E2: 缩放变异——deviceScaleFactor 切换(CSS 视口尺寸不变) */
280
+ setDeviceScaleFactor(dsf: number): Promise<void>;
273
281
  addInitScript(script: string): Promise<void>;
274
282
  /** 覆盖当前页会话的 User-Agent(Network.setUserAgentOverride,会话级持久) */
275
283
  setUserAgent(userAgent: string): Promise<void>;
@@ -286,6 +294,10 @@ interface XBPage {
286
294
  route(url: string | RegExp, handler: (route: XBRoute) => Promise<void> | void): Promise<void>;
287
295
  unroute(url: string | RegExp, handler?: (route: XBRoute) => Promise<void> | void): Promise<void>;
288
296
  setInputFiles(selector: string, files: XBFilePayload | XBFilePayload[]): Promise<void>;
297
+ /** sup-s4: Dropzone 拖拽上传模拟——DataTransfer+File 派发 dragenter/dragover/drop */
298
+ dropFiles(selector: string, payload: XBFilePayload): Promise<void>;
299
+ /** sup-s11: beforeunload 自动应答语义(accept=离开默认 / dismiss=留守) */
300
+ setBeforeUnloadBehavior(mode: 'accept' | 'dismiss'): void;
289
301
  dragAndDrop(source: string, target: string): Promise<void>;
290
302
  on(event: string, handler: Function): void;
291
303
  off(event: string, handler: Function): void;
@@ -1136,7 +1148,7 @@ interface DetectionConfig {
1136
1148
  * along with optional `waitForHuman` (CAPTCHA handling) and
1137
1149
  * `detectAntiBot` (anti-bot detection) capabilities.
1138
1150
  */
1139
- interface BrowserCommandContext extends CommandContext {
1151
+ interface BrowserCommandContext extends Omit<CommandContext, 'waitForHuman' | 'detectAntiBot' | 'page'> {
1140
1152
  page: XBPage;
1141
1153
  browser: XBBrowser;
1142
1154
  browserContext: XBContext;
@@ -1853,7 +1865,7 @@ interface HoverContext {
1853
1865
  }
1854
1866
  interface UserAction {
1855
1867
  id: number;
1856
- type: 'click' | 'input' | 'change' | 'keydown' | 'submit' | 'scroll' | 'navigation' | 'goto' | 'cdp-fill' | 'cdp-click' | 'cdp-eval' | 'filechooser' | 'dblclick' | 'contextmenu' | 'hover' | 'drag' | 'resize' | 'clipboard' | 'touch' | 'focus' | 'visibility' | 'popup_appear' | 'discovered_filters';
1868
+ type: 'click' | 'input' | 'change' | 'keydown' | 'submit' | 'scroll' | 'navigation' | 'goto' | 'cdp-fill' | 'cdp-click' | 'cdp-eval' | 'filechooser' | 'dblclick' | 'contextmenu' | 'hover' | 'drag' | 'resize' | 'clipboard' | 'touch' | 'focus' | 'visibility' | 'drop' | 'popup_appear' | 'discovered_filters';
1857
1869
  timestamp: number;
1858
1870
  url: string;
1859
1871
  pageTitle: string;
@@ -1877,6 +1889,24 @@ interface UserAction {
1877
1889
  placeholder?: string;
1878
1890
  ariaLabel?: string;
1879
1891
  href?: string;
1892
+ /** 结构地址(r6):祖先 form 在同级 form 中的序 + 元素在 form 内同 tag
1893
+ * 兄弟中的序(仅 form 直接子元素捕获)。布局位移后坐标失效时仍可定位。 */
1894
+ ordinal?: {
1895
+ formNth: number;
1896
+ tagNth: number;
1897
+ };
1898
+ /** 关联 label 的文本(r16):for= 关联或祖先 label 包裹。行重排/虚拟
1899
+ * 列表重建后结构序失效时的内容锚。 */
1900
+ labelText?: string;
1901
+ /** 元素尺寸(r25):录制时 rounded rect。同指纹诱饵消歧的评分信号
1902
+ * (仅加分不否决——响应式布局合法改变尺寸)。 */
1903
+ size?: {
1904
+ w: number;
1905
+ h: number;
1906
+ };
1907
+ /** 所在行文本(r27):closest('tr,li') 的 textContent 前 40 字符。
1908
+ * 表格/列表行重排后结构序失效时的内容锚(label 锚的行推广)。 */
1909
+ rowText?: string;
1880
1910
  };
1881
1911
  value?: string;
1882
1912
  key?: string;
@@ -2277,6 +2307,12 @@ interface PlaybackResult {
2277
2307
  event?: RecordedEvent;
2278
2308
  error: string;
2279
2309
  }>;
2310
+ /** r13: 自愈步数与明细(SessionReplayer 路径填充) */
2311
+ healed?: number;
2312
+ healedDetails?: Array<{
2313
+ index: number;
2314
+ strategy: string;
2315
+ }>;
2280
2316
  }
2281
2317
  /**
2282
2318
  * Engine for playing back a recorded browser session.
@@ -2908,26 +2944,38 @@ interface HTTPServerConfig {
2908
2944
  port?: number;
2909
2945
  host?: string;
2910
2946
  tokens?: string[];
2947
+ /**
2948
+ * Explicit CORS origin allowlist for remote web clients (e.g.
2949
+ * `['https://app.example']`, or `['*']` to opt back into wildcard).
2950
+ * When omitted, only loopback browser origins are granted CORS.
2951
+ */
2952
+ corsOrigins?: string[];
2911
2953
  }
2912
2954
 
2913
2955
  /**
2914
2956
  * HTTP server exposing the xbrowser REST API for remote command execution.
2915
2957
  *
2916
2958
  * Provides endpoints for health checks, session management, single command
2917
- * execution, and command chain execution. Supports optional Bearer token
2959
+ * execution, and command chain execution. Supports Bearer token
2918
2960
  * authentication via config or environment variable.
2961
+ *
2962
+ * Secure defaults: binds loopback (127.0.0.1) only, and grants CORS only
2963
+ * to loopback browser origins. Binding a non-loopback host requires a
2964
+ * token — `start()` refuses otherwise.
2919
2965
  */
2920
2966
  declare class HTTPServer {
2921
2967
  private port;
2922
2968
  private host;
2923
2969
  private server;
2924
2970
  private validTokens;
2971
+ private corsOrigins;
2925
2972
  constructor(config?: HTTPServerConfig);
2926
2973
  /**
2927
2974
  * Start the HTTP server and begin listening for requests.
2928
2975
  *
2929
2976
  * @returns The actual port and host the server bound to.
2930
- * @throws If the server is already running or fails to start.
2977
+ * @throws If the server is already running, if binding a non-loopback
2978
+ * host without an auth token, or if the port cannot be bound.
2931
2979
  */
2932
2980
  start(): Promise<{
2933
2981
  port: number;