uilint 0.2.78 → 0.2.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-EBKSYMP2.js → chunk-KCDJL7K7.js} +37 -10
- package/dist/chunk-KCDJL7K7.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/{init-ui-3ACPQCQD.js → init-ui-J7TB6LI4.js} +2 -2
- package/dist/{remove-ui-LSV3JOZO.js → remove-ui-IJMGC7YS.js} +2 -2
- package/package.json +5 -5
- package/dist/chunk-EBKSYMP2.js.map +0 -1
- /package/dist/{init-ui-3ACPQCQD.js.map → init-ui-J7TB6LI4.js.map} +0 -0
- /package/dist/{remove-ui-LSV3JOZO.js.map → remove-ui-IJMGC7YS.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/init/analyze.ts","../src/utils/vite-detect.ts","../src/utils/package-detect.ts","../src/commands/init/execute.ts","../src/utils/react-inject.ts","../src/utils/next-config-inject.ts","../src/utils/vite-config-inject.ts","../src/utils/next-routes.ts","../src/utils/prettier.ts","../src/utils/tsconfig-inject.ts","../src/commands/init/installers/registry.ts","../src/commands/init/installers/genstyleguide.ts","../src/commands/init/installers/skill.ts","../src/commands/init/installers/eslint.ts","../src/commands/init/installers/ai-hooks.ts","../src/utils/client-boundary-tracer.ts","../src/commands/init/installers/next-overlay.ts","../src/commands/init/installers/vite-overlay.ts","../src/commands/init/installers/index.ts","../src/commands/init/components/Spinner.tsx"],"sourcesContent":["/**\n * Analyze phase - scan project and return ProjectState\n *\n * This is a pure scanning function with no prompts or mutations.\n * It aggregates detection from existing utilities to build a complete\n * picture of the project state.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { join, relative } from \"path\";\nimport { findWorkspaceRoot } from \"uilint-core/node\";\nimport {\n detectNextAppRouter,\n findNextAppRouterProjects,\n} from \"../../utils/next-detect.js\";\nimport {\n detectViteReact,\n findViteReactProjects,\n} from \"../../utils/vite-detect.js\";\nimport { findPackages } from \"../../utils/package-detect.js\";\nimport { detectPackageManager } from \"../../utils/package-manager.js\";\nimport {\n findEslintConfigFile,\n getEslintConfigFilename,\n getUilintEslintConfigInfoFromSource,\n} from \"../../utils/eslint-config-inject.js\";\nimport type {\n ProjectState,\n EslintPackageInfo,\n NextAppInfo,\n ViteAppInfo,\n} from \"./types.js\";\n\n// NOTE: uilint rule detection must ignore commented-out keys and handle spreads.\n// We re-use the AST-backed detector from eslint-config-inject.\n\n/**\n * Safely parse JSON file, returning undefined on error\n */\nfunction safeParseJson<T>(filePath: string): T | undefined {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if uilint-react overlay is installed in a project\n * Detects by checking if uilint-react is in dependencies\n */\nfunction hasUilintOverlayInstalled(projectPath: string): boolean {\n const pkgPath = join(projectPath, \"package.json\");\n const pkg = safeParseJson<{\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n }>(pkgPath);\n\n if (!pkg) return false;\n\n return !!(\n pkg.dependencies?.[\"uilint-react\"] ||\n pkg.devDependencies?.[\"uilint-react\"]\n );\n}\n\n/**\n * Analyze a project and return its state\n *\n * @param projectPath - The project directory to analyze (defaults to cwd)\n * @returns ProjectState describing what exists in the project\n */\nexport async function analyze(\n projectPath: string = process.cwd()\n): Promise<ProjectState> {\n // Find workspace root (may differ from projectPath in monorepos)\n const workspaceRoot = findWorkspaceRoot(projectPath);\n\n // Detect package manager\n const packageManager = detectPackageManager(projectPath);\n\n // .cursor directory\n const cursorDir = join(projectPath, \".cursor\");\n const cursorDirExists = existsSync(cursorDir);\n\n // Styleguide\n const styleguidePath = join(projectPath, \".uilint\", \"styleguide.md\");\n const styleguideExists = existsSync(styleguidePath);\n\n // Cursor commands\n const commandsDir = join(cursorDir, \"commands\");\n const genstyleguideExists = existsSync(join(commandsDir, \"genstyleguide.md\"));\n\n // Detect Next.js App Router projects\n const nextApps: NextAppInfo[] = [];\n const directDetection = detectNextAppRouter(projectPath);\n if (directDetection) {\n nextApps.push({\n projectPath,\n detection: directDetection,\n hasUilintOverlay: hasUilintOverlayInstalled(projectPath),\n });\n } else {\n // Search in workspace for Next.js apps\n const matches = findNextAppRouterProjects(workspaceRoot, { maxDepth: 5 });\n for (const match of matches) {\n nextApps.push({\n projectPath: match.projectPath,\n detection: match.detection,\n hasUilintOverlay: hasUilintOverlayInstalled(match.projectPath),\n });\n }\n }\n\n // Detect Vite + React projects\n const viteApps: ViteAppInfo[] = [];\n const directVite = detectViteReact(projectPath);\n if (directVite) {\n viteApps.push({\n projectPath,\n detection: directVite,\n hasUilintOverlay: hasUilintOverlayInstalled(projectPath),\n });\n } else {\n const matches = findViteReactProjects(workspaceRoot, { maxDepth: 5 });\n for (const match of matches) {\n viteApps.push({\n projectPath: match.projectPath,\n detection: match.detection,\n hasUilintOverlay: hasUilintOverlayInstalled(match.projectPath),\n });\n }\n }\n\n // Find packages to configure ESLint in\n // If projectPath is a package itself, only include that package (not the whole workspace)\n // This prevents installing into sibling packages when running from a specific project\n let rawPackages = findPackages(workspaceRoot);\n const projectHasPackageJson = existsSync(join(projectPath, \"package.json\"));\n if (projectHasPackageJson && projectPath !== workspaceRoot) {\n // Filter to only include the current project\n rawPackages = rawPackages.filter((pkg) => pkg.path === projectPath);\n\n // If the current project wasn't found (e.g., it's in a dot-prefixed directory\n // like .vercel-deploy which findPackages skips), add it directly\n if (rawPackages.length === 0) {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const name = pkg.name || relative(workspaceRoot, projectPath) || \".\";\n const displayPath = relative(workspaceRoot, projectPath) || \".\";\n\n // Detect if it's a frontend package\n const deps = {\n ...(pkg.dependencies as Record<string, string> | undefined),\n ...(pkg.devDependencies as Record<string, string> | undefined),\n };\n const frontendIndicators = [\"react\", \"react-dom\", \"next\", \"vue\", \"svelte\", \"@angular/core\", \"solid-js\", \"preact\"];\n const isFrontend = frontendIndicators.some((dep) => dep in deps);\n\n // Detect TypeScript\n const isTypeScript = existsSync(join(projectPath, \"tsconfig.json\")) || \"typescript\" in deps;\n\n // Check for ESLint config\n const eslintConfigFiles = [\"eslint.config.js\", \"eslint.config.ts\", \"eslint.config.mjs\", \"eslint.config.cjs\"];\n const hasEslintConfig = eslintConfigFiles.some((f) => existsSync(join(projectPath, f)));\n\n rawPackages.push({\n path: projectPath,\n displayPath,\n name,\n hasEslintConfig,\n isFrontend,\n isRoot: false,\n isTypeScript,\n });\n } catch {\n // Ignore parse errors\n }\n }\n }\n const packages: EslintPackageInfo[] = rawPackages.map((pkg) => {\n const eslintConfigPath = findEslintConfigFile(pkg.path);\n let eslintConfigFilename: string | null = null;\n let hasRules = false;\n let configuredRuleIds: string[] = [];\n\n if (eslintConfigPath) {\n eslintConfigFilename = getEslintConfigFilename(eslintConfigPath);\n try {\n const source = readFileSync(eslintConfigPath, \"utf-8\");\n const info = getUilintEslintConfigInfoFromSource(source);\n hasRules = info.configuredRuleIds.size > 0;\n configuredRuleIds = Array.from(info.configuredRuleIds);\n } catch {\n // Ignore read errors\n }\n }\n\n return {\n ...pkg,\n eslintConfigPath,\n eslintConfigFilename,\n hasUilintRules: hasRules,\n configuredRuleIds,\n };\n });\n\n return {\n projectPath,\n workspaceRoot,\n packageManager,\n cursorDir: {\n exists: cursorDirExists,\n path: cursorDir,\n },\n styleguide: {\n exists: styleguideExists,\n path: styleguidePath,\n },\n commands: {\n genstyleguide: genstyleguideExists,\n },\n nextApps,\n viteApps,\n packages,\n };\n}\n","import { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface ViteReactDetection {\n /**\n * Relative path to the Vite config file (e.g. \"vite.config.ts\").\n */\n configFile: string;\n /**\n * Absolute path to the Vite config file.\n */\n configFileAbs: string;\n /**\n * Relative path to the source root (usually \"src\").\n */\n entryRoot: string;\n /**\n * Candidate entry files (relative paths) that are good injection targets.\n * For Vite+React this is usually `src/main.*`.\n */\n candidates: string[];\n}\n\nconst VITE_CONFIG_EXTS = [\".ts\", \".mjs\", \".js\", \".cjs\"];\n\nfunction findViteConfigFile(projectPath: string): string | null {\n for (const ext of VITE_CONFIG_EXTS) {\n const rel = `vite.config${ext}`;\n if (existsSync(join(projectPath, rel))) return rel;\n }\n return null;\n}\n\nfunction looksLikeReactPackage(projectPath: string): boolean {\n try {\n const pkgPath = join(projectPath, \"package.json\");\n if (!existsSync(pkgPath)) return false;\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };\n return \"react\" in deps || \"react-dom\" in deps;\n } catch {\n return false;\n }\n}\n\nfunction fileExists(projectPath: string, relPath: string): boolean {\n return existsSync(join(projectPath, relPath));\n}\n\nexport function detectViteReact(projectPath: string): ViteReactDetection | null {\n const configFile = findViteConfigFile(projectPath);\n if (!configFile) return null;\n\n // Overlay integration currently targets React apps.\n if (!looksLikeReactPackage(projectPath)) return null;\n\n // Prefer Vite defaults: src/main.(tsx|jsx|ts|js)\n const entryRoot = \"src\";\n const candidates: string[] = [];\n const entryCandidates = [\n join(entryRoot, \"main.tsx\"),\n join(entryRoot, \"main.jsx\"),\n join(entryRoot, \"main.ts\"),\n join(entryRoot, \"main.js\"),\n ];\n\n for (const rel of entryCandidates) {\n if (fileExists(projectPath, rel)) candidates.push(rel);\n }\n\n // If no main.* exists, try common fallbacks (some templates render in App.tsx)\n const fallbackCandidates = [\n join(entryRoot, \"App.tsx\"),\n join(entryRoot, \"App.jsx\"),\n ];\n for (const rel of fallbackCandidates) {\n if (!candidates.includes(rel) && fileExists(projectPath, rel)) {\n candidates.push(rel);\n }\n }\n\n return {\n configFile,\n configFileAbs: join(projectPath, configFile),\n entryRoot,\n candidates,\n };\n}\n\nexport interface ViteReactProjectMatch {\n /**\n * Absolute path to the Vite project root (dir containing vite.config.*).\n */\n projectPath: string;\n detection: ViteReactDetection;\n}\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \".turbo\",\n \".vercel\",\n \".cursor\",\n \"coverage\",\n \".uilint\",\n]);\n\n/**\n * Best-effort monorepo discovery for Vite + React apps.\n *\n * Walks down from `rootDir` looking for directories that contain `vite.config.*`\n * and whose package.json looks like a React project.\n */\nexport function findViteReactProjects(\n rootDir: string,\n options?: { maxDepth?: number; ignoreDirs?: Set<string> }\n): ViteReactProjectMatch[] {\n const maxDepth = options?.maxDepth ?? 4;\n const ignoreDirs = options?.ignoreDirs ?? DEFAULT_IGNORE_DIRS;\n const results: ViteReactProjectMatch[] = [];\n const visited = new Set<string>();\n\n function walk(dir: string, depth: number) {\n if (depth > maxDepth) return;\n if (visited.has(dir)) return;\n visited.add(dir);\n\n const detection = detectViteReact(dir);\n if (detection) {\n results.push({ projectPath: dir, detection });\n return;\n }\n\n let entries: Array<{ name: string; isDirectory: boolean }> = [];\n try {\n entries = readdirSync(dir, { withFileTypes: true }).map((d) => ({\n name: d.name,\n isDirectory: d.isDirectory(),\n }));\n } catch {\n return;\n }\n\n for (const ent of entries) {\n if (!ent.isDirectory) continue;\n if (ignoreDirs.has(ent.name)) continue;\n if (ent.name.startsWith(\".\") && ent.name !== \".\") continue;\n walk(join(dir, ent.name), depth + 1);\n }\n }\n\n walk(rootDir, 0);\n return results;\n}\n","/**\n * Package.json detection utilities for monorepo discovery\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join, relative } from \"path\";\n\nexport interface PackageInfo {\n /** Absolute path to the package directory */\n path: string;\n /** Display name (relative path from workspace root) */\n displayPath: string;\n /** Package name from package.json */\n name: string;\n /** Whether this package has ESLint config */\n hasEslintConfig: boolean;\n /** Whether this appears to be a frontend/UI package */\n isFrontend: boolean;\n /** Whether this is the workspace root */\n isRoot: boolean;\n /** Whether this package uses TypeScript */\n isTypeScript: boolean;\n}\n\nconst DEFAULT_IGNORE_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \".turbo\",\n \".vercel\",\n \".cursor\",\n \"coverage\",\n \".uilint\",\n \".pnpm\",\n]);\n\nconst ESLINT_CONFIG_FILES = [\n \"eslint.config.js\",\n \"eslint.config.ts\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \".eslintrc.js\",\n \".eslintrc.cjs\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n \".eslintrc\",\n];\n\nconst FRONTEND_INDICATORS = [\n \"react\",\n \"react-dom\",\n \"next\",\n \"vue\",\n \"svelte\",\n \"@angular/core\",\n \"solid-js\",\n \"preact\",\n];\n\n/**\n * Check if a package.json indicates a frontend project\n */\nfunction isFrontendPackage(pkgJson: Record<string, unknown>): boolean {\n const deps = {\n ...(pkgJson.dependencies as Record<string, string> | undefined),\n ...(pkgJson.devDependencies as Record<string, string> | undefined),\n };\n\n return FRONTEND_INDICATORS.some((pkg) => pkg in deps);\n}\n\n/**\n * Check if a package uses TypeScript\n */\nfunction isTypeScriptPackage(dir: string, pkgJson: Record<string, unknown>): boolean {\n // Check for tsconfig.json\n if (existsSync(join(dir, \"tsconfig.json\"))) {\n return true;\n }\n\n // Check for typescript in dependencies\n const deps = {\n ...(pkgJson.dependencies as Record<string, string> | undefined),\n ...(pkgJson.devDependencies as Record<string, string> | undefined),\n };\n\n if (\"typescript\" in deps) {\n return true;\n }\n\n // Check ESLint config file extension (if .ts, it's TypeScript)\n for (const configFile of ESLINT_CONFIG_FILES) {\n if (configFile.endsWith(\".ts\") && existsSync(join(dir, configFile))) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if directory has ESLint config\n */\nfunction hasEslintConfig(dir: string): boolean {\n for (const file of ESLINT_CONFIG_FILES) {\n if (existsSync(join(dir, file))) {\n return true;\n }\n }\n\n // Also check package.json for eslintConfig field\n try {\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n if (pkg.eslintConfig) return true;\n }\n } catch {\n // Ignore parse errors\n }\n\n return false;\n}\n\n/**\n * Find all packages in a workspace that could have ESLint installed\n */\nexport function findPackages(\n rootDir: string,\n options?: { maxDepth?: number; ignoreDirs?: Set<string> }\n): PackageInfo[] {\n const maxDepth = options?.maxDepth ?? 5;\n const ignoreDirs = options?.ignoreDirs ?? DEFAULT_IGNORE_DIRS;\n const results: PackageInfo[] = [];\n const visited = new Set<string>();\n\n function processPackage(dir: string, isRoot: boolean): PackageInfo | null {\n const pkgPath = join(dir, \"package.json\");\n if (!existsSync(pkgPath)) return null;\n\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n const name = pkg.name || relative(rootDir, dir) || \".\";\n\n return {\n path: dir,\n displayPath: relative(rootDir, dir) || \".\",\n name,\n hasEslintConfig: hasEslintConfig(dir),\n isFrontend: isFrontendPackage(pkg),\n isRoot,\n isTypeScript: isTypeScriptPackage(dir, pkg),\n };\n } catch {\n return null;\n }\n }\n\n function walk(dir: string, depth: number) {\n if (depth > maxDepth) return;\n if (visited.has(dir)) return;\n visited.add(dir);\n\n // Check for package.json in this dir\n const pkg = processPackage(dir, depth === 0);\n if (pkg) {\n results.push(pkg);\n }\n\n // Continue walking (even if we found a package - monorepos have nested packages)\n let entries: Array<{ name: string; isDirectory: boolean }> = [];\n try {\n entries = readdirSync(dir, { withFileTypes: true }).map((d) => ({\n name: d.name,\n isDirectory: d.isDirectory(),\n }));\n } catch {\n return;\n }\n\n for (const ent of entries) {\n if (!ent.isDirectory) continue;\n if (ignoreDirs.has(ent.name)) continue;\n if (ent.name.startsWith(\".\")) continue;\n walk(join(dir, ent.name), depth + 1);\n }\n }\n\n walk(rootDir, 0);\n\n // Sort: frontend packages first, then by path\n return results.sort((a, b) => {\n // Root package first\n if (a.isRoot && !b.isRoot) return -1;\n if (!a.isRoot && b.isRoot) return 1;\n // Frontend packages next\n if (a.isFrontend && !b.isFrontend) return -1;\n if (!a.isFrontend && b.isFrontend) return 1;\n // Then alphabetically by path\n return a.displayPath.localeCompare(b.displayPath);\n });\n}\n\n/**\n * Format package info for display in selection menu\n */\nexport function formatPackageOption(pkg: PackageInfo): {\n value: string;\n label: string;\n hint?: string;\n} {\n const hints: string[] = [];\n\n if (pkg.isRoot) hints.push(\"workspace root\");\n if (pkg.isFrontend) hints.push(\"frontend\");\n if (pkg.hasEslintConfig) hints.push(\"has ESLint config\");\n\n return {\n value: pkg.path,\n label:\n pkg.displayPath === \".\" ? pkg.name : `${pkg.name} (${pkg.displayPath})`,\n hint: hints.length > 0 ? hints.join(\", \") : undefined,\n };\n}\n","/**\n * Execute phase - perform side effects from InstallPlan\n *\n * This module takes an InstallPlan and performs all the actual file operations,\n * dependency installations, and config modifications.\n */\n\nimport {\n existsSync,\n mkdirSync,\n writeFileSync,\n readFileSync,\n unlinkSync,\n chmodSync,\n rmSync,\n} from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport type {\n InstallPlan,\n InstallAction,\n InstallResult,\n ActionResult,\n DependencyResult,\n InstallSummary,\n ExecuteOptions,\n InjectEslintAction,\n InjectReactAction,\n InjectNextConfigAction,\n InjectViteConfigAction,\n InjectVitestCoverageAction,\n InjectTsconfigAction,\n InstallNextRoutesAction,\n RemoveEslintAction,\n RemoveReactAction,\n RemoveNextConfigAction,\n RemoveViteConfigAction,\n RemoveNextRoutesAction,\n RemoveDirectoryAction,\n UpdateManifestAction,\n} from \"./types.js\";\nimport { installDependencies as defaultInstallDependencies } from \"../../utils/package-manager.js\";\nimport { installEslintPlugin, removeEslintPlugin } from \"../../utils/eslint-config-inject.js\";\nimport { installReactUILintOverlay, removeReactUILintOverlay } from \"../../utils/react-inject.js\";\nimport { installJsxLocPlugin, removeJsxLocPlugin } from \"../../utils/next-config-inject.js\";\nimport { installViteJsxLocPlugin, removeViteJsxLocPlugin } from \"../../utils/vite-config-inject.js\";\nimport { installNextUILintRoutes, removeNextUILintRoutes } from \"../../utils/next-routes.js\";\nimport { formatFilesWithPrettier, touchFiles } from \"../../utils/prettier.js\";\nimport { findWorkspaceRoot } from \"uilint-core/node\";\nimport { detectCoverageSetup } from \"../../utils/coverage-detect.js\";\nimport { injectCoverageConfig } from \"../../utils/coverage-prepare.js\";\nimport { injectTsconfigExclusion } from \"../../utils/tsconfig-inject.js\";\nimport { updateManifestRule } from \"../../utils/manifest.js\";\n\n/**\n * Execute a single action and return the result\n */\nasync function executeAction(\n action: InstallAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n try {\n switch (action.type) {\n case \"create_directory\": {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Create directory: ${action.path}`,\n };\n }\n if (!existsSync(action.path)) {\n mkdirSync(action.path, { recursive: true });\n }\n return { action, success: true };\n }\n\n case \"create_file\": {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Create file: ${action.path}${\n action.permissions\n ? ` (mode: ${action.permissions.toString(8)})`\n : \"\"\n }`,\n };\n }\n // Ensure parent directory exists\n const dir = dirname(action.path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(action.path, action.content, \"utf-8\");\n if (action.permissions) {\n chmodSync(action.path, action.permissions);\n }\n return { action, success: true };\n }\n\n case \"merge_json\": {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Merge JSON into: ${action.path}`,\n };\n }\n let existing: Record<string, unknown> = {};\n if (existsSync(action.path)) {\n try {\n existing = JSON.parse(readFileSync(action.path, \"utf-8\"));\n } catch {\n // Start fresh if parse fails\n }\n }\n const merged = deepMerge(existing, action.merge);\n // Ensure parent directory exists\n const dir = dirname(action.path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(action.path, JSON.stringify(merged, null, 2), \"utf-8\");\n return { action, success: true };\n }\n\n case \"delete_file\": {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Delete file: ${action.path}`,\n };\n }\n if (existsSync(action.path)) {\n unlinkSync(action.path);\n }\n return { action, success: true };\n }\n\n case \"append_to_file\": {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Append to file: ${action.path}`,\n };\n }\n if (existsSync(action.path)) {\n const content = readFileSync(action.path, \"utf-8\");\n if (action.ifNotContains && content.includes(action.ifNotContains)) {\n // Already contains the content, skip\n return { action, success: true };\n }\n writeFileSync(action.path, content + action.content, \"utf-8\");\n }\n // If file doesn't exist, skip (don't create .gitignore from scratch)\n return { action, success: true };\n }\n\n case \"inject_eslint\": {\n return await executeInjectEslint(action, options);\n }\n\n case \"inject_react\": {\n return await executeInjectReact(action, options);\n }\n\n case \"inject_next_config\": {\n return await executeInjectNextConfig(action, options);\n }\n\n case \"inject_vite_config\": {\n return await executeInjectViteConfig(action, options);\n }\n\n case \"inject_vitest_coverage\": {\n return await executeInjectVitestCoverage(action, options);\n }\n\n case \"inject_tsconfig\": {\n return await executeInjectTsconfig(action, options);\n }\n\n case \"install_next_routes\": {\n return await executeInstallNextRoutes(action, options);\n }\n\n // Uninstall actions\n case \"remove_eslint\": {\n return await executeRemoveEslint(action, options);\n }\n\n case \"remove_react\": {\n return await executeRemoveReact(action, options);\n }\n\n case \"remove_next_config\": {\n return await executeRemoveNextConfig(action, options);\n }\n\n case \"remove_vite_config\": {\n return await executeRemoveViteConfig(action, options);\n }\n\n case \"remove_next_routes\": {\n return await executeRemoveNextRoutes(action, options);\n }\n\n case \"remove_directory\": {\n return await executeRemoveDirectory(action, options);\n }\n\n case \"update_manifest\": {\n return await executeUpdateManifest(action, options);\n }\n\n default: {\n // Exhaustiveness check\n const _exhaustive: never = action;\n return {\n action: _exhaustive,\n success: false,\n error: `Unknown action type`,\n };\n }\n }\n } catch (error) {\n return {\n action,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Execute ESLint injection\n */\nasync function executeInjectEslint(\n action: InjectEslintAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Inject ESLint rules into: ${action.configPath}`,\n };\n }\n\n // Use the existing installEslintPlugin function\n // It handles all the complexity of parsing and modifying the config\n const result = await installEslintPlugin({\n projectPath: action.packagePath,\n selectedRules: action.rules,\n force: !action.hasExistingRules, // Don't force if already has rules\n // Auto-confirm for execute phase (choices were made during planning)\n confirmAddMissingRules: async () => true,\n });\n\n return {\n action,\n success: result.configFile !== null && result.configured,\n error:\n result.configFile === null\n ? \"No ESLint config found\"\n : result.configured\n ? undefined\n : result.error ?? \"Failed to configure uilint in ESLint config\",\n };\n}\n\n/**\n * Execute React overlay injection\n */\nasync function executeInjectReact(\n action: InjectReactAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n const dryRunDescription = action.createProviders\n ? `Create providers.tsx and inject <uilint-devtools /> in: ${action.projectPath}`\n : action.targetFile\n ? `Inject <uilint-devtools /> into: ${action.targetFile}`\n : `Inject <uilint-devtools /> into React app: ${action.projectPath}`;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: dryRunDescription,\n };\n }\n\n const result = await installReactUILintOverlay({\n projectPath: action.projectPath,\n appRoot: action.appRoot,\n mode: action.mode,\n force: false,\n // Pass through targetFile and createProviders from the action\n targetFile: action.targetFile,\n createProviders: action.createProviders,\n // Auto-select first choice for execute phase (fallback if no targetFile)\n confirmFileChoice: async (choices) => choices[0]!,\n });\n\n // Success if modified OR already configured (goal achieved either way)\n const success = result.modified || result.alreadyConfigured === true;\n\n return {\n action,\n success,\n error: success ? undefined : \"Failed to configure React overlay\",\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute Vite config injection\n */\nasync function executeInjectViteConfig(\n action: InjectViteConfigAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Inject jsx-loc-plugin into vite.config: ${action.projectPath}`,\n };\n }\n\n const result = await installViteJsxLocPlugin({\n projectPath: action.projectPath,\n force: false,\n });\n\n return {\n action,\n success: result.modified || result.configFile !== null,\n error: result.configFile === null ? \"No vite.config found\" : undefined,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute vitest coverage config injection\n *\n * This action is \"soft\" - it succeeds even if no vitest config is found.\n * The coverage rule will still work, it just won't have automatic coverage setup.\n */\nasync function executeInjectVitestCoverage(\n action: InjectVitestCoverageAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n // Detect vitest config\n const setup = detectCoverageSetup(action.projectPath);\n const vitestConfigPath = action.vitestConfigPath || setup.vitestConfigPath;\n\n // If no vitest config found, succeed silently (soft failure)\n // The package will still be installed, user can configure coverage manually\n if (!vitestConfigPath) {\n return {\n action,\n success: true, // Don't fail the install, coverage config is optional\n };\n }\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Inject coverage config into vitest.config: ${vitestConfigPath}`,\n };\n }\n\n // Inject coverage config\n const modified = injectCoverageConfig(vitestConfigPath);\n\n return {\n action,\n success: true,\n modifiedFiles: modified ? [vitestConfigPath] : undefined,\n };\n}\n\n/**\n * Execute tsconfig.json exclusion injection\n *\n * This action is \"soft\" - it succeeds even if no tsconfig.json is found.\n * Projects without TypeScript don't need this exclusion.\n */\nasync function executeInjectTsconfig(\n action: InjectTsconfigAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Add .uilint to tsconfig.json exclude: ${action.projectPath}`,\n };\n }\n\n const result = injectTsconfigExclusion(action.projectPath);\n\n return {\n action,\n success: true, // Soft failure - don't fail install if tsconfig not found\n modifiedFiles: result.modified && result.tsconfigPath ? [result.tsconfigPath] : undefined,\n };\n}\n\n/**\n * Execute Next.js config injection\n */\nasync function executeInjectNextConfig(\n action: InjectNextConfigAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Inject jsx-loc-plugin into next.config: ${action.projectPath}`,\n };\n }\n\n const result = await installJsxLocPlugin({\n projectPath: action.projectPath,\n force: false,\n });\n\n return {\n action,\n success: result.modified || result.configFile !== null,\n error: result.configFile === null ? \"No next.config found\" : undefined,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute Next.js routes installation\n */\nasync function executeInstallNextRoutes(\n action: InstallNextRoutesAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Install Next.js API routes: ${action.projectPath}`,\n };\n }\n\n await installNextUILintRoutes({\n projectPath: action.projectPath,\n appRoot: action.appRoot,\n force: false,\n });\n\n return { action, success: true };\n}\n\n// ============================================================================\n// Remove action executors\n// ============================================================================\n\n/**\n * Execute ESLint removal\n */\nasync function executeRemoveEslint(\n action: RemoveEslintAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove uilint ESLint rules from: ${action.configPath}`,\n };\n }\n\n const result = await removeEslintPlugin({\n projectPath: action.packagePath,\n });\n\n return {\n action,\n success: result.success,\n error: result.error,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute React overlay removal\n */\nasync function executeRemoveReact(\n action: RemoveReactAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove <uilint-devtools /> from: ${action.projectPath}`,\n };\n }\n\n const result = await removeReactUILintOverlay({\n projectPath: action.projectPath,\n appRoot: action.appRoot,\n mode: action.mode,\n });\n\n return {\n action,\n success: result.success,\n error: result.error,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute Next.js config plugin removal\n */\nasync function executeRemoveNextConfig(\n action: RemoveNextConfigAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove jsx-loc-plugin from next.config: ${action.projectPath}`,\n };\n }\n\n const result = await removeJsxLocPlugin({\n projectPath: action.projectPath,\n });\n\n return {\n action,\n success: result.success,\n error: result.error,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute Vite config plugin removal\n */\nasync function executeRemoveViteConfig(\n action: RemoveViteConfigAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove jsx-loc-plugin from vite.config: ${action.projectPath}`,\n };\n }\n\n const result = await removeViteJsxLocPlugin({\n projectPath: action.projectPath,\n });\n\n return {\n action,\n success: result.success,\n error: result.error,\n modifiedFiles: result.modifiedFiles,\n };\n}\n\n/**\n * Execute Next.js routes removal\n */\nasync function executeRemoveNextRoutes(\n action: RemoveNextRoutesAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove Next.js API routes: ${action.projectPath}`,\n };\n }\n\n const result = await removeNextUILintRoutes({\n projectPath: action.projectPath,\n appRoot: action.appRoot,\n });\n\n return {\n action,\n success: result.success,\n error: result.error,\n };\n}\n\n/**\n * Execute directory removal\n */\nasync function executeRemoveDirectory(\n action: RemoveDirectoryAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Remove directory: ${action.path}`,\n };\n }\n\n if (existsSync(action.path)) {\n rmSync(action.path, { recursive: true, force: true });\n }\n\n return { action, success: true };\n}\n\n/**\n * Execute manifest update\n */\nasync function executeUpdateManifest(\n action: UpdateManifestAction,\n options: ExecuteOptions\n): Promise<ActionResult> {\n const { dryRun = false } = options;\n\n if (dryRun) {\n const ruleCount = Object.keys(action.rules).length;\n return {\n action,\n success: true,\n wouldDo: `Update manifest with ${ruleCount} rule(s) in: ${action.projectPath}`,\n };\n }\n\n try {\n // Get the CLI version for the manifest\n const cliVersion = getCliVersion();\n\n // Update manifest for each rule\n for (const [ruleId, version] of Object.entries(action.rules)) {\n updateManifestRule(action.projectPath, ruleId, version, cliVersion);\n }\n\n return { action, success: true };\n } catch (error) {\n return {\n action,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Get CLI version from package.json\n */\nfunction getCliVersion(): string {\n try {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = join(__dirname, \"..\", \"..\", \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as {\n version?: string;\n };\n return pkg.version || \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\n/**\n * Deep merge two objects\n */\nfunction deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>\n): Record<string, unknown> {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n\n if (\n sourceVal &&\n typeof sourceVal === \"object\" &&\n !Array.isArray(sourceVal) &&\n targetVal &&\n typeof targetVal === \"object\" &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(\n targetVal as Record<string, unknown>,\n sourceVal as Record<string, unknown>\n );\n } else {\n result[key] = sourceVal;\n }\n }\n\n return result;\n}\n\n/**\n * Build the install summary from results\n */\nfunction buildSummary(\n actionsPerformed: ActionResult[],\n dependencyResults: DependencyResult[],\n items: string[]\n): InstallSummary {\n const filesCreated: string[] = [];\n const filesModified: string[] = [];\n const filesDeleted: string[] = [];\n const eslintTargets: { displayName: string; configFile: string }[] = [];\n let nextApp: { appRoot: string } | undefined;\n let viteApp: { entryRoot: string } | undefined;\n\n for (const result of actionsPerformed) {\n if (!result.success) continue;\n\n const { action } = result;\n switch (action.type) {\n case \"create_file\":\n filesCreated.push(action.path);\n break;\n case \"merge_json\":\n case \"append_to_file\":\n filesModified.push(action.path);\n break;\n case \"delete_file\":\n filesDeleted.push(action.path);\n break;\n case \"inject_eslint\":\n filesModified.push(action.configPath);\n eslintTargets.push({\n displayName: action.packagePath,\n configFile: action.configPath,\n });\n break;\n case \"inject_react\":\n if (action.mode === \"vite\") {\n viteApp = { entryRoot: action.appRoot };\n } else {\n nextApp = { appRoot: action.appRoot };\n }\n break;\n case \"install_next_routes\":\n nextApp = { appRoot: action.appRoot };\n break;\n }\n }\n\n const dependenciesInstalled: { packagePath: string; packages: string[] }[] =\n [];\n for (const result of dependencyResults) {\n if (result.success && !result.skipped) {\n dependenciesInstalled.push({\n packagePath: result.install.packagePath,\n packages: result.install.packages,\n });\n }\n }\n\n return {\n installedItems: items as InstallSummary[\"installedItems\"],\n filesCreated,\n filesModified,\n filesDeleted,\n dependenciesInstalled,\n eslintTargets,\n nextApp,\n viteApp,\n };\n}\n\n/**\n * Collect files that should be formatted with prettier\n * Includes source files (.ts, .tsx, .js, .jsx, .mjs, .cjs) but excludes markdown\n */\nfunction collectFormattableFiles(actionsPerformed: ActionResult[]): string[] {\n const formattableExtensions = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".mjs\",\n \".cjs\",\n \".json\",\n ]);\n\n const files: string[] = [];\n\n for (const result of actionsPerformed) {\n if (!result.success) continue;\n const { action } = result;\n\n let filePath: string | undefined;\n\n switch (action.type) {\n case \"create_file\":\n filePath = action.path;\n break;\n case \"merge_json\":\n filePath = action.path;\n break;\n case \"append_to_file\":\n filePath = action.path;\n break;\n case \"inject_eslint\":\n filePath = action.configPath;\n break;\n case \"inject_next_config\":\n case \"inject_vite_config\":\n case \"inject_react\":\n // These actions now return modifiedFiles, which are collected below\n break;\n }\n\n if (filePath) {\n const ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n if (formattableExtensions.has(ext)) {\n files.push(filePath);\n }\n }\n\n // Also collect any modifiedFiles from injection actions\n if (result.modifiedFiles) {\n for (const modifiedPath of result.modifiedFiles) {\n const ext = modifiedPath.slice(modifiedPath.lastIndexOf(\".\")).toLowerCase();\n if (formattableExtensions.has(ext) && !files.includes(modifiedPath)) {\n files.push(modifiedPath);\n }\n }\n }\n }\n\n return files;\n}\n\n/**\n * Extract project path from actions\n */\nfunction getProjectPathFromActions(\n actionsPerformed: ActionResult[]\n): string | undefined {\n for (const result of actionsPerformed) {\n if (!result.success) continue;\n const { action } = result;\n\n switch (action.type) {\n case \"inject_eslint\":\n return action.packagePath;\n case \"inject_react\":\n case \"inject_next_config\":\n case \"inject_vite_config\":\n case \"install_next_routes\":\n return action.projectPath;\n }\n }\n return undefined;\n}\n\nfunction normalizePnpmWorkspaceUilintSpecs(\n packagePath: string,\n packages: string[]\n): string[] {\n // If we're in a pnpm workspace, prefer linking internal packages from the\n // workspace to avoid registry mismatches during local dev.\n const workspaceRoot = findWorkspaceRoot(packagePath);\n if (!existsSync(join(workspaceRoot, \"pnpm-workspace.yaml\"))) return packages;\n\n // Only attempt normalization when the install is touching uilint packages.\n const touchesUilint = packages.some((p) => p === \"uilint-eslint\" || p.startsWith(\"uilint-\"));\n if (!touchesUilint) return packages;\n\n const pkgJsonPath = join(packagePath, \"package.json\");\n if (!existsSync(pkgJsonPath)) return packages;\n\n type PkgJson = {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n let pkg: PkgJson | null = null;\n try {\n pkg = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as PkgJson;\n } catch {\n return packages;\n }\n\n const wanted = [\"uilint-core\", \"uilint-eslint\", \"uilint-react\"] as const;\n const present = new Set<string>();\n for (const name of wanted) {\n const range =\n pkg?.dependencies?.[name] ??\n pkg?.devDependencies?.[name];\n if (typeof range === \"string\") {\n present.add(name);\n }\n }\n\n if (present.size === 0) return packages;\n\n // Remove any existing uilint-* specs, then re-add as workspace:* for packages\n // that are already present in the target package.json.\n const filtered = packages.filter(\n (p) => !/^uilint-(core|eslint|react)(@.+)?$/.test(p)\n );\n\n for (const name of present) {\n filtered.push(`${name}@workspace:*`);\n }\n\n return filtered;\n}\n\n/**\n * Execute an install plan\n *\n * @param plan - The install plan to execute\n * @param options - Execution options\n * @returns InstallResult with details of what was done\n */\nexport async function execute(\n plan: InstallPlan,\n options: ExecuteOptions = {}\n): Promise<InstallResult> {\n const {\n dryRun = false,\n installDependencies = defaultInstallDependencies,\n projectPath,\n skipPrettier = false,\n } = options;\n\n const actionsPerformed: ActionResult[] = [];\n const dependencyResults: DependencyResult[] = [];\n\n // Execute all actions in order\n for (const action of plan.actions) {\n const result = await executeAction(action, options);\n actionsPerformed.push(result);\n }\n\n // Install dependencies\n for (const dep of plan.dependencies) {\n if (dryRun) {\n dependencyResults.push({\n install: dep,\n success: true,\n skipped: true,\n });\n continue;\n }\n\n try {\n const pkgs =\n dep.packageManager === \"pnpm\"\n ? normalizePnpmWorkspaceUilintSpecs(dep.packagePath, dep.packages)\n : dep.packages;\n await installDependencies(\n dep.packageManager,\n dep.packagePath,\n pkgs\n );\n dependencyResults.push({\n install: { ...dep, packages: pkgs },\n success: true,\n });\n } catch (error) {\n dependencyResults.push({\n install: dep,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Format modified files with prettier (if available)\n if (!dryRun && !skipPrettier) {\n const filesToFormat = collectFormattableFiles(actionsPerformed);\n if (filesToFormat.length > 0) {\n // Determine project path from options or from first dependency/action\n const formatProjectPath =\n projectPath ||\n plan.dependencies[0]?.packagePath ||\n getProjectPathFromActions(actionsPerformed);\n\n if (formatProjectPath) {\n // Run prettier silently - don't fail install if formatting fails\n await formatFilesWithPrettier(filesToFormat, formatProjectPath).catch(\n () => {\n // Ignore formatting errors\n }\n );\n\n // Touch files to trigger IDE file watchers (for format-on-save)\n // Small delay to ensure file system has flushed\n await new Promise((resolve) => setTimeout(resolve, 100));\n touchFiles(filesToFormat);\n }\n }\n }\n\n // Determine overall success\n const actionsFailed = actionsPerformed.filter((r) => !r.success);\n const depsFailed = dependencyResults.filter((r) => !r.success);\n const success = actionsFailed.length === 0 && depsFailed.length === 0;\n\n // Collect items from actions (reverse engineer what was installed)\n const items: string[] = [];\n for (const result of actionsPerformed) {\n if (!result.success) continue;\n const { action } = result;\n if (action.type === \"create_file\") {\n if (action.path.includes(\"genstyleguide.md\")) items.push(\"genstyleguide\");\n if (action.path.includes(\"/skills/\") && action.path.includes(\"SKILL.md\")) items.push(\"skill\");\n }\n if (action.type === \"inject_eslint\") items.push(\"eslint\");\n if (action.type === \"install_next_routes\") items.push(\"next\");\n if (action.type === \"inject_react\") {\n items.push(action.mode === \"vite\" ? \"vite\" : \"next\");\n }\n if (action.type === \"inject_vite_config\") items.push(\"vite\");\n }\n // Dedupe\n const uniqueItems = [...new Set(items)];\n\n const summary = buildSummary(\n actionsPerformed,\n dependencyResults,\n uniqueItems\n );\n\n return {\n success,\n actionsPerformed,\n dependencyResults,\n summary,\n };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { join, relative, dirname, basename } from \"path\";\nimport { parseModule, generateCode } from \"magicast\";\n\nexport interface InstallReactOverlayOptions {\n projectPath: string;\n /**\n * Relative entry root:\n * - Next.js: \"app\" or \"src/app\"\n * - Vite: typically \"src\"\n */\n appRoot: string;\n /**\n * Injection mode:\n * - \"next\": wraps `{children}` (App Router layout/page)\n * - \"vite\": wraps the first `*.render(<...>)` argument\n */\n mode?: \"next\" | \"vite\";\n force?: boolean;\n /**\n * If multiple candidates are found, prompt user to choose.\n */\n confirmFileChoice?: (choices: string[]) => Promise<string>;\n /**\n * Specific file to inject into (absolute path).\n * If provided, skips candidate detection.\n */\n targetFile?: string;\n /**\n * If true, create a new providers.tsx file and wrap the layout's children.\n * Used when no existing client boundaries are found.\n */\n createProviders?: boolean;\n}\n\n/**\n * Find top-level layout.* or page.* files in the app root.\n * Prefer layout.* over page.* (layouts are better for providers).\n */\nfunction getDefaultCandidates(projectPath: string, appRoot: string): string[] {\n // Vite entry files (prefer src/main.*)\n const viteMainCandidates = [\n join(appRoot, \"main.tsx\"),\n join(appRoot, \"main.jsx\"),\n join(appRoot, \"main.ts\"),\n join(appRoot, \"main.js\"),\n ];\n const existingViteMain = viteMainCandidates.filter((rel) =>\n existsSync(join(projectPath, rel))\n );\n if (existingViteMain.length > 0) return existingViteMain;\n\n // Vite fallback: src/App.* (some templates wire provider there)\n const viteAppCandidates = [join(appRoot, \"App.tsx\"), join(appRoot, \"App.jsx\")];\n const existingViteApp = viteAppCandidates.filter((rel) =>\n existsSync(join(projectPath, rel))\n );\n if (existingViteApp.length > 0) return existingViteApp;\n\n // Check layout files first (preferred)\n const layoutCandidates = [\n join(appRoot, \"layout.tsx\"),\n join(appRoot, \"layout.jsx\"),\n join(appRoot, \"layout.ts\"),\n join(appRoot, \"layout.js\"),\n ];\n\n const existingLayouts = layoutCandidates.filter((rel) =>\n existsSync(join(projectPath, rel))\n );\n\n if (existingLayouts.length > 0) {\n return existingLayouts;\n }\n\n // Fall back to page files if no layouts found\n const pageCandidates = [join(appRoot, \"page.tsx\"), join(appRoot, \"page.jsx\")];\n\n return pageCandidates.filter((rel) => existsSync(join(projectPath, rel)));\n}\n\nfunction isUseClientDirective(stmt: any): boolean {\n return (\n stmt?.type === \"ExpressionStatement\" &&\n stmt.expression?.type === \"StringLiteral\" &&\n stmt.expression.value === \"use client\"\n );\n}\n\nfunction findImportDeclaration(program: any, from: string): any | null {\n if (!program || program.type !== \"Program\") return null;\n for (const stmt of program.body ?? []) {\n if (stmt?.type !== \"ImportDeclaration\") continue;\n if (stmt.source?.value === from) return stmt;\n }\n return null;\n}\n\nfunction walkAst(node: any, visit: (n: any) => void): void {\n if (!node || typeof node !== \"object\") return;\n if (node.type) visit(node);\n for (const key of Object.keys(node)) {\n const v = (node as any)[key];\n if (!v) continue;\n if (Array.isArray(v)) {\n for (const item of v) walkAst(item, visit);\n } else if (typeof v === \"object\" && v.type) {\n walkAst(v, visit);\n }\n }\n}\n\nfunction ensureNamedImport(\n program: any,\n from: string,\n name: string\n): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n const existing = findImportDeclaration(program, from);\n if (existing) {\n const has = (existing.specifiers ?? []).some(\n (s: any) =>\n s?.type === \"ImportSpecifier\" &&\n (s.imported?.name === name || s.imported?.value === name)\n );\n if (has) return { changed: false };\n\n const spec = (parseModule(`import { ${name} } from \"${from}\";`).$ast as any)\n .body?.[0]?.specifiers?.[0];\n if (!spec) return { changed: false };\n\n existing.specifiers = [...(existing.specifiers ?? []), spec];\n return { changed: true };\n }\n\n // Insert a fresh import after directives, and after existing imports.\n const importDecl = (\n parseModule(`import { ${name} } from \"${from}\";`).$ast as any\n ).body?.[0];\n if (!importDecl) return { changed: false };\n\n const body = program.body ?? [];\n let insertAt = 0;\n while (insertAt < body.length && isUseClientDirective(body[insertAt])) {\n insertAt++;\n }\n // Skip over existing imports\n while (\n insertAt < body.length &&\n body[insertAt]?.type === \"ImportDeclaration\"\n ) {\n insertAt++;\n }\n program.body.splice(insertAt, 0, importDecl);\n return { changed: true };\n}\n\nfunction hasUILintDevtoolsJsx(program: any): boolean {\n let found = false;\n walkAst(program, (node) => {\n if (found) return;\n if (node.type !== \"JSXElement\") return;\n const name = node.openingElement?.name;\n // Check for both old UILintProvider and new uilint-devtools\n if (name?.type === \"JSXIdentifier\") {\n if (name.name === \"UILintProvider\" || name.name === \"uilint-devtools\") {\n found = true;\n }\n }\n });\n return found;\n}\n\n/**\n * Add <uilint-devtools /> element as a sibling to {children} in Next.js layouts.\n * This injects the devtools web component without wrapping the children.\n */\nfunction addDevtoolsElementNextJs(program: any): {\n changed: boolean;\n} {\n if (!program || program.type !== \"Program\") return { changed: false };\n if (hasUILintDevtoolsJsx(program)) return { changed: false };\n\n // Create the devtools JSX element: <uilint-devtools />\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const devtoolsMod = parseModule(\n 'const __uilint_devtools = <uilint-devtools />;'\n );\n const devtoolsJsx =\n (devtoolsMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!devtoolsJsx || devtoolsJsx.type !== \"JSXElement\")\n return { changed: false };\n\n // Find the return statement that contains {children} and add devtools as sibling\n let added = false;\n walkAst(program, (node) => {\n if (added) return;\n\n // Look for JSX elements that contain {children}\n if (node.type !== \"JSXElement\" && node.type !== \"JSXFragment\") return;\n\n const children = node.children ?? [];\n const childrenIndex = children.findIndex(\n (child: any) =>\n child?.type === \"JSXExpressionContainer\" &&\n child.expression?.type === \"Identifier\" &&\n child.expression.name === \"children\"\n );\n\n if (childrenIndex === -1) return;\n\n // Add devtools element after {children}\n children.splice(childrenIndex + 1, 0, devtoolsJsx);\n added = true;\n });\n\n if (!added) {\n throw new Error(\"Could not find `{children}` in target file to add devtools.\");\n }\n return { changed: true };\n}\n\n/**\n * Add <uilint-devtools /> element to Vite's render call.\n * Wraps the existing render argument in a fragment with the devtools element.\n */\nfunction addDevtoolsElementVite(program: any): {\n changed: boolean;\n} {\n if (!program || program.type !== \"Program\") return { changed: false };\n if (hasUILintDevtoolsJsx(program)) return { changed: false };\n\n // Create a fragment containing the original content + devtools:\n // <>...original...<uilint-devtools /></>\n let added = false;\n walkAst(program, (node) => {\n if (added) return;\n if (node.type !== \"CallExpression\") return;\n const callee = node.callee;\n // Match: something.render(<JSX />)\n if (callee?.type !== \"MemberExpression\") return;\n const prop = callee.property;\n const isRender =\n (prop?.type === \"Identifier\" && prop.name === \"render\") ||\n (prop?.type === \"StringLiteral\" && prop.value === \"render\") ||\n (prop?.type === \"Literal\" && prop.value === \"render\");\n if (!isRender) return;\n\n const arg0 = node.arguments?.[0];\n if (!arg0) return;\n if (arg0.type !== \"JSXElement\" && arg0.type !== \"JSXFragment\") return;\n\n // Create the devtools JSX element\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const devtoolsMod = parseModule(\n 'const __uilint_devtools = <uilint-devtools />;'\n );\n const devtoolsJsx =\n (devtoolsMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!devtoolsJsx) return;\n\n // Create a fragment wrapping original + devtools\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const fragmentMod = parseModule(\n 'const __fragment = <></>;'\n );\n const fragmentJsx =\n (fragmentMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!fragmentJsx) return;\n\n // Add original content and devtools as children of the fragment\n fragmentJsx.children = [arg0, devtoolsJsx];\n node.arguments[0] = fragmentJsx;\n added = true;\n });\n\n if (!added) {\n throw new Error(\n 'Could not find a `.render(<...>)` call to add devtools. Expected a React entry like `createRoot(...).render(<App />)`.'\n );\n }\n return { changed: true };\n}\n\n/**\n * Ensure a side-effect import exists in the program.\n * e.g., import \"uilint-react/devtools\";\n */\nfunction ensureSideEffectImport(\n program: any,\n from: string\n): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Check if import already exists\n const existing = findImportDeclaration(program, from);\n if (existing) return { changed: false };\n\n // Create a side-effect import\n const importDecl = (\n parseModule(`import \"${from}\";`).$ast as any\n ).body?.[0];\n if (!importDecl) return { changed: false };\n\n const body = program.body ?? [];\n let insertAt = 0;\n // Skip \"use client\" directive\n while (insertAt < body.length && isUseClientDirective(body[insertAt])) {\n insertAt++;\n }\n // Skip over existing imports\n while (\n insertAt < body.length &&\n body[insertAt]?.type === \"ImportDeclaration\"\n ) {\n insertAt++;\n }\n program.body.splice(insertAt, 0, importDecl);\n return { changed: true };\n}\n\n/**\n * Add <uilint-devtools /> to a client component file.\n * Finds the main component's return statement and wraps JSX in a fragment.\n */\nfunction addDevtoolsToClientComponent(program: any): {\n changed: boolean;\n} {\n if (!program || program.type !== \"Program\") return { changed: false };\n if (hasUILintDevtoolsJsx(program)) return { changed: false };\n\n // Create the devtools JSX element\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const devtoolsMod = parseModule(\n 'const __uilint_devtools = <uilint-devtools />;'\n );\n const devtoolsJsx =\n (devtoolsMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!devtoolsJsx || devtoolsJsx.type !== \"JSXElement\")\n return { changed: false };\n\n // First try: look for {children} pattern (common in provider components)\n let added = false;\n walkAst(program, (node) => {\n if (added) return;\n if (node.type !== \"JSXElement\" && node.type !== \"JSXFragment\") return;\n\n const children = node.children ?? [];\n const childrenIndex = children.findIndex(\n (child: any) =>\n child?.type === \"JSXExpressionContainer\" &&\n child.expression?.type === \"Identifier\" &&\n child.expression.name === \"children\"\n );\n\n if (childrenIndex !== -1) {\n // Add devtools element after {children}\n children.splice(childrenIndex + 1, 0, devtoolsJsx);\n added = true;\n }\n });\n\n if (added) return { changed: true };\n\n // Second try: find the first return statement with JSX and wrap it in a fragment\n walkAst(program, (node) => {\n if (added) return;\n if (node.type !== \"ReturnStatement\") return;\n const arg = node.argument;\n if (!arg) return;\n if (arg.type !== \"JSXElement\" && arg.type !== \"JSXFragment\") return;\n\n // Create a fragment wrapping original + devtools\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const fragmentMod = parseModule('const __fragment = <></>;');\n const fragmentJsx =\n (fragmentMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!fragmentJsx) return;\n\n // Add original content and devtools as children of the fragment\n fragmentJsx.children = [arg, devtoolsJsx];\n node.argument = fragmentJsx;\n added = true;\n });\n\n if (!added) {\n throw new Error(\n \"Could not find a suitable location to add devtools. Expected a component with JSX return or {children}.\"\n );\n }\n return { changed: true };\n}\n\n/**\n * Generate the content for a new providers.tsx file\n */\nfunction generateProvidersContent(isTypeScript: boolean): string {\n const ext = isTypeScript ? \"tsx\" : \"jsx\";\n const typeAnnotation = isTypeScript\n ? \": { children: React.ReactNode }\"\n : \"\";\n\n return `\"use client\";\n\nimport React from \"react\";\nimport \"uilint-react/devtools\";\n\nexport function Providers({ children }${typeAnnotation}) {\n return (\n <>\n {children}\n <uilint-devtools />\n </>\n );\n}\n`;\n}\n\n/**\n * Wrap {children} in a layout file with a <Providers> component\n */\nfunction wrapChildrenWithProviders(\n program: any,\n providersImportPath: string\n): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Check if Providers is already imported\n let hasProvidersImport = false;\n for (const stmt of (program as any).body ?? []) {\n if (stmt?.type !== \"ImportDeclaration\") continue;\n if (stmt.source?.value === providersImportPath) {\n hasProvidersImport = true;\n break;\n }\n }\n\n // Add Providers import if not present\n if (!hasProvidersImport) {\n const importRes = ensureNamedImport(program, providersImportPath, \"Providers\");\n if (!importRes.changed) return { changed: false };\n }\n\n // Find {children} and wrap with <Providers>\n let wrapped = false;\n walkAst(program, (node) => {\n if (wrapped) return;\n if (node.type !== \"JSXElement\" && node.type !== \"JSXFragment\") return;\n\n const children = node.children ?? [];\n const childrenIndex = children.findIndex(\n (child: any) =>\n child?.type === \"JSXExpressionContainer\" &&\n child.expression?.type === \"Identifier\" &&\n child.expression.name === \"children\"\n );\n\n if (childrenIndex === -1) return;\n\n // Create <Providers>{children}</Providers>\n // Note: Parse without parentheses to avoid extra.parenthesized in AST\n const providersMod = parseModule(\n 'const __providers = <Providers>{children}</Providers>;'\n );\n const providersJsx =\n (providersMod.$ast as any).body?.[0]?.declarations?.[0]?.init ?? null;\n if (!providersJsx) return;\n\n // Replace {children} with <Providers>{children}</Providers>\n children[childrenIndex] = providersJsx;\n wrapped = true;\n });\n\n if (!wrapped) {\n throw new Error(\n \"Could not find {children} in layout to wrap with Providers.\"\n );\n }\n\n return { changed: true };\n}\n\n/**\n * Find the layout file in the app root\n */\nfunction findLayoutFile(projectPath: string, appRoot: string): string | null {\n const extensions = [\".tsx\", \".jsx\", \".ts\", \".js\"];\n for (const ext of extensions) {\n const layoutPath = join(projectPath, appRoot, `layout${ext}`);\n if (existsSync(layoutPath)) return layoutPath;\n }\n return null;\n}\n\n/**\n * Create providers.tsx file and modify the layout to use it\n */\nasync function createProvidersAndModifyLayout(\n projectPath: string,\n appRoot: string\n): Promise<{\n providersFile: string;\n layoutFile: string;\n modified: boolean;\n}> {\n // Find the layout file\n const layoutPath = findLayoutFile(projectPath, appRoot);\n if (!layoutPath) {\n throw new Error(`Could not find layout file in ${appRoot}`);\n }\n\n // Determine if TypeScript based on layout extension\n const isTypeScript = layoutPath.endsWith(\".tsx\") || layoutPath.endsWith(\".ts\");\n const providersExt = isTypeScript ? \".tsx\" : \".jsx\";\n const providersPath = join(projectPath, appRoot, `providers${providersExt}`);\n\n // Check if providers already exists\n if (existsSync(providersPath)) {\n throw new Error(\n `providers${providersExt} already exists. Please select it from the list instead.`\n );\n }\n\n // Create the providers file\n const providersContent = generateProvidersContent(isTypeScript);\n writeFileSync(providersPath, providersContent, \"utf-8\");\n\n // Modify the layout to import and use Providers\n const layoutContent = readFileSync(layoutPath, \"utf-8\");\n let layoutMod: any;\n try {\n layoutMod = parseModule(layoutContent);\n } catch {\n throw new Error(\n `Unable to parse ${relative(projectPath, layoutPath)} as JavaScript/TypeScript.`\n );\n }\n\n const layoutProgram = layoutMod.$ast;\n const wrapRes = wrapChildrenWithProviders(layoutProgram, \"./providers\");\n\n if (wrapRes.changed) {\n const updatedLayout = generateCode(layoutMod).code;\n writeFileSync(layoutPath, updatedLayout, \"utf-8\");\n }\n\n return {\n providersFile: relative(projectPath, providersPath),\n layoutFile: relative(projectPath, layoutPath),\n modified: true,\n };\n}\n\nexport async function installReactUILintOverlay(\n opts: InstallReactOverlayOptions\n): Promise<{\n targetFile: string;\n modified: boolean;\n alreadyConfigured?: boolean;\n /** Additional file created (e.g., providers.tsx) */\n createdFile?: string;\n /** Layout file modified to wrap children */\n layoutModified?: string;\n /** Absolute paths of all files that were modified/created (for formatting) */\n modifiedFiles: string[];\n}> {\n // Handle createProviders mode: create providers.tsx and modify layout\n if (opts.createProviders) {\n const result = await createProvidersAndModifyLayout(\n opts.projectPath,\n opts.appRoot\n );\n // Collect absolute paths of modified files\n const modifiedFiles: string[] = [];\n if (result.modified) {\n modifiedFiles.push(join(opts.projectPath, result.providersFile));\n modifiedFiles.push(join(opts.projectPath, result.layoutFile));\n }\n return {\n targetFile: result.providersFile,\n modified: result.modified,\n createdFile: result.providersFile,\n layoutModified: result.layoutFile,\n modifiedFiles,\n };\n }\n\n // Handle targetFile mode: inject into a specific client component\n if (opts.targetFile) {\n const absTarget = opts.targetFile;\n const relTarget = relative(opts.projectPath, absTarget);\n\n if (!existsSync(absTarget)) {\n throw new Error(`Target file not found: ${relTarget}`);\n }\n\n const original = readFileSync(absTarget, \"utf-8\");\n let mod: any;\n try {\n mod = parseModule(original);\n } catch {\n throw new Error(\n `Unable to parse ${relTarget} as JavaScript/TypeScript. Please update it manually.`\n );\n }\n\n const program = mod.$ast;\n\n // Check if already configured\n const hasDevtoolsImport = !!findImportDeclaration(program, \"uilint-react/devtools\");\n const hasOldImport = !!findImportDeclaration(program, \"uilint-react\");\n const alreadyConfigured =\n (hasDevtoolsImport || hasOldImport) && hasUILintDevtoolsJsx(program);\n\n if (alreadyConfigured) {\n return {\n targetFile: relTarget,\n modified: false,\n alreadyConfigured: true,\n modifiedFiles: [],\n };\n }\n\n let changed = false;\n\n // Add side-effect import for the devtools web component\n const importRes = ensureSideEffectImport(program, \"uilint-react/devtools\");\n if (importRes.changed) changed = true;\n\n // Use client component injection (handles both {children} and return JSX)\n const addRes = addDevtoolsToClientComponent(program);\n if (addRes.changed) changed = true;\n\n const updated = changed ? generateCode(mod).code : original;\n const modified = updated !== original;\n\n if (modified) {\n writeFileSync(absTarget, updated, \"utf-8\");\n }\n\n return {\n targetFile: relTarget,\n modified,\n alreadyConfigured: false,\n modifiedFiles: modified ? [absTarget] : [],\n };\n }\n\n // Default mode: auto-detect candidates (original behavior)\n const candidates = getDefaultCandidates(opts.projectPath, opts.appRoot);\n if (!candidates.length) {\n throw new Error(\n `No suitable entry files found under ${opts.appRoot} (expected Next.js layout/page or Vite main/App).`\n );\n }\n\n let chosen: string;\n\n // If there are multiple candidates, ask user to choose\n if (candidates.length > 1 && opts.confirmFileChoice) {\n chosen = await opts.confirmFileChoice(candidates);\n } else {\n // Single candidate - use it\n chosen = candidates[0]!;\n }\n\n const absTarget = join(opts.projectPath, chosen);\n const original = readFileSync(absTarget, \"utf-8\");\n\n let mod: any;\n try {\n mod = parseModule(original);\n } catch {\n throw new Error(\n `Unable to parse ${chosen} as JavaScript/TypeScript. Please update it manually.`\n );\n }\n\n const program = mod.$ast;\n\n // Check if already configured (either old UILintProvider or new devtools approach)\n const hasDevtoolsImport = !!findImportDeclaration(program, \"uilint-react/devtools\");\n const hasOldImport = !!findImportDeclaration(program, \"uilint-react\");\n const alreadyConfigured =\n (hasDevtoolsImport || hasOldImport) && hasUILintDevtoolsJsx(program);\n\n let changed = false;\n\n // Add side-effect import for the devtools web component\n const importRes = ensureSideEffectImport(program, \"uilint-react/devtools\");\n if (importRes.changed) changed = true;\n\n const mode = opts.mode ?? \"next\";\n const addRes =\n mode === \"vite\"\n ? addDevtoolsElementVite(program)\n : addDevtoolsElementNextJs(program);\n if (addRes.changed) changed = true;\n\n const updated = changed ? generateCode(mod).code : original;\n\n const modified = updated !== original;\n if (modified) {\n writeFileSync(absTarget, updated, \"utf-8\");\n }\n\n return {\n targetFile: chosen,\n modified,\n alreadyConfigured: alreadyConfigured && !modified,\n modifiedFiles: modified ? [absTarget] : [],\n };\n}\n\nexport interface RemoveReactOverlayOptions {\n projectPath: string;\n appRoot: string;\n mode?: \"next\" | \"vite\";\n}\n\nexport interface RemoveReactOverlayResult {\n success: boolean;\n error?: string;\n modifiedFiles?: string[];\n}\n\n/**\n * Remove uilint-react devtools from React files\n *\n * This is a best-effort removal that:\n * 1. Removes uilint-react/devtools import\n * 2. Removes <uilint-devtools /> element\n */\nexport async function removeReactUILintOverlay(\n options: RemoveReactOverlayOptions\n): Promise<RemoveReactOverlayResult> {\n const { projectPath, appRoot, mode = \"next\" } = options;\n\n const candidates = getDefaultCandidates(projectPath, appRoot);\n const modifiedFiles: string[] = [];\n\n for (const candidate of candidates) {\n const absPath = join(projectPath, candidate);\n if (!existsSync(absPath)) continue;\n\n try {\n const original = readFileSync(absPath, \"utf-8\");\n\n // Remove uilint-react/devtools import\n let updated = original.replace(\n /^import\\s+[\"']uilint-react\\/devtools[\"'];?\\s*$/gm,\n \"\"\n );\n\n // Remove uilint-react import (legacy)\n updated = updated.replace(\n /^import\\s+\\{[^}]*UILintProvider[^}]*\\}\\s+from\\s+[\"']uilint-react[\"'];?\\s*$/gm,\n \"\"\n );\n\n // Remove <uilint-devtools /> or <uilint-devtools></uilint-devtools>\n updated = updated.replace(/<uilint-devtools\\s*\\/>/g, \"\");\n updated = updated.replace(/<uilint-devtools><\\/uilint-devtools>/g, \"\");\n updated = updated.replace(/<uilint-devtools\\s*>\\s*<\\/uilint-devtools>/g, \"\");\n\n // Remove UILintProvider wrapper (legacy)\n updated = updated.replace(\n /<UILintProvider[^>]*>([\\s\\S]*?)<\\/UILintProvider>/g,\n \"$1\"\n );\n\n // Clean up empty lines\n updated = updated.replace(/\\n{3,}/g, \"\\n\\n\");\n\n if (updated !== original) {\n writeFileSync(absPath, updated, \"utf-8\");\n modifiedFiles.push(absPath);\n }\n } catch {\n // Skip files that fail to process\n }\n }\n\n return {\n success: true,\n modifiedFiles,\n };\n}\n","/**\n * Inject jsx-loc-plugin into Next.js config\n *\n * Modifies next.config.{ts,js,mjs,cjs} to wrap the export with withJsxLoc()\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseModule, generateCode } from \"magicast\";\n\nexport interface InstallJsxLocPluginOptions {\n projectPath: string;\n force?: boolean;\n}\n\nconst CONFIG_EXTENSIONS = [\".ts\", \".mjs\", \".js\", \".cjs\"];\n\n/**\n * Find the next.config file in a project\n */\nexport function findNextConfigFile(projectPath: string): string | null {\n for (const ext of CONFIG_EXTENSIONS) {\n const configPath = join(projectPath, `next.config${ext}`);\n if (existsSync(configPath)) {\n return configPath;\n }\n }\n return null;\n}\n\n/**\n * Get the relative config filename for display\n */\nexport function getNextConfigFilename(configPath: string): string {\n const parts = configPath.split(\"/\");\n return parts[parts.length - 1] || \"next.config.ts\";\n}\n\n/**\n * Check if the source already has withJsxLoc imported\n */\nfunction hasJsxLocImport(source: string): boolean {\n return (\n source.includes('from \"jsx-loc-plugin\"') ||\n source.includes(\"from 'jsx-loc-plugin'\")\n );\n}\n\n/**\n * Check if the source already uses withJsxLoc\n */\nfunction hasJsxLocWrapper(source: string): boolean {\n return source.includes(\"withJsxLoc(\");\n}\n\nfunction isIdentifier(node: any, name?: string): boolean {\n return (\n !!node &&\n node.type === \"Identifier\" &&\n (name ? node.name === name : typeof node.name === \"string\")\n );\n}\n\nfunction isStringLiteral(node: any): node is { type: string; value: string } {\n return (\n !!node &&\n (node.type === \"StringLiteral\" || node.type === \"Literal\") &&\n typeof node.value === \"string\"\n );\n}\n\nfunction ensureEsmWithJsxLocImport(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Find existing import from jsx-loc-plugin\n const existing = (program.body ?? []).find(\n (s: any) => s?.type === \"ImportDeclaration\" && s.source?.value === \"jsx-loc-plugin\"\n );\n\n if (existing) {\n const has = (existing.specifiers ?? []).some(\n (sp: any) =>\n sp?.type === \"ImportSpecifier\" &&\n (sp.imported?.name === \"withJsxLoc\" || sp.imported?.value === \"withJsxLoc\")\n );\n if (has) return { changed: false };\n\n const spec = (parseModule('import { withJsxLoc } from \"jsx-loc-plugin\";')\n .$ast as any).body?.[0]?.specifiers?.[0];\n if (!spec) return { changed: false };\n existing.specifiers = [...(existing.specifiers ?? []), spec];\n return { changed: true };\n }\n\n const importDecl = (parseModule('import { withJsxLoc } from \"jsx-loc-plugin\";')\n .$ast as any).body?.[0];\n if (!importDecl) return { changed: false };\n\n // Insert after last import\n const body = program.body ?? [];\n let insertAt = 0;\n while (insertAt < body.length && body[insertAt]?.type === \"ImportDeclaration\") {\n insertAt++;\n }\n program.body.splice(insertAt, 0, importDecl);\n return { changed: true };\n}\n\nfunction ensureCjsWithJsxLocRequire(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Detect an existing require(\"jsx-loc-plugin\") that binds withJsxLoc\n for (const stmt of program.body ?? []) {\n if (stmt?.type !== \"VariableDeclaration\") continue;\n for (const decl of stmt.declarations ?? []) {\n const init = decl?.init;\n if (\n init?.type === \"CallExpression\" &&\n isIdentifier(init.callee, \"require\") &&\n isStringLiteral(init.arguments?.[0]) &&\n init.arguments[0].value === \"jsx-loc-plugin\"\n ) {\n // If destructuring, ensure property exists\n if (decl.id?.type === \"ObjectPattern\") {\n const has = (decl.id.properties ?? []).some((p: any) => {\n if (p?.type !== \"ObjectProperty\" && p?.type !== \"Property\") return false;\n return isIdentifier(p.key, \"withJsxLoc\");\n });\n if (has) return { changed: false };\n const prop = (parseModule('const { withJsxLoc } = require(\"jsx-loc-plugin\");')\n .$ast as any).body?.[0]?.declarations?.[0]?.id?.properties?.[0];\n if (!prop) return { changed: false };\n decl.id.properties = [...(decl.id.properties ?? []), prop];\n return { changed: true };\n }\n\n // Already requiring the module in some other shape; don't try to rewrite.\n return { changed: false };\n }\n }\n }\n\n // Insert: const { withJsxLoc } = require(\"jsx-loc-plugin\");\n const reqDecl = (parseModule('const { withJsxLoc } = require(\"jsx-loc-plugin\");')\n .$ast as any).body?.[0];\n if (!reqDecl) return { changed: false };\n program.body.unshift(reqDecl);\n return { changed: true };\n}\n\nfunction wrapEsmExportDefault(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n const exportDecl = (program.body ?? []).find(\n (s: any) => s?.type === \"ExportDefaultDeclaration\"\n );\n if (!exportDecl) return { changed: false };\n\n const decl = exportDecl.declaration;\n if (\n decl?.type === \"CallExpression\" &&\n isIdentifier(decl.callee, \"withJsxLoc\")\n ) {\n return { changed: false };\n }\n\n exportDecl.declaration = {\n type: \"CallExpression\",\n callee: { type: \"Identifier\", name: \"withJsxLoc\" },\n arguments: [decl],\n };\n return { changed: true };\n}\n\nfunction wrapCjsModuleExports(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n for (const stmt of program.body ?? []) {\n if (!stmt || stmt.type !== \"ExpressionStatement\") continue;\n const expr = stmt.expression;\n if (!expr || expr.type !== \"AssignmentExpression\") continue;\n const left = expr.left;\n const right = expr.right;\n const isModuleExports =\n left?.type === \"MemberExpression\" &&\n isIdentifier(left.object, \"module\") &&\n isIdentifier(left.property, \"exports\");\n if (!isModuleExports) continue;\n\n if (\n right?.type === \"CallExpression\" &&\n isIdentifier(right.callee, \"withJsxLoc\")\n ) {\n return { changed: false };\n }\n\n expr.right = {\n type: \"CallExpression\",\n callee: { type: \"Identifier\", name: \"withJsxLoc\" },\n arguments: [right],\n };\n return { changed: true };\n }\n\n return { changed: false };\n}\n\n/**\n * Install jsx-loc-plugin into next.config\n */\nexport async function installJsxLocPlugin(\n opts: InstallJsxLocPluginOptions\n): Promise<{\n configFile: string | null;\n modified: boolean;\n /** Absolute paths of all files that were modified (for formatting) */\n modifiedFiles: string[];\n}> {\n const configPath = findNextConfigFile(opts.projectPath);\n\n if (!configPath) {\n return { configFile: null, modified: false, modifiedFiles: [] };\n }\n\n const configFilename = getNextConfigFilename(configPath);\n const original = readFileSync(configPath, \"utf-8\");\n\n let mod: any;\n try {\n mod = parseModule(original);\n } catch {\n return { configFile: configFilename, modified: false, modifiedFiles: [] };\n }\n\n const program = mod.$ast;\n const isCjs = configPath.endsWith(\".cjs\");\n\n // No confirmOverwrite needed: injector is idempotent.\n\n let changed = false;\n if (isCjs) {\n const reqRes = ensureCjsWithJsxLocRequire(program);\n if (reqRes.changed) changed = true;\n const wrapRes = wrapCjsModuleExports(program);\n if (wrapRes.changed) changed = true;\n } else {\n const impRes = ensureEsmWithJsxLocImport(program);\n if (impRes.changed) changed = true;\n const wrapRes = wrapEsmExportDefault(program);\n if (wrapRes.changed) changed = true;\n }\n\n const updated = changed ? generateCode(mod).code : original;\n\n if (updated !== original) {\n writeFileSync(configPath, updated, \"utf-8\");\n return { configFile: configFilename, modified: true, modifiedFiles: [configPath] };\n }\n\n return { configFile: configFilename, modified: false, modifiedFiles: [] };\n}\n\nexport interface RemoveJsxLocPluginOptions {\n projectPath: string;\n}\n\nexport interface RemoveJsxLocPluginResult {\n success: boolean;\n error?: string;\n modifiedFiles?: string[];\n}\n\n/**\n * Remove jsx-loc-plugin from next.config\n *\n * This is a best-effort removal that:\n * 1. Removes jsx-loc-plugin import\n * 2. Removes withJsxLoc wrapper\n */\nexport async function removeJsxLocPlugin(\n options: RemoveJsxLocPluginOptions\n): Promise<RemoveJsxLocPluginResult> {\n const { projectPath } = options;\n\n const configPath = findNextConfigFile(projectPath);\n if (!configPath) {\n return {\n success: true,\n modifiedFiles: [],\n };\n }\n\n try {\n const original = readFileSync(configPath, \"utf-8\");\n\n // Remove jsx-loc-plugin import\n let updated = original.replace(\n /^import\\s+\\{[^}]*withJsxLoc[^}]*\\}\\s+from\\s+[\"']jsx-loc-plugin\\/next[\"'];?\\s*$/gm,\n \"\"\n );\n\n // Remove jsx-loc-plugin require\n updated = updated.replace(\n /^const\\s+\\{[^}]*withJsxLoc[^}]*\\}\\s*=\\s*require\\s*\\(\\s*[\"']jsx-loc-plugin\\/next[\"']\\s*\\)\\s*;?\\s*$/gm,\n \"\"\n );\n\n // Remove withJsxLoc wrapper from export default\n updated = updated.replace(\n /export\\s+default\\s+withJsxLoc\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*;?/g,\n \"export default $1;\"\n );\n\n // Remove withJsxLoc wrapper from module.exports\n updated = updated.replace(\n /module\\.exports\\s*=\\s*withJsxLoc\\s*\\(\\s*([\\s\\S]*?)\\s*\\)\\s*;?/g,\n \"module.exports = $1;\"\n );\n\n // Clean up empty lines\n updated = updated.replace(/\\n{3,}/g, \"\\n\\n\");\n\n if (updated !== original) {\n writeFileSync(configPath, updated, \"utf-8\");\n return {\n success: true,\n modifiedFiles: [configPath],\n };\n }\n\n return {\n success: true,\n modifiedFiles: [],\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n","/**\n * Inject jsx-loc-plugin into Vite config\n *\n * Modifies vite.config.{ts,js,mjs,cjs} to add `jsxLoc()` to the `plugins` array.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { parseModule, generateCode } from \"magicast\";\n\nexport interface InstallViteJsxLocPluginOptions {\n projectPath: string;\n force?: boolean;\n}\n\nconst CONFIG_EXTENSIONS = [\".ts\", \".mjs\", \".js\", \".cjs\"];\n\nexport function findViteConfigFile(projectPath: string): string | null {\n for (const ext of CONFIG_EXTENSIONS) {\n const configPath = join(projectPath, `vite.config${ext}`);\n if (existsSync(configPath)) return configPath;\n }\n return null;\n}\n\nexport function getViteConfigFilename(configPath: string): string {\n const parts = configPath.split(\"/\");\n return parts[parts.length - 1] || \"vite.config.ts\";\n}\n\nfunction isIdentifier(node: any, name?: string): boolean {\n return (\n !!node &&\n node.type === \"Identifier\" &&\n (name ? node.name === name : typeof node.name === \"string\")\n );\n}\n\nfunction isStringLiteral(node: any): node is { type: string; value: string } {\n return (\n !!node &&\n (node.type === \"StringLiteral\" || node.type === \"Literal\") &&\n typeof node.value === \"string\"\n );\n}\n\nfunction unwrapExpression(expr: any): any {\n let e = expr;\n while (e) {\n if (e.type === \"TSAsExpression\" || e.type === \"TSNonNullExpression\") {\n e = e.expression;\n continue;\n }\n if (e.type === \"TSSatisfiesExpression\") {\n e = e.expression;\n continue;\n }\n if (e.type === \"ParenthesizedExpression\") {\n e = e.expression;\n continue;\n }\n break;\n }\n return e;\n}\n\nfunction findExportedConfigObjectExpression(mod: any): {\n kind: \"esm\" | \"cjs\";\n objExpr: any;\n program: any;\n} | null {\n const program = mod?.$ast;\n if (!program || program.type !== \"Program\") return null;\n\n // ESM: export default { ... } OR export default defineConfig({ ... })\n for (const stmt of program.body ?? []) {\n if (!stmt || stmt.type !== \"ExportDefaultDeclaration\") continue;\n const decl = unwrapExpression(stmt.declaration);\n if (!decl) break;\n\n if (decl.type === \"ObjectExpression\") {\n return { kind: \"esm\", objExpr: decl, program };\n }\n if (\n decl.type === \"CallExpression\" &&\n isIdentifier(decl.callee, \"defineConfig\") &&\n unwrapExpression(decl.arguments?.[0])?.type === \"ObjectExpression\"\n ) {\n return {\n kind: \"esm\",\n objExpr: unwrapExpression(decl.arguments?.[0]),\n program,\n };\n }\n break;\n }\n\n // CJS: module.exports = { ... } OR module.exports = defineConfig({ ... })\n for (const stmt of program.body ?? []) {\n if (!stmt || stmt.type !== \"ExpressionStatement\") continue;\n const expr = stmt.expression;\n if (!expr || expr.type !== \"AssignmentExpression\") continue;\n const left = expr.left;\n const right = unwrapExpression(expr.right);\n const isModuleExports =\n left?.type === \"MemberExpression\" &&\n isIdentifier(left.object, \"module\") &&\n isIdentifier(left.property, \"exports\");\n if (!isModuleExports) continue;\n\n if (right?.type === \"ObjectExpression\") {\n return { kind: \"cjs\", objExpr: right, program };\n }\n if (\n right?.type === \"CallExpression\" &&\n isIdentifier(right.callee, \"defineConfig\") &&\n unwrapExpression(right.arguments?.[0])?.type === \"ObjectExpression\"\n ) {\n return {\n kind: \"cjs\",\n objExpr: unwrapExpression(right.arguments?.[0]),\n program,\n };\n }\n }\n\n return null;\n}\n\nfunction getObjectProperty(obj: any, keyName: string): any | null {\n if (!obj || obj.type !== \"ObjectExpression\") return null;\n for (const prop of obj.properties ?? []) {\n if (!prop) continue;\n if (prop.type !== \"ObjectProperty\" && prop.type !== \"Property\") continue;\n const key = prop.key;\n const keyMatch =\n (key?.type === \"Identifier\" && key.name === keyName) ||\n (isStringLiteral(key) && key.value === keyName);\n if (keyMatch) return prop;\n }\n return null;\n}\n\nfunction ensureEsmJsxLocImport(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Find existing import from jsx-loc-plugin/vite\n const existing = (program.body ?? []).find(\n (s: any) =>\n s?.type === \"ImportDeclaration\" && s.source?.value === \"jsx-loc-plugin/vite\"\n );\n if (existing) {\n const has = (existing.specifiers ?? []).some(\n (sp: any) =>\n sp?.type === \"ImportSpecifier\" &&\n (sp.imported?.name === \"jsxLoc\" || sp.imported?.value === \"jsxLoc\")\n );\n if (has) return { changed: false };\n const spec = (\n parseModule('import { jsxLoc } from \"jsx-loc-plugin/vite\";').$ast as any\n ).body?.[0]?.specifiers?.[0];\n if (!spec) return { changed: false };\n existing.specifiers = [...(existing.specifiers ?? []), spec];\n return { changed: true };\n }\n\n const importDecl = (\n parseModule('import { jsxLoc } from \"jsx-loc-plugin/vite\";').$ast as any\n ).body?.[0];\n if (!importDecl) return { changed: false };\n\n // Insert after last import\n const body = program.body ?? [];\n let insertAt = 0;\n while (insertAt < body.length && body[insertAt]?.type === \"ImportDeclaration\") {\n insertAt++;\n }\n program.body.splice(insertAt, 0, importDecl);\n return { changed: true };\n}\n\nfunction ensureCjsJsxLocRequire(program: any): { changed: boolean } {\n if (!program || program.type !== \"Program\") return { changed: false };\n\n // Detect an existing require(\"jsx-loc-plugin/vite\") that binds jsxLoc\n for (const stmt of program.body ?? []) {\n if (stmt?.type !== \"VariableDeclaration\") continue;\n for (const decl of stmt.declarations ?? []) {\n const init = decl?.init;\n if (\n init?.type === \"CallExpression\" &&\n isIdentifier(init.callee, \"require\") &&\n isStringLiteral(init.arguments?.[0]) &&\n init.arguments[0].value === \"jsx-loc-plugin/vite\"\n ) {\n // If destructuring, ensure property exists\n if (decl.id?.type === \"ObjectPattern\") {\n const has = (decl.id.properties ?? []).some((p: any) => {\n if (p?.type !== \"ObjectProperty\" && p?.type !== \"Property\") return false;\n return isIdentifier(p.key, \"jsxLoc\");\n });\n if (has) return { changed: false };\n const prop = (\n parseModule('const { jsxLoc } = require(\"jsx-loc-plugin/vite\");')\n .$ast as any\n ).body?.[0]?.declarations?.[0]?.id?.properties?.[0];\n if (!prop) return { changed: false };\n decl.id.properties = [...(decl.id.properties ?? []), prop];\n return { changed: true };\n }\n return { changed: false };\n }\n }\n }\n\n // Insert: const { jsxLoc } = require(\"jsx-loc-plugin/vite\");\n const reqDecl = (\n parseModule('const { jsxLoc } = require(\"jsx-loc-plugin/vite\");').$ast as any\n ).body?.[0];\n if (!reqDecl) return { changed: false };\n program.body.unshift(reqDecl);\n return { changed: true };\n}\n\nfunction pluginsHasJsxLoc(arr: any): boolean {\n if (!arr || arr.type !== \"ArrayExpression\") return false;\n for (const el of arr.elements ?? []) {\n const e = unwrapExpression(el);\n if (!e) continue;\n if (e.type === \"CallExpression\" && isIdentifier(e.callee, \"jsxLoc\")) return true;\n }\n return false;\n}\n\nfunction ensurePluginsContainsJsxLoc(configObj: any): { changed: boolean } {\n const pluginsProp = getObjectProperty(configObj, \"plugins\");\n\n // No plugins: create plugins: [jsxLoc()]\n if (!pluginsProp) {\n const prop = (parseModule(\"export default { plugins: [jsxLoc()] };\").$ast as any)\n .body?.find((s: any) => s.type === \"ExportDefaultDeclaration\")\n ?.declaration?.properties?.find((p: any) => {\n const k = p?.key;\n return (k?.type === \"Identifier\" && k.name === \"plugins\") ||\n (isStringLiteral(k) && k.value === \"plugins\");\n });\n if (!prop) return { changed: false };\n configObj.properties = [...(configObj.properties ?? []), prop];\n return { changed: true };\n }\n\n const value = unwrapExpression(pluginsProp.value);\n if (!value) return { changed: false };\n\n // plugins: [ ... ]\n if (value.type === \"ArrayExpression\") {\n if (pluginsHasJsxLoc(value)) return { changed: false };\n const jsxLocCall = (parseModule(\"const __x = jsxLoc();\").$ast as any).body?.[0]\n ?.declarations?.[0]?.init;\n if (!jsxLocCall) return { changed: false };\n value.elements.push(jsxLocCall);\n return { changed: true };\n }\n\n // Non-array plugins: best-effort wrap into array with spread.\n // plugins: something -> plugins: [...something, jsxLoc()]\n const jsxLocCall = (parseModule(\"const __x = jsxLoc();\").$ast as any).body?.[0]\n ?.declarations?.[0]?.init;\n if (!jsxLocCall) return { changed: false };\n const spread = { type: \"SpreadElement\", argument: value };\n pluginsProp.value = { type: \"ArrayExpression\", elements: [spread, jsxLocCall] };\n return { changed: true };\n}\n\nexport async function installViteJsxLocPlugin(\n opts: InstallViteJsxLocPluginOptions\n): Promise<{\n configFile: string | null;\n modified: boolean;\n /** Absolute paths of all files that were modified (for formatting) */\n modifiedFiles: string[];\n}> {\n const configPath = findViteConfigFile(opts.projectPath);\n if (!configPath) return { configFile: null, modified: false, modifiedFiles: [] };\n\n const configFilename = getViteConfigFilename(configPath);\n const original = readFileSync(configPath, \"utf-8\");\n const isCjs = configPath.endsWith(\".cjs\");\n\n let mod: any;\n try {\n mod = parseModule(original);\n } catch {\n return { configFile: configFilename, modified: false, modifiedFiles: [] };\n }\n\n const found = findExportedConfigObjectExpression(mod);\n if (!found) return { configFile: configFilename, modified: false, modifiedFiles: [] };\n\n let changed = false;\n\n // Ensure import/require first (so generated code has the symbol)\n if (isCjs) {\n const reqRes = ensureCjsJsxLocRequire(found.program);\n if (reqRes.changed) changed = true;\n } else {\n const impRes = ensureEsmJsxLocImport(found.program);\n if (impRes.changed) changed = true;\n }\n\n const pluginsRes = ensurePluginsContainsJsxLoc(found.objExpr);\n if (pluginsRes.changed) changed = true;\n\n const updated = changed ? generateCode(mod).code : original;\n if (updated !== original) {\n writeFileSync(configPath, updated, \"utf-8\");\n return { configFile: configFilename, modified: true, modifiedFiles: [configPath] };\n }\n\n return { configFile: configFilename, modified: false, modifiedFiles: [] };\n}\n\nexport interface RemoveViteJsxLocPluginOptions {\n projectPath: string;\n}\n\nexport interface RemoveViteJsxLocPluginResult {\n success: boolean;\n error?: string;\n modifiedFiles?: string[];\n}\n\n/**\n * Remove jsx-loc-plugin from vite.config\n *\n * This is a best-effort removal that:\n * 1. Removes jsx-loc-plugin import\n * 2. Removes jsxLoc() from plugins array\n */\nexport async function removeViteJsxLocPlugin(\n options: RemoveViteJsxLocPluginOptions\n): Promise<RemoveViteJsxLocPluginResult> {\n const { projectPath } = options;\n\n const configPath = findViteConfigFile(projectPath);\n if (!configPath) {\n return {\n success: true,\n modifiedFiles: [],\n };\n }\n\n try {\n const original = readFileSync(configPath, \"utf-8\");\n\n // Remove jsx-loc-plugin import\n let updated = original.replace(\n /^import\\s+\\{[^}]*jsxLoc[^}]*\\}\\s+from\\s+[\"']jsx-loc-plugin\\/vite[\"'];?\\s*$/gm,\n \"\"\n );\n\n // Remove jsx-loc-plugin default import\n updated = updated.replace(\n /^import\\s+jsxLoc\\s+from\\s+[\"']jsx-loc-plugin\\/vite[\"'];?\\s*$/gm,\n \"\"\n );\n\n // Remove jsx-loc-plugin require\n updated = updated.replace(\n /^const\\s+\\{[^}]*jsxLoc[^}]*\\}\\s*=\\s*require\\s*\\(\\s*[\"']jsx-loc-plugin\\/vite[\"']\\s*\\)\\s*;?\\s*$/gm,\n \"\"\n );\n\n // Remove jsxLoc() from plugins array\n updated = updated.replace(/jsxLoc\\s*\\(\\s*\\)\\s*,?\\s*/g, \"\");\n\n // Clean up empty lines\n updated = updated.replace(/\\n{3,}/g, \"\\n\\n\");\n\n if (updated !== original) {\n writeFileSync(configPath, updated, \"utf-8\");\n return {\n success: true,\n modifiedFiles: [configPath],\n };\n }\n\n return {\n success: true,\n modifiedFiles: [],\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n","import { existsSync } from \"fs\";\nimport { mkdir, readdir, writeFile } from \"fs/promises\";\nimport { join } from \"path\";\n\nexport interface InstallNextRoutesOptions {\n projectPath: string;\n /**\n * Relative app root: \"app\" or \"src/app\"\n */\n appRoot: string;\n force?: boolean;\n}\n\nconst DEV_SOURCE_ROUTE_TS = `/**\n * Dev-only API route for fetching source files\n *\n * This route allows the UILint overlay to fetch and display source code\n * for components rendered on the page.\n *\n * Security:\n * - Only available in development mode\n * - Validates file path is within project root\n * - Only allows specific file extensions\n */\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { resolve, relative, dirname, extname, sep } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport const runtime = \"nodejs\";\n\n// Allowed file extensions\nconst ALLOWED_EXTENSIONS = new Set([\".tsx\", \".ts\", \".jsx\", \".js\", \".css\"]);\n\n/**\n * Best-effort: resolve the Next.js project root (the dir that owns .next/) even in monorepos.\n *\n * Why: In monorepos, process.cwd() might be the workspace root (it also has package.json),\n * which would incorrectly store/read files under the wrong directory.\n */\nfunction findNextProjectRoot(): string {\n // Prefer discovering via this route module's on-disk path.\n // In Next, route code is executed from within \".next/server/...\".\n try {\n const selfPath = fileURLToPath(import.meta.url);\n const marker = sep + \".next\" + sep;\n const idx = selfPath.lastIndexOf(marker);\n if (idx !== -1) {\n return selfPath.slice(0, idx);\n }\n } catch {\n // ignore\n }\n\n // Fallback: walk up from cwd looking for .next/\n let dir = process.cwd();\n for (let i = 0; i < 20; i++) {\n if (existsSync(resolve(dir, \".next\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // Final fallback: cwd\n return process.cwd();\n}\n\n/**\n * Validate that a path is within the allowed directory\n */\nfunction isPathWithinRoot(filePath: string, root: string): boolean {\n const resolved = resolve(filePath);\n const resolvedRoot = resolve(root);\n return resolved.startsWith(resolvedRoot + \"/\") || resolved === resolvedRoot;\n}\n\n/**\n * Find workspace root by walking up looking for pnpm-workspace.yaml or .git\n */\nfunction findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 10; i++) {\n if (\n existsSync(resolve(dir, \"pnpm-workspace.yaml\")) ||\n existsSync(resolve(dir, \".git\"))\n ) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\nexport async function GET(request: NextRequest) {\n // Block in production\n if (process.env.NODE_ENV === \"production\") {\n return NextResponse.json(\n { error: \"Not available in production\" },\n { status: 404 }\n );\n }\n\n const { searchParams } = new URL(request.url);\n const filePath = searchParams.get(\"path\");\n\n if (!filePath) {\n return NextResponse.json(\n { error: \"Missing 'path' query parameter\" },\n { status: 400 }\n );\n }\n\n // Validate extension\n const ext = extname(filePath).toLowerCase();\n if (!ALLOWED_EXTENSIONS.has(ext)) {\n return NextResponse.json(\n { error: \\`File extension '\\${ext}' not allowed\\` },\n { status: 403 }\n );\n }\n\n // Find project root (prefer Next project root over workspace root)\n const projectRoot = findNextProjectRoot();\n\n // Resolve the file path\n const resolvedPath = resolve(filePath);\n\n // Security check: ensure path is within project root or workspace root\n const workspaceRoot = findWorkspaceRoot(projectRoot);\n const isWithinApp = isPathWithinRoot(resolvedPath, projectRoot);\n const isWithinWorkspace = isPathWithinRoot(resolvedPath, workspaceRoot);\n\n if (!isWithinApp && !isWithinWorkspace) {\n return NextResponse.json(\n { error: \"Path outside project directory\" },\n { status: 403 }\n );\n }\n\n // Check file exists\n if (!existsSync(resolvedPath)) {\n return NextResponse.json({ error: \"File not found\" }, { status: 404 });\n }\n\n try {\n const content = readFileSync(resolvedPath, \"utf-8\");\n const relativePath = relative(workspaceRoot, resolvedPath);\n\n return NextResponse.json({\n content,\n relativePath,\n projectRoot,\n workspaceRoot,\n });\n } catch (error) {\n console.error(\"[Dev Source API] Error reading file:\", error);\n return NextResponse.json({ error: \"Failed to read file\" }, { status: 500 });\n }\n}\n`;\n\nconst SCREENSHOT_ROUTE_TS = `/**\n * Dev-only API route for saving and retrieving vision analysis screenshots\n *\n * This route allows the UILint overlay to:\n * - POST: Save screenshots and element manifests for vision analysis\n * - GET: Retrieve screenshots or list available screenshots\n *\n * Security:\n * - Only available in development mode\n * - Saves to .uilint/screenshots/ directory within project\n */\n\nimport { NextRequest, NextResponse } from \"next/server\";\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from \"fs\";\nimport { resolve, join, dirname, basename, sep } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport const runtime = \"nodejs\";\n\n// Maximum screenshot size (10MB)\nconst MAX_SCREENSHOT_SIZE = 10 * 1024 * 1024;\n\n/**\n * Best-effort: resolve the Next.js project root (the dir that owns .next/) even in monorepos.\n */\nfunction findNextProjectRoot(): string {\n try {\n const selfPath = fileURLToPath(import.meta.url);\n const marker = sep + \".next\" + sep;\n const idx = selfPath.lastIndexOf(marker);\n if (idx !== -1) {\n return selfPath.slice(0, idx);\n }\n } catch {\n // ignore\n }\n\n let dir = process.cwd();\n for (let i = 0; i < 20; i++) {\n if (existsSync(resolve(dir, \".next\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return process.cwd();\n}\n\n/**\n * Get the screenshots directory path, creating it if needed\n */\nfunction getScreenshotsDir(projectRoot: string): string {\n const screenshotsDir = join(projectRoot, \".uilint\", \"screenshots\");\n if (!existsSync(screenshotsDir)) {\n mkdirSync(screenshotsDir, { recursive: true });\n }\n return screenshotsDir;\n}\n\n/**\n * Validate filename to prevent path traversal\n */\nfunction isValidFilename(filename: string): boolean {\n // Only allow alphanumeric, hyphens, underscores, and dots\n // Must end with .png, .jpeg, .jpg, or .json\n const validPattern = /^[a-zA-Z0-9_-]+\\\\.(png|jpeg|jpg|json)$/;\n return validPattern.test(filename) && !filename.includes(\"..\");\n}\n\n/**\n * POST: Save a screenshot and optionally its manifest\n */\nexport async function POST(request: NextRequest) {\n // Block in production\n if (process.env.NODE_ENV === \"production\") {\n return NextResponse.json(\n { error: \"Not available in production\" },\n { status: 404 }\n );\n }\n\n try {\n const body = await request.json();\n const { filename, imageData, manifest, analysisResult } = body;\n\n if (!filename) {\n return NextResponse.json({ error: \"Missing 'filename'\" }, { status: 400 });\n }\n\n // Validate filename\n if (!isValidFilename(filename)) {\n return NextResponse.json(\n { error: \"Invalid filename format\" },\n { status: 400 }\n );\n }\n\n // Allow \"sidecar-only\" updates (manifest/analysisResult) without re-sending image bytes.\n const hasImageData = typeof imageData === \"string\" && imageData.length > 0;\n const hasSidecar =\n typeof manifest !== \"undefined\" || typeof analysisResult !== \"undefined\";\n\n if (!hasImageData && !hasSidecar) {\n return NextResponse.json(\n { error: \"Nothing to save (provide imageData and/or manifest/analysisResult)\" },\n { status: 400 }\n );\n }\n\n // Check size (image only)\n if (hasImageData && imageData.length > MAX_SCREENSHOT_SIZE) {\n return NextResponse.json(\n { error: \"Screenshot too large (max 10MB)\" },\n { status: 413 }\n );\n }\n\n const projectRoot = findNextProjectRoot();\n const screenshotsDir = getScreenshotsDir(projectRoot);\n\n const imagePath = join(screenshotsDir, filename);\n\n // Save the image (base64 data URL) if provided\n if (hasImageData) {\n const base64Data = imageData.includes(\",\")\n ? imageData.split(\",\")[1]\n : imageData;\n writeFileSync(imagePath, Buffer.from(base64Data, \"base64\"));\n }\n\n // Save manifest and analysis result as JSON sidecar\n if (hasSidecar) {\n const jsonFilename = filename.replace(/\\\\.(png|jpeg|jpg)$/, \".json\");\n const jsonPath = join(screenshotsDir, jsonFilename);\n\n // If a sidecar already exists, merge updates (lets us POST analysisResult later without re-sending image).\n let existing: any = null;\n if (existsSync(jsonPath)) {\n try {\n existing = JSON.parse(readFileSync(jsonPath, \"utf-8\"));\n } catch {\n existing = null;\n }\n }\n\n const routeFromAnalysis =\n analysisResult && typeof analysisResult === \"object\"\n ? (analysisResult as any).route\n : undefined;\n const issuesFromAnalysis =\n analysisResult && typeof analysisResult === \"object\"\n ? (analysisResult as any).issues\n : undefined;\n\n const jsonData = {\n ...(existing && typeof existing === \"object\" ? existing : {}),\n timestamp: Date.now(),\n filename,\n screenshotFile: filename,\n route:\n typeof routeFromAnalysis === \"string\"\n ? routeFromAnalysis\n : (existing as any)?.route ?? null,\n issues:\n Array.isArray(issuesFromAnalysis)\n ? issuesFromAnalysis\n : (existing as any)?.issues ?? null,\n manifest: typeof manifest === \"undefined\" ? existing?.manifest ?? null : manifest,\n analysisResult:\n typeof analysisResult === \"undefined\"\n ? existing?.analysisResult ?? null\n : analysisResult,\n };\n writeFileSync(jsonPath, JSON.stringify(jsonData, null, 2));\n }\n\n return NextResponse.json({\n success: true,\n path: imagePath,\n projectRoot,\n screenshotsDir,\n });\n } catch (error) {\n console.error(\"[Screenshot API] Error saving screenshot:\", error);\n return NextResponse.json(\n { error: \"Failed to save screenshot\" },\n { status: 500 }\n );\n }\n}\n\n/**\n * GET: Retrieve a screenshot or list available screenshots\n */\nexport async function GET(request: NextRequest) {\n // Block in production\n if (process.env.NODE_ENV === \"production\") {\n return NextResponse.json(\n { error: \"Not available in production\" },\n { status: 404 }\n );\n }\n\n const { searchParams } = new URL(request.url);\n const filename = searchParams.get(\"filename\");\n const list = searchParams.get(\"list\");\n\n const projectRoot = findNextProjectRoot();\n const screenshotsDir = getScreenshotsDir(projectRoot);\n\n // List mode: return all screenshots\n if (list === \"true\") {\n try {\n const files = readdirSync(screenshotsDir);\n const screenshots = files\n .filter((f) => /\\\\.(png|jpeg|jpg)$/.test(f))\n .map((f) => {\n const jsonFile = f.replace(/\\\\.(png|jpeg|jpg)$/, \".json\");\n const jsonPath = join(screenshotsDir, jsonFile);\n let metadata = null;\n if (existsSync(jsonPath)) {\n try {\n metadata = JSON.parse(readFileSync(jsonPath, \"utf-8\"));\n } catch {\n // Ignore parse errors\n }\n }\n return {\n filename: f,\n metadata,\n };\n })\n .sort((a, b) => {\n // Sort by timestamp descending (newest first)\n const aTime = a.metadata?.timestamp || 0;\n const bTime = b.metadata?.timestamp || 0;\n return bTime - aTime;\n });\n\n return NextResponse.json({ screenshots, projectRoot, screenshotsDir });\n } catch (error) {\n console.error(\"[Screenshot API] Error listing screenshots:\", error);\n return NextResponse.json(\n { error: \"Failed to list screenshots\" },\n { status: 500 }\n );\n }\n }\n\n // Retrieve mode: get specific screenshot\n if (!filename) {\n return NextResponse.json(\n { error: \"Missing 'filename' parameter\" },\n { status: 400 }\n );\n }\n\n if (!isValidFilename(filename)) {\n return NextResponse.json(\n { error: \"Invalid filename format\" },\n { status: 400 }\n );\n }\n\n const filePath = join(screenshotsDir, filename);\n\n if (!existsSync(filePath)) {\n return NextResponse.json(\n { error: \"Screenshot not found\" },\n { status: 404 }\n );\n }\n\n try {\n const content = readFileSync(filePath);\n \n // Determine content type\n const ext = filename.split(\".\").pop()?.toLowerCase();\n const contentType =\n ext === \"json\"\n ? \"application/json\"\n : ext === \"png\"\n ? \"image/png\"\n : \"image/jpeg\";\n\n if (ext === \"json\") {\n return NextResponse.json(JSON.parse(content.toString()));\n }\n\n return new NextResponse(content, {\n headers: {\n \"Content-Type\": contentType,\n \"Cache-Control\": \"no-cache\",\n },\n });\n } catch (error) {\n console.error(\"[Screenshot API] Error reading screenshot:\", error);\n return NextResponse.json(\n { error: \"Failed to read screenshot\" },\n { status: 500 }\n );\n }\n}\n`;\n\nasync function writeRouteFile(\n absPath: string,\n relPath: string,\n content: string,\n opts: InstallNextRoutesOptions\n): Promise<void> {\n // This generator is deterministic; no confirmOverwrite prompts needed.\n // If a file exists and we're not forcing, just skip it.\n if (existsSync(absPath) && !opts.force) return;\n await writeFile(absPath, content, \"utf-8\");\n}\n\nexport async function installNextUILintRoutes(\n opts: InstallNextRoutesOptions\n): Promise<void> {\n const baseRel = join(opts.appRoot, \"api\", \".uilint\");\n const baseAbs = join(opts.projectPath, baseRel);\n\n // UILint API routes\n\n // Source file API (for source visualization in overlay)\n await mkdir(join(baseAbs, \"source\"), { recursive: true });\n\n await writeRouteFile(\n join(baseAbs, \"source\", \"route.ts\"),\n join(baseRel, \"source\", \"route.ts\"),\n DEV_SOURCE_ROUTE_TS,\n opts\n );\n\n // Screenshot API (for vision analysis screenshots)\n await mkdir(join(baseAbs, \"screenshots\"), { recursive: true });\n\n await writeRouteFile(\n join(baseAbs, \"screenshots\", \"route.ts\"),\n join(baseRel, \"screenshots\", \"route.ts\"),\n SCREENSHOT_ROUTE_TS,\n opts\n );\n}\n\nexport interface RemoveNextRoutesOptions {\n projectPath: string;\n appRoot: string;\n}\n\nexport interface RemoveNextRoutesResult {\n success: boolean;\n error?: string;\n}\n\n/**\n * Remove UILint API routes from Next.js app\n */\nexport async function removeNextUILintRoutes(\n options: RemoveNextRoutesOptions\n): Promise<RemoveNextRoutesResult> {\n const { projectPath, appRoot } = options;\n const { rm } = await import(\"fs/promises\");\n\n const baseAbs = join(projectPath, appRoot, \"api\", \".uilint\");\n\n try {\n if (existsSync(baseAbs)) {\n await rm(baseAbs, { recursive: true, force: true });\n }\n return { success: true };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n","/**\n * Prettier formatting utilities\n *\n * Formats files using the target project's prettier if available.\n * Falls back gracefully if prettier is not installed.\n */\n\nimport { existsSync, utimesSync } from \"fs\";\nimport { spawn } from \"child_process\";\nimport { join, dirname } from \"path\";\nimport { detectPackageManager, type PackageManager } from \"./package-manager.js\";\n\n/**\n * Check if prettier is available in the target project\n */\nexport function hasPrettier(projectPath: string): boolean {\n // Check for prettier in node_modules\n const prettierPath = join(projectPath, \"node_modules\", \".bin\", \"prettier\");\n if (existsSync(prettierPath)) return true;\n\n // Walk up to find prettier (monorepo support)\n let dir = projectPath;\n for (let i = 0; i < 10; i++) {\n const binPath = join(dir, \"node_modules\", \".bin\", \"prettier\");\n if (existsSync(binPath)) return true;\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return false;\n}\n\n/**\n * Get the prettier executable path for the project\n */\nfunction getPrettierPath(projectPath: string): string | null {\n // Check local first\n const localPath = join(projectPath, \"node_modules\", \".bin\", \"prettier\");\n if (existsSync(localPath)) return localPath;\n\n // Walk up for monorepo\n let dir = projectPath;\n for (let i = 0; i < 10; i++) {\n const binPath = join(dir, \"node_modules\", \".bin\", \"prettier\");\n if (existsSync(binPath)) return binPath;\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return null;\n}\n\n/**\n * Get the package manager runner command (npx, pnpm exec, yarn, bunx)\n */\nfunction getPmRunner(pm: PackageManager): { command: string; args: string[] } {\n switch (pm) {\n case \"pnpm\":\n return { command: \"pnpm\", args: [\"exec\"] };\n case \"yarn\":\n return { command: \"yarn\", args: [] };\n case \"bun\":\n return { command: \"bunx\", args: [] };\n case \"npm\":\n default:\n return { command: \"npx\", args: [] };\n }\n}\n\n/**\n * Format a file using prettier\n *\n * @param filePath - Absolute path to the file to format\n * @param projectPath - Project root (used to find prettier config)\n * @returns Promise that resolves when formatting is complete\n */\nexport async function formatWithPrettier(\n filePath: string,\n projectPath: string\n): Promise<{ formatted: boolean; error?: string }> {\n const prettierPath = getPrettierPath(projectPath);\n\n if (!prettierPath) {\n // Try using package manager runner as fallback\n const pm = detectPackageManager(projectPath);\n const runner = getPmRunner(pm);\n\n return new Promise((resolve) => {\n const args = [...runner.args, \"prettier\", \"--write\", filePath];\n const child = spawn(runner.command, args, {\n cwd: projectPath,\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n\n let stderr = \"\";\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n child.on(\"error\", () => {\n // Prettier not available, that's OK\n resolve({ formatted: false, error: \"prettier not available\" });\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ formatted: true });\n } else {\n // Non-zero exit could mean prettier isn't installed\n resolve({ formatted: false, error: stderr || \"prettier failed\" });\n }\n });\n });\n }\n\n return new Promise((resolve) => {\n const child = spawn(prettierPath, [\"--write\", filePath], {\n cwd: projectPath,\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n\n let stderr = \"\";\n child.stderr?.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n child.on(\"error\", (err) => {\n resolve({ formatted: false, error: err.message });\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ formatted: true });\n } else {\n resolve({ formatted: false, error: stderr || `exit code ${code}` });\n }\n });\n });\n}\n\n/**\n * Format multiple files using prettier\n *\n * @param filePaths - Array of absolute file paths to format\n * @param projectPath - Project root (used to find prettier config)\n * @returns Promise that resolves when all formatting is complete\n */\nexport async function formatFilesWithPrettier(\n filePaths: string[],\n projectPath: string\n): Promise<{ formatted: string[]; failed: string[] }> {\n if (filePaths.length === 0) {\n return { formatted: [], failed: [] };\n }\n\n const prettierPath = getPrettierPath(projectPath);\n const formatted: string[] = [];\n const failed: string[] = [];\n\n if (!prettierPath) {\n // Try using package manager runner\n const pm = detectPackageManager(projectPath);\n const runner = getPmRunner(pm);\n\n return new Promise((resolve) => {\n const args = [...runner.args, \"prettier\", \"--write\", ...filePaths];\n const child = spawn(runner.command, args, {\n cwd: projectPath,\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", () => {\n // Prettier not available\n resolve({ formatted: [], failed: filePaths });\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ formatted: filePaths, failed: [] });\n } else {\n resolve({ formatted: [], failed: filePaths });\n }\n });\n });\n }\n\n // Format all files in one prettier call for efficiency\n return new Promise((resolve) => {\n const child = spawn(prettierPath, [\"--write\", ...filePaths], {\n cwd: projectPath,\n stdio: \"pipe\",\n shell: process.platform === \"win32\",\n });\n\n child.on(\"error\", () => {\n resolve({ formatted: [], failed: filePaths });\n });\n\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ formatted: filePaths, failed: [] });\n } else {\n // If batch fails, try individual files\n Promise.all(\n filePaths.map(async (fp) => {\n const result = await formatWithPrettier(fp, projectPath);\n if (result.formatted) {\n formatted.push(fp);\n } else {\n failed.push(fp);\n }\n })\n ).then(() => {\n resolve({ formatted, failed });\n });\n }\n });\n });\n}\n\n/**\n * Touch files to update their modification time.\n * This can trigger IDE file watchers which may invoke format-on-save.\n *\n * @param filePaths - Array of absolute file paths to touch\n */\nexport function touchFiles(filePaths: string[]): void {\n const now = new Date();\n for (const filePath of filePaths) {\n try {\n if (existsSync(filePath)) {\n utimesSync(filePath, now, now);\n }\n } catch {\n // Silently ignore touch failures - this is a best-effort operation\n }\n }\n}\n","/**\n * Utility to add .uilint to tsconfig.json exclude array\n *\n * When uilint installs ESLint rules to .uilint/rules/, we need to exclude\n * this directory from the app's TypeScript compilation to prevent build errors.\n * The rules are loaded dynamically by ESLint at runtime, not compiled with the app.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { join } from \"path\";\n\nexport interface TsconfigInjectResult {\n /** Whether the file was modified */\n modified: boolean;\n /** Path to tsconfig.json if found */\n tsconfigPath?: string;\n /** Error message if something went wrong */\n error?: string;\n}\n\n/**\n * Add .uilint to tsconfig.json exclude array\n *\n * @param projectPath - Path to the project root containing tsconfig.json\n * @returns Result indicating whether the file was modified\n */\nexport function injectTsconfigExclusion(\n projectPath: string\n): TsconfigInjectResult {\n const tsconfigPath = join(projectPath, \"tsconfig.json\");\n\n // If no tsconfig.json, that's fine - project might be JS-only\n if (!existsSync(tsconfigPath)) {\n return { modified: false };\n }\n\n try {\n const content = readFileSync(tsconfigPath, \"utf-8\");\n const tsconfig = JSON.parse(content) as {\n exclude?: string[];\n [key: string]: unknown;\n };\n\n // Check if .uilint is already in exclude\n const exclude = tsconfig.exclude ?? [];\n if (exclude.includes(\".uilint\")) {\n return { modified: false, tsconfigPath };\n }\n\n // Add .uilint to exclude array\n tsconfig.exclude = [...exclude, \".uilint\"];\n\n // Write back with same formatting (2-space indent is standard for tsconfig)\n writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + \"\\n\", \"utf-8\");\n\n return { modified: true, tsconfigPath };\n } catch (err) {\n return {\n modified: false,\n tsconfigPath,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Installer registry - central registration point for all installers\n *\n * Installers self-register here to be available in the install flow.\n */\n\nimport type { Installer } from \"./types.js\";\n\n/**\n * Global registry of all installers\n */\nconst installers: Installer[] = [];\n\n/**\n * Register an installer\n * @param installer - Installer to register\n */\nexport function registerInstaller(installer: Installer): void {\n // Prevent duplicate registrations\n if (installers.some((i) => i.id === installer.id)) {\n console.warn(`Installer \"${installer.id}\" is already registered`);\n return;\n }\n installers.push(installer);\n}\n\n/**\n * Get all registered installers\n * @returns Array of all installers\n */\nexport function getAllInstallers(): readonly Installer[] {\n return installers;\n}\n\n/**\n * Get installer by ID\n * @param id - Installer ID\n * @returns Installer or undefined if not found\n */\nexport function getInstallerById(id: string): Installer | undefined {\n return installers.find((i) => i.id === id);\n}\n\n/**\n * Clear all registered installers (for testing)\n */\nexport function clearInstallers(): void {\n installers.length = 0;\n}\n","/**\n * Genstyleguide installer - Cursor command for generating style guides\n */\n\nimport { join } from \"path\";\nimport type { Installer, InstallTarget, InstallerConfig, ProgressEvent } from \"./types.js\";\nimport type { ProjectState, InstallAction, DependencyInstall } from \"../types.js\";\nimport { GENSTYLEGUIDE_COMMAND_MD } from \"../constants.js\";\n\nexport const genstyleguideInstaller: Installer = {\n id: \"genstyleguide\",\n name: \"/genstyleguide command\",\n description: \"Cursor command to generate UI style guides\",\n icon: \"📝\",\n\n isApplicable(project: ProjectState): boolean {\n // Always applicable - works in any project\n return true;\n },\n\n getTargets(project: ProjectState): InstallTarget[] {\n const commandPath = join(project.cursorDir.path, \"commands\", \"genstyleguide.md\");\n const isInstalled = project.commands.genstyleguide;\n\n return [\n {\n id: \"genstyleguide-command\",\n label: \".cursor/commands/genstyleguide.md\",\n path: commandPath,\n isInstalled,\n },\n ];\n },\n\n plan(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): {\n actions: InstallAction[];\n dependencies: DependencyInstall[];\n } {\n const actions: InstallAction[] = [];\n\n // Ensure .cursor/commands directory exists\n const commandsDir = join(project.cursorDir.path, \"commands\");\n\n if (!project.cursorDir.exists) {\n actions.push({\n type: \"create_directory\",\n path: project.cursorDir.path,\n });\n }\n\n actions.push({\n type: \"create_directory\",\n path: commandsDir,\n });\n\n // Create the command file\n actions.push({\n type: \"create_file\",\n path: join(commandsDir, \"genstyleguide.md\"),\n content: GENSTYLEGUIDE_COMMAND_MD,\n });\n\n return {\n actions,\n dependencies: [],\n };\n },\n\n async *execute(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): AsyncGenerator<ProgressEvent> {\n yield {\n type: \"start\",\n message: \"Installing /genstyleguide command\",\n };\n\n yield {\n type: \"progress\",\n message: \"Creating .cursor/commands directory\",\n };\n\n yield {\n type: \"progress\",\n message: \"Writing command file\",\n detail: \"→ .cursor/commands/genstyleguide.md\",\n };\n\n yield {\n type: \"complete\",\n message: \"Installed /genstyleguide command\",\n };\n },\n\n planRemove(\n targets: InstallTarget[],\n project: ProjectState\n ): {\n actions: InstallAction[];\n } {\n const actions: InstallAction[] = [];\n\n // Delete the command file\n const commandPath = join(project.cursorDir.path, \"commands\", \"genstyleguide.md\");\n actions.push({\n type: \"delete_file\",\n path: commandPath,\n });\n\n return { actions };\n },\n};\n","/**\n * Skill installer - Claude Code Agent Skills for UI consistency\n */\n\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport type { Installer, InstallTarget, InstallerConfig, ProgressEvent } from \"./types.js\";\nimport type { ProjectState, InstallAction, DependencyInstall } from \"../types.js\";\nimport { loadSkill } from \"../../../utils/skill-loader.js\";\n\nexport const skillInstaller: Installer = {\n id: \"skill\",\n name: \"UI Consistency Agent skill\",\n description: \"Claude Code skill for enforcing UI consistency\",\n icon: \"⚡\",\n\n isApplicable(project: ProjectState): boolean {\n // Always applicable - works in any project\n return true;\n },\n\n getTargets(project: ProjectState): InstallTarget[] {\n const skillsDir = join(project.cursorDir.path, \"skills\", \"ui-consistency-enforcer\");\n const skillMdPath = join(skillsDir, \"SKILL.md\");\n\n // Check if skill is already installed by checking for SKILL.md\n const isInstalled = existsSync(skillMdPath);\n\n return [\n {\n id: \"ui-consistency-skill\",\n label: \".cursor/skills/ui-consistency-enforcer\",\n path: skillsDir,\n isInstalled,\n hint: \"Agent skill for UI consistency checks\",\n },\n ];\n },\n\n plan(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): {\n actions: InstallAction[];\n dependencies: DependencyInstall[];\n } {\n const actions: InstallAction[] = [];\n\n // Ensure .cursor directory exists\n if (!project.cursorDir.exists) {\n actions.push({\n type: \"create_directory\",\n path: project.cursorDir.path,\n });\n }\n\n // Create skills directory\n const skillsDir = join(project.cursorDir.path, \"skills\");\n actions.push({\n type: \"create_directory\",\n path: skillsDir,\n });\n\n // Load and install the ui-consistency-enforcer skill\n try {\n const skill = loadSkill(\"ui-consistency-enforcer\");\n const skillDir = join(skillsDir, skill.name);\n\n // Create skill directory\n actions.push({\n type: \"create_directory\",\n path: skillDir,\n });\n\n // Create all skill files\n for (const file of skill.files) {\n const filePath = join(skillDir, file.relativePath);\n\n // Ensure subdirectories exist (e.g., references/)\n const fileDir = join(\n skillDir,\n file.relativePath.split(\"/\").slice(0, -1).join(\"/\")\n );\n if (fileDir !== skillDir && file.relativePath.includes(\"/\")) {\n actions.push({\n type: \"create_directory\",\n path: fileDir,\n });\n }\n\n actions.push({\n type: \"create_file\",\n path: filePath,\n content: file.content,\n });\n }\n } catch (error) {\n // Skill not found - this shouldn't happen in normal install\n console.warn(\"Failed to load ui-consistency-enforcer skill:\", error);\n }\n\n return {\n actions,\n dependencies: [],\n };\n },\n\n async *execute(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): AsyncGenerator<ProgressEvent> {\n yield {\n type: \"start\",\n message: \"Installing UI Consistency Agent skill\",\n };\n\n yield {\n type: \"progress\",\n message: \"Creating .cursor/skills directory\",\n };\n\n try {\n const skill = loadSkill(\"ui-consistency-enforcer\");\n\n for (const file of skill.files) {\n yield {\n type: \"progress\",\n message: \"Writing skill file\",\n detail: `→ ${file.relativePath}`,\n };\n }\n\n yield {\n type: \"complete\",\n message: \"Installed UI Consistency Agent skill\",\n };\n } catch (error) {\n yield {\n type: \"error\",\n message: \"Failed to install skill\",\n error: error instanceof Error ? error.message : String(error),\n };\n }\n },\n\n planRemove(\n targets: InstallTarget[],\n project: ProjectState\n ): {\n actions: InstallAction[];\n } {\n const actions: InstallAction[] = [];\n\n // Delete the skill directory\n const skillDir = join(project.cursorDir.path, \"skills\", \"ui-consistency-enforcer\");\n actions.push({\n type: \"remove_directory\",\n path: skillDir,\n });\n\n return { actions };\n },\n};\n","/**\n * ESLint installer - UILint ESLint plugin configuration\n *\n * Provides interactive rule selection and severity configuration during install.\n */\n\nimport { join } from \"path\";\nimport { ruleRegistry, getRulesByCategory, getRuleDocs, getCategoryMeta } from \"uilint-eslint\";\nimport type {\n Installer,\n InstallTarget,\n InstallerConfig,\n ProgressEvent,\n UpgradeInfo,\n} from \"./types.js\";\nimport type {\n ProjectState,\n InstallAction,\n DependencyInstall,\n} from \"../types.js\";\nimport type { RuleMeta, OptionFieldSchema } from \"uilint-eslint\";\nimport * as prompts from \"../../../utils/prompts.js\";\nimport { detectPackageManager } from \"../../../utils/package-manager.js\";\nimport { toInstallSpecifier } from \"../versioning.js\";\nimport {\n type AIHookProvider,\n isHookInstalled,\n planClaudeHook,\n planCursorHook,\n} from \"./ai-hooks.js\";\n\n// ============================================================================\n// Rule Options Configuration Helpers\n// ============================================================================\n\n/**\n * Prompt for a single option field based on its schema\n */\nasync function promptForField(\n field: OptionFieldSchema,\n currentValue: unknown\n): Promise<unknown> {\n const hint = field.description ? prompts.pc.dim(` ${field.description}`) : \"\";\n\n switch (field.type) {\n case \"boolean\":\n return prompts.confirm({\n message: field.label,\n initialValue: (currentValue as boolean) ?? (field.defaultValue as boolean) ?? false,\n });\n\n case \"number\": {\n const numResult = await prompts.text({\n message: field.label + hint,\n placeholder: field.placeholder || String(currentValue ?? field.defaultValue ?? \"\"),\n defaultValue: String(currentValue ?? field.defaultValue ?? \"\"),\n validate: (value) => {\n const num = Number(value);\n if (isNaN(num)) return \"Please enter a valid number\";\n return undefined;\n },\n });\n return Number(numResult);\n }\n\n case \"text\": {\n const defaultVal = currentValue ?? field.defaultValue ?? \"\";\n // If default is an array, join it for display\n const displayDefault = Array.isArray(defaultVal)\n ? defaultVal.join(\", \")\n : String(defaultVal);\n\n return prompts.text({\n message: field.label + hint,\n placeholder: field.placeholder || displayDefault,\n defaultValue: displayDefault,\n });\n }\n\n case \"select\":\n if (!field.options?.length) {\n return currentValue ?? field.defaultValue;\n }\n return prompts.select({\n message: field.label + hint,\n options: field.options.map((opt) => ({\n value: String(opt.value),\n label: opt.label,\n })),\n initialValue: String(currentValue ?? field.defaultValue),\n });\n\n case \"multiselect\":\n if (!field.options?.length) {\n return currentValue ?? field.defaultValue;\n }\n return prompts.multiselect({\n message: field.label + hint,\n options: field.options.map((opt) => ({\n value: String(opt.value),\n label: opt.label,\n })),\n initialValues: Array.isArray(currentValue)\n ? currentValue.map(String)\n : Array.isArray(field.defaultValue)\n ? (field.defaultValue as string[]).map(String)\n : [],\n });\n\n default:\n return currentValue ?? field.defaultValue;\n }\n}\n\n/**\n * Convert field value to the expected type for the rule options\n * Handles comma-separated text → array conversion\n * @internal Exported for testing\n */\nexport function convertFieldValue(\n value: unknown,\n field: OptionFieldSchema,\n defaultValue: unknown\n): unknown {\n // If defaultValue is an array but field type is text, parse comma-separated\n if (Array.isArray(defaultValue) && field.type === \"text\" && typeof value === \"string\") {\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n }\n return value;\n}\n\n/**\n * Configure options for a single rule based on its schema\n */\nasync function configureRuleOptions(\n rule: RuleMeta\n): Promise<Record<string, unknown> | undefined> {\n if (!rule.optionSchema?.fields?.length) {\n return undefined;\n }\n\n prompts.log(\"\");\n prompts.log(\n prompts.pc.bold(prompts.pc.cyan(`${rule.icon ?? \"⚙️\"} ${rule.name}`)) +\n prompts.pc.dim(` - ${rule.description}`)\n );\n\n const baseOptions = rule.defaultOptions?.[0] ?? {};\n const options: Record<string, unknown> = {};\n\n for (const field of rule.optionSchema.fields) {\n const currentValue = (baseOptions as Record<string, unknown>)[field.key];\n const defaultValue = currentValue ?? field.defaultValue;\n\n const value = await promptForField(field, currentValue);\n options[field.key] = convertFieldValue(value, field, defaultValue);\n }\n\n return options;\n}\n\n/**\n * Calculate upgrade info for a package that already has uilint rules configured\n */\nfunction getUpgradeInfo(configuredRuleIds: string[]): UpgradeInfo | undefined {\n const configuredSet = new Set(configuredRuleIds);\n const allRuleIds = ruleRegistry.map((r) => r.id);\n\n // Find rules that are available but not configured\n const missingRules = allRuleIds.filter((id) => !configuredSet.has(id));\n\n if (missingRules.length === 0) {\n return undefined;\n }\n\n const summary =\n missingRules.length === 1\n ? \"1 new rule available\"\n : `${missingRules.length} new rules available`;\n\n return {\n missingRules,\n summary,\n };\n}\n\n/**\n * Configured rule with user-selected severity\n */\nexport interface ConfiguredRule {\n /** Rule metadata */\n rule: RuleMeta;\n /** User-selected severity */\n severity: \"error\" | \"warn\" | \"off\";\n /** Custom options (if user configured them) */\n options?: unknown[];\n}\n\nexport interface ESLintInstallerConfig extends InstallerConfig {\n /** Selected rules with their configurations */\n configuredRules: ConfiguredRule[];\n /** Selected AI hooks to install (Claude, Cursor, or both) */\n aiHooks: AIHookProvider[];\n}\n\n/**\n * Format rule for display in multiselect\n */\nfunction formatRuleOption(rule: RuleMeta): {\n value: string;\n label: string;\n hint: string;\n} {\n const severityBadge =\n rule.defaultSeverity === \"error\"\n ? prompts.pc.red(\"error\")\n : prompts.pc.yellow(\"warn\");\n return {\n value: rule.id,\n label: `${rule.icon ?? \"\"} ${rule.name}`.trim(),\n hint: `${rule.hint ?? rule.description} [${severityBadge}]`,\n };\n}\n\n/**\n * Display rule documentation in a nice format\n */\nfunction showRuleDoc(rule: RuleMeta): void {\n prompts.note(\n rule.docs.trim().slice(0, 500) + (rule.docs.length > 500 ? \"...\" : \"\"),\n `📖 ${rule.name}`\n );\n}\n\nexport const eslintInstaller: Installer = {\n id: \"eslint\",\n name: \"ESLint plugin\",\n description: \"Lint UI consistency with ESLint rules\",\n icon: \"🔍\",\n\n isApplicable(project: ProjectState): boolean {\n return project.packages.some((pkg) => pkg.eslintConfigPath !== null);\n },\n\n getTargets(project: ProjectState): InstallTarget[] {\n return project.packages\n .filter((pkg) => pkg.eslintConfigPath !== null)\n .map((pkg) => {\n const upgradeInfo = pkg.hasUilintRules\n ? getUpgradeInfo(pkg.configuredRuleIds)\n : undefined;\n\n // Build hint showing config file and upgrade status\n let hint = pkg.eslintConfigFilename || \"ESLint config detected\";\n if (upgradeInfo?.summary) {\n hint = `${hint} · ${upgradeInfo.summary}`;\n }\n\n return {\n id: `eslint-${pkg.name}`,\n label: pkg.name,\n path: pkg.path,\n hint,\n isInstalled: pkg.hasUilintRules,\n canUpgrade: upgradeInfo !== undefined,\n upgradeInfo,\n };\n });\n },\n\n async configure(\n targets: InstallTarget[],\n project: ProjectState\n ): Promise<ESLintInstallerConfig> {\n const staticRules = getRulesByCategory(\"static\");\n const semanticRules = getRulesByCategory(\"semantic\");\n\n // Step 1: Ask about installation mode\n const installMode = await prompts.select({\n message: \"How would you like to configure UILint ESLint rules?\",\n options: [\n {\n value: \"recommended\",\n label: \"Recommended (static rules only)\",\n hint: \"Best for most projects - fast and reliable\",\n },\n {\n value: \"strict\",\n label: \"Strict (all rules including semantic)\",\n hint: \"Includes LLM-powered analysis - requires Ollama\",\n },\n {\n value: \"custom\",\n label: \"Custom selection\",\n hint: \"Choose individual rules and configure severity\",\n },\n ],\n });\n\n let selectedRuleIds: string[];\n let configuredRules: ConfiguredRule[];\n\n if (installMode === \"recommended\") {\n // Use all static rules with default severity\n configuredRules = staticRules.map((rule) => ({\n rule,\n severity: rule.defaultSeverity as \"error\" | \"warn\",\n options: rule.defaultOptions,\n }));\n } else if (installMode === \"strict\") {\n // Use all rules with default severity\n configuredRules = ruleRegistry.map((rule) => ({\n rule,\n severity: rule.defaultSeverity as \"error\" | \"warn\",\n options: rule.defaultOptions,\n }));\n } else {\n // Custom selection flow\n const staticCat = getCategoryMeta(\"static\");\n const semanticCat = getCategoryMeta(\"semantic\");\n\n prompts.log(prompts.pc.dim(`\\n${staticCat?.icon ?? \"📋\"} ${staticCat?.name ?? \"Static rules\"} (${staticCat?.description ?? \"pattern-based, fast\"}):`));\n\n // Select static rules\n const selectedStaticIds = await prompts.multiselect({\n message: \"Select static rules to enable:\",\n options: staticRules.map(formatRuleOption),\n initialValues: staticRules.filter((r) => r.defaultEnabled ?? staticCat?.defaultEnabled ?? true).map((r) => r.id),\n });\n\n // Ask about semantic rules\n const includeSemanticRules = await prompts.confirm({\n message: `Include semantic rules? ${prompts.pc.dim(\n `(${semanticCat?.description ?? \"LLM-powered analysis\"})`\n )}`,\n initialValue: false,\n });\n\n let selectedSemanticIds: string[] = [];\n if (includeSemanticRules) {\n prompts.log(\n prompts.pc.dim(`\\n${semanticCat?.icon ?? \"🧠\"} ${semanticCat?.name ?? \"Semantic rules\"} (${semanticCat?.description ?? \"LLM-powered, slower\"}):`)\n );\n selectedSemanticIds = await prompts.multiselect({\n message: \"Select semantic rules:\",\n options: semanticRules.map(formatRuleOption),\n initialValues: semanticRules.filter((r) => r.defaultEnabled ?? semanticCat?.defaultEnabled ?? false).map((r) => r.id),\n });\n }\n\n selectedRuleIds = [...selectedStaticIds, ...selectedSemanticIds];\n\n // Step 2: Configure severity for each selected rule\n const configureSeverity = await prompts.confirm({\n message: \"Would you like to customize severity levels?\",\n initialValue: false,\n });\n\n configuredRules = [];\n\n for (const ruleId of selectedRuleIds) {\n const rule = ruleRegistry.find((r) => r.id === ruleId)!;\n\n if (configureSeverity) {\n const severity = await prompts.select({\n message: `${rule.name} - severity:`,\n options: [\n {\n value: rule.defaultSeverity,\n label: `${rule.defaultSeverity} (default)`,\n },\n ...(rule.defaultSeverity !== \"error\"\n ? [{ value: \"error\" as const, label: \"error\" }]\n : []),\n ...(rule.defaultSeverity !== \"warn\"\n ? [{ value: \"warn\" as const, label: \"warn\" }]\n : []),\n ],\n initialValue: rule.defaultSeverity,\n });\n\n configuredRules.push({\n rule,\n severity: severity as \"error\" | \"warn\",\n options: rule.defaultOptions,\n });\n } else {\n configuredRules.push({\n rule,\n severity: rule.defaultSeverity as \"error\" | \"warn\",\n options: rule.defaultOptions,\n });\n }\n }\n\n }\n\n // Step: Configure individual rule options (applies to all modes)\n const rulesWithOptions = configuredRules.filter(\n (cr) => cr.rule.optionSchema && cr.rule.optionSchema.fields.length > 0\n );\n\n if (rulesWithOptions.length > 0) {\n const customizeOptions = await prompts.confirm({\n message: `Customize rule options? ${prompts.pc.dim(\n `(${rulesWithOptions.length} rules have configurable options)`\n )}`,\n initialValue: false,\n });\n\n if (customizeOptions) {\n for (const cr of configuredRules) {\n if (cr.rule.optionSchema && cr.rule.optionSchema.fields.length > 0) {\n const options = await configureRuleOptions(cr.rule);\n if (options) {\n // Merge with existing defaultOptions structure\n const existingOptions =\n cr.options && cr.options.length > 0\n ? (cr.options[0] as Record<string, unknown>)\n : ({} as Record<string, unknown>);\n cr.options = [{ ...existingOptions, ...options }];\n }\n }\n }\n }\n }\n\n // Summary\n const errorCount = configuredRules.filter(\n (r) => r.severity === \"error\"\n ).length;\n const warnCount = configuredRules.filter(\n (r) => r.severity === \"warn\"\n ).length;\n\n prompts.log(\"\");\n prompts.note(\n configuredRules\n .map(\n (cr) =>\n `${cr.severity === \"error\" ? \"🔴\" : \"🟡\"} ${cr.rule.icon ?? \"\"} ${cr.rule.name} (${\n cr.severity\n })`\n )\n .join(\"\\n\"),\n `Selected ${configuredRules.length} rules (${errorCount} errors, ${warnCount} warnings)`\n );\n\n // Display post-install instructions and requirements from rule metadata\n const rulesWithInstructions = configuredRules.filter(\n (cr) => cr.rule.postInstallInstructions || (cr.rule.requirements?.length ?? 0) > 0\n );\n\n if (rulesWithInstructions.length > 0) {\n prompts.log(\"\");\n prompts.log(prompts.pc.bold(\"📋 Setup Requirements:\"));\n\n for (const cr of rulesWithInstructions) {\n // Show requirements\n if (cr.rule.requirements?.length) {\n for (const req of cr.rule.requirements) {\n prompts.log(\n prompts.pc.yellow(` ⚠️ ${cr.rule.name}: ${req.description}`)\n );\n if (req.setupHint) {\n prompts.log(prompts.pc.dim(` → ${req.setupHint}`));\n }\n }\n }\n\n // Show post-install instructions\n if (cr.rule.postInstallInstructions) {\n prompts.log(\n prompts.pc.cyan(` ℹ️ ${cr.rule.name}: ${cr.rule.postInstallInstructions}`)\n );\n }\n }\n }\n\n // Step: Ask about AI editor hooks\n prompts.log(\"\");\n const claudeInstalled = isHookInstalled(project.projectPath, \"claude\");\n const cursorInstalled = isHookInstalled(project.projectPath, \"cursor\");\n\n // Build options for AI hooks\n const hookOptions: Array<{ value: string; label: string; hint?: string }> = [];\n\n if (!claudeInstalled) {\n hookOptions.push({\n value: \"claude\",\n label: \"Claude Code\",\n hint: \"Auto-lint on file edit via .claude/hooks/post-edit.sh\",\n });\n }\n\n if (!cursorInstalled) {\n hookOptions.push({\n value: \"cursor\",\n label: \"Cursor\",\n hint: \"Auto-lint on file edit via .cursor/hooks/post-edit.sh\",\n });\n }\n\n let aiHooks: AIHookProvider[] = [];\n\n if (hookOptions.length > 0) {\n hookOptions.push({\n value: \"none\",\n label: \"None\",\n hint: \"Skip AI editor integration\",\n });\n\n const selectedHooks = await prompts.multiselect({\n message: \"Install AI editor hooks? \" + prompts.pc.dim(\"(auto-lint on file edit)\"),\n options: hookOptions,\n initialValues: [],\n required: false,\n });\n\n aiHooks = selectedHooks.filter((h): h is AIHookProvider => h === \"claude\" || h === \"cursor\");\n\n if (aiHooks.length > 0) {\n prompts.log(\n prompts.pc.dim(` → Will install hooks for: ${aiHooks.join(\", \")}`)\n );\n }\n } else {\n prompts.log(\n prompts.pc.dim(\" AI hooks already installed (Claude and Cursor)\")\n );\n }\n\n return { configuredRules, aiHooks };\n },\n\n plan(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): {\n actions: InstallAction[];\n dependencies: DependencyInstall[];\n } {\n const actions: InstallAction[] = [];\n const dependencies: DependencyInstall[] = [];\n const eslintConfig = config as ESLintInstallerConfig;\n const { configuredRules } = eslintConfig;\n\n // Convert configuredRules to the format expected by inject_eslint\n const rulesWithSeverity = configuredRules.map((cr) => ({\n ...cr.rule,\n defaultSeverity: cr.severity,\n defaultOptions: cr.options,\n }));\n\n for (const target of targets) {\n const pkgInfo = project.packages.find((p) => p.path === target.path);\n if (!pkgInfo || !pkgInfo.eslintConfigPath) continue;\n\n // Create .uilint/rules directory\n const rulesDir = join(target.path, \".uilint\", \"rules\");\n actions.push({\n type: \"create_directory\",\n path: rulesDir,\n });\n\n // Collect npm dependencies from all selected rules\n const ruleNpmDeps = new Set<string>();\n for (const cr of configuredRules) {\n if (cr.rule.npmDependencies) {\n for (const dep of cr.rule.npmDependencies) {\n ruleNpmDeps.add(dep);\n }\n }\n }\n\n // Install dependencies using the package manager for this specific target\n const packages = [\n toInstallSpecifier(\"uilint-eslint\", {\n preferWorkspaceProtocol: project.packageManager === \"pnpm\",\n workspaceRoot: project.workspaceRoot,\n targetProjectPath: target.path,\n }),\n \"typescript-eslint\",\n ...ruleNpmDeps,\n ];\n\n dependencies.push({\n packagePath: target.path,\n packageManager: detectPackageManager(target.path),\n packages,\n });\n\n // Inject ESLint rules\n actions.push({\n type: \"inject_eslint\",\n packagePath: target.path,\n configPath: pkgInfo.eslintConfigPath,\n rules: rulesWithSeverity,\n hasExistingRules: pkgInfo.hasUilintRules,\n });\n }\n\n // Add .uilint/.cache to .gitignore\n const gitignorePath = join(project.workspaceRoot, \".gitignore\");\n actions.push({\n type: \"append_to_file\",\n path: gitignorePath,\n content: \"\\n# UILint cache\\n.uilint/.cache\\n\",\n ifNotContains: \".uilint/.cache\",\n });\n\n // Add AI hooks if selected\n const { aiHooks } = eslintConfig;\n if (aiHooks?.includes(\"claude\")) {\n actions.push(...planClaudeHook(project.projectPath));\n }\n if (aiHooks?.includes(\"cursor\")) {\n actions.push(...planCursorHook(project.projectPath));\n }\n\n return { actions, dependencies };\n },\n\n async *execute(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): AsyncGenerator<ProgressEvent> {\n const eslintConfig = config as ESLintInstallerConfig;\n\n yield {\n type: \"start\",\n message: \"Installing ESLint plugin\",\n };\n\n for (const target of targets) {\n yield {\n type: \"progress\",\n message: `Configuring ESLint in ${target.label}`,\n detail: \"→ Adding uilint-eslint to dependencies\",\n };\n\n yield {\n type: \"progress\",\n message: `Injecting ${eslintConfig.configuredRules.length} rules`,\n detail: `→ ${target.hint}`,\n };\n }\n\n // Show progress for AI hooks\n const { aiHooks } = eslintConfig;\n if (aiHooks?.includes(\"claude\")) {\n yield {\n type: \"progress\",\n message: \"Installing Claude Code hook\",\n detail: \"→ .claude/hooks/post-edit.sh\",\n };\n }\n if (aiHooks?.includes(\"cursor\")) {\n yield {\n type: \"progress\",\n message: \"Installing Cursor hook\",\n detail: \"→ .cursor/hooks/post-edit.sh\",\n };\n }\n\n const hookSuffix = aiHooks?.length\n ? ` + ${aiHooks.length} AI hook(s)`\n : \"\";\n\n yield {\n type: \"complete\",\n message: `ESLint plugin installed in ${targets.length} package(s)${hookSuffix}`,\n };\n },\n\n planRemove(\n targets: InstallTarget[],\n project: ProjectState\n ): {\n actions: InstallAction[];\n } {\n const actions: InstallAction[] = [];\n\n for (const target of targets) {\n const pkgInfo = project.packages.find((p) => p.path === target.path);\n if (!pkgInfo || !pkgInfo.eslintConfigPath) continue;\n\n // Remove ESLint rules from config\n actions.push({\n type: \"remove_eslint\",\n packagePath: target.path,\n configPath: pkgInfo.eslintConfigPath,\n });\n\n // Remove .uilint/rules directory\n const rulesDir = join(target.path, \".uilint\", \"rules\");\n actions.push({\n type: \"remove_directory\",\n path: rulesDir,\n });\n }\n\n return { actions };\n },\n};\n","/**\n * AI Hooks utility - Post-tool-use ESLint hooks for Claude Code and Cursor\n *\n * Provides functions to generate installation actions for AI editor hooks\n * that automatically run ESLint when files are edited.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { InstallAction } from \"../types.js\";\n\nexport type AIHookProvider = \"claude\" | \"cursor\";\n\n/**\n * Bash script that runs ESLint on edited files and returns results\n * Works for both Claude and Cursor hooks\n */\nconst POST_EDIT_HOOK_SCRIPT = `#!/bin/bash\n# AI Editor Hook: Run ESLint on edited files\n# Triggered after file edits to provide lint feedback\n#\n# Output: JSON with lint errors for the AI to see\n\n# Read JSON input from stdin\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // .file_path // empty')\n\n# Exit if no file path\nif [[ -z \"$file_path\" ]]; then\n exit 0\nfi\n\n# Only lint TypeScript/JavaScript files\nif [[ \"$file_path\" =~ \\\\.(ts|tsx|js|jsx)$ ]]; then\n # Find the package directory (look for eslint.config.ts or package.json)\n dir=$(dirname \"$file_path\")\n while [[ \"$dir\" != \"/\" ]]; do\n if [[ -f \"$dir/eslint.config.ts\" ]] || [[ -f \"$dir/eslint.config.js\" ]] || [[ -f \"$dir/eslint.config.mjs\" ]]; then\n break\n fi\n dir=$(dirname \"$dir\")\n done\n\n # If no config found, exit\n if [[ \"$dir\" == \"/\" ]]; then\n exit 0\n fi\n\n # Run ESLint with --fix first (auto-fix what we can), suppress output\n (cd \"$dir\" && npx eslint \"$file_path\" --fix >/dev/null 2>&1) || true\n\n # Then report ALL remaining issues\n remaining=$( (cd \"$dir\" && npx eslint \"$file_path\" --format stylish 2>/dev/null) | grep -E \"^\\\\s+[0-9]+:[0-9]+\" | head -10)\n\n if [[ -n \"$remaining\" ]]; then\n # Output JSON so the AI sees the lint errors\n jq -n --arg issues \"$remaining\" '{\"additionalContext\": (\"ESLint errors - fix these:\\\\n\" + $issues)}'\n # Exit with error code to signal lint issues\n exit 1\n fi\nfi\n`;\n\n/**\n * Claude settings.json content for the PostToolUse hook\n */\nconst CLAUDE_HOOK_CONFIG = {\n hooks: {\n PostToolUse: [\n {\n matcher: \"Edit|Write\",\n hooks: [\n {\n type: \"command\",\n command: \"bash .claude/hooks/post-edit.sh\",\n },\n ],\n },\n ],\n },\n};\n\n/**\n * Cursor hooks.json content for the afterFileEdit hook\n */\nconst CURSOR_HOOK_CONFIG = {\n hooks: {\n afterFileEdit: [\n {\n command: \"bash .cursor/hooks/post-edit.sh\",\n filePattern: \"**/*.{ts,tsx,js,jsx}\",\n },\n ],\n },\n};\n\n/**\n * Check if a hook is already installed for the given provider\n */\nexport function isHookInstalled(projectPath: string, provider: AIHookProvider): boolean {\n if (provider === \"claude\") {\n const settingsPath = join(projectPath, \".claude\", \"settings.json\");\n if (!existsSync(settingsPath)) return false;\n\n try {\n const content = readFileSync(settingsPath, \"utf-8\");\n const settings = JSON.parse(content);\n const hooks = settings.hooks?.PostToolUse;\n if (!Array.isArray(hooks)) return false;\n\n return hooks.some(\n (h: { matcher?: string; hooks?: Array<{ command?: string }> }) =>\n h.matcher?.includes(\"Edit\") &&\n h.hooks?.some((hh) => hh.command?.includes(\"post-edit\"))\n );\n } catch {\n return false;\n }\n } else {\n const hooksPath = join(projectPath, \".cursor\", \"hooks.json\");\n if (!existsSync(hooksPath)) return false;\n\n try {\n const content = readFileSync(hooksPath, \"utf-8\");\n const hooks = JSON.parse(content);\n const afterFileEdit = hooks.hooks?.afterFileEdit;\n if (!Array.isArray(afterFileEdit)) return false;\n\n return afterFileEdit.some(\n (h: { command?: string }) => h.command?.includes(\"post-edit\")\n );\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Generate installation actions for Claude Code hook\n */\nexport function planClaudeHook(projectPath: string): InstallAction[] {\n const actions: InstallAction[] = [];\n const claudeDir = join(projectPath, \".claude\");\n const hooksDir = join(claudeDir, \"hooks\");\n const settingsPath = join(claudeDir, \"settings.json\");\n\n // Create .claude directory\n actions.push({\n type: \"create_directory\",\n path: claudeDir,\n });\n\n // Create hooks directory\n actions.push({\n type: \"create_directory\",\n path: hooksDir,\n });\n\n // Create post-edit.sh script (executable)\n actions.push({\n type: \"create_file\",\n path: join(hooksDir, \"post-edit.sh\"),\n content: POST_EDIT_HOOK_SCRIPT,\n permissions: 0o755,\n });\n\n // Create or merge settings.json\n if (existsSync(settingsPath)) {\n actions.push({\n type: \"merge_json\",\n path: settingsPath,\n merge: CLAUDE_HOOK_CONFIG,\n });\n } else {\n actions.push({\n type: \"create_file\",\n path: settingsPath,\n content: JSON.stringify(CLAUDE_HOOK_CONFIG, null, 2),\n });\n }\n\n return actions;\n}\n\n/**\n * Generate installation actions for Cursor hook\n */\nexport function planCursorHook(projectPath: string): InstallAction[] {\n const actions: InstallAction[] = [];\n const cursorDir = join(projectPath, \".cursor\");\n const hooksDir = join(cursorDir, \"hooks\");\n const hooksJsonPath = join(cursorDir, \"hooks.json\");\n\n // Create .cursor directory\n actions.push({\n type: \"create_directory\",\n path: cursorDir,\n });\n\n // Create hooks directory\n actions.push({\n type: \"create_directory\",\n path: hooksDir,\n });\n\n // Create post-edit.sh script (executable)\n actions.push({\n type: \"create_file\",\n path: join(hooksDir, \"post-edit.sh\"),\n content: POST_EDIT_HOOK_SCRIPT,\n permissions: 0o755,\n });\n\n // Create or merge hooks.json\n if (existsSync(hooksJsonPath)) {\n actions.push({\n type: \"merge_json\",\n path: hooksJsonPath,\n merge: CURSOR_HOOK_CONFIG,\n });\n } else {\n actions.push({\n type: \"create_file\",\n path: hooksJsonPath,\n content: JSON.stringify(CURSOR_HOOK_CONFIG, null, 2),\n });\n }\n\n return actions;\n}\n\n/**\n * Generate removal actions for Claude Code hook\n */\nexport function planRemoveClaudeHook(projectPath: string): InstallAction[] {\n const claudeDir = join(projectPath, \".claude\");\n return [\n {\n type: \"delete_file\",\n path: join(claudeDir, \"hooks\", \"post-edit.sh\"),\n },\n ];\n}\n\n/**\n * Generate removal actions for Cursor hook\n */\nexport function planRemoveCursorHook(projectPath: string): InstallAction[] {\n const cursorDir = join(projectPath, \".cursor\");\n return [\n {\n type: \"delete_file\",\n path: join(cursorDir, \"hooks\", \"post-edit.sh\"),\n },\n ];\n}\n","/**\n * Client Boundary Tracer\n *\n * Traces imports from a Next.js root layout to find all files with \"use client\" directive.\n * Used to help users choose where to inject the UILint devtools component.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { join, dirname, relative } from \"path\";\nimport { parseModule } from \"magicast\";\n\n/**\n * Information about a client boundary file\n */\nexport interface ClientBoundary {\n /** Absolute file path */\n filePath: string;\n /** Relative path for display (e.g., \"./providers.tsx\") */\n relativePath: string;\n /** Names of components/exports imported from this file */\n componentNames: string[];\n /** Import source as written in the layout (e.g., \"./providers\") */\n importSource: string;\n}\n\n/**\n * Result of tracing client boundaries from a layout file\n */\nexport interface TraceResult {\n /** Whether the root layout itself has \"use client\" directive */\n layoutIsClient: boolean;\n /** Client boundary files found in the layout's imports */\n clientBoundaries: ClientBoundary[];\n /** The root layout file path (absolute) */\n layoutFile: string;\n /** Relative path to layout from project root */\n layoutRelative: string;\n}\n\n/**\n * Check if a file has \"use client\" directive\n */\nfunction hasUseClientDirective(filePath: string): boolean {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const mod = parseModule(content);\n const program = mod.$ast;\n\n if (!program || program.type !== \"Program\") return false;\n\n // Check program.directives array (where babel/magicast puts \"use client\")\n const directives = (program as any).directives ?? [];\n for (const directive of directives) {\n if (\n directive?.type === \"Directive\" &&\n directive.value?.type === \"DirectiveLiteral\" &&\n directive.value.value === \"use client\"\n ) {\n return true;\n }\n }\n\n // Also check first statement as fallback (older parsing behavior)\n const firstStmt = (program as any).body?.[0];\n if (\n firstStmt?.type === \"ExpressionStatement\" &&\n (firstStmt.expression?.type === \"StringLiteral\" ||\n firstStmt.expression?.type === \"Literal\") &&\n firstStmt.expression.value === \"use client\"\n ) {\n return true;\n }\n\n return false;\n } catch {\n return false;\n }\n}\n\n/**\n * Extract imports from a parsed module\n */\nfunction extractImports(\n program: any\n): Array<{ source: string; specifiers: string[] }> {\n const imports: Array<{ source: string; specifiers: string[] }> = [];\n\n if (!program || program.type !== \"Program\") return imports;\n\n for (const stmt of (program as any).body ?? []) {\n if (stmt?.type !== \"ImportDeclaration\") continue;\n\n const source = stmt.source?.value;\n if (typeof source !== \"string\") continue;\n\n // Skip non-relative imports (node_modules, etc.)\n // We only trace local imports for client boundaries\n if (!source.startsWith(\".\") && !source.startsWith(\"@/\") && !source.startsWith(\"~/\")) {\n continue;\n }\n\n const specifiers: string[] = [];\n for (const spec of stmt.specifiers ?? []) {\n if (spec.type === \"ImportDefaultSpecifier\") {\n specifiers.push(\"default\");\n } else if (spec.type === \"ImportSpecifier\") {\n const name = spec.imported?.name ?? spec.imported?.value;\n if (name) specifiers.push(name);\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n specifiers.push(\"*\");\n }\n }\n\n imports.push({ source, specifiers });\n }\n\n return imports;\n}\n\n/**\n * Try to resolve an import source to an absolute file path\n */\nfunction resolveImportPath(\n importSource: string,\n fromFile: string,\n projectPath: string\n): string | null {\n const fromDir = dirname(fromFile);\n\n // Handle path aliases\n let basePath: string;\n if (importSource.startsWith(\"@/\")) {\n // Common Next.js alias - @/ -> project root or src/\n const withoutAlias = importSource.slice(2);\n // Try src/ first, then project root\n const srcPath = join(projectPath, \"src\", withoutAlias);\n const rootPath = join(projectPath, withoutAlias);\n basePath = existsSync(dirname(srcPath)) ? srcPath : rootPath;\n } else if (importSource.startsWith(\"~/\")) {\n // Another common alias\n basePath = join(projectPath, importSource.slice(2));\n } else if (importSource.startsWith(\".\")) {\n // Relative import\n basePath = join(fromDir, importSource);\n } else {\n // Likely a node_modules import, skip\n return null;\n }\n\n // Try different extensions\n const extensions = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\n // Try exact path with extensions\n for (const ext of extensions) {\n const fullPath = basePath + ext;\n if (existsSync(fullPath)) return fullPath;\n }\n\n // Try as directory with index file\n for (const ext of extensions) {\n const indexPath = join(basePath, `index${ext}`);\n if (existsSync(indexPath)) return indexPath;\n }\n\n // Try exact path (might already have extension)\n if (existsSync(basePath)) return basePath;\n\n return null;\n}\n\n/**\n * Find the root layout file in a Next.js App Router project\n */\nfunction findLayoutFile(projectPath: string, appRoot: string): string | null {\n const extensions = [\".tsx\", \".jsx\", \".ts\", \".js\"];\n\n for (const ext of extensions) {\n const layoutPath = join(projectPath, appRoot, `layout${ext}`);\n if (existsSync(layoutPath)) return layoutPath;\n }\n\n return null;\n}\n\n/**\n * Trace imports from a Next.js root layout to find client boundaries\n */\nexport function traceClientBoundaries(\n projectPath: string,\n appRoot: string\n): TraceResult | null {\n const layoutFile = findLayoutFile(projectPath, appRoot);\n if (!layoutFile) {\n return null;\n }\n\n const layoutIsClient = hasUseClientDirective(layoutFile);\n const layoutRelative = relative(projectPath, layoutFile);\n\n // If layout is already a client component, no need to trace further\n if (layoutIsClient) {\n return {\n layoutIsClient: true,\n clientBoundaries: [],\n layoutFile,\n layoutRelative,\n };\n }\n\n // Parse the layout file\n let program: any;\n try {\n const content = readFileSync(layoutFile, \"utf-8\");\n const mod = parseModule(content);\n program = mod.$ast;\n } catch {\n return {\n layoutIsClient: false,\n clientBoundaries: [],\n layoutFile,\n layoutRelative,\n };\n }\n\n // Extract and trace imports\n const imports = extractImports(program);\n const clientBoundaries: ClientBoundary[] = [];\n\n for (const imp of imports) {\n const resolvedPath = resolveImportPath(imp.source, layoutFile, projectPath);\n if (!resolvedPath) continue;\n\n if (hasUseClientDirective(resolvedPath)) {\n clientBoundaries.push({\n filePath: resolvedPath,\n relativePath: relative(projectPath, resolvedPath),\n componentNames: imp.specifiers,\n importSource: imp.source,\n });\n }\n }\n\n return {\n layoutIsClient: false,\n clientBoundaries,\n layoutFile,\n layoutRelative,\n };\n}\n\n/**\n * Check if a providers file already exists in the app root\n */\nexport function providersFileExists(\n projectPath: string,\n appRoot: string\n): string | null {\n const extensions = [\".tsx\", \".jsx\", \".ts\", \".js\"];\n const names = [\"providers\", \"Providers\"];\n\n for (const name of names) {\n for (const ext of extensions) {\n const providersPath = join(projectPath, appRoot, `${name}${ext}`);\n if (existsSync(providersPath)) return providersPath;\n }\n }\n\n return null;\n}\n","/**\n * Next.js overlay installer - UI devtools for Next.js App Router apps\n *\n * Smart client boundary detection:\n * - Traces imports from root layout to find \"use client\" files\n * - Lets user choose which client component to inject into\n * - Can create a new providers.tsx if no client boundaries found\n */\n\nimport type {\n Installer,\n InstallTarget,\n InstallerConfig,\n ProgressEvent,\n} from \"./types.js\";\nimport type {\n ProjectState,\n InstallAction,\n DependencyInstall,\n} from \"../types.js\";\nimport { toInstallSpecifier } from \"../versioning.js\";\nimport {\n traceClientBoundaries,\n providersFileExists,\n type TraceResult,\n} from \"../../../utils/client-boundary-tracer.js\";\n\n/**\n * Represents an injection point option within a Next.js app\n */\nexport interface InjectionPoint {\n /** Unique ID */\n id: string;\n /** Display label (e.g., \"providers.tsx\") */\n label: string;\n /** Hint text (e.g., \"Recommended\", \"existing\") */\n hint?: string;\n /** Absolute path to the file */\n filePath?: string;\n /** Whether to create a new providers.tsx */\n createProviders?: boolean;\n /** Whether this is the recommended option */\n recommended?: boolean;\n}\n\n/**\n * Configuration returned by the configure() step\n */\ninterface NextOverlayConfig extends InstallerConfig {\n /** Traced client boundaries for the target */\n traceResult?: TraceResult;\n /** Selected target file (absolute path) */\n selectedTargetFile?: string;\n /** Whether to create a new providers.tsx */\n createProviders?: boolean;\n}\n\n/**\n * Get injection points for a specific Next.js app\n * This is called after the user selects a Next.js app to configure\n */\nexport function getInjectionPoints(\n projectPath: string,\n appRoot: string\n): InjectionPoint[] {\n const points: InjectionPoint[] = [];\n\n const traceResult = traceClientBoundaries(projectPath, appRoot);\n\n if (!traceResult) {\n // No layout found - offer to create providers\n points.push({\n id: \"create-providers\",\n label: \"Create providers.tsx\",\n hint: \"Recommended\",\n createProviders: true,\n recommended: true,\n });\n return points;\n }\n\n if (traceResult.layoutIsClient) {\n // Layout is already a client component - single option\n points.push({\n id: \"layout\",\n label: \"Root layout\",\n hint: \"Already a client component\",\n filePath: traceResult.layoutFile,\n recommended: true,\n });\n return points;\n }\n\n // Layout is a server component - offer client boundary choices\n const existingProviders = providersFileExists(projectPath, appRoot);\n\n // First option: create new providers.tsx (recommended if none exists)\n if (!existingProviders) {\n points.push({\n id: \"create-providers\",\n label: \"Create providers.tsx\",\n hint: \"Recommended\",\n createProviders: true,\n recommended: true,\n });\n }\n\n // Add existing client boundaries as options\n for (const boundary of traceResult.clientBoundaries) {\n const componentNames =\n boundary.componentNames.length > 0\n ? boundary.componentNames.join(\", \")\n : \"default\";\n\n points.push({\n id: boundary.relativePath,\n label: boundary.relativePath,\n hint: componentNames,\n filePath: boundary.filePath,\n // Mark existing providers as recommended if it exists\n recommended: existingProviders === boundary.filePath,\n });\n }\n\n // If existing providers file found and not in boundaries, add it\n if (existingProviders) {\n const relativePath = existingProviders\n .replace(projectPath + \"/\", \"\")\n .replace(projectPath, \"\");\n\n const alreadyListed = traceResult.clientBoundaries.some(\n (b) => b.filePath === existingProviders\n );\n\n if (!alreadyListed) {\n points.push({\n id: \"existing-providers\",\n label: relativePath,\n hint: \"Existing providers\",\n filePath: existingProviders,\n recommended: true,\n });\n }\n }\n\n // Fallback: if no options, offer to create providers\n if (points.length === 0) {\n points.push({\n id: \"create-providers\",\n label: \"Create providers.tsx\",\n hint: \"Recommended\",\n createProviders: true,\n recommended: true,\n });\n }\n\n return points;\n}\n\nexport const nextOverlayInstaller: Installer = {\n id: \"next\",\n name: \"Next.js overlay\",\n description: \"Alt+Click UI inspector for Next.js App Router\",\n icon: \"🔷\",\n\n isApplicable(project: ProjectState): boolean {\n return project.nextApps.length > 0;\n },\n\n getTargets(project: ProjectState): InstallTarget[] {\n // Return a single target per Next.js app\n // Injection point selection happens in a follow-up step\n return project.nextApps.map((app) => ({\n id: `next-${app.projectPath}`,\n label: app.projectPath.split(\"/\").pop() || app.projectPath,\n path: app.projectPath,\n hint: \"App Router\",\n isInstalled: app.hasUilintOverlay,\n }));\n },\n\n plan(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): {\n actions: InstallAction[];\n dependencies: DependencyInstall[];\n } {\n const actions: InstallAction[] = [];\n const dependencies: DependencyInstall[] = [];\n\n // Only install for the first selected target\n if (targets.length === 0) return { actions, dependencies };\n\n const target = targets[0]!;\n const appInfo = project.nextApps.find(\n (app) => app.projectPath === target.path\n );\n if (!appInfo) return { actions, dependencies };\n\n const { projectPath, detection } = appInfo;\n\n // Get injection point from config (selected in follow-up UI)\n const nextConfig = config as NextOverlayConfig;\n const targetFile = nextConfig.selectedTargetFile;\n const createProviders = nextConfig.createProviders;\n\n // Install Next.js routes\n actions.push({\n type: \"install_next_routes\",\n projectPath,\n appRoot: detection.appRoot,\n });\n\n // Install React overlay dependencies\n dependencies.push({\n packagePath: projectPath,\n packageManager: project.packageManager,\n packages: [\n toInstallSpecifier(\"uilint-react\", {\n preferWorkspaceProtocol: project.packageManager === \"pnpm\",\n workspaceRoot: project.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n toInstallSpecifier(\"uilint-core\", {\n preferWorkspaceProtocol: project.packageManager === \"pnpm\",\n workspaceRoot: project.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n \"jsx-loc-plugin\",\n ],\n });\n\n // Inject <uilint-devtools /> web component into React\n // Use the selected injection point from config\n actions.push({\n type: \"inject_react\",\n projectPath,\n appRoot: detection.appRoot,\n mode: \"next\",\n targetFile,\n createProviders,\n });\n\n // Inject jsx-loc-plugin into next.config\n actions.push({\n type: \"inject_next_config\",\n projectPath,\n });\n\n return { actions, dependencies };\n },\n\n async *execute(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): AsyncGenerator<ProgressEvent> {\n if (targets.length === 0) return;\n\n const target = targets[0]!;\n const nextConfig = config as NextOverlayConfig;\n\n yield {\n type: \"start\",\n message: \"Installing Next.js overlay\",\n };\n\n yield {\n type: \"progress\",\n message: `Installing in ${target.label}`,\n detail: \"→ Adding API routes\",\n };\n\n yield {\n type: \"progress\",\n message: \"Installing dependencies\",\n detail: \"→ uilint-react, uilint-core, jsx-loc-plugin\",\n };\n\n const injectDetail = nextConfig.createProviders\n ? \"→ Creating providers.tsx\"\n : nextConfig.selectedTargetFile\n ? `→ ${\n nextConfig.selectedTargetFile.split(\"/\").pop() || \"client component\"\n }`\n : \"→ <uilint-devtools /> in root layout\";\n\n yield {\n type: \"progress\",\n message: \"Injecting devtools component\",\n detail: injectDetail,\n };\n\n yield {\n type: \"progress\",\n message: \"Configuring jsx-loc-plugin\",\n detail: \"→ next.config.js\",\n };\n\n yield {\n type: \"complete\",\n message: \"Next.js overlay installed\",\n };\n },\n\n planRemove(\n targets: InstallTarget[],\n project: ProjectState\n ): {\n actions: InstallAction[];\n } {\n const actions: InstallAction[] = [];\n\n if (targets.length === 0) return { actions };\n\n const target = targets[0]!;\n const appInfo = project.nextApps.find(\n (app) => app.projectPath === target.path\n );\n if (!appInfo) return { actions };\n\n const { projectPath, detection } = appInfo;\n\n // Remove React overlay injection\n actions.push({\n type: \"remove_react\",\n projectPath,\n appRoot: detection.appRoot,\n mode: \"next\",\n });\n\n // Remove jsx-loc-plugin from next.config\n actions.push({\n type: \"remove_next_config\",\n projectPath,\n });\n\n // Remove Next.js API routes\n actions.push({\n type: \"remove_next_routes\",\n projectPath,\n appRoot: detection.appRoot,\n });\n\n return { actions };\n },\n};\n","/**\n * Vite overlay installer - UI devtools for Vite + React apps\n */\n\nimport type {\n Installer,\n InstallTarget,\n InstallerConfig,\n ProgressEvent,\n} from \"./types.js\";\nimport type {\n ProjectState,\n InstallAction,\n DependencyInstall,\n} from \"../types.js\";\nimport { toInstallSpecifier } from \"../versioning.js\";\n\nexport const viteOverlayInstaller: Installer = {\n id: \"vite\",\n name: \"Vite overlay\",\n description: \"Alt+Click UI inspector for Vite + React apps\",\n icon: \"⚡\",\n\n isApplicable(project: ProjectState): boolean {\n return project.viteApps.length > 0;\n },\n\n getTargets(project: ProjectState): InstallTarget[] {\n return project.viteApps.map((app) => ({\n id: `vite-${app.projectPath}`,\n label: app.projectPath.split(\"/\").pop() || app.projectPath,\n path: app.projectPath,\n hint: \"React + Vite\",\n isInstalled: app.hasUilintOverlay,\n }));\n },\n\n plan(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): {\n actions: InstallAction[];\n dependencies: DependencyInstall[];\n } {\n const actions: InstallAction[] = [];\n const dependencies: DependencyInstall[] = [];\n\n // Only install for the first selected target\n if (targets.length === 0) return { actions, dependencies };\n\n const target = targets[0];\n const appInfo = project.viteApps.find(\n (app) => app.projectPath === target.path\n );\n if (!appInfo) return { actions, dependencies };\n\n const { projectPath, detection } = appInfo;\n\n // Install React overlay dependencies\n dependencies.push({\n packagePath: projectPath,\n packageManager: project.packageManager,\n packages: [\n toInstallSpecifier(\"uilint-react\", {\n preferWorkspaceProtocol: project.packageManager === \"pnpm\",\n workspaceRoot: project.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n toInstallSpecifier(\"uilint-core\", {\n preferWorkspaceProtocol: project.packageManager === \"pnpm\",\n workspaceRoot: project.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n \"jsx-loc-plugin\",\n ],\n });\n\n // Inject <uilint-devtools /> web component into React entry\n actions.push({\n type: \"inject_react\",\n projectPath,\n appRoot: detection.entryRoot,\n mode: \"vite\",\n });\n\n // Inject jsx-loc-plugin into vite.config\n actions.push({\n type: \"inject_vite_config\",\n projectPath,\n });\n\n return { actions, dependencies };\n },\n\n async *execute(\n targets: InstallTarget[],\n config: InstallerConfig,\n project: ProjectState\n ): AsyncGenerator<ProgressEvent> {\n if (targets.length === 0) return;\n\n const target = targets[0];\n\n yield {\n type: \"start\",\n message: \"Installing Vite overlay\",\n };\n\n yield {\n type: \"progress\",\n message: `Installing in ${target.label}`,\n detail: \"→ Adding dependencies\",\n };\n\n yield {\n type: \"progress\",\n message: \"Installing dependencies\",\n detail: \"→ uilint-react, uilint-core, jsx-loc-plugin\",\n };\n\n yield {\n type: \"progress\",\n message: \"Injecting devtools component\",\n detail: \"→ <uilint-devtools /> in entry file\",\n };\n\n yield {\n type: \"progress\",\n message: \"Configuring jsx-loc-plugin\",\n detail: \"→ vite.config.ts\",\n };\n\n yield {\n type: \"complete\",\n message: \"Vite overlay installed\",\n };\n },\n\n planRemove(\n targets: InstallTarget[],\n project: ProjectState\n ): {\n actions: InstallAction[];\n } {\n const actions: InstallAction[] = [];\n\n if (targets.length === 0) return { actions };\n\n const target = targets[0]!;\n const appInfo = project.viteApps.find(\n (app) => app.projectPath === target.path\n );\n if (!appInfo) return { actions };\n\n const { projectPath, detection } = appInfo;\n\n // Remove React overlay injection\n actions.push({\n type: \"remove_react\",\n projectPath,\n appRoot: detection.entryRoot,\n mode: \"vite\",\n });\n\n // Remove jsx-loc-plugin from vite.config\n actions.push({\n type: \"remove_vite_config\",\n projectPath,\n });\n\n return { actions };\n },\n};\n","/**\n * Installer registry - auto-registration of all installers\n */\n\nimport { registerInstaller } from \"./registry.js\";\nimport { genstyleguideInstaller } from \"./genstyleguide.js\";\nimport { skillInstaller } from \"./skill.js\";\nimport { eslintInstaller } from \"./eslint.js\";\nimport { nextOverlayInstaller } from \"./next-overlay.js\";\nimport { viteOverlayInstaller } from \"./vite-overlay.js\";\n\n// Export types\nexport * from \"./types.js\";\nexport * from \"./registry.js\";\n\n// Export individual installers\nexport { genstyleguideInstaller } from \"./genstyleguide.js\";\nexport { skillInstaller } from \"./skill.js\";\nexport { eslintInstaller } from \"./eslint.js\";\nexport { nextOverlayInstaller } from \"./next-overlay.js\";\nexport { viteOverlayInstaller } from \"./vite-overlay.js\";\n\n// Export AI hooks utilities\nexport * from \"./ai-hooks.js\";\n\n// Auto-register all installers\nregisterInstaller(genstyleguideInstaller);\nregisterInstaller(skillInstaller);\nregisterInstaller(eslintInstaller);\nregisterInstaller(nextOverlayInstaller);\nregisterInstaller(viteOverlayInstaller);\n","/**\n * Simple Spinner component using core ink\n */\n\nimport React, { useState, useEffect } from \"react\";\nimport { Text } from \"ink\";\n\nconst frames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\nexport function Spinner(): React.ReactElement {\n const [frame, setFrame] = useState(0);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame((prevFrame) => (prevFrame + 1) % frames.length);\n }, 80);\n\n return () => {\n clearInterval(timer);\n };\n }, []);\n\n return <Text color=\"cyan\">{frames[frame]}</Text>;\n}\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuJ5B,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["existsSync","readFileSync","join","relative","existsSync","readdirSync","readFileSync","join","DEFAULT_IGNORE_DIRS","readFileSync","join","existsSync","relative","hasEslintConfig","existsSync","writeFileSync","readFileSync","dirname","join","existsSync","readFileSync","join","relative","absTarget","original","mod","program","hasDevtoolsImport","hasOldImport","alreadyConfigured","changed","importRes","addRes","updated","modified","existsSync","readFileSync","writeFileSync","join","parseModule","generateCode","parseModule","readFileSync","generateCode","writeFileSync","existsSync","readFileSync","writeFileSync","join","parseModule","generateCode","CONFIG_EXTENSIONS","findViteConfigFile","isIdentifier","isStringLiteral","jsxLocCall","existsSync","join","existsSync","join","dirname","join","existsSync","dirname","findWorkspaceRoot","existsSync","readFileSync","writeFileSync","join","existsSync","dirname","writeFileSync","readFileSync","join","findWorkspaceRoot","installDependencies","join","join","existsSync","join","join","existsSync","join","existsSync","readFileSync","join","join","existsSync","readFileSync","join","dirname","relative","parseModule","findLayoutFile"]}
|