@react-grab/cli 0.1.11 → 0.1.13

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 +527 -87
  2. package/dist/cli.js +525 -89
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -8,12 +8,18 @@ var child_process = require('child_process');
8
8
  var fs = require('fs');
9
9
  var path = require('path');
10
10
  var ni = require('@antfu/ni');
11
+ var os = require('os');
12
+ var process2 = require('process');
11
13
  var ora = require('ora');
12
14
 
13
15
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
16
 
15
17
  var pc__default = /*#__PURE__*/_interopDefault(pc);
16
18
  var basePrompts__default = /*#__PURE__*/_interopDefault(basePrompts);
19
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
20
+ var path__default = /*#__PURE__*/_interopDefault(path);
21
+ var os__default = /*#__PURE__*/_interopDefault(os);
22
+ var process2__default = /*#__PURE__*/_interopDefault(process2);
17
23
  var ora__default = /*#__PURE__*/_interopDefault(ora);
18
24
 
19
25
  var highlighter = {
@@ -302,7 +308,8 @@ var AGENT_PACKAGES = [
302
308
  "@react-grab/codex",
303
309
  "@react-grab/gemini",
304
310
  "@react-grab/amp",
305
- "@react-grab/ami"
311
+ "@react-grab/ami",
312
+ "@react-grab/mcp"
306
313
  ];
307
314
  var detectUnsupportedFramework = (projectRoot) => {
308
315
  const packageJsonPath = path.join(projectRoot, "package.json");
@@ -533,6 +540,301 @@ var getPackagesToUninstall = (agent) => {
533
540
  };
534
541
  var spinner = (text, options) => ora__default.default({ text, isSilent: options?.silent });
535
542
 
543
+ // src/utils/install-mcp.ts
544
+ var SERVER_NAME = "react-grab-mcp";
545
+ var PACKAGE_NAME = "@react-grab/mcp";
546
+ var getBaseDir = () => {
547
+ const homeDir = os__default.default.homedir();
548
+ if (process2__default.default.platform === "win32") {
549
+ return process2__default.default.env.APPDATA || path__default.default.join(homeDir, "AppData", "Roaming");
550
+ }
551
+ if (process2__default.default.platform === "darwin") {
552
+ return path__default.default.join(homeDir, "Library", "Application Support");
553
+ }
554
+ return process2__default.default.env.XDG_CONFIG_HOME || path__default.default.join(homeDir, ".config");
555
+ };
556
+ var getZedConfigPath = () => {
557
+ const homeDir = os__default.default.homedir();
558
+ if (process2__default.default.platform === "win32") {
559
+ const appData = process2__default.default.env.APPDATA || path__default.default.join(homeDir, "AppData", "Roaming");
560
+ return path__default.default.join(appData, "Zed", "settings.json");
561
+ }
562
+ return path__default.default.join(homeDir, ".config", "zed", "settings.json");
563
+ };
564
+ var getClients = () => {
565
+ const homeDir = os__default.default.homedir();
566
+ const baseDir = getBaseDir();
567
+ const stdioConfig = {
568
+ command: "npx",
569
+ args: ["-y", PACKAGE_NAME, "--stdio"]
570
+ };
571
+ return [
572
+ {
573
+ name: "Cursor",
574
+ configPath: path__default.default.join(homeDir, ".cursor", "mcp.json"),
575
+ configKey: "mcpServers",
576
+ format: "json",
577
+ serverConfig: stdioConfig
578
+ },
579
+ {
580
+ name: "VS Code",
581
+ configPath: path__default.default.join(baseDir, "Code", "User", "mcp.json"),
582
+ configKey: "servers",
583
+ format: "json",
584
+ serverConfig: { type: "stdio", ...stdioConfig }
585
+ },
586
+ {
587
+ name: "Claude Code",
588
+ configPath: path__default.default.join(homeDir, ".claude.json"),
589
+ configKey: "mcpServers",
590
+ format: "json",
591
+ serverConfig: stdioConfig
592
+ },
593
+ {
594
+ name: "Amp",
595
+ configPath: path__default.default.join(homeDir, ".config", "amp", "settings.json"),
596
+ configKey: "amp.mcpServers",
597
+ format: "json",
598
+ serverConfig: stdioConfig
599
+ },
600
+ {
601
+ name: "Droid",
602
+ configPath: path__default.default.join(homeDir, ".factory", "mcp.json"),
603
+ configKey: "mcpServers",
604
+ format: "json",
605
+ serverConfig: { type: "stdio", ...stdioConfig }
606
+ },
607
+ {
608
+ name: "Codex",
609
+ configPath: path__default.default.join(
610
+ process2__default.default.env.CODEX_HOME || path__default.default.join(homeDir, ".codex"),
611
+ "config.toml"
612
+ ),
613
+ configKey: "mcp_servers",
614
+ format: "toml",
615
+ serverConfig: stdioConfig
616
+ },
617
+ {
618
+ name: "Zed",
619
+ configPath: getZedConfigPath(),
620
+ configKey: "context_servers",
621
+ format: "json",
622
+ serverConfig: { source: "custom", ...stdioConfig, env: {} }
623
+ },
624
+ {
625
+ name: "Windsurf",
626
+ configPath: path__default.default.join(homeDir, ".codeium", "windsurf", "mcp_config.json"),
627
+ configKey: "mcpServers",
628
+ format: "json",
629
+ serverConfig: stdioConfig
630
+ }
631
+ ];
632
+ };
633
+ var ensureDirectory = (filePath) => {
634
+ const directory = path__default.default.dirname(filePath);
635
+ if (!fs__default.default.existsSync(directory)) {
636
+ fs__default.default.mkdirSync(directory, { recursive: true });
637
+ }
638
+ };
639
+ var indentJson = (json, baseIndent) => json.split("\n").map((line, index) => index === 0 ? line : baseIndent + line).join("\n");
640
+ var insertIntoJsonc = (filePath, content, configKey, serverName, serverConfig) => {
641
+ if (content.includes(`"${serverName}"`)) return;
642
+ const serverJson = indentJson(
643
+ JSON.stringify(serverConfig, null, 2),
644
+ " "
645
+ );
646
+ const escapedConfigKey = configKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
647
+ const keyPattern = new RegExp(`"${escapedConfigKey}"\\s*:\\s*\\{`);
648
+ const keyMatch = keyPattern.exec(content);
649
+ if (keyMatch) {
650
+ const insertPosition = keyMatch.index + keyMatch[0].length;
651
+ const entry = `
652
+ "${serverName}": ${serverJson},`;
653
+ fs__default.default.writeFileSync(
654
+ filePath,
655
+ content.slice(0, insertPosition) + entry + content.slice(insertPosition)
656
+ );
657
+ return;
658
+ }
659
+ const lastBrace = content.lastIndexOf("}");
660
+ if (lastBrace === -1) return;
661
+ const beforeBrace = content.slice(0, lastBrace).trimEnd();
662
+ const withoutComments = beforeBrace.replace(/\/\/.*$/, "").trimEnd();
663
+ const lastChar = withoutComments[withoutComments.length - 1];
664
+ const needsComma = lastChar !== void 0 && lastChar !== "{" && lastChar !== ",";
665
+ const section = `${needsComma ? "," : ""}
666
+ "${configKey}": {
667
+ "${serverName}": ${serverJson}
668
+ }`;
669
+ fs__default.default.writeFileSync(filePath, beforeBrace + section + "\n}\n");
670
+ };
671
+ var installJsonClient = (client) => {
672
+ ensureDirectory(client.configPath);
673
+ if (!fs__default.default.existsSync(client.configPath)) {
674
+ const config = {
675
+ [client.configKey]: { [SERVER_NAME]: client.serverConfig }
676
+ };
677
+ fs__default.default.writeFileSync(client.configPath, JSON.stringify(config, null, 2) + "\n");
678
+ return;
679
+ }
680
+ const content = fs__default.default.readFileSync(client.configPath, "utf8");
681
+ try {
682
+ const config = JSON.parse(content);
683
+ const servers = config[client.configKey] ?? {};
684
+ servers[SERVER_NAME] = client.serverConfig;
685
+ config[client.configKey] = servers;
686
+ fs__default.default.writeFileSync(client.configPath, JSON.stringify(config, null, 2) + "\n");
687
+ } catch {
688
+ insertIntoJsonc(
689
+ client.configPath,
690
+ content,
691
+ client.configKey,
692
+ SERVER_NAME,
693
+ client.serverConfig
694
+ );
695
+ }
696
+ };
697
+ var buildTomlSection = (configKey, serverConfig) => {
698
+ const lines = [`[${configKey}.${SERVER_NAME}]`];
699
+ for (const [key, value] of Object.entries(serverConfig)) {
700
+ if (typeof value === "string") {
701
+ lines.push(`${key} = "${value}"`);
702
+ } else if (Array.isArray(value)) {
703
+ const items = value.map((item) => `"${item}"`).join(", ");
704
+ lines.push(`${key} = [${items}]`);
705
+ }
706
+ }
707
+ return lines.join("\n");
708
+ };
709
+ var installTomlClient = (client) => {
710
+ ensureDirectory(client.configPath);
711
+ const sectionHeader = `[${client.configKey}.${SERVER_NAME}]`;
712
+ const newSection = buildTomlSection(client.configKey, client.serverConfig);
713
+ if (!fs__default.default.existsSync(client.configPath)) {
714
+ fs__default.default.writeFileSync(client.configPath, newSection + "\n");
715
+ return;
716
+ }
717
+ const content = fs__default.default.readFileSync(client.configPath, "utf8");
718
+ if (!content.includes(sectionHeader)) {
719
+ fs__default.default.writeFileSync(
720
+ client.configPath,
721
+ content.trimEnd() + "\n\n" + newSection + "\n"
722
+ );
723
+ return;
724
+ }
725
+ const lines = content.split("\n");
726
+ const resultLines = [];
727
+ let isInsideOurSection = false;
728
+ let didInsertReplacement = false;
729
+ for (const line of lines) {
730
+ if (line.trim() === sectionHeader) {
731
+ isInsideOurSection = true;
732
+ if (!didInsertReplacement) {
733
+ resultLines.push(newSection);
734
+ didInsertReplacement = true;
735
+ }
736
+ continue;
737
+ }
738
+ if (isInsideOurSection && line.startsWith("[")) {
739
+ isInsideOurSection = false;
740
+ }
741
+ if (!isInsideOurSection) {
742
+ resultLines.push(line);
743
+ }
744
+ }
745
+ fs__default.default.writeFileSync(client.configPath, resultLines.join("\n"));
746
+ };
747
+ var getMcpClientNames = () => getClients().map((client) => client.name);
748
+ var installMcpServers = (selectedClients) => {
749
+ const allClients = getClients();
750
+ const clients = selectedClients ? allClients.filter((client) => selectedClients.includes(client.name)) : allClients;
751
+ const results = [];
752
+ const installSpinner = spinner("Installing MCP server.").start();
753
+ for (const client of clients) {
754
+ try {
755
+ if (client.format === "toml") {
756
+ installTomlClient(client);
757
+ } else {
758
+ installJsonClient(client);
759
+ }
760
+ results.push({
761
+ client: client.name,
762
+ configPath: client.configPath,
763
+ success: true
764
+ });
765
+ } catch (error) {
766
+ const message = error instanceof Error ? error.message : String(error);
767
+ results.push({
768
+ client: client.name,
769
+ configPath: client.configPath,
770
+ success: false,
771
+ error: message
772
+ });
773
+ }
774
+ }
775
+ const successCount = results.filter((result) => result.success).length;
776
+ const failedCount = results.length - successCount;
777
+ if (failedCount > 0) {
778
+ installSpinner.warn(
779
+ `Installed to ${successCount}/${results.length} agents.`
780
+ );
781
+ } else {
782
+ installSpinner.succeed(`Installed to ${successCount} agents.`);
783
+ }
784
+ for (const result of results) {
785
+ if (result.success) {
786
+ logger.log(
787
+ ` ${highlighter.success("\u2713")} ${result.client} ${highlighter.dim("\u2192")} ${highlighter.dim(result.configPath)}`
788
+ );
789
+ } else {
790
+ logger.log(
791
+ ` ${highlighter.error("\u2717")} ${result.client} ${highlighter.dim("\u2192")} ${result.error}`
792
+ );
793
+ }
794
+ }
795
+ return results;
796
+ };
797
+ var promptConnectionMode = async () => {
798
+ const { connectionMode } = await prompts({
799
+ type: "select",
800
+ name: "connectionMode",
801
+ message: "How would you like to connect?",
802
+ choices: [
803
+ {
804
+ title: `MCP ${highlighter.dim("(recommended)")}`,
805
+ description: "Installs to all supported agents at once",
806
+ value: "mcp"
807
+ },
808
+ {
809
+ title: "Legacy",
810
+ description: "Install a per-project agent package",
811
+ value: "legacy"
812
+ }
813
+ ]
814
+ });
815
+ return connectionMode;
816
+ };
817
+ var promptMcpInstall = async () => {
818
+ const clientNames = getMcpClientNames();
819
+ const { selectedAgents } = await prompts({
820
+ type: "multiselect",
821
+ name: "selectedAgents",
822
+ message: "Select agents to install MCP server for:",
823
+ choices: clientNames.map((name) => ({
824
+ title: name,
825
+ value: name,
826
+ selected: true
827
+ }))
828
+ });
829
+ if (selectedAgents === void 0 || selectedAgents.length === 0) {
830
+ return false;
831
+ }
832
+ logger.break();
833
+ const results = installMcpServers(selectedAgents);
834
+ const hasSuccess = results.some((result) => result.success);
835
+ return hasSuccess;
836
+ };
837
+
536
838
  // src/utils/templates.ts
537
839
  var AGENTS = [
538
840
  "claude-code",
@@ -554,6 +856,13 @@ var AGENT_NAMES = {
554
856
  ami: "Ami",
555
857
  droid: "Droid"
556
858
  };
859
+ var getAgentDisplayName = (agent) => {
860
+ if (agent === "mcp") return "MCP";
861
+ if (agent in AGENT_NAMES) {
862
+ return AGENT_NAMES[agent];
863
+ }
864
+ return agent;
865
+ };
557
866
  var NEXT_APP_ROUTER_SCRIPT = `{process.env.NODE_ENV === "development" && (
558
867
  <Script
559
868
  src="//unpkg.com/react-grab/dist/index.global.js"
@@ -1307,6 +1616,14 @@ var previewPackageJsonTransform = (projectRoot, agent, installedAgents, packageM
1307
1616
  noChanges: true
1308
1617
  };
1309
1618
  }
1619
+ if (agent === "mcp") {
1620
+ return {
1621
+ success: true,
1622
+ filePath: "",
1623
+ message: "MCP does not use package.json dev script",
1624
+ noChanges: true
1625
+ };
1626
+ }
1310
1627
  const packageJsonPath = path.join(projectRoot, "package.json");
1311
1628
  if (!fs.existsSync(packageJsonPath)) {
1312
1629
  return {
@@ -1868,9 +2185,9 @@ var previewCdnTransform = (projectRoot, framework, nextRouterType, targetCdnDoma
1868
2185
  };
1869
2186
 
1870
2187
  // src/commands/add.ts
1871
- var VERSION = "0.1.11";
2188
+ var VERSION = "0.1.13";
1872
2189
  var formatInstalledAgentNames = (agents) => agents.map((agent) => AGENT_NAMES[agent] || agent).join(", ");
1873
- 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(
2190
+ var add = new commander.Command().name("add").alias("install").description("connect React Grab to your agent").argument("[agent]", `agent to add (${AGENTS.join(", ")})`).option("-y, --yes", "skip confirmation prompts", false).option(
1874
2191
  "-c, --cwd <cwd>",
1875
2192
  "working directory (defaults to current directory)",
1876
2193
  process.cwd()
@@ -1897,9 +2214,10 @@ var add = new commander.Command().name("add").alias("install").description("add
1897
2214
  const availableAgents = AGENTS.filter(
1898
2215
  (agent) => !projectInfo.installedAgents.includes(agent)
1899
2216
  );
1900
- if (availableAgents.length === 0) {
2217
+ if (availableAgents.length === 0 && isNonInteractive && !agentArg) {
1901
2218
  logger.break();
1902
- logger.success("All agent integrations are already installed.");
2219
+ logger.success("All legacy agents are already installed.");
2220
+ logger.log("Run without -y to add MCP.");
1903
2221
  logger.break();
1904
2222
  process.exit(0);
1905
2223
  }
@@ -1933,11 +2251,11 @@ var add = new commander.Command().name("add").alias("install").description("add
1933
2251
  message: "How would you like to proceed?",
1934
2252
  choices: [
1935
2253
  {
1936
- title: `Replace with ${AGENT_NAMES[agentIntegration]}`,
2254
+ title: `Replace with ${getAgentDisplayName(agentIntegration)}`,
1937
2255
  value: "replace"
1938
2256
  },
1939
2257
  {
1940
- title: `Add ${AGENT_NAMES[agentIntegration]} alongside existing`,
2258
+ title: `Add ${getAgentDisplayName(agentIntegration)} alongside existing`,
1941
2259
  value: "add"
1942
2260
  },
1943
2261
  { title: "Cancel", value: "cancel" }
@@ -1961,48 +2279,72 @@ var add = new commander.Command().name("add").alias("install").description("add
1961
2279
  logger.warn(`Currently installed: ${installedNames}`);
1962
2280
  logger.break();
1963
2281
  }
1964
- const { agent } = await prompts({
1965
- type: "select",
1966
- name: "agent",
1967
- message: `Which ${highlighter.info("coding agent")} would you like to connect?`,
1968
- choices: availableAgents.map((availableAgent) => ({
1969
- title: AGENT_NAMES[availableAgent],
1970
- value: availableAgent
1971
- }))
1972
- });
1973
- if (!agent) {
2282
+ const connectionMode = await promptConnectionMode();
2283
+ if (connectionMode === void 0) {
1974
2284
  logger.break();
1975
2285
  process.exit(1);
1976
2286
  }
1977
- agentIntegration = agent;
1978
- if (projectInfo.installedAgents.length > 0) {
1979
- const installedNames = formatInstalledAgentNames(
1980
- projectInfo.installedAgents
2287
+ if (connectionMode === "mcp") {
2288
+ const didInstall = await promptMcpInstall();
2289
+ if (!didInstall) {
2290
+ logger.break();
2291
+ process.exit(0);
2292
+ }
2293
+ logger.break();
2294
+ logger.log(
2295
+ `${highlighter.success("Success!")} MCP server has been configured.`
1981
2296
  );
1982
- const { action } = await prompts({
2297
+ logger.log("Restart your agents to activate.");
2298
+ logger.break();
2299
+ agentIntegration = "mcp";
2300
+ projectInfo.installedAgents = [...projectInfo.installedAgents, "mcp"];
2301
+ } else {
2302
+ const { agent } = await prompts({
1983
2303
  type: "select",
1984
- name: "action",
1985
- message: "How would you like to proceed?",
2304
+ name: "agent",
2305
+ message: `Which ${highlighter.info("agent")} would you like to connect?`,
1986
2306
  choices: [
1987
- {
1988
- title: `Replace ${installedNames} with ${AGENT_NAMES[agentIntegration]}`,
1989
- value: "replace"
1990
- },
1991
- {
1992
- title: `Add ${AGENT_NAMES[agentIntegration]} alongside existing`,
1993
- value: "add"
1994
- },
1995
- { title: "Cancel", value: "cancel" }
2307
+ ...availableAgents.map((availableAgent) => ({
2308
+ title: AGENT_NAMES[availableAgent],
2309
+ value: availableAgent
2310
+ })),
2311
+ { title: "Skip", value: "skip" }
1996
2312
  ]
1997
2313
  });
1998
- if (!action || action === "cancel") {
1999
- logger.break();
2000
- logger.log("Changes cancelled.");
2314
+ if (!agent || agent === "skip") {
2001
2315
  logger.break();
2002
2316
  process.exit(0);
2003
2317
  }
2004
- if (action === "replace") {
2005
- agentsToRemove = [...projectInfo.installedAgents];
2318
+ agentIntegration = agent;
2319
+ if (projectInfo.installedAgents.length > 0) {
2320
+ const installedNames = formatInstalledAgentNames(
2321
+ projectInfo.installedAgents
2322
+ );
2323
+ const { action } = await prompts({
2324
+ type: "select",
2325
+ name: "action",
2326
+ message: "How would you like to proceed?",
2327
+ choices: [
2328
+ {
2329
+ title: `Replace ${installedNames} with ${getAgentDisplayName(agentIntegration)}`,
2330
+ value: "replace"
2331
+ },
2332
+ {
2333
+ title: `Add ${getAgentDisplayName(agentIntegration)} alongside existing`,
2334
+ value: "add"
2335
+ },
2336
+ { title: "Cancel", value: "cancel" }
2337
+ ]
2338
+ });
2339
+ if (!action || action === "cancel") {
2340
+ logger.break();
2341
+ logger.log("Changes cancelled.");
2342
+ logger.break();
2343
+ process.exit(0);
2344
+ }
2345
+ if (action === "replace") {
2346
+ agentsToRemove = [...projectInfo.installedAgents];
2347
+ }
2006
2348
  }
2007
2349
  }
2008
2350
  } else {
@@ -2079,7 +2421,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2079
2421
  );
2080
2422
  }
2081
2423
  const addingSpinner = spinner(
2082
- `Adding ${AGENT_NAMES[agentIntegration]}.`
2424
+ `Adding ${getAgentDisplayName(agentIntegration)}.`
2083
2425
  ).start();
2084
2426
  addingSpinner.succeed();
2085
2427
  const result = previewTransform(
@@ -2185,7 +2527,7 @@ var add = new commander.Command().name("add").alias("install").description("add
2185
2527
  }
2186
2528
  logger.break();
2187
2529
  logger.log(
2188
- `${highlighter.success("Success!")} ${AGENT_NAMES[agentIntegration]} has been added.`
2530
+ `${highlighter.success("Success!")} ${getAgentDisplayName(agentIntegration)} has been added.`
2189
2531
  );
2190
2532
  if (packageJsonResult.warning) {
2191
2533
  logger.warn(packageJsonResult.warning);
@@ -2204,7 +2546,7 @@ var MAX_KEY_HOLD_DURATION_MS = 2e3;
2204
2546
  var MAX_CONTEXT_LINES = 50;
2205
2547
 
2206
2548
  // src/commands/configure.ts
2207
- var VERSION2 = "0.1.11";
2549
+ var VERSION2 = "0.1.13";
2208
2550
  var isMac = process.platform === "darwin";
2209
2551
  var META_LABEL = isMac ? "Cmd" : "Win";
2210
2552
  var ALT_LABEL = isMac ? "Option" : "Alt";
@@ -2707,7 +3049,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
2707
3049
  });
2708
3050
 
2709
3051
  // src/utils/cli-helpers.ts
2710
- var formatInstalledAgentNames2 = (agents) => agents.map((agent) => AGENT_NAMES[agent] ?? agent).join(", ");
3052
+ var formatInstalledAgentNames2 = (agents) => agents.map(getAgentDisplayName).join(", ");
2711
3053
  var applyTransformWithFeedback = (result, message) => {
2712
3054
  const writeSpinner = spinner(
2713
3055
  message ?? `Applying changes to ${result.filePath}.`
@@ -2760,7 +3102,7 @@ var uninstallPackagesWithFeedback = (packages, packageManager, projectRoot) => {
2760
3102
  };
2761
3103
 
2762
3104
  // src/commands/init.ts
2763
- var VERSION3 = "0.1.11";
3105
+ var VERSION3 = "0.1.13";
2764
3106
  var REPORT_URL = "https://react-grab.com/api/report-cli";
2765
3107
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
2766
3108
  var reportToCli = (type, config, error) => {
@@ -2796,12 +3138,7 @@ var UNSUPPORTED_FRAMEWORK_NAMES = {
2796
3138
  sveltekit: "SvelteKit",
2797
3139
  gatsby: "Gatsby"
2798
3140
  };
2799
- var getAgentName = (agent) => {
2800
- if (agent in AGENT_NAMES) {
2801
- return AGENT_NAMES[agent];
2802
- }
2803
- return agent;
2804
- };
3141
+ var getAgentName = getAgentDisplayName;
2805
3142
  var formatActivationKeyDisplay2 = (activationKey) => {
2806
3143
  if (!activationKey) return "Default (Option/Alt)";
2807
3144
  return activationKey.split("+").map((part) => {
@@ -2816,7 +3153,7 @@ var formatActivationKeyDisplay2 = (activationKey) => {
2816
3153
  };
2817
3154
  var init = new commander.Command().name("init").description("initialize React Grab in your project").option("-y, --yes", "skip confirmation prompts", false).option("-f, --force", "force overwrite existing config", false).option(
2818
3155
  "-a, --agent <agent>",
2819
- "agent integration (claude-code, cursor, opencode, codex, gemini, amp, droid)"
3156
+ "connect to your agent (claude-code, cursor, opencode, codex, gemini, amp, mcp)"
2820
3157
  ).option(
2821
3158
  "-k, --key <key>",
2822
3159
  "activation key (e.g., Meta+K, Ctrl+Shift+G, Space)"
@@ -3035,23 +3372,108 @@ var init = new commander.Command().name("init").description("initialize React Gr
3035
3372
  const availableAgents = AGENTS.filter(
3036
3373
  (agent) => !projectInfo.installedAgents.includes(agent)
3037
3374
  );
3038
- if (availableAgents.length > 0) {
3375
+ logger.break();
3376
+ const { wantAddAgent } = await prompts({
3377
+ type: "confirm",
3378
+ name: "wantAddAgent",
3379
+ message: `Would you like to ${highlighter.info("connect it to your agent")}?`,
3380
+ initial: false
3381
+ });
3382
+ if (wantAddAgent === void 0) {
3039
3383
  logger.break();
3040
- const { wantAddAgent } = await prompts({
3041
- type: "confirm",
3042
- name: "wantAddAgent",
3043
- message: `Would you like to connect React Grab to a ${highlighter.info("coding agent")}? ${highlighter.dim("(optional)")}`,
3044
- initial: false
3045
- });
3046
- if (wantAddAgent === void 0) {
3384
+ process.exit(1);
3385
+ }
3386
+ if (wantAddAgent) {
3387
+ const connectionMode = await promptConnectionMode();
3388
+ if (connectionMode === void 0) {
3047
3389
  logger.break();
3048
3390
  process.exit(1);
3049
3391
  }
3050
- if (wantAddAgent) {
3392
+ let agentIntegration2;
3393
+ if (connectionMode === "mcp") {
3394
+ const didInstall = await promptMcpInstall();
3395
+ if (!didInstall) {
3396
+ logger.break();
3397
+ process.exit(0);
3398
+ }
3399
+ logger.break();
3400
+ logger.success("MCP server has been configured.");
3401
+ logger.log("Restart your agents to activate.");
3402
+ agentIntegration2 = "mcp";
3403
+ projectInfo.installedAgents = ["mcp"];
3404
+ const result2 = previewTransform(
3405
+ projectInfo.projectRoot,
3406
+ projectInfo.framework,
3407
+ projectInfo.nextRouterType,
3408
+ agentIntegration2,
3409
+ true
3410
+ );
3411
+ const packageJsonResult2 = previewPackageJsonTransform(
3412
+ projectInfo.projectRoot,
3413
+ agentIntegration2,
3414
+ projectInfo.installedAgents,
3415
+ projectInfo.packageManager
3416
+ );
3417
+ if (!result2.success) {
3418
+ logger.break();
3419
+ logger.error(result2.message);
3420
+ logger.break();
3421
+ process.exit(1);
3422
+ }
3423
+ const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
3424
+ const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
3425
+ if (hasLayoutChanges2 || hasPackageJsonChanges2) {
3426
+ logger.break();
3427
+ if (hasLayoutChanges2) {
3428
+ printDiff(
3429
+ result2.filePath,
3430
+ result2.originalContent,
3431
+ result2.newContent
3432
+ );
3433
+ }
3434
+ if (hasPackageJsonChanges2) {
3435
+ if (hasLayoutChanges2) {
3436
+ logger.break();
3437
+ }
3438
+ printDiff(
3439
+ packageJsonResult2.filePath,
3440
+ packageJsonResult2.originalContent,
3441
+ packageJsonResult2.newContent
3442
+ );
3443
+ }
3444
+ logger.break();
3445
+ const { proceed } = await prompts({
3446
+ type: "confirm",
3447
+ name: "proceed",
3448
+ message: "Apply these changes?",
3449
+ initial: true
3450
+ });
3451
+ if (!proceed) {
3452
+ logger.break();
3453
+ logger.log("Agent addition cancelled.");
3454
+ } else {
3455
+ installPackagesWithFeedback(
3456
+ getPackagesToInstall(agentIntegration2, false),
3457
+ projectInfo.packageManager,
3458
+ projectInfo.projectRoot
3459
+ );
3460
+ if (hasLayoutChanges2) {
3461
+ applyTransformWithFeedback(result2);
3462
+ }
3463
+ if (hasPackageJsonChanges2) {
3464
+ applyPackageJsonWithFeedback(packageJsonResult2);
3465
+ }
3466
+ logger.break();
3467
+ logger.success(
3468
+ `${getAgentName(agentIntegration2)} has been added.`
3469
+ );
3470
+ }
3471
+ }
3472
+ } else {
3051
3473
  const { agent } = await prompts({
3052
3474
  type: "select",
3053
3475
  name: "agent",
3054
- message: `Which ${highlighter.info("coding agent")} would you like to connect?`,
3476
+ message: `Which ${highlighter.info("agent")} would you like to connect?`,
3055
3477
  choices: [
3056
3478
  ...availableAgents.map((innerAgent) => ({
3057
3479
  title: getAgentName(innerAgent),
@@ -3064,7 +3486,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3064
3486
  logger.break();
3065
3487
  process.exit(0);
3066
3488
  }
3067
- const agentIntegration2 = agent;
3489
+ agentIntegration2 = agent;
3068
3490
  let agentsToRemove2 = [];
3069
3491
  if (projectInfo.installedAgents.length > 0) {
3070
3492
  const installedNames = formatInstalledAgentNames2(
@@ -3362,7 +3784,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
3362
3784
  const { wantAddAgent } = await prompts({
3363
3785
  type: "confirm",
3364
3786
  name: "wantAddAgent",
3365
- message: `Would you like to connect React Grab to a ${highlighter.info("coding agent")}? ${highlighter.dim("(optional)")}`,
3787
+ message: `Would you like to ${highlighter.info("connect it to your agent")}?`,
3366
3788
  initial: false
3367
3789
  });
3368
3790
  if (wantAddAgent === void 0) {
@@ -3370,24 +3792,42 @@ var init = new commander.Command().name("init").description("initialize React Gr
3370
3792
  process.exit(1);
3371
3793
  }
3372
3794
  if (wantAddAgent) {
3373
- const { agent } = await prompts({
3374
- type: "select",
3375
- name: "agent",
3376
- message: `Which ${highlighter.info("coding agent")} would you like to connect?`,
3377
- choices: [
3378
- ...AGENTS.map((innerAgent) => ({
3379
- title: getAgentName(innerAgent),
3380
- value: innerAgent
3381
- })),
3382
- { title: "Skip", value: "skip" }
3383
- ]
3384
- });
3385
- if (agent === void 0) {
3795
+ const connectionMode = await promptConnectionMode();
3796
+ if (connectionMode === void 0) {
3386
3797
  logger.break();
3387
3798
  process.exit(1);
3388
3799
  }
3389
- if (agent !== "skip") {
3390
- agentIntegration = agent;
3800
+ if (connectionMode === "mcp") {
3801
+ const didInstall = await promptMcpInstall();
3802
+ if (!didInstall) {
3803
+ logger.break();
3804
+ process.exit(0);
3805
+ }
3806
+ logger.break();
3807
+ logger.success("MCP server has been configured.");
3808
+ logger.log("Continuing with React Grab installation...");
3809
+ logger.break();
3810
+ agentIntegration = "mcp";
3811
+ } else {
3812
+ const { agent } = await prompts({
3813
+ type: "select",
3814
+ name: "agent",
3815
+ message: `Which ${highlighter.info("agent")} would you like to connect?`,
3816
+ choices: [
3817
+ ...AGENTS.map((innerAgent) => ({
3818
+ title: getAgentName(innerAgent),
3819
+ value: innerAgent
3820
+ })),
3821
+ { title: "Skip", value: "skip" }
3822
+ ]
3823
+ });
3824
+ if (agent === void 0) {
3825
+ logger.break();
3826
+ process.exit(1);
3827
+ }
3828
+ if (agent !== "skip") {
3829
+ agentIntegration = agent;
3830
+ }
3391
3831
  }
3392
3832
  }
3393
3833
  }
@@ -3496,10 +3936,10 @@ var init = new commander.Command().name("init").description("initialize React Gr
3496
3936
  reportToCli("error", void 0, error);
3497
3937
  }
3498
3938
  });
3499
- var VERSION4 = "0.1.11";
3500
- var remove = new commander.Command().name("remove").description("remove an agent integration").argument(
3939
+ var VERSION4 = "0.1.13";
3940
+ var remove = new commander.Command().name("remove").description("disconnect React Grab from your agent").argument(
3501
3941
  "[agent]",
3502
- "agent to remove (claude-code, cursor, opencode, codex, gemini, amp, ami)"
3942
+ "agent to remove (claude-code, cursor, opencode, codex, gemini, amp, ami, mcp)"
3503
3943
  ).option("-y, --yes", "skip confirmation prompts", false).option(
3504
3944
  "-c, --cwd <cwd>",
3505
3945
  "working directory (defaults to current directory)",
@@ -3526,7 +3966,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3526
3966
  if (projectInfo.installedAgents.length === 0) {
3527
3967
  preflightSpinner.succeed();
3528
3968
  logger.break();
3529
- logger.warn("No agent integrations are installed.");
3969
+ logger.warn("No agent connections are installed.");
3530
3970
  logger.break();
3531
3971
  process.exit(0);
3532
3972
  }
@@ -3537,7 +3977,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3537
3977
  logger.break();
3538
3978
  logger.error(`Agent ${highlighter.info(agentArg)} is not installed.`);
3539
3979
  logger.log(
3540
- `Installed agents: ${projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES[innerAgent] || innerAgent).join(", ")}`
3980
+ `Installed agents: ${projectInfo.installedAgents.map(getAgentDisplayName).join(", ")}`
3541
3981
  );
3542
3982
  logger.break();
3543
3983
  process.exit(1);
@@ -3548,9 +3988,9 @@ var remove = new commander.Command().name("remove").description("remove an agent
3548
3988
  const { agent } = await prompts({
3549
3989
  type: "select",
3550
3990
  name: "agent",
3551
- message: `Which ${highlighter.info("agent integration")} would you like to remove?`,
3991
+ message: `Which ${highlighter.info("agent")} would you like to disconnect?`,
3552
3992
  choices: projectInfo.installedAgents.map((innerAgent) => ({
3553
- title: AGENT_NAMES[innerAgent] || innerAgent,
3993
+ title: getAgentDisplayName(innerAgent),
3554
3994
  value: innerAgent
3555
3995
  }))
3556
3996
  });
@@ -3569,7 +4009,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3569
4009
  process.exit(1);
3570
4010
  }
3571
4011
  const removingSpinner = spinner(
3572
- `Preparing to remove ${AGENT_NAMES[agentToRemove] || agentToRemove}.`
4012
+ `Preparing to remove ${getAgentDisplayName(agentToRemove)}.`
3573
4013
  ).start();
3574
4014
  removingSpinner.succeed();
3575
4015
  const result = previewAgentRemoval(
@@ -3666,7 +4106,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3666
4106
  }
3667
4107
  logger.break();
3668
4108
  logger.log(
3669
- `${highlighter.success("Success!")} ${AGENT_NAMES[agentToRemove] || agentToRemove} has been removed.`
4109
+ `${highlighter.success("Success!")} ${getAgentDisplayName(agentToRemove)} has been removed.`
3670
4110
  );
3671
4111
  logger.break();
3672
4112
  } catch (error) {
@@ -3675,7 +4115,7 @@ var remove = new commander.Command().name("remove").description("remove an agent
3675
4115
  });
3676
4116
 
3677
4117
  // src/cli.ts
3678
- var VERSION5 = "0.1.11";
4118
+ var VERSION5 = "0.1.13";
3679
4119
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
3680
4120
  process.on("SIGINT", () => process.exit(0));
3681
4121
  process.on("SIGTERM", () => process.exit(0));