@react-grab/cli 0.1.2 → 0.1.4
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 +169 -566
- package/dist/cli.js +167 -564
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,56 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import pc from 'picocolors';
|
|
4
|
+
import basePrompts from 'prompts';
|
|
5
5
|
import { execSync } from 'child_process';
|
|
6
6
|
import { readFileSync, existsSync, writeFileSync, accessSync, constants, readdirSync } from 'fs';
|
|
7
7
|
import { join, basename } from 'path';
|
|
8
8
|
import { detect } from '@antfu/ni';
|
|
9
9
|
import ora from 'ora';
|
|
10
10
|
|
|
11
|
+
var highlighter = {
|
|
12
|
+
error: pc.red,
|
|
13
|
+
warn: pc.yellow,
|
|
14
|
+
info: pc.cyan,
|
|
15
|
+
success: pc.green,
|
|
16
|
+
dim: pc.dim
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// src/utils/logger.ts
|
|
20
|
+
var logger = {
|
|
21
|
+
error(...args) {
|
|
22
|
+
console.log(highlighter.error(args.join(" ")));
|
|
23
|
+
},
|
|
24
|
+
warn(...args) {
|
|
25
|
+
console.log(highlighter.warn(args.join(" ")));
|
|
26
|
+
},
|
|
27
|
+
info(...args) {
|
|
28
|
+
console.log(highlighter.info(args.join(" ")));
|
|
29
|
+
},
|
|
30
|
+
success(...args) {
|
|
31
|
+
console.log(highlighter.success(args.join(" ")));
|
|
32
|
+
},
|
|
33
|
+
dim(...args) {
|
|
34
|
+
console.log(highlighter.dim(args.join(" ")));
|
|
35
|
+
},
|
|
36
|
+
log(...args) {
|
|
37
|
+
console.log(args.join(" "));
|
|
38
|
+
},
|
|
39
|
+
break() {
|
|
40
|
+
console.log("");
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/utils/prompts.ts
|
|
45
|
+
var onCancel = () => {
|
|
46
|
+
logger.break();
|
|
47
|
+
logger.log("Cancelled.");
|
|
48
|
+
logger.break();
|
|
49
|
+
process.exit(0);
|
|
50
|
+
};
|
|
51
|
+
var prompts = (questions) => {
|
|
52
|
+
return basePrompts(questions, { onCancel });
|
|
53
|
+
};
|
|
11
54
|
var detectPackageManager = async (projectRoot) => {
|
|
12
55
|
const detected = await detect({ cwd: projectRoot });
|
|
13
56
|
if (detected && ["npm", "yarn", "pnpm", "bun"].includes(detected)) {
|
|
@@ -253,85 +296,6 @@ var AGENT_PACKAGES = [
|
|
|
253
296
|
"@react-grab/amp",
|
|
254
297
|
"@react-grab/ami"
|
|
255
298
|
];
|
|
256
|
-
var REACT_SCAN_DETECTION_PATTERNS = [
|
|
257
|
-
/["'`][^"'`]*react-scan/,
|
|
258
|
-
/react-scan[^"'`]*["'`]/,
|
|
259
|
-
/unpkg\.com\/react-scan/,
|
|
260
|
-
/import\s*\(?["']react-scan/,
|
|
261
|
-
/require\s*\(["']react-scan/,
|
|
262
|
-
/from\s+["']react-scan/,
|
|
263
|
-
/<Script[^>]*react-scan/i,
|
|
264
|
-
/<script[^>]*react-scan/i
|
|
265
|
-
];
|
|
266
|
-
var REACT_SCAN_FILE_PATTERNS = [
|
|
267
|
-
["app", "layout"],
|
|
268
|
-
["src", "app", "layout"],
|
|
269
|
-
["pages", "_document"],
|
|
270
|
-
["pages", "_app"],
|
|
271
|
-
["src", "pages", "_document"],
|
|
272
|
-
["src", "pages", "_app"],
|
|
273
|
-
["index"],
|
|
274
|
-
["public", "index"],
|
|
275
|
-
["src", "index"],
|
|
276
|
-
["src", "main"],
|
|
277
|
-
["src", "routes", "__root"],
|
|
278
|
-
["app", "routes", "__root"]
|
|
279
|
-
];
|
|
280
|
-
var SCRIPT_EXTENSIONS = ["tsx", "jsx", "ts", "js"];
|
|
281
|
-
var getReactScanFilesToCheck = (projectRoot) => REACT_SCAN_FILE_PATTERNS.flatMap((segments) => {
|
|
282
|
-
const baseName = segments[segments.length - 1];
|
|
283
|
-
const isHtmlFile = baseName === "index" && segments.length <= 2;
|
|
284
|
-
const extensions = isHtmlFile ? [...SCRIPT_EXTENSIONS, "html"] : SCRIPT_EXTENSIONS;
|
|
285
|
-
return extensions.map(
|
|
286
|
-
(extension) => join(projectRoot, ...segments) + `.${extension}`
|
|
287
|
-
);
|
|
288
|
-
});
|
|
289
|
-
var hasReactScanInFile = (filePath) => {
|
|
290
|
-
if (!existsSync(filePath)) return false;
|
|
291
|
-
try {
|
|
292
|
-
const content = readFileSync(filePath, "utf-8");
|
|
293
|
-
return REACT_SCAN_DETECTION_PATTERNS.some(
|
|
294
|
-
(pattern) => pattern.test(content)
|
|
295
|
-
);
|
|
296
|
-
} catch {
|
|
297
|
-
return false;
|
|
298
|
-
}
|
|
299
|
-
};
|
|
300
|
-
var detectReactScan = (projectRoot) => {
|
|
301
|
-
const result = {
|
|
302
|
-
hasReactScan: false,
|
|
303
|
-
hasReactScanMonitoring: false,
|
|
304
|
-
isPackageInstalled: false,
|
|
305
|
-
detectedFiles: []
|
|
306
|
-
};
|
|
307
|
-
const packageJsonPath = join(projectRoot, "package.json");
|
|
308
|
-
if (existsSync(packageJsonPath)) {
|
|
309
|
-
try {
|
|
310
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
311
|
-
const allDependencies = {
|
|
312
|
-
...packageJson.dependencies,
|
|
313
|
-
...packageJson.devDependencies
|
|
314
|
-
};
|
|
315
|
-
if (allDependencies["react-scan"]) {
|
|
316
|
-
result.isPackageInstalled = true;
|
|
317
|
-
result.hasReactScan = true;
|
|
318
|
-
}
|
|
319
|
-
if (allDependencies["@react-scan/monitoring"]) {
|
|
320
|
-
result.hasReactScanMonitoring = true;
|
|
321
|
-
result.hasReactScan = true;
|
|
322
|
-
}
|
|
323
|
-
} catch {
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
const filesToCheck = getReactScanFilesToCheck(projectRoot);
|
|
327
|
-
for (const filePath of filesToCheck) {
|
|
328
|
-
if (hasReactScanInFile(filePath)) {
|
|
329
|
-
result.hasReactScan = true;
|
|
330
|
-
result.detectedFiles.push(filePath);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
return result;
|
|
334
|
-
};
|
|
335
299
|
var detectUnsupportedFramework = (projectRoot) => {
|
|
336
300
|
const packageJsonPath = join(projectRoot, "package.json");
|
|
337
301
|
if (!existsSync(packageJsonPath)) {
|
|
@@ -492,38 +456,6 @@ ${BOLD}File: ${filePath}${RESET}`);
|
|
|
492
456
|
console.log(formatDiff(diff));
|
|
493
457
|
console.log("\u2500".repeat(60));
|
|
494
458
|
};
|
|
495
|
-
var highlighter = {
|
|
496
|
-
error: pc5.red,
|
|
497
|
-
warn: pc5.yellow,
|
|
498
|
-
info: pc5.cyan,
|
|
499
|
-
success: pc5.green,
|
|
500
|
-
dim: pc5.dim
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
// src/utils/logger.ts
|
|
504
|
-
var logger = {
|
|
505
|
-
error(...args) {
|
|
506
|
-
console.log(highlighter.error(args.join(" ")));
|
|
507
|
-
},
|
|
508
|
-
warn(...args) {
|
|
509
|
-
console.log(highlighter.warn(args.join(" ")));
|
|
510
|
-
},
|
|
511
|
-
info(...args) {
|
|
512
|
-
console.log(highlighter.info(args.join(" ")));
|
|
513
|
-
},
|
|
514
|
-
success(...args) {
|
|
515
|
-
console.log(highlighter.success(args.join(" ")));
|
|
516
|
-
},
|
|
517
|
-
dim(...args) {
|
|
518
|
-
console.log(highlighter.dim(args.join(" ")));
|
|
519
|
-
},
|
|
520
|
-
log(...args) {
|
|
521
|
-
console.log(args.join(" "));
|
|
522
|
-
},
|
|
523
|
-
break() {
|
|
524
|
-
console.log("");
|
|
525
|
-
}
|
|
526
|
-
};
|
|
527
459
|
|
|
528
460
|
// src/utils/handle-error.ts
|
|
529
461
|
var handleError = (error) => {
|
|
@@ -1526,7 +1458,7 @@ var findReactGrabFile = (projectRoot, framework, nextRouterType) => {
|
|
|
1526
1458
|
};
|
|
1527
1459
|
var addOptionsToNextScript = (originalContent, options, filePath) => {
|
|
1528
1460
|
const reactGrabScriptMatch = originalContent.match(
|
|
1529
|
-
/(<Script[
|
|
1461
|
+
/(<Script[\s\S]*?react-grab[\s\S]*?)\s*(\/?>)/i
|
|
1530
1462
|
);
|
|
1531
1463
|
if (!reactGrabScriptMatch) {
|
|
1532
1464
|
return {
|
|
@@ -1565,10 +1497,10 @@ var addOptionsToNextScript = (originalContent, options, filePath) => {
|
|
|
1565
1497
|
};
|
|
1566
1498
|
};
|
|
1567
1499
|
var addOptionsToViteScript = (originalContent, options, filePath) => {
|
|
1568
|
-
const
|
|
1569
|
-
/import\s*\(\s*["']react-grab["']\s*\)
|
|
1500
|
+
const reactGrabImportWithInitMatch = originalContent.match(
|
|
1501
|
+
/import\s*\(\s*["']react-grab["']\s*\)(?:\.then\s*\(\s*\(m\)\s*=>\s*m\.init\s*\([^)]*\)\s*\))?/
|
|
1570
1502
|
);
|
|
1571
|
-
if (!
|
|
1503
|
+
if (!reactGrabImportWithInitMatch) {
|
|
1572
1504
|
return {
|
|
1573
1505
|
success: false,
|
|
1574
1506
|
filePath,
|
|
@@ -1578,7 +1510,7 @@ var addOptionsToViteScript = (originalContent, options, filePath) => {
|
|
|
1578
1510
|
const optionsJson = formatOptionsAsJson(options);
|
|
1579
1511
|
const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
|
|
1580
1512
|
const newContent = originalContent.replace(
|
|
1581
|
-
|
|
1513
|
+
reactGrabImportWithInitMatch[0],
|
|
1582
1514
|
newImport
|
|
1583
1515
|
);
|
|
1584
1516
|
return {
|
|
@@ -1590,10 +1522,10 @@ var addOptionsToViteScript = (originalContent, options, filePath) => {
|
|
|
1590
1522
|
};
|
|
1591
1523
|
};
|
|
1592
1524
|
var addOptionsToWebpackImport = (originalContent, options, filePath) => {
|
|
1593
|
-
const
|
|
1594
|
-
/import\s*\(\s*["']react-grab["']\s*\)
|
|
1525
|
+
const reactGrabImportWithInitMatch = originalContent.match(
|
|
1526
|
+
/import\s*\(\s*["']react-grab["']\s*\)(?:\.then\s*\(\s*\(m\)\s*=>\s*m\.init\s*\([^)]*\)\s*\))?/
|
|
1595
1527
|
);
|
|
1596
|
-
if (!
|
|
1528
|
+
if (!reactGrabImportWithInitMatch) {
|
|
1597
1529
|
return {
|
|
1598
1530
|
success: false,
|
|
1599
1531
|
filePath,
|
|
@@ -1603,7 +1535,7 @@ var addOptionsToWebpackImport = (originalContent, options, filePath) => {
|
|
|
1603
1535
|
const optionsJson = formatOptionsAsJson(options);
|
|
1604
1536
|
const newImport = `import("react-grab").then((m) => m.init(${optionsJson}))`;
|
|
1605
1537
|
const newContent = originalContent.replace(
|
|
1606
|
-
|
|
1538
|
+
reactGrabImportWithInitMatch[0],
|
|
1607
1539
|
newImport
|
|
1608
1540
|
);
|
|
1609
1541
|
return {
|
|
@@ -1615,10 +1547,10 @@ var addOptionsToWebpackImport = (originalContent, options, filePath) => {
|
|
|
1615
1547
|
};
|
|
1616
1548
|
};
|
|
1617
1549
|
var addOptionsToTanStackImport = (originalContent, options, filePath) => {
|
|
1618
|
-
const
|
|
1619
|
-
/void\s+import\s*\(\s*["']react-grab["']\s*\)/
|
|
1550
|
+
const reactGrabImportWithInitMatch = originalContent.match(
|
|
1551
|
+
/(?:void\s+import\s*\(\s*["']react-grab["']\s*\)|import\s*\(\s*["']react-grab\/core["']\s*\)\.then\s*\(\s*\(\s*\{\s*init\s*\}\s*\)\s*=>\s*init\s*\([^)]*\)\s*\))/
|
|
1620
1552
|
);
|
|
1621
|
-
if (!
|
|
1553
|
+
if (!reactGrabImportWithInitMatch) {
|
|
1622
1554
|
return {
|
|
1623
1555
|
success: false,
|
|
1624
1556
|
filePath,
|
|
@@ -1628,7 +1560,7 @@ var addOptionsToTanStackImport = (originalContent, options, filePath) => {
|
|
|
1628
1560
|
const optionsJson = formatOptionsAsJson(options);
|
|
1629
1561
|
const newImport = `import("react-grab/core").then(({ init }) => init(${optionsJson}))`;
|
|
1630
1562
|
const newContent = originalContent.replace(
|
|
1631
|
-
|
|
1563
|
+
reactGrabImportWithInitMatch[0],
|
|
1632
1564
|
newImport
|
|
1633
1565
|
);
|
|
1634
1566
|
return {
|
|
@@ -1891,120 +1823,9 @@ var previewPackageJsonAgentRemoval = (projectRoot, agent) => {
|
|
|
1891
1823
|
};
|
|
1892
1824
|
}
|
|
1893
1825
|
};
|
|
1894
|
-
var hasReactScanCode = (content) => REACT_SCAN_DETECTION_PATTERNS.some((pattern) => pattern.test(content));
|
|
1895
|
-
var createRemovalTransform = (removalPatterns) => {
|
|
1896
|
-
return (originalContent, filePath) => {
|
|
1897
|
-
if (!hasReactScanCode(originalContent)) {
|
|
1898
|
-
return {
|
|
1899
|
-
success: true,
|
|
1900
|
-
filePath,
|
|
1901
|
-
message: "React Scan is not configured in this file",
|
|
1902
|
-
noChanges: true
|
|
1903
|
-
};
|
|
1904
|
-
}
|
|
1905
|
-
let newContent = originalContent;
|
|
1906
|
-
for (const pattern of removalPatterns) {
|
|
1907
|
-
newContent = newContent.replace(pattern, "");
|
|
1908
|
-
}
|
|
1909
|
-
if (newContent === originalContent) {
|
|
1910
|
-
return {
|
|
1911
|
-
success: true,
|
|
1912
|
-
filePath,
|
|
1913
|
-
message: "Could not remove React Scan code",
|
|
1914
|
-
noChanges: true
|
|
1915
|
-
};
|
|
1916
|
-
}
|
|
1917
|
-
return {
|
|
1918
|
-
success: true,
|
|
1919
|
-
filePath,
|
|
1920
|
-
message: "Remove React Scan",
|
|
1921
|
-
originalContent,
|
|
1922
|
-
newContent
|
|
1923
|
-
};
|
|
1924
|
-
};
|
|
1925
|
-
};
|
|
1926
|
-
var NEXT_APP_REMOVAL_PATTERNS = [
|
|
1927
|
-
/\s*\{process\.env\.NODE_ENV\s*===\s*["']development["']\s*&&\s*\(\s*<Script[^>]*react-scan[^>]*\/>\s*\)\}/gs,
|
|
1928
|
-
/\s*<Script[^>]*react-scan[^>]*\/>/gi,
|
|
1929
|
-
/\s*<script[^>]*>\s*(?:if\s*\([^)]*\)\s*\{)?\s*import\s*\(\s*["']react-scan["']\s*\)[^<]*<\/script>/gi,
|
|
1930
|
-
/\s*<script[^>]*react-scan[^>]*>[^<]*<\/script>/gi,
|
|
1931
|
-
/\s*<script[^>]*react-scan[^>]*\/>/gi
|
|
1932
|
-
];
|
|
1933
|
-
var VITE_REMOVAL_PATTERNS = [
|
|
1934
|
-
/\s*import\s*\(\s*["']react-scan["']\s*\)\s*\.then\s*\([^)]*\)[^;]*;?/g,
|
|
1935
|
-
/\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
|
|
1936
|
-
/^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm,
|
|
1937
|
-
/<script[^>]*type="module"[^>]*>\s*if\s*\(\s*import\.meta\.env\.DEV\s*\)\s*\{\s*\}\s*<\/script>/gi
|
|
1938
|
-
];
|
|
1939
|
-
var WEBPACK_REMOVAL_PATTERNS = [
|
|
1940
|
-
/\s*import\s*\(\s*["']react-scan["']\s*\)\s*\.then\s*\([^)]*\)[^;]*;?/g,
|
|
1941
|
-
/\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
|
|
1942
|
-
/^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm,
|
|
1943
|
-
/if\s*\(\s*process\.env\.NODE_ENV\s*===\s*["']development["']\s*\)\s*\{\s*\}/g
|
|
1944
|
-
];
|
|
1945
|
-
var TANSTACK_REMOVAL_PATTERNS = [
|
|
1946
|
-
/\s*void\s+import\s*\(\s*["']react-scan["']\s*\);?/g,
|
|
1947
|
-
/\s*import\s*\(\s*["']react-scan["']\s*\);?/g,
|
|
1948
|
-
/^\s*import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+["']react-scan["'];?\s*$/gm
|
|
1949
|
-
];
|
|
1950
|
-
var removeReactScanFromNextApp = createRemovalTransform(
|
|
1951
|
-
NEXT_APP_REMOVAL_PATTERNS
|
|
1952
|
-
);
|
|
1953
|
-
var removeReactScanFromVite = createRemovalTransform(VITE_REMOVAL_PATTERNS);
|
|
1954
|
-
var removeReactScanFromWebpack = createRemovalTransform(
|
|
1955
|
-
WEBPACK_REMOVAL_PATTERNS
|
|
1956
|
-
);
|
|
1957
|
-
var removeReactScanFromTanStack = createRemovalTransform(
|
|
1958
|
-
TANSTACK_REMOVAL_PATTERNS
|
|
1959
|
-
);
|
|
1960
|
-
var findReactScanFile = (projectRoot, framework, nextRouterType) => {
|
|
1961
|
-
switch (framework) {
|
|
1962
|
-
case "next":
|
|
1963
|
-
if (nextRouterType === "app") {
|
|
1964
|
-
return findLayoutFile(projectRoot);
|
|
1965
|
-
}
|
|
1966
|
-
return findDocumentFile(projectRoot);
|
|
1967
|
-
case "vite":
|
|
1968
|
-
return findIndexHtml(projectRoot);
|
|
1969
|
-
case "tanstack":
|
|
1970
|
-
return findTanStackRootFile(projectRoot);
|
|
1971
|
-
case "webpack":
|
|
1972
|
-
return findEntryFile(projectRoot);
|
|
1973
|
-
default:
|
|
1974
|
-
return null;
|
|
1975
|
-
}
|
|
1976
|
-
};
|
|
1977
|
-
var previewReactScanRemoval = (projectRoot, framework, nextRouterType) => {
|
|
1978
|
-
const filePath = findReactScanFile(projectRoot, framework, nextRouterType);
|
|
1979
|
-
if (!filePath) {
|
|
1980
|
-
return {
|
|
1981
|
-
success: true,
|
|
1982
|
-
filePath: "",
|
|
1983
|
-
message: "Could not find file containing React Scan configuration",
|
|
1984
|
-
noChanges: true
|
|
1985
|
-
};
|
|
1986
|
-
}
|
|
1987
|
-
const originalContent = readFileSync(filePath, "utf-8");
|
|
1988
|
-
switch (framework) {
|
|
1989
|
-
case "next":
|
|
1990
|
-
return removeReactScanFromNextApp(originalContent, filePath);
|
|
1991
|
-
case "vite":
|
|
1992
|
-
return removeReactScanFromVite(originalContent, filePath);
|
|
1993
|
-
case "tanstack":
|
|
1994
|
-
return removeReactScanFromTanStack(originalContent, filePath);
|
|
1995
|
-
case "webpack":
|
|
1996
|
-
return removeReactScanFromWebpack(originalContent, filePath);
|
|
1997
|
-
default:
|
|
1998
|
-
return {
|
|
1999
|
-
success: false,
|
|
2000
|
-
filePath,
|
|
2001
|
-
message: `Unknown framework: ${framework}`
|
|
2002
|
-
};
|
|
2003
|
-
}
|
|
2004
|
-
};
|
|
2005
1826
|
|
|
2006
1827
|
// src/commands/add.ts
|
|
2007
|
-
var VERSION = "0.1.
|
|
1828
|
+
var VERSION = "0.1.3";
|
|
2008
1829
|
var formatInstalledAgentNames = (agents) => agents.map((agent) => AGENT_NAMES[agent] || agent).join(", ");
|
|
2009
1830
|
var add = new Command().name("add").alias("install").description("add an agent integration").argument("[agent]", `agent to add (${AGENTS.join(", ")})`).option("-y, --yes", "skip confirmation prompts", false).option(
|
|
2010
1831
|
"-c, --cwd <cwd>",
|
|
@@ -2012,7 +1833,7 @@ var add = new Command().name("add").alias("install").description("add an agent i
|
|
|
2012
1833
|
process.cwd()
|
|
2013
1834
|
).action(async (agentArg, opts) => {
|
|
2014
1835
|
console.log(
|
|
2015
|
-
`${
|
|
1836
|
+
`${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION)}`
|
|
2016
1837
|
);
|
|
2017
1838
|
console.log();
|
|
2018
1839
|
try {
|
|
@@ -2063,7 +1884,7 @@ var add = new Command().name("add").alias("install").description("add an agent i
|
|
|
2063
1884
|
);
|
|
2064
1885
|
logger.break();
|
|
2065
1886
|
logger.warn(`${installedNames} is already installed.`);
|
|
2066
|
-
const { action } = await
|
|
1887
|
+
const { action } = await prompts({
|
|
2067
1888
|
type: "select",
|
|
2068
1889
|
name: "action",
|
|
2069
1890
|
message: "How would you like to proceed?",
|
|
@@ -2097,7 +1918,7 @@ var add = new Command().name("add").alias("install").description("add an agent i
|
|
|
2097
1918
|
logger.warn(`Currently installed: ${installedNames}`);
|
|
2098
1919
|
logger.break();
|
|
2099
1920
|
}
|
|
2100
|
-
const { agent } = await
|
|
1921
|
+
const { agent } = await prompts({
|
|
2101
1922
|
type: "select",
|
|
2102
1923
|
name: "agent",
|
|
2103
1924
|
message: `Which ${highlighter.info("agent integration")} would you like to add?`,
|
|
@@ -2115,7 +1936,7 @@ var add = new Command().name("add").alias("install").description("add an agent i
|
|
|
2115
1936
|
const installedNames = formatInstalledAgentNames(
|
|
2116
1937
|
projectInfo.installedAgents
|
|
2117
1938
|
);
|
|
2118
|
-
const { action } = await
|
|
1939
|
+
const { action } = await prompts({
|
|
2119
1940
|
type: "select",
|
|
2120
1941
|
name: "action",
|
|
2121
1942
|
message: "How would you like to proceed?",
|
|
@@ -2260,7 +2081,7 @@ var add = new Command().name("add").alias("install").description("add an agent i
|
|
|
2260
2081
|
}
|
|
2261
2082
|
if (!isNonInteractive && agentsToRemove.length === 0) {
|
|
2262
2083
|
logger.break();
|
|
2263
|
-
const { proceed } = await
|
|
2084
|
+
const { proceed } = await prompts({
|
|
2264
2085
|
type: "confirm",
|
|
2265
2086
|
name: "proceed",
|
|
2266
2087
|
message: "Apply these changes?",
|
|
@@ -2340,7 +2161,7 @@ var MAX_KEY_HOLD_DURATION_MS = 2e3;
|
|
|
2340
2161
|
var MAX_CONTEXT_LINES = 50;
|
|
2341
2162
|
|
|
2342
2163
|
// src/commands/configure.ts
|
|
2343
|
-
var VERSION2 = "0.1.
|
|
2164
|
+
var VERSION2 = "0.1.3";
|
|
2344
2165
|
var isMac = process.platform === "darwin";
|
|
2345
2166
|
var META_LABEL = isMac ? "Cmd" : "Win";
|
|
2346
2167
|
var ALT_LABEL = isMac ? "Option" : "Alt";
|
|
@@ -2550,7 +2371,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2550
2371
|
process.cwd()
|
|
2551
2372
|
).action(async (opts) => {
|
|
2552
2373
|
console.log(
|
|
2553
|
-
`${
|
|
2374
|
+
`${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION2)}`
|
|
2554
2375
|
);
|
|
2555
2376
|
console.log();
|
|
2556
2377
|
try {
|
|
@@ -2622,7 +2443,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2622
2443
|
logger.log(` Max context lines: ${highlighter.info(String(lines))}`);
|
|
2623
2444
|
}
|
|
2624
2445
|
} else {
|
|
2625
|
-
const { selectedOption } = await
|
|
2446
|
+
const { selectedOption } = await prompts({
|
|
2626
2447
|
type: "autocomplete",
|
|
2627
2448
|
name: "selectedOption",
|
|
2628
2449
|
message: "Search for an option to configure:",
|
|
@@ -2642,7 +2463,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2642
2463
|
process.exit(1);
|
|
2643
2464
|
}
|
|
2644
2465
|
if (selectedOption === "activationKey") {
|
|
2645
|
-
const { selectedCombo } = await
|
|
2466
|
+
const { selectedCombo } = await prompts({
|
|
2646
2467
|
type: "autocomplete",
|
|
2647
2468
|
name: "selectedCombo",
|
|
2648
2469
|
message: "Type key combination (e.g. ctrl+shift+g):",
|
|
@@ -2659,7 +2480,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2659
2480
|
);
|
|
2660
2481
|
}
|
|
2661
2482
|
if (selectedOption === "activationMode") {
|
|
2662
|
-
const { activationMode } = await
|
|
2483
|
+
const { activationMode } = await prompts({
|
|
2663
2484
|
type: "select",
|
|
2664
2485
|
name: "activationMode",
|
|
2665
2486
|
message: `Select ${highlighter.info("activation mode")}:`,
|
|
@@ -2679,7 +2500,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2679
2500
|
collectedOptions.activationMode = activationMode;
|
|
2680
2501
|
}
|
|
2681
2502
|
if (selectedOption === "keyHoldDuration") {
|
|
2682
|
-
const { keyHoldDuration } = await
|
|
2503
|
+
const { keyHoldDuration } = await prompts({
|
|
2683
2504
|
type: "number",
|
|
2684
2505
|
name: "keyHoldDuration",
|
|
2685
2506
|
message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
|
|
@@ -2694,7 +2515,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2694
2515
|
collectedOptions.keyHoldDuration = keyHoldDuration;
|
|
2695
2516
|
}
|
|
2696
2517
|
if (selectedOption === "allowActivationInsideInput") {
|
|
2697
|
-
const { allowActivationInsideInput } = await
|
|
2518
|
+
const { allowActivationInsideInput } = await prompts({
|
|
2698
2519
|
type: "confirm",
|
|
2699
2520
|
name: "allowActivationInsideInput",
|
|
2700
2521
|
message: `Allow activation ${highlighter.info("inside input fields")}?`,
|
|
@@ -2707,7 +2528,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2707
2528
|
collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
|
|
2708
2529
|
}
|
|
2709
2530
|
if (selectedOption === "maxContextLines") {
|
|
2710
|
-
const { maxContextLines } = await
|
|
2531
|
+
const { maxContextLines } = await prompts({
|
|
2711
2532
|
type: "number",
|
|
2712
2533
|
name: "maxContextLines",
|
|
2713
2534
|
message: `Enter ${highlighter.info("max context lines")} to include:`,
|
|
@@ -2737,7 +2558,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2737
2558
|
`Add this to your ${highlighter.info("init()")} call or ${highlighter.info("data-options")} attribute:`
|
|
2738
2559
|
);
|
|
2739
2560
|
logger.break();
|
|
2740
|
-
console.log(` ${
|
|
2561
|
+
console.log(` ${pc.cyan(configJson)}`);
|
|
2741
2562
|
logger.break();
|
|
2742
2563
|
process.exit(1);
|
|
2743
2564
|
}
|
|
@@ -2747,7 +2568,7 @@ var configure = new Command().name("configure").alias("config").description("con
|
|
|
2747
2568
|
printDiff(result.filePath, result.originalContent, result.newContent);
|
|
2748
2569
|
if (!opts.yes) {
|
|
2749
2570
|
logger.break();
|
|
2750
|
-
const { proceed } = await
|
|
2571
|
+
const { proceed } = await prompts({
|
|
2751
2572
|
type: "confirm",
|
|
2752
2573
|
name: "proceed",
|
|
2753
2574
|
message: "Apply these changes?",
|
|
@@ -2840,7 +2661,7 @@ var uninstallPackagesWithFeedback = (packages, packageManager, projectRoot) => {
|
|
|
2840
2661
|
};
|
|
2841
2662
|
|
|
2842
2663
|
// src/commands/init.ts
|
|
2843
|
-
var VERSION3 = "0.1.
|
|
2664
|
+
var VERSION3 = "0.1.3";
|
|
2844
2665
|
var REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
2845
2666
|
var DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
2846
2667
|
var reportToCli = (type, config, error) => {
|
|
@@ -2906,7 +2727,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
2906
2727
|
process.cwd()
|
|
2907
2728
|
).action(async (opts) => {
|
|
2908
2729
|
console.log(
|
|
2909
|
-
`${
|
|
2730
|
+
`${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION3)}`
|
|
2910
2731
|
);
|
|
2911
2732
|
console.log();
|
|
2912
2733
|
try {
|
|
@@ -2967,7 +2788,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
2967
2788
|
);
|
|
2968
2789
|
logger.break();
|
|
2969
2790
|
}
|
|
2970
|
-
const { wantCustomizeOptions } = await
|
|
2791
|
+
const { wantCustomizeOptions } = await prompts({
|
|
2971
2792
|
type: "confirm",
|
|
2972
2793
|
name: "wantCustomizeOptions",
|
|
2973
2794
|
message: `Would you like to customize ${highlighter.info("options")}?`,
|
|
@@ -2988,7 +2809,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
2988
2809
|
` Activation key: ${highlighter.info(formatActivationKeyDisplay2(collectedOptions.activationKey))}`
|
|
2989
2810
|
);
|
|
2990
2811
|
} else {
|
|
2991
|
-
const { wantActivationKey } = await
|
|
2812
|
+
const { wantActivationKey } = await prompts({
|
|
2992
2813
|
type: "confirm",
|
|
2993
2814
|
name: "wantActivationKey",
|
|
2994
2815
|
message: `Configure ${highlighter.info("activation key")}?`,
|
|
@@ -2999,7 +2820,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
2999
2820
|
process.exit(1);
|
|
3000
2821
|
}
|
|
3001
2822
|
if (wantActivationKey) {
|
|
3002
|
-
const { key } = await
|
|
2823
|
+
const { key } = await prompts({
|
|
3003
2824
|
type: "text",
|
|
3004
2825
|
name: "key",
|
|
3005
2826
|
message: "Enter the activation key (e.g., g, k, space):",
|
|
@@ -3015,7 +2836,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3015
2836
|
);
|
|
3016
2837
|
}
|
|
3017
2838
|
}
|
|
3018
|
-
const { activationMode } = await
|
|
2839
|
+
const { activationMode } = await prompts({
|
|
3019
2840
|
type: "select",
|
|
3020
2841
|
name: "activationMode",
|
|
3021
2842
|
message: `Select ${highlighter.info("activation mode")}:`,
|
|
@@ -3034,7 +2855,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3034
2855
|
}
|
|
3035
2856
|
collectedOptions.activationMode = activationMode;
|
|
3036
2857
|
if (activationMode === "hold") {
|
|
3037
|
-
const { keyHoldDuration } = await
|
|
2858
|
+
const { keyHoldDuration } = await prompts({
|
|
3038
2859
|
type: "number",
|
|
3039
2860
|
name: "keyHoldDuration",
|
|
3040
2861
|
message: `Enter ${highlighter.info("key hold duration")} in milliseconds:`,
|
|
@@ -3048,7 +2869,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3048
2869
|
}
|
|
3049
2870
|
collectedOptions.keyHoldDuration = keyHoldDuration;
|
|
3050
2871
|
}
|
|
3051
|
-
const { allowActivationInsideInput } = await
|
|
2872
|
+
const { allowActivationInsideInput } = await prompts({
|
|
3052
2873
|
type: "confirm",
|
|
3053
2874
|
name: "allowActivationInsideInput",
|
|
3054
2875
|
message: `Allow activation ${highlighter.info("inside input fields")}?`,
|
|
@@ -3059,7 +2880,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3059
2880
|
process.exit(1);
|
|
3060
2881
|
}
|
|
3061
2882
|
collectedOptions.allowActivationInsideInput = allowActivationInsideInput;
|
|
3062
|
-
const { maxContextLines } = await
|
|
2883
|
+
const { maxContextLines } = await prompts({
|
|
3063
2884
|
type: "number",
|
|
3064
2885
|
name: "maxContextLines",
|
|
3065
2886
|
message: `Enter ${highlighter.info("max context lines")} to include:`,
|
|
@@ -3093,7 +2914,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3093
2914
|
optionsResult.newContent
|
|
3094
2915
|
);
|
|
3095
2916
|
logger.break();
|
|
3096
|
-
const { proceed } = await
|
|
2917
|
+
const { proceed } = await prompts({
|
|
3097
2918
|
type: "confirm",
|
|
3098
2919
|
name: "proceed",
|
|
3099
2920
|
message: "Apply these changes?",
|
|
@@ -3117,7 +2938,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3117
2938
|
);
|
|
3118
2939
|
if (availableAgents.length > 0) {
|
|
3119
2940
|
logger.break();
|
|
3120
|
-
const { wantAddAgent } = await
|
|
2941
|
+
const { wantAddAgent } = await prompts({
|
|
3121
2942
|
type: "confirm",
|
|
3122
2943
|
name: "wantAddAgent",
|
|
3123
2944
|
message: `Would you like to add an ${highlighter.info("agent integration")}?`,
|
|
@@ -3128,7 +2949,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3128
2949
|
process.exit(1);
|
|
3129
2950
|
}
|
|
3130
2951
|
if (wantAddAgent) {
|
|
3131
|
-
const { agent } = await
|
|
2952
|
+
const { agent } = await prompts({
|
|
3132
2953
|
type: "select",
|
|
3133
2954
|
name: "agent",
|
|
3134
2955
|
message: `Which ${highlighter.info("agent integration")} would you like to add?`,
|
|
@@ -3150,7 +2971,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3150
2971
|
const installedNames = formatInstalledAgentNames2(
|
|
3151
2972
|
projectInfo.installedAgents
|
|
3152
2973
|
);
|
|
3153
|
-
const { action } = await
|
|
2974
|
+
const { action } = await prompts({
|
|
3154
2975
|
type: "select",
|
|
3155
2976
|
name: "action",
|
|
3156
2977
|
message: "How would you like to proceed?",
|
|
@@ -3221,7 +3042,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3221
3042
|
}
|
|
3222
3043
|
if (agentsToRemove2.length === 0) {
|
|
3223
3044
|
logger.break();
|
|
3224
|
-
const { proceed } = await
|
|
3045
|
+
const { proceed } = await prompts({
|
|
3225
3046
|
type: "confirm",
|
|
3226
3047
|
name: "proceed",
|
|
3227
3048
|
message: "Apply these changes?",
|
|
@@ -3266,6 +3087,75 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3266
3087
|
}
|
|
3267
3088
|
}
|
|
3268
3089
|
}
|
|
3090
|
+
} else {
|
|
3091
|
+
const result2 = previewTransform(
|
|
3092
|
+
projectInfo.projectRoot,
|
|
3093
|
+
projectInfo.framework,
|
|
3094
|
+
projectInfo.nextRouterType,
|
|
3095
|
+
agentIntegration2,
|
|
3096
|
+
true
|
|
3097
|
+
);
|
|
3098
|
+
const packageJsonResult2 = previewPackageJsonTransform(
|
|
3099
|
+
projectInfo.projectRoot,
|
|
3100
|
+
agentIntegration2,
|
|
3101
|
+
projectInfo.installedAgents,
|
|
3102
|
+
projectInfo.packageManager
|
|
3103
|
+
);
|
|
3104
|
+
if (!result2.success) {
|
|
3105
|
+
logger.break();
|
|
3106
|
+
logger.error(result2.message);
|
|
3107
|
+
logger.break();
|
|
3108
|
+
process.exit(1);
|
|
3109
|
+
}
|
|
3110
|
+
const hasLayoutChanges2 = !result2.noChanges && result2.originalContent && result2.newContent;
|
|
3111
|
+
const hasPackageJsonChanges2 = packageJsonResult2.success && !packageJsonResult2.noChanges && packageJsonResult2.originalContent && packageJsonResult2.newContent;
|
|
3112
|
+
if (hasLayoutChanges2 || hasPackageJsonChanges2) {
|
|
3113
|
+
logger.break();
|
|
3114
|
+
if (hasLayoutChanges2) {
|
|
3115
|
+
printDiff(
|
|
3116
|
+
result2.filePath,
|
|
3117
|
+
result2.originalContent,
|
|
3118
|
+
result2.newContent
|
|
3119
|
+
);
|
|
3120
|
+
}
|
|
3121
|
+
if (hasPackageJsonChanges2) {
|
|
3122
|
+
if (hasLayoutChanges2) {
|
|
3123
|
+
logger.break();
|
|
3124
|
+
}
|
|
3125
|
+
printDiff(
|
|
3126
|
+
packageJsonResult2.filePath,
|
|
3127
|
+
packageJsonResult2.originalContent,
|
|
3128
|
+
packageJsonResult2.newContent
|
|
3129
|
+
);
|
|
3130
|
+
}
|
|
3131
|
+
logger.break();
|
|
3132
|
+
const { proceed } = await prompts({
|
|
3133
|
+
type: "confirm",
|
|
3134
|
+
name: "proceed",
|
|
3135
|
+
message: "Apply these changes?",
|
|
3136
|
+
initial: true
|
|
3137
|
+
});
|
|
3138
|
+
if (!proceed) {
|
|
3139
|
+
logger.break();
|
|
3140
|
+
logger.log("Agent addition cancelled.");
|
|
3141
|
+
} else {
|
|
3142
|
+
installPackagesWithFeedback(
|
|
3143
|
+
getPackagesToInstall(agentIntegration2, false),
|
|
3144
|
+
projectInfo.packageManager,
|
|
3145
|
+
projectInfo.projectRoot
|
|
3146
|
+
);
|
|
3147
|
+
if (hasLayoutChanges2) {
|
|
3148
|
+
applyTransformWithFeedback(result2);
|
|
3149
|
+
}
|
|
3150
|
+
if (hasPackageJsonChanges2) {
|
|
3151
|
+
applyPackageJsonWithFeedback(packageJsonResult2);
|
|
3152
|
+
}
|
|
3153
|
+
logger.break();
|
|
3154
|
+
logger.success(
|
|
3155
|
+
`${getAgentName(agentIntegration2)} has been added.`
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3269
3159
|
}
|
|
3270
3160
|
}
|
|
3271
3161
|
}
|
|
@@ -3303,7 +3193,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3303
3193
|
return 0;
|
|
3304
3194
|
}
|
|
3305
3195
|
);
|
|
3306
|
-
const { selectedProject } = await
|
|
3196
|
+
const { selectedProject } = await prompts({
|
|
3307
3197
|
type: "select",
|
|
3308
3198
|
name: "selectedProject",
|
|
3309
3199
|
message: "Select a project to install React Grab:",
|
|
@@ -3370,7 +3260,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3370
3260
|
const agentsToRemove = [];
|
|
3371
3261
|
if (!isNonInteractive && !opts.agent) {
|
|
3372
3262
|
logger.break();
|
|
3373
|
-
const { wantAddAgent } = await
|
|
3263
|
+
const { wantAddAgent } = await prompts({
|
|
3374
3264
|
type: "confirm",
|
|
3375
3265
|
name: "wantAddAgent",
|
|
3376
3266
|
message: `Would you like to add an ${highlighter.info("agent integration")}?`,
|
|
@@ -3381,7 +3271,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3381
3271
|
process.exit(1);
|
|
3382
3272
|
}
|
|
3383
3273
|
if (wantAddAgent) {
|
|
3384
|
-
const { agent } = await
|
|
3274
|
+
const { agent } = await prompts({
|
|
3385
3275
|
type: "select",
|
|
3386
3276
|
name: "agent",
|
|
3387
3277
|
message: `Which ${highlighter.info("agent integration")} would you like to add?`,
|
|
@@ -3448,7 +3338,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3448
3338
|
logger.warn("Please verify the changes before committing.");
|
|
3449
3339
|
if (!isNonInteractive) {
|
|
3450
3340
|
logger.break();
|
|
3451
|
-
const { proceed } = await
|
|
3341
|
+
const { proceed } = await prompts({
|
|
3452
3342
|
type: "confirm",
|
|
3453
3343
|
name: "proceed",
|
|
3454
3344
|
message: "Apply these changes?",
|
|
@@ -3507,293 +3397,7 @@ var init = new Command().name("init").description("initialize React Grab in your
|
|
|
3507
3397
|
reportToCli("error", void 0, error);
|
|
3508
3398
|
}
|
|
3509
3399
|
});
|
|
3510
|
-
var VERSION4 = "0.1.
|
|
3511
|
-
var DOCS_URL2 = "https://github.com/aidenybai/react-grab";
|
|
3512
|
-
var exitWithMessage = (message, code = 0) => {
|
|
3513
|
-
if (message) logger.log(message);
|
|
3514
|
-
logger.break();
|
|
3515
|
-
process.exit(code);
|
|
3516
|
-
};
|
|
3517
|
-
var confirmOrExit = async (message, isNonInteractive) => {
|
|
3518
|
-
if (isNonInteractive) return;
|
|
3519
|
-
const { proceed } = await prompts3({
|
|
3520
|
-
type: "confirm",
|
|
3521
|
-
name: "proceed",
|
|
3522
|
-
message,
|
|
3523
|
-
initial: true
|
|
3524
|
-
});
|
|
3525
|
-
if (!proceed) exitWithMessage("Migration cancelled.");
|
|
3526
|
-
};
|
|
3527
|
-
var hasTransformChanges = (result) => result.success && !result.noChanges && Boolean(result.originalContent) && Boolean(result.newContent);
|
|
3528
|
-
var MIGRATION_SOURCES = ["react-scan"];
|
|
3529
|
-
var MIGRATION_SOURCE_NAMES = {
|
|
3530
|
-
"react-scan": "React Scan"
|
|
3531
|
-
};
|
|
3532
|
-
var FRAMEWORK_NAMES2 = {
|
|
3533
|
-
next: "Next.js",
|
|
3534
|
-
vite: "Vite",
|
|
3535
|
-
tanstack: "TanStack Start",
|
|
3536
|
-
webpack: "Webpack",
|
|
3537
|
-
unknown: "Unknown"
|
|
3538
|
-
};
|
|
3539
|
-
var migrate = new Command().name("migrate").description("migrate to React Grab from another tool").option("-y, --yes", "skip confirmation prompts", false).option("-f, --from <source>", "migration source (react-scan)").option(
|
|
3540
|
-
"-c, --cwd <cwd>",
|
|
3541
|
-
"working directory (defaults to current directory)",
|
|
3542
|
-
process.cwd()
|
|
3543
|
-
).action(async (opts) => {
|
|
3544
|
-
console.log(
|
|
3545
|
-
`${pc5.magenta("\u273F")} ${pc5.bold("React Grab")} ${pc5.gray(VERSION4)}`
|
|
3546
|
-
);
|
|
3547
|
-
console.log();
|
|
3548
|
-
try {
|
|
3549
|
-
const cwd = opts.cwd;
|
|
3550
|
-
const isNonInteractive = opts.yes;
|
|
3551
|
-
let migrationSource = opts.from;
|
|
3552
|
-
if (!migrationSource) {
|
|
3553
|
-
if (isNonInteractive) {
|
|
3554
|
-
logger.error(
|
|
3555
|
-
"Migration source is required in non-interactive mode. Use --from <source>"
|
|
3556
|
-
);
|
|
3557
|
-
logger.log(
|
|
3558
|
-
`Available sources: ${MIGRATION_SOURCES.map((innerSource) => highlighter.info(innerSource)).join(", ")}`
|
|
3559
|
-
);
|
|
3560
|
-
logger.break();
|
|
3561
|
-
process.exit(1);
|
|
3562
|
-
}
|
|
3563
|
-
const { source } = await prompts3({
|
|
3564
|
-
type: "select",
|
|
3565
|
-
name: "source",
|
|
3566
|
-
message: `What would you like to migrate ${highlighter.info("from")}?`,
|
|
3567
|
-
choices: MIGRATION_SOURCES.map((innerSource) => ({
|
|
3568
|
-
title: MIGRATION_SOURCE_NAMES[innerSource],
|
|
3569
|
-
value: innerSource
|
|
3570
|
-
}))
|
|
3571
|
-
});
|
|
3572
|
-
if (!source) exitWithMessage();
|
|
3573
|
-
migrationSource = source;
|
|
3574
|
-
}
|
|
3575
|
-
if (!MIGRATION_SOURCES.includes(migrationSource)) {
|
|
3576
|
-
logger.error(`Unknown migration source: ${migrationSource}`);
|
|
3577
|
-
logger.log(
|
|
3578
|
-
`Available sources: ${MIGRATION_SOURCES.map((innerSource) => highlighter.info(innerSource)).join(", ")}`
|
|
3579
|
-
);
|
|
3580
|
-
logger.break();
|
|
3581
|
-
process.exit(1);
|
|
3582
|
-
}
|
|
3583
|
-
logger.break();
|
|
3584
|
-
logger.log(
|
|
3585
|
-
`Migrating from ${highlighter.info(MIGRATION_SOURCE_NAMES[migrationSource])} to ${highlighter.info("React Grab")}...`
|
|
3586
|
-
);
|
|
3587
|
-
logger.break();
|
|
3588
|
-
const preflightSpinner = spinner("Preflight checks.").start();
|
|
3589
|
-
const projectInfo = await detectProject(cwd);
|
|
3590
|
-
preflightSpinner.succeed();
|
|
3591
|
-
if (projectInfo.framework === "unknown") {
|
|
3592
|
-
logger.break();
|
|
3593
|
-
logger.error("Could not detect a supported framework.");
|
|
3594
|
-
logger.log(
|
|
3595
|
-
"React Grab supports Next.js, Vite, TanStack Start, and Webpack projects."
|
|
3596
|
-
);
|
|
3597
|
-
logger.log(`Visit ${highlighter.info(DOCS_URL2)} for manual setup.`);
|
|
3598
|
-
logger.break();
|
|
3599
|
-
process.exit(1);
|
|
3600
|
-
}
|
|
3601
|
-
const frameworkSpinner = spinner("Verifying framework.").start();
|
|
3602
|
-
frameworkSpinner.succeed(
|
|
3603
|
-
`Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES2[projectInfo.framework])}.`
|
|
3604
|
-
);
|
|
3605
|
-
if (projectInfo.framework === "next") {
|
|
3606
|
-
const routerSpinner = spinner("Detecting router type.").start();
|
|
3607
|
-
routerSpinner.succeed(
|
|
3608
|
-
`Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === "app" ? "App Router" : "Pages Router")}.`
|
|
3609
|
-
);
|
|
3610
|
-
}
|
|
3611
|
-
const sourceSpinner = spinner(
|
|
3612
|
-
`Checking for ${MIGRATION_SOURCE_NAMES[migrationSource]}.`
|
|
3613
|
-
).start();
|
|
3614
|
-
const reactScanInfo = detectReactScan(cwd);
|
|
3615
|
-
const sourceName = MIGRATION_SOURCE_NAMES[migrationSource];
|
|
3616
|
-
if (!reactScanInfo.hasReactScan) {
|
|
3617
|
-
sourceSpinner.fail(`${sourceName} is not installed in this project.`);
|
|
3618
|
-
exitWithMessage(
|
|
3619
|
-
`Use ${highlighter.info("npx grab init")} to install React Grab directly.`
|
|
3620
|
-
);
|
|
3621
|
-
}
|
|
3622
|
-
sourceSpinner.succeed(
|
|
3623
|
-
`Checking for ${sourceName}. Found ${highlighter.info(reactScanInfo.isPackageInstalled ? "npm package" : "script reference")}.`
|
|
3624
|
-
);
|
|
3625
|
-
if (reactScanInfo.hasReactScanMonitoring) {
|
|
3626
|
-
logger.break();
|
|
3627
|
-
logger.warn(
|
|
3628
|
-
`${sourceName} Monitoring (@react-scan/monitoring) detected.`
|
|
3629
|
-
);
|
|
3630
|
-
logger.warn(
|
|
3631
|
-
"Monitoring features are not available in React Grab. You may need to remove it manually."
|
|
3632
|
-
);
|
|
3633
|
-
}
|
|
3634
|
-
if (projectInfo.hasReactGrab) {
|
|
3635
|
-
logger.break();
|
|
3636
|
-
logger.success("React Grab is already installed.");
|
|
3637
|
-
logger.log(
|
|
3638
|
-
`This migration will only remove ${sourceName} from your project.`
|
|
3639
|
-
);
|
|
3640
|
-
logger.break();
|
|
3641
|
-
const removalResult2 = previewReactScanRemoval(
|
|
3642
|
-
projectInfo.projectRoot,
|
|
3643
|
-
projectInfo.framework,
|
|
3644
|
-
projectInfo.nextRouterType
|
|
3645
|
-
);
|
|
3646
|
-
if (removalResult2.noChanges) {
|
|
3647
|
-
logger.log(`No ${sourceName} code found in configuration files.`);
|
|
3648
|
-
logger.break();
|
|
3649
|
-
if (reactScanInfo.isPackageInstalled) {
|
|
3650
|
-
if (reactScanInfo.detectedFiles.length > 0) {
|
|
3651
|
-
logger.warn(
|
|
3652
|
-
`${sourceName} was detected in files that cannot be automatically cleaned:`
|
|
3653
|
-
);
|
|
3654
|
-
for (const file of reactScanInfo.detectedFiles) {
|
|
3655
|
-
logger.log(` - ${file}`);
|
|
3656
|
-
}
|
|
3657
|
-
logger.warn(
|
|
3658
|
-
"Please remove React Scan references manually before uninstalling the package."
|
|
3659
|
-
);
|
|
3660
|
-
logger.break();
|
|
3661
|
-
process.exit(1);
|
|
3662
|
-
}
|
|
3663
|
-
await confirmOrExit(
|
|
3664
|
-
`Uninstall ${migrationSource} package?`,
|
|
3665
|
-
isNonInteractive
|
|
3666
|
-
);
|
|
3667
|
-
uninstallPackagesWithFeedback(
|
|
3668
|
-
[migrationSource],
|
|
3669
|
-
projectInfo.packageManager,
|
|
3670
|
-
projectInfo.projectRoot
|
|
3671
|
-
);
|
|
3672
|
-
logger.break();
|
|
3673
|
-
logger.success(`${sourceName} has been removed.`);
|
|
3674
|
-
}
|
|
3675
|
-
exitWithMessage();
|
|
3676
|
-
}
|
|
3677
|
-
if (hasTransformChanges(removalResult2)) {
|
|
3678
|
-
logger.break();
|
|
3679
|
-
printDiff(
|
|
3680
|
-
removalResult2.filePath,
|
|
3681
|
-
removalResult2.originalContent,
|
|
3682
|
-
removalResult2.newContent
|
|
3683
|
-
);
|
|
3684
|
-
logger.break();
|
|
3685
|
-
await confirmOrExit("Apply these changes?", isNonInteractive);
|
|
3686
|
-
applyTransformWithFeedback(
|
|
3687
|
-
removalResult2,
|
|
3688
|
-
`Removing ${sourceName} from ${removalResult2.filePath}.`
|
|
3689
|
-
);
|
|
3690
|
-
if (reactScanInfo.isPackageInstalled) {
|
|
3691
|
-
uninstallPackagesWithFeedback(
|
|
3692
|
-
[migrationSource],
|
|
3693
|
-
projectInfo.packageManager,
|
|
3694
|
-
projectInfo.projectRoot
|
|
3695
|
-
);
|
|
3696
|
-
}
|
|
3697
|
-
logger.break();
|
|
3698
|
-
logger.success(`Migration complete! ${sourceName} has been removed.`);
|
|
3699
|
-
}
|
|
3700
|
-
exitWithMessage();
|
|
3701
|
-
}
|
|
3702
|
-
const removalResult = previewReactScanRemoval(
|
|
3703
|
-
projectInfo.projectRoot,
|
|
3704
|
-
projectInfo.framework,
|
|
3705
|
-
projectInfo.nextRouterType
|
|
3706
|
-
);
|
|
3707
|
-
const addResult = previewTransform(
|
|
3708
|
-
projectInfo.projectRoot,
|
|
3709
|
-
projectInfo.framework,
|
|
3710
|
-
projectInfo.nextRouterType,
|
|
3711
|
-
"none",
|
|
3712
|
-
false
|
|
3713
|
-
);
|
|
3714
|
-
const hasRemovalChanges = hasTransformChanges(removalResult);
|
|
3715
|
-
const hasAddChanges = hasTransformChanges(addResult);
|
|
3716
|
-
if (!hasRemovalChanges && !hasAddChanges) {
|
|
3717
|
-
exitWithMessage("No changes needed.");
|
|
3718
|
-
}
|
|
3719
|
-
logger.break();
|
|
3720
|
-
logger.log("Migration will perform the following changes:");
|
|
3721
|
-
logger.break();
|
|
3722
|
-
if (hasRemovalChanges) {
|
|
3723
|
-
logger.log(
|
|
3724
|
-
` ${pc5.red("\u2212")} Remove ${sourceName} from ${removalResult.filePath}`
|
|
3725
|
-
);
|
|
3726
|
-
}
|
|
3727
|
-
if (reactScanInfo.isPackageInstalled) {
|
|
3728
|
-
logger.log(` ${pc5.red("\u2212")} Uninstall ${migrationSource} package`);
|
|
3729
|
-
}
|
|
3730
|
-
logger.log(` ${pc5.green("+")} Install react-grab package`);
|
|
3731
|
-
if (hasAddChanges) {
|
|
3732
|
-
logger.log(
|
|
3733
|
-
` ${pc5.green("+")} Add React Grab to ${addResult.filePath}`
|
|
3734
|
-
);
|
|
3735
|
-
}
|
|
3736
|
-
if (hasRemovalChanges && hasAddChanges && removalResult.filePath === addResult.filePath) {
|
|
3737
|
-
const combinedOriginal = removalResult.originalContent;
|
|
3738
|
-
const combinedNew = addResult.newContent;
|
|
3739
|
-
logger.break();
|
|
3740
|
-
printDiff(removalResult.filePath, combinedOriginal, combinedNew);
|
|
3741
|
-
} else {
|
|
3742
|
-
if (hasRemovalChanges) {
|
|
3743
|
-
logger.break();
|
|
3744
|
-
printDiff(
|
|
3745
|
-
removalResult.filePath,
|
|
3746
|
-
removalResult.originalContent,
|
|
3747
|
-
removalResult.newContent
|
|
3748
|
-
);
|
|
3749
|
-
}
|
|
3750
|
-
if (hasAddChanges) {
|
|
3751
|
-
logger.break();
|
|
3752
|
-
printDiff(
|
|
3753
|
-
addResult.filePath,
|
|
3754
|
-
addResult.originalContent,
|
|
3755
|
-
addResult.newContent
|
|
3756
|
-
);
|
|
3757
|
-
}
|
|
3758
|
-
}
|
|
3759
|
-
logger.break();
|
|
3760
|
-
logger.warn("Auto-detection may not be 100% accurate.");
|
|
3761
|
-
logger.warn("Please verify the changes before committing.");
|
|
3762
|
-
logger.break();
|
|
3763
|
-
await confirmOrExit("Apply these changes?", isNonInteractive);
|
|
3764
|
-
if (reactScanInfo.isPackageInstalled && (hasRemovalChanges || reactScanInfo.detectedFiles.length === 0)) {
|
|
3765
|
-
uninstallPackagesWithFeedback(
|
|
3766
|
-
[migrationSource],
|
|
3767
|
-
projectInfo.packageManager,
|
|
3768
|
-
projectInfo.projectRoot
|
|
3769
|
-
);
|
|
3770
|
-
}
|
|
3771
|
-
installPackagesWithFeedback(
|
|
3772
|
-
getPackagesToInstall("none", true),
|
|
3773
|
-
projectInfo.packageManager,
|
|
3774
|
-
projectInfo.projectRoot
|
|
3775
|
-
);
|
|
3776
|
-
if (hasRemovalChanges) {
|
|
3777
|
-
applyTransformWithFeedback(
|
|
3778
|
-
removalResult,
|
|
3779
|
-
`Removing ${sourceName} from ${removalResult.filePath}.`
|
|
3780
|
-
);
|
|
3781
|
-
}
|
|
3782
|
-
if (hasAddChanges) {
|
|
3783
|
-
applyTransformWithFeedback(
|
|
3784
|
-
addResult,
|
|
3785
|
-
`Adding React Grab to ${addResult.filePath}.`
|
|
3786
|
-
);
|
|
3787
|
-
}
|
|
3788
|
-
logger.break();
|
|
3789
|
-
logger.log(`${highlighter.success("Success!")} Migration complete.`);
|
|
3790
|
-
logger.log("You may now start your development server.");
|
|
3791
|
-
logger.break();
|
|
3792
|
-
} catch (error) {
|
|
3793
|
-
handleError(error);
|
|
3794
|
-
}
|
|
3795
|
-
});
|
|
3796
|
-
var VERSION5 = "0.1.1";
|
|
3400
|
+
var VERSION4 = "0.1.3";
|
|
3797
3401
|
var remove = new Command().name("remove").description("remove an agent integration").argument(
|
|
3798
3402
|
"[agent]",
|
|
3799
3403
|
"agent to remove (claude-code, cursor, opencode, codex, gemini, amp, ami)"
|
|
@@ -3803,7 +3407,7 @@ var remove = new Command().name("remove").description("remove an agent integrati
|
|
|
3803
3407
|
process.cwd()
|
|
3804
3408
|
).action(async (agentArg, opts) => {
|
|
3805
3409
|
console.log(
|
|
3806
|
-
`${
|
|
3410
|
+
`${pc.magenta("\u273F")} ${pc.bold("React Grab")} ${pc.gray(VERSION4)}`
|
|
3807
3411
|
);
|
|
3808
3412
|
console.log();
|
|
3809
3413
|
try {
|
|
@@ -3842,7 +3446,7 @@ var remove = new Command().name("remove").description("remove an agent integrati
|
|
|
3842
3446
|
agentToRemove = agentArg;
|
|
3843
3447
|
} else if (!isNonInteractive) {
|
|
3844
3448
|
logger.break();
|
|
3845
|
-
const { agent } = await
|
|
3449
|
+
const { agent } = await prompts({
|
|
3846
3450
|
type: "select",
|
|
3847
3451
|
name: "agent",
|
|
3848
3452
|
message: `Which ${highlighter.info("agent integration")} would you like to remove?`,
|
|
@@ -3902,7 +3506,7 @@ var remove = new Command().name("remove").description("remove an agent integrati
|
|
|
3902
3506
|
}
|
|
3903
3507
|
if (!isNonInteractive) {
|
|
3904
3508
|
logger.break();
|
|
3905
|
-
const { proceed } = await
|
|
3509
|
+
const { proceed } = await prompts({
|
|
3906
3510
|
type: "confirm",
|
|
3907
3511
|
name: "proceed",
|
|
3908
3512
|
message: "Apply these changes?",
|
|
@@ -3972,7 +3576,7 @@ var remove = new Command().name("remove").description("remove an agent integrati
|
|
|
3972
3576
|
});
|
|
3973
3577
|
|
|
3974
3578
|
// src/cli.ts
|
|
3975
|
-
var
|
|
3579
|
+
var VERSION5 = "0.1.3";
|
|
3976
3580
|
var VERSION_API_URL = "https://www.react-grab.com/api/version";
|
|
3977
3581
|
process.on("SIGINT", () => process.exit(0));
|
|
3978
3582
|
process.on("SIGTERM", () => process.exit(0));
|
|
@@ -3981,12 +3585,11 @@ try {
|
|
|
3981
3585
|
});
|
|
3982
3586
|
} catch {
|
|
3983
3587
|
}
|
|
3984
|
-
var program = new Command().name("grab").description("add React Grab to your project").version(
|
|
3588
|
+
var program = new Command().name("grab").description("add React Grab to your project").version(VERSION5, "-v, --version", "display the version number");
|
|
3985
3589
|
program.addCommand(init);
|
|
3986
3590
|
program.addCommand(add);
|
|
3987
3591
|
program.addCommand(remove);
|
|
3988
3592
|
program.addCommand(configure);
|
|
3989
|
-
program.addCommand(migrate);
|
|
3990
3593
|
var main = async () => {
|
|
3991
3594
|
await program.parseAsync();
|
|
3992
3595
|
};
|