@ceraph/react-native-mcp 0.3.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +335 -68
  2. package/dist/babel-plugin/index.cjs +1 -0
  3. package/dist/babel-plugin/index.js +1 -0
  4. package/dist/cli.d.ts +3 -1
  5. package/dist/cli.js +1 -47
  6. package/dist/index.d.ts +106 -1
  7. package/dist/index.js +2 -1651
  8. package/dist/shim/async-storage-ops.d.ts +26 -0
  9. package/dist/shim/async-storage-ops.js +1 -0
  10. package/dist/shim/boot.d.ts +9 -0
  11. package/dist/shim/boot.js +1 -141
  12. package/dist/shim/camera.js +1 -62
  13. package/dist/shim/command-poll.d.ts +18 -0
  14. package/dist/shim/command-poll.js +1 -0
  15. package/dist/shim/config.js +1 -56
  16. package/dist/shim/console-capture.d.ts +16 -0
  17. package/dist/shim/console-capture.js +1 -0
  18. package/dist/shim/deep-link.js +1 -25
  19. package/dist/shim/dev-guard.js +1 -3
  20. package/dist/shim/dev-host.d.ts +1 -0
  21. package/dist/shim/dev-host.js +1 -0
  22. package/dist/shim/error-handler.js +1 -66
  23. package/dist/shim/fetch-interceptor.js +1 -93
  24. package/dist/shim/index.d.ts +3 -0
  25. package/dist/shim/index.js +1 -6
  26. package/dist/shim/keep-awake.js +1 -118
  27. package/dist/shim/network-ownership.d.ts +4 -0
  28. package/dist/shim/network-ownership.js +1 -0
  29. package/dist/shim/optimistic-observer.d.ts +29 -0
  30. package/dist/shim/optimistic-observer.js +1 -0
  31. package/dist/shim/reload.js +1 -76
  32. package/dist/shim/reset.d.ts +30 -0
  33. package/dist/shim/reset.js +1 -0
  34. package/dist/shim/signal-capture.d.ts +8 -0
  35. package/dist/shim/signal-capture.js +1 -15
  36. package/dist/shim/signal-transport.d.ts +14 -1
  37. package/dist/shim/signal-transport.js +1 -43
  38. package/dist/shim/xhr-interceptor.d.ts +39 -0
  39. package/dist/shim/xhr-interceptor.js +1 -0
  40. package/package.json +40 -11
  41. package/dist/app-lifecycle.d.ts +0 -50
  42. package/dist/app-lifecycle.js +0 -487
  43. package/dist/camera-image-writer.d.ts +0 -43
  44. package/dist/camera-image-writer.js +0 -280
  45. package/dist/camera-registry-sync.d.ts +0 -18
  46. package/dist/camera-registry-sync.js +0 -117
  47. package/dist/device-autonomy.d.ts +0 -30
  48. package/dist/device-autonomy.js +0 -117
  49. package/dist/error-parser.d.ts +0 -51
  50. package/dist/error-parser.js +0 -275
  51. package/dist/expo-manager.d.ts +0 -62
  52. package/dist/expo-manager.js +0 -447
  53. package/dist/init/ast-camera.d.ts +0 -29
  54. package/dist/init/ast-camera.js +0 -267
  55. package/dist/init/ast-layout.d.ts +0 -15
  56. package/dist/init/ast-layout.js +0 -167
  57. package/dist/init/claude-hook-constants.d.ts +0 -9
  58. package/dist/init/claude-hook-constants.js +0 -91
  59. package/dist/init/lan-ip.d.ts +0 -11
  60. package/dist/init/lan-ip.js +0 -51
  61. package/dist/init/monorepo.d.ts +0 -13
  62. package/dist/init/monorepo.js +0 -185
  63. package/dist/init/oauth.d.ts +0 -52
  64. package/dist/init/oauth.js +0 -220
  65. package/dist/init/package-manager.d.ts +0 -11
  66. package/dist/init/package-manager.js +0 -60
  67. package/dist/init/prompt.d.ts +0 -12
  68. package/dist/init/prompt.js +0 -68
  69. package/dist/init/shell-profile.d.ts +0 -22
  70. package/dist/init/shell-profile.js +0 -85
  71. package/dist/init/steps.d.ts +0 -135
  72. package/dist/init/steps.js +0 -399
  73. package/dist/init/url-scheme.d.ts +0 -42
  74. package/dist/init/url-scheme.js +0 -187
  75. package/dist/init/walkthrough.d.ts +0 -76
  76. package/dist/init/walkthrough.js +0 -340
  77. package/dist/init.d.ts +0 -8
  78. package/dist/init.js +0 -395
  79. package/dist/iproxy-manager.d.ts +0 -32
  80. package/dist/iproxy-manager.js +0 -216
  81. package/dist/mac-caffeinate.d.ts +0 -10
  82. package/dist/mac-caffeinate.js +0 -56
  83. package/dist/permission-interceptor.d.ts +0 -29
  84. package/dist/permission-interceptor.js +0 -185
  85. package/dist/prebuild-detector.d.ts +0 -19
  86. package/dist/prebuild-detector.js +0 -174
  87. package/dist/preflight.d.ts +0 -34
  88. package/dist/preflight.js +0 -847
  89. package/dist/screen.d.ts +0 -184
  90. package/dist/screen.js +0 -931
  91. package/dist/signal-listener.d.ts +0 -27
  92. package/dist/signal-listener.js +0 -135
  93. package/dist/simulator-boot.d.ts +0 -52
  94. package/dist/simulator-boot.js +0 -227
  95. package/dist/target.d.ts +0 -48
  96. package/dist/target.js +0 -267
  97. package/dist/uninstall/cli-runner.d.ts +0 -32
  98. package/dist/uninstall/cli-runner.js +0 -223
  99. package/dist/uninstall/footprint.d.ts +0 -40
  100. package/dist/uninstall/footprint.js +0 -288
  101. package/dist/uninstall/mcp-tools.d.ts +0 -14
  102. package/dist/uninstall/mcp-tools.js +0 -175
  103. package/dist/uninstall/revert-auth.d.ts +0 -22
  104. package/dist/uninstall/revert-auth.js +0 -31
  105. package/dist/uninstall/revert-boot.d.ts +0 -24
  106. package/dist/uninstall/revert-boot.js +0 -242
  107. package/dist/uninstall/revert-camera.d.ts +0 -12
  108. package/dist/uninstall/revert-camera.js +0 -199
  109. package/dist/uninstall/revert-ceraph-dir.d.ts +0 -27
  110. package/dist/uninstall/revert-ceraph-dir.js +0 -38
  111. package/dist/uninstall/revert-claude-hooks.d.ts +0 -19
  112. package/dist/uninstall/revert-claude-hooks.js +0 -191
  113. package/dist/uninstall/revert-gitignore.d.ts +0 -17
  114. package/dist/uninstall/revert-gitignore.js +0 -43
  115. package/dist/uninstall/revert-mcp-clients.d.ts +0 -57
  116. package/dist/uninstall/revert-mcp-clients.js +0 -194
  117. package/dist/uninstall/revert-package.d.ts +0 -34
  118. package/dist/uninstall/revert-package.js +0 -98
  119. package/dist/uninstall/revert-scheme.d.ts +0 -36
  120. package/dist/uninstall/revert-scheme.js +0 -139
  121. package/dist/uninstall/revert-signal-host-env.d.ts +0 -31
  122. package/dist/uninstall/revert-signal-host-env.js +0 -61
  123. package/dist/uninstall/walkthrough.d.ts +0 -80
  124. package/dist/uninstall/walkthrough.js +0 -1244
  125. package/dist/utils/atomic-write.d.ts +0 -1
  126. package/dist/utils/atomic-write.js +0 -30
  127. package/dist/wait-for-device.d.ts +0 -68
  128. package/dist/wait-for-device.js +0 -368
  129. package/dist/wda-manager.d.ts +0 -38
  130. package/dist/wda-manager.js +0 -186
  131. package/dist/wda-simulator.d.ts +0 -28
  132. package/dist/wda-simulator.js +0 -257
@@ -1,447 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { writeFile, access } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { parseBuildOutput, parseMetroOutput, MetroErrorParser, classifyLogLevel, } from "./error-parser.js";
5
- export class RNManager {
6
- buildProcess = null;
7
- metroProcess = null;
8
- buildKilled = false;
9
- metroKilled = false;
10
- buildOutput = [];
11
- metroOutput = [];
12
- buildErrors = [];
13
- runtimeErrors = [];
14
- buildWarnings = [];
15
- metroWarnings = [];
16
- metroParser = new MetroErrorParser();
17
- MAX_BUILD_LINES = 1000;
18
- MAX_METRO_LINES = 500;
19
- MAX_ERRORS = 100;
20
- cwd;
21
- errorFilePath;
22
- constructor(cwd) {
23
- this.cwd = cwd;
24
- this.errorFilePath = join(cwd, ".rn-errors.json");
25
- }
26
- async detectProjectType() {
27
- try {
28
- const appJsonPath = join(this.cwd, "app.json");
29
- await access(appJsonPath);
30
- const appJson = JSON.parse(await (await import("node:fs/promises")).readFile(appJsonPath, "utf-8"));
31
- if (appJson.expo) {
32
- return true;
33
- }
34
- }
35
- catch {
36
- }
37
- try {
38
- const pkgPath = join(this.cwd, "package.json");
39
- const pkg = JSON.parse(await (await import("node:fs/promises")).readFile(pkgPath, "utf-8"));
40
- if (pkg.dependencies?.expo) {
41
- return true;
42
- }
43
- }
44
- catch {
45
- }
46
- return false;
47
- }
48
- async writeErrorFile(errors) {
49
- try {
50
- await writeFile(this.errorFilePath, JSON.stringify({
51
- timestamp: new Date().toISOString(),
52
- errors: errors.map((e) => ({
53
- message: e.message,
54
- stack: e.stack,
55
- timestamp: e.timestamp,
56
- kind: e.kind ?? "metro-error",
57
- ...(e.url !== undefined ? { url: e.url } : {}),
58
- ...(e.status !== undefined ? { status: e.status } : {}),
59
- ...(e.method !== undefined ? { method: e.method } : {}),
60
- ...(e.durationMs !== undefined ? { durationMs: e.durationMs } : {}),
61
- })),
62
- }, null, 2), "utf-8");
63
- }
64
- catch {
65
- }
66
- }
67
- async appendShimSignal(entry) {
68
- this.runtimeErrors.push(entry);
69
- this.capErrors(this.runtimeErrors);
70
- await this.writeErrorFile(this.runtimeErrors);
71
- }
72
- async clearErrorFile() {
73
- try {
74
- await writeFile(this.errorFilePath, JSON.stringify({ timestamp: new Date().toISOString(), errors: [] }), "utf-8");
75
- }
76
- catch {
77
- }
78
- }
79
- pushLine(buffer, line, max) {
80
- buffer.push(line);
81
- if (buffer.length > max) {
82
- buffer.splice(0, buffer.length - max);
83
- }
84
- }
85
- capErrors(arr) {
86
- if (arr.length > this.MAX_ERRORS) {
87
- arr.splice(0, arr.length - this.MAX_ERRORS);
88
- }
89
- }
90
- async killProcess(proc) {
91
- return new Promise((resolve) => {
92
- if (!proc.pid || proc.exitCode !== null) {
93
- resolve();
94
- return;
95
- }
96
- let hardTimer = null;
97
- const softTimer = setTimeout(() => {
98
- try {
99
- proc.kill("SIGKILL");
100
- }
101
- catch {
102
- }
103
- hardTimer = setTimeout(() => {
104
- proc.off("exit", onExit);
105
- resolve();
106
- }, 2000);
107
- }, 5000);
108
- const onExit = () => {
109
- clearTimeout(softTimer);
110
- if (hardTimer)
111
- clearTimeout(hardTimer);
112
- resolve();
113
- };
114
- proc.once("exit", onExit);
115
- try {
116
- proc.kill("SIGTERM");
117
- }
118
- catch {
119
- proc.off("exit", onExit);
120
- clearTimeout(softTimer);
121
- resolve();
122
- return;
123
- }
124
- if (proc.exitCode !== null) {
125
- proc.off("exit", onExit);
126
- clearTimeout(softTimer);
127
- resolve();
128
- }
129
- });
130
- }
131
- runPrebuildClean() {
132
- return new Promise((resolve) => {
133
- const lines = [];
134
- const proc = spawn("npx", ["expo", "prebuild", "--clean"], {
135
- cwd: this.cwd,
136
- stdio: ["ignore", "pipe", "pipe"],
137
- });
138
- const onData = (data) => {
139
- const text = data.toString();
140
- for (const line of text.split("\n")) {
141
- if (line.trim())
142
- lines.push(line);
143
- }
144
- };
145
- proc.stdout?.on("data", onData);
146
- proc.stderr?.on("data", onData);
147
- let resolved = false;
148
- proc.on("error", (err) => {
149
- if (resolved)
150
- return;
151
- resolved = true;
152
- resolve({
153
- success: false,
154
- output: `Failed to spawn prebuild: ${err.message}`,
155
- });
156
- });
157
- proc.on("exit", (code) => {
158
- if (resolved)
159
- return;
160
- resolved = true;
161
- resolve({
162
- success: code === 0,
163
- output: lines.join("\n"),
164
- });
165
- });
166
- });
167
- }
168
- async runBuild(options = {}) {
169
- const isExpo = await this.detectProjectType();
170
- if (this.buildProcess) {
171
- this.buildKilled = true;
172
- await this.killProcess(this.buildProcess);
173
- this.buildProcess = null;
174
- }
175
- this.buildKilled = false;
176
- this.buildOutput = [];
177
- this.buildErrors = [];
178
- this.buildWarnings = [];
179
- if (options.clean) {
180
- if (!isExpo) {
181
- return {
182
- success: false,
183
- errors: [
184
- {
185
- file: "",
186
- line: 0,
187
- message: "prebuild --clean is only available for Expo projects.",
188
- type: "build",
189
- },
190
- ],
191
- warnings: [],
192
- output: "",
193
- };
194
- }
195
- const prebuildResult = await this.runPrebuildClean();
196
- if (!prebuildResult.success) {
197
- return {
198
- success: false,
199
- errors: [
200
- {
201
- file: "",
202
- line: 0,
203
- message: `prebuild --clean failed:\n${prebuildResult.output}`,
204
- type: "build",
205
- },
206
- ],
207
- warnings: [],
208
- output: prebuildResult.output,
209
- };
210
- }
211
- for (const line of prebuildResult.output.split("\n")) {
212
- this.pushLine(this.buildOutput, line, this.MAX_BUILD_LINES);
213
- }
214
- }
215
- const args = isExpo ? ["expo", "run:ios"] : ["react-native", "run-ios"];
216
- if (options.device) {
217
- args.push(isExpo ? "--device" : "--udid", options.device);
218
- }
219
- return new Promise((resolve) => {
220
- const proc = spawn("npx", args, {
221
- cwd: this.cwd,
222
- stdio: ["ignore", "pipe", "pipe"],
223
- });
224
- this.buildProcess = proc;
225
- const onData = (data) => {
226
- const text = data.toString();
227
- for (const line of text.split("\n")) {
228
- if (line.trim()) {
229
- this.pushLine(this.buildOutput, line, this.MAX_BUILD_LINES);
230
- }
231
- }
232
- };
233
- proc.stdout?.on("data", onData);
234
- proc.stderr?.on("data", onData);
235
- let resolved = false;
236
- proc.on("error", (err) => {
237
- if (resolved)
238
- return;
239
- resolved = true;
240
- this.buildProcess = null;
241
- resolve({
242
- success: false,
243
- errors: [
244
- {
245
- file: "",
246
- line: 0,
247
- message: `Failed to spawn ${isExpo ? "expo run:ios" : "react-native run-ios"}: ${err.message}`,
248
- type: "build",
249
- },
250
- ],
251
- warnings: [],
252
- output: this.buildOutput.join("\n"),
253
- });
254
- });
255
- proc.on("exit", (code) => {
256
- if (resolved)
257
- return;
258
- resolved = true;
259
- this.buildProcess = null;
260
- if (this.buildKilled) {
261
- resolve({
262
- success: false,
263
- errors: [],
264
- warnings: [],
265
- output: "Build was cancelled.",
266
- });
267
- return;
268
- }
269
- const parsed = parseBuildOutput(this.buildOutput);
270
- this.buildErrors = parsed.errors;
271
- this.buildWarnings = parsed.warnings;
272
- this.capErrors(this.buildErrors);
273
- const success = code === 0 && !parsed.buildFailed;
274
- resolve({
275
- success,
276
- errors: parsed.errors.map((e) => ({
277
- file: e.file,
278
- line: e.line,
279
- message: e.message,
280
- type: e.type,
281
- })),
282
- warnings: parsed.warnings,
283
- output: this.buildOutput.slice(-100).join("\n"),
284
- });
285
- });
286
- });
287
- }
288
- async startMetro(options = {}) {
289
- const isExpo = await this.detectProjectType();
290
- if (this.metroProcess) {
291
- this.metroKilled = true;
292
- await this.killProcess(this.metroProcess);
293
- this.metroProcess = null;
294
- }
295
- this.metroKilled = false;
296
- this.metroOutput = [];
297
- this.runtimeErrors = [];
298
- this.metroWarnings = [];
299
- this.metroParser = new MetroErrorParser();
300
- const args = isExpo
301
- ? ["expo", "start", "--dev-client"]
302
- : ["react-native", "start"];
303
- if (options.port) {
304
- args.push("--port", String(options.port));
305
- }
306
- if (options.clear) {
307
- args.push(isExpo ? "--clear" : "--reset-cache");
308
- }
309
- await this.clearErrorFile();
310
- return new Promise((resolve) => {
311
- const proc = spawn("npx", args, {
312
- cwd: this.cwd,
313
- stdio: ["ignore", "pipe", "pipe"],
314
- });
315
- this.metroProcess = proc;
316
- let resolved = false;
317
- const onData = (data) => {
318
- const text = data.toString();
319
- const chunkLines = [];
320
- for (const line of text.split("\n")) {
321
- if (line.trim()) {
322
- this.pushLine(this.metroOutput, line, this.MAX_METRO_LINES);
323
- chunkLines.push(line);
324
- }
325
- }
326
- if (chunkLines.length > 0) {
327
- const parsed = this.metroParser.parse(chunkLines);
328
- if (parsed.runtimeErrors.length > 0) {
329
- this.runtimeErrors.push(...parsed.runtimeErrors);
330
- this.capErrors(this.runtimeErrors);
331
- this.writeErrorFile(this.runtimeErrors);
332
- }
333
- if (parsed.warnings.length > 0) {
334
- this.metroWarnings.push(...parsed.warnings);
335
- }
336
- }
337
- if (!resolved && text.includes("Metro waiting on")) {
338
- resolved = true;
339
- resolve({
340
- success: true,
341
- message: "Metro dev server started successfully.",
342
- });
343
- }
344
- };
345
- proc.stdout?.on("data", onData);
346
- proc.stderr?.on("data", onData);
347
- proc.on("error", (err) => {
348
- this.metroProcess = null;
349
- if (!resolved) {
350
- resolved = true;
351
- resolve({
352
- success: false,
353
- message: `Failed to start Metro: ${err.message}`,
354
- });
355
- }
356
- });
357
- proc.on("exit", (code) => {
358
- this.metroProcess = null;
359
- const flushed = this.metroParser.flush();
360
- if (flushed.runtimeErrors.length > 0) {
361
- this.runtimeErrors.push(...flushed.runtimeErrors);
362
- this.capErrors(this.runtimeErrors);
363
- this.writeErrorFile(this.runtimeErrors);
364
- }
365
- if (this.metroKilled) {
366
- if (!resolved) {
367
- resolved = true;
368
- resolve({
369
- success: false,
370
- message: "Metro was cancelled.",
371
- });
372
- }
373
- return;
374
- }
375
- if (!resolved) {
376
- resolved = true;
377
- resolve({
378
- success: false,
379
- message: `Metro exited unexpectedly with code ${code}.`,
380
- });
381
- }
382
- });
383
- setTimeout(() => {
384
- if (!resolved) {
385
- resolved = true;
386
- resolve({
387
- success: true,
388
- message: "Metro process started but has not confirmed readiness yet. " +
389
- "It may still be initializing. Use rn_get_console to check.",
390
- });
391
- }
392
- }, 30_000);
393
- });
394
- }
395
- getErrors() {
396
- const metroParsed = this.metroProcess === null
397
- ? parseMetroOutput(this.metroOutput)
398
- : { runtimeErrors: [], warnings: [] };
399
- return {
400
- buildErrors: this.buildErrors.map((e) => ({
401
- file: e.file,
402
- line: e.line,
403
- column: e.column,
404
- message: e.message,
405
- severity: e.severity,
406
- type: e.type,
407
- })),
408
- runtimeErrors: this.runtimeErrors.length > 0
409
- ? this.runtimeErrors
410
- : metroParsed.runtimeErrors,
411
- warnings: [...this.buildWarnings, ...this.metroWarnings],
412
- };
413
- }
414
- getConsole(options = {}) {
415
- const { lines = 50, level = "all" } = options;
416
- let output = this.metroOutput;
417
- if (level !== "all") {
418
- output = output.filter((line) => {
419
- const classified = classifyLogLevel(line);
420
- return classified === level;
421
- });
422
- }
423
- return output.slice(-lines);
424
- }
425
- async stopAll() {
426
- const stopped = [];
427
- if (this.buildProcess) {
428
- this.buildKilled = true;
429
- await this.killProcess(this.buildProcess);
430
- this.buildProcess = null;
431
- stopped.push("build");
432
- }
433
- if (this.metroProcess) {
434
- this.metroKilled = true;
435
- await this.killProcess(this.metroProcess);
436
- this.metroProcess = null;
437
- stopped.push("metro");
438
- }
439
- return stopped;
440
- }
441
- getBuildOutput() {
442
- return [...this.buildOutput];
443
- }
444
- getMetroOutput() {
445
- return [...this.metroOutput];
446
- }
447
- }
@@ -1,29 +0,0 @@
1
- export interface CameraReplacementEdit {
2
- filePath: string;
3
- relPath: string;
4
- line: number;
5
- suggestedKey: string;
6
- alreadyHasImageKey: boolean;
7
- }
8
- export interface ScanCameraViewsResult {
9
- edits: CameraReplacementEdit[];
10
- filesScanned: number;
11
- }
12
- export declare function suggestImageKey(absPath: string): string;
13
- export declare function scanCameraViews(projectDir: string): Promise<ScanCameraViewsResult>;
14
- export interface ApplyEditsResult {
15
- filesEdited: string[];
16
- totalReplacements: number;
17
- }
18
- export interface ApplyEditsOptions {
19
- omitImageKey?: boolean;
20
- }
21
- export declare function applyCameraEdits(projectDir: string, edits: CameraReplacementEdit[], options?: ApplyEditsOptions): Promise<ApplyEditsResult>;
22
- export interface SetImageKeyResult {
23
- applied: boolean;
24
- previousValue?: string | null;
25
- reason?: string;
26
- }
27
- export declare function setImageKeyOnExistingTag(filePath: string, line: number, imageKey: string): Promise<SetImageKeyResult>;
28
- export declare function snapshotFile(filePath: string): Promise<string | null>;
29
- export declare function restoreFile(filePath: string, snapshot: string): Promise<void>;