uilint 0.2.140 → 0.2.142

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.
Files changed (37) hide show
  1. package/dist/{chunk-RYRHWTLC.js → chunk-7GQXW4CT.js} +14 -10
  2. package/dist/chunk-7GQXW4CT.js.map +1 -0
  3. package/dist/{chunk-VSBVUS56.js → chunk-JWSZKDZY.js} +77 -77
  4. package/dist/chunk-JWSZKDZY.js.map +1 -0
  5. package/dist/{chunk-JIFAHBJ2.js → chunk-OW7Y4RTR.js} +4 -4
  6. package/dist/chunk-OW7Y4RTR.js.map +1 -0
  7. package/dist/{chunk-TKJ27W62.js → chunk-VKI3SQMQ.js} +2 -2
  8. package/dist/{chunk-TKJ27W62.js.map → chunk-VKI3SQMQ.js.map} +1 -1
  9. package/dist/chunk-WG2WZTB2.js +56 -0
  10. package/dist/chunk-WG2WZTB2.js.map +1 -0
  11. package/dist/{chunk-BFHNMKBU.js → chunk-ZUOFUPGT.js} +27 -27
  12. package/dist/chunk-ZUOFUPGT.js.map +1 -0
  13. package/dist/index.js +163 -58
  14. package/dist/index.js.map +1 -1
  15. package/dist/{init-ui-YAXRGBIJ.js → init-ui-KJYYI5DH.js} +42 -17
  16. package/dist/init-ui-KJYYI5DH.js.map +1 -0
  17. package/dist/{plan-2ISQNZBR.js → plan-ZJSVJL5X.js} +4 -4
  18. package/dist/plugin-loader-O6PNFN6D.js +11 -0
  19. package/dist/plugin-loader-O6PNFN6D.js.map +1 -0
  20. package/dist/{remove-ui-RHRSEUWJ.js → remove-ui-ZHW4GUFL.js} +7 -7
  21. package/dist/remove-ui-ZHW4GUFL.js.map +1 -0
  22. package/dist/{render-3GGNWYTF.js → render-43OMCORR.js} +1 -1
  23. package/dist/render-43OMCORR.js.map +1 -0
  24. package/dist/{upgrade-2EVTOYTJ.js → upgrade-TPZ62BT2.js} +8 -6
  25. package/dist/upgrade-TPZ62BT2.js.map +1 -0
  26. package/package.json +12 -7
  27. package/dist/chunk-BFHNMKBU.js.map +0 -1
  28. package/dist/chunk-JIFAHBJ2.js.map +0 -1
  29. package/dist/chunk-RUMBVNPY.js +0 -29
  30. package/dist/chunk-RUMBVNPY.js.map +0 -1
  31. package/dist/chunk-RYRHWTLC.js.map +0 -1
  32. package/dist/chunk-VSBVUS56.js.map +0 -1
  33. package/dist/init-ui-YAXRGBIJ.js.map +0 -1
  34. package/dist/remove-ui-RHRSEUWJ.js.map +0 -1
  35. package/dist/render-3GGNWYTF.js.map +0 -1
  36. package/dist/upgrade-2EVTOYTJ.js.map +0 -1
  37. /package/dist/{plan-2ISQNZBR.js.map → plan-ZJSVJL5X.js.map} +0 -0
package/dist/index.js CHANGED
@@ -12,10 +12,11 @@ import {
12
12
  readRuleConfigsFromConfig,
13
13
  updateRuleConfigInConfig,
14
14
  updateRuleSeverityInConfig
15
- } from "./chunk-RYRHWTLC.js";
15
+ } from "./chunk-7GQXW4CT.js";
16
16
  import {
17
+ discoverPlugins,
17
18
  loadPluginESLintRules
18
- } from "./chunk-RUMBVNPY.js";
19
+ } from "./chunk-WG2WZTB2.js";
19
20
  import {
20
21
  createSpinner,
21
22
  intro,
@@ -242,12 +243,12 @@ async function initializeLangfuseIfEnabled() {
242
243
  }) => {
243
244
  let resolveTrace;
244
245
  let generationRef;
245
- let traceRef;
246
+ let _traceRef;
246
247
  let endData;
247
248
  const tracePromise = startActiveObservation(
248
249
  `uilint-${name}`,
249
250
  async (span) => {
250
- traceRef = span;
251
+ _traceRef = span;
251
252
  span.update({
252
253
  input: { operation: name },
253
254
  metadata: {
@@ -1416,10 +1417,13 @@ import {
1416
1417
  readdirSync,
1417
1418
  readFileSync as readFileSync2,
1418
1419
  mkdirSync as mkdirSync3,
1419
- writeFileSync as writeFileSync3
1420
+ writeFileSync as writeFileSync3,
1421
+ unlinkSync
1420
1422
  } from "fs";
1423
+ import { createServer } from "http";
1421
1424
  import { createRequire as createRequire3 } from "module";
1422
1425
  import { dirname as dirname5, resolve as resolve6, relative as relative2, join as join3, parse } from "path";
1426
+ import { URL } from "url";
1423
1427
  import { WebSocketServer, WebSocket } from "ws";
1424
1428
  import { watch } from "chokidar";
1425
1429
  import { findWorkspaceRoot as findWorkspaceRoot4 } from "uilint-core/node";
@@ -1741,7 +1745,7 @@ function collectScopeBoundaries(ast) {
1741
1745
  return;
1742
1746
  }
1743
1747
  if (node.type === "ArrowFunctionExpression") {
1744
- let name = null;
1748
+ const name = null;
1745
1749
  const returnsJsx = containsJsxReturn(node.body);
1746
1750
  if (range && loc) {
1747
1751
  const scopeType = determineScopeType(name, true, false, returnsJsx);
@@ -1937,7 +1941,7 @@ function findContainingJsxElement(ast, offset) {
1937
1941
  walk(ast);
1938
1942
  return result.innermost?.type ?? null;
1939
1943
  }
1940
- function findEnclosingScopeBatch(source, positions, options) {
1944
+ function findEnclosingScopeBatch(source, positions, _options) {
1941
1945
  const localRequire2 = createRequire(import.meta.url);
1942
1946
  const { parse: parse2 } = localRequire2("@typescript-eslint/typescript-estree");
1943
1947
  let ast;
@@ -2120,7 +2124,7 @@ async function lintFileWithDataLoc(absolutePath, projectCwd, onProgress) {
2120
2124
  lineStarts = buildLineStarts(fileCode);
2121
2125
  spans = buildJsxElementSpans(fileCode, dataLocFile);
2122
2126
  progress(`JSX map: ${spans.length} element(s)`);
2123
- } catch (e) {
2127
+ } catch {
2124
2128
  progress("JSX map failed (falling back to unmapped issues)");
2125
2129
  spans = [];
2126
2130
  lineStarts = [];
@@ -2208,6 +2212,29 @@ function isSentinelIssue(issue) {
2208
2212
  if (!issue.ruleId || !issue.messageId) return false;
2209
2213
  return getSentinelKeys().has(`${issue.ruleId}:${issue.messageId}`);
2210
2214
  }
2215
+ var DEFAULT_PORT = 9234;
2216
+ var PORT_RANGE_SIZE = 10;
2217
+ function isPortAvailable(port) {
2218
+ return new Promise((resolve11) => {
2219
+ const srv = createServer();
2220
+ srv.once("error", () => {
2221
+ resolve11(false);
2222
+ });
2223
+ srv.once("listening", () => {
2224
+ srv.close(() => resolve11(true));
2225
+ });
2226
+ srv.listen(port, "127.0.0.1");
2227
+ });
2228
+ }
2229
+ async function findAvailablePort(preferred) {
2230
+ for (let offset = 0; offset < PORT_RANGE_SIZE; offset++) {
2231
+ const port = preferred + offset;
2232
+ if (await isPortAvailable(port)) return port;
2233
+ }
2234
+ throw new Error(
2235
+ `No available ports in range ${preferred}\u2013${preferred + PORT_RANGE_SIZE - 1}`
2236
+ );
2237
+ }
2211
2238
  function pickAppRoot(params) {
2212
2239
  const { cwd, workspaceRoot } = params;
2213
2240
  if (detectNextAppRouter(cwd)) return cwd;
@@ -2433,9 +2460,11 @@ async function getESLintForProject2(projectCwd) {
2433
2460
  try {
2434
2461
  const req = createRequire3(join3(projectCwd, "package.json"));
2435
2462
  const mod = req("eslint");
2436
- const ESLintCtor = mod?.ESLint ?? mod?.default?.ESLint ?? mod?.default ?? mod;
2463
+ const modDefault = mod?.default;
2464
+ const ESLintCtor = mod?.ESLint ?? modDefault?.ESLint ?? mod?.default ?? mod;
2437
2465
  if (!ESLintCtor) return null;
2438
- const eslint = new ESLintCtor({ cwd: projectCwd });
2466
+ const Ctor = ESLintCtor;
2467
+ const eslint = new Ctor({ cwd: projectCwd });
2439
2468
  eslintInstances2.set(projectCwd, eslint);
2440
2469
  return eslint;
2441
2470
  } catch {
@@ -2449,9 +2478,11 @@ async function getESLintWithOverrides(projectCwd, overrideRules, instanceCache)
2449
2478
  try {
2450
2479
  const req = createRequire3(join3(projectCwd, "package.json"));
2451
2480
  const mod = req("eslint");
2452
- const ESLintCtor = mod?.ESLint ?? mod?.default?.ESLint ?? mod?.default ?? mod;
2481
+ const modDefault = mod?.default;
2482
+ const ESLintCtor = mod?.ESLint ?? modDefault?.ESLint ?? mod?.default ?? mod;
2453
2483
  if (!ESLintCtor) return null;
2454
- const eslint = new ESLintCtor({
2484
+ const Ctor = ESLintCtor;
2485
+ const eslint = new Ctor({
2455
2486
  cwd: projectCwd,
2456
2487
  overrideConfig: { rules: overrideRules }
2457
2488
  });
@@ -2668,7 +2699,7 @@ async function handleMessage(ws, data) {
2668
2699
  });
2669
2700
  setImmediate(async () => {
2670
2701
  try {
2671
- const semanticStart = Date.now();
2702
+ const _semanticStart = Date.now();
2672
2703
  const semanticIssues = await lintFileSemantic(filePath, (phase) => {
2673
2704
  sendMessage(ws, { type: "lint:progress", filePath, requestId, phase });
2674
2705
  });
@@ -2831,8 +2862,9 @@ async function handleMessage(ws, data) {
2831
2862
  const analyzer = await getVisionAnalyzerInstance();
2832
2863
  const releaseOllama = await acquireOllamaMutex();
2833
2864
  try {
2834
- const analyzerModel = typeof analyzer?.getModel === "function" ? analyzer.getModel() : void 0;
2835
- const analyzerBaseUrl = typeof analyzer?.getBaseUrl === "function" ? analyzer.getBaseUrl() : void 0;
2865
+ const analyzerObj = analyzer;
2866
+ const analyzerModel = typeof analyzerObj?.getModel === "function" ? analyzerObj.getModel() : void 0;
2867
+ const analyzerBaseUrl = typeof analyzerObj?.getBaseUrl === "function" ? analyzerObj.getBaseUrl() : void 0;
2836
2868
  if (!screenshot) {
2837
2869
  sendMessage(ws, {
2838
2870
  type: "vision:result",
@@ -2894,11 +2926,12 @@ async function handleMessage(ws, data) {
2894
2926
  }
2895
2927
  }
2896
2928
  const elapsed = Date.now() - startedAt;
2897
- logVisionDone(route, result.issues.length, elapsed);
2929
+ const resultIssues = result.issues;
2930
+ logVisionDone(route, resultIssues.length, elapsed);
2898
2931
  sendMessage(ws, {
2899
2932
  type: "vision:result",
2900
2933
  route,
2901
- issues: result.issues,
2934
+ issues: resultIssues,
2902
2935
  analysisTime: result.analysisTime,
2903
2936
  requestId
2904
2937
  });
@@ -2928,7 +2961,8 @@ async function handleMessage(ws, data) {
2928
2961
  sendMessage(ws, { type: "vision:status", available: false, requestId });
2929
2962
  break;
2930
2963
  }
2931
- const model = typeof analyzer.getModel === "function" ? analyzer.getModel() : void 0;
2964
+ const analyzerObj = analyzer;
2965
+ const model = typeof analyzerObj.getModel === "function" ? analyzerObj.getModel() : void 0;
2932
2966
  sendMessage(ws, { type: "vision:status", available: true, model, requestId });
2933
2967
  } catch {
2934
2968
  sendMessage(ws, { type: "vision:status", available: false, requestId });
@@ -3354,14 +3388,15 @@ function handleRuleConfigSet(ws, ruleId, severity, options, requestId) {
3354
3388
  }
3355
3389
  }
3356
3390
  async function serve(options) {
3357
- const port = options.port || 9234;
3391
+ const preferredPort = options.port || DEFAULT_PORT;
3358
3392
  const useDashboardUI = process.stdout.isTTY && !options.noDashboard;
3359
3393
  if (useDashboardUI) {
3360
3394
  enableDashboard();
3361
3395
  } else {
3362
3396
  disableDashboard();
3363
3397
  }
3364
- await loadPluginESLintRules();
3398
+ const pluginManifests = await discoverPlugins();
3399
+ await loadPluginESLintRules(pluginManifests);
3365
3400
  const cwd = process.cwd();
3366
3401
  const wsRoot = findWorkspaceRoot4(cwd);
3367
3402
  const appRoot = pickAppRoot({ cwd, workspaceRoot: wsRoot });
@@ -3385,7 +3420,64 @@ async function serve(options) {
3385
3420
  fileWatcher.add(coveragePath);
3386
3421
  logServerInfo(`Watching coverage`, coveragePath);
3387
3422
  }
3388
- const wss = new WebSocketServer({ port });
3423
+ const port = await findAvailablePort(preferredPort);
3424
+ if (port !== preferredPort) {
3425
+ logServerInfo(`Port ${preferredPort} in use, using ${port}`);
3426
+ }
3427
+ const httpServer = createServer((req, res) => {
3428
+ if (req.method === "OPTIONS") {
3429
+ res.writeHead(204, {
3430
+ "Access-Control-Allow-Origin": "*",
3431
+ "Access-Control-Allow-Methods": "GET, OPTIONS",
3432
+ "Access-Control-Allow-Headers": "Content-Type"
3433
+ });
3434
+ res.end();
3435
+ return;
3436
+ }
3437
+ const parsedUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
3438
+ if (parsedUrl.pathname === "/_uilint/info") {
3439
+ const probePath = parsedUrl.searchParams.get("probe");
3440
+ let probeExists;
3441
+ if (probePath) {
3442
+ const absolute = join3(appRoot, probePath);
3443
+ probeExists = existsSync5(absolute);
3444
+ }
3445
+ res.writeHead(200, {
3446
+ "Content-Type": "application/json",
3447
+ "Access-Control-Allow-Origin": "*"
3448
+ });
3449
+ res.end(
3450
+ JSON.stringify({
3451
+ appRoot,
3452
+ workspaceRoot: wsRoot,
3453
+ serverCwd: cwd,
3454
+ port,
3455
+ pid: process.pid,
3456
+ ...probeExists !== void 0 && { probeExists }
3457
+ })
3458
+ );
3459
+ return;
3460
+ }
3461
+ res.writeHead(404);
3462
+ res.end();
3463
+ });
3464
+ const wss = new WebSocketServer({ noServer: true });
3465
+ httpServer.on("upgrade", (request, socket, head) => {
3466
+ wss.handleUpgrade(request, socket, head, (ws) => {
3467
+ wss.emit("connection", ws, request);
3468
+ });
3469
+ });
3470
+ httpServer.listen(port, "127.0.0.1");
3471
+ const portFilePath = join3(appRoot, ".uilint", "port");
3472
+ const uilintDir = join3(appRoot, ".uilint");
3473
+ if (!existsSync5(uilintDir)) mkdirSync3(uilintDir, { recursive: true });
3474
+ writeFileSync3(portFilePath, String(port), "utf-8");
3475
+ function removePortFile() {
3476
+ try {
3477
+ unlinkSync(portFilePath);
3478
+ } catch {
3479
+ }
3480
+ }
3389
3481
  const PING_INTERVAL = 3e4;
3390
3482
  const aliveClients = /* @__PURE__ */ new WeakSet();
3391
3483
  const pingInterval = setInterval(() => {
@@ -3469,12 +3561,14 @@ async function serve(options) {
3469
3561
  });
3470
3562
  setServerRunning(port);
3471
3563
  if (useDashboardUI) {
3472
- const { renderDashboard } = await import("./render-3GGNWYTF.js");
3564
+ const { renderDashboard } = await import("./render-43OMCORR.js");
3473
3565
  const { waitUntilExit } = renderDashboard({
3474
3566
  onQuit: () => {
3475
3567
  clearInterval(pingInterval);
3476
3568
  wss.close();
3569
+ httpServer.close();
3477
3570
  fileWatcher?.close();
3571
+ removePortFile();
3478
3572
  },
3479
3573
  onRebuildIndex: () => {
3480
3574
  buildDuplicatesIndex(appRoot);
@@ -3487,7 +3581,9 @@ async function serve(options) {
3487
3581
  logServerInfo("Shutting down...");
3488
3582
  clearInterval(pingInterval);
3489
3583
  wss.close();
3584
+ httpServer.close();
3490
3585
  fileWatcher?.close();
3586
+ removePortFile();
3491
3587
  resolve11();
3492
3588
  });
3493
3589
  });
@@ -3565,7 +3661,8 @@ function listScreenshotSidecars(dirPath) {
3565
3661
  for (const p of entries) {
3566
3662
  try {
3567
3663
  const json = loadJsonFile(p);
3568
- const issues = Array.isArray(json?.issues) ? json.issues : json?.analysisResult?.issues;
3664
+ const analysisResult = json?.analysisResult;
3665
+ const issues = Array.isArray(json?.issues) ? json.issues : analysisResult?.issues;
3569
3666
  out.push({
3570
3667
  path: p,
3571
3668
  filename: json?.filename || json?.screenshotFile || p.split("/").pop() || p,
@@ -4535,7 +4632,7 @@ import { fileURLToPath } from "url";
4535
4632
 
4536
4633
  // src/commands/manifest/index.ts
4537
4634
  import { Command as Command6 } from "commander";
4538
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
4635
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
4539
4636
  import { dirname as dirname8, resolve as resolve10 } from "path";
4540
4637
 
4541
4638
  // src/commands/manifest/generator.ts
@@ -4578,11 +4675,10 @@ function getGitInfo(cwd) {
4578
4675
  function buildRuleMetadata(appRoot) {
4579
4676
  const eslintConfigPath = findEslintConfigFile(appRoot);
4580
4677
  const currentRuleConfigs = eslintConfigPath ? readRuleConfigsFromConfig(eslintConfigPath) : /* @__PURE__ */ new Map();
4581
- return ruleRegistry2.filter((rule) => currentRuleConfigs.has(`uilint/${rule.id}`)).map((rule) => {
4582
- const fullId = `uilint/${rule.id}`;
4583
- const currentConfig = currentRuleConfigs.get(fullId);
4678
+ return ruleRegistry2.filter((rule) => currentRuleConfigs.has(rule.id)).map((rule) => {
4679
+ const currentConfig = currentRuleConfigs.get(rule.id);
4584
4680
  return {
4585
- id: fullId,
4681
+ id: `uilint/${rule.id}`,
4586
4682
  name: rule.name,
4587
4683
  description: rule.description,
4588
4684
  category: rule.category,
@@ -4733,7 +4829,8 @@ function createManifestCommand() {
4733
4829
  return cmd;
4734
4830
  }
4735
4831
  async function buildManifest(options) {
4736
- await loadPluginESLintRules();
4832
+ const pluginManifests = await discoverPlugins();
4833
+ await loadPluginESLintRules(pluginManifests);
4737
4834
  const startTime = Date.now();
4738
4835
  const outputPath = resolve10(process.cwd(), options.output);
4739
4836
  if (!options.quiet) {
@@ -4756,11 +4853,11 @@ async function buildManifest(options) {
4756
4853
  }
4757
4854
  });
4758
4855
  const outputDir = dirname8(outputPath);
4759
- if (!existsSync8(outputDir)) {
4760
- mkdirSync5(outputDir, { recursive: true });
4856
+ if (!existsSync7(outputDir)) {
4857
+ mkdirSync4(outputDir, { recursive: true });
4761
4858
  }
4762
4859
  const json = options.pretty ? JSON.stringify(manifest, null, 2) : JSON.stringify(manifest);
4763
- writeFileSync5(outputPath, json, "utf-8");
4860
+ writeFileSync4(outputPath, json, "utf-8");
4764
4861
  const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
4765
4862
  const sizeKb = Math.round(Buffer.byteLength(json) / 1024);
4766
4863
  if (!options.quiet) {
@@ -4794,7 +4891,7 @@ async function buildManifest(options) {
4794
4891
 
4795
4892
  // src/commands/socket/index.ts
4796
4893
  import { Command as Command7 } from "commander";
4797
- import { readFileSync as readFileSync5, existsSync as existsSync9 } from "fs";
4894
+ import { readFileSync as readFileSync5, existsSync as existsSync8 } from "fs";
4798
4895
  import chalk6 from "chalk";
4799
4896
 
4800
4897
  // src/commands/socket/client.ts
@@ -5125,25 +5222,22 @@ function formatMessage(msg, json) {
5125
5222
  }
5126
5223
  return lines.join("\n");
5127
5224
  }
5128
- // Vision messages: types live in the plugin package but still flow through the WebSocket
5129
5225
  case "vision:status": {
5130
- const m = msg;
5131
- if (m.available) {
5132
- return `${chalk6.cyan("vision:status")} ${chalk6.green("available")} (${m.model})`;
5226
+ if (msg.available) {
5227
+ return `${chalk6.cyan("vision:status")} ${chalk6.green("available")} (${msg.model})`;
5133
5228
  }
5134
5229
  return `${chalk6.cyan("vision:status")} ${chalk6.red("not available")}`;
5135
5230
  }
5136
5231
  case "vision:result": {
5137
- const m = msg;
5138
5232
  const lines = [
5139
- `${chalk6.cyan("vision:result")} ${m.route} (${m.analysisTime}ms)`
5233
+ `${chalk6.cyan("vision:result")} ${msg.route} (${msg.analysisTime}ms)`
5140
5234
  ];
5141
- if (m.error) {
5142
- lines.push(chalk6.red(` Error: ${m.error}`));
5143
- } else if (m.issues.length === 0) {
5235
+ if (msg.error) {
5236
+ lines.push(chalk6.red(` Error: ${msg.error}`));
5237
+ } else if (msg.issues.length === 0) {
5144
5238
  lines.push(chalk6.green(" No issues found"));
5145
5239
  } else {
5146
- for (const issue of m.issues) {
5240
+ for (const issue of msg.issues) {
5147
5241
  const severity = issue.severity === "error" ? chalk6.red("error") : issue.severity === "warning" ? chalk6.yellow("warn") : chalk6.blue("info");
5148
5242
  lines.push(` ${severity} [${issue.category}] ${issue.message}`);
5149
5243
  if (issue.dataLoc) {
@@ -5262,13 +5356,13 @@ Available commands:
5262
5356
  console.log(chalk6.red("Usage: vision:analyze <route> <manifestFile> [screenshotFile]"));
5263
5357
  } else {
5264
5358
  const manifestPath = args[1];
5265
- if (!existsSync9(manifestPath)) {
5359
+ if (!existsSync8(manifestPath)) {
5266
5360
  console.log(chalk6.red(`Manifest file not found: ${manifestPath}`));
5267
5361
  } else {
5268
5362
  const manifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
5269
5363
  const params = { route: args[0], manifest };
5270
5364
  if (args[2]) {
5271
- if (existsSync9(args[2])) {
5365
+ if (existsSync8(args[2])) {
5272
5366
  const imageBuffer = readFileSync5(args[2]);
5273
5367
  params.screenshot = imageBuffer.toString("base64");
5274
5368
  } else {
@@ -5608,18 +5702,9 @@ program.command("update").description("Update existing style guide with new styl
5608
5702
  llm: options.llm
5609
5703
  });
5610
5704
  });
5611
- 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)").action(async (options) => {
5612
- const { initUI } = await import("./init-ui-YAXRGBIJ.js");
5613
- await initUI({
5614
- force: options.force,
5615
- react: options.react,
5616
- eslint: options.eslint,
5617
- genstyleguide: options.genstyleguide,
5618
- skill: options.skill
5619
- });
5620
- });
5705
+ 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)");
5621
5706
  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) => {
5622
- const { removeUI } = await import("./remove-ui-RHRSEUWJ.js");
5707
+ const { removeUI } = await import("./remove-ui-ZHW4GUFL.js");
5623
5708
  await removeUI({ dryRun: options.dryRun, yes: options.yes });
5624
5709
  });
5625
5710
  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) => {
@@ -5671,7 +5756,7 @@ program.addCommand(createDuplicatesCommand());
5671
5756
  program.addCommand(createManifestCommand());
5672
5757
  program.addCommand(createSocketCommand());
5673
5758
  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) => {
5674
- const { upgrade } = await import("./upgrade-2EVTOYTJ.js");
5759
+ const { upgrade } = await import("./upgrade-TPZ62BT2.js");
5675
5760
  await upgrade({
5676
5761
  check: options.check,
5677
5762
  yes: options.yes,
@@ -5679,5 +5764,25 @@ program.command("upgrade").description("Update installed ESLint rules to latest
5679
5764
  rule: options.rule
5680
5765
  });
5681
5766
  });
5682
- program.parse();
5767
+ async function main() {
5768
+ const { discoverPlugins: discoverPlugins2 } = await import("./plugin-loader-O6PNFN6D.js");
5769
+ const pluginManifests = await discoverPlugins2();
5770
+ for (const manifest of pluginManifests) {
5771
+ initCommand.option(`--${manifest.cliFlag}`, manifest.cliDescription);
5772
+ }
5773
+ initCommand.action(async (options) => {
5774
+ const plugins = pluginManifests.filter((m) => options[m.cliFlag]).map((m) => m.cliFlag);
5775
+ const { initUI } = await import("./init-ui-KJYYI5DH.js");
5776
+ await initUI({
5777
+ force: options.force,
5778
+ react: options.react,
5779
+ eslint: options.eslint,
5780
+ genstyleguide: options.genstyleguide,
5781
+ skill: options.skill,
5782
+ plugins: plugins.length > 0 ? plugins : void 0
5783
+ });
5784
+ });
5785
+ await program.parseAsync();
5786
+ }
5787
+ main();
5683
5788
  //# sourceMappingURL=index.js.map