@mearl/browser-core 3.0.0-beta.1 → 3.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/README.zh-CN.md +13 -0
- package/dist/agentChat.d.ts +10 -1
- package/dist/agentChat.js +8 -0
- package/dist/agentServiceProtocol.d.ts +23 -0
- package/dist/agentServiceProtocol.js +3 -0
- package/dist/agentSkills.d.ts +1 -1
- package/dist/app-profile-runtime/types.d.ts +10 -12
- package/dist/appProfileDefinition.d.ts +32 -14
- package/dist/appProfileDefinition.js +63 -69
- package/dist/axSnapshot.js +1 -1
- package/dist/boundedRequestBuffer.d.ts +4 -4
- package/dist/browserActionProtocol.d.ts +55 -45
- package/dist/browserActionProtocol.js +12 -15
- package/dist/browserCapabilities.d.ts +47 -0
- package/dist/browserCapabilities.js +63 -0
- package/dist/browserDiscovery.d.ts +3 -0
- package/dist/browserDiscovery.js +20 -0
- package/dist/browserEnhancement.d.ts +161 -0
- package/dist/browserEnhancement.js +80 -0
- package/dist/cookie.d.ts +6 -0
- package/dist/cookie.js +20 -5
- package/dist/dataStructure.d.ts +8 -0
- package/dist/dataStructure.js +58 -0
- package/dist/deviceEmulation.d.ts +6 -0
- package/dist/deviceEmulation.js +13 -0
- package/dist/deviceEnvironmentObservation.d.ts +48 -0
- package/dist/deviceEnvironmentObservation.js +77 -0
- package/dist/domClicking.d.ts +14 -0
- package/dist/domClicking.js +98 -10
- package/dist/domInspection.js +13 -1
- package/dist/extensionServiceProtocol.d.ts +7 -0
- package/dist/extensionServiceProtocol.js +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/pageAct.d.ts +2 -0
- package/dist/pageAct.js +42 -10
- package/dist/pageDialog.d.ts +66 -0
- package/dist/pageDialog.js +175 -0
- package/dist/pageObserver.js +16 -5
- package/dist/pagePressing.d.ts +1 -1
- package/dist/pluginPageHost.js +2 -2
- package/dist/providerAppResources.d.ts +39 -0
- package/dist/providerAppResources.js +2 -0
- package/dist/proxyPermissions.js +3 -3
- package/dist/requestMetadata.d.ts +9 -0
- package/dist/requestMetadata.js +8 -0
- package/dist/requestSerializer.d.ts +2 -2
- package/dist/requestSerializer.js +1 -29
- package/dist/requestStreamCapture.d.ts +5 -3
- package/dist/requestStreamCapture.js +2 -0
- package/dist/runActions.js +1 -1
- package/dist/types.d.ts +4 -2
- package/package.json +2 -2
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type { BrowserCapabilityCatalog } from './browserCapabilities.js';
|
|
2
|
+
export interface GetCapabilitiesParams {
|
|
3
|
+
/** Include method and setting details for this installed App ID. */
|
|
4
|
+
app?: string;
|
|
5
|
+
}
|
|
1
6
|
export interface GetRequestsParams {
|
|
2
7
|
tabId: number;
|
|
3
8
|
count?: number;
|
|
@@ -13,7 +18,7 @@ export interface GetRequestsParams {
|
|
|
13
18
|
fields?: string[];
|
|
14
19
|
keysOnly?: boolean;
|
|
15
20
|
applyHiddenFilter?: boolean;
|
|
16
|
-
source?: '
|
|
21
|
+
source?: 'protocol' | 'requests' | 'all';
|
|
17
22
|
}
|
|
18
23
|
export interface GetLogsParams {
|
|
19
24
|
tabId: number;
|
|
@@ -107,18 +112,9 @@ export interface SendRequestParams {
|
|
|
107
112
|
responseType?: 'json' | 'text' | 'auto';
|
|
108
113
|
timeout?: number;
|
|
109
114
|
}
|
|
110
|
-
export
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
api: string;
|
|
114
|
-
data?: unknown;
|
|
115
|
-
version?: string;
|
|
116
|
-
method?: string;
|
|
117
|
-
appKey?: string;
|
|
118
|
-
env?: MtopEnvironmentTarget;
|
|
119
|
-
timeout?: number;
|
|
120
|
-
headers?: Record<string, string>;
|
|
121
|
-
ttid?: string;
|
|
115
|
+
export interface NetworkControlSelection {
|
|
116
|
+
id: string;
|
|
117
|
+
value: string;
|
|
122
118
|
}
|
|
123
119
|
export type BrowserStatus = 'connected' | 'pairing' | 'running_disconnected' | 'stopped';
|
|
124
120
|
export type BrowserTransport = 'extension' | 'cdp' | 'provider';
|
|
@@ -184,6 +180,7 @@ export interface BrowserInfoBase {
|
|
|
184
180
|
pairing?: BrowserPairingInfo;
|
|
185
181
|
}
|
|
186
182
|
export type BrowserScreenshotKind = 'native' | 'reconstructed' | 'none';
|
|
183
|
+
export type BrowserControlSessionMode = 'mearl' | 'external';
|
|
187
184
|
/** Browser-targeted actions that an external provider may implement. */
|
|
188
185
|
export type BrowserCapabilityAction = ExtensionBrowserAction | 'page_download';
|
|
189
186
|
/** Capabilities advertised by an external browser-control provider. */
|
|
@@ -191,6 +188,8 @@ export interface BrowserCapabilities {
|
|
|
191
188
|
actions: BrowserCapabilityAction[];
|
|
192
189
|
/** Pixel fidelity of page_screenshot, or none when that action is unavailable. */
|
|
193
190
|
screenshot: BrowserScreenshotKind;
|
|
191
|
+
/** Fixed per instance. Omitted means Mearl sessions; external delegates task control. */
|
|
192
|
+
controlSessionMode?: BrowserControlSessionMode;
|
|
194
193
|
}
|
|
195
194
|
export interface RegularBrowserInfo extends BrowserInfoBase {
|
|
196
195
|
type: 'regular';
|
|
@@ -204,6 +203,13 @@ export interface ManagedBrowserInfo extends BrowserInfoBase {
|
|
|
204
203
|
operations: BrowserProviderOperation[];
|
|
205
204
|
}
|
|
206
205
|
export type BrowserInfo = RegularBrowserInfo | ManagedBrowserInfo;
|
|
206
|
+
export interface BrowserListParams {
|
|
207
|
+
provider: string;
|
|
208
|
+
launchForm: {
|
|
209
|
+
variant?: string;
|
|
210
|
+
values: Record<string, BrowserJsonValue>;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
207
213
|
export interface BrowserListResult {
|
|
208
214
|
count: number;
|
|
209
215
|
connectedCount: number;
|
|
@@ -211,6 +217,11 @@ export interface BrowserListResult {
|
|
|
211
217
|
browsers: BrowserInfo[];
|
|
212
218
|
/** Partial discovery failures; successfully inspected browser sources remain in the result. */
|
|
213
219
|
warnings?: string[];
|
|
220
|
+
/** Present only for an explicit, source-local Provider launch-form query. */
|
|
221
|
+
discovery?: {
|
|
222
|
+
provider: string;
|
|
223
|
+
launchForm: BrowserProviderLaunchForm;
|
|
224
|
+
};
|
|
214
225
|
}
|
|
215
226
|
export interface SelectBrowserParams {
|
|
216
227
|
browser?: string;
|
|
@@ -366,6 +377,7 @@ export interface BrowserProviderDefinition {
|
|
|
366
377
|
provider: BrowserProviderIdentity;
|
|
367
378
|
browserType: {
|
|
368
379
|
name: string;
|
|
380
|
+
controlSessionModes?: readonly BrowserControlSessionMode[];
|
|
369
381
|
documentationUrl?: string;
|
|
370
382
|
inputSchema: BrowserProviderObjectSchema;
|
|
371
383
|
configuration?: {
|
|
@@ -457,7 +469,8 @@ export interface BrowserEmulationOptions {
|
|
|
457
469
|
/** App 容器横屏时将根页面与业务页面分置左右 WebView;仅与 deviceShell、App 档案同时生效。 */
|
|
458
470
|
splitScreen?: boolean;
|
|
459
471
|
}
|
|
460
|
-
|
|
472
|
+
/** Provider-defined behavior ID; core does not execute or enumerate business behaviors. */
|
|
473
|
+
export type AppBridgeConfigBehavior = string;
|
|
461
474
|
/** 单个桥方法的声明式覆盖;行为、固定回包、成功空实现三选一。 */
|
|
462
475
|
export interface AppBridgeMethodConfig {
|
|
463
476
|
behavior?: AppBridgeConfigBehavior;
|
|
@@ -486,8 +499,8 @@ export interface TabOpenParams {
|
|
|
486
499
|
emulation?: BrowserEmulationOptions;
|
|
487
500
|
group?: string;
|
|
488
501
|
/**
|
|
489
|
-
*
|
|
490
|
-
* 设备视口和 iframe 系统外壳由 emulation.deviceShell
|
|
502
|
+
* 客户端容器模拟档案名(由已安装能力目录提供)。只注入容器 UA、环境变量、JSBridge 与桥协议;
|
|
503
|
+
* 设备视口和 iframe 系统外壳由 emulation.deviceShell 独立控制。可用档案通过 get_capabilities 查询。
|
|
491
504
|
*/
|
|
492
505
|
appProfile?: AppProfileName;
|
|
493
506
|
/** 与 appProfile 配合使用;容器系统,默认 ios */
|
|
@@ -504,16 +517,9 @@ export type TabGroupParams = {
|
|
|
504
517
|
ungroup: true;
|
|
505
518
|
title?: never;
|
|
506
519
|
};
|
|
507
|
-
/**
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
* 档案数据(UA / 桥对象 / 方法映射)在 @mearl/app-profiles 维护,但名单属于协议:
|
|
511
|
-
* 它是 set_app_profile.profile 与 tab_open.appProfile 的取值域,CLI 帮助与 MCP 工具
|
|
512
|
-
* schema 的 enum 也由它生成。app-profiles 反向引用本清单约束自己的档案表,
|
|
513
|
-
* 因此新增档案时只需改两处(名单 + 档案数据),且漏改会在类型检查时暴露。
|
|
514
|
-
*/
|
|
515
|
-
export declare const APP_PROFILE_NAMES: readonly ["fliggy", "taobao", "wechat", "alipay"];
|
|
516
|
-
export type BuiltinAppProfileName = (typeof APP_PROFILE_NAMES)[number];
|
|
520
|
+
/** App identities are supplied by installed capability catalogs. */
|
|
521
|
+
export declare const APP_PROFILE_NAMES: readonly string[];
|
|
522
|
+
export type BuiltinAppProfileName = string;
|
|
517
523
|
/** Hosts validate dynamic profile IDs against the active capability catalog. */
|
|
518
524
|
export type AppProfileName = string;
|
|
519
525
|
export interface SetAppProfileParams {
|
|
@@ -534,10 +540,10 @@ export interface SetAppProfileParams {
|
|
|
534
540
|
/** 按方法覆盖档案内置桥配置,仅支持受控行为、固定 JSON 回包和成功空实现 */
|
|
535
541
|
bridgeConfig?: AppBridgeConfig;
|
|
536
542
|
/**
|
|
537
|
-
*
|
|
543
|
+
* 可选已安装的网络控件选择;null 清除,省略时保持当前设置。
|
|
538
544
|
* 仅作用于目标 tab,扩展模式与该 tab 的快捷设置共享。
|
|
539
545
|
*/
|
|
540
|
-
|
|
546
|
+
networkControl?: NetworkControlSelection | null;
|
|
541
547
|
/**
|
|
542
548
|
* 可选设备联动参数。传入时显式字段覆盖档案推荐设备,空对象使用推荐设备且默认开启
|
|
543
549
|
* deviceShell;省略时不设置或清除该 tab 的设备状态。
|
|
@@ -672,6 +678,10 @@ export interface PageInspectParams {
|
|
|
672
678
|
export interface PagePressParams {
|
|
673
679
|
tabId: number;
|
|
674
680
|
key: string;
|
|
681
|
+
/** Explicit native JavaScript dialog target obtained from a receipt or page_snapshot. */
|
|
682
|
+
dialogId?: string;
|
|
683
|
+
/** Only for accepting a native prompt with dialogId + Enter. */
|
|
684
|
+
promptText?: string;
|
|
675
685
|
modifiers?: string[];
|
|
676
686
|
/** Dispatch strategy. Auto uses DOM events when the page is hidden. */
|
|
677
687
|
pressMode?: 'auto' | 'dom' | 'keyboard';
|
|
@@ -762,10 +772,10 @@ export interface SetCookieResult {
|
|
|
762
772
|
path: string;
|
|
763
773
|
reloaded: boolean;
|
|
764
774
|
}
|
|
765
|
-
export interface
|
|
775
|
+
export interface RequestPermissionParams {
|
|
766
776
|
domain: string;
|
|
767
777
|
}
|
|
768
|
-
export type RunActionName = Exclude<ExtensionBrowserAction, 'run_actions' | 'browser_release'>;
|
|
778
|
+
export type RunActionName = Exclude<ExtensionBrowserAction, 'run_actions' | 'browser_release' | 'get_capabilities'>;
|
|
769
779
|
export interface ActionStep {
|
|
770
780
|
action: RunActionName;
|
|
771
781
|
data?: Record<string, unknown>;
|
|
@@ -775,6 +785,10 @@ export interface RunActionsParams {
|
|
|
775
785
|
tabId: number;
|
|
776
786
|
}
|
|
777
787
|
export interface BrowserActionMap {
|
|
788
|
+
get_capabilities: {
|
|
789
|
+
request: GetCapabilitiesParams;
|
|
790
|
+
response: BrowserCapabilityCatalog;
|
|
791
|
+
};
|
|
778
792
|
tab_checkpoint: {
|
|
779
793
|
request: CaptureCheckpointParams;
|
|
780
794
|
response: CaptureCheckpointResult;
|
|
@@ -816,12 +830,8 @@ export interface BrowserActionMap {
|
|
|
816
830
|
request: SendRequestParams;
|
|
817
831
|
response: unknown;
|
|
818
832
|
};
|
|
819
|
-
send_mtop_request: {
|
|
820
|
-
request: SendMtopRequestParams;
|
|
821
|
-
response: unknown;
|
|
822
|
-
};
|
|
823
833
|
browser_list: {
|
|
824
|
-
request: undefined;
|
|
834
|
+
request: BrowserListParams | undefined;
|
|
825
835
|
response: BrowserListResult;
|
|
826
836
|
};
|
|
827
837
|
browser_select_browser: {
|
|
@@ -946,8 +956,8 @@ export interface BrowserActionMap {
|
|
|
946
956
|
request: SetCookieParams;
|
|
947
957
|
response: SetCookieResult;
|
|
948
958
|
};
|
|
949
|
-
|
|
950
|
-
request:
|
|
959
|
+
request_permission: {
|
|
960
|
+
request: RequestPermissionParams;
|
|
951
961
|
response: unknown;
|
|
952
962
|
};
|
|
953
963
|
run_actions: {
|
|
@@ -979,8 +989,8 @@ export declare const BROWSER_ACTIONS: {
|
|
|
979
989
|
readonly get_mocks: true;
|
|
980
990
|
readonly set_rule: true;
|
|
981
991
|
readonly get_rules: true;
|
|
992
|
+
readonly get_capabilities: true;
|
|
982
993
|
readonly send_request: true;
|
|
983
|
-
readonly send_mtop_request: true;
|
|
984
994
|
readonly browser_list: true;
|
|
985
995
|
readonly browser_select_browser: true;
|
|
986
996
|
readonly browser_release: true;
|
|
@@ -1012,7 +1022,7 @@ export declare const BROWSER_ACTIONS: {
|
|
|
1012
1022
|
readonly set_timezone: true;
|
|
1013
1023
|
readonly get_cookie: true;
|
|
1014
1024
|
readonly set_cookie: true;
|
|
1015
|
-
readonly
|
|
1025
|
+
readonly request_permission: true;
|
|
1016
1026
|
readonly run_actions: true;
|
|
1017
1027
|
};
|
|
1018
1028
|
export declare const BROWSER_COMMAND_ACTIONS: {
|
|
@@ -1025,8 +1035,8 @@ export declare const BROWSER_COMMAND_ACTIONS: {
|
|
|
1025
1035
|
readonly get_mocks: true;
|
|
1026
1036
|
readonly set_rule: true;
|
|
1027
1037
|
readonly get_rules: true;
|
|
1038
|
+
readonly get_capabilities: true;
|
|
1028
1039
|
readonly send_request: true;
|
|
1029
|
-
readonly send_mtop_request: true;
|
|
1030
1040
|
readonly browser_list: true;
|
|
1031
1041
|
readonly browser_release: true;
|
|
1032
1042
|
readonly browser_control: true;
|
|
@@ -1057,7 +1067,7 @@ export declare const BROWSER_COMMAND_ACTIONS: {
|
|
|
1057
1067
|
readonly set_timezone: true;
|
|
1058
1068
|
readonly get_cookie: true;
|
|
1059
1069
|
readonly set_cookie: true;
|
|
1060
|
-
readonly
|
|
1070
|
+
readonly request_permission: true;
|
|
1061
1071
|
readonly run_actions: true;
|
|
1062
1072
|
};
|
|
1063
1073
|
export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
@@ -1070,8 +1080,8 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
|
1070
1080
|
readonly get_mocks: true;
|
|
1071
1081
|
readonly set_rule: true;
|
|
1072
1082
|
readonly get_rules: true;
|
|
1083
|
+
readonly get_capabilities: true;
|
|
1073
1084
|
readonly send_request: true;
|
|
1074
|
-
readonly send_mtop_request: true;
|
|
1075
1085
|
readonly browser_release: true;
|
|
1076
1086
|
readonly page_screenshot: true;
|
|
1077
1087
|
readonly tab_open: true;
|
|
@@ -1097,7 +1107,7 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
|
1097
1107
|
readonly set_timezone: true;
|
|
1098
1108
|
readonly get_cookie: true;
|
|
1099
1109
|
readonly set_cookie: true;
|
|
1100
|
-
readonly
|
|
1110
|
+
readonly request_permission: true;
|
|
1101
1111
|
readonly run_actions: true;
|
|
1102
1112
|
};
|
|
1103
1113
|
export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
@@ -1111,8 +1121,8 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
|
1111
1121
|
readonly get_mocks: true;
|
|
1112
1122
|
readonly set_rule: true;
|
|
1113
1123
|
readonly get_rules: true;
|
|
1124
|
+
readonly get_capabilities: true;
|
|
1114
1125
|
readonly send_request: true;
|
|
1115
|
-
readonly send_mtop_request: true;
|
|
1116
1126
|
readonly browser_release: true;
|
|
1117
1127
|
readonly page_screenshot: true;
|
|
1118
1128
|
readonly tab_open: true;
|
|
@@ -1138,7 +1148,7 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
|
1138
1148
|
readonly set_timezone: true;
|
|
1139
1149
|
readonly get_cookie: true;
|
|
1140
1150
|
readonly set_cookie: true;
|
|
1141
|
-
readonly
|
|
1151
|
+
readonly request_permission: true;
|
|
1142
1152
|
readonly run_actions: true;
|
|
1143
1153
|
};
|
|
1144
1154
|
export declare function isBrowserAction(value: unknown): value is BrowserAction;
|
|
@@ -20,15 +20,8 @@ export const BROWSER_DEVICE_PRESET_NAMES = [
|
|
|
20
20
|
'ipad-mini',
|
|
21
21
|
'galaxy-s23',
|
|
22
22
|
];
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
*
|
|
26
|
-
* 档案数据(UA / 桥对象 / 方法映射)在 @mearl/app-profiles 维护,但名单属于协议:
|
|
27
|
-
* 它是 set_app_profile.profile 与 tab_open.appProfile 的取值域,CLI 帮助与 MCP 工具
|
|
28
|
-
* schema 的 enum 也由它生成。app-profiles 反向引用本清单约束自己的档案表,
|
|
29
|
-
* 因此新增档案时只需改两处(名单 + 档案数据),且漏改会在类型检查时暴露。
|
|
30
|
-
*/
|
|
31
|
-
export const APP_PROFILE_NAMES = ['fliggy', 'taobao', 'wechat', 'alipay'];
|
|
23
|
+
/** App identities are supplied by installed capability catalogs. */
|
|
24
|
+
export const APP_PROFILE_NAMES = [];
|
|
32
25
|
export function resolvePageEvalExpression(params) {
|
|
33
26
|
if (typeof params.expression !== 'string' || !params.expression.trim())
|
|
34
27
|
throw new Error('Invalid expression');
|
|
@@ -83,6 +76,10 @@ export function actionRequiresTabId(action) {
|
|
|
83
76
|
return typeof action === 'string' && TAB_ID_REQUIRED_ACTION_SET.has(action);
|
|
84
77
|
}
|
|
85
78
|
export function validateRequiredActionTabId(action, data) {
|
|
79
|
+
if (action === 'get_capabilities' && data && typeof data === 'object' &&
|
|
80
|
+
['tabId', 'tabIds', 'openerTabId'].some(key => Object.hasOwn(data, key))) {
|
|
81
|
+
throw new Error('get_capabilities does not accept page targets');
|
|
82
|
+
}
|
|
86
83
|
const cookieAction = action === 'get_cookie' || action === 'set_cookie';
|
|
87
84
|
if (!actionRequiresTabId(action) && !cookieAction)
|
|
88
85
|
return;
|
|
@@ -123,8 +120,8 @@ export const BROWSER_ACTIONS = {
|
|
|
123
120
|
get_mocks: true,
|
|
124
121
|
set_rule: true,
|
|
125
122
|
get_rules: true,
|
|
123
|
+
get_capabilities: true,
|
|
126
124
|
send_request: true,
|
|
127
|
-
send_mtop_request: true,
|
|
128
125
|
browser_list: true,
|
|
129
126
|
browser_select_browser: true,
|
|
130
127
|
browser_release: true,
|
|
@@ -156,7 +153,7 @@ export const BROWSER_ACTIONS = {
|
|
|
156
153
|
set_timezone: true,
|
|
157
154
|
get_cookie: true,
|
|
158
155
|
set_cookie: true,
|
|
159
|
-
|
|
156
|
+
request_permission: true,
|
|
160
157
|
run_actions: true,
|
|
161
158
|
};
|
|
162
159
|
export const BROWSER_COMMAND_ACTIONS = {
|
|
@@ -169,8 +166,8 @@ export const BROWSER_COMMAND_ACTIONS = {
|
|
|
169
166
|
get_mocks: true,
|
|
170
167
|
set_rule: true,
|
|
171
168
|
get_rules: true,
|
|
169
|
+
get_capabilities: true,
|
|
172
170
|
send_request: true,
|
|
173
|
-
send_mtop_request: true,
|
|
174
171
|
browser_list: true,
|
|
175
172
|
browser_release: true,
|
|
176
173
|
browser_control: true,
|
|
@@ -201,7 +198,7 @@ export const BROWSER_COMMAND_ACTIONS = {
|
|
|
201
198
|
set_timezone: true,
|
|
202
199
|
get_cookie: true,
|
|
203
200
|
set_cookie: true,
|
|
204
|
-
|
|
201
|
+
request_permission: true,
|
|
205
202
|
run_actions: true,
|
|
206
203
|
};
|
|
207
204
|
export const EXTENSION_BROWSER_ACTIONS = {
|
|
@@ -214,8 +211,8 @@ export const EXTENSION_BROWSER_ACTIONS = {
|
|
|
214
211
|
get_mocks: true,
|
|
215
212
|
set_rule: true,
|
|
216
213
|
get_rules: true,
|
|
214
|
+
get_capabilities: true,
|
|
217
215
|
send_request: true,
|
|
218
|
-
send_mtop_request: true,
|
|
219
216
|
browser_release: true,
|
|
220
217
|
page_screenshot: true,
|
|
221
218
|
tab_open: true,
|
|
@@ -241,7 +238,7 @@ export const EXTENSION_BROWSER_ACTIONS = {
|
|
|
241
238
|
set_timezone: true,
|
|
242
239
|
get_cookie: true,
|
|
243
240
|
set_cookie: true,
|
|
244
|
-
|
|
241
|
+
request_permission: true,
|
|
245
242
|
run_actions: true,
|
|
246
243
|
};
|
|
247
244
|
export const BROWSER_CAPABILITY_ACTIONS = {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AppProfileCatalogEntry, AppProfileSetting, AppProfileUsage } from './appProfileDefinition.js';
|
|
2
|
+
import type { GetCapabilitiesParams } from './browserActionProtocol.js';
|
|
3
|
+
export interface AppCapability {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
source: AppProfileCatalogEntry['source'];
|
|
7
|
+
plugin?: string;
|
|
8
|
+
available: boolean;
|
|
9
|
+
features: string[];
|
|
10
|
+
usage?: AppProfileUsage;
|
|
11
|
+
details?: {
|
|
12
|
+
defaultAppVersion: string;
|
|
13
|
+
bridges: string[];
|
|
14
|
+
methods: Record<string, string[]>;
|
|
15
|
+
behaviors: Record<string, string>;
|
|
16
|
+
settings: AppProfileSetting[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface BrowserCapabilityCatalog {
|
|
20
|
+
/** Supported operations, not a grant of page permissions or business authorization. */
|
|
21
|
+
actions: string[];
|
|
22
|
+
devicePresets: string[];
|
|
23
|
+
apps: {
|
|
24
|
+
status: 'available' | 'partial' | 'unsupported';
|
|
25
|
+
entries: AppCapability[];
|
|
26
|
+
issues: Array<{
|
|
27
|
+
plugin: string;
|
|
28
|
+
error: string;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
limitations: string[];
|
|
32
|
+
help: {
|
|
33
|
+
skill: string;
|
|
34
|
+
commands: string[];
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Project validated installed metadata without scripts, global values or Mock response bodies. */
|
|
38
|
+
export declare function describeBrowserCapabilities(actions: readonly string[], catalog: {
|
|
39
|
+
profiles: AppProfileCatalogEntry[];
|
|
40
|
+
errors: Array<{
|
|
41
|
+
plugin: string;
|
|
42
|
+
error: string;
|
|
43
|
+
}>;
|
|
44
|
+
offline?: boolean;
|
|
45
|
+
} | {
|
|
46
|
+
apps: BrowserCapabilityCatalog['apps'];
|
|
47
|
+
} | undefined, params?: GetCapabilitiesParams): BrowserCapabilityCatalog;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BROWSER_DEVICE_PRESET_NAMES } from './browserActionProtocol.js';
|
|
2
|
+
/** Project validated installed metadata without scripts, global values or Mock response bodies. */
|
|
3
|
+
export function describeBrowserCapabilities(actions, catalog, params = {}) {
|
|
4
|
+
if (!params || typeof params !== 'object' || Array.isArray(params))
|
|
5
|
+
throw new Error('Invalid capability query');
|
|
6
|
+
if (params.app !== undefined && (typeof params.app !== 'string' || !params.app || params.app.length > 161))
|
|
7
|
+
throw new Error('Invalid App capability ID');
|
|
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))
|
|
13
|
+
throw new Error(`App profile is not installed: ${params.app}`);
|
|
14
|
+
const supportsApps = actions.includes('set_app_profile');
|
|
15
|
+
const profiles = supportsApps ? installed?.profiles ?? [] : [];
|
|
16
|
+
return {
|
|
17
|
+
actions: [...new Set(actions)],
|
|
18
|
+
devicePresets: actions.includes('set_device_emulation') ? [...BROWSER_DEVICE_PRESET_NAMES] : [],
|
|
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',
|
|
31
|
+
entries: profiles.filter(entry => !params.app || entry.id === params.app).map(entry => {
|
|
32
|
+
const definition = entry.definition;
|
|
33
|
+
const methods = {};
|
|
34
|
+
for (const [name, values] of Object.entries(definition.actions)) {
|
|
35
|
+
const names = Array.isArray(values) ? values : Object.keys(values ?? {});
|
|
36
|
+
if (names.length)
|
|
37
|
+
methods[name] = [...names];
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
id: entry.id, label: entry.label, source: entry.source, plugin: entry.plugin,
|
|
41
|
+
available: entry.available !== false,
|
|
42
|
+
features: ['userAgent', ...(definition.bridges.length ? ['jsBridge'] : []), ...Object.keys(methods), ...(definition.schemes.length ? ['schemes'] : []), ...(definition.settings?.length ? ['settings'] : [])],
|
|
43
|
+
...(definition.usage ? { usage: structuredClone(definition.usage) } : {}),
|
|
44
|
+
...(params.app ? { details: {
|
|
45
|
+
defaultAppVersion: definition.defaultAppVersion,
|
|
46
|
+
bridges: definition.bridges.map(bridge => bridge.global),
|
|
47
|
+
methods,
|
|
48
|
+
behaviors: { ...definition.actions.behaviors },
|
|
49
|
+
settings: structuredClone(definition.settings ?? []),
|
|
50
|
+
} } : {}),
|
|
51
|
+
};
|
|
52
|
+
}),
|
|
53
|
+
issues: (installed?.errors ?? projected?.issues)?.map(({ plugin, error }) => ({ plugin, error })) ?? [],
|
|
54
|
+
},
|
|
55
|
+
limitations: [
|
|
56
|
+
'Actions describe support, not current domain permissions, login state or device connectivity.',
|
|
57
|
+
'App profiles simulate a WebView. Declared bridge methods, behaviors and response stubs do not guarantee real native authorization, payment or other business effects.',
|
|
58
|
+
'Package usage and Skill names are guidance from the package author; referenced Skills may need separate installation. Read the relevant help only when needed.',
|
|
59
|
+
...(!catalog && supportsApps ? ['This Provider does not expose an installed App catalog.'] : []),
|
|
60
|
+
],
|
|
61
|
+
help: { skill: 'mearl', commands: ['mearl get_capabilities --help', 'mearl set_device_emulation --help', 'mearl set_app_profile --help', 'mearl tab_open --help'] },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { BrowserActionMap } from './browserActionProtocol.js';
|
|
2
|
+
import { type DeviceEnvironmentObservation } from './deviceEnvironmentObservation.js';
|
|
3
|
+
export declare const BROWSER_ENHANCEMENT_PROTOCOL_VERSION = 1;
|
|
4
|
+
export declare const BROWSER_ENHANCEMENT_NAVIGATION_ORIGIN_VERSION = 1;
|
|
5
|
+
export declare const BROWSER_ENHANCEMENT_PREPARATION_VERSION = 1;
|
|
6
|
+
export declare const BROWSER_ENHANCEMENT_HOST_ENVIRONMENT_VERSION = 1;
|
|
7
|
+
export declare const BROWSER_ENHANCEMENT_PREPARATION_PATH = "src/pages/browser-transport/index.html";
|
|
8
|
+
/** Only the installed Extension's inert top-level page can prepare a new document. */
|
|
9
|
+
export declare function isBrowserEnhancementPreparationUrl(value: unknown): value is string;
|
|
10
|
+
/** Narrow internal host contract. Ordinary input, navigation and browser lifecycle are excluded. */
|
|
11
|
+
export type BrowserEnhancementAction = 'set_device_emulation' | 'set_app_profile' | 'set_timezone';
|
|
12
|
+
export declare function isBrowserEnhancementAction(value: unknown): value is BrowserEnhancementAction;
|
|
13
|
+
export type BrowserEnhancementInvocation = {
|
|
14
|
+
[A in BrowserEnhancementAction]: {
|
|
15
|
+
action: A;
|
|
16
|
+
data: BrowserActionMap[A]['request'];
|
|
17
|
+
};
|
|
18
|
+
}[BrowserEnhancementAction];
|
|
19
|
+
export declare function requiredBrowserEnhancementActions(invocation: BrowserEnhancementInvocation): BrowserEnhancementAction[];
|
|
20
|
+
export interface BrowserEnhancementBinding {
|
|
21
|
+
bindingId: string;
|
|
22
|
+
generation: number;
|
|
23
|
+
tabId: number;
|
|
24
|
+
mainFrameId: string;
|
|
25
|
+
targetId?: string;
|
|
26
|
+
actions: BrowserEnhancementAction[];
|
|
27
|
+
}
|
|
28
|
+
export interface BrowserEnhancementCapabilities {
|
|
29
|
+
protocolVersion: typeof BROWSER_ENHANCEMENT_PROTOCOL_VERSION;
|
|
30
|
+
actions: BrowserEnhancementAction[];
|
|
31
|
+
navigationOriginVersion?: typeof BROWSER_ENHANCEMENT_NAVIGATION_ORIGIN_VERSION;
|
|
32
|
+
preparationVersion?: typeof BROWSER_ENHANCEMENT_PREPARATION_VERSION;
|
|
33
|
+
hostEnvironmentVersion?: typeof BROWSER_ENHANCEMENT_HOST_ENVIRONMENT_VERSION;
|
|
34
|
+
}
|
|
35
|
+
export interface BrowserEnhancementPreparation {
|
|
36
|
+
tabId: number;
|
|
37
|
+
targetId: string;
|
|
38
|
+
url: string;
|
|
39
|
+
capabilities: BrowserEnhancementCapabilities;
|
|
40
|
+
}
|
|
41
|
+
export interface ProviderEnhancementPreparation extends BrowserEnhancementPreparation {
|
|
42
|
+
nativeBrowserId: string;
|
|
43
|
+
providerTabId: number;
|
|
44
|
+
}
|
|
45
|
+
/** Captured by the accepted external owner immediately after creating this target. */
|
|
46
|
+
export interface ProviderInitialEnvironment {
|
|
47
|
+
device: DeviceEnvironmentObservation;
|
|
48
|
+
/** Keep the physical root's captured platform while logical App/device identities remain unchanged. */
|
|
49
|
+
preserveHostPlatform?: true;
|
|
50
|
+
/** The external host owns native pointer/touch delivery; Chrome must not convert its mouse events. */
|
|
51
|
+
preserveHostInput?: true;
|
|
52
|
+
}
|
|
53
|
+
export declare function isProviderInitialEnvironment(value: unknown): value is ProviderInitialEnvironment;
|
|
54
|
+
export declare function isEnhancementNavigationOrigin(value: unknown): value is string;
|
|
55
|
+
/** owner is derived by the accepted Provider control host, never from an ordinary action payload. */
|
|
56
|
+
export type BrowserEnhancementRequest = ({
|
|
57
|
+
operation: 'probe';
|
|
58
|
+
tabId: number;
|
|
59
|
+
} | {
|
|
60
|
+
operation: 'inspect';
|
|
61
|
+
owner: string;
|
|
62
|
+
tabId: number;
|
|
63
|
+
targetId: string;
|
|
64
|
+
actions: BrowserEnhancementAction[];
|
|
65
|
+
navigationOrigin: string;
|
|
66
|
+
} | {
|
|
67
|
+
operation: 'bind';
|
|
68
|
+
owner: string;
|
|
69
|
+
tabId: number;
|
|
70
|
+
mainFrameId: string;
|
|
71
|
+
targetId?: string;
|
|
72
|
+
actions: BrowserEnhancementAction[];
|
|
73
|
+
navigationOrigin?: string;
|
|
74
|
+
initialEnvironment?: ProviderInitialEnvironment;
|
|
75
|
+
} | ({
|
|
76
|
+
operation: 'invoke';
|
|
77
|
+
owner: string;
|
|
78
|
+
bindingId: string;
|
|
79
|
+
generation: number;
|
|
80
|
+
} & BrowserEnhancementInvocation) | {
|
|
81
|
+
operation: 'release';
|
|
82
|
+
owner: string;
|
|
83
|
+
bindingId: string;
|
|
84
|
+
generation: number;
|
|
85
|
+
}) & {
|
|
86
|
+
deadline?: number;
|
|
87
|
+
};
|
|
88
|
+
export type BrowserEnhancementResponse = {
|
|
89
|
+
capabilities: BrowserEnhancementCapabilities;
|
|
90
|
+
tabId: number;
|
|
91
|
+
mainFrameId: string;
|
|
92
|
+
targetId?: string;
|
|
93
|
+
} | {
|
|
94
|
+
preparation: BrowserEnhancementPreparation;
|
|
95
|
+
} | {
|
|
96
|
+
binding: BrowserEnhancementBinding;
|
|
97
|
+
} | {
|
|
98
|
+
result: unknown;
|
|
99
|
+
} | {
|
|
100
|
+
released: boolean;
|
|
101
|
+
conflicts?: string[];
|
|
102
|
+
};
|
|
103
|
+
export interface ProviderEnhancementBinding extends BrowserEnhancementBinding {
|
|
104
|
+
nativeBrowserId: string;
|
|
105
|
+
providerTabId: number;
|
|
106
|
+
}
|
|
107
|
+
/** Read-only control/identity preflight supplied by the external page owner. */
|
|
108
|
+
export type ProviderEnhancementTarget = {
|
|
109
|
+
tabId: number;
|
|
110
|
+
ready: false;
|
|
111
|
+
} | {
|
|
112
|
+
tabId: number;
|
|
113
|
+
ready: true;
|
|
114
|
+
mainFrameId?: string;
|
|
115
|
+
targetId?: string;
|
|
116
|
+
url: string;
|
|
117
|
+
initialEnvironment?: ProviderInitialEnvironment;
|
|
118
|
+
};
|
|
119
|
+
export declare function isProviderEnhancementTarget(value: unknown): value is ProviderEnhancementTarget;
|
|
120
|
+
/** Match every identity asserted by the external owner; URL alone is never proof. */
|
|
121
|
+
export declare function matchesProviderEnhancementTarget(target: Extract<ProviderEnhancementTarget, {
|
|
122
|
+
ready: true;
|
|
123
|
+
}>, physical: {
|
|
124
|
+
mainFrameId: string;
|
|
125
|
+
targetId?: string;
|
|
126
|
+
}): boolean;
|
|
127
|
+
export declare function requireReadyProviderEnhancementTarget(value: unknown, tabId: number): Extract<ProviderEnhancementTarget, {
|
|
128
|
+
ready: true;
|
|
129
|
+
}>;
|
|
130
|
+
/** Provider-side request. The control host supplies ownership and physical tab mappings. */
|
|
131
|
+
export type ProviderEnhancementRequest = {
|
|
132
|
+
operation: 'inspect';
|
|
133
|
+
providerTabId: number;
|
|
134
|
+
nativeBrowserId?: string;
|
|
135
|
+
actions: BrowserEnhancementAction[];
|
|
136
|
+
navigationOrigin: string;
|
|
137
|
+
} | {
|
|
138
|
+
operation: 'bind';
|
|
139
|
+
providerTabId: number;
|
|
140
|
+
nativeBrowserId?: string;
|
|
141
|
+
actions: BrowserEnhancementAction[];
|
|
142
|
+
navigationOrigin?: string;
|
|
143
|
+
} | ({
|
|
144
|
+
operation: 'invoke';
|
|
145
|
+
bindingId: string;
|
|
146
|
+
generation: number;
|
|
147
|
+
} & BrowserEnhancementInvocation) | {
|
|
148
|
+
operation: 'release';
|
|
149
|
+
bindingId: string;
|
|
150
|
+
generation: number;
|
|
151
|
+
};
|
|
152
|
+
export type ProviderEnhancementResponse = {
|
|
153
|
+
preparation: ProviderEnhancementPreparation;
|
|
154
|
+
} | {
|
|
155
|
+
binding: ProviderEnhancementBinding;
|
|
156
|
+
} | {
|
|
157
|
+
result: unknown;
|
|
158
|
+
} | {
|
|
159
|
+
released: boolean;
|
|
160
|
+
conflicts?: string[];
|
|
161
|
+
};
|