uilint 0.2.153 → 0.2.155

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.
@@ -8,7 +8,6 @@ import { createRequire } from "module";
8
8
  import { existsSync, readFileSync } from "fs";
9
9
  import { join } from "path";
10
10
  import { pathToFileURL } from "url";
11
- var KNOWN_PLUGIN_PACKAGES = ["uilint-vision", "uilint-semantic", "uilint-duplicates", "uilint-coverage"];
12
11
  async function importFromProject(specifier, projectPath) {
13
12
  try {
14
13
  const req = createRequire(join(projectPath, "package.json"));
@@ -33,15 +32,16 @@ async function importFromProject(specifier, projectPath) {
33
32
  return await import(pathToFileURL(fullPath).href);
34
33
  }
35
34
  async function discoverPlugins(resolveFrom) {
35
+ const core = await import("uilint-core");
36
+ const KNOWN_PLUGINS = core.KNOWN_PLUGINS ?? [];
36
37
  const manifests = [];
37
- for (const pkg of KNOWN_PLUGIN_PACKAGES) {
38
- const specifier = `${pkg}/cli-manifest`;
38
+ for (const known of KNOWN_PLUGINS) {
39
39
  try {
40
40
  let mod;
41
41
  if (resolveFrom) {
42
- mod = await importFromProject(specifier, resolveFrom);
42
+ mod = await importFromProject(known.manifestSpecifier, resolveFrom);
43
43
  } else {
44
- mod = await import(specifier);
44
+ mod = await import(known.manifestSpecifier);
45
45
  }
46
46
  if (mod?.cliManifest) {
47
47
  manifests.push(mod.cliManifest);
@@ -77,4 +77,4 @@ export {
77
77
  discoverPlugins,
78
78
  loadPluginESLintRules
79
79
  };
80
- //# sourceMappingURL=chunk-GFJDTSYD.js.map
80
+ //# sourceMappingURL=chunk-GYGQ7HHN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/plugin-loader.ts"],"sourcesContent":["/**\n * Dynamic plugin loader for the CLI.\n *\n * Probes known plugin package names for a `cli-manifest` subpath export.\n * Each manifest describes the CLI flag, help text, and registration entry\n * point, keeping the core CLI free of plugin-specific knowledge.\n *\n * The list of known plugins comes from `uilint-core/KNOWN_PLUGINS` —\n * a single source of truth shared by the CLI, React loader, and plugins.\n */\n\nimport { createRequire } from \"module\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport { logInfo } from \"./prompts.js\";\n\n/**\n * Metadata a plugin exposes via its `<pkg>/cli-manifest` subpath export.\n * Plugins define a plain object matching this shape — no shared type import needed.\n */\nexport interface PluginCLIManifest {\n /** npm package name, e.g. \"uilint-vision\" */\n packageName: string;\n /** CLI flag name (without --), e.g. \"vision\" */\n cliFlag: string;\n /** Description shown in --help */\n cliDescription: string;\n /** Import specifier for the register module, e.g. \"uilint-vision/eslint-rules/register\" */\n registerSpecifier: string;\n /** Display name shown in the interactive install UI, e.g. \"Vision Analysis\" */\n displayName: string;\n /** Description shown in the interactive install UI */\n displayDescription: string;\n /** Emoji icon for the interactive install UI, e.g. \"👁️\" */\n displayIcon: string;\n}\n\n/**\n * Resolve and import a package subpath specifier from a given project directory.\n *\n * First tries CJS `createRequire().resolve()`, which works for packages with\n * a `\"require\"` export condition. If that fails (e.g. the package only defines\n * `\"import\"`), falls back to manually reading the package's `exports` map and\n * constructing a file URL.\n */\nasync function importFromProject(\n specifier: string,\n projectPath: string,\n): Promise<unknown> {\n // Try CJS resolution first (fast path)\n try {\n const req = createRequire(join(projectPath, \"package.json\"));\n const resolved = req.resolve(specifier);\n return await import(resolved);\n } catch {\n // CJS resolution failed — try ESM-only export resolution\n }\n\n // Parse \"pkg/subpath\" → [\"pkg\", \"./subpath\"]\n const slashIdx = specifier.indexOf(\"/\");\n if (slashIdx === -1) return undefined;\n const pkgName = specifier.slice(0, slashIdx);\n const subpath = `./${specifier.slice(slashIdx + 1)}`;\n\n const pkgDir = join(projectPath, \"node_modules\", pkgName);\n const pkgJsonPath = join(pkgDir, \"package.json\");\n if (!existsSync(pkgJsonPath)) return undefined;\n\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, \"utf8\"));\n const exportEntry = pkgJson.exports?.[subpath];\n if (!exportEntry) return undefined;\n\n const importPath =\n typeof exportEntry === \"string\"\n ? exportEntry\n : exportEntry.import ?? exportEntry.default;\n if (!importPath) return undefined;\n\n const fullPath = join(pkgDir, importPath);\n if (!existsSync(fullPath)) return undefined;\n\n return await import(pathToFileURL(fullPath).href);\n}\n\n/**\n * Discover available plugin manifests by probing `<pkg>/cli-manifest`.\n *\n * Uses `KNOWN_PLUGINS` from uilint-core as the single source of truth\n * for which packages to probe.\n *\n * @param resolveFrom - Optional project path to resolve plugins from.\n * When provided, resolves plugins from the project's node_modules\n * so plugins installed in the project can be found.\n * @returns Array of discovered plugin manifests\n */\nexport async function discoverPlugins(\n resolveFrom?: string,\n): Promise<PluginCLIManifest[]> {\n // Dynamic import — avoids a static named-export binding on uilint-core which\n // tsup auto-externalizes. Gracefully degrades if the installed uilint-core\n // version doesn't yet export KNOWN_PLUGINS (e.g. preview deploys).\n const core = await import(\"uilint-core\");\n const KNOWN_PLUGINS: ReadonlyArray<{ packageName: string; manifestSpecifier: string }> =\n core.KNOWN_PLUGINS ?? [];\n\n const manifests: PluginCLIManifest[] = [];\n\n for (const known of KNOWN_PLUGINS) {\n try {\n let mod: { cliManifest?: PluginCLIManifest } | undefined;\n if (resolveFrom) {\n mod = (await importFromProject(known.manifestSpecifier, resolveFrom)) as typeof mod;\n } else {\n mod = (await import(known.manifestSpecifier)) as typeof mod;\n }\n if (mod?.cliManifest) {\n manifests.push(mod.cliManifest);\n }\n } catch {\n // Plugin not installed — skip silently\n }\n }\n\n return manifests;\n}\n\n/**\n * Load ESLint rules from discovered plugins by importing their register modules.\n *\n * The register modules call `registerRuleMeta()` from `uilint-eslint`, which\n * mutates the shared `ruleRegistry` array. To avoid the dual-package problem\n * (project-resolved plugin getting a different `uilint-eslint` instance), we\n * always try a bare `import()` first — this resolves from the CLI's own\n * context so both the CLI and the plugin share the same `ruleRegistry`.\n * Only falls back to project-scoped resolution when the bare import fails\n * (e.g. when running via `npx` where plugins aren't alongside the CLI).\n *\n * @param manifests - Plugin manifests (from discoverPlugins)\n * @param resolveFrom - Optional project path to resolve plugins from.\n * @returns Array of loaded plugin package names\n */\nexport async function loadPluginESLintRules(\n manifests: PluginCLIManifest[],\n resolveFrom?: string,\n): Promise<string[]> {\n const loaded: string[] = [];\n\n for (const manifest of manifests) {\n try {\n // Prefer bare import so the register module shares the CLI's uilint-eslint\n await import(manifest.registerSpecifier);\n loaded.push(manifest.packageName);\n } catch {\n // Bare import failed — try from consumer project if a path was provided\n if (resolveFrom) {\n try {\n await importFromProject(manifest.registerSpecifier, resolveFrom);\n loaded.push(manifest.packageName);\n } catch {\n // Plugin register module not available — skip silently\n }\n }\n }\n }\n\n if (loaded.length > 0) {\n logInfo(`Loaded plugin rules: ${loaded.join(\", \")}`);\n }\n\n return loaded;\n}\n"],"mappings":";;;;;;AAWA,SAAS,qBAAqB;AAC9B,SAAS,YAAY,oBAAoB;AACzC,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAgC9B,eAAe,kBACb,WACA,aACkB;AAElB,MAAI;AACF,UAAM,MAAM,cAAc,KAAK,aAAa,cAAc,CAAC;AAC3D,UAAM,WAAW,IAAI,QAAQ,SAAS;AACtC,WAAO,MAAM,OAAO;AAAA,EACtB,QAAQ;AAAA,EAER;AAGA,QAAM,WAAW,UAAU,QAAQ,GAAG;AACtC,MAAI,aAAa,GAAI,QAAO;AAC5B,QAAM,UAAU,UAAU,MAAM,GAAG,QAAQ;AAC3C,QAAM,UAAU,KAAK,UAAU,MAAM,WAAW,CAAC,CAAC;AAElD,QAAM,SAAS,KAAK,aAAa,gBAAgB,OAAO;AACxD,QAAM,cAAc,KAAK,QAAQ,cAAc;AAC/C,MAAI,CAAC,WAAW,WAAW,EAAG,QAAO;AAErC,QAAM,UAAU,KAAK,MAAM,aAAa,aAAa,MAAM,CAAC;AAC5D,QAAM,cAAc,QAAQ,UAAU,OAAO;AAC7C,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,aACJ,OAAO,gBAAgB,WACnB,cACA,YAAY,UAAU,YAAY;AACxC,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,SAAO,MAAM,OAAO,cAAc,QAAQ,EAAE;AAC9C;AAaA,eAAsB,gBACpB,aAC8B;AAI9B,QAAM,OAAO,MAAM,OAAO,aAAa;AACvC,QAAM,gBACJ,KAAK,iBAAiB,CAAC;AAEzB,QAAM,YAAiC,CAAC;AAExC,aAAW,SAAS,eAAe;AACjC,QAAI;AACF,UAAI;AACJ,UAAI,aAAa;AACf,cAAO,MAAM,kBAAkB,MAAM,mBAAmB,WAAW;AAAA,MACrE,OAAO;AACL,cAAO,MAAM,OAAO,MAAM;AAAA,MAC5B;AACA,UAAI,KAAK,aAAa;AACpB,kBAAU,KAAK,IAAI,WAAW;AAAA,MAChC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAiBA,eAAsB,sBACpB,WACA,aACmB;AACnB,QAAM,SAAmB,CAAC;AAE1B,aAAW,YAAY,WAAW;AAChC,QAAI;AAEF,YAAM,OAAO,SAAS;AACtB,aAAO,KAAK,SAAS,WAAW;AAAA,IAClC,QAAQ;AAEN,UAAI,aAAa;AACf,YAAI;AACF,gBAAM,kBAAkB,SAAS,mBAAmB,WAAW;AAC/D,iBAAO,KAAK,SAAS,WAAW;AAAA,QAClC,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,YAAQ,wBAAwB,OAAO,KAAK,IAAI,CAAC,EAAE;AAAA,EACrD;AAEA,SAAO;AACT;","names":[]}
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  discoverPlugins,
18
18
  loadPluginESLintRules
19
- } from "./chunk-GFJDTSYD.js";
19
+ } from "./chunk-GYGQ7HHN.js";
20
20
  import {
21
21
  createSpinner,
22
22
  intro,
@@ -3902,7 +3902,7 @@ async function serve(options) {
3902
3902
  });
3903
3903
  setServerRunning(port);
3904
3904
  if (useDashboardUI) {
3905
- const { renderDashboard } = await import("./render-2P4YWHXV.js");
3905
+ const { renderDashboard } = await import("./render-XJWB6MVI.js");
3906
3906
  const { waitUntilExit } = renderDashboard({
3907
3907
  onQuit: () => {
3908
3908
  clearInterval(pingInterval);
@@ -3913,6 +3913,37 @@ async function serve(options) {
3913
3913
  },
3914
3914
  onRebuildIndex: () => {
3915
3915
  buildDuplicatesIndex(appRoot);
3916
+ },
3917
+ onClearCache: () => {
3918
+ cache.clear();
3919
+ fastCache.clear();
3920
+ semanticCache.clear();
3921
+ eslintInstances2.clear();
3922
+ eslintFastInstances.clear();
3923
+ updateCacheCount(0);
3924
+ logCacheInvalidate();
3925
+ import("uilint-eslint").then(
3926
+ ({ clearCache, clearAllSuggestions }) => {
3927
+ clearCache(wsRoot);
3928
+ clearAllSuggestions(wsRoot);
3929
+ if (appRoot !== wsRoot) {
3930
+ clearCache(appRoot);
3931
+ clearAllSuggestions(appRoot);
3932
+ }
3933
+ }
3934
+ );
3935
+ import("uilint-coverage").then(({ clearCoverageCache }) => {
3936
+ clearCoverageCache();
3937
+ });
3938
+ const coveragePath2 = join3(appRoot, "coverage", "coverage-final.json");
3939
+ if (existsSync5(coveragePath2)) {
3940
+ unlinkSync(coveragePath2);
3941
+ }
3942
+ buildCoverageData(appRoot);
3943
+ import("uilint-duplicates").then(({ clearIndexerCache }) => {
3944
+ clearIndexerCache(appRoot);
3945
+ });
3946
+ buildDuplicatesIndex(appRoot);
3916
3947
  }
3917
3948
  });
3918
3949
  await waitUntilExit();
@@ -6043,7 +6074,7 @@ program.command("update").description("Update existing style guide with new styl
6043
6074
  llm: options.llm
6044
6075
  });
6045
6076
  });
6046
- 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)").option("--vision", "Install Vision Analysis plugin").option("--semantic", "Install Semantic Analysis plugin").option("--duplicates", "Install Duplicates Detection plugin").option("--coverage", "Install test coverage rules");
6077
+ 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)");
6047
6078
  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) => {
6048
6079
  const { removeUI } = await import("./remove-ui-GZRFA2AC.js");
6049
6080
  await removeUI({ dryRun: options.dryRun, yes: options.yes });
@@ -6102,7 +6133,7 @@ program.addCommand(createDuplicatesCommand());
6102
6133
  program.addCommand(createManifestCommand());
6103
6134
  program.addCommand(createSocketCommand());
6104
6135
  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) => {
6105
- const { upgrade } = await import("./upgrade-WP6U3LEO.js");
6136
+ const { upgrade } = await import("./upgrade-QKD7JRI7.js");
6106
6137
  await upgrade({
6107
6138
  check: options.check,
6108
6139
  yes: options.yes,
@@ -6111,9 +6142,21 @@ program.command("upgrade").description("Update installed ESLint rules to latest
6111
6142
  });
6112
6143
  });
6113
6144
  async function main() {
6114
- const { discoverPlugins: discoverPlugins2 } = await import("./plugin-loader-V5CAMTYQ.js");
6145
+ const core = await import("uilint-core");
6146
+ const KNOWN_PLUGINS = core.KNOWN_PLUGINS ?? [
6147
+ { packageName: "uilint-vision" },
6148
+ { packageName: "uilint-semantic" },
6149
+ { packageName: "uilint-duplicates" },
6150
+ { packageName: "uilint-coverage" }
6151
+ ];
6152
+ const KNOWN_PLUGIN_FLAGS = [];
6153
+ for (const kp of KNOWN_PLUGINS) {
6154
+ const flag = kp.packageName.replace(/^uilint-/, "");
6155
+ KNOWN_PLUGIN_FLAGS.push(flag);
6156
+ initCommand.option(`--${flag}`, `Install ${kp.packageName} plugin`);
6157
+ }
6158
+ const { discoverPlugins: discoverPlugins2 } = await import("./plugin-loader-VTAJHQNK.js");
6115
6159
  const pluginManifests = await discoverPlugins2();
6116
- const KNOWN_PLUGIN_FLAGS = ["vision", "semantic", "duplicates", "coverage"];
6117
6160
  for (const manifest of pluginManifests) {
6118
6161
  if (!KNOWN_PLUGIN_FLAGS.includes(manifest.cliFlag)) {
6119
6162
  initCommand.option(`--${manifest.cliFlag}`, manifest.cliDescription);
@@ -6125,7 +6168,7 @@ async function main() {
6125
6168
  ...pluginManifests.map((m) => m.cliFlag)
6126
6169
  ]);
6127
6170
  const plugins = [...allFlags].filter((flag) => options[flag]);
6128
- const { initUI } = await import("./init-ui-CIK6YKOZ.js");
6171
+ const { initUI } = await import("./init-ui-ATSYWDOI.js");
6129
6172
  await initUI({
6130
6173
  force: options.force,
6131
6174
  react: options.react,