@react-grab/cli 0.1.33 → 0.1.34
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 +12 -38
- package/dist/cli.cjs +46 -31
- package/dist/cli.js +46 -31
- package/dist/cli.js.map +1 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @react-grab/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CLI for installing React Grab and configuring its activation behavior.
|
|
4
|
+
|
|
5
|
+
The CLI detects supported React projects, applies the dev-only setup, and can reconfigure an existing installation without hand-editing framework files.
|
|
4
6
|
|
|
5
7
|
## Quick Start
|
|
6
8
|
|
|
@@ -12,7 +14,7 @@ npx grab@latest init
|
|
|
12
14
|
|
|
13
15
|
### `grab init`
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Install React Grab in the current project. The CLI auto-detects the framework and applies the required development-only integration.
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
20
|
npx grab@latest init
|
|
@@ -27,35 +29,9 @@ npx grab@latest init
|
|
|
27
29
|
| `--pkg <pkg>` | | Custom package URL |
|
|
28
30
|
| `--cwd <cwd>` | `-c` | Working directory (default: current dir) |
|
|
29
31
|
|
|
30
|
-
### `grab add`
|
|
31
|
-
|
|
32
|
-
Connect React Grab to your coding agent via MCP.
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npx grab@latest add mcp
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
| Option | Alias | Description |
|
|
39
|
-
| ------------- | ----- | ---------------------------------------- |
|
|
40
|
-
| `--yes` | `-y` | Skip confirmation prompts |
|
|
41
|
-
| `--cwd <cwd>` | `-c` | Working directory (default: current dir) |
|
|
42
|
-
|
|
43
|
-
### `grab remove`
|
|
44
|
-
|
|
45
|
-
Disconnect React Grab from your coding agent.
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npx grab@latest remove mcp
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
| Option | Alias | Description |
|
|
52
|
-
| ------------- | ----- | ---------------------------------------- |
|
|
53
|
-
| `--yes` | `-y` | Skip confirmation prompts |
|
|
54
|
-
| `--cwd <cwd>` | `-c` | Working directory (default: current dir) |
|
|
55
|
-
|
|
56
32
|
### `grab configure`
|
|
57
33
|
|
|
58
|
-
|
|
34
|
+
Update React Grab options. Runs an interactive wizard when called without flags.
|
|
59
35
|
|
|
60
36
|
```bash
|
|
61
37
|
npx grab@latest configure
|
|
@@ -84,9 +60,6 @@ npx grab@latest init -y
|
|
|
84
60
|
# Set a custom activation key
|
|
85
61
|
npx grab@latest init -k "Meta+K"
|
|
86
62
|
|
|
87
|
-
# Connect MCP to your agent
|
|
88
|
-
npx grab@latest add mcp
|
|
89
|
-
|
|
90
63
|
# Change activation mode to hold
|
|
91
64
|
npx grab@latest configure --mode hold --hold-duration 500
|
|
92
65
|
|
|
@@ -96,9 +69,10 @@ npx grab@latest configure
|
|
|
96
69
|
|
|
97
70
|
## Supported Frameworks
|
|
98
71
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
72
|
+
The CLI currently configures:
|
|
73
|
+
|
|
74
|
+
- Next.js App Router
|
|
75
|
+
- Next.js Pages Router
|
|
76
|
+
- Vite
|
|
77
|
+
- TanStack Start
|
|
78
|
+
- Webpack
|
package/dist/cli.cjs
CHANGED
|
@@ -28,7 +28,7 @@ let node_fs = require("node:fs");
|
|
|
28
28
|
node_fs = __toESM(node_fs, 1);
|
|
29
29
|
let node_path = require("node:path");
|
|
30
30
|
node_path = __toESM(node_path, 1);
|
|
31
|
-
let
|
|
31
|
+
let package_manager_detector_detect = require("package-manager-detector/detect");
|
|
32
32
|
let ignore = require("ignore");
|
|
33
33
|
ignore = __toESM(ignore, 1);
|
|
34
34
|
let node_os = require("node:os");
|
|
@@ -43,7 +43,7 @@ let prompts = require("prompts");
|
|
|
43
43
|
prompts = __toESM(prompts, 1);
|
|
44
44
|
let ora = require("ora");
|
|
45
45
|
ora = __toESM(ora, 1);
|
|
46
|
-
let
|
|
46
|
+
let tinyexec = require("tinyexec");
|
|
47
47
|
//#region src/utils/is-non-interactive.ts
|
|
48
48
|
const AGENT_ENVIRONMENT_VARIABLES = [
|
|
49
49
|
"CI",
|
|
@@ -65,9 +65,9 @@ const VALID_PACKAGE_MANAGERS = new Set([
|
|
|
65
65
|
"bun"
|
|
66
66
|
]);
|
|
67
67
|
const detectPackageManager = async (projectRoot) => {
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
70
|
-
const managerName =
|
|
68
|
+
const result = await (0, package_manager_detector_detect.detect)({ cwd: projectRoot });
|
|
69
|
+
if (result?.agent) {
|
|
70
|
+
const managerName = result.agent.split("@")[0];
|
|
71
71
|
if (VALID_PACKAGE_MANAGERS.has(managerName)) return managerName;
|
|
72
72
|
}
|
|
73
73
|
return "npm";
|
|
@@ -587,7 +587,7 @@ const promptMcpInstall = async () => {
|
|
|
587
587
|
};
|
|
588
588
|
//#endregion
|
|
589
589
|
//#region src/commands/add.ts
|
|
590
|
-
const VERSION$5 = "0.1.
|
|
590
|
+
const VERSION$5 = "0.1.34";
|
|
591
591
|
const add = new commander.Command().name("add").alias("install").description("connect React Grab to your agent via MCP").argument("[agent]", "agent to connect (mcp)").option("-y, --yes", "skip confirmation prompts", false).option("-c, --cwd <cwd>", "working directory (defaults to current directory)", process.cwd()).action(async (agentArg, opts) => {
|
|
592
592
|
console.log(`${picocolors.default.magenta("✿")} ${picocolors.default.bold("React Grab")} ${picocolors.default.gray(VERSION$5)}`);
|
|
593
593
|
console.log();
|
|
@@ -1217,7 +1217,7 @@ const formatActivationKeyDisplay = (activationKey) => {
|
|
|
1217
1217
|
};
|
|
1218
1218
|
//#endregion
|
|
1219
1219
|
//#region src/commands/configure.ts
|
|
1220
|
-
const VERSION$4 = "0.1.
|
|
1220
|
+
const VERSION$4 = "0.1.34";
|
|
1221
1221
|
const isMac = process.platform === "darwin";
|
|
1222
1222
|
const META_LABEL = isMac ? "Cmd" : "Win";
|
|
1223
1223
|
const ALT_LABEL = isMac ? "Option" : "Alt";
|
|
@@ -1776,23 +1776,31 @@ const configure = new commander.Command().name("configure").alias("config").desc
|
|
|
1776
1776
|
});
|
|
1777
1777
|
//#endregion
|
|
1778
1778
|
//#region src/utils/install.ts
|
|
1779
|
-
const
|
|
1780
|
-
npm: "npm install",
|
|
1781
|
-
yarn: "yarn add",
|
|
1782
|
-
pnpm: "pnpm add",
|
|
1783
|
-
bun: "bun add"
|
|
1784
|
-
};
|
|
1785
|
-
const installPackages = (packages, packageManager, projectRoot, isDev = true) => {
|
|
1779
|
+
const installPackages = async (packages, options = {}) => {
|
|
1786
1780
|
if (packages.length === 0) return;
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1789
|
-
(
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1781
|
+
const detectedAgent = options.packageManager ?? await detectPackageManager(options.cwd ?? process.cwd());
|
|
1782
|
+
const args = [];
|
|
1783
|
+
if (options.preferOffline) args.push("--prefer-offline");
|
|
1784
|
+
if (detectedAgent === "pnpm") {
|
|
1785
|
+
args.push("--prod=false");
|
|
1786
|
+
if ((0, node_fs.existsSync)((0, node_path.resolve)(options.cwd ?? process.cwd(), "pnpm-workspace.yaml"))) args.push("-w");
|
|
1787
|
+
}
|
|
1788
|
+
if (options.additionalArgs) args.push(...options.additionalArgs);
|
|
1789
|
+
await (0, tinyexec.x)(detectedAgent, [
|
|
1790
|
+
detectedAgent === "npm" ? "install" : "add",
|
|
1791
|
+
...options.isDev !== false ? ["-D"] : [],
|
|
1792
|
+
...args,
|
|
1793
|
+
...packages
|
|
1794
|
+
], {
|
|
1795
|
+
nodeOptions: {
|
|
1796
|
+
stdio: options.silent ? "ignore" : "inherit",
|
|
1797
|
+
cwd: options.cwd,
|
|
1798
|
+
env: {
|
|
1799
|
+
...process.env,
|
|
1800
|
+
REACT_GRAB_INIT: "1"
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
throwOnError: true
|
|
1796
1804
|
});
|
|
1797
1805
|
};
|
|
1798
1806
|
const getPackagesToInstall = (includeReactGrab = true) => {
|
|
@@ -1812,11 +1820,14 @@ const applyTransformWithFeedback = (result, message) => {
|
|
|
1812
1820
|
}
|
|
1813
1821
|
writeSpinner.succeed();
|
|
1814
1822
|
};
|
|
1815
|
-
const installPackagesWithFeedback = (packages, packageManager, projectRoot) => {
|
|
1823
|
+
const installPackagesWithFeedback = async (packages, packageManager, projectRoot) => {
|
|
1816
1824
|
if (packages.length === 0) return;
|
|
1817
1825
|
const installSpinner = spinner(`Installing ${packages.join(", ")}.`).start();
|
|
1818
1826
|
try {
|
|
1819
|
-
installPackages(packages,
|
|
1827
|
+
await installPackages(packages, {
|
|
1828
|
+
packageManager,
|
|
1829
|
+
cwd: projectRoot
|
|
1830
|
+
});
|
|
1820
1831
|
installSpinner.succeed();
|
|
1821
1832
|
} catch (error) {
|
|
1822
1833
|
installSpinner.fail();
|
|
@@ -1825,7 +1836,7 @@ const installPackagesWithFeedback = (packages, packageManager, projectRoot) => {
|
|
|
1825
1836
|
};
|
|
1826
1837
|
//#endregion
|
|
1827
1838
|
//#region src/commands/init.ts
|
|
1828
|
-
const VERSION$3 = "0.1.
|
|
1839
|
+
const VERSION$3 = "0.1.34";
|
|
1829
1840
|
const REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
1830
1841
|
const DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
1831
1842
|
const reportToCli = (type, config, error) => {
|
|
@@ -2183,7 +2194,7 @@ const init = new commander.Command().name("init").alias("setup").description("in
|
|
|
2183
2194
|
}
|
|
2184
2195
|
}
|
|
2185
2196
|
const shouldInstallReactGrab = !projectInfo.hasReactGrab;
|
|
2186
|
-
if (!opts.skipInstall && shouldInstallReactGrab) installPackagesWithFeedback(getPackagesToInstall(shouldInstallReactGrab), finalPackageManager, projectInfo.projectRoot);
|
|
2197
|
+
if (!opts.skipInstall && shouldInstallReactGrab) await installPackagesWithFeedback(getPackagesToInstall(shouldInstallReactGrab), finalPackageManager, projectInfo.projectRoot);
|
|
2187
2198
|
if (hasLayoutChanges) applyTransformWithFeedback(result);
|
|
2188
2199
|
logger.break();
|
|
2189
2200
|
logger.log(`${highlighter.success("Success!")} React Grab has been installed.`);
|
|
@@ -2203,7 +2214,7 @@ const init = new commander.Command().name("init").alias("setup").description("in
|
|
|
2203
2214
|
});
|
|
2204
2215
|
//#endregion
|
|
2205
2216
|
//#region src/commands/remove.ts
|
|
2206
|
-
const VERSION$2 = "0.1.
|
|
2217
|
+
const VERSION$2 = "0.1.34";
|
|
2207
2218
|
const remove = new commander.Command().name("remove").description("disconnect React Grab from your agent").argument("[agent]", "agent to disconnect (mcp)").option("-y, --yes", "skip confirmation prompts", false).option("-c, --cwd <cwd>", "working directory (defaults to current directory)", process.cwd()).action(async (agentArg, opts) => {
|
|
2208
2219
|
console.log(`${picocolors.default.magenta("✿")} ${picocolors.default.bold("React Grab")} ${picocolors.default.gray(VERSION$2)}`);
|
|
2209
2220
|
console.log();
|
|
@@ -2233,7 +2244,7 @@ const remove = new commander.Command().name("remove").description("disconnect Re
|
|
|
2233
2244
|
});
|
|
2234
2245
|
//#endregion
|
|
2235
2246
|
//#region src/commands/upgrade.ts
|
|
2236
|
-
const VERSION$1 = "0.1.
|
|
2247
|
+
const VERSION$1 = "0.1.34";
|
|
2237
2248
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org/react-grab/latest";
|
|
2238
2249
|
const fetchLatestVersion = async () => {
|
|
2239
2250
|
try {
|
|
@@ -2286,7 +2297,11 @@ const upgrade = new commander.Command().name("upgrade").alias("update").descript
|
|
|
2286
2297
|
versionSpinner.succeed(`Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`);
|
|
2287
2298
|
const upgradeSpinner = spinner("Upgrading react-grab.").start();
|
|
2288
2299
|
try {
|
|
2289
|
-
installPackages(["react-grab@latest"],
|
|
2300
|
+
await installPackages(["react-grab@latest"], {
|
|
2301
|
+
packageManager: projectInfo.packageManager,
|
|
2302
|
+
cwd: projectInfo.projectRoot,
|
|
2303
|
+
isDev: isDevDependency(projectInfo.projectRoot)
|
|
2304
|
+
});
|
|
2290
2305
|
upgradeSpinner.succeed();
|
|
2291
2306
|
} catch {
|
|
2292
2307
|
upgradeSpinner.fail();
|
|
@@ -2304,7 +2319,7 @@ const upgrade = new commander.Command().name("upgrade").alias("update").descript
|
|
|
2304
2319
|
});
|
|
2305
2320
|
//#endregion
|
|
2306
2321
|
//#region src/cli.ts
|
|
2307
|
-
const VERSION = "0.1.
|
|
2322
|
+
const VERSION = "0.1.34";
|
|
2308
2323
|
const VERSION_API_URL = "https://www.react-grab.com/api/version";
|
|
2309
2324
|
process.on("SIGINT", () => process.exit(0));
|
|
2310
2325
|
process.on("SIGTERM", () => process.exit(0));
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from "commander";
|
|
|
3
3
|
import pc from "picocolors";
|
|
4
4
|
import fs, { accessSync, constants, existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
6
|
-
import { detect } from "
|
|
6
|
+
import { detect } from "package-manager-detector/detect";
|
|
7
7
|
import ignore from "ignore";
|
|
8
8
|
import os from "node:os";
|
|
9
9
|
import process$1 from "node:process";
|
|
@@ -11,7 +11,7 @@ import * as jsonc from "jsonc-parser";
|
|
|
11
11
|
import * as TOML from "smol-toml";
|
|
12
12
|
import basePrompts from "prompts";
|
|
13
13
|
import ora from "ora";
|
|
14
|
-
import {
|
|
14
|
+
import { x } from "tinyexec";
|
|
15
15
|
//#region src/utils/is-non-interactive.ts
|
|
16
16
|
const AGENT_ENVIRONMENT_VARIABLES = [
|
|
17
17
|
"CI",
|
|
@@ -33,9 +33,9 @@ const VALID_PACKAGE_MANAGERS = new Set([
|
|
|
33
33
|
"bun"
|
|
34
34
|
]);
|
|
35
35
|
const detectPackageManager = async (projectRoot) => {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
const managerName =
|
|
36
|
+
const result = await detect({ cwd: projectRoot });
|
|
37
|
+
if (result?.agent) {
|
|
38
|
+
const managerName = result.agent.split("@")[0];
|
|
39
39
|
if (VALID_PACKAGE_MANAGERS.has(managerName)) return managerName;
|
|
40
40
|
}
|
|
41
41
|
return "npm";
|
|
@@ -555,7 +555,7 @@ const promptMcpInstall = async () => {
|
|
|
555
555
|
};
|
|
556
556
|
//#endregion
|
|
557
557
|
//#region src/commands/add.ts
|
|
558
|
-
const VERSION$5 = "0.1.
|
|
558
|
+
const VERSION$5 = "0.1.34";
|
|
559
559
|
const add = new Command().name("add").alias("install").description("connect React Grab to your agent via MCP").argument("[agent]", "agent to connect (mcp)").option("-y, --yes", "skip confirmation prompts", false).option("-c, --cwd <cwd>", "working directory (defaults to current directory)", process.cwd()).action(async (agentArg, opts) => {
|
|
560
560
|
console.log(`${pc.magenta("✿")} ${pc.bold("React Grab")} ${pc.gray(VERSION$5)}`);
|
|
561
561
|
console.log();
|
|
@@ -1185,7 +1185,7 @@ const formatActivationKeyDisplay = (activationKey) => {
|
|
|
1185
1185
|
};
|
|
1186
1186
|
//#endregion
|
|
1187
1187
|
//#region src/commands/configure.ts
|
|
1188
|
-
const VERSION$4 = "0.1.
|
|
1188
|
+
const VERSION$4 = "0.1.34";
|
|
1189
1189
|
const isMac = process.platform === "darwin";
|
|
1190
1190
|
const META_LABEL = isMac ? "Cmd" : "Win";
|
|
1191
1191
|
const ALT_LABEL = isMac ? "Option" : "Alt";
|
|
@@ -1744,23 +1744,31 @@ const configure = new Command().name("configure").alias("config").description("c
|
|
|
1744
1744
|
});
|
|
1745
1745
|
//#endregion
|
|
1746
1746
|
//#region src/utils/install.ts
|
|
1747
|
-
const
|
|
1748
|
-
npm: "npm install",
|
|
1749
|
-
yarn: "yarn add",
|
|
1750
|
-
pnpm: "pnpm add",
|
|
1751
|
-
bun: "bun add"
|
|
1752
|
-
};
|
|
1753
|
-
const installPackages = (packages, packageManager, projectRoot, isDev = true) => {
|
|
1747
|
+
const installPackages = async (packages, options = {}) => {
|
|
1754
1748
|
if (packages.length === 0) return;
|
|
1755
|
-
const
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1749
|
+
const detectedAgent = options.packageManager ?? await detectPackageManager(options.cwd ?? process.cwd());
|
|
1750
|
+
const args = [];
|
|
1751
|
+
if (options.preferOffline) args.push("--prefer-offline");
|
|
1752
|
+
if (detectedAgent === "pnpm") {
|
|
1753
|
+
args.push("--prod=false");
|
|
1754
|
+
if (existsSync(resolve(options.cwd ?? process.cwd(), "pnpm-workspace.yaml"))) args.push("-w");
|
|
1755
|
+
}
|
|
1756
|
+
if (options.additionalArgs) args.push(...options.additionalArgs);
|
|
1757
|
+
await x(detectedAgent, [
|
|
1758
|
+
detectedAgent === "npm" ? "install" : "add",
|
|
1759
|
+
...options.isDev !== false ? ["-D"] : [],
|
|
1760
|
+
...args,
|
|
1761
|
+
...packages
|
|
1762
|
+
], {
|
|
1763
|
+
nodeOptions: {
|
|
1764
|
+
stdio: options.silent ? "ignore" : "inherit",
|
|
1765
|
+
cwd: options.cwd,
|
|
1766
|
+
env: {
|
|
1767
|
+
...process.env,
|
|
1768
|
+
REACT_GRAB_INIT: "1"
|
|
1769
|
+
}
|
|
1770
|
+
},
|
|
1771
|
+
throwOnError: true
|
|
1764
1772
|
});
|
|
1765
1773
|
};
|
|
1766
1774
|
const getPackagesToInstall = (includeReactGrab = true) => {
|
|
@@ -1780,11 +1788,14 @@ const applyTransformWithFeedback = (result, message) => {
|
|
|
1780
1788
|
}
|
|
1781
1789
|
writeSpinner.succeed();
|
|
1782
1790
|
};
|
|
1783
|
-
const installPackagesWithFeedback = (packages, packageManager, projectRoot) => {
|
|
1791
|
+
const installPackagesWithFeedback = async (packages, packageManager, projectRoot) => {
|
|
1784
1792
|
if (packages.length === 0) return;
|
|
1785
1793
|
const installSpinner = spinner(`Installing ${packages.join(", ")}.`).start();
|
|
1786
1794
|
try {
|
|
1787
|
-
installPackages(packages,
|
|
1795
|
+
await installPackages(packages, {
|
|
1796
|
+
packageManager,
|
|
1797
|
+
cwd: projectRoot
|
|
1798
|
+
});
|
|
1788
1799
|
installSpinner.succeed();
|
|
1789
1800
|
} catch (error) {
|
|
1790
1801
|
installSpinner.fail();
|
|
@@ -1793,7 +1804,7 @@ const installPackagesWithFeedback = (packages, packageManager, projectRoot) => {
|
|
|
1793
1804
|
};
|
|
1794
1805
|
//#endregion
|
|
1795
1806
|
//#region src/commands/init.ts
|
|
1796
|
-
const VERSION$3 = "0.1.
|
|
1807
|
+
const VERSION$3 = "0.1.34";
|
|
1797
1808
|
const REPORT_URL = "https://react-grab.com/api/report-cli";
|
|
1798
1809
|
const DOCS_URL = "https://github.com/aidenybai/react-grab";
|
|
1799
1810
|
const reportToCli = (type, config, error) => {
|
|
@@ -2151,7 +2162,7 @@ const init = new Command().name("init").alias("setup").description("initialize R
|
|
|
2151
2162
|
}
|
|
2152
2163
|
}
|
|
2153
2164
|
const shouldInstallReactGrab = !projectInfo.hasReactGrab;
|
|
2154
|
-
if (!opts.skipInstall && shouldInstallReactGrab) installPackagesWithFeedback(getPackagesToInstall(shouldInstallReactGrab), finalPackageManager, projectInfo.projectRoot);
|
|
2165
|
+
if (!opts.skipInstall && shouldInstallReactGrab) await installPackagesWithFeedback(getPackagesToInstall(shouldInstallReactGrab), finalPackageManager, projectInfo.projectRoot);
|
|
2155
2166
|
if (hasLayoutChanges) applyTransformWithFeedback(result);
|
|
2156
2167
|
logger.break();
|
|
2157
2168
|
logger.log(`${highlighter.success("Success!")} React Grab has been installed.`);
|
|
@@ -2171,7 +2182,7 @@ const init = new Command().name("init").alias("setup").description("initialize R
|
|
|
2171
2182
|
});
|
|
2172
2183
|
//#endregion
|
|
2173
2184
|
//#region src/commands/remove.ts
|
|
2174
|
-
const VERSION$2 = "0.1.
|
|
2185
|
+
const VERSION$2 = "0.1.34";
|
|
2175
2186
|
const remove = new Command().name("remove").description("disconnect React Grab from your agent").argument("[agent]", "agent to disconnect (mcp)").option("-y, --yes", "skip confirmation prompts", false).option("-c, --cwd <cwd>", "working directory (defaults to current directory)", process.cwd()).action(async (agentArg, opts) => {
|
|
2176
2187
|
console.log(`${pc.magenta("✿")} ${pc.bold("React Grab")} ${pc.gray(VERSION$2)}`);
|
|
2177
2188
|
console.log();
|
|
@@ -2201,7 +2212,7 @@ const remove = new Command().name("remove").description("disconnect React Grab f
|
|
|
2201
2212
|
});
|
|
2202
2213
|
//#endregion
|
|
2203
2214
|
//#region src/commands/upgrade.ts
|
|
2204
|
-
const VERSION$1 = "0.1.
|
|
2215
|
+
const VERSION$1 = "0.1.34";
|
|
2205
2216
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org/react-grab/latest";
|
|
2206
2217
|
const fetchLatestVersion = async () => {
|
|
2207
2218
|
try {
|
|
@@ -2254,7 +2265,11 @@ const upgrade = new Command().name("upgrade").alias("update").description("upgra
|
|
|
2254
2265
|
versionSpinner.succeed(`Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`);
|
|
2255
2266
|
const upgradeSpinner = spinner("Upgrading react-grab.").start();
|
|
2256
2267
|
try {
|
|
2257
|
-
installPackages(["react-grab@latest"],
|
|
2268
|
+
await installPackages(["react-grab@latest"], {
|
|
2269
|
+
packageManager: projectInfo.packageManager,
|
|
2270
|
+
cwd: projectInfo.projectRoot,
|
|
2271
|
+
isDev: isDevDependency(projectInfo.projectRoot)
|
|
2272
|
+
});
|
|
2258
2273
|
upgradeSpinner.succeed();
|
|
2259
2274
|
} catch {
|
|
2260
2275
|
upgradeSpinner.fail();
|
|
@@ -2272,7 +2287,7 @@ const upgrade = new Command().name("upgrade").alias("update").description("upgra
|
|
|
2272
2287
|
});
|
|
2273
2288
|
//#endregion
|
|
2274
2289
|
//#region src/cli.ts
|
|
2275
|
-
const VERSION = "0.1.
|
|
2290
|
+
const VERSION = "0.1.34";
|
|
2276
2291
|
const VERSION_API_URL = "https://www.react-grab.com/api/version";
|
|
2277
2292
|
process.on("SIGINT", () => process.exit(0));
|
|
2278
2293
|
process.on("SIGTERM", () => process.exit(0));
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":["process","VERSION","VERSION","VERSION","VERSION","VERSION"],"sources":["../src/utils/is-non-interactive.ts","../src/utils/detect.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/handle-error.ts","../src/utils/prompts.ts","../src/utils/spinner.ts","../src/utils/install-mcp.ts","../src/commands/add.ts","../src/utils/diff.ts","../src/utils/templates.ts","../src/utils/transform.ts","../src/utils/constants.ts","../src/utils/format-activation-key.ts","../src/commands/configure.ts","../src/utils/install.ts","../src/utils/cli-helpers.ts","../src/commands/init.ts","../src/commands/remove.ts","../src/commands/upgrade.ts","../src/cli.ts"],"sourcesContent":["const AGENT_ENVIRONMENT_VARIABLES = [\n \"CI\",\n \"CLAUDECODE\",\n \"CURSOR_AGENT\",\n \"CODEX_CI\",\n \"OPENCODE\",\n \"AMP_HOME\",\n \"AMI\",\n] as const;\n\nconst isEnvironmentVariableSet = (variable: string): boolean => Boolean(process.env[variable]);\n\nexport const detectNonInteractive = (yesFlag: boolean): boolean =>\n yesFlag || AGENT_ENVIRONMENT_VARIABLES.some(isEnvironmentVariableSet) || !process.stdin.isTTY;\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { detect } from \"@antfu/ni\";\nimport ignore from \"ignore\";\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\nexport type Framework = \"next\" | \"vite\" | \"tanstack\" | \"webpack\" | \"unknown\";\nexport type NextRouterType = \"app\" | \"pages\" | \"unknown\";\nexport type UnsupportedFramework = \"remix\" | \"astro\" | \"sveltekit\" | \"gatsby\" | null;\n\ninterface ProjectInfo {\n packageManager: PackageManager;\n framework: Framework;\n nextRouterType: NextRouterType;\n isMonorepo: boolean;\n projectRoot: string;\n hasReactGrab: boolean;\n reactGrabVersion: string | null;\n unsupportedFramework: UnsupportedFramework;\n}\n\nconst VALID_PACKAGE_MANAGERS: ReadonlySet<string> = new Set([\"npm\", \"yarn\", \"pnpm\", \"bun\"]);\n\nconst detectPackageManager = async (projectRoot: string): Promise<PackageManager> => {\n const detected = await detect({ cwd: projectRoot });\n if (detected) {\n // @antfu/ni returns versioned agents like \"pnpm@6\" or \"yarn@berry\"\n const managerName = detected.split(\"@\")[0];\n if (VALID_PACKAGE_MANAGERS.has(managerName)) {\n return managerName as PackageManager;\n }\n }\n return \"npm\";\n};\n\nexport const detectFramework = (projectRoot: string): Framework => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return \"unknown\";\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (allDependencies[\"next\"]) {\n return \"next\";\n }\n\n if (allDependencies[\"@tanstack/react-start\"]) {\n return \"tanstack\";\n }\n\n if (allDependencies[\"vite\"]) {\n return \"vite\";\n }\n\n if (allDependencies[\"webpack\"]) {\n return \"webpack\";\n }\n\n return \"unknown\";\n } catch {\n return \"unknown\";\n }\n};\n\nexport const detectNextRouterType = (projectRoot: string): NextRouterType => {\n const hasAppDir = existsSync(join(projectRoot, \"app\"));\n const hasSrcAppDir = existsSync(join(projectRoot, \"src\", \"app\"));\n const hasPagesDir = existsSync(join(projectRoot, \"pages\"));\n const hasSrcPagesDir = existsSync(join(projectRoot, \"src\", \"pages\"));\n\n if (hasAppDir || hasSrcAppDir) {\n return \"app\";\n }\n\n if (hasPagesDir || hasSrcPagesDir) {\n return \"pages\";\n }\n\n return \"unknown\";\n};\n\nexport const detectMonorepo = (projectRoot: string): boolean => {\n if (existsSync(join(projectRoot, \"pnpm-workspace.yaml\"))) {\n return true;\n }\n\n if (existsSync(join(projectRoot, \"lerna.json\"))) {\n return true;\n }\n\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.workspaces) {\n return true;\n }\n } catch {\n return false;\n }\n }\n\n return false;\n};\n\nexport interface WorkspaceProject {\n name: string;\n path: string;\n framework: Framework;\n}\n\nconst getWorkspacePatterns = (projectRoot: string): string[] => {\n const patterns: string[] = [];\n\n const pnpmWorkspacePath = join(projectRoot, \"pnpm-workspace.yaml\");\n if (existsSync(pnpmWorkspacePath)) {\n const content = readFileSync(pnpmWorkspacePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let inPackages = false;\n\n for (const line of lines) {\n if (line.match(/^packages:\\s*$/)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n if (line.match(/^[a-zA-Z]/) || line.trim() === \"\") {\n if (line.match(/^[a-zA-Z]/)) inPackages = false;\n continue;\n }\n const match = line.match(/^\\s*-\\s*['\"]?([^'\"#\\n]+?)['\"]?\\s*$/);\n if (match) {\n patterns.push(match[1].trim());\n }\n }\n }\n }\n\n const lernaJsonPath = join(projectRoot, \"lerna.json\");\n if (existsSync(lernaJsonPath)) {\n try {\n const lernaJson = JSON.parse(readFileSync(lernaJsonPath, \"utf-8\"));\n if (Array.isArray(lernaJson.packages)) {\n patterns.push(...lernaJson.packages);\n }\n } catch {}\n }\n\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (Array.isArray(packageJson.workspaces)) {\n patterns.push(...packageJson.workspaces);\n } else if (packageJson.workspaces?.packages) {\n patterns.push(...packageJson.workspaces.packages);\n }\n } catch {}\n }\n\n return [...new Set(patterns)];\n};\n\nconst expandWorkspacePattern = (projectRoot: string, pattern: string): string[] => {\n const isGlob = pattern.endsWith(\"/*\");\n const cleanPattern = pattern.replace(/\\/\\*$/, \"\");\n const basePath = join(projectRoot, cleanPattern);\n\n if (!existsSync(basePath)) return [];\n\n if (!isGlob) {\n const hasPackageJson = existsSync(join(basePath, \"package.json\"));\n return hasPackageJson ? [basePath] : [];\n }\n\n const results: string[] = [];\n try {\n const entries = readdirSync(basePath, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const packageJsonPath = join(basePath, entry.name, \"package.json\");\n if (existsSync(packageJsonPath)) {\n results.push(join(basePath, entry.name));\n }\n }\n } catch {\n return results;\n }\n return results;\n};\n\nconst hasReactDependency = (projectPath: string): boolean => {\n const packageJsonPath = join(projectPath, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n return Boolean(allDeps[\"react\"] || allDeps[\"react-dom\"]);\n } catch {\n return false;\n }\n};\n\nconst buildReactProject = (projectPath: string): WorkspaceProject | null => {\n const framework = detectFramework(projectPath);\n if (!hasReactDependency(projectPath) && framework === \"unknown\") return null;\n\n let name = basename(projectPath);\n const packageJsonPath = join(projectPath, \"package.json\");\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n name = packageJson.name || name;\n } catch {}\n\n return { name, path: projectPath, framework };\n};\n\nconst findWorkspaceProjects = (projectRoot: string): WorkspaceProject[] => {\n const patterns = getWorkspacePatterns(projectRoot);\n const projects: WorkspaceProject[] = [];\n\n for (const pattern of patterns) {\n for (const projectPath of expandWorkspacePattern(projectRoot, pattern)) {\n const project = buildReactProject(projectPath);\n if (project) projects.push(project);\n }\n }\n\n return projects;\n};\n\nconst ALWAYS_IGNORED_DIRECTORIES = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".cache\",\n \".turbo\",\n \"dist\",\n \"build\",\n \"coverage\",\n \"test-results\",\n];\n\nconst loadGitignore = (projectRoot: string): ReturnType<typeof ignore> => {\n const ignorer = ignore().add(ALWAYS_IGNORED_DIRECTORIES);\n const gitignorePath = join(projectRoot, \".gitignore\");\n if (existsSync(gitignorePath)) {\n try {\n ignorer.add(readFileSync(gitignorePath, \"utf-8\"));\n } catch {}\n }\n return ignorer;\n};\n\nconst scanDirectoryForProjects = (\n rootDirectory: string,\n ignorer: ReturnType<typeof ignore>,\n maxDepth: number,\n currentDepth: number = 0,\n): WorkspaceProject[] => {\n if (currentDepth >= maxDepth) return [];\n if (!existsSync(rootDirectory)) return [];\n\n const projects: WorkspaceProject[] = [];\n\n try {\n const entries = readdirSync(rootDirectory, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (ignorer.ignores(entry.name)) continue;\n\n const entryPath = join(rootDirectory, entry.name);\n const hasPackageJson = existsSync(join(entryPath, \"package.json\"));\n\n if (hasPackageJson) {\n const project = buildReactProject(entryPath);\n if (project) {\n projects.push(project);\n continue;\n }\n }\n\n projects.push(...scanDirectoryForProjects(entryPath, ignorer, maxDepth, currentDepth + 1));\n }\n } catch {\n return projects;\n }\n\n return projects;\n};\n\nconst MAX_SCAN_DEPTH = 2;\n\nexport const findReactProjects = (projectRoot: string): WorkspaceProject[] => {\n if (detectMonorepo(projectRoot)) {\n const workspaceProjects = findWorkspaceProjects(projectRoot);\n if (workspaceProjects.length > 0) {\n return workspaceProjects;\n }\n }\n\n const ignorer = loadGitignore(projectRoot);\n const scannedProjects = scanDirectoryForProjects(projectRoot, ignorer, MAX_SCAN_DEPTH);\n if (scannedProjects.length > 0) {\n return scannedProjects;\n }\n\n let currentDirectory = dirname(projectRoot);\n while (currentDirectory !== dirname(currentDirectory)) {\n const parentProject = buildReactProject(currentDirectory);\n if (parentProject) {\n return [parentProject];\n }\n currentDirectory = dirname(currentDirectory);\n }\n\n return [];\n};\n\nconst hasReactGrabInFile = (filePath: string): boolean => {\n if (!existsSync(filePath)) return false;\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const fuzzyPatterns = [\n /[\"'`][^\"'`]*react-grab/,\n /react-grab[^\"'`]*[\"'`]/,\n /<[^>]*react-grab/i,\n /import[^;]*react-grab/i,\n /require[^)]*react-grab/i,\n /from\\s+[^;]*react-grab/i,\n /src[^>]*react-grab/i,\n ];\n return fuzzyPatterns.some((pattern) => pattern.test(content));\n } catch {\n return false;\n }\n};\n\nexport const detectReactGrab = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n if (allDependencies[\"react-grab\"]) {\n return true;\n }\n } catch {}\n }\n\n const filesToCheck = [\n join(projectRoot, \"app\", \"layout.tsx\"),\n join(projectRoot, \"app\", \"layout.jsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.tsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.jsx\"),\n join(projectRoot, \"pages\", \"_document.tsx\"),\n join(projectRoot, \"pages\", \"_document.jsx\"),\n join(projectRoot, \"instrumentation-client.ts\"),\n join(projectRoot, \"instrumentation-client.js\"),\n join(projectRoot, \"src\", \"instrumentation-client.ts\"),\n join(projectRoot, \"src\", \"instrumentation-client.js\"),\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n join(projectRoot, \"src\", \"index.tsx\"),\n join(projectRoot, \"src\", \"index.ts\"),\n join(projectRoot, \"src\", \"main.tsx\"),\n join(projectRoot, \"src\", \"main.ts\"),\n join(projectRoot, \"src\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"src\", \"routes\", \"__root.jsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.jsx\"),\n ];\n\n return filesToCheck.some(hasReactGrabInFile);\n};\n\nexport const detectUnsupportedFramework = (projectRoot: string): UnsupportedFramework => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (allDependencies[\"@remix-run/react\"] || allDependencies[\"remix\"]) {\n return \"remix\";\n }\n\n if (allDependencies[\"astro\"]) {\n return \"astro\";\n }\n\n if (allDependencies[\"@sveltejs/kit\"]) {\n return \"sveltekit\";\n }\n\n if (allDependencies[\"gatsby\"]) {\n return \"gatsby\";\n }\n\n return null;\n } catch {\n return null;\n }\n};\n\nconst detectReactGrabVersion = (projectRoot: string): string | null => {\n const installedPackageJsonPath = join(projectRoot, \"node_modules\", \"react-grab\", \"package.json\");\n if (existsSync(installedPackageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(installedPackageJsonPath, \"utf-8\"));\n return packageJson.version ?? null;\n } catch {}\n }\n return null;\n};\n\nexport const detectProject = async (projectRoot: string = process.cwd()): Promise<ProjectInfo> => {\n const framework = detectFramework(projectRoot);\n const packageManager = await detectPackageManager(projectRoot);\n\n return {\n packageManager,\n framework,\n nextRouterType: framework === \"next\" ? detectNextRouterType(projectRoot) : \"unknown\",\n isMonorepo: detectMonorepo(projectRoot),\n projectRoot,\n hasReactGrab: detectReactGrab(projectRoot),\n reactGrabVersion: detectReactGrabVersion(projectRoot),\n unsupportedFramework: detectUnsupportedFramework(projectRoot),\n };\n};\n","import pc from \"picocolors\";\n\nexport const highlighter = {\n error: pc.red,\n warn: pc.yellow,\n info: pc.cyan,\n success: pc.green,\n dim: pc.dim,\n};\n","import { highlighter } from \"./highlighter.js\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import { logger } from \"./logger.js\";\n\nexport const handleError = (error: unknown) => {\n logger.break();\n logger.error(\"Something went wrong. Please check the error below for more details.\");\n logger.error(\"If the problem persists, please open an issue on GitHub.\");\n logger.error(\"\");\n if (error instanceof Error) {\n logger.error(error.message);\n }\n logger.break();\n process.exit(1);\n};\n","import basePrompts, { type PromptObject, type Answers } from \"prompts\";\nimport { logger } from \"./logger.js\";\n\nconst onCancel = () => {\n logger.break();\n logger.log(\"Cancelled.\");\n logger.break();\n process.exit(0);\n};\n\nexport const prompts = <T extends string = string>(\n questions: PromptObject<T> | PromptObject<T>[],\n): Promise<Answers<T>> => {\n return basePrompts(questions, { onCancel });\n};\n","import ora from \"ora\";\n\nexport const spinner = (text: string) => ora({ text });\n","import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport * as jsonc from \"jsonc-parser\";\nimport * as TOML from \"smol-toml\";\nimport { highlighter } from \"./highlighter.js\";\nimport { logger } from \"./logger.js\";\nimport { prompts } from \"./prompts.js\";\nimport { spinner } from \"./spinner.js\";\n\nconst SERVER_NAME = \"react-grab-mcp\";\nconst PACKAGE_NAME = \"@react-grab/mcp\";\n\nexport interface ClientDefinition {\n name: string;\n configPath: string;\n configKey: string;\n format: \"json\" | \"toml\";\n serverConfig: Record<string, unknown>;\n}\n\ninterface InstallResult {\n client: string;\n configPath: string;\n success: boolean;\n error?: string;\n}\n\nconst getXdgConfigHome = (): string =>\n process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\n\nconst getBaseDir = (): string => {\n const homeDir = os.homedir();\n if (process.platform === \"win32\") {\n return process.env.APPDATA || path.join(homeDir, \"AppData\", \"Roaming\");\n }\n if (process.platform === \"darwin\") {\n return path.join(homeDir, \"Library\", \"Application Support\");\n }\n return getXdgConfigHome();\n};\n\nconst getZedConfigPath = (): string => {\n if (process.platform === \"win32\") {\n return path.join(getBaseDir(), \"Zed\", \"settings.json\");\n }\n return path.join(os.homedir(), \".config\", \"zed\", \"settings.json\");\n};\n\nexport const getOpenCodeConfigPath = (): string => {\n const configDir = path.join(getXdgConfigHome(), \"opencode\");\n const jsoncPath = path.join(configDir, \"opencode.jsonc\");\n const jsonPath = path.join(configDir, \"opencode.json\");\n\n if (fs.existsSync(jsoncPath)) return jsoncPath;\n if (fs.existsSync(jsonPath)) return jsonPath;\n return jsoncPath;\n};\n\nconst getClients = (): ClientDefinition[] => {\n const homeDir = os.homedir();\n const baseDir = getBaseDir();\n\n const stdioConfig = {\n command: \"npx\",\n args: [\"-y\", PACKAGE_NAME, \"--stdio\"],\n };\n\n return [\n {\n name: \"Claude Code\",\n configPath: path.join(homeDir, \".claude.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Codex\",\n configPath: path.join(process.env.CODEX_HOME || path.join(homeDir, \".codex\"), \"config.toml\"),\n configKey: \"mcp_servers\",\n format: \"toml\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Cursor\",\n configPath: path.join(homeDir, \".cursor\", \"mcp.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"OpenCode\",\n configPath: getOpenCodeConfigPath(),\n configKey: \"mcp\",\n format: \"json\",\n serverConfig: {\n type: \"local\",\n command: [\"npx\", \"-y\", PACKAGE_NAME, \"--stdio\"],\n },\n },\n {\n name: \"VS Code\",\n configPath: path.join(baseDir, \"Code\", \"User\", \"mcp.json\"),\n configKey: \"servers\",\n format: \"json\",\n serverConfig: { type: \"stdio\", ...stdioConfig },\n },\n {\n name: \"Amp\",\n configPath: path.join(homeDir, \".config\", \"amp\", \"settings.json\"),\n configKey: \"amp.mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Droid\",\n configPath: path.join(homeDir, \".factory\", \"mcp.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: { type: \"stdio\", ...stdioConfig },\n },\n {\n name: \"Windsurf\",\n configPath: path.join(homeDir, \".codeium\", \"windsurf\", \"mcp_config.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Zed\",\n configPath: getZedConfigPath(),\n configKey: \"context_servers\",\n format: \"json\",\n serverConfig: { source: \"custom\", ...stdioConfig, env: {} },\n },\n ];\n};\n\nconst ensureDirectory = (filePath: string): void => {\n const directory = path.dirname(filePath);\n if (!fs.existsSync(directory)) {\n fs.mkdirSync(directory, { recursive: true });\n }\n};\n\nconst JSONC_FORMAT_OPTIONS: jsonc.FormattingOptions = {\n tabSize: 2,\n insertSpaces: true,\n};\n\nexport const upsertIntoJsonc = (\n filePath: string,\n content: string,\n configKey: string,\n serverName: string,\n serverConfig: Record<string, unknown>,\n): void => {\n const edits = jsonc.modify(content, [configKey, serverName], serverConfig, {\n formattingOptions: JSONC_FORMAT_OPTIONS,\n });\n fs.writeFileSync(filePath, jsonc.applyEdits(content, edits));\n};\n\nexport const installJsonClient = (client: ClientDefinition): void => {\n ensureDirectory(client.configPath);\n\n const content = fs.existsSync(client.configPath)\n ? fs.readFileSync(client.configPath, \"utf8\")\n : \"{}\";\n\n upsertIntoJsonc(client.configPath, content, client.configKey, SERVER_NAME, client.serverConfig);\n};\n\nexport const installTomlClient = (client: ClientDefinition): void => {\n ensureDirectory(client.configPath);\n\n const existingConfig: Record<string, unknown> = fs.existsSync(client.configPath)\n ? TOML.parse(fs.readFileSync(client.configPath, \"utf8\"))\n : {};\n\n const serverSection = (existingConfig[client.configKey] ?? {}) as Record<string, unknown>;\n serverSection[SERVER_NAME] = client.serverConfig;\n existingConfig[client.configKey] = serverSection;\n\n fs.writeFileSync(client.configPath, TOML.stringify(existingConfig));\n};\n\nexport const getMcpClientNames = (): string[] => getClients().map((client) => client.name);\n\nexport const installMcpServers = (selectedClients?: string[]): InstallResult[] => {\n const allClients = getClients();\n const clients = selectedClients\n ? allClients.filter((client) => selectedClients.includes(client.name))\n : allClients;\n const results: InstallResult[] = [];\n\n const installSpinner = spinner(\"Installing MCP server.\").start();\n\n for (const client of clients) {\n try {\n if (client.format === \"toml\") {\n installTomlClient(client);\n } else {\n installJsonClient(client);\n }\n results.push({\n client: client.name,\n configPath: client.configPath,\n success: true,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n results.push({\n client: client.name,\n configPath: client.configPath,\n success: false,\n error: message,\n });\n }\n }\n\n const successCount = results.filter((result) => result.success).length;\n\n if (successCount < results.length) {\n installSpinner.warn(`Installed to ${successCount}/${results.length} agents.`);\n } else {\n installSpinner.succeed(`Installed to ${successCount} agents.`);\n }\n\n for (const result of results) {\n if (result.success) {\n logger.log(\n ` ${highlighter.success(\"\\u2713\")} ${result.client} ${highlighter.dim(\"\\u2192\")} ${highlighter.dim(result.configPath)}`,\n );\n } else {\n logger.log(\n ` ${highlighter.error(\"\\u2717\")} ${result.client} ${highlighter.dim(\"\\u2192\")} ${result.error}`,\n );\n }\n }\n\n return results;\n};\n\nexport const promptMcpInstall = async (): Promise<boolean> => {\n const clientNames = getMcpClientNames();\n const { selectedAgents } = await prompts({\n type: \"multiselect\",\n name: \"selectedAgents\",\n message: \"Select agents to install MCP server for:\",\n choices: clientNames.map((name) => ({\n title: name,\n value: name,\n selected: true,\n })),\n });\n\n if (selectedAgents === undefined || selectedAgents.length === 0) {\n return false;\n }\n\n logger.break();\n const results = installMcpServers(selectedAgents);\n const hasSuccess = results.some((result) => result.success);\n return hasSuccess;\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installMcpServers, promptMcpInstall } from \"../utils/install-mcp.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const add = new Command()\n .name(\"add\")\n .alias(\"install\")\n .description(\"connect React Grab to your agent via MCP\")\n .argument(\"[agent]\", \"agent to connect (mcp)\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (agentArg, opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (agentArg && agentArg !== \"mcp\") {\n logger.break();\n logger.warn(\n `Legacy agent packages are deprecated. Use ${highlighter.info(\"mcp\")} instead.`,\n );\n logger.log(`Run ${highlighter.info(\"grab add mcp\")} to install the MCP server.`);\n logger.break();\n process.exit(1);\n }\n\n if (agentArg === \"mcp\" || isNonInteractive) {\n if (isNonInteractive) {\n const results = installMcpServers();\n const hasSuccess = results.some((result) => result.success);\n if (!hasSuccess) {\n logger.break();\n logger.error(\"Failed to install MCP server.\");\n logger.break();\n process.exit(1);\n }\n } else {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n }\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} MCP server has been configured.`);\n logger.log(\"Restart your agents to activate.\");\n logger.break();\n } else {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} MCP server has been configured.`);\n logger.log(\"Restart your agents to activate.\");\n logger.break();\n }\n } catch (error) {\n handleError(error);\n }\n });\n","interface DiffLine {\n type: \"added\" | \"removed\" | \"unchanged\";\n content: string;\n lineNumber?: number;\n}\n\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst GRAY = \"\\x1b[90m\";\nconst RESET = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\n\nexport const generateDiff = (originalContent: string, newContent: string): DiffLine[] => {\n const originalLines = originalContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const diff: DiffLine[] = [];\n\n let originalIndex = 0;\n let newIndex = 0;\n\n while (originalIndex < originalLines.length || newIndex < newLines.length) {\n const originalLine = originalLines[originalIndex];\n const newLine = newLines[newIndex];\n\n if (originalLine === newLine) {\n diff.push({\n type: \"unchanged\",\n content: originalLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n } else if (originalLine === undefined) {\n diff.push({ type: \"added\", content: newLine, lineNumber: newIndex + 1 });\n newIndex++;\n } else if (newLine === undefined) {\n diff.push({ type: \"removed\", content: originalLine });\n originalIndex++;\n } else {\n const originalInNew = newLines.indexOf(originalLine, newIndex);\n const newInOriginal = originalLines.indexOf(newLine, originalIndex);\n\n if (\n originalInNew !== -1 &&\n (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)\n ) {\n while (newIndex < originalInNew) {\n diff.push({\n type: \"added\",\n content: newLines[newIndex],\n lineNumber: newIndex + 1,\n });\n newIndex++;\n }\n } else if (newInOriginal !== -1) {\n while (originalIndex < newInOriginal) {\n diff.push({ type: \"removed\", content: originalLines[originalIndex] });\n originalIndex++;\n }\n } else {\n diff.push({ type: \"removed\", content: originalLine });\n diff.push({\n type: \"added\",\n content: newLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n }\n }\n }\n\n return diff;\n};\n\nexport const formatDiff = (diff: DiffLine[], contextLines: number = 3): string => {\n const lines: string[] = [];\n let lastPrintedIndex = -1;\n let hasChanges = false;\n\n const changedIndices = diff\n .map((line, index) => (line.type !== \"unchanged\" ? index : -1))\n .filter((index) => index !== -1);\n\n if (changedIndices.length === 0) {\n return `${GRAY}No changes${RESET}`;\n }\n\n for (const changedIndex of changedIndices) {\n const startContext = Math.max(0, changedIndex - contextLines);\n const endContext = Math.min(diff.length - 1, changedIndex + contextLines);\n\n if (startContext > lastPrintedIndex + 1 && lastPrintedIndex !== -1) {\n lines.push(`${GRAY} ...${RESET}`);\n }\n\n for (\n let lineIndex = Math.max(startContext, lastPrintedIndex + 1);\n lineIndex <= endContext;\n lineIndex++\n ) {\n const diffLine = diff[lineIndex];\n\n if (diffLine.type === \"added\") {\n lines.push(`${GREEN}+ ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else if (diffLine.type === \"removed\") {\n lines.push(`${RED}- ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else {\n lines.push(`${GRAY} ${diffLine.content}${RESET}`);\n }\n\n lastPrintedIndex = lineIndex;\n }\n }\n\n return hasChanges ? lines.join(\"\\n\") : `${GRAY}No changes${RESET}`;\n};\n\nexport const printDiff = (filePath: string, originalContent: string, newContent: string): void => {\n console.log(`\\n${BOLD}File: ${filePath}${RESET}`);\n console.log(\"─\".repeat(60));\n\n const diff = generateDiff(originalContent, newContent);\n console.log(formatDiff(diff));\n\n console.log(\"─\".repeat(60));\n};\n","export const NEXT_APP_ROUTER_SCRIPT = `{process.env.NODE_ENV === \"development\" && (\n <Script\n src=\"//unpkg.com/react-grab/dist/index.global.js\"\n crossOrigin=\"anonymous\"\n strategy=\"beforeInteractive\"\n />\n )}`;\n\nexport const VITE_IMPORT = `if (import.meta.env.DEV) {\n import(\"react-grab\");\n}`;\n\nexport const WEBPACK_IMPORT = `if (process.env.NODE_ENV === \"development\") {\n import(\"react-grab\");\n}`;\n\nexport const TANSTACK_EFFECT = `useEffect(() => {\n if (import.meta.env.DEV) {\n void import(\"react-grab\");\n }\n }, []);`;\n\nexport const SCRIPT_IMPORT = 'import Script from \"next/script\";';\n","import { accessSync, constants, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Framework, NextRouterType } from \"./detect.js\";\nimport {\n NEXT_APP_ROUTER_SCRIPT,\n SCRIPT_IMPORT,\n TANSTACK_EFFECT,\n VITE_IMPORT,\n WEBPACK_IMPORT,\n} from \"./templates.js\";\n\nexport interface TransformResult {\n success: boolean;\n filePath: string;\n message: string;\n originalContent?: string;\n newContent?: string;\n noChanges?: boolean;\n}\n\nexport interface ReactGrabOptions {\n activationKey?: string;\n activationMode?: \"toggle\" | \"hold\";\n keyHoldDuration?: number;\n allowActivationInsideInput?: boolean;\n maxContextLines?: number;\n}\n\nconst hasReactGrabCode = (content: string): boolean => {\n const fuzzyPatterns = [\n /[\"'`][^\"'`]*react-grab/,\n /react-grab[^\"'`]*[\"'`]/,\n /<[^>]*react-grab/i,\n /import[^;]*react-grab/i,\n /require[^)]*react-grab/i,\n /from\\s+[^;]*react-grab/i,\n /src[^>]*react-grab/i,\n /href[^>]*react-grab/i,\n ];\n return fuzzyPatterns.some((pattern) => pattern.test(content));\n};\n\nconst findLayoutFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"app\", \"layout.tsx\"),\n join(projectRoot, \"app\", \"layout.jsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.tsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findInstrumentationFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"instrumentation-client.ts\"),\n join(projectRoot, \"instrumentation-client.js\"),\n join(projectRoot, \"src\", \"instrumentation-client.ts\"),\n join(projectRoot, \"src\", \"instrumentation-client.js\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst hasReactGrabInInstrumentation = (projectRoot: string): boolean => {\n const instrumentationPath = findInstrumentationFile(projectRoot);\n if (!instrumentationPath) return false;\n\n const content = readFileSync(instrumentationPath, \"utf-8\");\n return hasReactGrabCode(content);\n};\n\nconst findDocumentFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"pages\", \"_document.tsx\"),\n join(projectRoot, \"pages\", \"_document.jsx\"),\n join(projectRoot, \"src\", \"pages\", \"_document.tsx\"),\n join(projectRoot, \"src\", \"pages\", \"_document.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findIndexHtml = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findEntryFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"src\", \"index.tsx\"),\n join(projectRoot, \"src\", \"index.jsx\"),\n join(projectRoot, \"src\", \"index.ts\"),\n join(projectRoot, \"src\", \"index.js\"),\n join(projectRoot, \"src\", \"main.tsx\"),\n join(projectRoot, \"src\", \"main.jsx\"),\n join(projectRoot, \"src\", \"main.ts\"),\n join(projectRoot, \"src\", \"main.js\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findTanStackRootFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"src\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"src\", \"routes\", \"__root.jsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst alreadyConfiguredResult = (filePath: string): TransformResult => ({\n success: true,\n filePath,\n message: \"React Grab is already configured\",\n noChanges: true,\n});\n\nconst transformNextAppRouter = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const layoutPath = findLayoutFile(projectRoot);\n\n if (!layoutPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find app/layout.tsx or app/layout.jsx\",\n };\n }\n\n const originalContent = readFileSync(layoutPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(layoutPath);\n }\n\n if (!force && (hasReactGrabInFile || hasReactGrabInInstrumentationFile)) {\n return {\n success: true,\n filePath: layoutPath,\n message:\n \"React Grab is already installed\" +\n (hasReactGrabInInstrumentationFile ? \" in instrumentation-client\" : \" in this file\"),\n noChanges: true,\n };\n }\n\n if (!newContent.includes('import Script from \"next/script\"')) {\n const importMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (importMatch) {\n newContent = newContent.replace(importMatch[0], `${importMatch[0]}\\n${SCRIPT_IMPORT}`);\n } else {\n newContent = `${SCRIPT_IMPORT}\\n\\n${newContent}`;\n }\n }\n\n const headMatch = newContent.match(/<head[^>]*>/);\n if (headMatch) {\n newContent = newContent.replace(\n headMatch[0],\n `${headMatch[0]}\\n ${NEXT_APP_ROUTER_SCRIPT}`,\n );\n } else {\n const htmlMatch = newContent.match(/<html[^>]*>/);\n if (htmlMatch) {\n newContent = newContent.replace(\n htmlMatch[0],\n `${htmlMatch[0]}\\n <head>\\n ${NEXT_APP_ROUTER_SCRIPT}\\n </head>`,\n );\n }\n }\n\n return {\n success: true,\n filePath: layoutPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformNextPagesRouter = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const documentPath = findDocumentFile(projectRoot);\n\n if (!documentPath) {\n return {\n success: false,\n filePath: \"\",\n message:\n \"Could not find pages/_document.tsx or pages/_document.jsx.\\n\\n\" +\n \"To set up React Grab with Pages Router, create pages/_document.tsx with:\\n\\n\" +\n ' import { Html, Head, Main, NextScript } from \"next/document\";\\n' +\n ' import Script from \"next/script\";\\n\\n' +\n \" export default function Document() {\\n\" +\n \" return (\\n\" +\n \" <Html>\\n\" +\n \" <Head>\\n\" +\n ' {process.env.NODE_ENV === \"development\" && (\\n' +\n ' <Script src=\"//unpkg.com/react-grab/dist/index.global.js\" strategy=\"beforeInteractive\" />\\n' +\n \" )}\\n\" +\n \" </Head>\\n\" +\n \" <body>\\n\" +\n \" <Main />\\n\" +\n \" <NextScript />\\n\" +\n \" </body>\\n\" +\n \" </Html>\\n\" +\n \" );\\n\" +\n \" }\",\n };\n }\n\n const originalContent = readFileSync(documentPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(documentPath);\n }\n\n if (!force && (hasReactGrabInFile || hasReactGrabInInstrumentationFile)) {\n return {\n success: true,\n filePath: documentPath,\n message:\n \"React Grab is already installed\" +\n (hasReactGrabInInstrumentationFile ? \" in instrumentation-client\" : \" in this file\"),\n noChanges: true,\n };\n }\n\n if (!newContent.includes('import Script from \"next/script\"')) {\n const importMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (importMatch) {\n newContent = newContent.replace(importMatch[0], `${importMatch[0]}\\n${SCRIPT_IMPORT}`);\n }\n }\n\n const headMatch = newContent.match(/<Head[^>]*>/);\n if (headMatch) {\n newContent = newContent.replace(\n headMatch[0],\n `${headMatch[0]}\\n ${NEXT_APP_ROUTER_SCRIPT}`,\n );\n }\n\n return {\n success: true,\n filePath: documentPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst checkExistingInstallation = (\n filePath: string,\n reactGrabAlreadyConfigured: boolean,\n): TransformResult | null => {\n const content = readFileSync(filePath, \"utf-8\");\n if (!hasReactGrabCode(content)) return null;\n\n return {\n success: true,\n filePath,\n message: reactGrabAlreadyConfigured\n ? \"React Grab is already configured\"\n : \"React Grab is already installed in this file\",\n noChanges: true,\n };\n};\n\nconst transformVite = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n if (!force) {\n const indexPath = findIndexHtml(projectRoot);\n if (indexPath) {\n const existingResult = checkExistingInstallation(indexPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n }\n\n if (!entryPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find entry file (src/index.tsx, src/main.tsx, etc.)\",\n };\n }\n\n if (!force) {\n const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n\n const originalContent = readFileSync(entryPath, \"utf-8\");\n const newContent = `${VITE_IMPORT}\\n\\n${originalContent}`;\n\n return {\n success: true,\n filePath: entryPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformWebpack = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n if (!entryPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find entry file (src/index.tsx, src/main.tsx, etc.)\",\n };\n }\n\n if (!force) {\n const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n\n const originalContent = readFileSync(entryPath, \"utf-8\");\n const newContent = `${WEBPACK_IMPORT}\\n\\n${originalContent}`;\n\n return {\n success: true,\n filePath: entryPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformTanStack = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const rootPath = findTanStackRootFile(projectRoot);\n\n if (!rootPath) {\n return {\n success: false,\n filePath: \"\",\n message:\n \"Could not find src/routes/__root.tsx or app/routes/__root.tsx.\\n\\n\" +\n \"To set up React Grab with TanStack Start, add this to your root route component:\\n\\n\" +\n ' import { useEffect } from \"react\";\\n\\n' +\n \" useEffect(() => {\\n\" +\n \" if (import.meta.env.DEV) {\\n\" +\n ' void import(\"react-grab\");\\n' +\n \" }\\n\" +\n \" }, []);\",\n };\n }\n\n const originalContent = readFileSync(rootPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(rootPath);\n }\n\n if (!force && hasReactGrabInFile) {\n return {\n success: true,\n filePath: rootPath,\n message: \"React Grab is already installed in this file\",\n noChanges: true,\n };\n }\n\n const hasUseEffectImport = /import\\s+\\{[^}]*useEffect[^}]*\\}\\s+from\\s+[\"']react[\"']/.test(\n newContent,\n );\n if (!hasUseEffectImport) {\n const reactImportMatch = newContent.match(/import\\s+\\{([^}]*)\\}\\s+from\\s+[\"']react[\"'];?/);\n if (reactImportMatch) {\n const existingImports = reactImportMatch[1];\n newContent = newContent.replace(\n reactImportMatch[0],\n `import { ${existingImports.trim()}, useEffect } from \"react\";`,\n );\n } else {\n const firstImportMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (firstImportMatch) {\n newContent = newContent.replace(\n firstImportMatch[0],\n `import { useEffect } from \"react\";\\n${firstImportMatch[0]}`,\n );\n } else {\n newContent = `import { useEffect } from \"react\";\\n\\n${newContent}`;\n }\n }\n }\n\n const componentMatch = newContent.match(/function\\s+(\\w+)\\s*\\([^)]*\\)\\s*\\{/);\n\n if (componentMatch) {\n const insertPosition = componentMatch.index! + componentMatch[0].length;\n newContent =\n newContent.slice(0, insertPosition) +\n `\\n ${TANSTACK_EFFECT}\\n` +\n newContent.slice(insertPosition);\n } else {\n return {\n success: false,\n filePath: rootPath,\n message: \"Could not find a component function in the root file\",\n };\n }\n\n return {\n success: true,\n filePath: rootPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nexport const previewTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n reactGrabAlreadyConfigured: boolean = false,\n force: boolean = false,\n): TransformResult => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return transformNextAppRouter(projectRoot, reactGrabAlreadyConfigured, force);\n }\n return transformNextPagesRouter(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"vite\":\n return transformVite(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"tanstack\":\n return transformTanStack(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"webpack\":\n return transformWebpack(projectRoot, reactGrabAlreadyConfigured, force);\n\n default:\n return {\n success: false,\n filePath: \"\",\n message: `Unknown framework: ${framework}. Please add React Grab manually.`,\n };\n }\n};\n\nconst canWriteToFile = (filePath: string): boolean => {\n try {\n accessSync(filePath, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const applyTransform = (result: TransformResult): { success: boolean; error?: string } => {\n if (result.success && result.newContent && result.filePath) {\n if (!canWriteToFile(result.filePath)) {\n return {\n success: false,\n error: `Cannot write to ${result.filePath}. Check file permissions.`,\n };\n }\n\n try {\n writeFileSync(result.filePath, result.newContent);\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: `Failed to write to ${result.filePath}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n }\n return { success: true };\n};\n\nconst formatOptionsForNextjs = (options: ReactGrabOptions): string => {\n const parts: string[] = [];\n\n if (options.activationKey) {\n parts.push(`activationKey: ${JSON.stringify(options.activationKey)}`);\n }\n\n if (options.activationMode) {\n parts.push(`activationMode: \"${options.activationMode}\"`);\n }\n\n if (options.keyHoldDuration !== undefined) {\n parts.push(`keyHoldDuration: ${options.keyHoldDuration}`);\n }\n\n if (options.allowActivationInsideInput !== undefined) {\n parts.push(`allowActivationInsideInput: ${options.allowActivationInsideInput}`);\n }\n\n if (options.maxContextLines !== undefined) {\n parts.push(`maxContextLines: ${options.maxContextLines}`);\n }\n\n return `{ ${parts.join(\", \")} }`;\n};\n\nconst formatOptionsAsJson = (options: ReactGrabOptions): string => {\n const cleanOptions: Record<string, unknown> = {};\n\n if (options.activationKey) {\n cleanOptions.activationKey = options.activationKey;\n }\n\n if (options.activationMode) {\n cleanOptions.activationMode = options.activationMode;\n }\n\n if (options.keyHoldDuration !== undefined) {\n cleanOptions.keyHoldDuration = options.keyHoldDuration;\n }\n\n if (options.allowActivationInsideInput !== undefined) {\n cleanOptions.allowActivationInsideInput = options.allowActivationInsideInput;\n }\n\n if (options.maxContextLines !== undefined) {\n cleanOptions.maxContextLines = options.maxContextLines;\n }\n\n return JSON.stringify(cleanOptions);\n};\n\nconst findReactGrabFile = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n): string | null => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return findLayoutFile(projectRoot);\n }\n return findDocumentFile(projectRoot);\n case \"vite\": {\n const entryFile = findEntryFile(projectRoot);\n if (entryFile && hasReactGrabCode(readFileSync(entryFile, \"utf-8\"))) {\n return entryFile;\n }\n const indexHtml = findIndexHtml(projectRoot);\n if (indexHtml && hasReactGrabCode(readFileSync(indexHtml, \"utf-8\"))) {\n return indexHtml;\n }\n return entryFile;\n }\n case \"tanstack\":\n return findTanStackRootFile(projectRoot);\n case \"webpack\":\n return findEntryFile(projectRoot);\n default:\n return null;\n }\n};\n\nconst addOptionsToNextScript = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabScriptMatch = originalContent.match(\n /(<Script[\\s\\S]*?react-grab[\\s\\S]*?)\\s*(\\/?>)/i,\n );\n\n if (!reactGrabScriptMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab Script tag\",\n };\n }\n\n const scriptTag = reactGrabScriptMatch[0];\n const scriptOpening = reactGrabScriptMatch[1];\n const scriptClosing = reactGrabScriptMatch[2];\n\n const existingDataOptionsMatch = scriptTag.match(/data-options=\\{JSON\\.stringify\\([^)]+\\)\\}/);\n\n const dataOptionsAttr = `data-options={JSON.stringify(\\n ${formatOptionsForNextjs(options)}\\n )}`;\n\n let newScriptTag: string;\n if (existingDataOptionsMatch) {\n newScriptTag = scriptTag.replace(existingDataOptionsMatch[0], dataOptionsAttr);\n } else {\n newScriptTag = `${scriptOpening}\\n ${dataOptionsAttr}\\n ${scriptClosing}`;\n }\n\n const newContent = originalContent.replace(scriptTag, newScriptTag);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nconst addOptionsToDynamicImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabImportWithInitMatch = originalContent.match(\n /import\\s*\\(\\s*[\"']react-grab[\"']\\s*\\)(?:\\.then\\s*\\(\\s*\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\)\\s*\\))?/,\n );\n\n if (!reactGrabImportWithInitMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab import\",\n };\n }\n\n const optionsJson = formatOptionsAsJson(options);\n const newImport = `import(\"react-grab\").then((m) => m.init(${optionsJson}))`;\n\n const newContent = originalContent.replace(reactGrabImportWithInitMatch[0], newImport);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nconst addOptionsToTanStackImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabImportWithInitMatch = originalContent.match(\n /(?: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*\\))/,\n );\n\n if (!reactGrabImportWithInitMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab import\",\n };\n }\n\n const optionsJson = formatOptionsAsJson(options);\n const newImport = `import(\"react-grab/core\").then(({ init }) => init(${optionsJson}))`;\n\n const newContent = originalContent.replace(reactGrabImportWithInitMatch[0], newImport);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nexport const previewOptionsTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n options: ReactGrabOptions,\n): TransformResult => {\n const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);\n\n if (!filePath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find file containing React Grab configuration\",\n };\n }\n\n const originalContent = readFileSync(filePath, \"utf-8\");\n\n if (!hasReactGrabCode(originalContent)) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab code in the file\",\n };\n }\n\n switch (framework) {\n case \"next\":\n return addOptionsToNextScript(originalContent, options, filePath);\n case \"vite\":\n return addOptionsToDynamicImport(originalContent, options, filePath);\n case \"tanstack\":\n return addOptionsToTanStackImport(originalContent, options, filePath);\n case \"webpack\":\n return addOptionsToDynamicImport(originalContent, options, filePath);\n default:\n return {\n success: false,\n filePath,\n message: `Unknown framework: ${framework}`,\n };\n }\n};\n\nexport const previewCdnTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n targetCdnDomain: string,\n): TransformResult => {\n const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);\n if (!filePath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find React Grab file\",\n };\n }\n const originalContent = readFileSync(filePath, \"utf-8\");\n const newContent = originalContent\n .replace(/(https?:)?\\/\\/[^/\\s\"']+(?=\\/(?:@?react-grab))/g, `//${targetCdnDomain}`)\n .replace(\n /(https?:)?\\/\\/[^/\\s\"']*react-grab[^/\\s\"']*\\.com(?=\\/script\\.js)/g,\n `//${targetCdnDomain}`,\n );\n if (newContent === originalContent) {\n return {\n success: true,\n filePath,\n message: \"CDN already set\",\n noChanges: true,\n };\n }\n return {\n success: true,\n filePath,\n message: \"Update CDN\",\n originalContent,\n newContent,\n };\n};\n","export const MAX_SUGGESTIONS_COUNT = 30;\nexport const MAX_KEY_HOLD_DURATION_MS = 2000;\nexport const MAX_CONTEXT_LINES = 50;\n","import type { ReactGrabOptions } from \"./transform.js\";\n\nexport const formatActivationKeyDisplay = (\n activationKey: ReactGrabOptions[\"activationKey\"],\n): string => {\n const defaultLabel = process.platform === \"darwin\" ? \"Option\" : \"Alt\";\n if (!activationKey) return `Default (${defaultLabel})`;\n return activationKey\n .split(\"+\")\n .map((part) => {\n const lower = part.toLowerCase();\n if (lower === \"meta\") return process.platform === \"darwin\" ? \"⌘\" : \"Win\";\n if (lower === \"alt\") return process.platform === \"darwin\" ? \"⌥\" : \"Alt\";\n if (lower === \"ctrl\") return \"Ctrl\";\n if (lower === \"shift\") return \"Shift\";\n if (lower === \"space\" || lower === \" \") return \"Space\";\n return part.toUpperCase();\n })\n .join(\" + \");\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n applyTransform,\n previewCdnTransform,\n previewOptionsTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport {\n MAX_SUGGESTIONS_COUNT,\n MAX_KEY_HOLD_DURATION_MS,\n MAX_CONTEXT_LINES,\n} from \"../utils/constants.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\ninterface ConfigOption {\n id: string;\n title: string;\n description: string;\n}\n\nconst isMac = process.platform === \"darwin\";\nconst META_LABEL = isMac ? \"Cmd\" : \"Win\";\nconst ALT_LABEL = isMac ? \"Option\" : \"Alt\";\n\nconst MODIFIER_ALIASES: Record<string, string> = {\n cmd: \"meta\",\n command: \"meta\",\n win: \"meta\",\n windows: \"meta\",\n meta: \"meta\",\n ctrl: \"ctrl\",\n control: \"ctrl\",\n shift: \"shift\",\n alt: \"alt\",\n option: \"alt\",\n opt: \"alt\",\n};\n\nconst MODIFIERS = [\"meta\", \"ctrl\", \"shift\", \"alt\"] as const;\n\nconst BASE_KEYS: Array<{ key: string; aliases: string[] }> = [\n { key: \" \", aliases: [\"space\", \"spacebar\"] },\n { key: \"Enter\", aliases: [\"enter\", \"return\"] },\n { key: \"Escape\", aliases: [\"escape\", \"esc\"] },\n { key: \"Tab\", aliases: [\"tab\"] },\n { key: \"Backspace\", aliases: [\"backspace\", \"back\"] },\n { key: \"Delete\", aliases: [\"delete\", \"del\"] },\n { key: \"Insert\", aliases: [\"insert\", \"ins\"] },\n { key: \"Home\", aliases: [\"home\"] },\n { key: \"End\", aliases: [\"end\"] },\n { key: \"PageUp\", aliases: [\"pageup\", \"pgup\"] },\n { key: \"PageDown\", aliases: [\"pagedown\", \"pgdn\", \"pgdown\"] },\n { key: \"ArrowUp\", aliases: [\"arrowup\", \"up\"] },\n { key: \"ArrowDown\", aliases: [\"arrowdown\", \"down\"] },\n { key: \"ArrowLeft\", aliases: [\"arrowleft\", \"left\"] },\n { key: \"ArrowRight\", aliases: [\"arrowright\", \"right\"] },\n ...Array.from({ length: 12 }, (_, i) => ({\n key: `F${i + 1}`,\n aliases: [`f${i + 1}`],\n })),\n ...Array.from({ length: 26 }, (_, i) => {\n const letter = String.fromCharCode(97 + i);\n return { key: letter, aliases: [letter] };\n }),\n ...Array.from({ length: 10 }, (_, i) => ({\n key: String(i),\n aliases: [String(i)],\n })),\n { key: \"`\", aliases: [\"backtick\", \"grave\", \"`\"] },\n { key: \"-\", aliases: [\"minus\", \"dash\", \"-\"] },\n { key: \"=\", aliases: [\"equals\", \"equal\", \"=\"] },\n { key: \"[\", aliases: [\"leftbracket\", \"lbracket\", \"[\"] },\n { key: \"]\", aliases: [\"rightbracket\", \"rbracket\", \"]\"] },\n { key: \"\\\\\", aliases: [\"backslash\", \"\\\\\"] },\n { key: \";\", aliases: [\"semicolon\", \";\"] },\n { key: \"'\", aliases: [\"quote\", \"apostrophe\", \"'\"] },\n { key: \",\", aliases: [\"comma\", \",\"] },\n { key: \".\", aliases: [\"period\", \"dot\", \".\"] },\n { key: \"/\", aliases: [\"slash\", \"forwardslash\", \"/\"] },\n];\n\ninterface KeyCombo {\n key: string;\n metaKey?: boolean;\n ctrlKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n}\n\ninterface KeyChoice {\n title: string;\n value: KeyCombo;\n}\n\nconst formatCombo = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(META_LABEL);\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(ALT_LABEL);\n const keyDisplay =\n combo.key === \" \" ? \"Space\" : combo.key.length === 1 ? combo.key.toUpperCase() : combo.key;\n parts.push(keyDisplay);\n return parts.join(\"+\");\n};\n\nconst parseInput = (input: string): { modifiers: Set<string>; partial: string } => {\n const normalized = input.toLowerCase().replace(/\\s+/g, \"\");\n const parts = normalized.split(/[+-]/);\n const modifiers = new Set<string>();\n let partial = \"\";\n\n for (const part of parts) {\n if (!part) continue;\n const modifierKey = MODIFIER_ALIASES[part];\n if (modifierKey) {\n modifiers.add(modifierKey);\n } else {\n partial = part;\n }\n }\n\n return { modifiers, partial };\n};\n\nconst POPULAR_KEYS = [\"g\", \"k\", \"e\", \"d\", \"b\", \" \", \"Escape\", \"Enter\"];\n\nconst generateSuggestions = (input: string): KeyChoice[] => {\n const { modifiers, partial } = parseInput(input);\n const suggestions: KeyChoice[] = [];\n\n if (!partial && modifiers.size === 0 && !input) {\n for (const mod of MODIFIERS) {\n const label =\n mod === \"meta\"\n ? META_LABEL\n : mod === \"alt\"\n ? ALT_LABEL\n : mod.charAt(0).toUpperCase() + mod.slice(1);\n for (const popularKey of POPULAR_KEYS) {\n const keyDisplay =\n popularKey === \" \"\n ? \"Space\"\n : popularKey.length === 1\n ? popularKey.toUpperCase()\n : popularKey;\n suggestions.push({\n title: `${label}+${keyDisplay}`,\n value: {\n key: popularKey,\n ...(mod === \"meta\" ? { metaKey: true } : {}),\n ...(mod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mod === \"shift\" ? { shiftKey: true } : {}),\n ...(mod === \"alt\" ? { altKey: true } : {}),\n },\n });\n }\n }\n for (const baseKey of BASE_KEYS) {\n suggestions.push({\n title:\n baseKey.key === \" \"\n ? \"Space\"\n : baseKey.key.length === 1\n ? baseKey.key.toUpperCase()\n : baseKey.key,\n value: { key: baseKey.key },\n });\n }\n return suggestions;\n }\n\n const buildCombo = (key: string, mods: Set<string>, extraMod?: string): KeyCombo => ({\n key,\n ...(mods.has(\"meta\") || extraMod === \"meta\" ? { metaKey: true } : {}),\n ...(mods.has(\"ctrl\") || extraMod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mods.has(\"shift\") || extraMod === \"shift\" ? { shiftKey: true } : {}),\n ...(mods.has(\"alt\") || extraMod === \"alt\" ? { altKey: true } : {}),\n });\n\n for (const baseKey of BASE_KEYS) {\n const matches = partial ? baseKey.aliases.some((alias) => alias.startsWith(partial)) : true;\n if (matches) {\n const combo = buildCombo(baseKey.key, modifiers);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n\n if (!partial) {\n const unusedMods = MODIFIERS.filter((m) => !modifiers.has(m));\n for (const mod of unusedMods) {\n for (const popularKey of POPULAR_KEYS) {\n const combo = buildCombo(popularKey, modifiers, mod);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n }\n\n return suggestions.slice(0, MAX_SUGGESTIONS_COUNT);\n};\n\nconst CONFIG_OPTIONS: ConfigOption[] = [\n {\n id: \"activationKey\",\n title: \"Activation Key\",\n description: \"The key used to activate React Grab (e.g., g, k, space)\",\n },\n {\n id: \"activationMode\",\n title: \"Activation Mode\",\n description: \"Toggle (press to activate/deactivate) or Hold (hold key)\",\n },\n {\n id: \"keyHoldDuration\",\n title: \"Key Hold Duration\",\n description: \"Milliseconds to hold the key before activation (hold mode)\",\n },\n {\n id: \"allowActivationInsideInput\",\n title: \"Allow Activation Inside Input\",\n description: \"Whether to allow activation when focused on input fields\",\n },\n {\n id: \"maxContextLines\",\n title: \"Max Context Lines\",\n description: \"Number of surrounding code lines to include in context\",\n },\n];\n\nconst comboToString = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(\"Meta\");\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(\"Alt\");\n if (combo.key) {\n const keyDisplay = combo.key === \" \" ? \"Space\" : combo.key;\n parts.push(keyDisplay);\n }\n return parts.join(\"+\");\n};\n\nexport const configure = new Command()\n .name(\"configure\")\n .alias(\"config\")\n .description(\"configure React Grab options\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-k, --key <key>\", \"activation key (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"-m, --mode <mode>\", \"activation mode (toggle, hold)\")\n .option(\"--hold-duration <ms>\", \"key hold duration in milliseconds (for hold mode)\")\n .option(\"--allow-input <boolean>\", \"allow activation inside input fields (true/false)\")\n .option(\"--context-lines <lines>\", \"max context lines to include\")\n .option(\"--cdn <domain>\", \"CDN domain (e.g., unpkg.com, custom.react-grab.com)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (opts.cdn) {\n const result = previewCdnTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n opts.cdn,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.break();\n process.exit(1);\n }\n\n if (result.noChanges) {\n logger.break();\n logger.log(\"No changes needed.\");\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} CDN updated.`);\n logger.break();\n return;\n }\n\n const hasFlags =\n opts.key || opts.mode || opts.holdDuration || opts.allowInput || opts.contextLines;\n\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (hasFlags) {\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (opts.mode) {\n if (opts.mode !== \"toggle\" && opts.mode !== \"hold\") {\n logger.error(`Invalid mode: ${opts.mode}. Use \"toggle\" or \"hold\".`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.activationMode = opts.mode;\n logger.log(` Activation mode: ${highlighter.info(opts.mode)}`);\n }\n\n if (opts.holdDuration) {\n const duration = parseInt(opts.holdDuration, 10);\n if (isNaN(duration) || duration < 0 || duration > MAX_KEY_HOLD_DURATION_MS) {\n logger.error(`Invalid hold duration. Must be 0-${MAX_KEY_HOLD_DURATION_MS}ms.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.keyHoldDuration = duration;\n logger.log(` Key hold duration: ${highlighter.info(`${duration}ms`)}`);\n }\n\n if (opts.allowInput !== undefined) {\n const allowInput = opts.allowInput === \"true\" || opts.allowInput === true;\n collectedOptions.allowActivationInsideInput = allowInput;\n logger.log(` Allow activation inside input: ${highlighter.info(String(allowInput))}`);\n }\n\n if (opts.contextLines) {\n const lines = parseInt(opts.contextLines, 10);\n if (isNaN(lines) || lines < 0 || lines > MAX_CONTEXT_LINES) {\n logger.error(`Invalid context lines. Must be 0-${MAX_CONTEXT_LINES}.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.maxContextLines = lines;\n logger.log(` Max context lines: ${highlighter.info(String(lines))}`);\n }\n } else {\n const { selectedOption } = await prompts({\n type: \"autocomplete\",\n name: \"selectedOption\",\n message: \"Search for an option to configure:\",\n choices: CONFIG_OPTIONS.map((option) => ({\n title: option.title,\n value: option.id,\n description: option.description,\n })),\n suggest: (input, choices) =>\n Promise.resolve(\n choices.filter(\n (choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()) ||\n (choice.description?.toLowerCase().includes(input.toLowerCase()) ?? false),\n ),\n ),\n });\n\n if (selectedOption === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (selectedOption === \"activationKey\") {\n const { selectedCombo } = await prompts({\n type: \"autocomplete\",\n name: \"selectedCombo\",\n message: \"Type key combination (e.g. ctrl+shift+g):\",\n choices: generateSuggestions(\"\"),\n suggest: (input) => Promise.resolve(generateSuggestions(input)),\n });\n\n if (selectedCombo === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = comboToString(selectedCombo);\n\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (selectedOption === \"activationMode\") {\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n }\n\n if (selectedOption === \"keyHoldDuration\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n if (selectedOption === \"allowActivationInsideInput\") {\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n }\n\n if (selectedOption === \"maxContextLines\") {\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n }\n }\n\n const result = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!result.success) {\n logger.break();\n logger.warn(result.message);\n logger.break();\n\n const configJson = JSON.stringify(collectedOptions);\n logger.log(\n `Add this to your ${highlighter.info(\"init()\")} call or ${highlighter.info(\"data-options\")} attribute:`,\n );\n logger.break();\n console.log(` ${pc.cyan(configJson)}`);\n logger.break();\n process.exit(1);\n }\n\n const hasChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasChanges) {\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n } else {\n logger.break();\n logger.log(\"No changes needed.\");\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab options have been configured.`);\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { execSync } from \"node:child_process\";\nimport type { PackageManager } from \"./detect.js\";\n\nconst INSTALL_COMMANDS: Record<PackageManager, string> = {\n npm: \"npm install\",\n yarn: \"yarn add\",\n pnpm: \"pnpm add\",\n bun: \"bun add\",\n};\n\nexport const installPackages = (\n packages: string[],\n packageManager: PackageManager,\n projectRoot: string,\n isDev: boolean = true,\n): void => {\n if (packages.length === 0) {\n return;\n }\n\n const command = INSTALL_COMMANDS[packageManager];\n const devFlag = isDev ? \" -D\" : \"\";\n const fullCommand = `${command}${devFlag} ${packages.join(\" \")}`;\n\n console.log(`Running: ${fullCommand}\\n`);\n\n execSync(fullCommand, {\n cwd: projectRoot,\n stdio: \"inherit\",\n env: { ...process.env, REACT_GRAB_INIT: \"1\" },\n });\n};\n\nexport const getPackagesToInstall = (includeReactGrab: boolean = true): string[] => {\n return includeReactGrab ? [\"react-grab\"] : [];\n};\n","import type { PackageManager } from \"./detect.js\";\nimport type { TransformResult } from \"./transform.js\";\nimport { applyTransform } from \"./transform.js\";\nimport { handleError } from \"./handle-error.js\";\nimport { installPackages } from \"./install.js\";\nimport { logger } from \"./logger.js\";\nimport { spinner } from \"./spinner.js\";\n\nexport const applyTransformWithFeedback = (result: TransformResult, message?: string): void => {\n const writeSpinner = spinner(message ?? `Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n};\n\nexport const installPackagesWithFeedback = (\n packages: string[],\n packageManager: PackageManager,\n projectRoot: string,\n): void => {\n if (packages.length === 0) return;\n const installSpinner = spinner(`Installing ${packages.join(\", \")}.`).start();\n try {\n installPackages(packages, packageManager, projectRoot);\n installSpinner.succeed();\n } catch (error) {\n installSpinner.fail();\n handleError(error);\n }\n};\n","import { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { applyTransformWithFeedback, installPackagesWithFeedback } from \"../utils/cli-helpers.js\";\nimport { promptMcpInstall } from \"../utils/install-mcp.js\";\nimport {\n detectProject,\n findReactProjects,\n type Framework,\n type PackageManager,\n type UnsupportedFramework,\n type WorkspaceProject,\n} from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { getPackagesToInstall } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n previewOptionsTransform,\n previewTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst REPORT_URL = \"https://react-grab.com/api/report-cli\";\nconst DOCS_URL = \"https://github.com/aidenybai/react-grab\";\n\ninterface ReportConfig {\n framework: string;\n packageManager: string;\n router?: string;\n agent?: string;\n isMonorepo: boolean;\n}\n\nconst reportToCli = (type: \"error\" | \"completed\", config?: ReportConfig, error?: Error): void => {\n fetch(REPORT_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n type,\n version: VERSION,\n config,\n error: error ? { message: error.message, stack: error.stack } : undefined,\n timestamp: new Date().toISOString(),\n }),\n }).catch(() => {});\n};\n\nconst FRAMEWORK_NAMES: Record<Framework, string> = {\n next: \"Next.js\",\n vite: \"Vite\",\n tanstack: \"TanStack Start\",\n webpack: \"Webpack\",\n unknown: \"Unknown\",\n};\n\nconst PACKAGE_MANAGER_NAMES: Record<PackageManager, string> = {\n npm: \"npm\",\n yarn: \"Yarn\",\n pnpm: \"pnpm\",\n bun: \"Bun\",\n};\n\nconst UNSUPPORTED_FRAMEWORK_NAMES: Record<NonNullable<UnsupportedFramework>, string> = {\n remix: \"Remix\",\n astro: \"Astro\",\n sveltekit: \"SvelteKit\",\n gatsby: \"Gatsby\",\n};\n\nconst sortProjectsByFramework = (projects: WorkspaceProject[]): WorkspaceProject[] =>\n [...projects].sort((projectA, projectB) => {\n if (projectA.framework === \"unknown\" && projectB.framework !== \"unknown\") return 1;\n if (projectA.framework !== \"unknown\" && projectB.framework === \"unknown\") return -1;\n return 0;\n });\n\nconst printSubprojects = (searchRoot: string, sortedProjects: WorkspaceProject[]): void => {\n logger.break();\n logger.log(\"Found the following projects:\");\n logger.break();\n for (const project of sortedProjects) {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n const relativePath = relative(searchRoot, project.path);\n logger.log(\n ` ${highlighter.info(project.name)}${frameworkLabel} ${highlighter.dim(relativePath)}`,\n );\n }\n logger.break();\n logger.log(`Re-run with ${highlighter.info(\"-c <path>\")} to specify a project:`);\n logger.break();\n logger.log(\n ` ${highlighter.dim(\"$\")} npx grab@latest init -c ${relative(searchRoot, sortedProjects[0].path)}`,\n );\n logger.break();\n};\n\nexport const init = new Command()\n .name(\"init\")\n .alias(\"setup\")\n .description(\"initialize React Grab in your project\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-f, --force\", \"force overwrite existing config\", false)\n .option(\"-k, --key <key>\", \"activation key (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"--skip-install\", \"skip package installation\", false)\n .option(\"--pkg <pkg>\", \"custom package URL for CLI (e.g., grab)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n if (!existsSync(cwd)) {\n logger.break();\n logger.error(`Directory does not exist: ${highlighter.info(cwd)}`);\n logger.break();\n process.exit(1);\n }\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (projectInfo.hasReactGrab && !opts.force) {\n preflightSpinner.succeed();\n\n if (isNonInteractive) {\n logger.break();\n logger.warn(\"React Grab is already installed.\");\n logger.log(\n `Use ${highlighter.info(\"--force\")} to reconfigure, or remove ${highlighter.info(\"--yes\")} for interactive mode.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.success(\"React Grab is already installed.\");\n logger.break();\n\n const { wantCustomizeOptions } = await prompts({\n type: \"confirm\",\n name: \"wantCustomizeOptions\",\n message: `Would you like to customize ${highlighter.info(\"options\")}?`,\n initial: false,\n });\n\n if (wantCustomizeOptions === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantCustomizeOptions || opts.key) {\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n } else {\n const { wantActivationKey } = await prompts({\n type: \"confirm\",\n name: \"wantActivationKey\",\n message: `Configure ${highlighter.info(\"activation key\")}?`,\n initial: false,\n });\n\n if (wantActivationKey === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantActivationKey) {\n const { key } = await prompts({\n type: \"text\",\n name: \"key\",\n message: \"Enter the activation key (e.g., g, k, space):\",\n initial: \"\",\n });\n\n if (key === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = key ? key.toLowerCase() : undefined;\n\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n }\n\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n\n if (activationMode === \"hold\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n\n const optionsResult = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!optionsResult.success) {\n logger.break();\n logger.error(optionsResult.message);\n logger.break();\n process.exit(1);\n }\n\n const hasOptionsChanges =\n !optionsResult.noChanges && optionsResult.originalContent && optionsResult.newContent;\n\n if (hasOptionsChanges) {\n logger.break();\n printDiff(\n optionsResult.filePath,\n optionsResult.originalContent!,\n optionsResult.newContent!,\n );\n\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Options configuration cancelled.\");\n } else {\n applyTransformWithFeedback(optionsResult);\n\n logger.break();\n logger.success(\"React Grab options have been configured.\");\n }\n } else {\n logger.break();\n logger.log(\"No option changes needed.\");\n }\n }\n\n logger.break();\n const { wantAddMcp } = await prompts({\n type: \"confirm\",\n name: \"wantAddMcp\",\n message: `Would you like to ${highlighter.info(\"connect it to your agent via MCP\")}?`,\n initial: false,\n });\n\n if (wantAddMcp === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantAddMcp) {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.success(\"MCP server has been configured.\");\n logger.log(\"Restart your agents to activate.\");\n }\n\n logger.break();\n process.exit(0);\n }\n\n preflightSpinner.succeed();\n\n const frameworkSpinner = spinner(\"Verifying framework.\").start();\n\n if (projectInfo.unsupportedFramework) {\n const frameworkName = UNSUPPORTED_FRAMEWORK_NAMES[projectInfo.unsupportedFramework];\n frameworkSpinner.fail(`Found ${highlighter.info(frameworkName)}.`);\n logger.break();\n logger.log(`${frameworkName} is not yet supported by automatic setup.`);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n if (projectInfo.framework === \"unknown\") {\n let searchRoot = cwd;\n let reactProjects = findReactProjects(searchRoot);\n if (reactProjects.length === 0 && cwd !== process.cwd()) {\n searchRoot = process.cwd();\n reactProjects = findReactProjects(searchRoot);\n }\n\n if (reactProjects.length > 0) {\n frameworkSpinner.info(\n `Verifying framework. Found ${reactProjects.length} project${reactProjects.length === 1 ? \"\" : \"s\"}.`,\n );\n\n const sortedProjects = sortProjectsByFramework(reactProjects);\n\n if (isNonInteractive) {\n printSubprojects(searchRoot, sortedProjects);\n process.exit(1);\n }\n\n logger.break();\n const { selectedProject } = await prompts({\n type: \"select\",\n name: \"selectedProject\",\n message: \"Select a project to install React Grab:\",\n choices: [\n ...sortedProjects.map((project) => {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n return {\n title: `${project.name}${frameworkLabel}`,\n value: project.path,\n };\n }),\n { title: \"Skip\", value: \"skip\" },\n ],\n });\n\n if (!selectedProject || selectedProject === \"skip\") {\n logger.break();\n process.exit(0);\n }\n\n process.chdir(selectedProject);\n const newProjectInfo = await detectProject(selectedProject);\n Object.assign(projectInfo, newProjectInfo);\n\n const newFrameworkSpinner = spinner(\"Verifying framework.\").start();\n newFrameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[newProjectInfo.framework])}.`,\n );\n } else {\n frameworkSpinner.fail(\"Could not detect a supported framework.\");\n logger.break();\n logger.log(\"React Grab supports Next.js, Vite, TanStack Start, and Webpack projects.\");\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n } else {\n frameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}.`,\n );\n }\n\n if (projectInfo.framework === \"next\") {\n const routerSpinner = spinner(\"Detecting router type.\").start();\n routerSpinner.succeed(\n `Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === \"app\" ? \"App Router\" : \"Pages Router\")}.`,\n );\n }\n\n const packageManagerSpinner = spinner(\"Detecting package manager.\").start();\n packageManagerSpinner.succeed(\n `Detecting package manager. Found ${highlighter.info(PACKAGE_MANAGER_NAMES[projectInfo.packageManager])}.`,\n );\n\n const finalFramework = projectInfo.framework;\n const finalPackageManager = projectInfo.packageManager;\n const finalNextRouterType = projectInfo.nextRouterType;\n let didInstallMcp = false;\n\n if (!isNonInteractive) {\n logger.break();\n const { wantAddMcp } = await prompts({\n type: \"confirm\",\n name: \"wantAddMcp\",\n message: `Would you like to ${highlighter.info(\"connect it to your agent via MCP\")}?`,\n initial: false,\n });\n\n if (wantAddMcp === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantAddMcp) {\n didInstallMcp = Boolean(await promptMcpInstall());\n if (!didInstallMcp) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.success(\"MCP server has been configured.\");\n logger.log(\"Continuing with React Grab installation...\");\n logger.break();\n }\n }\n\n const result = previewTransform(\n projectInfo.projectRoot,\n finalFramework,\n finalNextRouterType,\n false,\n opts.force,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.error(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n const hasLayoutChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasLayoutChanges) {\n logger.break();\n\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n logger.break();\n logger.warn(\"Auto-detection may not be 100% accurate.\");\n logger.warn(\"Please verify the changes before committing.\");\n\n if (!isNonInteractive) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n }\n\n const shouldInstallReactGrab = !projectInfo.hasReactGrab;\n\n if (!opts.skipInstall && shouldInstallReactGrab) {\n installPackagesWithFeedback(\n getPackagesToInstall(shouldInstallReactGrab),\n finalPackageManager,\n projectInfo.projectRoot,\n );\n }\n\n if (hasLayoutChanges) {\n applyTransformWithFeedback(result);\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab has been installed.`);\n logger.log(\"You may now start your development server.\");\n logger.break();\n\n reportToCli(\"completed\", {\n framework: finalFramework,\n packageManager: finalPackageManager,\n router: finalNextRouterType,\n agent: didInstallMcp ? \"mcp\" : undefined,\n isMonorepo: projectInfo.isMonorepo,\n });\n } catch (error) {\n handleError(error);\n reportToCli(\"error\", undefined, error as Error);\n }\n });\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const remove = new Command()\n .name(\"remove\")\n .description(\"disconnect React Grab from your agent\")\n .argument(\"[agent]\", \"agent to disconnect (mcp)\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (agentArg, opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (agentArg && agentArg !== \"mcp\") {\n logger.break();\n logger.warn(\n `Legacy agent packages are deprecated. Uninstall ${highlighter.info(`@react-grab/${agentArg}`)} manually with your package manager.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.warn(\n \"To remove the MCP server, delete the react-grab-mcp entry from your agent's MCP config file.\",\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installPackages } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/react-grab/latest\";\n\ninterface NpmPackageInfo {\n version: string;\n}\n\nconst fetchLatestVersion = async (): Promise<string | null> => {\n try {\n const response = await fetch(NPM_REGISTRY_URL);\n const data: NpmPackageInfo = await response.json();\n return data.version ?? null;\n } catch {\n return null;\n }\n};\n\nconst isDevDependency = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return true;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.devDependencies?.[\"react-grab\"]) return true;\n if (packageJson.dependencies?.[\"react-grab\"]) return false;\n } catch {}\n return true;\n};\n\nexport const upgrade = new Command()\n .name(\"upgrade\")\n .alias(\"update\")\n .description(\"upgrade react-grab to the latest version\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n\n const detectSpinner = spinner(\"Detecting project.\").start();\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n detectSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"npx grab@latest init\")} first to install React Grab.`,\n );\n logger.break();\n process.exit(1);\n }\n\n detectSpinner.succeed();\n\n const versionSpinner = spinner(\"Checking for updates.\").start();\n const latestVersion = await fetchLatestVersion();\n\n if (!latestVersion) {\n versionSpinner.fail(\"Could not check for updates.\");\n logger.break();\n logger.error(\"Failed to reach the npm registry. Check your network connection.\");\n logger.break();\n process.exit(1);\n }\n\n const installedVersion = projectInfo.reactGrabVersion;\n\n if (installedVersion && installedVersion === latestVersion) {\n versionSpinner.succeed(\n `Already on the latest version ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n process.exit(0);\n }\n\n const fromLabel = installedVersion ? `v${installedVersion}` : \"unknown\";\n versionSpinner.succeed(\n `Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`,\n );\n\n const upgradeSpinner = spinner(\"Upgrading react-grab.\").start();\n\n try {\n installPackages(\n [\"react-grab@latest\"],\n projectInfo.packageManager,\n projectInfo.projectRoot,\n isDevDependency(projectInfo.projectRoot),\n );\n upgradeSpinner.succeed();\n } catch {\n upgradeSpinner.fail();\n logger.break();\n logger.error(\"Failed to upgrade. Check your network connection and try again.\");\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n logger.log(\n `${highlighter.success(\"Success!\")} React Grab has been upgraded to ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { Command } from \"commander\";\nimport { add } from \"./commands/add.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { init } from \"./commands/init.js\";\nimport { remove } from \"./commands/remove.js\";\nimport { upgrade } from \"./commands/upgrade.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst VERSION_API_URL = \"https://www.react-grab.com/api/version\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\ntry {\n fetch(`${VERSION_API_URL}?source=cli&v=${VERSION}&t=${Date.now()}`).catch(() => {});\n} catch {}\n\nconst program = new Command()\n .name(\"grab\")\n .description(\"add React Grab to your project\")\n .version(VERSION, \"-v, --version\", \"display the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(remove);\nprogram.addCommand(configure);\nprogram.addCommand(upgrade);\n\nconst main = async () => {\n await program.parseAsync();\n};\n\nmain();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":["process","VERSION","VERSION","VERSION","VERSION","VERSION"],"sources":["../src/utils/is-non-interactive.ts","../src/utils/detect.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/handle-error.ts","../src/utils/prompts.ts","../src/utils/spinner.ts","../src/utils/install-mcp.ts","../src/commands/add.ts","../src/utils/diff.ts","../src/utils/templates.ts","../src/utils/transform.ts","../src/utils/constants.ts","../src/utils/format-activation-key.ts","../src/commands/configure.ts","../src/utils/install.ts","../src/utils/cli-helpers.ts","../src/commands/init.ts","../src/commands/remove.ts","../src/commands/upgrade.ts","../src/cli.ts"],"sourcesContent":["const AGENT_ENVIRONMENT_VARIABLES = [\n \"CI\",\n \"CLAUDECODE\",\n \"CURSOR_AGENT\",\n \"CODEX_CI\",\n \"OPENCODE\",\n \"AMP_HOME\",\n \"AMI\",\n] as const;\n\nconst isEnvironmentVariableSet = (variable: string): boolean => Boolean(process.env[variable]);\n\nexport const detectNonInteractive = (yesFlag: boolean): boolean =>\n yesFlag || AGENT_ENVIRONMENT_VARIABLES.some(isEnvironmentVariableSet) || !process.stdin.isTTY;\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { detect } from \"package-manager-detector/detect\";\nimport ignore from \"ignore\";\n\nexport type PackageManager = \"npm\" | \"yarn\" | \"pnpm\" | \"bun\";\nexport type Framework = \"next\" | \"vite\" | \"tanstack\" | \"webpack\" | \"unknown\";\nexport type NextRouterType = \"app\" | \"pages\" | \"unknown\";\nexport type UnsupportedFramework = \"remix\" | \"astro\" | \"sveltekit\" | \"gatsby\" | null;\n\ninterface ProjectInfo {\n packageManager: PackageManager;\n framework: Framework;\n nextRouterType: NextRouterType;\n isMonorepo: boolean;\n projectRoot: string;\n hasReactGrab: boolean;\n reactGrabVersion: string | null;\n unsupportedFramework: UnsupportedFramework;\n}\n\nconst VALID_PACKAGE_MANAGERS: ReadonlySet<string> = new Set([\"npm\", \"yarn\", \"pnpm\", \"bun\"]);\n\nexport const detectPackageManager = async (projectRoot: string): Promise<PackageManager> => {\n const result = await detect({ cwd: projectRoot });\n if (result?.agent) {\n const managerName = result.agent.split(\"@\")[0];\n if (VALID_PACKAGE_MANAGERS.has(managerName)) {\n return managerName as PackageManager;\n }\n }\n return \"npm\";\n};\n\nexport const detectFramework = (projectRoot: string): Framework => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return \"unknown\";\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (allDependencies[\"next\"]) {\n return \"next\";\n }\n\n if (allDependencies[\"@tanstack/react-start\"]) {\n return \"tanstack\";\n }\n\n if (allDependencies[\"vite\"]) {\n return \"vite\";\n }\n\n if (allDependencies[\"webpack\"]) {\n return \"webpack\";\n }\n\n return \"unknown\";\n } catch {\n return \"unknown\";\n }\n};\n\nexport const detectNextRouterType = (projectRoot: string): NextRouterType => {\n const hasAppDir = existsSync(join(projectRoot, \"app\"));\n const hasSrcAppDir = existsSync(join(projectRoot, \"src\", \"app\"));\n const hasPagesDir = existsSync(join(projectRoot, \"pages\"));\n const hasSrcPagesDir = existsSync(join(projectRoot, \"src\", \"pages\"));\n\n if (hasAppDir || hasSrcAppDir) {\n return \"app\";\n }\n\n if (hasPagesDir || hasSrcPagesDir) {\n return \"pages\";\n }\n\n return \"unknown\";\n};\n\nexport const detectMonorepo = (projectRoot: string): boolean => {\n if (existsSync(join(projectRoot, \"pnpm-workspace.yaml\"))) {\n return true;\n }\n\n if (existsSync(join(projectRoot, \"lerna.json\"))) {\n return true;\n }\n\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.workspaces) {\n return true;\n }\n } catch {\n return false;\n }\n }\n\n return false;\n};\n\nexport interface WorkspaceProject {\n name: string;\n path: string;\n framework: Framework;\n}\n\nconst getWorkspacePatterns = (projectRoot: string): string[] => {\n const patterns: string[] = [];\n\n const pnpmWorkspacePath = join(projectRoot, \"pnpm-workspace.yaml\");\n if (existsSync(pnpmWorkspacePath)) {\n const content = readFileSync(pnpmWorkspacePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n let inPackages = false;\n\n for (const line of lines) {\n if (line.match(/^packages:\\s*$/)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n if (line.match(/^[a-zA-Z]/) || line.trim() === \"\") {\n if (line.match(/^[a-zA-Z]/)) inPackages = false;\n continue;\n }\n const match = line.match(/^\\s*-\\s*['\"]?([^'\"#\\n]+?)['\"]?\\s*$/);\n if (match) {\n patterns.push(match[1].trim());\n }\n }\n }\n }\n\n const lernaJsonPath = join(projectRoot, \"lerna.json\");\n if (existsSync(lernaJsonPath)) {\n try {\n const lernaJson = JSON.parse(readFileSync(lernaJsonPath, \"utf-8\"));\n if (Array.isArray(lernaJson.packages)) {\n patterns.push(...lernaJson.packages);\n }\n } catch {}\n }\n\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (Array.isArray(packageJson.workspaces)) {\n patterns.push(...packageJson.workspaces);\n } else if (packageJson.workspaces?.packages) {\n patterns.push(...packageJson.workspaces.packages);\n }\n } catch {}\n }\n\n return [...new Set(patterns)];\n};\n\nconst expandWorkspacePattern = (projectRoot: string, pattern: string): string[] => {\n const isGlob = pattern.endsWith(\"/*\");\n const cleanPattern = pattern.replace(/\\/\\*$/, \"\");\n const basePath = join(projectRoot, cleanPattern);\n\n if (!existsSync(basePath)) return [];\n\n if (!isGlob) {\n const hasPackageJson = existsSync(join(basePath, \"package.json\"));\n return hasPackageJson ? [basePath] : [];\n }\n\n const results: string[] = [];\n try {\n const entries = readdirSync(basePath, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const packageJsonPath = join(basePath, entry.name, \"package.json\");\n if (existsSync(packageJsonPath)) {\n results.push(join(basePath, entry.name));\n }\n }\n } catch {\n return results;\n }\n return results;\n};\n\nconst hasReactDependency = (projectPath: string): boolean => {\n const packageJsonPath = join(projectPath, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n return Boolean(allDeps[\"react\"] || allDeps[\"react-dom\"]);\n } catch {\n return false;\n }\n};\n\nconst buildReactProject = (projectPath: string): WorkspaceProject | null => {\n const framework = detectFramework(projectPath);\n if (!hasReactDependency(projectPath) && framework === \"unknown\") return null;\n\n let name = basename(projectPath);\n const packageJsonPath = join(projectPath, \"package.json\");\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n name = packageJson.name || name;\n } catch {}\n\n return { name, path: projectPath, framework };\n};\n\nconst findWorkspaceProjects = (projectRoot: string): WorkspaceProject[] => {\n const patterns = getWorkspacePatterns(projectRoot);\n const projects: WorkspaceProject[] = [];\n\n for (const pattern of patterns) {\n for (const projectPath of expandWorkspacePattern(projectRoot, pattern)) {\n const project = buildReactProject(projectPath);\n if (project) projects.push(project);\n }\n }\n\n return projects;\n};\n\nconst ALWAYS_IGNORED_DIRECTORIES = [\n \"node_modules\",\n \".git\",\n \".next\",\n \".cache\",\n \".turbo\",\n \"dist\",\n \"build\",\n \"coverage\",\n \"test-results\",\n];\n\nconst loadGitignore = (projectRoot: string): ReturnType<typeof ignore> => {\n const ignorer = ignore().add(ALWAYS_IGNORED_DIRECTORIES);\n const gitignorePath = join(projectRoot, \".gitignore\");\n if (existsSync(gitignorePath)) {\n try {\n ignorer.add(readFileSync(gitignorePath, \"utf-8\"));\n } catch {}\n }\n return ignorer;\n};\n\nconst scanDirectoryForProjects = (\n rootDirectory: string,\n ignorer: ReturnType<typeof ignore>,\n maxDepth: number,\n currentDepth: number = 0,\n): WorkspaceProject[] => {\n if (currentDepth >= maxDepth) return [];\n if (!existsSync(rootDirectory)) return [];\n\n const projects: WorkspaceProject[] = [];\n\n try {\n const entries = readdirSync(rootDirectory, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (ignorer.ignores(entry.name)) continue;\n\n const entryPath = join(rootDirectory, entry.name);\n const hasPackageJson = existsSync(join(entryPath, \"package.json\"));\n\n if (hasPackageJson) {\n const project = buildReactProject(entryPath);\n if (project) {\n projects.push(project);\n continue;\n }\n }\n\n projects.push(...scanDirectoryForProjects(entryPath, ignorer, maxDepth, currentDepth + 1));\n }\n } catch {\n return projects;\n }\n\n return projects;\n};\n\nconst MAX_SCAN_DEPTH = 2;\n\nexport const findReactProjects = (projectRoot: string): WorkspaceProject[] => {\n if (detectMonorepo(projectRoot)) {\n const workspaceProjects = findWorkspaceProjects(projectRoot);\n if (workspaceProjects.length > 0) {\n return workspaceProjects;\n }\n }\n\n const ignorer = loadGitignore(projectRoot);\n const scannedProjects = scanDirectoryForProjects(projectRoot, ignorer, MAX_SCAN_DEPTH);\n if (scannedProjects.length > 0) {\n return scannedProjects;\n }\n\n let currentDirectory = dirname(projectRoot);\n while (currentDirectory !== dirname(currentDirectory)) {\n const parentProject = buildReactProject(currentDirectory);\n if (parentProject) {\n return [parentProject];\n }\n currentDirectory = dirname(currentDirectory);\n }\n\n return [];\n};\n\nconst hasReactGrabInFile = (filePath: string): boolean => {\n if (!existsSync(filePath)) return false;\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const fuzzyPatterns = [\n /[\"'`][^\"'`]*react-grab/,\n /react-grab[^\"'`]*[\"'`]/,\n /<[^>]*react-grab/i,\n /import[^;]*react-grab/i,\n /require[^)]*react-grab/i,\n /from\\s+[^;]*react-grab/i,\n /src[^>]*react-grab/i,\n ];\n return fuzzyPatterns.some((pattern) => pattern.test(content));\n } catch {\n return false;\n }\n};\n\nexport const detectReactGrab = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n if (allDependencies[\"react-grab\"]) {\n return true;\n }\n } catch {}\n }\n\n const filesToCheck = [\n join(projectRoot, \"app\", \"layout.tsx\"),\n join(projectRoot, \"app\", \"layout.jsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.tsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.jsx\"),\n join(projectRoot, \"pages\", \"_document.tsx\"),\n join(projectRoot, \"pages\", \"_document.jsx\"),\n join(projectRoot, \"instrumentation-client.ts\"),\n join(projectRoot, \"instrumentation-client.js\"),\n join(projectRoot, \"src\", \"instrumentation-client.ts\"),\n join(projectRoot, \"src\", \"instrumentation-client.js\"),\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n join(projectRoot, \"src\", \"index.tsx\"),\n join(projectRoot, \"src\", \"index.ts\"),\n join(projectRoot, \"src\", \"main.tsx\"),\n join(projectRoot, \"src\", \"main.ts\"),\n join(projectRoot, \"src\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"src\", \"routes\", \"__root.jsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.jsx\"),\n ];\n\n return filesToCheck.some(hasReactGrabInFile);\n};\n\nexport const detectUnsupportedFramework = (projectRoot: string): UnsupportedFramework => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n const allDependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (allDependencies[\"@remix-run/react\"] || allDependencies[\"remix\"]) {\n return \"remix\";\n }\n\n if (allDependencies[\"astro\"]) {\n return \"astro\";\n }\n\n if (allDependencies[\"@sveltejs/kit\"]) {\n return \"sveltekit\";\n }\n\n if (allDependencies[\"gatsby\"]) {\n return \"gatsby\";\n }\n\n return null;\n } catch {\n return null;\n }\n};\n\nconst detectReactGrabVersion = (projectRoot: string): string | null => {\n const installedPackageJsonPath = join(projectRoot, \"node_modules\", \"react-grab\", \"package.json\");\n if (existsSync(installedPackageJsonPath)) {\n try {\n const packageJson = JSON.parse(readFileSync(installedPackageJsonPath, \"utf-8\"));\n return packageJson.version ?? null;\n } catch {}\n }\n return null;\n};\n\nexport const detectProject = async (projectRoot: string = process.cwd()): Promise<ProjectInfo> => {\n const framework = detectFramework(projectRoot);\n const packageManager = await detectPackageManager(projectRoot);\n\n return {\n packageManager,\n framework,\n nextRouterType: framework === \"next\" ? detectNextRouterType(projectRoot) : \"unknown\",\n isMonorepo: detectMonorepo(projectRoot),\n projectRoot,\n hasReactGrab: detectReactGrab(projectRoot),\n reactGrabVersion: detectReactGrabVersion(projectRoot),\n unsupportedFramework: detectUnsupportedFramework(projectRoot),\n };\n};\n","import pc from \"picocolors\";\n\nexport const highlighter = {\n error: pc.red,\n warn: pc.yellow,\n info: pc.cyan,\n success: pc.green,\n dim: pc.dim,\n};\n","import { highlighter } from \"./highlighter.js\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import { logger } from \"./logger.js\";\n\nexport const handleError = (error: unknown) => {\n logger.break();\n logger.error(\"Something went wrong. Please check the error below for more details.\");\n logger.error(\"If the problem persists, please open an issue on GitHub.\");\n logger.error(\"\");\n if (error instanceof Error) {\n logger.error(error.message);\n }\n logger.break();\n process.exit(1);\n};\n","import basePrompts, { type PromptObject, type Answers } from \"prompts\";\nimport { logger } from \"./logger.js\";\n\nconst onCancel = () => {\n logger.break();\n logger.log(\"Cancelled.\");\n logger.break();\n process.exit(0);\n};\n\nexport const prompts = <T extends string = string>(\n questions: PromptObject<T> | PromptObject<T>[],\n): Promise<Answers<T>> => {\n return basePrompts(questions, { onCancel });\n};\n","import ora from \"ora\";\n\nexport const spinner = (text: string) => ora({ text });\n","import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport * as jsonc from \"jsonc-parser\";\nimport * as TOML from \"smol-toml\";\nimport { highlighter } from \"./highlighter.js\";\nimport { logger } from \"./logger.js\";\nimport { prompts } from \"./prompts.js\";\nimport { spinner } from \"./spinner.js\";\n\nconst SERVER_NAME = \"react-grab-mcp\";\nconst PACKAGE_NAME = \"@react-grab/mcp\";\n\nexport interface ClientDefinition {\n name: string;\n configPath: string;\n configKey: string;\n format: \"json\" | \"toml\";\n serverConfig: Record<string, unknown>;\n}\n\ninterface InstallResult {\n client: string;\n configPath: string;\n success: boolean;\n error?: string;\n}\n\nconst getXdgConfigHome = (): string =>\n process.env.XDG_CONFIG_HOME || path.join(os.homedir(), \".config\");\n\nconst getBaseDir = (): string => {\n const homeDir = os.homedir();\n if (process.platform === \"win32\") {\n return process.env.APPDATA || path.join(homeDir, \"AppData\", \"Roaming\");\n }\n if (process.platform === \"darwin\") {\n return path.join(homeDir, \"Library\", \"Application Support\");\n }\n return getXdgConfigHome();\n};\n\nconst getZedConfigPath = (): string => {\n if (process.platform === \"win32\") {\n return path.join(getBaseDir(), \"Zed\", \"settings.json\");\n }\n return path.join(os.homedir(), \".config\", \"zed\", \"settings.json\");\n};\n\nexport const getOpenCodeConfigPath = (): string => {\n const configDir = path.join(getXdgConfigHome(), \"opencode\");\n const jsoncPath = path.join(configDir, \"opencode.jsonc\");\n const jsonPath = path.join(configDir, \"opencode.json\");\n\n if (fs.existsSync(jsoncPath)) return jsoncPath;\n if (fs.existsSync(jsonPath)) return jsonPath;\n return jsoncPath;\n};\n\nconst getClients = (): ClientDefinition[] => {\n const homeDir = os.homedir();\n const baseDir = getBaseDir();\n\n const stdioConfig = {\n command: \"npx\",\n args: [\"-y\", PACKAGE_NAME, \"--stdio\"],\n };\n\n return [\n {\n name: \"Claude Code\",\n configPath: path.join(homeDir, \".claude.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Codex\",\n configPath: path.join(process.env.CODEX_HOME || path.join(homeDir, \".codex\"), \"config.toml\"),\n configKey: \"mcp_servers\",\n format: \"toml\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Cursor\",\n configPath: path.join(homeDir, \".cursor\", \"mcp.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"OpenCode\",\n configPath: getOpenCodeConfigPath(),\n configKey: \"mcp\",\n format: \"json\",\n serverConfig: {\n type: \"local\",\n command: [\"npx\", \"-y\", PACKAGE_NAME, \"--stdio\"],\n },\n },\n {\n name: \"VS Code\",\n configPath: path.join(baseDir, \"Code\", \"User\", \"mcp.json\"),\n configKey: \"servers\",\n format: \"json\",\n serverConfig: { type: \"stdio\", ...stdioConfig },\n },\n {\n name: \"Amp\",\n configPath: path.join(homeDir, \".config\", \"amp\", \"settings.json\"),\n configKey: \"amp.mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Droid\",\n configPath: path.join(homeDir, \".factory\", \"mcp.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: { type: \"stdio\", ...stdioConfig },\n },\n {\n name: \"Windsurf\",\n configPath: path.join(homeDir, \".codeium\", \"windsurf\", \"mcp_config.json\"),\n configKey: \"mcpServers\",\n format: \"json\",\n serverConfig: stdioConfig,\n },\n {\n name: \"Zed\",\n configPath: getZedConfigPath(),\n configKey: \"context_servers\",\n format: \"json\",\n serverConfig: { source: \"custom\", ...stdioConfig, env: {} },\n },\n ];\n};\n\nconst ensureDirectory = (filePath: string): void => {\n const directory = path.dirname(filePath);\n if (!fs.existsSync(directory)) {\n fs.mkdirSync(directory, { recursive: true });\n }\n};\n\nconst JSONC_FORMAT_OPTIONS: jsonc.FormattingOptions = {\n tabSize: 2,\n insertSpaces: true,\n};\n\nexport const upsertIntoJsonc = (\n filePath: string,\n content: string,\n configKey: string,\n serverName: string,\n serverConfig: Record<string, unknown>,\n): void => {\n const edits = jsonc.modify(content, [configKey, serverName], serverConfig, {\n formattingOptions: JSONC_FORMAT_OPTIONS,\n });\n fs.writeFileSync(filePath, jsonc.applyEdits(content, edits));\n};\n\nexport const installJsonClient = (client: ClientDefinition): void => {\n ensureDirectory(client.configPath);\n\n const content = fs.existsSync(client.configPath)\n ? fs.readFileSync(client.configPath, \"utf8\")\n : \"{}\";\n\n upsertIntoJsonc(client.configPath, content, client.configKey, SERVER_NAME, client.serverConfig);\n};\n\nexport const installTomlClient = (client: ClientDefinition): void => {\n ensureDirectory(client.configPath);\n\n const existingConfig: Record<string, unknown> = fs.existsSync(client.configPath)\n ? TOML.parse(fs.readFileSync(client.configPath, \"utf8\"))\n : {};\n\n const serverSection = (existingConfig[client.configKey] ?? {}) as Record<string, unknown>;\n serverSection[SERVER_NAME] = client.serverConfig;\n existingConfig[client.configKey] = serverSection;\n\n fs.writeFileSync(client.configPath, TOML.stringify(existingConfig));\n};\n\nexport const getMcpClientNames = (): string[] => getClients().map((client) => client.name);\n\nexport const installMcpServers = (selectedClients?: string[]): InstallResult[] => {\n const allClients = getClients();\n const clients = selectedClients\n ? allClients.filter((client) => selectedClients.includes(client.name))\n : allClients;\n const results: InstallResult[] = [];\n\n const installSpinner = spinner(\"Installing MCP server.\").start();\n\n for (const client of clients) {\n try {\n if (client.format === \"toml\") {\n installTomlClient(client);\n } else {\n installJsonClient(client);\n }\n results.push({\n client: client.name,\n configPath: client.configPath,\n success: true,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n results.push({\n client: client.name,\n configPath: client.configPath,\n success: false,\n error: message,\n });\n }\n }\n\n const successCount = results.filter((result) => result.success).length;\n\n if (successCount < results.length) {\n installSpinner.warn(`Installed to ${successCount}/${results.length} agents.`);\n } else {\n installSpinner.succeed(`Installed to ${successCount} agents.`);\n }\n\n for (const result of results) {\n if (result.success) {\n logger.log(\n ` ${highlighter.success(\"\\u2713\")} ${result.client} ${highlighter.dim(\"\\u2192\")} ${highlighter.dim(result.configPath)}`,\n );\n } else {\n logger.log(\n ` ${highlighter.error(\"\\u2717\")} ${result.client} ${highlighter.dim(\"\\u2192\")} ${result.error}`,\n );\n }\n }\n\n return results;\n};\n\nexport const promptMcpInstall = async (): Promise<boolean> => {\n const clientNames = getMcpClientNames();\n const { selectedAgents } = await prompts({\n type: \"multiselect\",\n name: \"selectedAgents\",\n message: \"Select agents to install MCP server for:\",\n choices: clientNames.map((name) => ({\n title: name,\n value: name,\n selected: true,\n })),\n });\n\n if (selectedAgents === undefined || selectedAgents.length === 0) {\n return false;\n }\n\n logger.break();\n const results = installMcpServers(selectedAgents);\n const hasSuccess = results.some((result) => result.success);\n return hasSuccess;\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installMcpServers, promptMcpInstall } from \"../utils/install-mcp.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const add = new Command()\n .name(\"add\")\n .alias(\"install\")\n .description(\"connect React Grab to your agent via MCP\")\n .argument(\"[agent]\", \"agent to connect (mcp)\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (agentArg, opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (agentArg && agentArg !== \"mcp\") {\n logger.break();\n logger.warn(\n `Legacy agent packages are deprecated. Use ${highlighter.info(\"mcp\")} instead.`,\n );\n logger.log(`Run ${highlighter.info(\"grab add mcp\")} to install the MCP server.`);\n logger.break();\n process.exit(1);\n }\n\n if (agentArg === \"mcp\" || isNonInteractive) {\n if (isNonInteractive) {\n const results = installMcpServers();\n const hasSuccess = results.some((result) => result.success);\n if (!hasSuccess) {\n logger.break();\n logger.error(\"Failed to install MCP server.\");\n logger.break();\n process.exit(1);\n }\n } else {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n }\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} MCP server has been configured.`);\n logger.log(\"Restart your agents to activate.\");\n logger.break();\n } else {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} MCP server has been configured.`);\n logger.log(\"Restart your agents to activate.\");\n logger.break();\n }\n } catch (error) {\n handleError(error);\n }\n });\n","interface DiffLine {\n type: \"added\" | \"removed\" | \"unchanged\";\n content: string;\n lineNumber?: number;\n}\n\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst GRAY = \"\\x1b[90m\";\nconst RESET = \"\\x1b[0m\";\nconst BOLD = \"\\x1b[1m\";\n\nexport const generateDiff = (originalContent: string, newContent: string): DiffLine[] => {\n const originalLines = originalContent.split(\"\\n\");\n const newLines = newContent.split(\"\\n\");\n const diff: DiffLine[] = [];\n\n let originalIndex = 0;\n let newIndex = 0;\n\n while (originalIndex < originalLines.length || newIndex < newLines.length) {\n const originalLine = originalLines[originalIndex];\n const newLine = newLines[newIndex];\n\n if (originalLine === newLine) {\n diff.push({\n type: \"unchanged\",\n content: originalLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n } else if (originalLine === undefined) {\n diff.push({ type: \"added\", content: newLine, lineNumber: newIndex + 1 });\n newIndex++;\n } else if (newLine === undefined) {\n diff.push({ type: \"removed\", content: originalLine });\n originalIndex++;\n } else {\n const originalInNew = newLines.indexOf(originalLine, newIndex);\n const newInOriginal = originalLines.indexOf(newLine, originalIndex);\n\n if (\n originalInNew !== -1 &&\n (newInOriginal === -1 || originalInNew - newIndex < newInOriginal - originalIndex)\n ) {\n while (newIndex < originalInNew) {\n diff.push({\n type: \"added\",\n content: newLines[newIndex],\n lineNumber: newIndex + 1,\n });\n newIndex++;\n }\n } else if (newInOriginal !== -1) {\n while (originalIndex < newInOriginal) {\n diff.push({ type: \"removed\", content: originalLines[originalIndex] });\n originalIndex++;\n }\n } else {\n diff.push({ type: \"removed\", content: originalLine });\n diff.push({\n type: \"added\",\n content: newLine,\n lineNumber: newIndex + 1,\n });\n originalIndex++;\n newIndex++;\n }\n }\n }\n\n return diff;\n};\n\nexport const formatDiff = (diff: DiffLine[], contextLines: number = 3): string => {\n const lines: string[] = [];\n let lastPrintedIndex = -1;\n let hasChanges = false;\n\n const changedIndices = diff\n .map((line, index) => (line.type !== \"unchanged\" ? index : -1))\n .filter((index) => index !== -1);\n\n if (changedIndices.length === 0) {\n return `${GRAY}No changes${RESET}`;\n }\n\n for (const changedIndex of changedIndices) {\n const startContext = Math.max(0, changedIndex - contextLines);\n const endContext = Math.min(diff.length - 1, changedIndex + contextLines);\n\n if (startContext > lastPrintedIndex + 1 && lastPrintedIndex !== -1) {\n lines.push(`${GRAY} ...${RESET}`);\n }\n\n for (\n let lineIndex = Math.max(startContext, lastPrintedIndex + 1);\n lineIndex <= endContext;\n lineIndex++\n ) {\n const diffLine = diff[lineIndex];\n\n if (diffLine.type === \"added\") {\n lines.push(`${GREEN}+ ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else if (diffLine.type === \"removed\") {\n lines.push(`${RED}- ${diffLine.content}${RESET}`);\n hasChanges = true;\n } else {\n lines.push(`${GRAY} ${diffLine.content}${RESET}`);\n }\n\n lastPrintedIndex = lineIndex;\n }\n }\n\n return hasChanges ? lines.join(\"\\n\") : `${GRAY}No changes${RESET}`;\n};\n\nexport const printDiff = (filePath: string, originalContent: string, newContent: string): void => {\n console.log(`\\n${BOLD}File: ${filePath}${RESET}`);\n console.log(\"─\".repeat(60));\n\n const diff = generateDiff(originalContent, newContent);\n console.log(formatDiff(diff));\n\n console.log(\"─\".repeat(60));\n};\n","export const NEXT_APP_ROUTER_SCRIPT = `{process.env.NODE_ENV === \"development\" && (\n <Script\n src=\"//unpkg.com/react-grab/dist/index.global.js\"\n crossOrigin=\"anonymous\"\n strategy=\"beforeInteractive\"\n />\n )}`;\n\nexport const VITE_IMPORT = `if (import.meta.env.DEV) {\n import(\"react-grab\");\n}`;\n\nexport const WEBPACK_IMPORT = `if (process.env.NODE_ENV === \"development\") {\n import(\"react-grab\");\n}`;\n\nexport const TANSTACK_EFFECT = `useEffect(() => {\n if (import.meta.env.DEV) {\n void import(\"react-grab\");\n }\n }, []);`;\n\nexport const SCRIPT_IMPORT = 'import Script from \"next/script\";';\n","import { accessSync, constants, existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Framework, NextRouterType } from \"./detect.js\";\nimport {\n NEXT_APP_ROUTER_SCRIPT,\n SCRIPT_IMPORT,\n TANSTACK_EFFECT,\n VITE_IMPORT,\n WEBPACK_IMPORT,\n} from \"./templates.js\";\n\nexport interface TransformResult {\n success: boolean;\n filePath: string;\n message: string;\n originalContent?: string;\n newContent?: string;\n noChanges?: boolean;\n}\n\nexport interface ReactGrabOptions {\n activationKey?: string;\n activationMode?: \"toggle\" | \"hold\";\n keyHoldDuration?: number;\n allowActivationInsideInput?: boolean;\n maxContextLines?: number;\n}\n\nconst hasReactGrabCode = (content: string): boolean => {\n const fuzzyPatterns = [\n /[\"'`][^\"'`]*react-grab/,\n /react-grab[^\"'`]*[\"'`]/,\n /<[^>]*react-grab/i,\n /import[^;]*react-grab/i,\n /require[^)]*react-grab/i,\n /from\\s+[^;]*react-grab/i,\n /src[^>]*react-grab/i,\n /href[^>]*react-grab/i,\n ];\n return fuzzyPatterns.some((pattern) => pattern.test(content));\n};\n\nconst findLayoutFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"app\", \"layout.tsx\"),\n join(projectRoot, \"app\", \"layout.jsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.tsx\"),\n join(projectRoot, \"src\", \"app\", \"layout.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findInstrumentationFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"instrumentation-client.ts\"),\n join(projectRoot, \"instrumentation-client.js\"),\n join(projectRoot, \"src\", \"instrumentation-client.ts\"),\n join(projectRoot, \"src\", \"instrumentation-client.js\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst hasReactGrabInInstrumentation = (projectRoot: string): boolean => {\n const instrumentationPath = findInstrumentationFile(projectRoot);\n if (!instrumentationPath) return false;\n\n const content = readFileSync(instrumentationPath, \"utf-8\");\n return hasReactGrabCode(content);\n};\n\nconst findDocumentFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"pages\", \"_document.tsx\"),\n join(projectRoot, \"pages\", \"_document.jsx\"),\n join(projectRoot, \"src\", \"pages\", \"_document.tsx\"),\n join(projectRoot, \"src\", \"pages\", \"_document.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findIndexHtml = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findEntryFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"src\", \"index.tsx\"),\n join(projectRoot, \"src\", \"index.jsx\"),\n join(projectRoot, \"src\", \"index.ts\"),\n join(projectRoot, \"src\", \"index.js\"),\n join(projectRoot, \"src\", \"main.tsx\"),\n join(projectRoot, \"src\", \"main.jsx\"),\n join(projectRoot, \"src\", \"main.ts\"),\n join(projectRoot, \"src\", \"main.js\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst findTanStackRootFile = (projectRoot: string): string | null => {\n const possiblePaths = [\n join(projectRoot, \"src\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"src\", \"routes\", \"__root.jsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.tsx\"),\n join(projectRoot, \"app\", \"routes\", \"__root.jsx\"),\n ];\n\n for (const filePath of possiblePaths) {\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n};\n\nconst alreadyConfiguredResult = (filePath: string): TransformResult => ({\n success: true,\n filePath,\n message: \"React Grab is already configured\",\n noChanges: true,\n});\n\nconst transformNextAppRouter = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const layoutPath = findLayoutFile(projectRoot);\n\n if (!layoutPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find app/layout.tsx or app/layout.jsx\",\n };\n }\n\n const originalContent = readFileSync(layoutPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(layoutPath);\n }\n\n if (!force && (hasReactGrabInFile || hasReactGrabInInstrumentationFile)) {\n return {\n success: true,\n filePath: layoutPath,\n message:\n \"React Grab is already installed\" +\n (hasReactGrabInInstrumentationFile ? \" in instrumentation-client\" : \" in this file\"),\n noChanges: true,\n };\n }\n\n if (!newContent.includes('import Script from \"next/script\"')) {\n const importMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (importMatch) {\n newContent = newContent.replace(importMatch[0], `${importMatch[0]}\\n${SCRIPT_IMPORT}`);\n } else {\n newContent = `${SCRIPT_IMPORT}\\n\\n${newContent}`;\n }\n }\n\n const headMatch = newContent.match(/<head[^>]*>/);\n if (headMatch) {\n newContent = newContent.replace(\n headMatch[0],\n `${headMatch[0]}\\n ${NEXT_APP_ROUTER_SCRIPT}`,\n );\n } else {\n const htmlMatch = newContent.match(/<html[^>]*>/);\n if (htmlMatch) {\n newContent = newContent.replace(\n htmlMatch[0],\n `${htmlMatch[0]}\\n <head>\\n ${NEXT_APP_ROUTER_SCRIPT}\\n </head>`,\n );\n }\n }\n\n return {\n success: true,\n filePath: layoutPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformNextPagesRouter = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const documentPath = findDocumentFile(projectRoot);\n\n if (!documentPath) {\n return {\n success: false,\n filePath: \"\",\n message:\n \"Could not find pages/_document.tsx or pages/_document.jsx.\\n\\n\" +\n \"To set up React Grab with Pages Router, create pages/_document.tsx with:\\n\\n\" +\n ' import { Html, Head, Main, NextScript } from \"next/document\";\\n' +\n ' import Script from \"next/script\";\\n\\n' +\n \" export default function Document() {\\n\" +\n \" return (\\n\" +\n \" <Html>\\n\" +\n \" <Head>\\n\" +\n ' {process.env.NODE_ENV === \"development\" && (\\n' +\n ' <Script src=\"//unpkg.com/react-grab/dist/index.global.js\" strategy=\"beforeInteractive\" />\\n' +\n \" )}\\n\" +\n \" </Head>\\n\" +\n \" <body>\\n\" +\n \" <Main />\\n\" +\n \" <NextScript />\\n\" +\n \" </body>\\n\" +\n \" </Html>\\n\" +\n \" );\\n\" +\n \" }\",\n };\n }\n\n const originalContent = readFileSync(documentPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(documentPath);\n }\n\n if (!force && (hasReactGrabInFile || hasReactGrabInInstrumentationFile)) {\n return {\n success: true,\n filePath: documentPath,\n message:\n \"React Grab is already installed\" +\n (hasReactGrabInInstrumentationFile ? \" in instrumentation-client\" : \" in this file\"),\n noChanges: true,\n };\n }\n\n if (!newContent.includes('import Script from \"next/script\"')) {\n const importMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (importMatch) {\n newContent = newContent.replace(importMatch[0], `${importMatch[0]}\\n${SCRIPT_IMPORT}`);\n }\n }\n\n const headMatch = newContent.match(/<Head[^>]*>/);\n if (headMatch) {\n newContent = newContent.replace(\n headMatch[0],\n `${headMatch[0]}\\n ${NEXT_APP_ROUTER_SCRIPT}`,\n );\n }\n\n return {\n success: true,\n filePath: documentPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst checkExistingInstallation = (\n filePath: string,\n reactGrabAlreadyConfigured: boolean,\n): TransformResult | null => {\n const content = readFileSync(filePath, \"utf-8\");\n if (!hasReactGrabCode(content)) return null;\n\n return {\n success: true,\n filePath,\n message: reactGrabAlreadyConfigured\n ? \"React Grab is already configured\"\n : \"React Grab is already installed in this file\",\n noChanges: true,\n };\n};\n\nconst transformVite = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n if (!force) {\n const indexPath = findIndexHtml(projectRoot);\n if (indexPath) {\n const existingResult = checkExistingInstallation(indexPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n }\n\n if (!entryPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find entry file (src/index.tsx, src/main.tsx, etc.)\",\n };\n }\n\n if (!force) {\n const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n\n const originalContent = readFileSync(entryPath, \"utf-8\");\n const newContent = `${VITE_IMPORT}\\n\\n${originalContent}`;\n\n return {\n success: true,\n filePath: entryPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformWebpack = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n if (!entryPath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find entry file (src/index.tsx, src/main.tsx, etc.)\",\n };\n }\n\n if (!force) {\n const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\n }\n\n const originalContent = readFileSync(entryPath, \"utf-8\");\n const newContent = `${WEBPACK_IMPORT}\\n\\n${originalContent}`;\n\n return {\n success: true,\n filePath: entryPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nconst transformTanStack = (\n projectRoot: string,\n reactGrabAlreadyConfigured: boolean,\n force: boolean = false,\n): TransformResult => {\n const rootPath = findTanStackRootFile(projectRoot);\n\n if (!rootPath) {\n return {\n success: false,\n filePath: \"\",\n message:\n \"Could not find src/routes/__root.tsx or app/routes/__root.tsx.\\n\\n\" +\n \"To set up React Grab with TanStack Start, add this to your root route component:\\n\\n\" +\n ' import { useEffect } from \"react\";\\n\\n' +\n \" useEffect(() => {\\n\" +\n \" if (import.meta.env.DEV) {\\n\" +\n ' void import(\"react-grab\");\\n' +\n \" }\\n\" +\n \" }, []);\",\n };\n }\n\n const originalContent = readFileSync(rootPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabCode(originalContent);\n\n if (!force && hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(rootPath);\n }\n\n if (!force && hasReactGrabInFile) {\n return {\n success: true,\n filePath: rootPath,\n message: \"React Grab is already installed in this file\",\n noChanges: true,\n };\n }\n\n const hasUseEffectImport = /import\\s+\\{[^}]*useEffect[^}]*\\}\\s+from\\s+[\"']react[\"']/.test(\n newContent,\n );\n if (!hasUseEffectImport) {\n const reactImportMatch = newContent.match(/import\\s+\\{([^}]*)\\}\\s+from\\s+[\"']react[\"'];?/);\n if (reactImportMatch) {\n const existingImports = reactImportMatch[1];\n newContent = newContent.replace(\n reactImportMatch[0],\n `import { ${existingImports.trim()}, useEffect } from \"react\";`,\n );\n } else {\n const firstImportMatch = newContent.match(/^import .+ from ['\"].+['\"];?\\s*$/m);\n if (firstImportMatch) {\n newContent = newContent.replace(\n firstImportMatch[0],\n `import { useEffect } from \"react\";\\n${firstImportMatch[0]}`,\n );\n } else {\n newContent = `import { useEffect } from \"react\";\\n\\n${newContent}`;\n }\n }\n }\n\n const componentMatch = newContent.match(/function\\s+(\\w+)\\s*\\([^)]*\\)\\s*\\{/);\n\n if (componentMatch) {\n const insertPosition = componentMatch.index! + componentMatch[0].length;\n newContent =\n newContent.slice(0, insertPosition) +\n `\\n ${TANSTACK_EFFECT}\\n` +\n newContent.slice(insertPosition);\n } else {\n return {\n success: false,\n filePath: rootPath,\n message: \"Could not find a component function in the root file\",\n };\n }\n\n return {\n success: true,\n filePath: rootPath,\n message: \"Add React Grab\",\n originalContent,\n newContent,\n };\n};\n\nexport const previewTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n reactGrabAlreadyConfigured: boolean = false,\n force: boolean = false,\n): TransformResult => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return transformNextAppRouter(projectRoot, reactGrabAlreadyConfigured, force);\n }\n return transformNextPagesRouter(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"vite\":\n return transformVite(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"tanstack\":\n return transformTanStack(projectRoot, reactGrabAlreadyConfigured, force);\n\n case \"webpack\":\n return transformWebpack(projectRoot, reactGrabAlreadyConfigured, force);\n\n default:\n return {\n success: false,\n filePath: \"\",\n message: `Unknown framework: ${framework}. Please add React Grab manually.`,\n };\n }\n};\n\nconst canWriteToFile = (filePath: string): boolean => {\n try {\n accessSync(filePath, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const applyTransform = (result: TransformResult): { success: boolean; error?: string } => {\n if (result.success && result.newContent && result.filePath) {\n if (!canWriteToFile(result.filePath)) {\n return {\n success: false,\n error: `Cannot write to ${result.filePath}. Check file permissions.`,\n };\n }\n\n try {\n writeFileSync(result.filePath, result.newContent);\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: `Failed to write to ${result.filePath}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n }\n return { success: true };\n};\n\nconst formatOptionsForNextjs = (options: ReactGrabOptions): string => {\n const parts: string[] = [];\n\n if (options.activationKey) {\n parts.push(`activationKey: ${JSON.stringify(options.activationKey)}`);\n }\n\n if (options.activationMode) {\n parts.push(`activationMode: \"${options.activationMode}\"`);\n }\n\n if (options.keyHoldDuration !== undefined) {\n parts.push(`keyHoldDuration: ${options.keyHoldDuration}`);\n }\n\n if (options.allowActivationInsideInput !== undefined) {\n parts.push(`allowActivationInsideInput: ${options.allowActivationInsideInput}`);\n }\n\n if (options.maxContextLines !== undefined) {\n parts.push(`maxContextLines: ${options.maxContextLines}`);\n }\n\n return `{ ${parts.join(\", \")} }`;\n};\n\nconst formatOptionsAsJson = (options: ReactGrabOptions): string => {\n const cleanOptions: Record<string, unknown> = {};\n\n if (options.activationKey) {\n cleanOptions.activationKey = options.activationKey;\n }\n\n if (options.activationMode) {\n cleanOptions.activationMode = options.activationMode;\n }\n\n if (options.keyHoldDuration !== undefined) {\n cleanOptions.keyHoldDuration = options.keyHoldDuration;\n }\n\n if (options.allowActivationInsideInput !== undefined) {\n cleanOptions.allowActivationInsideInput = options.allowActivationInsideInput;\n }\n\n if (options.maxContextLines !== undefined) {\n cleanOptions.maxContextLines = options.maxContextLines;\n }\n\n return JSON.stringify(cleanOptions);\n};\n\nconst findReactGrabFile = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n): string | null => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return findLayoutFile(projectRoot);\n }\n return findDocumentFile(projectRoot);\n case \"vite\": {\n const entryFile = findEntryFile(projectRoot);\n if (entryFile && hasReactGrabCode(readFileSync(entryFile, \"utf-8\"))) {\n return entryFile;\n }\n const indexHtml = findIndexHtml(projectRoot);\n if (indexHtml && hasReactGrabCode(readFileSync(indexHtml, \"utf-8\"))) {\n return indexHtml;\n }\n return entryFile;\n }\n case \"tanstack\":\n return findTanStackRootFile(projectRoot);\n case \"webpack\":\n return findEntryFile(projectRoot);\n default:\n return null;\n }\n};\n\nconst addOptionsToNextScript = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabScriptMatch = originalContent.match(\n /(<Script[\\s\\S]*?react-grab[\\s\\S]*?)\\s*(\\/?>)/i,\n );\n\n if (!reactGrabScriptMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab Script tag\",\n };\n }\n\n const scriptTag = reactGrabScriptMatch[0];\n const scriptOpening = reactGrabScriptMatch[1];\n const scriptClosing = reactGrabScriptMatch[2];\n\n const existingDataOptionsMatch = scriptTag.match(/data-options=\\{JSON\\.stringify\\([^)]+\\)\\}/);\n\n const dataOptionsAttr = `data-options={JSON.stringify(\\n ${formatOptionsForNextjs(options)}\\n )}`;\n\n let newScriptTag: string;\n if (existingDataOptionsMatch) {\n newScriptTag = scriptTag.replace(existingDataOptionsMatch[0], dataOptionsAttr);\n } else {\n newScriptTag = `${scriptOpening}\\n ${dataOptionsAttr}\\n ${scriptClosing}`;\n }\n\n const newContent = originalContent.replace(scriptTag, newScriptTag);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nconst addOptionsToDynamicImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabImportWithInitMatch = originalContent.match(\n /import\\s*\\(\\s*[\"']react-grab[\"']\\s*\\)(?:\\.then\\s*\\(\\s*\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\)\\s*\\))?/,\n );\n\n if (!reactGrabImportWithInitMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab import\",\n };\n }\n\n const optionsJson = formatOptionsAsJson(options);\n const newImport = `import(\"react-grab\").then((m) => m.init(${optionsJson}))`;\n\n const newContent = originalContent.replace(reactGrabImportWithInitMatch[0], newImport);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nconst addOptionsToTanStackImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const reactGrabImportWithInitMatch = originalContent.match(\n /(?: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*\\))/,\n );\n\n if (!reactGrabImportWithInitMatch) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab import\",\n };\n }\n\n const optionsJson = formatOptionsAsJson(options);\n const newImport = `import(\"react-grab/core\").then(({ init }) => init(${optionsJson}))`;\n\n const newContent = originalContent.replace(reactGrabImportWithInitMatch[0], newImport);\n\n return {\n success: true,\n filePath,\n message: \"Update React Grab options\",\n originalContent,\n newContent,\n };\n};\n\nexport const previewOptionsTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n options: ReactGrabOptions,\n): TransformResult => {\n const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);\n\n if (!filePath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find file containing React Grab configuration\",\n };\n }\n\n const originalContent = readFileSync(filePath, \"utf-8\");\n\n if (!hasReactGrabCode(originalContent)) {\n return {\n success: false,\n filePath,\n message: \"Could not find React Grab code in the file\",\n };\n }\n\n switch (framework) {\n case \"next\":\n return addOptionsToNextScript(originalContent, options, filePath);\n case \"vite\":\n return addOptionsToDynamicImport(originalContent, options, filePath);\n case \"tanstack\":\n return addOptionsToTanStackImport(originalContent, options, filePath);\n case \"webpack\":\n return addOptionsToDynamicImport(originalContent, options, filePath);\n default:\n return {\n success: false,\n filePath,\n message: `Unknown framework: ${framework}`,\n };\n }\n};\n\nexport const previewCdnTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n targetCdnDomain: string,\n): TransformResult => {\n const filePath = findReactGrabFile(projectRoot, framework, nextRouterType);\n if (!filePath) {\n return {\n success: false,\n filePath: \"\",\n message: \"Could not find React Grab file\",\n };\n }\n const originalContent = readFileSync(filePath, \"utf-8\");\n const newContent = originalContent\n .replace(/(https?:)?\\/\\/[^/\\s\"']+(?=\\/(?:@?react-grab))/g, `//${targetCdnDomain}`)\n .replace(\n /(https?:)?\\/\\/[^/\\s\"']*react-grab[^/\\s\"']*\\.com(?=\\/script\\.js)/g,\n `//${targetCdnDomain}`,\n );\n if (newContent === originalContent) {\n return {\n success: true,\n filePath,\n message: \"CDN already set\",\n noChanges: true,\n };\n }\n return {\n success: true,\n filePath,\n message: \"Update CDN\",\n originalContent,\n newContent,\n };\n};\n","export const MAX_SUGGESTIONS_COUNT = 30;\nexport const MAX_KEY_HOLD_DURATION_MS = 2000;\nexport const MAX_CONTEXT_LINES = 50;\n","import type { ReactGrabOptions } from \"./transform.js\";\n\nexport const formatActivationKeyDisplay = (\n activationKey: ReactGrabOptions[\"activationKey\"],\n): string => {\n const defaultLabel = process.platform === \"darwin\" ? \"Option\" : \"Alt\";\n if (!activationKey) return `Default (${defaultLabel})`;\n return activationKey\n .split(\"+\")\n .map((part) => {\n const lower = part.toLowerCase();\n if (lower === \"meta\") return process.platform === \"darwin\" ? \"⌘\" : \"Win\";\n if (lower === \"alt\") return process.platform === \"darwin\" ? \"⌥\" : \"Alt\";\n if (lower === \"ctrl\") return \"Ctrl\";\n if (lower === \"shift\") return \"Shift\";\n if (lower === \"space\" || lower === \" \") return \"Space\";\n return part.toUpperCase();\n })\n .join(\" + \");\n};\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n applyTransform,\n previewCdnTransform,\n previewOptionsTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport {\n MAX_SUGGESTIONS_COUNT,\n MAX_KEY_HOLD_DURATION_MS,\n MAX_CONTEXT_LINES,\n} from \"../utils/constants.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\ninterface ConfigOption {\n id: string;\n title: string;\n description: string;\n}\n\nconst isMac = process.platform === \"darwin\";\nconst META_LABEL = isMac ? \"Cmd\" : \"Win\";\nconst ALT_LABEL = isMac ? \"Option\" : \"Alt\";\n\nconst MODIFIER_ALIASES: Record<string, string> = {\n cmd: \"meta\",\n command: \"meta\",\n win: \"meta\",\n windows: \"meta\",\n meta: \"meta\",\n ctrl: \"ctrl\",\n control: \"ctrl\",\n shift: \"shift\",\n alt: \"alt\",\n option: \"alt\",\n opt: \"alt\",\n};\n\nconst MODIFIERS = [\"meta\", \"ctrl\", \"shift\", \"alt\"] as const;\n\nconst BASE_KEYS: Array<{ key: string; aliases: string[] }> = [\n { key: \" \", aliases: [\"space\", \"spacebar\"] },\n { key: \"Enter\", aliases: [\"enter\", \"return\"] },\n { key: \"Escape\", aliases: [\"escape\", \"esc\"] },\n { key: \"Tab\", aliases: [\"tab\"] },\n { key: \"Backspace\", aliases: [\"backspace\", \"back\"] },\n { key: \"Delete\", aliases: [\"delete\", \"del\"] },\n { key: \"Insert\", aliases: [\"insert\", \"ins\"] },\n { key: \"Home\", aliases: [\"home\"] },\n { key: \"End\", aliases: [\"end\"] },\n { key: \"PageUp\", aliases: [\"pageup\", \"pgup\"] },\n { key: \"PageDown\", aliases: [\"pagedown\", \"pgdn\", \"pgdown\"] },\n { key: \"ArrowUp\", aliases: [\"arrowup\", \"up\"] },\n { key: \"ArrowDown\", aliases: [\"arrowdown\", \"down\"] },\n { key: \"ArrowLeft\", aliases: [\"arrowleft\", \"left\"] },\n { key: \"ArrowRight\", aliases: [\"arrowright\", \"right\"] },\n ...Array.from({ length: 12 }, (_, i) => ({\n key: `F${i + 1}`,\n aliases: [`f${i + 1}`],\n })),\n ...Array.from({ length: 26 }, (_, i) => {\n const letter = String.fromCharCode(97 + i);\n return { key: letter, aliases: [letter] };\n }),\n ...Array.from({ length: 10 }, (_, i) => ({\n key: String(i),\n aliases: [String(i)],\n })),\n { key: \"`\", aliases: [\"backtick\", \"grave\", \"`\"] },\n { key: \"-\", aliases: [\"minus\", \"dash\", \"-\"] },\n { key: \"=\", aliases: [\"equals\", \"equal\", \"=\"] },\n { key: \"[\", aliases: [\"leftbracket\", \"lbracket\", \"[\"] },\n { key: \"]\", aliases: [\"rightbracket\", \"rbracket\", \"]\"] },\n { key: \"\\\\\", aliases: [\"backslash\", \"\\\\\"] },\n { key: \";\", aliases: [\"semicolon\", \";\"] },\n { key: \"'\", aliases: [\"quote\", \"apostrophe\", \"'\"] },\n { key: \",\", aliases: [\"comma\", \",\"] },\n { key: \".\", aliases: [\"period\", \"dot\", \".\"] },\n { key: \"/\", aliases: [\"slash\", \"forwardslash\", \"/\"] },\n];\n\ninterface KeyCombo {\n key: string;\n metaKey?: boolean;\n ctrlKey?: boolean;\n shiftKey?: boolean;\n altKey?: boolean;\n}\n\ninterface KeyChoice {\n title: string;\n value: KeyCombo;\n}\n\nconst formatCombo = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(META_LABEL);\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(ALT_LABEL);\n const keyDisplay =\n combo.key === \" \" ? \"Space\" : combo.key.length === 1 ? combo.key.toUpperCase() : combo.key;\n parts.push(keyDisplay);\n return parts.join(\"+\");\n};\n\nconst parseInput = (input: string): { modifiers: Set<string>; partial: string } => {\n const normalized = input.toLowerCase().replace(/\\s+/g, \"\");\n const parts = normalized.split(/[+-]/);\n const modifiers = new Set<string>();\n let partial = \"\";\n\n for (const part of parts) {\n if (!part) continue;\n const modifierKey = MODIFIER_ALIASES[part];\n if (modifierKey) {\n modifiers.add(modifierKey);\n } else {\n partial = part;\n }\n }\n\n return { modifiers, partial };\n};\n\nconst POPULAR_KEYS = [\"g\", \"k\", \"e\", \"d\", \"b\", \" \", \"Escape\", \"Enter\"];\n\nconst generateSuggestions = (input: string): KeyChoice[] => {\n const { modifiers, partial } = parseInput(input);\n const suggestions: KeyChoice[] = [];\n\n if (!partial && modifiers.size === 0 && !input) {\n for (const mod of MODIFIERS) {\n const label =\n mod === \"meta\"\n ? META_LABEL\n : mod === \"alt\"\n ? ALT_LABEL\n : mod.charAt(0).toUpperCase() + mod.slice(1);\n for (const popularKey of POPULAR_KEYS) {\n const keyDisplay =\n popularKey === \" \"\n ? \"Space\"\n : popularKey.length === 1\n ? popularKey.toUpperCase()\n : popularKey;\n suggestions.push({\n title: `${label}+${keyDisplay}`,\n value: {\n key: popularKey,\n ...(mod === \"meta\" ? { metaKey: true } : {}),\n ...(mod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mod === \"shift\" ? { shiftKey: true } : {}),\n ...(mod === \"alt\" ? { altKey: true } : {}),\n },\n });\n }\n }\n for (const baseKey of BASE_KEYS) {\n suggestions.push({\n title:\n baseKey.key === \" \"\n ? \"Space\"\n : baseKey.key.length === 1\n ? baseKey.key.toUpperCase()\n : baseKey.key,\n value: { key: baseKey.key },\n });\n }\n return suggestions;\n }\n\n const buildCombo = (key: string, mods: Set<string>, extraMod?: string): KeyCombo => ({\n key,\n ...(mods.has(\"meta\") || extraMod === \"meta\" ? { metaKey: true } : {}),\n ...(mods.has(\"ctrl\") || extraMod === \"ctrl\" ? { ctrlKey: true } : {}),\n ...(mods.has(\"shift\") || extraMod === \"shift\" ? { shiftKey: true } : {}),\n ...(mods.has(\"alt\") || extraMod === \"alt\" ? { altKey: true } : {}),\n });\n\n for (const baseKey of BASE_KEYS) {\n const matches = partial ? baseKey.aliases.some((alias) => alias.startsWith(partial)) : true;\n if (matches) {\n const combo = buildCombo(baseKey.key, modifiers);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n\n if (!partial) {\n const unusedMods = MODIFIERS.filter((m) => !modifiers.has(m));\n for (const mod of unusedMods) {\n for (const popularKey of POPULAR_KEYS) {\n const combo = buildCombo(popularKey, modifiers, mod);\n suggestions.push({\n title: formatCombo(combo),\n value: combo,\n });\n }\n }\n }\n\n return suggestions.slice(0, MAX_SUGGESTIONS_COUNT);\n};\n\nconst CONFIG_OPTIONS: ConfigOption[] = [\n {\n id: \"activationKey\",\n title: \"Activation Key\",\n description: \"The key used to activate React Grab (e.g., g, k, space)\",\n },\n {\n id: \"activationMode\",\n title: \"Activation Mode\",\n description: \"Toggle (press to activate/deactivate) or Hold (hold key)\",\n },\n {\n id: \"keyHoldDuration\",\n title: \"Key Hold Duration\",\n description: \"Milliseconds to hold the key before activation (hold mode)\",\n },\n {\n id: \"allowActivationInsideInput\",\n title: \"Allow Activation Inside Input\",\n description: \"Whether to allow activation when focused on input fields\",\n },\n {\n id: \"maxContextLines\",\n title: \"Max Context Lines\",\n description: \"Number of surrounding code lines to include in context\",\n },\n];\n\nconst comboToString = (combo: KeyCombo): string => {\n const parts: string[] = [];\n if (combo.metaKey) parts.push(\"Meta\");\n if (combo.ctrlKey) parts.push(\"Ctrl\");\n if (combo.shiftKey) parts.push(\"Shift\");\n if (combo.altKey) parts.push(\"Alt\");\n if (combo.key) {\n const keyDisplay = combo.key === \" \" ? \"Space\" : combo.key;\n parts.push(keyDisplay);\n }\n return parts.join(\"+\");\n};\n\nexport const configure = new Command()\n .name(\"configure\")\n .alias(\"config\")\n .description(\"configure React Grab options\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-k, --key <key>\", \"activation key (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"-m, --mode <mode>\", \"activation mode (toggle, hold)\")\n .option(\"--hold-duration <ms>\", \"key hold duration in milliseconds (for hold mode)\")\n .option(\"--allow-input <boolean>\", \"allow activation inside input fields (true/false)\")\n .option(\"--context-lines <lines>\", \"max context lines to include\")\n .option(\"--cdn <domain>\", \"CDN domain (e.g., unpkg.com, custom.react-grab.com)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (opts.cdn) {\n const result = previewCdnTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n opts.cdn,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.break();\n process.exit(1);\n }\n\n if (result.noChanges) {\n logger.break();\n logger.log(\"No changes needed.\");\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} CDN updated.`);\n logger.break();\n return;\n }\n\n const hasFlags =\n opts.key || opts.mode || opts.holdDuration || opts.allowInput || opts.contextLines;\n\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (hasFlags) {\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (opts.mode) {\n if (opts.mode !== \"toggle\" && opts.mode !== \"hold\") {\n logger.error(`Invalid mode: ${opts.mode}. Use \"toggle\" or \"hold\".`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.activationMode = opts.mode;\n logger.log(` Activation mode: ${highlighter.info(opts.mode)}`);\n }\n\n if (opts.holdDuration) {\n const duration = parseInt(opts.holdDuration, 10);\n if (isNaN(duration) || duration < 0 || duration > MAX_KEY_HOLD_DURATION_MS) {\n logger.error(`Invalid hold duration. Must be 0-${MAX_KEY_HOLD_DURATION_MS}ms.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.keyHoldDuration = duration;\n logger.log(` Key hold duration: ${highlighter.info(`${duration}ms`)}`);\n }\n\n if (opts.allowInput !== undefined) {\n const allowInput = opts.allowInput === \"true\" || opts.allowInput === true;\n collectedOptions.allowActivationInsideInput = allowInput;\n logger.log(` Allow activation inside input: ${highlighter.info(String(allowInput))}`);\n }\n\n if (opts.contextLines) {\n const lines = parseInt(opts.contextLines, 10);\n if (isNaN(lines) || lines < 0 || lines > MAX_CONTEXT_LINES) {\n logger.error(`Invalid context lines. Must be 0-${MAX_CONTEXT_LINES}.`);\n logger.break();\n process.exit(1);\n }\n collectedOptions.maxContextLines = lines;\n logger.log(` Max context lines: ${highlighter.info(String(lines))}`);\n }\n } else {\n const { selectedOption } = await prompts({\n type: \"autocomplete\",\n name: \"selectedOption\",\n message: \"Search for an option to configure:\",\n choices: CONFIG_OPTIONS.map((option) => ({\n title: option.title,\n value: option.id,\n description: option.description,\n })),\n suggest: (input, choices) =>\n Promise.resolve(\n choices.filter(\n (choice) =>\n choice.title.toLowerCase().includes(input.toLowerCase()) ||\n (choice.description?.toLowerCase().includes(input.toLowerCase()) ?? false),\n ),\n ),\n });\n\n if (selectedOption === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (selectedOption === \"activationKey\") {\n const { selectedCombo } = await prompts({\n type: \"autocomplete\",\n name: \"selectedCombo\",\n message: \"Type key combination (e.g. ctrl+shift+g):\",\n choices: generateSuggestions(\"\"),\n suggest: (input) => Promise.resolve(generateSuggestions(input)),\n });\n\n if (selectedCombo === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = comboToString(selectedCombo);\n\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n\n if (selectedOption === \"activationMode\") {\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n }\n\n if (selectedOption === \"keyHoldDuration\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n if (selectedOption === \"allowActivationInsideInput\") {\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n }\n\n if (selectedOption === \"maxContextLines\") {\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n }\n }\n\n const result = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!result.success) {\n logger.break();\n logger.warn(result.message);\n logger.break();\n\n const configJson = JSON.stringify(collectedOptions);\n logger.log(\n `Add this to your ${highlighter.info(\"init()\")} call or ${highlighter.info(\"data-options\")} attribute:`,\n );\n logger.break();\n console.log(` ${pc.cyan(configJson)}`);\n logger.break();\n process.exit(1);\n }\n\n const hasChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasChanges) {\n logger.break();\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n if (!opts.yes) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n\n const writeSpinner = spinner(`Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n } else {\n logger.break();\n logger.log(\"No changes needed.\");\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab options have been configured.`);\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { x } from \"tinyexec\";\nimport { detectPackageManager, type PackageManager } from \"./detect.js\";\n\nexport interface InstallPackageOptions {\n cwd?: string;\n isDev?: boolean;\n silent?: boolean;\n packageManager?: PackageManager;\n preferOffline?: boolean;\n additionalArgs?: string[];\n}\n\nexport const installPackages = async (\n packages: string[],\n options: InstallPackageOptions = {},\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const detectedAgent =\n options.packageManager ?? (await detectPackageManager(options.cwd ?? process.cwd()));\n const args: string[] = [];\n\n if (options.preferOffline) {\n args.push(\"--prefer-offline\");\n }\n\n if (detectedAgent === \"pnpm\") {\n args.push(\"--prod=false\");\n if (existsSync(resolve(options.cwd ?? process.cwd(), \"pnpm-workspace.yaml\"))) {\n args.push(\"-w\");\n }\n }\n\n if (options.additionalArgs) {\n args.push(...options.additionalArgs);\n }\n\n const installVerb = detectedAgent === \"npm\" ? \"install\" : \"add\";\n\n await x(\n detectedAgent,\n [installVerb, ...(options.isDev !== false ? [\"-D\"] : []), ...args, ...packages],\n {\n nodeOptions: {\n stdio: options.silent ? \"ignore\" : \"inherit\",\n cwd: options.cwd,\n env: { ...process.env, REACT_GRAB_INIT: \"1\" },\n },\n throwOnError: true,\n },\n );\n};\n\nexport const uninstallPackages = async (\n packages: string[],\n options: Omit<InstallPackageOptions, \"isDev\" | \"preferOffline\"> = {},\n): Promise<void> => {\n if (packages.length === 0) return;\n\n const detectedAgent =\n options.packageManager ?? (await detectPackageManager(options.cwd ?? process.cwd()));\n const args: string[] = [];\n\n if (\n detectedAgent === \"pnpm\" &&\n existsSync(resolve(options.cwd ?? process.cwd(), \"pnpm-workspace.yaml\"))\n ) {\n args.push(\"-w\");\n }\n\n if (options.additionalArgs) {\n args.push(...options.additionalArgs);\n }\n\n await x(detectedAgent, [detectedAgent === \"npm\" ? \"uninstall\" : \"remove\", ...args, ...packages], {\n nodeOptions: {\n stdio: options.silent ? \"ignore\" : \"inherit\",\n cwd: options.cwd,\n },\n throwOnError: true,\n });\n};\n\nexport const getPackagesToInstall = (includeReactGrab: boolean = true): string[] => {\n return includeReactGrab ? [\"react-grab\"] : [];\n};\n","import type { PackageManager } from \"./detect.js\";\nimport type { TransformResult } from \"./transform.js\";\nimport { applyTransform } from \"./transform.js\";\nimport { handleError } from \"./handle-error.js\";\nimport { installPackages } from \"./install.js\";\nimport { logger } from \"./logger.js\";\nimport { spinner } from \"./spinner.js\";\n\nexport const applyTransformWithFeedback = (result: TransformResult, message?: string): void => {\n const writeSpinner = spinner(message ?? `Applying changes to ${result.filePath}.`).start();\n const writeResult = applyTransform(result);\n if (!writeResult.success) {\n writeSpinner.fail();\n logger.break();\n logger.error(writeResult.error || \"Failed to write file.\");\n logger.break();\n process.exit(1);\n }\n writeSpinner.succeed();\n};\n\nexport const installPackagesWithFeedback = async (\n packages: string[],\n packageManager: PackageManager,\n projectRoot: string,\n): Promise<void> => {\n if (packages.length === 0) return;\n const installSpinner = spinner(`Installing ${packages.join(\", \")}.`).start();\n try {\n await installPackages(packages, { packageManager, cwd: projectRoot });\n installSpinner.succeed();\n } catch (error) {\n installSpinner.fail();\n handleError(error);\n }\n};\n","import { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectNonInteractive } from \"../utils/is-non-interactive.js\";\nimport { prompts } from \"../utils/prompts.js\";\nimport { applyTransformWithFeedback, installPackagesWithFeedback } from \"../utils/cli-helpers.js\";\nimport { promptMcpInstall } from \"../utils/install-mcp.js\";\nimport {\n detectProject,\n findReactProjects,\n type Framework,\n type PackageManager,\n type UnsupportedFramework,\n type WorkspaceProject,\n} from \"../utils/detect.js\";\nimport { printDiff } from \"../utils/diff.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { getPackagesToInstall } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\nimport {\n previewOptionsTransform,\n previewTransform,\n type ReactGrabOptions,\n} from \"../utils/transform.js\";\nimport { formatActivationKeyDisplay } from \"../utils/format-activation-key.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst REPORT_URL = \"https://react-grab.com/api/report-cli\";\nconst DOCS_URL = \"https://github.com/aidenybai/react-grab\";\n\ninterface ReportConfig {\n framework: string;\n packageManager: string;\n router?: string;\n agent?: string;\n isMonorepo: boolean;\n}\n\nconst reportToCli = (type: \"error\" | \"completed\", config?: ReportConfig, error?: Error): void => {\n fetch(REPORT_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n type,\n version: VERSION,\n config,\n error: error ? { message: error.message, stack: error.stack } : undefined,\n timestamp: new Date().toISOString(),\n }),\n }).catch(() => {});\n};\n\nconst FRAMEWORK_NAMES: Record<Framework, string> = {\n next: \"Next.js\",\n vite: \"Vite\",\n tanstack: \"TanStack Start\",\n webpack: \"Webpack\",\n unknown: \"Unknown\",\n};\n\nconst PACKAGE_MANAGER_NAMES: Record<PackageManager, string> = {\n npm: \"npm\",\n yarn: \"Yarn\",\n pnpm: \"pnpm\",\n bun: \"Bun\",\n};\n\nconst UNSUPPORTED_FRAMEWORK_NAMES: Record<NonNullable<UnsupportedFramework>, string> = {\n remix: \"Remix\",\n astro: \"Astro\",\n sveltekit: \"SvelteKit\",\n gatsby: \"Gatsby\",\n};\n\nconst sortProjectsByFramework = (projects: WorkspaceProject[]): WorkspaceProject[] =>\n [...projects].sort((projectA, projectB) => {\n if (projectA.framework === \"unknown\" && projectB.framework !== \"unknown\") return 1;\n if (projectA.framework !== \"unknown\" && projectB.framework === \"unknown\") return -1;\n return 0;\n });\n\nconst printSubprojects = (searchRoot: string, sortedProjects: WorkspaceProject[]): void => {\n logger.break();\n logger.log(\"Found the following projects:\");\n logger.break();\n for (const project of sortedProjects) {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n const relativePath = relative(searchRoot, project.path);\n logger.log(\n ` ${highlighter.info(project.name)}${frameworkLabel} ${highlighter.dim(relativePath)}`,\n );\n }\n logger.break();\n logger.log(`Re-run with ${highlighter.info(\"-c <path>\")} to specify a project:`);\n logger.break();\n logger.log(\n ` ${highlighter.dim(\"$\")} npx grab@latest init -c ${relative(searchRoot, sortedProjects[0].path)}`,\n );\n logger.break();\n};\n\nexport const init = new Command()\n .name(\"init\")\n .alias(\"setup\")\n .description(\"initialize React Grab in your project\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-f, --force\", \"force overwrite existing config\", false)\n .option(\"-k, --key <key>\", \"activation key (e.g., Meta+K, Ctrl+Shift+G, Space)\")\n .option(\"--skip-install\", \"skip package installation\", false)\n .option(\"--pkg <pkg>\", \"custom package URL for CLI (e.g., grab)\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n const isNonInteractive = detectNonInteractive(opts.yes);\n\n if (!existsSync(cwd)) {\n logger.break();\n logger.error(`Directory does not exist: ${highlighter.info(cwd)}`);\n logger.break();\n process.exit(1);\n }\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (projectInfo.hasReactGrab && !opts.force) {\n preflightSpinner.succeed();\n\n if (isNonInteractive) {\n logger.break();\n logger.warn(\"React Grab is already installed.\");\n logger.log(\n `Use ${highlighter.info(\"--force\")} to reconfigure, or remove ${highlighter.info(\"--yes\")} for interactive mode.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.success(\"React Grab is already installed.\");\n logger.break();\n\n const { wantCustomizeOptions } = await prompts({\n type: \"confirm\",\n name: \"wantCustomizeOptions\",\n message: `Would you like to customize ${highlighter.info(\"options\")}?`,\n initial: false,\n });\n\n if (wantCustomizeOptions === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantCustomizeOptions || opts.key) {\n logger.break();\n logger.log(`Configure ${highlighter.info(\"React Grab\")} options:`);\n logger.break();\n\n const collectedOptions: ReactGrabOptions = {};\n\n if (opts.key) {\n collectedOptions.activationKey = opts.key;\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n } else {\n const { wantActivationKey } = await prompts({\n type: \"confirm\",\n name: \"wantActivationKey\",\n message: `Configure ${highlighter.info(\"activation key\")}?`,\n initial: false,\n });\n\n if (wantActivationKey === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantActivationKey) {\n const { key } = await prompts({\n type: \"text\",\n name: \"key\",\n message: \"Enter the activation key (e.g., g, k, space):\",\n initial: \"\",\n });\n\n if (key === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationKey = key ? key.toLowerCase() : undefined;\n\n logger.log(\n ` Activation key: ${highlighter.info(formatActivationKeyDisplay(collectedOptions.activationKey))}`,\n );\n }\n }\n\n const { activationMode } = await prompts({\n type: \"select\",\n name: \"activationMode\",\n message: `Select ${highlighter.info(\"activation mode\")}:`,\n choices: [\n {\n title: \"Toggle (press to activate/deactivate)\",\n value: \"toggle\",\n },\n { title: \"Hold (hold key to keep active)\", value: \"hold\" },\n ],\n initial: 0,\n });\n\n if (activationMode === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.activationMode = activationMode;\n\n if (activationMode === \"hold\") {\n const { keyHoldDuration } = await prompts({\n type: \"number\",\n name: \"keyHoldDuration\",\n message: `Enter ${highlighter.info(\"key hold duration\")} in milliseconds:`,\n initial: 150,\n min: 0,\n max: 2000,\n });\n\n if (keyHoldDuration === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.keyHoldDuration = keyHoldDuration;\n }\n\n const { allowActivationInsideInput } = await prompts({\n type: \"confirm\",\n name: \"allowActivationInsideInput\",\n message: `Allow activation ${highlighter.info(\"inside input fields\")}?`,\n initial: true,\n });\n\n if (allowActivationInsideInput === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.allowActivationInsideInput = allowActivationInsideInput;\n\n const { maxContextLines } = await prompts({\n type: \"number\",\n name: \"maxContextLines\",\n message: `Enter ${highlighter.info(\"max context lines\")} to include:`,\n initial: 3,\n min: 0,\n max: 50,\n });\n\n if (maxContextLines === undefined) {\n logger.break();\n process.exit(1);\n }\n\n collectedOptions.maxContextLines = maxContextLines;\n\n const optionsResult = previewOptionsTransform(\n projectInfo.projectRoot,\n projectInfo.framework,\n projectInfo.nextRouterType,\n collectedOptions,\n );\n\n if (!optionsResult.success) {\n logger.break();\n logger.error(optionsResult.message);\n logger.break();\n process.exit(1);\n }\n\n const hasOptionsChanges =\n !optionsResult.noChanges && optionsResult.originalContent && optionsResult.newContent;\n\n if (hasOptionsChanges) {\n logger.break();\n printDiff(\n optionsResult.filePath,\n optionsResult.originalContent!,\n optionsResult.newContent!,\n );\n\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Options configuration cancelled.\");\n } else {\n applyTransformWithFeedback(optionsResult);\n\n logger.break();\n logger.success(\"React Grab options have been configured.\");\n }\n } else {\n logger.break();\n logger.log(\"No option changes needed.\");\n }\n }\n\n logger.break();\n const { wantAddMcp } = await prompts({\n type: \"confirm\",\n name: \"wantAddMcp\",\n message: `Would you like to ${highlighter.info(\"connect it to your agent via MCP\")}?`,\n initial: false,\n });\n\n if (wantAddMcp === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantAddMcp) {\n const didInstall = await promptMcpInstall();\n if (!didInstall) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.success(\"MCP server has been configured.\");\n logger.log(\"Restart your agents to activate.\");\n }\n\n logger.break();\n process.exit(0);\n }\n\n preflightSpinner.succeed();\n\n const frameworkSpinner = spinner(\"Verifying framework.\").start();\n\n if (projectInfo.unsupportedFramework) {\n const frameworkName = UNSUPPORTED_FRAMEWORK_NAMES[projectInfo.unsupportedFramework];\n frameworkSpinner.fail(`Found ${highlighter.info(frameworkName)}.`);\n logger.break();\n logger.log(`${frameworkName} is not yet supported by automatic setup.`);\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n if (projectInfo.framework === \"unknown\") {\n let searchRoot = cwd;\n let reactProjects = findReactProjects(searchRoot);\n if (reactProjects.length === 0 && cwd !== process.cwd()) {\n searchRoot = process.cwd();\n reactProjects = findReactProjects(searchRoot);\n }\n\n if (reactProjects.length > 0) {\n frameworkSpinner.info(\n `Verifying framework. Found ${reactProjects.length} project${reactProjects.length === 1 ? \"\" : \"s\"}.`,\n );\n\n const sortedProjects = sortProjectsByFramework(reactProjects);\n\n if (isNonInteractive) {\n printSubprojects(searchRoot, sortedProjects);\n process.exit(1);\n }\n\n logger.break();\n const { selectedProject } = await prompts({\n type: \"select\",\n name: \"selectedProject\",\n message: \"Select a project to install React Grab:\",\n choices: [\n ...sortedProjects.map((project) => {\n const frameworkLabel =\n project.framework !== \"unknown\"\n ? ` ${highlighter.dim(`(${FRAMEWORK_NAMES[project.framework]})`)}`\n : \"\";\n return {\n title: `${project.name}${frameworkLabel}`,\n value: project.path,\n };\n }),\n { title: \"Skip\", value: \"skip\" },\n ],\n });\n\n if (!selectedProject || selectedProject === \"skip\") {\n logger.break();\n process.exit(0);\n }\n\n process.chdir(selectedProject);\n const newProjectInfo = await detectProject(selectedProject);\n Object.assign(projectInfo, newProjectInfo);\n\n const newFrameworkSpinner = spinner(\"Verifying framework.\").start();\n newFrameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[newProjectInfo.framework])}.`,\n );\n } else {\n frameworkSpinner.fail(\"Could not detect a supported framework.\");\n logger.break();\n logger.log(\"React Grab supports Next.js, Vite, TanStack Start, and Webpack projects.\");\n logger.log(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n } else {\n frameworkSpinner.succeed(\n `Verifying framework. Found ${highlighter.info(FRAMEWORK_NAMES[projectInfo.framework])}.`,\n );\n }\n\n if (projectInfo.framework === \"next\") {\n const routerSpinner = spinner(\"Detecting router type.\").start();\n routerSpinner.succeed(\n `Detecting router type. Found ${highlighter.info(projectInfo.nextRouterType === \"app\" ? \"App Router\" : \"Pages Router\")}.`,\n );\n }\n\n const packageManagerSpinner = spinner(\"Detecting package manager.\").start();\n packageManagerSpinner.succeed(\n `Detecting package manager. Found ${highlighter.info(PACKAGE_MANAGER_NAMES[projectInfo.packageManager])}.`,\n );\n\n const finalFramework = projectInfo.framework;\n const finalPackageManager = projectInfo.packageManager;\n const finalNextRouterType = projectInfo.nextRouterType;\n let didInstallMcp = false;\n\n if (!isNonInteractive) {\n logger.break();\n const { wantAddMcp } = await prompts({\n type: \"confirm\",\n name: \"wantAddMcp\",\n message: `Would you like to ${highlighter.info(\"connect it to your agent via MCP\")}?`,\n initial: false,\n });\n\n if (wantAddMcp === undefined) {\n logger.break();\n process.exit(1);\n }\n\n if (wantAddMcp) {\n didInstallMcp = Boolean(await promptMcpInstall());\n if (!didInstallMcp) {\n logger.break();\n process.exit(0);\n }\n logger.break();\n logger.success(\"MCP server has been configured.\");\n logger.log(\"Continuing with React Grab installation...\");\n logger.break();\n }\n }\n\n const result = previewTransform(\n projectInfo.projectRoot,\n finalFramework,\n finalNextRouterType,\n false,\n opts.force,\n );\n\n if (!result.success) {\n logger.break();\n logger.error(result.message);\n logger.error(`Visit ${highlighter.info(DOCS_URL)} for manual setup.`);\n logger.break();\n process.exit(1);\n }\n\n const hasLayoutChanges = !result.noChanges && result.originalContent && result.newContent;\n\n if (hasLayoutChanges) {\n logger.break();\n\n printDiff(result.filePath, result.originalContent!, result.newContent!);\n\n logger.break();\n logger.warn(\"Auto-detection may not be 100% accurate.\");\n logger.warn(\"Please verify the changes before committing.\");\n\n if (!isNonInteractive) {\n logger.break();\n const { proceed } = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Apply these changes?\",\n initial: true,\n });\n\n if (!proceed) {\n logger.break();\n logger.log(\"Changes cancelled.\");\n logger.break();\n process.exit(0);\n }\n }\n }\n\n const shouldInstallReactGrab = !projectInfo.hasReactGrab;\n\n if (!opts.skipInstall && shouldInstallReactGrab) {\n await installPackagesWithFeedback(\n getPackagesToInstall(shouldInstallReactGrab),\n finalPackageManager,\n projectInfo.projectRoot,\n );\n }\n\n if (hasLayoutChanges) {\n applyTransformWithFeedback(result);\n }\n\n logger.break();\n logger.log(`${highlighter.success(\"Success!\")} React Grab has been installed.`);\n logger.log(\"You may now start your development server.\");\n logger.break();\n\n reportToCli(\"completed\", {\n framework: finalFramework,\n packageManager: finalPackageManager,\n router: finalNextRouterType,\n agent: didInstallMcp ? \"mcp\" : undefined,\n isMonorepo: projectInfo.isMonorepo,\n });\n } catch (error) {\n handleError(error);\n reportToCli(\"error\", undefined, error as Error);\n }\n });\n","import { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\n\nexport const remove = new Command()\n .name(\"remove\")\n .description(\"disconnect React Grab from your agent\")\n .argument(\"[agent]\", \"agent to disconnect (mcp)\")\n .option(\"-y, --yes\", \"skip confirmation prompts\", false)\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (agentArg, opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = opts.cwd;\n\n const preflightSpinner = spinner(\"Preflight checks.\").start();\n\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n preflightSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(`Run ${highlighter.info(\"react-grab init\")} first to install React Grab.`);\n logger.break();\n process.exit(1);\n }\n\n preflightSpinner.succeed();\n\n if (agentArg && agentArg !== \"mcp\") {\n logger.break();\n logger.warn(\n `Legacy agent packages are deprecated. Uninstall ${highlighter.info(`@react-grab/${agentArg}`)} manually with your package manager.`,\n );\n logger.break();\n process.exit(0);\n }\n\n logger.break();\n logger.warn(\n \"To remove the MCP server, delete the react-grab-mcp entry from your agent's MCP config file.\",\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { detectProject } from \"../utils/detect.js\";\nimport { handleError } from \"../utils/handle-error.js\";\nimport { highlighter } from \"../utils/highlighter.js\";\nimport { installPackages } from \"../utils/install.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { spinner } from \"../utils/spinner.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org/react-grab/latest\";\n\ninterface NpmPackageInfo {\n version: string;\n}\n\nconst fetchLatestVersion = async (): Promise<string | null> => {\n try {\n const response = await fetch(NPM_REGISTRY_URL);\n const data: NpmPackageInfo = await response.json();\n return data.version ?? null;\n } catch {\n return null;\n }\n};\n\nconst isDevDependency = (projectRoot: string): boolean => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return true;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n if (packageJson.devDependencies?.[\"react-grab\"]) return true;\n if (packageJson.dependencies?.[\"react-grab\"]) return false;\n } catch {}\n return true;\n};\n\nexport const upgrade = new Command()\n .name(\"upgrade\")\n .alias(\"update\")\n .description(\"upgrade react-grab to the latest version\")\n .option(\"-c, --cwd <cwd>\", \"working directory (defaults to current directory)\", process.cwd())\n .action(async (opts) => {\n console.log(`${pc.magenta(\"✿\")} ${pc.bold(\"React Grab\")} ${pc.gray(VERSION)}`);\n console.log();\n\n try {\n const cwd = resolve(opts.cwd);\n\n const detectSpinner = spinner(\"Detecting project.\").start();\n const projectInfo = await detectProject(cwd);\n\n if (!projectInfo.hasReactGrab) {\n detectSpinner.fail(\"React Grab is not installed.\");\n logger.break();\n logger.error(\n `Run ${highlighter.info(\"npx grab@latest init\")} first to install React Grab.`,\n );\n logger.break();\n process.exit(1);\n }\n\n detectSpinner.succeed();\n\n const versionSpinner = spinner(\"Checking for updates.\").start();\n const latestVersion = await fetchLatestVersion();\n\n if (!latestVersion) {\n versionSpinner.fail(\"Could not check for updates.\");\n logger.break();\n logger.error(\"Failed to reach the npm registry. Check your network connection.\");\n logger.break();\n process.exit(1);\n }\n\n const installedVersion = projectInfo.reactGrabVersion;\n\n if (installedVersion && installedVersion === latestVersion) {\n versionSpinner.succeed(\n `Already on the latest version ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n process.exit(0);\n }\n\n const fromLabel = installedVersion ? `v${installedVersion}` : \"unknown\";\n versionSpinner.succeed(\n `Update available: ${highlighter.dim(fromLabel)} → ${highlighter.info(`v${latestVersion}`)}.`,\n );\n\n const upgradeSpinner = spinner(\"Upgrading react-grab.\").start();\n\n try {\n await installPackages([\"react-grab@latest\"], {\n packageManager: projectInfo.packageManager,\n cwd: projectInfo.projectRoot,\n isDev: isDevDependency(projectInfo.projectRoot),\n });\n upgradeSpinner.succeed();\n } catch {\n upgradeSpinner.fail();\n logger.break();\n logger.error(\"Failed to upgrade. Check your network connection and try again.\");\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n logger.log(\n `${highlighter.success(\"Success!\")} React Grab has been upgraded to ${highlighter.info(`v${latestVersion}`)}.`,\n );\n logger.break();\n } catch (error) {\n handleError(error);\n }\n });\n","import { Command } from \"commander\";\nimport { add } from \"./commands/add.js\";\nimport { configure } from \"./commands/configure.js\";\nimport { init } from \"./commands/init.js\";\nimport { remove } from \"./commands/remove.js\";\nimport { upgrade } from \"./commands/upgrade.js\";\n\nconst VERSION = process.env.VERSION ?? \"0.0.1\";\nconst VERSION_API_URL = \"https://www.react-grab.com/api/version\";\n\nprocess.on(\"SIGINT\", () => process.exit(0));\nprocess.on(\"SIGTERM\", () => process.exit(0));\n\ntry {\n fetch(`${VERSION_API_URL}?source=cli&v=${VERSION}&t=${Date.now()}`).catch(() => {});\n} catch {}\n\nconst program = new Command()\n .name(\"grab\")\n .description(\"add React Grab to your project\")\n .version(VERSION, \"-v, --version\", \"display the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(remove);\nprogram.addCommand(configure);\nprogram.addCommand(upgrade);\n\nconst main = async () => {\n await program.parseAsync();\n};\n\nmain();\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-grab/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"bin": {
|
|
5
5
|
"react-grab": "./bin/cli.js"
|
|
6
6
|
},
|
|
@@ -17,17 +17,19 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@antfu/ni": "^30.1.0",
|
|
21
20
|
"commander": "^14.0.3",
|
|
22
21
|
"ignore": "^7.0.5",
|
|
23
22
|
"jsonc-parser": "^3.3.1",
|
|
24
23
|
"ora": "^9.4.0",
|
|
24
|
+
"package-manager-detector": "^1.6.0",
|
|
25
25
|
"picocolors": "^1.1.1",
|
|
26
26
|
"prompts": "^2.4.2",
|
|
27
|
-
"smol-toml": "^1.6.1"
|
|
27
|
+
"smol-toml": "^1.6.1",
|
|
28
|
+
"tinyexec": "^1.1.2"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@types/prompts": "^2.4.9"
|
|
31
|
+
"@types/prompts": "^2.4.9",
|
|
32
|
+
"vite-plus": "^0.1.20"
|
|
31
33
|
},
|
|
32
34
|
"scripts": {
|
|
33
35
|
"dev": "vp pack --watch",
|