@metamask/device-mcp 0.1.0 → 0.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/CHANGELOG.md +9 -14
- package/LICENSE +6 -0
- package/LICENSE.APACHE2 +201 -0
- package/LICENSE.MIT +21 -0
- package/README.md +61 -33
- package/dist/backends/adb-backend.cjs +9 -0
- package/dist/backends/adb-backend.cjs.map +1 -1
- package/dist/backends/adb-backend.d.cts +1 -0
- package/dist/backends/adb-backend.d.cts.map +1 -1
- package/dist/backends/adb-backend.d.mts +1 -0
- package/dist/backends/adb-backend.d.mts.map +1 -1
- package/dist/backends/adb-backend.mjs +9 -0
- package/dist/backends/adb-backend.mjs.map +1 -1
- package/dist/backends/appium-backend.cjs +9 -0
- package/dist/backends/appium-backend.cjs.map +1 -1
- package/dist/backends/appium-backend.d.cts +1 -0
- package/dist/backends/appium-backend.d.cts.map +1 -1
- package/dist/backends/appium-backend.d.mts +1 -0
- package/dist/backends/appium-backend.d.mts.map +1 -1
- package/dist/backends/appium-backend.mjs +9 -0
- package/dist/backends/appium-backend.mjs.map +1 -1
- package/dist/backends/idb-backend.cjs +84 -33
- package/dist/backends/idb-backend.cjs.map +1 -1
- package/dist/backends/idb-backend.d.cts +1 -0
- package/dist/backends/idb-backend.d.cts.map +1 -1
- package/dist/backends/idb-backend.d.mts +1 -0
- package/dist/backends/idb-backend.d.mts.map +1 -1
- package/dist/backends/idb-backend.mjs +85 -34
- package/dist/backends/idb-backend.mjs.map +1 -1
- package/dist/backends/index.cjs +33 -12
- package/dist/backends/index.cjs.map +1 -1
- package/dist/backends/index.d.cts +8 -11
- package/dist/backends/index.d.cts.map +1 -1
- package/dist/backends/index.d.mts +8 -11
- package/dist/backends/index.d.mts.map +1 -1
- package/dist/backends/index.mjs +34 -13
- package/dist/backends/index.mjs.map +1 -1
- package/dist/backends/types.cjs.map +1 -1
- package/dist/backends/types.d.cts +1 -0
- package/dist/backends/types.d.cts.map +1 -1
- package/dist/backends/types.d.mts +1 -0
- package/dist/backends/types.d.mts.map +1 -1
- package/dist/backends/types.mjs.map +1 -1
- package/dist/cli/device-mcp.cjs +11 -2
- package/dist/cli/device-mcp.cjs.map +1 -1
- package/dist/cli/device-mcp.mjs +11 -2
- package/dist/cli/device-mcp.mjs.map +1 -1
- package/dist/index.cjs +4 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/server.cjs +5 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.mts.map +1 -1
- package/dist/server.mjs +6 -1
- package/dist/server.mjs.map +1 -1
- package/dist/tools/get-element-text.cjs +46 -0
- package/dist/tools/get-element-text.cjs.map +1 -0
- package/dist/tools/get-element-text.d.cts +4 -0
- package/dist/tools/get-element-text.d.cts.map +1 -0
- package/dist/tools/get-element-text.d.mts +4 -0
- package/dist/tools/get-element-text.d.mts.map +1 -0
- package/dist/tools/get-element-text.mjs +43 -0
- package/dist/tools/get-element-text.mjs.map +1 -0
- package/dist/tools/index.cjs +7 -1
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.cts +3 -0
- package/dist/tools/index.d.cts.map +1 -1
- package/dist/tools/index.d.mts +3 -0
- package/dist/tools/index.d.mts.map +1 -1
- package/dist/tools/index.mjs +3 -0
- package/dist/tools/index.mjs.map +1 -1
- package/dist/tools/list-devices.cjs +36 -0
- package/dist/tools/list-devices.cjs.map +1 -0
- package/dist/tools/list-devices.d.cts +4 -0
- package/dist/tools/list-devices.d.cts.map +1 -0
- package/dist/tools/list-devices.d.mts +4 -0
- package/dist/tools/list-devices.d.mts.map +1 -0
- package/dist/tools/list-devices.mjs +33 -0
- package/dist/tools/list-devices.mjs.map +1 -0
- package/dist/tools/select-device.cjs +38 -0
- package/dist/tools/select-device.cjs.map +1 -0
- package/dist/tools/select-device.d.cts +4 -0
- package/dist/tools/select-device.d.cts.map +1 -0
- package/dist/tools/select-device.d.mts +4 -0
- package/dist/tools/select-device.d.mts.map +1 -0
- package/dist/tools/select-device.mjs +35 -0
- package/dist/tools/select-device.mjs.map +1 -0
- package/dist/utils/exec.cjs +11 -9
- package/dist/utils/exec.cjs.map +1 -1
- package/dist/utils/exec.d.cts.map +1 -1
- package/dist/utils/exec.d.mts.map +1 -1
- package/dist/utils/exec.mjs +11 -9
- package/dist/utils/exec.mjs.map +1 -1
- package/dist/utils/platform.cjs +121 -36
- package/dist/utils/platform.cjs.map +1 -1
- package/dist/utils/platform.d.cts +14 -3
- package/dist/utils/platform.d.cts.map +1 -1
- package/dist/utils/platform.d.mts +14 -3
- package/dist/utils/platform.d.mts.map +1 -1
- package/dist/utils/platform.mjs +117 -36
- package/dist/utils/platform.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { errorResult } from "./shared.mjs";
|
|
3
|
+
export function registerGetElementTextTool(server, backend) {
|
|
4
|
+
server.registerTool('device_get_element_text', {
|
|
5
|
+
title: 'Get Element Text',
|
|
6
|
+
description: 'Find an element in the UI hierarchy by query and return its text content (label or value). ' +
|
|
7
|
+
'Specify at least one of: label, identifier, text, type. ' +
|
|
8
|
+
'Call device_snapshot first to see available elements.',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
label: z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('Accessibility label (iOS) or content-description (Android)'),
|
|
14
|
+
identifier: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Accessibility identifier (iOS) or resource-id (Android)'),
|
|
18
|
+
text: z.string().optional().describe('Visible text content'),
|
|
19
|
+
type: z.string().optional().describe('Element type/class name'),
|
|
20
|
+
},
|
|
21
|
+
}, async ({ label, identifier, text, type }) => {
|
|
22
|
+
try {
|
|
23
|
+
const result = await backend.getElementText({
|
|
24
|
+
label,
|
|
25
|
+
identifier,
|
|
26
|
+
text,
|
|
27
|
+
type,
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: 'text',
|
|
33
|
+
text: result || '(empty)',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return errorResult(error);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=get-element-text.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-element-text.mjs","sourceRoot":"","sources":["../../src/tools/get-element-text.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,0BAA0B,CACxC,MAAiB,EACjB,OAAsB;IAEtB,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,6FAA6F;YAC7F,0DAA0D;YAC1D,uDAAuD;QACzD,WAAW,EAAE;YACX,KAAK,EAAE,CAAC;iBACL,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,4DAA4D,CAC7D;YACH,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yDAAyD,CAAC;YACtE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;SAChE;KACF,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;QAC1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC;gBAC1C,KAAK;gBACL,UAAU;gBACV,IAAI;gBACJ,IAAI;aACL,CAAC,CAAC;YACH,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,IAAI,SAAS;qBAC1B;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { DeviceBackend } from '../backends/types.js';\n\nexport function registerGetElementTextTool(\n server: McpServer,\n backend: DeviceBackend,\n): void {\n server.registerTool(\n 'device_get_element_text',\n {\n title: 'Get Element Text',\n description:\n 'Find an element in the UI hierarchy by query and return its text content (label or value). ' +\n 'Specify at least one of: label, identifier, text, type. ' +\n 'Call device_snapshot first to see available elements.',\n inputSchema: {\n label: z\n .string()\n .optional()\n .describe(\n 'Accessibility label (iOS) or content-description (Android)',\n ),\n identifier: z\n .string()\n .optional()\n .describe('Accessibility identifier (iOS) or resource-id (Android)'),\n text: z.string().optional().describe('Visible text content'),\n type: z.string().optional().describe('Element type/class name'),\n },\n },\n async ({ label, identifier, text, type }) => {\n try {\n const result = await backend.getElementText({\n label,\n identifier,\n text,\n type,\n });\n return {\n content: [\n {\n type: 'text' as const,\n text: result || '(empty)',\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
|
package/dist/tools/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.registerGenerateLocatorsTool = exports.registerScreenRecordingTool = exports.registerClipboardTool = exports.registerContextTool = exports.registerWindowSizeTool = exports.registerAlertTextTool = exports.registerScrollToElementTool = exports.registerLogsTool = exports.registerDismissAlertTool = exports.registerDismissKeyboardTool = exports.registerPressButtonTool = exports.registerCloseAppTool = exports.registerOpenAppTool = exports.registerDeviceInfoTool = exports.registerAppStateTool = exports.registerWaitForTool = exports.registerLongPressTool = exports.registerSwipeTool = exports.registerTypeTool = exports.registerTapCoordinatesTool = exports.registerTapElementTool = exports.registerScreenshotTool = exports.registerSnapshotTool = void 0;
|
|
3
|
+
exports.registerSelectDeviceTool = exports.registerListDevicesTool = exports.registerGetElementTextTool = exports.registerGenerateLocatorsTool = exports.registerScreenRecordingTool = exports.registerClipboardTool = exports.registerContextTool = exports.registerWindowSizeTool = exports.registerAlertTextTool = exports.registerScrollToElementTool = exports.registerLogsTool = exports.registerDismissAlertTool = exports.registerDismissKeyboardTool = exports.registerPressButtonTool = exports.registerCloseAppTool = exports.registerOpenAppTool = exports.registerDeviceInfoTool = exports.registerAppStateTool = exports.registerWaitForTool = exports.registerLongPressTool = exports.registerSwipeTool = exports.registerTypeTool = exports.registerTapCoordinatesTool = exports.registerTapElementTool = exports.registerScreenshotTool = exports.registerSnapshotTool = void 0;
|
|
4
4
|
var snapshot_js_1 = require("./snapshot.cjs");
|
|
5
5
|
Object.defineProperty(exports, "registerSnapshotTool", { enumerable: true, get: function () { return snapshot_js_1.registerSnapshotTool; } });
|
|
6
6
|
var screenshot_js_1 = require("./screenshot.cjs");
|
|
@@ -47,4 +47,10 @@ var screen_recording_js_1 = require("./screen-recording.cjs");
|
|
|
47
47
|
Object.defineProperty(exports, "registerScreenRecordingTool", { enumerable: true, get: function () { return screen_recording_js_1.registerScreenRecordingTool; } });
|
|
48
48
|
var generate_locators_js_1 = require("./generate-locators.cjs");
|
|
49
49
|
Object.defineProperty(exports, "registerGenerateLocatorsTool", { enumerable: true, get: function () { return generate_locators_js_1.registerGenerateLocatorsTool; } });
|
|
50
|
+
var get_element_text_js_1 = require("./get-element-text.cjs");
|
|
51
|
+
Object.defineProperty(exports, "registerGetElementTextTool", { enumerable: true, get: function () { return get_element_text_js_1.registerGetElementTextTool; } });
|
|
52
|
+
var list_devices_js_1 = require("./list-devices.cjs");
|
|
53
|
+
Object.defineProperty(exports, "registerListDevicesTool", { enumerable: true, get: function () { return list_devices_js_1.registerListDevicesTool; } });
|
|
54
|
+
var select_device_js_1 = require("./select-device.cjs");
|
|
55
|
+
Object.defineProperty(exports, "registerSelectDeviceTool", { enumerable: true, get: function () { return select_device_js_1.registerSelectDeviceTool; } });
|
|
50
56
|
//# sourceMappingURL=index.cjs.map
|
package/dist/tools/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;AAAA,8CAAqD;AAA5C,mHAAA,oBAAoB,OAAA;AAC7B,kDAAyD;AAAhD,uHAAA,sBAAsB,OAAA;AAC/B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,4DAAkE;AAAzD,gIAAA,0BAA0B,OAAA;AACnC,gDAAkD;AAAzC,gHAAA,gBAAgB,OAAA;AACzB,wCAA+C;AAAtC,6GAAA,iBAAiB,OAAA;AAC1B,kDAAwD;AAA/C,sHAAA,qBAAqB,OAAA;AAC9B,8CAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAC5B,gDAAsD;AAA7C,oHAAA,oBAAoB,OAAA;AAC7B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,8CAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAC5B,gDAAsD;AAA7C,oHAAA,oBAAoB,OAAA;AAC7B,sDAA4D;AAAnD,0HAAA,uBAAuB,OAAA;AAChC,8DAAoE;AAA3D,kIAAA,2BAA2B,OAAA;AACpC,wDAA8D;AAArD,4HAAA,wBAAwB,OAAA;AACjC,sCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AACzB,gEAAqE;AAA5D,mIAAA,2BAA2B,OAAA;AACpC,kDAAwD;AAA/C,sHAAA,qBAAqB,OAAA;AAC9B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,4CAAmD;AAA1C,iHAAA,mBAAmB,OAAA;AAC5B,gDAAuD;AAA9C,qHAAA,qBAAqB,OAAA;AAC9B,8DAAoE;AAA3D,kIAAA,2BAA2B,OAAA;AACpC,gEAAsE;AAA7D,oIAAA,4BAA4B,OAAA","sourcesContent":["export { registerSnapshotTool } from './snapshot.js';\nexport { registerScreenshotTool } from './screenshot.js';\nexport { registerTapElementTool } from './tap-element.js';\nexport { registerTapCoordinatesTool } from './tap-coordinates.js';\nexport { registerTypeTool } from './type-text.js';\nexport { registerSwipeTool } from './swipe.js';\nexport { registerLongPressTool } from './long-press.js';\nexport { registerWaitForTool } from './wait-for.js';\nexport { registerAppStateTool } from './app-state.js';\nexport { registerDeviceInfoTool } from './device-info.js';\nexport { registerOpenAppTool } from './open-app.js';\nexport { registerCloseAppTool } from './close-app.js';\nexport { registerPressButtonTool } from './press-button.js';\nexport { registerDismissKeyboardTool } from './dismiss-keyboard.js';\nexport { registerDismissAlertTool } from './dismiss-alert.js';\nexport { registerLogsTool } from './logs.js';\nexport { registerScrollToElementTool } from './scroll-to-element.js';\nexport { registerAlertTextTool } from './alert-text.js';\nexport { registerWindowSizeTool } from './window-size.js';\nexport { registerContextTool } from './context.js';\nexport { registerClipboardTool } from './clipboard.js';\nexport { registerScreenRecordingTool } from './screen-recording.js';\nexport { registerGenerateLocatorsTool } from './generate-locators.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;AAAA,8CAAqD;AAA5C,mHAAA,oBAAoB,OAAA;AAC7B,kDAAyD;AAAhD,uHAAA,sBAAsB,OAAA;AAC/B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,4DAAkE;AAAzD,gIAAA,0BAA0B,OAAA;AACnC,gDAAkD;AAAzC,gHAAA,gBAAgB,OAAA;AACzB,wCAA+C;AAAtC,6GAAA,iBAAiB,OAAA;AAC1B,kDAAwD;AAA/C,sHAAA,qBAAqB,OAAA;AAC9B,8CAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAC5B,gDAAsD;AAA7C,oHAAA,oBAAoB,OAAA;AAC7B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,8CAAoD;AAA3C,kHAAA,mBAAmB,OAAA;AAC5B,gDAAsD;AAA7C,oHAAA,oBAAoB,OAAA;AAC7B,sDAA4D;AAAnD,0HAAA,uBAAuB,OAAA;AAChC,8DAAoE;AAA3D,kIAAA,2BAA2B,OAAA;AACpC,wDAA8D;AAArD,4HAAA,wBAAwB,OAAA;AACjC,sCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AACzB,gEAAqE;AAA5D,mIAAA,2BAA2B,OAAA;AACpC,kDAAwD;AAA/C,sHAAA,qBAAqB,OAAA;AAC9B,oDAA0D;AAAjD,wHAAA,sBAAsB,OAAA;AAC/B,4CAAmD;AAA1C,iHAAA,mBAAmB,OAAA;AAC5B,gDAAuD;AAA9C,qHAAA,qBAAqB,OAAA;AAC9B,8DAAoE;AAA3D,kIAAA,2BAA2B,OAAA;AACpC,gEAAsE;AAA7D,oIAAA,4BAA4B,OAAA;AACrC,8DAAmE;AAA1D,iIAAA,0BAA0B,OAAA;AACnC,sDAA4D;AAAnD,0HAAA,uBAAuB,OAAA;AAChC,wDAA8D;AAArD,4HAAA,wBAAwB,OAAA","sourcesContent":["export { registerSnapshotTool } from './snapshot.js';\nexport { registerScreenshotTool } from './screenshot.js';\nexport { registerTapElementTool } from './tap-element.js';\nexport { registerTapCoordinatesTool } from './tap-coordinates.js';\nexport { registerTypeTool } from './type-text.js';\nexport { registerSwipeTool } from './swipe.js';\nexport { registerLongPressTool } from './long-press.js';\nexport { registerWaitForTool } from './wait-for.js';\nexport { registerAppStateTool } from './app-state.js';\nexport { registerDeviceInfoTool } from './device-info.js';\nexport { registerOpenAppTool } from './open-app.js';\nexport { registerCloseAppTool } from './close-app.js';\nexport { registerPressButtonTool } from './press-button.js';\nexport { registerDismissKeyboardTool } from './dismiss-keyboard.js';\nexport { registerDismissAlertTool } from './dismiss-alert.js';\nexport { registerLogsTool } from './logs.js';\nexport { registerScrollToElementTool } from './scroll-to-element.js';\nexport { registerAlertTextTool } from './alert-text.js';\nexport { registerWindowSizeTool } from './window-size.js';\nexport { registerContextTool } from './context.js';\nexport { registerClipboardTool } from './clipboard.js';\nexport { registerScreenRecordingTool } from './screen-recording.js';\nexport { registerGenerateLocatorsTool } from './generate-locators.js';\nexport { registerGetElementTextTool } from './get-element-text.js';\nexport { registerListDevicesTool } from './list-devices.js';\nexport { registerSelectDeviceTool } from './select-device.js';\n"]}
|
package/dist/tools/index.d.cts
CHANGED
|
@@ -21,4 +21,7 @@ export { registerContextTool } from "./context.cjs";
|
|
|
21
21
|
export { registerClipboardTool } from "./clipboard.cjs";
|
|
22
22
|
export { registerScreenRecordingTool } from "./screen-recording.cjs";
|
|
23
23
|
export { registerGenerateLocatorsTool } from "./generate-locators.cjs";
|
|
24
|
+
export { registerGetElementTextTool } from "./get-element-text.cjs";
|
|
25
|
+
export { registerListDevicesTool } from "./list-devices.cjs";
|
|
26
|
+
export { registerSelectDeviceTool } from "./select-device.cjs";
|
|
24
27
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B"}
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B;AACtE,OAAO,EAAE,0BAA0B,EAAE,+BAA8B;AACnE,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,wBAAwB,EAAE,4BAA2B"}
|
package/dist/tools/index.d.mts
CHANGED
|
@@ -21,4 +21,7 @@ export { registerContextTool } from "./context.mjs";
|
|
|
21
21
|
export { registerClipboardTool } from "./clipboard.mjs";
|
|
22
22
|
export { registerScreenRecordingTool } from "./screen-recording.mjs";
|
|
23
23
|
export { registerGenerateLocatorsTool } from "./generate-locators.mjs";
|
|
24
|
+
export { registerGetElementTextTool } from "./get-element-text.mjs";
|
|
25
|
+
export { registerListDevicesTool } from "./list-devices.mjs";
|
|
26
|
+
export { registerSelectDeviceTool } from "./select-device.mjs";
|
|
24
27
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B;AACtE,OAAO,EAAE,0BAA0B,EAAE,+BAA8B;AACnE,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,wBAAwB,EAAE,4BAA2B"}
|
package/dist/tools/index.mjs
CHANGED
|
@@ -21,4 +21,7 @@ export { registerContextTool } from "./context.mjs";
|
|
|
21
21
|
export { registerClipboardTool } from "./clipboard.mjs";
|
|
22
22
|
export { registerScreenRecordingTool } from "./screen-recording.mjs";
|
|
23
23
|
export { registerGenerateLocatorsTool } from "./generate-locators.mjs";
|
|
24
|
+
export { registerGetElementTextTool } from "./get-element-text.mjs";
|
|
25
|
+
export { registerListDevicesTool } from "./list-devices.mjs";
|
|
26
|
+
export { registerSelectDeviceTool } from "./select-device.mjs";
|
|
24
27
|
//# sourceMappingURL=index.mjs.map
|
package/dist/tools/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B","sourcesContent":["export { registerSnapshotTool } from './snapshot.js';\nexport { registerScreenshotTool } from './screenshot.js';\nexport { registerTapElementTool } from './tap-element.js';\nexport { registerTapCoordinatesTool } from './tap-coordinates.js';\nexport { registerTypeTool } from './type-text.js';\nexport { registerSwipeTool } from './swipe.js';\nexport { registerLongPressTool } from './long-press.js';\nexport { registerWaitForTool } from './wait-for.js';\nexport { registerAppStateTool } from './app-state.js';\nexport { registerDeviceInfoTool } from './device-info.js';\nexport { registerOpenAppTool } from './open-app.js';\nexport { registerCloseAppTool } from './close-app.js';\nexport { registerPressButtonTool } from './press-button.js';\nexport { registerDismissKeyboardTool } from './dismiss-keyboard.js';\nexport { registerDismissAlertTool } from './dismiss-alert.js';\nexport { registerLogsTool } from './logs.js';\nexport { registerScrollToElementTool } from './scroll-to-element.js';\nexport { registerAlertTextTool } from './alert-text.js';\nexport { registerWindowSizeTool } from './window-size.js';\nexport { registerContextTool } from './context.js';\nexport { registerClipboardTool } from './clipboard.js';\nexport { registerScreenRecordingTool } from './screen-recording.js';\nexport { registerGenerateLocatorsTool } from './generate-locators.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,uBAAsB;AACrD,OAAO,EAAE,sBAAsB,EAAE,yBAAwB;AACzD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,0BAA0B,EAAE,8BAA6B;AAClE,OAAO,EAAE,gBAAgB,EAAE,wBAAuB;AAClD,OAAO,EAAE,iBAAiB,EAAE,oBAAmB;AAC/C,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,uBAAsB;AACpD,OAAO,EAAE,oBAAoB,EAAE,wBAAuB;AACtD,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,wBAAwB,EAAE,4BAA2B;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAkB;AAC7C,OAAO,EAAE,2BAA2B,EAAE,gCAA+B;AACrE,OAAO,EAAE,qBAAqB,EAAE,yBAAwB;AACxD,OAAO,EAAE,sBAAsB,EAAE,0BAAyB;AAC1D,OAAO,EAAE,mBAAmB,EAAE,sBAAqB;AACnD,OAAO,EAAE,qBAAqB,EAAE,wBAAuB;AACvD,OAAO,EAAE,2BAA2B,EAAE,+BAA8B;AACpE,OAAO,EAAE,4BAA4B,EAAE,gCAA+B;AACtE,OAAO,EAAE,0BAA0B,EAAE,+BAA8B;AACnE,OAAO,EAAE,uBAAuB,EAAE,2BAA0B;AAC5D,OAAO,EAAE,wBAAwB,EAAE,4BAA2B","sourcesContent":["export { registerSnapshotTool } from './snapshot.js';\nexport { registerScreenshotTool } from './screenshot.js';\nexport { registerTapElementTool } from './tap-element.js';\nexport { registerTapCoordinatesTool } from './tap-coordinates.js';\nexport { registerTypeTool } from './type-text.js';\nexport { registerSwipeTool } from './swipe.js';\nexport { registerLongPressTool } from './long-press.js';\nexport { registerWaitForTool } from './wait-for.js';\nexport { registerAppStateTool } from './app-state.js';\nexport { registerDeviceInfoTool } from './device-info.js';\nexport { registerOpenAppTool } from './open-app.js';\nexport { registerCloseAppTool } from './close-app.js';\nexport { registerPressButtonTool } from './press-button.js';\nexport { registerDismissKeyboardTool } from './dismiss-keyboard.js';\nexport { registerDismissAlertTool } from './dismiss-alert.js';\nexport { registerLogsTool } from './logs.js';\nexport { registerScrollToElementTool } from './scroll-to-element.js';\nexport { registerAlertTextTool } from './alert-text.js';\nexport { registerWindowSizeTool } from './window-size.js';\nexport { registerContextTool } from './context.js';\nexport { registerClipboardTool } from './clipboard.js';\nexport { registerScreenRecordingTool } from './screen-recording.js';\nexport { registerGenerateLocatorsTool } from './generate-locators.js';\nexport { registerGetElementTextTool } from './get-element-text.js';\nexport { registerListDevicesTool } from './list-devices.js';\nexport { registerSelectDeviceTool } from './select-device.js';\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerListDevicesTool = registerListDevicesTool;
|
|
4
|
+
const shared_js_1 = require("./shared.cjs");
|
|
5
|
+
function registerListDevicesTool(server, backend) {
|
|
6
|
+
server.registerTool('device_list_devices', {
|
|
7
|
+
title: 'List Devices',
|
|
8
|
+
description: 'List all connected devices and simulators/emulators.',
|
|
9
|
+
inputSchema: {},
|
|
10
|
+
annotations: { readOnlyHint: true },
|
|
11
|
+
}, async () => {
|
|
12
|
+
try {
|
|
13
|
+
const devices = await backend.listDevices();
|
|
14
|
+
if (devices.length === 0) {
|
|
15
|
+
return {
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: 'No connected devices found. Boot a simulator/emulator or connect a device.',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const header = 'Platform\tDevice ID';
|
|
25
|
+
const rows = devices.map((d) => `${d.platform}\t${d.deviceId}`);
|
|
26
|
+
const text = [header, ...rows].join('\n');
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: 'text', text }],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return (0, shared_js_1.errorResult)(error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=list-devices.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-devices.cjs","sourceRoot":"","sources":["../../src/tools/list-devices.ts"],"names":[],"mappings":";;AAKA,0DAuCC;AA1CD,4CAA0C;AAG1C,SAAgB,uBAAuB,CACrC,MAAiB,EACjB,OAA0B;IAE1B,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAE5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,4EAA4E;yBACnF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,qBAAqB,CAAC;YACrC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;aAC3C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport { errorResult } from './shared.js';\nimport type { LazyDeviceBackend } from '../backends/index.js';\n\nexport function registerListDevicesTool(\n server: McpServer,\n backend: LazyDeviceBackend,\n): void {\n server.registerTool(\n 'device_list_devices',\n {\n title: 'List Devices',\n description: 'List all connected devices and simulators/emulators.',\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => {\n try {\n const devices = await backend.listDevices();\n\n if (devices.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No connected devices found. Boot a simulator/emulator or connect a device.',\n },\n ],\n };\n }\n\n const header = 'Platform\\tDevice ID';\n const rows = devices.map((d) => `${d.platform}\\t${d.deviceId}`);\n const text = [header, ...rows].join('\\n');\n\n return {\n content: [{ type: 'text' as const, text }],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { LazyDeviceBackend } from "../backends/index.cjs";
|
|
3
|
+
export declare function registerListDevicesTool(server: McpServer, backend: LazyDeviceBackend): void;
|
|
4
|
+
//# sourceMappingURL=list-devices.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-devices.d.cts","sourceRoot":"","sources":["../../src/tools/list-devices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAGzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,8BAA6B;AAE9D,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,GACzB,IAAI,CAoCN"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { LazyDeviceBackend } from "../backends/index.mjs";
|
|
3
|
+
export declare function registerListDevicesTool(server: McpServer, backend: LazyDeviceBackend): void;
|
|
4
|
+
//# sourceMappingURL=list-devices.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-devices.d.mts","sourceRoot":"","sources":["../../src/tools/list-devices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAGzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,8BAA6B;AAE9D,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,GACzB,IAAI,CAoCN"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { errorResult } from "./shared.mjs";
|
|
2
|
+
export function registerListDevicesTool(server, backend) {
|
|
3
|
+
server.registerTool('device_list_devices', {
|
|
4
|
+
title: 'List Devices',
|
|
5
|
+
description: 'List all connected devices and simulators/emulators.',
|
|
6
|
+
inputSchema: {},
|
|
7
|
+
annotations: { readOnlyHint: true },
|
|
8
|
+
}, async () => {
|
|
9
|
+
try {
|
|
10
|
+
const devices = await backend.listDevices();
|
|
11
|
+
if (devices.length === 0) {
|
|
12
|
+
return {
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: 'No connected devices found. Boot a simulator/emulator or connect a device.',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const header = 'Platform\tDevice ID';
|
|
22
|
+
const rows = devices.map((d) => `${d.platform}\t${d.deviceId}`);
|
|
23
|
+
const text = [header, ...rows].join('\n');
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: 'text', text }],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return errorResult(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=list-devices.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-devices.mjs","sourceRoot":"","sources":["../../src/tools/list-devices.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,OAA0B;IAE1B,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,EAAE;QACf,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACpC,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;YAE5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,4EAA4E;yBACnF;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,qBAAqB,CAAC;YACrC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE1C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;aAC3C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nimport { errorResult } from './shared.js';\nimport type { LazyDeviceBackend } from '../backends/index.js';\n\nexport function registerListDevicesTool(\n server: McpServer,\n backend: LazyDeviceBackend,\n): void {\n server.registerTool(\n 'device_list_devices',\n {\n title: 'List Devices',\n description: 'List all connected devices and simulators/emulators.',\n inputSchema: {},\n annotations: { readOnlyHint: true },\n },\n async () => {\n try {\n const devices = await backend.listDevices();\n\n if (devices.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No connected devices found. Boot a simulator/emulator or connect a device.',\n },\n ],\n };\n }\n\n const header = 'Platform\\tDevice ID';\n const rows = devices.map((d) => `${d.platform}\\t${d.deviceId}`);\n const text = [header, ...rows].join('\\n');\n\n return {\n content: [{ type: 'text' as const, text }],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSelectDeviceTool = registerSelectDeviceTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const shared_js_1 = require("./shared.cjs");
|
|
6
|
+
function registerSelectDeviceTool(server, backend) {
|
|
7
|
+
server.registerTool('device_select_device', {
|
|
8
|
+
title: 'Select Device',
|
|
9
|
+
description: 'Select a device to use for this session. Call device_list_devices first to see available devices.',
|
|
10
|
+
inputSchema: {
|
|
11
|
+
deviceId: zod_1.z
|
|
12
|
+
.string()
|
|
13
|
+
.describe('Device ID to select (UDID for iOS, serial for Android)'),
|
|
14
|
+
},
|
|
15
|
+
}, async ({ deviceId }) => {
|
|
16
|
+
try {
|
|
17
|
+
backend.selectDevice(deviceId);
|
|
18
|
+
const info = await backend.getDeviceInfo();
|
|
19
|
+
return {
|
|
20
|
+
content: [
|
|
21
|
+
{
|
|
22
|
+
type: 'text',
|
|
23
|
+
text: [
|
|
24
|
+
`Selected device: ${info.name}`,
|
|
25
|
+
`Platform: ${info.platform}`,
|
|
26
|
+
`OS: ${info.osVersion}`,
|
|
27
|
+
`ID: ${info.deviceId}`,
|
|
28
|
+
].join('\n'),
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return (0, shared_js_1.errorResult)(error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=select-device.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-device.cjs","sourceRoot":"","sources":["../../src/tools/select-device.ts"],"names":[],"mappings":";;AAMA,4DAuCC;AA5CD,6BAAwB;AAExB,4CAA0C;AAG1C,SAAgB,wBAAwB,CACtC,MAAiB,EACjB,OAA0B;IAE1B,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,QAAQ,EAAE,OAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,CAAC,wDAAwD,CAAC;SACtE;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;YAE3C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,oBAAoB,IAAI,CAAC,IAAI,EAAE;4BAC/B,aAAa,IAAI,CAAC,QAAQ,EAAE;4BAC5B,OAAO,IAAI,CAAC,SAAS,EAAE;4BACvB,OAAO,IAAI,CAAC,QAAQ,EAAE;yBACvB,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAA,uBAAW,EAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { LazyDeviceBackend } from '../backends/index.js';\n\nexport function registerSelectDeviceTool(\n server: McpServer,\n backend: LazyDeviceBackend,\n): void {\n server.registerTool(\n 'device_select_device',\n {\n title: 'Select Device',\n description:\n 'Select a device to use for this session. Call device_list_devices first to see available devices.',\n inputSchema: {\n deviceId: z\n .string()\n .describe('Device ID to select (UDID for iOS, serial for Android)'),\n },\n },\n async ({ deviceId }) => {\n try {\n backend.selectDevice(deviceId);\n const info = await backend.getDeviceInfo();\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Selected device: ${info.name}`,\n `Platform: ${info.platform}`,\n `OS: ${info.osVersion}`,\n `ID: ${info.deviceId}`,\n ].join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { LazyDeviceBackend } from "../backends/index.cjs";
|
|
3
|
+
export declare function registerSelectDeviceTool(server: McpServer, backend: LazyDeviceBackend): void;
|
|
4
|
+
//# sourceMappingURL=select-device.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-device.d.cts","sourceRoot":"","sources":["../../src/tools/select-device.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,8BAA6B;AAE9D,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,GACzB,IAAI,CAoCN"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { LazyDeviceBackend } from "../backends/index.mjs";
|
|
3
|
+
export declare function registerSelectDeviceTool(server: McpServer, backend: LazyDeviceBackend): void;
|
|
4
|
+
//# sourceMappingURL=select-device.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-device.d.mts","sourceRoot":"","sources":["../../src/tools/select-device.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,gDAAgD;AAIzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,8BAA6B;AAE9D,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,GACzB,IAAI,CAoCN"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { errorResult } from "./shared.mjs";
|
|
3
|
+
export function registerSelectDeviceTool(server, backend) {
|
|
4
|
+
server.registerTool('device_select_device', {
|
|
5
|
+
title: 'Select Device',
|
|
6
|
+
description: 'Select a device to use for this session. Call device_list_devices first to see available devices.',
|
|
7
|
+
inputSchema: {
|
|
8
|
+
deviceId: z
|
|
9
|
+
.string()
|
|
10
|
+
.describe('Device ID to select (UDID for iOS, serial for Android)'),
|
|
11
|
+
},
|
|
12
|
+
}, async ({ deviceId }) => {
|
|
13
|
+
try {
|
|
14
|
+
backend.selectDevice(deviceId);
|
|
15
|
+
const info = await backend.getDeviceInfo();
|
|
16
|
+
return {
|
|
17
|
+
content: [
|
|
18
|
+
{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: [
|
|
21
|
+
`Selected device: ${info.name}`,
|
|
22
|
+
`Platform: ${info.platform}`,
|
|
23
|
+
`OS: ${info.osVersion}`,
|
|
24
|
+
`ID: ${info.deviceId}`,
|
|
25
|
+
].join('\n'),
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return errorResult(error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=select-device.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-device.mjs","sourceRoot":"","sources":["../../src/tools/select-device.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,YAAY;AAExB,OAAO,EAAE,WAAW,EAAE,qBAAoB;AAG1C,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,OAA0B;IAE1B,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,QAAQ,EAAE,CAAC;iBACR,MAAM,EAAE;iBACR,QAAQ,CAAC,wDAAwD,CAAC;SACtE;KACF,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC;YAE3C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,oBAAoB,IAAI,CAAC,IAAI,EAAE;4BAC/B,aAAa,IAAI,CAAC,QAAQ,EAAE;4BAC5B,OAAO,IAAI,CAAC,SAAS,EAAE;4BACvB,OAAO,IAAI,CAAC,QAAQ,EAAE;yBACvB,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\n\nimport { errorResult } from './shared.js';\nimport type { LazyDeviceBackend } from '../backends/index.js';\n\nexport function registerSelectDeviceTool(\n server: McpServer,\n backend: LazyDeviceBackend,\n): void {\n server.registerTool(\n 'device_select_device',\n {\n title: 'Select Device',\n description:\n 'Select a device to use for this session. Call device_list_devices first to see available devices.',\n inputSchema: {\n deviceId: z\n .string()\n .describe('Device ID to select (UDID for iOS, serial for Android)'),\n },\n },\n async ({ deviceId }) => {\n try {\n backend.selectDevice(deviceId);\n const info = await backend.getDeviceInfo();\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Selected device: ${info.name}`,\n `Platform: ${info.platform}`,\n `OS: ${info.osVersion}`,\n `ID: ${info.deviceId}`,\n ].join('\\n'),\n },\n ],\n };\n } catch (error) {\n return errorResult(error);\n }\n },\n );\n}\n"]}
|
package/dist/utils/exec.cjs
CHANGED
|
@@ -21,17 +21,19 @@ async function exec(command, args, options) {
|
|
|
21
21
|
timeout: timeoutMs,
|
|
22
22
|
maxBuffer: 10 * 1024 * 1024, // 10MB — UI hierarchies can be large
|
|
23
23
|
}, (error, stdout, stderr) => {
|
|
24
|
-
if (error
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
if (error) {
|
|
25
|
+
const errno = error;
|
|
26
|
+
if (errno.code === 'ENOENT' ||
|
|
27
|
+
errno.code === 'EACCES' ||
|
|
28
|
+
errno.code === 'EPERM') {
|
|
29
|
+
reject(new Error(error.message));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
resolve({
|
|
30
34
|
stdout: stdout?.toString() ?? '',
|
|
31
35
|
stderr: stderr?.toString() ?? '',
|
|
32
|
-
exitCode: error
|
|
33
|
-
? 1
|
|
34
|
-
: (child.exitCode ?? 0),
|
|
36
|
+
exitCode: child.exitCode ?? (error ? 1 : 0),
|
|
35
37
|
});
|
|
36
38
|
});
|
|
37
39
|
});
|
|
@@ -47,8 +49,8 @@ async function execStrict(command, args, options) {
|
|
|
47
49
|
}
|
|
48
50
|
async function isCommandAvailable(command) {
|
|
49
51
|
try {
|
|
50
|
-
await exec('which', [command], { timeoutMs: 5000 });
|
|
51
|
-
return
|
|
52
|
+
const result = await exec('which', [command], { timeoutMs: 5000 });
|
|
53
|
+
return result.exitCode === 0;
|
|
52
54
|
}
|
|
53
55
|
catch {
|
|
54
56
|
return false;
|
package/dist/utils/exec.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.cjs","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":";;AAiBA,
|
|
1
|
+
{"version":3,"file":"exec.cjs","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":";;AAiBA,oBAoCC;AAED,gCAcC;AAED,gDAOC;AA9ED,2DAA+D;AAQ/D;;;;;;;;GAQG;AACI,KAAK,UAAU,IAAI,CACxB,OAAe,EACf,IAAc,EACd,OAAkD;IAElD,MAAM,EAAE,SAAS,GAAG,KAAM,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAE7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,IAAA,6BAAQ,EACpB,OAAO,EACP,IAAI,EACJ;YACE,GAAG,WAAW;YACd,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,qCAAqC;SACnE,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,KAA8B,CAAC;gBAC7C,IACE,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACvB,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACvB,KAAK,CAAC,IAAI,KAAK,OAAO,EACtB,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBACjC,OAAO;gBACT,CAAC;YACH,CAAC;YACD,OAAO,CAAC;gBACN,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAChC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC5C,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,IAAc,EACd,OAAkD;IAElD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,mBAAmB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;YAC9C,cAAc,MAAM,CAAC,QAAQ,IAAI;YACjC,WAAW,MAAM,CAAC,MAAM,EAAE,CAC7B,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAK,EAAE,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["import { execFile, ExecFileOptions } from 'node:child_process';\n\nexport type ExecResult = {\n stdout: string;\n stderr: string;\n exitCode: number;\n};\n\n/**\n * Execute a command and return stdout/stderr/exitCode.\n * Rejects only on spawn failure — non-zero exit codes are returned, not thrown.\n *\n * @param command - The command to execute.\n * @param args - Arguments to pass to the command.\n * @param options - Execution options including timeoutMs.\n * @returns The stdout, stderr, and exit code.\n */\nexport async function exec(\n command: string,\n args: string[],\n options?: ExecFileOptions & { timeoutMs?: number },\n): Promise<ExecResult> {\n const { timeoutMs = 30_000, ...execOptions } = options ?? {};\n\n return new Promise((resolve, reject) => {\n const child = execFile(\n command,\n args,\n {\n ...execOptions,\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024, // 10MB — UI hierarchies can be large\n },\n (error, stdout, stderr) => {\n if (error) {\n const errno = error as NodeJS.ErrnoException;\n if (\n errno.code === 'ENOENT' ||\n errno.code === 'EACCES' ||\n errno.code === 'EPERM'\n ) {\n reject(new Error(error.message));\n return;\n }\n }\n resolve({\n stdout: stdout?.toString() ?? '',\n stderr: stderr?.toString() ?? '',\n exitCode: child.exitCode ?? (error ? 1 : 0),\n });\n },\n );\n });\n}\n\nexport async function execStrict(\n command: string,\n args: string[],\n options?: ExecFileOptions & { timeoutMs?: number },\n): Promise<string> {\n const result = await exec(command, args, options);\n if (result.exitCode !== 0) {\n throw new Error(\n `Command failed: ${command} ${args.join(' ')}\\n` +\n `Exit code: ${result.exitCode}\\n` +\n `stderr: ${result.stderr}`,\n );\n }\n return result.stdout;\n}\n\nexport async function isCommandAvailable(command: string): Promise<boolean> {\n try {\n const result = await exec('which', [command], { timeoutMs: 5_000 });\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.cts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAE,2BAA2B;AAE/D,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"exec.d.cts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAE,2BAA2B;AAE/D,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.mts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAE,2BAA2B;AAE/D,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"exec.d.mts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,eAAe,EAAE,2BAA2B;AAE/D,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,UAAU,CAAC,CAgCrB;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjD,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO1E"}
|
package/dist/utils/exec.mjs
CHANGED
|
@@ -16,17 +16,19 @@ export async function exec(command, args, options) {
|
|
|
16
16
|
timeout: timeoutMs,
|
|
17
17
|
maxBuffer: 10 * 1024 * 1024, // 10MB — UI hierarchies can be large
|
|
18
18
|
}, (error, stdout, stderr) => {
|
|
19
|
-
if (error
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
if (error) {
|
|
20
|
+
const errno = error;
|
|
21
|
+
if (errno.code === 'ENOENT' ||
|
|
22
|
+
errno.code === 'EACCES' ||
|
|
23
|
+
errno.code === 'EPERM') {
|
|
24
|
+
reject(new Error(error.message));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
23
27
|
}
|
|
24
28
|
resolve({
|
|
25
29
|
stdout: stdout?.toString() ?? '',
|
|
26
30
|
stderr: stderr?.toString() ?? '',
|
|
27
|
-
exitCode: error
|
|
28
|
-
? 1
|
|
29
|
-
: (child.exitCode ?? 0),
|
|
31
|
+
exitCode: child.exitCode ?? (error ? 1 : 0),
|
|
30
32
|
});
|
|
31
33
|
});
|
|
32
34
|
});
|
|
@@ -42,8 +44,8 @@ export async function execStrict(command, args, options) {
|
|
|
42
44
|
}
|
|
43
45
|
export async function isCommandAvailable(command) {
|
|
44
46
|
try {
|
|
45
|
-
await exec('which', [command], { timeoutMs: 5000 });
|
|
46
|
-
return
|
|
47
|
+
const result = await exec('which', [command], { timeoutMs: 5000 });
|
|
48
|
+
return result.exitCode === 0;
|
|
47
49
|
}
|
|
48
50
|
catch {
|
|
49
51
|
return false;
|
package/dist/utils/exec.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.mjs","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,2BAA2B;AAQ/D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAe,EACf,IAAc,EACd,OAAkD;IAElD,MAAM,EAAE,SAAS,GAAG,KAAM,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAE7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,QAAQ,CACpB,OAAO,EACP,IAAI,EACJ;YACE,GAAG,WAAW;YACd,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,qCAAqC;SACnE,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"exec.mjs","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,2BAA2B;AAQ/D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAe,EACf,IAAc,EACd,OAAkD;IAElD,MAAM,EAAE,SAAS,GAAG,KAAM,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAE7D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,QAAQ,CACpB,OAAO,EACP,IAAI,EACJ;YACE,GAAG,WAAW;YACd,OAAO,EAAE,SAAS;YAClB,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,qCAAqC;SACnE,EACD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,KAAK,GAAG,KAA8B,CAAC;gBAC7C,IACE,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACvB,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACvB,KAAK,CAAC,IAAI,KAAK,OAAO,EACtB,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBACjC,OAAO;gBACT,CAAC;YACH,CAAC;YACD,OAAO,CAAC;gBACN,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAChC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAC5C,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,IAAc,EACd,OAAkD;IAElD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,mBAAmB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI;YAC9C,cAAc,MAAM,CAAC,QAAQ,IAAI;YACjC,WAAW,MAAM,CAAC,MAAM,EAAE,CAC7B,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAK,EAAE,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["import { execFile, ExecFileOptions } from 'node:child_process';\n\nexport type ExecResult = {\n stdout: string;\n stderr: string;\n exitCode: number;\n};\n\n/**\n * Execute a command and return stdout/stderr/exitCode.\n * Rejects only on spawn failure — non-zero exit codes are returned, not thrown.\n *\n * @param command - The command to execute.\n * @param args - Arguments to pass to the command.\n * @param options - Execution options including timeoutMs.\n * @returns The stdout, stderr, and exit code.\n */\nexport async function exec(\n command: string,\n args: string[],\n options?: ExecFileOptions & { timeoutMs?: number },\n): Promise<ExecResult> {\n const { timeoutMs = 30_000, ...execOptions } = options ?? {};\n\n return new Promise((resolve, reject) => {\n const child = execFile(\n command,\n args,\n {\n ...execOptions,\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024, // 10MB — UI hierarchies can be large\n },\n (error, stdout, stderr) => {\n if (error) {\n const errno = error as NodeJS.ErrnoException;\n if (\n errno.code === 'ENOENT' ||\n errno.code === 'EACCES' ||\n errno.code === 'EPERM'\n ) {\n reject(new Error(error.message));\n return;\n }\n }\n resolve({\n stdout: stdout?.toString() ?? '',\n stderr: stderr?.toString() ?? '',\n exitCode: child.exitCode ?? (error ? 1 : 0),\n });\n },\n );\n });\n}\n\nexport async function execStrict(\n command: string,\n args: string[],\n options?: ExecFileOptions & { timeoutMs?: number },\n): Promise<string> {\n const result = await exec(command, args, options);\n if (result.exitCode !== 0) {\n throw new Error(\n `Command failed: ${command} ${args.join(' ')}\\n` +\n `Exit code: ${result.exitCode}\\n` +\n `stderr: ${result.stderr}`,\n );\n }\n return result.stdout;\n}\n\nexport async function isCommandAvailable(command: string): Promise<boolean> {\n try {\n const result = await exec('which', [command], { timeoutMs: 5_000 });\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n"]}
|