@tmhs/mobile-mcp 0.11.0 → 1.0.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/LICENSE +43 -0
- package/README.md +92 -0
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/checkNativeCompat.d.ts +3 -0
- package/dist/tools/checkNativeCompat.d.ts.map +1 -0
- package/dist/tools/checkNativeCompat.js +255 -0
- package/dist/tools/checkNativeCompat.js.map +1 -0
- package/dist/tools/createNativeModule.d.ts +3 -0
- package/dist/tools/createNativeModule.d.ts.map +1 -0
- package/dist/tools/createNativeModule.js +291 -0
- package/dist/tools/createNativeModule.js.map +1 -0
- package/dist/tools/upgradeSDK.d.ts +3 -0
- package/dist/tools/upgradeSDK.d.ts.map +1 -0
- package/dist/tools/upgradeSDK.js +170 -0
- package/dist/tools/upgradeSDK.js.map +1 -0
- package/package.json +13 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TM Hospitality Strategies
|
|
4
|
+
|
|
5
|
+
This work is licensed under the Creative Commons
|
|
6
|
+
Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
|
7
|
+
|
|
8
|
+
You are free to:
|
|
9
|
+
|
|
10
|
+
Share - copy and redistribute the material in any medium or format.
|
|
11
|
+
|
|
12
|
+
The licensor cannot revoke these freedoms as long as you follow the
|
|
13
|
+
license terms.
|
|
14
|
+
|
|
15
|
+
Under the following terms:
|
|
16
|
+
|
|
17
|
+
Attribution - You must give appropriate credit, provide a link to the
|
|
18
|
+
license, and indicate if changes were made. You may do so in any
|
|
19
|
+
reasonable manner, but not in any way that suggests the licensor endorses
|
|
20
|
+
you or your use.
|
|
21
|
+
|
|
22
|
+
NonCommercial - You may not use the material for commercial purposes.
|
|
23
|
+
|
|
24
|
+
NoDerivatives - If you remix, transform, or build upon the material, you
|
|
25
|
+
may not distribute the modified material.
|
|
26
|
+
|
|
27
|
+
No additional restrictions - You may not apply legal terms or
|
|
28
|
+
technological measures that legally restrict others from doing anything
|
|
29
|
+
the license permits.
|
|
30
|
+
|
|
31
|
+
Notices:
|
|
32
|
+
|
|
33
|
+
You do not have to comply with the license for elements of the material
|
|
34
|
+
in the public domain or where your use is permitted by an applicable
|
|
35
|
+
exception or limitation.
|
|
36
|
+
|
|
37
|
+
No warranties are given. The license may not give you all of the
|
|
38
|
+
permissions necessary for your intended use. For example, other rights
|
|
39
|
+
such as publicity, privacy, or moral rights may limit how you use the
|
|
40
|
+
material.
|
|
41
|
+
|
|
42
|
+
For the full license text, see:
|
|
43
|
+
https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @tmhs/mobile-mcp
|
|
2
|
+
|
|
3
|
+
MCP server for mobile app development. **36 tools** that let AI agents scaffold, build, test, and ship React Native/Expo and Flutter apps.
|
|
4
|
+
|
|
5
|
+
Part of [Mobile App Developer Tools](https://github.com/TMHSDigital/Mobile-App-Developer-Tools), a Cursor plugin with 43 skills, 12 rules, and this companion MCP server.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @tmhs/mobile-mcp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires **Node 20+**.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
Add to your MCP client config (e.g. Cursor, Claude Desktop):
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"mobile-mcp": {
|
|
23
|
+
"command": "npx",
|
|
24
|
+
"args": ["-y", "@tmhs/mobile-mcp"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or run directly:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx @tmhs/mobile-mcp
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The server communicates over **stdio** using the [Model Context Protocol](https://modelcontextprotocol.io/).
|
|
37
|
+
|
|
38
|
+
## Tools (36)
|
|
39
|
+
|
|
40
|
+
All tools use the `mobile_` prefix.
|
|
41
|
+
|
|
42
|
+
| Tool | Description |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `mobile_checkDevEnvironment` | Detect installed tools and SDKs (Node, Expo CLI, Watchman, Xcode, Android Studio, JDK) |
|
|
45
|
+
| `mobile_scaffoldProject` | Generate a new Expo project from a template with chosen options |
|
|
46
|
+
| `mobile_runOnDevice` | Start dev server and provide instructions for connecting a physical device |
|
|
47
|
+
| `mobile_generateScreen` | Create a new Expo Router screen file with navigation wiring |
|
|
48
|
+
| `mobile_generateComponent` | Create a React Native component with typed props, StyleSheet, and optional tests |
|
|
49
|
+
| `mobile_installDependency` | Install a package via `npx expo install` with native module detection |
|
|
50
|
+
| `mobile_addPermission` | Add platform permission with iOS rationale string to app.json |
|
|
51
|
+
| `mobile_integrateAI` | Scaffold AI API client with provider config, error handling, and TypeScript types |
|
|
52
|
+
| `mobile_checkBuildHealth` | Validate app.json, check dependencies, verify TypeScript, detect native module issues |
|
|
53
|
+
| `mobile_addPushNotifications` | Add expo-notifications plugin, create notification handler, configure Android channel |
|
|
54
|
+
| `mobile_configureDeepLinks` | Set scheme, add intent filters, iOS associated domains, generate AASA template |
|
|
55
|
+
| `mobile_resetDevEnvironment` | Clear Metro cache, .expo dir, node_modules cache, optionally Pods and Gradle |
|
|
56
|
+
| `mobile_buildForStore` | Create a production build for app store submission via EAS Build |
|
|
57
|
+
| `mobile_validateStoreMetadata` | Check app.json for required store listing fields |
|
|
58
|
+
| `mobile_submitToAppStore` | Submit latest iOS build to App Store Connect via EAS Submit |
|
|
59
|
+
| `mobile_submitToPlayStore` | Submit latest Android build to Google Play Console via EAS Submit |
|
|
60
|
+
| `mobile_generateScreenshots` | Generate screenshot capture script and list required store dimensions |
|
|
61
|
+
| `mobile_analyzeBundle` | Analyze bundle for large dependencies, heavy assets, and optimization opportunities |
|
|
62
|
+
| `mobile_configureOTA` | Configure EAS Update for over-the-air JavaScript updates |
|
|
63
|
+
| `mobile_runTests` | Execute test suite (Jest or flutter test) and return structured results |
|
|
64
|
+
| `mobile_setupCI` | Generate GitHub Actions CI workflow for build, test, and EAS Build |
|
|
65
|
+
| `mobile_generateTestFile` | Scaffold a test file for an existing component or module |
|
|
66
|
+
| `mobile_setupI18n` | Initialize i18n config with locale files and translation structure |
|
|
67
|
+
| `mobile_addMap` | Add map view with provider config, permissions, and marker support |
|
|
68
|
+
| `mobile_generateForm` | Scaffold a validated form with typed fields and error handling |
|
|
69
|
+
| `mobile_setupRealtime` | Add real-time client with connection management and typed events |
|
|
70
|
+
| `mobile_securityAudit` | Scan project for common mobile security anti-patterns |
|
|
71
|
+
| `mobile_profilePerformance` | Analyze project for performance anti-patterns and flag jank/memory issues |
|
|
72
|
+
| `mobile_checkOfflineReady` | Validate offline-first setup: local DB, network listener, query cache |
|
|
73
|
+
| `mobile_setupMonitoring` | Configure APM with Sentry Performance or Datadog RUM |
|
|
74
|
+
| `mobile_setupTheming` | Initialize design token system with light/dark themes and semantic colors |
|
|
75
|
+
| `mobile_auditAccessibility` | Scan project for a11y violations: labels, touch targets, alt text |
|
|
76
|
+
| `mobile_setupFeatureFlags` | Add typed feature flag provider with default values and remote sync |
|
|
77
|
+
| `mobile_createNativeModule` | Scaffold an Expo Module or Flutter plugin with Swift/Kotlin stubs |
|
|
78
|
+
| `mobile_upgradeSDK` | Generate SDK upgrade plan with dependency fixes and breaking changes |
|
|
79
|
+
| `mobile_checkNativeCompat` | Audit packages for New Architecture support and deprecated dependencies |
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/TMHSDigital/Mobile-App-Developer-Tools.git
|
|
85
|
+
cd Mobile-App-Developer-Tools/mcp-server
|
|
86
|
+
npm install
|
|
87
|
+
npm run build
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
[CC-BY-NC-ND-4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/) - Copyright 2026 TM Hospitality Strategies.
|
package/dist/index.js
CHANGED
|
@@ -34,9 +34,12 @@ import { register as registerSetupMonitoring } from "./tools/setupMonitoring.js"
|
|
|
34
34
|
import { register as registerSetupTheming } from "./tools/setupTheming.js";
|
|
35
35
|
import { register as registerAuditAccessibility } from "./tools/auditAccessibility.js";
|
|
36
36
|
import { register as registerSetupFeatureFlags } from "./tools/setupFeatureFlags.js";
|
|
37
|
+
import { register as registerCreateNativeModule } from "./tools/createNativeModule.js";
|
|
38
|
+
import { register as registerUpgradeSDK } from "./tools/upgradeSDK.js";
|
|
39
|
+
import { register as registerCheckNativeCompat } from "./tools/checkNativeCompat.js";
|
|
37
40
|
const server = new McpServer({
|
|
38
41
|
name: "mobile-mcp",
|
|
39
|
-
version: "0.
|
|
42
|
+
version: "1.0.0",
|
|
40
43
|
});
|
|
41
44
|
registerCheckDevEnvironment(server);
|
|
42
45
|
registerScaffoldProject(server);
|
|
@@ -71,6 +74,9 @@ registerSetupMonitoring(server);
|
|
|
71
74
|
registerSetupTheming(server);
|
|
72
75
|
registerAuditAccessibility(server);
|
|
73
76
|
registerSetupFeatureFlags(server);
|
|
77
|
+
registerCreateNativeModule(server);
|
|
78
|
+
registerUpgradeSDK(server);
|
|
79
|
+
registerCheckNativeCompat(server);
|
|
74
80
|
async function main() {
|
|
75
81
|
const transport = new StdioServerTransport();
|
|
76
82
|
await server.connect(transport);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,QAAQ,IAAI,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,QAAQ,IAAI,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AAErF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkNativeCompat.d.ts","sourceRoot":"","sources":["../../src/tools/checkNativeCompat.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuPzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0ChD"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
project_path: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
10
|
+
framework: z
|
|
11
|
+
.enum(["expo", "flutter"])
|
|
12
|
+
.optional()
|
|
13
|
+
.default("expo")
|
|
14
|
+
.describe("Framework (default: expo)."),
|
|
15
|
+
};
|
|
16
|
+
const KNOWN_BRIDGE_ONLY_PACKAGES = new Set([
|
|
17
|
+
"react-native-camera",
|
|
18
|
+
"react-native-image-picker",
|
|
19
|
+
"react-native-video",
|
|
20
|
+
"react-native-fbsdk",
|
|
21
|
+
"react-native-firebase",
|
|
22
|
+
"react-native-push-notification",
|
|
23
|
+
"react-native-sound",
|
|
24
|
+
"react-native-background-geolocation",
|
|
25
|
+
"@react-native-community/netinfo",
|
|
26
|
+
"react-native-bluetooth-serial",
|
|
27
|
+
]);
|
|
28
|
+
const DEPRECATED_PACKAGES = {
|
|
29
|
+
"react-native-camera": "expo-camera or react-native-vision-camera",
|
|
30
|
+
"react-native-image-picker": "expo-image-picker or react-native-image-picker@5+",
|
|
31
|
+
"react-native-fbsdk": "@react-native-fbsdk-next/fbsdk-next",
|
|
32
|
+
"react-native-push-notification": "expo-notifications or @notifee/react-native",
|
|
33
|
+
"react-native-sound": "expo-av or react-native-track-player",
|
|
34
|
+
"@react-native-community/netinfo": "@react-native-community/netinfo@11+ (New Arch support)",
|
|
35
|
+
"react-native-navigation": "expo-router or @react-navigation/native@7+",
|
|
36
|
+
"react-native-vector-icons": "@expo/vector-icons (Expo) or react-native-vector-icons@10+",
|
|
37
|
+
};
|
|
38
|
+
const NEW_ARCH_READY_PACKAGES = new Set([
|
|
39
|
+
"react-native-reanimated",
|
|
40
|
+
"react-native-gesture-handler",
|
|
41
|
+
"react-native-screens",
|
|
42
|
+
"react-native-safe-area-context",
|
|
43
|
+
"@react-native-async-storage/async-storage",
|
|
44
|
+
"react-native-svg",
|
|
45
|
+
"react-native-webview",
|
|
46
|
+
"react-native-maps",
|
|
47
|
+
"@react-native-community/datetimepicker",
|
|
48
|
+
"react-native-pager-view",
|
|
49
|
+
"react-native-vision-camera",
|
|
50
|
+
"expo-camera",
|
|
51
|
+
"expo-location",
|
|
52
|
+
"expo-notifications",
|
|
53
|
+
"expo-file-system",
|
|
54
|
+
"expo-image-picker",
|
|
55
|
+
"expo-av",
|
|
56
|
+
"expo-haptics",
|
|
57
|
+
"expo-secure-store",
|
|
58
|
+
"expo-sqlite",
|
|
59
|
+
]);
|
|
60
|
+
function auditExpoProject(root) {
|
|
61
|
+
const issues = [];
|
|
62
|
+
const pkgPath = join(root, "package.json");
|
|
63
|
+
if (!existsSync(pkgPath)) {
|
|
64
|
+
issues.push({
|
|
65
|
+
severity: "critical",
|
|
66
|
+
package_name: "package.json",
|
|
67
|
+
message: "No package.json found at project root.",
|
|
68
|
+
recommendation: "Ensure you are pointing to the correct project directory.",
|
|
69
|
+
});
|
|
70
|
+
return issues;
|
|
71
|
+
}
|
|
72
|
+
let pkg;
|
|
73
|
+
try {
|
|
74
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
issues.push({
|
|
78
|
+
severity: "critical",
|
|
79
|
+
package_name: "package.json",
|
|
80
|
+
message: "Failed to parse package.json.",
|
|
81
|
+
recommendation: "Fix JSON syntax errors in package.json.",
|
|
82
|
+
});
|
|
83
|
+
return issues;
|
|
84
|
+
}
|
|
85
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
86
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
87
|
+
if (DEPRECATED_PACKAGES[name]) {
|
|
88
|
+
issues.push({
|
|
89
|
+
severity: "critical",
|
|
90
|
+
package_name: name,
|
|
91
|
+
message: `Deprecated package. Use ${DEPRECATED_PACKAGES[name]} instead.`,
|
|
92
|
+
recommendation: `Replace ${name} with ${DEPRECATED_PACKAGES[name]} for New Architecture support.`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else if (KNOWN_BRIDGE_ONLY_PACKAGES.has(name)) {
|
|
96
|
+
issues.push({
|
|
97
|
+
severity: "warning",
|
|
98
|
+
package_name: name,
|
|
99
|
+
message: "This package may not support the New Architecture (Fabric/TurboModules).",
|
|
100
|
+
recommendation: "Check the package README for New Architecture support or find an alternative.",
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
if (name.startsWith("react-native-") && !name.startsWith("@") && !NEW_ARCH_READY_PACKAGES.has(name)) {
|
|
104
|
+
const isKnownIssue = DEPRECATED_PACKAGES[name] || KNOWN_BRIDGE_ONLY_PACKAGES.has(name);
|
|
105
|
+
if (!isKnownIssue) {
|
|
106
|
+
issues.push({
|
|
107
|
+
severity: "info",
|
|
108
|
+
package_name: name,
|
|
109
|
+
message: "Unverified New Architecture compatibility. Check package docs.",
|
|
110
|
+
recommendation: `Verify ${name} supports Fabric/TurboModules before enabling New Architecture.`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const appJsonPath = join(root, "app.json");
|
|
116
|
+
if (existsSync(appJsonPath)) {
|
|
117
|
+
try {
|
|
118
|
+
const appJson = JSON.parse(readFileSync(appJsonPath, "utf-8"));
|
|
119
|
+
const newArchEnabled = appJson?.expo?.newArchEnabled;
|
|
120
|
+
if (newArchEnabled === undefined) {
|
|
121
|
+
issues.push({
|
|
122
|
+
severity: "info",
|
|
123
|
+
package_name: "app.json",
|
|
124
|
+
message: 'New Architecture not explicitly configured. Set "newArchEnabled" in app.json.',
|
|
125
|
+
recommendation: 'Add "newArchEnabled": true under expo key to enable Fabric and TurboModules.',
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch { /* skip parse errors */ }
|
|
130
|
+
}
|
|
131
|
+
if (issues.length === 0) {
|
|
132
|
+
issues.push({
|
|
133
|
+
severity: "info",
|
|
134
|
+
package_name: "project",
|
|
135
|
+
message: "No known compatibility issues detected. All checked packages appear New Architecture ready.",
|
|
136
|
+
recommendation: "Enable New Architecture in app.json and test thoroughly on both platforms.",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return issues;
|
|
140
|
+
}
|
|
141
|
+
function auditFlutterProject(root) {
|
|
142
|
+
const issues = [];
|
|
143
|
+
const pubspecPath = join(root, "pubspec.yaml");
|
|
144
|
+
if (!existsSync(pubspecPath)) {
|
|
145
|
+
issues.push({
|
|
146
|
+
severity: "critical",
|
|
147
|
+
package_name: "pubspec.yaml",
|
|
148
|
+
message: "No pubspec.yaml found at project root.",
|
|
149
|
+
recommendation: "Ensure you are pointing to the correct Flutter project directory.",
|
|
150
|
+
});
|
|
151
|
+
return issues;
|
|
152
|
+
}
|
|
153
|
+
let content;
|
|
154
|
+
try {
|
|
155
|
+
content = readFileSync(pubspecPath, "utf-8");
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
issues.push({
|
|
159
|
+
severity: "critical",
|
|
160
|
+
package_name: "pubspec.yaml",
|
|
161
|
+
message: "Failed to read pubspec.yaml.",
|
|
162
|
+
recommendation: "Check file permissions.",
|
|
163
|
+
});
|
|
164
|
+
return issues;
|
|
165
|
+
}
|
|
166
|
+
const sdkMatch = content.match(/sdk:\s*['"]?>=?\s*([\d.]+)/);
|
|
167
|
+
if (sdkMatch) {
|
|
168
|
+
const minSdk = sdkMatch[1];
|
|
169
|
+
const parts = minSdk.split(".").map(Number);
|
|
170
|
+
if (parts[0] < 3) {
|
|
171
|
+
issues.push({
|
|
172
|
+
severity: "critical",
|
|
173
|
+
package_name: "dart-sdk",
|
|
174
|
+
message: `Dart SDK constraint starts at ${minSdk}. Dart 3+ is required for modern Flutter.`,
|
|
175
|
+
recommendation: "Update sdk constraint to >=3.0.0 in pubspec.yaml.",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const androidDir = join(root, "android");
|
|
180
|
+
if (existsSync(androidDir)) {
|
|
181
|
+
const buildGradlePath = join(androidDir, "app", "build.gradle");
|
|
182
|
+
if (existsSync(buildGradlePath)) {
|
|
183
|
+
try {
|
|
184
|
+
const gradle = readFileSync(buildGradlePath, "utf-8");
|
|
185
|
+
const minSdkMatch = gradle.match(/minSdkVersion\s+(\d+)/);
|
|
186
|
+
if (minSdkMatch && parseInt(minSdkMatch[1], 10) < 21) {
|
|
187
|
+
issues.push({
|
|
188
|
+
severity: "warning",
|
|
189
|
+
package_name: "android/app/build.gradle",
|
|
190
|
+
message: `minSdkVersion ${minSdkMatch[1]} is below 21. Most modern packages require 21+.`,
|
|
191
|
+
recommendation: "Update minSdkVersion to at least 21 (or 23 for best compatibility).",
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch { /* skip */ }
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const deprecatedFlutterPackages = {
|
|
199
|
+
"flutter_webview_plugin": "webview_flutter",
|
|
200
|
+
"flutter_calendar_carousel": "table_calendar",
|
|
201
|
+
"flutter_slidable": "flutter_slidable@3+ (check API migration)",
|
|
202
|
+
"cached_network_image": "cached_network_image@3+ (null safety)",
|
|
203
|
+
"sqflite": "drift or sqflite@2+ (null safety)",
|
|
204
|
+
};
|
|
205
|
+
for (const [name, replacement] of Object.entries(deprecatedFlutterPackages)) {
|
|
206
|
+
if (content.includes(name + ":")) {
|
|
207
|
+
issues.push({
|
|
208
|
+
severity: "warning",
|
|
209
|
+
package_name: name,
|
|
210
|
+
message: `Consider upgrading or replacing with ${replacement}.`,
|
|
211
|
+
recommendation: `Migrate from ${name} to ${replacement} for better compatibility.`,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (issues.length === 0) {
|
|
216
|
+
issues.push({
|
|
217
|
+
severity: "info",
|
|
218
|
+
package_name: "project",
|
|
219
|
+
message: "No known compatibility issues detected.",
|
|
220
|
+
recommendation: "Run flutter analyze and flutter test to verify full compatibility.",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return issues;
|
|
224
|
+
}
|
|
225
|
+
export function register(server) {
|
|
226
|
+
server.tool("mobile_checkNativeCompat", "Audit installed packages for New Architecture (Fabric/TurboModules) support. Flag bridge-only dependencies, deprecated native APIs, and packages without JSI support.", inputSchema, async (args) => {
|
|
227
|
+
try {
|
|
228
|
+
const root = args.project_path || process.cwd();
|
|
229
|
+
if (!existsSync(root)) {
|
|
230
|
+
return errorResponse(new Error(`Project path does not exist: ${root}`));
|
|
231
|
+
}
|
|
232
|
+
const issues = args.framework === "flutter"
|
|
233
|
+
? auditFlutterProject(root)
|
|
234
|
+
: auditExpoProject(root);
|
|
235
|
+
const criticalCount = issues.filter((i) => i.severity === "critical").length;
|
|
236
|
+
const warningCount = issues.filter((i) => i.severity === "warning").length;
|
|
237
|
+
const infoCount = issues.filter((i) => i.severity === "info").length;
|
|
238
|
+
return textResponse(JSON.stringify({
|
|
239
|
+
success: true,
|
|
240
|
+
framework: args.framework,
|
|
241
|
+
summary: {
|
|
242
|
+
total_issues: issues.length,
|
|
243
|
+
critical: criticalCount,
|
|
244
|
+
warnings: warningCount,
|
|
245
|
+
info: infoCount,
|
|
246
|
+
},
|
|
247
|
+
issues,
|
|
248
|
+
}, null, 2));
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
return errorResponse(err);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=checkNativeCompat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkNativeCompat.js","sourceRoot":"","sources":["../../src/tools/checkNativeCompat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNativeModule.d.ts","sourceRoot":"","sources":["../../src/tools/createNativeModule.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkOzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4FhD"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
5
|
+
const inputSchema = {
|
|
6
|
+
project_path: z
|
|
7
|
+
.string()
|
|
8
|
+
.optional()
|
|
9
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
10
|
+
framework: z
|
|
11
|
+
.enum(["expo", "flutter"])
|
|
12
|
+
.optional()
|
|
13
|
+
.default("expo")
|
|
14
|
+
.describe("Framework (default: expo)."),
|
|
15
|
+
module_name: z
|
|
16
|
+
.string()
|
|
17
|
+
.describe("Name of the native module (PascalCase, e.g. 'Haptics')."),
|
|
18
|
+
output_directory: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.default("modules")
|
|
22
|
+
.describe("Output directory relative to project root (default: modules)."),
|
|
23
|
+
};
|
|
24
|
+
function toPascalCase(name) {
|
|
25
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
26
|
+
}
|
|
27
|
+
function toKebabCase(name) {
|
|
28
|
+
return name.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
29
|
+
}
|
|
30
|
+
function generateExpoModuleIndex(name) {
|
|
31
|
+
return `import ${name}Module from "./${name}Module";
|
|
32
|
+
|
|
33
|
+
export function hello(): string {
|
|
34
|
+
return ${name}Module.hello();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function multiply(a: number, b: number): number {
|
|
38
|
+
return ${name}Module.multiply(a, b);
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
function generateExpoModuleNative(name) {
|
|
43
|
+
return `import { requireNativeModule } from "expo-modules-core";
|
|
44
|
+
|
|
45
|
+
const ${name}Module = requireNativeModule("${name}");
|
|
46
|
+
|
|
47
|
+
export default ${name}Module;
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
function generateExpoModuleConfig(name) {
|
|
51
|
+
return `{
|
|
52
|
+
"name": "${name}",
|
|
53
|
+
"platforms": ["ios", "android"],
|
|
54
|
+
"ios": {
|
|
55
|
+
"modules": ["${name}Module"]
|
|
56
|
+
},
|
|
57
|
+
"android": {
|
|
58
|
+
"modules": ["${name}Module"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
function generateSwiftModule(name) {
|
|
64
|
+
return `import ExpoModulesCore
|
|
65
|
+
|
|
66
|
+
public class ${name}Module: Module {
|
|
67
|
+
public func definition() -> ModuleDefinition {
|
|
68
|
+
Name("${name}")
|
|
69
|
+
|
|
70
|
+
Function("hello") {
|
|
71
|
+
return "Hello from ${name} native module!"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Function("multiply") { (a: Double, b: Double) -> Double in
|
|
75
|
+
return a * b
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
function generateKotlinModule(name) {
|
|
82
|
+
const pkg = `expo.modules.${name.toLowerCase()}`;
|
|
83
|
+
return `package ${pkg}
|
|
84
|
+
|
|
85
|
+
import expo.modules.kotlin.modules.Module
|
|
86
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
87
|
+
|
|
88
|
+
class ${name}Module : Module() {
|
|
89
|
+
override fun definition() = ModuleDefinition {
|
|
90
|
+
Name("${name}")
|
|
91
|
+
|
|
92
|
+
Function("hello") {
|
|
93
|
+
"Hello from ${name} native module!"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Function("multiply") { a: Double, b: Double ->
|
|
97
|
+
a * b
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
function generateFlutterPluginDart(name) {
|
|
104
|
+
const snakeName = toKebabCase(name).replace(/-/g, "_");
|
|
105
|
+
return `import 'dart:async';
|
|
106
|
+
import 'package:flutter/services.dart';
|
|
107
|
+
|
|
108
|
+
class ${name} {
|
|
109
|
+
static const MethodChannel _channel = MethodChannel('${snakeName}');
|
|
110
|
+
|
|
111
|
+
static Future<String> hello() async {
|
|
112
|
+
final result = await _channel.invokeMethod<String>('hello');
|
|
113
|
+
return result ?? '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static Future<double> multiply(double a, double b) async {
|
|
117
|
+
final result = await _channel.invokeMethod<double>('multiply', {
|
|
118
|
+
'a': a,
|
|
119
|
+
'b': b,
|
|
120
|
+
});
|
|
121
|
+
return result ?? 0;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
function generateFlutterPlatformInterface(name) {
|
|
127
|
+
const snakeName = toKebabCase(name).replace(/-/g, "_");
|
|
128
|
+
return `import 'package:flutter/services.dart';
|
|
129
|
+
|
|
130
|
+
class ${name}Platform {
|
|
131
|
+
static const MethodChannel _channel = MethodChannel('${snakeName}');
|
|
132
|
+
|
|
133
|
+
Future<String> hello() async {
|
|
134
|
+
final result = await _channel.invokeMethod<String>('hello');
|
|
135
|
+
return result ?? '';
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
Future<double> multiply(double a, double b) async {
|
|
139
|
+
final result = await _channel.invokeMethod<double>('multiply', {
|
|
140
|
+
'a': a,
|
|
141
|
+
'b': b,
|
|
142
|
+
});
|
|
143
|
+
return result ?? 0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
function generateSwiftPlugin(name) {
|
|
149
|
+
const snakeName = toKebabCase(name).replace(/-/g, "_");
|
|
150
|
+
return `import Flutter
|
|
151
|
+
import UIKit
|
|
152
|
+
|
|
153
|
+
public class ${name}Plugin: NSObject, FlutterPlugin {
|
|
154
|
+
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
155
|
+
let channel = FlutterMethodChannel(
|
|
156
|
+
name: "${snakeName}",
|
|
157
|
+
binaryMessenger: registrar.messenger()
|
|
158
|
+
)
|
|
159
|
+
let instance = ${name}Plugin()
|
|
160
|
+
registrar.addMethodCallDelegate(instance, channel: channel)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
164
|
+
switch call.method {
|
|
165
|
+
case "hello":
|
|
166
|
+
result("Hello from ${name} native module!")
|
|
167
|
+
case "multiply":
|
|
168
|
+
guard let args = call.arguments as? [String: Any],
|
|
169
|
+
let a = args["a"] as? Double,
|
|
170
|
+
let b = args["b"] as? Double else {
|
|
171
|
+
result(FlutterError(code: "INVALID_ARGS", message: "Expected a and b", details: nil))
|
|
172
|
+
return
|
|
173
|
+
}
|
|
174
|
+
result(a * b)
|
|
175
|
+
default:
|
|
176
|
+
result(FlutterMethodNotImplemented)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
function generateKotlinPlugin(name) {
|
|
183
|
+
const snakeName = toKebabCase(name).replace(/-/g, "_");
|
|
184
|
+
return `package com.example.${snakeName}
|
|
185
|
+
|
|
186
|
+
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
|
187
|
+
import io.flutter.plugin.common.MethodCall
|
|
188
|
+
import io.flutter.plugin.common.MethodChannel
|
|
189
|
+
|
|
190
|
+
class ${name}Plugin : FlutterPlugin, MethodChannel.MethodCallHandler {
|
|
191
|
+
private lateinit var channel: MethodChannel
|
|
192
|
+
|
|
193
|
+
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
|
194
|
+
channel = MethodChannel(binding.binaryMessenger, "${snakeName}")
|
|
195
|
+
channel.setMethodCallHandler(this)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
|
199
|
+
when (call.method) {
|
|
200
|
+
"hello" -> result.success("Hello from ${name} native module!")
|
|
201
|
+
"multiply" -> {
|
|
202
|
+
val a = call.argument<Double>("a") ?: return result.error("INVALID_ARGS", "Missing a", null)
|
|
203
|
+
val b = call.argument<Double>("b") ?: return result.error("INVALID_ARGS", "Missing b", null)
|
|
204
|
+
result.success(a * b)
|
|
205
|
+
}
|
|
206
|
+
else -> result.notImplemented()
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
|
211
|
+
channel.setMethodCallHandler(null)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
216
|
+
export function register(server) {
|
|
217
|
+
server.tool("mobile_createNativeModule", "Scaffold an Expo Module or Flutter platform plugin with Swift/Kotlin stubs and TypeScript/Dart bindings.", inputSchema, async (args) => {
|
|
218
|
+
try {
|
|
219
|
+
const root = args.project_path || process.cwd();
|
|
220
|
+
const name = toPascalCase(args.module_name);
|
|
221
|
+
const kebab = toKebabCase(name);
|
|
222
|
+
const isFlutter = args.framework === "flutter";
|
|
223
|
+
const moduleDir = join(root, args.output_directory, kebab);
|
|
224
|
+
if (existsSync(moduleDir)) {
|
|
225
|
+
return errorResponse(new Error(`Module directory already exists: ${moduleDir}`));
|
|
226
|
+
}
|
|
227
|
+
const created = [];
|
|
228
|
+
if (isFlutter) {
|
|
229
|
+
const libDir = join(moduleDir, "lib");
|
|
230
|
+
const iosDir = join(moduleDir, "ios", "Classes");
|
|
231
|
+
const androidDir = join(moduleDir, "android", "src", "main", "kotlin", "com", "example", kebab.replace(/-/g, "_"));
|
|
232
|
+
mkdirSync(libDir, { recursive: true });
|
|
233
|
+
mkdirSync(iosDir, { recursive: true });
|
|
234
|
+
mkdirSync(androidDir, { recursive: true });
|
|
235
|
+
const files = [
|
|
236
|
+
{ path: join(libDir, `${kebab.replace(/-/g, "_")}.dart`), content: generateFlutterPluginDart(name) },
|
|
237
|
+
{ path: join(libDir, `${kebab.replace(/-/g, "_")}_platform.dart`), content: generateFlutterPlatformInterface(name) },
|
|
238
|
+
{ path: join(iosDir, `${name}Plugin.swift`), content: generateSwiftPlugin(name) },
|
|
239
|
+
{ path: join(androidDir, `${name}Plugin.kt`), content: generateKotlinPlugin(name) },
|
|
240
|
+
];
|
|
241
|
+
for (const f of files) {
|
|
242
|
+
writeFileSync(f.path, f.content, "utf-8");
|
|
243
|
+
created.push(f.path);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
const srcDir = join(moduleDir, "src");
|
|
248
|
+
const iosDir = join(moduleDir, "ios");
|
|
249
|
+
const androidDir = join(moduleDir, "android", "src", "main", "java", "expo", "modules", name.toLowerCase());
|
|
250
|
+
mkdirSync(srcDir, { recursive: true });
|
|
251
|
+
mkdirSync(iosDir, { recursive: true });
|
|
252
|
+
mkdirSync(androidDir, { recursive: true });
|
|
253
|
+
const files = [
|
|
254
|
+
{ path: join(srcDir, "index.ts"), content: generateExpoModuleIndex(name) },
|
|
255
|
+
{ path: join(srcDir, `${name}Module.ts`), content: generateExpoModuleNative(name) },
|
|
256
|
+
{ path: join(moduleDir, "expo-module.config.json"), content: generateExpoModuleConfig(name) },
|
|
257
|
+
{ path: join(iosDir, `${name}Module.swift`), content: generateSwiftModule(name) },
|
|
258
|
+
{ path: join(androidDir, `${name}Module.kt`), content: generateKotlinModule(name) },
|
|
259
|
+
];
|
|
260
|
+
for (const f of files) {
|
|
261
|
+
writeFileSync(f.path, f.content, "utf-8");
|
|
262
|
+
created.push(f.path);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const nextSteps = isFlutter
|
|
266
|
+
? [
|
|
267
|
+
`Add the plugin to pubspec.yaml as a path dependency: path: ${args.output_directory}/${kebab}`,
|
|
268
|
+
"Run flutter pub get",
|
|
269
|
+
"Import and call the module from Dart code",
|
|
270
|
+
"Customize Swift and Kotlin implementations for your use case",
|
|
271
|
+
]
|
|
272
|
+
: [
|
|
273
|
+
`Import from "${args.output_directory}/${kebab}/src" in your app code`,
|
|
274
|
+
"Run npx expo prebuild to generate native projects",
|
|
275
|
+
"Customize the Swift and Kotlin Module definitions",
|
|
276
|
+
"Add new native functions following the existing pattern",
|
|
277
|
+
];
|
|
278
|
+
return textResponse(JSON.stringify({
|
|
279
|
+
success: true,
|
|
280
|
+
framework: args.framework,
|
|
281
|
+
module_name: name,
|
|
282
|
+
files_created: created,
|
|
283
|
+
next_steps: nextSteps,
|
|
284
|
+
}, null, 2));
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
return errorResponse(err);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=createNativeModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNativeModule.js","sourceRoot":"","sources":["../../src/tools/createNativeModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgradeSDK.d.ts","sourceRoot":"","sources":["../../src/tools/upgradeSDK.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4JzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BhD"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
import { textResponse, errorResponse } from "../types.js";
|
|
6
|
+
const inputSchema = {
|
|
7
|
+
project_path: z
|
|
8
|
+
.string()
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Absolute path to the project root. Defaults to cwd."),
|
|
11
|
+
framework: z
|
|
12
|
+
.enum(["expo", "flutter"])
|
|
13
|
+
.optional()
|
|
14
|
+
.default("expo")
|
|
15
|
+
.describe("Framework (default: expo)."),
|
|
16
|
+
target_version: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Target SDK version to upgrade to. If omitted, detects latest."),
|
|
20
|
+
};
|
|
21
|
+
function detectExpoVersion(root) {
|
|
22
|
+
const pkgPath = join(root, "package.json");
|
|
23
|
+
if (!existsSync(pkgPath))
|
|
24
|
+
return null;
|
|
25
|
+
try {
|
|
26
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
27
|
+
const expoVersion = pkg.dependencies?.expo || pkg.devDependencies?.expo;
|
|
28
|
+
if (!expoVersion)
|
|
29
|
+
return null;
|
|
30
|
+
return expoVersion.replace(/[\^~>=<]/g, "").trim();
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function detectFlutterVersion(root) {
|
|
37
|
+
try {
|
|
38
|
+
const output = execSync("flutter --version --machine", {
|
|
39
|
+
cwd: root,
|
|
40
|
+
timeout: 15000,
|
|
41
|
+
encoding: "utf-8",
|
|
42
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
43
|
+
});
|
|
44
|
+
const parsed = JSON.parse(output);
|
|
45
|
+
return parsed.frameworkVersion || null;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
const pubspecPath = join(root, "pubspec.yaml");
|
|
49
|
+
if (!existsSync(pubspecPath))
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
const content = readFileSync(pubspecPath, "utf-8");
|
|
53
|
+
const match = content.match(/sdk:\s*['"]?>=?\s*([\d.]+)/);
|
|
54
|
+
return match ? match[1] : null;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function getExpoUpgradeSteps(current, target) {
|
|
62
|
+
return {
|
|
63
|
+
framework: "expo",
|
|
64
|
+
current_version: current,
|
|
65
|
+
target_version: target || "latest",
|
|
66
|
+
pre_upgrade_checklist: [
|
|
67
|
+
"Commit all current changes to git (create a clean restore point)",
|
|
68
|
+
"Run existing tests and confirm they pass",
|
|
69
|
+
"Review CHANGELOG for target SDK version at expo.dev/changelog",
|
|
70
|
+
"Run npx expo-doctor to check current project health",
|
|
71
|
+
"Back up app.json / app.config.js",
|
|
72
|
+
],
|
|
73
|
+
upgrade_steps: [
|
|
74
|
+
`Run: npx expo install expo@${target || "latest"} --fix`,
|
|
75
|
+
"Run: npx expo install --fix (updates all Expo packages to compatible versions)",
|
|
76
|
+
"Run: npx expo-doctor (check for remaining compatibility issues)",
|
|
77
|
+
"Update app.json sdkVersion if present",
|
|
78
|
+
"Run: npx expo prebuild --clean (regenerate native projects)",
|
|
79
|
+
"Run: npx expo start --clear (clear Metro cache)",
|
|
80
|
+
"Test on both iOS and Android simulators/devices",
|
|
81
|
+
],
|
|
82
|
+
breaking_changes: [
|
|
83
|
+
"Check for deprecated APIs removed in the new SDK version",
|
|
84
|
+
"Review Expo Router version compatibility if using file-based routing",
|
|
85
|
+
"Check if any config plugins need updates for the new SDK",
|
|
86
|
+
"Verify native module compatibility with expo-doctor",
|
|
87
|
+
"Check React Native version bump (Expo SDK pins a specific RN version)",
|
|
88
|
+
],
|
|
89
|
+
dependency_actions: [
|
|
90
|
+
"Run: npx expo install --check (list packages needing updates)",
|
|
91
|
+
"Update @react-navigation/* packages if using React Navigation directly",
|
|
92
|
+
"Update react-native-reanimated, react-native-gesture-handler to compatible versions",
|
|
93
|
+
"Check third-party native modules for SDK compatibility",
|
|
94
|
+
"Run: npm outdated (check for other stale dependencies)",
|
|
95
|
+
],
|
|
96
|
+
rollback_strategy: [
|
|
97
|
+
"git stash or git checkout to restore pre-upgrade state",
|
|
98
|
+
"Restore package.json and package-lock.json from git",
|
|
99
|
+
"Run npm install to restore node_modules",
|
|
100
|
+
"Run npx expo prebuild --clean to regenerate native projects",
|
|
101
|
+
"If using EAS, the previous build is still available for download",
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function getFlutterUpgradeSteps(current, target) {
|
|
106
|
+
return {
|
|
107
|
+
framework: "flutter",
|
|
108
|
+
current_version: current,
|
|
109
|
+
target_version: target || "latest stable",
|
|
110
|
+
pre_upgrade_checklist: [
|
|
111
|
+
"Commit all current changes to git",
|
|
112
|
+
"Run flutter test and confirm tests pass",
|
|
113
|
+
"Run flutter analyze to check for existing issues",
|
|
114
|
+
"Review Flutter release notes at docs.flutter.dev/release/release-notes",
|
|
115
|
+
"Back up pubspec.yaml and pubspec.lock",
|
|
116
|
+
],
|
|
117
|
+
upgrade_steps: [
|
|
118
|
+
`Run: flutter upgrade${target ? ` ${target}` : ""}`,
|
|
119
|
+
"Run: flutter pub upgrade --major-versions (update dependencies)",
|
|
120
|
+
"Run: flutter pub get",
|
|
121
|
+
"Run: flutter analyze (check for new lint warnings)",
|
|
122
|
+
"Run: dart fix --apply (auto-fix deprecations)",
|
|
123
|
+
"Run: flutter clean && flutter pub get",
|
|
124
|
+
"Test on both iOS and Android",
|
|
125
|
+
],
|
|
126
|
+
breaking_changes: [
|
|
127
|
+
"Check for deprecated Widget APIs removed in the new version",
|
|
128
|
+
"Review Material 3 migration status if upgrading across major versions",
|
|
129
|
+
"Check Gradle and AGP version requirements for Android",
|
|
130
|
+
"Verify CocoaPods and Xcode version compatibility for iOS",
|
|
131
|
+
"Check for Dart language version changes affecting your code",
|
|
132
|
+
],
|
|
133
|
+
dependency_actions: [
|
|
134
|
+
"Run: flutter pub outdated (list packages needing updates)",
|
|
135
|
+
"Update go_router, riverpod, bloc if using those packages",
|
|
136
|
+
"Check native plugin compatibility (firebase, maps, camera)",
|
|
137
|
+
"Update build.gradle minSdkVersion if required by new Flutter",
|
|
138
|
+
"Update Podfile deployment target if required",
|
|
139
|
+
],
|
|
140
|
+
rollback_strategy: [
|
|
141
|
+
"git checkout to restore pre-upgrade state",
|
|
142
|
+
"Restore pubspec.yaml and pubspec.lock from git",
|
|
143
|
+
"Run flutter pub get to restore packages",
|
|
144
|
+
"Run flutter clean to clear build artifacts",
|
|
145
|
+
"Use flutter downgrade if needed (only works for latest->previous)",
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
export function register(server) {
|
|
150
|
+
server.tool("mobile_upgradeSDK", "Detect current SDK version, compare to target, and generate a step-by-step upgrade plan with dependency fixes, breaking change warnings, and rollback strategy.", inputSchema, async (args) => {
|
|
151
|
+
try {
|
|
152
|
+
const root = args.project_path || process.cwd();
|
|
153
|
+
if (!existsSync(root)) {
|
|
154
|
+
return errorResponse(new Error(`Project path does not exist: ${root}`));
|
|
155
|
+
}
|
|
156
|
+
const isFlutter = args.framework === "flutter";
|
|
157
|
+
const currentVersion = isFlutter
|
|
158
|
+
? detectFlutterVersion(root)
|
|
159
|
+
: detectExpoVersion(root);
|
|
160
|
+
const report = isFlutter
|
|
161
|
+
? getFlutterUpgradeSteps(currentVersion, args.target_version ?? null)
|
|
162
|
+
: getExpoUpgradeSteps(currentVersion, args.target_version ?? null);
|
|
163
|
+
return textResponse(JSON.stringify(report, null, 2));
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
return errorResponse(err);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=upgradeSDK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgradeSDK.js","sourceRoot":"","sources":["../../src/tools/upgradeSDK.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tmhs/mobile-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "MCP server for mobile app development -
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for mobile app development - 36 tools for environment checks, project scaffolding, device deployment, screen/component generation, dependency installation, permissions, AI integration, build health, push notifications, deep links, dev environment reset, store builds, metadata validation, App Store submission, Play Store submission, screenshot capture, bundle analysis, OTA update configuration, test execution, CI/CD setup, test file generation, i18n setup, map integration, form generation, real-time client setup, security auditing, performance profiling, offline readiness checks, APM monitoring setup, theming setup, accessibility auditing, feature flag configuration, native module scaffolding, SDK upgrade planning, and native compatibility auditing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -43,5 +43,15 @@
|
|
|
43
43
|
"bugs": {
|
|
44
44
|
"url": "https://github.com/TMHSDigital/Mobile-App-Developer-Tools/issues"
|
|
45
45
|
},
|
|
46
|
-
"author": "TMHSDigital"
|
|
46
|
+
"author": "TMHSDigital",
|
|
47
|
+
"keywords": [
|
|
48
|
+
"mcp",
|
|
49
|
+
"mobile",
|
|
50
|
+
"react-native",
|
|
51
|
+
"expo",
|
|
52
|
+
"flutter",
|
|
53
|
+
"model-context-protocol",
|
|
54
|
+
"developer-tools",
|
|
55
|
+
"mobile-dev"
|
|
56
|
+
]
|
|
47
57
|
}
|