uilint 0.2.20 → 0.2.22

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/index.js CHANGED
@@ -1595,6 +1595,7 @@ function writeVisionMarkdownReport(args) {
1595
1595
  }
1596
1596
 
1597
1597
  // src/commands/serve.ts
1598
+ import { ruleRegistry } from "uilint-eslint";
1598
1599
  function pickAppRoot(params) {
1599
1600
  const { cwd, workspaceRoot } = params;
1600
1601
  if (detectNextAppRouter(cwd)) return cwd;
@@ -1886,6 +1887,7 @@ async function handleMessage(ws, data) {
1886
1887
  )}`
1887
1888
  );
1888
1889
  } else if (message.type === "vision:analyze") {
1890
+ } else if (message.type === "config:set") {
1889
1891
  }
1890
1892
  switch (message.type) {
1891
1893
  case "lint:file": {
@@ -2147,6 +2149,11 @@ ${stack}` : ""
2147
2149
  }
2148
2150
  break;
2149
2151
  }
2152
+ case "config:set": {
2153
+ const { key, value } = message;
2154
+ handleConfigSet(key, value);
2155
+ break;
2156
+ }
2150
2157
  }
2151
2158
  }
2152
2159
  function handleDisconnect(ws) {
@@ -2172,6 +2179,19 @@ function handleFileChange(filePath) {
2172
2179
  sendMessage(ws, { type: "file:changed", filePath: clientFilePath });
2173
2180
  }
2174
2181
  }
2182
+ var configStore = /* @__PURE__ */ new Map();
2183
+ var connectedClientsSet = /* @__PURE__ */ new Set();
2184
+ function broadcastConfigUpdate(key, value) {
2185
+ const message = { type: "config:update", key, value };
2186
+ for (const ws of connectedClientsSet) {
2187
+ sendMessage(ws, message);
2188
+ }
2189
+ }
2190
+ function handleConfigSet(key, value) {
2191
+ configStore.set(key, value);
2192
+ logInfo(`${pc.dim("[ws]")} config:set ${pc.bold(key)} = ${pc.dim(JSON.stringify(value))}`);
2193
+ broadcastConfigUpdate(key, value);
2194
+ }
2175
2195
  async function serve(options) {
2176
2196
  const port = options.port || 9234;
2177
2197
  const cwd = process.cwd();
@@ -2191,6 +2211,7 @@ async function serve(options) {
2191
2211
  const wss = new WebSocketServer({ port });
2192
2212
  wss.on("connection", (ws) => {
2193
2213
  connectedClients += 1;
2214
+ connectedClientsSet.add(ws);
2194
2215
  logInfo(`Client connected (${connectedClients} total)`);
2195
2216
  sendMessage(ws, {
2196
2217
  type: "workspace:info",
@@ -2198,11 +2219,25 @@ async function serve(options) {
2198
2219
  workspaceRoot: wsRoot,
2199
2220
  serverCwd: cwd
2200
2221
  });
2222
+ sendMessage(ws, {
2223
+ type: "rules:metadata",
2224
+ rules: ruleRegistry.map((rule) => ({
2225
+ id: rule.id,
2226
+ name: rule.name,
2227
+ description: rule.description,
2228
+ category: rule.category,
2229
+ defaultSeverity: rule.defaultSeverity
2230
+ }))
2231
+ });
2232
+ for (const [key, value] of configStore) {
2233
+ sendMessage(ws, { type: "config:update", key, value });
2234
+ }
2201
2235
  ws.on("message", (data) => {
2202
2236
  handleMessage(ws, data.toString());
2203
2237
  });
2204
2238
  ws.on("close", () => {
2205
2239
  connectedClients = Math.max(0, connectedClients - 1);
2240
+ connectedClientsSet.delete(ws);
2206
2241
  logInfo(`Client disconnected (${connectedClients} total)`);
2207
2242
  handleDisconnect(ws);
2208
2243
  });
@@ -2710,6 +2745,147 @@ async function vision(options) {
2710
2745
  await flushLangfuse();
2711
2746
  }
2712
2747
 
2748
+ // src/commands/config.ts
2749
+ import { WebSocket as WebSocket2 } from "ws";
2750
+ function parsePosition(value) {
2751
+ const presets = {
2752
+ "top-center": true,
2753
+ "top-left": true,
2754
+ "top-right": true,
2755
+ "bottom-center": true,
2756
+ "bottom-left": true,
2757
+ "bottom-right": true
2758
+ };
2759
+ if (presets[value]) {
2760
+ return { preset: value };
2761
+ }
2762
+ const match = value.match(/^(\d+),(\d+)$/);
2763
+ if (match) {
2764
+ return { x: parseInt(match[1], 10), y: parseInt(match[2], 10) };
2765
+ }
2766
+ return null;
2767
+ }
2768
+ function presetToPosition(preset) {
2769
+ const positions = {
2770
+ "top-center": { x: 500, y: 30 },
2771
+ "top-left": { x: 60, y: 30 },
2772
+ "top-right": { x: 940, y: 30 },
2773
+ "bottom-center": { x: 500, y: 700 },
2774
+ "bottom-left": { x: 60, y: 700 },
2775
+ "bottom-right": { x: 940, y: 700 }
2776
+ };
2777
+ return positions[preset] || { x: 500, y: 30 };
2778
+ }
2779
+ async function sendConfigMessage(port, key, value) {
2780
+ return new Promise((resolve7) => {
2781
+ const url = `ws://localhost:${port}`;
2782
+ const ws = new WebSocket2(url);
2783
+ let resolved = false;
2784
+ const timeout = setTimeout(() => {
2785
+ if (!resolved) {
2786
+ resolved = true;
2787
+ ws.close();
2788
+ resolve7(false);
2789
+ }
2790
+ }, 5e3);
2791
+ ws.on("open", () => {
2792
+ const message = JSON.stringify({ type: "config:set", key, value });
2793
+ ws.send(message);
2794
+ setTimeout(() => {
2795
+ if (!resolved) {
2796
+ resolved = true;
2797
+ clearTimeout(timeout);
2798
+ ws.close();
2799
+ resolve7(true);
2800
+ }
2801
+ }, 100);
2802
+ });
2803
+ ws.on("error", () => {
2804
+ if (!resolved) {
2805
+ resolved = true;
2806
+ clearTimeout(timeout);
2807
+ resolve7(false);
2808
+ }
2809
+ });
2810
+ });
2811
+ }
2812
+ async function handleSet(key, value, port) {
2813
+ switch (key) {
2814
+ case "position": {
2815
+ const parsed = parsePosition(value);
2816
+ if (!parsed) {
2817
+ logError(
2818
+ `Invalid position value: ${value}
2819
+ Expected format: x,y (e.g., 100,50) or preset (top-center, top-left, etc.)`
2820
+ );
2821
+ process.exit(1);
2822
+ }
2823
+ let position;
2824
+ if ("preset" in parsed) {
2825
+ position = presetToPosition(parsed.preset);
2826
+ logInfo(`Using preset "${parsed.preset}" \u2192 (${position.x}, ${position.y})`);
2827
+ } else {
2828
+ position = parsed;
2829
+ }
2830
+ const success = await sendConfigMessage(
2831
+ port,
2832
+ "floatingIconPosition",
2833
+ position
2834
+ );
2835
+ if (success) {
2836
+ logSuccess(
2837
+ `Set floating icon position to (${position.x}, ${position.y})`
2838
+ );
2839
+ } else {
2840
+ logError(
2841
+ `Failed to set position. Is the server running?
2842
+ Start it with: ${pc.bold("npx uilint serve")}`
2843
+ );
2844
+ process.exit(1);
2845
+ }
2846
+ break;
2847
+ }
2848
+ default:
2849
+ logError(`Unknown config key: ${key}`);
2850
+ logInfo(`Available keys: position`);
2851
+ process.exit(1);
2852
+ }
2853
+ }
2854
+ async function handleGet(key, _port) {
2855
+ switch (key) {
2856
+ case "position":
2857
+ logInfo(
2858
+ `Position is stored in the browser's localStorage.
2859
+ To view it, check your browser's dev tools:
2860
+ localStorage.getItem("uilint:floatingIconPosition")`
2861
+ );
2862
+ break;
2863
+ default:
2864
+ logError(`Unknown config key: ${key}`);
2865
+ logInfo(`Available keys: position`);
2866
+ process.exit(1);
2867
+ }
2868
+ }
2869
+ async function config2(action, key, value, options = {}) {
2870
+ const port = options.port || 9234;
2871
+ switch (action) {
2872
+ case "set":
2873
+ if (!value) {
2874
+ logError(`Missing value for config set ${key}`);
2875
+ process.exit(1);
2876
+ }
2877
+ await handleSet(key, value, port);
2878
+ break;
2879
+ case "get":
2880
+ await handleGet(key, port);
2881
+ break;
2882
+ default:
2883
+ logError(`Unknown action: ${action}`);
2884
+ logInfo(`Usage: uilint config <set|get> <key> [value]`);
2885
+ process.exit(1);
2886
+ }
2887
+ }
2888
+
2713
2889
  // src/index.ts
2714
2890
  import { readFileSync as readFileSync3 } from "fs";
2715
2891
  import { dirname as dirname7, join as join5 } from "path";
@@ -2805,7 +2981,7 @@ program.command("update").description("Update existing style guide with new styl
2805
2981
  });
2806
2982
  });
2807
2983
  program.command("install").description("Install UILint integration").option("--force", "Overwrite existing configuration files").action(async (options) => {
2808
- const { installUI } = await import("./install-ui-FE5AA75P.js");
2984
+ const { installUI } = await import("./install-ui-HTVB5HDB.js");
2809
2985
  await installUI({ force: options.force });
2810
2986
  });
2811
2987
  program.command("serve").description("Start WebSocket server for real-time UI linting").option("-p, --port <number>", "Port to listen on", "9234").action(async (options) => {
@@ -2847,5 +3023,10 @@ program.command("vision").description("Analyze a screenshot with Ollama vision m
2847
3023
  debugDump: options.debugDump
2848
3024
  });
2849
3025
  });
3026
+ program.command("config").description("Get or set UILint configuration options").argument("<action>", "Action: set or get").argument("<key>", "Config key (e.g., position)").argument("[value]", "Value to set (for set action)").option("-p, --port <number>", "WebSocket server port", "9234").action(async (action, key, value, options) => {
3027
+ await config2(action, key, value, {
3028
+ port: parseInt(options.port, 10)
3029
+ });
3030
+ });
2850
3031
  program.parse();
2851
3032
  //# sourceMappingURL=index.js.map