@react-grab/cli 0.1.2 → 0.1.3

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 (3) hide show
  1. package/dist/cli.cjs +157 -554
  2. package/dist/cli.js +155 -552
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
  'use strict';
3
3
 
4
4
  var commander = require('commander');
5
- var pc5 = require('picocolors');
6
- var prompts3 = require('prompts');
5
+ var pc = require('picocolors');
6
+ var basePrompts = require('prompts');
7
7
  var child_process = require('child_process');
8
8
  var fs = require('fs');
9
9
  var path = require('path');
@@ -12,10 +12,53 @@ var ora = require('ora');
12
12
 
13
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
14
 
15
- var pc5__default = /*#__PURE__*/_interopDefault(pc5);
16
- var prompts3__default = /*#__PURE__*/_interopDefault(prompts3);
15
+ var pc__default = /*#__PURE__*/_interopDefault(pc);
16
+ var basePrompts__default = /*#__PURE__*/_interopDefault(basePrompts);
17
17
  var ora__default = /*#__PURE__*/_interopDefault(ora);
18
18
 
19
+ var highlighter = {
20
+ error: pc__default.default.red,
21
+ warn: pc__default.default.yellow,
22
+ info: pc__default.default.cyan,
23
+ success: pc__default.default.green,
24
+ dim: pc__default.default.dim
25
+ };
26
+
27
+ // src/utils/logger.ts
28
+ var logger = {
29
+ error(...args) {
30
+ console.log(highlighter.error(args.join(" ")));
31
+ },
32
+ warn(...args) {
33
+ console.log(highlighter.warn(args.join(" ")));
34
+ },
35
+ info(...args) {
36
+ console.log(highlighter.info(args.join(" ")));
37
+ },
38
+ success(...args) {
39
+ console.log(highlighter.success(args.join(" ")));
40
+ },
41
+ dim(...args) {
42
+ console.log(highlighter.dim(args.join(" ")));
43
+ },
44
+ log(...args) {
45
+ console.log(args.join(" "));
46
+ },
47
+ break() {
48
+ console.log("");
49
+ }
50
+ };
51
+
52
+ // src/utils/prompts.ts
53
+ var onCancel = () => {
54
+ logger.break();
55
+ logger.log("Cancelled.");
56
+ logger.break();
57
+ process.exit(0);
58
+ };
59
+ var prompts = (questions) => {
60
+ return basePrompts__default.default(questions, { onCancel });
61
+ };
19
62
  var detectPackageManager = async (projectRoot) => {
20
63
  const detected = await ni.detect({ cwd: projectRoot });
21
64
  if (detected && ["npm", "yarn", "pnpm", "bun"].includes(detected)) {
@@ -261,85 +304,6 @@ var AGENT_PACKAGES = [
261
304
  "@react-grab/amp",
262
305
  "@react-grab/ami"
263
306
  ];
264
- var REACT_SCAN_DETECTION_PATTERNS = [
265
- /["'`][^"'`]*react-scan/,
266
- /react-scan[^"'`]*["'`]/,
267
- /unpkg\.com\/react-scan/,
268
- /import\s*\(?["']react-scan/,
269
- /require\s*\(["']react-scan/,
270
- /from\s+["']react-scan/,
271
- /<Script[^>]*react-scan/i,
272
- /<script[^>]*react-scan/i
273
- ];
274
- var REACT_SCAN_FILE_PATTERNS = [
275
- ["app", "layout"],
276
- ["src", "app", "layout"],
277
- ["pages", "_document"],
278
- ["pages", "_app"],
279
- ["src", "pages", "_document"],
280
- ["src", "pages", "_app"],
281
- ["index"],
282
- ["public", "index"],
283
- ["src", "index"],
284
- ["src", "main"],
285
- ["src", "routes", "__root"],
286
- ["app", "routes", "__root"]
287
- ];
288
- var SCRIPT_EXTENSIONS = ["tsx", "jsx", "ts", "js"];
289
- var getReactScanFilesToCheck = (projectRoot) => REACT_SCAN_FILE_PATTERNS.flatMap((segments) => {
290
- const baseName = segments[segments.length - 1];
291
- const isHtmlFile = baseName === "index" && segments.length <= 2;
292
- const extensions = isHtmlFile ? [...SCRIPT_EXTENSIONS, "html"] : SCRIPT_EXTENSIONS;
293
- return extensions.map(
294
- (extension) => path.join(projectRoot, ...segments) + `.${extension}`
295
- );
296
- });
297
- var hasReactScanInFile = (filePath) => {
298
- if (!fs.existsSync(filePath)) return false;
299
- try {
300
- const content = fs.readFileSync(filePath, "utf-8");
301
- return REACT_SCAN_DETECTION_PATTERNS.some(
302
- (pattern) => pattern.test(content)
303
- );
304
- } catch {
305
- return false;
306
- }
307
- };
308
- var detectReactScan = (projectRoot) => {
309
- const result = {
310
- hasReactScan: false,
311
- hasReactScanMonitoring: false,
312
- isPackageInstalled: false,
313
- detectedFiles: []
314
- };
315
- const packageJsonPath = path.join(projectRoot, "package.json");
316
- if (fs.existsSync(packageJsonPath)) {
317
- try {
318
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
319
- const allDependencies = {
320
- ...packageJson.dependencies,
321
- ...packageJson.devDependencies
322
- };
323
- if (allDependencies["react-scan"]) {
324
- result.isPackageInstalled = true;
325
- result.hasReactScan = true;
326
- }
327
- if (allDependencies["@react-scan/monitoring"]) {
328
- result.hasReactScanMonitoring = true;
329
- result.hasReactScan = true;
330
- }
331
- } catch {
332
- }
333
- }
334
- const filesToCheck = getReactScanFilesToCheck(projectRoot);
335
- for (const filePath of filesToCheck) {
336
- if (hasReactScanInFile(filePath)) {
337
- result.hasReactScan = true;
338
- result.detectedFiles.push(filePath);
339
- }
340
- }
341
- return result;
342
- };
343
307
  var detectUnsupportedFramework = (projectRoot) => {
344
308
  const packageJsonPath = path.join(projectRoot, "package.json");
345
309
  if (!fs.existsSync(packageJsonPath)) {
@@ -500,38 +464,6 @@ ${BOLD}File: ${filePath}${RESET}`);
500
464
  console.log(formatDiff(diff));
501
465
  console.log("\u2500".repeat(60));
502
466
  };
503
- var highlighter = {
504
- error: pc5__default.default.red,
505
- warn: pc5__default.default.yellow,
506
- info: pc5__default.default.cyan,
507
- success: pc5__default.default.green,
508
- dim: pc5__default.default.dim
509
- };
510
-
511
- // src/utils/logger.ts
512
- var logger = {
513
- error(...args) {
514
- console.log(highlighter.error(args.join(" ")));
515
- },
516
- warn(...args) {
517
- console.log(highlighter.warn(args.join(" ")));
518
- },
519
- info(...args) {
520
- console.log(highlighter.info(args.join(" ")));
521
- },
522
- success(...args) {
523
- console.log(highlighter.success(args.join(" ")));
524
- },
525
- dim(...args) {
526
- console.log(highlighter.dim(args.join(" ")));
527
- },
528
- log(...args) {
529
- console.log(args.join(" "));
530
- },
531
- break() {
532
- console.log("");
533
- }
534
- };
535
467
 
536
468
  // src/utils/handle-error.ts
537
469
  var handleError = (error) => {
@@ -1534,7 +1466,7 @@ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
1534
1466
  };
1535
1467
  var addOptionsToNextScript = (originalContent, options, filePath) => {
1536
1468
  const reactGrabScriptMatch = originalContent.match(
1537
- /(<Script[^>]*react-grab[^>]*)(\/?>)/is
1469
+ /(<Script[\s\S]*?react-grab[\s\S]*?)\s*(\/?>)/i
1538
1470
  );
1539
1471
  if (!reactGrabScriptMatch) {
1540
1472
  return {
@@ -1899,120 +1831,9 @@ var previewPackageJsonAgentRemoval = (projectRoot, agent) => {
1899
1831
  };
1900
1832
  }
1901
1833
  };
1902
- var hasReactScanCode = (content) => REACT_SCAN_DETECTION_PATTERNS.some((pattern) => pattern.test(content));
1903
- var createRemovalTransform = (removalPatterns) => {
1904
- return (originalContent, filePath) => {
1905
- if (!hasReactScanCode(originalContent)) {
1906
- return {
1907
- success: true,
1908
- filePath,
1909
- message: "React Scan is not configured in this file",
1910
- noChanges: true
1911
- };
1912
- }
1913
- let newContent = originalContent;
1914
- for (const pattern of removalPatterns) {
1915
- newContent = newContent.replace(pattern, "");
1916
- }
1917
- if (newContent === originalContent) {
1918
- return {
1919
- success: true,
1920
- filePath,
1921
- message: "Could not remove React Scan code",
1922
- noChanges: true
1923
- };
1924
- }
1925
- return {
1926
- success: true,
1927
- filePath,
1928
- message: "Remove React Scan",
1929
- originalContent,
1930
- newContent
1931
- };
1932
- };
1933
- };
1934
- var NEXT_APP_REMOVAL_PATTERNS = [
1935
- /\s*\{process\.env\.NODE_ENV\s*===\s*["']development["']\s*&&\s*\(\s*<Script[^>]*react-scan[^>]*\/>\s*\)\}/gs,
1936
- /\s*<Script[^>]*react-scan[^>]*\/>/gi,
1937
- /\s*<script[^>]*>\s*(?:if\s*\([^)]*\)\s*\{)?\s*import\s*\(\s*["']react-scan["']\s*\)[^<]*<\/script>/gi,
1938
- /\s*<script[^>]*react-scan[^>]*>[^<]*<\/script>/gi,
1939
- /\s*<script[^>]*react-scan[^>]*\/>/gi
1940
- ];
1941
- var VITE_REMOVAL_PATTERNS = [
1942
- /\s*import\s*\(\s*["']react-scan["']\s*\)\s*\.then\s*\([^)]*\)[^;]*;?/g,
1943
- /\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
1944
- /^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm,
1945
- /<script[^>]*type="module"[^>]*>\s*if\s*\(\s*import\.meta\.env\.DEV\s*\)\s*\{\s*\}\s*<\/script>/gi
1946
- ];
1947
- var WEBPACK_REMOVAL_PATTERNS = [
1948
- /\s*import\s*\(\s*["']react-scan["']\s*\)\s*\.then\s*\([^)]*\)[^;]*;?/g,
1949
- /\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
1950
- /^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm,
1951
- /if\s*\(\s*process\.env\.NODE_ENV\s*===\s*["']development["']\s*\)\s*\{\s*\}/g
1952
- ];
1953
- var TANSTACK_REMOVAL_PATTERNS = [
1954
- /\s*void\s+import\s*\(\s*["']react-scan["']\s*\);?/g,
1955
- /\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
1956
- /^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm
1957
- ];
1958
- var removeReactScanFromNextApp = createRemovalTransform(
1959
- NEXT_APP_REMOVAL_PATTERNS
1960
- );
1961
- var removeReactScanFromVite = createRemovalTransform(VITE_REMOVAL_PATTERNS);
1962
- var removeReactScanFromWebpack = createRemovalTransform(
1963
- WEBPACK_REMOVAL_PATTERNS
1964
- );
1965
- var removeReactScanFromTanStack = createRemovalTransform(
1966
- TANSTACK_REMOVAL_PATTERNS
1967
- );
1968
- var findReactScanFile = (projectRoot, framework, nextRouterType) => {
1969
- switch (framework) {
1970
- case "next":
1971
- if (nextRouterType === "app") {
1972
- return findLayoutFile(projectRoot);
1973
- }
1974
- return findDocumentFile(projectRoot);
1975
- case "vite":
1976
- return findIndexHtml(projectRoot);
1977
- case "tanstack":
1978
- return findTanStackRootFile(projectRoot);
1979
- case "webpack":
1980
- return findEntryFile(projectRoot);
1981
- default:
1982
- return null;
1983
- }
1984
- };
1985
- var previewReactScanRemoval = (projectRoot, framework, nextRouterType) => {
1986
- const filePath = findReactScanFile(projectRoot, framework, nextRouterType);
1987
- if (!filePath) {
1988
- return {
1989
- success: true,
1990
- filePath: "",
1991
- message: "Could not find file containing React Scan configuration",
1992
- noChanges: true
1993
- };
1994
- }
1995
- const originalContent = fs.readFileSync(filePath, "utf-8");
1996
- switch (framework) {
1997
- case "next":
1998
- return removeReactScanFromNextApp(originalContent, filePath);
1999
- case "vite":
2000
- return removeReactScanFromVite(originalContent, filePath);
2001
- case "tanstack":
2002
- return removeReactScanFromTanStack(originalContent, filePath);
2003
- case "webpack":
2004
- return removeReactScanFromWebpack(originalContent, filePath);
2005
- default:
2006
- return {
2007
- success: false,
2008
- filePath,
2009
- message: `Unknown framework: ${framework}`
2010
- };
2011
- }
2012
- };
2013
1834
 
2014
1835
  // src/commands/add.ts
2015
- var VERSION = "0.1.1";
1836
+ var VERSION = "0.1.2";
2016
1837
  var formatInstalledAgentNames = (agents) => agents.map((agent) => AGENT_NAMES[agent] || agent).join(", ");
2017
1838
  var add = new commander.Command().name("add").alias("install").description("add an agent integration").argument("[agent]", `agent to add (${AGENTS.join(", ")})`).option("-y, --yes", "skip confirmation prompts", false).option(
2018
1839
  "-c, --cwd <cwd>",
@@ -2020,7 +1841,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2020
1841
  process.cwd()
2021
1842
  ).action(async (agentArg, opts) => {
2022
1843
  console.log(
2023
- `${pc5__default.default.magenta("\u273F")} ${pc5__default.default.bold("React Grab")} ${pc5__default.default.gray(VERSION)}`
1844
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)}`
2024
1845
  );
2025
1846
  console.log();
2026
1847
  try {
@@ -2071,7 +1892,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2071
1892
  );
2072
1893
  logger.break();
2073
1894
  logger.warn(`${installedNames} is already installed.`);
2074
- const { action } = await prompts3__default.default({
1895
+ const { action } = await prompts({
2075
1896
  type: "select",
2076
1897
  name: "action",
2077
1898
  message: "How would you like to proceed?",
@@ -2105,7 +1926,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2105
1926
  logger.warn(`Currently installed: ${installedNames}`);
2106
1927
  logger.break();
2107
1928
  }
2108
- const { agent } = await prompts3__default.default({
1929
+ const { agent } = await prompts({
2109
1930
  type: "select",
2110
1931
  name: "agent",
2111
1932
  message: `Which ${highlighter.info("agent integration")} would you like to add?`,
@@ -2123,7 +1944,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2123
1944
  const installedNames = formatInstalledAgentNames(
2124
1945
  projectInfo.installedAgents
2125
1946
  );
2126
- const { action } = await prompts3__default.default({
1947
+ const { action } = await prompts({
2127
1948
  type: "select",
2128
1949
  name: "action",
2129
1950
  message: "How would you like to proceed?",
@@ -2268,7 +2089,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2268
2089
  }
2269
2090
  if (!isNonInteractive && agentsToRemove.length === 0) {
2270
2091
  logger.break();
2271
- const { proceed } = await prompts3__default.default({
2092
+ const { proceed } = await prompts({
2272
2093
  type: "confirm",
2273
2094
  name: "proceed",
2274
2095
  message: "Apply these changes?",
@@ -2348,7 +2169,7 @@ var MAX_KEY_HOLD_DURATION_MS = 2e3;
2348
2169
  var MAX_CONTEXT_LINES = 50;
2349
2170
 
2350
2171
  // src/commands/configure.ts
2351
- var VERSION2 = "0.1.1";
2172
+ var VERSION2 = "0.1.2";
2352
2173
  var isMac = process.platform === "darwin";
2353
2174
  var META_LABEL = isMac ? "Cmd" : "Win";
2354
2175
  var ALT_LABEL = isMac ? "Option" : "Alt";
@@ -2558,7 +2379,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2558
2379
  process.cwd()
2559
2380
  ).action(async (opts) => {
2560
2381
  console.log(
2561
- `${pc5__default.default.magenta("\u273F")} ${pc5__default.default.bold("React Grab")} ${pc5__default.default.gray(VERSION2)}`
2382
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION2)}`
2562
2383
  );
2563
2384
  console.log();
2564
2385
  try {
@@ -2630,7 +2451,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2630
2451
  logger.log(` Max context lines: ${highlighter.info(String(lines))}`);
2631
2452
  }
2632
2453
  } else {
2633
- const { selectedOption } = await prompts3__default.default({
2454
+ const { selectedOption } = await prompts({
2634
2455
  type: "autocomplete",
2635
2456
  name: "selectedOption",
2636
2457
  message: "Search for an option to configure:",
@@ -2650,7 +2471,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2650
2471
  process.exit(1);
2651
2472
  }
2652
2473
  if (selectedOption === "activationKey") {
2653
- const { selectedCombo } = await prompts3__default.default({
2474
+ const { selectedCombo } = await prompts({
2654
2475
  type: "autocomplete",
2655
2476
  name: "selectedCombo",
2656
2477
  message: "Type key combination (e.g. ctrl+shift+g):",
@@ -2667,7 +2488,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2667
2488
  );
2668
2489
  }
2669
2490
  if (selectedOption === "activationMode") {
2670
- const { activationMode } = await prompts3__default.default({
2491
+ const { activationMode } = await prompts({
2671
2492
  type: "select",
2672
2493
  name: "activationMode",
2673
2494
  message: `Select ${highlighter.info("activation mode")}:`,
@@ -2687,7 +2508,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2687
2508
  collectedOptions.activationMode = activationMode;
2688
2509
  }
2689
2510
  if (selectedOption === "keyHoldDuration") {
2690
- const { keyHoldDuration } = await prompts3__default.default({
2511
+ const { keyHoldDuration } = await prompts({
2691
2512
  type: "number",
2692
2513
  name: "keyHoldDuration",
2693
2514
  message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
@@ -2702,7 +2523,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2702
2523
  collectedOptions.keyHoldDuration = keyHoldDuration;
2703
2524
  }
2704
2525
  if (selectedOption === "allowActivationInsideInput") {
2705
- const { allowActivationInsideInput } = await prompts3__default.default({
2526
+ const { allowActivationInsideInput } = await prompts({
2706
2527
  type: "confirm",
2707
2528
  name: "allowActivationInsideInput",
2708
2529
  message: `Allow activation ${highlighter.info("inside input fields")}?`,
@@ -2715,7 +2536,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2715
2536
  collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
2716
2537
  }
2717
2538
  if (selectedOption === "maxContextLines") {
2718
- const { maxContextLines } = await prompts3__default.default({
2539
+ const { maxContextLines } = await prompts({
2719
2540
  type: "number",
2720
2541
  name: "maxContextLines",
2721
2542
  message: `Enter ${highlighter.info("max context lines")} to include:`,
@@ -2745,7 +2566,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2745
2566
  `Add this to your ${highlighter.info("init()")} call or ${highlighter.info("data-options")} attribute:`
2746
2567
  );
2747
2568
  logger.break();
2748
- console.log(` ${pc5__default.default.cyan(configJson)}`);
2569
+ console.log(` ${pc__default.default.cyan(configJson)}`);
2749
2570
  logger.break();
2750
2571
  process.exit(1);
2751
2572
  }
@@ -2755,7 +2576,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2755
2576
  printDiff(result.filePath, result.originalContent, result.newContent);
2756
2577
  if (!opts.yes) {
2757
2578
  logger.break();
2758
- const { proceed } = await prompts3__default.default({
2579
+ const { proceed } = await prompts({
2759
2580
  type: "confirm",
2760
2581
  name: "proceed",
2761
2582
  message: "Apply these changes?",
@@ -2848,7 +2669,7 @@ var uninstallPackagesWithFeedback = (packages, packageManager, projectRoot) => {
2848
2669
  };
2849
2670
 
2850
2671
  // src/commands/init.ts
2851
- var VERSION3 = "0.1.1";
2672
+ var VERSION3 = "0.1.2";
2852
2673
  var REPORT_URL = "https://react-grab.com/api/report-cli";
2853
2674
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
2854
2675
  var reportToCli = (type, config, error) => {
@@ -2914,7 +2735,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
2914
2735
  process.cwd()
2915
2736
  ).action(async (opts) => {
2916
2737
  console.log(
2917
- `${pc5__default.default.magenta("\u273F")} ${pc5__default.default.bold("React Grab")} ${pc5__default.default.gray(VERSION3)}`
2738
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION3)}`
2918
2739
  );
2919
2740
  console.log();
2920
2741
  try {
@@ -2975,7 +2796,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
2975
2796
  );
2976
2797
  logger.break();
2977
2798
  }
2978
- const { wantCustomizeOptions } = await prompts3__default.default({
2799
+ const { wantCustomizeOptions } = await prompts({
2979
2800
  type: "confirm",
2980
2801
  name: "wantCustomizeOptions",
2981
2802
  message: `Would you like to customize ${highlighter.info("options")}?`,
@@ -2996,7 +2817,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
2996
2817
  ` Activation key: ${highlighter.info(formatActivationKeyDisplay2(collectedOptions.activationKey))}`
2997
2818
  );
2998
2819
  } else {
2999
- const { wantActivationKey } = await prompts3__default.default({
2820
+ const { wantActivationKey } = await prompts({
3000
2821
  type: "confirm",
3001
2822
  name: "wantActivationKey",
3002
2823
  message: `Configure ${highlighter.info("activation key")}?`,
@@ -3007,7 +2828,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3007
2828
  process.exit(1);
3008
2829
  }
3009
2830
  if (wantActivationKey) {
3010
- const { key } = await prompts3__default.default({
2831
+ const { key } = await prompts({
3011
2832
  type: "text",
3012
2833
  name: "key",
3013
2834
  message: "Enter the activation key (e.g., g, k, space):",
@@ -3023,7 +2844,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3023
2844
  );
3024
2845
  }
3025
2846
  }
3026
- const { activationMode } = await prompts3__default.default({
2847
+ const { activationMode } = await prompts({
3027
2848
  type: "select",
3028
2849
  name: "activationMode",
3029
2850
  message: `Select ${highlighter.info("activation mode")}:`,
@@ -3042,7 +2863,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3042
2863
  }
3043
2864
  collectedOptions.activationMode = activationMode;
3044
2865
  if (activationMode === "hold") {
3045
- const { keyHoldDuration } = await prompts3__default.default({
2866
+ const { keyHoldDuration } = await prompts({
3046
2867
  type: "number",
3047
2868
  name: "keyHoldDuration",
3048
2869
  message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
@@ -3056,7 +2877,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3056
2877
  }
3057
2878
  collectedOptions.keyHoldDuration = keyHoldDuration;
3058
2879
  }
3059
- const { allowActivationInsideInput } = await prompts3__default.default({
2880
+ const { allowActivationInsideInput } = await prompts({
3060
2881
  type: "confirm",
3061
2882
  name: "allowActivationInsideInput",
3062
2883
  message: `Allow activation ${highlighter.info("inside input fields")}?`,
@@ -3067,7 +2888,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3067
2888
  process.exit(1);
3068
2889
  }
3069
2890
  collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
3070
- const { maxContextLines } = await prompts3__default.default({
2891
+ const { maxContextLines } = await prompts({
3071
2892
  type: "number",
3072
2893
  name: "maxContextLines",
3073
2894
  message: `Enter ${highlighter.info("max context lines")} to include:`,
@@ -3101,7 +2922,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3101
2922
  optionsResult.newContent
3102
2923
  );
3103
2924
  logger.break();
3104
- const { proceed } = await prompts3__default.default({
2925
+ const { proceed } = await prompts({
3105
2926
  type: "confirm",
3106
2927
  name: "proceed",
3107
2928
  message: "Apply these changes?",
@@ -3125,7 +2946,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3125
2946
  );
3126
2947
  if (availableAgents.length > 0) {
3127
2948
  logger.break();
3128
- const { wantAddAgent } = await prompts3__default.default({
2949
+ const { wantAddAgent } = await prompts({
3129
2950
  type: "confirm",
3130
2951
  name: "wantAddAgent",
3131
2952
  message: `Would you like to add an ${highlighter.info("agent integration")}?`,
@@ -3136,7 +2957,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3136
2957
  process.exit(1);
3137
2958
  }
3138
2959
  if (wantAddAgent) {
3139
- const { agent } = await prompts3__default.default({
2960
+ const { agent } = await prompts({
3140
2961
  type: "select",
3141
2962
  name: "agent",
3142
2963
  message: `Which ${highlighter.info("agent integration")} would you like to add?`,
@@ -3158,7 +2979,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3158
2979
  const installedNames = formatInstalledAgentNames2(
3159
2980
  projectInfo.installedAgents
3160
2981
  );
3161
- const { action } = await prompts3__default.default({
2982
+ const { action } = await prompts({
3162
2983
  type: "select",
3163
2984
  name: "action",
3164
2985
  message: "How would you like to proceed?",
@@ -3229,7 +3050,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3229
3050
  }
3230
3051
  if (agentsToRemove2.length === 0) {
3231
3052
  logger.break();
3232
- const { proceed } = await prompts3__default.default({
3053
+ const { proceed } = await prompts({
3233
3054
  type: "confirm",
3234
3055
  name: "proceed",
3235
3056
  message: "Apply these changes?",
@@ -3274,6 +3095,75 @@ var init = new commander.Command().name("init").description("initialize React Gr
3274
3095
  }
3275
3096
  }
3276
3097
  }
3098
+ } else {
3099
+ const result2 = previewTransform(
3100
+ projectInfo.projectRoot,
3101
+ projectInfo.framework,
3102
+ projectInfo.nextRouterType,
3103
+ agentIntegration2,
3104
+ true
3105
+ );
3106
+ const packageJsonResult2 = previewPackageJsonTransform(
3107
+ projectInfo.projectRoot,
3108
+ agentIntegration2,
3109
+ projectInfo.installedAgents,
3110
+ projectInfo.packageManager
3111
+ );
3112
+ if (!result2.success) {
3113
+ logger.break();
3114
+ logger.error(result2.message);
3115
+ logger.break();
3116
+ process.exit(1);
3117
+ }
3118
+ const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
3119
+ const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
3120
+ if (hasLayoutChanges2 || hasPackageJsonChanges2) {
3121
+ logger.break();
3122
+ if (hasLayoutChanges2) {
3123
+ printDiff(
3124
+ result2.filePath,
3125
+ result2.originalContent,
3126
+ result2.newContent
3127
+ );
3128
+ }
3129
+ if (hasPackageJsonChanges2) {
3130
+ if (hasLayoutChanges2) {
3131
+ logger.break();
3132
+ }
3133
+ printDiff(
3134
+ packageJsonResult2.filePath,
3135
+ packageJsonResult2.originalContent,
3136
+ packageJsonResult2.newContent
3137
+ );
3138
+ }
3139
+ logger.break();
3140
+ const { proceed } = await prompts({
3141
+ type: "confirm",
3142
+ name: "proceed",
3143
+ message: "Apply these changes?",
3144
+ initial: true
3145
+ });
3146
+ if (!proceed) {
3147
+ logger.break();
3148
+ logger.log("Agent addition cancelled.");
3149
+ } else {
3150
+ installPackagesWithFeedback(
3151
+ getPackagesToInstall(agentIntegration2, false),
3152
+ projectInfo.packageManager,
3153
+ projectInfo.projectRoot
3154
+ );
3155
+ if (hasLayoutChanges2) {
3156
+ applyTransformWithFeedback(result2);
3157
+ }
3158
+ if (hasPackageJsonChanges2) {
3159
+ applyPackageJsonWithFeedback(packageJsonResult2);
3160
+ }
3161
+ logger.break();
3162
+ logger.success(
3163
+ `${getAgentName(agentIntegration2)} has been added.`
3164
+ );
3165
+ }
3166
+ }
3277
3167
  }
3278
3168
  }
3279
3169
  }
@@ -3311,7 +3201,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3311
3201
  return 0;
3312
3202
  }
3313
3203
  );
3314
- const { selectedProject } = await prompts3__default.default({
3204
+ const { selectedProject } = await prompts({
3315
3205
  type: "select",
3316
3206
  name: "selectedProject",
3317
3207
  message: "Select a project to install React Grab:",
@@ -3378,7 +3268,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3378
3268
  const agentsToRemove = [];
3379
3269
  if (!isNonInteractive && !opts.agent) {
3380
3270
  logger.break();
3381
- const { wantAddAgent } = await prompts3__default.default({
3271
+ const { wantAddAgent } = await prompts({
3382
3272
  type: "confirm",
3383
3273
  name: "wantAddAgent",
3384
3274
  message: `Would you like to add an ${highlighter.info("agent integration")}?`,
@@ -3389,7 +3279,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3389
3279
  process.exit(1);
3390
3280
  }
3391
3281
  if (wantAddAgent) {
3392
- const { agent } = await prompts3__default.default({
3282
+ const { agent } = await prompts({
3393
3283
  type: "select",
3394
3284
  name: "agent",
3395
3285
  message: `Which ${highlighter.info("agent integration")} would you like to add?`,
@@ -3456,7 +3346,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3456
3346
  logger.warn("Please verify the changes before committing.");
3457
3347
  if (!isNonInteractive) {
3458
3348
  logger.break();
3459
- const { proceed } = await prompts3__default.default({
3349
+ const { proceed } = await prompts({
3460
3350
  type: "confirm",
3461
3351
  name: "proceed",
3462
3352
  message: "Apply these changes?",
@@ -3515,293 +3405,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3515
3405
  reportToCli("error", void 0, error);
3516
3406
  }
3517
3407
  });
3518
- var VERSION4 = "0.1.1";
3519
- var DOCS_URL2 = "https://github.com/aidenybai/react-grab";
3520
- var exitWithMessage = (message, code = 0) => {
3521
- if (message) logger.log(message);
3522
- logger.break();
3523
- process.exit(code);
3524
- };
3525
- var confirmOrExit = async (message, isNonInteractive) => {
3526
- if (isNonInteractive) return;
3527
- const { proceed } = await prompts3__default.default({
3528
- type: "confirm",
3529
- name: "proceed",
3530
- message,
3531
- initial: true
3532
- });
3533
- if (!proceed) exitWithMessage("Migration cancelled.");
3534
- };
3535
- var hasTransformChanges = (result) => result.success && !result.noChanges && Boolean(result.originalContent) && Boolean(result.newContent);
3536
- var MIGRATION_SOURCES = ["react-scan"];
3537
- var MIGRATION_SOURCE_NAMES = {
3538
- "react-scan": "React Scan"
3539
- };
3540
- var FRAMEWORK_NAMES2 = {
3541
- next: "Next.js",
3542
- vite: "Vite",
3543
- tanstack: "TanStack Start",
3544
- webpack: "Webpack",
3545
- unknown: "Unknown"
3546
- };
3547
- var migrate = new commander.Command().name("migrate").description("migrate to React Grab from another tool").option("-y, --yes", "skip confirmation prompts", false).option("-f, --from <source>", "migration source (react-scan)").option(
3548
- "-c, --cwd <cwd>",
3549
- "working directory (defaults to current directory)",
3550
- process.cwd()
3551
- ).action(async (opts) => {
3552
- console.log(
3553
- `${pc5__default.default.magenta("\u273F")} ${pc5__default.default.bold("React Grab")} ${pc5__default.default.gray(VERSION4)}`
3554
- );
3555
- console.log();
3556
- try {
3557
- const cwd = opts.cwd;
3558
- const isNonInteractive = opts.yes;
3559
- let migrationSource = opts.from;
3560
- if (!migrationSource) {
3561
- if (isNonInteractive) {
3562
- logger.error(
3563
- "Migration source is required in non-interactive mode. Use --from <source>"
3564
- );
3565
- logger.log(
3566
- `Available sources: ${MIGRATION_SOURCES.map((innerSource) => highlighter.info(innerSource)).join(", ")}`
3567
- );
3568
- logger.break();
3569
- process.exit(1);
3570
- }
3571
- const { source } = await prompts3__default.default({
3572
- type: "select",
3573
- name: "source",
3574
- message: `What would you like to migrate ${highlighter.info("from")}?`,
3575
- choices: MIGRATION_SOURCES.map((innerSource) => ({
3576
- title: MIGRATION_SOURCE_NAMES[innerSource],
3577
- value: innerSource
3578
- }))
3579
- });
3580
- if (!source) exitWithMessage();
3581
- migrationSource = source;
3582
- }
3583
- if (!MIGRATION_SOURCES.includes(migrationSource)) {
3584
- logger.error(`Unknown migration source: ${migrationSource}`);
3585
- logger.log(
3586
- `Available sources: ${MIGRATION_SOURCES.map((innerSource) => highlighter.info(innerSource)).join(", ")}`
3587
- );
3588
- logger.break();
3589
- process.exit(1);
3590
- }
3591
- logger.break();
3592
- logger.log(
3593
- `Migrating from ${highlighter.info(MIGRATION_SOURCE_NAMES[migrationSource])} to ${highlighter.info("React Grab")}...`
3594
- );
3595
- logger.break();
3596
- const preflightSpinner = spinner("Preflight checks.").start();
3597
- const projectInfo = await detectProject(cwd);
3598
- preflightSpinner.succeed();
3599
- if (projectInfo.framework === "unknown") {
3600
- logger.break();
3601
- logger.error("Could not detect a supported framework.");
3602
- logger.log(
3603
- "React Grab supports Next.js, Vite, TanStack Start, and Webpack projects."
3604
- );
3605
- logger.log(`Visit ${highlighter.info(DOCS_URL2)} for manual setup.`);
3606
- logger.break();
3607
- process.exit(1);
3608
- }
3609
- const frameworkSpinner = spinner("Verifying framework.").start();
3610
- frameworkSpinner.succeed(
3611
- `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES2[projectInfo.framework])}.`
3612
- );
3613
- if (projectInfo.framework === "next") {
3614
- const routerSpinner = spinner("Detecting router type.").start();
3615
- routerSpinner.succeed(
3616
- `Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === "app" ? "App Router" : "Pages Router")}.`
3617
- );
3618
- }
3619
- const sourceSpinner = spinner(
3620
- `Checking for ${MIGRATION_SOURCE_NAMES[migrationSource]}.`
3621
- ).start();
3622
- const reactScanInfo = detectReactScan(cwd);
3623
- const sourceName = MIGRATION_SOURCE_NAMES[migrationSource];
3624
- if (!reactScanInfo.hasReactScan) {
3625
- sourceSpinner.fail(`${sourceName} is not installed in this project.`);
3626
- exitWithMessage(
3627
- `Use ${highlighter.info("npx grab init")} to install React Grab directly.`
3628
- );
3629
- }
3630
- sourceSpinner.succeed(
3631
- `Checking for ${sourceName}. Found ${highlighter.info(reactScanInfo.isPackageInstalled ? "npm package" : "script reference")}.`
3632
- );
3633
- if (reactScanInfo.hasReactScanMonitoring) {
3634
- logger.break();
3635
- logger.warn(
3636
- `${sourceName} Monitoring (@react-scan/monitoring) detected.`
3637
- );
3638
- logger.warn(
3639
- "Monitoring features are not available in React Grab. You may need to remove it manually."
3640
- );
3641
- }
3642
- if (projectInfo.hasReactGrab) {
3643
- logger.break();
3644
- logger.success("React Grab is already installed.");
3645
- logger.log(
3646
- `This migration will only remove ${sourceName} from your project.`
3647
- );
3648
- logger.break();
3649
- const removalResult2 = previewReactScanRemoval(
3650
- projectInfo.projectRoot,
3651
- projectInfo.framework,
3652
- projectInfo.nextRouterType
3653
- );
3654
- if (removalResult2.noChanges) {
3655
- logger.log(`No ${sourceName} code found in configuration files.`);
3656
- logger.break();
3657
- if (reactScanInfo.isPackageInstalled) {
3658
- if (reactScanInfo.detectedFiles.length > 0) {
3659
- logger.warn(
3660
- `${sourceName} was detected in files that cannot be automatically cleaned:`
3661
- );
3662
- for (const file of reactScanInfo.detectedFiles) {
3663
- logger.log(` - ${file}`);
3664
- }
3665
- logger.warn(
3666
- "Please remove React Scan references manually before uninstalling the package."
3667
- );
3668
- logger.break();
3669
- process.exit(1);
3670
- }
3671
- await confirmOrExit(
3672
- `Uninstall ${migrationSource} package?`,
3673
- isNonInteractive
3674
- );
3675
- uninstallPackagesWithFeedback(
3676
- [migrationSource],
3677
- projectInfo.packageManager,
3678
- projectInfo.projectRoot
3679
- );
3680
- logger.break();
3681
- logger.success(`${sourceName} has been removed.`);
3682
- }
3683
- exitWithMessage();
3684
- }
3685
- if (hasTransformChanges(removalResult2)) {
3686
- logger.break();
3687
- printDiff(
3688
- removalResult2.filePath,
3689
- removalResult2.originalContent,
3690
- removalResult2.newContent
3691
- );
3692
- logger.break();
3693
- await confirmOrExit("Apply these changes?", isNonInteractive);
3694
- applyTransformWithFeedback(
3695
- removalResult2,
3696
- `Removing ${sourceName} from ${removalResult2.filePath}.`
3697
- );
3698
- if (reactScanInfo.isPackageInstalled) {
3699
- uninstallPackagesWithFeedback(
3700
- [migrationSource],
3701
- projectInfo.packageManager,
3702
- projectInfo.projectRoot
3703
- );
3704
- }
3705
- logger.break();
3706
- logger.success(`Migration complete! ${sourceName} has been removed.`);
3707
- }
3708
- exitWithMessage();
3709
- }
3710
- const removalResult = previewReactScanRemoval(
3711
- projectInfo.projectRoot,
3712
- projectInfo.framework,
3713
- projectInfo.nextRouterType
3714
- );
3715
- const addResult = previewTransform(
3716
- projectInfo.projectRoot,
3717
- projectInfo.framework,
3718
- projectInfo.nextRouterType,
3719
- "none",
3720
- false
3721
- );
3722
- const hasRemovalChanges = hasTransformChanges(removalResult);
3723
- const hasAddChanges = hasTransformChanges(addResult);
3724
- if (!hasRemovalChanges && !hasAddChanges) {
3725
- exitWithMessage("No changes needed.");
3726
- }
3727
- logger.break();
3728
- logger.log("Migration will perform the following changes:");
3729
- logger.break();
3730
- if (hasRemovalChanges) {
3731
- logger.log(
3732
- ` ${pc5__default.default.red("\u2212")} Remove ${sourceName} from ${removalResult.filePath}`
3733
- );
3734
- }
3735
- if (reactScanInfo.isPackageInstalled) {
3736
- logger.log(` ${pc5__default.default.red("\u2212")} Uninstall ${migrationSource} package`);
3737
- }
3738
- logger.log(` ${pc5__default.default.green("+")} Install react-grab package`);
3739
- if (hasAddChanges) {
3740
- logger.log(
3741
- ` ${pc5__default.default.green("+")} Add React Grab to ${addResult.filePath}`
3742
- );
3743
- }
3744
- if (hasRemovalChanges && hasAddChanges && removalResult.filePath === addResult.filePath) {
3745
- const combinedOriginal = removalResult.originalContent;
3746
- const combinedNew = addResult.newContent;
3747
- logger.break();
3748
- printDiff(removalResult.filePath, combinedOriginal, combinedNew);
3749
- } else {
3750
- if (hasRemovalChanges) {
3751
- logger.break();
3752
- printDiff(
3753
- removalResult.filePath,
3754
- removalResult.originalContent,
3755
- removalResult.newContent
3756
- );
3757
- }
3758
- if (hasAddChanges) {
3759
- logger.break();
3760
- printDiff(
3761
- addResult.filePath,
3762
- addResult.originalContent,
3763
- addResult.newContent
3764
- );
3765
- }
3766
- }
3767
- logger.break();
3768
- logger.warn("Auto-detection may not be 100% accurate.");
3769
- logger.warn("Please verify the changes before committing.");
3770
- logger.break();
3771
- await confirmOrExit("Apply these changes?", isNonInteractive);
3772
- if (reactScanInfo.isPackageInstalled && (hasRemovalChanges || reactScanInfo.detectedFiles.length === 0)) {
3773
- uninstallPackagesWithFeedback(
3774
- [migrationSource],
3775
- projectInfo.packageManager,
3776
- projectInfo.projectRoot
3777
- );
3778
- }
3779
- installPackagesWithFeedback(
3780
- getPackagesToInstall("none", true),
3781
- projectInfo.packageManager,
3782
- projectInfo.projectRoot
3783
- );
3784
- if (hasRemovalChanges) {
3785
- applyTransformWithFeedback(
3786
- removalResult,
3787
- `Removing ${sourceName} from ${removalResult.filePath}.`
3788
- );
3789
- }
3790
- if (hasAddChanges) {
3791
- applyTransformWithFeedback(
3792
- addResult,
3793
- `Adding React Grab to ${addResult.filePath}.`
3794
- );
3795
- }
3796
- logger.break();
3797
- logger.log(`${highlighter.success("Success!")} Migration complete.`);
3798
- logger.log("You may now start your development server.");
3799
- logger.break();
3800
- } catch (error) {
3801
- handleError(error);
3802
- }
3803
- });
3804
- var VERSION5 = "0.1.1";
3408
+ var VERSION4 = "0.1.2";
3805
3409
  var remove = new commander.Command().name("remove").description("remove an agent integration").argument(
3806
3410
  "[agent]",
3807
3411
  "agent to remove (claude-code, cursor, opencode, codex, gemini, amp, ami)"
@@ -3811,7 +3415,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3811
3415
  process.cwd()
3812
3416
  ).action(async (agentArg, opts) => {
3813
3417
  console.log(
3814
- `${pc5__default.default.magenta("\u273F")} ${pc5__default.default.bold("React Grab")} ${pc5__default.default.gray(VERSION5)}`
3418
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION4)}`
3815
3419
  );
3816
3420
  console.log();
3817
3421
  try {
@@ -3850,7 +3454,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3850
3454
  agentToRemove = agentArg;
3851
3455
  } else if (!isNonInteractive) {
3852
3456
  logger.break();
3853
- const { agent } = await prompts3__default.default({
3457
+ const { agent } = await prompts({
3854
3458
  type: "select",
3855
3459
  name: "agent",
3856
3460
  message: `Which ${highlighter.info("agent integration")} would you like to remove?`,
@@ -3910,7 +3514,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3910
3514
  }
3911
3515
  if (!isNonInteractive) {
3912
3516
  logger.break();
3913
- const { proceed } = await prompts3__default.default({
3517
+ const { proceed } = await prompts({
3914
3518
  type: "confirm",
3915
3519
  name: "proceed",
3916
3520
  message: "Apply these changes?",
@@ -3980,7 +3584,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3980
3584
  });
3981
3585
 
3982
3586
  // src/cli.ts
3983
- var VERSION6 = "0.1.1";
3587
+ var VERSION5 = "0.1.2";
3984
3588
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
3985
3589
  process.on("SIGINT", () => process.exit(0));
3986
3590
  process.on("SIGTERM", () => process.exit(0));
@@ -3989,12 +3593,11 @@ try {
3989
3593
  });
3990
3594
  } catch {
3991
3595
  }
3992
- var program = new commander.Command().name("grab").description("add React Grab to your project").version(VERSION6, "-v, --version", "display the version number");
3596
+ var program = new commander.Command().name("grab").description("add React Grab to your project").version(VERSION5, "-v, --version", "display the version number");
3993
3597
  program.addCommand(init);
3994
3598
  program.addCommand(add);
3995
3599
  program.addCommand(remove);
3996
3600
  program.addCommand(configure);
3997
- program.addCommand(migrate);
3998
3601
  var main = async () => {
3999
3602
  await program.parseAsync();
4000
3603
  };