@react-grab/cli 0.1.28 → 0.1.29

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 +106 -181
  2. package/dist/cli.js +106 -181
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -909,7 +909,6 @@ var AGENTS = [
909
909
  "codex",
910
910
  "gemini",
911
911
  "amp",
912
- "ami",
913
912
  "droid",
914
913
  "copilot"
915
914
  ];
@@ -920,7 +919,6 @@ var AGENT_NAMES = {
920
919
  codex: "Codex",
921
920
  gemini: "Gemini",
922
921
  amp: "Amp",
923
- ami: "Ami",
924
922
  droid: "Droid",
925
923
  copilot: "Copilot"
926
924
  };
@@ -977,19 +975,15 @@ var NEXT_PAGES_ROUTER_SCRIPT_WITH_AGENT = (agent) => {
977
975
  />
978
976
  )}`;
979
977
  };
980
- var VITE_SCRIPT = `<script type="module">
981
- if (import.meta.env.DEV) {
982
- import("react-grab");
983
- }
984
- </script>`;
985
- var VITE_SCRIPT_WITH_AGENT = (agent) => {
986
- if (agent === "none") return VITE_SCRIPT;
987
- return `<script type="module">
988
- if (import.meta.env.DEV) {
989
- import("react-grab");
990
- import("@react-grab/${agent}/client");
991
- }
992
- </script>`;
978
+ var VITE_IMPORT = `if (import.meta.env.DEV) {
979
+ import("react-grab");
980
+ }`;
981
+ var VITE_IMPORT_WITH_AGENT = (agent) => {
982
+ if (agent === "none") return VITE_IMPORT;
983
+ return `if (import.meta.env.DEV) {
984
+ import("react-grab");
985
+ import("@react-grab/${agent}/client");
986
+ }`;
993
987
  };
994
988
  var WEBPACK_IMPORT = `if (process.env.NODE_ENV === "development") {
995
989
  import("react-grab");
@@ -1185,51 +1179,7 @@ var addAgentToExistingNextApp = (originalContent, agent, filePath) => {
1185
1179
  message: "Could not find React Grab script to add agent after"
1186
1180
  };
1187
1181
  };
1188
- var addAgentToExistingVite = (originalContent, agent, filePath) => {
1189
- if (agent === "none") {
1190
- return {
1191
- success: true,
1192
- filePath,
1193
- message: "React Grab is already configured",
1194
- noChanges: true
1195
- };
1196
- }
1197
- const agentPackage = `@react-grab/${agent}`;
1198
- if (originalContent.includes(agentPackage)) {
1199
- return {
1200
- success: true,
1201
- filePath,
1202
- message: `Agent ${agent} is already configured`,
1203
- noChanges: true
1204
- };
1205
- }
1206
- const agentImport = `import("${agentPackage}/client");`;
1207
- const reactGrabImportMatch = originalContent.match(
1208
- /import\s*\(\s*["']react-grab["']\s*\);?/
1209
- );
1210
- if (reactGrabImportMatch) {
1211
- const matchedText = reactGrabImportMatch[0];
1212
- const hasSemicolon = matchedText.endsWith(";");
1213
- const newContent = originalContent.replace(
1214
- matchedText,
1215
- `${hasSemicolon ? matchedText.slice(0, -1) : matchedText};
1216
- ${agentImport}`
1217
- );
1218
- return {
1219
- success: true,
1220
- filePath,
1221
- message: `Add ${agent} agent`,
1222
- originalContent,
1223
- newContent
1224
- };
1225
- }
1226
- return {
1227
- success: false,
1228
- filePath,
1229
- message: "Could not find React Grab import to add agent after"
1230
- };
1231
- };
1232
- var addAgentToExistingWebpack = (originalContent, agent, filePath) => {
1182
+ var addAgentToExistingImport = (originalContent, agent, filePath) => {
1233
1183
  if (agent === "none") {
1234
1184
  return {
1235
1185
  success: true,
@@ -1434,41 +1384,55 @@ ${SCRIPT_IMPORT}`
1434
1384
  newContent
1435
1385
  };
1436
1386
  };
1387
+ var checkExistingInstallation = (filePath, agent, reactGrabAlreadyConfigured) => {
1388
+ const content = fs.readFileSync(filePath, "utf-8");
1389
+ if (!hasReactGrabCode(content)) return null;
1390
+ if (reactGrabAlreadyConfigured) {
1391
+ return addAgentToExistingImport(content, agent, filePath);
1392
+ }
1393
+ return {
1394
+ success: true,
1395
+ filePath,
1396
+ message: "React Grab is already installed in this file",
1397
+ noChanges: true
1398
+ };
1399
+ };
1437
1400
  var transformVite = (projectRoot, agent, reactGrabAlreadyConfigured, force = false) => {
1438
- const indexPath = findIndexHtml(projectRoot);
1439
- if (!indexPath) {
1401
+ const entryPath = findEntryFile(projectRoot);
1402
+ if (!force) {
1403
+ const indexPath = findIndexHtml(projectRoot);
1404
+ if (indexPath) {
1405
+ const existingResult = checkExistingInstallation(
1406
+ indexPath,
1407
+ agent,
1408
+ reactGrabAlreadyConfigured
1409
+ );
1410
+ if (existingResult) return existingResult;
1411
+ }
1412
+ }
1413
+ if (!entryPath) {
1440
1414
  return {
1441
1415
  success: false,
1442
1416
  filePath: "",
1443
- message: "Could not find index.html"
1444
- };
1445
- }
1446
- const originalContent = fs.readFileSync(indexPath, "utf-8");
1447
- let newContent = originalContent;
1448
- const hasReactGrabInFile2 = hasReactGrabCode(originalContent);
1449
- if (!force && hasReactGrabInFile2 && reactGrabAlreadyConfigured) {
1450
- return addAgentToExistingVite(originalContent, agent, indexPath);
1451
- }
1452
- if (!force && hasReactGrabInFile2) {
1453
- return {
1454
- success: true,
1455
- filePath: indexPath,
1456
- message: "React Grab is already installed in this file",
1457
- noChanges: true
1417
+ message: "Could not find entry file (src/index.tsx, src/main.tsx, etc.)"
1458
1418
  };
1459
1419
  }
1460
- const scriptBlock = VITE_SCRIPT_WITH_AGENT(agent);
1461
- const headMatch = newContent.match(/<head[^>]*>/i);
1462
- if (headMatch) {
1463
- newContent = newContent.replace(
1464
- headMatch[0],
1465
- `${headMatch[0]}
1466
- ${scriptBlock}`
1420
+ if (!force) {
1421
+ const existingResult = checkExistingInstallation(
1422
+ entryPath,
1423
+ agent,
1424
+ reactGrabAlreadyConfigured
1467
1425
  );
1426
+ if (existingResult) return existingResult;
1468
1427
  }
1428
+ const originalContent = fs.readFileSync(entryPath, "utf-8");
1429
+ const importBlock = VITE_IMPORT_WITH_AGENT(agent);
1430
+ const newContent = `${importBlock}
1431
+
1432
+ ${originalContent}`;
1469
1433
  return {
1470
1434
  success: true,
1471
- filePath: indexPath,
1435
+ filePath: entryPath,
1472
1436
  message: "Add React Grab" + (agent !== "none" ? ` with ${agent} agent` : ""),
1473
1437
  originalContent,
1474
1438
  newContent
@@ -1483,19 +1447,15 @@ var transformWebpack = (projectRoot, agent, reactGrabAlreadyConfigured, force =
1483
1447
  message: "Could not find entry file (src/index.tsx, src/main.tsx, etc.)"
1484
1448
  };
1485
1449
  }
1486
- const originalContent = fs.readFileSync(entryPath, "utf-8");
1487
- const hasReactGrabInFile2 = hasReactGrabCode(originalContent);
1488
- if (!force && hasReactGrabInFile2 && reactGrabAlreadyConfigured) {
1489
- return addAgentToExistingWebpack(originalContent, agent, entryPath);
1490
- }
1491
- if (!force && hasReactGrabInFile2) {
1492
- return {
1493
- success: true,
1494
- filePath: entryPath,
1495
- message: "React Grab is already installed in this file",
1496
- noChanges: true
1497
- };
1450
+ if (!force) {
1451
+ const existingResult = checkExistingInstallation(
1452
+ entryPath,
1453
+ agent,
1454
+ reactGrabAlreadyConfigured
1455
+ );
1456
+ if (existingResult) return existingResult;
1498
1457
  }
1458
+ const originalContent = fs.readFileSync(entryPath, "utf-8");
1499
1459
  const importBlock = WEBPACK_IMPORT_WITH_AGENT(agent);
1500
1460
  const newContent = `${importBlock}
1501
1461
 
@@ -1582,40 +1542,41 @@ ${newContent}`;
1582
1542
  };
1583
1543
  };
1584
1544
  var previewTransform = (projectRoot, framework, nextRouterType, agent, reactGrabAlreadyConfigured = false, force = false) => {
1545
+ const resolvedAgent = agent === "mcp" ? "none" : agent;
1585
1546
  switch (framework) {
1586
1547
  case "next":
1587
1548
  if (nextRouterType === "app") {
1588
1549
  return transformNextAppRouter(
1589
1550
  projectRoot,
1590
- agent,
1551
+ resolvedAgent,
1591
1552
  reactGrabAlreadyConfigured,
1592
1553
  force
1593
1554
  );
1594
1555
  }
1595
1556
  return transformNextPagesRouter(
1596
1557
  projectRoot,
1597
- agent,
1558
+ resolvedAgent,
1598
1559
  reactGrabAlreadyConfigured,
1599
1560
  force
1600
1561
  );
1601
1562
  case "vite":
1602
1563
  return transformVite(
1603
1564
  projectRoot,
1604
- agent,
1565
+ resolvedAgent,
1605
1566
  reactGrabAlreadyConfigured,
1606
1567
  force
1607
1568
  );
1608
1569
  case "tanstack":
1609
1570
  return transformTanStack(
1610
1571
  projectRoot,
1611
- agent,
1572
+ resolvedAgent,
1612
1573
  reactGrabAlreadyConfigured,
1613
1574
  force
1614
1575
  );
1615
1576
  case "webpack":
1616
1577
  return transformWebpack(
1617
1578
  projectRoot,
1618
- agent,
1579
+ resolvedAgent,
1619
1580
  reactGrabAlreadyConfigured,
1620
1581
  force
1621
1582
  );
@@ -1860,8 +1821,17 @@ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
1860
1821
  return findLayoutFile(projectRoot);
1861
1822
  }
1862
1823
  return findDocumentFile(projectRoot);
1863
- case "vite":
1864
- return findIndexHtml(projectRoot);
1824
+ case "vite": {
1825
+ const entryFile = findEntryFile(projectRoot);
1826
+ if (entryFile && hasReactGrabCode(fs.readFileSync(entryFile, "utf-8"))) {
1827
+ return entryFile;
1828
+ }
1829
+ const indexHtml = findIndexHtml(projectRoot);
1830
+ if (indexHtml && hasReactGrabCode(fs.readFileSync(indexHtml, "utf-8"))) {
1831
+ return indexHtml;
1832
+ }
1833
+ return entryFile;
1834
+ }
1865
1835
  case "tanstack":
1866
1836
  return findTanStackRootFile(projectRoot);
1867
1837
  case "webpack":
@@ -2272,7 +2242,7 @@ var previewCdnTransform = (projectRoot, framework, nextRouterType, targetCdnDoma
2272
2242
  };
2273
2243
 
2274
2244
  // src/commands/add.ts
2275
- var VERSION = "0.1.28";
2245
+ var VERSION = "0.1.29";
2276
2246
  var formatInstalledAgentNames = (agents) => agents.map((agent) => AGENT_NAMES[agent] || agent).join(", ");
2277
2247
  var add = new commander.Command().name("add").alias("install").description("connect React Grab to your agent").argument("[agent]", `agent to connect (${AGENTS.join(", ")}, mcp)`).option("-y, --yes", "skip confirmation prompts", false).option(
2278
2248
  "-c, --cwd <cwd>",
@@ -2310,11 +2280,36 @@ var add = new commander.Command().name("add").alias("install").description("conn
2310
2280
  }
2311
2281
  let agentIntegration;
2312
2282
  let agentsToRemove = [];
2313
- if (agentArg) {
2283
+ if (agentArg === "mcp") {
2284
+ if (isNonInteractive) {
2285
+ const results = installMcpServers();
2286
+ const hasSuccess = results.some((result2) => result2.success);
2287
+ if (!hasSuccess) {
2288
+ logger.break();
2289
+ logger.error("Failed to install MCP server.");
2290
+ logger.break();
2291
+ process.exit(1);
2292
+ }
2293
+ } else {
2294
+ const didInstall = await promptMcpInstall();
2295
+ if (!didInstall) {
2296
+ logger.break();
2297
+ process.exit(0);
2298
+ }
2299
+ }
2300
+ logger.break();
2301
+ logger.log(
2302
+ `${highlighter.success("Success!")} MCP server has been configured.`
2303
+ );
2304
+ logger.log("Restart your agents to activate.");
2305
+ logger.break();
2306
+ agentIntegration = "mcp";
2307
+ projectInfo.installedAgents = [...projectInfo.installedAgents, "mcp"];
2308
+ } else if (agentArg) {
2314
2309
  if (!AGENTS.includes(agentArg)) {
2315
2310
  logger.break();
2316
2311
  logger.error(`Invalid agent: ${agentArg}`);
2317
- logger.error(`Available agents: ${AGENTS.join(", ")}`);
2312
+ logger.error(`Available agents: ${AGENTS.join(", ")}, mcp`);
2318
2313
  logger.break();
2319
2314
  process.exit(1);
2320
2315
  }
@@ -2633,7 +2628,7 @@ var MAX_KEY_HOLD_DURATION_MS = 2e3;
2633
2628
  var MAX_CONTEXT_LINES = 50;
2634
2629
 
2635
2630
  // src/commands/configure.ts
2636
- var VERSION2 = "0.1.28";
2631
+ var VERSION2 = "0.1.29";
2637
2632
  var isMac = process.platform === "darwin";
2638
2633
  var META_LABEL = isMac ? "Cmd" : "Win";
2639
2634
  var ALT_LABEL = isMac ? "Option" : "Alt";
@@ -3189,7 +3184,7 @@ var uninstallPackagesWithFeedback = (packages, packageManager, projectRoot) => {
3189
3184
  };
3190
3185
 
3191
3186
  // src/commands/init.ts
3192
- var VERSION3 = "0.1.28";
3187
+ var VERSION3 = "0.1.29";
3193
3188
  var REPORT_URL = "https://react-grab.com/api/report-cli";
3194
3189
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
3195
3190
  var reportToCli = (type, config, error) => {
@@ -3520,76 +3515,6 @@ var init = new commander.Command().name("init").description("initialize React Gr
3520
3515
  logger.break();
3521
3516
  logger.success("MCP server has been configured.");
3522
3517
  logger.log("Restart your agents to activate.");
3523
- agentIntegration2 = "mcp";
3524
- projectInfo.installedAgents = ["mcp"];
3525
- const result2 = previewTransform(
3526
- projectInfo.projectRoot,
3527
- projectInfo.framework,
3528
- projectInfo.nextRouterType,
3529
- agentIntegration2,
3530
- true
3531
- );
3532
- const packageJsonResult2 = previewPackageJsonTransform(
3533
- projectInfo.projectRoot,
3534
- agentIntegration2,
3535
- projectInfo.installedAgents,
3536
- projectInfo.packageManager
3537
- );
3538
- if (!result2.success) {
3539
- logger.break();
3540
- logger.error(result2.message);
3541
- logger.break();
3542
- process.exit(1);
3543
- }
3544
- const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
3545
- const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
3546
- if (hasLayoutChanges2 || hasPackageJsonChanges2) {
3547
- logger.break();
3548
- if (hasLayoutChanges2) {
3549
- printDiff(
3550
- result2.filePath,
3551
- result2.originalContent,
3552
- result2.newContent
3553
- );
3554
- }
3555
- if (hasPackageJsonChanges2) {
3556
- if (hasLayoutChanges2) {
3557
- logger.break();
3558
- }
3559
- printDiff(
3560
- packageJsonResult2.filePath,
3561
- packageJsonResult2.originalContent,
3562
- packageJsonResult2.newContent
3563
- );
3564
- }
3565
- logger.break();
3566
- const { proceed } = await prompts({
3567
- type: "confirm",
3568
- name: "proceed",
3569
- message: "Apply these changes?",
3570
- initial: true
3571
- });
3572
- if (!proceed) {
3573
- logger.break();
3574
- logger.log("Agent addition cancelled.");
3575
- } else {
3576
- installPackagesWithFeedback(
3577
- getPackagesToInstall(agentIntegration2, false),
3578
- projectInfo.packageManager,
3579
- projectInfo.projectRoot
3580
- );
3581
- if (hasLayoutChanges2) {
3582
- applyTransformWithFeedback(result2);
3583
- }
3584
- if (hasPackageJsonChanges2) {
3585
- applyPackageJsonWithFeedback(packageJsonResult2);
3586
- }
3587
- logger.break();
3588
- logger.success(
3589
- `${getAgentName(agentIntegration2)} has been added.`
3590
- );
3591
- }
3592
- }
3593
3518
  } else {
3594
3519
  const { agent } = await prompts({
3595
3520
  type: "select",
@@ -4048,7 +3973,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
4048
3973
  reportToCli("error", void 0, error);
4049
3974
  }
4050
3975
  });
4051
- var VERSION4 = "0.1.28";
3976
+ var VERSION4 = "0.1.29";
4052
3977
  var remove = new commander.Command().name("remove").description("disconnect React Grab from your agent").argument("[agent]", `agent to disconnect (${AGENTS.join(", ")}, mcp)`).option("-y, --yes", "skip confirmation prompts", false).option(
4053
3978
  "-c, --cwd <cwd>",
4054
3979
  "working directory (defaults to current directory)",
@@ -4224,7 +4149,7 @@ var remove = new commander.Command().name("remove").description("disconnect Reac
4224
4149
  });
4225
4150
 
4226
4151
  // src/cli.ts
4227
- var VERSION5 = "0.1.28";
4152
+ var VERSION5 = "0.1.29";
4228
4153
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
4229
4154
  process.on("SIGINT", () => process.exit(0));
4230
4155
  process.on("SIGTERM", () => process.exit(0));
package/dist/cli.js CHANGED
@@ -876,7 +876,6 @@ var AGENTS = [
876
876
  "codex",
877
877
  "gemini",
878
878
  "amp",
879
- "ami",
880
879
  "droid",
881
880
  "copilot"
882
881
  ];
@@ -887,7 +886,6 @@ var AGENT_NAMES = {
887
886
  codex: "Codex",
888
887
  gemini: "Gemini",
889
888
  amp: "Amp",
890
- ami: "Ami",
891
889
  droid: "Droid",
892
890
  copilot: "Copilot"
893
891
  };
@@ -944,19 +942,15 @@ var NEXT_PAGES_ROUTER_SCRIPT_WITH_AGENT = (agent) => {
944
942
  />
945
943
  )}`;
946
944
  };
947
- var VITE_SCRIPT = `<script type="module">
948
- if (import.meta.env.DEV) {
949
- import("react-grab");
950
- }
951
- </script>`;
952
- var VITE_SCRIPT_WITH_AGENT = (agent) => {
953
- if (agent === "none") return VITE_SCRIPT;
954
- return `<script type="module">
955
- if (import.meta.env.DEV) {
956
- import("react-grab");
957
- import("@react-grab/${agent}/client");
958
- }
959
- </script>`;
945
+ var VITE_IMPORT = `if (import.meta.env.DEV) {
946
+ import("react-grab");
947
+ }`;
948
+ var VITE_IMPORT_WITH_AGENT = (agent) => {
949
+ if (agent === "none") return VITE_IMPORT;
950
+ return `if (import.meta.env.DEV) {
951
+ import("react-grab");
952
+ import("@react-grab/${agent}/client");
953
+ }`;
960
954
  };
961
955
  var WEBPACK_IMPORT = `if (process.env.NODE_ENV === "development") {
962
956
  import("react-grab");
@@ -1152,51 +1146,7 @@ var addAgentToExistingNextApp = (originalContent, agent, filePath) => {
1152
1146
  message: "Could not find React Grab script to add agent after"
1153
1147
  };
1154
1148
  };
1155
- var addAgentToExistingVite = (originalContent, agent, filePath) => {
1156
- if (agent === "none") {
1157
- return {
1158
- success: true,
1159
- filePath,
1160
- message: "React Grab is already configured",
1161
- noChanges: true
1162
- };
1163
- }
1164
- const agentPackage = `@react-grab/${agent}`;
1165
- if (originalContent.includes(agentPackage)) {
1166
- return {
1167
- success: true,
1168
- filePath,
1169
- message: `Agent ${agent} is already configured`,
1170
- noChanges: true
1171
- };
1172
- }
1173
- const agentImport = `import("${agentPackage}/client");`;
1174
- const reactGrabImportMatch = originalContent.match(
1175
- /import\s*\(\s*["']react-grab["']\s*\);?/
1176
- );
1177
- if (reactGrabImportMatch) {
1178
- const matchedText = reactGrabImportMatch[0];
1179
- const hasSemicolon = matchedText.endsWith(";");
1180
- const newContent = originalContent.replace(
1181
- matchedText,
1182
- `${hasSemicolon ? matchedText.slice(0, -1) : matchedText};
1183
- ${agentImport}`
1184
- );
1185
- return {
1186
- success: true,
1187
- filePath,
1188
- message: `Add ${agent} agent`,
1189
- originalContent,
1190
- newContent
1191
- };
1192
- }
1193
- return {
1194
- success: false,
1195
- filePath,
1196
- message: "Could not find React Grab import to add agent after"
1197
- };
1198
- };
1199
- var addAgentToExistingWebpack = (originalContent, agent, filePath) => {
1149
+ var addAgentToExistingImport = (originalContent, agent, filePath) => {
1200
1150
  if (agent === "none") {
1201
1151
  return {
1202
1152
  success: true,
@@ -1401,41 +1351,55 @@ ${SCRIPT_IMPORT}`
1401
1351
  newContent
1402
1352
  };
1403
1353
  };
1354
+ var checkExistingInstallation = (filePath, agent, reactGrabAlreadyConfigured) => {
1355
+ const content = readFileSync(filePath, "utf-8");
1356
+ if (!hasReactGrabCode(content)) return null;
1357
+ if (reactGrabAlreadyConfigured) {
1358
+ return addAgentToExistingImport(content, agent, filePath);
1359
+ }
1360
+ return {
1361
+ success: true,
1362
+ filePath,
1363
+ message: "React Grab is already installed in this file",
1364
+ noChanges: true
1365
+ };
1366
+ };
1404
1367
  var transformVite = (projectRoot, agent, reactGrabAlreadyConfigured, force = false) => {
1405
- const indexPath = findIndexHtml(projectRoot);
1406
- if (!indexPath) {
1368
+ const entryPath = findEntryFile(projectRoot);
1369
+ if (!force) {
1370
+ const indexPath = findIndexHtml(projectRoot);
1371
+ if (indexPath) {
1372
+ const existingResult = checkExistingInstallation(
1373
+ indexPath,
1374
+ agent,
1375
+ reactGrabAlreadyConfigured
1376
+ );
1377
+ if (existingResult) return existingResult;
1378
+ }
1379
+ }
1380
+ if (!entryPath) {
1407
1381
  return {
1408
1382
  success: false,
1409
1383
  filePath: "",
1410
- message: "Could not find index.html"
1411
- };
1412
- }
1413
- const originalContent = readFileSync(indexPath, "utf-8");
1414
- let newContent = originalContent;
1415
- const hasReactGrabInFile2 = hasReactGrabCode(originalContent);
1416
- if (!force && hasReactGrabInFile2 && reactGrabAlreadyConfigured) {
1417
- return addAgentToExistingVite(originalContent, agent, indexPath);
1418
- }
1419
- if (!force && hasReactGrabInFile2) {
1420
- return {
1421
- success: true,
1422
- filePath: indexPath,
1423
- message: "React Grab is already installed in this file",
1424
- noChanges: true
1384
+ message: "Could not find entry file (src/index.tsx, src/main.tsx, etc.)"
1425
1385
  };
1426
1386
  }
1427
- const scriptBlock = VITE_SCRIPT_WITH_AGENT(agent);
1428
- const headMatch = newContent.match(/<head[^>]*>/i);
1429
- if (headMatch) {
1430
- newContent = newContent.replace(
1431
- headMatch[0],
1432
- `${headMatch[0]}
1433
- ${scriptBlock}`
1387
+ if (!force) {
1388
+ const existingResult = checkExistingInstallation(
1389
+ entryPath,
1390
+ agent,
1391
+ reactGrabAlreadyConfigured
1434
1392
  );
1393
+ if (existingResult) return existingResult;
1435
1394
  }
1395
+ const originalContent = readFileSync(entryPath, "utf-8");
1396
+ const importBlock = VITE_IMPORT_WITH_AGENT(agent);
1397
+ const newContent = `${importBlock}
1398
+
1399
+ ${originalContent}`;
1436
1400
  return {
1437
1401
  success: true,
1438
- filePath: indexPath,
1402
+ filePath: entryPath,
1439
1403
  message: "Add React Grab" + (agent !== "none" ? ` with ${agent} agent` : ""),
1440
1404
  originalContent,
1441
1405
  newContent
@@ -1450,19 +1414,15 @@ var transformWebpack = (projectRoot, agent, reactGrabAlreadyConfigured, force =
1450
1414
  message: "Could not find entry file (src/index.tsx, src/main.tsx, etc.)"
1451
1415
  };
1452
1416
  }
1453
- const originalContent = readFileSync(entryPath, "utf-8");
1454
- const hasReactGrabInFile2 = hasReactGrabCode(originalContent);
1455
- if (!force && hasReactGrabInFile2 && reactGrabAlreadyConfigured) {
1456
- return addAgentToExistingWebpack(originalContent, agent, entryPath);
1457
- }
1458
- if (!force && hasReactGrabInFile2) {
1459
- return {
1460
- success: true,
1461
- filePath: entryPath,
1462
- message: "React Grab is already installed in this file",
1463
- noChanges: true
1464
- };
1417
+ if (!force) {
1418
+ const existingResult = checkExistingInstallation(
1419
+ entryPath,
1420
+ agent,
1421
+ reactGrabAlreadyConfigured
1422
+ );
1423
+ if (existingResult) return existingResult;
1465
1424
  }
1425
+ const originalContent = readFileSync(entryPath, "utf-8");
1466
1426
  const importBlock = WEBPACK_IMPORT_WITH_AGENT(agent);
1467
1427
  const newContent = `${importBlock}
1468
1428
 
@@ -1549,40 +1509,41 @@ ${newContent}`;
1549
1509
  };
1550
1510
  };
1551
1511
  var previewTransform = (projectRoot, framework, nextRouterType, agent, reactGrabAlreadyConfigured = false, force = false) => {
1512
+ const resolvedAgent = agent === "mcp" ? "none" : agent;
1552
1513
  switch (framework) {
1553
1514
  case "next":
1554
1515
  if (nextRouterType === "app") {
1555
1516
  return transformNextAppRouter(
1556
1517
  projectRoot,
1557
- agent,
1518
+ resolvedAgent,
1558
1519
  reactGrabAlreadyConfigured,
1559
1520
  force
1560
1521
  );
1561
1522
  }
1562
1523
  return transformNextPagesRouter(
1563
1524
  projectRoot,
1564
- agent,
1525
+ resolvedAgent,
1565
1526
  reactGrabAlreadyConfigured,
1566
1527
  force
1567
1528
  );
1568
1529
  case "vite":
1569
1530
  return transformVite(
1570
1531
  projectRoot,
1571
- agent,
1532
+ resolvedAgent,
1572
1533
  reactGrabAlreadyConfigured,
1573
1534
  force
1574
1535
  );
1575
1536
  case "tanstack":
1576
1537
  return transformTanStack(
1577
1538
  projectRoot,
1578
- agent,
1539
+ resolvedAgent,
1579
1540
  reactGrabAlreadyConfigured,
1580
1541
  force
1581
1542
  );
1582
1543
  case "webpack":
1583
1544
  return transformWebpack(
1584
1545
  projectRoot,
1585
- agent,
1546
+ resolvedAgent,
1586
1547
  reactGrabAlreadyConfigured,
1587
1548
  force
1588
1549
  );
@@ -1827,8 +1788,17 @@ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
1827
1788
  return findLayoutFile(projectRoot);
1828
1789
  }
1829
1790
  return findDocumentFile(projectRoot);
1830
- case "vite":
1831
- return findIndexHtml(projectRoot);
1791
+ case "vite": {
1792
+ const entryFile = findEntryFile(projectRoot);
1793
+ if (entryFile && hasReactGrabCode(readFileSync(entryFile, "utf-8"))) {
1794
+ return entryFile;
1795
+ }
1796
+ const indexHtml = findIndexHtml(projectRoot);
1797
+ if (indexHtml && hasReactGrabCode(readFileSync(indexHtml, "utf-8"))) {
1798
+ return indexHtml;
1799
+ }
1800
+ return entryFile;
1801
+ }
1832
1802
  case "tanstack":
1833
1803
  return findTanStackRootFile(projectRoot);
1834
1804
  case "webpack":
@@ -2239,7 +2209,7 @@ var previewCdnTransform = (projectRoot, framework, nextRouterType, targetCdnDoma
2239
2209
  };
2240
2210
 
2241
2211
  // src/commands/add.ts
2242
- var VERSION = "0.1.28";
2212
+ var VERSION = "0.1.29";
2243
2213
  var formatInstalledAgentNames = (agents) => agents.map((agent) => AGENT_NAMES[agent] || agent).join(", ");
2244
2214
  var add = new Command().name("add").alias("install").description("connect React Grab to your agent").argument("[agent]", `agent to connect (${AGENTS.join(", ")}, mcp)`).option("-y, --yes", "skip confirmation prompts", false).option(
2245
2215
  "-c, --cwd <cwd>",
@@ -2277,11 +2247,36 @@ var add = new Command().name("add").alias("install").description("connect React
2277
2247
  }
2278
2248
  let agentIntegration;
2279
2249
  let agentsToRemove = [];
2280
- if (agentArg) {
2250
+ if (agentArg === "mcp") {
2251
+ if (isNonInteractive) {
2252
+ const results = installMcpServers();
2253
+ const hasSuccess = results.some((result2) => result2.success);
2254
+ if (!hasSuccess) {
2255
+ logger.break();
2256
+ logger.error("Failed to install MCP server.");
2257
+ logger.break();
2258
+ process.exit(1);
2259
+ }
2260
+ } else {
2261
+ const didInstall = await promptMcpInstall();
2262
+ if (!didInstall) {
2263
+ logger.break();
2264
+ process.exit(0);
2265
+ }
2266
+ }
2267
+ logger.break();
2268
+ logger.log(
2269
+ `${highlighter.success("Success!")} MCP server has been configured.`
2270
+ );
2271
+ logger.log("Restart your agents to activate.");
2272
+ logger.break();
2273
+ agentIntegration = "mcp";
2274
+ projectInfo.installedAgents = [...projectInfo.installedAgents, "mcp"];
2275
+ } else if (agentArg) {
2281
2276
  if (!AGENTS.includes(agentArg)) {
2282
2277
  logger.break();
2283
2278
  logger.error(`Invalid agent: ${agentArg}`);
2284
- logger.error(`Available agents: ${AGENTS.join(", ")}`);
2279
+ logger.error(`Available agents: ${AGENTS.join(", ")}, mcp`);
2285
2280
  logger.break();
2286
2281
  process.exit(1);
2287
2282
  }
@@ -2600,7 +2595,7 @@ var MAX_KEY_HOLD_DURATION_MS = 2e3;
2600
2595
  var MAX_CONTEXT_LINES = 50;
2601
2596
 
2602
2597
  // src/commands/configure.ts
2603
- var VERSION2 = "0.1.28";
2598
+ var VERSION2 = "0.1.29";
2604
2599
  var isMac = process.platform === "darwin";
2605
2600
  var META_LABEL = isMac ? "Cmd" : "Win";
2606
2601
  var ALT_LABEL = isMac ? "Option" : "Alt";
@@ -3156,7 +3151,7 @@ var uninstallPackagesWithFeedback = (packages, packageManager, projectRoot) => {
3156
3151
  };
3157
3152
 
3158
3153
  // src/commands/init.ts
3159
- var VERSION3 = "0.1.28";
3154
+ var VERSION3 = "0.1.29";
3160
3155
  var REPORT_URL = "https://react-grab.com/api/report-cli";
3161
3156
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
3162
3157
  var reportToCli = (type, config, error) => {
@@ -3487,76 +3482,6 @@ var init = new Command().name("init").description("initialize React Grab in your
3487
3482
  logger.break();
3488
3483
  logger.success("MCP server has been configured.");
3489
3484
  logger.log("Restart your agents to activate.");
3490
- agentIntegration2 = "mcp";
3491
- projectInfo.installedAgents = ["mcp"];
3492
- const result2 = previewTransform(
3493
- projectInfo.projectRoot,
3494
- projectInfo.framework,
3495
- projectInfo.nextRouterType,
3496
- agentIntegration2,
3497
- true
3498
- );
3499
- const packageJsonResult2 = previewPackageJsonTransform(
3500
- projectInfo.projectRoot,
3501
- agentIntegration2,
3502
- projectInfo.installedAgents,
3503
- projectInfo.packageManager
3504
- );
3505
- if (!result2.success) {
3506
- logger.break();
3507
- logger.error(result2.message);
3508
- logger.break();
3509
- process.exit(1);
3510
- }
3511
- const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
3512
- const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
3513
- if (hasLayoutChanges2 || hasPackageJsonChanges2) {
3514
- logger.break();
3515
- if (hasLayoutChanges2) {
3516
- printDiff(
3517
- result2.filePath,
3518
- result2.originalContent,
3519
- result2.newContent
3520
- );
3521
- }
3522
- if (hasPackageJsonChanges2) {
3523
- if (hasLayoutChanges2) {
3524
- logger.break();
3525
- }
3526
- printDiff(
3527
- packageJsonResult2.filePath,
3528
- packageJsonResult2.originalContent,
3529
- packageJsonResult2.newContent
3530
- );
3531
- }
3532
- logger.break();
3533
- const { proceed } = await prompts({
3534
- type: "confirm",
3535
- name: "proceed",
3536
- message: "Apply these changes?",
3537
- initial: true
3538
- });
3539
- if (!proceed) {
3540
- logger.break();
3541
- logger.log("Agent addition cancelled.");
3542
- } else {
3543
- installPackagesWithFeedback(
3544
- getPackagesToInstall(agentIntegration2, false),
3545
- projectInfo.packageManager,
3546
- projectInfo.projectRoot
3547
- );
3548
- if (hasLayoutChanges2) {
3549
- applyTransformWithFeedback(result2);
3550
- }
3551
- if (hasPackageJsonChanges2) {
3552
- applyPackageJsonWithFeedback(packageJsonResult2);
3553
- }
3554
- logger.break();
3555
- logger.success(
3556
- `${getAgentName(agentIntegration2)} has been added.`
3557
- );
3558
- }
3559
- }
3560
3485
  } else {
3561
3486
  const { agent } = await prompts({
3562
3487
  type: "select",
@@ -4015,7 +3940,7 @@ var init = new Command().name("init").description("initialize React Grab in your
4015
3940
  reportToCli("error", void 0, error);
4016
3941
  }
4017
3942
  });
4018
- var VERSION4 = "0.1.28";
3943
+ var VERSION4 = "0.1.29";
4019
3944
  var remove = new Command().name("remove").description("disconnect React Grab from your agent").argument("[agent]", `agent to disconnect (${AGENTS.join(", ")}, mcp)`).option("-y, --yes", "skip confirmation prompts", false).option(
4020
3945
  "-c, --cwd <cwd>",
4021
3946
  "working directory (defaults to current directory)",
@@ -4191,7 +4116,7 @@ var remove = new Command().name("remove").description("disconnect React Grab fro
4191
4116
  });
4192
4117
 
4193
4118
  // src/cli.ts
4194
- var VERSION5 = "0.1.28";
4119
+ var VERSION5 = "0.1.29";
4195
4120
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
4196
4121
  process.on("SIGINT", () => process.exit(0));
4197
4122
  process.on("SIGTERM", () => process.exit(0));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-grab/cli",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "bin": {
5
5
  "react-grab": "./dist/cli.js"
6
6
  },