@mercuryo-ai/agentbrowse 0.2.60 → 0.2.61
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/README.md +30 -5
- package/dist/browser-session-state.d.ts +39 -0
- package/dist/browser-session-state.d.ts.map +1 -1
- package/dist/browser-session-state.js +63 -1
- package/dist/commands/act.d.ts.map +1 -1
- package/dist/commands/act.js +539 -535
- package/dist/commands/attach.d.ts.map +1 -1
- package/dist/commands/attach.js +5 -10
- package/dist/commands/browser-connection-failure.d.ts +9 -0
- package/dist/commands/browser-connection-failure.d.ts.map +1 -0
- package/dist/commands/browser-connection-failure.js +15 -0
- package/dist/commands/browser-status.d.ts.map +1 -1
- package/dist/commands/browser-status.js +26 -30
- package/dist/commands/close.d.ts.map +1 -1
- package/dist/commands/close.js +5 -0
- package/dist/commands/extract.d.ts.map +1 -1
- package/dist/commands/extract.js +147 -144
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +11 -8
- package/dist/commands/navigate.d.ts.map +1 -1
- package/dist/commands/navigate.js +79 -73
- package/dist/commands/observe-inventory.d.ts +1 -0
- package/dist/commands/observe-inventory.d.ts.map +1 -1
- package/dist/commands/observe-inventory.js +15 -3
- package/dist/commands/observe.d.ts.map +1 -1
- package/dist/commands/observe.js +260 -272
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/commands/screenshot.js +50 -64
- package/dist/library.d.ts +2 -1
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +2 -1
- package/dist/protected-fill.d.ts.map +1 -1
- package/dist/protected-fill.js +46 -7
- package/dist/sticky-owner-host-entry.d.ts +2 -0
- package/dist/sticky-owner-host-entry.d.ts.map +1 -0
- package/dist/sticky-owner-host-entry.js +97 -0
- package/dist/sticky-owner.d.ts +15 -0
- package/dist/sticky-owner.d.ts.map +1 -0
- package/dist/sticky-owner.js +431 -0
- package/docs/configuration.md +36 -4
- package/docs/getting-started.md +28 -4
- package/docs/troubleshooting.md +42 -6
- package/package.json +1 -1
- package/dist/protected-fill-browser.d.ts +0 -22
- package/dist/protected-fill-browser.d.ts.map +0 -1
- package/dist/protected-fill-browser.js +0 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"attach.d.ts","sourceRoot":"","sources":["../../src/commands/attach.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAChC,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAG1E,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,oCAAqC,CAAC;AAErE,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,sBAAuB,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,0BAA0B,CAAC;IAC1C,SAAS,CAAC,EAAE,sBAAsB,CAAC;CACpC,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,EAAE,wBAAwB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAErE,wFAAwF;AACxF,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAsC/F"}
|
package/dist/commands/attach.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
* attach <cdp-url> — Attach AgentBrowse to an existing browser session.
|
|
3
3
|
*/
|
|
4
4
|
import { buildAttachedSession, buildCdpHttpEndpointUrl, } from '../browser-session-state.js';
|
|
5
|
-
import {
|
|
5
|
+
import { syncLaunchPage } from '../playwright-runtime.js';
|
|
6
|
+
import { initializeBrowserSessionOwner, withStickyOwnerBrowser } from '../sticky-owner.js';
|
|
6
7
|
/** Stable top-level error codes returned by `attach(...)`. */
|
|
7
8
|
export const ATTACH_ERROR_CODES = ['browser_attach_failed'];
|
|
8
9
|
/** Stable outcome categories emitted by `attach(...)`. */
|
|
9
10
|
export const ATTACH_OUTCOME_TYPES = ['blocked'];
|
|
10
11
|
/** Attaches AgentBrowse to an existing browser via a CDP websocket or HTTP endpoint. */
|
|
11
12
|
export async function attach(cdpUrl, options = {}) {
|
|
12
|
-
let browser = null;
|
|
13
13
|
try {
|
|
14
14
|
const normalizedCdpUrl = await resolveAttachEndpoint(cdpUrl);
|
|
15
15
|
const session = buildAttachedSession({
|
|
@@ -19,11 +19,11 @@ export async function attach(cdpUrl, options = {}) {
|
|
|
19
19
|
...(options.capabilities ? { capabilities: options.capabilities } : {}),
|
|
20
20
|
...(options.transport ? { transport: options.transport } : {}),
|
|
21
21
|
});
|
|
22
|
-
|
|
23
|
-
const syncedPage = await syncLaunchPage(session, browser, {
|
|
22
|
+
await initializeBrowserSessionOwner(session);
|
|
23
|
+
const syncedPage = await withStickyOwnerBrowser(session, (browser) => syncLaunchPage(session, browser, {
|
|
24
24
|
fallbackUrl: '',
|
|
25
25
|
fallbackTitle: '',
|
|
26
|
-
});
|
|
26
|
+
}));
|
|
27
27
|
return {
|
|
28
28
|
success: true,
|
|
29
29
|
runtime: 'attached',
|
|
@@ -44,11 +44,6 @@ export async function attach(cdpUrl, options = {}) {
|
|
|
44
44
|
reason: formatUnknownError(error),
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
finally {
|
|
48
|
-
if (browser) {
|
|
49
|
-
await disconnectPlaywright(browser);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
47
|
}
|
|
53
48
|
async function resolveAttachEndpoint(input) {
|
|
54
49
|
const normalized = input.trim();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const STICKY_OWNER_UNRECOVERABLE_REASON = "sticky_owner_unrecoverable";
|
|
2
|
+
export declare function describeBrowserConnectionFailure(error: unknown, options: {
|
|
3
|
+
defaultMessage: string;
|
|
4
|
+
unrecoverableSessionMessage: string;
|
|
5
|
+
}): {
|
|
6
|
+
message: string;
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=browser-connection-failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-connection-failure.d.ts","sourceRoot":"","sources":["../../src/commands/browser-connection-failure.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,+BAA+B,CAAC;AAK9E,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;IACP,cAAc,EAAE,MAAM,CAAC;IACvB,2BAA2B,EAAE,MAAM,CAAC;CACrC,GACA;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAcrC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const STICKY_OWNER_UNRECOVERABLE_REASON = 'sticky_owner_unrecoverable';
|
|
2
|
+
const STICKY_OWNER_UNRECOVERABLE_PUBLIC_REASON = 'The previous browser session is no longer reachable, so AgentBrowse could not restore control of the browser. Launch or attach a new browser session and try again.';
|
|
3
|
+
export function describeBrowserConnectionFailure(error, options) {
|
|
4
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
5
|
+
if (reason === STICKY_OWNER_UNRECOVERABLE_REASON) {
|
|
6
|
+
return {
|
|
7
|
+
message: options.unrecoverableSessionMessage,
|
|
8
|
+
reason: STICKY_OWNER_UNRECOVERABLE_PUBLIC_REASON,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
message: options.defaultMessage,
|
|
13
|
+
reason,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-status.d.ts","sourceRoot":"","sources":["../../src/commands/browser-status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-status.d.ts","sourceRoot":"","sources":["../../src/commands/browser-status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;AAiBrC,KAAK,mBAAmB,GAAG;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CAAC;CAC5C,CAAC;AAEF,0DAA0D;AAC1D,eAAO,MAAM,4BAA4B,gFAI/B,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AACrF,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAClE,MAAM,MAAM,gCAAgC,GAAG,mBAAmB,CAAC;AAEnE,uGAAuG;AACvG,MAAM,MAAM,oCAAoC,GAAG;IACjD,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,WAAW,EAAE,OAAO,CAAC,wBAAwB,EAAE,2BAA2B,CAAC,CAAC;IAC5E,OAAO,CAAC,EAAE,2BAA2B,CAAC;IACtC,mBAAmB,CAAC,EAAE,gCAAgC,CAAC;IACvD,uBAAuB,EAAE,IAAI,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,qGAAqG;AACrG,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,2BAA2B,CAAC;IACtC,mBAAmB,CAAC,EAAE,gCAAgC,CAAC;IACvD,qBAAqB,CAAC,EAAE,IAAI,CAAC;CAC9B,CAAC;AAEF,kEAAkE;AAClE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,CAAC,EAAE,2BAA2B,CAAC;IACtC,qBAAqB,CAAC,EAAE,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B,oCAAoC,GACpC,wBAAwB,GACxB,6BAA6B,CAAC;AAmLlC,qFAAqF;AACrF,wBAAsB,aAAa,CACjC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAClC,OAAO,CAAC,mBAAmB,CAAC,CAgG9B"}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* browse browser-status — Check live browser/page/runtime state.
|
|
3
3
|
*/
|
|
4
4
|
import { buildCdpHttpEndpointUrl, getSessionPort, supportsCaptchaSolve, } from '../browser-session-state.js';
|
|
5
|
-
import {
|
|
5
|
+
import { resolveCurrentPageContext } from '../playwright-runtime.js';
|
|
6
6
|
import { captureDiagnosticSnapshotBestEffort, finishDiagnosticStepBestEffort, recordCommandLifecycleEventBestEffort, startDiagnosticStep, } from '../diagnostics.js';
|
|
7
7
|
import { scrubProtectedExactValues } from '../secrets/protected-exact-value-redaction.js';
|
|
8
|
+
import { withStickyOwnerBrowser } from '../sticky-owner.js';
|
|
8
9
|
/** Stable outcome categories exposed by `status(...)`. */
|
|
9
10
|
export const BROWSER_STATUS_OUTCOME_TYPES = [
|
|
10
11
|
'browser_alive',
|
|
@@ -56,40 +57,35 @@ function buildProtectedStatusPayload(params) {
|
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
59
|
async function readCanonicalStatus(session) {
|
|
59
|
-
let browser = null;
|
|
60
60
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
61
|
+
return await withStickyOwnerBrowser(session, async (browser) => {
|
|
62
|
+
const resolved = await resolveCurrentPageContext(browser, session);
|
|
63
|
+
const persisted = session.runtime?.currentPageRef;
|
|
64
|
+
const title = (await resolved.page
|
|
65
|
+
.title()
|
|
66
|
+
.catch(() => session.runtime?.pages[resolved.pageRef]?.title ?? '')) ||
|
|
67
|
+
session.runtime?.pages[resolved.pageRef]?.title ||
|
|
68
|
+
'unknown';
|
|
69
|
+
const url = resolved.page.url() || session.runtime?.pages[resolved.pageRef]?.url || 'unknown';
|
|
70
|
+
return {
|
|
71
|
+
pageRef: resolved.pageRef,
|
|
72
|
+
url,
|
|
73
|
+
title,
|
|
74
|
+
...(persisted && (persisted !== resolved.pageRef || resolved.recoveredVia)
|
|
75
|
+
? {
|
|
76
|
+
currentPageMismatch: {
|
|
77
|
+
persistedPageRef: persisted,
|
|
78
|
+
...(persisted !== resolved.pageRef ? { livePageRef: resolved.pageRef } : {}),
|
|
79
|
+
...(resolved.recoveredVia ? { recoveredVia: resolved.recoveredVia } : {}),
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
: {}),
|
|
83
|
+
};
|
|
84
|
+
});
|
|
84
85
|
}
|
|
85
86
|
catch {
|
|
86
87
|
return null;
|
|
87
88
|
}
|
|
88
|
-
finally {
|
|
89
|
-
if (browser) {
|
|
90
|
-
await disconnectPlaywright(browser);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
89
|
}
|
|
94
90
|
function buildStatusEndpointUrl(session, port, resourcePath) {
|
|
95
91
|
if (session) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAYvF,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,mCAAoC,CAAC;AAEnE,yDAAyD;AACzD,eAAO,MAAM,mBAAmB,gEAAiE,CAAC;AAElG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,uCAAuC;AACvC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAEF,mCAAmC;AACnC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,cAAc,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAsClE,sFAAsF;AACtF,wBAAsB,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAyErF"}
|
package/dist/commands/close.js
CHANGED
|
@@ -6,6 +6,7 @@ import { captureDiagnosticSnapshotBestEffort, finishDiagnosticStepBestEffort, re
|
|
|
6
6
|
import { info } from '../output.js';
|
|
7
7
|
import { closeOwnedBrowser } from '../owned-browser.js';
|
|
8
8
|
import { isManagedBrowserPid } from '../owned-process.js';
|
|
9
|
+
import { terminateBrowserSessionOwner } from '../sticky-owner.js';
|
|
9
10
|
/** Stable top-level error codes returned by `close(...)`. */
|
|
10
11
|
export const CLOSE_ERROR_CODES = ['browser_close_failed'];
|
|
11
12
|
/** Stable outcome categories emitted by `close(...)`. */
|
|
@@ -64,6 +65,7 @@ export async function close(session) {
|
|
|
64
65
|
},
|
|
65
66
|
});
|
|
66
67
|
if (isCloseableManagedSession(session)) {
|
|
68
|
+
await terminateBrowserSessionOwner(session);
|
|
67
69
|
const closeResult = await closeOwnedBrowser(session);
|
|
68
70
|
if (!closeResult.success) {
|
|
69
71
|
recordCommandLifecycleEventBestEffort({
|
|
@@ -90,6 +92,9 @@ export async function close(session) {
|
|
|
90
92
|
};
|
|
91
93
|
}
|
|
92
94
|
}
|
|
95
|
+
else if (session?.stickyOwner) {
|
|
96
|
+
await terminateBrowserSessionOwner(session);
|
|
97
|
+
}
|
|
93
98
|
recordCommandLifecycleEventBestEffort({
|
|
94
99
|
step: closeStep,
|
|
95
100
|
phase: 'completed',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAUzE,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAsBtB,KAAK,sBAAsB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAC1B,sBAAsB,GACtB,uBAAuB,GACvB,kBAAkB,EAAE,CAAC;AAEzB,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACnC;AAED,4DAA4D;AAC5D,MAAM,MAAM,kBAAkB,GAAG,uBAAuB,GAAG,CAAC,CAAC,UAAU,CAAC;AAExE,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,8MAStB,CAAC;AAEX,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,8EAKxB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,+CAA+C;AAC/C,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG;IAChD,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC,kBAAkB,EAAE,eAAe,GAAG,SAAS,GAAG,aAAa,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,2CAA2C;AAC3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,GAAG,qBAAqB,CAAC;AAE9E,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAibxE;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,kBAAkB,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAUzE,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAsBtB,KAAK,sBAAsB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,MAAM,kBAAkB,GAC1B,sBAAsB,GACtB,uBAAuB,GACvB,kBAAkB,EAAE,CAAC;AAEzB,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAC;CACnC;AAED,4DAA4D;AAC5D,MAAM,MAAM,kBAAkB,GAAG,uBAAuB,GAAG,CAAC,CAAC,UAAU,CAAC;AAExE,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,8MAStB,CAAC;AAEX,2DAA2D;AAC3D,eAAO,MAAM,qBAAqB,8EAKxB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,+CAA+C;AAC/C,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG;IAChD,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC,kBAAkB,EAAE,eAAe,GAAG,SAAS,GAAG,aAAa,CAAC,CAAC;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,2CAA2C;AAC3C,MAAM,MAAM,oBAAoB,GAAG;IAAE,OAAO,EAAE,KAAK,CAAA;CAAE,GAAG,qBAAqB,CAAC;AAE9E,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAibxE;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,kBAAkB,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CAgSxB;AAED,sFAAsF;AACtF,wBAAsB,OAAO,CAC3B,OAAO,EAAE,qBAAqB,EAC9B,WAAW,EAAE,MAAM,GAAG,kBAAkB,EACxC,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgCf"}
|
package/dist/commands/extract.js
CHANGED
|
@@ -8,12 +8,14 @@ import { getSurface, getTarget, markSurfaceLifecycle, markTargetLifecycle, } fro
|
|
|
8
8
|
import { getPageScopeEpoch, setCurrentPage } from '../runtime-page-state.js';
|
|
9
9
|
import { outputContractFailure, outputJSON, } from '../output.js';
|
|
10
10
|
import { captureDiagnosticSnapshotBestEffort, finishDiagnosticStepBestEffort, recordCommandLifecycleEventBestEffort, startDiagnosticStep, } from '../diagnostics.js';
|
|
11
|
-
import {
|
|
11
|
+
import { resolveCurrentPageContext, resolvePageByRef as resolvePlaywrightPageByRef, syncSessionPage, } from '../playwright-runtime.js';
|
|
12
12
|
import { withApiTraceContext } from '../command-api-tracing.js';
|
|
13
13
|
import { normalizePageSignature } from './descriptor-validation.js';
|
|
14
14
|
import { readScopedDialogText } from './extract-scoped-dialog-text.js';
|
|
15
15
|
import { resolveScopedExtractContext } from './extract-scope-resolution.js';
|
|
16
16
|
import { executeStagehandExtract } from './extract-stagehand-executor.js';
|
|
17
|
+
import { describeBrowserConnectionFailure } from './browser-connection-failure.js';
|
|
18
|
+
import { withStickyOwnerBrowser } from '../sticky-owner.js';
|
|
17
19
|
/** Stable top-level error codes returned by `extract(...)`. */
|
|
18
20
|
export const EXTRACT_ERROR_CODES = [
|
|
19
21
|
'browser_connection_failed',
|
|
@@ -459,180 +461,181 @@ export async function extractBrowser(session, schemaInput, scopeRef) {
|
|
|
459
461
|
scopeRef,
|
|
460
462
|
});
|
|
461
463
|
}
|
|
462
|
-
let browser = null;
|
|
463
464
|
let failureMessage = null;
|
|
464
465
|
let cleanupScopedExtract = null;
|
|
465
466
|
let staleScope = false;
|
|
466
467
|
let staleReason = null;
|
|
467
468
|
try {
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
catch (err) {
|
|
471
|
-
return buildExtractContractFailureResult(session, {
|
|
472
|
-
step: extractStep,
|
|
473
|
-
error: 'browser_connection_failed',
|
|
474
|
-
outcomeType: 'blocked',
|
|
475
|
-
message: 'Extraction could not start because AgentBrowse failed to connect to the browser.',
|
|
476
|
-
reason: err instanceof Error ? err.message : String(err),
|
|
477
|
-
scopeRef,
|
|
478
|
-
pageRef,
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
try {
|
|
482
|
-
let sourcePage;
|
|
483
|
-
if (scopeTarget) {
|
|
484
|
-
sourcePage = await resolvePlaywrightPageByRef(browser, session, pageRef);
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
const resolvedPage = await resolveCurrentPageContext(browser, session);
|
|
488
|
-
pageRef = resolvedPage.pageRef;
|
|
489
|
-
sourcePage = resolvedPage.page;
|
|
490
|
-
}
|
|
491
|
-
let page = sourcePage;
|
|
492
|
-
let scopedResolution = null;
|
|
493
|
-
const { url, title } = await syncSessionPage(session, pageRef, sourcePage);
|
|
494
|
-
if (scopeTarget?.pageSignature &&
|
|
495
|
-
normalizePageSignature(url) !== scopeTarget.pageSignature) {
|
|
496
|
-
staleScope = true;
|
|
497
|
-
staleReason = 'page-signature-mismatch';
|
|
498
|
-
throw new Error('stale_scope_target_page_signature_changed');
|
|
499
|
-
}
|
|
500
|
-
let effectiveSelector;
|
|
501
|
-
if (scopeTarget) {
|
|
469
|
+
return await withStickyOwnerBrowser(session, async (browser) => {
|
|
502
470
|
try {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
471
|
+
let sourcePage;
|
|
472
|
+
if (scopeTarget) {
|
|
473
|
+
sourcePage = await resolvePlaywrightPageByRef(browser, session, pageRef);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
const resolvedPage = await resolveCurrentPageContext(browser, session);
|
|
477
|
+
pageRef = resolvedPage.pageRef;
|
|
478
|
+
sourcePage = resolvedPage.page;
|
|
479
|
+
}
|
|
480
|
+
let page = sourcePage;
|
|
481
|
+
let scopedResolution = null;
|
|
482
|
+
const { url, title } = await syncSessionPage(session, pageRef, sourcePage);
|
|
483
|
+
if (scopeTarget?.pageSignature &&
|
|
484
|
+
normalizePageSignature(url) !== scopeTarget.pageSignature) {
|
|
485
|
+
staleScope = true;
|
|
486
|
+
staleReason = 'page-signature-mismatch';
|
|
487
|
+
throw new Error('stale_scope_target_page_signature_changed');
|
|
488
|
+
}
|
|
489
|
+
let effectiveSelector;
|
|
490
|
+
if (scopeTarget) {
|
|
491
|
+
try {
|
|
492
|
+
scopedResolution = await resolveScopedExtractContext({
|
|
493
|
+
page: sourcePage,
|
|
494
|
+
scopeTarget,
|
|
495
|
+
validateDomSignature: Boolean(targetScope),
|
|
496
|
+
});
|
|
497
|
+
cleanupScopedExtract = scopedResolution.cleanup;
|
|
498
|
+
page = scopedResolution.page;
|
|
499
|
+
effectiveSelector = scopedResolution.selector;
|
|
500
|
+
}
|
|
501
|
+
catch (error) {
|
|
502
|
+
if (error instanceof Error &&
|
|
503
|
+
error.message === 'stale_scope_target_dom_signature_changed') {
|
|
504
|
+
staleScope = true;
|
|
505
|
+
staleReason = 'dom-signature-mismatch';
|
|
506
|
+
}
|
|
507
|
+
else if (surfaceScope &&
|
|
508
|
+
surfaceExtractScopeLifetime(surfaceScope) === 'snapshot' &&
|
|
509
|
+
error instanceof Error &&
|
|
510
|
+
error.message === 'scope_target_unresolvable') {
|
|
511
|
+
return buildExtractContractFailureResult(session, {
|
|
512
|
+
step: extractStep,
|
|
513
|
+
error: 'expired_extract_scope',
|
|
514
|
+
outcomeType: 'binding_stale',
|
|
515
|
+
message: 'Extraction failed because the requested snapshot scope expired before it could be rebound.',
|
|
516
|
+
reason: `Snapshot scope ${scopeRef} is no longer present in the current visible page state.`,
|
|
517
|
+
scopeRef,
|
|
518
|
+
pageRef,
|
|
519
|
+
staleScope: true,
|
|
520
|
+
staleReason: 'snapshot-scope-expired',
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
throw error;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
setCurrentPage(session, pageRef);
|
|
527
|
+
const execution = await executeStagehandExtract({
|
|
528
|
+
session,
|
|
529
|
+
instruction,
|
|
530
|
+
schema: normalizedSchema.schema,
|
|
531
|
+
page,
|
|
532
|
+
selector: effectiveSelector,
|
|
533
|
+
degradationReason: scopedResolution?.degraded
|
|
534
|
+
? scopedResolution.degradationReason
|
|
535
|
+
: undefined,
|
|
536
|
+
});
|
|
537
|
+
let data = execution.data;
|
|
538
|
+
if (scopeTarget &&
|
|
539
|
+
effectiveSelector &&
|
|
540
|
+
normalizedSchema.requestsScopedDialogText &&
|
|
541
|
+
data &&
|
|
542
|
+
typeof data === 'object' &&
|
|
543
|
+
!Array.isArray(data)) {
|
|
544
|
+
const dialogText = await readScopedDialogText(page, effectiveSelector);
|
|
545
|
+
if (typeof dialogText === 'string' && dialogText.trim().length > 0) {
|
|
546
|
+
data = {
|
|
547
|
+
...data,
|
|
548
|
+
dialog_text: dialogText,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return buildExtractSuccessResult(session, extractStep, {
|
|
553
|
+
success: true,
|
|
554
|
+
...execution,
|
|
555
|
+
data,
|
|
556
|
+
pageRef,
|
|
557
|
+
scopeRef,
|
|
558
|
+
metrics: session.runtime?.metrics,
|
|
559
|
+
url,
|
|
560
|
+
title,
|
|
507
561
|
});
|
|
508
|
-
cleanupScopedExtract = scopedResolution.cleanup;
|
|
509
|
-
page = scopedResolution.page;
|
|
510
|
-
effectiveSelector = scopedResolution.selector;
|
|
511
562
|
}
|
|
512
|
-
catch (
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
563
|
+
catch (err) {
|
|
564
|
+
if (staleScope && scopeRef) {
|
|
565
|
+
if (targetScope) {
|
|
566
|
+
markTargetLifecycle(session, scopeRef, 'stale', staleReason ?? 'unknown');
|
|
567
|
+
}
|
|
568
|
+
else if (surfaceScope) {
|
|
569
|
+
markSurfaceLifecycle(session, scopeRef, 'stale', staleReason ?? 'unknown');
|
|
570
|
+
}
|
|
517
571
|
}
|
|
518
|
-
|
|
519
|
-
surfaceExtractScopeLifetime(surfaceScope) === 'snapshot' &&
|
|
520
|
-
error instanceof Error &&
|
|
521
|
-
error.message === 'scope_target_unresolvable') {
|
|
572
|
+
if (!staleScope && err instanceof AssistiveStructuredOutputTruncatedError) {
|
|
522
573
|
return buildExtractContractFailureResult(session, {
|
|
523
574
|
step: extractStep,
|
|
524
|
-
error: '
|
|
525
|
-
outcomeType: '
|
|
526
|
-
message: 'Extraction failed because the
|
|
527
|
-
reason:
|
|
575
|
+
error: 'extract_output_truncated',
|
|
576
|
+
outcomeType: 'blocked',
|
|
577
|
+
message: 'Extraction failed because the provider truncated structured output.',
|
|
578
|
+
reason: buildTruncationReason(err),
|
|
528
579
|
scopeRef,
|
|
529
580
|
pageRef,
|
|
530
|
-
staleScope:
|
|
531
|
-
|
|
581
|
+
staleScope: false,
|
|
582
|
+
provider: err.provider,
|
|
583
|
+
model: err.model,
|
|
584
|
+
finishReason: err.finishReason,
|
|
585
|
+
maxOutputTokens: err.maxOutputTokens,
|
|
586
|
+
completionTokens: err.completionTokens,
|
|
532
587
|
});
|
|
533
588
|
}
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
setCurrentPage(session, pageRef);
|
|
538
|
-
const execution = await executeStagehandExtract({
|
|
539
|
-
session,
|
|
540
|
-
instruction,
|
|
541
|
-
schema: normalizedSchema.schema,
|
|
542
|
-
page,
|
|
543
|
-
selector: effectiveSelector,
|
|
544
|
-
degradationReason: scopedResolution?.degraded
|
|
545
|
-
? scopedResolution.degradationReason
|
|
546
|
-
: undefined,
|
|
547
|
-
});
|
|
548
|
-
let data = execution.data;
|
|
549
|
-
if (scopeTarget &&
|
|
550
|
-
effectiveSelector &&
|
|
551
|
-
normalizedSchema.requestsScopedDialogText &&
|
|
552
|
-
data &&
|
|
553
|
-
typeof data === 'object' &&
|
|
554
|
-
!Array.isArray(data)) {
|
|
555
|
-
const dialogText = await readScopedDialogText(page, effectiveSelector);
|
|
556
|
-
if (typeof dialogText === 'string' && dialogText.trim().length > 0) {
|
|
557
|
-
data = {
|
|
558
|
-
...data,
|
|
559
|
-
dialog_text: dialogText,
|
|
560
|
-
};
|
|
589
|
+
failureMessage = `Extract failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
561
590
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
data,
|
|
567
|
-
pageRef,
|
|
568
|
-
scopeRef,
|
|
569
|
-
metrics: session.runtime?.metrics,
|
|
570
|
-
url,
|
|
571
|
-
title,
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
catch (err) {
|
|
575
|
-
if (staleScope && scopeRef) {
|
|
576
|
-
if (targetScope) {
|
|
577
|
-
markTargetLifecycle(session, scopeRef, 'stale', staleReason ?? 'unknown');
|
|
591
|
+
finally {
|
|
592
|
+
if (cleanupScopedExtract) {
|
|
593
|
+
await cleanupScopedExtract().catch(() => undefined);
|
|
594
|
+
}
|
|
578
595
|
}
|
|
579
|
-
|
|
580
|
-
|
|
596
|
+
if (failureMessage) {
|
|
597
|
+
return buildExtractContractFailureResult(session, {
|
|
598
|
+
step: extractStep,
|
|
599
|
+
error: staleScope ? 'stale_extract_scope' : 'extract_failed',
|
|
600
|
+
outcomeType: staleScope ? 'binding_stale' : 'blocked',
|
|
601
|
+
message: staleScope
|
|
602
|
+
? 'Extraction failed because the requested scope became stale.'
|
|
603
|
+
: 'Extraction failed.',
|
|
604
|
+
reason: staleScope && scopeRef
|
|
605
|
+
? `${failureMessage} (${scopeRef} marked stale: ${staleReason ?? 'stale'})`
|
|
606
|
+
: failureMessage.replace(/^Extract failed:\s*/, ''),
|
|
607
|
+
scopeRef,
|
|
608
|
+
pageRef,
|
|
609
|
+
staleScope,
|
|
610
|
+
staleReason: staleReason ?? undefined,
|
|
611
|
+
});
|
|
581
612
|
}
|
|
582
|
-
}
|
|
583
|
-
if (!staleScope && err instanceof AssistiveStructuredOutputTruncatedError) {
|
|
584
613
|
return buildExtractContractFailureResult(session, {
|
|
585
614
|
step: extractStep,
|
|
586
|
-
error: '
|
|
615
|
+
error: 'extract_failed',
|
|
587
616
|
outcomeType: 'blocked',
|
|
588
|
-
message: 'Extraction failed
|
|
589
|
-
reason:
|
|
617
|
+
message: 'Extraction failed.',
|
|
618
|
+
reason: 'Extraction did not produce a success or failure result.',
|
|
590
619
|
scopeRef,
|
|
591
620
|
pageRef,
|
|
592
|
-
staleScope: false,
|
|
593
|
-
provider: err.provider,
|
|
594
|
-
model: err.model,
|
|
595
|
-
finishReason: err.finishReason,
|
|
596
|
-
maxOutputTokens: err.maxOutputTokens,
|
|
597
|
-
completionTokens: err.completionTokens,
|
|
598
621
|
});
|
|
599
|
-
}
|
|
600
|
-
failureMessage = `Extract failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
601
|
-
}
|
|
602
|
-
finally {
|
|
603
|
-
if (cleanupScopedExtract) {
|
|
604
|
-
await cleanupScopedExtract().catch(() => undefined);
|
|
605
|
-
}
|
|
606
|
-
if (browser) {
|
|
607
|
-
await disconnectPlaywright(browser);
|
|
608
|
-
}
|
|
622
|
+
});
|
|
609
623
|
}
|
|
610
|
-
|
|
624
|
+
catch (err) {
|
|
625
|
+
const browserConnectionFailure = describeBrowserConnectionFailure(err, {
|
|
626
|
+
defaultMessage: 'Extraction could not start because AgentBrowse failed to connect to the browser.',
|
|
627
|
+
unrecoverableSessionMessage: 'Extraction could not start because the previous browser session is no longer reachable.',
|
|
628
|
+
});
|
|
611
629
|
return buildExtractContractFailureResult(session, {
|
|
612
630
|
step: extractStep,
|
|
613
|
-
error:
|
|
614
|
-
outcomeType:
|
|
615
|
-
message:
|
|
616
|
-
|
|
617
|
-
: 'Extraction failed.',
|
|
618
|
-
reason: staleScope && scopeRef
|
|
619
|
-
? `${failureMessage} (${scopeRef} marked stale: ${staleReason ?? 'stale'})`
|
|
620
|
-
: failureMessage.replace(/^Extract failed:\s*/, ''),
|
|
631
|
+
error: 'browser_connection_failed',
|
|
632
|
+
outcomeType: 'blocked',
|
|
633
|
+
message: browserConnectionFailure.message,
|
|
634
|
+
reason: browserConnectionFailure.reason,
|
|
621
635
|
scopeRef,
|
|
622
636
|
pageRef,
|
|
623
|
-
staleScope,
|
|
624
|
-
staleReason: staleReason ?? undefined,
|
|
625
637
|
});
|
|
626
638
|
}
|
|
627
|
-
return buildExtractContractFailureResult(session, {
|
|
628
|
-
step: extractStep,
|
|
629
|
-
error: 'extract_failed',
|
|
630
|
-
outcomeType: 'blocked',
|
|
631
|
-
message: 'Extraction failed.',
|
|
632
|
-
reason: 'Extraction did not produce a success or failure result.',
|
|
633
|
-
scopeRef,
|
|
634
|
-
pageRef,
|
|
635
|
-
});
|
|
636
639
|
});
|
|
637
640
|
}
|
|
638
641
|
/** CLI wrapper for `extractBrowser(...)` that accepts JSON text or schema objects. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/commands/launch.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/commands/launch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqB,KAAK,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAW1F,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,oCAAqC,CAAC;AAErE,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,sBAAuB,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wCAAwC;AACxC,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,SAAS,CAAC;IACnB,mBAAmB,EAAE,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,EAAE,wBAAwB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAErE,4EAA4E;AAC5E,wBAAsB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAOtF"}
|
package/dist/commands/launch.js
CHANGED
|
@@ -5,8 +5,9 @@ import { buildOwnedSession } from '../browser-session-state.js';
|
|
|
5
5
|
import { getConfigPath, readConfig } from '../solver/config.js';
|
|
6
6
|
import { launchSolver } from '../solver/browser-launcher.js';
|
|
7
7
|
import { ensureProfile } from '../solver/profile-manager.js';
|
|
8
|
-
import {
|
|
8
|
+
import { syncLaunchPage } from '../playwright-runtime.js';
|
|
9
9
|
import { info } from '../output.js';
|
|
10
|
+
import { initializeBrowserSessionOwner, withStickyOwnerBrowser } from '../sticky-owner.js';
|
|
10
11
|
const DEFAULT_PROFILE = 'default';
|
|
11
12
|
/** Stable top-level error codes returned by `launch(...)`. */
|
|
12
13
|
export const LAUNCH_ERROR_CODES = ['browser_launch_failed'];
|
|
@@ -31,7 +32,6 @@ function buildLaunchFailure(err) {
|
|
|
31
32
|
}
|
|
32
33
|
async function launchManaged(url, profileName, headless, useProxy = false, proxyOverride) {
|
|
33
34
|
let session;
|
|
34
|
-
let browser = null;
|
|
35
35
|
let runtimeProxy;
|
|
36
36
|
try {
|
|
37
37
|
const baseProfile = ensureProfile(profileName);
|
|
@@ -72,15 +72,21 @@ async function launchManaged(url, profileName, headless, useProxy = false, proxy
|
|
|
72
72
|
captchaSolve: true,
|
|
73
73
|
},
|
|
74
74
|
});
|
|
75
|
+
try {
|
|
76
|
+
await initializeBrowserSessionOwner(persistedSession);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
await session.disconnect().catch(() => undefined);
|
|
80
|
+
return buildLaunchFailure(error);
|
|
81
|
+
}
|
|
75
82
|
let currentUrl = session.page.url();
|
|
76
83
|
let title = await session.page.title().catch(() => '');
|
|
77
84
|
try {
|
|
78
|
-
|
|
79
|
-
const syncedPage = await syncLaunchPage(persistedSession, browser, {
|
|
85
|
+
const syncedPage = await withStickyOwnerBrowser(persistedSession, (browser) => syncLaunchPage(persistedSession, browser, {
|
|
80
86
|
requestedUrl: url,
|
|
81
87
|
fallbackUrl: currentUrl,
|
|
82
88
|
fallbackTitle: title,
|
|
83
|
-
});
|
|
89
|
+
}));
|
|
84
90
|
currentUrl = syncedPage.url;
|
|
85
91
|
title = syncedPage.title;
|
|
86
92
|
}
|
|
@@ -88,9 +94,6 @@ async function launchManaged(url, profileName, headless, useProxy = false, proxy
|
|
|
88
94
|
// Preserve the successful launch and fall back to the launcher snapshot.
|
|
89
95
|
}
|
|
90
96
|
finally {
|
|
91
|
-
if (browser) {
|
|
92
|
-
await disconnectPlaywright(browser);
|
|
93
|
-
}
|
|
94
97
|
await session.disconnect();
|
|
95
98
|
}
|
|
96
99
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/commands/navigate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/commands/navigate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAezE,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,6DAA8D,CAAC;AAEhG,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB,8CAA+C,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,yDAAyD;AACzD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,mEAAmE;AACnE,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;AAiD3E,0DAA0D;AAC1D,wBAAsB,eAAe,CACnC,OAAO,EAAE,qBAAqB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CA+JzB;AAED,+FAA+F;AAC/F,wBAAsB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY/F"}
|