@react-grab/cli 0.0.85 → 0.0.87

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 +417 -24
  2. package/dist/cli.js +417 -24
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -255,7 +255,7 @@ var AGENT_PACKAGES = [
255
255
  "@react-grab/gemini",
256
256
  "@react-grab/amp",
257
257
  "@react-grab/ami",
258
- "@react-grab/instant"
258
+ "@react-grab/visual-edit"
259
259
  ];
260
260
  var detectUnsupportedFramework = (projectRoot) => {
261
261
  const packageJsonPath = path.join(projectRoot, "package.json");
@@ -1046,11 +1046,11 @@ var AGENT_PREFIXES = {
1046
1046
  amp: "npx @react-grab/amp@latest &&"
1047
1047
  };
1048
1048
  var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
1049
- if (agent === "none" || agent === "ami" || agent === "instant") {
1049
+ if (agent === "none" || agent === "ami" || agent === "visual-edit") {
1050
1050
  return {
1051
1051
  success: true,
1052
1052
  filePath: "",
1053
- message: agent === "ami" || agent === "instant" ? `${agent === "ami" ? "Ami" : "Instant"} does not require package.json modification` : "No agent selected, skipping package.json modification",
1053
+ message: agent === "ami" || agent === "visual-edit" ? `${agent === "ami" ? "Ami" : "Visual Edit"} does not require package.json modification` : "No agent selected, skipping package.json modification",
1054
1054
  noChanges: true
1055
1055
  };
1056
1056
  }
@@ -1137,9 +1137,197 @@ var applyPackageJsonTransform = (result) => {
1137
1137
  }
1138
1138
  return { success: true };
1139
1139
  };
1140
+ var formatOptionsForNextjs = (options) => {
1141
+ const parts = [];
1142
+ if (options.activationKey) {
1143
+ const keyParts = [];
1144
+ if (options.activationKey.key)
1145
+ keyParts.push(`key: "${options.activationKey.key}"`);
1146
+ if (options.activationKey.metaKey) keyParts.push("metaKey: true");
1147
+ if (options.activationKey.ctrlKey) keyParts.push("ctrlKey: true");
1148
+ if (options.activationKey.shiftKey) keyParts.push("shiftKey: true");
1149
+ if (options.activationKey.altKey) keyParts.push("altKey: true");
1150
+ if (keyParts.length > 0) {
1151
+ parts.push(`activationKey: { ${keyParts.join(", ")} }`);
1152
+ }
1153
+ }
1154
+ if (options.activationMode) {
1155
+ parts.push(`activationMode: "${options.activationMode}"`);
1156
+ }
1157
+ if (options.keyHoldDuration !== void 0) {
1158
+ parts.push(`keyHoldDuration: ${options.keyHoldDuration}`);
1159
+ }
1160
+ if (options.allowActivationInsideInput !== void 0) {
1161
+ parts.push(
1162
+ `allowActivationInsideInput: ${options.allowActivationInsideInput}`
1163
+ );
1164
+ }
1165
+ if (options.maxContextLines !== void 0) {
1166
+ parts.push(`maxContextLines: ${options.maxContextLines}`);
1167
+ }
1168
+ return `{ ${parts.join(", ")} }`;
1169
+ };
1170
+ var formatOptionsAsJson = (options) => {
1171
+ const cleanOptions = {};
1172
+ if (options.activationKey) {
1173
+ const activationKey = {};
1174
+ if (options.activationKey.key) activationKey.key = options.activationKey.key;
1175
+ if (options.activationKey.metaKey) activationKey.metaKey = true;
1176
+ if (options.activationKey.ctrlKey) activationKey.ctrlKey = true;
1177
+ if (options.activationKey.shiftKey) activationKey.shiftKey = true;
1178
+ if (options.activationKey.altKey) activationKey.altKey = true;
1179
+ if (Object.keys(activationKey).length > 0) {
1180
+ cleanOptions.activationKey = activationKey;
1181
+ }
1182
+ }
1183
+ if (options.activationMode) {
1184
+ cleanOptions.activationMode = options.activationMode;
1185
+ }
1186
+ if (options.keyHoldDuration !== void 0) {
1187
+ cleanOptions.keyHoldDuration = options.keyHoldDuration;
1188
+ }
1189
+ if (options.allowActivationInsideInput !== void 0) {
1190
+ cleanOptions.allowActivationInsideInput = options.allowActivationInsideInput;
1191
+ }
1192
+ if (options.maxContextLines !== void 0) {
1193
+ cleanOptions.maxContextLines = options.maxContextLines;
1194
+ }
1195
+ return JSON.stringify(cleanOptions);
1196
+ };
1197
+ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
1198
+ switch (framework) {
1199
+ case "next":
1200
+ if (nextRouterType === "app") {
1201
+ return findLayoutFile(projectRoot);
1202
+ }
1203
+ return findDocumentFile(projectRoot);
1204
+ case "vite":
1205
+ return findIndexHtml(projectRoot);
1206
+ case "webpack":
1207
+ return findEntryFile(projectRoot);
1208
+ default:
1209
+ return null;
1210
+ }
1211
+ };
1212
+ var addOptionsToNextScript = (originalContent, options, filePath) => {
1213
+ const reactGrabScriptMatch = originalContent.match(
1214
+ /(<Script[^>]*react-grab[^>]*)(\/?>)/is
1215
+ );
1216
+ if (!reactGrabScriptMatch) {
1217
+ return {
1218
+ success: false,
1219
+ filePath,
1220
+ message: "Could not find React Grab Script tag"
1221
+ };
1222
+ }
1223
+ const scriptTag = reactGrabScriptMatch[0];
1224
+ const scriptOpening = reactGrabScriptMatch[1];
1225
+ const scriptClosing = reactGrabScriptMatch[2];
1226
+ const existingDataOptionsMatch = scriptTag.match(
1227
+ /data-options=\{JSON\.stringify\([^)]+\)\}/
1228
+ );
1229
+ const dataOptionsAttr = `data-options={JSON.stringify(
1230
+ ${formatOptionsForNextjs(options)}
1231
+ )}`;
1232
+ let newScriptTag;
1233
+ if (existingDataOptionsMatch) {
1234
+ newScriptTag = scriptTag.replace(existingDataOptionsMatch[0], dataOptionsAttr);
1235
+ } else {
1236
+ newScriptTag = `${scriptOpening}
1237
+ ${dataOptionsAttr}
1238
+ ${scriptClosing}`;
1239
+ }
1240
+ const newContent = originalContent.replace(scriptTag, newScriptTag);
1241
+ return {
1242
+ success: true,
1243
+ filePath,
1244
+ message: "Update React Grab options",
1245
+ originalContent,
1246
+ newContent
1247
+ };
1248
+ };
1249
+ var addOptionsToViteScript = (originalContent, options, filePath) => {
1250
+ const reactGrabImportMatch = originalContent.match(
1251
+ /import\s*\(\s*["']react-grab["']\s*\)/
1252
+ );
1253
+ if (!reactGrabImportMatch) {
1254
+ return {
1255
+ success: false,
1256
+ filePath,
1257
+ message: "Could not find React Grab import"
1258
+ };
1259
+ }
1260
+ const optionsJson = formatOptionsAsJson(options);
1261
+ const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
1262
+ const newContent = originalContent.replace(reactGrabImportMatch[0], newImport);
1263
+ return {
1264
+ success: true,
1265
+ filePath,
1266
+ message: "Update React Grab options",
1267
+ originalContent,
1268
+ newContent
1269
+ };
1270
+ };
1271
+ var addOptionsToWebpackImport = (originalContent, options, filePath) => {
1272
+ const reactGrabImportMatch = originalContent.match(
1273
+ /import\s*\(\s*["']react-grab["']\s*\)/
1274
+ );
1275
+ if (!reactGrabImportMatch) {
1276
+ return {
1277
+ success: false,
1278
+ filePath,
1279
+ message: "Could not find React Grab import"
1280
+ };
1281
+ }
1282
+ const optionsJson = formatOptionsAsJson(options);
1283
+ const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
1284
+ const newContent = originalContent.replace(reactGrabImportMatch[0], newImport);
1285
+ return {
1286
+ success: true,
1287
+ filePath,
1288
+ message: "Update React Grab options",
1289
+ originalContent,
1290
+ newContent
1291
+ };
1292
+ };
1293
+ var previewOptionsTransform = (projectRoot, framework, nextRouterType, options) => {
1294
+ const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);
1295
+ if (!filePath) {
1296
+ return {
1297
+ success: false,
1298
+ filePath: "",
1299
+ message: "Could not find file containing React Grab configuration"
1300
+ };
1301
+ }
1302
+ const originalContent = fs.readFileSync(filePath, "utf-8");
1303
+ if (!hasReactGrabCode(originalContent)) {
1304
+ return {
1305
+ success: false,
1306
+ filePath,
1307
+ message: "Could not find React Grab code in the file"
1308
+ };
1309
+ }
1310
+ switch (framework) {
1311
+ case "next":
1312
+ return addOptionsToNextScript(originalContent, options, filePath);
1313
+ case "vite":
1314
+ return addOptionsToViteScript(originalContent, options, filePath);
1315
+ case "webpack":
1316
+ return addOptionsToWebpackImport(originalContent, options, filePath);
1317
+ default:
1318
+ return {
1319
+ success: false,
1320
+ filePath,
1321
+ message: `Unknown framework: ${framework}`
1322
+ };
1323
+ }
1324
+ };
1325
+ var applyOptionsTransform = (result) => {
1326
+ return applyTransform(result);
1327
+ };
1140
1328
 
1141
1329
  // src/commands/add.ts
1142
- var VERSION = "0.0.85";
1330
+ var VERSION = "0.0.87";
1143
1331
  var AGENT_NAMES = {
1144
1332
  "claude-code": "Claude Code",
1145
1333
  cursor: "Cursor",
@@ -1147,19 +1335,18 @@ var AGENT_NAMES = {
1147
1335
  codex: "Codex",
1148
1336
  gemini: "Gemini",
1149
1337
  amp: "Amp",
1150
- ami: "Ami",
1151
- instant: "Instant"
1338
+ "visual-edit": "Visual Edit"
1152
1339
  };
1153
1340
  var add = new commander.Command().name("add").description("add an agent integration").argument(
1154
1341
  "[agent]",
1155
- "agent to add (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
1342
+ "agent to add (claude-code, cursor, opencode, codex, gemini, amp, visual-edit)"
1156
1343
  ).option("-y, --yes", "skip confirmation prompts", false).option(
1157
1344
  "-c, --cwd <cwd>",
1158
1345
  "working directory (defaults to current directory)",
1159
1346
  process.cwd()
1160
1347
  ).action(async (agentArg, opts) => {
1161
1348
  console.log(
1162
- `${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)}`
1349
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)}`
1163
1350
  );
1164
1351
  console.log();
1165
1352
  try {
@@ -1184,8 +1371,7 @@ var add = new commander.Command().name("add").description("add an agent integrat
1184
1371
  "codex",
1185
1372
  "gemini",
1186
1373
  "amp",
1187
- "ami",
1188
- "instant"
1374
+ "visual-edit"
1189
1375
  ].filter((agent) => !projectInfo.installedAgents.includes(agent));
1190
1376
  if (availableAgents.length === 0) {
1191
1377
  logger.break();
@@ -1202,13 +1388,12 @@ var add = new commander.Command().name("add").description("add an agent integrat
1202
1388
  "codex",
1203
1389
  "gemini",
1204
1390
  "amp",
1205
- "ami",
1206
- "instant"
1391
+ "visual-edit"
1207
1392
  ].includes(agentArg)) {
1208
1393
  logger.break();
1209
1394
  logger.error(`Invalid agent: ${agentArg}`);
1210
1395
  logger.error(
1211
- "Available agents: claude-code, cursor, opencode, codex, gemini, amp, ami, instant"
1396
+ "Available agents: claude-code, cursor, opencode, codex, gemini, amp, visual-edit"
1212
1397
  );
1213
1398
  logger.break();
1214
1399
  process.exit(1);
@@ -1357,7 +1542,215 @@ var add = new commander.Command().name("add").description("add an agent integrat
1357
1542
  handleError(error);
1358
1543
  }
1359
1544
  });
1360
- var VERSION2 = "0.0.85";
1545
+ var VERSION2 = "0.0.87";
1546
+ var MODIFIER_KEY_NAMES = {
1547
+ metaKey: process.platform === "darwin" ? "\u2318 Command" : "\u229E Windows",
1548
+ ctrlKey: "Ctrl",
1549
+ shiftKey: "Shift",
1550
+ altKey: process.platform === "darwin" ? "\u2325 Option" : "Alt"
1551
+ };
1552
+ var formatActivationKey = (activationKey) => {
1553
+ if (!activationKey) return "Default (Option/Alt)";
1554
+ const parts = [];
1555
+ if (activationKey.metaKey) parts.push(process.platform === "darwin" ? "\u2318" : "Win");
1556
+ if (activationKey.ctrlKey) parts.push("Ctrl");
1557
+ if (activationKey.shiftKey) parts.push("Shift");
1558
+ if (activationKey.altKey) parts.push(process.platform === "darwin" ? "\u2325" : "Alt");
1559
+ if (activationKey.key) parts.push(activationKey.key.toUpperCase());
1560
+ return parts.length > 0 ? parts.join(" + ") : "Default (Option/Alt)";
1561
+ };
1562
+ var configure = new commander.Command().name("configure").alias("config").description("configure React Grab options").option("-y, --yes", "skip confirmation prompts", false).option(
1563
+ "-c, --cwd <cwd>",
1564
+ "working directory (defaults to current directory)",
1565
+ process.cwd()
1566
+ ).action(async (opts) => {
1567
+ console.log(
1568
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION2)}`
1569
+ );
1570
+ console.log();
1571
+ try {
1572
+ const cwd = opts.cwd;
1573
+ const isNonInteractive = opts.yes;
1574
+ const preflightSpinner = spinner("Preflight checks.").start();
1575
+ const projectInfo = await detectProject(cwd);
1576
+ if (!projectInfo.hasReactGrab) {
1577
+ preflightSpinner.fail("React Grab is not installed.");
1578
+ logger.break();
1579
+ logger.error(
1580
+ `Run ${highlighter.info("react-grab init")} first to install React Grab.`
1581
+ );
1582
+ logger.break();
1583
+ process.exit(1);
1584
+ }
1585
+ preflightSpinner.succeed();
1586
+ if (isNonInteractive) {
1587
+ logger.break();
1588
+ logger.error("Configure command requires interactive mode.");
1589
+ logger.error("Remove the --yes flag to use interactive prompts.");
1590
+ logger.break();
1591
+ process.exit(1);
1592
+ }
1593
+ logger.break();
1594
+ logger.log(`Configure ${highlighter.info("React Grab")} options:`);
1595
+ logger.break();
1596
+ const collectedOptions = {};
1597
+ const { wantActivationKey } = await prompts2__default.default({
1598
+ type: "confirm",
1599
+ name: "wantActivationKey",
1600
+ message: `Configure ${highlighter.info("activation key")}?`,
1601
+ initial: false
1602
+ });
1603
+ if (wantActivationKey === void 0) {
1604
+ logger.break();
1605
+ process.exit(1);
1606
+ }
1607
+ if (wantActivationKey) {
1608
+ const { key } = await prompts2__default.default({
1609
+ type: "text",
1610
+ name: "key",
1611
+ message: "Enter the activation key (e.g., g, k, space):",
1612
+ initial: ""
1613
+ });
1614
+ if (key === void 0) {
1615
+ logger.break();
1616
+ process.exit(1);
1617
+ }
1618
+ const { modifiers } = await prompts2__default.default({
1619
+ type: "multiselect",
1620
+ name: "modifiers",
1621
+ message: "Select modifier keys (space to select, enter to confirm):",
1622
+ choices: [
1623
+ { title: MODIFIER_KEY_NAMES.metaKey, value: "metaKey" },
1624
+ { title: MODIFIER_KEY_NAMES.ctrlKey, value: "ctrlKey" },
1625
+ { title: MODIFIER_KEY_NAMES.shiftKey, value: "shiftKey" },
1626
+ { title: MODIFIER_KEY_NAMES.altKey, value: "altKey", selected: true }
1627
+ ],
1628
+ hint: "- Space to select, Enter to confirm"
1629
+ });
1630
+ if (modifiers === void 0) {
1631
+ logger.break();
1632
+ process.exit(1);
1633
+ }
1634
+ collectedOptions.activationKey = {
1635
+ ...key && { key: key.toLowerCase() },
1636
+ ...modifiers.includes("metaKey") && { metaKey: true },
1637
+ ...modifiers.includes("ctrlKey") && { ctrlKey: true },
1638
+ ...modifiers.includes("shiftKey") && { shiftKey: true },
1639
+ ...modifiers.includes("altKey") && { altKey: true }
1640
+ };
1641
+ logger.log(
1642
+ ` Activation key: ${highlighter.info(formatActivationKey(collectedOptions.activationKey))}`
1643
+ );
1644
+ }
1645
+ const { activationMode } = await prompts2__default.default({
1646
+ type: "select",
1647
+ name: "activationMode",
1648
+ message: `Select ${highlighter.info("activation mode")}:`,
1649
+ choices: [
1650
+ { title: "Toggle (press to activate/deactivate)", value: "toggle" },
1651
+ { title: "Hold (hold key to keep active)", value: "hold" }
1652
+ ],
1653
+ initial: 0
1654
+ });
1655
+ if (activationMode === void 0) {
1656
+ logger.break();
1657
+ process.exit(1);
1658
+ }
1659
+ collectedOptions.activationMode = activationMode;
1660
+ if (activationMode === "hold") {
1661
+ const { keyHoldDuration } = await prompts2__default.default({
1662
+ type: "number",
1663
+ name: "keyHoldDuration",
1664
+ message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
1665
+ initial: 150,
1666
+ min: 0,
1667
+ max: 2e3
1668
+ });
1669
+ if (keyHoldDuration === void 0) {
1670
+ logger.break();
1671
+ process.exit(1);
1672
+ }
1673
+ collectedOptions.keyHoldDuration = keyHoldDuration;
1674
+ }
1675
+ const { allowActivationInsideInput } = await prompts2__default.default({
1676
+ type: "confirm",
1677
+ name: "allowActivationInsideInput",
1678
+ message: `Allow activation ${highlighter.info("inside input fields")}?`,
1679
+ initial: true
1680
+ });
1681
+ if (allowActivationInsideInput === void 0) {
1682
+ logger.break();
1683
+ process.exit(1);
1684
+ }
1685
+ collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
1686
+ const { maxContextLines } = await prompts2__default.default({
1687
+ type: "number",
1688
+ name: "maxContextLines",
1689
+ message: `Enter ${highlighter.info("max context lines")} to include:`,
1690
+ initial: 3,
1691
+ min: 0,
1692
+ max: 50
1693
+ });
1694
+ if (maxContextLines === void 0) {
1695
+ logger.break();
1696
+ process.exit(1);
1697
+ }
1698
+ collectedOptions.maxContextLines = maxContextLines;
1699
+ const result = previewOptionsTransform(
1700
+ projectInfo.projectRoot,
1701
+ projectInfo.framework,
1702
+ projectInfo.nextRouterType,
1703
+ collectedOptions
1704
+ );
1705
+ if (!result.success) {
1706
+ logger.break();
1707
+ logger.error(result.message);
1708
+ logger.break();
1709
+ process.exit(1);
1710
+ }
1711
+ const hasChanges = !result.noChanges && result.originalContent && result.newContent;
1712
+ if (hasChanges) {
1713
+ logger.break();
1714
+ printDiff(result.filePath, result.originalContent, result.newContent);
1715
+ logger.break();
1716
+ const { proceed } = await prompts2__default.default({
1717
+ type: "confirm",
1718
+ name: "proceed",
1719
+ message: "Apply these changes?",
1720
+ initial: true
1721
+ });
1722
+ if (!proceed) {
1723
+ logger.break();
1724
+ logger.log("Changes cancelled.");
1725
+ logger.break();
1726
+ process.exit(0);
1727
+ }
1728
+ const writeSpinner = spinner(
1729
+ `Applying changes to ${result.filePath}.`
1730
+ ).start();
1731
+ const writeResult = applyOptionsTransform(result);
1732
+ if (!writeResult.success) {
1733
+ writeSpinner.fail();
1734
+ logger.break();
1735
+ logger.error(writeResult.error || "Failed to write file.");
1736
+ logger.break();
1737
+ process.exit(1);
1738
+ }
1739
+ writeSpinner.succeed();
1740
+ } else {
1741
+ logger.break();
1742
+ logger.log("No changes needed.");
1743
+ }
1744
+ logger.break();
1745
+ logger.log(
1746
+ `${highlighter.success("Success!")} React Grab options have been configured.`
1747
+ );
1748
+ logger.break();
1749
+ } catch (error) {
1750
+ handleError(error);
1751
+ }
1752
+ });
1753
+ var VERSION3 = "0.0.87";
1361
1754
  var REPORT_URL = "https://react-grab.com/api/report-cli";
1362
1755
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
1363
1756
  var reportToCli = async (type, config, error) => {
@@ -1367,7 +1760,7 @@ var reportToCli = async (type, config, error) => {
1367
1760
  headers: { "Content-Type": "application/json" },
1368
1761
  body: JSON.stringify({
1369
1762
  type,
1370
- version: VERSION2,
1763
+ version: VERSION3,
1371
1764
  config,
1372
1765
  error: error ? { message: error.message, stack: error.stack } : void 0,
1373
1766
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -1397,14 +1790,14 @@ var UNSUPPORTED_FRAMEWORK_NAMES = {
1397
1790
  };
1398
1791
  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(
1399
1792
  "-a, --agent <agent>",
1400
- "agent integration (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
1793
+ "agent integration (claude-code, cursor, opencode, codex, gemini, amp, visual-edit)"
1401
1794
  ).option("--skip-install", "skip package installation", false).option(
1402
1795
  "-c, --cwd <cwd>",
1403
1796
  "working directory (defaults to current directory)",
1404
1797
  process.cwd()
1405
1798
  ).action(async (opts) => {
1406
1799
  console.log(
1407
- `${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION2)}`
1800
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION3)}`
1408
1801
  );
1409
1802
  console.log();
1410
1803
  try {
@@ -1528,8 +1921,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
1528
1921
  { title: "Codex", value: "codex" },
1529
1922
  { title: "Gemini", value: "gemini" },
1530
1923
  { title: "Amp", value: "amp" },
1531
- { title: "Ami", value: "ami" },
1532
- { title: "Instant", value: "instant" }
1924
+ { title: "Visual Edit", value: "visual-edit" }
1533
1925
  ]
1534
1926
  });
1535
1927
  if (agent === void 0) {
@@ -1667,7 +2059,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
1667
2059
  await reportToCli("error", void 0, error);
1668
2060
  }
1669
2061
  });
1670
- var VERSION3 = "0.0.85";
2062
+ var VERSION4 = "0.0.87";
1671
2063
  var DEFAULT_PROXY_PORT = 2e3;
1672
2064
  var REACT_GRAB_SCRIPT = '<script src="//unpkg.com/react-grab/dist/index.global.js"></script>';
1673
2065
  var buildProviderScript = (provider) => `<script src="//unpkg.com/${provider}/dist/client.global.js"></script>`;
@@ -1712,7 +2104,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
1712
2104
  "provider package to run via npx (e.g., @react-grab/cursor)"
1713
2105
  ).action(async (urlArg, opts) => {
1714
2106
  console.log(
1715
- `${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION3)}`
2107
+ `${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION4)}`
1716
2108
  );
1717
2109
  console.log();
1718
2110
  let url = urlArg;
@@ -1742,7 +2134,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
1742
2134
  { title: "Codex", value: "@react-grab/codex" },
1743
2135
  { title: "Gemini", value: "@react-grab/gemini" },
1744
2136
  { title: "Amp", value: "@react-grab/amp" },
1745
- { title: "Ami", value: "@react-grab/ami" }
2137
+ { title: "Visual Edit", value: "@react-grab/visual-edit" }
1746
2138
  ]
1747
2139
  });
1748
2140
  if (selectedProvider === void 0) {
@@ -1892,7 +2284,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
1892
2284
  });
1893
2285
 
1894
2286
  // src/cli.ts
1895
- var VERSION4 = "0.0.85";
2287
+ var VERSION5 = "0.0.87";
1896
2288
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
1897
2289
  process.on("SIGINT", () => process.exit(0));
1898
2290
  process.on("SIGTERM", () => process.exit(0));
@@ -1901,8 +2293,9 @@ try {
1901
2293
  });
1902
2294
  } catch {
1903
2295
  }
1904
- var program = new commander.Command().name("react-grab").description("add React Grab to your project").version(VERSION4, "-v, --version", "display the version number");
2296
+ var program = new commander.Command().name("react-grab").description("add React Grab to your project").version(VERSION5, "-v, --version", "display the version number");
1905
2297
  program.addCommand(init);
1906
2298
  program.addCommand(add);
2299
+ program.addCommand(configure);
1907
2300
  program.addCommand(start);
1908
2301
  program.parse();
package/dist/cli.js CHANGED
@@ -247,7 +247,7 @@ var AGENT_PACKAGES = [
247
247
  "@react-grab/gemini",
248
248
  "@react-grab/amp",
249
249
  "@react-grab/ami",
250
- "@react-grab/instant"
250
+ "@react-grab/visual-edit"
251
251
  ];
252
252
  var detectUnsupportedFramework = (projectRoot) => {
253
253
  const packageJsonPath = join(projectRoot, "package.json");
@@ -1038,11 +1038,11 @@ var AGENT_PREFIXES = {
1038
1038
  amp: "npx @react-grab/amp@latest &&"
1039
1039
  };
1040
1040
  var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
1041
- if (agent === "none" || agent === "ami" || agent === "instant") {
1041
+ if (agent === "none" || agent === "ami" || agent === "visual-edit") {
1042
1042
  return {
1043
1043
  success: true,
1044
1044
  filePath: "",
1045
- message: agent === "ami" || agent === "instant" ? `${agent === "ami" ? "Ami" : "Instant"} does not require package.json modification` : "No agent selected, skipping package.json modification",
1045
+ message: agent === "ami" || agent === "visual-edit" ? `${agent === "ami" ? "Ami" : "Visual Edit"} does not require package.json modification` : "No agent selected, skipping package.json modification",
1046
1046
  noChanges: true
1047
1047
  };
1048
1048
  }
@@ -1129,9 +1129,197 @@ var applyPackageJsonTransform = (result) => {
1129
1129
  }
1130
1130
  return { success: true };
1131
1131
  };
1132
+ var formatOptionsForNextjs = (options) => {
1133
+ const parts = [];
1134
+ if (options.activationKey) {
1135
+ const keyParts = [];
1136
+ if (options.activationKey.key)
1137
+ keyParts.push(`key: "${options.activationKey.key}"`);
1138
+ if (options.activationKey.metaKey) keyParts.push("metaKey: true");
1139
+ if (options.activationKey.ctrlKey) keyParts.push("ctrlKey: true");
1140
+ if (options.activationKey.shiftKey) keyParts.push("shiftKey: true");
1141
+ if (options.activationKey.altKey) keyParts.push("altKey: true");
1142
+ if (keyParts.length > 0) {
1143
+ parts.push(`activationKey: { ${keyParts.join(", ")} }`);
1144
+ }
1145
+ }
1146
+ if (options.activationMode) {
1147
+ parts.push(`activationMode: "${options.activationMode}"`);
1148
+ }
1149
+ if (options.keyHoldDuration !== void 0) {
1150
+ parts.push(`keyHoldDuration: ${options.keyHoldDuration}`);
1151
+ }
1152
+ if (options.allowActivationInsideInput !== void 0) {
1153
+ parts.push(
1154
+ `allowActivationInsideInput: ${options.allowActivationInsideInput}`
1155
+ );
1156
+ }
1157
+ if (options.maxContextLines !== void 0) {
1158
+ parts.push(`maxContextLines: ${options.maxContextLines}`);
1159
+ }
1160
+ return `{ ${parts.join(", ")} }`;
1161
+ };
1162
+ var formatOptionsAsJson = (options) => {
1163
+ const cleanOptions = {};
1164
+ if (options.activationKey) {
1165
+ const activationKey = {};
1166
+ if (options.activationKey.key) activationKey.key = options.activationKey.key;
1167
+ if (options.activationKey.metaKey) activationKey.metaKey = true;
1168
+ if (options.activationKey.ctrlKey) activationKey.ctrlKey = true;
1169
+ if (options.activationKey.shiftKey) activationKey.shiftKey = true;
1170
+ if (options.activationKey.altKey) activationKey.altKey = true;
1171
+ if (Object.keys(activationKey).length > 0) {
1172
+ cleanOptions.activationKey = activationKey;
1173
+ }
1174
+ }
1175
+ if (options.activationMode) {
1176
+ cleanOptions.activationMode = options.activationMode;
1177
+ }
1178
+ if (options.keyHoldDuration !== void 0) {
1179
+ cleanOptions.keyHoldDuration = options.keyHoldDuration;
1180
+ }
1181
+ if (options.allowActivationInsideInput !== void 0) {
1182
+ cleanOptions.allowActivationInsideInput = options.allowActivationInsideInput;
1183
+ }
1184
+ if (options.maxContextLines !== void 0) {
1185
+ cleanOptions.maxContextLines = options.maxContextLines;
1186
+ }
1187
+ return JSON.stringify(cleanOptions);
1188
+ };
1189
+ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
1190
+ switch (framework) {
1191
+ case "next":
1192
+ if (nextRouterType === "app") {
1193
+ return findLayoutFile(projectRoot);
1194
+ }
1195
+ return findDocumentFile(projectRoot);
1196
+ case "vite":
1197
+ return findIndexHtml(projectRoot);
1198
+ case "webpack":
1199
+ return findEntryFile(projectRoot);
1200
+ default:
1201
+ return null;
1202
+ }
1203
+ };
1204
+ var addOptionsToNextScript = (originalContent, options, filePath) => {
1205
+ const reactGrabScriptMatch = originalContent.match(
1206
+ /(<Script[^>]*react-grab[^>]*)(\/?>)/is
1207
+ );
1208
+ if (!reactGrabScriptMatch) {
1209
+ return {
1210
+ success: false,
1211
+ filePath,
1212
+ message: "Could not find React Grab Script tag"
1213
+ };
1214
+ }
1215
+ const scriptTag = reactGrabScriptMatch[0];
1216
+ const scriptOpening = reactGrabScriptMatch[1];
1217
+ const scriptClosing = reactGrabScriptMatch[2];
1218
+ const existingDataOptionsMatch = scriptTag.match(
1219
+ /data-options=\{JSON\.stringify\([^)]+\)\}/
1220
+ );
1221
+ const dataOptionsAttr = `data-options={JSON.stringify(
1222
+ ${formatOptionsForNextjs(options)}
1223
+ )}`;
1224
+ let newScriptTag;
1225
+ if (existingDataOptionsMatch) {
1226
+ newScriptTag = scriptTag.replace(existingDataOptionsMatch[0], dataOptionsAttr);
1227
+ } else {
1228
+ newScriptTag = `${scriptOpening}
1229
+ ${dataOptionsAttr}
1230
+ ${scriptClosing}`;
1231
+ }
1232
+ const newContent = originalContent.replace(scriptTag, newScriptTag);
1233
+ return {
1234
+ success: true,
1235
+ filePath,
1236
+ message: "Update React Grab options",
1237
+ originalContent,
1238
+ newContent
1239
+ };
1240
+ };
1241
+ var addOptionsToViteScript = (originalContent, options, filePath) => {
1242
+ const reactGrabImportMatch = originalContent.match(
1243
+ /import\s*\(\s*["']react-grab["']\s*\)/
1244
+ );
1245
+ if (!reactGrabImportMatch) {
1246
+ return {
1247
+ success: false,
1248
+ filePath,
1249
+ message: "Could not find React Grab import"
1250
+ };
1251
+ }
1252
+ const optionsJson = formatOptionsAsJson(options);
1253
+ const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
1254
+ const newContent = originalContent.replace(reactGrabImportMatch[0], newImport);
1255
+ return {
1256
+ success: true,
1257
+ filePath,
1258
+ message: "Update React Grab options",
1259
+ originalContent,
1260
+ newContent
1261
+ };
1262
+ };
1263
+ var addOptionsToWebpackImport = (originalContent, options, filePath) => {
1264
+ const reactGrabImportMatch = originalContent.match(
1265
+ /import\s*\(\s*["']react-grab["']\s*\)/
1266
+ );
1267
+ if (!reactGrabImportMatch) {
1268
+ return {
1269
+ success: false,
1270
+ filePath,
1271
+ message: "Could not find React Grab import"
1272
+ };
1273
+ }
1274
+ const optionsJson = formatOptionsAsJson(options);
1275
+ const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
1276
+ const newContent = originalContent.replace(reactGrabImportMatch[0], newImport);
1277
+ return {
1278
+ success: true,
1279
+ filePath,
1280
+ message: "Update React Grab options",
1281
+ originalContent,
1282
+ newContent
1283
+ };
1284
+ };
1285
+ var previewOptionsTransform = (projectRoot, framework, nextRouterType, options) => {
1286
+ const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);
1287
+ if (!filePath) {
1288
+ return {
1289
+ success: false,
1290
+ filePath: "",
1291
+ message: "Could not find file containing React Grab configuration"
1292
+ };
1293
+ }
1294
+ const originalContent = readFileSync(filePath, "utf-8");
1295
+ if (!hasReactGrabCode(originalContent)) {
1296
+ return {
1297
+ success: false,
1298
+ filePath,
1299
+ message: "Could not find React Grab code in the file"
1300
+ };
1301
+ }
1302
+ switch (framework) {
1303
+ case "next":
1304
+ return addOptionsToNextScript(originalContent, options, filePath);
1305
+ case "vite":
1306
+ return addOptionsToViteScript(originalContent, options, filePath);
1307
+ case "webpack":
1308
+ return addOptionsToWebpackImport(originalContent, options, filePath);
1309
+ default:
1310
+ return {
1311
+ success: false,
1312
+ filePath,
1313
+ message: `Unknown framework: ${framework}`
1314
+ };
1315
+ }
1316
+ };
1317
+ var applyOptionsTransform = (result) => {
1318
+ return applyTransform(result);
1319
+ };
1132
1320
 
1133
1321
  // src/commands/add.ts
1134
- var VERSION = "0.0.85";
1322
+ var VERSION = "0.0.87";
1135
1323
  var AGENT_NAMES = {
1136
1324
  "claude-code": "Claude Code",
1137
1325
  cursor: "Cursor",
@@ -1139,19 +1327,18 @@ var AGENT_NAMES = {
1139
1327
  codex: "Codex",
1140
1328
  gemini: "Gemini",
1141
1329
  amp: "Amp",
1142
- ami: "Ami",
1143
- instant: "Instant"
1330
+ "visual-edit": "Visual Edit"
1144
1331
  };
1145
1332
  var add = new Command().name("add").description("add an agent integration").argument(
1146
1333
  "[agent]",
1147
- "agent to add (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
1334
+ "agent to add (claude-code, cursor, opencode, codex, gemini, amp, visual-edit)"
1148
1335
  ).option("-y, --yes", "skip confirmation prompts", false).option(
1149
1336
  "-c, --cwd <cwd>",
1150
1337
  "working directory (defaults to current directory)",
1151
1338
  process.cwd()
1152
1339
  ).action(async (agentArg, opts) => {
1153
1340
  console.log(
1154
- `${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION)}`
1341
+ `${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION)}`
1155
1342
  );
1156
1343
  console.log();
1157
1344
  try {
@@ -1176,8 +1363,7 @@ var add = new Command().name("add").description("add an agent integration").argu
1176
1363
  "codex",
1177
1364
  "gemini",
1178
1365
  "amp",
1179
- "ami",
1180
- "instant"
1366
+ "visual-edit"
1181
1367
  ].filter((agent) => !projectInfo.installedAgents.includes(agent));
1182
1368
  if (availableAgents.length === 0) {
1183
1369
  logger.break();
@@ -1194,13 +1380,12 @@ var add = new Command().name("add").description("add an agent integration").argu
1194
1380
  "codex",
1195
1381
  "gemini",
1196
1382
  "amp",
1197
- "ami",
1198
- "instant"
1383
+ "visual-edit"
1199
1384
  ].includes(agentArg)) {
1200
1385
  logger.break();
1201
1386
  logger.error(`Invalid agent: ${agentArg}`);
1202
1387
  logger.error(
1203
- "Available agents: claude-code, cursor, opencode, codex, gemini, amp, ami, instant"
1388
+ "Available agents: claude-code, cursor, opencode, codex, gemini, amp, visual-edit"
1204
1389
  );
1205
1390
  logger.break();
1206
1391
  process.exit(1);
@@ -1349,7 +1534,215 @@ var add = new Command().name("add").description("add an agent integration").argu
1349
1534
  handleError(error);
1350
1535
  }
1351
1536
  });
1352
- var VERSION2 = "0.0.85";
1537
+ var VERSION2 = "0.0.87";
1538
+ var MODIFIER_KEY_NAMES = {
1539
+ metaKey: process.platform === "darwin" ? "\u2318 Command" : "\u229E Windows",
1540
+ ctrlKey: "Ctrl",
1541
+ shiftKey: "Shift",
1542
+ altKey: process.platform === "darwin" ? "\u2325 Option" : "Alt"
1543
+ };
1544
+ var formatActivationKey = (activationKey) => {
1545
+ if (!activationKey) return "Default (Option/Alt)";
1546
+ const parts = [];
1547
+ if (activationKey.metaKey) parts.push(process.platform === "darwin" ? "\u2318" : "Win");
1548
+ if (activationKey.ctrlKey) parts.push("Ctrl");
1549
+ if (activationKey.shiftKey) parts.push("Shift");
1550
+ if (activationKey.altKey) parts.push(process.platform === "darwin" ? "\u2325" : "Alt");
1551
+ if (activationKey.key) parts.push(activationKey.key.toUpperCase());
1552
+ return parts.length > 0 ? parts.join(" + ") : "Default (Option/Alt)";
1553
+ };
1554
+ var configure = new Command().name("configure").alias("config").description("configure React Grab options").option("-y, --yes", "skip confirmation prompts", false).option(
1555
+ "-c, --cwd <cwd>",
1556
+ "working directory (defaults to current directory)",
1557
+ process.cwd()
1558
+ ).action(async (opts) => {
1559
+ console.log(
1560
+ `${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION2)}`
1561
+ );
1562
+ console.log();
1563
+ try {
1564
+ const cwd = opts.cwd;
1565
+ const isNonInteractive = opts.yes;
1566
+ const preflightSpinner = spinner("Preflight checks.").start();
1567
+ const projectInfo = await detectProject(cwd);
1568
+ if (!projectInfo.hasReactGrab) {
1569
+ preflightSpinner.fail("React Grab is not installed.");
1570
+ logger.break();
1571
+ logger.error(
1572
+ `Run ${highlighter.info("react-grab init")} first to install React Grab.`
1573
+ );
1574
+ logger.break();
1575
+ process.exit(1);
1576
+ }
1577
+ preflightSpinner.succeed();
1578
+ if (isNonInteractive) {
1579
+ logger.break();
1580
+ logger.error("Configure command requires interactive mode.");
1581
+ logger.error("Remove the --yes flag to use interactive prompts.");
1582
+ logger.break();
1583
+ process.exit(1);
1584
+ }
1585
+ logger.break();
1586
+ logger.log(`Configure ${highlighter.info("React Grab")} options:`);
1587
+ logger.break();
1588
+ const collectedOptions = {};
1589
+ const { wantActivationKey } = await prompts2({
1590
+ type: "confirm",
1591
+ name: "wantActivationKey",
1592
+ message: `Configure ${highlighter.info("activation key")}?`,
1593
+ initial: false
1594
+ });
1595
+ if (wantActivationKey === void 0) {
1596
+ logger.break();
1597
+ process.exit(1);
1598
+ }
1599
+ if (wantActivationKey) {
1600
+ const { key } = await prompts2({
1601
+ type: "text",
1602
+ name: "key",
1603
+ message: "Enter the activation key (e.g., g, k, space):",
1604
+ initial: ""
1605
+ });
1606
+ if (key === void 0) {
1607
+ logger.break();
1608
+ process.exit(1);
1609
+ }
1610
+ const { modifiers } = await prompts2({
1611
+ type: "multiselect",
1612
+ name: "modifiers",
1613
+ message: "Select modifier keys (space to select, enter to confirm):",
1614
+ choices: [
1615
+ { title: MODIFIER_KEY_NAMES.metaKey, value: "metaKey" },
1616
+ { title: MODIFIER_KEY_NAMES.ctrlKey, value: "ctrlKey" },
1617
+ { title: MODIFIER_KEY_NAMES.shiftKey, value: "shiftKey" },
1618
+ { title: MODIFIER_KEY_NAMES.altKey, value: "altKey", selected: true }
1619
+ ],
1620
+ hint: "- Space to select, Enter to confirm"
1621
+ });
1622
+ if (modifiers === void 0) {
1623
+ logger.break();
1624
+ process.exit(1);
1625
+ }
1626
+ collectedOptions.activationKey = {
1627
+ ...key && { key: key.toLowerCase() },
1628
+ ...modifiers.includes("metaKey") && { metaKey: true },
1629
+ ...modifiers.includes("ctrlKey") && { ctrlKey: true },
1630
+ ...modifiers.includes("shiftKey") && { shiftKey: true },
1631
+ ...modifiers.includes("altKey") && { altKey: true }
1632
+ };
1633
+ logger.log(
1634
+ ` Activation key: ${highlighter.info(formatActivationKey(collectedOptions.activationKey))}`
1635
+ );
1636
+ }
1637
+ const { activationMode } = await prompts2({
1638
+ type: "select",
1639
+ name: "activationMode",
1640
+ message: `Select ${highlighter.info("activation mode")}:`,
1641
+ choices: [
1642
+ { title: "Toggle (press to activate/deactivate)", value: "toggle" },
1643
+ { title: "Hold (hold key to keep active)", value: "hold" }
1644
+ ],
1645
+ initial: 0
1646
+ });
1647
+ if (activationMode === void 0) {
1648
+ logger.break();
1649
+ process.exit(1);
1650
+ }
1651
+ collectedOptions.activationMode = activationMode;
1652
+ if (activationMode === "hold") {
1653
+ const { keyHoldDuration } = await prompts2({
1654
+ type: "number",
1655
+ name: "keyHoldDuration",
1656
+ message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
1657
+ initial: 150,
1658
+ min: 0,
1659
+ max: 2e3
1660
+ });
1661
+ if (keyHoldDuration === void 0) {
1662
+ logger.break();
1663
+ process.exit(1);
1664
+ }
1665
+ collectedOptions.keyHoldDuration = keyHoldDuration;
1666
+ }
1667
+ const { allowActivationInsideInput } = await prompts2({
1668
+ type: "confirm",
1669
+ name: "allowActivationInsideInput",
1670
+ message: `Allow activation ${highlighter.info("inside input fields")}?`,
1671
+ initial: true
1672
+ });
1673
+ if (allowActivationInsideInput === void 0) {
1674
+ logger.break();
1675
+ process.exit(1);
1676
+ }
1677
+ collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
1678
+ const { maxContextLines } = await prompts2({
1679
+ type: "number",
1680
+ name: "maxContextLines",
1681
+ message: `Enter ${highlighter.info("max context lines")} to include:`,
1682
+ initial: 3,
1683
+ min: 0,
1684
+ max: 50
1685
+ });
1686
+ if (maxContextLines === void 0) {
1687
+ logger.break();
1688
+ process.exit(1);
1689
+ }
1690
+ collectedOptions.maxContextLines = maxContextLines;
1691
+ const result = previewOptionsTransform(
1692
+ projectInfo.projectRoot,
1693
+ projectInfo.framework,
1694
+ projectInfo.nextRouterType,
1695
+ collectedOptions
1696
+ );
1697
+ if (!result.success) {
1698
+ logger.break();
1699
+ logger.error(result.message);
1700
+ logger.break();
1701
+ process.exit(1);
1702
+ }
1703
+ const hasChanges = !result.noChanges && result.originalContent && result.newContent;
1704
+ if (hasChanges) {
1705
+ logger.break();
1706
+ printDiff(result.filePath, result.originalContent, result.newContent);
1707
+ logger.break();
1708
+ const { proceed } = await prompts2({
1709
+ type: "confirm",
1710
+ name: "proceed",
1711
+ message: "Apply these changes?",
1712
+ initial: true
1713
+ });
1714
+ if (!proceed) {
1715
+ logger.break();
1716
+ logger.log("Changes cancelled.");
1717
+ logger.break();
1718
+ process.exit(0);
1719
+ }
1720
+ const writeSpinner = spinner(
1721
+ `Applying changes to ${result.filePath}.`
1722
+ ).start();
1723
+ const writeResult = applyOptionsTransform(result);
1724
+ if (!writeResult.success) {
1725
+ writeSpinner.fail();
1726
+ logger.break();
1727
+ logger.error(writeResult.error || "Failed to write file.");
1728
+ logger.break();
1729
+ process.exit(1);
1730
+ }
1731
+ writeSpinner.succeed();
1732
+ } else {
1733
+ logger.break();
1734
+ logger.log("No changes needed.");
1735
+ }
1736
+ logger.break();
1737
+ logger.log(
1738
+ `${highlighter.success("Success!")} React Grab options have been configured.`
1739
+ );
1740
+ logger.break();
1741
+ } catch (error) {
1742
+ handleError(error);
1743
+ }
1744
+ });
1745
+ var VERSION3 = "0.0.87";
1353
1746
  var REPORT_URL = "https://react-grab.com/api/report-cli";
1354
1747
  var DOCS_URL = "https://github.com/aidenybai/react-grab";
1355
1748
  var reportToCli = async (type, config, error) => {
@@ -1359,7 +1752,7 @@ var reportToCli = async (type, config, error) => {
1359
1752
  headers: { "Content-Type": "application/json" },
1360
1753
  body: JSON.stringify({
1361
1754
  type,
1362
- version: VERSION2,
1755
+ version: VERSION3,
1363
1756
  config,
1364
1757
  error: error ? { message: error.message, stack: error.stack } : void 0,
1365
1758
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
@@ -1389,14 +1782,14 @@ var UNSUPPORTED_FRAMEWORK_NAMES = {
1389
1782
  };
1390
1783
  var init = new 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(
1391
1784
  "-a, --agent <agent>",
1392
- "agent integration (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
1785
+ "agent integration (claude-code, cursor, opencode, codex, gemini, amp, visual-edit)"
1393
1786
  ).option("--skip-install", "skip package installation", false).option(
1394
1787
  "-c, --cwd <cwd>",
1395
1788
  "working directory (defaults to current directory)",
1396
1789
  process.cwd()
1397
1790
  ).action(async (opts) => {
1398
1791
  console.log(
1399
- `${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION2)}`
1792
+ `${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION3)}`
1400
1793
  );
1401
1794
  console.log();
1402
1795
  try {
@@ -1520,8 +1913,7 @@ var init = new Command().name("init").description("initialize React Grab in your
1520
1913
  { title: "Codex", value: "codex" },
1521
1914
  { title: "Gemini", value: "gemini" },
1522
1915
  { title: "Amp", value: "amp" },
1523
- { title: "Ami", value: "ami" },
1524
- { title: "Instant", value: "instant" }
1916
+ { title: "Visual Edit", value: "visual-edit" }
1525
1917
  ]
1526
1918
  });
1527
1919
  if (agent === void 0) {
@@ -1659,7 +2051,7 @@ var init = new Command().name("init").description("initialize React Grab in your
1659
2051
  await reportToCli("error", void 0, error);
1660
2052
  }
1661
2053
  });
1662
- var VERSION3 = "0.0.85";
2054
+ var VERSION4 = "0.0.87";
1663
2055
  var DEFAULT_PROXY_PORT = 2e3;
1664
2056
  var REACT_GRAB_SCRIPT = '<script src="//unpkg.com/react-grab/dist/index.global.js"></script>';
1665
2057
  var buildProviderScript = (provider) => `<script src="//unpkg.com/${provider}/dist/client.global.js"></script>`;
@@ -1704,7 +2096,7 @@ var start = new Command().name("start").alias("proxy").description("start a prox
1704
2096
  "provider package to run via npx (e.g., @react-grab/cursor)"
1705
2097
  ).action(async (urlArg, opts) => {
1706
2098
  console.log(
1707
- `${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION3)}`
2099
+ `${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION4)}`
1708
2100
  );
1709
2101
  console.log();
1710
2102
  let url = urlArg;
@@ -1734,7 +2126,7 @@ var start = new Command().name("start").alias("proxy").description("start a prox
1734
2126
  { title: "Codex", value: "@react-grab/codex" },
1735
2127
  { title: "Gemini", value: "@react-grab/gemini" },
1736
2128
  { title: "Amp", value: "@react-grab/amp" },
1737
- { title: "Ami", value: "@react-grab/ami" }
2129
+ { title: "Visual Edit", value: "@react-grab/visual-edit" }
1738
2130
  ]
1739
2131
  });
1740
2132
  if (selectedProvider === void 0) {
@@ -1884,7 +2276,7 @@ var start = new Command().name("start").alias("proxy").description("start a prox
1884
2276
  });
1885
2277
 
1886
2278
  // src/cli.ts
1887
- var VERSION4 = "0.0.85";
2279
+ var VERSION5 = "0.0.87";
1888
2280
  var VERSION_API_URL = "https://www.react-grab.com/api/version";
1889
2281
  process.on("SIGINT", () => process.exit(0));
1890
2282
  process.on("SIGTERM", () => process.exit(0));
@@ -1893,8 +2285,9 @@ try {
1893
2285
  });
1894
2286
  } catch {
1895
2287
  }
1896
- var program = new Command().name("react-grab").description("add React Grab to your project").version(VERSION4, "-v, --version", "display the version number");
2288
+ var program = new Command().name("react-grab").description("add React Grab to your project").version(VERSION5, "-v, --version", "display the version number");
1897
2289
  program.addCommand(init);
1898
2290
  program.addCommand(add);
2291
+ program.addCommand(configure);
1899
2292
  program.addCommand(start);
1900
2293
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-grab/cli",
3
- "version": "0.0.85",
3
+ "version": "0.0.87",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "react-grab": "./dist/cli.js"