@react-grab/cli 0.0.83 → 0.0.84
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/README.md +17 -17
- package/dist/cli.cjs +122 -38
- package/dist/cli.js +122 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,16 +33,16 @@ npx @react-grab/cli -p pnpm -a claude-code -y
|
|
|
33
33
|
|
|
34
34
|
## Options
|
|
35
35
|
|
|
36
|
-
| Option
|
|
37
|
-
|
|
38
|
-
| `--framework`
|
|
39
|
-
| `--package-manager` | `-p`
|
|
40
|
-
| `--router`
|
|
41
|
-
| `--agent`
|
|
42
|
-
| `--yes`
|
|
43
|
-
| `--skip-install`
|
|
44
|
-
| `--help`
|
|
45
|
-
| `--version`
|
|
36
|
+
| Option | Alias | Description | Choices |
|
|
37
|
+
| ------------------- | ----- | --------------------------------------------- | --------------------------------------------------------------------- |
|
|
38
|
+
| `--framework` | `-f` | Framework to configure | `next`, `vite`, `webpack` |
|
|
39
|
+
| `--package-manager` | `-p` | Package manager to use | `npm`, `yarn`, `pnpm`, `bun` |
|
|
40
|
+
| `--router` | `-r` | Next.js router type | `app`, `pages` |
|
|
41
|
+
| `--agent` | `-a` | Agent integration to add | `claude-code`, `cursor`, `opencode`, `codex`, `gemini`, `amp`, `none` |
|
|
42
|
+
| `--yes` | `-y` | Skip all confirmation prompts | - |
|
|
43
|
+
| `--skip-install` | - | Skip package installation (only modify files) | - |
|
|
44
|
+
| `--help` | `-h` | Show help | - |
|
|
45
|
+
| `--version` | `-v` | Show version | - |
|
|
46
46
|
|
|
47
47
|
## Examples
|
|
48
48
|
|
|
@@ -68,12 +68,12 @@ npx @react-grab/cli -a cursor --skip-install -y
|
|
|
68
68
|
|
|
69
69
|
## Supported Frameworks
|
|
70
70
|
|
|
71
|
-
| Framework
|
|
72
|
-
|
|
73
|
-
| Next.js (App Router)
|
|
74
|
-
| Next.js (Pages Router) | `pages/_document.tsx`
|
|
75
|
-
| Vite
|
|
76
|
-
| Webpack
|
|
71
|
+
| Framework | File Modified |
|
|
72
|
+
| ---------------------- | --------------------------------- |
|
|
73
|
+
| Next.js (App Router) | `app/layout.tsx` |
|
|
74
|
+
| Next.js (Pages Router) | `pages/_document.tsx` |
|
|
75
|
+
| Vite | `index.html` |
|
|
76
|
+
| Webpack | `src/index.tsx` or `src/main.tsx` |
|
|
77
77
|
|
|
78
78
|
## Agent Integrations
|
|
79
79
|
|
|
@@ -81,7 +81,7 @@ The CLI can optionally set up agent integrations for:
|
|
|
81
81
|
|
|
82
82
|
- **Claude Code** (`-a claude-code`) - Send selected elements to Claude Code
|
|
83
83
|
- **Cursor** (`-a cursor`) - Send selected elements to Cursor
|
|
84
|
-
- **
|
|
84
|
+
- **OpenCode** (`-a opencode`) - Send selected elements to OpenCode
|
|
85
85
|
- **Codex** (`-a codex`) - Send selected elements to OpenAI Codex
|
|
86
86
|
- **Gemini** (`-a gemini`) - Send selected elements to Google Gemini CLI
|
|
87
87
|
- **Amp** (`-a amp`) - Send selected elements to Amp
|
package/dist/cli.cjs
CHANGED
|
@@ -156,7 +156,10 @@ var hasReactDependency = (projectPath) => {
|
|
|
156
156
|
if (!fs.existsSync(packageJsonPath)) return false;
|
|
157
157
|
try {
|
|
158
158
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
159
|
-
const allDeps = {
|
|
159
|
+
const allDeps = {
|
|
160
|
+
...packageJson.dependencies,
|
|
161
|
+
...packageJson.devDependencies
|
|
162
|
+
};
|
|
160
163
|
return Boolean(allDeps["react"] || allDeps["react-dom"]);
|
|
161
164
|
} catch {
|
|
162
165
|
return false;
|
|
@@ -174,7 +177,9 @@ var findWorkspaceProjects = (projectRoot) => {
|
|
|
174
177
|
const packageJsonPath = path.join(projectPath, "package.json");
|
|
175
178
|
let name = path.basename(projectPath);
|
|
176
179
|
try {
|
|
177
|
-
const packageJson = JSON.parse(
|
|
180
|
+
const packageJson = JSON.parse(
|
|
181
|
+
fs.readFileSync(packageJsonPath, "utf-8")
|
|
182
|
+
);
|
|
178
183
|
name = packageJson.name || name;
|
|
179
184
|
} catch {
|
|
180
185
|
}
|
|
@@ -242,7 +247,16 @@ var detectReactGrab = (projectRoot) => {
|
|
|
242
247
|
];
|
|
243
248
|
return filesToCheck.some(hasReactGrabInFile);
|
|
244
249
|
};
|
|
245
|
-
var AGENT_PACKAGES = [
|
|
250
|
+
var AGENT_PACKAGES = [
|
|
251
|
+
"@react-grab/claude-code",
|
|
252
|
+
"@react-grab/cursor",
|
|
253
|
+
"@react-grab/opencode",
|
|
254
|
+
"@react-grab/codex",
|
|
255
|
+
"@react-grab/gemini",
|
|
256
|
+
"@react-grab/amp",
|
|
257
|
+
"@react-grab/ami",
|
|
258
|
+
"@react-grab/instant"
|
|
259
|
+
];
|
|
246
260
|
var detectUnsupportedFramework = (projectRoot) => {
|
|
247
261
|
const packageJsonPath = path.join(projectRoot, "package.json");
|
|
248
262
|
if (!fs.existsSync(packageJsonPath)) {
|
|
@@ -282,9 +296,9 @@ var detectInstalledAgents = (projectRoot) => {
|
|
|
282
296
|
...packageJson.dependencies,
|
|
283
297
|
...packageJson.devDependencies
|
|
284
298
|
};
|
|
285
|
-
return AGENT_PACKAGES.filter(
|
|
286
|
-
(agent) => agent
|
|
287
|
-
);
|
|
299
|
+
return AGENT_PACKAGES.filter(
|
|
300
|
+
(agent) => Boolean(allDependencies[agent])
|
|
301
|
+
).map((agent) => agent.replace("@react-grab/", ""));
|
|
288
302
|
} catch {
|
|
289
303
|
return [];
|
|
290
304
|
}
|
|
@@ -321,7 +335,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
321
335
|
const originalLine = originalLines[originalIndex];
|
|
322
336
|
const newLine = newLines[newIndex];
|
|
323
337
|
if (originalLine === newLine) {
|
|
324
|
-
diff.push({
|
|
338
|
+
diff.push({
|
|
339
|
+
type: "unchanged",
|
|
340
|
+
content: originalLine,
|
|
341
|
+
lineNumber: newIndex + 1
|
|
342
|
+
});
|
|
325
343
|
originalIndex++;
|
|
326
344
|
newIndex++;
|
|
327
345
|
} else if (originalLine === void 0) {
|
|
@@ -335,7 +353,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
335
353
|
const newInOriginal = originalLines.indexOf(newLine, originalIndex);
|
|
336
354
|
if (originalInNew !== -1 && (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)) {
|
|
337
355
|
while (newIndex < originalInNew) {
|
|
338
|
-
diff.push({
|
|
356
|
+
diff.push({
|
|
357
|
+
type: "added",
|
|
358
|
+
content: newLines[newIndex],
|
|
359
|
+
lineNumber: newIndex + 1
|
|
360
|
+
});
|
|
339
361
|
newIndex++;
|
|
340
362
|
}
|
|
341
363
|
} else if (newInOriginal !== -1) {
|
|
@@ -345,7 +367,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
345
367
|
}
|
|
346
368
|
} else {
|
|
347
369
|
diff.push({ type: "removed", content: originalLine });
|
|
348
|
-
diff.push({
|
|
370
|
+
diff.push({
|
|
371
|
+
type: "added",
|
|
372
|
+
content: newLine,
|
|
373
|
+
lineNumber: newIndex + 1
|
|
374
|
+
});
|
|
349
375
|
originalIndex++;
|
|
350
376
|
newIndex++;
|
|
351
377
|
}
|
|
@@ -696,7 +722,9 @@ var addAgentToExistingVite = (originalContent, agent, filePath) => {
|
|
|
696
722
|
};
|
|
697
723
|
}
|
|
698
724
|
const agentImport = `import("${agentPackage}/client");`;
|
|
699
|
-
const reactGrabImportMatch = originalContent.match(
|
|
725
|
+
const reactGrabImportMatch = originalContent.match(
|
|
726
|
+
/import\s*\(\s*["']react-grab["']\s*\);?/
|
|
727
|
+
);
|
|
700
728
|
if (reactGrabImportMatch) {
|
|
701
729
|
const matchedText = reactGrabImportMatch[0];
|
|
702
730
|
const hasSemicolon = matchedText.endsWith(";");
|
|
@@ -738,7 +766,9 @@ var addAgentToExistingWebpack = (originalContent, agent, filePath) => {
|
|
|
738
766
|
};
|
|
739
767
|
}
|
|
740
768
|
const agentImport = `import("${agentPackage}/client");`;
|
|
741
|
-
const reactGrabImportMatch = originalContent.match(
|
|
769
|
+
const reactGrabImportMatch = originalContent.match(
|
|
770
|
+
/import\s*\(\s*["']react-grab["']\s*\);?/
|
|
771
|
+
);
|
|
742
772
|
if (reactGrabImportMatch) {
|
|
743
773
|
const matchedText = reactGrabImportMatch[0];
|
|
744
774
|
const hasSemicolon = matchedText.endsWith(";");
|
|
@@ -788,8 +818,11 @@ var transformNextAppRouter = (projectRoot, agent, reactGrabAlreadyConfigured) =>
|
|
|
788
818
|
if (!newContent.includes('import Script from "next/script"')) {
|
|
789
819
|
const importMatch = newContent.match(/^import .+ from ['"].+['"];?\s*$/m);
|
|
790
820
|
if (importMatch) {
|
|
791
|
-
newContent = newContent.replace(
|
|
792
|
-
|
|
821
|
+
newContent = newContent.replace(
|
|
822
|
+
importMatch[0],
|
|
823
|
+
`${importMatch[0]}
|
|
824
|
+
${SCRIPT_IMPORT}`
|
|
825
|
+
);
|
|
793
826
|
} else {
|
|
794
827
|
newContent = `${SCRIPT_IMPORT}
|
|
795
828
|
|
|
@@ -799,8 +832,11 @@ ${newContent}`;
|
|
|
799
832
|
const scriptBlock = NEXT_APP_ROUTER_SCRIPT_WITH_AGENT(agent);
|
|
800
833
|
const headMatch = newContent.match(/<head[^>]*>/);
|
|
801
834
|
if (headMatch) {
|
|
802
|
-
newContent = newContent.replace(
|
|
803
|
-
|
|
835
|
+
newContent = newContent.replace(
|
|
836
|
+
headMatch[0],
|
|
837
|
+
`${headMatch[0]}
|
|
838
|
+
${scriptBlock}`
|
|
839
|
+
);
|
|
804
840
|
} else {
|
|
805
841
|
const htmlMatch = newContent.match(/<html[^>]*>/);
|
|
806
842
|
if (htmlMatch) {
|
|
@@ -848,15 +884,21 @@ var transformNextPagesRouter = (projectRoot, agent, reactGrabAlreadyConfigured)
|
|
|
848
884
|
if (!newContent.includes('import Script from "next/script"')) {
|
|
849
885
|
const importMatch = newContent.match(/^import .+ from ['"].+['"];?\s*$/m);
|
|
850
886
|
if (importMatch) {
|
|
851
|
-
newContent = newContent.replace(
|
|
852
|
-
|
|
887
|
+
newContent = newContent.replace(
|
|
888
|
+
importMatch[0],
|
|
889
|
+
`${importMatch[0]}
|
|
890
|
+
${SCRIPT_IMPORT}`
|
|
891
|
+
);
|
|
853
892
|
}
|
|
854
893
|
}
|
|
855
894
|
const scriptBlock = NEXT_PAGES_ROUTER_SCRIPT_WITH_AGENT(agent);
|
|
856
895
|
const headMatch = newContent.match(/<Head[^>]*>/);
|
|
857
896
|
if (headMatch) {
|
|
858
|
-
newContent = newContent.replace(
|
|
859
|
-
|
|
897
|
+
newContent = newContent.replace(
|
|
898
|
+
headMatch[0],
|
|
899
|
+
`${headMatch[0]}
|
|
900
|
+
${scriptBlock}`
|
|
901
|
+
);
|
|
860
902
|
}
|
|
861
903
|
return {
|
|
862
904
|
success: true,
|
|
@@ -892,8 +934,11 @@ var transformVite = (projectRoot, agent, reactGrabAlreadyConfigured) => {
|
|
|
892
934
|
const scriptBlock = VITE_SCRIPT_WITH_AGENT(agent);
|
|
893
935
|
const headMatch = newContent.match(/<head[^>]*>/i);
|
|
894
936
|
if (headMatch) {
|
|
895
|
-
newContent = newContent.replace(
|
|
896
|
-
|
|
937
|
+
newContent = newContent.replace(
|
|
938
|
+
headMatch[0],
|
|
939
|
+
`${headMatch[0]}
|
|
940
|
+
${scriptBlock}`
|
|
941
|
+
);
|
|
897
942
|
}
|
|
898
943
|
return {
|
|
899
944
|
success: true,
|
|
@@ -941,9 +986,17 @@ var previewTransform = (projectRoot, framework, nextRouterType, agent, reactGrab
|
|
|
941
986
|
switch (framework) {
|
|
942
987
|
case "next":
|
|
943
988
|
if (nextRouterType === "app") {
|
|
944
|
-
return transformNextAppRouter(
|
|
989
|
+
return transformNextAppRouter(
|
|
990
|
+
projectRoot,
|
|
991
|
+
agent,
|
|
992
|
+
reactGrabAlreadyConfigured
|
|
993
|
+
);
|
|
945
994
|
}
|
|
946
|
-
return transformNextPagesRouter(
|
|
995
|
+
return transformNextPagesRouter(
|
|
996
|
+
projectRoot,
|
|
997
|
+
agent,
|
|
998
|
+
reactGrabAlreadyConfigured
|
|
999
|
+
);
|
|
947
1000
|
case "vite":
|
|
948
1001
|
return transformVite(projectRoot, agent, reactGrabAlreadyConfigured);
|
|
949
1002
|
case "webpack":
|
|
@@ -1086,23 +1139,28 @@ var applyPackageJsonTransform = (result) => {
|
|
|
1086
1139
|
};
|
|
1087
1140
|
|
|
1088
1141
|
// src/commands/add.ts
|
|
1089
|
-
var VERSION = "0.0.
|
|
1142
|
+
var VERSION = "0.0.84";
|
|
1090
1143
|
var AGENT_NAMES = {
|
|
1091
1144
|
"claude-code": "Claude Code",
|
|
1092
1145
|
cursor: "Cursor",
|
|
1093
|
-
opencode: "
|
|
1146
|
+
opencode: "OpenCode",
|
|
1094
1147
|
codex: "Codex",
|
|
1095
1148
|
gemini: "Gemini",
|
|
1096
1149
|
amp: "Amp",
|
|
1097
1150
|
ami: "Ami",
|
|
1098
1151
|
instant: "Instant"
|
|
1099
1152
|
};
|
|
1100
|
-
var add = new commander.Command().name("add").description("add an agent integration").argument(
|
|
1153
|
+
var add = new commander.Command().name("add").description("add an agent integration").argument(
|
|
1154
|
+
"[agent]",
|
|
1155
|
+
"agent to add (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
|
|
1156
|
+
).option("-y, --yes", "skip confirmation prompts", false).option(
|
|
1101
1157
|
"-c, --cwd <cwd>",
|
|
1102
1158
|
"working directory (defaults to current directory)",
|
|
1103
1159
|
process.cwd()
|
|
1104
1160
|
).action(async (agentArg, opts) => {
|
|
1105
|
-
console.log(
|
|
1161
|
+
console.log(
|
|
1162
|
+
`${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION)}`
|
|
1163
|
+
);
|
|
1106
1164
|
console.log();
|
|
1107
1165
|
try {
|
|
1108
1166
|
const cwd = opts.cwd;
|
|
@@ -1119,7 +1177,16 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1119
1177
|
process.exit(1);
|
|
1120
1178
|
}
|
|
1121
1179
|
preflightSpinner.succeed();
|
|
1122
|
-
const availableAgents = [
|
|
1180
|
+
const availableAgents = [
|
|
1181
|
+
"claude-code",
|
|
1182
|
+
"cursor",
|
|
1183
|
+
"opencode",
|
|
1184
|
+
"codex",
|
|
1185
|
+
"gemini",
|
|
1186
|
+
"amp",
|
|
1187
|
+
"ami",
|
|
1188
|
+
"instant"
|
|
1189
|
+
].filter((agent) => !projectInfo.installedAgents.includes(agent));
|
|
1123
1190
|
if (availableAgents.length === 0) {
|
|
1124
1191
|
logger.break();
|
|
1125
1192
|
logger.success("All agent integrations are already installed.");
|
|
@@ -1128,10 +1195,21 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1128
1195
|
}
|
|
1129
1196
|
let agentIntegration;
|
|
1130
1197
|
if (agentArg) {
|
|
1131
|
-
if (![
|
|
1198
|
+
if (![
|
|
1199
|
+
"claude-code",
|
|
1200
|
+
"cursor",
|
|
1201
|
+
"opencode",
|
|
1202
|
+
"codex",
|
|
1203
|
+
"gemini",
|
|
1204
|
+
"amp",
|
|
1205
|
+
"ami",
|
|
1206
|
+
"instant"
|
|
1207
|
+
].includes(agentArg)) {
|
|
1132
1208
|
logger.break();
|
|
1133
1209
|
logger.error(`Invalid agent: ${agentArg}`);
|
|
1134
|
-
logger.error(
|
|
1210
|
+
logger.error(
|
|
1211
|
+
"Available agents: claude-code, cursor, opencode, codex, gemini, amp, ami, instant"
|
|
1212
|
+
);
|
|
1135
1213
|
logger.break();
|
|
1136
1214
|
process.exit(1);
|
|
1137
1215
|
}
|
|
@@ -1279,7 +1357,7 @@ var add = new commander.Command().name("add").description("add an agent integrat
|
|
|
1279
1357
|
handleError(error);
|
|
1280
1358
|
}
|
|
1281
1359
|
});
|
|
1282
|
-
var VERSION2 = "0.0.
|
|
1360
|
+
var VERSION2 = "0.0.84";
|
|
1283
1361
|
var REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
1284
1362
|
var DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
1285
1363
|
var reportToCli = async (type, config, error) => {
|
|
@@ -1325,7 +1403,9 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1325
1403
|
"working directory (defaults to current directory)",
|
|
1326
1404
|
process.cwd()
|
|
1327
1405
|
).action(async (opts) => {
|
|
1328
|
-
console.log(
|
|
1406
|
+
console.log(
|
|
1407
|
+
`${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION2)}`
|
|
1408
|
+
);
|
|
1329
1409
|
console.log();
|
|
1330
1410
|
try {
|
|
1331
1411
|
const cwd = opts.cwd;
|
|
@@ -1444,7 +1524,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1444
1524
|
{ title: "None", value: "none" },
|
|
1445
1525
|
{ title: "Claude Code", value: "claude-code" },
|
|
1446
1526
|
{ title: "Cursor", value: "cursor" },
|
|
1447
|
-
{ title: "
|
|
1527
|
+
{ title: "OpenCode", value: "opencode" },
|
|
1448
1528
|
{ title: "Codex", value: "codex" },
|
|
1449
1529
|
{ title: "Gemini", value: "gemini" },
|
|
1450
1530
|
{ title: "Amp", value: "amp" },
|
|
@@ -1587,7 +1667,7 @@ var init = new commander.Command().name("init").description("initialize React Gr
|
|
|
1587
1667
|
await reportToCli("error", void 0, error);
|
|
1588
1668
|
}
|
|
1589
1669
|
});
|
|
1590
|
-
var VERSION3 = "0.0.
|
|
1670
|
+
var VERSION3 = "0.0.84";
|
|
1591
1671
|
var DEFAULT_PROXY_PORT = 2e3;
|
|
1592
1672
|
var REACT_GRAB_SCRIPT = '<script src="//unpkg.com/react-grab/dist/index.global.js"></script>';
|
|
1593
1673
|
var buildProviderScript = (provider) => `<script src="//unpkg.com/${provider}/dist/client.global.js"></script>`;
|
|
@@ -1631,7 +1711,9 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
1631
1711
|
"--provider <package>",
|
|
1632
1712
|
"provider package to run via npx (e.g., @react-grab/cursor)"
|
|
1633
1713
|
).action(async (urlArg, opts) => {
|
|
1634
|
-
console.log(
|
|
1714
|
+
console.log(
|
|
1715
|
+
`${pc__default.default.magenta("\u269B")} ${pc__default.default.bold("React Grab")} ${pc__default.default.gray(VERSION3)}`
|
|
1716
|
+
);
|
|
1635
1717
|
console.log();
|
|
1636
1718
|
let url = urlArg;
|
|
1637
1719
|
let provider = opts.provider;
|
|
@@ -1656,7 +1738,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
1656
1738
|
{ title: "None", value: "" },
|
|
1657
1739
|
{ title: "Claude Code", value: "@react-grab/claude-code" },
|
|
1658
1740
|
{ title: "Cursor", value: "@react-grab/cursor" },
|
|
1659
|
-
{ title: "
|
|
1741
|
+
{ title: "OpenCode", value: "@react-grab/opencode" },
|
|
1660
1742
|
{ title: "Codex", value: "@react-grab/codex" },
|
|
1661
1743
|
{ title: "Gemini", value: "@react-grab/gemini" },
|
|
1662
1744
|
{ title: "Amp", value: "@react-grab/amp" },
|
|
@@ -1741,7 +1823,9 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
1741
1823
|
server.on("upgrade", proxyMiddleware.upgrade);
|
|
1742
1824
|
const startSpinner = spinner("Starting.").start();
|
|
1743
1825
|
const showSuccess = () => {
|
|
1744
|
-
startSpinner.succeed(
|
|
1826
|
+
startSpinner.succeed(
|
|
1827
|
+
`Open in your browser: http://${hostname}:${proxyPort}`
|
|
1828
|
+
);
|
|
1745
1829
|
const commandParts = ["npx react-grab@latest start", url];
|
|
1746
1830
|
if (opts.port !== String(DEFAULT_PROXY_PORT)) {
|
|
1747
1831
|
commandParts.push(`--port=${opts.port}`);
|
|
@@ -1808,7 +1892,7 @@ var start = new commander.Command().name("start").alias("proxy").description("st
|
|
|
1808
1892
|
});
|
|
1809
1893
|
|
|
1810
1894
|
// src/cli.ts
|
|
1811
|
-
var VERSION4 = "0.0.
|
|
1895
|
+
var VERSION4 = "0.0.84";
|
|
1812
1896
|
var VERSION_API_URL = "https://react-grab.com/api/version";
|
|
1813
1897
|
process.on("SIGINT", () => process.exit(0));
|
|
1814
1898
|
process.on("SIGTERM", () => process.exit(0));
|
package/dist/cli.js
CHANGED
|
@@ -148,7 +148,10 @@ var hasReactDependency = (projectPath) => {
|
|
|
148
148
|
if (!existsSync(packageJsonPath)) return false;
|
|
149
149
|
try {
|
|
150
150
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
151
|
-
const allDeps = {
|
|
151
|
+
const allDeps = {
|
|
152
|
+
...packageJson.dependencies,
|
|
153
|
+
...packageJson.devDependencies
|
|
154
|
+
};
|
|
152
155
|
return Boolean(allDeps["react"] || allDeps["react-dom"]);
|
|
153
156
|
} catch {
|
|
154
157
|
return false;
|
|
@@ -166,7 +169,9 @@ var findWorkspaceProjects = (projectRoot) => {
|
|
|
166
169
|
const packageJsonPath = join(projectPath, "package.json");
|
|
167
170
|
let name = basename(projectPath);
|
|
168
171
|
try {
|
|
169
|
-
const packageJson = JSON.parse(
|
|
172
|
+
const packageJson = JSON.parse(
|
|
173
|
+
readFileSync(packageJsonPath, "utf-8")
|
|
174
|
+
);
|
|
170
175
|
name = packageJson.name || name;
|
|
171
176
|
} catch {
|
|
172
177
|
}
|
|
@@ -234,7 +239,16 @@ var detectReactGrab = (projectRoot) => {
|
|
|
234
239
|
];
|
|
235
240
|
return filesToCheck.some(hasReactGrabInFile);
|
|
236
241
|
};
|
|
237
|
-
var AGENT_PACKAGES = [
|
|
242
|
+
var AGENT_PACKAGES = [
|
|
243
|
+
"@react-grab/claude-code",
|
|
244
|
+
"@react-grab/cursor",
|
|
245
|
+
"@react-grab/opencode",
|
|
246
|
+
"@react-grab/codex",
|
|
247
|
+
"@react-grab/gemini",
|
|
248
|
+
"@react-grab/amp",
|
|
249
|
+
"@react-grab/ami",
|
|
250
|
+
"@react-grab/instant"
|
|
251
|
+
];
|
|
238
252
|
var detectUnsupportedFramework = (projectRoot) => {
|
|
239
253
|
const packageJsonPath = join(projectRoot, "package.json");
|
|
240
254
|
if (!existsSync(packageJsonPath)) {
|
|
@@ -274,9 +288,9 @@ var detectInstalledAgents = (projectRoot) => {
|
|
|
274
288
|
...packageJson.dependencies,
|
|
275
289
|
...packageJson.devDependencies
|
|
276
290
|
};
|
|
277
|
-
return AGENT_PACKAGES.filter(
|
|
278
|
-
(agent) => agent
|
|
279
|
-
);
|
|
291
|
+
return AGENT_PACKAGES.filter(
|
|
292
|
+
(agent) => Boolean(allDependencies[agent])
|
|
293
|
+
).map((agent) => agent.replace("@react-grab/", ""));
|
|
280
294
|
} catch {
|
|
281
295
|
return [];
|
|
282
296
|
}
|
|
@@ -313,7 +327,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
313
327
|
const originalLine = originalLines[originalIndex];
|
|
314
328
|
const newLine = newLines[newIndex];
|
|
315
329
|
if (originalLine === newLine) {
|
|
316
|
-
diff.push({
|
|
330
|
+
diff.push({
|
|
331
|
+
type: "unchanged",
|
|
332
|
+
content: originalLine,
|
|
333
|
+
lineNumber: newIndex + 1
|
|
334
|
+
});
|
|
317
335
|
originalIndex++;
|
|
318
336
|
newIndex++;
|
|
319
337
|
} else if (originalLine === void 0) {
|
|
@@ -327,7 +345,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
327
345
|
const newInOriginal = originalLines.indexOf(newLine, originalIndex);
|
|
328
346
|
if (originalInNew !== -1 && (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)) {
|
|
329
347
|
while (newIndex < originalInNew) {
|
|
330
|
-
diff.push({
|
|
348
|
+
diff.push({
|
|
349
|
+
type: "added",
|
|
350
|
+
content: newLines[newIndex],
|
|
351
|
+
lineNumber: newIndex + 1
|
|
352
|
+
});
|
|
331
353
|
newIndex++;
|
|
332
354
|
}
|
|
333
355
|
} else if (newInOriginal !== -1) {
|
|
@@ -337,7 +359,11 @@ var generateDiff = (originalContent, newContent) => {
|
|
|
337
359
|
}
|
|
338
360
|
} else {
|
|
339
361
|
diff.push({ type: "removed", content: originalLine });
|
|
340
|
-
diff.push({
|
|
362
|
+
diff.push({
|
|
363
|
+
type: "added",
|
|
364
|
+
content: newLine,
|
|
365
|
+
lineNumber: newIndex + 1
|
|
366
|
+
});
|
|
341
367
|
originalIndex++;
|
|
342
368
|
newIndex++;
|
|
343
369
|
}
|
|
@@ -688,7 +714,9 @@ var addAgentToExistingVite = (originalContent, agent, filePath) => {
|
|
|
688
714
|
};
|
|
689
715
|
}
|
|
690
716
|
const agentImport = `import("${agentPackage}/client");`;
|
|
691
|
-
const reactGrabImportMatch = originalContent.match(
|
|
717
|
+
const reactGrabImportMatch = originalContent.match(
|
|
718
|
+
/import\s*\(\s*["']react-grab["']\s*\);?/
|
|
719
|
+
);
|
|
692
720
|
if (reactGrabImportMatch) {
|
|
693
721
|
const matchedText = reactGrabImportMatch[0];
|
|
694
722
|
const hasSemicolon = matchedText.endsWith(";");
|
|
@@ -730,7 +758,9 @@ var addAgentToExistingWebpack = (originalContent, agent, filePath) => {
|
|
|
730
758
|
};
|
|
731
759
|
}
|
|
732
760
|
const agentImport = `import("${agentPackage}/client");`;
|
|
733
|
-
const reactGrabImportMatch = originalContent.match(
|
|
761
|
+
const reactGrabImportMatch = originalContent.match(
|
|
762
|
+
/import\s*\(\s*["']react-grab["']\s*\);?/
|
|
763
|
+
);
|
|
734
764
|
if (reactGrabImportMatch) {
|
|
735
765
|
const matchedText = reactGrabImportMatch[0];
|
|
736
766
|
const hasSemicolon = matchedText.endsWith(";");
|
|
@@ -780,8 +810,11 @@ var transformNextAppRouter = (projectRoot, agent, reactGrabAlreadyConfigured) =>
|
|
|
780
810
|
if (!newContent.includes('import Script from "next/script"')) {
|
|
781
811
|
const importMatch = newContent.match(/^import .+ from ['"].+['"];?\s*$/m);
|
|
782
812
|
if (importMatch) {
|
|
783
|
-
newContent = newContent.replace(
|
|
784
|
-
|
|
813
|
+
newContent = newContent.replace(
|
|
814
|
+
importMatch[0],
|
|
815
|
+
`${importMatch[0]}
|
|
816
|
+
${SCRIPT_IMPORT}`
|
|
817
|
+
);
|
|
785
818
|
} else {
|
|
786
819
|
newContent = `${SCRIPT_IMPORT}
|
|
787
820
|
|
|
@@ -791,8 +824,11 @@ ${newContent}`;
|
|
|
791
824
|
const scriptBlock = NEXT_APP_ROUTER_SCRIPT_WITH_AGENT(agent);
|
|
792
825
|
const headMatch = newContent.match(/<head[^>]*>/);
|
|
793
826
|
if (headMatch) {
|
|
794
|
-
newContent = newContent.replace(
|
|
795
|
-
|
|
827
|
+
newContent = newContent.replace(
|
|
828
|
+
headMatch[0],
|
|
829
|
+
`${headMatch[0]}
|
|
830
|
+
${scriptBlock}`
|
|
831
|
+
);
|
|
796
832
|
} else {
|
|
797
833
|
const htmlMatch = newContent.match(/<html[^>]*>/);
|
|
798
834
|
if (htmlMatch) {
|
|
@@ -840,15 +876,21 @@ var transformNextPagesRouter = (projectRoot, agent, reactGrabAlreadyConfigured)
|
|
|
840
876
|
if (!newContent.includes('import Script from "next/script"')) {
|
|
841
877
|
const importMatch = newContent.match(/^import .+ from ['"].+['"];?\s*$/m);
|
|
842
878
|
if (importMatch) {
|
|
843
|
-
newContent = newContent.replace(
|
|
844
|
-
|
|
879
|
+
newContent = newContent.replace(
|
|
880
|
+
importMatch[0],
|
|
881
|
+
`${importMatch[0]}
|
|
882
|
+
${SCRIPT_IMPORT}`
|
|
883
|
+
);
|
|
845
884
|
}
|
|
846
885
|
}
|
|
847
886
|
const scriptBlock = NEXT_PAGES_ROUTER_SCRIPT_WITH_AGENT(agent);
|
|
848
887
|
const headMatch = newContent.match(/<Head[^>]*>/);
|
|
849
888
|
if (headMatch) {
|
|
850
|
-
newContent = newContent.replace(
|
|
851
|
-
|
|
889
|
+
newContent = newContent.replace(
|
|
890
|
+
headMatch[0],
|
|
891
|
+
`${headMatch[0]}
|
|
892
|
+
${scriptBlock}`
|
|
893
|
+
);
|
|
852
894
|
}
|
|
853
895
|
return {
|
|
854
896
|
success: true,
|
|
@@ -884,8 +926,11 @@ var transformVite = (projectRoot, agent, reactGrabAlreadyConfigured) => {
|
|
|
884
926
|
const scriptBlock = VITE_SCRIPT_WITH_AGENT(agent);
|
|
885
927
|
const headMatch = newContent.match(/<head[^>]*>/i);
|
|
886
928
|
if (headMatch) {
|
|
887
|
-
newContent = newContent.replace(
|
|
888
|
-
|
|
929
|
+
newContent = newContent.replace(
|
|
930
|
+
headMatch[0],
|
|
931
|
+
`${headMatch[0]}
|
|
932
|
+
${scriptBlock}`
|
|
933
|
+
);
|
|
889
934
|
}
|
|
890
935
|
return {
|
|
891
936
|
success: true,
|
|
@@ -933,9 +978,17 @@ var previewTransform = (projectRoot, framework, nextRouterType, agent, reactGrab
|
|
|
933
978
|
switch (framework) {
|
|
934
979
|
case "next":
|
|
935
980
|
if (nextRouterType === "app") {
|
|
936
|
-
return transformNextAppRouter(
|
|
981
|
+
return transformNextAppRouter(
|
|
982
|
+
projectRoot,
|
|
983
|
+
agent,
|
|
984
|
+
reactGrabAlreadyConfigured
|
|
985
|
+
);
|
|
937
986
|
}
|
|
938
|
-
return transformNextPagesRouter(
|
|
987
|
+
return transformNextPagesRouter(
|
|
988
|
+
projectRoot,
|
|
989
|
+
agent,
|
|
990
|
+
reactGrabAlreadyConfigured
|
|
991
|
+
);
|
|
939
992
|
case "vite":
|
|
940
993
|
return transformVite(projectRoot, agent, reactGrabAlreadyConfigured);
|
|
941
994
|
case "webpack":
|
|
@@ -1078,23 +1131,28 @@ var applyPackageJsonTransform = (result) => {
|
|
|
1078
1131
|
};
|
|
1079
1132
|
|
|
1080
1133
|
// src/commands/add.ts
|
|
1081
|
-
var VERSION = "0.0.
|
|
1134
|
+
var VERSION = "0.0.84";
|
|
1082
1135
|
var AGENT_NAMES = {
|
|
1083
1136
|
"claude-code": "Claude Code",
|
|
1084
1137
|
cursor: "Cursor",
|
|
1085
|
-
opencode: "
|
|
1138
|
+
opencode: "OpenCode",
|
|
1086
1139
|
codex: "Codex",
|
|
1087
1140
|
gemini: "Gemini",
|
|
1088
1141
|
amp: "Amp",
|
|
1089
1142
|
ami: "Ami",
|
|
1090
1143
|
instant: "Instant"
|
|
1091
1144
|
};
|
|
1092
|
-
var add = new Command().name("add").description("add an agent integration").argument(
|
|
1145
|
+
var add = new Command().name("add").description("add an agent integration").argument(
|
|
1146
|
+
"[agent]",
|
|
1147
|
+
"agent to add (claude-code, cursor, opencode, codex, gemini, amp, ami, instant)"
|
|
1148
|
+
).option("-y, --yes", "skip confirmation prompts", false).option(
|
|
1093
1149
|
"-c, --cwd <cwd>",
|
|
1094
1150
|
"working directory (defaults to current directory)",
|
|
1095
1151
|
process.cwd()
|
|
1096
1152
|
).action(async (agentArg, opts) => {
|
|
1097
|
-
console.log(
|
|
1153
|
+
console.log(
|
|
1154
|
+
`${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION)}`
|
|
1155
|
+
);
|
|
1098
1156
|
console.log();
|
|
1099
1157
|
try {
|
|
1100
1158
|
const cwd = opts.cwd;
|
|
@@ -1111,7 +1169,16 @@ var add = new Command().name("add").description("add an agent integration").argu
|
|
|
1111
1169
|
process.exit(1);
|
|
1112
1170
|
}
|
|
1113
1171
|
preflightSpinner.succeed();
|
|
1114
|
-
const availableAgents = [
|
|
1172
|
+
const availableAgents = [
|
|
1173
|
+
"claude-code",
|
|
1174
|
+
"cursor",
|
|
1175
|
+
"opencode",
|
|
1176
|
+
"codex",
|
|
1177
|
+
"gemini",
|
|
1178
|
+
"amp",
|
|
1179
|
+
"ami",
|
|
1180
|
+
"instant"
|
|
1181
|
+
].filter((agent) => !projectInfo.installedAgents.includes(agent));
|
|
1115
1182
|
if (availableAgents.length === 0) {
|
|
1116
1183
|
logger.break();
|
|
1117
1184
|
logger.success("All agent integrations are already installed.");
|
|
@@ -1120,10 +1187,21 @@ var add = new Command().name("add").description("add an agent integration").argu
|
|
|
1120
1187
|
}
|
|
1121
1188
|
let agentIntegration;
|
|
1122
1189
|
if (agentArg) {
|
|
1123
|
-
if (![
|
|
1190
|
+
if (![
|
|
1191
|
+
"claude-code",
|
|
1192
|
+
"cursor",
|
|
1193
|
+
"opencode",
|
|
1194
|
+
"codex",
|
|
1195
|
+
"gemini",
|
|
1196
|
+
"amp",
|
|
1197
|
+
"ami",
|
|
1198
|
+
"instant"
|
|
1199
|
+
].includes(agentArg)) {
|
|
1124
1200
|
logger.break();
|
|
1125
1201
|
logger.error(`Invalid agent: ${agentArg}`);
|
|
1126
|
-
logger.error(
|
|
1202
|
+
logger.error(
|
|
1203
|
+
"Available agents: claude-code, cursor, opencode, codex, gemini, amp, ami, instant"
|
|
1204
|
+
);
|
|
1127
1205
|
logger.break();
|
|
1128
1206
|
process.exit(1);
|
|
1129
1207
|
}
|
|
@@ -1271,7 +1349,7 @@ var add = new Command().name("add").description("add an agent integration").argu
|
|
|
1271
1349
|
handleError(error);
|
|
1272
1350
|
}
|
|
1273
1351
|
});
|
|
1274
|
-
var VERSION2 = "0.0.
|
|
1352
|
+
var VERSION2 = "0.0.84";
|
|
1275
1353
|
var REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
1276
1354
|
var DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
1277
1355
|
var reportToCli = async (type, config, error) => {
|
|
@@ -1317,7 +1395,9 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
1317
1395
|
"working directory (defaults to current directory)",
|
|
1318
1396
|
process.cwd()
|
|
1319
1397
|
).action(async (opts) => {
|
|
1320
|
-
console.log(
|
|
1398
|
+
console.log(
|
|
1399
|
+
`${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION2)}`
|
|
1400
|
+
);
|
|
1321
1401
|
console.log();
|
|
1322
1402
|
try {
|
|
1323
1403
|
const cwd = opts.cwd;
|
|
@@ -1436,7 +1516,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
1436
1516
|
{ title: "None", value: "none" },
|
|
1437
1517
|
{ title: "Claude Code", value: "claude-code" },
|
|
1438
1518
|
{ title: "Cursor", value: "cursor" },
|
|
1439
|
-
{ title: "
|
|
1519
|
+
{ title: "OpenCode", value: "opencode" },
|
|
1440
1520
|
{ title: "Codex", value: "codex" },
|
|
1441
1521
|
{ title: "Gemini", value: "gemini" },
|
|
1442
1522
|
{ title: "Amp", value: "amp" },
|
|
@@ -1579,7 +1659,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
1579
1659
|
await reportToCli("error", void 0, error);
|
|
1580
1660
|
}
|
|
1581
1661
|
});
|
|
1582
|
-
var VERSION3 = "0.0.
|
|
1662
|
+
var VERSION3 = "0.0.84";
|
|
1583
1663
|
var DEFAULT_PROXY_PORT = 2e3;
|
|
1584
1664
|
var REACT_GRAB_SCRIPT = '<script src="//unpkg.com/react-grab/dist/index.global.js"></script>';
|
|
1585
1665
|
var buildProviderScript = (provider) => `<script src="//unpkg.com/${provider}/dist/client.global.js"></script>`;
|
|
@@ -1623,7 +1703,9 @@ var start = new Command().name("start").alias("proxy").description("start a prox
|
|
|
1623
1703
|
"--provider <package>",
|
|
1624
1704
|
"provider package to run via npx (e.g., @react-grab/cursor)"
|
|
1625
1705
|
).action(async (urlArg, opts) => {
|
|
1626
|
-
console.log(
|
|
1706
|
+
console.log(
|
|
1707
|
+
`${pc.magenta("\u269B")} ${pc.bold("React Grab")} ${pc.gray(VERSION3)}`
|
|
1708
|
+
);
|
|
1627
1709
|
console.log();
|
|
1628
1710
|
let url = urlArg;
|
|
1629
1711
|
let provider = opts.provider;
|
|
@@ -1648,7 +1730,7 @@ var start = new Command().name("start").alias("proxy").description("start a prox
|
|
|
1648
1730
|
{ title: "None", value: "" },
|
|
1649
1731
|
{ title: "Claude Code", value: "@react-grab/claude-code" },
|
|
1650
1732
|
{ title: "Cursor", value: "@react-grab/cursor" },
|
|
1651
|
-
{ title: "
|
|
1733
|
+
{ title: "OpenCode", value: "@react-grab/opencode" },
|
|
1652
1734
|
{ title: "Codex", value: "@react-grab/codex" },
|
|
1653
1735
|
{ title: "Gemini", value: "@react-grab/gemini" },
|
|
1654
1736
|
{ title: "Amp", value: "@react-grab/amp" },
|
|
@@ -1733,7 +1815,9 @@ var start = new Command().name("start").alias("proxy").description("start a prox
|
|
|
1733
1815
|
server.on("upgrade", proxyMiddleware.upgrade);
|
|
1734
1816
|
const startSpinner = spinner("Starting.").start();
|
|
1735
1817
|
const showSuccess = () => {
|
|
1736
|
-
startSpinner.succeed(
|
|
1818
|
+
startSpinner.succeed(
|
|
1819
|
+
`Open in your browser: http://${hostname}:${proxyPort}`
|
|
1820
|
+
);
|
|
1737
1821
|
const commandParts = ["npx react-grab@latest start", url];
|
|
1738
1822
|
if (opts.port !== String(DEFAULT_PROXY_PORT)) {
|
|
1739
1823
|
commandParts.push(`--port=${opts.port}`);
|
|
@@ -1800,7 +1884,7 @@ var start = new Command().name("start").alias("proxy").description("start a prox
|
|
|
1800
1884
|
});
|
|
1801
1885
|
|
|
1802
1886
|
// src/cli.ts
|
|
1803
|
-
var VERSION4 = "0.0.
|
|
1887
|
+
var VERSION4 = "0.0.84";
|
|
1804
1888
|
var VERSION_API_URL = "https://react-grab.com/api/version";
|
|
1805
1889
|
process.on("SIGINT", () => process.exit(0));
|
|
1806
1890
|
process.on("SIGTERM", () => process.exit(0));
|