@tangle-network/browser-agent-driver 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +196 -0
- package/README.md +149 -0
- package/dist/artifacts/composite-sink.d.ts +15 -0
- package/dist/artifacts/composite-sink.d.ts.map +1 -0
- package/dist/artifacts/composite-sink.js +27 -0
- package/dist/artifacts/composite-sink.js.map +1 -0
- package/dist/artifacts/filesystem-sink.d.ts +26 -0
- package/dist/artifacts/filesystem-sink.d.ts.map +1 -0
- package/dist/artifacts/filesystem-sink.js +81 -0
- package/dist/artifacts/filesystem-sink.js.map +1 -0
- package/dist/artifacts/types.d.ts +97 -0
- package/dist/artifacts/types.d.ts.map +1 -0
- package/dist/artifacts/types.js +9 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/webhook-sink.d.ts +71 -0
- package/dist/artifacts/webhook-sink.d.ts.map +1 -0
- package/dist/artifacts/webhook-sink.js +117 -0
- package/dist/artifacts/webhook-sink.js.map +1 -0
- package/dist/brain/index.d.ts +149 -0
- package/dist/brain/index.d.ts.map +1 -0
- package/dist/brain/index.js +1030 -0
- package/dist/brain/index.js.map +1 -0
- package/dist/browser-launch.d.ts +27 -0
- package/dist/browser-launch.d.ts.map +1 -0
- package/dist/browser-launch.js +92 -0
- package/dist/browser-launch.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1035 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +143 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +205 -0
- package/dist/config.js.map +1 -0
- package/dist/context-budget.d.ts +14 -0
- package/dist/context-budget.d.ts.map +1 -0
- package/dist/context-budget.js +39 -0
- package/dist/context-budget.js.map +1 -0
- package/dist/design-audit.d.ts +48 -0
- package/dist/design-audit.d.ts.map +1 -0
- package/dist/design-audit.js +172 -0
- package/dist/design-audit.js.map +1 -0
- package/dist/domain-policy.d.ts +4 -0
- package/dist/domain-policy.d.ts.map +1 -0
- package/dist/domain-policy.js +69 -0
- package/dist/domain-policy.js.map +1 -0
- package/dist/drivers/block-patterns.d.ts +11 -0
- package/dist/drivers/block-patterns.d.ts.map +1 -0
- package/dist/drivers/block-patterns.js +123 -0
- package/dist/drivers/block-patterns.js.map +1 -0
- package/dist/drivers/cdp-page-state.d.ts +22 -0
- package/dist/drivers/cdp-page-state.d.ts.map +1 -0
- package/dist/drivers/cdp-page-state.js +38 -0
- package/dist/drivers/cdp-page-state.js.map +1 -0
- package/dist/drivers/cdp-snapshot.d.ts +32 -0
- package/dist/drivers/cdp-snapshot.d.ts.map +1 -0
- package/dist/drivers/cdp-snapshot.js +120 -0
- package/dist/drivers/cdp-snapshot.js.map +1 -0
- package/dist/drivers/playwright.d.ts +84 -0
- package/dist/drivers/playwright.d.ts.map +1 -0
- package/dist/drivers/playwright.js +385 -0
- package/dist/drivers/playwright.js.map +1 -0
- package/dist/drivers/snapshot.d.ts +134 -0
- package/dist/drivers/snapshot.d.ts.map +1 -0
- package/dist/drivers/snapshot.js +354 -0
- package/dist/drivers/snapshot.js.map +1 -0
- package/dist/drivers/types.d.ts +37 -0
- package/dist/drivers/types.d.ts.map +1 -0
- package/dist/drivers/types.js +5 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/env-loader.d.ts +2 -0
- package/dist/env-loader.d.ts.map +1 -0
- package/dist/env-loader.js +35 -0
- package/dist/env-loader.js.map +1 -0
- package/dist/formatters/slack.d.ts +37 -0
- package/dist/formatters/slack.d.ts.map +1 -0
- package/dist/formatters/slack.js +97 -0
- package/dist/formatters/slack.js.map +1 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/analyzer.d.ts +67 -0
- package/dist/memory/analyzer.d.ts.map +1 -0
- package/dist/memory/analyzer.js +265 -0
- package/dist/memory/analyzer.js.map +1 -0
- package/dist/memory/knowledge.d.ts +55 -0
- package/dist/memory/knowledge.d.ts.map +1 -0
- package/dist/memory/knowledge.js +115 -0
- package/dist/memory/knowledge.js.map +1 -0
- package/dist/memory/project-store.d.ts +43 -0
- package/dist/memory/project-store.d.ts.map +1 -0
- package/dist/memory/project-store.js +119 -0
- package/dist/memory/project-store.js.map +1 -0
- package/dist/memory/selectors.d.ts +46 -0
- package/dist/memory/selectors.d.ts.map +1 -0
- package/dist/memory/selectors.js +89 -0
- package/dist/memory/selectors.js.map +1 -0
- package/dist/memory/store.d.ts +39 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +193 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/model-pricing.d.ts +41 -0
- package/dist/model-pricing.d.ts.map +1 -0
- package/dist/model-pricing.js +197 -0
- package/dist/model-pricing.js.map +1 -0
- package/dist/multi-actor.d.ts +108 -0
- package/dist/multi-actor.d.ts.map +1 -0
- package/dist/multi-actor.js +192 -0
- package/dist/multi-actor.js.map +1 -0
- package/dist/override-pipeline.d.ts +57 -0
- package/dist/override-pipeline.d.ts.map +1 -0
- package/dist/override-pipeline.js +26 -0
- package/dist/override-pipeline.js.map +1 -0
- package/dist/personas.d.ts +19 -0
- package/dist/personas.d.ts.map +1 -0
- package/dist/personas.js +86 -0
- package/dist/personas.js.map +1 -0
- package/dist/preview.d.ts +32 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +138 -0
- package/dist/preview.js.map +1 -0
- package/dist/provider-defaults.d.ts +6 -0
- package/dist/provider-defaults.d.ts.map +1 -0
- package/dist/provider-defaults.js +40 -0
- package/dist/provider-defaults.js.map +1 -0
- package/dist/providers/sandbox-backend.d.ts +22 -0
- package/dist/providers/sandbox-backend.d.ts.map +1 -0
- package/dist/providers/sandbox-backend.js +259 -0
- package/dist/providers/sandbox-backend.js.map +1 -0
- package/dist/recovery.d.ts +91 -0
- package/dist/recovery.d.ts.map +1 -0
- package/dist/recovery.js +500 -0
- package/dist/recovery.js.map +1 -0
- package/dist/reporters/junit.d.ts +8 -0
- package/dist/reporters/junit.d.ts.map +1 -0
- package/dist/reporters/junit.js +99 -0
- package/dist/reporters/junit.js.map +1 -0
- package/dist/run-metrics.d.ts +4 -0
- package/dist/run-metrics.d.ts.map +1 -0
- package/dist/run-metrics.js +48 -0
- package/dist/run-metrics.js.map +1 -0
- package/dist/run-state.d.ts +22 -0
- package/dist/run-state.d.ts.map +1 -0
- package/dist/run-state.js +33 -0
- package/dist/run-state.js.map +1 -0
- package/dist/runner/goal-verification.d.ts +13 -0
- package/dist/runner/goal-verification.d.ts.map +1 -0
- package/dist/runner/goal-verification.js +152 -0
- package/dist/runner/goal-verification.js.map +1 -0
- package/dist/runner/index.d.ts +12 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +18 -0
- package/dist/runner/index.js.map +1 -0
- package/dist/runner/overrides.d.ts +75 -0
- package/dist/runner/overrides.d.ts.map +1 -0
- package/dist/runner/overrides.js +385 -0
- package/dist/runner/overrides.js.map +1 -0
- package/dist/runner/page-analysis.d.ts +23 -0
- package/dist/runner/page-analysis.d.ts.map +1 -0
- package/dist/runner/page-analysis.js +91 -0
- package/dist/runner/page-analysis.js.map +1 -0
- package/dist/runner/runner.d.ts +66 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +1314 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/scout.d.ts +29 -0
- package/dist/runner/scout.d.ts.map +1 -0
- package/dist/runner/scout.js +81 -0
- package/dist/runner/scout.js.map +1 -0
- package/dist/runner/search-guidance.d.ts +31 -0
- package/dist/runner/search-guidance.d.ts.map +1 -0
- package/dist/runner/search-guidance.js +210 -0
- package/dist/runner/search-guidance.js.map +1 -0
- package/dist/runner/utils.d.ts +28 -0
- package/dist/runner/utils.d.ts.map +1 -0
- package/dist/runner/utils.js +119 -0
- package/dist/runner/utils.js.map +1 -0
- package/dist/runner.d.ts +8 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +21 -0
- package/dist/runner.js.map +1 -0
- package/dist/supervisor/critic.d.ts +29 -0
- package/dist/supervisor/critic.d.ts.map +1 -0
- package/dist/supervisor/critic.js +320 -0
- package/dist/supervisor/critic.js.map +1 -0
- package/dist/supervisor/policy.d.ts +11 -0
- package/dist/supervisor/policy.d.ts.map +1 -0
- package/dist/supervisor/policy.js +118 -0
- package/dist/supervisor/policy.js.map +1 -0
- package/dist/test-report.d.ts +15 -0
- package/dist/test-report.d.ts.map +1 -0
- package/dist/test-report.js +241 -0
- package/dist/test-report.js.map +1 -0
- package/dist/test-runner.d.ts +99 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +1075 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/types.d.ts +493 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/wallet/automation.d.ts +52 -0
- package/dist/wallet/automation.d.ts.map +1 -0
- package/dist/wallet/automation.js +507 -0
- package/dist/wallet/automation.js.map +1 -0
- package/package.json +101 -0
- package/scripts/postinstall-provider-patches.mjs +52 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright driver — accessibility tree + screenshot observation
|
|
3
|
+
* with ref-based element resolution and full browser action vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* Uses AriaSnapshotHelper for consistent a11y tree snapshots across all drivers.
|
|
6
|
+
* Optionally uses CDP (Chrome DevTools Protocol) for faster observe() calls:
|
|
7
|
+
* - Accessibility.getFullAXTree instead of ariaSnapshot() (no YAML serialize→parse)
|
|
8
|
+
* - Runtime.evaluate for batched page metadata (URL + title + testids in one call)
|
|
9
|
+
* - No 1-second hard sleep (uses lifecycle events only)
|
|
10
|
+
*/
|
|
11
|
+
import type { Page } from 'playwright';
|
|
12
|
+
import type { Driver, ActionResult, ResourceBlockingOptions } from './types.js';
|
|
13
|
+
import type { Action, PageState } from '../types.js';
|
|
14
|
+
/** Phase-level timing breakdown for observe() */
|
|
15
|
+
export interface ObserveTiming {
|
|
16
|
+
/** Total observe() time in ms */
|
|
17
|
+
totalMs: number;
|
|
18
|
+
/** Time waiting for page load state */
|
|
19
|
+
waitForLoadMs: number;
|
|
20
|
+
/** Time building accessibility tree snapshot */
|
|
21
|
+
snapshotMs: number;
|
|
22
|
+
/** Time getting page metadata (URL, title, testids) */
|
|
23
|
+
metadataMs: number;
|
|
24
|
+
/** Time capturing screenshot (0 if disabled) */
|
|
25
|
+
screenshotMs: number;
|
|
26
|
+
/** Whether CDP fast-path was used */
|
|
27
|
+
usedCdp: boolean;
|
|
28
|
+
/** Size of snapshot in characters */
|
|
29
|
+
snapshotSize: number;
|
|
30
|
+
/** Number of refs in snapshot */
|
|
31
|
+
refCount: number;
|
|
32
|
+
}
|
|
33
|
+
export interface PlaywrightDriverOptions {
|
|
34
|
+
/** Action timeout in ms */
|
|
35
|
+
timeout?: number;
|
|
36
|
+
/** Capture screenshots on each observe (default: true for vision) */
|
|
37
|
+
captureScreenshots?: boolean;
|
|
38
|
+
/** Screenshot quality (1-100, default 50) */
|
|
39
|
+
screenshotQuality?: number;
|
|
40
|
+
/** Disable CDP fast-path (fall back to Playwright for everything) */
|
|
41
|
+
disableCdp?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare class PlaywrightDriver implements Driver {
|
|
44
|
+
private page;
|
|
45
|
+
private options;
|
|
46
|
+
private snapshot;
|
|
47
|
+
private cdpSession;
|
|
48
|
+
private cdpFailed;
|
|
49
|
+
private lastTiming;
|
|
50
|
+
constructor(page: Page, options?: PlaywrightDriverOptions);
|
|
51
|
+
/** Get phase-level timing from the last observe() call */
|
|
52
|
+
getLastTiming(): ObserveTiming | undefined;
|
|
53
|
+
getPage(): Page;
|
|
54
|
+
inspectSelectorHref(selector: string): Promise<string | undefined>;
|
|
55
|
+
private adoptPage;
|
|
56
|
+
/**
|
|
57
|
+
* Set up resource blocking to speed up page loads by aborting unnecessary requests.
|
|
58
|
+
* Call before first navigation for best results.
|
|
59
|
+
*/
|
|
60
|
+
setupResourceBlocking(options: ResourceBlockingOptions): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Lazy-init a CDP session. Returns null if CDP is unavailable
|
|
63
|
+
* (non-Chromium browser) or if a previous attempt failed.
|
|
64
|
+
*/
|
|
65
|
+
private ensureCdpSession;
|
|
66
|
+
observe(): Promise<PageState>;
|
|
67
|
+
/**
|
|
68
|
+
* Fast CDP observation path — no 1s sleep, batched calls.
|
|
69
|
+
*/
|
|
70
|
+
private observeCdp;
|
|
71
|
+
/**
|
|
72
|
+
* Original Playwright observation path — used as fallback when CDP is unavailable.
|
|
73
|
+
*/
|
|
74
|
+
private observePlaywright;
|
|
75
|
+
screenshot(): Promise<Buffer>;
|
|
76
|
+
close(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Execute an action first. If it fails and a blocking overlay is detected,
|
|
79
|
+
* dismiss it and retry once.
|
|
80
|
+
*/
|
|
81
|
+
private withOverlayRecovery;
|
|
82
|
+
execute(action: Action): Promise<ActionResult>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=playwright.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUrD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,gBAAiB,YAAW,MAAM;IAO3C,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IAPjB,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA4B;gBAGpC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,uBAA4B;IAG/C,0DAA0D;IAC1D,aAAa,IAAI,aAAa,GAAG,SAAS;IAI1C,OAAO,IAAI,IAAI;IAIT,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAS1D,SAAS;IAWvB;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuC5E;;;OAGG;YACW,gBAAgB;IAcxB,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;IAuCnC;;OAEG;YACW,UAAU;IA0DxB;;OAEG;YACW,iBAAiB;IAuCzB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;OAGG;YACW,mBAAmB;IAU3B,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAsIrD"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright driver — accessibility tree + screenshot observation
|
|
3
|
+
* with ref-based element resolution and full browser action vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* Uses AriaSnapshotHelper for consistent a11y tree snapshots across all drivers.
|
|
6
|
+
* Optionally uses CDP (Chrome DevTools Protocol) for faster observe() calls:
|
|
7
|
+
* - Accessibility.getFullAXTree instead of ariaSnapshot() (no YAML serialize→parse)
|
|
8
|
+
* - Runtime.evaluate for batched page metadata (URL + title + testids in one call)
|
|
9
|
+
* - No 1-second hard sleep (uses lifecycle events only)
|
|
10
|
+
*/
|
|
11
|
+
import { AriaSnapshotHelper, dismissOverlays } from './snapshot.js';
|
|
12
|
+
import { ANALYTICS_PATTERNS, IMAGE_PATTERNS, MEDIA_PATTERNS } from './block-patterns.js';
|
|
13
|
+
import { buildCdpSnapshot } from './cdp-snapshot.js';
|
|
14
|
+
import { getPageMetadata } from './cdp-page-state.js';
|
|
15
|
+
function isPointerInterceptError(error) {
|
|
16
|
+
return /intercepts pointer events|subtree intercepts pointer events|not receiving pointer events/i.test(error);
|
|
17
|
+
}
|
|
18
|
+
export class PlaywrightDriver {
|
|
19
|
+
page;
|
|
20
|
+
options;
|
|
21
|
+
snapshot = new AriaSnapshotHelper();
|
|
22
|
+
cdpSession = null;
|
|
23
|
+
cdpFailed = false;
|
|
24
|
+
lastTiming;
|
|
25
|
+
constructor(page, options = {}) {
|
|
26
|
+
this.page = page;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
/** Get phase-level timing from the last observe() call */
|
|
30
|
+
getLastTiming() {
|
|
31
|
+
return this.lastTiming;
|
|
32
|
+
}
|
|
33
|
+
getPage() {
|
|
34
|
+
return this.page;
|
|
35
|
+
}
|
|
36
|
+
async inspectSelectorHref(selector) {
|
|
37
|
+
const locator = this.snapshot.resolveLocator(this.page, selector);
|
|
38
|
+
return locator.evaluate((node) => {
|
|
39
|
+
const element = node;
|
|
40
|
+
const anchor = element?.closest('a[href]');
|
|
41
|
+
return anchor?.href || undefined;
|
|
42
|
+
}).catch(() => undefined);
|
|
43
|
+
}
|
|
44
|
+
async adoptPage(nextPage) {
|
|
45
|
+
if (this.page === nextPage)
|
|
46
|
+
return;
|
|
47
|
+
if (this.cdpSession) {
|
|
48
|
+
await this.cdpSession.detach().catch(() => { });
|
|
49
|
+
}
|
|
50
|
+
this.page = nextPage;
|
|
51
|
+
this.cdpSession = null;
|
|
52
|
+
this.cdpFailed = false;
|
|
53
|
+
this.snapshot.reset();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Set up resource blocking to speed up page loads by aborting unnecessary requests.
|
|
57
|
+
* Call before first navigation for best results.
|
|
58
|
+
*/
|
|
59
|
+
async setupResourceBlocking(options) {
|
|
60
|
+
const urlPatterns = [];
|
|
61
|
+
if (options.blockImages)
|
|
62
|
+
urlPatterns.push(...IMAGE_PATTERNS);
|
|
63
|
+
if (options.blockMedia)
|
|
64
|
+
urlPatterns.push(...MEDIA_PATTERNS);
|
|
65
|
+
if (options.blockAnalytics)
|
|
66
|
+
urlPatterns.push(...ANALYTICS_PATTERNS);
|
|
67
|
+
if (options.blockPatterns)
|
|
68
|
+
urlPatterns.push(...options.blockPatterns);
|
|
69
|
+
if (urlPatterns.length === 0)
|
|
70
|
+
return;
|
|
71
|
+
const blockImages = options.blockImages ?? false;
|
|
72
|
+
const blockMedia = options.blockMedia ?? false;
|
|
73
|
+
await this.page.route('**/*', async (route) => {
|
|
74
|
+
const url = route.request().url();
|
|
75
|
+
const type = route.request().resourceType();
|
|
76
|
+
// Fast path: check resource type
|
|
77
|
+
if (blockImages && type === 'image') {
|
|
78
|
+
await route.abort();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (blockMedia && type === 'media') {
|
|
82
|
+
await route.abort();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// URL pattern matching
|
|
86
|
+
for (const pattern of urlPatterns) {
|
|
87
|
+
if (url.includes(pattern)) {
|
|
88
|
+
await route.abort();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
await route.continue();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Lazy-init a CDP session. Returns null if CDP is unavailable
|
|
97
|
+
* (non-Chromium browser) or if a previous attempt failed.
|
|
98
|
+
*/
|
|
99
|
+
async ensureCdpSession() {
|
|
100
|
+
if (this.options.disableCdp || this.cdpFailed)
|
|
101
|
+
return null;
|
|
102
|
+
if (this.cdpSession)
|
|
103
|
+
return this.cdpSession;
|
|
104
|
+
try {
|
|
105
|
+
this.cdpSession = await this.page.context().newCDPSession(this.page);
|
|
106
|
+
return this.cdpSession;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Non-Chromium browser or CDP not available
|
|
110
|
+
this.cdpFailed = true;
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async observe() {
|
|
115
|
+
const observeStart = performance.now();
|
|
116
|
+
const captureScreenshot = this.options.captureScreenshots ?? true;
|
|
117
|
+
const quality = this.options.screenshotQuality ?? 50;
|
|
118
|
+
const waitStart = performance.now();
|
|
119
|
+
// Cap load state wait at 10s — heavy JS sites (AliExpress) can stall
|
|
120
|
+
// domcontentloaded for 30s+. The page usually has usable DOM much earlier.
|
|
121
|
+
await Promise.race([
|
|
122
|
+
this.page.waitForLoadState('domcontentloaded').catch(() => { }),
|
|
123
|
+
new Promise(resolve => setTimeout(resolve, 10_000)),
|
|
124
|
+
]);
|
|
125
|
+
const waitForLoadMs = performance.now() - waitStart;
|
|
126
|
+
this.snapshot.reset();
|
|
127
|
+
const cdp = await this.ensureCdpSession();
|
|
128
|
+
if (cdp) {
|
|
129
|
+
try {
|
|
130
|
+
const result = await this.observeCdp(cdp, captureScreenshot, quality);
|
|
131
|
+
this.lastTiming.waitForLoadMs = waitForLoadMs;
|
|
132
|
+
this.lastTiming.totalMs = performance.now() - observeStart;
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// CDP call failed — detach and fall back to Playwright for this turn
|
|
137
|
+
this.cdpSession = null;
|
|
138
|
+
this.cdpFailed = false; // Allow retry next turn (transient failure)
|
|
139
|
+
this.snapshot.reset(); // Reset refs since CDP partially populated them
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Fallback: original Playwright path (with 1s sleep)
|
|
143
|
+
const result = await this.observePlaywright(captureScreenshot, quality);
|
|
144
|
+
this.lastTiming.waitForLoadMs = waitForLoadMs;
|
|
145
|
+
this.lastTiming.totalMs = performance.now() - observeStart;
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Fast CDP observation path — no 1s sleep, batched calls.
|
|
150
|
+
*/
|
|
151
|
+
async observeCdp(cdp, captureScreenshot, quality) {
|
|
152
|
+
// Parallel: get page metadata + build AX tree snapshot
|
|
153
|
+
const snapshotStart = performance.now();
|
|
154
|
+
const [metadata, cdpResult] = await Promise.all([
|
|
155
|
+
getPageMetadata(cdp),
|
|
156
|
+
buildCdpSnapshot(cdp),
|
|
157
|
+
]);
|
|
158
|
+
const snapshotMs = performance.now() - snapshotStart;
|
|
159
|
+
// Import refs into the snapshot helper (for resolveLocator + getDiff)
|
|
160
|
+
this.snapshot.importCdpRefs(cdpResult.refMap, cdpResult.elements);
|
|
161
|
+
// Append testid selectors to snapshot (same as Playwright path)
|
|
162
|
+
let snapshotText = cdpResult.snapshot;
|
|
163
|
+
if (metadata.testIds.length > 0) {
|
|
164
|
+
snapshotText += '\n\nDATA-TESTID SELECTORS (use [data-testid="..."] as selector):';
|
|
165
|
+
for (const el of metadata.testIds) {
|
|
166
|
+
const disabled = el.disabled ? ' [disabled]' : '';
|
|
167
|
+
const text = el.text ? ` "${el.text}"` : '';
|
|
168
|
+
snapshotText += `\n [data-testid="${el.testId}"] ${el.tag}${text}${disabled}`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Screenshot still via Playwright (viewport compositing)
|
|
172
|
+
const ssStart = performance.now();
|
|
173
|
+
let screenshot;
|
|
174
|
+
if (captureScreenshot) {
|
|
175
|
+
const buf = await this.page.screenshot({ type: 'jpeg', quality });
|
|
176
|
+
screenshot = buf.toString('base64');
|
|
177
|
+
}
|
|
178
|
+
const screenshotMs = performance.now() - ssStart;
|
|
179
|
+
const snapshotDiff = this.snapshot.getDiff();
|
|
180
|
+
this.lastTiming = {
|
|
181
|
+
totalMs: 0, // filled by observe()
|
|
182
|
+
waitForLoadMs: 0, // filled by observe()
|
|
183
|
+
snapshotMs,
|
|
184
|
+
metadataMs: snapshotMs, // metadata fetched in parallel with snapshot
|
|
185
|
+
screenshotMs,
|
|
186
|
+
usedCdp: true,
|
|
187
|
+
snapshotSize: snapshotText.length,
|
|
188
|
+
refCount: cdpResult.refMap.size,
|
|
189
|
+
};
|
|
190
|
+
return {
|
|
191
|
+
url: metadata.url,
|
|
192
|
+
title: metadata.title,
|
|
193
|
+
snapshot: snapshotText,
|
|
194
|
+
screenshot,
|
|
195
|
+
snapshotDiff,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Original Playwright observation path — used as fallback when CDP is unavailable.
|
|
200
|
+
*/
|
|
201
|
+
async observePlaywright(captureScreenshot, quality) {
|
|
202
|
+
await this.page.waitForTimeout(1000);
|
|
203
|
+
const snapshotStart = performance.now();
|
|
204
|
+
const [url, title, snapshotText] = await Promise.all([
|
|
205
|
+
this.page.url(),
|
|
206
|
+
this.page.title(),
|
|
207
|
+
this.snapshot.buildSnapshot(this.page),
|
|
208
|
+
]);
|
|
209
|
+
const snapshotMs = performance.now() - snapshotStart;
|
|
210
|
+
const ssStart = performance.now();
|
|
211
|
+
let screenshot;
|
|
212
|
+
if (captureScreenshot) {
|
|
213
|
+
const buf = await this.page.screenshot({ type: 'jpeg', quality });
|
|
214
|
+
screenshot = buf.toString('base64');
|
|
215
|
+
}
|
|
216
|
+
const screenshotMs = performance.now() - ssStart;
|
|
217
|
+
const snapshotDiff = this.snapshot.getDiff();
|
|
218
|
+
const refMatches = snapshotText.match(/\[ref=\w+\]/g);
|
|
219
|
+
this.lastTiming = {
|
|
220
|
+
totalMs: 0, // filled by observe()
|
|
221
|
+
waitForLoadMs: 0, // filled by observe()
|
|
222
|
+
snapshotMs,
|
|
223
|
+
metadataMs: snapshotMs, // metadata fetched in parallel with snapshot
|
|
224
|
+
screenshotMs,
|
|
225
|
+
usedCdp: false,
|
|
226
|
+
snapshotSize: snapshotText.length,
|
|
227
|
+
refCount: refMatches?.length ?? 0,
|
|
228
|
+
};
|
|
229
|
+
return { url, title, snapshot: snapshotText, screenshot, snapshotDiff };
|
|
230
|
+
}
|
|
231
|
+
async screenshot() {
|
|
232
|
+
return this.page.screenshot({ type: 'jpeg', quality: this.options.screenshotQuality ?? 70 });
|
|
233
|
+
}
|
|
234
|
+
async close() {
|
|
235
|
+
if (this.cdpSession) {
|
|
236
|
+
await this.cdpSession.detach().catch(() => { });
|
|
237
|
+
this.cdpSession = null;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Execute an action first. If it fails and a blocking overlay is detected,
|
|
242
|
+
* dismiss it and retry once.
|
|
243
|
+
*/
|
|
244
|
+
async withOverlayRecovery(operation) {
|
|
245
|
+
try {
|
|
246
|
+
return await operation();
|
|
247
|
+
}
|
|
248
|
+
catch (firstError) {
|
|
249
|
+
const dismissed = await dismissOverlays(this.page);
|
|
250
|
+
if (!dismissed)
|
|
251
|
+
throw firstError;
|
|
252
|
+
return operation();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async execute(action) {
|
|
256
|
+
const timeout = this.options.timeout ?? 30000;
|
|
257
|
+
try {
|
|
258
|
+
switch (action.action) {
|
|
259
|
+
case 'click': {
|
|
260
|
+
const locator = this.snapshot.resolveLocator(this.page, action.selector);
|
|
261
|
+
const popupPromise = this.page.context()
|
|
262
|
+
.waitForEvent('page', { timeout: Math.min(timeout, 2_000) })
|
|
263
|
+
.catch(() => null);
|
|
264
|
+
try {
|
|
265
|
+
await this.withOverlayRecovery(async () => {
|
|
266
|
+
await locator.click({ timeout });
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
271
|
+
if (!isPointerInterceptError(message))
|
|
272
|
+
throw err;
|
|
273
|
+
// Fallback for sticky overlays/sidebars that still intercept pointer events.
|
|
274
|
+
await locator.click({ timeout, force: true });
|
|
275
|
+
}
|
|
276
|
+
const popupPage = await popupPromise;
|
|
277
|
+
if (popupPage && !popupPage.isClosed()) {
|
|
278
|
+
await popupPage.waitForLoadState('domcontentloaded').catch(() => { });
|
|
279
|
+
await this.adoptPage(popupPage);
|
|
280
|
+
}
|
|
281
|
+
return { success: true };
|
|
282
|
+
}
|
|
283
|
+
case 'type': {
|
|
284
|
+
const locator = this.snapshot.resolveLocator(this.page, action.selector);
|
|
285
|
+
try {
|
|
286
|
+
await this.withOverlayRecovery(async () => {
|
|
287
|
+
await locator.click({ timeout });
|
|
288
|
+
await locator.fill(action.text, { timeout });
|
|
289
|
+
await locator.evaluate((el) => {
|
|
290
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
291
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
297
|
+
if (!isPointerInterceptError(message))
|
|
298
|
+
throw err;
|
|
299
|
+
await locator.click({ timeout, force: true });
|
|
300
|
+
await locator.fill(action.text, { timeout });
|
|
301
|
+
await locator.evaluate((el) => {
|
|
302
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
303
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return { success: true };
|
|
307
|
+
}
|
|
308
|
+
case 'press': {
|
|
309
|
+
const locator = this.snapshot.resolveLocator(this.page, action.selector);
|
|
310
|
+
await this.withOverlayRecovery(async () => {
|
|
311
|
+
await locator.press(action.key, { timeout });
|
|
312
|
+
});
|
|
313
|
+
return { success: true };
|
|
314
|
+
}
|
|
315
|
+
case 'hover': {
|
|
316
|
+
const locator = this.snapshot.resolveLocator(this.page, action.selector);
|
|
317
|
+
await locator.hover({ timeout });
|
|
318
|
+
return { success: true };
|
|
319
|
+
}
|
|
320
|
+
case 'select': {
|
|
321
|
+
const locator = this.snapshot.resolveLocator(this.page, action.selector);
|
|
322
|
+
await locator.selectOption(action.value, { timeout });
|
|
323
|
+
return { success: true };
|
|
324
|
+
}
|
|
325
|
+
case 'scroll': {
|
|
326
|
+
const delta = action.direction === 'down'
|
|
327
|
+
? (action.amount ?? 500)
|
|
328
|
+
: -(action.amount ?? 500);
|
|
329
|
+
if (action.selector) {
|
|
330
|
+
// Scroll a specific container element
|
|
331
|
+
const container = this.snapshot.resolveLocator(this.page, action.selector);
|
|
332
|
+
await container.evaluate((el, d) => { el.scrollBy(0, d); }, delta);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
await this.page.mouse.wheel(0, delta);
|
|
336
|
+
}
|
|
337
|
+
return { success: true };
|
|
338
|
+
}
|
|
339
|
+
case 'navigate': {
|
|
340
|
+
// Cap navigation at 15s — heavy JS sites (AliExpress, etc.) can stall domcontentloaded
|
|
341
|
+
// for 40s+. Better to proceed with partial DOM than timeout the whole case.
|
|
342
|
+
const navTimeout = Math.min(timeout, 15_000);
|
|
343
|
+
try {
|
|
344
|
+
await this.page.goto(action.url, { timeout: navTimeout, waitUntil: 'domcontentloaded' });
|
|
345
|
+
}
|
|
346
|
+
catch (navErr) {
|
|
347
|
+
// If domcontentloaded timed out but the page has started loading,
|
|
348
|
+
// proceed — the agent can still interact with whatever is in the DOM.
|
|
349
|
+
const currentUrl = this.page.url();
|
|
350
|
+
if (currentUrl !== 'about:blank' && currentUrl !== '') {
|
|
351
|
+
// Page partially loaded — continue with what we have
|
|
352
|
+
return { success: true };
|
|
353
|
+
}
|
|
354
|
+
throw navErr;
|
|
355
|
+
}
|
|
356
|
+
return { success: true };
|
|
357
|
+
}
|
|
358
|
+
case 'wait':
|
|
359
|
+
await this.page.waitForTimeout(action.ms);
|
|
360
|
+
return { success: true };
|
|
361
|
+
case 'runScript': {
|
|
362
|
+
const scriptResult = await this.page.evaluate(action.script);
|
|
363
|
+
const stringified = typeof scriptResult === 'string'
|
|
364
|
+
? scriptResult
|
|
365
|
+
: JSON.stringify(scriptResult, null, 2);
|
|
366
|
+
return { success: true, error: undefined, data: stringified };
|
|
367
|
+
}
|
|
368
|
+
case 'evaluate':
|
|
369
|
+
case 'verifyPreview':
|
|
370
|
+
// Handled by the runner — the driver just acknowledges it.
|
|
371
|
+
return { success: true };
|
|
372
|
+
case 'complete':
|
|
373
|
+
case 'abort':
|
|
374
|
+
return { success: true };
|
|
375
|
+
default:
|
|
376
|
+
return { success: false, error: `Unknown action: ${action.action}` };
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch (err) {
|
|
380
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
381
|
+
return { success: false, error };
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=playwright.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../../src/drivers/playwright.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared accessibility tree snapshot helper.
|
|
3
|
+
*
|
|
4
|
+
* Uses Playwright's `locator.ariaSnapshot()` to produce a YAML-like tree,
|
|
5
|
+
* assigns STABLE ref IDs to interactive elements (deterministic hash of
|
|
6
|
+
* role+name), and resolves @ref selectors back to Playwright locators via
|
|
7
|
+
* getByRole().
|
|
8
|
+
*
|
|
9
|
+
* Stable refs mean the same element (e.g. button "Send") gets the SAME ref ID
|
|
10
|
+
* across observations. Only elements that truly disappear produce invalid refs.
|
|
11
|
+
* Duplicates (multiple elements with same role+name) get index suffixes.
|
|
12
|
+
*
|
|
13
|
+
* Used by PlaywrightDriver.
|
|
14
|
+
*/
|
|
15
|
+
import type { Page, Locator } from 'playwright';
|
|
16
|
+
/** Parsed element with value for diffing */
|
|
17
|
+
export interface ParsedElement {
|
|
18
|
+
ref: string;
|
|
19
|
+
role: string;
|
|
20
|
+
name: string;
|
|
21
|
+
value?: string;
|
|
22
|
+
}
|
|
23
|
+
/** Structured diff between two snapshots */
|
|
24
|
+
export interface SnapshotDiff {
|
|
25
|
+
added: string[];
|
|
26
|
+
removed: string[];
|
|
27
|
+
changed: string[];
|
|
28
|
+
unchangedCount: number;
|
|
29
|
+
}
|
|
30
|
+
export declare const INTERACTIVE_ROLES: Set<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Generate a short deterministic hash from role+name.
|
|
33
|
+
* Produces a 3-4 char hex string (e.g. "b3f", "1a2c").
|
|
34
|
+
*/
|
|
35
|
+
export declare function stableHash(role: string, name: string): string;
|
|
36
|
+
export declare class AriaSnapshotHelper {
|
|
37
|
+
private refMap;
|
|
38
|
+
/** Track how many times each base hash has been seen (for duplicate disambiguation) */
|
|
39
|
+
private hashCounts;
|
|
40
|
+
/** Previous snapshot's parsed elements for diffing */
|
|
41
|
+
private prevElements;
|
|
42
|
+
/** Current snapshot's parsed elements (populated during parseAriaSnapshot) */
|
|
43
|
+
private currElements;
|
|
44
|
+
/** Last computed diff (undefined on first observe) */
|
|
45
|
+
private lastDiff;
|
|
46
|
+
/** Clear refs -- call at the start of each observe() cycle */
|
|
47
|
+
reset(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Import refs and elements from an external source (e.g., CDP snapshot).
|
|
50
|
+
*
|
|
51
|
+
* Populates the internal refMap and currElements so that resolveLocator()
|
|
52
|
+
* and getDiff() work identically to the Playwright ariaSnapshot path.
|
|
53
|
+
*/
|
|
54
|
+
importCdpRefs(refMap: Map<string, {
|
|
55
|
+
role: string;
|
|
56
|
+
name: string;
|
|
57
|
+
}>, elements: Map<string, ParsedElement>): void;
|
|
58
|
+
/**
|
|
59
|
+
* Build an accessibility tree snapshot with stable ref IDs.
|
|
60
|
+
*
|
|
61
|
+
* Calls `page.locator('body').ariaSnapshot()` and parses the YAML output,
|
|
62
|
+
* assigning deterministic `[ref=XX]` to interactive/named elements.
|
|
63
|
+
*/
|
|
64
|
+
buildSnapshot(page: Page): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Resolve a selector to a Playwright Locator.
|
|
67
|
+
*
|
|
68
|
+
* - `@b3f` -> resolved from ref map via getByRole()
|
|
69
|
+
* - Standard selectors (CSS, text=, role=, [data-testid=...]) -> page.locator()
|
|
70
|
+
*/
|
|
71
|
+
resolveLocator(page: Page, selector: string): Locator;
|
|
72
|
+
/**
|
|
73
|
+
* Parse Playwright's ARIA snapshot YAML and assign stable ref IDs.
|
|
74
|
+
*
|
|
75
|
+
* Ref IDs are deterministic hashes of role+name, so the same element gets
|
|
76
|
+
* the same ref across observations. Duplicates get index suffixes (_1, _2).
|
|
77
|
+
*
|
|
78
|
+
* Input:
|
|
79
|
+
* - button "Sign in"
|
|
80
|
+
* - textbox "Email" [value=""]
|
|
81
|
+
* - list "Nav":
|
|
82
|
+
* - link "Home"
|
|
83
|
+
*
|
|
84
|
+
* Output:
|
|
85
|
+
* - button "Sign in" [ref=b2a1]
|
|
86
|
+
* - textbox "Email" [ref=t3f0] [value=""]
|
|
87
|
+
* - list "Nav" [ref=l1b2]:
|
|
88
|
+
* - link "Home" [ref=la3c]
|
|
89
|
+
*/
|
|
90
|
+
private parseAriaSnapshot;
|
|
91
|
+
/**
|
|
92
|
+
* Get the diff from the last buildSnapshot() call.
|
|
93
|
+
* Returns undefined on the first call (no previous snapshot to diff against).
|
|
94
|
+
*/
|
|
95
|
+
getDiff(): string | undefined;
|
|
96
|
+
/** Get the raw structured diff (for programmatic use) */
|
|
97
|
+
getRawDiff(): SnapshotDiff | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Format a snapshot in compact form: one line per element, ref-first,
|
|
100
|
+
* flat (no nesting), ~50-60% fewer tokens.
|
|
101
|
+
*
|
|
102
|
+
* Full format:
|
|
103
|
+
* - button "Sign in" [ref=b2a1]
|
|
104
|
+
* - textbox "Email" [ref=t3f0] [value=""]
|
|
105
|
+
* - list "Nav" [ref=l1b2]:
|
|
106
|
+
* - link "Home" [ref=la3c]
|
|
107
|
+
*
|
|
108
|
+
* Compact format:
|
|
109
|
+
* @b2a1 button "Sign in"
|
|
110
|
+
* @t3f0 textbox "Email" val=""
|
|
111
|
+
* @l1b2 list "Nav"
|
|
112
|
+
* @la3c link "Home"
|
|
113
|
+
*/
|
|
114
|
+
static formatCompact(snapshot: string): string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Typed error for stale ref detection -- allows runner to catch specifically
|
|
118
|
+
* and auto-retry with a fresh observation.
|
|
119
|
+
*/
|
|
120
|
+
export declare class StaleRefError extends Error {
|
|
121
|
+
readonly staleRef: string;
|
|
122
|
+
readonly availableRefs: string[];
|
|
123
|
+
constructor(staleRef: string, availableRefs: string[]);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Dismiss blocking overlays (dialogs, modals, Vite errors).
|
|
127
|
+
* Shared between drivers that operate on a Playwright page.
|
|
128
|
+
*
|
|
129
|
+
* Returns 'clicked' if a close button was found and clicked,
|
|
130
|
+
* 'found' if an overlay exists but no close button was found (Escape pressed),
|
|
131
|
+
* or false if no overlay was detected.
|
|
132
|
+
*/
|
|
133
|
+
export declare function dismissOverlays(page: Page): Promise<'clicked' | 'found' | false>;
|
|
134
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/drivers/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAOhD,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAqCD,eAAO,MAAM,iBAAiB,aAK5B,CAAC;AAEH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAA+B;IAC7C,uFAAuF;IACvF,OAAO,CAAC,UAAU,CAA6B;IAE/C,sDAAsD;IACtD,OAAO,CAAC,YAAY,CAAoC;IACxD,8EAA8E;IAC9E,OAAO,CAAC,YAAY,CAAoC;IACxD,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAA2B;IAE3C,8DAA8D;IAC9D,KAAK,IAAI,IAAI;IAKb;;;;;OAKG;IACH,aAAa,CACX,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EACnD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GACnC,IAAI;IAkBP;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IA+ChD;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IA6BrD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,iBAAiB;IA8CzB;;;OAGG;IACH,OAAO,IAAI,MAAM,GAAG,SAAS;IAK7B,yDAAyD;IACzD,UAAU,IAAI,YAAY,GAAG,SAAS;IAItC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAgB/C;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;gBAErB,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE;CAUtD;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,OAAO,GAAG,KAAK,CAAC,CAsCtF"}
|