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
package/dist/index.js
CHANGED
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
logSuccess,
|
|
26
26
|
logWarning,
|
|
27
27
|
note,
|
|
28
|
-
outro,
|
|
29
28
|
pc,
|
|
30
29
|
withSpinner
|
|
31
30
|
} from "./chunk-CZNPG4UI.js";
|
|
@@ -84,29 +83,6 @@ function isHtmlLikeExtension(ext) {
|
|
|
84
83
|
function isJsonLikeExtension(ext) {
|
|
85
84
|
return ext === ".json";
|
|
86
85
|
}
|
|
87
|
-
async function getInput(options) {
|
|
88
|
-
if (options.inputJson) {
|
|
89
|
-
return parseCLIInput(options.inputJson);
|
|
90
|
-
}
|
|
91
|
-
if (options.inputFile) {
|
|
92
|
-
const filePath = resolvePathSpecifier(options.inputFile, process.cwd());
|
|
93
|
-
if (!existsSync(filePath)) {
|
|
94
|
-
throw new Error(`File not found: ${options.inputFile}`);
|
|
95
|
-
}
|
|
96
|
-
const content = await readFile(filePath, "utf-8");
|
|
97
|
-
return parseCLIInput(content);
|
|
98
|
-
}
|
|
99
|
-
if (hasStdin()) {
|
|
100
|
-
const content = await readStdin();
|
|
101
|
-
if (!content.trim()) {
|
|
102
|
-
throw new Error("No input provided via stdin");
|
|
103
|
-
}
|
|
104
|
-
return parseCLIInput(content);
|
|
105
|
-
}
|
|
106
|
-
throw new Error(
|
|
107
|
-
"No input provided. Use --input-file, --input-json, or pipe content to stdin."
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
86
|
async function getScanInput(options) {
|
|
111
87
|
if (options.inputJson) {
|
|
112
88
|
return {
|
|
@@ -268,8 +244,8 @@ async function initializeLangfuseIfEnabled() {
|
|
|
268
244
|
},
|
|
269
245
|
{ asType: "generation" }
|
|
270
246
|
);
|
|
271
|
-
await new Promise((
|
|
272
|
-
resolveTrace =
|
|
247
|
+
await new Promise((resolve10) => {
|
|
248
|
+
resolveTrace = resolve10;
|
|
273
249
|
});
|
|
274
250
|
if (endData && generationRef) {
|
|
275
251
|
const usageDetails = endData.usage ? Object.fromEntries(
|
|
@@ -1185,14 +1161,14 @@ import {
|
|
|
1185
1161
|
} from "uilint-core";
|
|
1186
1162
|
import { ensureOllamaReady as ensureOllamaReady3 } from "uilint-core/node";
|
|
1187
1163
|
async function readStdin2() {
|
|
1188
|
-
return new Promise((
|
|
1164
|
+
return new Promise((resolve10) => {
|
|
1189
1165
|
let data = "";
|
|
1190
1166
|
const rl = createInterface({ input: process.stdin });
|
|
1191
1167
|
rl.on("line", (line) => {
|
|
1192
1168
|
data += line;
|
|
1193
1169
|
});
|
|
1194
1170
|
rl.on("close", () => {
|
|
1195
|
-
|
|
1171
|
+
resolve10(data);
|
|
1196
1172
|
});
|
|
1197
1173
|
});
|
|
1198
1174
|
}
|
|
@@ -1288,128 +1264,6 @@ async function consistency(options) {
|
|
|
1288
1264
|
}
|
|
1289
1265
|
}
|
|
1290
1266
|
|
|
1291
|
-
// src/commands/update.ts
|
|
1292
|
-
import { dirname as dirname3, resolve as resolve4 } from "path";
|
|
1293
|
-
import {
|
|
1294
|
-
createStyleSummary as createStyleSummary2,
|
|
1295
|
-
parseStyleGuide,
|
|
1296
|
-
mergeStyleGuides,
|
|
1297
|
-
styleGuideToMarkdown
|
|
1298
|
-
} from "uilint-core";
|
|
1299
|
-
import {
|
|
1300
|
-
readStyleGuide as readStyleGuide3,
|
|
1301
|
-
writeStyleGuide,
|
|
1302
|
-
findStyleGuidePath as findStyleGuidePath3,
|
|
1303
|
-
ensureOllamaReady as ensureOllamaReady4,
|
|
1304
|
-
readTailwindThemeTokens as readTailwindThemeTokens2
|
|
1305
|
-
} from "uilint-core/node";
|
|
1306
|
-
async function update(options) {
|
|
1307
|
-
intro("Update Style Guide");
|
|
1308
|
-
try {
|
|
1309
|
-
const projectPath = process.cwd();
|
|
1310
|
-
const styleGuidePath = options.styleguide || findStyleGuidePath3(projectPath);
|
|
1311
|
-
if (!styleGuidePath) {
|
|
1312
|
-
logError("No style guide found");
|
|
1313
|
-
note(
|
|
1314
|
-
`Create ${pc.cyan(
|
|
1315
|
-
".uilint/styleguide.md"
|
|
1316
|
-
)} first (recommended: run ${pc.cyan("/genstyleguide")} in Cursor).`,
|
|
1317
|
-
"Tip"
|
|
1318
|
-
);
|
|
1319
|
-
await flushLangfuse();
|
|
1320
|
-
process.exit(1);
|
|
1321
|
-
}
|
|
1322
|
-
logInfo(`Using styleguide: ${pc.dim(styleGuidePath)}`);
|
|
1323
|
-
const existingContent = await readStyleGuide3(styleGuidePath);
|
|
1324
|
-
const existingGuide = parseStyleGuide(existingContent);
|
|
1325
|
-
let snapshot;
|
|
1326
|
-
try {
|
|
1327
|
-
snapshot = await withSpinner("Analyzing project", async () => {
|
|
1328
|
-
return await getInput(options);
|
|
1329
|
-
});
|
|
1330
|
-
} catch {
|
|
1331
|
-
logError("No input provided. Use --input-file or pipe HTML to stdin.");
|
|
1332
|
-
await flushLangfuse();
|
|
1333
|
-
process.exit(1);
|
|
1334
|
-
}
|
|
1335
|
-
logInfo(`Found ${pc.cyan(String(snapshot.elementCount))} elements`);
|
|
1336
|
-
const tailwindSearchDir = options.inputFile ? dirname3(resolve4(projectPath, options.inputFile)) : projectPath;
|
|
1337
|
-
const tailwindTheme = readTailwindThemeTokens2(tailwindSearchDir);
|
|
1338
|
-
if (options.llm) {
|
|
1339
|
-
await withSpinner("Preparing Ollama", async () => {
|
|
1340
|
-
await ensureOllamaReady4();
|
|
1341
|
-
});
|
|
1342
|
-
const result = await withSpinner(
|
|
1343
|
-
"Analyzing styles with LLM",
|
|
1344
|
-
async () => {
|
|
1345
|
-
const client = await createLLMClient({});
|
|
1346
|
-
const styleSummary = createStyleSummary2(snapshot.styles, {
|
|
1347
|
-
html: snapshot.html,
|
|
1348
|
-
tailwindTheme
|
|
1349
|
-
});
|
|
1350
|
-
return await client.analyzeStyles(styleSummary, existingContent);
|
|
1351
|
-
}
|
|
1352
|
-
);
|
|
1353
|
-
if (result.issues.length > 0) {
|
|
1354
|
-
const suggestions = result.issues.map((issue) => {
|
|
1355
|
-
let line = `\u2022 ${issue.message}`;
|
|
1356
|
-
if (issue.suggestion) {
|
|
1357
|
-
line += `
|
|
1358
|
-
${pc.cyan("\u2192")} ${issue.suggestion}`;
|
|
1359
|
-
}
|
|
1360
|
-
return line;
|
|
1361
|
-
});
|
|
1362
|
-
note(
|
|
1363
|
-
suggestions.join("\n\n"),
|
|
1364
|
-
`Found ${result.issues.length} suggestion(s)`
|
|
1365
|
-
);
|
|
1366
|
-
logInfo("Edit the styleguide manually to apply these changes.");
|
|
1367
|
-
outro("Analysis complete");
|
|
1368
|
-
} else {
|
|
1369
|
-
logSuccess("Style guide is up to date!");
|
|
1370
|
-
outro("No changes needed");
|
|
1371
|
-
}
|
|
1372
|
-
} else {
|
|
1373
|
-
const updatedContent = await withSpinner("Merging styles", async () => {
|
|
1374
|
-
const mergedColors = new Map(snapshot.styles.colors);
|
|
1375
|
-
for (const m of (snapshot.html || "").matchAll(/#[A-Fa-f0-9]{6}\b/g)) {
|
|
1376
|
-
const hex = (m[0] || "").toUpperCase();
|
|
1377
|
-
if (!hex) continue;
|
|
1378
|
-
mergedColors.set(hex, (mergedColors.get(hex) || 0) + 1);
|
|
1379
|
-
}
|
|
1380
|
-
const detectedColors = [...mergedColors.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([value], index) => ({
|
|
1381
|
-
name: `Color ${index + 1}`,
|
|
1382
|
-
value: value.toUpperCase(),
|
|
1383
|
-
usage: ""
|
|
1384
|
-
}));
|
|
1385
|
-
const detectedGuide = {
|
|
1386
|
-
colors: detectedColors,
|
|
1387
|
-
typography: [],
|
|
1388
|
-
spacing: [],
|
|
1389
|
-
components: []
|
|
1390
|
-
};
|
|
1391
|
-
const mergedGuide = mergeStyleGuides(existingGuide, detectedGuide);
|
|
1392
|
-
return styleGuideToMarkdown(mergedGuide);
|
|
1393
|
-
});
|
|
1394
|
-
if (updatedContent === existingContent) {
|
|
1395
|
-
logSuccess("Style guide is already up to date!");
|
|
1396
|
-
outro("No changes needed");
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
await withSpinner("Writing styleguide", async () => {
|
|
1400
|
-
await writeStyleGuide(styleGuidePath, updatedContent);
|
|
1401
|
-
});
|
|
1402
|
-
note(`Updated: ${pc.dim(styleGuidePath)}`, "Success");
|
|
1403
|
-
outro("Style guide updated!");
|
|
1404
|
-
}
|
|
1405
|
-
} catch (error) {
|
|
1406
|
-
logError(error instanceof Error ? error.message : "Update failed");
|
|
1407
|
-
await flushLangfuse();
|
|
1408
|
-
process.exit(1);
|
|
1409
|
-
}
|
|
1410
|
-
await flushLangfuse();
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
1267
|
// src/commands/serve.ts
|
|
1414
1268
|
import {
|
|
1415
1269
|
existsSync as existsSync5,
|
|
@@ -1422,7 +1276,7 @@ import {
|
|
|
1422
1276
|
} from "fs";
|
|
1423
1277
|
import { createServer } from "http";
|
|
1424
1278
|
import { createRequire as createRequire3 } from "module";
|
|
1425
|
-
import { dirname as
|
|
1279
|
+
import { dirname as dirname4, resolve as resolve5, relative as relative2, join as join3, parse } from "path";
|
|
1426
1280
|
import { URL } from "url";
|
|
1427
1281
|
import { WebSocketServer, WebSocket } from "ws";
|
|
1428
1282
|
import { watch } from "chokidar";
|
|
@@ -1689,7 +1543,7 @@ import { ruleRegistry } from "uilint-eslint";
|
|
|
1689
1543
|
// src/utils/eslint-utils.ts
|
|
1690
1544
|
import { existsSync as existsSync4, readFileSync } from "fs";
|
|
1691
1545
|
import { createRequire as createRequire2 } from "module";
|
|
1692
|
-
import { dirname as
|
|
1546
|
+
import { dirname as dirname3, resolve as resolve4, relative, join as join2 } from "path";
|
|
1693
1547
|
|
|
1694
1548
|
// src/scope-extractor.ts
|
|
1695
1549
|
import { createRequire } from "module";
|
|
@@ -2106,8 +1960,8 @@ function normalizePathSlashes(p) {
|
|
|
2106
1960
|
return p.replace(/\\/g, "/");
|
|
2107
1961
|
}
|
|
2108
1962
|
function normalizeDataLocFilePath(absoluteFilePath, projectCwd) {
|
|
2109
|
-
const abs = normalizePathSlashes(
|
|
2110
|
-
const cwd = normalizePathSlashes(
|
|
1963
|
+
const abs = normalizePathSlashes(resolve4(absoluteFilePath));
|
|
1964
|
+
const cwd = normalizePathSlashes(resolve4(projectCwd));
|
|
2111
1965
|
if (abs === cwd || abs.startsWith(cwd + "/")) {
|
|
2112
1966
|
return normalizePathSlashes(relative(cwd, abs));
|
|
2113
1967
|
}
|
|
@@ -2120,7 +1974,7 @@ function findESLintCwd(startDir) {
|
|
|
2120
1974
|
if (existsSync4(join2(dir, cfg))) return dir;
|
|
2121
1975
|
}
|
|
2122
1976
|
if (existsSync4(join2(dir, "package.json"))) return dir;
|
|
2123
|
-
const parent =
|
|
1977
|
+
const parent = dirname3(dir);
|
|
2124
1978
|
if (parent === dir) break;
|
|
2125
1979
|
dir = parent;
|
|
2126
1980
|
}
|
|
@@ -2262,13 +2116,13 @@ function isSentinelIssue(issue) {
|
|
|
2262
2116
|
var DEFAULT_PORT = 9234;
|
|
2263
2117
|
var PORT_RANGE_SIZE = 10;
|
|
2264
2118
|
function isPortAvailable(port) {
|
|
2265
|
-
return new Promise((
|
|
2119
|
+
return new Promise((resolve10) => {
|
|
2266
2120
|
const srv = createServer();
|
|
2267
2121
|
srv.once("error", () => {
|
|
2268
|
-
|
|
2122
|
+
resolve10(false);
|
|
2269
2123
|
});
|
|
2270
2124
|
srv.once("listening", () => {
|
|
2271
|
-
srv.close(() =>
|
|
2125
|
+
srv.close(() => resolve10(true));
|
|
2272
2126
|
});
|
|
2273
2127
|
srv.listen(port, "127.0.0.1");
|
|
2274
2128
|
});
|
|
@@ -2354,8 +2208,8 @@ var ollamaMutexQueue = [];
|
|
|
2354
2208
|
function acquireOllamaMutex(pluginId) {
|
|
2355
2209
|
let release;
|
|
2356
2210
|
const prev = ollamaMutexPromise;
|
|
2357
|
-
ollamaMutexPromise = new Promise((
|
|
2358
|
-
release =
|
|
2211
|
+
ollamaMutexPromise = new Promise((resolve10) => {
|
|
2212
|
+
release = resolve10;
|
|
2359
2213
|
});
|
|
2360
2214
|
ollamaMutexQueue.push(pluginId);
|
|
2361
2215
|
setPluginStatus(pluginId, "waiting-for-ollama", "Queued for Ollama...");
|
|
@@ -2492,7 +2346,7 @@ function findESLintCwd2(startDir) {
|
|
|
2492
2346
|
if (existsSync5(join3(dir, cfg))) return dir;
|
|
2493
2347
|
}
|
|
2494
2348
|
if (existsSync5(join3(dir, "package.json"))) return dir;
|
|
2495
|
-
const parent =
|
|
2349
|
+
const parent = dirname4(dir);
|
|
2496
2350
|
if (parent === dir) break;
|
|
2497
2351
|
dir = parent;
|
|
2498
2352
|
}
|
|
@@ -2502,8 +2356,8 @@ function normalizePathSlashes2(p) {
|
|
|
2502
2356
|
return p.replace(/\\/g, "/");
|
|
2503
2357
|
}
|
|
2504
2358
|
function normalizeDataLocFilePath2(absoluteFilePath, projectCwd) {
|
|
2505
|
-
const abs = normalizePathSlashes2(
|
|
2506
|
-
const cwd = normalizePathSlashes2(
|
|
2359
|
+
const abs = normalizePathSlashes2(resolve5(absoluteFilePath));
|
|
2360
|
+
const cwd = normalizePathSlashes2(resolve5(projectCwd));
|
|
2507
2361
|
if (abs === cwd || abs.startsWith(cwd + "/")) {
|
|
2508
2362
|
return normalizePathSlashes2(relative2(cwd, abs));
|
|
2509
2363
|
}
|
|
@@ -2511,18 +2365,18 @@ function normalizeDataLocFilePath2(absoluteFilePath, projectCwd) {
|
|
|
2511
2365
|
}
|
|
2512
2366
|
function resolveRequestedFilePath(filePath) {
|
|
2513
2367
|
if (filePath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(filePath)) {
|
|
2514
|
-
return
|
|
2368
|
+
return resolve5(filePath);
|
|
2515
2369
|
}
|
|
2516
2370
|
const cached = resolvedPathCache.get(filePath);
|
|
2517
2371
|
if (cached) return cached;
|
|
2518
2372
|
const cwd = process.cwd();
|
|
2519
|
-
const fromCwd =
|
|
2373
|
+
const fromCwd = resolve5(cwd, filePath);
|
|
2520
2374
|
if (existsSync5(fromCwd)) {
|
|
2521
2375
|
resolvedPathCache.set(filePath, fromCwd);
|
|
2522
2376
|
return fromCwd;
|
|
2523
2377
|
}
|
|
2524
2378
|
const wsRoot = findWorkspaceRoot4(cwd);
|
|
2525
|
-
const fromWs =
|
|
2379
|
+
const fromWs = resolve5(wsRoot, filePath);
|
|
2526
2380
|
if (existsSync5(fromWs)) {
|
|
2527
2381
|
resolvedPathCache.set(filePath, fromWs);
|
|
2528
2382
|
return fromWs;
|
|
@@ -2534,7 +2388,7 @@ function resolveRequestedFilePath(filePath) {
|
|
|
2534
2388
|
const entries = readdirSync(base, { withFileTypes: true });
|
|
2535
2389
|
for (const ent of entries) {
|
|
2536
2390
|
if (!ent.isDirectory()) continue;
|
|
2537
|
-
const p =
|
|
2391
|
+
const p = resolve5(base, ent.name, filePath);
|
|
2538
2392
|
if (existsSync5(p)) {
|
|
2539
2393
|
resolvedPathCache.set(filePath, p);
|
|
2540
2394
|
return p;
|
|
@@ -2652,7 +2506,7 @@ async function lintFileFast(filePath, onProgress) {
|
|
|
2652
2506
|
onProgress("Cache hit (unchanged)");
|
|
2653
2507
|
return cached.issues;
|
|
2654
2508
|
}
|
|
2655
|
-
const fileDir =
|
|
2509
|
+
const fileDir = dirname4(absolutePath);
|
|
2656
2510
|
const projectCwd = findESLintCwd2(fileDir);
|
|
2657
2511
|
onProgress(`Resolving ESLint project... ${pc.dim(projectCwd)}`);
|
|
2658
2512
|
const eslint = await getESLintWithOverrides(
|
|
@@ -2704,7 +2558,7 @@ async function runSemanticAnalysisAsync(filePath, ws, requestId) {
|
|
|
2704
2558
|
const styleguidePath = semanticConfig?.options?.styleguidePath || void 0;
|
|
2705
2559
|
setPluginModel("semantic", model);
|
|
2706
2560
|
const { getStyleguide, hashContentSync, setCacheEntry, getCacheEntry } = await import("uilint-eslint");
|
|
2707
|
-
const fileDir =
|
|
2561
|
+
const fileDir = dirname4(absolutePath);
|
|
2708
2562
|
const { content: styleguide } = getStyleguide(fileDir, styleguidePath);
|
|
2709
2563
|
if (!styleguide) {
|
|
2710
2564
|
logSemanticSkipped(filePath, "no styleguide found");
|
|
@@ -2838,7 +2692,7 @@ async function runSemanticAnalysisAsync(filePath, ws, requestId) {
|
|
|
2838
2692
|
issues,
|
|
2839
2693
|
timestamp: Date.now()
|
|
2840
2694
|
});
|
|
2841
|
-
const fileDir2 =
|
|
2695
|
+
const fileDir2 = dirname4(absolutePath);
|
|
2842
2696
|
const projectCwd = findESLintCwd2(fileDir2);
|
|
2843
2697
|
const dataLocFile = normalizeDataLocFilePath2(absolutePath, projectCwd);
|
|
2844
2698
|
const lintIssues = issues.map((issue) => ({
|
|
@@ -3766,7 +3620,7 @@ async function serve(options) {
|
|
|
3766
3620
|
ignoreInitial: true
|
|
3767
3621
|
});
|
|
3768
3622
|
fileWatcher.on("change", (path) => {
|
|
3769
|
-
const resolvedPath =
|
|
3623
|
+
const resolvedPath = resolve5(path);
|
|
3770
3624
|
if (resolvedPath.endsWith("coverage-final.json")) {
|
|
3771
3625
|
handleCoverageFileChange(resolvedPath);
|
|
3772
3626
|
return;
|
|
@@ -3968,7 +3822,7 @@ async function serve(options) {
|
|
|
3968
3822
|
});
|
|
3969
3823
|
await waitUntilExit();
|
|
3970
3824
|
} else {
|
|
3971
|
-
await new Promise((
|
|
3825
|
+
await new Promise((resolve10) => {
|
|
3972
3826
|
process.on("SIGINT", () => {
|
|
3973
3827
|
logServerInfo("Shutting down...");
|
|
3974
3828
|
clearInterval(pingInterval);
|
|
@@ -3976,20 +3830,20 @@ async function serve(options) {
|
|
|
3976
3830
|
httpServer.close();
|
|
3977
3831
|
fileWatcher?.close();
|
|
3978
3832
|
removePortFile();
|
|
3979
|
-
|
|
3833
|
+
resolve10();
|
|
3980
3834
|
});
|
|
3981
3835
|
});
|
|
3982
3836
|
}
|
|
3983
3837
|
}
|
|
3984
3838
|
|
|
3985
3839
|
// src/commands/vision.ts
|
|
3986
|
-
import { dirname as
|
|
3840
|
+
import { dirname as dirname5, resolve as resolve6, join as join4 } from "path";
|
|
3987
3841
|
import {
|
|
3988
3842
|
existsSync as existsSync6,
|
|
3989
3843
|
readFileSync as readFileSync3,
|
|
3990
3844
|
readdirSync as readdirSync2
|
|
3991
3845
|
} from "fs";
|
|
3992
|
-
import { ensureOllamaReady as
|
|
3846
|
+
import { ensureOllamaReady as ensureOllamaReady4, STYLEGUIDE_PATHS as STYLEGUIDE_PATHS2 } from "uilint-core/node";
|
|
3993
3847
|
var _visionNodeModule = null;
|
|
3994
3848
|
async function loadVisionModule() {
|
|
3995
3849
|
if (_visionNodeModule) return _visionNodeModule;
|
|
@@ -4019,7 +3873,7 @@ function debugDumpPath3(options) {
|
|
|
4019
3873
|
const v = options.debugDump ?? process.env.UILINT_DEBUG_DUMP;
|
|
4020
3874
|
if (!v) return null;
|
|
4021
3875
|
if (v === "1" || v.toLowerCase() === "true" || v.toLowerCase() === "yes") {
|
|
4022
|
-
return
|
|
3876
|
+
return resolve6(process.cwd(), ".uilint");
|
|
4023
3877
|
}
|
|
4024
3878
|
return v;
|
|
4025
3879
|
}
|
|
@@ -4040,7 +3894,7 @@ function findScreenshotsDirUpwards(startDir) {
|
|
|
4040
3894
|
for (let i = 0; i < 20; i++) {
|
|
4041
3895
|
const candidate = join4(dir, ".uilint", "screenshots");
|
|
4042
3896
|
if (existsSync6(candidate)) return candidate;
|
|
4043
|
-
const parent =
|
|
3897
|
+
const parent = dirname5(dir);
|
|
4044
3898
|
if (parent === dir) break;
|
|
4045
3899
|
dir = parent;
|
|
4046
3900
|
}
|
|
@@ -4196,7 +4050,7 @@ async function vision(options) {
|
|
|
4196
4050
|
const resolved = await resolveVisionStyleGuide({
|
|
4197
4051
|
projectPath,
|
|
4198
4052
|
styleguide: options.styleguide,
|
|
4199
|
-
startDir: startPath ?
|
|
4053
|
+
startDir: startPath ? dirname5(startPath) : projectPath,
|
|
4200
4054
|
pathResolver: resolvePathSpecifier
|
|
4201
4055
|
});
|
|
4202
4056
|
styleGuide = resolved.styleGuide;
|
|
@@ -4234,20 +4088,20 @@ async function vision(options) {
|
|
|
4234
4088
|
const prepStartNs = nsNow();
|
|
4235
4089
|
if (!isJsonOutput) {
|
|
4236
4090
|
await withSpinner("Preparing Ollama", async () => {
|
|
4237
|
-
await
|
|
4091
|
+
await ensureOllamaReady4({
|
|
4238
4092
|
model: visionModel,
|
|
4239
4093
|
baseUrl: options.baseUrl
|
|
4240
4094
|
});
|
|
4241
4095
|
});
|
|
4242
4096
|
} else {
|
|
4243
|
-
await
|
|
4097
|
+
await ensureOllamaReady4({ model: visionModel, baseUrl: options.baseUrl });
|
|
4244
4098
|
}
|
|
4245
4099
|
const prepEndNs = nsNow();
|
|
4246
4100
|
const resolvedImagePath = imagePath || (() => {
|
|
4247
4101
|
const screenshotFile = typeof sidecar?.screenshotFile === "string" ? sidecar.screenshotFile : typeof sidecar?.filename === "string" ? sidecar.filename : void 0;
|
|
4248
4102
|
if (!screenshotFile) return null;
|
|
4249
|
-
const baseDir = sidecarPath ?
|
|
4250
|
-
const abs =
|
|
4103
|
+
const baseDir = sidecarPath ? dirname5(sidecarPath) : projectPath;
|
|
4104
|
+
const abs = resolve6(baseDir, screenshotFile);
|
|
4251
4105
|
return abs;
|
|
4252
4106
|
})();
|
|
4253
4107
|
if (!resolvedImagePath) {
|
|
@@ -4541,7 +4395,7 @@ function parseOptionsJson(optionsStr) {
|
|
|
4541
4395
|
}
|
|
4542
4396
|
}
|
|
4543
4397
|
async function sendConfigMessage(port, key, value) {
|
|
4544
|
-
return new Promise((
|
|
4398
|
+
return new Promise((resolve10) => {
|
|
4545
4399
|
const url = `ws://localhost:${port}`;
|
|
4546
4400
|
const ws = new WebSocket2(url);
|
|
4547
4401
|
let resolved = false;
|
|
@@ -4549,7 +4403,7 @@ async function sendConfigMessage(port, key, value) {
|
|
|
4549
4403
|
if (!resolved) {
|
|
4550
4404
|
resolved = true;
|
|
4551
4405
|
ws.close();
|
|
4552
|
-
|
|
4406
|
+
resolve10(false);
|
|
4553
4407
|
}
|
|
4554
4408
|
}, 5e3);
|
|
4555
4409
|
ws.on("open", () => {
|
|
@@ -4560,7 +4414,7 @@ async function sendConfigMessage(port, key, value) {
|
|
|
4560
4414
|
resolved = true;
|
|
4561
4415
|
clearTimeout(timeout);
|
|
4562
4416
|
ws.close();
|
|
4563
|
-
|
|
4417
|
+
resolve10(true);
|
|
4564
4418
|
}
|
|
4565
4419
|
}, 100);
|
|
4566
4420
|
});
|
|
@@ -4568,13 +4422,13 @@ async function sendConfigMessage(port, key, value) {
|
|
|
4568
4422
|
if (!resolved) {
|
|
4569
4423
|
resolved = true;
|
|
4570
4424
|
clearTimeout(timeout);
|
|
4571
|
-
|
|
4425
|
+
resolve10(false);
|
|
4572
4426
|
}
|
|
4573
4427
|
});
|
|
4574
4428
|
});
|
|
4575
4429
|
}
|
|
4576
4430
|
async function sendRuleConfigMessage(port, ruleId, severity, options) {
|
|
4577
|
-
return new Promise((
|
|
4431
|
+
return new Promise((resolve10) => {
|
|
4578
4432
|
const url = `ws://localhost:${port}`;
|
|
4579
4433
|
const ws = new WebSocket2(url);
|
|
4580
4434
|
let resolved = false;
|
|
@@ -4583,7 +4437,7 @@ async function sendRuleConfigMessage(port, ruleId, severity, options) {
|
|
|
4583
4437
|
if (!resolved) {
|
|
4584
4438
|
resolved = true;
|
|
4585
4439
|
ws.close();
|
|
4586
|
-
|
|
4440
|
+
resolve10({ success: false, error: "Request timed out" });
|
|
4587
4441
|
}
|
|
4588
4442
|
}, 1e4);
|
|
4589
4443
|
ws.on("open", () => {
|
|
@@ -4604,7 +4458,7 @@ async function sendRuleConfigMessage(port, ruleId, severity, options) {
|
|
|
4604
4458
|
resolved = true;
|
|
4605
4459
|
clearTimeout(timeout);
|
|
4606
4460
|
ws.close();
|
|
4607
|
-
|
|
4461
|
+
resolve10({
|
|
4608
4462
|
success: msg.success,
|
|
4609
4463
|
error: msg.error
|
|
4610
4464
|
});
|
|
@@ -4617,7 +4471,7 @@ async function sendRuleConfigMessage(port, ruleId, severity, options) {
|
|
|
4617
4471
|
if (!resolved) {
|
|
4618
4472
|
resolved = true;
|
|
4619
4473
|
clearTimeout(timeout);
|
|
4620
|
-
|
|
4474
|
+
resolve10({ success: false, error: "Connection error" });
|
|
4621
4475
|
}
|
|
4622
4476
|
});
|
|
4623
4477
|
});
|
|
@@ -4930,7 +4784,7 @@ function searchCommand() {
|
|
|
4930
4784
|
|
|
4931
4785
|
// src/commands/duplicates/similar.ts
|
|
4932
4786
|
import { Command as Command4 } from "commander";
|
|
4933
|
-
import { relative as relative5, resolve as
|
|
4787
|
+
import { relative as relative5, resolve as resolve7, isAbsolute as isAbsolute2 } from "path";
|
|
4934
4788
|
import chalk5 from "chalk";
|
|
4935
4789
|
function similarCommand() {
|
|
4936
4790
|
return new Command4("similar").description("Find code similar to a specific location").argument("<location>", "File location in format file:line (e.g., src/Button.tsx:15)").option("-k, --top <n>", "Number of results (default: 10)", parseInt).option("--threshold <n>", "Minimum similarity (default: 0.7)", parseFloat).option("-o, --output <format>", "Output format: text or json", "text").action(async (location, options) => {
|
|
@@ -4959,7 +4813,7 @@ function similarCommand() {
|
|
|
4959
4813
|
}
|
|
4960
4814
|
process.exit(1);
|
|
4961
4815
|
}
|
|
4962
|
-
const filePath = isAbsolute2(filePart) ? filePart :
|
|
4816
|
+
const filePath = isAbsolute2(filePart) ? filePart : resolve7(projectRoot, filePart);
|
|
4963
4817
|
try {
|
|
4964
4818
|
const results = await findSimilarAtLocation({
|
|
4965
4819
|
path: projectRoot,
|
|
@@ -5019,17 +4873,17 @@ function createDuplicatesCommand() {
|
|
|
5019
4873
|
|
|
5020
4874
|
// src/index.ts
|
|
5021
4875
|
import { readFileSync as readFileSync6 } from "fs";
|
|
5022
|
-
import { dirname as
|
|
4876
|
+
import { dirname as dirname8, join as join5 } from "path";
|
|
5023
4877
|
import { fileURLToPath } from "url";
|
|
5024
4878
|
|
|
5025
4879
|
// src/commands/manifest/index.ts
|
|
5026
4880
|
import { Command as Command6 } from "commander";
|
|
5027
4881
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
5028
|
-
import { dirname as
|
|
4882
|
+
import { dirname as dirname7, resolve as resolve9 } from "path";
|
|
5029
4883
|
|
|
5030
4884
|
// src/commands/manifest/generator.ts
|
|
5031
4885
|
import { readFileSync as readFileSync4 } from "fs";
|
|
5032
|
-
import { resolve as
|
|
4886
|
+
import { resolve as resolve8, dirname as dirname6, relative as relative6 } from "path";
|
|
5033
4887
|
import { glob } from "glob";
|
|
5034
4888
|
import { execSync } from "child_process";
|
|
5035
4889
|
import { findWorkspaceRoot as findWorkspaceRoot5 } from "uilint-core/node";
|
|
@@ -5082,7 +4936,7 @@ function buildRuleMetadata(appRoot) {
|
|
|
5082
4936
|
});
|
|
5083
4937
|
}
|
|
5084
4938
|
async function generateManifest(options = {}) {
|
|
5085
|
-
const cwd =
|
|
4939
|
+
const cwd = resolve8(options.cwd ?? process.cwd());
|
|
5086
4940
|
const include = options.include ?? DEFAULT_INCLUDE;
|
|
5087
4941
|
const exclude = options.exclude ?? DEFAULT_EXCLUDE;
|
|
5088
4942
|
const includeSource = options.includeSource ?? true;
|
|
@@ -5112,7 +4966,7 @@ async function generateManifest(options = {}) {
|
|
|
5112
4966
|
const absolutePath = files[i];
|
|
5113
4967
|
const relativePath = relative6(cwd, absolutePath);
|
|
5114
4968
|
onProgress(`Linting ${relativePath}...`, i + 1, files.length);
|
|
5115
|
-
const fileDir =
|
|
4969
|
+
const fileDir = dirname6(absolutePath);
|
|
5116
4970
|
const projectCwd = findESLintCwd(fileDir);
|
|
5117
4971
|
const issues = await lintFileWithDataLoc(absolutePath, projectCwd);
|
|
5118
4972
|
if (issues.length === 0) continue;
|
|
@@ -5224,7 +5078,7 @@ async function buildManifest(options) {
|
|
|
5224
5078
|
const pluginManifests = await discoverPlugins();
|
|
5225
5079
|
await loadPluginESLintRules(pluginManifests);
|
|
5226
5080
|
const startTime = Date.now();
|
|
5227
|
-
const outputPath =
|
|
5081
|
+
const outputPath = resolve9(process.cwd(), options.output);
|
|
5228
5082
|
if (!options.quiet) {
|
|
5229
5083
|
logInfo(`Building lint manifest...`);
|
|
5230
5084
|
logInfo(`Output: ${pc.dim(outputPath)}`);
|
|
@@ -5244,7 +5098,7 @@ async function buildManifest(options) {
|
|
|
5244
5098
|
}
|
|
5245
5099
|
}
|
|
5246
5100
|
});
|
|
5247
|
-
const outputDir =
|
|
5101
|
+
const outputDir = dirname7(outputPath);
|
|
5248
5102
|
if (!existsSync7(outputDir)) {
|
|
5249
5103
|
mkdirSync4(outputDir, { recursive: true });
|
|
5250
5104
|
}
|
|
@@ -5310,7 +5164,7 @@ var SocketClient = class {
|
|
|
5310
5164
|
async connect() {
|
|
5311
5165
|
if (this.connected) return;
|
|
5312
5166
|
if (this.connectionPromise) return this.connectionPromise;
|
|
5313
|
-
this.connectionPromise = new Promise((
|
|
5167
|
+
this.connectionPromise = new Promise((resolve10, reject) => {
|
|
5314
5168
|
const timeout = setTimeout(() => {
|
|
5315
5169
|
reject(new Error(`Connection timeout to ${this.url}`));
|
|
5316
5170
|
}, this.connectTimeout);
|
|
@@ -5319,7 +5173,7 @@ var SocketClient = class {
|
|
|
5319
5173
|
clearTimeout(timeout);
|
|
5320
5174
|
this.connected = true;
|
|
5321
5175
|
this.log("Connected to", this.url);
|
|
5322
|
-
|
|
5176
|
+
resolve10();
|
|
5323
5177
|
});
|
|
5324
5178
|
this.ws.on("message", (data) => {
|
|
5325
5179
|
try {
|
|
@@ -5395,7 +5249,7 @@ var SocketClient = class {
|
|
|
5395
5249
|
this.messageQueue = this.messageQueue.filter((m) => m !== existing);
|
|
5396
5250
|
return Promise.resolve(existing);
|
|
5397
5251
|
}
|
|
5398
|
-
return new Promise((
|
|
5252
|
+
return new Promise((resolve10, reject) => {
|
|
5399
5253
|
const timeoutId = setTimeout(() => {
|
|
5400
5254
|
this.pendingRequests = this.pendingRequests.filter(
|
|
5401
5255
|
(r) => r.timeout !== timeoutId
|
|
@@ -5404,7 +5258,7 @@ var SocketClient = class {
|
|
|
5404
5258
|
}, timeout);
|
|
5405
5259
|
this.pendingRequests.push({
|
|
5406
5260
|
predicate,
|
|
5407
|
-
resolve:
|
|
5261
|
+
resolve: resolve10,
|
|
5408
5262
|
reject,
|
|
5409
5263
|
timeout: timeoutId
|
|
5410
5264
|
});
|
|
@@ -6019,7 +5873,7 @@ assertNodeVersion(20, 19);
|
|
|
6019
5873
|
var program = new Command8();
|
|
6020
5874
|
function getCLIVersion() {
|
|
6021
5875
|
try {
|
|
6022
|
-
const __dirname =
|
|
5876
|
+
const __dirname = dirname8(fileURLToPath(import.meta.url));
|
|
6023
5877
|
const pkgPath = join5(__dirname, "..", "package.json");
|
|
6024
5878
|
const pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
|
|
6025
5879
|
return pkg.version || "0.0.0";
|
|
@@ -6086,17 +5940,9 @@ program.command("consistency").description("Analyze grouped DOM elements for vis
|
|
|
6086
5940
|
output: options.output
|
|
6087
5941
|
});
|
|
6088
5942
|
});
|
|
6089
|
-
program.command("update").description("Update existing style guide with new styles").option("-f, --input-file <path>", "Path to HTML file to analyze").option("-j, --input-json <json>", "JSON input with html and styles").option("-s, --styleguide <path>", "Path to style guide file").option("--llm", "Use LLM to suggest updates").action(async (options) => {
|
|
6090
|
-
await update({
|
|
6091
|
-
inputFile: options.inputFile,
|
|
6092
|
-
inputJson: options.inputJson,
|
|
6093
|
-
styleguide: options.styleguide,
|
|
6094
|
-
llm: options.llm
|
|
6095
|
-
});
|
|
6096
|
-
});
|
|
6097
5943
|
var initCommand = program.command("init").description("Initialize UILint integration").option("--force", "Overwrite existing configuration files").option("--react", "Install React DevTool (non-interactive)").option("--eslint", "Install ESLint rules (non-interactive)").option("--genstyleguide", "Generate styleguide (non-interactive)").option("--skill", "Install Claude skill (non-interactive)");
|
|
6098
5944
|
program.command("remove").description("Remove UILint components from your project").option("--dry-run", "Preview changes without removing anything").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
|
|
6099
|
-
const { removeUI } = await import("./remove-ui-
|
|
5945
|
+
const { removeUI } = await import("./remove-ui-7MULR7IB.js");
|
|
6100
5946
|
await removeUI({ dryRun: options.dryRun, yes: options.yes });
|
|
6101
5947
|
});
|
|
6102
5948
|
program.command("serve").description("Start WebSocket server for real-time UI linting").option("-p, --port <number>", "Port to listen on", "9234").option("--no-dashboard", "Disable dashboard UI (use simple logging)").action(async (options) => {
|
|
@@ -6153,7 +5999,7 @@ program.addCommand(createDuplicatesCommand());
|
|
|
6153
5999
|
program.addCommand(createManifestCommand());
|
|
6154
6000
|
program.addCommand(createSocketCommand());
|
|
6155
6001
|
program.command("upgrade").description("Update installed ESLint rules to latest versions").option("--check", "Show available updates without applying").option("-y, --yes", "Auto-confirm all updates").option("--dry-run", "Show what would change without modifying files").option("--rule <id>", "Upgrade only a specific rule").action(async (options) => {
|
|
6156
|
-
const { upgrade } = await import("./upgrade-
|
|
6002
|
+
const { upgrade } = await import("./upgrade-ALSJMTTW.js");
|
|
6157
6003
|
await upgrade({
|
|
6158
6004
|
check: options.check,
|
|
6159
6005
|
yes: options.yes,
|
|
@@ -6188,7 +6034,7 @@ async function main() {
|
|
|
6188
6034
|
...pluginManifests.map((m) => m.cliFlag)
|
|
6189
6035
|
]);
|
|
6190
6036
|
const plugins = [...allFlags].filter((flag) => options[flag]);
|
|
6191
|
-
const { initUI } = await import("./init-ui-
|
|
6037
|
+
const { initUI } = await import("./init-ui-NWRVGEEM.js");
|
|
6192
6038
|
await initUI({
|
|
6193
6039
|
force: options.force,
|
|
6194
6040
|
react: options.react,
|