uilint 0.2.13 → 0.2.14
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-EYCSOCU4.js → chunk-FRNXXIEM.js} +1 -32
- package/dist/{chunk-EYCSOCU4.js.map → chunk-FRNXXIEM.js.map} +1 -1
- package/dist/{chunk-2RNDQVEK.js → chunk-PBEKMDUH.js} +68 -13
- package/dist/chunk-PBEKMDUH.js.map +1 -0
- package/dist/index.js +16 -7
- package/dist/index.js.map +1 -1
- package/dist/{install-ui-ITXPOUVQ.js → install-ui-H2KOQ6SP.js} +152 -234
- package/dist/install-ui-H2KOQ6SP.js.map +1 -0
- package/dist/{plan-PX7FFJ25.js → plan-G43256ML.js} +6 -5
- package/dist/plan-G43256ML.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-2RNDQVEK.js.map +0 -1
- package/dist/install-ui-ITXPOUVQ.js.map +0 -1
- package/dist/plan-PX7FFJ25.js.map +0 -1
|
@@ -7,13 +7,14 @@ import {
|
|
|
7
7
|
multiselect,
|
|
8
8
|
note,
|
|
9
9
|
pc,
|
|
10
|
-
printBox,
|
|
11
10
|
select
|
|
12
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-FRNXXIEM.js";
|
|
13
12
|
import {
|
|
14
13
|
GENSTYLEGUIDE_COMMAND_MD,
|
|
14
|
+
detectPackageManager,
|
|
15
|
+
installDependencies,
|
|
15
16
|
loadSkill
|
|
16
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PBEKMDUH.js";
|
|
17
18
|
|
|
18
19
|
// src/commands/install-ui.tsx
|
|
19
20
|
import { render } from "ink";
|
|
@@ -141,6 +142,9 @@ function StatusIndicator({ status, isSelected }) {
|
|
|
141
142
|
if (status === "installed") {
|
|
142
143
|
return /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713" });
|
|
143
144
|
}
|
|
145
|
+
if (status === "upgradeable") {
|
|
146
|
+
return isSelected ? /* @__PURE__ */ jsx3(Text3, { color: "blue", children: "\u2B06" }) : /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713" });
|
|
147
|
+
}
|
|
144
148
|
if (isSelected || status === "selected") {
|
|
145
149
|
return /* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "\u25C9" });
|
|
146
150
|
}
|
|
@@ -153,6 +157,9 @@ function StatusLabel({ status }) {
|
|
|
153
157
|
if (status === "installed") {
|
|
154
158
|
return /* @__PURE__ */ jsx3(Text3, { color: "green", dimColor: true, children: "installed" });
|
|
155
159
|
}
|
|
160
|
+
if (status === "upgradeable") {
|
|
161
|
+
return /* @__PURE__ */ jsx3(Text3, { color: "blue", dimColor: true, children: "upgrade available" });
|
|
162
|
+
}
|
|
156
163
|
if (status === "partial") {
|
|
157
164
|
return /* @__PURE__ */ jsx3(Text3, { color: "yellow", dimColor: true, children: "partial" });
|
|
158
165
|
}
|
|
@@ -178,7 +185,8 @@ function ConfigSelector({
|
|
|
178
185
|
const flatItems = items;
|
|
179
186
|
const handleToggle = useCallback(() => {
|
|
180
187
|
const item = flatItems[cursor];
|
|
181
|
-
|
|
188
|
+
const canToggle = item && !item.disabled && item.status !== "installed";
|
|
189
|
+
if (!canToggle) return;
|
|
182
190
|
setSelected((prev) => {
|
|
183
191
|
const next = new Set(prev);
|
|
184
192
|
if (next.has(item.id)) {
|
|
@@ -519,6 +527,15 @@ function getAllInstallers() {
|
|
|
519
527
|
|
|
520
528
|
// src/commands/install/components/InstallApp.tsx
|
|
521
529
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
530
|
+
function getTargetStatus(target) {
|
|
531
|
+
if (!target.isInstalled) {
|
|
532
|
+
return "not_installed";
|
|
533
|
+
}
|
|
534
|
+
if (target.canUpgrade) {
|
|
535
|
+
return "upgradeable";
|
|
536
|
+
}
|
|
537
|
+
return "installed";
|
|
538
|
+
}
|
|
522
539
|
function buildConfigItemsForProject(project, selectedProject, selections) {
|
|
523
540
|
const items = [];
|
|
524
541
|
for (const selection of selections) {
|
|
@@ -546,7 +563,7 @@ function buildConfigItemsForProject(project, selectedProject, selections) {
|
|
|
546
563
|
id: `${installer.id}:${target.id}`,
|
|
547
564
|
label: installer.name,
|
|
548
565
|
hint: target.hint,
|
|
549
|
-
status: target
|
|
566
|
+
status: getTargetStatus(target),
|
|
550
567
|
category: info.category,
|
|
551
568
|
categoryIcon: info.icon
|
|
552
569
|
});
|
|
@@ -571,7 +588,7 @@ function buildGlobalConfigItems(selections) {
|
|
|
571
588
|
id: `${installer.id}:${target.id}`,
|
|
572
589
|
label: installer.name,
|
|
573
590
|
hint: target.hint,
|
|
574
|
-
status: target
|
|
591
|
+
status: getTargetStatus(target),
|
|
575
592
|
category: info.category,
|
|
576
593
|
categoryIcon: info.icon
|
|
577
594
|
});
|
|
@@ -653,11 +670,13 @@ function InstallApp({
|
|
|
653
670
|
const installers2 = getAllInstallers();
|
|
654
671
|
const initialSelections = installers2.filter((installer) => installer.isApplicable(proj)).map((installer) => {
|
|
655
672
|
const targets = installer.getTargets(proj);
|
|
656
|
-
const
|
|
673
|
+
const actionableTargets = targets.filter(
|
|
674
|
+
(t) => !t.isInstalled || t.canUpgrade
|
|
675
|
+
);
|
|
657
676
|
return {
|
|
658
677
|
installer,
|
|
659
678
|
targets,
|
|
660
|
-
selected:
|
|
679
|
+
selected: actionableTargets.length > 0
|
|
661
680
|
};
|
|
662
681
|
});
|
|
663
682
|
setSelections(initialSelections);
|
|
@@ -798,8 +817,8 @@ function InstallApp({
|
|
|
798
817
|
}
|
|
799
818
|
|
|
800
819
|
// src/commands/install/analyze.ts
|
|
801
|
-
import { existsSync as
|
|
802
|
-
import { join as
|
|
820
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
821
|
+
import { join as join4 } from "path";
|
|
803
822
|
import { findWorkspaceRoot as findWorkspaceRoot2 } from "uilint-core/node";
|
|
804
823
|
|
|
805
824
|
// src/utils/vite-detect.ts
|
|
@@ -1043,86 +1062,16 @@ function findPackages(rootDir, options) {
|
|
|
1043
1062
|
});
|
|
1044
1063
|
}
|
|
1045
1064
|
|
|
1046
|
-
// src/utils/package-manager.ts
|
|
1047
|
-
import { existsSync as existsSync3 } from "fs";
|
|
1048
|
-
import { spawn } from "child_process";
|
|
1049
|
-
import { dirname, join as join3 } from "path";
|
|
1050
|
-
function detectExecutionPackageManager() {
|
|
1051
|
-
const userAgent = process.env.npm_config_user_agent;
|
|
1052
|
-
if (userAgent) {
|
|
1053
|
-
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
1054
|
-
if (userAgent.startsWith("yarn/")) return "yarn";
|
|
1055
|
-
if (userAgent.startsWith("bun/")) return "bun";
|
|
1056
|
-
if (userAgent.startsWith("npm/")) return "npm";
|
|
1057
|
-
}
|
|
1058
|
-
const execPath = process.env.npm_execpath;
|
|
1059
|
-
if (execPath) {
|
|
1060
|
-
if (execPath.includes("pnpm")) return "pnpm";
|
|
1061
|
-
if (execPath.includes("yarn")) return "yarn";
|
|
1062
|
-
if (execPath.includes("bun")) return "bun";
|
|
1063
|
-
if (execPath.includes("npm")) return "npm";
|
|
1064
|
-
}
|
|
1065
|
-
return null;
|
|
1066
|
-
}
|
|
1067
|
-
function detectPackageManager(projectPath) {
|
|
1068
|
-
let dir = projectPath;
|
|
1069
|
-
for (; ; ) {
|
|
1070
|
-
if (existsSync3(join3(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
1071
|
-
if (existsSync3(join3(dir, "pnpm-workspace.yaml"))) return "pnpm";
|
|
1072
|
-
if (existsSync3(join3(dir, "yarn.lock"))) return "yarn";
|
|
1073
|
-
if (existsSync3(join3(dir, "bun.lockb"))) return "bun";
|
|
1074
|
-
if (existsSync3(join3(dir, "bun.lock"))) return "bun";
|
|
1075
|
-
if (existsSync3(join3(dir, "package-lock.json"))) return "npm";
|
|
1076
|
-
const parent = dirname(dir);
|
|
1077
|
-
if (parent === dir) break;
|
|
1078
|
-
dir = parent;
|
|
1079
|
-
}
|
|
1080
|
-
return "npm";
|
|
1081
|
-
}
|
|
1082
|
-
function spawnAsync(command, args, cwd) {
|
|
1083
|
-
return new Promise((resolve, reject) => {
|
|
1084
|
-
const child = spawn(command, args, {
|
|
1085
|
-
cwd,
|
|
1086
|
-
stdio: "inherit",
|
|
1087
|
-
shell: process.platform === "win32"
|
|
1088
|
-
});
|
|
1089
|
-
child.on("error", reject);
|
|
1090
|
-
child.on("close", (code) => {
|
|
1091
|
-
if (code === 0) resolve();
|
|
1092
|
-
else
|
|
1093
|
-
reject(new Error(`${command} ${args.join(" ")} exited with ${code}`));
|
|
1094
|
-
});
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
async function installDependencies(pm, projectPath, packages) {
|
|
1098
|
-
if (!packages.length) return;
|
|
1099
|
-
switch (pm) {
|
|
1100
|
-
case "pnpm":
|
|
1101
|
-
await spawnAsync("pnpm", ["add", ...packages], projectPath);
|
|
1102
|
-
return;
|
|
1103
|
-
case "yarn":
|
|
1104
|
-
await spawnAsync("yarn", ["add", ...packages], projectPath);
|
|
1105
|
-
return;
|
|
1106
|
-
case "bun":
|
|
1107
|
-
await spawnAsync("bun", ["add", ...packages], projectPath);
|
|
1108
|
-
return;
|
|
1109
|
-
case "npm":
|
|
1110
|
-
default:
|
|
1111
|
-
await spawnAsync("npm", ["install", "--save", ...packages], projectPath);
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
1065
|
// src/utils/eslint-config-inject.ts
|
|
1117
|
-
import { existsSync as
|
|
1118
|
-
import { join as
|
|
1066
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1067
|
+
import { join as join3, relative as relative2, dirname } from "path";
|
|
1119
1068
|
import { parseExpression, parseModule, generateCode } from "magicast";
|
|
1120
1069
|
import { findWorkspaceRoot } from "uilint-core/node";
|
|
1121
1070
|
var CONFIG_EXTENSIONS = [".ts", ".mjs", ".js", ".cjs"];
|
|
1122
1071
|
function findEslintConfigFile(projectPath) {
|
|
1123
1072
|
for (const ext of CONFIG_EXTENSIONS) {
|
|
1124
|
-
const configPath =
|
|
1125
|
-
if (
|
|
1073
|
+
const configPath = join3(projectPath, `eslint.config${ext}`);
|
|
1074
|
+
if (existsSync3(configPath)) {
|
|
1126
1075
|
return configPath;
|
|
1127
1076
|
}
|
|
1128
1077
|
}
|
|
@@ -1345,8 +1294,8 @@ function chooseUniqueIdentifier(base, used) {
|
|
|
1345
1294
|
function addLocalRuleImportsAst(mod, selectedRules, configPath, rulesRoot, fileExtension = ".js") {
|
|
1346
1295
|
const importNames = /* @__PURE__ */ new Map();
|
|
1347
1296
|
let changed = false;
|
|
1348
|
-
const configDir =
|
|
1349
|
-
const rulesDir =
|
|
1297
|
+
const configDir = dirname(configPath);
|
|
1298
|
+
const rulesDir = join3(rulesRoot, ".uilint", "rules");
|
|
1350
1299
|
const relativeRulesPath = relative2(configDir, rulesDir).replace(/\\/g, "/");
|
|
1351
1300
|
const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
|
|
1352
1301
|
const used = collectTopLevelBindings(mod.$ast);
|
|
@@ -1373,8 +1322,8 @@ function addLocalRuleRequiresAst(program, selectedRules, configPath, rulesRoot,
|
|
|
1373
1322
|
if (!program || program.type !== "Program") {
|
|
1374
1323
|
return { importNames, changed };
|
|
1375
1324
|
}
|
|
1376
|
-
const configDir =
|
|
1377
|
-
const rulesDir =
|
|
1325
|
+
const configDir = dirname(configPath);
|
|
1326
|
+
const rulesDir = join3(rulesRoot, ".uilint", "rules");
|
|
1378
1327
|
const relativeRulesPath = relative2(configDir, rulesDir).replace(/\\/g, "/");
|
|
1379
1328
|
const normalizedRulesPath = relativeRulesPath.startsWith("./") || relativeRulesPath.startsWith("../") ? relativeRulesPath : `./${relativeRulesPath}`;
|
|
1380
1329
|
const used = collectTopLevelBindings(program);
|
|
@@ -1585,10 +1534,10 @@ async function installEslintPlugin(opts) {
|
|
|
1585
1534
|
};
|
|
1586
1535
|
}
|
|
1587
1536
|
let modifiedAst = false;
|
|
1588
|
-
const localRulesDir =
|
|
1537
|
+
const localRulesDir = join3(opts.projectPath, ".uilint", "rules");
|
|
1589
1538
|
const workspaceRoot = findWorkspaceRoot(opts.projectPath);
|
|
1590
|
-
const workspaceRulesDir =
|
|
1591
|
-
const rulesRoot =
|
|
1539
|
+
const workspaceRulesDir = join3(workspaceRoot, ".uilint", "rules");
|
|
1540
|
+
const rulesRoot = existsSync3(localRulesDir) ? opts.projectPath : workspaceRoot;
|
|
1592
1541
|
const isTypeScriptConfig = configPath.endsWith(".ts");
|
|
1593
1542
|
let fileExtension = isTypeScriptConfig ? "" : ".js";
|
|
1594
1543
|
let ruleImportNames;
|
|
@@ -1663,12 +1612,12 @@ async function installEslintPlugin(opts) {
|
|
|
1663
1612
|
async function analyze(projectPath = process.cwd()) {
|
|
1664
1613
|
const workspaceRoot = findWorkspaceRoot2(projectPath);
|
|
1665
1614
|
const packageManager = detectPackageManager(projectPath);
|
|
1666
|
-
const cursorDir =
|
|
1667
|
-
const cursorDirExists =
|
|
1668
|
-
const styleguidePath =
|
|
1669
|
-
const styleguideExists =
|
|
1670
|
-
const commandsDir =
|
|
1671
|
-
const genstyleguideExists =
|
|
1615
|
+
const cursorDir = join4(projectPath, ".cursor");
|
|
1616
|
+
const cursorDirExists = existsSync4(cursorDir);
|
|
1617
|
+
const styleguidePath = join4(projectPath, ".uilint", "styleguide.md");
|
|
1618
|
+
const styleguideExists = existsSync4(styleguidePath);
|
|
1619
|
+
const commandsDir = join4(cursorDir, "commands");
|
|
1620
|
+
const genstyleguideExists = existsSync4(join4(commandsDir, "genstyleguide.md"));
|
|
1672
1621
|
const nextApps = [];
|
|
1673
1622
|
const directDetection = detectNextAppRouter(projectPath);
|
|
1674
1623
|
if (directDetection) {
|
|
@@ -1742,49 +1691,49 @@ async function analyze(projectPath = process.cwd()) {
|
|
|
1742
1691
|
|
|
1743
1692
|
// src/commands/install/execute.ts
|
|
1744
1693
|
import {
|
|
1745
|
-
existsSync as
|
|
1694
|
+
existsSync as existsSync10,
|
|
1746
1695
|
mkdirSync,
|
|
1747
1696
|
writeFileSync as writeFileSync5,
|
|
1748
1697
|
readFileSync as readFileSync8,
|
|
1749
1698
|
unlinkSync,
|
|
1750
1699
|
chmodSync
|
|
1751
1700
|
} from "fs";
|
|
1752
|
-
import { dirname as
|
|
1701
|
+
import { dirname as dirname3 } from "path";
|
|
1753
1702
|
|
|
1754
1703
|
// src/utils/react-inject.ts
|
|
1755
|
-
import { existsSync as
|
|
1756
|
-
import { join as
|
|
1704
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
1705
|
+
import { join as join5 } from "path";
|
|
1757
1706
|
import { parseModule as parseModule2, generateCode as generateCode2 } from "magicast";
|
|
1758
1707
|
function getDefaultCandidates(projectPath, appRoot) {
|
|
1759
1708
|
const viteMainCandidates = [
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1709
|
+
join5(appRoot, "main.tsx"),
|
|
1710
|
+
join5(appRoot, "main.jsx"),
|
|
1711
|
+
join5(appRoot, "main.ts"),
|
|
1712
|
+
join5(appRoot, "main.js")
|
|
1764
1713
|
];
|
|
1765
1714
|
const existingViteMain = viteMainCandidates.filter(
|
|
1766
|
-
(rel) =>
|
|
1715
|
+
(rel) => existsSync5(join5(projectPath, rel))
|
|
1767
1716
|
);
|
|
1768
1717
|
if (existingViteMain.length > 0) return existingViteMain;
|
|
1769
|
-
const viteAppCandidates = [
|
|
1718
|
+
const viteAppCandidates = [join5(appRoot, "App.tsx"), join5(appRoot, "App.jsx")];
|
|
1770
1719
|
const existingViteApp = viteAppCandidates.filter(
|
|
1771
|
-
(rel) =>
|
|
1720
|
+
(rel) => existsSync5(join5(projectPath, rel))
|
|
1772
1721
|
);
|
|
1773
1722
|
if (existingViteApp.length > 0) return existingViteApp;
|
|
1774
1723
|
const layoutCandidates = [
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1724
|
+
join5(appRoot, "layout.tsx"),
|
|
1725
|
+
join5(appRoot, "layout.jsx"),
|
|
1726
|
+
join5(appRoot, "layout.ts"),
|
|
1727
|
+
join5(appRoot, "layout.js")
|
|
1779
1728
|
];
|
|
1780
1729
|
const existingLayouts = layoutCandidates.filter(
|
|
1781
|
-
(rel) =>
|
|
1730
|
+
(rel) => existsSync5(join5(projectPath, rel))
|
|
1782
1731
|
);
|
|
1783
1732
|
if (existingLayouts.length > 0) {
|
|
1784
1733
|
return existingLayouts;
|
|
1785
1734
|
}
|
|
1786
|
-
const pageCandidates = [
|
|
1787
|
-
return pageCandidates.filter((rel) =>
|
|
1735
|
+
const pageCandidates = [join5(appRoot, "page.tsx"), join5(appRoot, "page.jsx")];
|
|
1736
|
+
return pageCandidates.filter((rel) => existsSync5(join5(projectPath, rel)));
|
|
1788
1737
|
}
|
|
1789
1738
|
function isUseClientDirective(stmt) {
|
|
1790
1739
|
return stmt?.type === "ExpressionStatement" && stmt.expression?.type === "StringLiteral" && stmt.expression.value === "use client";
|
|
@@ -1916,7 +1865,7 @@ async function installReactUILintOverlay(opts) {
|
|
|
1916
1865
|
} else {
|
|
1917
1866
|
chosen = candidates[0];
|
|
1918
1867
|
}
|
|
1919
|
-
const absTarget =
|
|
1868
|
+
const absTarget = join5(opts.projectPath, chosen);
|
|
1920
1869
|
const original = readFileSync5(absTarget, "utf-8");
|
|
1921
1870
|
let mod;
|
|
1922
1871
|
try {
|
|
@@ -1949,14 +1898,14 @@ async function installReactUILintOverlay(opts) {
|
|
|
1949
1898
|
}
|
|
1950
1899
|
|
|
1951
1900
|
// src/utils/next-config-inject.ts
|
|
1952
|
-
import { existsSync as
|
|
1953
|
-
import { join as
|
|
1901
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
1902
|
+
import { join as join6 } from "path";
|
|
1954
1903
|
import { parseModule as parseModule3, generateCode as generateCode3 } from "magicast";
|
|
1955
1904
|
var CONFIG_EXTENSIONS2 = [".ts", ".mjs", ".js", ".cjs"];
|
|
1956
1905
|
function findNextConfigFile(projectPath) {
|
|
1957
1906
|
for (const ext of CONFIG_EXTENSIONS2) {
|
|
1958
|
-
const configPath =
|
|
1959
|
-
if (
|
|
1907
|
+
const configPath = join6(projectPath, `next.config${ext}`);
|
|
1908
|
+
if (existsSync6(configPath)) {
|
|
1960
1909
|
return configPath;
|
|
1961
1910
|
}
|
|
1962
1911
|
}
|
|
@@ -2099,14 +2048,14 @@ async function installJsxLocPlugin(opts) {
|
|
|
2099
2048
|
}
|
|
2100
2049
|
|
|
2101
2050
|
// src/utils/vite-config-inject.ts
|
|
2102
|
-
import { existsSync as
|
|
2103
|
-
import { join as
|
|
2051
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
2052
|
+
import { join as join7 } from "path";
|
|
2104
2053
|
import { parseModule as parseModule4, generateCode as generateCode4 } from "magicast";
|
|
2105
2054
|
var CONFIG_EXTENSIONS3 = [".ts", ".mjs", ".js", ".cjs"];
|
|
2106
2055
|
function findViteConfigFile2(projectPath) {
|
|
2107
2056
|
for (const ext of CONFIG_EXTENSIONS3) {
|
|
2108
|
-
const configPath =
|
|
2109
|
-
if (
|
|
2057
|
+
const configPath = join7(projectPath, `vite.config${ext}`);
|
|
2058
|
+
if (existsSync7(configPath)) return configPath;
|
|
2110
2059
|
}
|
|
2111
2060
|
return null;
|
|
2112
2061
|
}
|
|
@@ -2310,9 +2259,9 @@ async function installViteJsxLocPlugin(opts) {
|
|
|
2310
2259
|
}
|
|
2311
2260
|
|
|
2312
2261
|
// src/utils/next-routes.ts
|
|
2313
|
-
import { existsSync as
|
|
2262
|
+
import { existsSync as existsSync8 } from "fs";
|
|
2314
2263
|
import { mkdir, writeFile } from "fs/promises";
|
|
2315
|
-
import { join as
|
|
2264
|
+
import { join as join8 } from "path";
|
|
2316
2265
|
var DEV_SOURCE_ROUTE_TS = `/**
|
|
2317
2266
|
* Dev-only API route for fetching source files
|
|
2318
2267
|
*
|
|
@@ -2768,40 +2717,40 @@ export async function GET(request: NextRequest) {
|
|
|
2768
2717
|
}
|
|
2769
2718
|
`;
|
|
2770
2719
|
async function writeRouteFile(absPath, relPath, content, opts) {
|
|
2771
|
-
if (
|
|
2720
|
+
if (existsSync8(absPath) && !opts.force) return;
|
|
2772
2721
|
await writeFile(absPath, content, "utf-8");
|
|
2773
2722
|
}
|
|
2774
2723
|
async function installNextUILintRoutes(opts) {
|
|
2775
|
-
const baseRel =
|
|
2776
|
-
const baseAbs =
|
|
2777
|
-
await mkdir(
|
|
2724
|
+
const baseRel = join8(opts.appRoot, "api", ".uilint");
|
|
2725
|
+
const baseAbs = join8(opts.projectPath, baseRel);
|
|
2726
|
+
await mkdir(join8(baseAbs, "source"), { recursive: true });
|
|
2778
2727
|
await writeRouteFile(
|
|
2779
|
-
|
|
2780
|
-
|
|
2728
|
+
join8(baseAbs, "source", "route.ts"),
|
|
2729
|
+
join8(baseRel, "source", "route.ts"),
|
|
2781
2730
|
DEV_SOURCE_ROUTE_TS,
|
|
2782
2731
|
opts
|
|
2783
2732
|
);
|
|
2784
|
-
await mkdir(
|
|
2733
|
+
await mkdir(join8(baseAbs, "screenshots"), { recursive: true });
|
|
2785
2734
|
await writeRouteFile(
|
|
2786
|
-
|
|
2787
|
-
|
|
2735
|
+
join8(baseAbs, "screenshots", "route.ts"),
|
|
2736
|
+
join8(baseRel, "screenshots", "route.ts"),
|
|
2788
2737
|
SCREENSHOT_ROUTE_TS,
|
|
2789
2738
|
opts
|
|
2790
2739
|
);
|
|
2791
2740
|
}
|
|
2792
2741
|
|
|
2793
2742
|
// src/utils/prettier.ts
|
|
2794
|
-
import { existsSync as
|
|
2795
|
-
import { spawn
|
|
2796
|
-
import { join as
|
|
2743
|
+
import { existsSync as existsSync9 } from "fs";
|
|
2744
|
+
import { spawn } from "child_process";
|
|
2745
|
+
import { join as join9, dirname as dirname2 } from "path";
|
|
2797
2746
|
function getPrettierPath(projectPath) {
|
|
2798
|
-
const localPath =
|
|
2799
|
-
if (
|
|
2747
|
+
const localPath = join9(projectPath, "node_modules", ".bin", "prettier");
|
|
2748
|
+
if (existsSync9(localPath)) return localPath;
|
|
2800
2749
|
let dir = projectPath;
|
|
2801
2750
|
for (let i = 0; i < 10; i++) {
|
|
2802
|
-
const binPath =
|
|
2803
|
-
if (
|
|
2804
|
-
const parent =
|
|
2751
|
+
const binPath = join9(dir, "node_modules", ".bin", "prettier");
|
|
2752
|
+
if (existsSync9(binPath)) return binPath;
|
|
2753
|
+
const parent = dirname2(dir);
|
|
2805
2754
|
if (parent === dir) break;
|
|
2806
2755
|
dir = parent;
|
|
2807
2756
|
}
|
|
@@ -2827,7 +2776,7 @@ async function formatWithPrettier(filePath, projectPath) {
|
|
|
2827
2776
|
const runner = getPmRunner(pm);
|
|
2828
2777
|
return new Promise((resolve) => {
|
|
2829
2778
|
const args = [...runner.args, "prettier", "--write", filePath];
|
|
2830
|
-
const child =
|
|
2779
|
+
const child = spawn(runner.command, args, {
|
|
2831
2780
|
cwd: projectPath,
|
|
2832
2781
|
stdio: "pipe",
|
|
2833
2782
|
shell: process.platform === "win32"
|
|
@@ -2849,7 +2798,7 @@ async function formatWithPrettier(filePath, projectPath) {
|
|
|
2849
2798
|
});
|
|
2850
2799
|
}
|
|
2851
2800
|
return new Promise((resolve) => {
|
|
2852
|
-
const child =
|
|
2801
|
+
const child = spawn(prettierPath, ["--write", filePath], {
|
|
2853
2802
|
cwd: projectPath,
|
|
2854
2803
|
stdio: "pipe",
|
|
2855
2804
|
shell: process.platform === "win32"
|
|
@@ -2882,7 +2831,7 @@ async function formatFilesWithPrettier(filePaths, projectPath) {
|
|
|
2882
2831
|
const runner = getPmRunner(pm);
|
|
2883
2832
|
return new Promise((resolve) => {
|
|
2884
2833
|
const args = [...runner.args, "prettier", "--write", ...filePaths];
|
|
2885
|
-
const child =
|
|
2834
|
+
const child = spawn(runner.command, args, {
|
|
2886
2835
|
cwd: projectPath,
|
|
2887
2836
|
stdio: "pipe",
|
|
2888
2837
|
shell: process.platform === "win32"
|
|
@@ -2900,7 +2849,7 @@ async function formatFilesWithPrettier(filePaths, projectPath) {
|
|
|
2900
2849
|
});
|
|
2901
2850
|
}
|
|
2902
2851
|
return new Promise((resolve) => {
|
|
2903
|
-
const child =
|
|
2852
|
+
const child = spawn(prettierPath, ["--write", ...filePaths], {
|
|
2904
2853
|
cwd: projectPath,
|
|
2905
2854
|
stdio: "pipe",
|
|
2906
2855
|
shell: process.platform === "win32"
|
|
@@ -2942,7 +2891,7 @@ async function executeAction(action, options) {
|
|
|
2942
2891
|
wouldDo: `Create directory: ${action.path}`
|
|
2943
2892
|
};
|
|
2944
2893
|
}
|
|
2945
|
-
if (!
|
|
2894
|
+
if (!existsSync10(action.path)) {
|
|
2946
2895
|
mkdirSync(action.path, { recursive: true });
|
|
2947
2896
|
}
|
|
2948
2897
|
return { action, success: true };
|
|
@@ -2955,8 +2904,8 @@ async function executeAction(action, options) {
|
|
|
2955
2904
|
wouldDo: `Create file: ${action.path}${action.permissions ? ` (mode: ${action.permissions.toString(8)})` : ""}`
|
|
2956
2905
|
};
|
|
2957
2906
|
}
|
|
2958
|
-
const dir =
|
|
2959
|
-
if (!
|
|
2907
|
+
const dir = dirname3(action.path);
|
|
2908
|
+
if (!existsSync10(dir)) {
|
|
2960
2909
|
mkdirSync(dir, { recursive: true });
|
|
2961
2910
|
}
|
|
2962
2911
|
writeFileSync5(action.path, action.content, "utf-8");
|
|
@@ -2974,15 +2923,15 @@ async function executeAction(action, options) {
|
|
|
2974
2923
|
};
|
|
2975
2924
|
}
|
|
2976
2925
|
let existing = {};
|
|
2977
|
-
if (
|
|
2926
|
+
if (existsSync10(action.path)) {
|
|
2978
2927
|
try {
|
|
2979
2928
|
existing = JSON.parse(readFileSync8(action.path, "utf-8"));
|
|
2980
2929
|
} catch {
|
|
2981
2930
|
}
|
|
2982
2931
|
}
|
|
2983
2932
|
const merged = deepMerge(existing, action.merge);
|
|
2984
|
-
const dir =
|
|
2985
|
-
if (!
|
|
2933
|
+
const dir = dirname3(action.path);
|
|
2934
|
+
if (!existsSync10(dir)) {
|
|
2986
2935
|
mkdirSync(dir, { recursive: true });
|
|
2987
2936
|
}
|
|
2988
2937
|
writeFileSync5(action.path, JSON.stringify(merged, null, 2), "utf-8");
|
|
@@ -2996,7 +2945,7 @@ async function executeAction(action, options) {
|
|
|
2996
2945
|
wouldDo: `Delete file: ${action.path}`
|
|
2997
2946
|
};
|
|
2998
2947
|
}
|
|
2999
|
-
if (
|
|
2948
|
+
if (existsSync10(action.path)) {
|
|
3000
2949
|
unlinkSync(action.path);
|
|
3001
2950
|
}
|
|
3002
2951
|
return { action, success: true };
|
|
@@ -3009,7 +2958,7 @@ async function executeAction(action, options) {
|
|
|
3009
2958
|
wouldDo: `Append to file: ${action.path}`
|
|
3010
2959
|
};
|
|
3011
2960
|
}
|
|
3012
|
-
if (
|
|
2961
|
+
if (existsSync10(action.path)) {
|
|
3013
2962
|
const content = readFileSync8(action.path, "utf-8");
|
|
3014
2963
|
if (action.ifNotContains && content.includes(action.ifNotContains)) {
|
|
3015
2964
|
return { action, success: true };
|
|
@@ -3371,11 +3320,9 @@ async function execute(plan, options = {}) {
|
|
|
3371
3320
|
|
|
3372
3321
|
// src/commands/install-ui.tsx
|
|
3373
3322
|
import { ruleRegistry as ruleRegistry3 } from "uilint-eslint";
|
|
3374
|
-
import { existsSync as existsSync13 } from "fs";
|
|
3375
|
-
import { join as join14 } from "path";
|
|
3376
3323
|
|
|
3377
3324
|
// src/commands/install/installers/genstyleguide.ts
|
|
3378
|
-
import { join as
|
|
3325
|
+
import { join as join10 } from "path";
|
|
3379
3326
|
var genstyleguideInstaller = {
|
|
3380
3327
|
id: "genstyleguide",
|
|
3381
3328
|
name: "/genstyleguide command",
|
|
@@ -3385,7 +3332,7 @@ var genstyleguideInstaller = {
|
|
|
3385
3332
|
return true;
|
|
3386
3333
|
},
|
|
3387
3334
|
getTargets(project) {
|
|
3388
|
-
const commandPath =
|
|
3335
|
+
const commandPath = join10(project.cursorDir.path, "commands", "genstyleguide.md");
|
|
3389
3336
|
const isInstalled = project.commands.genstyleguide;
|
|
3390
3337
|
return [
|
|
3391
3338
|
{
|
|
@@ -3398,7 +3345,7 @@ var genstyleguideInstaller = {
|
|
|
3398
3345
|
},
|
|
3399
3346
|
plan(targets, config, project) {
|
|
3400
3347
|
const actions = [];
|
|
3401
|
-
const commandsDir =
|
|
3348
|
+
const commandsDir = join10(project.cursorDir.path, "commands");
|
|
3402
3349
|
if (!project.cursorDir.exists) {
|
|
3403
3350
|
actions.push({
|
|
3404
3351
|
type: "create_directory",
|
|
@@ -3411,7 +3358,7 @@ var genstyleguideInstaller = {
|
|
|
3411
3358
|
});
|
|
3412
3359
|
actions.push({
|
|
3413
3360
|
type: "create_file",
|
|
3414
|
-
path:
|
|
3361
|
+
path: join10(commandsDir, "genstyleguide.md"),
|
|
3415
3362
|
content: GENSTYLEGUIDE_COMMAND_MD
|
|
3416
3363
|
});
|
|
3417
3364
|
return {
|
|
@@ -3441,8 +3388,8 @@ var genstyleguideInstaller = {
|
|
|
3441
3388
|
};
|
|
3442
3389
|
|
|
3443
3390
|
// src/commands/install/installers/skill.ts
|
|
3444
|
-
import { existsSync as
|
|
3445
|
-
import { join as
|
|
3391
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3392
|
+
import { join as join11 } from "path";
|
|
3446
3393
|
var skillInstaller = {
|
|
3447
3394
|
id: "skill",
|
|
3448
3395
|
name: "UI Consistency Agent skill",
|
|
@@ -3452,9 +3399,9 @@ var skillInstaller = {
|
|
|
3452
3399
|
return true;
|
|
3453
3400
|
},
|
|
3454
3401
|
getTargets(project) {
|
|
3455
|
-
const skillsDir =
|
|
3456
|
-
const skillMdPath =
|
|
3457
|
-
const isInstalled =
|
|
3402
|
+
const skillsDir = join11(project.cursorDir.path, "skills", "ui-consistency-enforcer");
|
|
3403
|
+
const skillMdPath = join11(skillsDir, "SKILL.md");
|
|
3404
|
+
const isInstalled = existsSync11(skillMdPath);
|
|
3458
3405
|
return [
|
|
3459
3406
|
{
|
|
3460
3407
|
id: "ui-consistency-skill",
|
|
@@ -3473,21 +3420,21 @@ var skillInstaller = {
|
|
|
3473
3420
|
path: project.cursorDir.path
|
|
3474
3421
|
});
|
|
3475
3422
|
}
|
|
3476
|
-
const skillsDir =
|
|
3423
|
+
const skillsDir = join11(project.cursorDir.path, "skills");
|
|
3477
3424
|
actions.push({
|
|
3478
3425
|
type: "create_directory",
|
|
3479
3426
|
path: skillsDir
|
|
3480
3427
|
});
|
|
3481
3428
|
try {
|
|
3482
3429
|
const skill = loadSkill("ui-consistency-enforcer");
|
|
3483
|
-
const skillDir =
|
|
3430
|
+
const skillDir = join11(skillsDir, skill.name);
|
|
3484
3431
|
actions.push({
|
|
3485
3432
|
type: "create_directory",
|
|
3486
3433
|
path: skillDir
|
|
3487
3434
|
});
|
|
3488
3435
|
for (const file of skill.files) {
|
|
3489
|
-
const filePath =
|
|
3490
|
-
const fileDir =
|
|
3436
|
+
const filePath = join11(skillDir, file.relativePath);
|
|
3437
|
+
const fileDir = join11(
|
|
3491
3438
|
skillDir,
|
|
3492
3439
|
file.relativePath.split("/").slice(0, -1).join("/")
|
|
3493
3440
|
);
|
|
@@ -3544,8 +3491,21 @@ var skillInstaller = {
|
|
|
3544
3491
|
};
|
|
3545
3492
|
|
|
3546
3493
|
// src/commands/install/installers/eslint.ts
|
|
3547
|
-
import { join as
|
|
3494
|
+
import { join as join12 } from "path";
|
|
3548
3495
|
import { ruleRegistry as ruleRegistry2, getRulesByCategory as getRulesByCategory2 } from "uilint-eslint";
|
|
3496
|
+
function getUpgradeInfo(configuredRuleIds) {
|
|
3497
|
+
const configuredSet = new Set(configuredRuleIds);
|
|
3498
|
+
const allRuleIds = ruleRegistry2.map((r) => r.id);
|
|
3499
|
+
const missingRules = allRuleIds.filter((id) => !configuredSet.has(id));
|
|
3500
|
+
if (missingRules.length === 0) {
|
|
3501
|
+
return void 0;
|
|
3502
|
+
}
|
|
3503
|
+
const summary = missingRules.length === 1 ? "1 new rule available" : `${missingRules.length} new rules available`;
|
|
3504
|
+
return {
|
|
3505
|
+
missingRules,
|
|
3506
|
+
summary
|
|
3507
|
+
};
|
|
3508
|
+
}
|
|
3549
3509
|
function toInstallSpecifier(pkgName) {
|
|
3550
3510
|
return pkgName;
|
|
3551
3511
|
}
|
|
@@ -3566,13 +3526,22 @@ var eslintInstaller = {
|
|
|
3566
3526
|
return project.packages.some((pkg) => pkg.eslintConfigPath !== null);
|
|
3567
3527
|
},
|
|
3568
3528
|
getTargets(project) {
|
|
3569
|
-
return project.packages.filter((pkg) => pkg.eslintConfigPath !== null).map((pkg) =>
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3529
|
+
return project.packages.filter((pkg) => pkg.eslintConfigPath !== null).map((pkg) => {
|
|
3530
|
+
const upgradeInfo = pkg.hasUilintRules ? getUpgradeInfo(pkg.configuredRuleIds) : void 0;
|
|
3531
|
+
let hint = pkg.eslintConfigFilename || "ESLint config detected";
|
|
3532
|
+
if (upgradeInfo?.summary) {
|
|
3533
|
+
hint = `${hint} \xB7 ${upgradeInfo.summary}`;
|
|
3534
|
+
}
|
|
3535
|
+
return {
|
|
3536
|
+
id: `eslint-${pkg.name}`,
|
|
3537
|
+
label: pkg.name,
|
|
3538
|
+
path: pkg.path,
|
|
3539
|
+
hint,
|
|
3540
|
+
isInstalled: pkg.hasUilintRules,
|
|
3541
|
+
canUpgrade: upgradeInfo !== void 0,
|
|
3542
|
+
upgradeInfo
|
|
3543
|
+
};
|
|
3544
|
+
});
|
|
3576
3545
|
},
|
|
3577
3546
|
async configure(targets, project) {
|
|
3578
3547
|
const staticRules = getRulesByCategory2("static");
|
|
@@ -3698,14 +3667,14 @@ var eslintInstaller = {
|
|
|
3698
3667
|
for (const target of targets) {
|
|
3699
3668
|
const pkgInfo = project.packages.find((p) => p.path === target.path);
|
|
3700
3669
|
if (!pkgInfo || !pkgInfo.eslintConfigPath) continue;
|
|
3701
|
-
const rulesDir =
|
|
3670
|
+
const rulesDir = join12(target.path, ".uilint", "rules");
|
|
3702
3671
|
actions.push({
|
|
3703
3672
|
type: "create_directory",
|
|
3704
3673
|
path: rulesDir
|
|
3705
3674
|
});
|
|
3706
3675
|
dependencies.push({
|
|
3707
3676
|
packagePath: target.path,
|
|
3708
|
-
packageManager:
|
|
3677
|
+
packageManager: detectPackageManager(target.path),
|
|
3709
3678
|
packages: [toInstallSpecifier("uilint-eslint"), "typescript-eslint"]
|
|
3710
3679
|
});
|
|
3711
3680
|
actions.push({
|
|
@@ -3716,7 +3685,7 @@ var eslintInstaller = {
|
|
|
3716
3685
|
hasExistingRules: pkgInfo.hasUilintRules
|
|
3717
3686
|
});
|
|
3718
3687
|
}
|
|
3719
|
-
const gitignorePath =
|
|
3688
|
+
const gitignorePath = join12(project.workspaceRoot, ".gitignore");
|
|
3720
3689
|
actions.push({
|
|
3721
3690
|
type: "append_to_file",
|
|
3722
3691
|
path: gitignorePath,
|
|
@@ -3973,56 +3942,6 @@ function selectionsToUserChoices(selections, project, eslintRules) {
|
|
|
3973
3942
|
function isInteractiveTerminal() {
|
|
3974
3943
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
3975
3944
|
}
|
|
3976
|
-
function getRecommendedCommand(pm) {
|
|
3977
|
-
switch (pm) {
|
|
3978
|
-
case "pnpm":
|
|
3979
|
-
return "pnpm dlx uilint install";
|
|
3980
|
-
case "yarn":
|
|
3981
|
-
return "yarn dlx uilint install";
|
|
3982
|
-
case "bun":
|
|
3983
|
-
return "bunx uilint install";
|
|
3984
|
-
case "npm":
|
|
3985
|
-
default:
|
|
3986
|
-
return "npx uilint install";
|
|
3987
|
-
}
|
|
3988
|
-
}
|
|
3989
|
-
async function warnOnPackageManagerMismatch(projectPromise) {
|
|
3990
|
-
const executionPm = detectExecutionPackageManager();
|
|
3991
|
-
if (!executionPm) return;
|
|
3992
|
-
const project = await projectPromise;
|
|
3993
|
-
const packageManagers = /* @__PURE__ */ new Set();
|
|
3994
|
-
const hasRootPackageJson = existsSync13(join14(project.projectPath, "package.json"));
|
|
3995
|
-
if (hasRootPackageJson) {
|
|
3996
|
-
packageManagers.add(project.packageManager);
|
|
3997
|
-
} else {
|
|
3998
|
-
for (const pkg of project.packages) {
|
|
3999
|
-
const pm = detectPackageManager(pkg.path);
|
|
4000
|
-
packageManagers.add(pm);
|
|
4001
|
-
}
|
|
4002
|
-
}
|
|
4003
|
-
const specificPackageManagers = Array.from(packageManagers).filter(
|
|
4004
|
-
(pm) => pm !== "npm" || hasRootPackageJson
|
|
4005
|
-
);
|
|
4006
|
-
if (specificPackageManagers.length === 0) return;
|
|
4007
|
-
if (specificPackageManagers.includes(executionPm)) return;
|
|
4008
|
-
const primaryPm = specificPackageManagers[0];
|
|
4009
|
-
const recommendedCmd = getRecommendedCommand(primaryPm);
|
|
4010
|
-
const pmList = specificPackageManagers.length === 1 ? specificPackageManagers[0] : specificPackageManagers.join(", ");
|
|
4011
|
-
printBox(
|
|
4012
|
-
"Package manager mismatch detected",
|
|
4013
|
-
[
|
|
4014
|
-
`This project uses ${pmList}, but you ran this command with ${executionPm}.`,
|
|
4015
|
-
"",
|
|
4016
|
-
`Running with ${executionPm} may create unwanted lockfiles.`,
|
|
4017
|
-
"",
|
|
4018
|
-
"Recommended:",
|
|
4019
|
-
` ${recommendedCmd}`,
|
|
4020
|
-
"",
|
|
4021
|
-
"Continuing anyway..."
|
|
4022
|
-
],
|
|
4023
|
-
"warning"
|
|
4024
|
-
);
|
|
4025
|
-
}
|
|
4026
3945
|
async function installUI(options = {}, executeOptions = {}) {
|
|
4027
3946
|
const projectPath = process.cwd();
|
|
4028
3947
|
if (!isInteractiveTerminal()) {
|
|
@@ -4031,7 +3950,6 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4031
3950
|
process.exit(1);
|
|
4032
3951
|
}
|
|
4033
3952
|
const projectPromise = analyze(projectPath);
|
|
4034
|
-
await warnOnPackageManagerMismatch(projectPromise);
|
|
4035
3953
|
const { waitUntilExit } = render(
|
|
4036
3954
|
/* @__PURE__ */ jsx6(
|
|
4037
3955
|
InstallApp,
|
|
@@ -4044,7 +3962,7 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4044
3962
|
console.log("\nNo items selected for installation");
|
|
4045
3963
|
process.exit(0);
|
|
4046
3964
|
}
|
|
4047
|
-
const { createPlan } = await import("./plan-
|
|
3965
|
+
const { createPlan } = await import("./plan-G43256ML.js");
|
|
4048
3966
|
const plan = createPlan(project, choices, { force: options.force });
|
|
4049
3967
|
const result = await execute(plan, {
|
|
4050
3968
|
...executeOptions,
|
|
@@ -4069,4 +3987,4 @@ async function installUI(options = {}, executeOptions = {}) {
|
|
|
4069
3987
|
export {
|
|
4070
3988
|
installUI
|
|
4071
3989
|
};
|
|
4072
|
-
//# sourceMappingURL=install-ui-
|
|
3990
|
+
//# sourceMappingURL=install-ui-H2KOQ6SP.js.map
|