@react-grab/cli 0.1.48-dev.f29c951 → 0.1.48-dev.fe982d7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"install-Car5vKPk.js","names":[],"sources":["../src/utils/react-grab-code.ts","../src/utils/react-grab-setup-files.ts","../src/utils/detect.ts","../src/utils/detect-agents.ts","../src/utils/install-skill.ts","../src/utils/templates.ts","../src/utils/transform.ts","../src/utils/install.ts"],"sourcesContent":["const REACT_GRAB_SPECIFIER_PATTERN = String.raw`react-grab(?:\\/[^\"']+)?`;\n\nconst stripComments = (content: string): string =>\n content\n .replace(/<!--[\\s\\S]*?-->/g, \"\")\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .replace(/(^|\\s)\\/\\/.*$/gm, \"$1\");\n\nconst stripTypeOnlyReactGrabImports = (content: string): string => {\n return content\n .replace(\n new RegExp(\n String.raw`import\\s+type\\s+[^;]+from\\s+[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"'];?`,\n \"g\",\n ),\n \"\",\n )\n .replace(\n new RegExp(\n String.raw`import\\s*\\{\\s*type\\s+[^,}]+(?:\\s*,\\s*type\\s+[^,}]+)*\\s*,?\\s*\\}\\s*from\\s+[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"'];?`,\n \"g\",\n ),\n \"\",\n );\n};\n\nexport const hasReactGrabSetupCode = (content: string): boolean => {\n const setupCandidateContent = stripTypeOnlyReactGrabImports(stripComments(content));\n const setupPatterns = [\n new RegExp(String.raw`import\\s*\\(\\s*[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']\\s*\\)`),\n new RegExp(\n String.raw`import\\s+(?!type\\b)(?:[^\"';]+from\\s+)?[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']`,\n ),\n new RegExp(String.raw`require\\s*\\(\\s*[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']\\s*\\)`),\n /<Script[\\s\\S]*?src\\s*=\\s*(?:[\"'][^\"']*react-grab[^\"']*[\"']|\\{(?:[\"'][^\"']*react-grab[^\"']*[\"']|`[^`]*react-grab[^`]*`)\\})/i,\n /<script[\\s\\S]*?src\\s*=\\s*[\"'][^\"']*react-grab[^\"']*[\"']/i,\n ];\n\n return setupPatterns.some((pattern) => pattern.test(setupCandidateContent));\n};\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst COMPONENT_EXTENSIONS = [\"tsx\", \"jsx\", \"ts\", \"js\"];\nconst INSTRUMENTATION_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"mts\", \"cts\", \"mjs\", \"cjs\"];\nconst ROUTE_EXTENSIONS = [\"tsx\", \"jsx\"];\n\nconst createFileCandidates = (\n projectRoot: string,\n directories: string[],\n baseName: string,\n extensions: string[],\n): string[] => {\n const fileCandidates: string[] = [];\n for (const directory of directories) {\n for (const extension of extensions) {\n fileCandidates.push(join(projectRoot, directory, `${baseName}.${extension}`));\n }\n }\n return fileCandidates;\n};\n\nconst findExistingFile = (fileCandidates: string[]): string | null => {\n for (const filePath of fileCandidates) {\n if (existsSync(filePath)) return filePath;\n }\n return null;\n};\n\nexport const getLayoutFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"app\", \"src/app\"], \"layout\", COMPONENT_EXTENSIONS);\n\nexport const getDocumentFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"pages\", \"src/pages\"], \"_document\", COMPONENT_EXTENSIONS);\n\nexport const getInstrumentationFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(\n projectRoot,\n [\"\", \"src\"],\n \"instrumentation-client\",\n INSTRUMENTATION_EXTENSIONS,\n );\n\nexport const getIndexHtmlCandidates = (projectRoot: string): string[] => [\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n];\n\nexport const getEntryFileCandidates = (projectRoot: string): string[] => [\n ...createFileCandidates(projectRoot, [\"src\"], \"index\", COMPONENT_EXTENSIONS),\n ...createFileCandidates(projectRoot, [\"src\"], \"main\", COMPONENT_EXTENSIONS),\n];\n\nexport const getTanStackRootFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"src/routes\", \"app/routes\"], \"__root\", ROUTE_EXTENSIONS);\n\nexport const getReactGrabSetupFileCandidates = (projectRoot: string): string[] => [\n ...getLayoutFileCandidates(projectRoot),\n ...getDocumentFileCandidates(projectRoot),\n ...getInstrumentationFileCandidates(projectRoot),\n ...getIndexHtmlCandidates(projectRoot),\n ...getEntryFileCandidates(projectRoot),\n ...getTanStackRootFileCandidates(projectRoot),\n];\n\nexport const findLayoutFile = (projectRoot: string): string | null =>\n findExistingFile(getLayoutFileCandidates(projectRoot));\n\nexport const findDocumentFile = (projectRoot: string): string | null =>\n findExistingFile(getDocumentFileCandidates(projectRoot));\n\nexport const findInstrumentationFile = (projectRoot: string): string | null =>\n findExistingFile(getInstrumentationFileCandidates(projectRoot));\n\nexport const findIndexHtml = (projectRoot: string): string | null =>\n findExistingFile(getIndexHtmlCandidates(projectRoot));\n\nexport const findEntryFile = (projectRoot: string): string | null =>\n findExistingFile(getEntryFileCandidates(projectRoot));\n\nexport const findTanStackRootFile = (projectRoot: string): string | null =>\n findExistingFile(getTanStackRootFileCandidates(projectRoot));\n\nexport const isInstrumentationFile = (filePath: string): boolean =>\n /(?:^|[/\\\\])instrumentation-client\\.[cm]?[jt]sx?$/.test(filePath);\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\";\nimport { hasReactGrabSetupCode } from \"./react-grab-code.js\";\nimport { getReactGrabSetupFileCandidates } from \"./react-grab-setup-files.js\";\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\nexport interface ProjectInfo {\n packageManager: PackageManager;\n framework: Framework;\n nextRouterType: NextRouterType;\n isMonorepo: boolean;\n projectRoot: string;\n hasReactGrab: boolean;\n isReactGrabConfigured: 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\nconst CONFIG_EXTENSIONS = [\"ts\", \"mts\", \"cts\", \"js\", \"mjs\", \"cjs\"] as const;\n\nconst hasConfigFile = (projectRoot: string, configBaseName: string): boolean =>\n CONFIG_EXTENSIONS.some((extension) =>\n existsSync(join(projectRoot, `${configBaseName}.${extension}`)),\n );\n\nconst readMergedDependencies = (projectRoot: string): Record<string, string> | null => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return null;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n return {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n } catch {\n return null;\n }\n};\n\nconst detectFrameworkFromDependencies = (\n dependencies: Record<string, string> | null,\n): Framework => {\n if (!dependencies) return \"unknown\";\n if (dependencies[\"next\"]) return \"next\";\n if (dependencies[\"@tanstack/react-start\"]) return \"tanstack\";\n if (dependencies[\"vite\"]) return \"vite\";\n if (dependencies[\"webpack\"]) return \"webpack\";\n return \"unknown\";\n};\n\nconst detectFrameworkFromConfigFiles = (projectRoot: string): Framework => {\n if (hasConfigFile(projectRoot, \"next.config\")) return \"next\";\n if (hasConfigFile(projectRoot, \"app.config\")) return \"tanstack\";\n if (hasConfigFile(projectRoot, \"vite.config\")) return \"vite\";\n if (hasConfigFile(projectRoot, \"webpack.config\")) return \"webpack\";\n return \"unknown\";\n};\n\nconst findEnclosingMonorepoRoot = (projectRoot: string): string | null => {\n let currentDirectory = dirname(projectRoot);\n while (currentDirectory !== dirname(currentDirectory)) {\n if (detectMonorepo(currentDirectory)) return currentDirectory;\n currentDirectory = dirname(currentDirectory);\n }\n return null;\n};\n\nexport const detectFramework = (projectRoot: string): Framework => {\n const localFramework = detectFrameworkFromDependencies(readMergedDependencies(projectRoot));\n if (localFramework !== \"unknown\") return localFramework;\n return detectFrameworkFromConfigFiles(projectRoot);\n};\n\nconst detectFrameworkFromMonorepoRoot = (projectRoot: string): Framework => {\n const monorepoRoot = findEnclosingMonorepoRoot(projectRoot);\n if (!monorepoRoot) return \"unknown\";\n return detectFrameworkFromDependencies(readMergedDependencies(monorepoRoot));\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 dependencies = readMergedDependencies(projectPath);\n if (!dependencies) return false;\n return Boolean(dependencies[\"react\"] || dependencies[\"react-dom\"]);\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\nconst normalizePathForComparison = (filePath: string): string => filePath.replace(/\\\\/g, \"/\");\n\nexport const findReactProjects = (projectRoot: string): WorkspaceProject[] => {\n const monorepoRoot = detectMonorepo(projectRoot)\n ? projectRoot\n : findEnclosingMonorepoRoot(projectRoot);\n if (monorepoRoot) {\n const workspaceProjects = findWorkspaceProjects(monorepoRoot);\n const localProject = projectRoot === monorepoRoot ? null : buildReactProject(projectRoot);\n const projects = localProject\n ? [\n localProject,\n ...workspaceProjects.filter(\n (project) =>\n normalizePathForComparison(project.path) !==\n normalizePathForComparison(localProject.path),\n ),\n ]\n : workspaceProjects;\n if (projects.length > 0) {\n return projects;\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 hasReactGrabSetupInFile = (filePath: string): boolean => {\n if (!existsSync(filePath)) return false;\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return hasReactGrabSetupCode(content);\n } catch {\n return false;\n }\n};\n\nconst detectReactGrabDependency = (projectRoot: string): boolean => {\n const dependencies = readMergedDependencies(projectRoot);\n return Boolean(dependencies?.[\"react-grab\"]);\n};\n\nexport const detectReactGrabConfigured = (projectRoot: string): boolean => {\n return getReactGrabSetupFileCandidates(projectRoot).some(hasReactGrabSetupInFile);\n};\n\nexport const detectReactGrab = (projectRoot: string): boolean =>\n detectReactGrabDependency(projectRoot) || detectReactGrabConfigured(projectRoot);\n\nexport const detectUnsupportedFramework = (projectRoot: string): UnsupportedFramework => {\n const dependencies = readMergedDependencies(projectRoot);\n if (!dependencies) return null;\n if (dependencies[\"@remix-run/react\"] || dependencies[\"remix\"]) return \"remix\";\n if (dependencies[\"astro\"]) return \"astro\";\n if (dependencies[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (dependencies[\"gatsby\"]) return \"gatsby\";\n return null;\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 localFramework = detectFramework(projectRoot);\n const framework =\n localFramework === \"unknown\" ? detectFrameworkFromMonorepoRoot(projectRoot) : localFramework;\n const packageManager = await detectPackageManager(projectRoot);\n const isMonorepo = detectMonorepo(projectRoot) || findEnclosingMonorepoRoot(projectRoot) !== null;\n const isReactGrabConfigured = detectReactGrabConfigured(projectRoot);\n\n return {\n packageManager,\n framework,\n nextRouterType: framework === \"next\" ? detectNextRouterType(projectRoot) : \"unknown\",\n isMonorepo,\n projectRoot,\n hasReactGrab: detectReactGrabDependency(projectRoot) || isReactGrabConfigured,\n isReactGrabConfigured,\n reactGrabVersion: detectReactGrabVersion(projectRoot),\n unsupportedFramework: detectUnsupportedFramework(projectRoot),\n };\n};\n","import { accessSync, constants, statSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport {\n type SkillAgentType,\n detectInstalledSkillAgents,\n getSkillAgentTypes,\n} from \"agent-install/skill\";\n\n// PATH binaries used as a supplementary detection signal on top of\n// agent-install's filesystem detection. This catches users who installed a\n// CLI but have not run it yet (no ~/.claude / ~/.cursor / etc. on disk).\n// Only agents whose CLI ships an obvious binary name are listed; FS-only\n// agents rely entirely on agent-install. \"universal\" is a synthetic install\n// target with no binary or config dir.\nconst PATH_BINARIES: Partial<Record<SkillAgentType, readonly string[]>> = {\n \"claude-code\": [\"claude\"],\n codex: [\"codex\"],\n cursor: [\"cursor\", \"cursor-agent\"],\n droid: [\"droid\"],\n \"gemini-cli\": [\"gemini\"],\n \"github-copilot\": [\"copilot\"],\n opencode: [\"opencode\"],\n pi: [\"pi\", \"omegon\"],\n};\n\nconst isCommandAvailable = (command: string): boolean => {\n const pathDirectories = (process.env.PATH ?? \"\").split(delimiter).filter(Boolean);\n for (const directory of pathDirectories) {\n const binaryPath = join(directory, command);\n try {\n if (statSync(binaryPath).isFile()) {\n accessSync(binaryPath, constants.X_OK);\n return true;\n }\n } catch {}\n }\n return false;\n};\n\n// Union of agent-install's filesystem-detected agents (~/.claude, ~/.cursor,\n// etc.) with a supplementary $PATH binary scan that catches agents installed\n// but not yet run (no config dir on disk). Order follows getSkillAgentTypes()\n// for deterministic UI; the synthetic \"universal\" type is filtered out because\n// it is not a user-facing agent.\nexport const detectAvailableAgents = async (): Promise<SkillAgentType[]> => {\n const installedAgents = new Set(await detectInstalledSkillAgents());\n return getSkillAgentTypes().filter((agent) => {\n if (agent === \"universal\") return false;\n if (installedAgents.has(agent)) return true;\n return PATH_BINARIES[agent]?.some(isCommandAvailable) ?? false;\n });\n};\n","import { existsSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n type SkillAgentType,\n add,\n getCanonicalSkillsDir,\n getSkillAgentConfig,\n getSkillAgentDir,\n isUniversalSkillAgent,\n} from \"agent-install/skill\";\nimport { detectAvailableAgents } from \"./detect-agents.js\";\n\nconst SKILL_NAME = \"react-grab\";\n\n// The skill is bundled next to the compiled CLI (see scripts/bundle-skill.mjs)\n// so installs work offline and stay pinned to this CLI version.\nconst SKILL_SOURCE = fileURLToPath(new URL(\"../skills/react-grab\", import.meta.url));\n\nexport const agentLabel = (agent: SkillAgentType): string => getSkillAgentConfig(agent).displayName;\n\n// Universal agents share the canonical .agents/skills directory; others use\n// their own. Mirror where agent-install actually writes so removal lands.\nconst installedSkillDir = (agent: SkillAgentType, global: boolean, cwd: string): string =>\n join(\n isUniversalSkillAgent(agent)\n ? getCanonicalSkillsDir(global, cwd)\n : getSkillAgentDir(agent, { global, cwd }),\n SKILL_NAME,\n );\n\nexport interface InstallSkillOptions {\n agents?: SkillAgentType[];\n global?: boolean;\n cwd?: string;\n}\n\nexport const installSkill = async ({\n agents,\n global = false,\n cwd = process.cwd(),\n}: InstallSkillOptions = {}): Promise<Awaited<ReturnType<typeof add>>> => {\n const targetAgents = agents ?? (await detectAvailableAgents());\n return add({ source: SKILL_SOURCE, agents: targetAgents, global, cwd, mode: \"copy\" });\n};\n\ninterface RemoveSkillOptions {\n cwd?: string;\n global?: boolean;\n}\n\n// Scoped like install (project unless global) so it won't delete a global install\n// from inside an unrelated project.\nexport const removeSkill = async ({\n cwd = process.cwd(),\n global = false,\n}: RemoveSkillOptions = {}): Promise<SkillAgentType[]> => {\n const agents = await detectAvailableAgents();\n const removedAgents: SkillAgentType[] = [];\n const dirsToRemove = new Set<string>();\n for (const agent of agents) {\n const skillDir = installedSkillDir(agent, global, cwd);\n if (!existsSync(skillDir)) continue;\n removedAgents.push(agent);\n dirsToRemove.add(skillDir);\n }\n for (const skillDir of dirsToRemove) {\n rmSync(skillDir, { recursive: true, force: true });\n }\n return removedAgents;\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 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\";\nimport { hasReactGrabSetupCode } from \"./react-grab-code.js\";\nimport {\n findDocumentFile,\n findEntryFile,\n findIndexHtml,\n findLayoutFile,\n findTanStackRootFile,\n getDocumentFileCandidates,\n getEntryFileCandidates,\n getIndexHtmlCandidates,\n getInstrumentationFileCandidates,\n getLayoutFileCandidates,\n getTanStackRootFileCandidates,\n isInstrumentationFile,\n} from \"./react-grab-setup-files.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 hasReactGrabInInstrumentation = (projectRoot: string): boolean => {\n return findFileWithReactGrabSetup(getInstrumentationFileCandidates(projectRoot)) !== null;\n};\n\nconst findFileWithReactGrabSetup = (fileCandidates: string[]): string | null => {\n for (const filePath of fileCandidates) {\n if (!existsSync(filePath)) continue;\n if (hasReactGrabSetupCode(readFileSync(filePath, \"utf-8\"))) return filePath;\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): 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, app/layout.jsx, app/layout.ts, or app/layout.js\",\n };\n }\n\n const originalContent = readFileSync(layoutPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabSetupCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(layoutPath);\n }\n\n if (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): 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, pages/_document.jsx, pages/_document.ts, or pages/_document.js.\\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 = hasReactGrabSetupCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(documentPath);\n }\n\n if (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 (!hasReactGrabSetupCode(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): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n const indexPath = findIndexHtml(projectRoot);\n if (indexPath) {\n const existingResult = checkExistingInstallation(indexPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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 const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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): 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 const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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): 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 = hasReactGrabSetupCode(originalContent);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(rootPath);\n }\n\n if (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 hasFrameworkEntryPoint = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n): boolean => {\n switch (framework) {\n case \"next\":\n return nextRouterType === \"app\"\n ? findLayoutFile(projectRoot) !== null\n : findDocumentFile(projectRoot) !== null;\n case \"vite\":\n case \"webpack\":\n return findEntryFile(projectRoot) !== null;\n case \"tanstack\":\n return findTanStackRootFile(projectRoot) !== null;\n default:\n return false;\n }\n};\n\nexport const previewTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n reactGrabAlreadyConfigured: boolean = false,\n): TransformResult => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return transformNextAppRouter(projectRoot, reactGrabAlreadyConfigured);\n }\n return transformNextPagesRouter(projectRoot, reactGrabAlreadyConfigured);\n\n case \"vite\":\n return transformVite(projectRoot, reactGrabAlreadyConfigured);\n\n case \"tanstack\":\n return transformTanStack(projectRoot, reactGrabAlreadyConfigured);\n\n case \"webpack\":\n return transformWebpack(projectRoot, reactGrabAlreadyConfigured);\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 const primaryFile =\n nextRouterType === \"app\" ? findLayoutFile(projectRoot) : findDocumentFile(projectRoot);\n const primaryCandidates =\n nextRouterType === \"app\"\n ? getLayoutFileCandidates(projectRoot)\n : getDocumentFileCandidates(projectRoot);\n const primarySetupFile = findFileWithReactGrabSetup(primaryCandidates);\n if (primarySetupFile) return primarySetupFile;\n\n const instrumentationFile = findFileWithReactGrabSetup(\n getInstrumentationFileCandidates(projectRoot),\n );\n if (instrumentationFile) return instrumentationFile;\n\n return primaryFile;\n }\n case \"vite\": {\n const entryFile = findEntryFile(projectRoot);\n const entrySetupFile = findFileWithReactGrabSetup(getEntryFileCandidates(projectRoot));\n if (entrySetupFile) return entrySetupFile;\n\n const indexHtml = findFileWithReactGrabSetup(getIndexHtmlCandidates(projectRoot));\n if (indexHtml) return indexHtml;\n\n return entryFile;\n }\n case \"tanstack\": {\n const rootSetupFile = findFileWithReactGrabSetup(getTanStackRootFileCandidates(projectRoot));\n return rootSetupFile ?? findTanStackRootFile(projectRoot);\n }\n case \"webpack\": {\n const entrySetupFile = findFileWithReactGrabSetup(getEntryFileCandidates(projectRoot));\n return entrySetupFile ?? findEntryFile(projectRoot);\n }\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 /(void\\s+)?import\\s*\\(\\s*[\"']react-grab(?:\\/[^\"']+)?[\"']\\s*\\)(?:\\.then\\s*\\(\\s*(?:\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\)|\\(\\{\\s*init\\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 voidPrefix = reactGrabImportWithInitMatch[1] ?? \"\";\n const newImport = `${voidPrefix}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\\/core[\"']\\s*\\)\\.then\\s*\\(\\s*(?:\\(\\s*\\{\\s*init\\s*\\}\\s*\\)\\s*=>\\s*init\\s*\\([^)]*\\)|\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\))\\s*\\)|(void\\s+)?import\\s*\\(\\s*[\"']react-grab(?!\\/core)(?:\\/[^\"']+)?[\"']\\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 voidPrefix = reactGrabImportWithInitMatch[1] ?? reactGrabImportWithInitMatch[2] ?? \"\";\n const newImport = `${voidPrefix}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\nconst addOptionsToAnyImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const dynamicImportResult = addOptionsToDynamicImport(originalContent, options, filePath);\n if (dynamicImportResult.success) return dynamicImportResult;\n return addOptionsToTanStackImport(originalContent, options, filePath);\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 (!hasReactGrabSetupCode(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 if (isInstrumentationFile(filePath)) {\n return addOptionsToAnyImport(originalContent, options, filePath);\n }\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","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 getPackagesToInstall = (includeReactGrab: boolean = true): string[] => {\n return includeReactGrab ? [\"react-grab\"] : [];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"install-Car5vKPk.js","names":[],"sources":["../src/utils/react-grab-code.ts","../src/utils/react-grab-setup-files.ts","../src/utils/detect.ts","../src/utils/detect-agents.ts","../src/utils/install-skill.ts","../src/utils/templates.ts","../src/utils/transform.ts","../src/utils/install.ts"],"sourcesContent":["const REACT_GRAB_SPECIFIER_PATTERN = String.raw`react-grab(?:\\/[^\"']+)?`;\n\nconst stripComments = (content: string): string =>\n content\n .replace(/<!--[\\s\\S]*?-->/g, \"\")\n .replace(/\\{\\/\\*[\\s\\S]*?\\*\\/\\}/g, \"\")\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n .replace(/(^|\\s)\\/\\/.*$/gm, \"$1\");\n\nconst stripTypeOnlyReactGrabImports = (content: string): string => {\n return content\n .replace(\n new RegExp(\n String.raw`import\\s+type\\s+[^;]+from\\s+[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"'];?`,\n \"g\",\n ),\n \"\",\n )\n .replace(\n new RegExp(\n String.raw`import\\s*\\{\\s*type\\s+[^,}]+(?:\\s*,\\s*type\\s+[^,}]+)*\\s*,?\\s*\\}\\s*from\\s+[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"'];?`,\n \"g\",\n ),\n \"\",\n );\n};\n\nexport const hasReactGrabSetupCode = (content: string): boolean => {\n const setupCandidateContent = stripTypeOnlyReactGrabImports(stripComments(content));\n const setupPatterns = [\n new RegExp(String.raw`import\\s*\\(\\s*[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']\\s*\\)`),\n new RegExp(\n String.raw`import\\s+(?!type\\b)(?:[^\"';]+from\\s+)?[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']`,\n ),\n new RegExp(String.raw`require\\s*\\(\\s*[\"']${REACT_GRAB_SPECIFIER_PATTERN}[\"']\\s*\\)`),\n /<Script[\\s\\S]*?src\\s*=\\s*(?:[\"'][^\"']*react-grab[^\"']*[\"']|\\{(?:[\"'][^\"']*react-grab[^\"']*[\"']|`[^`]*react-grab[^`]*`)\\})/i,\n /<script[\\s\\S]*?src\\s*=\\s*[\"'][^\"']*react-grab[^\"']*[\"']/i,\n ];\n\n return setupPatterns.some((pattern) => pattern.test(setupCandidateContent));\n};\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst COMPONENT_EXTENSIONS = [\"tsx\", \"jsx\", \"ts\", \"js\"];\nconst INSTRUMENTATION_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"mts\", \"cts\", \"mjs\", \"cjs\"];\nconst ROUTE_EXTENSIONS = [\"tsx\", \"jsx\"];\n\nconst createFileCandidates = (\n projectRoot: string,\n directories: string[],\n baseName: string,\n extensions: string[],\n): string[] => {\n const fileCandidates: string[] = [];\n for (const directory of directories) {\n for (const extension of extensions) {\n fileCandidates.push(join(projectRoot, directory, `${baseName}.${extension}`));\n }\n }\n return fileCandidates;\n};\n\nconst findExistingFile = (fileCandidates: string[]): string | null => {\n for (const filePath of fileCandidates) {\n if (existsSync(filePath)) return filePath;\n }\n return null;\n};\n\nexport const getLayoutFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"app\", \"src/app\"], \"layout\", COMPONENT_EXTENSIONS);\n\nexport const getDocumentFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"pages\", \"src/pages\"], \"_document\", COMPONENT_EXTENSIONS);\n\nexport const getInstrumentationFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(\n projectRoot,\n [\"\", \"src\"],\n \"instrumentation-client\",\n INSTRUMENTATION_EXTENSIONS,\n );\n\nexport const getIndexHtmlCandidates = (projectRoot: string): string[] => [\n join(projectRoot, \"index.html\"),\n join(projectRoot, \"public\", \"index.html\"),\n];\n\nexport const getEntryFileCandidates = (projectRoot: string): string[] => [\n ...createFileCandidates(projectRoot, [\"src\"], \"index\", COMPONENT_EXTENSIONS),\n ...createFileCandidates(projectRoot, [\"src\"], \"main\", COMPONENT_EXTENSIONS),\n];\n\nexport const getTanStackRootFileCandidates = (projectRoot: string): string[] =>\n createFileCandidates(projectRoot, [\"src/routes\", \"app/routes\"], \"__root\", ROUTE_EXTENSIONS);\n\nexport const getReactGrabSetupFileCandidates = (projectRoot: string): string[] => [\n ...getLayoutFileCandidates(projectRoot),\n ...getDocumentFileCandidates(projectRoot),\n ...getInstrumentationFileCandidates(projectRoot),\n ...getIndexHtmlCandidates(projectRoot),\n ...getEntryFileCandidates(projectRoot),\n ...getTanStackRootFileCandidates(projectRoot),\n];\n\nexport const findLayoutFile = (projectRoot: string): string | null =>\n findExistingFile(getLayoutFileCandidates(projectRoot));\n\nexport const findDocumentFile = (projectRoot: string): string | null =>\n findExistingFile(getDocumentFileCandidates(projectRoot));\n\nexport const findIndexHtml = (projectRoot: string): string | null =>\n findExistingFile(getIndexHtmlCandidates(projectRoot));\n\nexport const findEntryFile = (projectRoot: string): string | null =>\n findExistingFile(getEntryFileCandidates(projectRoot));\n\nexport const findTanStackRootFile = (projectRoot: string): string | null =>\n findExistingFile(getTanStackRootFileCandidates(projectRoot));\n\nexport const isInstrumentationFile = (filePath: string): boolean =>\n /(?:^|[/\\\\])instrumentation-client\\.[cm]?[jt]sx?$/.test(filePath);\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\";\nimport { hasReactGrabSetupCode } from \"./react-grab-code.js\";\nimport { getReactGrabSetupFileCandidates } from \"./react-grab-setup-files.js\";\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\nexport interface ProjectInfo {\n packageManager: PackageManager;\n framework: Framework;\n nextRouterType: NextRouterType;\n isMonorepo: boolean;\n projectRoot: string;\n hasReactGrab: boolean;\n isReactGrabConfigured: 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\nconst CONFIG_EXTENSIONS = [\"ts\", \"mts\", \"cts\", \"js\", \"mjs\", \"cjs\"] as const;\n\nconst hasConfigFile = (projectRoot: string, configBaseName: string): boolean =>\n CONFIG_EXTENSIONS.some((extension) =>\n existsSync(join(projectRoot, `${configBaseName}.${extension}`)),\n );\n\nconst readMergedDependencies = (projectRoot: string): Record<string, string> | null => {\n const packageJsonPath = join(projectRoot, \"package.json\");\n if (!existsSync(packageJsonPath)) return null;\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n return {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n } catch {\n return null;\n }\n};\n\nconst detectFrameworkFromDependencies = (\n dependencies: Record<string, string> | null,\n): Framework => {\n if (!dependencies) return \"unknown\";\n if (dependencies[\"next\"]) return \"next\";\n if (dependencies[\"@tanstack/react-start\"]) return \"tanstack\";\n if (dependencies[\"vite\"]) return \"vite\";\n if (dependencies[\"webpack\"]) return \"webpack\";\n return \"unknown\";\n};\n\nconst detectFrameworkFromConfigFiles = (projectRoot: string): Framework => {\n if (hasConfigFile(projectRoot, \"next.config\")) return \"next\";\n if (hasConfigFile(projectRoot, \"app.config\")) return \"tanstack\";\n if (hasConfigFile(projectRoot, \"vite.config\")) return \"vite\";\n if (hasConfigFile(projectRoot, \"webpack.config\")) return \"webpack\";\n return \"unknown\";\n};\n\nconst findEnclosingMonorepoRoot = (projectRoot: string): string | null => {\n let currentDirectory = dirname(projectRoot);\n while (currentDirectory !== dirname(currentDirectory)) {\n if (detectMonorepo(currentDirectory)) return currentDirectory;\n currentDirectory = dirname(currentDirectory);\n }\n return null;\n};\n\nexport const detectFramework = (projectRoot: string): Framework => {\n const localFramework = detectFrameworkFromDependencies(readMergedDependencies(projectRoot));\n if (localFramework !== \"unknown\") return localFramework;\n return detectFrameworkFromConfigFiles(projectRoot);\n};\n\nconst detectFrameworkFromMonorepoRoot = (projectRoot: string): Framework => {\n const monorepoRoot = findEnclosingMonorepoRoot(projectRoot);\n if (!monorepoRoot) return \"unknown\";\n return detectFrameworkFromDependencies(readMergedDependencies(monorepoRoot));\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 dependencies = readMergedDependencies(projectPath);\n if (!dependencies) return false;\n return Boolean(dependencies[\"react\"] || dependencies[\"react-dom\"]);\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\nconst normalizePathForComparison = (filePath: string): string => filePath.replace(/\\\\/g, \"/\");\n\nexport const findReactProjects = (projectRoot: string): WorkspaceProject[] => {\n const monorepoRoot = detectMonorepo(projectRoot)\n ? projectRoot\n : findEnclosingMonorepoRoot(projectRoot);\n if (monorepoRoot) {\n const workspaceProjects = findWorkspaceProjects(monorepoRoot);\n const localProject = projectRoot === monorepoRoot ? null : buildReactProject(projectRoot);\n const projects = localProject\n ? [\n localProject,\n ...workspaceProjects.filter(\n (project) =>\n normalizePathForComparison(project.path) !==\n normalizePathForComparison(localProject.path),\n ),\n ]\n : workspaceProjects;\n if (projects.length > 0) {\n return projects;\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 hasReactGrabSetupInFile = (filePath: string): boolean => {\n if (!existsSync(filePath)) return false;\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return hasReactGrabSetupCode(content);\n } catch {\n return false;\n }\n};\n\nconst detectReactGrabDependency = (projectRoot: string): boolean => {\n const dependencies = readMergedDependencies(projectRoot);\n return Boolean(dependencies?.[\"react-grab\"]);\n};\n\nexport const detectReactGrabConfigured = (projectRoot: string): boolean => {\n return getReactGrabSetupFileCandidates(projectRoot).some(hasReactGrabSetupInFile);\n};\n\nexport const detectReactGrab = (projectRoot: string): boolean =>\n detectReactGrabDependency(projectRoot) || detectReactGrabConfigured(projectRoot);\n\nexport const detectUnsupportedFramework = (projectRoot: string): UnsupportedFramework => {\n const dependencies = readMergedDependencies(projectRoot);\n if (!dependencies) return null;\n if (dependencies[\"@remix-run/react\"] || dependencies[\"remix\"]) return \"remix\";\n if (dependencies[\"astro\"]) return \"astro\";\n if (dependencies[\"@sveltejs/kit\"]) return \"sveltekit\";\n if (dependencies[\"gatsby\"]) return \"gatsby\";\n return null;\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 localFramework = detectFramework(projectRoot);\n const framework =\n localFramework === \"unknown\" ? detectFrameworkFromMonorepoRoot(projectRoot) : localFramework;\n const packageManager = await detectPackageManager(projectRoot);\n const isMonorepo = detectMonorepo(projectRoot) || findEnclosingMonorepoRoot(projectRoot) !== null;\n const isReactGrabConfigured = detectReactGrabConfigured(projectRoot);\n\n return {\n packageManager,\n framework,\n nextRouterType: framework === \"next\" ? detectNextRouterType(projectRoot) : \"unknown\",\n isMonorepo,\n projectRoot,\n hasReactGrab: detectReactGrabDependency(projectRoot) || isReactGrabConfigured,\n isReactGrabConfigured,\n reactGrabVersion: detectReactGrabVersion(projectRoot),\n unsupportedFramework: detectUnsupportedFramework(projectRoot),\n };\n};\n","import { accessSync, constants, statSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\nimport {\n type SkillAgentType,\n detectInstalledSkillAgents,\n getSkillAgentTypes,\n} from \"agent-install/skill\";\n\n// PATH binaries used as a supplementary detection signal on top of\n// agent-install's filesystem detection. This catches users who installed a\n// CLI but have not run it yet (no ~/.claude / ~/.cursor / etc. on disk).\n// Only agents whose CLI ships an obvious binary name are listed; FS-only\n// agents rely entirely on agent-install. \"universal\" is a synthetic install\n// target with no binary or config dir.\nconst PATH_BINARIES: Partial<Record<SkillAgentType, readonly string[]>> = {\n \"claude-code\": [\"claude\"],\n codex: [\"codex\"],\n cursor: [\"cursor\", \"cursor-agent\"],\n droid: [\"droid\"],\n \"gemini-cli\": [\"gemini\"],\n \"github-copilot\": [\"copilot\"],\n opencode: [\"opencode\"],\n pi: [\"pi\", \"omegon\"],\n};\n\nconst isCommandAvailable = (command: string): boolean => {\n const pathDirectories = (process.env.PATH ?? \"\").split(delimiter).filter(Boolean);\n for (const directory of pathDirectories) {\n const binaryPath = join(directory, command);\n try {\n if (statSync(binaryPath).isFile()) {\n accessSync(binaryPath, constants.X_OK);\n return true;\n }\n } catch {}\n }\n return false;\n};\n\n// Union of agent-install's filesystem-detected agents (~/.claude, ~/.cursor,\n// etc.) with a supplementary $PATH binary scan that catches agents installed\n// but not yet run (no config dir on disk). Order follows getSkillAgentTypes()\n// for deterministic UI; the synthetic \"universal\" type is filtered out because\n// it is not a user-facing agent.\nexport const detectAvailableAgents = async (): Promise<SkillAgentType[]> => {\n const installedAgents = new Set(await detectInstalledSkillAgents());\n return getSkillAgentTypes().filter((agent) => {\n if (agent === \"universal\") return false;\n if (installedAgents.has(agent)) return true;\n return PATH_BINARIES[agent]?.some(isCommandAvailable) ?? false;\n });\n};\n","import { existsSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n type SkillAgentType,\n add,\n getCanonicalSkillsDir,\n getSkillAgentConfig,\n getSkillAgentDir,\n isUniversalSkillAgent,\n} from \"agent-install/skill\";\nimport { detectAvailableAgents } from \"./detect-agents.js\";\n\nconst SKILL_NAME = \"react-grab\";\n\n// The skill is bundled next to the compiled CLI (see scripts/bundle-skill.mjs)\n// so installs work offline and stay pinned to this CLI version.\nconst SKILL_SOURCE = fileURLToPath(new URL(\"../skills/react-grab\", import.meta.url));\n\nexport const agentLabel = (agent: SkillAgentType): string => getSkillAgentConfig(agent).displayName;\n\n// Universal agents share the canonical .agents/skills directory; others use\n// their own. Mirror where agent-install actually writes so removal lands.\nconst installedSkillDir = (agent: SkillAgentType, global: boolean, cwd: string): string =>\n join(\n isUniversalSkillAgent(agent)\n ? getCanonicalSkillsDir(global, cwd)\n : getSkillAgentDir(agent, { global, cwd }),\n SKILL_NAME,\n );\n\nexport interface InstallSkillOptions {\n agents?: SkillAgentType[];\n global?: boolean;\n cwd?: string;\n}\n\nexport const installSkill = async ({\n agents,\n global = false,\n cwd = process.cwd(),\n}: InstallSkillOptions = {}): Promise<Awaited<ReturnType<typeof add>>> => {\n const targetAgents = agents ?? (await detectAvailableAgents());\n return add({ source: SKILL_SOURCE, agents: targetAgents, global, cwd, mode: \"copy\" });\n};\n\ninterface RemoveSkillOptions {\n cwd?: string;\n global?: boolean;\n}\n\n// Scoped like install (project unless global) so it won't delete a global install\n// from inside an unrelated project.\nexport const removeSkill = async ({\n cwd = process.cwd(),\n global = false,\n}: RemoveSkillOptions = {}): Promise<SkillAgentType[]> => {\n const agents = await detectAvailableAgents();\n const removedAgents: SkillAgentType[] = [];\n const dirsToRemove = new Set<string>();\n for (const agent of agents) {\n const skillDir = installedSkillDir(agent, global, cwd);\n if (!existsSync(skillDir)) continue;\n removedAgents.push(agent);\n dirsToRemove.add(skillDir);\n }\n for (const skillDir of dirsToRemove) {\n rmSync(skillDir, { recursive: true, force: true });\n }\n return removedAgents;\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 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\";\nimport { hasReactGrabSetupCode } from \"./react-grab-code.js\";\nimport {\n findDocumentFile,\n findEntryFile,\n findIndexHtml,\n findLayoutFile,\n findTanStackRootFile,\n getDocumentFileCandidates,\n getEntryFileCandidates,\n getIndexHtmlCandidates,\n getInstrumentationFileCandidates,\n getLayoutFileCandidates,\n getTanStackRootFileCandidates,\n isInstrumentationFile,\n} from \"./react-grab-setup-files.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 hasReactGrabInInstrumentation = (projectRoot: string): boolean => {\n return findFileWithReactGrabSetup(getInstrumentationFileCandidates(projectRoot)) !== null;\n};\n\nconst findFileWithReactGrabSetup = (fileCandidates: string[]): string | null => {\n for (const filePath of fileCandidates) {\n if (!existsSync(filePath)) continue;\n if (hasReactGrabSetupCode(readFileSync(filePath, \"utf-8\"))) return filePath;\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): 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, app/layout.jsx, app/layout.ts, or app/layout.js\",\n };\n }\n\n const originalContent = readFileSync(layoutPath, \"utf-8\");\n let newContent = originalContent;\n const hasReactGrabInFile = hasReactGrabSetupCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(layoutPath);\n }\n\n if (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): 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, pages/_document.jsx, pages/_document.ts, or pages/_document.js.\\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 = hasReactGrabSetupCode(originalContent);\n const hasReactGrabInInstrumentationFile = hasReactGrabInInstrumentation(projectRoot);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(documentPath);\n }\n\n if (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 (!hasReactGrabSetupCode(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): TransformResult => {\n const entryPath = findEntryFile(projectRoot);\n\n const indexPath = findIndexHtml(projectRoot);\n if (indexPath) {\n const existingResult = checkExistingInstallation(indexPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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 const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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): 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 const existingResult = checkExistingInstallation(entryPath, reactGrabAlreadyConfigured);\n if (existingResult) return existingResult;\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): 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 = hasReactGrabSetupCode(originalContent);\n\n if (hasReactGrabInFile && reactGrabAlreadyConfigured) {\n return alreadyConfiguredResult(rootPath);\n }\n\n if (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 hasFrameworkEntryPoint = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n): boolean => {\n switch (framework) {\n case \"next\":\n return nextRouterType === \"app\"\n ? findLayoutFile(projectRoot) !== null\n : findDocumentFile(projectRoot) !== null;\n case \"vite\":\n case \"webpack\":\n return findEntryFile(projectRoot) !== null;\n case \"tanstack\":\n return findTanStackRootFile(projectRoot) !== null;\n default:\n return false;\n }\n};\n\nexport const previewTransform = (\n projectRoot: string,\n framework: Framework,\n nextRouterType: NextRouterType,\n reactGrabAlreadyConfigured: boolean = false,\n): TransformResult => {\n switch (framework) {\n case \"next\":\n if (nextRouterType === \"app\") {\n return transformNextAppRouter(projectRoot, reactGrabAlreadyConfigured);\n }\n return transformNextPagesRouter(projectRoot, reactGrabAlreadyConfigured);\n\n case \"vite\":\n return transformVite(projectRoot, reactGrabAlreadyConfigured);\n\n case \"tanstack\":\n return transformTanStack(projectRoot, reactGrabAlreadyConfigured);\n\n case \"webpack\":\n return transformWebpack(projectRoot, reactGrabAlreadyConfigured);\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 const primaryFile =\n nextRouterType === \"app\" ? findLayoutFile(projectRoot) : findDocumentFile(projectRoot);\n const primaryCandidates =\n nextRouterType === \"app\"\n ? getLayoutFileCandidates(projectRoot)\n : getDocumentFileCandidates(projectRoot);\n const primarySetupFile = findFileWithReactGrabSetup(primaryCandidates);\n if (primarySetupFile) return primarySetupFile;\n\n const instrumentationFile = findFileWithReactGrabSetup(\n getInstrumentationFileCandidates(projectRoot),\n );\n if (instrumentationFile) return instrumentationFile;\n\n return primaryFile;\n }\n case \"vite\": {\n const entryFile = findEntryFile(projectRoot);\n const entrySetupFile = findFileWithReactGrabSetup(getEntryFileCandidates(projectRoot));\n if (entrySetupFile) return entrySetupFile;\n\n const indexHtml = findFileWithReactGrabSetup(getIndexHtmlCandidates(projectRoot));\n if (indexHtml) return indexHtml;\n\n return entryFile;\n }\n case \"tanstack\": {\n const rootSetupFile = findFileWithReactGrabSetup(getTanStackRootFileCandidates(projectRoot));\n return rootSetupFile ?? findTanStackRootFile(projectRoot);\n }\n case \"webpack\": {\n const entrySetupFile = findFileWithReactGrabSetup(getEntryFileCandidates(projectRoot));\n return entrySetupFile ?? findEntryFile(projectRoot);\n }\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 /(void\\s+)?import\\s*\\(\\s*[\"']react-grab(?:\\/[^\"']+)?[\"']\\s*\\)(?:\\.then\\s*\\(\\s*(?:\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\)|\\(\\{\\s*init\\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 voidPrefix = reactGrabImportWithInitMatch[1] ?? \"\";\n const newImport = `${voidPrefix}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\\/core[\"']\\s*\\)\\.then\\s*\\(\\s*(?:\\(\\s*\\{\\s*init\\s*\\}\\s*\\)\\s*=>\\s*init\\s*\\([^)]*\\)|\\(m\\)\\s*=>\\s*m\\.init\\s*\\([^)]*\\))\\s*\\)|(void\\s+)?import\\s*\\(\\s*[\"']react-grab(?!\\/core)(?:\\/[^\"']+)?[\"']\\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 voidPrefix = reactGrabImportWithInitMatch[1] ?? reactGrabImportWithInitMatch[2] ?? \"\";\n const newImport = `${voidPrefix}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\nconst addOptionsToAnyImport = (\n originalContent: string,\n options: ReactGrabOptions,\n filePath: string,\n): TransformResult => {\n const dynamicImportResult = addOptionsToDynamicImport(originalContent, options, filePath);\n if (dynamicImportResult.success) return dynamicImportResult;\n return addOptionsToTanStackImport(originalContent, options, filePath);\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 (!hasReactGrabSetupCode(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 if (isInstrumentationFile(filePath)) {\n return addOptionsToAnyImport(originalContent, options, filePath);\n }\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","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 getPackagesToInstall = (includeReactGrab: boolean = true): string[] => {\n return includeReactGrab ? [\"react-grab\"] : [];\n};\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.48-dev.f29c951",
3
+ "version": "0.1.48-dev.fe982d7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/aidenybai/react-grab.git"