@ceraph/react-native-mcp 0.3.3 → 0.4.6

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
package/dist/target.js DELETED
@@ -1,267 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- function runCommand(cmd, args, opts = {}) {
3
- return new Promise((resolve) => {
4
- let stdout = "";
5
- let stderr = "";
6
- let child;
7
- try {
8
- child = spawn(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
9
- }
10
- catch (err) {
11
- resolve({
12
- code: 127,
13
- stdout: "",
14
- stderr: err instanceof Error ? err.message : String(err),
15
- });
16
- return;
17
- }
18
- const timer = setTimeout(() => {
19
- try {
20
- child.kill("SIGKILL");
21
- }
22
- catch {
23
- }
24
- }, opts.timeoutMs ?? 8000);
25
- child.stdout?.on("data", (d) => {
26
- stdout += d.toString();
27
- });
28
- child.stderr?.on("data", (d) => {
29
- stderr += d.toString();
30
- });
31
- let settled = false;
32
- child.on("error", (err) => {
33
- if (settled)
34
- return;
35
- settled = true;
36
- clearTimeout(timer);
37
- resolve({
38
- code: 127,
39
- stdout,
40
- stderr: stderr + (err.message ?? String(err)),
41
- });
42
- });
43
- child.on("exit", (code) => {
44
- if (settled)
45
- return;
46
- settled = true;
47
- clearTimeout(timer);
48
- resolve({ code: code ?? 1, stdout, stderr });
49
- });
50
- });
51
- }
52
- export function preferenceFromEnv(raw) {
53
- const v = (raw ?? "").trim().toLowerCase();
54
- if (v === "device")
55
- return "device";
56
- if (v === "simulator" || v === "sim")
57
- return "simulator";
58
- return "auto";
59
- }
60
- export async function listBootedSimulators() {
61
- const res = await runCommand("xcrun", [
62
- "simctl",
63
- "list",
64
- "devices",
65
- "booted",
66
- "-j",
67
- ]);
68
- if (res.code !== 0)
69
- return [];
70
- try {
71
- const parsed = JSON.parse(res.stdout);
72
- const out = [];
73
- const devices = parsed.devices ?? {};
74
- for (const [runtimeKey, list] of Object.entries(devices)) {
75
- const isIos = runtimeKey.toLowerCase().includes("ios") ||
76
- runtimeKey.toLowerCase().includes("iphone");
77
- if (!isIos)
78
- continue;
79
- if (!Array.isArray(list))
80
- continue;
81
- for (const dev of list) {
82
- if (!dev.udid)
83
- continue;
84
- if ((dev.state ?? "").toLowerCase() !== "booted")
85
- continue;
86
- out.push({
87
- udid: dev.udid,
88
- name: dev.name ?? dev.udid,
89
- runtime: dev.runtime ?? runtimeKey,
90
- });
91
- }
92
- }
93
- return out;
94
- }
95
- catch {
96
- return [];
97
- }
98
- }
99
- export function parseWdaPort(stdout) {
100
- const re = /ServerURLHere->https?:\/\/[^:/\s]+:(\d{2,5})<-ServerURLHere/;
101
- const m = re.exec(stdout);
102
- if (!m)
103
- return null;
104
- const port = Number(m[1]);
105
- if (!Number.isFinite(port) || port < 1 || port > 65535)
106
- return null;
107
- return port;
108
- }
109
- export const DEFAULT_DEVICE_WDA_BASE_URL = "http://localhost:8100";
110
- export function simulatorWdaBaseUrl(port) {
111
- return `http://localhost:${port}`;
112
- }
113
- export class TargetResolver {
114
- apps;
115
- readPreference;
116
- cached = null;
117
- cachedAt = 0;
118
- cacheTtlMs;
119
- inflight = null;
120
- stateVersion = 0;
121
- simulatorWdaPort = null;
122
- simulatorWdaUdid = null;
123
- constructor(opts = {}) {
124
- this.apps = opts.apps ?? null;
125
- this.readPreference = opts.readPreference ?? (() => preferenceFromEnv(process.env.CERAPH_TARGET));
126
- this.cacheTtlMs = opts.cacheTtlMs ?? 5_000;
127
- }
128
- setAppLifecycle(apps) {
129
- this.apps = apps;
130
- this.cached = null;
131
- this.stateVersion++;
132
- }
133
- setSimulatorWdaPort(port, udid) {
134
- this.simulatorWdaPort = port;
135
- this.simulatorWdaUdid = udid;
136
- this.cached = null;
137
- this.stateVersion++;
138
- }
139
- clearSimulatorWdaPort() {
140
- this.simulatorWdaPort = null;
141
- this.simulatorWdaUdid = null;
142
- this.cached = null;
143
- this.stateVersion++;
144
- }
145
- getSimulatorWdaPort() {
146
- return this.simulatorWdaPort;
147
- }
148
- getSimulatorWdaUdid() {
149
- return this.simulatorWdaUdid;
150
- }
151
- invalidate() {
152
- this.cached = null;
153
- this.stateVersion++;
154
- }
155
- async getBaseUrl() {
156
- const info = await this.resolve();
157
- return info.baseUrl;
158
- }
159
- async getTarget() {
160
- const info = await this.resolve();
161
- return info.target;
162
- }
163
- async resolve() {
164
- if (this.cached &&
165
- this.cacheTtlMs > 0 &&
166
- Date.now() - this.cachedAt < this.cacheTtlMs) {
167
- return this.cached;
168
- }
169
- if (this.inflight)
170
- return this.inflight;
171
- const versionAtStart = this.stateVersion;
172
- const work = (async () => {
173
- const pref = this.readPreference();
174
- if (pref === "device") {
175
- const udid = (await this.apps?.getUdid()) ?? null;
176
- return {
177
- target: "device",
178
- udid,
179
- baseUrl: DEFAULT_DEVICE_WDA_BASE_URL,
180
- wdaReady: true,
181
- reason: "env-override-device",
182
- };
183
- }
184
- if (pref === "simulator") {
185
- const sims = await listBootedSimulators();
186
- const picked = this.simulatorWdaUdid
187
- ? sims.find((s) => s.udid === this.simulatorWdaUdid) ?? sims[0]
188
- : sims[0];
189
- const pickedUdid = picked?.udid ?? this.simulatorWdaUdid ?? null;
190
- const wdaHostStillBooted = this.simulatorWdaUdid !== null &&
191
- sims.some((s) => s.udid === this.simulatorWdaUdid);
192
- const portMatchesSim = this.simulatorWdaPort !== null &&
193
- this.simulatorWdaUdid !== null &&
194
- wdaHostStillBooted &&
195
- pickedUdid === this.simulatorWdaUdid;
196
- return {
197
- target: "simulator",
198
- udid: pickedUdid,
199
- baseUrl: portMatchesSim
200
- ? simulatorWdaBaseUrl(this.simulatorWdaPort)
201
- : DEFAULT_DEVICE_WDA_BASE_URL,
202
- wdaReady: portMatchesSim,
203
- reason: "env-override-simulator",
204
- };
205
- }
206
- const [deviceUdid, sims] = await Promise.all([
207
- this.apps?.getUdid() ?? Promise.resolve(null),
208
- listBootedSimulators(),
209
- ]);
210
- if (deviceUdid) {
211
- return {
212
- target: "device",
213
- udid: deviceUdid,
214
- baseUrl: DEFAULT_DEVICE_WDA_BASE_URL,
215
- wdaReady: true,
216
- reason: "auto-prefer-device",
217
- };
218
- }
219
- if (sims.length > 0) {
220
- const picked = this.simulatorWdaUdid
221
- ? sims.find((s) => s.udid === this.simulatorWdaUdid) ?? sims[0]
222
- : sims[0];
223
- const wdaHostStillBooted = this.simulatorWdaUdid !== null &&
224
- sims.some((s) => s.udid === this.simulatorWdaUdid);
225
- const portMatchesSim = this.simulatorWdaPort !== null &&
226
- this.simulatorWdaUdid !== null &&
227
- wdaHostStillBooted &&
228
- picked.udid === this.simulatorWdaUdid;
229
- return {
230
- target: "simulator",
231
- udid: picked.udid,
232
- baseUrl: portMatchesSim
233
- ? simulatorWdaBaseUrl(this.simulatorWdaPort)
234
- : DEFAULT_DEVICE_WDA_BASE_URL,
235
- wdaReady: portMatchesSim,
236
- reason: "auto-only-simulator",
237
- };
238
- }
239
- return {
240
- target: "device",
241
- udid: null,
242
- baseUrl: DEFAULT_DEVICE_WDA_BASE_URL,
243
- wdaReady: true,
244
- reason: "auto-no-target-found",
245
- };
246
- })();
247
- this.inflight = work;
248
- try {
249
- const info = await work;
250
- if (this.stateVersion === versionAtStart) {
251
- this.cached = info;
252
- this.cachedAt = Date.now();
253
- }
254
- return info;
255
- }
256
- finally {
257
- this.inflight = null;
258
- }
259
- }
260
- reset() {
261
- this.cached = null;
262
- this.inflight = null;
263
- this.simulatorWdaPort = null;
264
- this.simulatorWdaUdid = null;
265
- this.stateVersion++;
266
- }
267
- }
@@ -1,32 +0,0 @@
1
- import { type PromptDeps } from "../init/prompt.js";
2
- import { type UninstallStep, type UninstallWalkthroughResult } from "./walkthrough.js";
3
- export interface CliRunnerOpts extends PromptDeps {
4
- argv: string[];
5
- cwd?: string;
6
- spawnRemove?: (input: {
7
- bin: string;
8
- args: string[];
9
- cwd: string;
10
- }) => Promise<{
11
- exitCode: number;
12
- }>;
13
- }
14
- export interface CliRunnerResult {
15
- exitCode: 0 | 1;
16
- walkthrough: UninstallWalkthroughResult | null;
17
- parsedFlags: ParsedFlags;
18
- }
19
- interface ParsedFlags {
20
- yes: boolean;
21
- purgeImages: boolean;
22
- global: boolean;
23
- dryRun: boolean;
24
- projectDir: string | null;
25
- help: boolean;
26
- unknown: string[];
27
- }
28
- export declare function runUninstallCli(opts: CliRunnerOpts): Promise<CliRunnerResult>;
29
- export declare function formatStepLine(step: UninstallStep): string;
30
- export declare function formatSummary(result: UninstallWalkthroughResult): string;
31
- export declare function parseArgs(argv: string[]): ParsedFlags;
32
- export {};
@@ -1,223 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { stat } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { confirm, print } from "../init/prompt.js";
5
- import { runUninstallWalkthrough, } from "./walkthrough.js";
6
- const USAGE = `Usage: npx @ceraph/react-native-mcp uninstall [flags]
7
-
8
- Removes Ceraph from the current React Native / Expo project. By default:
9
- - Reverts source-tree edits (CameraView, layout boot, ceraph URL scheme)
10
- - Strips MCP client configs (.mcp.json, .cursor/, .vscode/, .codex/)
11
- - Removes gitignore entries
12
- - Removes CERAPH_SIGNAL_HOST from your shell rc
13
- - Removes @ceraph/react-native-mcp from package.json
14
- - LEAVES .ceraph/ (test images, design snapshots) in place
15
- - LEAVES ~/.ceraph/auth.json in place (token is user-global)
16
-
17
- Flags:
18
- -y, --yes Skip confirmation prompts.
19
- --purge-images Also delete .ceraph/ (camera images + snapshots).
20
- --global Also delete ~/.ceraph/auth.json (logs you out of
21
- every Ceraph install on this machine).
22
- --dry-run Preview the revert without mutating anything.
23
- --project-dir <p> Operate on this subpackage. Required when a
24
- monorepo has more than one RN app.
25
- -h, --help Print this help and exit.
26
- `;
27
- export async function runUninstallCli(opts) {
28
- const flags = parseArgs(opts.argv);
29
- if (flags.help) {
30
- print(USAGE, opts);
31
- return { exitCode: 0, walkthrough: null, parsedFlags: flags };
32
- }
33
- if (flags.unknown.length > 0) {
34
- print(`Unknown flag(s): ${flags.unknown.join(", ")}\n\n${USAGE}`, opts);
35
- return { exitCode: 1, walkthrough: null, parsedFlags: flags };
36
- }
37
- const projectDir = flags.projectDir ?? opts.cwd ?? process.cwd();
38
- if (flags.projectDir != null) {
39
- const validation = await validateProjectDir(flags.projectDir);
40
- if (validation !== null) {
41
- print(`${validation}\n`, opts);
42
- return { exitCode: 1, walkthrough: null, parsedFlags: flags };
43
- }
44
- }
45
- let purgeImages = flags.purgeImages;
46
- let global = flags.global;
47
- if (!flags.yes && !flags.dryRun) {
48
- print(`\n@ceraph/react-native-mcp uninstall\n`, opts);
49
- print(` Project: ${projectDir}\n`, opts);
50
- print(` Mode: live (no --dry-run)\n`, opts);
51
- print(` Default-safe: leaves .ceraph/ and ~/.ceraph/auth.json untouched.\n\n`, opts);
52
- const proceed = await confirm("Continue with uninstall?", {
53
- ...opts,
54
- defaultYes: false,
55
- });
56
- if (!proceed) {
57
- print(`\nAborted — no changes made.\n`, opts);
58
- return { exitCode: 0, walkthrough: null, parsedFlags: flags };
59
- }
60
- if (!purgeImages) {
61
- purgeImages = await confirm("Also purge camera images + snapshots at .ceraph/?", { ...opts, defaultYes: false });
62
- }
63
- if (!global) {
64
- global = await confirm("Also sign out (delete ~/.ceraph/auth.json)?", { ...opts, defaultYes: false });
65
- }
66
- }
67
- if (flags.dryRun) {
68
- print(`\n@ceraph/react-native-mcp uninstall — dry-run preview\n`, opts);
69
- print(` Project: ${projectDir}\n\n`, opts);
70
- }
71
- const walkthrough = await runUninstallWalkthrough({
72
- projectDir,
73
- purgeImages,
74
- global,
75
- dryRun: flags.dryRun,
76
- nonInteractive: flags.yes,
77
- spawnRemove: opts.spawnRemove ?? defaultSpawnRemove,
78
- onStep: (step) => {
79
- print(formatStepLine(step), opts);
80
- },
81
- });
82
- print(formatSummary(walkthrough), opts);
83
- const hasError = walkthrough.steps.some((s) => s.status === "error" || s.status === "manual");
84
- return {
85
- exitCode: hasError ? 1 : 0,
86
- walkthrough,
87
- parsedFlags: { ...flags, purgeImages, global },
88
- };
89
- }
90
- export function formatStepLine(step) {
91
- const icon = iconFor(step.status);
92
- const summary = summaryFor(step);
93
- return ` ${icon} ${step.name.padEnd(13)} ${summary}\n`;
94
- }
95
- function iconFor(status) {
96
- switch (status) {
97
- case "reverted":
98
- return "[ok]";
99
- case "already-reverted":
100
- return "[--]";
101
- case "skipped":
102
- return "[--]";
103
- case "warning":
104
- return "[!]";
105
- case "manual":
106
- return "[!]";
107
- case "error":
108
- return "[X]";
109
- }
110
- }
111
- function summaryFor(step) {
112
- switch (step.status) {
113
- case "reverted":
114
- return `reverted${step.details?.dryRun ? " (preview)" : ""}`;
115
- case "already-reverted":
116
- return `nothing to do${step.details?.dryRun ? " (preview)" : ""}`;
117
- case "skipped":
118
- return `skipped — ${step.remediation ?? "gate closed"}`;
119
- case "warning":
120
- return `reverted with warning — ${step.remediation ?? ""}`;
121
- case "manual":
122
- return `manual action required — ${step.remediation ?? ""}`;
123
- case "error":
124
- return `error — ${step.remediation ?? step.details?.error ?? "see details"}`;
125
- }
126
- }
127
- export function formatSummary(result) {
128
- const { reverted, skipped, warnings, manualSteps } = result.summary;
129
- const lines = ["\nSummary:\n"];
130
- lines.push(` Reverted: ${reverted}\n`);
131
- lines.push(` Skipped/no-op: ${skipped}\n`);
132
- lines.push(` Warnings: ${warnings.length}\n`);
133
- lines.push(` Manual actions: ${manualSteps.length}\n`);
134
- if (warnings.length > 0) {
135
- lines.push(`\nWarnings:\n`);
136
- for (const w of warnings)
137
- lines.push(` - ${w}\n`);
138
- }
139
- if (manualSteps.length > 0) {
140
- lines.push(`\nManual actions needed:\n`);
141
- for (const m of manualSteps)
142
- lines.push(` - ${m}\n`);
143
- }
144
- return lines.join("");
145
- }
146
- export function parseArgs(argv) {
147
- const flags = {
148
- yes: false,
149
- purgeImages: false,
150
- global: false,
151
- dryRun: false,
152
- projectDir: null,
153
- help: false,
154
- unknown: [],
155
- };
156
- for (let i = 0; i < argv.length; i++) {
157
- const arg = argv[i];
158
- switch (arg) {
159
- case "-y":
160
- case "--yes":
161
- flags.yes = true;
162
- break;
163
- case "--purge-images":
164
- flags.purgeImages = true;
165
- break;
166
- case "--global":
167
- flags.global = true;
168
- break;
169
- case "--dry-run":
170
- flags.dryRun = true;
171
- break;
172
- case "--project-dir": {
173
- const next = argv[i + 1];
174
- if (next == null) {
175
- flags.unknown.push(`${arg} (missing value)`);
176
- }
177
- else {
178
- flags.projectDir = next;
179
- i++;
180
- }
181
- break;
182
- }
183
- case "-h":
184
- case "--help":
185
- flags.help = true;
186
- break;
187
- default:
188
- if (arg !== undefined)
189
- flags.unknown.push(arg);
190
- }
191
- }
192
- return flags;
193
- }
194
- async function validateProjectDir(path) {
195
- let entryStat;
196
- try {
197
- entryStat = await stat(path);
198
- }
199
- catch {
200
- return `Error: --project-dir does not exist: ${path}`;
201
- }
202
- if (!entryStat.isDirectory()) {
203
- return `Error: --project-dir is not a directory: ${path}`;
204
- }
205
- try {
206
- await stat(join(path, "package.json"));
207
- }
208
- catch {
209
- return (`Error: --project-dir does not look like an npm/RN project ` +
210
- `(no package.json at ${join(path, "package.json")})`);
211
- }
212
- return null;
213
- }
214
- function defaultSpawnRemove(input) {
215
- return new Promise((resolve) => {
216
- const child = spawn(input.bin, input.args, {
217
- cwd: input.cwd,
218
- stdio: "inherit",
219
- });
220
- child.on("error", () => resolve({ exitCode: 127 }));
221
- child.on("exit", (code) => resolve({ exitCode: code ?? 1 }));
222
- });
223
- }
@@ -1,40 +0,0 @@
1
- import { detectMonorepoSubpackages } from "../init/monorepo.js";
2
- import { type PackageManager } from "./revert-package.js";
3
- export interface InstalledFootprint {
4
- workingDir: string;
5
- monorepoConflict: {
6
- matches: Array<{
7
- relPath: string;
8
- absPath: string;
9
- }>;
10
- } | null;
11
- packageInstalled: boolean;
12
- packageManager: PackageManager;
13
- appiumPresent: boolean;
14
- gitignoreEntriesPresent: boolean;
15
- gitignoreEntries: string[];
16
- schemeRegistered: boolean | null;
17
- bootTargetPath: string | null;
18
- bootInjected: boolean | null;
19
- ceraphCameraUsageCount: number;
20
- mcpClientsConfigured: {
21
- claudeCode: boolean;
22
- cursor: boolean;
23
- codex: boolean;
24
- vscode: boolean;
25
- windsurf: boolean;
26
- antigravity: boolean;
27
- };
28
- claudeHooksPresent: {
29
- errorScript: boolean;
30
- flowProgressScript: boolean;
31
- settingsEntries: boolean;
32
- };
33
- ceraphDirPresent: boolean;
34
- authPresent: boolean;
35
- }
36
- export interface FootprintDeps {
37
- homeDir?: () => string;
38
- detectMonorepo?: typeof detectMonorepoSubpackages;
39
- }
40
- export declare function getInstalledFootprint(projectDir: string, deps?: FootprintDeps): Promise<InstalledFootprint>;