@mearl/mcp-server 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +111 -38
- package/package.json +3 -3
- package/dist/types.d.ts +0 -120
- package/dist/types.js +0 -2
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
- 📝 **browser_get_logs**: 获取控制台日志
|
|
10
10
|
- 🎭 **browser_set_mock**: 动态设置 Mock 数据
|
|
11
11
|
- 🌐 **browser_list**: 统一列出普通浏览器和托管浏览器,返回默认目标、类型及连接状态
|
|
12
|
+
- 📴 **browser_release**: 按用户明确要求释放 debugger/CDP 控制和会话级临时效果,并保留浏览器与全部标签页
|
|
12
13
|
- 🚀 **browser_launch / browser_close**: 启动或关闭独立 Profile 的托管 Chrome
|
|
13
14
|
- 🌐 **browser_page_snapshot**: 首次获取页面结构和可交互元素
|
|
14
15
|
- ⚡ **browser_page_click/type/hover/scroll/press/upload**: 执行页面动作,默认内置观察,返回通知、可交互控件和焦点等高置信度信号
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,51 @@ import { tmpdir } from 'os';
|
|
|
22
22
|
import { join, dirname } from 'path';
|
|
23
23
|
import { spawn } from 'child_process';
|
|
24
24
|
import { fileURLToPath } from 'url';
|
|
25
|
+
import { createRequire } from 'module';
|
|
25
26
|
import { RESPONSE_SIZE_SMALL, RESPONSE_SIZE_MEDIUM, RESPONSE_SIZE_LARGE, RESPONSE_SIZE_MAX, } from './constants.js';
|
|
27
|
+
const require = createRequire(import.meta.url);
|
|
28
|
+
const MCP_SERVER_VERSION = require('../package.json').version;
|
|
29
|
+
const MCP_TOOL_ACTIONS = {
|
|
30
|
+
browser_get_requests: 'get_requests',
|
|
31
|
+
browser_get_events: 'get_events',
|
|
32
|
+
browser_get_logs: 'get_logs',
|
|
33
|
+
browser_set_mock: 'set_mock',
|
|
34
|
+
browser_get_mocks: 'get_mocks',
|
|
35
|
+
browser_get_api_schema: 'get_api_schema',
|
|
36
|
+
browser_send_request: 'send_request',
|
|
37
|
+
browser_send_mtop_request: 'send_mtop_request',
|
|
38
|
+
browser_set_rule: 'set_rule',
|
|
39
|
+
browser_get_rules: 'get_rules',
|
|
40
|
+
browser_page_screenshot: 'page_screenshot',
|
|
41
|
+
browser_page_selected_element: 'page_selected_element',
|
|
42
|
+
get_user_info: 'get_user_info',
|
|
43
|
+
tdbank_account: 'tdbank_account',
|
|
44
|
+
browser_launch: 'browser_launch',
|
|
45
|
+
browser_close: 'browser_close',
|
|
46
|
+
browser_release: 'browser_release',
|
|
47
|
+
browser_tab_open: 'tab_open',
|
|
48
|
+
browser_tab_close: 'tab_close',
|
|
49
|
+
browser_tab_list: 'tab_list',
|
|
50
|
+
browser_page_click: 'page_click',
|
|
51
|
+
browser_page_type: 'page_type',
|
|
52
|
+
browser_page_scroll: 'page_scroll',
|
|
53
|
+
browser_page_hover: 'page_hover',
|
|
54
|
+
browser_page_eval: 'page_eval',
|
|
55
|
+
browser_page_snapshot: 'page_snapshot',
|
|
56
|
+
browser_page_press: 'page_press',
|
|
57
|
+
browser_page_wait: 'page_wait',
|
|
58
|
+
browser_page_navigate: 'page_navigate',
|
|
59
|
+
browser_page_upload: 'page_upload',
|
|
60
|
+
browser_page_frames: 'page_frames',
|
|
61
|
+
browser_set_device_emulation: 'set_device_emulation',
|
|
62
|
+
browser_set_timezone: 'set_timezone',
|
|
63
|
+
browser_run_actions: 'run_actions',
|
|
64
|
+
browser_list: 'browser_list',
|
|
65
|
+
browser_select_browser: 'browser_select_browser',
|
|
66
|
+
};
|
|
67
|
+
function defineMcpTools(tools) {
|
|
68
|
+
return tools;
|
|
69
|
+
}
|
|
26
70
|
// 日志输出到 stderr(不影响 stdio 通信)
|
|
27
71
|
const LOG_FILE = join(tmpdir(), 'mearl-mcp-server.log');
|
|
28
72
|
const log = (...args) => {
|
|
@@ -245,35 +289,32 @@ function formatResponseWithSizeCheck(result, toolName, args) {
|
|
|
245
289
|
},
|
|
246
290
|
];
|
|
247
291
|
}
|
|
248
|
-
// 策略 5: 超超大响应(>1MB 压缩)-
|
|
249
|
-
const truncateSize = RESPONSE_SIZE_MAX;
|
|
250
|
-
const truncatedStr = compactStr.substring(0, truncateSize);
|
|
292
|
+
// 策略 5: 超超大响应(>1MB 压缩)- 返回可解析的诊断信息
|
|
251
293
|
const suggestions = getOptimizationSuggestions(toolName, args, result, stats);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
stats.largestFields
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
294
|
+
const diagnostic = {
|
|
295
|
+
error: {
|
|
296
|
+
code: 'RESPONSE_TOO_LARGE',
|
|
297
|
+
message: 'The result exceeded the MCP response limit. Narrow the request and retry.',
|
|
298
|
+
originalSizeBytes: compactSize,
|
|
299
|
+
limitBytes: RESPONSE_SIZE_MAX,
|
|
300
|
+
},
|
|
301
|
+
meta: stats.meta,
|
|
302
|
+
largestFields: stats.largestFields?.map(field => ({
|
|
303
|
+
...field,
|
|
304
|
+
percentageOfTotal: Math.round((field.size / compactSize) * 100),
|
|
305
|
+
})),
|
|
306
|
+
suggestions: suggestions.length > 0
|
|
307
|
+
? suggestions
|
|
308
|
+
: [
|
|
309
|
+
'Significantly reduce the data requested',
|
|
310
|
+
'Use "fields" to extract only essential data',
|
|
311
|
+
'Add filters to narrow down results',
|
|
312
|
+
],
|
|
313
|
+
};
|
|
273
314
|
return [
|
|
274
315
|
{
|
|
275
316
|
type: 'text',
|
|
276
|
-
text:
|
|
317
|
+
text: JSON.stringify(diagnostic, null, 2),
|
|
277
318
|
},
|
|
278
319
|
];
|
|
279
320
|
}
|
|
@@ -317,7 +358,7 @@ async function main() {
|
|
|
317
358
|
// 创建 MCP Server
|
|
318
359
|
const server = new Server({
|
|
319
360
|
name: 'mearl',
|
|
320
|
-
version:
|
|
361
|
+
version: MCP_SERVER_VERSION,
|
|
321
362
|
}, {
|
|
322
363
|
capabilities: {
|
|
323
364
|
tools: {},
|
|
@@ -360,7 +401,7 @@ async function main() {
|
|
|
360
401
|
},
|
|
361
402
|
};
|
|
362
403
|
// 定义工具列表
|
|
363
|
-
const tools = [
|
|
404
|
+
const tools = defineMcpTools([
|
|
364
405
|
{
|
|
365
406
|
name: 'browser_get_requests',
|
|
366
407
|
description: '获取浏览器中最近的 API 请求历史记录,包含完整的请求和响应信息。适用于分析性能、排查问题、查看数据流等场景。无需等待用户操作,立即返回已有数据。',
|
|
@@ -466,6 +507,10 @@ async function main() {
|
|
|
466
507
|
inputSchema: {
|
|
467
508
|
type: 'object',
|
|
468
509
|
properties: {
|
|
510
|
+
tabId: {
|
|
511
|
+
type: 'number',
|
|
512
|
+
description: '目标标签页 ID,从 browser_tab_list 获取;不传时使用当前活动标签页',
|
|
513
|
+
},
|
|
469
514
|
level: {
|
|
470
515
|
type: 'string',
|
|
471
516
|
enum: ['log', 'warn', 'error', 'info', 'all'],
|
|
@@ -494,6 +539,10 @@ async function main() {
|
|
|
494
539
|
inputSchema: {
|
|
495
540
|
type: 'object',
|
|
496
541
|
properties: {
|
|
542
|
+
tabId: {
|
|
543
|
+
type: 'number',
|
|
544
|
+
description: '目标标签页 ID,从 browser_tab_list 获取;不传时使用当前活动标签页',
|
|
545
|
+
},
|
|
497
546
|
apiName: {
|
|
498
547
|
type: 'string',
|
|
499
548
|
description: 'API 名称或正则表达式模式。例如: "mtop.cart.query" 精确匹配, ".*\\.cart\\..*" 匹配所有购物车接口',
|
|
@@ -547,6 +596,10 @@ async function main() {
|
|
|
547
596
|
inputSchema: {
|
|
548
597
|
type: 'object',
|
|
549
598
|
properties: {
|
|
599
|
+
tabId: {
|
|
600
|
+
type: 'number',
|
|
601
|
+
description: '目标标签页 ID,从 browser_tab_list 获取;不传时使用当前活动标签页',
|
|
602
|
+
},
|
|
550
603
|
apiName: {
|
|
551
604
|
type: 'string',
|
|
552
605
|
description: '过滤指定接口,支持正则表达式。例如: "mtop.cart.query" 或 ".*\\.cart\\..*"。不传则返回所有 Mock',
|
|
@@ -964,6 +1017,14 @@ async function main() {
|
|
|
964
1017
|
required: ['browser'],
|
|
965
1018
|
},
|
|
966
1019
|
},
|
|
1020
|
+
{
|
|
1021
|
+
name: 'browser_release',
|
|
1022
|
+
description: '仅当用户明确要求结束调试、退出接管或清理会话资源时,释放当前目标浏览器的 debugger/CDP 控制;不要作为普通任务收尾。它会停止持续采集,并立即清除设备/时区模拟、会话级 Mock 和录制,但保留浏览器与全部标签页。后续浏览器操作仍可自动重新建立控制。',
|
|
1023
|
+
inputSchema: {
|
|
1024
|
+
type: 'object',
|
|
1025
|
+
properties: {},
|
|
1026
|
+
},
|
|
1027
|
+
},
|
|
967
1028
|
{
|
|
968
1029
|
name: 'browser_tab_open',
|
|
969
1030
|
description: '打开或按 URL 规则复用标签页。默认新建并等待加载完成;reuse=prefer 可优先复用,reuse=require 可限制为只复用。响应的 opened/reused 可用于判断流程结束时是否应关闭该 Tab。',
|
|
@@ -1435,7 +1496,7 @@ async function main() {
|
|
|
1435
1496
|
},
|
|
1436
1497
|
{
|
|
1437
1498
|
name: 'browser_set_device_emulation',
|
|
1438
|
-
description: '把目标标签页切换为移动端模拟态:视口尺寸 / DPR / UA / 触摸事件全部按指定设备生效,等价于 Chrome DevTools 设备工具栏,作用域仅限该 tab
|
|
1499
|
+
description: '把目标标签页切换为移动端模拟态:视口尺寸 / DPR / UA / 触摸事件全部按指定设备生效,等价于 Chrome DevTools 设备工具栏,作用域仅限该 tab,释放 debugger/CDP 控制会自动还原。适用于:调试 H5 移动页面、让 page_click 在 swiper/fastclick 等只听 touchstart 的页面生效、让服务端按移动 UA 返回数据。启用后默认 reload 一次让页面以移动模式重新初始化;成功响应中的实际配置可直接验证设置结果,无需固定追加快照。enabled=false 清除模拟。',
|
|
1439
1500
|
inputSchema: {
|
|
1440
1501
|
type: 'object',
|
|
1441
1502
|
properties: {
|
|
@@ -1549,7 +1610,7 @@ async function main() {
|
|
|
1549
1610
|
required: ['browser'],
|
|
1550
1611
|
},
|
|
1551
1612
|
},
|
|
1552
|
-
];
|
|
1613
|
+
]);
|
|
1553
1614
|
// 处理工具列表请求
|
|
1554
1615
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1555
1616
|
return { tools };
|
|
@@ -1558,8 +1619,11 @@ async function main() {
|
|
|
1558
1619
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1559
1620
|
const { name, arguments: args } = request.params;
|
|
1560
1621
|
try {
|
|
1622
|
+
if (!(name in MCP_TOOL_ACTIONS))
|
|
1623
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
1624
|
+
const toolName = name;
|
|
1561
1625
|
let result;
|
|
1562
|
-
switch (
|
|
1626
|
+
switch (toolName) {
|
|
1563
1627
|
case 'browser_get_requests': {
|
|
1564
1628
|
const { tabId, count = 10, filter, since, includeBody = true, includeHeaders = false, maxBodySize = 50000, fields, keysOnly = false, source, } = args;
|
|
1565
1629
|
result = await client.getRequests({
|
|
@@ -1590,13 +1654,13 @@ async function main() {
|
|
|
1590
1654
|
break;
|
|
1591
1655
|
}
|
|
1592
1656
|
case 'browser_get_logs': {
|
|
1593
|
-
const { level = 'all', since, limit = 100, filter } = args;
|
|
1594
|
-
result = await client.getLogs({ level, since, limit, filter });
|
|
1657
|
+
const { tabId, level = 'all', since, limit = 100, filter } = args;
|
|
1658
|
+
result = await client.getLogs({ tabId, level, since, limit, filter });
|
|
1595
1659
|
break;
|
|
1596
1660
|
}
|
|
1597
1661
|
case 'browser_set_mock': {
|
|
1598
1662
|
const { payloadFile } = args;
|
|
1599
|
-
let { apiName, mockData, fields, enabled, duration, conditions } = args;
|
|
1663
|
+
let { tabId, apiName, mockData, fields, enabled, duration, conditions } = args;
|
|
1600
1664
|
enabled = enabled ?? true;
|
|
1601
1665
|
// 如果提供了 payloadFile,从文件读取 mock 数据
|
|
1602
1666
|
if (payloadFile) {
|
|
@@ -1605,7 +1669,9 @@ async function main() {
|
|
|
1605
1669
|
}
|
|
1606
1670
|
const fileContent = readFileSync(payloadFile, 'utf-8');
|
|
1607
1671
|
const fileData = JSON.parse(fileContent);
|
|
1608
|
-
// 文件内容可以包含 apiName、mockData、fields、enabled、duration、conditions 等参数
|
|
1672
|
+
// 文件内容可以包含 tabId、apiName、mockData、fields、enabled、duration、conditions 等参数
|
|
1673
|
+
if (fileData.tabId !== undefined)
|
|
1674
|
+
tabId = fileData.tabId;
|
|
1609
1675
|
if (fileData.apiName)
|
|
1610
1676
|
apiName = fileData.apiName;
|
|
1611
1677
|
if (fileData.mockData !== undefined)
|
|
@@ -1620,6 +1686,7 @@ async function main() {
|
|
|
1620
1686
|
conditions = fileData.conditions;
|
|
1621
1687
|
}
|
|
1622
1688
|
result = await client.setMock({
|
|
1689
|
+
tabId,
|
|
1623
1690
|
apiName,
|
|
1624
1691
|
mockData,
|
|
1625
1692
|
fields,
|
|
@@ -1630,8 +1697,8 @@ async function main() {
|
|
|
1630
1697
|
break;
|
|
1631
1698
|
}
|
|
1632
1699
|
case 'browser_get_mocks': {
|
|
1633
|
-
const { apiName } = args;
|
|
1634
|
-
result = await client.getMocks({ apiName });
|
|
1700
|
+
const { tabId, apiName } = args;
|
|
1701
|
+
result = await client.getMocks({ tabId, apiName });
|
|
1635
1702
|
break;
|
|
1636
1703
|
}
|
|
1637
1704
|
case 'browser_get_api_schema': {
|
|
@@ -1723,6 +1790,10 @@ async function main() {
|
|
|
1723
1790
|
result = await client.browserClose(args);
|
|
1724
1791
|
break;
|
|
1725
1792
|
}
|
|
1793
|
+
case 'browser_release': {
|
|
1794
|
+
result = await client.browserRelease();
|
|
1795
|
+
break;
|
|
1796
|
+
}
|
|
1726
1797
|
case 'browser_tab_open': {
|
|
1727
1798
|
const { url, active = false, closeExisting = false, reuse = 'never', match, restoreFocusOnClose = false, emulation, group, } = args;
|
|
1728
1799
|
result = await client.tabOpen({
|
|
@@ -1879,8 +1950,10 @@ async function main() {
|
|
|
1879
1950
|
result = await client.selectBrowser(args);
|
|
1880
1951
|
break;
|
|
1881
1952
|
}
|
|
1882
|
-
default:
|
|
1883
|
-
|
|
1953
|
+
default: {
|
|
1954
|
+
const unhandledTool = toolName;
|
|
1955
|
+
throw new Error(`Unknown tool: ${unhandledTool}`);
|
|
1956
|
+
}
|
|
1884
1957
|
}
|
|
1885
1958
|
// 使用智能格式化返回结果
|
|
1886
1959
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/mcp-server",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "MCP Server for Mearl - enables AI to interact with Chrome browser requests and logs",
|
|
5
5
|
"mcpName": "io.github.F-loat/mearl",
|
|
6
6
|
"type": "module",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
32
32
|
"prompts": "^2.4.2",
|
|
33
|
-
"@mearl/
|
|
34
|
-
"@mearl/
|
|
33
|
+
"@mearl/client": "2.2.0",
|
|
34
|
+
"@mearl/native-host": "2.2.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^24.9.1",
|
package/dist/types.d.ts
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
export interface MtopRequest {
|
|
2
|
-
id: number;
|
|
3
|
-
timestamp: string;
|
|
4
|
-
timestampMs: number;
|
|
5
|
-
method: string;
|
|
6
|
-
url: string;
|
|
7
|
-
apiName: string;
|
|
8
|
-
status: number;
|
|
9
|
-
statusText: string;
|
|
10
|
-
headers: Array<{
|
|
11
|
-
name: string;
|
|
12
|
-
value: string;
|
|
13
|
-
}>;
|
|
14
|
-
responseHeaders: Array<{
|
|
15
|
-
name: string;
|
|
16
|
-
value: string;
|
|
17
|
-
}>;
|
|
18
|
-
queryString: Record<string, string>;
|
|
19
|
-
postData: Record<string, any> | null;
|
|
20
|
-
responseBody: any;
|
|
21
|
-
duration?: number;
|
|
22
|
-
proxyData?: any;
|
|
23
|
-
}
|
|
24
|
-
export interface ConsoleLog {
|
|
25
|
-
level: 'log' | 'warn' | 'error' | 'info';
|
|
26
|
-
message: string;
|
|
27
|
-
timestamp: number;
|
|
28
|
-
/** 来源文件和行号,格式 "filename.js:42",仅在可获取时存在 */
|
|
29
|
-
source?: string;
|
|
30
|
-
args: any[];
|
|
31
|
-
}
|
|
32
|
-
export interface WaitForRequestParams {
|
|
33
|
-
pattern: string;
|
|
34
|
-
timeout?: number;
|
|
35
|
-
includeExisting?: boolean;
|
|
36
|
-
}
|
|
37
|
-
export interface GetRequestsParams {
|
|
38
|
-
count?: number;
|
|
39
|
-
filter?: string;
|
|
40
|
-
since?: number;
|
|
41
|
-
}
|
|
42
|
-
export interface GetLogsParams {
|
|
43
|
-
level?: 'log' | 'warn' | 'error' | 'info' | 'all';
|
|
44
|
-
since?: number;
|
|
45
|
-
limit?: number;
|
|
46
|
-
filter?: string;
|
|
47
|
-
}
|
|
48
|
-
export interface SetMockParams {
|
|
49
|
-
apiName: string;
|
|
50
|
-
mockData: any;
|
|
51
|
-
enabled?: boolean;
|
|
52
|
-
duration?: number;
|
|
53
|
-
conditions?: Record<string, any>;
|
|
54
|
-
}
|
|
55
|
-
export interface GetApiSchemaParams {
|
|
56
|
-
api: string;
|
|
57
|
-
version?: string;
|
|
58
|
-
}
|
|
59
|
-
export interface GetSelectedElementParams {
|
|
60
|
-
includeOuterHTML?: boolean;
|
|
61
|
-
includeScreenshot?: boolean;
|
|
62
|
-
}
|
|
63
|
-
export interface RequestsResponse {
|
|
64
|
-
meta: {
|
|
65
|
-
/** 实际返回的请求数量 */
|
|
66
|
-
count: number;
|
|
67
|
-
/** 缓冲区中符合过滤条件的总请求数 */
|
|
68
|
-
totalMatched: number;
|
|
69
|
-
/** 缓冲区中的总请求数(未过滤) */
|
|
70
|
-
totalInBuffer: number;
|
|
71
|
-
/** 应用的过滤器(如果有) */
|
|
72
|
-
filter?: string;
|
|
73
|
-
/** 时间过滤器(秒) */
|
|
74
|
-
since?: number;
|
|
75
|
-
/** 是否包含请求/响应体 */
|
|
76
|
-
includeBody: boolean;
|
|
77
|
-
/** 是否包含请求/响应头 */
|
|
78
|
-
includeHeaders: boolean;
|
|
79
|
-
/** 提取的字段(如果有) */
|
|
80
|
-
fields?: string[];
|
|
81
|
-
/** 是否只返回键结构 */
|
|
82
|
-
keysOnly: boolean;
|
|
83
|
-
};
|
|
84
|
-
/** 请求数据列表 */
|
|
85
|
-
requests: MtopRequest[];
|
|
86
|
-
}
|
|
87
|
-
export interface LogsResponse {
|
|
88
|
-
meta: {
|
|
89
|
-
/** 实际返回的日志数量 */
|
|
90
|
-
count: number;
|
|
91
|
-
/** 符合过滤条件的总日志数 */
|
|
92
|
-
totalMatched: number;
|
|
93
|
-
/** 应用的日志级别过滤 */
|
|
94
|
-
level: string;
|
|
95
|
-
/** 时间过滤器(秒) */
|
|
96
|
-
since?: number;
|
|
97
|
-
/** 应用的过滤模式 */
|
|
98
|
-
filter?: string;
|
|
99
|
-
};
|
|
100
|
-
/** 日志数据列表 */
|
|
101
|
-
logs: ConsoleLog[];
|
|
102
|
-
}
|
|
103
|
-
export interface ScreenshotResponse {
|
|
104
|
-
meta: {
|
|
105
|
-
/** 截图格式 */
|
|
106
|
-
format: 'png' | 'jpeg';
|
|
107
|
-
/** 截图宽度 */
|
|
108
|
-
width: number;
|
|
109
|
-
/** 截图高度 */
|
|
110
|
-
height: number;
|
|
111
|
-
/** 截图数据大小(字节) */
|
|
112
|
-
size: number;
|
|
113
|
-
/** 截图的页面 URL */
|
|
114
|
-
url: string;
|
|
115
|
-
/** 截图的页面标题 */
|
|
116
|
-
title: string;
|
|
117
|
-
};
|
|
118
|
-
/** Base64 编码的截图数据 */
|
|
119
|
-
data: string;
|
|
120
|
-
}
|
package/dist/types.js
DELETED