@react-grab/cli 0.0.91 → 0.0.92
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.
- package/dist/cli.cjs +1288 -66
- package/dist/cli.js +1288 -66
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var commander = require('commander');
|
|
5
5
|
var pc = require('picocolors');
|
|
6
|
-
var
|
|
6
|
+
var prompts3 = require('prompts');
|
|
7
7
|
var child_process = require('child_process');
|
|
8
8
|
var fs = require('fs');
|
|
9
9
|
var path = require('path');
|
|
@@ -15,7 +15,7 @@ var httpProxyMiddleware = require('http-proxy-middleware');
|
|
|
15
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
16
|
|
|
17
17
|
var pc__default = /*#__PURE__*/_interopDefault(pc);
|
|
18
|
-
var
|
|
18
|
+
var prompts3__default = /*#__PURE__*/_interopDefault(prompts3);
|
|
19
19
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
20
20
|
|
|
21
21
|
var detectPackageManager = async (projectRoot) => {
|
|
@@ -467,6 +467,12 @@ var INSTALL_COMMANDS = {
|
|
|
467
467
|
pnpm: "pnpm add",
|
|
468
468
|
bun: "bun add"
|
|
469
469
|
};
|
|
470
|
+
var UNINSTALL_COMMANDS = {
|
|
471
|
+
npm: "npm uninstall",
|
|
472
|
+
yarn: "yarn remove",
|
|
473
|
+
pnpm: "pnpm remove",
|
|
474
|
+
bun: "bun remove"
|
|
475
|
+
};
|
|
470
476
|
var installPackages = (packages, packageManager, projectRoot, isDev = true) => {
|
|
471
477
|
if (packages.length === 0) {
|
|
472
478
|
return;
|
|
@@ -491,6 +497,22 @@ var getPackagesToInstall = (agent, includeReactGrab = true) => {
|
|
|
491
497
|
}
|
|
492
498
|
return packages;
|
|
493
499
|
};
|
|
500
|
+
var uninstallPackages = (packages, packageManager, projectRoot) => {
|
|
501
|
+
if (packages.length === 0) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const command = UNINSTALL_COMMANDS[packageManager];
|
|
505
|
+
const fullCommand = `${command} ${packages.join(" ")}`;
|
|
506
|
+
console.log(`Running: ${fullCommand}
|
|
507
|
+
`);
|
|
508
|
+
child_process.execSync(fullCommand, {
|
|
509
|
+
cwd: projectRoot,
|
|
510
|
+
stdio: "inherit"
|
|
511
|
+
});
|
|
512
|
+
};
|
|
513
|
+
var getPackagesToUninstall = (agent) => {
|
|
514
|
+
return [`@react-grab/${agent}`];
|
|
515
|
+
};
|
|
494
516
|
var spinner = (text, options) => ora__default.default({ text, isSilent: options?.silent, stream: process.stdout });
|
|
495
517
|
|
|
496
518
|
// src/utils/templates.ts
|
|
@@ -676,18 +698,20 @@ var addAgentToExistingNextApp = (originalContent, agent, filePath) => {
|
|
|
676
698
|
noChanges: true
|
|
677
699
|
};
|
|
678
700
|
}
|
|
679
|
-
const agentScript =
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
701
|
+
const agentScript = `{process.env.NODE_ENV === "development" && (
|
|
702
|
+
<Script
|
|
703
|
+
src="//unpkg.com/${agentPackage}/dist/client.global.js"
|
|
704
|
+
strategy="lazyOnload"
|
|
705
|
+
/>
|
|
706
|
+
)}`;
|
|
707
|
+
const reactGrabBlockMatch = originalContent.match(
|
|
708
|
+
/\{process\.env\.NODE_ENV\s*===\s*["']development["']\s*&&\s*\(\s*<Script[^>]*react-grab[^>]*\/>\s*\)\}/is
|
|
685
709
|
);
|
|
686
|
-
if (
|
|
710
|
+
if (reactGrabBlockMatch) {
|
|
687
711
|
const newContent = originalContent.replace(
|
|
688
|
-
|
|
689
|
-
`${
|
|
690
|
-
|
|
712
|
+
reactGrabBlockMatch[0],
|
|
713
|
+
`${reactGrabBlockMatch[0]}
|
|
714
|
+
${agentScript}`
|
|
691
715
|
);
|
|
692
716
|
return {
|
|
693
717
|
success: true,
|
|
@@ -1037,20 +1061,49 @@ var applyTransform = (result) => {
|
|
|
1037
1061
|
}
|
|
1038
1062
|
return { success: true };
|
|
1039
1063
|
};
|
|
1040
|
-
var
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1064
|
+
var getPackageExecutor = (packageManager) => {
|
|
1065
|
+
switch (packageManager) {
|
|
1066
|
+
case "bun":
|
|
1067
|
+
return "bunx";
|
|
1068
|
+
case "pnpm":
|
|
1069
|
+
return "pnpm dlx";
|
|
1070
|
+
case "yarn":
|
|
1071
|
+
return "npx";
|
|
1072
|
+
case "npm":
|
|
1073
|
+
default:
|
|
1074
|
+
return "npx";
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
var AGENT_PACKAGES2 = {
|
|
1078
|
+
"claude-code": "@react-grab/claude-code@latest",
|
|
1079
|
+
cursor: "@react-grab/cursor@latest",
|
|
1080
|
+
opencode: "@react-grab/opencode@latest",
|
|
1081
|
+
codex: "@react-grab/codex@latest",
|
|
1082
|
+
gemini: "@react-grab/gemini@latest",
|
|
1083
|
+
amp: "@react-grab/amp@latest"
|
|
1084
|
+
};
|
|
1085
|
+
var getAgentPrefix = (agent, packageManager) => {
|
|
1086
|
+
const agentPackage = AGENT_PACKAGES2[agent];
|
|
1087
|
+
if (!agentPackage) return null;
|
|
1088
|
+
const executor = getPackageExecutor(packageManager);
|
|
1089
|
+
return `${executor} ${agentPackage} &&`;
|
|
1090
|
+
};
|
|
1091
|
+
var getAllAgentPrefixVariants = (agent) => {
|
|
1092
|
+
const agentPackage = AGENT_PACKAGES2[agent];
|
|
1093
|
+
if (!agentPackage) return [];
|
|
1094
|
+
return [
|
|
1095
|
+
`npx ${agentPackage} &&`,
|
|
1096
|
+
`bunx ${agentPackage} &&`,
|
|
1097
|
+
`pnpm dlx ${agentPackage} &&`,
|
|
1098
|
+
`yarn dlx ${agentPackage} &&`
|
|
1099
|
+
];
|
|
1047
1100
|
};
|
|
1048
|
-
var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
|
|
1049
|
-
if (agent === "none" || agent === "
|
|
1101
|
+
var previewPackageJsonTransform = (projectRoot, agent, installedAgents, packageManager = "npm") => {
|
|
1102
|
+
if (agent === "none" || agent === "visual-edit") {
|
|
1050
1103
|
return {
|
|
1051
1104
|
success: true,
|
|
1052
1105
|
filePath: "",
|
|
1053
|
-
message: agent === "
|
|
1106
|
+
message: agent === "visual-edit" ? "Visual Edit does not require package.json modification" : "No agent selected, skipping package.json modification",
|
|
1054
1107
|
noChanges: true
|
|
1055
1108
|
};
|
|
1056
1109
|
}
|
|
@@ -1063,7 +1116,7 @@ var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
|
|
|
1063
1116
|
};
|
|
1064
1117
|
}
|
|
1065
1118
|
const originalContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
1066
|
-
const agentPrefix =
|
|
1119
|
+
const agentPrefix = getAgentPrefix(agent, packageManager);
|
|
1067
1120
|
if (!agentPrefix) {
|
|
1068
1121
|
return {
|
|
1069
1122
|
success: false,
|
|
@@ -1071,7 +1124,11 @@ var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
|
|
|
1071
1124
|
message: `Unknown agent: ${agent}`
|
|
1072
1125
|
};
|
|
1073
1126
|
}
|
|
1074
|
-
|
|
1127
|
+
const allPrefixVariants = getAllAgentPrefixVariants(agent);
|
|
1128
|
+
const hasExistingPrefix = allPrefixVariants.some(
|
|
1129
|
+
(prefix) => originalContent.includes(prefix)
|
|
1130
|
+
);
|
|
1131
|
+
if (hasExistingPrefix) {
|
|
1075
1132
|
return {
|
|
1076
1133
|
success: true,
|
|
1077
1134
|
filePath: packageJsonPath,
|
|
@@ -1094,14 +1151,19 @@ var previewPackageJsonTransform = (projectRoot, agent, installedAgents) => {
|
|
|
1094
1151
|
filePath: packageJsonPath,
|
|
1095
1152
|
message: "No dev script found in package.json",
|
|
1096
1153
|
noChanges: true,
|
|
1097
|
-
warning: `
|
|
1154
|
+
warning: `Could not inject agent into package.json (no dev script found).
|
|
1155
|
+
Run this command manually before starting your dev server:
|
|
1156
|
+
${agentPrefix} <your dev command>`
|
|
1098
1157
|
};
|
|
1099
1158
|
}
|
|
1100
1159
|
}
|
|
1101
1160
|
const currentDevScript = packageJson.scripts[targetScriptKey];
|
|
1102
1161
|
for (const installedAgent of installedAgents) {
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1162
|
+
const installedPrefixVariants = getAllAgentPrefixVariants(installedAgent);
|
|
1163
|
+
const hasInstalledAgentPrefix = installedPrefixVariants.some(
|
|
1164
|
+
(prefix) => currentDevScript.includes(prefix)
|
|
1165
|
+
);
|
|
1166
|
+
if (hasInstalledAgentPrefix) {
|
|
1105
1167
|
return {
|
|
1106
1168
|
success: true,
|
|
1107
1169
|
filePath: packageJsonPath,
|
|
@@ -1345,9 +1407,192 @@ var previewOptionsTransform = (projectRoot, framework, nextRouterType, options)
|
|
|
1345
1407
|
var applyOptionsTransform = (result) => {
|
|
1346
1408
|
return applyTransform(result);
|
|
1347
1409
|
};
|
|
1410
|
+
var removeAgentFromNextApp = (originalContent, agent, filePath) => {
|
|
1411
|
+
const agentPackage = `@react-grab/${agent}`;
|
|
1412
|
+
if (!originalContent.includes(agentPackage)) {
|
|
1413
|
+
return {
|
|
1414
|
+
success: true,
|
|
1415
|
+
filePath,
|
|
1416
|
+
message: `Agent ${agent} is not configured in this file`,
|
|
1417
|
+
noChanges: true
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
const agentScriptPattern = new RegExp(
|
|
1421
|
+
`\\s*\\{process\\.env\\.NODE_ENV === "development" && \\(\\s*<Script[^>]*${agentPackage.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^>]*\\/>\\s*\\)\\}`,
|
|
1422
|
+
"gs"
|
|
1423
|
+
);
|
|
1424
|
+
const simpleScriptPattern = new RegExp(
|
|
1425
|
+
`\\s*<Script[^>]*${agentPackage.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^>]*\\/>`,
|
|
1426
|
+
"gi"
|
|
1427
|
+
);
|
|
1428
|
+
let newContent = originalContent.replace(agentScriptPattern, "");
|
|
1429
|
+
if (newContent === originalContent) {
|
|
1430
|
+
newContent = originalContent.replace(simpleScriptPattern, "");
|
|
1431
|
+
}
|
|
1432
|
+
if (newContent === originalContent) {
|
|
1433
|
+
return {
|
|
1434
|
+
success: false,
|
|
1435
|
+
filePath,
|
|
1436
|
+
message: `Could not find agent ${agent} script to remove`
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
return {
|
|
1440
|
+
success: true,
|
|
1441
|
+
filePath,
|
|
1442
|
+
message: `Remove ${agent} agent`,
|
|
1443
|
+
originalContent,
|
|
1444
|
+
newContent
|
|
1445
|
+
};
|
|
1446
|
+
};
|
|
1447
|
+
var removeAgentFromVite = (originalContent, agent, filePath) => {
|
|
1448
|
+
const agentPackage = `@react-grab/${agent}`;
|
|
1449
|
+
if (!originalContent.includes(agentPackage)) {
|
|
1450
|
+
return {
|
|
1451
|
+
success: true,
|
|
1452
|
+
filePath,
|
|
1453
|
+
message: `Agent ${agent} is not configured in this file`,
|
|
1454
|
+
noChanges: true
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
const agentImportPattern = new RegExp(
|
|
1458
|
+
`\\s*import\\s*\\(\\s*["']${agentPackage.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/client["']\\s*\\);?`,
|
|
1459
|
+
"g"
|
|
1460
|
+
);
|
|
1461
|
+
const newContent = originalContent.replace(agentImportPattern, "");
|
|
1462
|
+
if (newContent === originalContent) {
|
|
1463
|
+
return {
|
|
1464
|
+
success: false,
|
|
1465
|
+
filePath,
|
|
1466
|
+
message: `Could not find agent ${agent} import to remove`
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
return {
|
|
1470
|
+
success: true,
|
|
1471
|
+
filePath,
|
|
1472
|
+
message: `Remove ${agent} agent`,
|
|
1473
|
+
originalContent,
|
|
1474
|
+
newContent
|
|
1475
|
+
};
|
|
1476
|
+
};
|
|
1477
|
+
var removeAgentFromWebpack = (originalContent, agent, filePath) => {
|
|
1478
|
+
const agentPackage = `@react-grab/${agent}`;
|
|
1479
|
+
if (!originalContent.includes(agentPackage)) {
|
|
1480
|
+
return {
|
|
1481
|
+
success: true,
|
|
1482
|
+
filePath,
|
|
1483
|
+
message: `Agent ${agent} is not configured in this file`,
|
|
1484
|
+
noChanges: true
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
const agentImportPattern = new RegExp(
|
|
1488
|
+
`\\s*import\\s*\\(\\s*["']${agentPackage.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/client["']\\s*\\);?`,
|
|
1489
|
+
"g"
|
|
1490
|
+
);
|
|
1491
|
+
const newContent = originalContent.replace(agentImportPattern, "");
|
|
1492
|
+
if (newContent === originalContent) {
|
|
1493
|
+
return {
|
|
1494
|
+
success: false,
|
|
1495
|
+
filePath,
|
|
1496
|
+
message: `Could not find agent ${agent} import to remove`
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
return {
|
|
1500
|
+
success: true,
|
|
1501
|
+
filePath,
|
|
1502
|
+
message: `Remove ${agent} agent`,
|
|
1503
|
+
originalContent,
|
|
1504
|
+
newContent
|
|
1505
|
+
};
|
|
1506
|
+
};
|
|
1507
|
+
var previewAgentRemoval = (projectRoot, framework, nextRouterType, agent) => {
|
|
1508
|
+
const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);
|
|
1509
|
+
if (!filePath) {
|
|
1510
|
+
return {
|
|
1511
|
+
success: true,
|
|
1512
|
+
filePath: "",
|
|
1513
|
+
message: "Could not find file containing React Grab configuration",
|
|
1514
|
+
noChanges: true
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
const originalContent = fs.readFileSync(filePath, "utf-8");
|
|
1518
|
+
switch (framework) {
|
|
1519
|
+
case "next":
|
|
1520
|
+
return removeAgentFromNextApp(originalContent, agent, filePath);
|
|
1521
|
+
case "vite":
|
|
1522
|
+
return removeAgentFromVite(originalContent, agent, filePath);
|
|
1523
|
+
case "webpack":
|
|
1524
|
+
return removeAgentFromWebpack(originalContent, agent, filePath);
|
|
1525
|
+
default:
|
|
1526
|
+
return {
|
|
1527
|
+
success: false,
|
|
1528
|
+
filePath,
|
|
1529
|
+
message: `Unknown framework: ${framework}`
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
};
|
|
1533
|
+
var previewPackageJsonAgentRemoval = (projectRoot, agent) => {
|
|
1534
|
+
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
1535
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
1536
|
+
return {
|
|
1537
|
+
success: true,
|
|
1538
|
+
filePath: "",
|
|
1539
|
+
message: "Could not find package.json",
|
|
1540
|
+
noChanges: true
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
const originalContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
1544
|
+
const allPrefixVariants = getAllAgentPrefixVariants(agent);
|
|
1545
|
+
if (allPrefixVariants.length === 0) {
|
|
1546
|
+
return {
|
|
1547
|
+
success: true,
|
|
1548
|
+
filePath: packageJsonPath,
|
|
1549
|
+
message: `Unknown agent: ${agent}`,
|
|
1550
|
+
noChanges: true
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
const hasAnyPrefix = allPrefixVariants.some(
|
|
1554
|
+
(prefix) => originalContent.includes(prefix)
|
|
1555
|
+
);
|
|
1556
|
+
if (!hasAnyPrefix) {
|
|
1557
|
+
return {
|
|
1558
|
+
success: true,
|
|
1559
|
+
filePath: packageJsonPath,
|
|
1560
|
+
message: `Agent ${agent} dev script is not configured`,
|
|
1561
|
+
noChanges: true
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
try {
|
|
1565
|
+
const packageJson = JSON.parse(originalContent);
|
|
1566
|
+
for (const scriptKey of Object.keys(packageJson.scripts || {})) {
|
|
1567
|
+
let scriptValue = packageJson.scripts[scriptKey];
|
|
1568
|
+
if (typeof scriptValue === "string") {
|
|
1569
|
+
for (const prefix of allPrefixVariants) {
|
|
1570
|
+
if (scriptValue.includes(prefix)) {
|
|
1571
|
+
scriptValue = scriptValue.replace(prefix + " ", "").replace(prefix, "");
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
packageJson.scripts[scriptKey] = scriptValue;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
const newContent = JSON.stringify(packageJson, null, 2) + "\n";
|
|
1578
|
+
return {
|
|
1579
|
+
success: true,
|
|
1580
|
+
filePath: packageJsonPath,
|
|
1581
|
+
message: `Remove ${agent} server from dev script`,
|
|
1582
|
+
originalContent,
|
|
1583
|
+
newContent
|
|
1584
|
+
};
|
|
1585
|
+
} catch {
|
|
1586
|
+
return {
|
|
1587
|
+
success: false,
|
|
1588
|
+
filePath: packageJsonPath,
|
|
1589
|
+
message: "Failed to parse package.json"
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1348
1593
|
|
|
1349
1594
|
// src/commands/add.ts
|
|
1350
|
-
var VERSION = "0.0.
|
|
1595
|
+
var VERSION = "0.0.92";
|
|
1351
1596
|
var AGENT_NAMES = {
|
|
1352
1597
|
"claude-code": "Claude Code",
|
|
1353
1598
|
cursor: "Cursor",
|
|
@@ -1384,7 +1629,7 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1384
1629
|
process.exit(1);
|
|
1385
1630
|
}
|
|
1386
1631
|
preflightSpinner.succeed();
|
|
1387
|
-
const
|
|
1632
|
+
const allAgents = [
|
|
1388
1633
|
"claude-code",
|
|
1389
1634
|
"cursor",
|
|
1390
1635
|
"opencode",
|
|
@@ -1392,7 +1637,10 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1392
1637
|
"gemini",
|
|
1393
1638
|
"amp",
|
|
1394
1639
|
"visual-edit"
|
|
1395
|
-
]
|
|
1640
|
+
];
|
|
1641
|
+
const availableAgents = allAgents.filter(
|
|
1642
|
+
(agent) => !projectInfo.installedAgents.includes(agent)
|
|
1643
|
+
);
|
|
1396
1644
|
if (availableAgents.length === 0) {
|
|
1397
1645
|
logger.break();
|
|
1398
1646
|
logger.success("All agent integrations are already installed.");
|
|
@@ -1400,16 +1648,9 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1400
1648
|
process.exit(0);
|
|
1401
1649
|
}
|
|
1402
1650
|
let agentIntegration;
|
|
1651
|
+
let agentsToRemove = [];
|
|
1403
1652
|
if (agentArg) {
|
|
1404
|
-
if (!
|
|
1405
|
-
"claude-code",
|
|
1406
|
-
"cursor",
|
|
1407
|
-
"opencode",
|
|
1408
|
-
"codex",
|
|
1409
|
-
"gemini",
|
|
1410
|
-
"amp",
|
|
1411
|
-
"visual-edit"
|
|
1412
|
-
].includes(agentArg)) {
|
|
1653
|
+
if (!allAgents.includes(agentArg)) {
|
|
1413
1654
|
logger.break();
|
|
1414
1655
|
logger.error(`Invalid agent: ${agentArg}`);
|
|
1415
1656
|
logger.error(
|
|
@@ -1425,9 +1666,44 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1425
1666
|
process.exit(0);
|
|
1426
1667
|
}
|
|
1427
1668
|
agentIntegration = agentArg;
|
|
1669
|
+
if (projectInfo.installedAgents.length > 0 && !isNonInteractive) {
|
|
1670
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES[innerAgent] || innerAgent).join(", ");
|
|
1671
|
+
logger.break();
|
|
1672
|
+
logger.warn(`${installedNames} is already installed.`);
|
|
1673
|
+
const { action } = await prompts3__default.default({
|
|
1674
|
+
type: "select",
|
|
1675
|
+
name: "action",
|
|
1676
|
+
message: "How would you like to proceed?",
|
|
1677
|
+
choices: [
|
|
1678
|
+
{
|
|
1679
|
+
title: `Replace with ${AGENT_NAMES[agentIntegration]}`,
|
|
1680
|
+
value: "replace"
|
|
1681
|
+
},
|
|
1682
|
+
{
|
|
1683
|
+
title: `Add ${AGENT_NAMES[agentIntegration]} alongside existing`,
|
|
1684
|
+
value: "add"
|
|
1685
|
+
},
|
|
1686
|
+
{ title: "Cancel", value: "cancel" }
|
|
1687
|
+
]
|
|
1688
|
+
});
|
|
1689
|
+
if (!action || action === "cancel") {
|
|
1690
|
+
logger.break();
|
|
1691
|
+
logger.log("Changes cancelled.");
|
|
1692
|
+
logger.break();
|
|
1693
|
+
process.exit(0);
|
|
1694
|
+
}
|
|
1695
|
+
if (action === "replace") {
|
|
1696
|
+
agentsToRemove = [...projectInfo.installedAgents];
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1428
1699
|
} else if (!isNonInteractive) {
|
|
1429
1700
|
logger.break();
|
|
1430
|
-
|
|
1701
|
+
if (projectInfo.installedAgents.length > 0) {
|
|
1702
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES[innerAgent] || innerAgent).join(", ");
|
|
1703
|
+
logger.warn(`Currently installed: ${installedNames}`);
|
|
1704
|
+
logger.break();
|
|
1705
|
+
}
|
|
1706
|
+
const { agent } = await prompts3__default.default({
|
|
1431
1707
|
type: "select",
|
|
1432
1708
|
name: "agent",
|
|
1433
1709
|
message: `Which ${highlighter.info("agent integration")} would you like to add?`,
|
|
@@ -1441,6 +1717,34 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1441
1717
|
process.exit(1);
|
|
1442
1718
|
}
|
|
1443
1719
|
agentIntegration = agent;
|
|
1720
|
+
if (projectInfo.installedAgents.length > 0) {
|
|
1721
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES[innerAgent] || innerAgent).join(", ");
|
|
1722
|
+
const { action } = await prompts3__default.default({
|
|
1723
|
+
type: "select",
|
|
1724
|
+
name: "action",
|
|
1725
|
+
message: "How would you like to proceed?",
|
|
1726
|
+
choices: [
|
|
1727
|
+
{
|
|
1728
|
+
title: `Replace ${installedNames} with ${AGENT_NAMES[agentIntegration]}`,
|
|
1729
|
+
value: "replace"
|
|
1730
|
+
},
|
|
1731
|
+
{
|
|
1732
|
+
title: `Add ${AGENT_NAMES[agentIntegration]} alongside existing`,
|
|
1733
|
+
value: "add"
|
|
1734
|
+
},
|
|
1735
|
+
{ title: "Cancel", value: "cancel" }
|
|
1736
|
+
]
|
|
1737
|
+
});
|
|
1738
|
+
if (!action || action === "cancel") {
|
|
1739
|
+
logger.break();
|
|
1740
|
+
logger.log("Changes cancelled.");
|
|
1741
|
+
logger.break();
|
|
1742
|
+
process.exit(0);
|
|
1743
|
+
}
|
|
1744
|
+
if (action === "replace") {
|
|
1745
|
+
agentsToRemove = [...projectInfo.installedAgents];
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1444
1748
|
} else {
|
|
1445
1749
|
logger.break();
|
|
1446
1750
|
logger.error("Please specify an agent to add.");
|
|
@@ -1448,6 +1752,72 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1448
1752
|
logger.break();
|
|
1449
1753
|
process.exit(1);
|
|
1450
1754
|
}
|
|
1755
|
+
if (agentsToRemove.length > 0) {
|
|
1756
|
+
for (const agentToRemove of agentsToRemove) {
|
|
1757
|
+
const removalResult = previewAgentRemoval(
|
|
1758
|
+
projectInfo.projectRoot,
|
|
1759
|
+
projectInfo.framework,
|
|
1760
|
+
projectInfo.nextRouterType,
|
|
1761
|
+
agentToRemove
|
|
1762
|
+
);
|
|
1763
|
+
const removalPackageJsonResult = previewPackageJsonAgentRemoval(
|
|
1764
|
+
projectInfo.projectRoot,
|
|
1765
|
+
agentToRemove
|
|
1766
|
+
);
|
|
1767
|
+
const packagesToRemove = getPackagesToUninstall(agentToRemove);
|
|
1768
|
+
if (packagesToRemove.length > 0) {
|
|
1769
|
+
const uninstallSpinner = spinner(
|
|
1770
|
+
`Removing ${packagesToRemove.join(", ")}.`
|
|
1771
|
+
).start();
|
|
1772
|
+
try {
|
|
1773
|
+
uninstallPackages(
|
|
1774
|
+
packagesToRemove,
|
|
1775
|
+
projectInfo.packageManager,
|
|
1776
|
+
projectInfo.projectRoot
|
|
1777
|
+
);
|
|
1778
|
+
uninstallSpinner.succeed();
|
|
1779
|
+
} catch (error) {
|
|
1780
|
+
uninstallSpinner.fail();
|
|
1781
|
+
handleError(error);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
if (removalResult.success && !removalResult.noChanges && removalResult.newContent) {
|
|
1785
|
+
const removeWriteSpinner = spinner(
|
|
1786
|
+
`Removing ${AGENT_NAMES[agentToRemove] || agentToRemove} from ${removalResult.filePath}.`
|
|
1787
|
+
).start();
|
|
1788
|
+
const writeResult = applyTransform(removalResult);
|
|
1789
|
+
if (!writeResult.success) {
|
|
1790
|
+
removeWriteSpinner.fail();
|
|
1791
|
+
logger.break();
|
|
1792
|
+
logger.error(writeResult.error || "Failed to write file.");
|
|
1793
|
+
logger.break();
|
|
1794
|
+
process.exit(1);
|
|
1795
|
+
}
|
|
1796
|
+
removeWriteSpinner.succeed();
|
|
1797
|
+
}
|
|
1798
|
+
if (removalPackageJsonResult.success && !removalPackageJsonResult.noChanges && removalPackageJsonResult.newContent) {
|
|
1799
|
+
const removePackageJsonSpinner = spinner(
|
|
1800
|
+
`Removing ${AGENT_NAMES[agentToRemove] || agentToRemove} from ${removalPackageJsonResult.filePath}.`
|
|
1801
|
+
).start();
|
|
1802
|
+
const packageJsonWriteResult = applyPackageJsonTransform(
|
|
1803
|
+
removalPackageJsonResult
|
|
1804
|
+
);
|
|
1805
|
+
if (!packageJsonWriteResult.success) {
|
|
1806
|
+
removePackageJsonSpinner.fail();
|
|
1807
|
+
logger.break();
|
|
1808
|
+
logger.error(
|
|
1809
|
+
packageJsonWriteResult.error || "Failed to write file."
|
|
1810
|
+
);
|
|
1811
|
+
logger.break();
|
|
1812
|
+
process.exit(1);
|
|
1813
|
+
}
|
|
1814
|
+
removePackageJsonSpinner.succeed();
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
projectInfo.installedAgents = projectInfo.installedAgents.filter(
|
|
1818
|
+
(innerAgent) => !agentsToRemove.includes(innerAgent)
|
|
1819
|
+
);
|
|
1820
|
+
}
|
|
1451
1821
|
const addingSpinner = spinner(
|
|
1452
1822
|
`Adding ${AGENT_NAMES[agentIntegration]}.`
|
|
1453
1823
|
).start();
|
|
@@ -1462,7 +1832,8 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1462
1832
|
const packageJsonResult = previewPackageJsonTransform(
|
|
1463
1833
|
projectInfo.projectRoot,
|
|
1464
1834
|
agentIntegration,
|
|
1465
|
-
projectInfo.installedAgents
|
|
1835
|
+
projectInfo.installedAgents,
|
|
1836
|
+
projectInfo.packageManager
|
|
1466
1837
|
);
|
|
1467
1838
|
if (!result.success) {
|
|
1468
1839
|
logger.break();
|
|
@@ -1491,9 +1862,9 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1491
1862
|
packageJsonResult.newContent
|
|
1492
1863
|
);
|
|
1493
1864
|
}
|
|
1494
|
-
if (!isNonInteractive) {
|
|
1865
|
+
if (!isNonInteractive && agentsToRemove.length === 0) {
|
|
1495
1866
|
logger.break();
|
|
1496
|
-
const { proceed } = await
|
|
1867
|
+
const { proceed } = await prompts3__default.default({
|
|
1497
1868
|
type: "confirm",
|
|
1498
1869
|
name: "proceed",
|
|
1499
1870
|
message: "Apply these changes?",
|
|
@@ -1566,7 +1937,7 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1566
1937
|
handleError(error);
|
|
1567
1938
|
}
|
|
1568
1939
|
});
|
|
1569
|
-
var VERSION2 = "0.0.
|
|
1940
|
+
var VERSION2 = "0.0.92";
|
|
1570
1941
|
var MODIFIER_KEY_NAMES = {
|
|
1571
1942
|
metaKey: process.platform === "darwin" ? "\u2318 Command" : "\u229E Windows",
|
|
1572
1943
|
ctrlKey: "Ctrl",
|
|
@@ -1620,7 +1991,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1620
1991
|
logger.log(`Configure ${highlighter.info("React Grab")} options:`);
|
|
1621
1992
|
logger.break();
|
|
1622
1993
|
const collectedOptions = {};
|
|
1623
|
-
const { wantActivationKey } = await
|
|
1994
|
+
const { wantActivationKey } = await prompts3__default.default({
|
|
1624
1995
|
type: "confirm",
|
|
1625
1996
|
name: "wantActivationKey",
|
|
1626
1997
|
message: `Configure ${highlighter.info("activation key")}?`,
|
|
@@ -1631,7 +2002,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1631
2002
|
process.exit(1);
|
|
1632
2003
|
}
|
|
1633
2004
|
if (wantActivationKey) {
|
|
1634
|
-
const { key } = await
|
|
2005
|
+
const { key } = await prompts3__default.default({
|
|
1635
2006
|
type: "text",
|
|
1636
2007
|
name: "key",
|
|
1637
2008
|
message: "Enter the activation key (e.g., g, k, space):",
|
|
@@ -1641,7 +2012,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1641
2012
|
logger.break();
|
|
1642
2013
|
process.exit(1);
|
|
1643
2014
|
}
|
|
1644
|
-
const { modifiers } = await
|
|
2015
|
+
const { modifiers } = await prompts3__default.default({
|
|
1645
2016
|
type: "multiselect",
|
|
1646
2017
|
name: "modifiers",
|
|
1647
2018
|
message: "Select modifier keys (space to select, enter to confirm):",
|
|
@@ -1672,7 +2043,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1672
2043
|
` Activation key: ${highlighter.info(formatActivationKey(collectedOptions.activationKey))}`
|
|
1673
2044
|
);
|
|
1674
2045
|
}
|
|
1675
|
-
const { activationMode } = await
|
|
2046
|
+
const { activationMode } = await prompts3__default.default({
|
|
1676
2047
|
type: "select",
|
|
1677
2048
|
name: "activationMode",
|
|
1678
2049
|
message: `Select ${highlighter.info("activation mode")}:`,
|
|
@@ -1688,7 +2059,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1688
2059
|
}
|
|
1689
2060
|
collectedOptions.activationMode = activationMode;
|
|
1690
2061
|
if (activationMode === "hold") {
|
|
1691
|
-
const { keyHoldDuration } = await
|
|
2062
|
+
const { keyHoldDuration } = await prompts3__default.default({
|
|
1692
2063
|
type: "number",
|
|
1693
2064
|
name: "keyHoldDuration",
|
|
1694
2065
|
message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
|
|
@@ -1702,7 +2073,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1702
2073
|
}
|
|
1703
2074
|
collectedOptions.keyHoldDuration = keyHoldDuration;
|
|
1704
2075
|
}
|
|
1705
|
-
const { allowActivationInsideInput } = await
|
|
2076
|
+
const { allowActivationInsideInput } = await prompts3__default.default({
|
|
1706
2077
|
type: "confirm",
|
|
1707
2078
|
name: "allowActivationInsideInput",
|
|
1708
2079
|
message: `Allow activation ${highlighter.info("inside input fields")}?`,
|
|
@@ -1713,7 +2084,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1713
2084
|
process.exit(1);
|
|
1714
2085
|
}
|
|
1715
2086
|
collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
|
|
1716
|
-
const { maxContextLines } = await
|
|
2087
|
+
const { maxContextLines } = await prompts3__default.default({
|
|
1717
2088
|
type: "number",
|
|
1718
2089
|
name: "maxContextLines",
|
|
1719
2090
|
message: `Enter ${highlighter.info("max context lines")} to include:`,
|
|
@@ -1743,7 +2114,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1743
2114
|
logger.break();
|
|
1744
2115
|
printDiff(result.filePath, result.originalContent, result.newContent);
|
|
1745
2116
|
logger.break();
|
|
1746
|
-
const { proceed } = await
|
|
2117
|
+
const { proceed } = await prompts3__default.default({
|
|
1747
2118
|
type: "confirm",
|
|
1748
2119
|
name: "proceed",
|
|
1749
2120
|
message: "Apply these changes?",
|
|
@@ -1780,7 +2151,7 @@ var configure = new commander.Command().name("configure").alias("config").descri
|
|
|
1780
2151
|
handleError(error);
|
|
1781
2152
|
}
|
|
1782
2153
|
});
|
|
1783
|
-
var VERSION3 = "0.0.
|
|
2154
|
+
var VERSION3 = "0.0.92";
|
|
1784
2155
|
var REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
1785
2156
|
var DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
1786
2157
|
var reportToCli = async (type, config, error) => {
|
|
@@ -1818,6 +2189,34 @@ var UNSUPPORTED_FRAMEWORK_NAMES = {
|
|
|
1818
2189
|
sveltekit: "SvelteKit",
|
|
1819
2190
|
gatsby: "Gatsby"
|
|
1820
2191
|
};
|
|
2192
|
+
var AGENT_NAMES2 = {
|
|
2193
|
+
"claude-code": "Claude Code",
|
|
2194
|
+
cursor: "Cursor",
|
|
2195
|
+
opencode: "OpenCode",
|
|
2196
|
+
codex: "Codex",
|
|
2197
|
+
gemini: "Gemini",
|
|
2198
|
+
amp: "Amp",
|
|
2199
|
+
ami: "Ami",
|
|
2200
|
+
"visual-edit": "Visual Edit"
|
|
2201
|
+
};
|
|
2202
|
+
var MODIFIER_KEY_NAMES2 = {
|
|
2203
|
+
metaKey: process.platform === "darwin" ? "\u2318 Command" : "\u229E Windows",
|
|
2204
|
+
ctrlKey: "Ctrl",
|
|
2205
|
+
shiftKey: "Shift",
|
|
2206
|
+
altKey: process.platform === "darwin" ? "\u2325 Option" : "Alt"
|
|
2207
|
+
};
|
|
2208
|
+
var formatActivationKey2 = (activationKey) => {
|
|
2209
|
+
if (!activationKey) return "Default (Option/Alt)";
|
|
2210
|
+
const parts = [];
|
|
2211
|
+
if (activationKey.metaKey)
|
|
2212
|
+
parts.push(process.platform === "darwin" ? "\u2318" : "Win");
|
|
2213
|
+
if (activationKey.ctrlKey) parts.push("Ctrl");
|
|
2214
|
+
if (activationKey.shiftKey) parts.push("Shift");
|
|
2215
|
+
if (activationKey.altKey)
|
|
2216
|
+
parts.push(process.platform === "darwin" ? "\u2325" : "Alt");
|
|
2217
|
+
if (activationKey.key) parts.push(activationKey.key.toUpperCase());
|
|
2218
|
+
return parts.length > 0 ? parts.join(" + ") : "Default (Option/Alt)";
|
|
2219
|
+
};
|
|
1821
2220
|
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(
|
|
1822
2221
|
"-a, --agent <agent>",
|
|
1823
2222
|
"agent integration (claude-code, cursor, opencode, codex, gemini, amp, visual-edit)"
|
|
@@ -1837,11 +2236,514 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1837
2236
|
const projectInfo = await detectProject(cwd);
|
|
1838
2237
|
if (projectInfo.hasReactGrab && !opts.force) {
|
|
1839
2238
|
preflightSpinner.succeed();
|
|
2239
|
+
if (isNonInteractive) {
|
|
2240
|
+
logger.break();
|
|
2241
|
+
logger.warn("React Grab is already installed.");
|
|
2242
|
+
logger.log(
|
|
2243
|
+
`Use ${highlighter.info("--force")} to reconfigure, or remove ${highlighter.info("--yes")} for interactive mode.`
|
|
2244
|
+
);
|
|
2245
|
+
logger.break();
|
|
2246
|
+
process.exit(0);
|
|
2247
|
+
}
|
|
1840
2248
|
logger.break();
|
|
1841
|
-
logger.
|
|
1842
|
-
logger.
|
|
1843
|
-
|
|
2249
|
+
logger.success("React Grab is already installed.");
|
|
2250
|
+
logger.break();
|
|
2251
|
+
const allAgents = [
|
|
2252
|
+
"claude-code",
|
|
2253
|
+
"cursor",
|
|
2254
|
+
"opencode",
|
|
2255
|
+
"codex",
|
|
2256
|
+
"gemini",
|
|
2257
|
+
"amp",
|
|
2258
|
+
"visual-edit"
|
|
2259
|
+
];
|
|
2260
|
+
const availableAgents = allAgents.filter(
|
|
2261
|
+
(agent) => !projectInfo.installedAgents.includes(agent)
|
|
1844
2262
|
);
|
|
2263
|
+
if (projectInfo.installedAgents.length > 0) {
|
|
2264
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES2[innerAgent] || innerAgent).join(", ");
|
|
2265
|
+
logger.log(
|
|
2266
|
+
`Currently installed agents: ${highlighter.info(installedNames)}`
|
|
2267
|
+
);
|
|
2268
|
+
logger.break();
|
|
2269
|
+
}
|
|
2270
|
+
let didAddAgent = false;
|
|
2271
|
+
if (availableAgents.length > 0) {
|
|
2272
|
+
const { wantAddAgent } = await prompts3__default.default({
|
|
2273
|
+
type: "confirm",
|
|
2274
|
+
name: "wantAddAgent",
|
|
2275
|
+
message: `Would you like to add an ${highlighter.info("agent integration")}?`,
|
|
2276
|
+
initial: true
|
|
2277
|
+
});
|
|
2278
|
+
if (wantAddAgent === void 0) {
|
|
2279
|
+
logger.break();
|
|
2280
|
+
process.exit(1);
|
|
2281
|
+
}
|
|
2282
|
+
if (wantAddAgent) {
|
|
2283
|
+
const { agent } = await prompts3__default.default({
|
|
2284
|
+
type: "select",
|
|
2285
|
+
name: "agent",
|
|
2286
|
+
message: `Which ${highlighter.info("agent integration")} would you like to add?`,
|
|
2287
|
+
choices: availableAgents.map((innerAgent) => ({
|
|
2288
|
+
title: AGENT_NAMES2[innerAgent],
|
|
2289
|
+
value: innerAgent
|
|
2290
|
+
}))
|
|
2291
|
+
});
|
|
2292
|
+
if (agent === void 0) {
|
|
2293
|
+
logger.break();
|
|
2294
|
+
process.exit(1);
|
|
2295
|
+
}
|
|
2296
|
+
const agentIntegration2 = agent;
|
|
2297
|
+
let agentsToRemove2 = [];
|
|
2298
|
+
if (projectInfo.installedAgents.length > 0) {
|
|
2299
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES2[innerAgent] || innerAgent).join(", ");
|
|
2300
|
+
const { action } = await prompts3__default.default({
|
|
2301
|
+
type: "select",
|
|
2302
|
+
name: "action",
|
|
2303
|
+
message: "How would you like to proceed?",
|
|
2304
|
+
choices: [
|
|
2305
|
+
{
|
|
2306
|
+
title: `Replace ${installedNames} with ${AGENT_NAMES2[agentIntegration2]}`,
|
|
2307
|
+
value: "replace"
|
|
2308
|
+
},
|
|
2309
|
+
{
|
|
2310
|
+
title: `Add ${AGENT_NAMES2[agentIntegration2]} alongside existing`,
|
|
2311
|
+
value: "add"
|
|
2312
|
+
},
|
|
2313
|
+
{ title: "Cancel", value: "cancel" }
|
|
2314
|
+
]
|
|
2315
|
+
});
|
|
2316
|
+
if (!action || action === "cancel") {
|
|
2317
|
+
logger.break();
|
|
2318
|
+
logger.log("Agent addition cancelled.");
|
|
2319
|
+
} else {
|
|
2320
|
+
if (action === "replace") {
|
|
2321
|
+
agentsToRemove2 = [...projectInfo.installedAgents];
|
|
2322
|
+
}
|
|
2323
|
+
if (agentsToRemove2.length > 0) {
|
|
2324
|
+
for (const agentToRemove of agentsToRemove2) {
|
|
2325
|
+
const removalResult = previewAgentRemoval(
|
|
2326
|
+
projectInfo.projectRoot,
|
|
2327
|
+
projectInfo.framework,
|
|
2328
|
+
projectInfo.nextRouterType,
|
|
2329
|
+
agentToRemove
|
|
2330
|
+
);
|
|
2331
|
+
const removalPackageJsonResult = previewPackageJsonAgentRemoval(
|
|
2332
|
+
projectInfo.projectRoot,
|
|
2333
|
+
agentToRemove
|
|
2334
|
+
);
|
|
2335
|
+
const packagesToRemove = getPackagesToUninstall(agentToRemove);
|
|
2336
|
+
if (packagesToRemove.length > 0) {
|
|
2337
|
+
const uninstallSpinner = spinner(
|
|
2338
|
+
`Removing ${packagesToRemove.join(", ")}.`
|
|
2339
|
+
).start();
|
|
2340
|
+
try {
|
|
2341
|
+
uninstallPackages(
|
|
2342
|
+
packagesToRemove,
|
|
2343
|
+
projectInfo.packageManager,
|
|
2344
|
+
projectInfo.projectRoot
|
|
2345
|
+
);
|
|
2346
|
+
uninstallSpinner.succeed();
|
|
2347
|
+
} catch (error) {
|
|
2348
|
+
uninstallSpinner.fail();
|
|
2349
|
+
handleError(error);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
if (removalResult.success && !removalResult.noChanges && removalResult.newContent) {
|
|
2353
|
+
const removeWriteSpinner = spinner(
|
|
2354
|
+
`Removing ${AGENT_NAMES2[agentToRemove] || agentToRemove} from ${removalResult.filePath}.`
|
|
2355
|
+
).start();
|
|
2356
|
+
const writeResult = applyTransform(removalResult);
|
|
2357
|
+
if (!writeResult.success) {
|
|
2358
|
+
removeWriteSpinner.fail();
|
|
2359
|
+
logger.break();
|
|
2360
|
+
logger.error(
|
|
2361
|
+
writeResult.error || "Failed to write file."
|
|
2362
|
+
);
|
|
2363
|
+
logger.break();
|
|
2364
|
+
process.exit(1);
|
|
2365
|
+
}
|
|
2366
|
+
removeWriteSpinner.succeed();
|
|
2367
|
+
}
|
|
2368
|
+
if (removalPackageJsonResult.success && !removalPackageJsonResult.noChanges && removalPackageJsonResult.newContent) {
|
|
2369
|
+
const removePackageJsonSpinner = spinner(
|
|
2370
|
+
`Removing ${AGENT_NAMES2[agentToRemove] || agentToRemove} from ${removalPackageJsonResult.filePath}.`
|
|
2371
|
+
).start();
|
|
2372
|
+
const packageJsonWriteResult = applyPackageJsonTransform(
|
|
2373
|
+
removalPackageJsonResult
|
|
2374
|
+
);
|
|
2375
|
+
if (!packageJsonWriteResult.success) {
|
|
2376
|
+
removePackageJsonSpinner.fail();
|
|
2377
|
+
logger.break();
|
|
2378
|
+
logger.error(
|
|
2379
|
+
packageJsonWriteResult.error || "Failed to write file."
|
|
2380
|
+
);
|
|
2381
|
+
logger.break();
|
|
2382
|
+
process.exit(1);
|
|
2383
|
+
}
|
|
2384
|
+
removePackageJsonSpinner.succeed();
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
projectInfo.installedAgents = projectInfo.installedAgents.filter(
|
|
2388
|
+
(innerAgent) => !agentsToRemove2.includes(innerAgent)
|
|
2389
|
+
);
|
|
2390
|
+
}
|
|
2391
|
+
const result2 = previewTransform(
|
|
2392
|
+
projectInfo.projectRoot,
|
|
2393
|
+
projectInfo.framework,
|
|
2394
|
+
projectInfo.nextRouterType,
|
|
2395
|
+
agentIntegration2,
|
|
2396
|
+
true
|
|
2397
|
+
);
|
|
2398
|
+
const packageJsonResult2 = previewPackageJsonTransform(
|
|
2399
|
+
projectInfo.projectRoot,
|
|
2400
|
+
agentIntegration2,
|
|
2401
|
+
projectInfo.installedAgents,
|
|
2402
|
+
projectInfo.packageManager
|
|
2403
|
+
);
|
|
2404
|
+
if (!result2.success) {
|
|
2405
|
+
logger.break();
|
|
2406
|
+
logger.error(result2.message);
|
|
2407
|
+
logger.break();
|
|
2408
|
+
process.exit(1);
|
|
2409
|
+
}
|
|
2410
|
+
const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
|
|
2411
|
+
const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
|
|
2412
|
+
if (hasLayoutChanges2 || hasPackageJsonChanges2) {
|
|
2413
|
+
logger.break();
|
|
2414
|
+
if (hasLayoutChanges2) {
|
|
2415
|
+
printDiff(
|
|
2416
|
+
result2.filePath,
|
|
2417
|
+
result2.originalContent,
|
|
2418
|
+
result2.newContent
|
|
2419
|
+
);
|
|
2420
|
+
}
|
|
2421
|
+
if (hasPackageJsonChanges2) {
|
|
2422
|
+
if (hasLayoutChanges2) {
|
|
2423
|
+
logger.break();
|
|
2424
|
+
}
|
|
2425
|
+
printDiff(
|
|
2426
|
+
packageJsonResult2.filePath,
|
|
2427
|
+
packageJsonResult2.originalContent,
|
|
2428
|
+
packageJsonResult2.newContent
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
if (agentsToRemove2.length === 0) {
|
|
2432
|
+
logger.break();
|
|
2433
|
+
const { proceed } = await prompts3__default.default({
|
|
2434
|
+
type: "confirm",
|
|
2435
|
+
name: "proceed",
|
|
2436
|
+
message: "Apply these changes?",
|
|
2437
|
+
initial: true
|
|
2438
|
+
});
|
|
2439
|
+
if (!proceed) {
|
|
2440
|
+
logger.break();
|
|
2441
|
+
logger.log("Agent addition cancelled.");
|
|
2442
|
+
} else {
|
|
2443
|
+
const packages = getPackagesToInstall(
|
|
2444
|
+
agentIntegration2,
|
|
2445
|
+
false
|
|
2446
|
+
);
|
|
2447
|
+
if (packages.length > 0) {
|
|
2448
|
+
const installSpinner = spinner(
|
|
2449
|
+
`Installing ${packages.join(", ")}.`
|
|
2450
|
+
).start();
|
|
2451
|
+
try {
|
|
2452
|
+
installPackages(
|
|
2453
|
+
packages,
|
|
2454
|
+
projectInfo.packageManager,
|
|
2455
|
+
projectInfo.projectRoot
|
|
2456
|
+
);
|
|
2457
|
+
installSpinner.succeed();
|
|
2458
|
+
} catch (error) {
|
|
2459
|
+
installSpinner.fail();
|
|
2460
|
+
handleError(error);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
if (hasLayoutChanges2) {
|
|
2464
|
+
const writeSpinner = spinner(
|
|
2465
|
+
`Applying changes to ${result2.filePath}.`
|
|
2466
|
+
).start();
|
|
2467
|
+
const writeResult = applyTransform(result2);
|
|
2468
|
+
if (!writeResult.success) {
|
|
2469
|
+
writeSpinner.fail();
|
|
2470
|
+
logger.break();
|
|
2471
|
+
logger.error(
|
|
2472
|
+
writeResult.error || "Failed to write file."
|
|
2473
|
+
);
|
|
2474
|
+
logger.break();
|
|
2475
|
+
process.exit(1);
|
|
2476
|
+
}
|
|
2477
|
+
writeSpinner.succeed();
|
|
2478
|
+
}
|
|
2479
|
+
if (hasPackageJsonChanges2) {
|
|
2480
|
+
const packageJsonSpinner = spinner(
|
|
2481
|
+
`Applying changes to ${packageJsonResult2.filePath}.`
|
|
2482
|
+
).start();
|
|
2483
|
+
const packageJsonWriteResult = applyPackageJsonTransform(packageJsonResult2);
|
|
2484
|
+
if (!packageJsonWriteResult.success) {
|
|
2485
|
+
packageJsonSpinner.fail();
|
|
2486
|
+
logger.break();
|
|
2487
|
+
logger.error(
|
|
2488
|
+
packageJsonWriteResult.error || "Failed to write file."
|
|
2489
|
+
);
|
|
2490
|
+
logger.break();
|
|
2491
|
+
process.exit(1);
|
|
2492
|
+
}
|
|
2493
|
+
packageJsonSpinner.succeed();
|
|
2494
|
+
}
|
|
2495
|
+
didAddAgent = true;
|
|
2496
|
+
logger.break();
|
|
2497
|
+
logger.success(
|
|
2498
|
+
`${AGENT_NAMES2[agentIntegration2]} has been added.`
|
|
2499
|
+
);
|
|
2500
|
+
}
|
|
2501
|
+
} else {
|
|
2502
|
+
const packages = getPackagesToInstall(
|
|
2503
|
+
agentIntegration2,
|
|
2504
|
+
false
|
|
2505
|
+
);
|
|
2506
|
+
if (packages.length > 0) {
|
|
2507
|
+
const installSpinner = spinner(
|
|
2508
|
+
`Installing ${packages.join(", ")}.`
|
|
2509
|
+
).start();
|
|
2510
|
+
try {
|
|
2511
|
+
installPackages(
|
|
2512
|
+
packages,
|
|
2513
|
+
projectInfo.packageManager,
|
|
2514
|
+
projectInfo.projectRoot
|
|
2515
|
+
);
|
|
2516
|
+
installSpinner.succeed();
|
|
2517
|
+
} catch (error) {
|
|
2518
|
+
installSpinner.fail();
|
|
2519
|
+
handleError(error);
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
if (hasLayoutChanges2) {
|
|
2523
|
+
const writeSpinner = spinner(
|
|
2524
|
+
`Applying changes to ${result2.filePath}.`
|
|
2525
|
+
).start();
|
|
2526
|
+
const writeResult = applyTransform(result2);
|
|
2527
|
+
if (!writeResult.success) {
|
|
2528
|
+
writeSpinner.fail();
|
|
2529
|
+
logger.break();
|
|
2530
|
+
logger.error(
|
|
2531
|
+
writeResult.error || "Failed to write file."
|
|
2532
|
+
);
|
|
2533
|
+
logger.break();
|
|
2534
|
+
process.exit(1);
|
|
2535
|
+
}
|
|
2536
|
+
writeSpinner.succeed();
|
|
2537
|
+
}
|
|
2538
|
+
if (hasPackageJsonChanges2) {
|
|
2539
|
+
const packageJsonSpinner = spinner(
|
|
2540
|
+
`Applying changes to ${packageJsonResult2.filePath}.`
|
|
2541
|
+
).start();
|
|
2542
|
+
const packageJsonWriteResult = applyPackageJsonTransform(packageJsonResult2);
|
|
2543
|
+
if (!packageJsonWriteResult.success) {
|
|
2544
|
+
packageJsonSpinner.fail();
|
|
2545
|
+
logger.break();
|
|
2546
|
+
logger.error(
|
|
2547
|
+
packageJsonWriteResult.error || "Failed to write file."
|
|
2548
|
+
);
|
|
2549
|
+
logger.break();
|
|
2550
|
+
process.exit(1);
|
|
2551
|
+
}
|
|
2552
|
+
packageJsonSpinner.succeed();
|
|
2553
|
+
}
|
|
2554
|
+
didAddAgent = true;
|
|
2555
|
+
logger.break();
|
|
2556
|
+
logger.success(
|
|
2557
|
+
`${AGENT_NAMES2[agentIntegration2]} has been added.`
|
|
2558
|
+
);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
} else {
|
|
2565
|
+
logger.log("All agent integrations are already installed.");
|
|
2566
|
+
}
|
|
2567
|
+
logger.break();
|
|
2568
|
+
const { wantCustomizeOptions } = await prompts3__default.default({
|
|
2569
|
+
type: "confirm",
|
|
2570
|
+
name: "wantCustomizeOptions",
|
|
2571
|
+
message: `Would you like to customize ${highlighter.info("options")}?`,
|
|
2572
|
+
initial: false
|
|
2573
|
+
});
|
|
2574
|
+
if (wantCustomizeOptions === void 0) {
|
|
2575
|
+
logger.break();
|
|
2576
|
+
process.exit(1);
|
|
2577
|
+
}
|
|
2578
|
+
if (wantCustomizeOptions) {
|
|
2579
|
+
logger.break();
|
|
2580
|
+
logger.log(`Configure ${highlighter.info("React Grab")} options:`);
|
|
2581
|
+
logger.break();
|
|
2582
|
+
const collectedOptions = {};
|
|
2583
|
+
const { wantActivationKey } = await prompts3__default.default({
|
|
2584
|
+
type: "confirm",
|
|
2585
|
+
name: "wantActivationKey",
|
|
2586
|
+
message: `Configure ${highlighter.info("activation key")}?`,
|
|
2587
|
+
initial: false
|
|
2588
|
+
});
|
|
2589
|
+
if (wantActivationKey === void 0) {
|
|
2590
|
+
logger.break();
|
|
2591
|
+
process.exit(1);
|
|
2592
|
+
}
|
|
2593
|
+
if (wantActivationKey) {
|
|
2594
|
+
const { key } = await prompts3__default.default({
|
|
2595
|
+
type: "text",
|
|
2596
|
+
name: "key",
|
|
2597
|
+
message: "Enter the activation key (e.g., g, k, space):",
|
|
2598
|
+
initial: ""
|
|
2599
|
+
});
|
|
2600
|
+
if (key === void 0) {
|
|
2601
|
+
logger.break();
|
|
2602
|
+
process.exit(1);
|
|
2603
|
+
}
|
|
2604
|
+
const { modifiers } = await prompts3__default.default({
|
|
2605
|
+
type: "multiselect",
|
|
2606
|
+
name: "modifiers",
|
|
2607
|
+
message: "Select modifier keys (space to select, enter to confirm):",
|
|
2608
|
+
choices: [
|
|
2609
|
+
{ title: MODIFIER_KEY_NAMES2.metaKey, value: "metaKey" },
|
|
2610
|
+
{ title: MODIFIER_KEY_NAMES2.ctrlKey, value: "ctrlKey" },
|
|
2611
|
+
{ title: MODIFIER_KEY_NAMES2.shiftKey, value: "shiftKey" },
|
|
2612
|
+
{
|
|
2613
|
+
title: MODIFIER_KEY_NAMES2.altKey,
|
|
2614
|
+
value: "altKey",
|
|
2615
|
+
selected: true
|
|
2616
|
+
}
|
|
2617
|
+
],
|
|
2618
|
+
hint: "- Space to select, Enter to confirm"
|
|
2619
|
+
});
|
|
2620
|
+
if (modifiers === void 0) {
|
|
2621
|
+
logger.break();
|
|
2622
|
+
process.exit(1);
|
|
2623
|
+
}
|
|
2624
|
+
collectedOptions.activationKey = {
|
|
2625
|
+
...key && { key: key.toLowerCase() },
|
|
2626
|
+
...modifiers.includes("metaKey") && { metaKey: true },
|
|
2627
|
+
...modifiers.includes("ctrlKey") && { ctrlKey: true },
|
|
2628
|
+
...modifiers.includes("shiftKey") && { shiftKey: true },
|
|
2629
|
+
...modifiers.includes("altKey") && { altKey: true }
|
|
2630
|
+
};
|
|
2631
|
+
logger.log(
|
|
2632
|
+
` Activation key: ${highlighter.info(formatActivationKey2(collectedOptions.activationKey))}`
|
|
2633
|
+
);
|
|
2634
|
+
}
|
|
2635
|
+
const { activationMode } = await prompts3__default.default({
|
|
2636
|
+
type: "select",
|
|
2637
|
+
name: "activationMode",
|
|
2638
|
+
message: `Select ${highlighter.info("activation mode")}:`,
|
|
2639
|
+
choices: [
|
|
2640
|
+
{
|
|
2641
|
+
title: "Toggle (press to activate/deactivate)",
|
|
2642
|
+
value: "toggle"
|
|
2643
|
+
},
|
|
2644
|
+
{ title: "Hold (hold key to keep active)", value: "hold" }
|
|
2645
|
+
],
|
|
2646
|
+
initial: 0
|
|
2647
|
+
});
|
|
2648
|
+
if (activationMode === void 0) {
|
|
2649
|
+
logger.break();
|
|
2650
|
+
process.exit(1);
|
|
2651
|
+
}
|
|
2652
|
+
collectedOptions.activationMode = activationMode;
|
|
2653
|
+
if (activationMode === "hold") {
|
|
2654
|
+
const { keyHoldDuration } = await prompts3__default.default({
|
|
2655
|
+
type: "number",
|
|
2656
|
+
name: "keyHoldDuration",
|
|
2657
|
+
message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
|
|
2658
|
+
initial: 150,
|
|
2659
|
+
min: 0,
|
|
2660
|
+
max: 2e3
|
|
2661
|
+
});
|
|
2662
|
+
if (keyHoldDuration === void 0) {
|
|
2663
|
+
logger.break();
|
|
2664
|
+
process.exit(1);
|
|
2665
|
+
}
|
|
2666
|
+
collectedOptions.keyHoldDuration = keyHoldDuration;
|
|
2667
|
+
}
|
|
2668
|
+
const { allowActivationInsideInput } = await prompts3__default.default({
|
|
2669
|
+
type: "confirm",
|
|
2670
|
+
name: "allowActivationInsideInput",
|
|
2671
|
+
message: `Allow activation ${highlighter.info("inside input fields")}?`,
|
|
2672
|
+
initial: true
|
|
2673
|
+
});
|
|
2674
|
+
if (allowActivationInsideInput === void 0) {
|
|
2675
|
+
logger.break();
|
|
2676
|
+
process.exit(1);
|
|
2677
|
+
}
|
|
2678
|
+
collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
|
|
2679
|
+
const { maxContextLines } = await prompts3__default.default({
|
|
2680
|
+
type: "number",
|
|
2681
|
+
name: "maxContextLines",
|
|
2682
|
+
message: `Enter ${highlighter.info("max context lines")} to include:`,
|
|
2683
|
+
initial: 3,
|
|
2684
|
+
min: 0,
|
|
2685
|
+
max: 50
|
|
2686
|
+
});
|
|
2687
|
+
if (maxContextLines === void 0) {
|
|
2688
|
+
logger.break();
|
|
2689
|
+
process.exit(1);
|
|
2690
|
+
}
|
|
2691
|
+
collectedOptions.maxContextLines = maxContextLines;
|
|
2692
|
+
const optionsResult = previewOptionsTransform(
|
|
2693
|
+
projectInfo.projectRoot,
|
|
2694
|
+
projectInfo.framework,
|
|
2695
|
+
projectInfo.nextRouterType,
|
|
2696
|
+
collectedOptions
|
|
2697
|
+
);
|
|
2698
|
+
if (!optionsResult.success) {
|
|
2699
|
+
logger.break();
|
|
2700
|
+
logger.error(optionsResult.message);
|
|
2701
|
+
logger.break();
|
|
2702
|
+
process.exit(1);
|
|
2703
|
+
}
|
|
2704
|
+
const hasOptionsChanges = !optionsResult.noChanges && optionsResult.originalContent && optionsResult.newContent;
|
|
2705
|
+
if (hasOptionsChanges) {
|
|
2706
|
+
logger.break();
|
|
2707
|
+
printDiff(
|
|
2708
|
+
optionsResult.filePath,
|
|
2709
|
+
optionsResult.originalContent,
|
|
2710
|
+
optionsResult.newContent
|
|
2711
|
+
);
|
|
2712
|
+
logger.break();
|
|
2713
|
+
const { proceed } = await prompts3__default.default({
|
|
2714
|
+
type: "confirm",
|
|
2715
|
+
name: "proceed",
|
|
2716
|
+
message: "Apply these changes?",
|
|
2717
|
+
initial: true
|
|
2718
|
+
});
|
|
2719
|
+
if (!proceed) {
|
|
2720
|
+
logger.break();
|
|
2721
|
+
logger.log("Options configuration cancelled.");
|
|
2722
|
+
} else {
|
|
2723
|
+
const writeSpinner = spinner(
|
|
2724
|
+
`Applying changes to ${optionsResult.filePath}.`
|
|
2725
|
+
).start();
|
|
2726
|
+
const writeResult = applyOptionsTransform(optionsResult);
|
|
2727
|
+
if (!writeResult.success) {
|
|
2728
|
+
writeSpinner.fail();
|
|
2729
|
+
logger.break();
|
|
2730
|
+
logger.error(writeResult.error || "Failed to write file.");
|
|
2731
|
+
logger.break();
|
|
2732
|
+
process.exit(1);
|
|
2733
|
+
}
|
|
2734
|
+
writeSpinner.succeed();
|
|
2735
|
+
logger.break();
|
|
2736
|
+
logger.success("React Grab options have been configured.");
|
|
2737
|
+
}
|
|
2738
|
+
} else {
|
|
2739
|
+
logger.break();
|
|
2740
|
+
logger.log("No option changes needed.");
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
if (!didAddAgent && !wantCustomizeOptions) {
|
|
2744
|
+
logger.break();
|
|
2745
|
+
logger.log("No changes made.");
|
|
2746
|
+
}
|
|
1845
2747
|
logger.break();
|
|
1846
2748
|
process.exit(0);
|
|
1847
2749
|
}
|
|
@@ -1876,7 +2778,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1876
2778
|
return 0;
|
|
1877
2779
|
}
|
|
1878
2780
|
);
|
|
1879
|
-
const { selectedProject } = await
|
|
2781
|
+
const { selectedProject } = await prompts3__default.default({
|
|
1880
2782
|
type: "select",
|
|
1881
2783
|
name: "selectedProject",
|
|
1882
2784
|
message: "Select a project to install React Grab:",
|
|
@@ -1937,9 +2839,15 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1937
2839
|
let finalPackageManager = projectInfo.packageManager;
|
|
1938
2840
|
let finalNextRouterType = projectInfo.nextRouterType;
|
|
1939
2841
|
let agentIntegration = opts.agent || "none";
|
|
2842
|
+
let agentsToRemove = [];
|
|
1940
2843
|
if (!isNonInteractive && !opts.agent) {
|
|
1941
2844
|
logger.break();
|
|
1942
|
-
|
|
2845
|
+
if (opts.force && projectInfo.installedAgents.length > 0) {
|
|
2846
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES2[innerAgent] || innerAgent).join(", ");
|
|
2847
|
+
logger.warn(`Currently installed: ${installedNames}`);
|
|
2848
|
+
logger.break();
|
|
2849
|
+
}
|
|
2850
|
+
const { agent } = await prompts3__default.default({
|
|
1943
2851
|
type: "select",
|
|
1944
2852
|
name: "agent",
|
|
1945
2853
|
message: `Would you like to add an ${highlighter.info("agent integration")}?`,
|
|
@@ -1959,6 +2867,63 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1959
2867
|
process.exit(1);
|
|
1960
2868
|
}
|
|
1961
2869
|
agentIntegration = agent;
|
|
2870
|
+
if (opts.force && projectInfo.installedAgents.length > 0 && agentIntegration !== "none" && !projectInfo.installedAgents.includes(agentIntegration)) {
|
|
2871
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES2[innerAgent] || innerAgent).join(", ");
|
|
2872
|
+
const { action } = await prompts3__default.default({
|
|
2873
|
+
type: "select",
|
|
2874
|
+
name: "action",
|
|
2875
|
+
message: "How would you like to proceed?",
|
|
2876
|
+
choices: [
|
|
2877
|
+
{
|
|
2878
|
+
title: `Replace ${installedNames} with ${AGENT_NAMES2[agentIntegration]}`,
|
|
2879
|
+
value: "replace"
|
|
2880
|
+
},
|
|
2881
|
+
{
|
|
2882
|
+
title: `Add ${AGENT_NAMES2[agentIntegration]} alongside existing`,
|
|
2883
|
+
value: "add"
|
|
2884
|
+
},
|
|
2885
|
+
{ title: "Cancel", value: "cancel" }
|
|
2886
|
+
]
|
|
2887
|
+
});
|
|
2888
|
+
if (!action || action === "cancel") {
|
|
2889
|
+
logger.break();
|
|
2890
|
+
logger.log("Changes cancelled.");
|
|
2891
|
+
logger.break();
|
|
2892
|
+
process.exit(0);
|
|
2893
|
+
}
|
|
2894
|
+
if (action === "replace") {
|
|
2895
|
+
agentsToRemove = [...projectInfo.installedAgents];
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
} else if (opts.agent && opts.force && projectInfo.installedAgents.length > 0 && !projectInfo.installedAgents.includes(opts.agent) && !isNonInteractive) {
|
|
2899
|
+
const installedNames = projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES2[innerAgent] || innerAgent).join(", ");
|
|
2900
|
+
logger.break();
|
|
2901
|
+
logger.warn(`Currently installed: ${installedNames}`);
|
|
2902
|
+
const { action } = await prompts3__default.default({
|
|
2903
|
+
type: "select",
|
|
2904
|
+
name: "action",
|
|
2905
|
+
message: "How would you like to proceed?",
|
|
2906
|
+
choices: [
|
|
2907
|
+
{
|
|
2908
|
+
title: `Replace ${installedNames} with ${AGENT_NAMES2[agentIntegration]}`,
|
|
2909
|
+
value: "replace"
|
|
2910
|
+
},
|
|
2911
|
+
{
|
|
2912
|
+
title: `Add ${AGENT_NAMES2[agentIntegration]} alongside existing`,
|
|
2913
|
+
value: "add"
|
|
2914
|
+
},
|
|
2915
|
+
{ title: "Cancel", value: "cancel" }
|
|
2916
|
+
]
|
|
2917
|
+
});
|
|
2918
|
+
if (!action || action === "cancel") {
|
|
2919
|
+
logger.break();
|
|
2920
|
+
logger.log("Changes cancelled.");
|
|
2921
|
+
logger.break();
|
|
2922
|
+
process.exit(0);
|
|
2923
|
+
}
|
|
2924
|
+
if (action === "replace") {
|
|
2925
|
+
agentsToRemove = [...projectInfo.installedAgents];
|
|
2926
|
+
}
|
|
1962
2927
|
}
|
|
1963
2928
|
const result = previewTransform(
|
|
1964
2929
|
projectInfo.projectRoot,
|
|
@@ -1970,7 +2935,8 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1970
2935
|
const packageJsonResult = previewPackageJsonTransform(
|
|
1971
2936
|
projectInfo.projectRoot,
|
|
1972
2937
|
agentIntegration,
|
|
1973
|
-
projectInfo.installedAgents
|
|
2938
|
+
projectInfo.installedAgents,
|
|
2939
|
+
finalPackageManager
|
|
1974
2940
|
);
|
|
1975
2941
|
if (!result.success) {
|
|
1976
2942
|
logger.break();
|
|
@@ -2005,7 +2971,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
2005
2971
|
logger.warn("Please verify the changes before committing.");
|
|
2006
2972
|
if (!isNonInteractive) {
|
|
2007
2973
|
logger.break();
|
|
2008
|
-
const { proceed } = await
|
|
2974
|
+
const { proceed } = await prompts3__default.default({
|
|
2009
2975
|
type: "confirm",
|
|
2010
2976
|
name: "proceed",
|
|
2011
2977
|
message: "Apply these changes?",
|
|
@@ -2019,6 +2985,72 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
2019
2985
|
}
|
|
2020
2986
|
}
|
|
2021
2987
|
}
|
|
2988
|
+
if (agentsToRemove.length > 0) {
|
|
2989
|
+
for (const agentToRemove of agentsToRemove) {
|
|
2990
|
+
const removalResult = previewAgentRemoval(
|
|
2991
|
+
projectInfo.projectRoot,
|
|
2992
|
+
projectInfo.framework,
|
|
2993
|
+
projectInfo.nextRouterType,
|
|
2994
|
+
agentToRemove
|
|
2995
|
+
);
|
|
2996
|
+
const removalPackageJsonResult = previewPackageJsonAgentRemoval(
|
|
2997
|
+
projectInfo.projectRoot,
|
|
2998
|
+
agentToRemove
|
|
2999
|
+
);
|
|
3000
|
+
const packagesToRemove = getPackagesToUninstall(agentToRemove);
|
|
3001
|
+
if (packagesToRemove.length > 0 && !opts.skipInstall) {
|
|
3002
|
+
const uninstallSpinner = spinner(
|
|
3003
|
+
`Removing ${packagesToRemove.join(", ")}.`
|
|
3004
|
+
).start();
|
|
3005
|
+
try {
|
|
3006
|
+
uninstallPackages(
|
|
3007
|
+
packagesToRemove,
|
|
3008
|
+
finalPackageManager,
|
|
3009
|
+
projectInfo.projectRoot
|
|
3010
|
+
);
|
|
3011
|
+
uninstallSpinner.succeed();
|
|
3012
|
+
} catch (error) {
|
|
3013
|
+
uninstallSpinner.fail();
|
|
3014
|
+
handleError(error);
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
if (removalResult.success && !removalResult.noChanges && removalResult.newContent) {
|
|
3018
|
+
const removeWriteSpinner = spinner(
|
|
3019
|
+
`Removing ${AGENT_NAMES2[agentToRemove] || agentToRemove} from ${removalResult.filePath}.`
|
|
3020
|
+
).start();
|
|
3021
|
+
const writeResult = applyTransform(removalResult);
|
|
3022
|
+
if (!writeResult.success) {
|
|
3023
|
+
removeWriteSpinner.fail();
|
|
3024
|
+
logger.break();
|
|
3025
|
+
logger.error(writeResult.error || "Failed to write file.");
|
|
3026
|
+
logger.break();
|
|
3027
|
+
process.exit(1);
|
|
3028
|
+
}
|
|
3029
|
+
removeWriteSpinner.succeed();
|
|
3030
|
+
}
|
|
3031
|
+
if (removalPackageJsonResult.success && !removalPackageJsonResult.noChanges && removalPackageJsonResult.newContent) {
|
|
3032
|
+
const removePackageJsonSpinner = spinner(
|
|
3033
|
+
`Removing ${AGENT_NAMES2[agentToRemove] || agentToRemove} from ${removalPackageJsonResult.filePath}.`
|
|
3034
|
+
).start();
|
|
3035
|
+
const packageJsonWriteResult = applyPackageJsonTransform(
|
|
3036
|
+
removalPackageJsonResult
|
|
3037
|
+
);
|
|
3038
|
+
if (!packageJsonWriteResult.success) {
|
|
3039
|
+
removePackageJsonSpinner.fail();
|
|
3040
|
+
logger.break();
|
|
3041
|
+
logger.error(
|
|
3042
|
+
packageJsonWriteResult.error || "Failed to write file."
|
|
3043
|
+
);
|
|
3044
|
+
logger.break();
|
|
3045
|
+
process.exit(1);
|
|
3046
|
+
}
|
|
3047
|
+
removePackageJsonSpinner.succeed();
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
projectInfo.installedAgents = projectInfo.installedAgents.filter(
|
|
3051
|
+
(innerAgent) => !agentsToRemove.includes(innerAgent)
|
|
3052
|
+
);
|
|
3053
|
+
}
|
|
2022
3054
|
const shouldInstallReactGrab = !projectInfo.hasReactGrab;
|
|
2023
3055
|
const shouldInstallAgent = agentIntegration !== "none" && !projectInfo.installedAgents.includes(agentIntegration);
|
|
2024
3056
|
if (!opts.skipInstall && (shouldInstallReactGrab || shouldInstallAgent)) {
|
|
@@ -2076,7 +3108,9 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
2076
3108
|
`${highlighter.success("Success!")} React Grab has been installed.`
|
|
2077
3109
|
);
|
|
2078
3110
|
if (packageJsonResult.warning) {
|
|
3111
|
+
logger.break();
|
|
2079
3112
|
logger.warn(packageJsonResult.warning);
|
|
3113
|
+
logger.break();
|
|
2080
3114
|
} else {
|
|
2081
3115
|
logger.log("You may now start your development server.");
|
|
2082
3116
|
}
|
|
@@ -2093,7 +3127,194 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
2093
3127
|
await reportToCli("error", void 0, error);
|
|
2094
3128
|
}
|
|
2095
3129
|
});
|
|
2096
|
-
var VERSION4 = "0.0.
|
|
3130
|
+
var VERSION4 = "0.0.92";
|
|
3131
|
+
var AGENT_NAMES3 = {
|
|
3132
|
+
"claude-code": "Claude Code",
|
|
3133
|
+
cursor: "Cursor",
|
|
3134
|
+
opencode: "OpenCode",
|
|
3135
|
+
codex: "Codex",
|
|
3136
|
+
gemini: "Gemini",
|
|
3137
|
+
amp: "Amp",
|
|
3138
|
+
ami: "Ami",
|
|
3139
|
+
"visual-edit": "Visual Edit"
|
|
3140
|
+
};
|
|
3141
|
+
var remove = new commander.Command().name("remove").description("remove an agent integration").argument(
|
|
3142
|
+
"[agent]",
|
|
3143
|
+
"agent to remove (claude-code, cursor, opencode, codex, gemini, amp, ami, visual-edit)"
|
|
3144
|
+
).option("-y, --yes", "skip confirmation prompts", false).option(
|
|
3145
|
+
"-c, --cwd <cwd>",
|
|
3146
|
+
"working directory (defaults to current directory)",
|
|
3147
|
+
process.cwd()
|
|
3148
|
+
).action(async (agentArg, opts) => {
|
|
3149
|
+
console.log(
|
|
3150
|
+
`${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION4)}`
|
|
3151
|
+
);
|
|
3152
|
+
console.log();
|
|
3153
|
+
try {
|
|
3154
|
+
const cwd = opts.cwd;
|
|
3155
|
+
const isNonInteractive = opts.yes;
|
|
3156
|
+
const preflightSpinner = spinner("Preflight checks.").start();
|
|
3157
|
+
const projectInfo = await detectProject(cwd);
|
|
3158
|
+
if (!projectInfo.hasReactGrab) {
|
|
3159
|
+
preflightSpinner.fail("React Grab is not installed.");
|
|
3160
|
+
logger.break();
|
|
3161
|
+
logger.error(
|
|
3162
|
+
`Run ${highlighter.info("react-grab init")} first to install React Grab.`
|
|
3163
|
+
);
|
|
3164
|
+
logger.break();
|
|
3165
|
+
process.exit(1);
|
|
3166
|
+
}
|
|
3167
|
+
if (projectInfo.installedAgents.length === 0) {
|
|
3168
|
+
preflightSpinner.succeed();
|
|
3169
|
+
logger.break();
|
|
3170
|
+
logger.warn("No agent integrations are installed.");
|
|
3171
|
+
logger.break();
|
|
3172
|
+
process.exit(0);
|
|
3173
|
+
}
|
|
3174
|
+
preflightSpinner.succeed();
|
|
3175
|
+
let agentToRemove;
|
|
3176
|
+
if (agentArg) {
|
|
3177
|
+
if (!projectInfo.installedAgents.includes(agentArg)) {
|
|
3178
|
+
logger.break();
|
|
3179
|
+
logger.error(`Agent ${highlighter.info(agentArg)} is not installed.`);
|
|
3180
|
+
logger.log(
|
|
3181
|
+
`Installed agents: ${projectInfo.installedAgents.map((innerAgent) => AGENT_NAMES3[innerAgent] || innerAgent).join(", ")}`
|
|
3182
|
+
);
|
|
3183
|
+
logger.break();
|
|
3184
|
+
process.exit(1);
|
|
3185
|
+
}
|
|
3186
|
+
agentToRemove = agentArg;
|
|
3187
|
+
} else if (!isNonInteractive) {
|
|
3188
|
+
logger.break();
|
|
3189
|
+
const { agent } = await prompts3__default.default({
|
|
3190
|
+
type: "select",
|
|
3191
|
+
name: "agent",
|
|
3192
|
+
message: `Which ${highlighter.info("agent integration")} would you like to remove?`,
|
|
3193
|
+
choices: projectInfo.installedAgents.map((innerAgent) => ({
|
|
3194
|
+
title: AGENT_NAMES3[innerAgent] || innerAgent,
|
|
3195
|
+
value: innerAgent
|
|
3196
|
+
}))
|
|
3197
|
+
});
|
|
3198
|
+
if (!agent) {
|
|
3199
|
+
logger.break();
|
|
3200
|
+
process.exit(1);
|
|
3201
|
+
}
|
|
3202
|
+
agentToRemove = agent;
|
|
3203
|
+
} else {
|
|
3204
|
+
logger.break();
|
|
3205
|
+
logger.error("Please specify an agent to remove.");
|
|
3206
|
+
logger.error(
|
|
3207
|
+
"Installed agents: " + projectInfo.installedAgents.join(", ")
|
|
3208
|
+
);
|
|
3209
|
+
logger.break();
|
|
3210
|
+
process.exit(1);
|
|
3211
|
+
}
|
|
3212
|
+
const removingSpinner = spinner(
|
|
3213
|
+
`Preparing to remove ${AGENT_NAMES3[agentToRemove] || agentToRemove}.`
|
|
3214
|
+
).start();
|
|
3215
|
+
removingSpinner.succeed();
|
|
3216
|
+
const result = previewAgentRemoval(
|
|
3217
|
+
projectInfo.projectRoot,
|
|
3218
|
+
projectInfo.framework,
|
|
3219
|
+
projectInfo.nextRouterType,
|
|
3220
|
+
agentToRemove
|
|
3221
|
+
);
|
|
3222
|
+
const packageJsonResult = previewPackageJsonAgentRemoval(
|
|
3223
|
+
projectInfo.projectRoot,
|
|
3224
|
+
agentToRemove
|
|
3225
|
+
);
|
|
3226
|
+
const hasLayoutChanges = result.success && !result.noChanges && result.originalContent && result.newContent;
|
|
3227
|
+
const hasPackageJsonChanges = packageJsonResult.success && !packageJsonResult.noChanges && packageJsonResult.originalContent && packageJsonResult.newContent;
|
|
3228
|
+
if (hasLayoutChanges || hasPackageJsonChanges) {
|
|
3229
|
+
logger.break();
|
|
3230
|
+
if (hasLayoutChanges) {
|
|
3231
|
+
printDiff(
|
|
3232
|
+
result.filePath,
|
|
3233
|
+
result.originalContent,
|
|
3234
|
+
result.newContent
|
|
3235
|
+
);
|
|
3236
|
+
}
|
|
3237
|
+
if (hasPackageJsonChanges) {
|
|
3238
|
+
if (hasLayoutChanges) {
|
|
3239
|
+
logger.break();
|
|
3240
|
+
}
|
|
3241
|
+
printDiff(
|
|
3242
|
+
packageJsonResult.filePath,
|
|
3243
|
+
packageJsonResult.originalContent,
|
|
3244
|
+
packageJsonResult.newContent
|
|
3245
|
+
);
|
|
3246
|
+
}
|
|
3247
|
+
if (!isNonInteractive) {
|
|
3248
|
+
logger.break();
|
|
3249
|
+
const { proceed } = await prompts3__default.default({
|
|
3250
|
+
type: "confirm",
|
|
3251
|
+
name: "proceed",
|
|
3252
|
+
message: "Apply these changes?",
|
|
3253
|
+
initial: true
|
|
3254
|
+
});
|
|
3255
|
+
if (!proceed) {
|
|
3256
|
+
logger.break();
|
|
3257
|
+
logger.log("Changes cancelled.");
|
|
3258
|
+
logger.break();
|
|
3259
|
+
process.exit(0);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
const packages = getPackagesToUninstall(agentToRemove);
|
|
3264
|
+
if (packages.length > 0) {
|
|
3265
|
+
const uninstallSpinner = spinner(
|
|
3266
|
+
`Removing ${packages.join(", ")}.`
|
|
3267
|
+
).start();
|
|
3268
|
+
try {
|
|
3269
|
+
uninstallPackages(
|
|
3270
|
+
packages,
|
|
3271
|
+
projectInfo.packageManager,
|
|
3272
|
+
projectInfo.projectRoot
|
|
3273
|
+
);
|
|
3274
|
+
uninstallSpinner.succeed();
|
|
3275
|
+
} catch (error) {
|
|
3276
|
+
uninstallSpinner.fail();
|
|
3277
|
+
handleError(error);
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
if (hasLayoutChanges) {
|
|
3281
|
+
const writeSpinner = spinner(
|
|
3282
|
+
`Applying changes to ${result.filePath}.`
|
|
3283
|
+
).start();
|
|
3284
|
+
const writeResult = applyTransform(result);
|
|
3285
|
+
if (!writeResult.success) {
|
|
3286
|
+
writeSpinner.fail();
|
|
3287
|
+
logger.break();
|
|
3288
|
+
logger.error(writeResult.error || "Failed to write file.");
|
|
3289
|
+
logger.break();
|
|
3290
|
+
process.exit(1);
|
|
3291
|
+
}
|
|
3292
|
+
writeSpinner.succeed();
|
|
3293
|
+
}
|
|
3294
|
+
if (hasPackageJsonChanges) {
|
|
3295
|
+
const packageJsonSpinner = spinner(
|
|
3296
|
+
`Applying changes to ${packageJsonResult.filePath}.`
|
|
3297
|
+
).start();
|
|
3298
|
+
const packageJsonWriteResult = applyPackageJsonTransform(packageJsonResult);
|
|
3299
|
+
if (!packageJsonWriteResult.success) {
|
|
3300
|
+
packageJsonSpinner.fail();
|
|
3301
|
+
logger.break();
|
|
3302
|
+
logger.error(packageJsonWriteResult.error || "Failed to write file.");
|
|
3303
|
+
logger.break();
|
|
3304
|
+
process.exit(1);
|
|
3305
|
+
}
|
|
3306
|
+
packageJsonSpinner.succeed();
|
|
3307
|
+
}
|
|
3308
|
+
logger.break();
|
|
3309
|
+
logger.log(
|
|
3310
|
+
`${highlighter.success("Success!")} ${AGENT_NAMES3[agentToRemove] || agentToRemove} has been removed.`
|
|
3311
|
+
);
|
|
3312
|
+
logger.break();
|
|
3313
|
+
} catch (error) {
|
|
3314
|
+
handleError(error);
|
|
3315
|
+
}
|
|
3316
|
+
});
|
|
3317
|
+
var VERSION5 = "0.0.92";
|
|
2097
3318
|
var DEFAULT_PROXY_PORT = 2e3;
|
|
2098
3319
|
var REACT_GRAB_SCRIPT = '<script src="https://unpkg.com/react-grab/dist/index.global.js"></script>';
|
|
2099
3320
|
var buildProviderScript = (provider) => `<script src="https://unpkg.com/${provider}/dist/client.global.js"></script>`;
|
|
@@ -2138,13 +3359,13 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
2138
3359
|
"provider package to run via npx (e.g., @react-grab/cursor)"
|
|
2139
3360
|
).action(async (urlArg, opts) => {
|
|
2140
3361
|
console.log(
|
|
2141
|
-
`${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(
|
|
3362
|
+
`${pc__default.default.magenta("\u273F")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION5)}`
|
|
2142
3363
|
);
|
|
2143
3364
|
console.log();
|
|
2144
3365
|
let url = urlArg;
|
|
2145
3366
|
let provider = opts.provider;
|
|
2146
3367
|
if (!url) {
|
|
2147
|
-
const { targetUrl: promptedUrl } = await
|
|
3368
|
+
const { targetUrl: promptedUrl } = await prompts3__default.default({
|
|
2148
3369
|
type: "text",
|
|
2149
3370
|
name: "targetUrl",
|
|
2150
3371
|
message: "Enter the target URL to proxy:",
|
|
@@ -2156,7 +3377,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
2156
3377
|
}
|
|
2157
3378
|
url = promptedUrl;
|
|
2158
3379
|
if (!provider) {
|
|
2159
|
-
const { selectedProvider } = await
|
|
3380
|
+
const { selectedProvider } = await prompts3__default.default({
|
|
2160
3381
|
type: "select",
|
|
2161
3382
|
name: "selectedProvider",
|
|
2162
3383
|
message: `Select a ${highlighter.info("provider")} to use:`,
|
|
@@ -2323,7 +3544,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
2323
3544
|
|
|
2324
3545
|
// src/cli.ts
|
|
2325
3546
|
process.noDeprecation = true;
|
|
2326
|
-
var
|
|
3547
|
+
var VERSION6 = "0.0.92";
|
|
2327
3548
|
var VERSION_API_URL = "https://www.react-grab.com/api/version";
|
|
2328
3549
|
process.on("SIGINT", () => process.exit(0));
|
|
2329
3550
|
process.on("SIGTERM", () => process.exit(0));
|
|
@@ -2332,9 +3553,10 @@ try {
|
|
|
2332
3553
|
});
|
|
2333
3554
|
} catch {
|
|
2334
3555
|
}
|
|
2335
|
-
var program = new commander.Command().name("react-grab").description("add React Grab to your project").version(
|
|
3556
|
+
var program = new commander.Command().name("react-grab").description("add React Grab to your project").version(VERSION6, "-v, --version", "display the version number");
|
|
2336
3557
|
program.addCommand(init);
|
|
2337
3558
|
program.addCommand(add);
|
|
3559
|
+
program.addCommand(remove);
|
|
2338
3560
|
program.addCommand(configure);
|
|
2339
3561
|
program.addCommand(start);
|
|
2340
3562
|
program.parse();
|