@xbrowser/cli 1.9.8 → 1.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{anti-bot-MCVM6IFB.js → anti-bot-DR56Y63V.js} +1 -1
- package/dist/{browser-GT4BMX6X.js → browser-FFYPFTBV.js} +1 -1
- package/dist/{browser-43YXUIML.js → browser-RHWUAMTB.js} +2 -2
- package/dist/{browser-SJWPJFN7.js → browser-YCO4GJMZ.js} +2 -2
- package/dist/{cdp-driver-WAFYSIIW.js → cdp-driver-2T4P4ZE2.js} +87 -1
- package/dist/{cdp-driver-PUZLDSQU.js → cdp-driver-J3YQ4LJV.js} +1 -1
- package/dist/chunk-3OD76SUE.js +20 -0
- package/dist/chunk-43TEMG4U.js +9 -0
- package/dist/{chunk-C3LIGO4V.js → chunk-4452SPFI.js} +906 -16
- package/dist/{chunk-VEWTHYDG.js → chunk-5UGR6MUK.js} +906 -16
- package/dist/{chunk-ENCEMM7Z.js → chunk-6OZWKXSW.js} +15 -16
- package/dist/{chunk-7ZDWM6T2.js → chunk-BNO7OKO4.js} +5 -6
- package/dist/{chunk-24SY6PE5.js → chunk-CG3D3CHY.js} +1 -8
- package/dist/{chunk-ZJHQPMCY.js → chunk-DWDXEGVK.js} +5 -6
- package/dist/{chunk-A4YHJW3Z.js → chunk-GUTBIYFW.js} +101 -16
- package/dist/{chunk-DPJNCMLC.js → chunk-INTQPBYF.js} +7 -0
- package/dist/{human-interaction-OU7LZ6OZ.js → chunk-MWFHZUIY.js} +6 -7
- package/dist/chunk-Q2DFJQGS.js +128 -0
- package/dist/{chunk-GM3HWQ5U.js → chunk-RRBXV7KE.js} +87 -1
- package/dist/{chunk-PBDID7SE.js → chunk-RZM5CNIY.js} +15 -16
- package/dist/{human-interaction-HJTXFVQS.js → chunk-SQHSZENE.js} +2 -2
- package/dist/chunk-TZPKFUBT.js +20 -0
- package/dist/{chunk-YAUG3NSI.js → chunk-YMUSHPU4.js} +16 -128
- package/dist/cli.js +41 -28
- package/dist/{daemon-client-4HJENICO.js → daemon-client-GKEPT4NY.js} +15 -3
- package/dist/{daemon-client-CMRAWXTN.js → daemon-client-O6BYVRXV.js} +4 -1
- package/dist/daemon-main.js +635 -57
- package/dist/human-interaction-5AO42MBA.js +8 -0
- package/dist/{human-interaction-2DZK4MW7.js → human-interaction-C5OEGXGO.js} +1 -1
- package/dist/human-interaction-ISXZTAYY.js +8 -0
- package/dist/index.d.ts +167 -2
- package/dist/index.js +173 -63
- package/dist/recovery-EF33LKRJ.js +77 -0
- package/dist/recovery-J2ISVGUL.js +77 -0
- package/dist/recovery-ZJVVHP7N.js +76 -0
- package/dist/{session-recorder-K3K63Q33.js → session-recorder-H3KEYU26.js} +1 -1
- package/dist/{session-recorder-AG6CH6EI.js → session-recorder-QRZMKFVL.js} +1 -1
- package/dist/{session-replayer-V4MP6M6I.js → session-replayer-LJUC4TI7.js} +24 -7
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -348,7 +348,7 @@ interface XBFillOptions {
|
|
|
348
348
|
noWaitAfter?: boolean;
|
|
349
349
|
}
|
|
350
350
|
interface XBScreenshotOptions {
|
|
351
|
-
type?: 'png' | 'jpeg';
|
|
351
|
+
type?: 'png' | 'jpeg' | 'webp';
|
|
352
352
|
quality?: number;
|
|
353
353
|
fullPage?: boolean;
|
|
354
354
|
clip?: {
|
|
@@ -490,6 +490,16 @@ type WSMessage = {
|
|
|
490
490
|
} | {
|
|
491
491
|
type: 'views_update';
|
|
492
492
|
views: ViewInfo[];
|
|
493
|
+
} | {
|
|
494
|
+
type: 'health_pong';
|
|
495
|
+
ts: number;
|
|
496
|
+
} | {
|
|
497
|
+
type: 'snapshot_result';
|
|
498
|
+
data: {
|
|
499
|
+
data: string;
|
|
500
|
+
format: string;
|
|
501
|
+
} | null;
|
|
502
|
+
error?: string;
|
|
493
503
|
} | {
|
|
494
504
|
type: 'error';
|
|
495
505
|
data: {
|
|
@@ -528,6 +538,15 @@ type WSInboundMessage = {
|
|
|
528
538
|
deltaY: number;
|
|
529
539
|
} | {
|
|
530
540
|
type: 'solved';
|
|
541
|
+
} | {
|
|
542
|
+
type: 'reconnect';
|
|
543
|
+
} | {
|
|
544
|
+
type: 'health_ping';
|
|
545
|
+
ts: number;
|
|
546
|
+
} | {
|
|
547
|
+
type: 'snapshot_request';
|
|
548
|
+
format?: string;
|
|
549
|
+
quality?: number;
|
|
531
550
|
} | {
|
|
532
551
|
type: 'bind';
|
|
533
552
|
sessionId: string;
|
|
@@ -649,6 +668,8 @@ declare class WSServer extends EventEmitter {
|
|
|
649
668
|
width?: number;
|
|
650
669
|
height?: number;
|
|
651
670
|
}): void;
|
|
671
|
+
/** Restart screencast for a session — used by viewer reconnect button. */
|
|
672
|
+
reconnectSession(sessionId: string): Promise<void>;
|
|
652
673
|
unregisterSession(sessionId: string): void;
|
|
653
674
|
pauseScreencast(sessionId: string): Promise<void>;
|
|
654
675
|
resumeScreencast(sessionId: string): Promise<void>;
|
|
@@ -738,6 +759,7 @@ declare function executeCommand(commandName: string, params: Record<string, unkn
|
|
|
738
759
|
cdpEndpoint?: string;
|
|
739
760
|
skipCleanup?: boolean;
|
|
740
761
|
timeout?: number;
|
|
762
|
+
_recoveryAttempted?: boolean;
|
|
741
763
|
}): Promise<ExecutionResult>;
|
|
742
764
|
/**
|
|
743
765
|
* Execute a chain of browser commands parsed from a string expression.
|
|
@@ -1648,6 +1670,8 @@ interface ClickContextItem {
|
|
|
1648
1670
|
tag?: string;
|
|
1649
1671
|
disabled?: boolean;
|
|
1650
1672
|
href?: string;
|
|
1673
|
+
/** Selector of this item, used for replay and AI-driven clicks. */
|
|
1674
|
+
selector?: string;
|
|
1651
1675
|
}
|
|
1652
1676
|
interface ClickContextElement {
|
|
1653
1677
|
tag: string;
|
|
@@ -1677,9 +1701,42 @@ interface ClickContext {
|
|
|
1677
1701
|
disappeared: unknown[];
|
|
1678
1702
|
stateChanges: ClickContextStateChange[];
|
|
1679
1703
|
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Popup/tooltip/dropdown that appears after a hover action.
|
|
1706
|
+
*
|
|
1707
|
+
* Captured via async sampling (200/500/1000ms after `mouseover`) plus a
|
|
1708
|
+
* short-lived MutationObserver. Each entry records the container that popped
|
|
1709
|
+
* up and the visible menu items inside it, so that replay and AI inspection
|
|
1710
|
+
* can correlate the hover trigger with the options that became available.
|
|
1711
|
+
*/
|
|
1712
|
+
interface HoverPopupInfo {
|
|
1713
|
+
tag: string;
|
|
1714
|
+
selector: string;
|
|
1715
|
+
role?: string;
|
|
1716
|
+
text: string;
|
|
1717
|
+
rect: {
|
|
1718
|
+
x: number;
|
|
1719
|
+
y: number;
|
|
1720
|
+
w: number;
|
|
1721
|
+
h: number;
|
|
1722
|
+
};
|
|
1723
|
+
/** Visible menu items (up to 20) — text + selector for replay targeting. */
|
|
1724
|
+
items: ClickContextItem[];
|
|
1725
|
+
}
|
|
1726
|
+
interface HoverContext {
|
|
1727
|
+
/** Popups that appeared after the hover trigger. */
|
|
1728
|
+
appeared: HoverPopupInfo[];
|
|
1729
|
+
/** Popups that disappeared while the hover was active. */
|
|
1730
|
+
disappeared: Array<{
|
|
1731
|
+
selector: string;
|
|
1732
|
+
reason: string;
|
|
1733
|
+
}>;
|
|
1734
|
+
/** Trigger element's aria-expanded / aria-haspopup state changes. */
|
|
1735
|
+
stateChanges: ClickContextStateChange[];
|
|
1736
|
+
}
|
|
1680
1737
|
interface UserAction {
|
|
1681
1738
|
id: number;
|
|
1682
|
-
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';
|
|
1739
|
+
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';
|
|
1683
1740
|
timestamp: number;
|
|
1684
1741
|
url: string;
|
|
1685
1742
|
pageTitle: string;
|
|
@@ -1711,6 +1768,8 @@ interface UserAction {
|
|
|
1711
1768
|
scrollX?: number;
|
|
1712
1769
|
scrollY?: number;
|
|
1713
1770
|
clickContext?: ClickContext;
|
|
1771
|
+
/** Popups/tooltip/dropdown observed after a `hover` action (analog of clickContext). */
|
|
1772
|
+
hoverContext?: HoverContext;
|
|
1714
1773
|
files?: {
|
|
1715
1774
|
names: string[];
|
|
1716
1775
|
count: number;
|
|
@@ -1770,6 +1829,50 @@ interface UserAction {
|
|
|
1770
1829
|
};
|
|
1771
1830
|
/** Base64-encoded PNG screenshot of the target element (captured on key actions) */
|
|
1772
1831
|
elementScreenshot?: string;
|
|
1832
|
+
/**
|
|
1833
|
+
* Auto-captured snapshot for this action (key types only).
|
|
1834
|
+
* PNG stored in .tmp/snapshots/ (easy to clean up);
|
|
1835
|
+
* aria tree stored inline as compact text (searchable via grep).
|
|
1836
|
+
*/
|
|
1837
|
+
snapshots?: {
|
|
1838
|
+
/** Viewport screenshot path (relative, under .tmp/snapshots/) */
|
|
1839
|
+
png?: string;
|
|
1840
|
+
/** Compact accessibility tree text (inline, grep-able) */
|
|
1841
|
+
aria?: string;
|
|
1842
|
+
};
|
|
1843
|
+
/** For type='popup_appear' — proactive sensing of a popover/dropdown/menu
|
|
1844
|
+
* becoming visible (whether triggered by user hover/click, or auto-shown). */
|
|
1845
|
+
popupAppear?: {
|
|
1846
|
+
/** The trigger element that caused the popup (if known) */
|
|
1847
|
+
trigger?: {
|
|
1848
|
+
selector: string;
|
|
1849
|
+
text: string;
|
|
1850
|
+
};
|
|
1851
|
+
/** The popup container */
|
|
1852
|
+
popup: {
|
|
1853
|
+
selector: string;
|
|
1854
|
+
text: string;
|
|
1855
|
+
rect: {
|
|
1856
|
+
x: number;
|
|
1857
|
+
y: number;
|
|
1858
|
+
w: number;
|
|
1859
|
+
h: number;
|
|
1860
|
+
};
|
|
1861
|
+
/** Menu items inside the popup */
|
|
1862
|
+
items: Array<{
|
|
1863
|
+
text: string;
|
|
1864
|
+
selector: string;
|
|
1865
|
+
disabled?: boolean;
|
|
1866
|
+
}>;
|
|
1867
|
+
};
|
|
1868
|
+
/** What caused the popup to appear */
|
|
1869
|
+
cause: 'user-hover' | 'user-click' | 'auto' | 'script';
|
|
1870
|
+
/** True if a real user action triggered it (false for auto-shown popups) */
|
|
1871
|
+
userTriggered: boolean;
|
|
1872
|
+
};
|
|
1873
|
+
/** For type='discovered_filters' — proactive baseline scan of the page.
|
|
1874
|
+
* Pushed on start and after navigation; merged into RecordingData.discoveredFilters. */
|
|
1875
|
+
discoveredFilters?: DiscoveredFilter[];
|
|
1773
1876
|
}
|
|
1774
1877
|
interface NetworkEntry {
|
|
1775
1878
|
id: number;
|
|
@@ -1843,6 +1946,32 @@ interface CheckpointEntry {
|
|
|
1843
1946
|
relatedActionId?: number;
|
|
1844
1947
|
context?: Record<string, unknown>;
|
|
1845
1948
|
}
|
|
1949
|
+
interface DiscoveredTrigger {
|
|
1950
|
+
/** Selector for replay/AI targeting */
|
|
1951
|
+
selector: string;
|
|
1952
|
+
/** Text label (e.g. "新发布", "综合", "价格") */
|
|
1953
|
+
text: string;
|
|
1954
|
+
/** Semantic role, if any */
|
|
1955
|
+
role?: string;
|
|
1956
|
+
/** Category — helps AI understand what this trigger does */
|
|
1957
|
+
category: 'sort' | 'filter' | 'tab' | 'menu' | 'navigation' | 'unknown';
|
|
1958
|
+
/** Set to true once we observe a popup appearing for this trigger */
|
|
1959
|
+
hasPopup: boolean;
|
|
1960
|
+
/** Set to true when the user actually clicks or hovers it */
|
|
1961
|
+
userInteracted: boolean;
|
|
1962
|
+
/** Set to true when the mouse lingered on it (>800ms) without clicking */
|
|
1963
|
+
explored: boolean;
|
|
1964
|
+
}
|
|
1965
|
+
interface DiscoveredFilter {
|
|
1966
|
+
/** Container element selector (the surrounding bar/region) */
|
|
1967
|
+
containerSelector: string;
|
|
1968
|
+
/** Container category */
|
|
1969
|
+
category: 'sort' | 'filter' | 'tab' | 'menu' | 'navigation';
|
|
1970
|
+
/** Container text (first 60 chars, for AI context) */
|
|
1971
|
+
containerText: string;
|
|
1972
|
+
/** Triggers found inside this container */
|
|
1973
|
+
triggers: DiscoveredTrigger[];
|
|
1974
|
+
}
|
|
1846
1975
|
interface RecordingData {
|
|
1847
1976
|
startUrl: string;
|
|
1848
1977
|
sessionName: string;
|
|
@@ -1851,6 +1980,9 @@ interface RecordingData {
|
|
|
1851
1980
|
network: NetworkEntry[];
|
|
1852
1981
|
contextChanges: ContextChange[];
|
|
1853
1982
|
checkpoints: CheckpointEntry[];
|
|
1983
|
+
/** Proactive baseline scan of filter/sort/tab/menu regions on the page.
|
|
1984
|
+
* Populated on start and after navigation; updated as popups are observed. */
|
|
1985
|
+
discoveredFilters?: DiscoveredFilter[];
|
|
1854
1986
|
}
|
|
1855
1987
|
interface RecordingControlFile {
|
|
1856
1988
|
pid: number;
|
|
@@ -1869,6 +2001,9 @@ declare class SessionRecorder {
|
|
|
1869
2001
|
private network;
|
|
1870
2002
|
private contextChanges;
|
|
1871
2003
|
private checkpoints;
|
|
2004
|
+
/** Proactive baseline scan of filter/sort/tab/menu regions. Keyed by
|
|
2005
|
+
* containerSelector so re-scans after navigation replace rather than dup. */
|
|
2006
|
+
private discoveredFilters;
|
|
1872
2007
|
private actionCounter;
|
|
1873
2008
|
private networkCounter;
|
|
1874
2009
|
private contextCounter;
|
|
@@ -1887,6 +2022,9 @@ declare class SessionRecorder {
|
|
|
1887
2022
|
private _lastRequestTs;
|
|
1888
2023
|
private _isRecording;
|
|
1889
2024
|
private streamMode;
|
|
2025
|
+
/** Snapshot throttle: prevents too many screenshots during rapid inputs.
|
|
2026
|
+
* Keyed by 'type|elementSelector', value = last snapshot timestamp. */
|
|
2027
|
+
private snapshotThrottle;
|
|
1890
2028
|
/** Ambient action types: filtered out in clean mode */
|
|
1891
2029
|
private static readonly AMBIENT_TYPES;
|
|
1892
2030
|
constructor(context: XBContext, page: XBPage, sessionName: string);
|
|
@@ -1907,6 +2045,8 @@ declare class SessionRecorder {
|
|
|
1907
2045
|
addManualCheckpoint(type: string, hint: string, selector?: string): CheckpointEntry;
|
|
1908
2046
|
/** Directory for this session's recordings. */
|
|
1909
2047
|
get recordingsDir(): string;
|
|
2048
|
+
/** Directory for auto-captured snapshots (PNG screenshots, stored in .tmp for easy cleanup). */
|
|
2049
|
+
get snapshotsDir(): string;
|
|
1910
2050
|
static getRecordingsDir(sessionName: string): string;
|
|
1911
2051
|
/** Path to the control file (used by record stop to signal this process). */
|
|
1912
2052
|
get controlFilePath(): string;
|
|
@@ -1924,6 +2064,12 @@ declare class SessionRecorder {
|
|
|
1924
2064
|
static sendStopSignal(sessionName: string): Promise<RecordingControlFile | null>;
|
|
1925
2065
|
static readSummary(sessionName: string): RecordingSummary | null;
|
|
1926
2066
|
static readData(sessionName: string): RecordingData | null;
|
|
2067
|
+
/** Whether the initial action-signal script injection succeeded. Check this
|
|
2068
|
+
* after start() returns — if false, user actions will NOT be recorded and
|
|
2069
|
+
* the caller should surface a clear error to the user instead of silently
|
|
2070
|
+
* pretending recording is working. */
|
|
2071
|
+
private _injectionFailed;
|
|
2072
|
+
get injectionFailed(): boolean;
|
|
1927
2073
|
private injectActionScript;
|
|
1928
2074
|
private handleRequest;
|
|
1929
2075
|
private handleResponse;
|
|
@@ -1946,6 +2092,25 @@ declare class SessionRecorder {
|
|
|
1946
2092
|
* 3. fallback to viewport screenshot (so we always get *something*)
|
|
1947
2093
|
*/
|
|
1948
2094
|
private captureElementScreenshot;
|
|
2095
|
+
/**
|
|
2096
|
+
* Action types that trigger auto-snapshot capture.
|
|
2097
|
+
* Hover is excluded — it's too noisy and rarely changes the page visually.
|
|
2098
|
+
* Popup_appear captures the popup state (after only).
|
|
2099
|
+
*/
|
|
2100
|
+
private static readonly SNAPSHOT_TYPES;
|
|
2101
|
+
/**
|
|
2102
|
+
* Throttle key for snapshot capture to avoid too many during rapid inputs.
|
|
2103
|
+
* Returns true if this action should be throttled (skip snapshot).
|
|
2104
|
+
*/
|
|
2105
|
+
private isSnapshotThrottled;
|
|
2106
|
+
/**
|
|
2107
|
+
* Capture a viewport screenshot + compact accessibility tree for a key action.
|
|
2108
|
+
* - PNG stored in .tmp/snapshots/ (temporary, easy to clean up)
|
|
2109
|
+
* - aria tree stored inline as compact text on the action (searchable via grep)
|
|
2110
|
+
*
|
|
2111
|
+
* Non-blocking (errors silently caught). Throttled for rapid inputs.
|
|
2112
|
+
*/
|
|
2113
|
+
private captureAutoSnapshot;
|
|
1949
2114
|
/**
|
|
1950
2115
|
* After a click, wait 300ms then scan for popover/dropdown/menu elements
|
|
1951
2116
|
* near the click position. This runs server-side to avoid race conditions
|