@mearl/native-host 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agentbay-browser.d.ts +6 -3
- package/dist/index.js +99 -20
- package/package.json +4 -4
|
@@ -14,7 +14,6 @@ export interface AgentBayBrowserRecord extends DaemonRecord {
|
|
|
14
14
|
contextName?: string;
|
|
15
15
|
/** Successful context sync checkpoint for retrying deletion of the current session. */
|
|
16
16
|
contextSyncedAt?: string;
|
|
17
|
-
accessUrl?: string;
|
|
18
17
|
createdAt: string;
|
|
19
18
|
copiedCookies?: {
|
|
20
19
|
domains: string[];
|
|
@@ -23,11 +22,15 @@ export interface AgentBayBrowserRecord extends DaemonRecord {
|
|
|
23
22
|
}
|
|
24
23
|
export interface AgentBaySessionLike {
|
|
25
24
|
sessionId: string;
|
|
26
|
-
resourceUrl?: string;
|
|
27
25
|
browser: {
|
|
28
26
|
initializeAsync(options: Record<string, unknown>): Promise<boolean>;
|
|
29
27
|
getEndpointUrl(): Promise<string>;
|
|
30
28
|
};
|
|
29
|
+
info?(): Promise<{
|
|
30
|
+
success?: boolean;
|
|
31
|
+
data?: unknown;
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
}>;
|
|
31
34
|
callMcpTool?(toolName: string, args: Record<string, unknown>, autoGenSession?: boolean): Promise<{
|
|
32
35
|
success?: boolean;
|
|
33
36
|
errorMessage?: string;
|
|
@@ -86,7 +89,6 @@ export interface AgentBayBrowserSummary {
|
|
|
86
89
|
agentbayImageId?: string;
|
|
87
90
|
agentbayContextId?: string;
|
|
88
91
|
agentbayContextName?: string;
|
|
89
|
-
agentbayAccessUrl?: string;
|
|
90
92
|
createdAt: string;
|
|
91
93
|
copiedCookies?: AgentBayBrowserRecord['copiedCookies'];
|
|
92
94
|
running: boolean;
|
|
@@ -118,6 +120,7 @@ export declare function normalizeDesktopUserAgent(value: unknown): string;
|
|
|
118
120
|
export declare function normalizeAgentBayAccessUrl(value: unknown): string | undefined;
|
|
119
121
|
export declare function hasAgentBayBrowser(selector: string): boolean;
|
|
120
122
|
export declare function listAgentBayBrowsers(): AgentBayBrowserSummary[];
|
|
123
|
+
export declare function getAgentBayAccessUrl(sessionId: string, dependencies?: Pick<AgentBayBrowserManagerDeps, 'createAgentBayClient' | 'resolveApiKey'>): Promise<string>;
|
|
121
124
|
export declare function resolveAgentBayEndpoint(sessionId: string): Promise<string>;
|
|
122
125
|
export declare function keepAgentBaySessionAlive(sessionId: string): Promise<void>;
|
|
123
126
|
export declare function initializeAgentBayBrowserSession(session: Pick<AgentBaySessionLike, 'browser'>, input: Pick<BrowserLaunchParams, 'url'>, cookies: TransferableCookie[], options?: AgentBayBrowserSessionInitOptions): Promise<number>;
|
package/dist/index.js
CHANGED
|
@@ -4795,7 +4795,15 @@ async function discoverTargets(port = 9222) {
|
|
|
4795
4795
|
});
|
|
4796
4796
|
}
|
|
4797
4797
|
async function isCdpAvailable(port = 9222, userDataDir) {
|
|
4798
|
-
|
|
4798
|
+
const activePort = readDevToolsActivePort(userDataDir)?.port;
|
|
4799
|
+
if (activePort !== void 0) {
|
|
4800
|
+
try {
|
|
4801
|
+
await discoverTargets(activePort);
|
|
4802
|
+
return true;
|
|
4803
|
+
} catch {
|
|
4804
|
+
if (activePort === port) return false;
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4799
4807
|
try {
|
|
4800
4808
|
await discoverTargets(port);
|
|
4801
4809
|
return true;
|
|
@@ -9608,7 +9616,6 @@ function normalizeAgentBayAccessUrl(value) {
|
|
|
9608
9616
|
}
|
|
9609
9617
|
}
|
|
9610
9618
|
function browserSummary2(record2, running) {
|
|
9611
|
-
const accessUrl = normalizeAgentBayAccessUrl(record2.accessUrl);
|
|
9612
9619
|
return {
|
|
9613
9620
|
browserId: record2.browserId,
|
|
9614
9621
|
name: record2.name,
|
|
@@ -9619,7 +9626,6 @@ function browserSummary2(record2, running) {
|
|
|
9619
9626
|
...record2.imageId ? { agentbayImageId: record2.imageId } : {},
|
|
9620
9627
|
...record2.contextId ? { agentbayContextId: record2.contextId } : {},
|
|
9621
9628
|
...record2.contextName ? { agentbayContextName: record2.contextName } : {},
|
|
9622
|
-
...accessUrl ? { agentbayAccessUrl: accessUrl } : {},
|
|
9623
9629
|
createdAt: record2.createdAt,
|
|
9624
9630
|
...record2.copiedCookies ? { copiedCookies: record2.copiedCookies } : {},
|
|
9625
9631
|
running
|
|
@@ -9628,11 +9634,13 @@ function browserSummary2(record2, running) {
|
|
|
9628
9634
|
function listRecords2() {
|
|
9629
9635
|
const records = [];
|
|
9630
9636
|
for (const file2 of listRecordFiles(keyedDir(AGENTBAY_BROWSERS_SUBDIR))) {
|
|
9631
|
-
const
|
|
9632
|
-
if (!
|
|
9637
|
+
const stored = readRecord(file2);
|
|
9638
|
+
if (!stored) {
|
|
9633
9639
|
removeRecord(file2);
|
|
9634
9640
|
continue;
|
|
9635
9641
|
}
|
|
9642
|
+
const { accessUrl: legacyAccessUrl, ...record2 } = stored;
|
|
9643
|
+
if (legacyAccessUrl !== void 0) writeRecord(file2, record2);
|
|
9636
9644
|
const running = isManagedProcess(record2.pid, `--browser-id ${record2.browserId}`);
|
|
9637
9645
|
if (!running) removeRecord(keyedConfigFile("browsers", record2.browserId));
|
|
9638
9646
|
records.push({ record: record2, running });
|
|
@@ -9662,6 +9670,26 @@ async function requireSessionFromClient(agentBay, sessionId) {
|
|
|
9662
9670
|
}
|
|
9663
9671
|
return result.session;
|
|
9664
9672
|
}
|
|
9673
|
+
async function getAgentBayAccessUrl(sessionId, dependencies = {}) {
|
|
9674
|
+
const apiKey = (dependencies.resolveApiKey ?? resolveAgentBayApiKey)();
|
|
9675
|
+
const agentBay = dependencies.createAgentBayClient ? await dependencies.createAgentBayClient(apiKey) : await createClient(apiKey);
|
|
9676
|
+
const session = await requireSessionFromClient(agentBay, sessionId);
|
|
9677
|
+
if (!session.info) {
|
|
9678
|
+
throw new Error("The installed AgentBay SDK does not support live session information");
|
|
9679
|
+
}
|
|
9680
|
+
const result = await session.info();
|
|
9681
|
+
if (result.success === false) {
|
|
9682
|
+
throw new Error(result.errorMessage || `AgentBay session info failed: ${sessionId}`);
|
|
9683
|
+
}
|
|
9684
|
+
const data = result.data && typeof result.data === "object" ? result.data : null;
|
|
9685
|
+
const accessUrl = normalizeAgentBayAccessUrl(
|
|
9686
|
+
data && "resourceUrl" in data ? data.resourceUrl : void 0
|
|
9687
|
+
);
|
|
9688
|
+
if (!accessUrl) {
|
|
9689
|
+
throw new Error(`AgentBay session did not return a browser access URL: ${sessionId}`);
|
|
9690
|
+
}
|
|
9691
|
+
return accessUrl;
|
|
9692
|
+
}
|
|
9665
9693
|
async function resolvePersistentContext(agentBay, browserId) {
|
|
9666
9694
|
if (!agentBay.context) {
|
|
9667
9695
|
throw new Error("The installed AgentBay SDK does not support persistent browser contexts");
|
|
@@ -9779,7 +9807,6 @@ async function launchAgentBayBrowser(input, deps) {
|
|
|
9779
9807
|
hostPid = host.pid ?? 0;
|
|
9780
9808
|
if (!hostPid) throw new Error("AgentBay native host launched without a process id");
|
|
9781
9809
|
host.unref();
|
|
9782
|
-
const accessUrl = normalizeAgentBayAccessUrl(session.resourceUrl);
|
|
9783
9810
|
const record2 = {
|
|
9784
9811
|
pid: hostPid,
|
|
9785
9812
|
browserId,
|
|
@@ -9788,7 +9815,6 @@ async function launchAgentBayBrowser(input, deps) {
|
|
|
9788
9815
|
imageId,
|
|
9789
9816
|
persistent,
|
|
9790
9817
|
...context ? { contextId: context.id, contextName: context.name } : {},
|
|
9791
|
-
...accessUrl ? { accessUrl } : {},
|
|
9792
9818
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9793
9819
|
...copyCookieDomains.length > 0 ? { copiedCookies: { domains: copyCookieDomains, count: copiedCookieCount } } : {}
|
|
9794
9820
|
};
|
|
@@ -9814,7 +9840,6 @@ async function launchAgentBayBrowser(input, deps) {
|
|
|
9814
9840
|
cleanupError = deleteError;
|
|
9815
9841
|
}
|
|
9816
9842
|
if (cleanupError) {
|
|
9817
|
-
const accessUrl = normalizeAgentBayAccessUrl(session.resourceUrl);
|
|
9818
9843
|
const recoveryRecord = {
|
|
9819
9844
|
pid: hostPid,
|
|
9820
9845
|
browserId,
|
|
@@ -9823,7 +9848,6 @@ async function launchAgentBayBrowser(input, deps) {
|
|
|
9823
9848
|
imageId,
|
|
9824
9849
|
persistent,
|
|
9825
9850
|
...context ? { contextId: context.id, contextName: context.name } : {},
|
|
9826
|
-
...accessUrl ? { accessUrl } : {},
|
|
9827
9851
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9828
9852
|
};
|
|
9829
9853
|
let recoverySaved = false;
|
|
@@ -10098,7 +10122,6 @@ function mergeBrowserInventory(connected, managed) {
|
|
|
10098
10122
|
..."agentbayImageId" in managedBrowser && managedBrowser.agentbayImageId ? { agentbayImageId: managedBrowser.agentbayImageId } : {},
|
|
10099
10123
|
..."agentbayContextId" in managedBrowser && managedBrowser.agentbayContextId ? { agentbayContextId: managedBrowser.agentbayContextId } : {},
|
|
10100
10124
|
..."agentbayContextName" in managedBrowser && managedBrowser.agentbayContextName ? { agentbayContextName: managedBrowser.agentbayContextName } : {},
|
|
10101
|
-
..."agentbayAccessUrl" in managedBrowser && managedBrowser.agentbayAccessUrl ? { agentbayAccessUrl: managedBrowser.agentbayAccessUrl } : {},
|
|
10102
10125
|
createdAt: managedBrowser.createdAt,
|
|
10103
10126
|
..."account" in managedBrowser ? { account: managedBrowser.account } : {},
|
|
10104
10127
|
..."copiedCookies" in managedBrowser ? { copiedCookies: managedBrowser.copiedCookies } : {}
|
|
@@ -10117,7 +10140,6 @@ function mergeBrowserInventory(connected, managed) {
|
|
|
10117
10140
|
..."agentbayImageId" in browser && browser.agentbayImageId ? { agentbayImageId: browser.agentbayImageId } : {},
|
|
10118
10141
|
..."agentbayContextId" in browser && browser.agentbayContextId ? { agentbayContextId: browser.agentbayContextId } : {},
|
|
10119
10142
|
..."agentbayContextName" in browser && browser.agentbayContextName ? { agentbayContextName: browser.agentbayContextName } : {},
|
|
10120
|
-
..."agentbayAccessUrl" in browser && browser.agentbayAccessUrl ? { agentbayAccessUrl: browser.agentbayAccessUrl } : {},
|
|
10121
10143
|
createdAt: browser.createdAt,
|
|
10122
10144
|
..."account" in browser ? { account: browser.account } : {},
|
|
10123
10145
|
..."copiedCookies" in browser ? { copiedCookies: browser.copiedCookies } : {}
|
|
@@ -10141,7 +10163,7 @@ import os2 from "node:os";
|
|
|
10141
10163
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10142
10164
|
|
|
10143
10165
|
// src/version.ts
|
|
10144
|
-
var NATIVE_HOST_VERSION = true ? "2.
|
|
10166
|
+
var NATIVE_HOST_VERSION = true ? "2.6.0" : "unknown";
|
|
10145
10167
|
|
|
10146
10168
|
// src/analytics.ts
|
|
10147
10169
|
var MEASUREMENT_ID = "G-W84LJDZ6PH";
|
|
@@ -30795,6 +30817,7 @@ var nativeMessageBuffer = Buffer.alloc(0);
|
|
|
30795
30817
|
var socketServer = null;
|
|
30796
30818
|
var legacyServer = null;
|
|
30797
30819
|
var inventoryExitTimer = null;
|
|
30820
|
+
var cdpRegistrationTimer = null;
|
|
30798
30821
|
function scheduleInventoryExit() {
|
|
30799
30822
|
if (inventoryExitTimer) clearTimeout(inventoryExitTimer);
|
|
30800
30823
|
inventoryExitTimer = setTimeout(() => cleanupAndExit(0), INVENTORY_IDLE_EXIT_MS);
|
|
@@ -31104,6 +31127,24 @@ async function handleSocketLine(socket, line) {
|
|
|
31104
31127
|
socket.write(JSON.stringify({ id, success: true, data: versions }) + "\n");
|
|
31105
31128
|
return;
|
|
31106
31129
|
}
|
|
31130
|
+
if (action === "get_agentbay_access_url") {
|
|
31131
|
+
try {
|
|
31132
|
+
if (!AGENTBAY_SESSION_ID) {
|
|
31133
|
+
throw new Error("The selected browser is not an AgentBay browser");
|
|
31134
|
+
}
|
|
31135
|
+
const agentbayAccessUrl = await getAgentBayAccessUrl(AGENTBAY_SESSION_ID);
|
|
31136
|
+
socket.write(JSON.stringify({ id, success: true, data: { agentbayAccessUrl } }) + "\n");
|
|
31137
|
+
} catch (error48) {
|
|
31138
|
+
socket.write(
|
|
31139
|
+
JSON.stringify({
|
|
31140
|
+
id,
|
|
31141
|
+
success: false,
|
|
31142
|
+
error: error48 instanceof Error ? error48.message : String(error48)
|
|
31143
|
+
}) + "\n"
|
|
31144
|
+
);
|
|
31145
|
+
}
|
|
31146
|
+
return;
|
|
31147
|
+
}
|
|
31107
31148
|
if (isInternalExtensionAction(action)) {
|
|
31108
31149
|
socket.write(
|
|
31109
31150
|
JSON.stringify({ id, success: false, error: "Internal action is not available to clients" }) + "\n"
|
|
@@ -31499,6 +31540,10 @@ function cleanupAndExit(code) {
|
|
|
31499
31540
|
clearTimeout(inventoryExitTimer);
|
|
31500
31541
|
inventoryExitTimer = null;
|
|
31501
31542
|
}
|
|
31543
|
+
if (cdpRegistrationTimer) {
|
|
31544
|
+
clearInterval(cdpRegistrationTimer);
|
|
31545
|
+
cdpRegistrationTimer = null;
|
|
31546
|
+
}
|
|
31502
31547
|
cdpSession?.close();
|
|
31503
31548
|
agentChatManager?.dispose();
|
|
31504
31549
|
agentChatManager = null;
|
|
@@ -31520,6 +31565,47 @@ function restartAfterUpdate() {
|
|
|
31520
31565
|
forcedExit.unref();
|
|
31521
31566
|
cleanupAndExit(0);
|
|
31522
31567
|
}
|
|
31568
|
+
async function isDaemonBrowserAvailable() {
|
|
31569
|
+
if (AGENTBAY_SESSION_ID) {
|
|
31570
|
+
return getCdpSession().getBrowserClient().then(
|
|
31571
|
+
() => true,
|
|
31572
|
+
() => false
|
|
31573
|
+
);
|
|
31574
|
+
}
|
|
31575
|
+
return isCdpAvailable(CDP_PORT, CDP_USER_DATA_DIR);
|
|
31576
|
+
}
|
|
31577
|
+
async function monitorDaemonBrowser() {
|
|
31578
|
+
let published = false;
|
|
31579
|
+
let checking = false;
|
|
31580
|
+
const refresh = async () => {
|
|
31581
|
+
if (checking) return;
|
|
31582
|
+
checking = true;
|
|
31583
|
+
try {
|
|
31584
|
+
const available = await isDaemonBrowserAvailable();
|
|
31585
|
+
if (available && !published) {
|
|
31586
|
+
registerBrowser({
|
|
31587
|
+
browserId: CDP_BROWSER_ID,
|
|
31588
|
+
socketPath: INSTANCE_SOCKET_PATH,
|
|
31589
|
+
browserName: CDP_BROWSER_NAME,
|
|
31590
|
+
nativeHostVersion: NATIVE_HOST_VERSION,
|
|
31591
|
+
transport: "cdp",
|
|
31592
|
+
lastFocusedAt: CDP_BROWSER_ID.startsWith("managed:") ? 0 : void 0
|
|
31593
|
+
});
|
|
31594
|
+
published = true;
|
|
31595
|
+
} else if (!available && published) {
|
|
31596
|
+
unregisterBrowser();
|
|
31597
|
+
published = false;
|
|
31598
|
+
}
|
|
31599
|
+
} finally {
|
|
31600
|
+
checking = false;
|
|
31601
|
+
}
|
|
31602
|
+
};
|
|
31603
|
+
await refresh();
|
|
31604
|
+
cdpRegistrationTimer = setInterval(() => {
|
|
31605
|
+
void refresh();
|
|
31606
|
+
}, 2e3);
|
|
31607
|
+
cdpRegistrationTimer.unref();
|
|
31608
|
+
}
|
|
31523
31609
|
async function main() {
|
|
31524
31610
|
initBrowserRegistry({ log });
|
|
31525
31611
|
pruneDeadBrowsers();
|
|
@@ -31541,14 +31627,7 @@ async function main() {
|
|
|
31541
31627
|
return;
|
|
31542
31628
|
}
|
|
31543
31629
|
if (isDaemonMode && !skipBrowserRegistration) {
|
|
31544
|
-
|
|
31545
|
-
browserId: CDP_BROWSER_ID,
|
|
31546
|
-
socketPath: INSTANCE_SOCKET_PATH,
|
|
31547
|
-
browserName: CDP_BROWSER_NAME,
|
|
31548
|
-
nativeHostVersion: NATIVE_HOST_VERSION,
|
|
31549
|
-
transport: "cdp",
|
|
31550
|
-
lastFocusedAt: CDP_BROWSER_ID.startsWith("managed:") ? 0 : void 0
|
|
31551
|
-
});
|
|
31630
|
+
await monitorDaemonBrowser();
|
|
31552
31631
|
}
|
|
31553
31632
|
if (AGENTBAY_SESSION_ID) {
|
|
31554
31633
|
const keepAliveTimer = setInterval(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/native-host",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Native Messaging Host for Mearl — bridges Chrome Extension and local socket server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/install.js",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"@types/ws": "^8.18.1",
|
|
38
38
|
"esbuild": "^0.25.2",
|
|
39
39
|
"typescript": "^5.8.3",
|
|
40
|
-
"@mearl/browser-core": "2.
|
|
41
|
-
"@mearl/daemon-core": "2.
|
|
42
|
-
"@mearl/setup": "2.
|
|
40
|
+
"@mearl/browser-core": "2.6.0",
|
|
41
|
+
"@mearl/daemon-core": "2.6.0",
|
|
42
|
+
"@mearl/setup": "2.6.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "rm -rf dist/ && node build.mjs",
|