@hy-sde-org/dsh-browser 0.1.1-rc.2
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 +37 -0
- package/README.md +33 -0
- package/cordis.patch.yml +21 -0
- package/dist/aria-bundle.d.ts +9 -0
- package/dist/aria-bundle.d.ts.map +1 -0
- package/dist/aria-bundle.js +16 -0
- package/dist/aria-bundle.js.map +1 -0
- package/dist/aria.d.ts +45 -0
- package/dist/aria.d.ts.map +1 -0
- package/dist/aria.js +79 -0
- package/dist/aria.js.map +1 -0
- package/dist/assets/background.js.txt +242 -0
- package/dist/assets/manifest.json.txt +14 -0
- package/dist/assets/options.html.txt +53 -0
- package/dist/assets/options.js.txt +23 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/invariant.d.ts +16 -0
- package/dist/invariant.d.ts.map +1 -0
- package/dist/invariant.js +22 -0
- package/dist/invariant.js.map +1 -0
- package/dist/relay/bridge.d.ts +36 -0
- package/dist/relay/bridge.d.ts.map +1 -0
- package/dist/relay/bridge.js +860 -0
- package/dist/relay/bridge.js.map +1 -0
- package/dist/relay/index.d.ts +16 -0
- package/dist/relay/index.d.ts.map +1 -0
- package/dist/relay/index.js +15 -0
- package/dist/relay/index.js.map +1 -0
- package/dist/relay/kind.d.ts +30 -0
- package/dist/relay/kind.d.ts.map +1 -0
- package/dist/relay/kind.js +33 -0
- package/dist/relay/kind.js.map +1 -0
- package/dist/relay/protocol.d.ts +101 -0
- package/dist/relay/protocol.d.ts.map +1 -0
- package/dist/relay/protocol.js +12 -0
- package/dist/relay/protocol.js.map +1 -0
- package/dist/relay/server.d.ts +44 -0
- package/dist/relay/server.d.ts.map +1 -0
- package/dist/relay/server.js +173 -0
- package/dist/relay/server.js.map +1 -0
- package/dist/service.d.ts +157 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +291 -0
- package/dist/service.js.map +1 -0
- package/dist/stealth-scripts.d.ts +11 -0
- package/dist/stealth-scripts.d.ts.map +1 -0
- package/dist/stealth-scripts.js +2010 -0
- package/dist/stealth-scripts.js.map +1 -0
- package/dist/stealth.d.ts +62 -0
- package/dist/stealth.d.ts.map +1 -0
- package/dist/stealth.js +194 -0
- package/dist/stealth.js.map +1 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/examples/agent-preset/agent.cordis.yml +19 -0
- package/examples/agent-preset/preset.yml +3 -0
- package/package.json +99 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `ctx.browser` service: an agent-facing browser over Playwright Core CDP.
|
|
3
|
+
*
|
|
4
|
+
* Three backends, mirroring omp's browser tool:
|
|
5
|
+
* - **launch** — spawn a (stealth-patched) browser executable,
|
|
6
|
+
* - **attach** — connect to an existing CDP endpoint (`cdp_url`), and
|
|
7
|
+
* - **relay** — connect to the local relay server whose companion Chrome
|
|
8
|
+
* extension drives the user's own tabs.
|
|
9
|
+
*
|
|
10
|
+
* Tabs are addressed by name (default `main`) per service instance; one
|
|
11
|
+
* browser connection is shared across tabs. The service owns no durable state
|
|
12
|
+
* and is conversation/session-scoped by the plugin row that mounts it.
|
|
13
|
+
*
|
|
14
|
+
* Port of oh-my-pi's browser (see port_omp.md item: browser tool with
|
|
15
|
+
* stealth + relay/CDP-attach). Model-facing surface lives in
|
|
16
|
+
* @hy-sde-org/dsh-tool-browser.
|
|
17
|
+
* @module @hy-sde-org/dsh-browser/service
|
|
18
|
+
*/
|
|
19
|
+
import { Service, type Context } from '@deepseek-ai/cordis';
|
|
20
|
+
import type { BrowserConfig, BrowserKind, PageObservation, ScreenshotResult } from './types.ts';
|
|
21
|
+
export type { BrowserConfig, BrowserKind, BrowserKindTag, PageObservation, ObservationEntry, ScreenshotResult } from './types.ts';
|
|
22
|
+
/** Navigation wait condition accepted by the tool (Playwright dialect). */
|
|
23
|
+
export type WaitUntil = 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
|
|
24
|
+
/** Map omp/puppeteer-style wait conditions onto Playwright's dialect. */
|
|
25
|
+
export declare function normalizeWaitUntil(value: string | undefined): WaitUntil | undefined;
|
|
26
|
+
/** How a tab is addressed in `close`. */
|
|
27
|
+
export type CloseMode = 'single' | 'all' | 'kill';
|
|
28
|
+
/** One browser connection per (cwd + kind), one tab per name. */
|
|
29
|
+
export declare class BrowserService extends Service {
|
|
30
|
+
private readonly browserPath;
|
|
31
|
+
private readonly headless;
|
|
32
|
+
private readonly viewport;
|
|
33
|
+
private readonly relayUrl;
|
|
34
|
+
private readonly relayToken;
|
|
35
|
+
private readonly timeoutMs;
|
|
36
|
+
private readonly browsers;
|
|
37
|
+
private readonly tabs;
|
|
38
|
+
private relay;
|
|
39
|
+
constructor(ctx: Context, config?: BrowserConfig);
|
|
40
|
+
/**
|
|
41
|
+
* The relay endpoint this instance serves (created lazily in relay kind).
|
|
42
|
+
* @returns the relay base URL this instance binds or resolves.
|
|
43
|
+
*/
|
|
44
|
+
relayEndpoint(): string;
|
|
45
|
+
private browserKeyFor;
|
|
46
|
+
private connect;
|
|
47
|
+
private openConnection;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the browser kind for a session (attach/launch/relay), like omp.
|
|
50
|
+
* @param input - optional app-path, cdp URL, or explicit relay opt-in.
|
|
51
|
+
* @returns the resolved {@link BrowserKind} to drive.
|
|
52
|
+
*/
|
|
53
|
+
resolveKind(input: {
|
|
54
|
+
path?: string;
|
|
55
|
+
cdpUrl?: string;
|
|
56
|
+
relay?: boolean;
|
|
57
|
+
}): BrowserKind;
|
|
58
|
+
/**
|
|
59
|
+
* Ensure the relay server is running for this instance (idempotent).
|
|
60
|
+
* @returns the relay base URL the in-process server is bound to.
|
|
61
|
+
*/
|
|
62
|
+
ensureRelay(): Promise<string>;
|
|
63
|
+
private tab;
|
|
64
|
+
/**
|
|
65
|
+
* Open (or navigate) a named tab to `url`; returns the page observation.
|
|
66
|
+
* @param name - tab id; one tab per name, one browser per cwd+kind.
|
|
67
|
+
* @param url - the URL to navigate to.
|
|
68
|
+
* @param opts - backend kind, working directory, wait condition, timeout.
|
|
69
|
+
* @returns the page observation (title, url, ARIA snapshot, size).
|
|
70
|
+
*/
|
|
71
|
+
open(name: string, url: string, opts: {
|
|
72
|
+
kind: BrowserKind;
|
|
73
|
+
cwd: string;
|
|
74
|
+
waitUntil?: WaitUntil;
|
|
75
|
+
timeoutMs?: number;
|
|
76
|
+
}): Promise<PageObservation>;
|
|
77
|
+
/**
|
|
78
|
+
* Evaluate `code` in the named tab and return the JSON-serializable value.
|
|
79
|
+
* @param name - tab id.
|
|
80
|
+
* @param code - JavaScript body/expression evaluated in the tab's page.
|
|
81
|
+
* @param opts - backend kind, working directory, timeout.
|
|
82
|
+
* @returns the evaluated value (JSON-serializable).
|
|
83
|
+
*/
|
|
84
|
+
run(name: string, code: string, opts: {
|
|
85
|
+
kind: BrowserKind;
|
|
86
|
+
cwd: string;
|
|
87
|
+
timeoutMs?: number;
|
|
88
|
+
}): Promise<unknown>;
|
|
89
|
+
/**
|
|
90
|
+
* Click an ARIA-ref (`aria-ref=e5`) or CSS selector in the named tab.
|
|
91
|
+
* @param name - tab id.
|
|
92
|
+
* @param selector - ARIA ref selector or CSS selector.
|
|
93
|
+
* @param opts - backend kind, working directory.
|
|
94
|
+
* @returns the re-observed page after the click.
|
|
95
|
+
*/
|
|
96
|
+
click(name: string, selector: string, opts: {
|
|
97
|
+
kind: BrowserKind;
|
|
98
|
+
cwd: string;
|
|
99
|
+
}): Promise<PageObservation>;
|
|
100
|
+
/**
|
|
101
|
+
* Type text into an ARIA-ref or CSS selector in the named tab.
|
|
102
|
+
* @param name - tab id.
|
|
103
|
+
* @param selector - ARIA ref selector or CSS selector.
|
|
104
|
+
* @param text - the text to fill.
|
|
105
|
+
* @param opts - backend kind, working directory.
|
|
106
|
+
* @returns the re-observed page after the fill.
|
|
107
|
+
*/
|
|
108
|
+
type(name: string, selector: string, text: string, opts: {
|
|
109
|
+
kind: BrowserKind;
|
|
110
|
+
cwd: string;
|
|
111
|
+
}): Promise<PageObservation>;
|
|
112
|
+
/**
|
|
113
|
+
* Close named tabs; `all` closes every tab, `kill` also closes browsers.
|
|
114
|
+
* @param name - tab id.
|
|
115
|
+
* @param opts - backend kind, working directory, close-all and kill flags.
|
|
116
|
+
* @returns a promise resolving once the close is initiated.
|
|
117
|
+
*/
|
|
118
|
+
close(name: string, opts: {
|
|
119
|
+
kind: BrowserKind;
|
|
120
|
+
cwd: string;
|
|
121
|
+
all?: boolean;
|
|
122
|
+
kill?: boolean;
|
|
123
|
+
}): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Screenshot the named tab to a PNG file; returns the written path.
|
|
126
|
+
* @param name - tab id.
|
|
127
|
+
* @param destination - the PNG file path to write.
|
|
128
|
+
* @param opts - backend kind, working directory, full-page flag.
|
|
129
|
+
* @returns the written screenshot path.
|
|
130
|
+
*/
|
|
131
|
+
screenshot(name: string, destination: string, opts: {
|
|
132
|
+
kind: BrowserKind;
|
|
133
|
+
cwd: string;
|
|
134
|
+
fullPage?: boolean;
|
|
135
|
+
}): Promise<ScreenshotResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Observe the named tab (title, url, size, ARIA snapshot) without navigating.
|
|
138
|
+
* @param name - tab id.
|
|
139
|
+
* @param opts - backend kind, working directory.
|
|
140
|
+
* @returns the page observation.
|
|
141
|
+
*/
|
|
142
|
+
observe(name: string, opts: {
|
|
143
|
+
kind: BrowserKind;
|
|
144
|
+
cwd: string;
|
|
145
|
+
}): Promise<PageObservation>;
|
|
146
|
+
/** Observe a page: title, url, size, and the ARIA snapshot. */
|
|
147
|
+
private observePage;
|
|
148
|
+
/** Close every browser connection and stop the relay (cleanup on ctx dispose). */
|
|
149
|
+
stop(): void;
|
|
150
|
+
/** Number of open browser connections (tests / diagnostics). */
|
|
151
|
+
get browserCount(): number;
|
|
152
|
+
}
|
|
153
|
+
export { captureAriaSnapshot, resolveAriaRefElement } from './aria.ts';
|
|
154
|
+
export { startRelayServer, type RelayServer } from './relay/server.ts';
|
|
155
|
+
export { resolveRelayKind, DEFAULT_RELAY_URL } from './relay/kind.ts';
|
|
156
|
+
export { DEFAULT_VIEWPORT, STEALTH_LAUNCH_ARGS, stealthIgnoreDefaultArgs, resolveUserAgentOverride, applyUserAgentOverride, type UserAgentOverride, } from './stealth.ts';
|
|
157
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `ctx.browser` service: an agent-facing browser over Playwright Core CDP.
|
|
3
|
+
*
|
|
4
|
+
* Three backends, mirroring omp's browser tool:
|
|
5
|
+
* - **launch** — spawn a (stealth-patched) browser executable,
|
|
6
|
+
* - **attach** — connect to an existing CDP endpoint (`cdp_url`), and
|
|
7
|
+
* - **relay** — connect to the local relay server whose companion Chrome
|
|
8
|
+
* extension drives the user's own tabs.
|
|
9
|
+
*
|
|
10
|
+
* Tabs are addressed by name (default `main`) per service instance; one
|
|
11
|
+
* browser connection is shared across tabs. The service owns no durable state
|
|
12
|
+
* and is conversation/session-scoped by the plugin row that mounts it.
|
|
13
|
+
*
|
|
14
|
+
* Port of oh-my-pi's browser (see port_omp.md item: browser tool with
|
|
15
|
+
* stealth + relay/CDP-attach). Model-facing surface lives in
|
|
16
|
+
* @hy-sde-org/dsh-tool-browser.
|
|
17
|
+
* @module @hy-sde-org/dsh-browser/service
|
|
18
|
+
*/
|
|
19
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
20
|
+
import { chromium } from 'playwright-core';
|
|
21
|
+
import { captureAriaSnapshot, resolveAriaRefElement } from "./aria.js";
|
|
22
|
+
import { DEFAULT_VIEWPORT, STEALTH_LAUNCH_ARGS, applyUserAgentOverride, preparePage, resolveUserAgentOverride, stealthIgnoreDefaultArgs, } from "./stealth.js";
|
|
23
|
+
import { startRelayServer } from "./relay/server.js";
|
|
24
|
+
import { resolveRelayKind } from "./relay/kind.js";
|
|
25
|
+
/** Map omp/puppeteer-style wait conditions onto Playwright's dialect. */
|
|
26
|
+
export function normalizeWaitUntil(value) {
|
|
27
|
+
if (value === 'networkidle0' || value === 'networkidle2')
|
|
28
|
+
return 'networkidle';
|
|
29
|
+
if (value === 'load' || value === 'domcontentloaded' || value === 'networkidle' || value === 'commit') {
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
35
|
+
/** One browser connection per (cwd + kind), one tab per name. */
|
|
36
|
+
export class BrowserService extends Service {
|
|
37
|
+
browserPath;
|
|
38
|
+
headless;
|
|
39
|
+
viewport;
|
|
40
|
+
relayUrl;
|
|
41
|
+
relayToken;
|
|
42
|
+
timeoutMs;
|
|
43
|
+
browsers = new Map();
|
|
44
|
+
tabs = new Map();
|
|
45
|
+
relay;
|
|
46
|
+
constructor(ctx, config = {}) {
|
|
47
|
+
super(ctx, 'browser');
|
|
48
|
+
this.browserPath = config.browserPath;
|
|
49
|
+
this.headless = config.headless ?? true;
|
|
50
|
+
this.viewport = config.viewport ?? DEFAULT_VIEWPORT;
|
|
51
|
+
this.relayUrl = config.relayUrl?.replace(/\/+$/, '') ?? 'http://127.0.0.1:9224';
|
|
52
|
+
this.relayToken = config.relayToken;
|
|
53
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The relay endpoint this instance serves (created lazily in relay kind).
|
|
57
|
+
* @returns the relay base URL this instance binds or resolves.
|
|
58
|
+
*/
|
|
59
|
+
relayEndpoint() {
|
|
60
|
+
return this.relay ? `http://127.0.0.1:${this.relay.port}` : this.relayUrl;
|
|
61
|
+
}
|
|
62
|
+
browserKeyFor(kind, cwd) {
|
|
63
|
+
if (kind.kind === 'launch')
|
|
64
|
+
return `launch:${cwd}`;
|
|
65
|
+
return `${kind.kind}:${'cdpUrl' in kind ? kind.cdpUrl : ''}`;
|
|
66
|
+
}
|
|
67
|
+
async connect(kind, cwd) {
|
|
68
|
+
const key = this.browserKeyFor(kind, cwd);
|
|
69
|
+
const existing = this.browsers.get(key);
|
|
70
|
+
if (existing)
|
|
71
|
+
return existing;
|
|
72
|
+
const entry = await this.openConnection(kind, cwd);
|
|
73
|
+
this.browsers.set(key, entry);
|
|
74
|
+
return entry;
|
|
75
|
+
}
|
|
76
|
+
async openConnection(kind, cwd) {
|
|
77
|
+
if (kind.kind === 'launch') {
|
|
78
|
+
const executablePath = kind.path ?? this.browserPath;
|
|
79
|
+
const launchOptions = {
|
|
80
|
+
executablePath,
|
|
81
|
+
headless: this.headless,
|
|
82
|
+
args: [...STEALTH_LAUNCH_ARGS],
|
|
83
|
+
ignoreDefaultArgs: stealthIgnoreDefaultArgs(executablePath),
|
|
84
|
+
};
|
|
85
|
+
const browser = await chromium.launch(launchOptions);
|
|
86
|
+
void applyUserAgentOverride(browser, await resolveUserAgentOverride(browser));
|
|
87
|
+
return { kind, browser, headless: this.headless, cwd };
|
|
88
|
+
}
|
|
89
|
+
// attach + relay both speak Chrome CDP discovery; the relay impersonates it.
|
|
90
|
+
const browser = await chromium.connectOverCDP(kind.cdpUrl);
|
|
91
|
+
return { kind, browser, headless: false, cwd };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resolve the browser kind for a session (attach/launch/relay), like omp.
|
|
95
|
+
* @param input - optional app-path, cdp URL, or explicit relay opt-in.
|
|
96
|
+
* @returns the resolved {@link BrowserKind} to drive.
|
|
97
|
+
*/
|
|
98
|
+
resolveKind(input) {
|
|
99
|
+
if (input.cdpUrl)
|
|
100
|
+
return { kind: 'attach', cdpUrl: input.cdpUrl.replace(/\/+$/, '') };
|
|
101
|
+
if (input.path)
|
|
102
|
+
return { kind: 'launch', path: input.path };
|
|
103
|
+
const relay = resolveRelayKind({ settingEnabled: input.relay ?? false, url: this.relayUrl });
|
|
104
|
+
if (relay)
|
|
105
|
+
return { kind: 'relay', cdpUrl: relay.cdpUrl };
|
|
106
|
+
return this.browserPath !== undefined ? { kind: 'launch', path: this.browserPath } : { kind: 'launch' };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Ensure the relay server is running for this instance (idempotent).
|
|
110
|
+
* @returns the relay base URL the in-process server is bound to.
|
|
111
|
+
*/
|
|
112
|
+
async ensureRelay() {
|
|
113
|
+
if (this.relay)
|
|
114
|
+
return this.relayEndpoint();
|
|
115
|
+
const port = Number(new URL(this.relayUrl).port || 80);
|
|
116
|
+
const server = await startRelayServer({
|
|
117
|
+
port,
|
|
118
|
+
...(this.relayToken !== undefined ? { token: this.relayToken } : {}),
|
|
119
|
+
// fall back to an ephemeral port if the default is taken
|
|
120
|
+
log: () => { },
|
|
121
|
+
});
|
|
122
|
+
this.relay = server;
|
|
123
|
+
return this.relayEndpoint();
|
|
124
|
+
}
|
|
125
|
+
async tab(name, kind, cwd) {
|
|
126
|
+
const existing = this.tabs.get(name);
|
|
127
|
+
if (existing)
|
|
128
|
+
return existing;
|
|
129
|
+
const entry = await this.connect(kind, cwd);
|
|
130
|
+
const page = await entry.browser.newPage({ viewport: this.viewport });
|
|
131
|
+
if (entry.kind.kind === 'launch')
|
|
132
|
+
await preparePage(page);
|
|
133
|
+
const tab = { page, browserKey: this.browserKeyFor(kind, cwd), name };
|
|
134
|
+
this.tabs.set(name, tab);
|
|
135
|
+
return tab;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Open (or navigate) a named tab to `url`; returns the page observation.
|
|
139
|
+
* @param name - tab id; one tab per name, one browser per cwd+kind.
|
|
140
|
+
* @param url - the URL to navigate to.
|
|
141
|
+
* @param opts - backend kind, working directory, wait condition, timeout.
|
|
142
|
+
* @returns the page observation (title, url, ARIA snapshot, size).
|
|
143
|
+
*/
|
|
144
|
+
async open(name, url, opts) {
|
|
145
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
146
|
+
await tab.page.goto(url, {
|
|
147
|
+
waitUntil: normalizeWaitUntil(opts.waitUntil) ?? 'load',
|
|
148
|
+
timeout: opts.timeoutMs ?? this.timeoutMs,
|
|
149
|
+
});
|
|
150
|
+
return this.observePage(tab.page);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Evaluate `code` in the named tab and return the JSON-serializable value.
|
|
154
|
+
* @param name - tab id.
|
|
155
|
+
* @param code - JavaScript body/expression evaluated in the tab's page.
|
|
156
|
+
* @param opts - backend kind, working directory, timeout.
|
|
157
|
+
* @returns the evaluated value (JSON-serializable).
|
|
158
|
+
*/
|
|
159
|
+
async run(name, code, opts) {
|
|
160
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
161
|
+
return tab.page.evaluate(code);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Click an ARIA-ref (`aria-ref=e5`) or CSS selector in the named tab.
|
|
165
|
+
* @param name - tab id.
|
|
166
|
+
* @param selector - ARIA ref selector or CSS selector.
|
|
167
|
+
* @param opts - backend kind, working directory.
|
|
168
|
+
* @returns the re-observed page after the click.
|
|
169
|
+
*/
|
|
170
|
+
async click(name, selector, opts) {
|
|
171
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
172
|
+
const ref = selector.trim();
|
|
173
|
+
const bareRef = ref.startsWith('aria-ref=') ? ref.split('=')[1] ?? '' : ref.startsWith('aria-ref/') || ref.startsWith('ariaref/') ? ref.split('/').pop() ?? '' : undefined;
|
|
174
|
+
if (bareRef !== undefined) {
|
|
175
|
+
const target = await resolveAriaRefElement(tab.page, bareRef);
|
|
176
|
+
if (target === null)
|
|
177
|
+
throw new Error(`browser: aria ref ${bareRef} no longer matches any element (re-snapshot)`);
|
|
178
|
+
await target.click();
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
await tab.page.locator(ref).first().click();
|
|
182
|
+
}
|
|
183
|
+
return this.observePage(tab.page);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Type text into an ARIA-ref or CSS selector in the named tab.
|
|
187
|
+
* @param name - tab id.
|
|
188
|
+
* @param selector - ARIA ref selector or CSS selector.
|
|
189
|
+
* @param text - the text to fill.
|
|
190
|
+
* @param opts - backend kind, working directory.
|
|
191
|
+
* @returns the re-observed page after the fill.
|
|
192
|
+
*/
|
|
193
|
+
async type(name, selector, text, opts) {
|
|
194
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
195
|
+
const ref = selector.trim();
|
|
196
|
+
const bareRef = ref.startsWith('aria-ref=') ? ref.split('=')[1] ?? '' : ref.startsWith('aria-ref/') || ref.startsWith('ariaref/') ? ref.split('/').pop() ?? '' : undefined;
|
|
197
|
+
if (bareRef !== undefined) {
|
|
198
|
+
const target = await resolveAriaRefElement(tab.page, bareRef);
|
|
199
|
+
if (target === null)
|
|
200
|
+
throw new Error(`browser: aria ref ${bareRef} no longer matches any element (re-snapshot)`);
|
|
201
|
+
await target.fill(text);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
await tab.page.locator(ref).first().fill(text);
|
|
205
|
+
}
|
|
206
|
+
return this.observePage(tab.page);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Close named tabs; `all` closes every tab, `kill` also closes browsers.
|
|
210
|
+
* @param name - tab id.
|
|
211
|
+
* @param opts - backend kind, working directory, close-all and kill flags.
|
|
212
|
+
* @returns a promise resolving once the close is initiated.
|
|
213
|
+
*/
|
|
214
|
+
async close(name, opts) {
|
|
215
|
+
const entry = this.browsers.get(this.browserKeyFor(opts.kind, opts.cwd));
|
|
216
|
+
if (opts.all) {
|
|
217
|
+
for (const [tabName, tab] of this.tabs) {
|
|
218
|
+
void tab.page.close().catch(() => { });
|
|
219
|
+
this.tabs.delete(tabName);
|
|
220
|
+
}
|
|
221
|
+
if (opts.kill && entry) {
|
|
222
|
+
await entry.browser.close().catch(() => { });
|
|
223
|
+
this.browsers.delete(this.browserKeyFor(opts.kind, opts.cwd));
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const tab = this.tabs.get(name);
|
|
228
|
+
if (!tab)
|
|
229
|
+
return;
|
|
230
|
+
void tab.page.close().catch(() => { });
|
|
231
|
+
this.tabs.delete(name);
|
|
232
|
+
if (opts.kill && entry) {
|
|
233
|
+
void entry.browser.close().catch(() => { });
|
|
234
|
+
this.browsers.delete(this.browserKeyFor(opts.kind, opts.cwd));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Screenshot the named tab to a PNG file; returns the written path.
|
|
239
|
+
* @param name - tab id.
|
|
240
|
+
* @param destination - the PNG file path to write.
|
|
241
|
+
* @param opts - backend kind, working directory, full-page flag.
|
|
242
|
+
* @returns the written screenshot path.
|
|
243
|
+
*/
|
|
244
|
+
async screenshot(name, destination, opts) {
|
|
245
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
246
|
+
await tab.page.screenshot({ path: destination, ...(opts.fullPage !== undefined ? { fullPage: opts.fullPage } : {}) });
|
|
247
|
+
return { path: destination };
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Observe the named tab (title, url, size, ARIA snapshot) without navigating.
|
|
251
|
+
* @param name - tab id.
|
|
252
|
+
* @param opts - backend kind, working directory.
|
|
253
|
+
* @returns the page observation.
|
|
254
|
+
*/
|
|
255
|
+
async observe(name, opts) {
|
|
256
|
+
const tab = await this.tab(name, opts.kind, opts.cwd);
|
|
257
|
+
return this.observePage(tab.page);
|
|
258
|
+
}
|
|
259
|
+
/** Observe a page: title, url, size, and the ARIA snapshot. */
|
|
260
|
+
async observePage(page) {
|
|
261
|
+
const [title, aria] = await Promise.all([page.title().catch(() => ''), captureAriaSnapshot(page, null, {})]);
|
|
262
|
+
const url = page.url();
|
|
263
|
+
const viewport = page.viewportSize();
|
|
264
|
+
return {
|
|
265
|
+
title,
|
|
266
|
+
url,
|
|
267
|
+
aria,
|
|
268
|
+
width: viewport?.width ?? 0,
|
|
269
|
+
height: viewport?.height ?? 0,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/** Close every browser connection and stop the relay (cleanup on ctx dispose). */
|
|
273
|
+
stop() {
|
|
274
|
+
for (const entry of this.browsers.values()) {
|
|
275
|
+
void entry.browser.close().catch(() => { });
|
|
276
|
+
}
|
|
277
|
+
this.browsers.clear();
|
|
278
|
+
this.tabs.clear();
|
|
279
|
+
this.relay?.stop();
|
|
280
|
+
this.relay = undefined;
|
|
281
|
+
}
|
|
282
|
+
/** Number of open browser connections (tests / diagnostics). */
|
|
283
|
+
get browserCount() {
|
|
284
|
+
return this.browsers.size;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
export { captureAriaSnapshot, resolveAriaRefElement } from "./aria.js";
|
|
288
|
+
export { startRelayServer } from "./relay/server.js";
|
|
289
|
+
export { resolveRelayKind, DEFAULT_RELAY_URL } from "./relay/kind.js";
|
|
290
|
+
export { DEFAULT_VIEWPORT, STEALTH_LAUNCH_ARGS, stealthIgnoreDefaultArgs, resolveUserAgentOverride, applyUserAgentOverride, } from "./stealth.js";
|
|
291
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth init scripts ported verbatim from oh-my-pi (MIT — see port_omp.md).
|
|
3
|
+
* Each script runs in every new document; together they hide Playwright/Puppeteer
|
|
4
|
+
* fingerprints: navigator.webdriver, automation UA + client hints, sourceURL
|
|
5
|
+
* tampering, fonts, WebGL, canvas/audio, plugins, hardware, codecs, workers, locale.
|
|
6
|
+
* Generated — regenerate from omp `packages/coding-agent/src/tools/puppeteer/*.txt`.
|
|
7
|
+
*/
|
|
8
|
+
import type { Page } from 'playwright-core';
|
|
9
|
+
/** Run every stealth script in a freshly created page; call before navigation. */
|
|
10
|
+
export declare function installStealth(page: Page): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=stealth-scripts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stealth-scripts.d.ts","sourceRoot":"","sources":["../src/stealth-scripts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAy9D3C,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D"}
|