@mearl/browser-core 3.0.0-beta.4 → 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.
- package/README.md +2 -2
- package/dist/agentChat.d.ts +2 -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 +65 -42
- package/dist/browserActionProtocol.js +15 -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/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 +1 -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/providerAppResources.d.ts +39 -0
- package/dist/providerAppResources.js +2 -0
- package/dist/proxyPermissions.js +4 -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,14 @@ export interface SendRequestParams {
|
|
|
107
112
|
responseType?: 'json' | 'text' | 'auto';
|
|
108
113
|
timeout?: number;
|
|
109
114
|
}
|
|
110
|
-
export
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
method?: string;
|
|
117
|
-
appKey?: string;
|
|
118
|
-
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 {
|
|
119
121
|
timeout?: number;
|
|
120
|
-
|
|
121
|
-
ttid?: string;
|
|
122
|
+
[key: string]: unknown;
|
|
122
123
|
}
|
|
123
124
|
export type BrowserStatus = 'connected' | 'pairing' | 'running_disconnected' | 'stopped';
|
|
124
125
|
export type BrowserTransport = 'extension' | 'cdp' | 'provider';
|
|
@@ -184,6 +185,7 @@ export interface BrowserInfoBase {
|
|
|
184
185
|
pairing?: BrowserPairingInfo;
|
|
185
186
|
}
|
|
186
187
|
export type BrowserScreenshotKind = 'native' | 'reconstructed' | 'none';
|
|
188
|
+
export type BrowserControlSessionMode = 'mearl' | 'external';
|
|
187
189
|
/** Browser-targeted actions that an external provider may implement. */
|
|
188
190
|
export type BrowserCapabilityAction = ExtensionBrowserAction | 'page_download';
|
|
189
191
|
/** Capabilities advertised by an external browser-control provider. */
|
|
@@ -191,6 +193,8 @@ export interface BrowserCapabilities {
|
|
|
191
193
|
actions: BrowserCapabilityAction[];
|
|
192
194
|
/** Pixel fidelity of page_screenshot, or none when that action is unavailable. */
|
|
193
195
|
screenshot: BrowserScreenshotKind;
|
|
196
|
+
/** Fixed per instance. Omitted means Mearl sessions; external delegates task control. */
|
|
197
|
+
controlSessionMode?: BrowserControlSessionMode;
|
|
194
198
|
}
|
|
195
199
|
export interface RegularBrowserInfo extends BrowserInfoBase {
|
|
196
200
|
type: 'regular';
|
|
@@ -204,6 +208,13 @@ export interface ManagedBrowserInfo extends BrowserInfoBase {
|
|
|
204
208
|
operations: BrowserProviderOperation[];
|
|
205
209
|
}
|
|
206
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
|
+
}
|
|
207
218
|
export interface BrowserListResult {
|
|
208
219
|
count: number;
|
|
209
220
|
connectedCount: number;
|
|
@@ -211,6 +222,11 @@ export interface BrowserListResult {
|
|
|
211
222
|
browsers: BrowserInfo[];
|
|
212
223
|
/** Partial discovery failures; successfully inspected browser sources remain in the result. */
|
|
213
224
|
warnings?: string[];
|
|
225
|
+
/** Present only for an explicit, source-local Provider launch-form query. */
|
|
226
|
+
discovery?: {
|
|
227
|
+
provider: string;
|
|
228
|
+
launchForm: BrowserProviderLaunchForm;
|
|
229
|
+
};
|
|
214
230
|
}
|
|
215
231
|
export interface SelectBrowserParams {
|
|
216
232
|
browser?: string;
|
|
@@ -366,6 +382,7 @@ export interface BrowserProviderDefinition {
|
|
|
366
382
|
provider: BrowserProviderIdentity;
|
|
367
383
|
browserType: {
|
|
368
384
|
name: string;
|
|
385
|
+
controlSessionModes?: readonly BrowserControlSessionMode[];
|
|
369
386
|
documentationUrl?: string;
|
|
370
387
|
inputSchema: BrowserProviderObjectSchema;
|
|
371
388
|
configuration?: {
|
|
@@ -457,7 +474,8 @@ export interface BrowserEmulationOptions {
|
|
|
457
474
|
/** App 容器横屏时将根页面与业务页面分置左右 WebView;仅与 deviceShell、App 档案同时生效。 */
|
|
458
475
|
splitScreen?: boolean;
|
|
459
476
|
}
|
|
460
|
-
|
|
477
|
+
/** Provider-defined behavior ID; core does not execute or enumerate business behaviors. */
|
|
478
|
+
export type AppBridgeConfigBehavior = string;
|
|
461
479
|
/** 单个桥方法的声明式覆盖;行为、固定回包、成功空实现三选一。 */
|
|
462
480
|
export interface AppBridgeMethodConfig {
|
|
463
481
|
behavior?: AppBridgeConfigBehavior;
|
|
@@ -486,8 +504,8 @@ export interface TabOpenParams {
|
|
|
486
504
|
emulation?: BrowserEmulationOptions;
|
|
487
505
|
group?: string;
|
|
488
506
|
/**
|
|
489
|
-
*
|
|
490
|
-
* 设备视口和 iframe 系统外壳由 emulation.deviceShell
|
|
507
|
+
* 客户端容器模拟档案名(由已安装能力目录提供)。只注入容器 UA、环境变量、JSBridge 与桥协议;
|
|
508
|
+
* 设备视口和 iframe 系统外壳由 emulation.deviceShell 独立控制。可用档案通过 get_capabilities 查询。
|
|
491
509
|
*/
|
|
492
510
|
appProfile?: AppProfileName;
|
|
493
511
|
/** 与 appProfile 配合使用;容器系统,默认 ios */
|
|
@@ -504,16 +522,9 @@ export type TabGroupParams = {
|
|
|
504
522
|
ungroup: true;
|
|
505
523
|
title?: never;
|
|
506
524
|
};
|
|
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];
|
|
525
|
+
/** App identities are supplied by installed capability catalogs. */
|
|
526
|
+
export declare const APP_PROFILE_NAMES: readonly string[];
|
|
527
|
+
export type BuiltinAppProfileName = string;
|
|
517
528
|
/** Hosts validate dynamic profile IDs against the active capability catalog. */
|
|
518
529
|
export type AppProfileName = string;
|
|
519
530
|
export interface SetAppProfileParams {
|
|
@@ -534,10 +545,10 @@ export interface SetAppProfileParams {
|
|
|
534
545
|
/** 按方法覆盖档案内置桥配置,仅支持受控行为、固定 JSON 回包和成功空实现 */
|
|
535
546
|
bridgeConfig?: AppBridgeConfig;
|
|
536
547
|
/**
|
|
537
|
-
*
|
|
548
|
+
* 可选已安装的网络控件选择;null 清除,省略时保持当前设置。
|
|
538
549
|
* 仅作用于目标 tab,扩展模式与该 tab 的快捷设置共享。
|
|
539
550
|
*/
|
|
540
|
-
|
|
551
|
+
networkControl?: NetworkControlSelection | null;
|
|
541
552
|
/**
|
|
542
553
|
* 可选设备联动参数。传入时显式字段覆盖档案推荐设备,空对象使用推荐设备且默认开启
|
|
543
554
|
* deviceShell;省略时不设置或清除该 tab 的设备状态。
|
|
@@ -672,6 +683,10 @@ export interface PageInspectParams {
|
|
|
672
683
|
export interface PagePressParams {
|
|
673
684
|
tabId: number;
|
|
674
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;
|
|
675
690
|
modifiers?: string[];
|
|
676
691
|
/** Dispatch strategy. Auto uses DOM events when the page is hidden. */
|
|
677
692
|
pressMode?: 'auto' | 'dom' | 'keyboard';
|
|
@@ -762,10 +777,10 @@ export interface SetCookieResult {
|
|
|
762
777
|
path: string;
|
|
763
778
|
reloaded: boolean;
|
|
764
779
|
}
|
|
765
|
-
export interface
|
|
780
|
+
export interface RequestPermissionParams {
|
|
766
781
|
domain: string;
|
|
767
782
|
}
|
|
768
|
-
export type RunActionName = Exclude<ExtensionBrowserAction, 'run_actions' | 'browser_release'>;
|
|
783
|
+
export type RunActionName = Exclude<ExtensionBrowserAction, 'run_actions' | 'browser_release' | 'get_capabilities'>;
|
|
769
784
|
export interface ActionStep {
|
|
770
785
|
action: RunActionName;
|
|
771
786
|
data?: Record<string, unknown>;
|
|
@@ -775,6 +790,10 @@ export interface RunActionsParams {
|
|
|
775
790
|
tabId: number;
|
|
776
791
|
}
|
|
777
792
|
export interface BrowserActionMap {
|
|
793
|
+
get_capabilities: {
|
|
794
|
+
request: GetCapabilitiesParams;
|
|
795
|
+
response: BrowserCapabilityCatalog;
|
|
796
|
+
};
|
|
778
797
|
tab_checkpoint: {
|
|
779
798
|
request: CaptureCheckpointParams;
|
|
780
799
|
response: CaptureCheckpointResult;
|
|
@@ -816,12 +835,12 @@ export interface BrowserActionMap {
|
|
|
816
835
|
request: SendRequestParams;
|
|
817
836
|
response: unknown;
|
|
818
837
|
};
|
|
819
|
-
|
|
820
|
-
request:
|
|
838
|
+
send_protocol_request: {
|
|
839
|
+
request: SendProtocolRequestParams;
|
|
821
840
|
response: unknown;
|
|
822
841
|
};
|
|
823
842
|
browser_list: {
|
|
824
|
-
request: undefined;
|
|
843
|
+
request: BrowserListParams | undefined;
|
|
825
844
|
response: BrowserListResult;
|
|
826
845
|
};
|
|
827
846
|
browser_select_browser: {
|
|
@@ -946,8 +965,8 @@ export interface BrowserActionMap {
|
|
|
946
965
|
request: SetCookieParams;
|
|
947
966
|
response: SetCookieResult;
|
|
948
967
|
};
|
|
949
|
-
|
|
950
|
-
request:
|
|
968
|
+
request_permission: {
|
|
969
|
+
request: RequestPermissionParams;
|
|
951
970
|
response: unknown;
|
|
952
971
|
};
|
|
953
972
|
run_actions: {
|
|
@@ -979,8 +998,9 @@ export declare const BROWSER_ACTIONS: {
|
|
|
979
998
|
readonly get_mocks: true;
|
|
980
999
|
readonly set_rule: true;
|
|
981
1000
|
readonly get_rules: true;
|
|
1001
|
+
readonly get_capabilities: true;
|
|
982
1002
|
readonly send_request: true;
|
|
983
|
-
readonly
|
|
1003
|
+
readonly send_protocol_request: true;
|
|
984
1004
|
readonly browser_list: true;
|
|
985
1005
|
readonly browser_select_browser: true;
|
|
986
1006
|
readonly browser_release: true;
|
|
@@ -1012,7 +1032,7 @@ export declare const BROWSER_ACTIONS: {
|
|
|
1012
1032
|
readonly set_timezone: true;
|
|
1013
1033
|
readonly get_cookie: true;
|
|
1014
1034
|
readonly set_cookie: true;
|
|
1015
|
-
readonly
|
|
1035
|
+
readonly request_permission: true;
|
|
1016
1036
|
readonly run_actions: true;
|
|
1017
1037
|
};
|
|
1018
1038
|
export declare const BROWSER_COMMAND_ACTIONS: {
|
|
@@ -1025,8 +1045,9 @@ export declare const BROWSER_COMMAND_ACTIONS: {
|
|
|
1025
1045
|
readonly get_mocks: true;
|
|
1026
1046
|
readonly set_rule: true;
|
|
1027
1047
|
readonly get_rules: true;
|
|
1048
|
+
readonly get_capabilities: true;
|
|
1028
1049
|
readonly send_request: true;
|
|
1029
|
-
readonly
|
|
1050
|
+
readonly send_protocol_request: true;
|
|
1030
1051
|
readonly browser_list: true;
|
|
1031
1052
|
readonly browser_release: true;
|
|
1032
1053
|
readonly browser_control: true;
|
|
@@ -1057,7 +1078,7 @@ export declare const BROWSER_COMMAND_ACTIONS: {
|
|
|
1057
1078
|
readonly set_timezone: true;
|
|
1058
1079
|
readonly get_cookie: true;
|
|
1059
1080
|
readonly set_cookie: true;
|
|
1060
|
-
readonly
|
|
1081
|
+
readonly request_permission: true;
|
|
1061
1082
|
readonly run_actions: true;
|
|
1062
1083
|
};
|
|
1063
1084
|
export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
@@ -1070,8 +1091,9 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
|
1070
1091
|
readonly get_mocks: true;
|
|
1071
1092
|
readonly set_rule: true;
|
|
1072
1093
|
readonly get_rules: true;
|
|
1094
|
+
readonly get_capabilities: true;
|
|
1073
1095
|
readonly send_request: true;
|
|
1074
|
-
readonly
|
|
1096
|
+
readonly send_protocol_request: true;
|
|
1075
1097
|
readonly browser_release: true;
|
|
1076
1098
|
readonly page_screenshot: true;
|
|
1077
1099
|
readonly tab_open: true;
|
|
@@ -1097,7 +1119,7 @@ export declare const EXTENSION_BROWSER_ACTIONS: {
|
|
|
1097
1119
|
readonly set_timezone: true;
|
|
1098
1120
|
readonly get_cookie: true;
|
|
1099
1121
|
readonly set_cookie: true;
|
|
1100
|
-
readonly
|
|
1122
|
+
readonly request_permission: true;
|
|
1101
1123
|
readonly run_actions: true;
|
|
1102
1124
|
};
|
|
1103
1125
|
export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
@@ -1111,8 +1133,9 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
|
1111
1133
|
readonly get_mocks: true;
|
|
1112
1134
|
readonly set_rule: true;
|
|
1113
1135
|
readonly get_rules: true;
|
|
1136
|
+
readonly get_capabilities: true;
|
|
1114
1137
|
readonly send_request: true;
|
|
1115
|
-
readonly
|
|
1138
|
+
readonly send_protocol_request: true;
|
|
1116
1139
|
readonly browser_release: true;
|
|
1117
1140
|
readonly page_screenshot: true;
|
|
1118
1141
|
readonly tab_open: true;
|
|
@@ -1138,7 +1161,7 @@ export declare const BROWSER_CAPABILITY_ACTIONS: {
|
|
|
1138
1161
|
readonly set_timezone: true;
|
|
1139
1162
|
readonly get_cookie: true;
|
|
1140
1163
|
readonly set_cookie: true;
|
|
1141
|
-
readonly
|
|
1164
|
+
readonly request_permission: true;
|
|
1142
1165
|
readonly run_actions: true;
|
|
1143
1166
|
};
|
|
1144
1167
|
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,9 @@ 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
|
-
|
|
125
|
+
send_protocol_request: true,
|
|
128
126
|
browser_list: true,
|
|
129
127
|
browser_select_browser: true,
|
|
130
128
|
browser_release: true,
|
|
@@ -156,7 +154,7 @@ export const BROWSER_ACTIONS = {
|
|
|
156
154
|
set_timezone: true,
|
|
157
155
|
get_cookie: true,
|
|
158
156
|
set_cookie: true,
|
|
159
|
-
|
|
157
|
+
request_permission: true,
|
|
160
158
|
run_actions: true,
|
|
161
159
|
};
|
|
162
160
|
export const BROWSER_COMMAND_ACTIONS = {
|
|
@@ -169,8 +167,9 @@ export const BROWSER_COMMAND_ACTIONS = {
|
|
|
169
167
|
get_mocks: true,
|
|
170
168
|
set_rule: true,
|
|
171
169
|
get_rules: true,
|
|
170
|
+
get_capabilities: true,
|
|
172
171
|
send_request: true,
|
|
173
|
-
|
|
172
|
+
send_protocol_request: true,
|
|
174
173
|
browser_list: true,
|
|
175
174
|
browser_release: true,
|
|
176
175
|
browser_control: true,
|
|
@@ -201,7 +200,7 @@ export const BROWSER_COMMAND_ACTIONS = {
|
|
|
201
200
|
set_timezone: true,
|
|
202
201
|
get_cookie: true,
|
|
203
202
|
set_cookie: true,
|
|
204
|
-
|
|
203
|
+
request_permission: true,
|
|
205
204
|
run_actions: true,
|
|
206
205
|
};
|
|
207
206
|
export const EXTENSION_BROWSER_ACTIONS = {
|
|
@@ -214,8 +213,9 @@ export const EXTENSION_BROWSER_ACTIONS = {
|
|
|
214
213
|
get_mocks: true,
|
|
215
214
|
set_rule: true,
|
|
216
215
|
get_rules: true,
|
|
216
|
+
get_capabilities: true,
|
|
217
217
|
send_request: true,
|
|
218
|
-
|
|
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
|
-
|
|
244
|
+
request_permission: true,
|
|
245
245
|
run_actions: true,
|
|
246
246
|
};
|
|
247
247
|
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
|
+
};
|