@tmhs/mobile-mcp 0.7.0 → 0.9.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/dist/index.js CHANGED
@@ -20,9 +20,16 @@ import { register as registerSubmitToPlayStore } from "./tools/submitToPlayStore
20
20
  import { register as registerGenerateScreenshots } from "./tools/generateScreenshots.js";
21
21
  import { register as registerAnalyzeBundle } from "./tools/analyzeBundle.js";
22
22
  import { register as registerConfigureOTA } from "./tools/configureOTA.js";
23
+ import { register as registerRunTests } from "./tools/runTests.js";
24
+ import { register as registerSetupCI } from "./tools/setupCI.js";
25
+ import { register as registerGenerateTestFile } from "./tools/generateTestFile.js";
26
+ import { register as registerSetupI18n } from "./tools/setupI18n.js";
27
+ import { register as registerAddMap } from "./tools/addMap.js";
28
+ import { register as registerGenerateForm } from "./tools/generateForm.js";
29
+ import { register as registerSetupRealtime } from "./tools/setupRealtime.js";
23
30
  const server = new McpServer({
24
31
  name: "mobile-mcp",
25
- version: "0.7.0",
32
+ version: "0.9.0",
26
33
  });
27
34
  registerCheckDevEnvironment(server);
28
35
  registerScaffoldProject(server);
@@ -43,6 +50,13 @@ registerSubmitToPlayStore(server);
43
50
  registerGenerateScreenshots(server);
44
51
  registerAnalyzeBundle(server);
45
52
  registerConfigureOTA(server);
53
+ registerRunTests(server);
54
+ registerSetupCI(server);
55
+ registerGenerateTestFile(server);
56
+ registerSetupI18n(server);
57
+ registerAddMap(server);
58
+ registerGenerateForm(server);
59
+ registerSetupRealtime(server);
46
60
  async function main() {
47
61
  const transport = new StdioServerTransport();
48
62
  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":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=addMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addMap.d.ts","sourceRoot":"","sources":["../../src/tools/addMap.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0IzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkHhD"}
@@ -0,0 +1,223 @@
1
+ import { z } from "zod";
2
+ import { writeFileSync, mkdirSync, existsSync, readFileSync } 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("Project framework (default: expo)."),
15
+ provider: z
16
+ .enum(["google", "apple"])
17
+ .optional()
18
+ .default("google")
19
+ .describe("Map provider (default: google). Apple Maps only available on iOS."),
20
+ screen_name: z
21
+ .string()
22
+ .optional()
23
+ .default("MapScreen")
24
+ .describe("Name for the generated map screen component (default: MapScreen)."),
25
+ };
26
+ function generateExpoMapScreen(name) {
27
+ return `import { useState } from "react";
28
+ import { StyleSheet, View } from "react-native";
29
+ import MapView, { Marker, type Region } from "react-native-maps";
30
+
31
+ const INITIAL_REGION: Region = {
32
+ latitude: 37.7749,
33
+ longitude: -122.4194,
34
+ latitudeDelta: 0.0922,
35
+ longitudeDelta: 0.0421,
36
+ };
37
+
38
+ interface MapMarker {
39
+ id: string;
40
+ coordinate: { latitude: number; longitude: number };
41
+ title: string;
42
+ description?: string;
43
+ }
44
+
45
+ export default function ${name}() {
46
+ const [markers] = useState<MapMarker[]>([
47
+ {
48
+ id: "1",
49
+ coordinate: { latitude: 37.7749, longitude: -122.4194 },
50
+ title: "San Francisco",
51
+ description: "Starting point",
52
+ },
53
+ ]);
54
+
55
+ return (
56
+ <View style={styles.container}>
57
+ <MapView
58
+ style={styles.map}
59
+ initialRegion={INITIAL_REGION}
60
+ showsUserLocation
61
+ showsMyLocationButton
62
+ >
63
+ {markers.map((marker) => (
64
+ <Marker
65
+ key={marker.id}
66
+ coordinate={marker.coordinate}
67
+ title={marker.title}
68
+ description={marker.description}
69
+ />
70
+ ))}
71
+ </MapView>
72
+ </View>
73
+ );
74
+ }
75
+
76
+ const styles = StyleSheet.create({
77
+ container: {
78
+ flex: 1,
79
+ },
80
+ map: {
81
+ width: "100%",
82
+ height: "100%",
83
+ },
84
+ });
85
+ `;
86
+ }
87
+ function generateFlutterMapScreen(name) {
88
+ const className = name.charAt(0).toUpperCase() + name.slice(1);
89
+ return `import 'package:flutter/material.dart';
90
+ import 'package:google_maps_flutter/google_maps_flutter.dart';
91
+
92
+ class ${className} extends StatefulWidget {
93
+ const ${className}({super.key});
94
+
95
+ @override
96
+ State<${className}> createState() => _${className}State();
97
+ }
98
+
99
+ class _${className}State extends State<${className}> {
100
+ static const _initialPosition = CameraPosition(
101
+ target: LatLng(37.7749, -122.4194),
102
+ zoom: 14,
103
+ );
104
+
105
+ final Set<Marker> _markers = {
106
+ const Marker(
107
+ markerId: MarkerId('san_francisco'),
108
+ position: LatLng(37.7749, -122.4194),
109
+ infoWindow: InfoWindow(title: 'San Francisco'),
110
+ ),
111
+ };
112
+
113
+ GoogleMapController? _controller;
114
+
115
+ @override
116
+ Widget build(BuildContext context) {
117
+ return Scaffold(
118
+ appBar: AppBar(title: const Text('Map')),
119
+ body: GoogleMap(
120
+ initialCameraPosition: _initialPosition,
121
+ markers: _markers,
122
+ myLocationEnabled: true,
123
+ myLocationButtonEnabled: true,
124
+ onMapCreated: (controller) => _controller = controller,
125
+ ),
126
+ );
127
+ }
128
+
129
+ @override
130
+ void dispose() {
131
+ _controller?.dispose();
132
+ super.dispose();
133
+ }
134
+ }
135
+ `;
136
+ }
137
+ export function register(server) {
138
+ server.tool("mobile_addMap", "Add a map view with provider config, location permissions, and marker support. Generates a starter map screen component.", inputSchema, async (args) => {
139
+ try {
140
+ const root = args.project_path || process.cwd();
141
+ const filesCreated = [];
142
+ const configChanges = [];
143
+ if (args.framework === "flutter") {
144
+ const screenDir = join(root, "lib", "screens");
145
+ mkdirSync(screenDir, { recursive: true });
146
+ const fileName = args.screen_name
147
+ .replace(/([A-Z])/g, "_$1")
148
+ .toLowerCase()
149
+ .replace(/^_/, "");
150
+ const screenPath = join(screenDir, `${fileName}.dart`);
151
+ if (existsSync(screenPath)) {
152
+ return errorResponse(new Error(`File already exists: ${screenPath}`));
153
+ }
154
+ writeFileSync(screenPath, generateFlutterMapScreen(args.screen_name), "utf-8");
155
+ filesCreated.push(screenPath);
156
+ return textResponse(JSON.stringify({
157
+ success: true,
158
+ framework: "flutter",
159
+ provider: args.provider,
160
+ files_created: filesCreated,
161
+ next_steps: [
162
+ "Add google_maps_flutter to pubspec.yaml: flutter pub add google_maps_flutter",
163
+ "Add your API key to android/app/src/main/AndroidManifest.xml:",
164
+ ' <meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_KEY"/>',
165
+ "Add your API key to ios/Runner/AppDelegate.swift:",
166
+ ' GMSServices.provideAPIKey("YOUR_KEY")',
167
+ "Add location permissions to AndroidManifest.xml and Info.plist",
168
+ "Get a Google Maps API key from console.cloud.google.com",
169
+ ],
170
+ }, null, 2));
171
+ }
172
+ const appJsonPath = join(root, "app.json");
173
+ if (existsSync(appJsonPath)) {
174
+ const appJson = JSON.parse(readFileSync(appJsonPath, "utf-8"));
175
+ const expo = appJson.expo || {};
176
+ if (!expo.plugins)
177
+ expo.plugins = [];
178
+ const hasMapPlugin = expo.plugins.some((p) => (typeof p === "string" && p === "react-native-maps") ||
179
+ (Array.isArray(p) && p[0] === "react-native-maps"));
180
+ if (!hasMapPlugin) {
181
+ const mapConfig = [
182
+ "react-native-maps",
183
+ {
184
+ googleMapsApiKey: "GOOGLE_MAPS_API_KEY_HERE",
185
+ },
186
+ ];
187
+ expo.plugins.push(mapConfig);
188
+ appJson.expo = expo;
189
+ writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + "\n", "utf-8");
190
+ configChanges.push("Added react-native-maps plugin to app.json");
191
+ }
192
+ }
193
+ const screenDir = join(root, "app");
194
+ if (!existsSync(screenDir)) {
195
+ mkdirSync(screenDir, { recursive: true });
196
+ }
197
+ const screenPath = join(screenDir, `${args.screen_name.charAt(0).toLowerCase() + args.screen_name.slice(1)}.tsx`);
198
+ if (!existsSync(screenPath)) {
199
+ writeFileSync(screenPath, generateExpoMapScreen(args.screen_name), "utf-8");
200
+ filesCreated.push(screenPath);
201
+ }
202
+ return textResponse(JSON.stringify({
203
+ success: true,
204
+ framework: "expo",
205
+ provider: args.provider,
206
+ files_created: filesCreated,
207
+ config_changes: configChanges,
208
+ next_steps: [
209
+ "Install react-native-maps: npx expo install react-native-maps",
210
+ "Install expo-location for user location: npx expo install expo-location",
211
+ "Replace GOOGLE_MAPS_API_KEY_HERE in app.json with your actual key",
212
+ "Get a Google Maps API key from console.cloud.google.com",
213
+ "Add location permission with mobile_addPermission",
214
+ "This requires a dev build (not Expo Go) for native map rendering",
215
+ ],
216
+ }, null, 2));
217
+ }
218
+ catch (err) {
219
+ return errorResponse(err);
220
+ }
221
+ });
222
+ }
223
+ //# sourceMappingURL=addMap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addMap.js","sourceRoot":"","sources":["../../src/tools/addMap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=generateForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateForm.d.ts","sourceRoot":"","sources":["../../src/tools/generateForm.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6RzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwFhD"}
@@ -0,0 +1,337 @@
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 fieldSchema = z.object({
6
+ name: z.string().describe("Field name in camelCase (e.g. 'email', 'firstName')."),
7
+ type: z
8
+ .enum(["text", "email", "password", "number", "phone", "textarea", "select"])
9
+ .describe("Field input type."),
10
+ label: z.string().describe("Display label for the field."),
11
+ required: z.boolean().optional().default(true).describe("Whether the field is required."),
12
+ placeholder: z.string().optional().describe("Placeholder text."),
13
+ });
14
+ const inputSchema = {
15
+ form_name: z
16
+ .string()
17
+ .describe("Form component name in PascalCase (e.g. 'LoginForm', 'ContactForm')."),
18
+ fields: z
19
+ .array(fieldSchema)
20
+ .min(1)
21
+ .describe("Array of field definitions."),
22
+ project_path: z
23
+ .string()
24
+ .optional()
25
+ .describe("Absolute path to the project root. Defaults to cwd."),
26
+ framework: z
27
+ .enum(["expo", "flutter"])
28
+ .optional()
29
+ .default("expo")
30
+ .describe("Project framework (default: expo)."),
31
+ output_directory: z
32
+ .string()
33
+ .optional()
34
+ .default("components")
35
+ .describe("Output directory relative to project root (default: components)."),
36
+ };
37
+ function zodValidation(field) {
38
+ let chain = "z.string()";
39
+ if (field.required)
40
+ chain += '.min(1, "Required")';
41
+ if (field.type === "email")
42
+ chain += '.email("Invalid email")';
43
+ if (field.type === "number")
44
+ chain = "z.coerce.number()";
45
+ if (field.type === "phone")
46
+ chain += '.regex(/^\\+?[0-9\\s-()]+$/, "Invalid phone number")';
47
+ if (field.type === "password")
48
+ chain += '.min(8, "At least 8 characters")';
49
+ return chain;
50
+ }
51
+ function rnInputType(type) {
52
+ switch (type) {
53
+ case "email": return "email-address";
54
+ case "number": return "numeric";
55
+ case "phone": return "phone-pad";
56
+ default: return "default";
57
+ }
58
+ }
59
+ function generateExpoForm(name, fields) {
60
+ const schemaFields = fields
61
+ .map((f) => ` ${f.name}: ${zodValidation(f)},`)
62
+ .join("\n");
63
+ const formFields = fields
64
+ .map((f) => {
65
+ const secureEntry = f.type === "password" ? "\n secureTextEntry" : "";
66
+ const multiline = f.type === "textarea" ? "\n multiline\n numberOfLines={4}" : "";
67
+ const keyboard = f.type !== "text" && f.type !== "password" && f.type !== "textarea" && f.type !== "select"
68
+ ? `\n keyboardType="${rnInputType(f.type)}"`
69
+ : "";
70
+ return ` <View style={styles.field}>
71
+ <Text style={styles.label}>${f.label}</Text>
72
+ <Controller
73
+ control={control}
74
+ name="${f.name}"
75
+ render={({ field: { onChange, onBlur, value } }) => (
76
+ <TextInput
77
+ style={[styles.input, errors.${f.name} && styles.inputError]}
78
+ onBlur={onBlur}
79
+ onChangeText={onChange}
80
+ value={value}
81
+ placeholder="${f.placeholder || f.label}"${secureEntry}${multiline}${keyboard}
82
+ />
83
+ )}
84
+ />
85
+ {errors.${f.name} && (
86
+ <Text style={styles.error}>{errors.${f.name}?.message}</Text>
87
+ )}
88
+ </View>`;
89
+ })
90
+ .join("\n\n");
91
+ const defaultValues = fields
92
+ .map((f) => ` ${f.name}: "",`)
93
+ .join("\n");
94
+ return `import { View, Text, TextInput, Pressable, StyleSheet } from "react-native";
95
+ import { useForm, Controller } from "react-hook-form";
96
+ import { zodResolver } from "@hookform/resolvers/zod";
97
+ import { z } from "zod";
98
+
99
+ const schema = z.object({
100
+ ${schemaFields}
101
+ });
102
+
103
+ type FormData = z.infer<typeof schema>;
104
+
105
+ interface ${name}Props {
106
+ onSubmit: (data: FormData) => void;
107
+ }
108
+
109
+ export function ${name}({ onSubmit }: ${name}Props) {
110
+ const {
111
+ control,
112
+ handleSubmit,
113
+ formState: { errors, isSubmitting },
114
+ } = useForm<FormData>({
115
+ resolver: zodResolver(schema),
116
+ defaultValues: {
117
+ ${defaultValues}
118
+ },
119
+ });
120
+
121
+ return (
122
+ <View style={styles.container}>
123
+ ${formFields}
124
+
125
+ <Pressable
126
+ style={[styles.button, isSubmitting && styles.buttonDisabled]}
127
+ onPress={handleSubmit(onSubmit)}
128
+ disabled={isSubmitting}
129
+ >
130
+ <Text style={styles.buttonText}>
131
+ {isSubmitting ? "Submitting..." : "Submit"}
132
+ </Text>
133
+ </Pressable>
134
+ </View>
135
+ );
136
+ }
137
+
138
+ const styles = StyleSheet.create({
139
+ container: {
140
+ padding: 16,
141
+ gap: 12,
142
+ },
143
+ field: {
144
+ gap: 4,
145
+ },
146
+ label: {
147
+ fontSize: 14,
148
+ fontWeight: "600",
149
+ },
150
+ input: {
151
+ borderWidth: 1,
152
+ borderColor: "#ccc",
153
+ borderRadius: 8,
154
+ padding: 12,
155
+ fontSize: 16,
156
+ },
157
+ inputError: {
158
+ borderColor: "#dc2626",
159
+ },
160
+ error: {
161
+ color: "#dc2626",
162
+ fontSize: 12,
163
+ },
164
+ button: {
165
+ backgroundColor: "#0A84FF",
166
+ padding: 16,
167
+ borderRadius: 8,
168
+ alignItems: "center",
169
+ marginTop: 8,
170
+ },
171
+ buttonDisabled: {
172
+ opacity: 0.6,
173
+ },
174
+ buttonText: {
175
+ color: "#fff",
176
+ fontSize: 16,
177
+ fontWeight: "600",
178
+ },
179
+ });
180
+ `;
181
+ }
182
+ function generateFlutterForm(name, fields) {
183
+ const className = name.charAt(0).toUpperCase() + name.slice(1);
184
+ const controllers = fields
185
+ .map((f) => ` final _${f.name}Controller = TextEditingController();`)
186
+ .join("\n");
187
+ const disposeControllers = fields
188
+ .map((f) => ` _${f.name}Controller.dispose();`)
189
+ .join("\n");
190
+ const formFields = fields
191
+ .map((f) => {
192
+ const obscure = f.type === "password" ? "\n obscureText: true," : "";
193
+ const maxLines = f.type === "textarea" ? "\n maxLines: 4," : "";
194
+ const keyboard = f.type === "email"
195
+ ? "\n keyboardType: TextInputType.emailAddress,"
196
+ : f.type === "number"
197
+ ? "\n keyboardType: TextInputType.number,"
198
+ : f.type === "phone"
199
+ ? "\n keyboardType: TextInputType.phone,"
200
+ : "";
201
+ const validator = f.required
202
+ ? `\n validator: (value) {\n if (value == null || value.isEmpty) return '${f.label} is required';\n return null;\n },`
203
+ : "";
204
+ return ` TextFormField(
205
+ controller: _${f.name}Controller,
206
+ decoration: const InputDecoration(
207
+ labelText: '${f.label}',
208
+ hintText: '${f.placeholder || f.label}',
209
+ ),${obscure}${maxLines}${keyboard}${validator}
210
+ ),
211
+ const SizedBox(height: 16),`;
212
+ })
213
+ .join("\n");
214
+ return `import 'package:flutter/material.dart';
215
+
216
+ class ${className} extends StatefulWidget {
217
+ final void Function(Map<String, String> data) onSubmit;
218
+
219
+ const ${className}({super.key, required this.onSubmit});
220
+
221
+ @override
222
+ State<${className}> createState() => _${className}State();
223
+ }
224
+
225
+ class _${className}State extends State<${className}> {
226
+ final _formKey = GlobalKey<FormState>();
227
+ bool _isSubmitting = false;
228
+
229
+ ${controllers}
230
+
231
+ @override
232
+ void dispose() {
233
+ ${disposeControllers}
234
+ super.dispose();
235
+ }
236
+
237
+ Future<void> _handleSubmit() async {
238
+ if (!_formKey.currentState!.validate()) return;
239
+
240
+ setState(() => _isSubmitting = true);
241
+ try {
242
+ widget.onSubmit({
243
+ ${fields.map((f) => ` '${f.name}': _${f.name}Controller.text,`).join("\n")}
244
+ });
245
+ } finally {
246
+ if (mounted) setState(() => _isSubmitting = false);
247
+ }
248
+ }
249
+
250
+ @override
251
+ Widget build(BuildContext context) {
252
+ return Form(
253
+ key: _formKey,
254
+ child: Padding(
255
+ padding: const EdgeInsets.all(16),
256
+ child: Column(
257
+ crossAxisAlignment: CrossAxisAlignment.stretch,
258
+ children: [
259
+ ${formFields}
260
+ ElevatedButton(
261
+ onPressed: _isSubmitting ? null : _handleSubmit,
262
+ child: Text(_isSubmitting ? 'Submitting...' : 'Submit'),
263
+ ),
264
+ ],
265
+ ),
266
+ ),
267
+ );
268
+ }
269
+ }
270
+ `;
271
+ }
272
+ export function register(server) {
273
+ server.tool("mobile_generateForm", "Scaffold a validated form component with typed fields, validation rules, and error handling. Uses React Hook Form + Zod for Expo or Form + TextFormField for Flutter.", inputSchema, async (args) => {
274
+ try {
275
+ const root = args.project_path || process.cwd();
276
+ const outDir = join(root, args.output_directory);
277
+ mkdirSync(outDir, { recursive: true });
278
+ const fields = args.fields.map((f) => ({
279
+ name: f.name,
280
+ type: f.type,
281
+ label: f.label,
282
+ required: f.required,
283
+ placeholder: f.placeholder,
284
+ }));
285
+ if (args.framework === "flutter") {
286
+ const fileName = args.form_name
287
+ .replace(/([A-Z])/g, "_$1")
288
+ .toLowerCase()
289
+ .replace(/^_/, "");
290
+ const filePath = join(outDir, `${fileName}.dart`);
291
+ if (existsSync(filePath)) {
292
+ return errorResponse(new Error(`File already exists: ${filePath}`));
293
+ }
294
+ writeFileSync(filePath, generateFlutterForm(args.form_name, fields), "utf-8");
295
+ return textResponse(JSON.stringify({
296
+ success: true,
297
+ framework: "flutter",
298
+ file_created: filePath,
299
+ form_name: args.form_name,
300
+ fields: fields.map((f) => f.name),
301
+ next_steps: [
302
+ "Import and use the form widget in your screen",
303
+ "Add email/phone validators if needed",
304
+ "Add keyboard avoidance with SingleChildScrollView",
305
+ ],
306
+ }, null, 2));
307
+ }
308
+ const filePath = join(outDir, `${args.form_name}.tsx`);
309
+ if (existsSync(filePath)) {
310
+ return errorResponse(new Error(`File already exists: ${filePath}`));
311
+ }
312
+ writeFileSync(filePath, generateExpoForm(args.form_name, fields), "utf-8");
313
+ return textResponse(JSON.stringify({
314
+ success: true,
315
+ framework: "expo",
316
+ file_created: filePath,
317
+ form_name: args.form_name,
318
+ fields: fields.map((f) => f.name),
319
+ dependencies_needed: [
320
+ "react-hook-form",
321
+ "@hookform/resolvers",
322
+ "zod",
323
+ ],
324
+ next_steps: [
325
+ "Install dependencies: npx expo install react-hook-form @hookform/resolvers zod",
326
+ "Import and render the form in your screen",
327
+ "Implement the onSubmit handler with your API call",
328
+ "Add KeyboardAvoidingView wrapper if fields are below the fold",
329
+ ],
330
+ }, null, 2));
331
+ }
332
+ catch (err) {
333
+ return errorResponse(err);
334
+ }
335
+ });
336
+ }
337
+ //# sourceMappingURL=generateForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateForm.js","sourceRoot":"","sources":["../../src/tools/generateForm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=generateTestFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateTestFile.d.ts","sourceRoot":"","sources":["../../src/tools/generateTestFile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwHzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyGhD"}