uilint 0.2.161 → 0.2.162
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-WB2QAJRH.js → chunk-FWQ62IQ6.js} +6 -1
- package/dist/chunk-FWQ62IQ6.js.map +1 -0
- package/dist/{chunk-UDLE6YHE.js → chunk-RIPGIYIO.js} +7 -1
- package/dist/{chunk-UDLE6YHE.js.map → chunk-RIPGIYIO.js.map} +1 -1
- package/dist/index.js +61 -215
- package/dist/index.js.map +1 -1
- package/dist/{init-ui-PEDBEN4B.js → init-ui-NWRVGEEM.js} +4 -4
- package/dist/{plan-4E2RJB64.js → plan-IXDQPKDA.js} +2 -2
- package/dist/{remove-ui-PXLUKW73.js → remove-ui-7MULR7IB.js} +2 -2
- package/dist/{upgrade-QKD7JRI7.js → upgrade-ALSJMTTW.js} +5 -1
- package/dist/upgrade-ALSJMTTW.js.map +1 -0
- package/package.json +9 -9
- package/dist/chunk-WB2QAJRH.js.map +0 -1
- package/dist/upgrade-QKD7JRI7.js.map +0 -1
- /package/dist/{init-ui-PEDBEN4B.js.map → init-ui-NWRVGEEM.js.map} +0 -0
- /package/dist/{plan-4E2RJB64.js.map → plan-IXDQPKDA.js.map} +0 -0
- /package/dist/{remove-ui-PXLUKW73.js.map → remove-ui-7MULR7IB.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getAllInstallers,
|
|
7
7
|
getInjectionPoints,
|
|
8
8
|
registerInstaller
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RIPGIYIO.js";
|
|
10
10
|
import {
|
|
11
11
|
detectCoverageSetup
|
|
12
12
|
} from "./chunk-7GQXW4CT.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./chunk-CZNPG4UI.js";
|
|
21
21
|
import {
|
|
22
22
|
createPlan
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-FWQ62IQ6.js";
|
|
24
24
|
import {
|
|
25
25
|
toInstallSpecifier
|
|
26
26
|
} from "./chunk-JWSZKDZY.js";
|
|
@@ -1936,7 +1936,7 @@ async function initUI(options = {}, executeOptions = {}) {
|
|
|
1936
1936
|
console.log("\nNo changes selected");
|
|
1937
1937
|
process.exit(0);
|
|
1938
1938
|
}
|
|
1939
|
-
const { createPlan: createPlan2 } = await import("./plan-
|
|
1939
|
+
const { createPlan: createPlan2 } = await import("./plan-IXDQPKDA.js");
|
|
1940
1940
|
const plan = createPlan2(project, choices, { force: options.force });
|
|
1941
1941
|
for (const sel of pluginSelections) {
|
|
1942
1942
|
const pluginPlan = sel.installer.plan(sel.targets, {}, project);
|
|
@@ -1993,4 +1993,4 @@ ${pc.blue("Running tests with coverage...")}`);
|
|
|
1993
1993
|
export {
|
|
1994
1994
|
initUI
|
|
1995
1995
|
};
|
|
1996
|
-
//# sourceMappingURL=init-ui-
|
|
1996
|
+
//# sourceMappingURL=init-ui-NWRVGEEM.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createPlan,
|
|
4
4
|
getMissingRules
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FWQ62IQ6.js";
|
|
6
6
|
import "./chunk-JWSZKDZY.js";
|
|
7
7
|
import "./chunk-EBGFEMCH.js";
|
|
8
8
|
import "./chunk-EKZZVYPF.js";
|
|
@@ -10,4 +10,4 @@ export {
|
|
|
10
10
|
createPlan,
|
|
11
11
|
getMissingRules
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=plan-
|
|
13
|
+
//# sourceMappingURL=plan-IXDQPKDA.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
analyze,
|
|
5
5
|
execute,
|
|
6
6
|
getAllInstallers
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RIPGIYIO.js";
|
|
8
8
|
import "./chunk-7GQXW4CT.js";
|
|
9
9
|
import "./chunk-ZDSDZNIB.js";
|
|
10
10
|
import {
|
|
@@ -599,4 +599,4 @@ async function removeUI(options = {}) {
|
|
|
599
599
|
export {
|
|
600
600
|
removeUI
|
|
601
601
|
};
|
|
602
|
-
//# sourceMappingURL=remove-ui-
|
|
602
|
+
//# sourceMappingURL=remove-ui-7MULR7IB.js.map
|
|
@@ -364,6 +364,10 @@ function executeCopyRuleFiles(action, dryRun) {
|
|
|
364
364
|
if (!existsSync(rulesDir)) {
|
|
365
365
|
mkdirSync(rulesDir, { recursive: true });
|
|
366
366
|
}
|
|
367
|
+
const uilintPkgPath = join(action.packagePath, ".uilint", "package.json");
|
|
368
|
+
if (!existsSync(uilintPkgPath)) {
|
|
369
|
+
writeFileSync(uilintPkgPath, '{ "type": "module" }\n', "utf-8");
|
|
370
|
+
}
|
|
367
371
|
const [ruleFile] = loadSelectedRules([action.ruleId], {
|
|
368
372
|
typescript: true
|
|
369
373
|
});
|
|
@@ -590,4 +594,4 @@ async function upgrade(options) {
|
|
|
590
594
|
export {
|
|
591
595
|
upgrade
|
|
592
596
|
};
|
|
593
|
-
//# sourceMappingURL=upgrade-
|
|
597
|
+
//# sourceMappingURL=upgrade-ALSJMTTW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/update/analyze.ts","../src/utils/migration-engine.ts","../src/commands/update/plan.ts","../src/commands/update/execute.ts","../src/commands/upgrade.ts"],"sourcesContent":["/**\n * Analyze phase for the update command\n *\n * Compares installed rule versions against available versions\n * and identifies what can be updated.\n */\n\nimport { basename } from \"path\";\nimport { getRuleMetadata } from \"uilint-eslint\";\nimport {\n detectPackageManager,\n getInstalledUilintPackages,\n} from \"../../utils/package-manager.js\";\nimport { findWorkspaceRoot } from \"uilint-core/node\";\nimport { getInstalledRuleVersions } from \"../../utils/manifest.js\";\nimport {\n findMigrationPath,\n getMigrationsForRule,\n hasBreakingMigrations,\n} from \"../../utils/migration-engine.js\";\nimport type {\n UpdateAnalysis,\n PackageUpdateInfo,\n RuleUpdateInfo,\n InstalledPackageInfo,\n} from \"./types.js\";\n\n/**\n * Compare two semver versions\n * Returns true if available > installed\n */\nfunction isNewerVersion(installed: string, available: string): boolean {\n const installedParts = installed.split(\".\").map(Number);\n const availableParts = available.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const a = availableParts[i] ?? 0;\n const b = installedParts[i] ?? 0;\n if (a > b) return true;\n if (a < b) return false;\n }\n\n return false;\n}\n\n/**\n * Analyze a single rule for updates\n */\nfunction analyzeRule(\n ruleId: string,\n installedVersion: string\n): RuleUpdateInfo | null {\n const ruleMeta = getRuleMetadata(ruleId);\n if (!ruleMeta) {\n // Rule no longer exists in registry\n return null;\n }\n\n const availableVersion = ruleMeta.version ?? \"1.0.0\";\n const hasUpdate = isNewerVersion(installedVersion, availableVersion);\n\n // Find migration path if update is available\n const migrations = hasUpdate\n ? findMigrationPath(\n installedVersion,\n availableVersion,\n getMigrationsForRule(ruleId)\n )\n : [];\n\n return {\n ruleId,\n installedVersion,\n availableVersion,\n hasUpdate,\n migrations,\n hasBreakingChanges: hasBreakingMigrations(migrations),\n };\n}\n\n/**\n * Analyze a package for rule updates\n */\nfunction analyzePackage(packagePath: string): PackageUpdateInfo {\n const installedVersions = getInstalledRuleVersions(packagePath);\n const rules: RuleUpdateInfo[] = [];\n\n // Check each installed rule\n for (const [ruleId, version] of Object.entries(installedVersions)) {\n const ruleInfo = analyzeRule(ruleId, version);\n if (ruleInfo) {\n rules.push(ruleInfo);\n }\n }\n\n const updatableRules = rules.filter((r) => r.hasUpdate);\n\n // Get installed uilint npm packages\n const installedPackagesMap = getInstalledUilintPackages(packagePath);\n const installedPackages: InstalledPackageInfo[] = [];\n for (const [name, version] of installedPackagesMap) {\n installedPackages.push({ name, installedVersion: version });\n }\n\n return {\n packagePath,\n displayName: basename(packagePath) || packagePath,\n eslintConfigPath: null, // TODO: detect ESLint config\n packageManager: detectPackageManager(packagePath),\n installedPackages,\n rules,\n updatableCount: updatableRules.length,\n hasBreakingChanges: updatableRules.some((r) => r.hasBreakingChanges),\n };\n}\n\n/**\n * Analyze a project for available rule updates\n *\n * @param projectPath - Path to the project (or package in a monorepo)\n * @returns Analysis of available updates\n */\nexport function analyzeForUpdates(projectPath: string): UpdateAnalysis {\n const workspaceRoot = findWorkspaceRoot(projectPath);\n const packageManager = detectPackageManager(projectPath);\n\n // For now, just analyze the single project path\n // TODO: In monorepo, scan all packages with manifests\n const packageInfo = analyzePackage(projectPath);\n const packages = [packageInfo];\n\n const totalUpdates = packages.reduce((sum, p) => sum + p.updatableCount, 0);\n const hasBreakingChanges = packages.some((p) => p.hasBreakingChanges);\n\n return {\n workspaceRoot,\n packageManager,\n packages,\n totalUpdates,\n hasBreakingChanges,\n };\n}\n\n/**\n * Get a summary of available updates for display\n */\nexport function formatUpdateSummary(analysis: UpdateAnalysis): string {\n const hasRuleUpdates = analysis.totalUpdates > 0;\n const hasPackages = analysis.packages.some(\n (p) => p.installedPackages.length > 0\n );\n\n if (!hasRuleUpdates && !hasPackages) {\n return \"No uilint packages or rules found.\";\n }\n\n const lines: string[] = [];\n\n for (const pkg of analysis.packages) {\n const hasUpdates =\n pkg.updatableCount > 0 || pkg.installedPackages.length > 0;\n if (!hasUpdates) continue;\n\n lines.push(`${pkg.displayName}:`);\n\n // Show installed npm packages\n if (pkg.installedPackages.length > 0) {\n lines.push(\" npm packages:\");\n for (const npmPkg of pkg.installedPackages) {\n lines.push(` ${npmPkg.name}: ${npmPkg.installedVersion} → latest`);\n }\n }\n\n // Show rule updates\n if (pkg.updatableCount > 0) {\n lines.push(\" rules:\");\n for (const rule of pkg.rules) {\n if (!rule.hasUpdate) continue;\n\n const breaking = rule.hasBreakingChanges ? \" (BREAKING)\" : \"\";\n lines.push(\n ` ${rule.ruleId}: ${rule.installedVersion} → ${rule.availableVersion}${breaking}`\n );\n }\n }\n\n lines.push(\"\");\n }\n\n if (analysis.hasBreakingChanges) {\n lines.push(\"⚠️ Some rule updates contain breaking changes.\");\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Migration Engine\n *\n * Handles migrating rule options between versions using migration definitions.\n */\n\nimport { getRuleMetadata, type RuleMigration } from \"uilint-eslint\";\n\n/**\n * Find a path of migrations to get from one version to another.\n *\n * Uses BFS to find the shortest path through the migration graph.\n *\n * @param from - Starting version (installed version)\n * @param to - Target version (available version)\n * @param migrations - Available migrations for the rule\n * @returns Array of migrations to apply in order, or empty array if no path exists\n */\nexport function findMigrationPath(\n from: string,\n to: string,\n migrations: RuleMigration[]\n): RuleMigration[] {\n // No migration needed if versions are the same\n if (from === to) {\n return [];\n }\n\n // No migrations available\n if (migrations.length === 0) {\n return [];\n }\n\n // Build a map of version -> outgoing migrations\n const migrationMap = new Map<string, RuleMigration[]>();\n for (const migration of migrations) {\n const existing = migrationMap.get(migration.from) ?? [];\n existing.push(migration);\n migrationMap.set(migration.from, existing);\n }\n\n // BFS to find path\n const visited = new Set<string>();\n const queue: { version: string; path: RuleMigration[] }[] = [\n { version: from, path: [] },\n ];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current.version)) {\n continue;\n }\n visited.add(current.version);\n\n const outgoing = migrationMap.get(current.version) ?? [];\n for (const migration of outgoing) {\n const newPath = [...current.path, migration];\n\n // Found the target\n if (migration.to === to) {\n return newPath;\n }\n\n // Add to queue for further exploration\n if (!visited.has(migration.to)) {\n queue.push({ version: migration.to, path: newPath });\n }\n }\n }\n\n // No path found\n return [];\n}\n\n/**\n * Apply a sequence of migrations to transform options.\n *\n * @param options - The current rule options array\n * @param migrations - Migrations to apply in order\n * @returns Transformed options array\n */\nexport function applyMigrations(\n options: unknown[],\n migrations: RuleMigration[]\n): unknown[] {\n let current = options;\n\n for (const migration of migrations) {\n current = migration.migrate(current);\n }\n\n return current;\n}\n\n/**\n * Get migrations defined for a specific rule.\n *\n * @param ruleId - The rule ID to look up\n * @returns Array of migrations, or empty array if none defined\n */\nexport function getMigrationsForRule(ruleId: string): RuleMigration[] {\n const ruleMeta = getRuleMetadata(ruleId);\n if (!ruleMeta) {\n return [];\n }\n\n return ruleMeta.migrations ?? [];\n}\n\n/**\n * Check if there are any breaking migrations in a migration path.\n *\n * @param migrations - The migration path to check\n * @returns True if any migration is marked as breaking\n */\nexport function hasBreakingMigrations(migrations: RuleMigration[]): boolean {\n return migrations.some((m) => m.breaking === true);\n}\n\n/**\n * Get descriptions of all migrations in a path.\n *\n * @param migrations - The migration path\n * @returns Array of migration descriptions\n */\nexport function getMigrationDescriptions(migrations: RuleMigration[]): string[] {\n return migrations.map(\n (m) => `${m.from} → ${m.to}: ${m.description}${m.breaking ? \" (BREAKING)\" : \"\"}`\n );\n}\n","/**\n * Plan phase for the update command\n *\n * Creates a plan of actions to update rules based on analysis and user choices.\n */\n\nimport type {\n UpdateAnalysis,\n UpdatePlan,\n UpdateAction,\n UpdateChoices,\n RuleUpdateInfo,\n} from \"./types.js\";\n\n/**\n * Create an update plan based on analysis and user choices\n *\n * @param analysis - Result from the analyze phase\n * @param choices - User selections for what to update\n * @returns Plan of actions to execute\n */\nexport function createUpdatePlan(\n analysis: UpdateAnalysis,\n choices: UpdateChoices\n): UpdatePlan {\n const actions: UpdateAction[] = [];\n const rules: RuleUpdateInfo[] = [];\n\n for (const pkg of analysis.packages) {\n // Skip packages not selected\n if (!choices.packagePaths.includes(pkg.packagePath)) {\n continue;\n }\n\n // Action: Update npm packages (do this first)\n if (pkg.installedPackages.length > 0) {\n actions.push({\n type: \"update_npm_packages\",\n packagePath: pkg.packagePath,\n packageManager: pkg.packageManager,\n packages: pkg.installedPackages.map((p) => p.name),\n });\n }\n\n for (const rule of pkg.rules) {\n // Skip rules that don't have updates\n if (!rule.hasUpdate) {\n continue;\n }\n\n // Skip rules not in the specific rule filter (if set)\n if (choices.ruleIds.length > 0 && !choices.ruleIds.includes(rule.ruleId)) {\n continue;\n }\n\n // Track this rule for the plan\n rules.push(rule);\n\n // Action 1: Copy updated rule files\n actions.push({\n type: \"copy_rule_files\",\n packagePath: pkg.packagePath,\n ruleId: rule.ruleId,\n version: rule.availableVersion,\n });\n\n // Action 2: Migrate options in ESLint config (if migrations exist)\n if (rule.migrations.length > 0 && pkg.eslintConfigPath) {\n actions.push({\n type: \"migrate_rule_options\",\n configPath: pkg.eslintConfigPath,\n ruleId: rule.ruleId,\n migrations: rule.migrations,\n });\n }\n\n // Action 3: Update manifest with new version\n actions.push({\n type: \"update_manifest_version\",\n packagePath: pkg.packagePath,\n ruleId: rule.ruleId,\n version: rule.availableVersion,\n });\n }\n }\n\n return { actions, rules };\n}\n\n/**\n * Get a summary of what the plan will do\n */\nexport function formatPlanSummary(plan: UpdatePlan): string {\n if (plan.actions.length === 0) {\n return \"No updates to apply.\";\n }\n\n const lines: string[] = [];\n lines.push(`Update plan (${plan.rules.length} rule(s)):\\n`);\n\n for (const rule of plan.rules) {\n const breaking = rule.hasBreakingChanges ? \" ⚠️ BREAKING\" : \"\";\n lines.push(\n ` ${rule.ruleId}: ${rule.installedVersion} → ${rule.availableVersion}${breaking}`\n );\n\n // Show migration descriptions\n if (rule.migrations.length > 0) {\n for (const migration of rule.migrations) {\n lines.push(` - ${migration.description}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Check if the plan has any breaking changes that require confirmation\n */\nexport function planHasBreakingChanges(plan: UpdatePlan): boolean {\n return plan.rules.some((r) => r.hasBreakingChanges);\n}\n\n/**\n * Filter plan to only include specific rules\n */\nexport function filterPlanByRules(\n plan: UpdatePlan,\n ruleIds: string[]\n): UpdatePlan {\n if (ruleIds.length === 0) {\n return plan;\n }\n\n const ruleIdSet = new Set(ruleIds);\n const filteredRules = plan.rules.filter((r) => ruleIdSet.has(r.ruleId));\n const filteredActions = plan.actions.filter((a) => {\n if (\"ruleId\" in a) {\n return ruleIdSet.has(a.ruleId);\n }\n return true;\n });\n\n return {\n actions: filteredActions,\n rules: filteredRules,\n };\n}\n","/**\n * Execute phase for the update command\n *\n * Performs the actual file operations to update rules.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadSelectedRules } from \"../../utils/rule-loader.js\";\nimport { updateManifestRule } from \"../../utils/manifest.js\";\nimport { updatePackages } from \"../../utils/package-manager.js\";\nimport type {\n UpdatePlan,\n UpdateAction,\n UpdateResult,\n UpdateActionResult,\n UpdateSummary,\n CopyRuleFilesAction,\n MigrateRuleOptionsAction,\n UpdateManifestVersionAction,\n UpdateNpmPackagesAction,\n} from \"./types.js\";\n\nexport interface ExecuteUpdateOptions {\n dryRun?: boolean;\n}\n\n/**\n * Execute an update plan\n *\n * @param plan - The plan to execute\n * @param options - Execution options\n * @returns Result of the execution\n */\nexport async function executeUpdatePlan(\n plan: UpdatePlan,\n options: ExecuteUpdateOptions = {}\n): Promise<UpdateResult> {\n const { dryRun = false } = options;\n const results: UpdateActionResult[] = [];\n const filesModified: string[] = [];\n\n for (const action of plan.actions) {\n const result = await executeAction(action, { dryRun });\n results.push(result);\n\n if (result.success && !dryRun) {\n // Track modified files\n if (action.type === \"copy_rule_files\") {\n filesModified.push(\n join(action.packagePath, \".uilint\", \"rules\", action.ruleId)\n );\n } else if (action.type === \"migrate_rule_options\") {\n filesModified.push(action.configPath);\n } else if (action.type === \"update_manifest_version\") {\n filesModified.push(\n join(action.packagePath, \".uilint\", \"rules\", \"manifest.json\")\n );\n }\n }\n }\n\n const success = results.every((r) => r.success);\n const rulesUpdated = new Set(plan.rules.map((r) => r.ruleId)).size;\n const packagesUpdated = new Set(\n plan.actions\n .filter((a) => \"packagePath\" in a)\n .map((a) => (a as { packagePath: string }).packagePath)\n ).size;\n\n const summary: UpdateSummary = {\n rulesUpdated,\n packagesUpdated,\n filesModified: [...new Set(filesModified)],\n breakingChanges: plan.rules\n .filter((r) => r.hasBreakingChanges)\n .map((r) => r.ruleId),\n };\n\n return {\n success,\n actionsPerformed: results,\n summary,\n };\n}\n\n/**\n * Execute a single update action\n */\nasync function executeAction(\n action: UpdateAction,\n options: ExecuteUpdateOptions\n): Promise<UpdateActionResult> {\n const { dryRun = false } = options;\n\n switch (action.type) {\n case \"update_npm_packages\":\n return await executeUpdateNpmPackages(action, dryRun);\n\n case \"copy_rule_files\":\n return executeCopyRuleFiles(action, dryRun);\n\n case \"migrate_rule_options\":\n return executeMigrateRuleOptions(action, dryRun);\n\n case \"update_manifest_version\":\n return executeUpdateManifestVersion(action, dryRun);\n\n default: {\n const _exhaustive: never = action;\n return {\n action: _exhaustive,\n success: false,\n error: `Unknown action type`,\n };\n }\n }\n}\n\n/**\n * Update npm packages to latest versions\n */\nasync function executeUpdateNpmPackages(\n action: UpdateNpmPackagesAction,\n dryRun: boolean\n): Promise<UpdateActionResult> {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Update npm packages: ${action.packages.join(\", \")} to latest`,\n };\n }\n\n try {\n await updatePackages(\n action.packageManager,\n action.packagePath,\n action.packages,\n { dev: true }\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 * Copy updated rule files\n */\nfunction executeCopyRuleFiles(\n action: CopyRuleFilesAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Copy rule files for ${action.ruleId} v${action.version} to ${action.packagePath}`,\n };\n }\n\n try {\n const rulesDir = join(action.packagePath, \".uilint\", \"rules\");\n\n // Ensure directory exists\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n // Ensure .uilint/package.json marks the directory as ESM\n const uilintPkgPath = join(action.packagePath, \".uilint\", \"package.json\");\n if (!existsSync(uilintPkgPath)) {\n writeFileSync(uilintPkgPath, '{ \"type\": \"module\" }\\n', \"utf-8\");\n }\n\n // Load rule files (TypeScript version - can adjust based on project config)\n const [ruleFile] = loadSelectedRules([action.ruleId], {\n typescript: true,\n });\n\n if (!ruleFile) {\n return {\n action,\n success: false,\n error: `Rule ${action.ruleId} not found in registry`,\n };\n }\n\n // Write implementation file\n const implPath = join(rulesDir, ruleFile.implementation.relativePath);\n mkdirSync(dirname(implPath), { recursive: true });\n writeFileSync(implPath, ruleFile.implementation.content, \"utf-8\");\n\n // Write additional files for directory-based rules\n if (ruleFile.additionalFiles) {\n for (const file of ruleFile.additionalFiles) {\n const filePath = join(rulesDir, file.relativePath);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, file.content, \"utf-8\");\n }\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 * Migrate rule options in ESLint config\n */\nfunction executeMigrateRuleOptions(\n action: MigrateRuleOptionsAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Migrate options for ${action.ruleId} in ${action.configPath}`,\n };\n }\n\n try {\n // TODO: Implement actual ESLint config modification\n // For now, this is a placeholder that succeeds without modifying the config\n // The actual implementation requires AST parsing and modification\n\n // Note: The migration engine is already implemented in migration-engine.ts\n // What's needed here is:\n // 1. Read the ESLint config\n // 2. Find the rule options for action.ruleId\n // 3. Apply migrations using applyMigrations()\n // 4. Write the modified config back\n\n // For now, we'll skip this and just succeed\n // Users can manually update their config if migrations are needed\n if (action.migrations.length === 0) {\n return { action, success: true };\n }\n\n // Log that manual migration may be needed\n console.warn(\n `Note: Rule ${action.ruleId} has migrations. Manual config update may be needed.`\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 * Update manifest with new version\n */\nfunction executeUpdateManifestVersion(\n action: UpdateManifestVersionAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Update manifest for ${action.ruleId} to v${action.version}`,\n };\n }\n\n try {\n const cliVersion = getCliVersion();\n updateManifestRule(\n action.packagePath,\n action.ruleId,\n action.version,\n 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 * Upgrade command - update installed rules to latest versions\n *\n * Usage:\n * uilint upgrade # Interactive upgrade\n * uilint upgrade --check # Show available updates only\n * uilint upgrade --yes # Auto-confirm all updates\n * uilint upgrade --dry-run # Show what would change\n * uilint upgrade --rule <id> # Upgrade specific rule\n */\n\nimport {\n analyzeForUpdates,\n formatUpdateSummary,\n} from \"./update/analyze.js\";\nimport {\n createUpdatePlan,\n formatPlanSummary,\n planHasBreakingChanges,\n} from \"./update/plan.js\";\nimport { executeUpdatePlan } from \"./update/execute.js\";\nimport type { UpdateChoices } from \"./update/types.js\";\nimport {\n intro,\n outro,\n logInfo,\n logSuccess,\n logError,\n logWarning,\n note,\n confirm,\n} from \"../utils/prompts.js\";\nimport { discoverPlugins, loadPluginESLintRules } from \"../utils/plugin-loader.js\";\n\nexport interface UpgradeCommandOptions {\n check?: boolean;\n yes?: boolean;\n dryRun?: boolean;\n rule?: string;\n}\n\n/**\n * Run the upgrade command\n */\nexport async function upgrade(options: UpgradeCommandOptions): Promise<void> {\n intro(\"UILint Upgrade\");\n\n // Load plugin ESLint rules so plugin rules appear in the registry\n const pluginManifests = await discoverPlugins();\n await loadPluginESLintRules(pluginManifests);\n\n try {\n const projectPath = process.cwd();\n\n // Phase 1: Analyze\n logInfo(\"Analyzing installed rules...\");\n const analysis = analyzeForUpdates(projectPath);\n\n const hasPackageUpdates = analysis.packages.some(\n (p) => p.installedPackages.length > 0\n );\n\n if (analysis.totalUpdates === 0 && !hasPackageUpdates) {\n logSuccess(\"All packages and rules are up to date!\");\n outro(\"No upgrades needed\");\n return;\n }\n\n // Display available updates\n note(formatUpdateSummary(analysis), \"Available Updates\");\n\n // --check mode: just show what's available\n if (options.check) {\n outro(\"Run 'uilint upgrade' to apply updates\");\n return;\n }\n\n // Filter by specific rule if requested\n let ruleIds: string[] = [];\n if (options.rule) {\n const ruleExists = analysis.packages.some((pkg) =>\n pkg.rules.some((r) => r.ruleId === options.rule && r.hasUpdate)\n );\n\n if (!ruleExists) {\n logError(`Rule '${options.rule}' not found or already up to date`);\n outro(\"Upgrade cancelled\");\n process.exit(1);\n }\n\n ruleIds = [options.rule];\n logInfo(`Upgrading only: ${options.rule}`);\n }\n\n // Phase 2: Plan\n const choices: UpdateChoices = {\n packagePaths: analysis.packages.map((p) => p.packagePath),\n ruleIds,\n confirmBreaking: false,\n };\n\n const plan = createUpdatePlan(analysis, choices);\n\n if (plan.actions.length === 0) {\n logSuccess(\"No updates to apply\");\n outro(\"Done\");\n return;\n }\n\n // Display plan\n note(formatPlanSummary(plan), \"Upgrade Plan\");\n\n // Handle breaking changes\n if (planHasBreakingChanges(plan) && !options.yes) {\n logWarning(\"This upgrade includes breaking changes!\");\n const confirmed = await confirm({\n message: \"Continue with breaking changes?\",\n initialValue: false,\n });\n\n if (!confirmed) {\n outro(\"Upgrade cancelled\");\n return;\n }\n }\n\n // Confirm upgrade (unless --yes)\n if (!options.yes && !options.dryRun) {\n const npmPkgCount = plan.actions.filter(\n (a) => a.type === \"update_npm_packages\"\n ).length;\n const rulePkgCount = plan.rules.length;\n\n const parts: string[] = [];\n if (npmPkgCount > 0) {\n parts.push(`${npmPkgCount} package(s)`);\n }\n if (rulePkgCount > 0) {\n parts.push(`${rulePkgCount} rule(s)`);\n }\n\n const confirmed = await confirm({\n message: `Apply ${parts.join(\" and \")} upgrade?`,\n initialValue: true,\n });\n\n if (!confirmed) {\n outro(\"Upgrade cancelled\");\n return;\n }\n }\n\n // Phase 3: Execute\n if (options.dryRun) {\n logInfo(\"Dry run mode - no changes will be made\");\n }\n\n const result = await executeUpdatePlan(plan, {\n dryRun: options.dryRun,\n });\n\n // Report results\n if (options.dryRun) {\n logInfo(\"Dry run complete. Would perform:\");\n for (const action of result.actionsPerformed) {\n if (action.wouldDo) {\n console.log(` • ${action.wouldDo}`);\n }\n }\n } else if (result.success) {\n // Count npm package updates\n const npmUpdates = plan.actions.filter(\n (a) => a.type === \"update_npm_packages\"\n ).length;\n\n const parts: string[] = [];\n if (npmUpdates > 0) {\n parts.push(`${npmUpdates} package(s)`);\n }\n if (result.summary.rulesUpdated > 0) {\n parts.push(`${result.summary.rulesUpdated} rule(s)`);\n }\n\n logSuccess(`Upgraded ${parts.join(\" and \")}`);\n\n if (result.summary.filesModified.length > 0) {\n note(\n result.summary.filesModified.map((f) => ` ${f}`).join(\"\\n\"),\n \"Modified files\"\n );\n }\n\n if (result.summary.breakingChanges.length > 0) {\n logWarning(\"Breaking changes applied to:\");\n for (const rule of result.summary.breakingChanges) {\n console.log(` • ${rule}`);\n }\n console.log(\n \"\\nPlease review your ESLint config for any manual adjustments.\"\n );\n }\n } else {\n logError(\"Some upgrades failed\");\n for (const action of result.actionsPerformed) {\n if (!action.success && action.error) {\n console.log(` • ${action.error}`);\n }\n }\n process.exit(1);\n }\n\n outro(\"Upgrade complete\");\n } catch (error) {\n logError(error instanceof Error ? error.message : \"Upgrade failed\");\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["getRuleMetadata","getRuleMetadata"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uilint",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.162",
|
|
4
4
|
"description": "CLI for UILint - AI-powered UI consistency checking",
|
|
5
5
|
"author": "Peter Suggate",
|
|
6
6
|
"repository": {
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"react": "^19.2.3",
|
|
50
50
|
"typescript": "^5.9.3",
|
|
51
51
|
"ws": "^8.19.0",
|
|
52
|
-
"uilint-
|
|
53
|
-
"uilint-
|
|
54
|
-
"uilint-
|
|
52
|
+
"uilint-duplicates": "0.2.162",
|
|
53
|
+
"uilint-eslint": "0.2.162",
|
|
54
|
+
"uilint-core": "0.2.162"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"uilint-vision": "0.2.
|
|
58
|
-
"uilint-
|
|
59
|
-
"uilint-
|
|
60
|
-
"uilint-
|
|
57
|
+
"uilint-vision": "0.2.162",
|
|
58
|
+
"uilint-semantic": "0.2.159",
|
|
59
|
+
"uilint-coverage": "0.2.160",
|
|
60
|
+
"uilint-duplicates": "0.2.162"
|
|
61
61
|
},
|
|
62
62
|
"peerDependenciesMeta": {
|
|
63
63
|
"uilint-vision": {
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"ink-testing-library": "^4.0.0",
|
|
88
88
|
"tsup": "^8.5.1",
|
|
89
89
|
"vitest": "^4.0.17",
|
|
90
|
-
"uilint-react": "0.2.
|
|
90
|
+
"uilint-react": "0.2.162"
|
|
91
91
|
},
|
|
92
92
|
"keywords": [
|
|
93
93
|
"cli",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/init/plan.ts"],"sourcesContent":["/**\n * Plan phase - pure function generating InstallPlan from state + choices\n *\n * This function has NO I/O whatsoever. It takes the analyzed ProjectState,\n * user choices, and options, then returns an InstallPlan describing exactly\n * what actions to take.\n */\n\nimport { join } from \"path\";\nimport type { RuleMetadata } from \"uilint-eslint\";\nimport type {\n ProjectState,\n UserChoices,\n InstallPlan,\n InstallAction,\n DependencyInstall,\n PlanOptions,\n} from \"./types.js\";\nimport { GENSTYLEGUIDE_COMMAND_MD } from \"./constants.js\";\nimport { toInstallSpecifier } from \"./versioning.js\";\nimport { loadSkill } from \"../../utils/skill-loader.js\";\nimport { loadSelectedRules } from \"../../utils/rule-loader.js\";\nimport { detectPackageManager } from \"../../utils/package-manager.js\";\n\n/**\n * Create the install plan from project state and user choices\n *\n * @param state - The analyzed project state\n * @param choices - User's installation choices\n * @param options - Planning options (force, etc.)\n * @returns InstallPlan with all actions and dependencies\n */\nexport function createPlan(\n state: ProjectState,\n choices: UserChoices,\n options: PlanOptions = {}\n): InstallPlan {\n const actions: InstallAction[] = [];\n const dependencies: DependencyInstall[] = [];\n\n const { force: _force = false } = options;\n const { items } = choices;\n\n // Ensure .cursor directory exists if needed\n const needsCursorDir =\n items.includes(\"genstyleguide\") || items.includes(\"skill\");\n\n if (needsCursorDir && !state.cursorDir.exists) {\n actions.push({\n type: \"create_directory\",\n path: state.cursorDir.path,\n });\n }\n\n // =========================================================================\n // Genstyleguide Command\n // =========================================================================\n if (items.includes(\"genstyleguide\")) {\n const commandsDir = join(state.cursorDir.path, \"commands\");\n\n actions.push({\n type: \"create_directory\",\n path: commandsDir,\n });\n\n actions.push({\n type: \"create_file\",\n path: join(commandsDir, \"genstyleguide.md\"),\n content: GENSTYLEGUIDE_COMMAND_MD,\n });\n }\n\n // =========================================================================\n // Agent Skill Installation\n // =========================================================================\n if (items.includes(\"skill\")) {\n const skillsDir = join(state.cursorDir.path, \"skills\");\n\n // Create skills directory\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 {\n // Skill not found - skip silently (shouldn't happen in normal install)\n }\n }\n\n // =========================================================================\n // Next.js Overlay Installation\n // =========================================================================\n if (items.includes(\"next\") && choices.next) {\n const { projectPath, detection, targetFile, createProviders } =\n choices.next;\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 using the package manager for this specific target\n dependencies.push({\n packagePath: projectPath,\n packageManager: detectPackageManager(projectPath),\n packages: [\n toInstallSpecifier(\"uilint-react\", {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n toInstallSpecifier(\"uilint-core\", {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n \"jsx-loc-plugin\",\n ],\n });\n\n // Inject <uilint-devtools /> web component into React\n // Use targetFile or createProviders if specified by the user\n actions.push({\n type: \"inject_react\",\n projectPath,\n appRoot: detection.appRoot,\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 // Add uilint-react/devtools to tsconfig.json types for TypeScript support\n actions.push({\n type: \"inject_tsconfig\",\n projectPath,\n addDevtoolsTypes: true,\n });\n }\n\n // =========================================================================\n // Vite Overlay Installation\n // =========================================================================\n if (items.includes(\"vite\") && choices.vite) {\n const { projectPath, detection } = choices.vite;\n\n // Install React overlay dependencies using the package manager for this specific target\n dependencies.push({\n packagePath: projectPath,\n packageManager: detectPackageManager(projectPath),\n packages: [\n toInstallSpecifier(\"uilint-react\", {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.workspaceRoot,\n targetProjectPath: projectPath,\n }),\n toInstallSpecifier(\"uilint-core\", {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.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 // Add uilint-react/devtools to tsconfig.json types for TypeScript support\n actions.push({\n type: \"inject_tsconfig\",\n projectPath,\n addDevtoolsTypes: true,\n });\n }\n\n // =========================================================================\n // ESLint Plugin Installation\n // =========================================================================\n if (items.includes(\"eslint\") && choices.eslint) {\n const { packagePaths, selectedRules } = choices.eslint;\n\n for (const pkgPath of packagePaths) {\n const pkgInfo = state.packages.find((p) => p.path === pkgPath);\n\n // Create .uilint/rules directory alongside the target app (not at workspace root)\n const rulesDir = join(pkgPath, \".uilint\", \"rules\");\n actions.push({\n type: \"create_directory\",\n path: rulesDir,\n });\n\n // Load and copy rule files into this target package\n // Use TypeScript rule files if the ESLint config is TypeScript (.ts)\n // This ensures the imports match the actual rule files being copied\n // Skip externally-registered plugin rules (e.g. vision, semantic, coverage) —\n // their implementations live in their own npm packages, not in uilint-eslint.\n // Rules with `eslintImport` or `plugin` are imported from their package by the config injector.\n const localRules = selectedRules.filter((r) => !r.eslintImport && !r.plugin);\n const isTypeScriptConfig =\n pkgInfo?.eslintConfigPath?.endsWith(\".ts\") ?? false;\n const ruleFiles = loadSelectedRules(\n localRules.map((r) => r.id),\n {\n typescript: isTypeScriptConfig,\n }\n );\n for (const ruleFile of ruleFiles) {\n // For directory-based rules, create the directory structure first\n if (ruleFile.additionalFiles && ruleFile.additionalFiles.length > 0) {\n // Create rule directory (e.g., .uilint/rules/no-mixed-component-libraries/)\n const ruleDir = join(rulesDir, ruleFile.ruleId);\n actions.push({\n type: \"create_directory\",\n path: ruleDir,\n });\n\n // Create lib/ subdirectory if any files are in lib/\n const hasLibFiles = ruleFile.additionalFiles.some((f) =>\n f.relativePath.includes(\"/lib/\")\n );\n if (hasLibFiles) {\n actions.push({\n type: \"create_directory\",\n path: join(ruleDir, \"lib\"),\n });\n }\n }\n\n // Copy implementation file\n actions.push({\n type: \"create_file\",\n path: join(rulesDir, ruleFile.implementation.relativePath),\n content: ruleFile.implementation.content,\n });\n\n // Copy additional files for directory-based rules\n if (ruleFile.additionalFiles) {\n for (const additionalFile of ruleFile.additionalFiles) {\n actions.push({\n type: \"create_file\",\n path: join(rulesDir, additionalFile.relativePath),\n content: additionalFile.content,\n });\n }\n }\n\n // Copy test file if it exists (only for TypeScript configs)\n if (ruleFile.test && isTypeScriptConfig) {\n actions.push({\n type: \"create_file\",\n path: join(rulesDir, ruleFile.test.relativePath),\n content: ruleFile.test.content,\n });\n }\n }\n\n // Install dependencies using the package manager for this specific target\n const packagesToInstall = [\n toInstallSpecifier(\"uilint-eslint\", {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.workspaceRoot,\n targetProjectPath: pkgPath,\n }),\n \"typescript-eslint\",\n ];\n\n // Collect npm dependencies declared by selected rules\n let needsVitestCoverage = false;\n for (const rule of selectedRules) {\n if (rule.npmDependencies) {\n for (const dep of rule.npmDependencies) {\n if (!packagesToInstall.includes(dep)) {\n packagesToInstall.push(dep);\n }\n if (dep === \"@vitest/coverage-v8\") {\n needsVitestCoverage = true;\n }\n }\n }\n }\n\n // If any rule needs vitest coverage, inject the coverage config\n if (needsVitestCoverage) {\n actions.push({\n type: \"inject_vitest_coverage\",\n projectPath: pkgPath,\n });\n }\n\n // Install plugin packages for external rules (e.g. uilint-vision, uilint-semantic)\n const externalPkgs = new Set<string>();\n for (const rule of selectedRules) {\n if (rule.eslintImport) {\n // Extract package name from import specifier (e.g. \"uilint-vision/eslint-rules/...\")\n const pkgName = rule.eslintImport.split(\"/\").slice(0, 1).join(\"/\");\n externalPkgs.add(pkgName);\n }\n }\n for (const pkg of externalPkgs) {\n const specifier = toInstallSpecifier(pkg, {\n preferWorkspaceProtocol: state.packageManager === \"pnpm\",\n workspaceRoot: state.workspaceRoot,\n targetProjectPath: pkgPath,\n });\n if (!packagesToInstall.includes(specifier)) {\n packagesToInstall.push(specifier);\n }\n }\n\n dependencies.push({\n packagePath: pkgPath,\n packageManager: detectPackageManager(pkgPath),\n packages: packagesToInstall,\n });\n\n // Inject ESLint rules (will reference local .uilint/rules/ files)\n if (pkgInfo?.eslintConfigPath) {\n actions.push({\n type: \"inject_eslint\",\n packagePath: pkgPath,\n configPath: pkgInfo.eslintConfigPath,\n rules: selectedRules,\n hasExistingRules: pkgInfo.hasUilintRules,\n });\n }\n\n // Add .uilint to tsconfig.json exclude to prevent build errors\n // The rule files are loaded by ESLint at runtime, not compiled with the app\n actions.push({\n type: \"inject_tsconfig\",\n projectPath: pkgPath,\n });\n\n // Update manifest with installed rule versions\n const ruleVersions: Record<string, string> = {};\n for (const rule of selectedRules) {\n // Use version from RuleMeta, default to \"1.0.0\" if not specified\n ruleVersions[rule.id] = rule.version ?? \"1.0.0\";\n }\n actions.push({\n type: \"update_manifest\",\n projectPath: pkgPath,\n rules: ruleVersions,\n });\n }\n\n // Add .uilint/.cache to .gitignore at workspace root\n const gitignorePath = join(state.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\n return { actions, dependencies };\n}\n\n/**\n * Get the list of rules that are missing from a package's ESLint config\n */\nexport function getMissingRules(\n configuredRuleIds: string[],\n selectedRules: RuleMetadata[]\n): RuleMetadata[] {\n const configuredSet = new Set(configuredRuleIds);\n return selectedRules.filter((rule) => !configuredSet.has(rule.id));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/update/analyze.ts","../src/utils/migration-engine.ts","../src/commands/update/plan.ts","../src/commands/update/execute.ts","../src/commands/upgrade.ts"],"sourcesContent":["/**\n * Analyze phase for the update command\n *\n * Compares installed rule versions against available versions\n * and identifies what can be updated.\n */\n\nimport { basename } from \"path\";\nimport { getRuleMetadata } from \"uilint-eslint\";\nimport {\n detectPackageManager,\n getInstalledUilintPackages,\n} from \"../../utils/package-manager.js\";\nimport { findWorkspaceRoot } from \"uilint-core/node\";\nimport { getInstalledRuleVersions } from \"../../utils/manifest.js\";\nimport {\n findMigrationPath,\n getMigrationsForRule,\n hasBreakingMigrations,\n} from \"../../utils/migration-engine.js\";\nimport type {\n UpdateAnalysis,\n PackageUpdateInfo,\n RuleUpdateInfo,\n InstalledPackageInfo,\n} from \"./types.js\";\n\n/**\n * Compare two semver versions\n * Returns true if available > installed\n */\nfunction isNewerVersion(installed: string, available: string): boolean {\n const installedParts = installed.split(\".\").map(Number);\n const availableParts = available.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const a = availableParts[i] ?? 0;\n const b = installedParts[i] ?? 0;\n if (a > b) return true;\n if (a < b) return false;\n }\n\n return false;\n}\n\n/**\n * Analyze a single rule for updates\n */\nfunction analyzeRule(\n ruleId: string,\n installedVersion: string\n): RuleUpdateInfo | null {\n const ruleMeta = getRuleMetadata(ruleId);\n if (!ruleMeta) {\n // Rule no longer exists in registry\n return null;\n }\n\n const availableVersion = ruleMeta.version ?? \"1.0.0\";\n const hasUpdate = isNewerVersion(installedVersion, availableVersion);\n\n // Find migration path if update is available\n const migrations = hasUpdate\n ? findMigrationPath(\n installedVersion,\n availableVersion,\n getMigrationsForRule(ruleId)\n )\n : [];\n\n return {\n ruleId,\n installedVersion,\n availableVersion,\n hasUpdate,\n migrations,\n hasBreakingChanges: hasBreakingMigrations(migrations),\n };\n}\n\n/**\n * Analyze a package for rule updates\n */\nfunction analyzePackage(packagePath: string): PackageUpdateInfo {\n const installedVersions = getInstalledRuleVersions(packagePath);\n const rules: RuleUpdateInfo[] = [];\n\n // Check each installed rule\n for (const [ruleId, version] of Object.entries(installedVersions)) {\n const ruleInfo = analyzeRule(ruleId, version);\n if (ruleInfo) {\n rules.push(ruleInfo);\n }\n }\n\n const updatableRules = rules.filter((r) => r.hasUpdate);\n\n // Get installed uilint npm packages\n const installedPackagesMap = getInstalledUilintPackages(packagePath);\n const installedPackages: InstalledPackageInfo[] = [];\n for (const [name, version] of installedPackagesMap) {\n installedPackages.push({ name, installedVersion: version });\n }\n\n return {\n packagePath,\n displayName: basename(packagePath) || packagePath,\n eslintConfigPath: null, // TODO: detect ESLint config\n packageManager: detectPackageManager(packagePath),\n installedPackages,\n rules,\n updatableCount: updatableRules.length,\n hasBreakingChanges: updatableRules.some((r) => r.hasBreakingChanges),\n };\n}\n\n/**\n * Analyze a project for available rule updates\n *\n * @param projectPath - Path to the project (or package in a monorepo)\n * @returns Analysis of available updates\n */\nexport function analyzeForUpdates(projectPath: string): UpdateAnalysis {\n const workspaceRoot = findWorkspaceRoot(projectPath);\n const packageManager = detectPackageManager(projectPath);\n\n // For now, just analyze the single project path\n // TODO: In monorepo, scan all packages with manifests\n const packageInfo = analyzePackage(projectPath);\n const packages = [packageInfo];\n\n const totalUpdates = packages.reduce((sum, p) => sum + p.updatableCount, 0);\n const hasBreakingChanges = packages.some((p) => p.hasBreakingChanges);\n\n return {\n workspaceRoot,\n packageManager,\n packages,\n totalUpdates,\n hasBreakingChanges,\n };\n}\n\n/**\n * Get a summary of available updates for display\n */\nexport function formatUpdateSummary(analysis: UpdateAnalysis): string {\n const hasRuleUpdates = analysis.totalUpdates > 0;\n const hasPackages = analysis.packages.some(\n (p) => p.installedPackages.length > 0\n );\n\n if (!hasRuleUpdates && !hasPackages) {\n return \"No uilint packages or rules found.\";\n }\n\n const lines: string[] = [];\n\n for (const pkg of analysis.packages) {\n const hasUpdates =\n pkg.updatableCount > 0 || pkg.installedPackages.length > 0;\n if (!hasUpdates) continue;\n\n lines.push(`${pkg.displayName}:`);\n\n // Show installed npm packages\n if (pkg.installedPackages.length > 0) {\n lines.push(\" npm packages:\");\n for (const npmPkg of pkg.installedPackages) {\n lines.push(` ${npmPkg.name}: ${npmPkg.installedVersion} → latest`);\n }\n }\n\n // Show rule updates\n if (pkg.updatableCount > 0) {\n lines.push(\" rules:\");\n for (const rule of pkg.rules) {\n if (!rule.hasUpdate) continue;\n\n const breaking = rule.hasBreakingChanges ? \" (BREAKING)\" : \"\";\n lines.push(\n ` ${rule.ruleId}: ${rule.installedVersion} → ${rule.availableVersion}${breaking}`\n );\n }\n }\n\n lines.push(\"\");\n }\n\n if (analysis.hasBreakingChanges) {\n lines.push(\"⚠️ Some rule updates contain breaking changes.\");\n }\n\n return lines.join(\"\\n\");\n}\n","/**\n * Migration Engine\n *\n * Handles migrating rule options between versions using migration definitions.\n */\n\nimport { getRuleMetadata, type RuleMigration } from \"uilint-eslint\";\n\n/**\n * Find a path of migrations to get from one version to another.\n *\n * Uses BFS to find the shortest path through the migration graph.\n *\n * @param from - Starting version (installed version)\n * @param to - Target version (available version)\n * @param migrations - Available migrations for the rule\n * @returns Array of migrations to apply in order, or empty array if no path exists\n */\nexport function findMigrationPath(\n from: string,\n to: string,\n migrations: RuleMigration[]\n): RuleMigration[] {\n // No migration needed if versions are the same\n if (from === to) {\n return [];\n }\n\n // No migrations available\n if (migrations.length === 0) {\n return [];\n }\n\n // Build a map of version -> outgoing migrations\n const migrationMap = new Map<string, RuleMigration[]>();\n for (const migration of migrations) {\n const existing = migrationMap.get(migration.from) ?? [];\n existing.push(migration);\n migrationMap.set(migration.from, existing);\n }\n\n // BFS to find path\n const visited = new Set<string>();\n const queue: { version: string; path: RuleMigration[] }[] = [\n { version: from, path: [] },\n ];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (visited.has(current.version)) {\n continue;\n }\n visited.add(current.version);\n\n const outgoing = migrationMap.get(current.version) ?? [];\n for (const migration of outgoing) {\n const newPath = [...current.path, migration];\n\n // Found the target\n if (migration.to === to) {\n return newPath;\n }\n\n // Add to queue for further exploration\n if (!visited.has(migration.to)) {\n queue.push({ version: migration.to, path: newPath });\n }\n }\n }\n\n // No path found\n return [];\n}\n\n/**\n * Apply a sequence of migrations to transform options.\n *\n * @param options - The current rule options array\n * @param migrations - Migrations to apply in order\n * @returns Transformed options array\n */\nexport function applyMigrations(\n options: unknown[],\n migrations: RuleMigration[]\n): unknown[] {\n let current = options;\n\n for (const migration of migrations) {\n current = migration.migrate(current);\n }\n\n return current;\n}\n\n/**\n * Get migrations defined for a specific rule.\n *\n * @param ruleId - The rule ID to look up\n * @returns Array of migrations, or empty array if none defined\n */\nexport function getMigrationsForRule(ruleId: string): RuleMigration[] {\n const ruleMeta = getRuleMetadata(ruleId);\n if (!ruleMeta) {\n return [];\n }\n\n return ruleMeta.migrations ?? [];\n}\n\n/**\n * Check if there are any breaking migrations in a migration path.\n *\n * @param migrations - The migration path to check\n * @returns True if any migration is marked as breaking\n */\nexport function hasBreakingMigrations(migrations: RuleMigration[]): boolean {\n return migrations.some((m) => m.breaking === true);\n}\n\n/**\n * Get descriptions of all migrations in a path.\n *\n * @param migrations - The migration path\n * @returns Array of migration descriptions\n */\nexport function getMigrationDescriptions(migrations: RuleMigration[]): string[] {\n return migrations.map(\n (m) => `${m.from} → ${m.to}: ${m.description}${m.breaking ? \" (BREAKING)\" : \"\"}`\n );\n}\n","/**\n * Plan phase for the update command\n *\n * Creates a plan of actions to update rules based on analysis and user choices.\n */\n\nimport type {\n UpdateAnalysis,\n UpdatePlan,\n UpdateAction,\n UpdateChoices,\n RuleUpdateInfo,\n} from \"./types.js\";\n\n/**\n * Create an update plan based on analysis and user choices\n *\n * @param analysis - Result from the analyze phase\n * @param choices - User selections for what to update\n * @returns Plan of actions to execute\n */\nexport function createUpdatePlan(\n analysis: UpdateAnalysis,\n choices: UpdateChoices\n): UpdatePlan {\n const actions: UpdateAction[] = [];\n const rules: RuleUpdateInfo[] = [];\n\n for (const pkg of analysis.packages) {\n // Skip packages not selected\n if (!choices.packagePaths.includes(pkg.packagePath)) {\n continue;\n }\n\n // Action: Update npm packages (do this first)\n if (pkg.installedPackages.length > 0) {\n actions.push({\n type: \"update_npm_packages\",\n packagePath: pkg.packagePath,\n packageManager: pkg.packageManager,\n packages: pkg.installedPackages.map((p) => p.name),\n });\n }\n\n for (const rule of pkg.rules) {\n // Skip rules that don't have updates\n if (!rule.hasUpdate) {\n continue;\n }\n\n // Skip rules not in the specific rule filter (if set)\n if (choices.ruleIds.length > 0 && !choices.ruleIds.includes(rule.ruleId)) {\n continue;\n }\n\n // Track this rule for the plan\n rules.push(rule);\n\n // Action 1: Copy updated rule files\n actions.push({\n type: \"copy_rule_files\",\n packagePath: pkg.packagePath,\n ruleId: rule.ruleId,\n version: rule.availableVersion,\n });\n\n // Action 2: Migrate options in ESLint config (if migrations exist)\n if (rule.migrations.length > 0 && pkg.eslintConfigPath) {\n actions.push({\n type: \"migrate_rule_options\",\n configPath: pkg.eslintConfigPath,\n ruleId: rule.ruleId,\n migrations: rule.migrations,\n });\n }\n\n // Action 3: Update manifest with new version\n actions.push({\n type: \"update_manifest_version\",\n packagePath: pkg.packagePath,\n ruleId: rule.ruleId,\n version: rule.availableVersion,\n });\n }\n }\n\n return { actions, rules };\n}\n\n/**\n * Get a summary of what the plan will do\n */\nexport function formatPlanSummary(plan: UpdatePlan): string {\n if (plan.actions.length === 0) {\n return \"No updates to apply.\";\n }\n\n const lines: string[] = [];\n lines.push(`Update plan (${plan.rules.length} rule(s)):\\n`);\n\n for (const rule of plan.rules) {\n const breaking = rule.hasBreakingChanges ? \" ⚠️ BREAKING\" : \"\";\n lines.push(\n ` ${rule.ruleId}: ${rule.installedVersion} → ${rule.availableVersion}${breaking}`\n );\n\n // Show migration descriptions\n if (rule.migrations.length > 0) {\n for (const migration of rule.migrations) {\n lines.push(` - ${migration.description}`);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Check if the plan has any breaking changes that require confirmation\n */\nexport function planHasBreakingChanges(plan: UpdatePlan): boolean {\n return plan.rules.some((r) => r.hasBreakingChanges);\n}\n\n/**\n * Filter plan to only include specific rules\n */\nexport function filterPlanByRules(\n plan: UpdatePlan,\n ruleIds: string[]\n): UpdatePlan {\n if (ruleIds.length === 0) {\n return plan;\n }\n\n const ruleIdSet = new Set(ruleIds);\n const filteredRules = plan.rules.filter((r) => ruleIdSet.has(r.ruleId));\n const filteredActions = plan.actions.filter((a) => {\n if (\"ruleId\" in a) {\n return ruleIdSet.has(a.ruleId);\n }\n return true;\n });\n\n return {\n actions: filteredActions,\n rules: filteredRules,\n };\n}\n","/**\n * Execute phase for the update command\n *\n * Performs the actual file operations to update rules.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { loadSelectedRules } from \"../../utils/rule-loader.js\";\nimport { updateManifestRule } from \"../../utils/manifest.js\";\nimport { updatePackages } from \"../../utils/package-manager.js\";\nimport type {\n UpdatePlan,\n UpdateAction,\n UpdateResult,\n UpdateActionResult,\n UpdateSummary,\n CopyRuleFilesAction,\n MigrateRuleOptionsAction,\n UpdateManifestVersionAction,\n UpdateNpmPackagesAction,\n} from \"./types.js\";\n\nexport interface ExecuteUpdateOptions {\n dryRun?: boolean;\n}\n\n/**\n * Execute an update plan\n *\n * @param plan - The plan to execute\n * @param options - Execution options\n * @returns Result of the execution\n */\nexport async function executeUpdatePlan(\n plan: UpdatePlan,\n options: ExecuteUpdateOptions = {}\n): Promise<UpdateResult> {\n const { dryRun = false } = options;\n const results: UpdateActionResult[] = [];\n const filesModified: string[] = [];\n\n for (const action of plan.actions) {\n const result = await executeAction(action, { dryRun });\n results.push(result);\n\n if (result.success && !dryRun) {\n // Track modified files\n if (action.type === \"copy_rule_files\") {\n filesModified.push(\n join(action.packagePath, \".uilint\", \"rules\", action.ruleId)\n );\n } else if (action.type === \"migrate_rule_options\") {\n filesModified.push(action.configPath);\n } else if (action.type === \"update_manifest_version\") {\n filesModified.push(\n join(action.packagePath, \".uilint\", \"rules\", \"manifest.json\")\n );\n }\n }\n }\n\n const success = results.every((r) => r.success);\n const rulesUpdated = new Set(plan.rules.map((r) => r.ruleId)).size;\n const packagesUpdated = new Set(\n plan.actions\n .filter((a) => \"packagePath\" in a)\n .map((a) => (a as { packagePath: string }).packagePath)\n ).size;\n\n const summary: UpdateSummary = {\n rulesUpdated,\n packagesUpdated,\n filesModified: [...new Set(filesModified)],\n breakingChanges: plan.rules\n .filter((r) => r.hasBreakingChanges)\n .map((r) => r.ruleId),\n };\n\n return {\n success,\n actionsPerformed: results,\n summary,\n };\n}\n\n/**\n * Execute a single update action\n */\nasync function executeAction(\n action: UpdateAction,\n options: ExecuteUpdateOptions\n): Promise<UpdateActionResult> {\n const { dryRun = false } = options;\n\n switch (action.type) {\n case \"update_npm_packages\":\n return await executeUpdateNpmPackages(action, dryRun);\n\n case \"copy_rule_files\":\n return executeCopyRuleFiles(action, dryRun);\n\n case \"migrate_rule_options\":\n return executeMigrateRuleOptions(action, dryRun);\n\n case \"update_manifest_version\":\n return executeUpdateManifestVersion(action, dryRun);\n\n default: {\n const _exhaustive: never = action;\n return {\n action: _exhaustive,\n success: false,\n error: `Unknown action type`,\n };\n }\n }\n}\n\n/**\n * Update npm packages to latest versions\n */\nasync function executeUpdateNpmPackages(\n action: UpdateNpmPackagesAction,\n dryRun: boolean\n): Promise<UpdateActionResult> {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Update npm packages: ${action.packages.join(\", \")} to latest`,\n };\n }\n\n try {\n await updatePackages(\n action.packageManager,\n action.packagePath,\n action.packages,\n { dev: true }\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 * Copy updated rule files\n */\nfunction executeCopyRuleFiles(\n action: CopyRuleFilesAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Copy rule files for ${action.ruleId} v${action.version} to ${action.packagePath}`,\n };\n }\n\n try {\n const rulesDir = join(action.packagePath, \".uilint\", \"rules\");\n\n // Ensure directory exists\n if (!existsSync(rulesDir)) {\n mkdirSync(rulesDir, { recursive: true });\n }\n\n // Load rule files (TypeScript version - can adjust based on project config)\n const [ruleFile] = loadSelectedRules([action.ruleId], {\n typescript: true,\n });\n\n if (!ruleFile) {\n return {\n action,\n success: false,\n error: `Rule ${action.ruleId} not found in registry`,\n };\n }\n\n // Write implementation file\n const implPath = join(rulesDir, ruleFile.implementation.relativePath);\n mkdirSync(dirname(implPath), { recursive: true });\n writeFileSync(implPath, ruleFile.implementation.content, \"utf-8\");\n\n // Write additional files for directory-based rules\n if (ruleFile.additionalFiles) {\n for (const file of ruleFile.additionalFiles) {\n const filePath = join(rulesDir, file.relativePath);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, file.content, \"utf-8\");\n }\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 * Migrate rule options in ESLint config\n */\nfunction executeMigrateRuleOptions(\n action: MigrateRuleOptionsAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Migrate options for ${action.ruleId} in ${action.configPath}`,\n };\n }\n\n try {\n // TODO: Implement actual ESLint config modification\n // For now, this is a placeholder that succeeds without modifying the config\n // The actual implementation requires AST parsing and modification\n\n // Note: The migration engine is already implemented in migration-engine.ts\n // What's needed here is:\n // 1. Read the ESLint config\n // 2. Find the rule options for action.ruleId\n // 3. Apply migrations using applyMigrations()\n // 4. Write the modified config back\n\n // For now, we'll skip this and just succeed\n // Users can manually update their config if migrations are needed\n if (action.migrations.length === 0) {\n return { action, success: true };\n }\n\n // Log that manual migration may be needed\n console.warn(\n `Note: Rule ${action.ruleId} has migrations. Manual config update may be needed.`\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 * Update manifest with new version\n */\nfunction executeUpdateManifestVersion(\n action: UpdateManifestVersionAction,\n dryRun: boolean\n): UpdateActionResult {\n if (dryRun) {\n return {\n action,\n success: true,\n wouldDo: `Update manifest for ${action.ruleId} to v${action.version}`,\n };\n }\n\n try {\n const cliVersion = getCliVersion();\n updateManifestRule(\n action.packagePath,\n action.ruleId,\n action.version,\n 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 * Upgrade command - update installed rules to latest versions\n *\n * Usage:\n * uilint upgrade # Interactive upgrade\n * uilint upgrade --check # Show available updates only\n * uilint upgrade --yes # Auto-confirm all updates\n * uilint upgrade --dry-run # Show what would change\n * uilint upgrade --rule <id> # Upgrade specific rule\n */\n\nimport {\n analyzeForUpdates,\n formatUpdateSummary,\n} from \"./update/analyze.js\";\nimport {\n createUpdatePlan,\n formatPlanSummary,\n planHasBreakingChanges,\n} from \"./update/plan.js\";\nimport { executeUpdatePlan } from \"./update/execute.js\";\nimport type { UpdateChoices } from \"./update/types.js\";\nimport {\n intro,\n outro,\n logInfo,\n logSuccess,\n logError,\n logWarning,\n note,\n confirm,\n} from \"../utils/prompts.js\";\nimport { discoverPlugins, loadPluginESLintRules } from \"../utils/plugin-loader.js\";\n\nexport interface UpgradeCommandOptions {\n check?: boolean;\n yes?: boolean;\n dryRun?: boolean;\n rule?: string;\n}\n\n/**\n * Run the upgrade command\n */\nexport async function upgrade(options: UpgradeCommandOptions): Promise<void> {\n intro(\"UILint Upgrade\");\n\n // Load plugin ESLint rules so plugin rules appear in the registry\n const pluginManifests = await discoverPlugins();\n await loadPluginESLintRules(pluginManifests);\n\n try {\n const projectPath = process.cwd();\n\n // Phase 1: Analyze\n logInfo(\"Analyzing installed rules...\");\n const analysis = analyzeForUpdates(projectPath);\n\n const hasPackageUpdates = analysis.packages.some(\n (p) => p.installedPackages.length > 0\n );\n\n if (analysis.totalUpdates === 0 && !hasPackageUpdates) {\n logSuccess(\"All packages and rules are up to date!\");\n outro(\"No upgrades needed\");\n return;\n }\n\n // Display available updates\n note(formatUpdateSummary(analysis), \"Available Updates\");\n\n // --check mode: just show what's available\n if (options.check) {\n outro(\"Run 'uilint upgrade' to apply updates\");\n return;\n }\n\n // Filter by specific rule if requested\n let ruleIds: string[] = [];\n if (options.rule) {\n const ruleExists = analysis.packages.some((pkg) =>\n pkg.rules.some((r) => r.ruleId === options.rule && r.hasUpdate)\n );\n\n if (!ruleExists) {\n logError(`Rule '${options.rule}' not found or already up to date`);\n outro(\"Upgrade cancelled\");\n process.exit(1);\n }\n\n ruleIds = [options.rule];\n logInfo(`Upgrading only: ${options.rule}`);\n }\n\n // Phase 2: Plan\n const choices: UpdateChoices = {\n packagePaths: analysis.packages.map((p) => p.packagePath),\n ruleIds,\n confirmBreaking: false,\n };\n\n const plan = createUpdatePlan(analysis, choices);\n\n if (plan.actions.length === 0) {\n logSuccess(\"No updates to apply\");\n outro(\"Done\");\n return;\n }\n\n // Display plan\n note(formatPlanSummary(plan), \"Upgrade Plan\");\n\n // Handle breaking changes\n if (planHasBreakingChanges(plan) && !options.yes) {\n logWarning(\"This upgrade includes breaking changes!\");\n const confirmed = await confirm({\n message: \"Continue with breaking changes?\",\n initialValue: false,\n });\n\n if (!confirmed) {\n outro(\"Upgrade cancelled\");\n return;\n }\n }\n\n // Confirm upgrade (unless --yes)\n if (!options.yes && !options.dryRun) {\n const npmPkgCount = plan.actions.filter(\n (a) => a.type === \"update_npm_packages\"\n ).length;\n const rulePkgCount = plan.rules.length;\n\n const parts: string[] = [];\n if (npmPkgCount > 0) {\n parts.push(`${npmPkgCount} package(s)`);\n }\n if (rulePkgCount > 0) {\n parts.push(`${rulePkgCount} rule(s)`);\n }\n\n const confirmed = await confirm({\n message: `Apply ${parts.join(\" and \")} upgrade?`,\n initialValue: true,\n });\n\n if (!confirmed) {\n outro(\"Upgrade cancelled\");\n return;\n }\n }\n\n // Phase 3: Execute\n if (options.dryRun) {\n logInfo(\"Dry run mode - no changes will be made\");\n }\n\n const result = await executeUpdatePlan(plan, {\n dryRun: options.dryRun,\n });\n\n // Report results\n if (options.dryRun) {\n logInfo(\"Dry run complete. Would perform:\");\n for (const action of result.actionsPerformed) {\n if (action.wouldDo) {\n console.log(` • ${action.wouldDo}`);\n }\n }\n } else if (result.success) {\n // Count npm package updates\n const npmUpdates = plan.actions.filter(\n (a) => a.type === \"update_npm_packages\"\n ).length;\n\n const parts: string[] = [];\n if (npmUpdates > 0) {\n parts.push(`${npmUpdates} package(s)`);\n }\n if (result.summary.rulesUpdated > 0) {\n parts.push(`${result.summary.rulesUpdated} rule(s)`);\n }\n\n logSuccess(`Upgraded ${parts.join(\" and \")}`);\n\n if (result.summary.filesModified.length > 0) {\n note(\n result.summary.filesModified.map((f) => ` ${f}`).join(\"\\n\"),\n \"Modified files\"\n );\n }\n\n if (result.summary.breakingChanges.length > 0) {\n logWarning(\"Breaking changes applied to:\");\n for (const rule of result.summary.breakingChanges) {\n console.log(` • ${rule}`);\n }\n console.log(\n \"\\nPlease review your ESLint config for any manual adjustments.\"\n );\n }\n } else {\n logError(\"Some upgrades failed\");\n for (const action of result.actionsPerformed) {\n if (!action.success && action.error) {\n console.log(` • ${action.error}`);\n }\n }\n process.exit(1);\n }\n\n outro(\"Upgrade complete\");\n } catch (error) {\n logError(error instanceof Error ? error.message : \"Upgrade failed\");\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["getRuleMetadata","getRuleMetadata"]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|