@mearl/native-host 2.5.1 → 2.6.1

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.
@@ -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
- if (readDevToolsActivePort(userDataDir) !== null) return true;
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 record2 = readRecord(file2);
9632
- if (!record2) {
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.5.1" : "unknown";
10166
+ var NATIVE_HOST_VERSION = true ? "2.6.1" : "unknown";
10145
10167
 
10146
10168
  // src/analytics.ts
10147
10169
  var MEASUREMENT_ID = "G-W84LJDZ6PH";
@@ -30786,7 +30808,7 @@ function buildVersionWarning(clientVersion) {
30786
30808
  versionList,
30787
30809
  "",
30788
30810
  "This may cause unexpected behavior. To update:",
30789
- " npm install -g @mearl/native-host@latest @mearl/client@latest",
30811
+ " npx @mearl/setup update --local",
30790
30812
  ` Browser extension: ${EXTENSION_INSTALL_URL}`
30791
30813
  ].join("\n");
30792
30814
  }
@@ -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
- registerBrowser({
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.5.1",
3
+ "version": "2.6.1",
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.5.1",
41
- "@mearl/daemon-core": "2.5.1",
42
- "@mearl/setup": "2.5.1"
40
+ "@mearl/browser-core": "2.6.1",
41
+ "@mearl/setup": "2.6.1",
42
+ "@mearl/daemon-core": "2.6.1"
43
43
  },
44
44
  "scripts": {
45
45
  "build": "rm -rf dist/ && node build.mjs",