@midscene/ios 1.7.5-beta-20260421030751.0 → 1.7.5
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/dist/es/cli.mjs +52 -12
- package/dist/es/index.mjs +49 -8
- package/dist/es/mcp-server.mjs +51 -9
- package/dist/lib/cli.js +52 -12
- package/dist/lib/index.js +50 -9
- package/dist/lib/mcp-server.js +51 -9
- package/dist/types/index.d.ts +9 -4
- package/dist/types/mcp-server.d.ts +9 -4
- package/package.json +5 -5
- package/static/index.html +1 -1
- package/static/static/css/index.dc500f18.css +2 -0
- package/static/static/css/index.dc500f18.css.map +1 -0
- package/static/static/js/{263.25db3a75.js → 883.516361ae.js} +30 -30
- package/static/static/js/{263.25db3a75.js.LICENSE.txt → 883.516361ae.js.LICENSE.txt} +16 -0
- package/static/static/js/883.516361ae.js.map +1 -0
- package/static/static/js/{index.b24f9a87.js → index.3bea1f00.js} +27 -17
- package/static/static/js/index.3bea1f00.js.map +1 -0
- package/static/static/css/index.1946f9fa.css +0 -2
- package/static/static/css/index.1946f9fa.css.map +0 -1
- package/static/static/js/263.25db3a75.js.map +0 -1
- package/static/static/js/index.b24f9a87.js.map +0 -1
- /package/static/static/js/{index.b24f9a87.js.LICENSE.txt → index.3bea1f00.js.LICENSE.txt} +0 -0
package/dist/es/cli.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createReportCliCommands, getMidsceneLocationSchema, z } from "@midscene/core";
|
|
2
|
-
import {
|
|
2
|
+
import { reportCLIError, runToolsCLI } from "@midscene/shared/cli";
|
|
3
3
|
import { getDebug } from "@midscene/shared/logger";
|
|
4
|
-
import { BaseMidsceneTools } from "@midscene/shared/mcp";
|
|
4
|
+
import { BaseMidsceneTools } from "@midscene/shared/mcp/base-tools";
|
|
5
5
|
import { Agent } from "@midscene/core/agent";
|
|
6
6
|
import { mergeAndNormalizeAppNameMapping, normalizeForComparison } from "@midscene/shared/utils";
|
|
7
7
|
import node_assert from "node:assert";
|
|
@@ -1320,17 +1320,46 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1320
1320
|
await device.connect();
|
|
1321
1321
|
return new IOSAgent(device, opts);
|
|
1322
1322
|
}
|
|
1323
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1324
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1325
|
+
value: value,
|
|
1326
|
+
enumerable: true,
|
|
1327
|
+
configurable: true,
|
|
1328
|
+
writable: true
|
|
1329
|
+
});
|
|
1330
|
+
else obj[key] = value;
|
|
1331
|
+
return obj;
|
|
1332
|
+
}
|
|
1323
1333
|
const debug = getDebug('mcp:ios-tools');
|
|
1334
|
+
const iosInitArgShape = {
|
|
1335
|
+
deviceId: z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1336
|
+
wdaHost: z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1337
|
+
wdaPort: z.number().optional().describe('WebDriverAgent port'),
|
|
1338
|
+
useWDA: z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1339
|
+
wdaMjpegPort: z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1340
|
+
};
|
|
1324
1341
|
class IOSMidsceneTools extends BaseMidsceneTools {
|
|
1325
1342
|
createTemporaryDevice() {
|
|
1326
1343
|
return new IOSDevice({});
|
|
1327
1344
|
}
|
|
1328
|
-
async ensureAgent() {
|
|
1345
|
+
async ensureAgent(opts) {
|
|
1346
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1347
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1348
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1349
|
+
try {
|
|
1350
|
+
await this.agent.destroy?.();
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1353
|
+
}
|
|
1354
|
+
this.agent = void 0;
|
|
1355
|
+
}
|
|
1329
1356
|
if (this.agent) return this.agent;
|
|
1330
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1357
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1331
1358
|
this.agent = await agentFromWebDriverAgent({
|
|
1332
|
-
autoDismissKeyboard: false
|
|
1359
|
+
autoDismissKeyboard: false,
|
|
1360
|
+
...opts ?? {}
|
|
1333
1361
|
});
|
|
1362
|
+
this.lastOptsSignature = nextSignature;
|
|
1334
1363
|
return this.agent;
|
|
1335
1364
|
}
|
|
1336
1365
|
preparePlatformTools() {
|
|
@@ -1338,15 +1367,17 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1338
1367
|
{
|
|
1339
1368
|
name: 'ios_connect',
|
|
1340
1369
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1341
|
-
schema:
|
|
1342
|
-
|
|
1343
|
-
|
|
1370
|
+
schema: this.getAgentInitArgSchema(),
|
|
1371
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1372
|
+
handler: async (args)=>{
|
|
1373
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1374
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1344
1375
|
const screenshot = await agent.page.screenshotBase64();
|
|
1345
1376
|
return {
|
|
1346
1377
|
content: [
|
|
1347
1378
|
{
|
|
1348
1379
|
type: 'text',
|
|
1349
|
-
text:
|
|
1380
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1350
1381
|
},
|
|
1351
1382
|
...this.buildScreenshotContent(screenshot)
|
|
1352
1383
|
],
|
|
@@ -1362,13 +1393,22 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1362
1393
|
}
|
|
1363
1394
|
];
|
|
1364
1395
|
}
|
|
1396
|
+
constructor(...args){
|
|
1397
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1398
|
+
namespace: 'ios',
|
|
1399
|
+
shape: iosInitArgShape,
|
|
1400
|
+
cli: {
|
|
1401
|
+
preferBareKeys: true
|
|
1402
|
+
},
|
|
1403
|
+
adapt: (extracted)=>extracted
|
|
1404
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1405
|
+
}
|
|
1365
1406
|
}
|
|
1366
1407
|
const tools = new IOSMidsceneTools();
|
|
1367
1408
|
runToolsCLI(tools, 'midscene-ios', {
|
|
1368
1409
|
stripPrefix: 'ios_',
|
|
1369
|
-
version: "1.7.5
|
|
1410
|
+
version: "1.7.5",
|
|
1370
1411
|
extraCommands: createReportCliCommands()
|
|
1371
1412
|
}).catch((e)=>{
|
|
1372
|
-
|
|
1373
|
-
process.exit(e instanceof CLIError ? e.exitCode : 1);
|
|
1413
|
+
process.exit(reportCLIError(e));
|
|
1374
1414
|
});
|
package/dist/es/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { getDebug } from "@midscene/shared/logger";
|
|
|
8
8
|
import { mergeAndNormalizeAppNameMapping, normalizeForComparison } from "@midscene/shared/utils";
|
|
9
9
|
import { WDAManager, WebDriverClient } from "@midscene/webdriver";
|
|
10
10
|
import { Agent } from "@midscene/core/agent";
|
|
11
|
-
import { BaseMidsceneTools } from "@midscene/shared/mcp";
|
|
11
|
+
import { BaseMidsceneTools } from "@midscene/shared/mcp/base-tools";
|
|
12
12
|
import { overrideAIConfig } from "@midscene/shared/env";
|
|
13
13
|
import { exec } from "node:child_process";
|
|
14
14
|
import { platform } from "node:os";
|
|
@@ -1326,17 +1326,46 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1326
1326
|
await device.connect();
|
|
1327
1327
|
return new IOSAgent(device, opts);
|
|
1328
1328
|
}
|
|
1329
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1330
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1331
|
+
value: value,
|
|
1332
|
+
enumerable: true,
|
|
1333
|
+
configurable: true,
|
|
1334
|
+
writable: true
|
|
1335
|
+
});
|
|
1336
|
+
else obj[key] = value;
|
|
1337
|
+
return obj;
|
|
1338
|
+
}
|
|
1329
1339
|
const debug = getDebug('mcp:ios-tools');
|
|
1340
|
+
const iosInitArgShape = {
|
|
1341
|
+
deviceId: z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1342
|
+
wdaHost: z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1343
|
+
wdaPort: z.number().optional().describe('WebDriverAgent port'),
|
|
1344
|
+
useWDA: z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1345
|
+
wdaMjpegPort: z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1346
|
+
};
|
|
1330
1347
|
class IOSMidsceneTools extends BaseMidsceneTools {
|
|
1331
1348
|
createTemporaryDevice() {
|
|
1332
1349
|
return new IOSDevice({});
|
|
1333
1350
|
}
|
|
1334
|
-
async ensureAgent() {
|
|
1351
|
+
async ensureAgent(opts) {
|
|
1352
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1353
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1354
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1355
|
+
try {
|
|
1356
|
+
await this.agent.destroy?.();
|
|
1357
|
+
} catch (error) {
|
|
1358
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1359
|
+
}
|
|
1360
|
+
this.agent = void 0;
|
|
1361
|
+
}
|
|
1335
1362
|
if (this.agent) return this.agent;
|
|
1336
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1363
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1337
1364
|
this.agent = await agentFromWebDriverAgent({
|
|
1338
|
-
autoDismissKeyboard: false
|
|
1365
|
+
autoDismissKeyboard: false,
|
|
1366
|
+
...opts ?? {}
|
|
1339
1367
|
});
|
|
1368
|
+
this.lastOptsSignature = nextSignature;
|
|
1340
1369
|
return this.agent;
|
|
1341
1370
|
}
|
|
1342
1371
|
preparePlatformTools() {
|
|
@@ -1344,15 +1373,17 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1344
1373
|
{
|
|
1345
1374
|
name: 'ios_connect',
|
|
1346
1375
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1347
|
-
schema:
|
|
1348
|
-
|
|
1349
|
-
|
|
1376
|
+
schema: this.getAgentInitArgSchema(),
|
|
1377
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1378
|
+
handler: async (args)=>{
|
|
1379
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1380
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1350
1381
|
const screenshot = await agent.page.screenshotBase64();
|
|
1351
1382
|
return {
|
|
1352
1383
|
content: [
|
|
1353
1384
|
{
|
|
1354
1385
|
type: 'text',
|
|
1355
|
-
text:
|
|
1386
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1356
1387
|
},
|
|
1357
1388
|
...this.buildScreenshotContent(screenshot)
|
|
1358
1389
|
],
|
|
@@ -1368,6 +1399,16 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1368
1399
|
}
|
|
1369
1400
|
];
|
|
1370
1401
|
}
|
|
1402
|
+
constructor(...args){
|
|
1403
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1404
|
+
namespace: 'ios',
|
|
1405
|
+
shape: iosInitArgShape,
|
|
1406
|
+
cli: {
|
|
1407
|
+
preferBareKeys: true
|
|
1408
|
+
},
|
|
1409
|
+
adapt: (extracted)=>extracted
|
|
1410
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1411
|
+
}
|
|
1371
1412
|
}
|
|
1372
1413
|
const execAsync = promisify(exec);
|
|
1373
1414
|
const debugUtils = getDebug('ios:utils');
|
package/dist/es/mcp-server.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseMCPServer,
|
|
1
|
+
import { BaseMCPServer, createMCPServerLauncher } from "@midscene/shared/mcp";
|
|
2
2
|
import { Agent } from "@midscene/core/agent";
|
|
3
3
|
import { getDebug } from "@midscene/shared/logger";
|
|
4
4
|
import { mergeAndNormalizeAppNameMapping, normalizeForComparison } from "@midscene/shared/utils";
|
|
@@ -9,6 +9,7 @@ import { sleep } from "@midscene/core/utils";
|
|
|
9
9
|
import { DEFAULT_WDA_PORT } from "@midscene/shared/constants";
|
|
10
10
|
import { createImgBase64ByFormat } from "@midscene/shared/img";
|
|
11
11
|
import { WDAManager, WebDriverClient } from "@midscene/webdriver";
|
|
12
|
+
import { BaseMidsceneTools } from "@midscene/shared/mcp/base-tools";
|
|
12
13
|
const defaultAppNameMapping = {
|
|
13
14
|
微信: 'com.tencent.xin',
|
|
14
15
|
企业微信: 'com.tencent.ww',
|
|
@@ -1319,17 +1320,46 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1319
1320
|
await device.connect();
|
|
1320
1321
|
return new IOSAgent(device, opts);
|
|
1321
1322
|
}
|
|
1323
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1324
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1325
|
+
value: value,
|
|
1326
|
+
enumerable: true,
|
|
1327
|
+
configurable: true,
|
|
1328
|
+
writable: true
|
|
1329
|
+
});
|
|
1330
|
+
else obj[key] = value;
|
|
1331
|
+
return obj;
|
|
1332
|
+
}
|
|
1322
1333
|
const debug = getDebug('mcp:ios-tools');
|
|
1334
|
+
const iosInitArgShape = {
|
|
1335
|
+
deviceId: z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1336
|
+
wdaHost: z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1337
|
+
wdaPort: z.number().optional().describe('WebDriverAgent port'),
|
|
1338
|
+
useWDA: z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1339
|
+
wdaMjpegPort: z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1340
|
+
};
|
|
1323
1341
|
class IOSMidsceneTools extends BaseMidsceneTools {
|
|
1324
1342
|
createTemporaryDevice() {
|
|
1325
1343
|
return new IOSDevice({});
|
|
1326
1344
|
}
|
|
1327
|
-
async ensureAgent() {
|
|
1345
|
+
async ensureAgent(opts) {
|
|
1346
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1347
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1348
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1349
|
+
try {
|
|
1350
|
+
await this.agent.destroy?.();
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1353
|
+
}
|
|
1354
|
+
this.agent = void 0;
|
|
1355
|
+
}
|
|
1328
1356
|
if (this.agent) return this.agent;
|
|
1329
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1357
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1330
1358
|
this.agent = await agentFromWebDriverAgent({
|
|
1331
|
-
autoDismissKeyboard: false
|
|
1359
|
+
autoDismissKeyboard: false,
|
|
1360
|
+
...opts ?? {}
|
|
1332
1361
|
});
|
|
1362
|
+
this.lastOptsSignature = nextSignature;
|
|
1333
1363
|
return this.agent;
|
|
1334
1364
|
}
|
|
1335
1365
|
preparePlatformTools() {
|
|
@@ -1337,15 +1367,17 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1337
1367
|
{
|
|
1338
1368
|
name: 'ios_connect',
|
|
1339
1369
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1340
|
-
schema:
|
|
1341
|
-
|
|
1342
|
-
|
|
1370
|
+
schema: this.getAgentInitArgSchema(),
|
|
1371
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1372
|
+
handler: async (args)=>{
|
|
1373
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1374
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1343
1375
|
const screenshot = await agent.page.screenshotBase64();
|
|
1344
1376
|
return {
|
|
1345
1377
|
content: [
|
|
1346
1378
|
{
|
|
1347
1379
|
type: 'text',
|
|
1348
|
-
text:
|
|
1380
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1349
1381
|
},
|
|
1350
1382
|
...this.buildScreenshotContent(screenshot)
|
|
1351
1383
|
],
|
|
@@ -1361,6 +1393,16 @@ class IOSMidsceneTools extends BaseMidsceneTools {
|
|
|
1361
1393
|
}
|
|
1362
1394
|
];
|
|
1363
1395
|
}
|
|
1396
|
+
constructor(...args){
|
|
1397
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1398
|
+
namespace: 'ios',
|
|
1399
|
+
shape: iosInitArgShape,
|
|
1400
|
+
cli: {
|
|
1401
|
+
preferBareKeys: true
|
|
1402
|
+
},
|
|
1403
|
+
adapt: (extracted)=>extracted
|
|
1404
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1405
|
+
}
|
|
1364
1406
|
}
|
|
1365
1407
|
class IOSMCPServer extends BaseMCPServer {
|
|
1366
1408
|
createToolsManager() {
|
|
@@ -1369,7 +1411,7 @@ class IOSMCPServer extends BaseMCPServer {
|
|
|
1369
1411
|
constructor(toolsManager){
|
|
1370
1412
|
super({
|
|
1371
1413
|
name: '@midscene/ios-mcp',
|
|
1372
|
-
version: "1.7.5
|
|
1414
|
+
version: "1.7.5",
|
|
1373
1415
|
description: 'Control the iOS device using natural language commands'
|
|
1374
1416
|
}, toolsManager);
|
|
1375
1417
|
}
|
package/dist/lib/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ var __webpack_exports__ = {};
|
|
|
24
24
|
const core_namespaceObject = require("@midscene/core");
|
|
25
25
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
26
26
|
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
27
|
-
const
|
|
27
|
+
const base_tools_namespaceObject = require("@midscene/shared/mcp/base-tools");
|
|
28
28
|
const agent_namespaceObject = require("@midscene/core/agent");
|
|
29
29
|
const utils_namespaceObject = require("@midscene/shared/utils");
|
|
30
30
|
const defaultAppNameMapping = {
|
|
@@ -1344,17 +1344,46 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1344
1344
|
await device.connect();
|
|
1345
1345
|
return new IOSAgent(device, opts);
|
|
1346
1346
|
}
|
|
1347
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1348
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1349
|
+
value: value,
|
|
1350
|
+
enumerable: true,
|
|
1351
|
+
configurable: true,
|
|
1352
|
+
writable: true
|
|
1353
|
+
});
|
|
1354
|
+
else obj[key] = value;
|
|
1355
|
+
return obj;
|
|
1356
|
+
}
|
|
1347
1357
|
const debug = (0, logger_namespaceObject.getDebug)('mcp:ios-tools');
|
|
1348
|
-
|
|
1358
|
+
const iosInitArgShape = {
|
|
1359
|
+
deviceId: core_namespaceObject.z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1360
|
+
wdaHost: core_namespaceObject.z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1361
|
+
wdaPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent port'),
|
|
1362
|
+
useWDA: core_namespaceObject.z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1363
|
+
wdaMjpegPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1364
|
+
};
|
|
1365
|
+
class IOSMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools {
|
|
1349
1366
|
createTemporaryDevice() {
|
|
1350
1367
|
return new IOSDevice({});
|
|
1351
1368
|
}
|
|
1352
|
-
async ensureAgent() {
|
|
1369
|
+
async ensureAgent(opts) {
|
|
1370
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1371
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1372
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1373
|
+
try {
|
|
1374
|
+
await this.agent.destroy?.();
|
|
1375
|
+
} catch (error) {
|
|
1376
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1377
|
+
}
|
|
1378
|
+
this.agent = void 0;
|
|
1379
|
+
}
|
|
1353
1380
|
if (this.agent) return this.agent;
|
|
1354
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1381
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1355
1382
|
this.agent = await agentFromWebDriverAgent({
|
|
1356
|
-
autoDismissKeyboard: false
|
|
1383
|
+
autoDismissKeyboard: false,
|
|
1384
|
+
...opts ?? {}
|
|
1357
1385
|
});
|
|
1386
|
+
this.lastOptsSignature = nextSignature;
|
|
1358
1387
|
return this.agent;
|
|
1359
1388
|
}
|
|
1360
1389
|
preparePlatformTools() {
|
|
@@ -1362,15 +1391,17 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1362
1391
|
{
|
|
1363
1392
|
name: 'ios_connect',
|
|
1364
1393
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1365
|
-
schema:
|
|
1366
|
-
|
|
1367
|
-
|
|
1394
|
+
schema: this.getAgentInitArgSchema(),
|
|
1395
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1396
|
+
handler: async (args)=>{
|
|
1397
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1398
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1368
1399
|
const screenshot = await agent.page.screenshotBase64();
|
|
1369
1400
|
return {
|
|
1370
1401
|
content: [
|
|
1371
1402
|
{
|
|
1372
1403
|
type: 'text',
|
|
1373
|
-
text:
|
|
1404
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1374
1405
|
},
|
|
1375
1406
|
...this.buildScreenshotContent(screenshot)
|
|
1376
1407
|
],
|
|
@@ -1386,15 +1417,24 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1386
1417
|
}
|
|
1387
1418
|
];
|
|
1388
1419
|
}
|
|
1420
|
+
constructor(...args){
|
|
1421
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1422
|
+
namespace: 'ios',
|
|
1423
|
+
shape: iosInitArgShape,
|
|
1424
|
+
cli: {
|
|
1425
|
+
preferBareKeys: true
|
|
1426
|
+
},
|
|
1427
|
+
adapt: (extracted)=>extracted
|
|
1428
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1429
|
+
}
|
|
1389
1430
|
}
|
|
1390
1431
|
const tools = new IOSMidsceneTools();
|
|
1391
1432
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-ios', {
|
|
1392
1433
|
stripPrefix: 'ios_',
|
|
1393
|
-
version: "1.7.5
|
|
1434
|
+
version: "1.7.5",
|
|
1394
1435
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
1395
1436
|
}).catch((e)=>{
|
|
1396
|
-
|
|
1397
|
-
process.exit(e instanceof cli_namespaceObject.CLIError ? e.exitCode : 1);
|
|
1437
|
+
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|
|
1398
1438
|
});
|
|
1399
1439
|
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
1400
1440
|
Object.defineProperty(exports, '__esModule', {
|
package/dist/lib/index.js
CHANGED
|
@@ -1363,18 +1363,47 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1363
1363
|
await device.connect();
|
|
1364
1364
|
return new IOSAgent(device, opts);
|
|
1365
1365
|
}
|
|
1366
|
-
const
|
|
1366
|
+
const base_tools_namespaceObject = require("@midscene/shared/mcp/base-tools");
|
|
1367
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1368
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1369
|
+
value: value,
|
|
1370
|
+
enumerable: true,
|
|
1371
|
+
configurable: true,
|
|
1372
|
+
writable: true
|
|
1373
|
+
});
|
|
1374
|
+
else obj[key] = value;
|
|
1375
|
+
return obj;
|
|
1376
|
+
}
|
|
1367
1377
|
const debug = (0, logger_namespaceObject.getDebug)('mcp:ios-tools');
|
|
1368
|
-
|
|
1378
|
+
const iosInitArgShape = {
|
|
1379
|
+
deviceId: core_namespaceObject.z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1380
|
+
wdaHost: core_namespaceObject.z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1381
|
+
wdaPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent port'),
|
|
1382
|
+
useWDA: core_namespaceObject.z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1383
|
+
wdaMjpegPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1384
|
+
};
|
|
1385
|
+
class IOSMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools {
|
|
1369
1386
|
createTemporaryDevice() {
|
|
1370
1387
|
return new IOSDevice({});
|
|
1371
1388
|
}
|
|
1372
|
-
async ensureAgent() {
|
|
1389
|
+
async ensureAgent(opts) {
|
|
1390
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1391
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1392
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1393
|
+
try {
|
|
1394
|
+
await this.agent.destroy?.();
|
|
1395
|
+
} catch (error) {
|
|
1396
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1397
|
+
}
|
|
1398
|
+
this.agent = void 0;
|
|
1399
|
+
}
|
|
1373
1400
|
if (this.agent) return this.agent;
|
|
1374
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1401
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1375
1402
|
this.agent = await agentFromWebDriverAgent({
|
|
1376
|
-
autoDismissKeyboard: false
|
|
1403
|
+
autoDismissKeyboard: false,
|
|
1404
|
+
...opts ?? {}
|
|
1377
1405
|
});
|
|
1406
|
+
this.lastOptsSignature = nextSignature;
|
|
1378
1407
|
return this.agent;
|
|
1379
1408
|
}
|
|
1380
1409
|
preparePlatformTools() {
|
|
@@ -1382,15 +1411,17 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1382
1411
|
{
|
|
1383
1412
|
name: 'ios_connect',
|
|
1384
1413
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1385
|
-
schema:
|
|
1386
|
-
|
|
1387
|
-
|
|
1414
|
+
schema: this.getAgentInitArgSchema(),
|
|
1415
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1416
|
+
handler: async (args)=>{
|
|
1417
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1418
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1388
1419
|
const screenshot = await agent.page.screenshotBase64();
|
|
1389
1420
|
return {
|
|
1390
1421
|
content: [
|
|
1391
1422
|
{
|
|
1392
1423
|
type: 'text',
|
|
1393
|
-
text:
|
|
1424
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1394
1425
|
},
|
|
1395
1426
|
...this.buildScreenshotContent(screenshot)
|
|
1396
1427
|
],
|
|
@@ -1406,6 +1437,16 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1406
1437
|
}
|
|
1407
1438
|
];
|
|
1408
1439
|
}
|
|
1440
|
+
constructor(...args){
|
|
1441
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1442
|
+
namespace: 'ios',
|
|
1443
|
+
shape: iosInitArgShape,
|
|
1444
|
+
cli: {
|
|
1445
|
+
preferBareKeys: true
|
|
1446
|
+
},
|
|
1447
|
+
adapt: (extracted)=>extracted
|
|
1448
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1449
|
+
}
|
|
1409
1450
|
}
|
|
1410
1451
|
const env_namespaceObject = require("@midscene/shared/env");
|
|
1411
1452
|
const external_node_child_process_namespaceObject = require("node:child_process");
|
package/dist/lib/mcp-server.js
CHANGED
|
@@ -1359,17 +1359,47 @@ async function agentFromWebDriverAgent(opts) {
|
|
|
1359
1359
|
await device.connect();
|
|
1360
1360
|
return new IOSAgent(device, opts);
|
|
1361
1361
|
}
|
|
1362
|
+
const base_tools_namespaceObject = require("@midscene/shared/mcp/base-tools");
|
|
1363
|
+
function mcp_tools_define_property(obj, key, value) {
|
|
1364
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
1365
|
+
value: value,
|
|
1366
|
+
enumerable: true,
|
|
1367
|
+
configurable: true,
|
|
1368
|
+
writable: true
|
|
1369
|
+
});
|
|
1370
|
+
else obj[key] = value;
|
|
1371
|
+
return obj;
|
|
1372
|
+
}
|
|
1362
1373
|
const debug = (0, logger_namespaceObject.getDebug)('mcp:ios-tools');
|
|
1363
|
-
|
|
1374
|
+
const iosInitArgShape = {
|
|
1375
|
+
deviceId: core_namespaceObject.z.string().optional().describe('iOS device UDID (optional when WDA auto-detect is sufficient)'),
|
|
1376
|
+
wdaHost: core_namespaceObject.z.string().optional().describe('WebDriverAgent host, defaults to localhost'),
|
|
1377
|
+
wdaPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent port'),
|
|
1378
|
+
useWDA: core_namespaceObject.z.boolean().optional().describe('Whether to reuse an existing WebDriverAgent session'),
|
|
1379
|
+
wdaMjpegPort: core_namespaceObject.z.number().optional().describe('WebDriverAgent MJPEG streaming port')
|
|
1380
|
+
};
|
|
1381
|
+
class IOSMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools {
|
|
1364
1382
|
createTemporaryDevice() {
|
|
1365
1383
|
return new IOSDevice({});
|
|
1366
1384
|
}
|
|
1367
|
-
async ensureAgent() {
|
|
1385
|
+
async ensureAgent(opts) {
|
|
1386
|
+
const hasOpts = !!opts && Object.keys(opts).length > 0;
|
|
1387
|
+
const nextSignature = hasOpts ? JSON.stringify(opts) : void 0;
|
|
1388
|
+
if (this.agent && hasOpts && nextSignature !== this.lastOptsSignature) {
|
|
1389
|
+
try {
|
|
1390
|
+
await this.agent.destroy?.();
|
|
1391
|
+
} catch (error) {
|
|
1392
|
+
debug('Failed to destroy agent during cleanup:', error);
|
|
1393
|
+
}
|
|
1394
|
+
this.agent = void 0;
|
|
1395
|
+
}
|
|
1368
1396
|
if (this.agent) return this.agent;
|
|
1369
|
-
debug('Creating iOS agent with WebDriverAgent');
|
|
1397
|
+
debug('Creating iOS agent with WebDriverAgent options:', opts || {});
|
|
1370
1398
|
this.agent = await agentFromWebDriverAgent({
|
|
1371
|
-
autoDismissKeyboard: false
|
|
1399
|
+
autoDismissKeyboard: false,
|
|
1400
|
+
...opts ?? {}
|
|
1372
1401
|
});
|
|
1402
|
+
this.lastOptsSignature = nextSignature;
|
|
1373
1403
|
return this.agent;
|
|
1374
1404
|
}
|
|
1375
1405
|
preparePlatformTools() {
|
|
@@ -1377,15 +1407,17 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1377
1407
|
{
|
|
1378
1408
|
name: 'ios_connect',
|
|
1379
1409
|
description: 'Connect to iOS device or simulator via WebDriverAgent',
|
|
1380
|
-
schema:
|
|
1381
|
-
|
|
1382
|
-
|
|
1410
|
+
schema: this.getAgentInitArgSchema(),
|
|
1411
|
+
cli: this.getAgentInitArgCliMetadata(),
|
|
1412
|
+
handler: async (args)=>{
|
|
1413
|
+
const initArgs = this.extractAgentInitParam(args);
|
|
1414
|
+
const agent = await this.ensureAgent(initArgs);
|
|
1383
1415
|
const screenshot = await agent.page.screenshotBase64();
|
|
1384
1416
|
return {
|
|
1385
1417
|
content: [
|
|
1386
1418
|
{
|
|
1387
1419
|
type: 'text',
|
|
1388
|
-
text:
|
|
1420
|
+
text: `Connected to iOS device${initArgs?.deviceId ? `: ${initArgs.deviceId}` : ''}`
|
|
1389
1421
|
},
|
|
1390
1422
|
...this.buildScreenshotContent(screenshot)
|
|
1391
1423
|
],
|
|
@@ -1401,6 +1433,16 @@ class IOSMidsceneTools extends mcp_namespaceObject.BaseMidsceneTools {
|
|
|
1401
1433
|
}
|
|
1402
1434
|
];
|
|
1403
1435
|
}
|
|
1436
|
+
constructor(...args){
|
|
1437
|
+
super(...args), mcp_tools_define_property(this, "initArgSpec", {
|
|
1438
|
+
namespace: 'ios',
|
|
1439
|
+
shape: iosInitArgShape,
|
|
1440
|
+
cli: {
|
|
1441
|
+
preferBareKeys: true
|
|
1442
|
+
},
|
|
1443
|
+
adapt: (extracted)=>extracted
|
|
1444
|
+
}), mcp_tools_define_property(this, "lastOptsSignature", void 0);
|
|
1445
|
+
}
|
|
1404
1446
|
}
|
|
1405
1447
|
class IOSMCPServer extends mcp_namespaceObject.BaseMCPServer {
|
|
1406
1448
|
createToolsManager() {
|
|
@@ -1409,7 +1451,7 @@ class IOSMCPServer extends mcp_namespaceObject.BaseMCPServer {
|
|
|
1409
1451
|
constructor(toolsManager){
|
|
1410
1452
|
super({
|
|
1411
1453
|
name: '@midscene/ios-mcp',
|
|
1412
|
-
version: "1.7.5
|
|
1454
|
+
version: "1.7.5",
|
|
1413
1455
|
description: 'Control the iOS device using natural language commands'
|
|
1414
1456
|
}, toolsManager);
|
|
1415
1457
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ import type { ActionParam } from '@midscene/core';
|
|
|
3
3
|
import type { ActionReturn } from '@midscene/core';
|
|
4
4
|
import { Agent } from '@midscene/core/agent';
|
|
5
5
|
import { AgentOpt } from '@midscene/core/agent';
|
|
6
|
-
import { BaseMidsceneTools } from '@midscene/shared/mcp';
|
|
6
|
+
import { BaseMidsceneTools } from '@midscene/shared/mcp/base-tools';
|
|
7
7
|
import { DeviceAction } from '@midscene/core';
|
|
8
8
|
import type { ElementInfo } from '@midscene/shared/extractor';
|
|
9
|
+
import { InitArgSpec } from '@midscene/shared/mcp/base-tools';
|
|
9
10
|
import { InterfaceType } from '@midscene/core';
|
|
10
11
|
import { IOSDeviceInputOpt } from '@midscene/core/device';
|
|
11
12
|
import { IOSDeviceOpt } from '@midscene/core/device';
|
|
@@ -13,7 +14,7 @@ import { overrideAIConfig } from '@midscene/shared/env';
|
|
|
13
14
|
import { PlaygroundPlatformDescriptor } from '@midscene/playground';
|
|
14
15
|
import { Point } from '@midscene/core';
|
|
15
16
|
import { Size } from '@midscene/core';
|
|
16
|
-
import { ToolDefinition } from '@midscene/shared/mcp';
|
|
17
|
+
import type { ToolDefinition } from '@midscene/shared/mcp/types';
|
|
17
18
|
import { WebDriverClient } from '@midscene/webdriver';
|
|
18
19
|
import { z } from '@midscene/core';
|
|
19
20
|
|
|
@@ -177,13 +178,17 @@ export declare class IOSDevice implements AbstractInterface {
|
|
|
177
178
|
destroy(): Promise<void>;
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
declare type IOSInitArgs = Pick<IOSDeviceOpt, 'deviceId' | 'wdaHost' | 'wdaPort' | 'useWDA' | 'wdaMjpegPort'>;
|
|
182
|
+
|
|
180
183
|
/**
|
|
181
184
|
* iOS-specific tools manager
|
|
182
185
|
* Extends BaseMidsceneTools to provide iOS WebDriverAgent connection tools
|
|
183
186
|
*/
|
|
184
|
-
export declare class IOSMidsceneTools extends BaseMidsceneTools<IOSAgent> {
|
|
187
|
+
export declare class IOSMidsceneTools extends BaseMidsceneTools<IOSAgent, IOSInitArgs> {
|
|
188
|
+
protected readonly initArgSpec: InitArgSpec<IOSInitArgs>;
|
|
189
|
+
private lastOptsSignature?;
|
|
185
190
|
protected createTemporaryDevice(): IOSDevice;
|
|
186
|
-
protected ensureAgent(): Promise<IOSAgent>;
|
|
191
|
+
protected ensureAgent(opts?: IOSInitArgs): Promise<IOSAgent>;
|
|
187
192
|
/**
|
|
188
193
|
* Provide iOS-specific platform tools
|
|
189
194
|
*/
|