@mearl/client 2.21.0 → 3.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -27
  3. package/dist/actionTimeouts.js +1 -1
  4. package/dist/artifacts.d.ts +1 -1
  5. package/dist/autoUpdate.js +1 -2
  6. package/dist/browserRegistry.d.ts +1 -1
  7. package/dist/check.d.ts +1 -1
  8. package/dist/check.js +4 -3
  9. package/dist/cli.js +4 -3
  10. package/dist/commands.d.ts +20 -20
  11. package/dist/commands.js +17 -15
  12. package/dist/index.d.ts +12 -15
  13. package/dist/index.js +7 -7
  14. package/dist/local.d.ts +3 -1
  15. package/dist/local.js +2 -1
  16. package/dist/pageEvalArguments.d.ts +1 -1
  17. package/dist/pageEvalArguments.js +1 -1
  18. package/dist/plugin-task-host.js +1 -1
  19. package/dist/plugin-worker.js +2 -2
  20. package/dist/plugin.d.ts +2 -118
  21. package/dist/plugin.js +2 -672
  22. package/dist/pluginModelSessionWorker.d.ts +2 -2
  23. package/dist/pluginModelSessionWorker.js +4 -4
  24. package/dist/{pluginHostConnection.d.ts → plugins/clients/pluginHostConnection.d.ts} +2 -2
  25. package/dist/{pluginHostConnection.js → plugins/clients/pluginHostConnection.js} +6 -7
  26. package/dist/{pluginModels.d.ts → plugins/clients/pluginModels.d.ts} +3 -3
  27. package/dist/{pluginPages.d.ts → plugins/clients/pluginPages.d.ts} +3 -3
  28. package/dist/{pluginPages.js → plugins/clients/pluginPages.js} +1 -1
  29. package/dist/{pluginState.d.ts → plugins/clients/pluginState.d.ts} +3 -3
  30. package/dist/{pluginTasks.d.ts → plugins/clients/pluginTasks.d.ts} +4 -4
  31. package/dist/{pluginTasks.js → plugins/clients/pluginTasks.js} +4 -4
  32. package/dist/plugins/officialPluginCatalog.d.ts +25 -0
  33. package/dist/plugins/officialPluginCatalog.js +125 -0
  34. package/dist/{officialPluginInstaller.js → plugins/officialPluginInstaller.js} +7 -4
  35. package/dist/{pluginRegistry.d.ts → plugins/pluginRegistry.d.ts} +1 -1
  36. package/dist/{pluginRegistry.js → plugins/pluginRegistry.js} +3 -3
  37. package/dist/{pluginTaskProtocol.d.ts → plugins/pluginTaskProtocol.d.ts} +2 -2
  38. package/dist/{pluginCommandWorker.js → plugins/runtime/pluginCommandWorker.js} +3 -3
  39. package/dist/{pluginDiagnostics.d.ts → plugins/runtime/pluginDiagnostics.d.ts} +4 -4
  40. package/dist/{pluginDiagnostics.js → plugins/runtime/pluginDiagnostics.js} +2 -2
  41. package/dist/{pluginExecution.d.ts → plugins/runtime/pluginExecution.d.ts} +3 -3
  42. package/dist/{pluginExecution.js → plugins/runtime/pluginExecution.js} +1 -1
  43. package/dist/{pluginExecutor.d.ts → plugins/runtime/pluginExecutor.d.ts} +3 -3
  44. package/dist/{pluginExecutor.js → plugins/runtime/pluginExecutor.js} +4 -4
  45. package/dist/{pluginExecutorProtocol.d.ts → plugins/runtime/pluginExecutorProtocol.d.ts} +4 -4
  46. package/dist/{pluginHost.d.ts → plugins/runtime/pluginHost.d.ts} +3 -3
  47. package/dist/{pluginHostPaths.js → plugins/runtime/pluginHostPaths.js} +1 -1
  48. package/dist/{pluginHostServer.js → plugins/runtime/pluginHostServer.js} +3 -3
  49. package/dist/{pluginModelCatalog.d.ts → plugins/runtime/pluginModelCatalog.d.ts} +1 -1
  50. package/dist/{pluginModelSessions.js → plugins/runtime/pluginModelSessions.js} +3 -3
  51. package/dist/{pluginPageManager.d.ts → plugins/runtime/pluginPageManager.d.ts} +4 -4
  52. package/dist/{pluginPageManager.js → plugins/runtime/pluginPageManager.js} +5 -5
  53. package/dist/{pluginRevision.d.ts → plugins/runtime/pluginRevision.d.ts} +1 -1
  54. package/dist/{pluginRevision.js → plugins/runtime/pluginRevision.js} +3 -2
  55. package/dist/{pluginRuntimeCleanup.js → plugins/runtime/pluginRuntimeCleanup.js} +2 -2
  56. package/dist/{pluginStateManager.d.ts → plugins/runtime/pluginStateManager.d.ts} +2 -2
  57. package/dist/{pluginStateManager.js → plugins/runtime/pluginStateManager.js} +2 -2
  58. package/dist/{pluginStateStore.d.ts → plugins/runtime/pluginStateStore.d.ts} +1 -1
  59. package/dist/{pluginStateStore.js → plugins/runtime/pluginStateStore.js} +1 -1
  60. package/dist/{pluginTaskManager.d.ts → plugins/runtime/pluginTaskManager.d.ts} +12 -12
  61. package/dist/{pluginTaskManager.js → plugins/runtime/pluginTaskManager.js} +6 -6
  62. package/dist/{pluginTaskStore.d.ts → plugins/runtime/pluginTaskStore.d.ts} +4 -4
  63. package/dist/{pluginTaskStore.js → plugins/runtime/pluginTaskStore.js} +1 -1
  64. package/dist/{pythonPlugin.d.ts → plugins/runtime/pythonPlugin.d.ts} +2 -2
  65. package/dist/{pythonPlugin.js → plugins/runtime/pythonPlugin.js} +2 -2
  66. package/dist/plugins/sdk/plugin.d.ts +115 -0
  67. package/dist/plugins/sdk/plugin.js +669 -0
  68. package/dist/{pluginAppProfiles.d.ts → plugins/sdk/pluginAppProfiles.d.ts} +1 -1
  69. package/dist/{pluginAppProfiles.js → plugins/sdk/pluginAppProfiles.js} +2 -2
  70. package/dist/{pluginModelDefinition.d.ts → plugins/sdk/pluginModelDefinition.d.ts} +1 -1
  71. package/dist/{pluginPageDefinition.d.ts → plugins/sdk/pluginPageDefinition.d.ts} +1 -1
  72. package/dist/{pluginPageDefinition.js → plugins/sdk/pluginPageDefinition.js} +1 -1
  73. package/dist/{pluginRecoveryDefinition.d.ts → plugins/sdk/pluginRecoveryDefinition.d.ts} +1 -1
  74. package/dist/{pluginStateDefinition.d.ts → plugins/sdk/pluginStateDefinition.d.ts} +2 -2
  75. package/dist/plugins/skillManifest.d.ts +10 -0
  76. package/dist/plugins/skillManifest.js +56 -0
  77. package/dist/runtimePaths.d.ts +4 -0
  78. package/dist/runtimePaths.js +8 -0
  79. package/dist/socket.d.ts +4 -2
  80. package/dist/socket.js +17 -6
  81. package/dist/unified.d.ts +2 -2
  82. package/dist/unified.js +7 -7
  83. package/package.json +9 -8
  84. package/dist/generated-app-profile-definition.d.ts +0 -130
  85. package/dist/generated-app-profile-definition.js +0 -458
  86. package/dist/generated-app-profile-runtime-types.d.ts +0 -213
  87. package/dist/generated-app-profile-runtime-types.js +0 -1
  88. package/dist/generated-browser-action-protocol.d.ts +0 -1147
  89. package/dist/generated-browser-action-protocol.js +0 -283
  90. package/dist/generated-plugin-diagnostics.d.ts +0 -110
  91. package/dist/generated-plugin-diagnostics.js +0 -1
  92. package/dist/generated-plugin-execution.d.ts +0 -27
  93. package/dist/generated-plugin-execution.js +0 -1
  94. package/dist/generated-plugin-models.d.ts +0 -64
  95. package/dist/generated-plugin-models.js +0 -1
  96. package/dist/generated-plugin-pages.d.ts +0 -76
  97. package/dist/generated-plugin-pages.js +0 -59
  98. package/dist/generated-plugin-recovery.d.ts +0 -32
  99. package/dist/generated-plugin-recovery.js +0 -1
  100. package/dist/generated-plugin-state.d.ts +0 -50
  101. package/dist/generated-plugin-state.js +0 -1
  102. package/dist/generated-plugin-tasks.d.ts +0 -74
  103. package/dist/generated-plugin-tasks.js +0 -7
  104. package/dist/generated-toolbox-icon.d.ts +0 -10
  105. package/dist/generated-toolbox-icon.js +0 -37
  106. package/dist/officialPluginCatalog.d.ts +0 -28
  107. package/dist/officialPluginCatalog.js +0 -29
  108. /package/dist/{pluginModels.js → plugins/clients/pluginModels.js} +0 -0
  109. /package/dist/{pluginState.js → plugins/clients/pluginState.js} +0 -0
  110. /package/dist/{officialPluginInstaller.d.ts → plugins/officialPluginInstaller.d.ts} +0 -0
  111. /package/dist/{pluginPageBundle.d.ts → plugins/pluginPageBundle.d.ts} +0 -0
  112. /package/dist/{pluginPageBundle.js → plugins/pluginPageBundle.js} +0 -0
  113. /package/dist/{pluginSource.d.ts → plugins/pluginSource.d.ts} +0 -0
  114. /package/dist/{pluginSource.js → plugins/pluginSource.js} +0 -0
  115. /package/dist/{pluginTaskProtocol.js → plugins/pluginTaskProtocol.js} +0 -0
  116. /package/dist/{pluginTaskWire.d.ts → plugins/pluginTaskWire.d.ts} +0 -0
  117. /package/dist/{pluginTaskWire.js → plugins/pluginTaskWire.js} +0 -0
  118. /package/dist/{pluginCommandWorker.d.ts → plugins/runtime/pluginCommandWorker.d.ts} +0 -0
  119. /package/dist/{pluginExecutorProtocol.js → plugins/runtime/pluginExecutorProtocol.js} +0 -0
  120. /package/dist/{pluginExecutorSupervisor.d.ts → plugins/runtime/pluginExecutorSupervisor.d.ts} +0 -0
  121. /package/dist/{pluginExecutorSupervisor.js → plugins/runtime/pluginExecutorSupervisor.js} +0 -0
  122. /package/dist/{pluginHost.js → plugins/runtime/pluginHost.js} +0 -0
  123. /package/dist/{pluginHostFiles.d.ts → plugins/runtime/pluginHostFiles.d.ts} +0 -0
  124. /package/dist/{pluginHostFiles.js → plugins/runtime/pluginHostFiles.js} +0 -0
  125. /package/dist/{pluginHostPaths.d.ts → plugins/runtime/pluginHostPaths.d.ts} +0 -0
  126. /package/dist/{pluginHostServer.d.ts → plugins/runtime/pluginHostServer.d.ts} +0 -0
  127. /package/dist/{pluginModelCatalog.js → plugins/runtime/pluginModelCatalog.js} +0 -0
  128. /package/dist/{pluginModelSessions.d.ts → plugins/runtime/pluginModelSessions.d.ts} +0 -0
  129. /package/dist/{pluginProcessTree.d.ts → plugins/runtime/pluginProcessTree.d.ts} +0 -0
  130. /package/dist/{pluginProcessTree.js → plugins/runtime/pluginProcessTree.js} +0 -0
  131. /package/dist/{pluginRuntimeCleanup.d.ts → plugins/runtime/pluginRuntimeCleanup.d.ts} +0 -0
  132. /package/dist/{pluginModelDefinition.js → plugins/sdk/pluginModelDefinition.js} +0 -0
  133. /package/dist/{pluginRecoveryDefinition.js → plugins/sdk/pluginRecoveryDefinition.js} +0 -0
  134. /package/dist/{pluginStateDefinition.js → plugins/sdk/pluginStateDefinition.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { readFileSync, realpathSync } from 'node:fs';
2
2
  import { basename, dirname, isAbsolute, relative, resolve } from 'node:path';
3
- import { validateAppProfileContribution, } from './generated-app-profile-definition.js';
4
- import { pluginFileVersion } from './pluginSource.js';
3
+ import { validateAppProfileContribution, } from '@mearl/browser-core';
4
+ import { pluginFileVersion } from '../pluginSource.js';
5
5
  /** Profile resources share the Skill root and metadata refresh rules of toolbox resources. */
6
6
  export function loadPluginAppProfiles(entry, value) {
7
7
  if (value === undefined)
@@ -1,4 +1,4 @@
1
- import type { PluginModelCapability, PluginModelRequest, PluginModelResult } from './generated-plugin-models.js';
1
+ import type { PluginModelCapability, PluginModelRequest, PluginModelResult } from '@mearl/browser-core';
2
2
  export declare function pluginModelCapabilities(): {
3
3
  providers: PluginModelCapability[];
4
4
  };
@@ -1,3 +1,3 @@
1
- import type { PluginPageRuntime } from './generated-plugin-pages.js';
1
+ import type { PluginPageRuntime } from '@mearl/browser-core';
2
2
  export declare function normalizePluginPageRuntime(value: unknown): PluginPageRuntime | undefined;
3
3
  export declare function compilePluginPageSchema(schema: Record<string, unknown>): import("ajv/dist/core.js").AnyValidateFunction<unknown>;
@@ -1,6 +1,6 @@
1
1
  import { parse } from 'acorn';
2
2
  import { Ajv } from 'ajv';
3
- import { isPluginPageMatchPattern } from './generated-plugin-pages.js';
3
+ import { isPluginPageMatchPattern } from '@mearl/browser-core';
4
4
  const validators = new WeakMap();
5
5
  export function normalizePluginPageRuntime(value) {
6
6
  if (value === undefined)
@@ -1,3 +1,3 @@
1
- import type { PluginTaskRecoveryDeclaration } from './generated-plugin-recovery.js';
1
+ import type { PluginTaskRecoveryDeclaration } from '@mearl/browser-core';
2
2
  export declare function normalizePluginTaskRecovery(value: unknown): PluginTaskRecoveryDeclaration | undefined;
3
3
  export declare function pluginRecoverySignature(value: unknown): string;
@@ -1,4 +1,4 @@
1
- import type { PluginStateDeclaration } from './generated-plugin-state.js';
1
+ import type { PluginStateDeclaration } from '@mearl/browser-core';
2
2
  export declare function compilePluginStateSchema(schema: Record<string, unknown>): import("ajv/dist/core.js").AnyValidateFunction<unknown>;
3
3
  export declare function normalizePluginState(value: unknown): PluginStateDeclaration | undefined;
4
- export declare function pluginStateSignature(collection: import('./generated-plugin-state.js').PluginStateCollection): string;
4
+ export declare function pluginStateSignature(collection: import('@mearl/browser-core').PluginStateCollection): string;
@@ -0,0 +1,10 @@
1
+ export declare const DISABLED_SKILL_MANIFEST = "SKILL.md.mearl-disabled";
2
+ /** Read the identity fields used by the runtime, including disabled Skills. */
3
+ export declare function readInstalledSkillMetadata(directory: string): {
4
+ name?: string;
5
+ version?: string;
6
+ } | undefined;
7
+ /** 保留的清单供工具运行时读取,但不参与 Agent 的 SKILL.md 发现。 */
8
+ export declare function skillManifestPath(directory: string): string | undefined;
9
+ export declare function getSkillEnabled(directory: string): boolean | undefined;
10
+ export declare function setSkillEnabled(directory: string, enabled: boolean): void;
@@ -0,0 +1,56 @@
1
+ import { existsSync, lstatSync, readFileSync, renameSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export const DISABLED_SKILL_MANIFEST = 'SKILL.md.mearl-disabled';
4
+ /** Read the identity fields used by the runtime, including disabled Skills. */
5
+ export function readInstalledSkillMetadata(directory) {
6
+ if (existsSync(join(directory, 'SKILL.md')) && existsSync(join(directory, DISABLED_SKILL_MANIFEST)))
7
+ throw new Error('Conflicting installed Skill manifests');
8
+ const file = skillManifestPath(directory);
9
+ if (!file)
10
+ return undefined;
11
+ const info = statSync(file);
12
+ if (!info.isFile() || info.size > 1024 * 1024)
13
+ throw new Error('Invalid installed Skill manifest');
14
+ const frontmatter = readFileSync(file, 'utf8').match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1];
15
+ if (!frontmatter)
16
+ return {};
17
+ const scalar = (key) => {
18
+ const lines = frontmatter.split(/\r?\n/).filter(line => line.startsWith(key + ':'));
19
+ if (lines.length !== 1)
20
+ return undefined;
21
+ return lines[0].match(/^[\w-]+:\s*(?:"([^"\r\n]*)"|'([^'\r\n]*)'|([^\s#"']+))\s*(?:#.*)?$/)?.slice(1).find(value => value !== undefined);
22
+ };
23
+ return { name: scalar('name'), version: scalar('version') };
24
+ }
25
+ /** 保留的清单供工具运行时读取,但不参与 Agent 的 SKILL.md 发现。 */
26
+ export function skillManifestPath(directory) {
27
+ for (const name of ['SKILL.md', DISABLED_SKILL_MANIFEST]) {
28
+ const file = join(directory, name);
29
+ if (existsSync(file))
30
+ return file;
31
+ }
32
+ return undefined;
33
+ }
34
+ export function getSkillEnabled(directory) {
35
+ const manifest = skillManifestPath(directory);
36
+ return manifest ? manifest === join(directory, 'SKILL.md') : undefined;
37
+ }
38
+ export function setSkillEnabled(directory, enabled) {
39
+ const active = join(directory, 'SKILL.md');
40
+ const disabled = join(directory, DISABLED_SKILL_MANIFEST);
41
+ const source = enabled ? disabled : active;
42
+ const destination = enabled ? active : disabled;
43
+ const sourceStatus = lstatSync(source, { throwIfNoEntry: false });
44
+ const destinationStatus = lstatSync(destination, { throwIfNoEntry: false });
45
+ if (sourceStatus && destinationStatus) {
46
+ throw new Error('Skill 清单存在冲突,请检查 SKILL.md 和 SKILL.md.mearl-disabled');
47
+ }
48
+ if (!sourceStatus) {
49
+ if (destinationStatus?.isFile())
50
+ return;
51
+ throw new Error('找不到 Skill 清单');
52
+ }
53
+ if (!sourceStatus.isFile())
54
+ throw new Error('Skill 清单必须是普通文件');
55
+ renameSync(source, destination);
56
+ }
@@ -0,0 +1,4 @@
1
+ export declare const CLIENT_VERSION: string;
2
+ export declare const PLUGIN_TASK_HOST_PATH: string;
3
+ export declare const PLUGIN_WORKER_PATH: string;
4
+ export declare const PLUGIN_MODEL_SESSION_WORKER_PATH: string;
@@ -0,0 +1,8 @@
1
+ import { createRequire } from 'node:module';
2
+ import { fileURLToPath } from 'node:url';
3
+ // Package metadata and process entries share this anchor in compiled and bundled hosts.
4
+ const require = createRequire(import.meta.url);
5
+ export const CLIENT_VERSION = require('../package.json').version;
6
+ export const PLUGIN_TASK_HOST_PATH = fileURLToPath(new URL('./plugin-task-host.js', import.meta.url));
7
+ export const PLUGIN_WORKER_PATH = fileURLToPath(new URL('./plugin-worker.js', import.meta.url));
8
+ export const PLUGIN_MODEL_SESSION_WORKER_PATH = fileURLToPath(new URL('./pluginModelSessionWorker.js', import.meta.url));
package/dist/socket.d.ts CHANGED
@@ -7,7 +7,8 @@
7
7
  * 当 Socket 不存在,或 legacy Socket 是无人监听的残留文件时,
8
8
  * 自动尝试拉起 native host,稍后重试连接。
9
9
  */
10
- export declare const CLIENT_VERSION: string;
10
+ import { CLIENT_VERSION } from './runtimePaths.js';
11
+ export { CLIENT_VERSION };
11
12
  /**
12
13
  * Legacy well-known socket. New native-hosts publish per-browser sockets in the
13
14
  * registry and we address those; this path is a fallback for pre-registry hosts
@@ -46,4 +47,5 @@ export declare function resolveLocalActionTarget(action: string, data: Record<st
46
47
  * legacy well-known socket,并在 socket 不存在或已残留时自动拉起 native host。
47
48
  */
48
49
  export declare function invoke(action: string, data?: Record<string, any>, options?: InvokeOptions): Promise<any>;
49
- export {};
50
+ /** Infrastructure calls stay on this machine even when an Agent has selected an external browser. */
51
+ export declare function invokeLocalHost(action: string, data?: Record<string, any>, options?: Pick<InvokeOptions, 'timeoutSec' | 'socketPath'>): Promise<any>;
package/dist/socket.js CHANGED
@@ -11,16 +11,16 @@ import net from 'node:net';
11
11
  import fs from 'node:fs';
12
12
  import os from 'node:os';
13
13
  import path from 'node:path';
14
- import { createRequire } from 'node:module';
14
+ import { CLIENT_VERSION } from './runtimePaths.js';
15
15
  import { StringDecoder } from 'node:string_decoder';
16
16
  import { ensureProviderControlHost, listInstalledProviders } from '@mearl/provider/host';
17
+ import { MEARL_PROVIDER_PROTOCOL_VERSION } from '@mearl/provider';
17
18
  import { readLiveProvider } from '@mearl/provider/runtime';
18
19
  import { resolveFileRefs } from './fileRefs.js';
19
20
  import { listLiveBrowsers, findBrowser, describeBrowser, } from './browserRegistry.js';
20
21
  import { resolveActionTimeoutSec } from './actionTimeouts.js';
21
- import { isBrowserCapabilityAction } from './generated-browser-action-protocol.js';
22
- const require = createRequire(import.meta.url);
23
- export const CLIENT_VERSION = require('../package.json').version;
22
+ import { isBrowserCapabilityAction } from '@mearl/browser-core';
23
+ export { CLIENT_VERSION };
24
24
  const MAX_SOCKET_BUFFER_SIZE = 64 * 1024 * 1024;
25
25
  /**
26
26
  * Legacy well-known socket. New native-hosts publish per-browser sockets in the
@@ -380,6 +380,15 @@ export function invoke(action, data = {}, options = {}) {
380
380
  const selector = browser ?? defaultBrowser ?? process.env.MEARL_BROWSER ?? undefined;
381
381
  return dispatchInvoke(action, resolvedData, timeoutSec, transport, selector, controlSource, options.socketPath);
382
382
  }
383
+ /** Infrastructure calls stay on this machine even when an Agent has selected an external browser. */
384
+ export function invokeLocalHost(action, data = {}, options = {}) {
385
+ const timeoutSec = options.timeoutSec ?? resolveActionTimeoutSec(action, data);
386
+ const socketPath = options.socketPath ?? process.env.MEARL_SOCKET_PATH?.trim();
387
+ const accepted = resolveFileRefs(data);
388
+ return socketPath
389
+ ? invokeOnce(action, accepted, timeoutSec, undefined, socketPath, 'local')
390
+ : invokeViaLegacy(action, accepted, timeoutSec, undefined, 'local', false, true);
391
+ }
383
392
  /** Session ownership lives in the control hosts and survives individual CLI connections. */
384
393
  async function resolveControlSession(sessionId, timeoutSec, controlSource) {
385
394
  const browsers = listLiveBrowsers();
@@ -545,7 +554,7 @@ async function dispatchInvoke(action, data, timeoutSec, transport, selector, con
545
554
  return invokeViaLegacy(action, data, timeoutSec, transport, controlSource, /* isRetry */ false);
546
555
  }
547
556
  /** Legacy well-known socket, repairing a missing or stale endpoint and retrying once. */
548
- async function invokeViaLegacy(action, data, timeoutSec, transport, controlSource, isRetry) {
557
+ async function invokeViaLegacy(action, data, timeoutSec, transport, controlSource, isRetry, localOnly = false) {
549
558
  const legacySocketIdentity = readOwnedLegacySocketIdentity();
550
559
  try {
551
560
  return await invokeOnce(action, data, timeoutSec, transport, SOCKET_PATH, controlSource);
@@ -561,13 +570,14 @@ async function invokeViaLegacy(action, data, timeoutSec, transport, controlSourc
561
570
  await new Promise(r => setTimeout(r, 1200));
562
571
  const browsers = listLiveBrowsers();
563
572
  const target = browsers.find(browser => isConnectedBrowser(browser) &&
573
+ (!localOnly || browser.transport !== 'provider') &&
564
574
  !(transport === 'cdp' && browser.transport === 'provider') &&
565
575
  supportsAction(browser, action, data));
566
576
  if (target) {
567
577
  return invokeOnce(action, data, timeoutSec, transport, target.socketPath, controlSource, target.transport === 'provider' ? target.browserId : undefined);
568
578
  }
569
579
  return invokeViaLegacy(action, data, timeoutSec, transport, controlSource,
570
- /* isRetry */ true);
580
+ /* isRetry */ true, localOnly);
571
581
  }
572
582
  }
573
583
  if (err instanceof Error && !isConnError(err) && !isSocketSandboxError(err))
@@ -617,6 +627,7 @@ async function invokeOnce(action, data, timeoutSec, transport, socketPath, contr
617
627
  action,
618
628
  data,
619
629
  version: CLIENT_VERSION,
630
+ protocolVersion: MEARL_PROVIDER_PROTOCOL_VERSION,
620
631
  controlSource: toControlSourceWireValue(controlSource),
621
632
  };
622
633
  if (data[SESSION_OPTION])
package/dist/unified.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import type { BrowserArtifact } from './generated-browser-action-protocol.js';
1
+ import type { BrowserArtifact } from '@mearl/browser-core';
2
2
  import { type CloudConnectorListResult } from '@mearl/cloud-types';
3
- import type { PluginInvocation, PluginInvokeOptions } from './plugin.js';
3
+ import type { PluginInvocation, PluginInvokeOptions } from './plugins/sdk/plugin.js';
4
4
  export interface UnifiedInvokeOptions {
5
5
  /** Use new on the first tab_open/page_snapshot, then reuse the returned id. */
6
6
  session?: string;
package/dist/unified.js CHANGED
@@ -3,7 +3,7 @@ import { stageFile, exportArtifact } from './artifacts.js';
3
3
  import WebSocket from 'ws';
4
4
  import { DEFAULT_CONNECT_TIMEOUT, DEFAULT_HEARTBEAT_INTERVAL, DEFAULT_REQUEST_TIMEOUT, MAX_BUFFER_SIZE, isHeartbeatMessage, resolveCloudConnectorSelector, } from '@mearl/cloud-types';
5
5
  import { resolveActionTimeoutSec } from './actionTimeouts.js';
6
- import { validateRequiredActionTabId, } from './generated-browser-action-protocol.js';
6
+ import { validateRequiredActionTabId, } from '@mearl/browser-core';
7
7
  import { invoke as invokeLocalBrowser, resolveLocalActionTarget } from './socket.js';
8
8
  import { loadCloudServerConfig, loadLocalConnectorId } from './unifiedConfig.js';
9
9
  const RESPONSE_GRACE_MS = 1_000;
@@ -124,11 +124,11 @@ export class UnifiedClient {
124
124
  this.ws = null;
125
125
  }
126
126
  async invokePlugin(name, invocation, options = {}) {
127
- const { invokeRegisteredPlugin } = await import('./plugin.js');
127
+ const { invokeRegisteredPlugin } = await import('./plugins/sdk/plugin.js');
128
128
  return invokeRegisteredPlugin(name, invocation, {
129
129
  invoke: (action, payload, invokeOptions) => this.invoke(action, payload, invokeOptions),
130
130
  runModel: async (plugin, request, execution) => {
131
- const { PluginModelClient } = await import('./pluginModels.js');
131
+ const { PluginModelClient } = await import('./plugins/clients/pluginModels.js');
132
132
  const models = new PluginModelClient({ source: options.source ?? 'sdk' });
133
133
  try {
134
134
  return await models.run(plugin, request, {
@@ -147,7 +147,7 @@ export class UnifiedClient {
147
147
  }
148
148
  async invoke(action, data = {}, options = {}) {
149
149
  if (action === 'plugin_state') {
150
- const { PluginStateClient } = await import('./pluginState.js');
150
+ const { PluginStateClient } = await import('./plugins/clients/pluginState.js');
151
151
  const state = new PluginStateClient();
152
152
  try {
153
153
  return await state.call(String(data.plugin ?? ''), data.collection, data.operation, data, options);
@@ -157,7 +157,7 @@ export class UnifiedClient {
157
157
  }
158
158
  }
159
159
  if (action === 'plugin_model') {
160
- const { PluginModelClient } = await import('./pluginModels.js');
160
+ const { PluginModelClient } = await import('./plugins/clients/pluginModels.js');
161
161
  const models = new PluginModelClient();
162
162
  try {
163
163
  if (data.operation === 'capabilities')
@@ -175,8 +175,8 @@ export class UnifiedClient {
175
175
  }
176
176
  }
177
177
  if (action === 'plugin_page') {
178
- const { PluginHostConnection } = await import('./pluginHostConnection.js');
179
- const { PluginPageClient } = await import('./pluginPages.js');
178
+ const { PluginHostConnection } = await import('./plugins/clients/pluginHostConnection.js');
179
+ const { PluginPageClient } = await import('./plugins/clients/pluginPages.js');
180
180
  const connection = new PluginHostConnection();
181
181
  const pages = new PluginPageClient({}, connection);
182
182
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearl/client",
3
- "version": "2.21.0",
3
+ "version": "3.0.0-beta.0",
4
4
  "description": "Unified Mearl SDK & CLI for local and remote browsers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -52,7 +52,7 @@
52
52
  "devtools",
53
53
  "socket-client"
54
54
  ],
55
- "license": "ISC",
55
+ "license": "Apache-2.0",
56
56
  "engines": {
57
57
  "node": ">=22.12.0"
58
58
  },
@@ -65,10 +65,11 @@
65
65
  "commander": "^15.0.0",
66
66
  "fastest-levenshtein": "^1.0.16",
67
67
  "ws": "^8.18.0",
68
- "@mearl/daemon-core": "2.21.0",
69
- "@mearl/provider": "2.21.0",
70
- "@mearl/agent-runtime": "2.21.0",
71
- "@mearl/cloud-types": "2.21.0"
68
+ "@mearl/daemon-core": "3.0.0-beta.0",
69
+ "@mearl/cloud-types": "3.0.0-beta.0",
70
+ "@mearl/provider": "3.0.0-beta.0",
71
+ "@mearl/agent-runtime": "3.0.0-beta.0",
72
+ "@mearl/browser-core": "3.0.0-beta.0"
72
73
  },
73
74
  "devDependencies": {
74
75
  "@types/node": "^24.9.1",
@@ -76,9 +77,9 @@
76
77
  "typescript": "^5.8.3"
77
78
  },
78
79
  "scripts": {
79
- "build": "node ../../scripts/generate-client-action-protocol.mjs --check && rm -rf dist/ && tsc && chmod +x dist/bin.js",
80
+ "build": "rm -rf dist/ && tsc && chmod +x dist/bin.js",
80
81
  "dev": "tsc --watch",
81
- "typecheck": "node ../../scripts/generate-client-action-protocol.mjs --check && tsc --noEmit",
82
+ "typecheck": "tsc --noEmit",
82
83
  "test": "vitest run"
83
84
  }
84
85
  }
@@ -1,130 +0,0 @@
1
- import type { BrowserDevicePresetName, AppBridgeConfig } from './generated-browser-action-protocol.js';
2
- import type { AppBridgeSpec, AppImagePickerConfig, AppLayerUrlProxyConfig, AppMiniProgramConfig, AppNativeBackConfig, AppOverlayConfig, AppSchemeRule, AppTitleBarHostStyle, BridgeActionMap } from './generated-app-profile-runtime-types.js';
3
- export interface AppProfilePolicies {
4
- titleBar?: 'default' | 'taobao' | 'fliggy' | 'alipay' | 'wechat';
5
- navigatorLanguage?: boolean;
6
- networkResult?: 'default' | 'alipay';
7
- languages?: string[];
8
- defaultLanguage?: string;
9
- }
10
- export interface AppProfileSetting {
11
- id: string;
12
- label: string;
13
- type: 'select' | 'boolean' | 'number' | 'text' | 'json';
14
- target: {
15
- option: 'language';
16
- } | {
17
- method: string;
18
- field?: string;
19
- };
20
- choices?: Array<{
21
- label: string;
22
- value: string;
23
- }>;
24
- minimum?: number;
25
- maximum?: number;
26
- }
27
- export interface AppProfileOptions {
28
- /** Keep this definition across document navigations until explicitly refreshed. */
29
- lockDefinition?: boolean;
30
- os?: 'ios' | 'android';
31
- appVersion?: string;
32
- language?: string;
33
- deviceModel?: string;
34
- devicePreset?: BrowserDevicePresetName;
35
- orientation?: 'portrait' | 'landscape';
36
- bridgeConfig?: AppBridgeConfig;
37
- }
38
- export interface AppProfileBinding {
39
- version: 1;
40
- revision: string;
41
- definition: AppProfileDefinition;
42
- options: AppProfileOptions;
43
- /** Explicit scalar choices; method overrides are always explicit and live in options.bridgeConfig. */
44
- explicitOptions?: Omit<AppProfileOptions, 'bridgeConfig'>;
45
- }
46
- export interface AppProfileContribution {
47
- version: 1;
48
- profiles: AppProfileDefinition[];
49
- }
50
- export interface AppProfileCatalogEntry {
51
- id: string;
52
- label: string;
53
- source: 'builtin' | 'plugin';
54
- available?: boolean;
55
- plugin?: string;
56
- revision: string;
57
- definition: AppProfileDefinition;
58
- }
59
- /** 单容器档案(纯数据) */
60
- export interface AppProfileDefinition {
61
- name: string;
62
- label: string;
63
- /** 容器的应用标识,如 LX / TB / AP / WeChat */
64
- appName: string;
65
- defaultAppVersion: string;
66
- /** UA 主体格式;默认使用 AliApp(appName/version) */
67
- uaFamily?: 'aliapp' | 'wechatMiniProgram';
68
- uaTemplate?: {
69
- ios: string;
70
- android: string;
71
- };
72
- policies?: AppProfilePolicies;
73
- settings?: AppProfileSetting[];
74
- settingsGroup?: 'fliggy' | 'alipay';
75
- /** AliApp UA 主体之后追加的 token,{v} 占位会被替换为 appVersion */
76
- uaTokens: string[];
77
- /** 额外注入到 window 的变量(公共变量由 resolve 统一生成) */
78
- globals: Record<string, string>;
79
- bridges: AppBridgeSpec[];
80
- /** 页面回到前台时分发到 document 的事件名(如 WV.Event.APP.Active) */
81
- activeEvents: string[];
82
- actions: BridgeActionMap;
83
- schemes: AppSchemeRule[];
84
- /** 小程序原生页面与 WebView 通信规则。 */
85
- miniProgram?: AppMiniProgramConfig;
86
- /** 原生图片页 scheme 的浏览器选图与上传配置 */
87
- imagePicker?: AppImagePickerConfig;
88
- geolocation?: {
89
- reverseGeocodeApi: string;
90
- version: string;
91
- };
92
- /**
93
- * 地址栏借位同步的可选 host 白名单:容器栈顶 URL 的 host 命中时,地址栏借 top
94
- * 域名同步其 path+query+hash(pushState 同源约束下保持域名不变只改 path);
95
- * 不配置则同步所有 HTTP(S) 业务层 URL。
96
- */
97
- urlSyncHostSuffixes?: string[];
98
- /** URL / pageParams 浮层协议 */
99
- overlay?: AppOverlayConfig;
100
- /** URL 参数为真时以新 WebView 替换当前业务层。 */
101
- popBeforeOpenParam?: string;
102
- /** 跨 WebView 消息抵达 opener 时分发的 document 事件。 */
103
- messageEvent?: string;
104
- /** 原生返回键的页面接管协议。 */
105
- nativeBack?: AppNativeBackConfig;
106
- /** 开发代理 origin 下的业务层 URL 映射 */
107
- layerUrlProxy?: AppLayerUrlProxyConfig;
108
- /** App 框架的根 WebView 与自绘标题栏协议。 */
109
- rootContainer?: {
110
- statusBarHeightCookie?: {
111
- name: string;
112
- domain?: string;
113
- path?: string;
114
- };
115
- };
116
- /** 页面自行绘制导航区域时,不渲染模拟标题栏。 */
117
- titleBarHiddenPathnames?: string[];
118
- /** 页面级状态栏背景色,key 为业务 pathname。 */
119
- statusBarBackgroundColors?: Record<string, string>;
120
- /** 按业务根域配置标题栏与状态栏样式。 */
121
- titleBarHostStyles?: AppTitleBarHostStyle[];
122
- /** 桥存在时仍将 MTOP 传输固定在浏览器 H5 通道 */
123
- forceH5Mtop?: boolean;
124
- }
125
- export declare const APP_BRIDGE_BEHAVIORS: readonly ["navigate", "closeAll", "closeBackData", "postMessage", "notifySubscribe", "notifyUnsubscribe", "notifyPost", "sharedFileRead", "sharedFileWrite", "sharedDataGet", "sharedDataSet", "legacyBroadcastCreate", "legacyBroadcastPost", "legacyBroadcastClose", "memoryGet", "memorySet", "memoryDelete", "availabilityMap", "userInfo", "authCode", "networkInfo", "geolocation", "permission", "imagePicker", "prefetch", "fptTrack", "mtopStream", "previewFile", "toast", "unsupportedNativeInput", "payment", "userTrack", "calendar", "networkQualityMonitor", "beaconRequest", "voiceRecognition"];
126
- /** Validate plain data before registration or compiling a document-start configuration. */
127
- export declare function validateAppProfileDefinition(value: unknown): AppProfileDefinition;
128
- export declare function validateAppProfileContribution(value: unknown): AppProfileContribution | undefined;
129
- /** Deterministic identity for immutable definitions; this identifier grants no host permissions. */
130
- export declare function appProfileRevision(definition: AppProfileDefinition): string;