@ceraph/react-native-mcp 0.2.1 → 0.3.1

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.
Files changed (124) hide show
  1. package/LICENSE +116 -15
  2. package/README.md +79 -77
  3. package/assets/default.png +0 -0
  4. package/dist/app-lifecycle.d.ts +50 -0
  5. package/dist/app-lifecycle.js +487 -0
  6. package/dist/camera-image-writer.d.ts +43 -0
  7. package/dist/camera-image-writer.js +280 -0
  8. package/dist/camera-registry-sync.d.ts +18 -0
  9. package/dist/camera-registry-sync.js +117 -0
  10. package/dist/cli.d.ts +0 -7
  11. package/dist/cli.js +41 -9
  12. package/dist/device-autonomy.d.ts +30 -0
  13. package/dist/device-autonomy.js +117 -0
  14. package/dist/error-parser.d.ts +6 -26
  15. package/dist/error-parser.js +4 -74
  16. package/dist/expo-manager.d.ts +2 -74
  17. package/dist/expo-manager.js +11 -125
  18. package/dist/index.d.ts +0 -7
  19. package/dist/index.js +1266 -56
  20. package/dist/init/ast-camera.d.ts +29 -0
  21. package/dist/init/ast-camera.js +267 -0
  22. package/dist/init/ast-layout.d.ts +15 -0
  23. package/dist/init/ast-layout.js +167 -0
  24. package/dist/init/claude-hook-constants.d.ts +9 -0
  25. package/dist/init/claude-hook-constants.js +91 -0
  26. package/dist/init/lan-ip.d.ts +11 -0
  27. package/dist/init/lan-ip.js +51 -0
  28. package/dist/init/monorepo.d.ts +13 -0
  29. package/dist/init/monorepo.js +185 -0
  30. package/dist/init/oauth.d.ts +52 -0
  31. package/dist/init/oauth.js +220 -0
  32. package/dist/init/package-manager.d.ts +11 -0
  33. package/dist/init/package-manager.js +60 -0
  34. package/dist/init/prompt.d.ts +12 -0
  35. package/dist/init/prompt.js +68 -0
  36. package/dist/init/shell-profile.d.ts +22 -0
  37. package/dist/init/shell-profile.js +85 -0
  38. package/dist/init/steps.d.ts +135 -0
  39. package/dist/init/steps.js +399 -0
  40. package/dist/init/url-scheme.d.ts +42 -0
  41. package/dist/init/url-scheme.js +187 -0
  42. package/dist/init/walkthrough.d.ts +76 -0
  43. package/dist/init/walkthrough.js +340 -0
  44. package/dist/init.d.ts +7 -7
  45. package/dist/init.js +280 -120
  46. package/dist/iproxy-manager.d.ts +32 -0
  47. package/dist/iproxy-manager.js +216 -0
  48. package/dist/mac-caffeinate.d.ts +10 -0
  49. package/dist/mac-caffeinate.js +56 -0
  50. package/dist/permission-interceptor.d.ts +29 -0
  51. package/dist/permission-interceptor.js +185 -0
  52. package/dist/prebuild-detector.d.ts +0 -30
  53. package/dist/prebuild-detector.js +1 -42
  54. package/dist/preflight.d.ts +34 -0
  55. package/dist/preflight.js +847 -0
  56. package/dist/screen.d.ts +132 -43
  57. package/dist/screen.js +668 -94
  58. package/dist/shim/boot.d.ts +41 -0
  59. package/dist/shim/boot.js +141 -0
  60. package/dist/shim/camera.d.ts +22 -0
  61. package/dist/shim/camera.js +62 -0
  62. package/dist/shim/config.d.ts +6 -0
  63. package/dist/shim/config.js +56 -0
  64. package/dist/shim/deep-link.d.ts +1 -0
  65. package/dist/shim/deep-link.js +25 -0
  66. package/dist/shim/dev-guard.d.ts +1 -0
  67. package/dist/shim/dev-guard.js +3 -0
  68. package/dist/shim/error-handler.d.ts +20 -0
  69. package/dist/shim/error-handler.js +66 -0
  70. package/dist/shim/fetch-interceptor.d.ts +13 -0
  71. package/dist/shim/fetch-interceptor.js +93 -0
  72. package/dist/shim/index.d.ts +6 -0
  73. package/dist/shim/index.js +6 -0
  74. package/dist/shim/keep-awake.d.ts +13 -0
  75. package/dist/shim/keep-awake.js +118 -0
  76. package/dist/shim/reload.d.ts +23 -0
  77. package/dist/shim/reload.js +76 -0
  78. package/dist/shim/signal-capture.d.ts +11 -0
  79. package/dist/shim/signal-capture.js +15 -0
  80. package/dist/shim/signal-transport.d.ts +17 -0
  81. package/dist/shim/signal-transport.js +43 -0
  82. package/dist/signal-listener.d.ts +27 -0
  83. package/dist/signal-listener.js +135 -0
  84. package/dist/simulator-boot.d.ts +52 -0
  85. package/dist/simulator-boot.js +227 -0
  86. package/dist/target.d.ts +48 -0
  87. package/dist/target.js +267 -0
  88. package/dist/uninstall/cli-runner.d.ts +32 -0
  89. package/dist/uninstall/cli-runner.js +223 -0
  90. package/dist/uninstall/footprint.d.ts +40 -0
  91. package/dist/uninstall/footprint.js +288 -0
  92. package/dist/uninstall/mcp-tools.d.ts +14 -0
  93. package/dist/uninstall/mcp-tools.js +175 -0
  94. package/dist/uninstall/revert-auth.d.ts +22 -0
  95. package/dist/uninstall/revert-auth.js +31 -0
  96. package/dist/uninstall/revert-boot.d.ts +24 -0
  97. package/dist/uninstall/revert-boot.js +242 -0
  98. package/dist/uninstall/revert-camera.d.ts +12 -0
  99. package/dist/uninstall/revert-camera.js +199 -0
  100. package/dist/uninstall/revert-ceraph-dir.d.ts +27 -0
  101. package/dist/uninstall/revert-ceraph-dir.js +38 -0
  102. package/dist/uninstall/revert-claude-hooks.d.ts +19 -0
  103. package/dist/uninstall/revert-claude-hooks.js +191 -0
  104. package/dist/uninstall/revert-gitignore.d.ts +17 -0
  105. package/dist/uninstall/revert-gitignore.js +43 -0
  106. package/dist/uninstall/revert-mcp-clients.d.ts +57 -0
  107. package/dist/uninstall/revert-mcp-clients.js +194 -0
  108. package/dist/uninstall/revert-package.d.ts +34 -0
  109. package/dist/uninstall/revert-package.js +98 -0
  110. package/dist/uninstall/revert-scheme.d.ts +36 -0
  111. package/dist/uninstall/revert-scheme.js +139 -0
  112. package/dist/uninstall/revert-signal-host-env.d.ts +31 -0
  113. package/dist/uninstall/revert-signal-host-env.js +61 -0
  114. package/dist/uninstall/walkthrough.d.ts +80 -0
  115. package/dist/uninstall/walkthrough.js +1244 -0
  116. package/dist/utils/atomic-write.d.ts +1 -0
  117. package/dist/utils/atomic-write.js +30 -0
  118. package/dist/wait-for-device.d.ts +68 -0
  119. package/dist/wait-for-device.js +368 -0
  120. package/dist/wda-manager.d.ts +38 -0
  121. package/dist/wda-manager.js +186 -0
  122. package/dist/wda-simulator.d.ts +28 -0
  123. package/dist/wda-simulator.js +257 -0
  124. package/package.json +38 -5
@@ -0,0 +1,28 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ export interface WdaSimulatorSession {
3
+ port: number;
4
+ udid: string;
5
+ projectPath: string;
6
+ process: ChildProcess;
7
+ output: string[];
8
+ stop: () => Promise<void>;
9
+ }
10
+ export interface LaunchOpts {
11
+ udid: string;
12
+ projectDir?: string;
13
+ derivedDataPath?: string;
14
+ startupTimeoutMs?: number;
15
+ onChildSpawned?: (child: ChildProcess) => void;
16
+ }
17
+ export type LaunchResult = {
18
+ ok: true;
19
+ session: WdaSimulatorSession;
20
+ } | {
21
+ ok: false;
22
+ reason: LaunchFailureReason;
23
+ error: string;
24
+ output?: string[];
25
+ };
26
+ export type LaunchFailureReason = "wda-package-missing" | "xcodebuild-missing" | "xcodebuild-spawn-failed" | "port-not-detected" | "xcodebuild-exited-early";
27
+ export declare function resolveWdaProjectPath(projectDir?: string): string | null;
28
+ export declare function launchSimulatorWda(opts: LaunchOpts): Promise<LaunchResult>;
@@ -0,0 +1,257 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join } from "node:path";
4
+ import { parseWdaPort } from "./target.js";
5
+ export function resolveWdaProjectPath(projectDir) {
6
+ const tryResolve = (anchor) => {
7
+ try {
8
+ const require = createRequire(anchor);
9
+ const pkgJson = require.resolve("appium-webdriveragent/package.json");
10
+ const pkgDir = dirname(pkgJson);
11
+ return join(pkgDir, "WebDriverAgent.xcodeproj");
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ };
17
+ if (projectDir) {
18
+ const fromConsumer = tryResolve(new URL("package.json", `file://${projectDir.endsWith("/") ? projectDir : projectDir + "/"}`));
19
+ if (fromConsumer)
20
+ return fromConsumer;
21
+ }
22
+ return tryResolve(import.meta.url);
23
+ }
24
+ export async function launchSimulatorWda(opts) {
25
+ const project = resolveWdaProjectPath(opts.projectDir);
26
+ if (!project) {
27
+ return {
28
+ ok: false,
29
+ reason: "wda-package-missing",
30
+ error: "Simulator WDA requires the `appium-webdriveragent` package, " +
31
+ "but it isn't installed. Run `npm i -D appium-webdriveragent` " +
32
+ "(or `pnpm add -D appium-webdriveragent`) in your project, then " +
33
+ "call `rn_wda_start` again. This is an optional dep — device-" +
34
+ "only setups don't need it.",
35
+ };
36
+ }
37
+ const xcb = await commandExists("xcodebuild");
38
+ if (!xcb) {
39
+ return {
40
+ ok: false,
41
+ reason: "xcodebuild-missing",
42
+ error: "`xcodebuild` not found on PATH. Install Xcode (full app, not " +
43
+ "just Command Line Tools) and accept the license: " +
44
+ "`sudo xcodebuild -license accept`.",
45
+ };
46
+ }
47
+ const args = [
48
+ "test-without-building",
49
+ "-project",
50
+ project,
51
+ "-scheme",
52
+ "WebDriverAgentRunner",
53
+ "-destination",
54
+ `platform=iOS Simulator,id=${opts.udid}`,
55
+ ];
56
+ if (opts.derivedDataPath) {
57
+ args.push("-derivedDataPath", opts.derivedDataPath);
58
+ }
59
+ args.push("-quiet");
60
+ let child;
61
+ try {
62
+ child = spawn("xcodebuild", args, {
63
+ stdio: ["ignore", "pipe", "pipe"],
64
+ });
65
+ }
66
+ catch (err) {
67
+ return {
68
+ ok: false,
69
+ reason: "xcodebuild-spawn-failed",
70
+ error: `Failed to spawn xcodebuild: ${err instanceof Error ? err.message : String(err)}`,
71
+ };
72
+ }
73
+ try {
74
+ opts.onChildSpawned?.(child);
75
+ }
76
+ catch (err) {
77
+ try {
78
+ child.kill("SIGTERM");
79
+ }
80
+ catch {
81
+ }
82
+ return {
83
+ ok: false,
84
+ reason: "xcodebuild-spawn-failed",
85
+ error: `onChildSpawned callback threw: ${err instanceof Error ? err.message : String(err)}`,
86
+ };
87
+ }
88
+ const output = [];
89
+ const pushLine = (chunk) => {
90
+ for (const line of chunk.split("\n")) {
91
+ if (!line.trim())
92
+ continue;
93
+ output.push(line);
94
+ if (output.length > 200)
95
+ output.shift();
96
+ }
97
+ };
98
+ let captured = null;
99
+ const checkPort = (chunk) => {
100
+ if (captured !== null)
101
+ return;
102
+ const port = parseWdaPort(output.join("\n") + "\n" + chunk);
103
+ if (port !== null)
104
+ captured = port;
105
+ };
106
+ child.stdout?.on("data", (d) => {
107
+ const text = d.toString();
108
+ pushLine(text);
109
+ checkPort(text);
110
+ });
111
+ child.stderr?.on("data", (d) => {
112
+ const text = d.toString();
113
+ pushLine(text);
114
+ checkPort(text);
115
+ });
116
+ let exited = false;
117
+ let exitCode = null;
118
+ child.on("exit", (code) => {
119
+ exited = true;
120
+ exitCode = code;
121
+ });
122
+ const startupTimeoutMs = opts.startupTimeoutMs ?? 120_000;
123
+ const pollIntervalMs = 250;
124
+ const start = Date.now();
125
+ while (Date.now() - start < startupTimeoutMs) {
126
+ if (captured !== null)
127
+ break;
128
+ if (exited)
129
+ break;
130
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
131
+ }
132
+ if (captured !== null && !exited) {
133
+ const port = captured;
134
+ return {
135
+ ok: true,
136
+ session: buildSession({ port, udid: opts.udid, projectPath: project, child, output }),
137
+ };
138
+ }
139
+ if (captured !== null && exited) {
140
+ return {
141
+ ok: false,
142
+ reason: "xcodebuild-exited-early",
143
+ error: `xcodebuild printed the WDA port marker but then exited with ` +
144
+ `code ${exitCode} before the session could be handed off. ` +
145
+ "This usually means the test target crashed during boot " +
146
+ "(check the simulator logs) or the simulator was shut down " +
147
+ "mid-build. Last 20 lines of xcodebuild output below.",
148
+ output: output.slice(-20),
149
+ };
150
+ }
151
+ try {
152
+ child.kill("SIGTERM");
153
+ }
154
+ catch {
155
+ }
156
+ if (exited) {
157
+ return {
158
+ ok: false,
159
+ reason: "xcodebuild-exited-early",
160
+ error: `xcodebuild exited with code ${exitCode} before WDA reported a port. ` +
161
+ "Most common cause: WebDriverAgentRunner has no code-signing " +
162
+ "identity selected. Open the project in Xcode once " +
163
+ `(\`open "${project}"\`), set a Development Team on the ` +
164
+ "WebDriverAgentRunner target, build it manually for the simulator, " +
165
+ "then retry `rn_wda_start`. Last 20 lines of xcodebuild output " +
166
+ "below.",
167
+ output: output.slice(-20),
168
+ };
169
+ }
170
+ return {
171
+ ok: false,
172
+ reason: "port-not-detected",
173
+ error: `xcodebuild ran for ${startupTimeoutMs}ms without printing the ` +
174
+ "WDA `ServerURLHere->...<-ServerURLHere` marker. The first build " +
175
+ "after installing `appium-webdriveragent` is usually the culprit " +
176
+ "— it can take 90+ seconds AND may surface an Xcode signing " +
177
+ "prompt. Open the project in Xcode " +
178
+ `(\`open "${project}"\`), set a Development Team on the ` +
179
+ "WebDriverAgentRunner target, build it once, then retry. Last 20 " +
180
+ "lines of xcodebuild output below.",
181
+ output: output.slice(-20),
182
+ };
183
+ }
184
+ function buildSession(args) {
185
+ let stopped = false;
186
+ const stop = async () => {
187
+ if (stopped)
188
+ return;
189
+ stopped = true;
190
+ if (args.child.exitCode !== null)
191
+ return;
192
+ try {
193
+ args.child.kill("SIGTERM");
194
+ }
195
+ catch {
196
+ return;
197
+ }
198
+ await new Promise((resolve) => {
199
+ let resolved = false;
200
+ const onExit = () => {
201
+ if (resolved)
202
+ return;
203
+ resolved = true;
204
+ resolve();
205
+ };
206
+ args.child.once("exit", onExit);
207
+ if (args.child.exitCode !== null) {
208
+ args.child.off("exit", onExit);
209
+ resolved = true;
210
+ resolve();
211
+ return;
212
+ }
213
+ setTimeout(() => {
214
+ if (resolved)
215
+ return;
216
+ try {
217
+ args.child.kill("SIGKILL");
218
+ }
219
+ catch {
220
+ }
221
+ setTimeout(() => {
222
+ if (resolved)
223
+ return;
224
+ args.child.off("exit", onExit);
225
+ resolved = true;
226
+ resolve();
227
+ }, 2000);
228
+ }, 5000);
229
+ });
230
+ };
231
+ return {
232
+ port: args.port,
233
+ udid: args.udid,
234
+ projectPath: args.projectPath,
235
+ process: args.child,
236
+ output: args.output,
237
+ stop,
238
+ };
239
+ }
240
+ async function commandExists(cmd) {
241
+ return new Promise((resolve) => {
242
+ let child;
243
+ try {
244
+ child = spawn("which", [cmd], { stdio: ["ignore", "pipe", "pipe"] });
245
+ }
246
+ catch {
247
+ resolve(false);
248
+ return;
249
+ }
250
+ let out = "";
251
+ child.stdout?.on("data", (d) => {
252
+ out += d.toString();
253
+ });
254
+ child.on("error", () => resolve(false));
255
+ child.on("exit", (code) => resolve(code === 0 && out.trim().length > 0));
256
+ });
257
+ }
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@ceraph/react-native-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "MCP server for React Native and Expo development workflow",
5
+ "homepage": "https://ceraph.dev",
6
+ "bugs": {
7
+ "url": "https://x.com/intent/post?text=%40FounderIke%20"
8
+ },
5
9
  "type": "module",
6
10
  "main": "./dist/index.js",
7
11
  "types": "./dist/index.d.ts",
@@ -12,23 +16,52 @@
12
16
  ".": {
13
17
  "types": "./dist/index.d.ts",
14
18
  "import": "./dist/index.js"
19
+ },
20
+ "./shim": {
21
+ "types": "./dist/shim/index.d.ts",
22
+ "import": "./dist/shim/index.js",
23
+ "react-native": "./dist/shim/index.js"
15
24
  }
16
25
  },
17
26
  "files": [
18
27
  "dist",
19
- "README.md"
28
+ "assets",
29
+ "README.md",
30
+ "LICENSE"
20
31
  ],
21
32
  "scripts": {
22
- "build": "tsc",
23
- "typecheck": "tsc --noEmit",
33
+ "build": "tsc && tsc -p tsconfig.shim.json",
34
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.shim.json",
24
35
  "test": "vitest run --passWithNoTests"
25
36
  },
26
37
  "dependencies": {
27
38
  "@modelcontextprotocol/sdk": "^1.29.0",
39
+ "plist": "^3.1.1",
40
+ "ts-morph": "^25",
28
41
  "zod": "^3.25.0"
29
42
  },
43
+ "optionalDependencies": {
44
+ "keytar": "^7.9.0"
45
+ },
46
+ "peerDependencies": {
47
+ "expo-camera": "*",
48
+ "react": "*",
49
+ "react-native": "*"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "react": {
53
+ "optional": true
54
+ },
55
+ "react-native": {
56
+ "optional": true
57
+ },
58
+ "expo-camera": {
59
+ "optional": true
60
+ }
61
+ },
30
62
  "devDependencies": {
31
63
  "@types/node": "^22",
64
+ "@types/plist": "^3.0.5",
32
65
  "typescript": "^5.7",
33
66
  "vitest": "^3"
34
67
  },
@@ -38,5 +71,5 @@
38
71
  "publishConfig": {
39
72
  "access": "public"
40
73
  },
41
- "license": "MIT"
74
+ "license": "SEE LICENSE IN LICENSE"
42
75
  }