@ap3x/browser 0.1.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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -0
  3. package/dist/cdp/connection.d.ts +53 -0
  4. package/dist/cdp/connection.d.ts.map +1 -0
  5. package/dist/cdp/endpoint.d.ts +18 -0
  6. package/dist/cdp/endpoint.d.ts.map +1 -0
  7. package/dist/cdp/reconnect.d.ts +22 -0
  8. package/dist/cdp/reconnect.d.ts.map +1 -0
  9. package/dist/chunk-DXCP25KX.js +77 -0
  10. package/dist/config.d.ts +91 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/dialogs/handler.d.ts +43 -0
  13. package/dist/dialogs/handler.d.ts.map +1 -0
  14. package/dist/dom/clickability.d.ts +4 -0
  15. package/dist/dom/clickability.d.ts.map +1 -0
  16. package/dist/dom/compound.d.ts +4 -0
  17. package/dist/dom/compound.d.ts.map +1 -0
  18. package/dist/dom/constants.d.ts +28 -0
  19. package/dist/dom/constants.d.ts.map +1 -0
  20. package/dist/dom/dom-service.d.ts +65 -0
  21. package/dist/dom/dom-service.d.ts.map +1 -0
  22. package/dist/dom/enhanced-tree.d.ts +52 -0
  23. package/dist/dom/enhanced-tree.d.ts.map +1 -0
  24. package/dist/dom/hashing.d.ts +21 -0
  25. package/dist/dom/hashing.d.ts.map +1 -0
  26. package/dist/dom/node.d.ts +43 -0
  27. package/dist/dom/node.d.ts.map +1 -0
  28. package/dist/dom/overlay.d.ts +11 -0
  29. package/dist/dom/overlay.d.ts.map +1 -0
  30. package/dist/dom/paint-order.d.ts +25 -0
  31. package/dist/dom/paint-order.d.ts.map +1 -0
  32. package/dist/dom/serialize-text.d.ts +16 -0
  33. package/dist/dom/serialize-text.d.ts.map +1 -0
  34. package/dist/dom/serializer.d.ts +33 -0
  35. package/dist/dom/serializer.d.ts.map +1 -0
  36. package/dist/dom/snapshot.d.ts +37 -0
  37. package/dist/dom/snapshot.d.ts.map +1 -0
  38. package/dist/dom/types.d.ts +178 -0
  39. package/dist/dom/types.d.ts.map +1 -0
  40. package/dist/downloads/sanitize.d.ts +13 -0
  41. package/dist/downloads/sanitize.d.ts.map +1 -0
  42. package/dist/driver.d.ts +88 -0
  43. package/dist/driver.d.ts.map +1 -0
  44. package/dist/errors.d.ts +71 -0
  45. package/dist/errors.d.ts.map +1 -0
  46. package/dist/events.d.ts +8 -0
  47. package/dist/events.d.ts.map +1 -0
  48. package/dist/index.d.ts +55 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +5066 -0
  51. package/dist/input/dispatcher.d.ts +196 -0
  52. package/dist/input/dispatcher.d.ts.map +1 -0
  53. package/dist/input/keys.d.ts +20 -0
  54. package/dist/input/keys.d.ts.map +1 -0
  55. package/dist/launch/discovery.d.ts +14 -0
  56. package/dist/launch/discovery.d.ts.map +1 -0
  57. package/dist/launch/local-browser.d.ts +59 -0
  58. package/dist/launch/local-browser.d.ts.map +1 -0
  59. package/dist/navigation/navigator.d.ts +37 -0
  60. package/dist/navigation/navigator.d.ts.map +1 -0
  61. package/dist/navigation/policy.d.ts +61 -0
  62. package/dist/navigation/policy.d.ts.map +1 -0
  63. package/dist/providers/cloak.d.ts +26 -0
  64. package/dist/providers/cloak.d.ts.map +1 -0
  65. package/dist/providers/factory.d.ts +17 -0
  66. package/dist/providers/factory.d.ts.map +1 -0
  67. package/dist/providers/index.d.ts +5 -0
  68. package/dist/providers/index.d.ts.map +1 -0
  69. package/dist/providers/local.d.ts +13 -0
  70. package/dist/providers/local.d.ts.map +1 -0
  71. package/dist/providers/types.d.ts +8 -0
  72. package/dist/providers/types.d.ts.map +1 -0
  73. package/dist/recording/har.d.ts +94 -0
  74. package/dist/recording/har.d.ts.map +1 -0
  75. package/dist/recording/screencast.d.ts +40 -0
  76. package/dist/recording/screencast.d.ts.map +1 -0
  77. package/dist/screenshot/service.d.ts +34 -0
  78. package/dist/screenshot/service.d.ts.map +1 -0
  79. package/dist/session.d.ts +130 -0
  80. package/dist/session.d.ts.map +1 -0
  81. package/dist/targets/registry.d.ts +99 -0
  82. package/dist/targets/registry.d.ts.map +1 -0
  83. package/dist/testing.d.ts +53 -0
  84. package/dist/testing.d.ts.map +1 -0
  85. package/dist/testing.js +8 -0
  86. package/dist/types.d.ts +88 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/package.json +42 -0
@@ -0,0 +1,40 @@
1
+ import type { TargetRegistry } from "../targets/registry";
2
+ import type { CdpTransport } from "../types";
3
+ export interface ScreencastFrame {
4
+ /** Base64 PNG data, as CDP delivers it. */
5
+ data: string;
6
+ timestamp: number;
7
+ }
8
+ export interface ScreencastRecorderOptions {
9
+ format?: "png" | "jpeg";
10
+ quality?: number;
11
+ maxWidth?: number;
12
+ maxHeight?: number;
13
+ everyNthFrame?: number;
14
+ /** Defensive cap on buffered frames (default 600 — e.g. 10min @ 1fps). */
15
+ maxFrames?: number;
16
+ }
17
+ export declare class ScreencastRecorder {
18
+ private readonly transport;
19
+ private readonly registry;
20
+ private readonly options;
21
+ private frames;
22
+ private frameListener?;
23
+ private focusListener?;
24
+ private currentSessionId?;
25
+ private recording;
26
+ private droppedFrames;
27
+ constructor(transport: CdpTransport, registry: TargetRegistry, options?: ScreencastRecorderOptions);
28
+ get isRecording(): boolean;
29
+ /** Frames captured so far (or, after {@link stop}, the final buffer). */
30
+ get capturedFrames(): readonly ScreencastFrame[];
31
+ /** How many frames were dropped after hitting `maxFrames` (observability). */
32
+ get dropped(): number;
33
+ /** Begin capturing frames from the focused target, following focus changes. Idempotent. */
34
+ start(): void;
35
+ /** Stop capturing and return every buffered frame. */
36
+ stop(): ScreencastFrame[];
37
+ private onFrame;
38
+ private followFocus;
39
+ }
40
+ //# sourceMappingURL=screencast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screencast.d.ts","sourceRoot":"","sources":["../../src/recording/screencast.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,kBAAkB;IAc3B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAd3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGoC;IAE5D,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAK;gBAGP,SAAS,EAAE,YAAY,EACvB,QAAQ,EAAE,cAAc,EACzC,OAAO,GAAE,yBAA8B;IAYzC,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,yEAAyE;IACzE,IAAI,cAAc,IAAI,SAAS,eAAe,EAAE,CAE/C;IAED,8EAA8E;IAC9E,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,2FAA2F;IAC3F,KAAK,IAAI,IAAI;IAeb,sDAAsD;IACtD,IAAI,IAAI,eAAe,EAAE;IAezB,OAAO,CAAC,OAAO;IAoBf,OAAO,CAAC,WAAW;CAwBpB"}
@@ -0,0 +1,34 @@
1
+ import type { DomSelectorMap } from "../dom/types";
2
+ import type { CdpTransport } from "../types";
3
+ /**
4
+ * A 4×4 transparent PNG, returned when no real screenshot is available. A
5
+ * non-empty base64 sentinel keeps downstream image handling total (design's
6
+ * placeholder semantics).
7
+ */
8
+ export declare const PLACEHOLDER_SCREENSHOT = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
9
+ export interface ScreenshotCaptureOptions {
10
+ /** Capture beyond the viewport (the full scrollable page). */
11
+ fullPage?: boolean;
12
+ /** Draw numbered boxes over the interactive elements before capturing. */
13
+ highlight?: boolean;
14
+ /** Required when `highlight` is set — the map whose elements get boxed. */
15
+ selectorMap?: DomSelectorMap;
16
+ /** Session of the page being captured (the focused page). */
17
+ sessionId?: string;
18
+ /** `"png"` (default) or `"jpeg"`. */
19
+ format?: "png" | "jpeg";
20
+ /** JPEG quality 0–100. */
21
+ quality?: number;
22
+ /** Caller abort, threaded into the CDP sends (composes with per-request timeout). */
23
+ signal?: AbortSignal;
24
+ }
25
+ export declare class ScreenshotService {
26
+ private readonly transport;
27
+ constructor(transport: CdpTransport);
28
+ /** Capture a screenshot (base64), optionally with a highlight overlay. */
29
+ capture(options?: ScreenshotCaptureOptions): Promise<string>;
30
+ /** Draw the overlay. Returns whether an inject was attempted; never throws. */
31
+ private injectHighlights;
32
+ private removeHighlights;
33
+ }
34
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/screenshot/service.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,qGACiE,CAAC;AAIrG,MAAM,WAAW,wBAAwB;IACvC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qFAAqF;IACrF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,YAAY;IAEpD,0EAA0E;IACpE,OAAO,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCtE,+EAA+E;YACjE,gBAAgB;YAkChB,gBAAgB;CAmB/B"}
@@ -0,0 +1,130 @@
1
+ import { type BrowserConfigOverrides, type ResolvedBrowserConfig } from "./config";
2
+ import { DialogHandler } from "./dialogs/handler";
3
+ import { DomService } from "./dom/dom-service";
4
+ import { ElementOverlay } from "./dom/overlay";
5
+ import type { DomSelectorMap, EnhancedDOMTreeNode } from "./dom/types";
6
+ import { type CdpConnectionError } from "./errors";
7
+ import { InputDispatcher } from "./input/dispatcher";
8
+ import { type LaunchedBrowser } from "./launch/local-browser";
9
+ import { type NavigateOptions, type NavigateResult, Navigator } from "./navigation/navigator";
10
+ import { NavigationPolicy } from "./navigation/policy";
11
+ import { HarRecorder } from "./recording/har";
12
+ import { ScreencastRecorder } from "./recording/screencast";
13
+ import { ScreenshotService } from "./screenshot/service";
14
+ import { TargetRegistry } from "./targets/registry";
15
+ import { type BackendNodeId, type BrowserStateSummary, type CdpTransport, type TabId, type TabInfo } from "./types";
16
+ export interface BrowserSessionOptions {
17
+ /** A launched browser to close when the session stops (launch path only). */
18
+ ownedBrowser?: LaunchedBrowser;
19
+ }
20
+ /** Injectable seams for {@link BrowserSession.connect} (tests / alt providers). */
21
+ export interface BrowserConnectOptions {
22
+ /** fetch used for http→ws resolution (defaults to the global fetch). */
23
+ fetch?: typeof fetch;
24
+ /** Build the transport from the resolved ws url (defaults to a real socket). */
25
+ openTransport?: (wsUrl: string) => Promise<CdpTransport>;
26
+ }
27
+ export interface BrowserStateOptions {
28
+ /** Include a base64 screenshot in the summary. */
29
+ screenshot?: boolean;
30
+ /** Caller abort, threaded into the DOM capture + screenshot CDP sends (§6.8). */
31
+ signal?: AbortSignal;
32
+ }
33
+ export declare class BrowserSession {
34
+ private readonly transport;
35
+ readonly config: ResolvedBrowserConfig;
36
+ readonly registry: TargetRegistry;
37
+ readonly policy: NavigationPolicy;
38
+ readonly navigator: Navigator;
39
+ readonly dom: DomService;
40
+ readonly input: InputDispatcher;
41
+ readonly dialogs: DialogHandler;
42
+ readonly screenshots: ScreenshotService;
43
+ /** Demo-mode single-element highlight (IMPROVEMENTS overlay). */
44
+ readonly overlay: ElementOverlay;
45
+ /** Network traffic -> HAR capture (M11). Off until `.start()` is called — never active by default. */
46
+ readonly har: HarRecorder;
47
+ /** CDP screencast frame capture, tab-follow (M11). Off until `.start()` is called. */
48
+ readonly screencast: ScreencastRecorder;
49
+ private lastSelectorMap;
50
+ private readonly ownedBrowser?;
51
+ private started;
52
+ constructor(transport: CdpTransport, config: ResolvedBrowserConfig, options?: BrowserSessionOptions);
53
+ /**
54
+ * {@link FrameTargetResolver} for OOPIF descent (W3/W3b). The registry
55
+ * already auto-attaches every target's session via `Target.setAutoAttach`
56
+ * (`TargetRegistry.handleAttached`), including cross-origin iframe targets —
57
+ * this only READS that bookkeeping, it never issues its own attach.
58
+ *
59
+ * Primary path: for OOPIF targets CDP guarantees `targetId == frameId` — an
60
+ * exact match against the surfaced node's own `frameId` is unambiguous by
61
+ * construction and needs no URL comparison at all.
62
+ *
63
+ * Fallback: match by url (ignoring query/hash and a trailing slash) when no
64
+ * exact frameId match is found (the same fallback design/04a documents for
65
+ * frames whose frameId can't be resolved directly). If MORE THAN ONE
66
+ * attached iframe target shares the same url key, the match is ambiguous —
67
+ * decline (`undefined`) rather than guess via first-attach order. An empty
68
+ * iframe is strictly better than grafting the wrong sibling frame's content.
69
+ */
70
+ private resolveFrameTarget;
71
+ /** Launch a local Chromium subprocess and open a session against it. */
72
+ static launch(overrides?: BrowserConfigOverrides): Promise<BrowserSession>;
73
+ /**
74
+ * Attach to an existing CDP endpoint (`ws://…` or an `http://…/json/version`
75
+ * base). This is the first-class connect path — the same one a remote/cloud
76
+ * provider drives.
77
+ */
78
+ static connect(cdpUrl: string, overrides?: BrowserConfigOverrides, options?: BrowserConnectOptions): Promise<BrowserSession>;
79
+ /** Discover targets, pick a focus, and begin auto-answering dialogs. Idempotent. */
80
+ start(): Promise<void>;
81
+ /** Tear down: stop dialogs, detach registry, close the socket and (if owned) the browser. */
82
+ stop(): Promise<void>;
83
+ /**
84
+ * Subscribe to the underlying CDP socket dropping unexpectedly (not on
85
+ * {@link stop}). Surfaces `CdpConnection.onDisconnect` at the session level so
86
+ * a host/provider can react — the seam to build a reconnect policy on
87
+ * (`reconnectWithBackoff` is the building block). The library takes NO reconnect
88
+ * action itself: on the `launch()` path a drop means the Chromium subprocess
89
+ * died (nothing to reconnect to), and on the `connect()` path the reconnect
90
+ * policy belongs to the provider that owns the endpoint. Returns an unsubscribe
91
+ * fn; a no-op if the transport doesn't surface disconnects.
92
+ */
93
+ onDisconnect(cb: (err: CdpConnectionError) => void): () => void;
94
+ /** The open tabs (4-char ids). */
95
+ get tabs(): TabInfo[];
96
+ /** The selector map from the most recent {@link getBrowserStateSummary}. */
97
+ get selectorMap(): DomSelectorMap;
98
+ /** Resolve an element by its map key — the backendNodeId the LLM saw as `[N]`. */
99
+ getElementByIndex(index: number): EnhancedDOMTreeNode | undefined;
100
+ /** Navigate the focused tab (policy-checked before any CDP navigate — A3). */
101
+ navigate(url: string, options?: NavigateOptions): Promise<NavigateResult>;
102
+ /**
103
+ * Assemble a full state summary for the focused tab: url + title + tabs +
104
+ * serialized numbered DOM text + selector map (+ optional screenshot). The
105
+ * selector map is cached so subsequent index-based actions resolve.
106
+ */
107
+ getBrowserStateSummary(options?: BrowserStateOptions): Promise<BrowserStateSummary>;
108
+ /**
109
+ * Navigate the focused tab back one history entry (CDP navigation history).
110
+ * A no-op when there is nothing to go back to.
111
+ */
112
+ goBack(): Promise<void>;
113
+ /**
114
+ * Evaluate a JS expression in the focused page and return the JSON value
115
+ * (`returnByValue`, promises awaited). Throws on a page-side exception
116
+ * instead of resolving to `undefined` — the seam {@link groundTruth}
117
+ * (`testing.ts`) builds on to assert real DOM effects (PRP T1) rather than
118
+ * a tool's self-report.
119
+ */
120
+ evaluate<T = unknown>(expression: string): Promise<T>;
121
+ /** Open a new tab (browser-level Target.createTarget). Returns its 4-char id. */
122
+ openTab(url?: string): Promise<TabId>;
123
+ /** Focus another tab by its 4-char id, bringing it to the foreground. */
124
+ switchTab(tabId: TabId): Promise<void>;
125
+ /** Close a tab by its 4-char id (best-effort — a stale id is not an error). */
126
+ closeTab(tabId: TabId): Promise<void>;
127
+ /** Get the element by its backendNodeId key (branded overload of index access). */
128
+ nodeForKey(index: BackendNodeId): EnhancedDOMTreeNode | undefined;
129
+ }
130
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { TypedEmitter } from "../events";
2
+ import { type TabId, type TargetId } from "../types";
3
+ import type { CdpTransport } from "../types";
4
+ /** A recent Page lifecycle event kept in the per-target ring buffer. */
5
+ export interface LifecycleRecord {
6
+ name: string;
7
+ loaderId: string;
8
+ timestamp: number;
9
+ }
10
+ interface TargetRecord {
11
+ targetId: TargetId;
12
+ type: string;
13
+ url: string;
14
+ title: string;
15
+ }
16
+ /** Genuine target notifications (A1). */
17
+ export interface TargetRegistryEvents {
18
+ tabCreated: {
19
+ targetId: TargetId;
20
+ tabId: TabId;
21
+ url: string;
22
+ };
23
+ tabClosed: {
24
+ targetId: TargetId;
25
+ tabId: TabId;
26
+ };
27
+ focusChanged: {
28
+ targetId: TargetId;
29
+ url: string;
30
+ };
31
+ targetCrashed: {
32
+ targetId: TargetId;
33
+ };
34
+ }
35
+ /** The last 4 chars of a target id — the only id the LLM ever sees (design/05). */
36
+ export declare const toTabId: (targetId: TargetId) => TabId;
37
+ export declare class TargetRegistry {
38
+ private readonly transport;
39
+ readonly events: TypedEmitter<TargetRegistryEvents>;
40
+ private readonly targets;
41
+ private readonly sessions;
42
+ private readonly targetSessions;
43
+ private readonly sessionToTarget;
44
+ private readonly lifecycleEvents;
45
+ private focusTargetId;
46
+ private recoveryInProgress;
47
+ private readonly unsubscribes;
48
+ constructor(transport: CdpTransport);
49
+ /** Register handlers and discover existing targets. */
50
+ start(): Promise<void>;
51
+ dispose(): void;
52
+ private handleAttached;
53
+ private handleDetached;
54
+ private handleInfoChanged;
55
+ private handleCrashed;
56
+ private handleLifecycle;
57
+ private enablePageMonitoring;
58
+ get focusedTargetId(): TargetId | undefined;
59
+ /** Focus a target. Only page-type targets may become the focus. */
60
+ setFocus(targetId: TargetId): boolean;
61
+ private recoverFocus;
62
+ getPageTargets(): TargetRecord[];
63
+ /** TabInfo-ready view of the page targets (4-char ids). */
64
+ getTabs(): Array<{
65
+ id: TabId;
66
+ url: string;
67
+ title: string;
68
+ }>;
69
+ getTargetIdFromTabId(tabId: TabId): TargetId | undefined;
70
+ getSessionIdForTarget(targetId: TargetId): string | undefined;
71
+ /**
72
+ * Attached targets of CDP type `"iframe"` (out-of-process/cross-origin
73
+ * iframes), with their url + session id. `Target.setAutoAttach` (called for
74
+ * every attached session in {@link handleAttached}) already cascades to these
75
+ * automatically — nothing here issues a new `attachToTarget`, so a caller
76
+ * matching a frame by url gets an existing session, never a fresh attach.
77
+ * Used by `BrowserSession`'s `FrameTargetResolver` (W3/W3b): for OOPIF
78
+ * targets CDP guarantees `targetId == frameId`, so the resolver's primary
79
+ * path matches `targetId` directly against the surfaced node's frameId.
80
+ * The `targetId` returned here is what makes that possible — url-matching
81
+ * (also exposed here) is only the fallback for when that invariant doesn't
82
+ * resolve a match; it is NOT the only resolution signal the registry offers.
83
+ */
84
+ getIframeTargets(): Array<{
85
+ targetId: TargetId;
86
+ url: string;
87
+ sessionId: string;
88
+ }>;
89
+ getCurrentUrl(targetId: TargetId): string | undefined;
90
+ getLifecycleEvents(targetId: TargetId): LifecycleRecord[];
91
+ /** For the Navigator's focus provider. */
92
+ getFocusedSession(): {
93
+ targetId: TargetId;
94
+ sessionId: string;
95
+ } | undefined;
96
+ private getLifecycleBuffer;
97
+ }
98
+ export {};
99
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/targets/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { CdpConnectionError } from "./errors";
2
+ import type { CdpCommand, CdpCommandParams, CdpCommandReturn, CdpEventListener, CdpEventName, CdpEventParams, CdpSendOptions, CdpTransport } from "./types";
3
+ /** A scripted response: a fixed value, or a fn of the call's params/sessionId. */
4
+ export type FakeResponder = unknown | ((params: unknown, sessionId?: string) => unknown);
5
+ /**
6
+ * A {@link CdpTransport} backed by a scripted `method -> response` map, with a
7
+ * multi-listener event registry and an {@link emitEvent} to push canned events.
8
+ * Every `send` is recorded in {@link calls} so tests can assert what was (or was
9
+ * NOT) sent. Unknown methods resolve to `{}`.
10
+ */
11
+ export declare class FakeCdpTransport implements CdpTransport {
12
+ private readonly responses;
13
+ /** Every `send` in order, for assertions. */
14
+ readonly calls: Array<{
15
+ method: string;
16
+ params?: unknown;
17
+ sessionId?: string;
18
+ }>;
19
+ private readonly registrations;
20
+ private readonly disconnectListeners;
21
+ constructor(responses?: Map<string, FakeResponder>);
22
+ send<T extends CdpCommand>(method: T, params?: CdpCommandParams<T>, options?: CdpSendOptions): Promise<CdpCommandReturn<T>>;
23
+ on<M extends CdpEventName>(method: M, listener: CdpEventListener<M>, sessionId?: string): () => void;
24
+ /** Push a canned CDP event to matching subscribers. */
25
+ emitEvent<M extends CdpEventName>(method: M, params: CdpEventParams<M>, sessionId?: string): void;
26
+ onDisconnect(cb: (err: CdpConnectionError) => void): () => void;
27
+ /** Simulate an unexpected socket drop for tests. */
28
+ emitDisconnect(err: CdpConnectionError): void;
29
+ /** Number of `send`s recorded for a method. */
30
+ sendCount(method: string): number;
31
+ close(): Promise<void>;
32
+ }
33
+ /** The minimal session surface {@link groundTruth} needs — real `BrowserSession` satisfies it. */
34
+ export interface EvaluableSession {
35
+ evaluate<T = unknown>(expression: string): Promise<T>;
36
+ }
37
+ /**
38
+ * Ground-truth assertions for interaction tests (PRP T1): reads the real DOM
39
+ * effect via CDP `Runtime.evaluate`, not the tool's self-report. Backed by
40
+ * `session.evaluate()`; unit-tested here against {@link FakeCdpTransport},
41
+ * driven against real Chromium once the W9(c) browser-gated tier exists.
42
+ */
43
+ export declare function groundTruth(session: EvaluableSession): {
44
+ /** Evaluate an arbitrary expression in the page and return the JSON value. */
45
+ evalInPage: <T = unknown>(expression: string) => Promise<T>;
46
+ /** `window.getClickCount()` — the golden-fixture click-counter contract (design/08-09 §9.3). */
47
+ clickCount: () => Promise<number>;
48
+ /** The live `.value` of the element matched by `selector`. */
49
+ inputValue: (selector: string) => Promise<string>;
50
+ /** The live `.checked` of the element matched by `selector`. */
51
+ checked: (selector: string) => Promise<boolean>;
52
+ };
53
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,kFAAkF;AAClF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;AAOzF;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IAMvC,OAAO,CAAC,QAAQ,CAAC,SAAS;IALtC,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAM;IACrF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4C;IAC1E,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgD;gBAEvD,SAAS,GAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAa;IAExE,IAAI,CAAC,CAAC,SAAS,UAAU,EAC7B,MAAM,EAAE,CAAC,EACT,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC5B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAU/B,EAAE,CAAC,CAAC,SAAS,YAAY,EACvB,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC7B,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,IAAI;IAiBb,uDAAuD;IACvD,SAAS,CAAC,CAAC,SAAS,YAAY,EAC9B,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,SAAS,CAAC,EAAE,MAAM,GACjB,IAAI;IAUP,YAAY,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,MAAM,IAAI;IAO/D,oDAAoD;IACpD,cAAc,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAI7C,+CAA+C;IAC/C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,kGAAkG;AAClG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,gBAAgB;IAEjD,8EAA8E;iBACjE,CAAC,wBAAwB,MAAM,KAAG,OAAO,CAAC,CAAC,CAAC;IACzD,gGAAgG;sBAChF,OAAO,CAAC,MAAM,CAAC;IAC/B,8DAA8D;2BACvC,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;IAE/C,gEAAgE;wBAC5C,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;EAGhD"}
@@ -0,0 +1,8 @@
1
+ import {
2
+ FakeCdpTransport,
3
+ groundTruth
4
+ } from "./chunk-DXCP25KX.js";
5
+ export {
6
+ FakeCdpTransport,
7
+ groundTruth
8
+ };
@@ -0,0 +1,88 @@
1
+ import type { ProtocolMapping } from "devtools-protocol/types/protocol-mapping";
2
+ import type { CdpConnectionError } from "./errors";
3
+ /** A stable index into the interactive-element selector map. */
4
+ export type ElementIndex = number & {
5
+ readonly __brand: "ElementIndex";
6
+ };
7
+ /** A CDP backend node id (`DOM.BackendNodeId`). */
8
+ export type BackendNodeId = number & {
9
+ readonly __brand: "BackendNodeId";
10
+ };
11
+ /** A CDP target id (`Target.TargetID`). */
12
+ export type TargetId = string & {
13
+ readonly __brand: "TargetId";
14
+ };
15
+ /** An AP3X-side tab identifier (the 4-char id the LLM sees). */
16
+ export type TabId = string & {
17
+ readonly __brand: "TabId";
18
+ };
19
+ export declare const asElementIndex: (n: number) => ElementIndex;
20
+ export declare const asBackendNodeId: (n: number) => BackendNodeId;
21
+ export declare const asTargetId: (s: string) => TargetId;
22
+ export declare const asTabId: (s: string) => TabId;
23
+ /** A CDP command method name (e.g. `"Page.navigate"`). */
24
+ export type CdpCommand = keyof ProtocolMapping.Commands;
25
+ /** A CDP event method name (e.g. `"Page.lifecycleEvent"`). */
26
+ export type CdpEventName = keyof ProtocolMapping.Events;
27
+ /**
28
+ * The params object for a CDP command. No-param commands resolve to `never`,
29
+ * so combined with an optional `params?` they simply take no argument.
30
+ */
31
+ export type CdpCommandParams<T extends CdpCommand> = ProtocolMapping.Commands[T]["paramsType"][number];
32
+ /** The response object for a CDP command. */
33
+ export type CdpCommandReturn<T extends CdpCommand> = ProtocolMapping.Commands[T]["returnType"];
34
+ /** The params object carried by a CDP event. */
35
+ export type CdpEventParams<M extends CdpEventName> = ProtocolMapping.Events[M][number];
36
+ /** Per-request send options. */
37
+ export interface CdpSendOptions {
38
+ /** Route to a specific target session (flatten mode). */
39
+ sessionId?: string;
40
+ /** Caller abort; merged with the per-request timeout. */
41
+ signal?: AbortSignal;
42
+ /** Override the default per-request timeout (ms). */
43
+ timeoutMs?: number;
44
+ }
45
+ /** A CDP event listener; receives typed params and the originating sessionId. */
46
+ export type CdpEventListener<M extends CdpEventName> = (params: CdpEventParams<M>, sessionId: string | undefined) => void;
47
+ /**
48
+ * Typed Chrome DevTools Protocol transport. `send` is request/response-typed by
49
+ * the protocol; `on` is a multi-listener registry keyed on (method, sessionId?)
50
+ * — a listener with no `sessionId` sees every session's events for that method.
51
+ */
52
+ export interface CdpTransport {
53
+ send<T extends CdpCommand>(method: T, params?: CdpCommandParams<T>, options?: CdpSendOptions): Promise<CdpCommandReturn<T>>;
54
+ /** Subscribe to a CDP event. Returns an unsubscribe fn. */
55
+ on<M extends CdpEventName>(method: M, listener: CdpEventListener<M>, sessionId?: string): () => void;
56
+ close(): Promise<void>;
57
+ /**
58
+ * Subscribe to the socket dropping unexpectedly (NOT on {@link close}). Returns
59
+ * an unsubscribe fn. Optional — a transport with no live socket (a bridge, a
60
+ * fake) may omit it. This is the seam a host/provider builds a reconnect policy
61
+ * on (see `reconnectWithBackoff`); the library takes no reconnect action itself.
62
+ */
63
+ onDisconnect?(cb: (err: CdpConnectionError) => void): () => void;
64
+ }
65
+ /** One open tab in the controlled browser. `id` is the 4-char {@link TabId}. */
66
+ export interface TabInfo {
67
+ id: TabId;
68
+ url: string;
69
+ title: string;
70
+ /** Parent page for popups / OOPIFs, if any. */
71
+ parentId?: TabId;
72
+ }
73
+ /**
74
+ * A snapshot of browser state handed to the agent — the @ap3x/browser ↔
75
+ * browser-agent seam (PRP A6). `serializedText` is the numbered/indented text
76
+ * projection the consumer reads; `selectorMap` is keyed by CDP backendNodeId
77
+ * (the `[N]` in the text == the key == what getElementByIndex resolves). No
78
+ * LLM-memory vocabulary lives here.
79
+ */
80
+ export interface BrowserStateSummary {
81
+ url: string;
82
+ title: string;
83
+ tabs: TabInfo[];
84
+ screenshot?: string;
85
+ serializedText: string;
86
+ selectorMap: import("./dom/types").DomSelectorMap;
87
+ }
88
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@ap3x/browser",
3
+ "version": "0.1.0",
4
+ "description": "Chrome DevTools Protocol browser control primitives",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/AP3X-Dev/AP3X.git",
8
+ "directory": "packages/browser"
9
+ },
10
+ "license": "MIT",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./testing": {
23
+ "types": "./dist/testing.d.ts",
24
+ "default": "./dist/testing.js"
25
+ }
26
+ },
27
+ "files": ["dist"],
28
+ "scripts": {
29
+ "build": "tsup src/index.ts src/testing.ts --format esm --clean --tsconfig tsconfig.build.json && tsc -p tsconfig.build.json",
30
+ "prepublishOnly": "node ../../scripts/publish-gate.mjs",
31
+ "test": "vitest run"
32
+ },
33
+ "dependencies": {
34
+ "@sinclair/typebox": "^0.34.49",
35
+ "devtools-protocol": "^0.0.1464554",
36
+ "ws": "^8.18.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/ws": "^8.18.0",
40
+ "fast-check": "^4.8.0"
41
+ }
42
+ }