@mearl/browser-core 3.0.0-beta.5 → 3.0.0-beta.7

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 (40) hide show
  1. package/README.md +1 -1
  2. package/dist/agentChat.d.ts +2 -0
  3. package/dist/agentSkills.d.ts +1 -1
  4. package/dist/app-profile-runtime/types.d.ts +4 -8
  5. package/dist/appProfileDefinition.d.ts +4 -7
  6. package/dist/appProfileDefinition.js +11 -49
  7. package/dist/axSnapshot.js +1 -1
  8. package/dist/boundedRequestBuffer.d.ts +4 -4
  9. package/dist/browserActionProtocol.d.ts +46 -29
  10. package/dist/browserActionProtocol.js +6 -6
  11. package/dist/browserCapabilities.d.ts +2 -0
  12. package/dist/browserCapabilities.js +19 -5
  13. package/dist/browserDiscovery.d.ts +3 -0
  14. package/dist/browserDiscovery.js +20 -0
  15. package/dist/browserEnhancement.d.ts +161 -0
  16. package/dist/browserEnhancement.js +80 -0
  17. package/dist/deviceEnvironmentObservation.d.ts +48 -0
  18. package/dist/deviceEnvironmentObservation.js +77 -0
  19. package/dist/domClicking.d.ts +14 -0
  20. package/dist/domClicking.js +46 -10
  21. package/dist/extensionServiceProtocol.d.ts +6 -0
  22. package/dist/extensionServiceProtocol.js +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.js +6 -0
  25. package/dist/pageAct.d.ts +2 -0
  26. package/dist/pageAct.js +42 -10
  27. package/dist/pageDialog.d.ts +66 -0
  28. package/dist/pageDialog.js +175 -0
  29. package/dist/pageObserver.js +16 -5
  30. package/dist/pagePressing.d.ts +1 -1
  31. package/dist/providerAppResources.d.ts +39 -0
  32. package/dist/providerAppResources.js +2 -0
  33. package/dist/proxyPermissions.js +3 -3
  34. package/dist/requestMetadata.d.ts +9 -0
  35. package/dist/requestMetadata.js +8 -0
  36. package/dist/requestSerializer.d.ts +2 -2
  37. package/dist/requestStreamCapture.d.ts +5 -3
  38. package/dist/requestStreamCapture.js +2 -0
  39. package/dist/types.d.ts +4 -2
  40. package/package.json +2 -2
package/README.md CHANGED
@@ -6,6 +6,6 @@
6
6
 
7
7
  `@mearl/browser-core/appProfileRuntime` 的内置安装器只同步 UA、navigator.appVersion、navigator.platform 和触摸点,不安装 App 桥、业务全局变量、容器栈或授权处理。有 pageRuntime 绑定时,宿主必须先从已安装的能力包准备确切代码,再通过页面运行时派发器执行;不能调用基础安装器代替。资源准备和派发见 [能力包](../../docs/browser-bundles.md#页面运行时)。
8
8
 
9
- 默认代理授权地址只有 localhost 与 127.0.0.1。其余站点由宿主取得权限后传入授权列表;组织域名和员工身份不属于本包默认值。业务请求辅助、业务事件解析、测试账号登录及用户 Cookie 身份推导留在独立能力中。
9
+ 默认代理授权地址只有 localhost 与 127.0.0.1。其余站点由宿主取得权限后传入授权列表;组织域名和员工身份不属于本包默认值。Aplus/RUM/ARMS 基础事件解析在核心内置;业务请求辅助、埋点内部查询与校验、测试账号登录及用户 Cookie 身份推导留在独立能力中。
10
10
 
11
11
  Agent 合同源在本包的 agentChat.ts、agentSkills.ts 和 pluginModels.ts;分别通过同名子路径导出,agent-runtime 使用这些合同,避免并行维护副本。可序列化的页面函数保持自包含,便于 Extension 与 CDP 共同使用。
@@ -15,6 +15,8 @@ export interface AgentChatProviderDescriptor {
15
15
  id: string;
16
16
  name: string;
17
17
  available: boolean;
18
+ /** False while accepted conversations retain a removed or superseded runtime. */
19
+ acceptsNewSessions?: boolean;
18
20
  capabilities: {
19
21
  streaming: boolean;
20
22
  resume: boolean;
@@ -1,4 +1,4 @@
1
- export type AgentSkillProviderId = 'codex' | 'qoder';
1
+ export type AgentSkillProviderId = string;
2
2
  export type AgentSkillScope = 'project' | 'global';
3
3
  export type AgentInstalledSkillScope = AgentSkillScope | 'system' | 'admin' | 'built-in' | 'unknown';
4
4
  export interface AgentInstalledSkill {
@@ -9,7 +9,8 @@ export interface AppBridgeSpec {
9
9
  /** 页面脚本重设全局对象时仍保留桥叶子,同时接纳页面对象上的其他 API。 */
10
10
  persistent?: boolean;
11
11
  }
12
- export type AppBridgeBehavior = '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';
12
+ /** Provider-defined identifier, interpreted by its installed page runtime. */
13
+ export type AppBridgeBehavior = string;
13
14
  /** 桥方法名到标准化动作的映射。命名空间桥使用 `Class.method`,其余使用 api 名。 */
14
15
  export interface BridgeActionMap {
15
16
  open: string[];
@@ -18,7 +19,7 @@ export interface BridgeActionMap {
18
19
  navigationBar?: string[];
19
20
  statusBar?: string[];
20
21
  systemInfo: string[];
21
- mtop: string[];
22
+ protocol: string[];
22
23
  kvGet?: string[];
23
24
  kvSet?: string[];
24
25
  kvDelete?: string[];
@@ -209,11 +210,6 @@ export interface InjectedAppProfileConfig {
209
210
  schemes: AppSchemeRule[];
210
211
  miniProgram?: AppMiniProgramConfig;
211
212
  imagePicker?: AppImagePickerConfig;
212
- /** 原生定位返回地址时使用的逆地理编码服务,复用容器的 MTop 传输。 */
213
- geolocation?: {
214
- reverseGeocodeApi: string;
215
- version: string;
216
- };
217
213
  overlay?: AppOverlayConfig;
218
214
  /** URL 参数为真时以新 WebView 替换当前业务层。 */
219
215
  popBeforeOpenParam?: string;
@@ -223,7 +219,7 @@ export interface InjectedAppProfileConfig {
223
219
  layerUrlProxy?: AppLayerUrlProxyConfig;
224
220
  urlSyncHostSuffixes?: string[];
225
221
  animationMs?: number;
226
- forceH5Mtop?: boolean;
222
+ runtimeOptions?: Record<string, unknown>;
227
223
  titleBar?: AppTitleBarConfig;
228
224
  rootContainer?: AppRootContainerConfig;
229
225
  simulateSystemBars?: boolean;
@@ -111,10 +111,6 @@ export interface AppProfileDefinition {
111
111
  miniProgram?: AppMiniProgramConfig;
112
112
  /** 原生图片页 scheme 的浏览器选图与上传配置 */
113
113
  imagePicker?: AppImagePickerConfig;
114
- geolocation?: {
115
- reverseGeocodeApi: string;
116
- version: string;
117
- };
118
114
  /**
119
115
  * 地址栏借位同步的可选 host 白名单:容器栈顶 URL 的 host 命中时,地址栏借 top
120
116
  * 域名同步其 path+query+hash(pushState 同源约束下保持域名不变只改 path);
@@ -145,10 +141,11 @@ export interface AppProfileDefinition {
145
141
  statusBarBackgroundColors?: Record<string, string>;
146
142
  /** 按业务根域配置标题栏与状态栏样式。 */
147
143
  titleBarHostStyles?: AppTitleBarHostStyle[];
148
- /** 桥存在时仍将 MTOP 传输固定在浏览器 H5 通道 */
149
- forceH5Mtop?: boolean;
144
+ /** Opaque configuration owned by the installed page runtime. */
145
+ runtimeOptions?: Record<string, unknown>;
150
146
  }
151
- 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"];
147
+ /** Behavior IDs belong to the installed page runtime, never to a host-side enum. */
148
+ export declare function isAppBridgeBehavior(value: unknown): value is string;
152
149
  /** Validate plain data before registration or compiling a document-start configuration. */
153
150
  export declare function validateAppProfileDefinition(value: unknown): AppProfileDefinition;
154
151
  export declare function validateAppProfileContribution(value: unknown): AppProfileContribution | undefined;
@@ -1,42 +1,7 @@
1
- export const APP_BRIDGE_BEHAVIORS = [
2
- 'navigate',
3
- 'closeAll',
4
- 'closeBackData',
5
- 'postMessage',
6
- 'notifySubscribe',
7
- 'notifyUnsubscribe',
8
- 'notifyPost',
9
- 'sharedFileRead',
10
- 'sharedFileWrite',
11
- 'sharedDataGet',
12
- 'sharedDataSet',
13
- 'legacyBroadcastCreate',
14
- 'legacyBroadcastPost',
15
- 'legacyBroadcastClose',
16
- 'memoryGet',
17
- 'memorySet',
18
- 'memoryDelete',
19
- 'availabilityMap',
20
- 'userInfo',
21
- 'authCode',
22
- 'networkInfo',
23
- 'geolocation',
24
- 'permission',
25
- 'imagePicker',
26
- 'prefetch',
27
- 'fptTrack',
28
- 'mtopStream',
29
- 'previewFile',
30
- 'toast',
31
- 'unsupportedNativeInput',
32
- 'payment',
33
- 'userTrack',
34
- 'calendar',
35
- 'networkQualityMonitor',
36
- 'beaconRequest',
37
- 'voiceRecognition',
38
- ];
39
- const BEHAVIORS = new Set(APP_BRIDGE_BEHAVIORS);
1
+ /** Behavior IDs belong to the installed page runtime, never to a host-side enum. */
2
+ export function isAppBridgeBehavior(value) {
3
+ return typeof value === 'string' && /^[a-zA-Z][a-zA-Z0-9_.:-]{0,95}$/.test(value);
4
+ }
40
5
  function record(value) {
41
6
  return value !== null && typeof value === 'object' && !Array.isArray(value);
42
7
  }
@@ -80,7 +45,7 @@ function validateActions(value) {
80
45
  'navigationBar',
81
46
  'statusBar',
82
47
  'systemInfo',
83
- 'mtop',
48
+ 'protocol',
84
49
  'kvGet',
85
50
  'kvSet',
86
51
  'kvDelete',
@@ -88,7 +53,7 @@ function validateActions(value) {
88
53
  'noop',
89
54
  'silent',
90
55
  ];
91
- fields(value, ['open', 'close', 'title', 'systemInfo', 'mtop', 'noop'], [...arrays, 'responses', 'behaviors'], 'actions');
56
+ fields(value, ['open', 'close', 'title', 'systemInfo', 'protocol', 'noop'], [...arrays, 'responses', 'behaviors'], 'actions');
92
57
  for (const key of arrays)
93
58
  if (value[key] !== undefined && !strings(value[key]))
94
59
  invalid(`actions.${key}`);
@@ -96,7 +61,7 @@ function validateActions(value) {
96
61
  invalid('actions.responses');
97
62
  if (value.behaviors !== undefined &&
98
63
  (!stringMap(value.behaviors) ||
99
- !Object.values(value.behaviors).every(item => BEHAVIORS.has(item))))
64
+ !Object.values(value.behaviors).every(item => isAppBridgeBehavior(item))))
100
65
  invalid('actions.behaviors');
101
66
  }
102
67
  /** Validate plain data before registration or compiling a document-start configuration. */
@@ -131,7 +96,6 @@ export function validateAppProfileDefinition(value) {
131
96
  'authorization',
132
97
  'miniProgram',
133
98
  'imagePicker',
134
- 'geolocation',
135
99
  'urlSyncHostSuffixes',
136
100
  'overlay',
137
101
  'popBeforeOpenParam',
@@ -142,7 +106,7 @@ export function validateAppProfileDefinition(value) {
142
106
  'titleBarHiddenPathnames',
143
107
  'statusBarBackgroundColors',
144
108
  'titleBarHostStyles',
145
- 'forceH5Mtop',
109
+ 'runtimeOptions',
146
110
  ];
147
111
  fields(value, required, optional, 'definition');
148
112
  for (const key of ['name', 'label', 'appName', 'defaultAppVersion'])
@@ -313,7 +277,7 @@ export function validateAppProfileDefinition(value) {
313
277
  'navigationBar',
314
278
  'statusBar',
315
279
  'systemInfo',
316
- 'mtop',
280
+ 'protocol',
317
281
  'kvGet',
318
282
  'kvSet',
319
283
  'kvDelete',
@@ -339,9 +303,8 @@ export function validateAppProfileDefinition(value) {
339
303
  invalid('setting.option type');
340
304
  }
341
305
  }
342
- for (const key of ['forceH5Mtop'])
343
- if (value[key] !== undefined && typeof value[key] !== 'boolean')
344
- invalid(key);
306
+ if (value.runtimeOptions !== undefined && (!record(value.runtimeOptions) || !json(value.runtimeOptions)))
307
+ invalid('runtimeOptions');
345
308
  for (const key of ['popBeforeOpenParam', 'messageEvent'])
346
309
  if (value[key] !== undefined && !text(value[key]))
347
310
  invalid(key);
@@ -353,7 +316,6 @@ export function validateAppProfileDefinition(value) {
353
316
  function validateStructuredOptions(value) {
354
317
  const shapes = {
355
318
  nativeBack: [[], ['event', 'controlFunction', 'handler']],
356
- geolocation: [['reverseGeocodeApi', 'version'], []],
357
319
  layerUrlProxy: [
358
320
  ['sourceHostPrefix', 'pathPrefix', 'targetHostSuffixes'],
359
321
  ['defaultTargetHost'],
@@ -290,7 +290,7 @@ export function resolvePageSnapshotQuery(query) {
290
290
  if (query === undefined)
291
291
  return undefined;
292
292
  if (!query || typeof query !== 'object' || Array.isArray(query)) {
293
- throw new Error('page_snapshot: query must be an object');
293
+ throw new Error('page_snapshot: query must be an object, for example {"query":{"text":"提交","exact":false}}.');
294
294
  }
295
295
  const { text, role, exact } = query;
296
296
  if (text !== undefined && (typeof text !== 'string' || !text.trim())) {
@@ -1,4 +1,4 @@
1
- import type { MtopRequest } from './types.js';
1
+ import type { CapturedRequest } from './types.js';
2
2
  export declare const REQUEST_BUFFER_MAX_ENTRIES = 500;
3
3
  export declare const REQUEST_BUFFER_MAX_BYTES: number;
4
4
  export declare const REQUEST_BUFFER_MAX_FIELD_BYTES: number;
@@ -12,7 +12,7 @@ export interface RequestBufferLimits {
12
12
  maxFieldBytes?: number;
13
13
  }
14
14
  export declare function limitBufferedField(value: any, maxBytes: number): any;
15
- export declare function estimateRequestBufferBytes(request: MtopRequest): number;
15
+ export declare function estimateRequestBufferBytes(request: CapturedRequest): number;
16
16
  export declare function createRequestBufferAccounting(): RequestBufferAccounting;
17
- export declare function appendRequestToBuffer(requests: MtopRequest[], accounting: RequestBufferAccounting, request: MtopRequest, limits?: RequestBufferLimits): MtopRequest[];
18
- export declare function refreshRequestInBuffer(requests: MtopRequest[], accounting: RequestBufferAccounting, request: MtopRequest, limits?: RequestBufferLimits): MtopRequest[];
17
+ export declare function appendRequestToBuffer(requests: CapturedRequest[], accounting: RequestBufferAccounting, request: CapturedRequest, limits?: RequestBufferLimits): CapturedRequest[];
18
+ export declare function refreshRequestInBuffer(requests: CapturedRequest[], accounting: RequestBufferAccounting, request: CapturedRequest, limits?: RequestBufferLimits): CapturedRequest[];
@@ -18,7 +18,7 @@ export interface GetRequestsParams {
18
18
  fields?: string[];
19
19
  keysOnly?: boolean;
20
20
  applyHiddenFilter?: boolean;
21
- source?: 'mtop' | 'requests' | 'all';
21
+ source?: 'protocol' | 'requests' | 'all';
22
22
  }
23
23
  export interface GetLogsParams {
24
24
  tabId: number;
@@ -112,18 +112,14 @@ export interface SendRequestParams {
112
112
  responseType?: 'json' | 'text' | 'auto';
113
113
  timeout?: number;
114
114
  }
115
- export type MtopEnvironmentTarget = 'prod' | 'pre';
116
- export type MtopEnvironment = 'default' | MtopEnvironmentTarget;
117
- export interface SendMtopRequestParams {
118
- api: string;
119
- data?: unknown;
120
- version?: string;
121
- method?: string;
122
- appKey?: string;
123
- env?: MtopEnvironmentTarget;
115
+ export interface NetworkControlSelection {
116
+ id: string;
117
+ value: string;
118
+ }
119
+ /** Parameters are interpreted and validated by the installed request protocol. */
120
+ export interface SendProtocolRequestParams {
124
121
  timeout?: number;
125
- headers?: Record<string, string>;
126
- ttid?: string;
122
+ [key: string]: unknown;
127
123
  }
128
124
  export type BrowserStatus = 'connected' | 'pairing' | 'running_disconnected' | 'stopped';
129
125
  export type BrowserTransport = 'extension' | 'cdp' | 'provider';
@@ -189,6 +185,7 @@ export interface BrowserInfoBase {
189
185
  pairing?: BrowserPairingInfo;
190
186
  }
191
187
  export type BrowserScreenshotKind = 'native' | 'reconstructed' | 'none';
188
+ export type BrowserControlSessionMode = 'mearl' | 'external';
192
189
  /** Browser-targeted actions that an external provider may implement. */
193
190
  export type BrowserCapabilityAction = ExtensionBrowserAction | 'page_download';
194
191
  /** Capabilities advertised by an external browser-control provider. */
@@ -196,6 +193,8 @@ export interface BrowserCapabilities {
196
193
  actions: BrowserCapabilityAction[];
197
194
  /** Pixel fidelity of page_screenshot, or none when that action is unavailable. */
198
195
  screenshot: BrowserScreenshotKind;
196
+ /** Fixed per instance. Omitted means Mearl sessions; external delegates task control. */
197
+ controlSessionMode?: BrowserControlSessionMode;
199
198
  }
200
199
  export interface RegularBrowserInfo extends BrowserInfoBase {
201
200
  type: 'regular';
@@ -209,6 +208,13 @@ export interface ManagedBrowserInfo extends BrowserInfoBase {
209
208
  operations: BrowserProviderOperation[];
210
209
  }
211
210
  export type BrowserInfo = RegularBrowserInfo | ManagedBrowserInfo;
211
+ export interface BrowserListParams {
212
+ provider: string;
213
+ launchForm: {
214
+ variant?: string;
215
+ values: Record<string, BrowserJsonValue>;
216
+ };
217
+ }
212
218
  export interface BrowserListResult {
213
219
  count: number;
214
220
  connectedCount: number;
@@ -216,6 +222,11 @@ export interface BrowserListResult {
216
222
  browsers: BrowserInfo[];
217
223
  /** Partial discovery failures; successfully inspected browser sources remain in the result. */
218
224
  warnings?: string[];
225
+ /** Present only for an explicit, source-local Provider launch-form query. */
226
+ discovery?: {
227
+ provider: string;
228
+ launchForm: BrowserProviderLaunchForm;
229
+ };
219
230
  }
220
231
  export interface SelectBrowserParams {
221
232
  browser?: string;
@@ -371,6 +382,7 @@ export interface BrowserProviderDefinition {
371
382
  provider: BrowserProviderIdentity;
372
383
  browserType: {
373
384
  name: string;
385
+ controlSessionModes?: readonly BrowserControlSessionMode[];
374
386
  documentationUrl?: string;
375
387
  inputSchema: BrowserProviderObjectSchema;
376
388
  configuration?: {
@@ -462,7 +474,8 @@ export interface BrowserEmulationOptions {
462
474
  /** App 容器横屏时将根页面与业务页面分置左右 WebView;仅与 deviceShell、App 档案同时生效。 */
463
475
  splitScreen?: boolean;
464
476
  }
465
- export type AppBridgeConfigBehavior = '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';
477
+ /** Provider-defined behavior ID; core does not execute or enumerate business behaviors. */
478
+ export type AppBridgeConfigBehavior = string;
466
479
  /** 单个桥方法的声明式覆盖;行为、固定回包、成功空实现三选一。 */
467
480
  export interface AppBridgeMethodConfig {
468
481
  behavior?: AppBridgeConfigBehavior;
@@ -532,10 +545,10 @@ export interface SetAppProfileParams {
532
545
  /** 按方法覆盖档案内置桥配置,仅支持受控行为、固定 JSON 回包和成功空实现 */
533
546
  bridgeConfig?: AppBridgeConfig;
534
547
  /**
535
- * 可选 MTop 接口环境。default 关闭环境改写;省略时保持当前设置。
548
+ * 可选已安装的网络控件选择;null 清除,省略时保持当前设置。
536
549
  * 仅作用于目标 tab,扩展模式与该 tab 的快捷设置共享。
537
550
  */
538
- mtopEnv?: MtopEnvironment;
551
+ networkControl?: NetworkControlSelection | null;
539
552
  /**
540
553
  * 可选设备联动参数。传入时显式字段覆盖档案推荐设备,空对象使用推荐设备且默认开启
541
554
  * deviceShell;省略时不设置或清除该 tab 的设备状态。
@@ -670,6 +683,10 @@ export interface PageInspectParams {
670
683
  export interface PagePressParams {
671
684
  tabId: number;
672
685
  key: string;
686
+ /** Explicit native JavaScript dialog target obtained from a receipt or page_snapshot. */
687
+ dialogId?: string;
688
+ /** Only for accepting a native prompt with dialogId + Enter. */
689
+ promptText?: string;
673
690
  modifiers?: string[];
674
691
  /** Dispatch strategy. Auto uses DOM events when the page is hidden. */
675
692
  pressMode?: 'auto' | 'dom' | 'keyboard';
@@ -760,7 +777,7 @@ export interface SetCookieResult {
760
777
  path: string;
761
778
  reloaded: boolean;
762
779
  }
763
- export interface RequestDomainPermissionParams {
780
+ export interface RequestPermissionParams {
764
781
  domain: string;
765
782
  }
766
783
  export type RunActionName = Exclude<ExtensionBrowserAction, 'run_actions' | 'browser_release' | 'get_capabilities'>;
@@ -818,12 +835,12 @@ export interface BrowserActionMap {
818
835
  request: SendRequestParams;
819
836
  response: unknown;
820
837
  };
821
- send_mtop_request: {
822
- request: SendMtopRequestParams;
838
+ send_protocol_request: {
839
+ request: SendProtocolRequestParams;
823
840
  response: unknown;
824
841
  };
825
842
  browser_list: {
826
- request: undefined;
843
+ request: BrowserListParams | undefined;
827
844
  response: BrowserListResult;
828
845
  };
829
846
  browser_select_browser: {
@@ -948,8 +965,8 @@ export interface BrowserActionMap {
948
965
  request: SetCookieParams;
949
966
  response: SetCookieResult;
950
967
  };
951
- request_domain_permission: {
952
- request: RequestDomainPermissionParams;
968
+ request_permission: {
969
+ request: RequestPermissionParams;
953
970
  response: unknown;
954
971
  };
955
972
  run_actions: {
@@ -983,7 +1000,7 @@ export declare const BROWSER_ACTIONS: {
983
1000
  readonly get_rules: true;
984
1001
  readonly get_capabilities: true;
985
1002
  readonly send_request: true;
986
- readonly send_mtop_request: true;
1003
+ readonly send_protocol_request: true;
987
1004
  readonly browser_list: true;
988
1005
  readonly browser_select_browser: true;
989
1006
  readonly browser_release: true;
@@ -1015,7 +1032,7 @@ export declare const BROWSER_ACTIONS: {
1015
1032
  readonly set_timezone: true;
1016
1033
  readonly get_cookie: true;
1017
1034
  readonly set_cookie: true;
1018
- readonly request_domain_permission: true;
1035
+ readonly request_permission: true;
1019
1036
  readonly run_actions: true;
1020
1037
  };
1021
1038
  export declare const BROWSER_COMMAND_ACTIONS: {
@@ -1030,7 +1047,7 @@ export declare const BROWSER_COMMAND_ACTIONS: {
1030
1047
  readonly get_rules: true;
1031
1048
  readonly get_capabilities: true;
1032
1049
  readonly send_request: true;
1033
- readonly send_mtop_request: true;
1050
+ readonly send_protocol_request: true;
1034
1051
  readonly browser_list: true;
1035
1052
  readonly browser_release: true;
1036
1053
  readonly browser_control: true;
@@ -1061,7 +1078,7 @@ export declare const BROWSER_COMMAND_ACTIONS: {
1061
1078
  readonly set_timezone: true;
1062
1079
  readonly get_cookie: true;
1063
1080
  readonly set_cookie: true;
1064
- readonly request_domain_permission: true;
1081
+ readonly request_permission: true;
1065
1082
  readonly run_actions: true;
1066
1083
  };
1067
1084
  export declare const EXTENSION_BROWSER_ACTIONS: {
@@ -1076,7 +1093,7 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
1076
1093
  readonly get_rules: true;
1077
1094
  readonly get_capabilities: true;
1078
1095
  readonly send_request: true;
1079
- readonly send_mtop_request: true;
1096
+ readonly send_protocol_request: true;
1080
1097
  readonly browser_release: true;
1081
1098
  readonly page_screenshot: true;
1082
1099
  readonly tab_open: true;
@@ -1102,7 +1119,7 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
1102
1119
  readonly set_timezone: true;
1103
1120
  readonly get_cookie: true;
1104
1121
  readonly set_cookie: true;
1105
- readonly request_domain_permission: true;
1122
+ readonly request_permission: true;
1106
1123
  readonly run_actions: true;
1107
1124
  };
1108
1125
  export declare const BROWSER_CAPABILITY_ACTIONS: {
@@ -1118,7 +1135,7 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
1118
1135
  readonly get_rules: true;
1119
1136
  readonly get_capabilities: true;
1120
1137
  readonly send_request: true;
1121
- readonly send_mtop_request: true;
1138
+ readonly send_protocol_request: true;
1122
1139
  readonly browser_release: true;
1123
1140
  readonly page_screenshot: true;
1124
1141
  readonly tab_open: true;
@@ -1144,7 +1161,7 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
1144
1161
  readonly set_timezone: true;
1145
1162
  readonly get_cookie: true;
1146
1163
  readonly set_cookie: true;
1147
- readonly request_domain_permission: true;
1164
+ readonly request_permission: true;
1148
1165
  readonly run_actions: true;
1149
1166
  };
1150
1167
  export declare function isBrowserAction(value: unknown): value is BrowserAction;
@@ -122,7 +122,7 @@ export const BROWSER_ACTIONS = {
122
122
  get_rules: true,
123
123
  get_capabilities: true,
124
124
  send_request: true,
125
- send_mtop_request: true,
125
+ send_protocol_request: true,
126
126
  browser_list: true,
127
127
  browser_select_browser: true,
128
128
  browser_release: true,
@@ -154,7 +154,7 @@ export const BROWSER_ACTIONS = {
154
154
  set_timezone: true,
155
155
  get_cookie: true,
156
156
  set_cookie: true,
157
- request_domain_permission: true,
157
+ request_permission: true,
158
158
  run_actions: true,
159
159
  };
160
160
  export const BROWSER_COMMAND_ACTIONS = {
@@ -169,7 +169,7 @@ export const BROWSER_COMMAND_ACTIONS = {
169
169
  get_rules: true,
170
170
  get_capabilities: true,
171
171
  send_request: true,
172
- send_mtop_request: true,
172
+ send_protocol_request: true,
173
173
  browser_list: true,
174
174
  browser_release: true,
175
175
  browser_control: true,
@@ -200,7 +200,7 @@ export const BROWSER_COMMAND_ACTIONS = {
200
200
  set_timezone: true,
201
201
  get_cookie: true,
202
202
  set_cookie: true,
203
- request_domain_permission: true,
203
+ request_permission: true,
204
204
  run_actions: true,
205
205
  };
206
206
  export const EXTENSION_BROWSER_ACTIONS = {
@@ -215,7 +215,7 @@ export const EXTENSION_BROWSER_ACTIONS = {
215
215
  get_rules: true,
216
216
  get_capabilities: true,
217
217
  send_request: true,
218
- send_mtop_request: true,
218
+ send_protocol_request: true,
219
219
  browser_release: true,
220
220
  page_screenshot: true,
221
221
  tab_open: true,
@@ -241,7 +241,7 @@ export const EXTENSION_BROWSER_ACTIONS = {
241
241
  set_timezone: true,
242
242
  get_cookie: true,
243
243
  set_cookie: true,
244
- request_domain_permission: true,
244
+ request_permission: true,
245
245
  run_actions: true,
246
246
  };
247
247
  export const BROWSER_CAPABILITY_ACTIONS = {
@@ -42,4 +42,6 @@ export declare function describeBrowserCapabilities(actions: readonly string[],
42
42
  error: string;
43
43
  }>;
44
44
  offline?: boolean;
45
+ } | {
46
+ apps: BrowserCapabilityCatalog['apps'];
45
47
  } | undefined, params?: GetCapabilitiesParams): BrowserCapabilityCatalog;
@@ -5,15 +5,29 @@ export function describeBrowserCapabilities(actions, catalog, params = {}) {
5
5
  throw new Error('Invalid capability query');
6
6
  if (params.app !== undefined && (typeof params.app !== 'string' || !params.app || params.app.length > 161))
7
7
  throw new Error('Invalid App capability ID');
8
- if (params.app && catalog && !catalog.offline && !catalog.errors.length && !catalog.profiles.some(entry => entry.id === params.app))
8
+ const installed = catalog && 'profiles' in catalog ? catalog : undefined;
9
+ const projected = catalog && 'apps' in catalog ? catalog.apps : undefined;
10
+ if (params.app && installed && !installed.offline && !installed.errors.length && !installed.profiles.some(entry => entry.id === params.app))
11
+ throw new Error(`App profile is not installed: ${params.app}`);
12
+ if (params.app && projected?.status === 'available' && !projected.entries.some(entry => entry.id === params.app))
9
13
  throw new Error(`App profile is not installed: ${params.app}`);
10
14
  const supportsApps = actions.includes('set_app_profile');
11
- const profiles = supportsApps ? catalog?.profiles ?? [] : [];
15
+ const profiles = supportsApps ? installed?.profiles ?? [] : [];
12
16
  return {
13
17
  actions: [...new Set(actions)],
14
18
  devicePresets: actions.includes('set_device_emulation') ? [...BROWSER_DEVICE_PRESET_NAMES] : [],
15
- apps: {
16
- status: !supportsApps || !catalog ? 'unsupported' : catalog.offline || catalog.errors.length || profiles.some(entry => entry.available === false) ? 'partial' : 'available',
19
+ apps: supportsApps && projected ? {
20
+ status: projected.status,
21
+ entries: projected.entries.filter(entry => !params.app || entry.id === params.app).map(entry => ({
22
+ id: entry.id, label: entry.label, source: entry.source,
23
+ ...(entry.plugin ? { plugin: entry.plugin } : {}), available: entry.available,
24
+ features: [...entry.features],
25
+ ...(entry.usage ? { usage: structuredClone(entry.usage) } : {}),
26
+ ...(params.app && entry.details ? { details: structuredClone(entry.details) } : {}),
27
+ })),
28
+ issues: projected.issues.map(({ plugin, error }) => ({ plugin, error })),
29
+ } : {
30
+ status: !supportsApps || !installed ? 'unsupported' : installed.offline || installed.errors.length || profiles.some(entry => entry.available === false) ? 'partial' : 'available',
17
31
  entries: profiles.filter(entry => !params.app || entry.id === params.app).map(entry => {
18
32
  const definition = entry.definition;
19
33
  const methods = {};
@@ -36,7 +50,7 @@ export function describeBrowserCapabilities(actions, catalog, params = {}) {
36
50
  } } : {}),
37
51
  };
38
52
  }),
39
- issues: catalog?.errors.map(issue => ({ ...issue })) ?? [],
53
+ issues: (installed?.errors ?? projected?.issues)?.map(({ plugin, error }) => ({ plugin, error })) ?? [],
40
54
  },
41
55
  limitations: [
42
56
  'Actions describe support, not current domain permissions, login state or device connectivity.',
@@ -0,0 +1,3 @@
1
+ import type { BrowserListParams } from './browserActionProtocol.js';
2
+ /** An empty request retains ordinary discovery; partial or unknown options cannot be ignored. */
3
+ export declare function parseBrowserListParams(value: unknown): BrowserListParams | undefined;
@@ -0,0 +1,20 @@
1
+ /** An empty request retains ordinary discovery; partial or unknown options cannot be ignored. */
2
+ export function parseBrowserListParams(value) {
3
+ if (value === undefined)
4
+ return undefined;
5
+ if (!value || typeof value !== 'object' || Array.isArray(value))
6
+ throw new Error('Invalid browser_list request');
7
+ const keys = Object.keys(value);
8
+ if (!keys.length)
9
+ return undefined;
10
+ const params = value;
11
+ const form = params.launchForm;
12
+ if (keys.some(key => key !== 'provider' && key !== 'launchForm') ||
13
+ typeof params.provider !== 'string' || !params.provider.trim() ||
14
+ !form || typeof form !== 'object' || Array.isArray(form) ||
15
+ Object.keys(form).some(key => key !== 'variant' && key !== 'values') ||
16
+ (form.variant !== undefined && typeof form.variant !== 'string') ||
17
+ !form.values || typeof form.values !== 'object' || Array.isArray(form.values))
18
+ throw new Error('browser_list discovery requires provider and launchForm with values');
19
+ return params;
20
+ }