tailwind-lint 0.1.0 → 0.2.1

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/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- const require_linter = require('./linter-QRh7wAZ7.cjs');
3
- const require_constants = require('./constants-BFubEpZ9.cjs');
2
+ const require_linter = require('./linter-psTnhyzO.cjs');
3
+ const require_constants = require('./constants-DgveH41I.cjs');
4
4
  let node_path = require("node:path");
5
5
  node_path = require_linter.__toESM(node_path);
6
6
  let node_fs = require("node:fs");
@@ -10,6 +10,7 @@ chalk = require_linter.__toESM(chalk);
10
10
  let commander = require("commander");
11
11
 
12
12
  //#region src/cli.ts
13
+ const MAX_FILENAME_DISPLAY_LENGTH = 50;
13
14
  function countDiagnosticsBySeverity(diagnostics) {
14
15
  let errors = 0;
15
16
  let warnings = 0;
@@ -45,20 +46,20 @@ function resolveOptions(files, options) {
45
46
  verbose: options.verbose || false
46
47
  };
47
48
  }
48
- function truncateFilename(filename, maxLength) {
49
- return filename.length > maxLength ? `...${filename.slice(-maxLength)}` : filename;
49
+ function truncateFilename(filename) {
50
+ return filename.length > MAX_FILENAME_DISPLAY_LENGTH ? `...${filename.slice(-MAX_FILENAME_DISPLAY_LENGTH)}` : filename;
50
51
  }
51
- async function displayResults(files, fixMode, verbose) {
52
+ async function displayResults(files, fixMode) {
52
53
  let totalErrors = 0;
53
54
  let totalWarnings = 0;
54
55
  let totalFixed = 0;
55
56
  let filesWithIssues = 0;
56
57
  let isFirstFile = true;
57
58
  for (const file of files) if (file.diagnostics.length > 0 || fixMode && file.fixed) {
58
- if (isFirstFile && verbose) {
59
+ if (isFirstFile) {
59
60
  console.log();
60
61
  isFirstFile = false;
61
- } else if (!isFirstFile) console.log();
62
+ } else console.log();
62
63
  console.log(chalk.default.underline.bold(file.path));
63
64
  if (fixMode && file.fixed) {
64
65
  const issueText = `${file.fixedCount || 0} issue${file.fixedCount !== 1 ? "s" : ""}`;
@@ -165,23 +166,21 @@ ${chalk.default.bold.cyan("Notes:")}
165
166
  ...resolved,
166
167
  onProgress: (current, total, file) => {
167
168
  if (process.stdout.isTTY && !resolved.verbose) {
168
- const displayFile = truncateFilename(file, 50);
169
+ const displayFile = truncateFilename(file);
169
170
  process.stdout.write(`\rLinting files... (${current}/${total}) ${chalk.default.dim(displayFile)}${" ".repeat(10)}`);
170
171
  } else if (resolved.verbose) console.log(chalk.default.dim(` [${current}/${total}] Linting ${file}`));
171
172
  }
172
173
  });
173
- if (process.stdout.isTTY && !resolved.verbose) process.stdout.write("\r\x1B[K");
174
+ if (process.stdout.isTTY && !resolved.verbose) process.stdout.write("\n");
174
175
  if (results.totalFilesProcessed === 0) {
175
- if (resolved.verbose) console.log();
176
176
  console.log(chalk.default.yellow("No files found to lint."));
177
177
  process.exit(0);
178
178
  }
179
179
  if (results.files.length === 0) {
180
- if (resolved.verbose) console.log();
181
180
  console.log(chalk.default.green.bold("✔ No issues found"));
182
181
  process.exit(0);
183
182
  }
184
- await displayResults(results.files, resolved.fix, resolved.verbose);
183
+ await displayResults(results.files, resolved.fix);
185
184
  const hasErrors = results.files.some((file) => file.diagnostics.some((d) => d.severity === 1));
186
185
  process.exit(hasErrors ? 1 : 0);
187
186
  } catch (error) {
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","names":["path","DEFAULT_FILE_PATTERN","Command","fs","DEFAULT_VERSION","lint"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { DEFAULT_FILE_PATTERN, DEFAULT_VERSION } from \"./constants\";\nimport { lint } from \"./linter\";\nimport type { LintFileResult, SerializedDiagnostic } from \"./types\";\n\nfunction countDiagnosticsBySeverity(diagnostics: SerializedDiagnostic[]): {\n\terrors: number;\n\twarnings: number;\n} {\n\tlet errors = 0;\n\tlet warnings = 0;\n\n\tfor (const diagnostic of diagnostics) {\n\t\tif (diagnostic.severity === 1) errors++;\n\t\tif (diagnostic.severity === 2) warnings++;\n\t}\n\n\treturn { errors, warnings };\n}\n\ninterface ResolvedOptions {\n\tcwd: string;\n\tconfigPath: string | undefined;\n\tpatterns: string[];\n\tautoDiscover: boolean;\n\tfix: boolean;\n\tverbose: boolean;\n}\n\ninterface CliOptions {\n\tconfig?: string;\n\tauto?: boolean;\n\tfix?: boolean;\n\tverbose?: boolean;\n}\n\nfunction resolveOptions(files: string[], options: CliOptions): ResolvedOptions {\n\tconst hasConfigFlag = !!options.config;\n\tconst hasAutoFlag = !!options.auto;\n\tconst hasFiles = files.length > 0;\n\n\tlet cwd = process.cwd();\n\tlet configPath = options.config;\n\tlet patterns = files;\n\n\tif (hasConfigFlag && options.config && !hasFiles) {\n\t\tconst absoluteConfigPath = path.isAbsolute(options.config)\n\t\t\t? options.config\n\t\t\t: path.resolve(process.cwd(), options.config);\n\t\tcwd = path.dirname(absoluteConfigPath);\n\t\tconfigPath = path.basename(absoluteConfigPath);\n\t\tpatterns = [DEFAULT_FILE_PATTERN];\n\t}\n\n\tconst autoDiscover = hasAutoFlag;\n\n\treturn {\n\t\tcwd,\n\t\tconfigPath,\n\t\tpatterns: autoDiscover ? [] : patterns,\n\t\tautoDiscover,\n\t\tfix: options.fix || false,\n\t\tverbose: options.verbose || false,\n\t};\n}\n\nfunction truncateFilename(filename: string, maxLength: number): string {\n\treturn filename.length > maxLength\n\t\t? `...${filename.slice(-maxLength)}`\n\t\t: filename;\n}\n\nasync function displayResults(\n\tfiles: LintFileResult[],\n\tfixMode: boolean,\n\tverbose: boolean,\n): Promise<void> {\n\tlet totalErrors = 0;\n\tlet totalWarnings = 0;\n\tlet totalFixed = 0;\n\tlet filesWithIssues = 0;\n\tlet isFirstFile = true;\n\n\tfor (const file of files) {\n\t\tif (file.diagnostics.length > 0 || (fixMode && file.fixed)) {\n\t\t\tif (isFirstFile && verbose) {\n\t\t\t\tconsole.log();\n\t\t\t\tisFirstFile = false;\n\t\t\t} else if (!isFirstFile) {\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t\tconsole.log(chalk.underline.bold(file.path));\n\n\t\t\tif (fixMode && file.fixed) {\n\t\t\t\tconst issueText = `${file.fixedCount || 0} issue${file.fixedCount !== 1 ? \"s\" : \"\"}`;\n\t\t\t\tconsole.log(chalk.green(` ✔ Fixed ${issueText}`));\n\t\t\t\ttotalFixed += file.fixedCount || 0;\n\t\t\t}\n\n\t\t\tconst { errors, warnings } = countDiagnosticsBySeverity(file.diagnostics);\n\t\t\ttotalErrors += errors;\n\t\t\ttotalWarnings += warnings;\n\n\t\t\tif (file.diagnostics.length > 0) {\n\t\t\t\tfilesWithIssues++;\n\t\t\t}\n\n\t\t\tfor (const diagnostic of file.diagnostics) {\n\t\t\t\tconst line = diagnostic.range.start.line + 1;\n\t\t\t\tconst char = diagnostic.range.start.character + 1;\n\t\t\t\tconst severity = diagnostic.severity === 1 ? \"error\" : \"warning\";\n\t\t\t\tconst severityColor =\n\t\t\t\t\tdiagnostic.severity === 1\n\t\t\t\t\t\t? chalk.red(severity)\n\t\t\t\t\t\t: chalk.yellow(severity);\n\t\t\t\tconst code = diagnostic.code ? chalk.dim(` (${diagnostic.code})`) : \"\";\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ${chalk.dim(`${line}:${char}`)} ${severityColor} ${diagnostic.message}${code}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconsole.log();\n\n\tif (totalErrors === 0 && totalWarnings === 0) {\n\t\tif (totalFixed > 0) {\n\t\t\tconst issueText = `${totalFixed} issue${totalFixed !== 1 ? \"s\" : \"\"}`;\n\t\t\tconsole.log(chalk.green.bold(`✔ Fixed ${issueText}`));\n\t\t} else {\n\t\t\tconsole.log(chalk.green.bold(\"✔ No issues found\"));\n\t\t}\n\t} else {\n\t\tconst parts = [];\n\t\tif (totalErrors > 0) {\n\t\t\tparts.push(`${totalErrors} error${totalErrors !== 1 ? \"s\" : \"\"}`);\n\t\t}\n\t\tif (totalWarnings > 0) {\n\t\t\tparts.push(`${totalWarnings} warning${totalWarnings !== 1 ? \"s\" : \"\"}`);\n\t\t}\n\n\t\tconst fileText = `${filesWithIssues} file${filesWithIssues !== 1 ? \"s\" : \"\"}`;\n\t\tconst summary = `Found ${parts.join(\" and \")} in ${fileText}`;\n\n\t\tif (totalFixed > 0) {\n\t\t\tconst issueText = `${totalFixed} issue${totalFixed !== 1 ? \"s\" : \"\"}`;\n\t\t\tconsole.log(chalk.green.bold(`✔ Fixed ${issueText}`));\n\t\t\tconsole.log(summary);\n\t\t} else {\n\t\t\tconsole.log(summary);\n\t\t}\n\t}\n}\n\nconst program = new Command();\n\nconst getVersion = (): string => {\n\tconst packageJsonPath = path.join(__dirname, \"../package.json\");\n\ttry {\n\t\tconst pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n\t\treturn pkg.version || DEFAULT_VERSION;\n\t} catch {\n\t\treturn DEFAULT_VERSION;\n\t}\n};\n\nprogram.configureHelp({\n\tformatHelp: (cmd, helper) => {\n\t\tconst termWidth = helper.padWidth(cmd, helper);\n\t\tlet output = \"\";\n\n\t\toutput += `${chalk.bold.cyan(\"Usage:\")} ${helper.commandUsage(cmd)}\\n\\n`;\n\n\t\tif (cmd.description()) {\n\t\t\toutput += `${cmd.description()}\\n\\n`;\n\t\t}\n\n\t\tconst args = helper.visibleArguments(cmd);\n\t\tif (args.length > 0) {\n\t\t\toutput += `${chalk.bold.cyan(\"Arguments:\")}\\n`;\n\t\t\targs.forEach((arg) => {\n\t\t\t\tconst argName = arg.required ? `<${arg.name()}>` : `[${arg.name()}]`;\n\t\t\t\toutput += ` ${chalk.green(argName.padEnd(termWidth))} ${arg.description}\\n`;\n\t\t\t});\n\t\t\toutput += \"\\n\";\n\t\t}\n\n\t\tconst options = helper.visibleOptions(cmd);\n\t\tif (options.length > 0) {\n\t\t\toutput += `${chalk.bold.cyan(\"Options:\")}\\n`;\n\t\t\toptions.forEach((option) => {\n\t\t\t\tconst flags = helper.optionTerm(option);\n\t\t\t\tconst description = helper.optionDescription(option);\n\t\t\t\toutput += ` ${chalk.yellow(flags.padEnd(termWidth))} ${description}\\n`;\n\t\t\t});\n\t\t\toutput += \"\\n\";\n\t\t}\n\n\t\treturn output;\n\t},\n});\n\nprogram\n\t.name(\"tailwind-lint\")\n\t.description(\"A CLI tool for linting Tailwind CSS class usage\")\n\t.version(getVersion())\n\t.argument(\n\t\t\"[files...]\",\n\t\t'File patterns to lint (e.g., \"src/**/*.{js,jsx,ts,tsx}\")',\n\t)\n\t.option(\n\t\t\"-c, --config <path>\",\n\t\t\"Path to Tailwind config file (default: auto-discover)\",\n\t)\n\t.option(\n\t\t\"-a, --auto\",\n\t\t\"Auto-discover files from Tailwind config content patterns\",\n\t)\n\t.option(\"--fix\", \"Automatically fix problems that can be fixed\")\n\t.option(\"-v, --verbose\", \"Enable verbose logging for debugging\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\n${chalk.bold.cyan(\"Examples:\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"src/**/*.{js,jsx,ts,tsx}\"')}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.yellow(\"--auto\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.yellow(\"--config\")} ${chalk.green(\"./tailwind.config.js\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"src/**/*.tsx\"')} ${chalk.yellow(\"--fix\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"**/*.vue\"')}\n\n${chalk.bold.cyan(\"Notes:\")}\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--auto\")} to auto-discover files from your Tailwind config (v3 only)\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--config\")} alone to lint common file types from that directory\n ${chalk.dim(\"•\")} Default pattern: ${chalk.dim(\"./**/*.{js,jsx,ts,tsx,html}\")}\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--fix\")} to automatically resolve fixable issues\n`,\n\t)\n\t.action(async (files: string[], options) => {\n\t\tconst hasConfigFlag = !!options.config;\n\t\tconst hasAutoFlag = !!options.auto;\n\t\tconst hasFiles = files.length > 0;\n\n\t\tif (!hasFiles && !hasAutoFlag && !hasConfigFlag) {\n\t\t\tconsole.error(\n\t\t\t\t\"Error: No files specified. Use glob patterns, --auto flag, or --config flag.\\n\",\n\t\t\t);\n\t\t\tprogram.help();\n\t\t}\n\n\t\tconst resolved = resolveOptions(files, options);\n\n\t\ttry {\n\t\t\tif (resolved.verbose) {\n\t\t\t\tconsole.log(chalk.cyan(\"→ Running in verbose mode\"));\n\t\t\t\tconsole.log(chalk.dim(` Working directory: ${resolved.cwd}`));\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(` Config path: ${resolved.configPath || \"auto-discover\"}`),\n\t\t\t\t);\n\t\t\t\tconsole.log(chalk.dim(` Fix mode: ${resolved.fix}`));\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(\n\t\t\t\t\t\t` Patterns: ${resolved.patterns.length > 0 ? resolved.patterns.join(\", \") : \"auto-discover\"}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconsole.log();\n\n\t\t\tconst results = await lint({\n\t\t\t\t...resolved,\n\t\t\t\tonProgress: (current, total, file) => {\n\t\t\t\t\tif (process.stdout.isTTY && !resolved.verbose) {\n\t\t\t\t\t\tconst displayFile = truncateFilename(file, 50);\n\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t`\\rLinting files... (${current}/${total}) ${chalk.dim(displayFile)}${\" \".repeat(10)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (resolved.verbose) {\n\t\t\t\t\t\tconsole.log(chalk.dim(` [${current}/${total}] Linting ${file}`));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (process.stdout.isTTY && !resolved.verbose) {\n\t\t\t\tprocess.stdout.write(\"\\r\\x1b[K\");\n\t\t\t}\n\n\t\t\tif (results.totalFilesProcessed === 0) {\n\t\t\t\tif (resolved.verbose) {\n\t\t\t\t\tconsole.log();\n\t\t\t\t}\n\t\t\t\tconsole.log(chalk.yellow(\"No files found to lint.\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\tif (results.files.length === 0) {\n\t\t\t\tif (resolved.verbose) {\n\t\t\t\t\tconsole.log();\n\t\t\t\t}\n\t\t\t\tconsole.log(chalk.green.bold(\"✔ No issues found\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\tawait displayResults(results.files, resolved.fix, resolved.verbose);\n\n\t\t\tconst hasErrors = results.files.some((file) =>\n\t\t\t\tfile.diagnostics.some((d) => d.severity === 1),\n\t\t\t);\n\t\t\tprocess.exit(hasErrors ? 1 : 0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tconsole.error(chalk.red(\"✖ Error:\"), errorMessage);\n\n\t\t\tif (resolved.verbose && error instanceof Error) {\n\t\t\t\tconsole.error(chalk.dim(\"\\nStack trace:\"));\n\t\t\t\tconsole.error(chalk.dim(error.stack || error.toString()));\n\t\t\t}\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.cjs","names":["path","DEFAULT_FILE_PATTERN","Command","fs","DEFAULT_VERSION","lint"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { DEFAULT_FILE_PATTERN, DEFAULT_VERSION } from \"./constants\";\nimport { lint } from \"./linter\";\nimport type { LintFileResult, SerializedDiagnostic } from \"./types\";\n\nconst MAX_FILENAME_DISPLAY_LENGTH = 50;\n\nfunction countDiagnosticsBySeverity(diagnostics: SerializedDiagnostic[]): {\n\terrors: number;\n\twarnings: number;\n} {\n\tlet errors = 0;\n\tlet warnings = 0;\n\n\tfor (const diagnostic of diagnostics) {\n\t\tif (diagnostic.severity === 1) errors++;\n\t\tif (diagnostic.severity === 2) warnings++;\n\t}\n\n\treturn { errors, warnings };\n}\n\ninterface ResolvedOptions {\n\tcwd: string;\n\tconfigPath: string | undefined;\n\tpatterns: string[];\n\tautoDiscover: boolean;\n\tfix: boolean;\n\tverbose: boolean;\n}\n\ninterface CliOptions {\n\tconfig?: string;\n\tauto?: boolean;\n\tfix?: boolean;\n\tverbose?: boolean;\n}\n\nfunction resolveOptions(files: string[], options: CliOptions): ResolvedOptions {\n\tconst hasConfigFlag = !!options.config;\n\tconst hasAutoFlag = !!options.auto;\n\tconst hasFiles = files.length > 0;\n\n\tlet cwd = process.cwd();\n\tlet configPath = options.config;\n\tlet patterns = files;\n\n\tif (hasConfigFlag && options.config && !hasFiles) {\n\t\tconst absoluteConfigPath = path.isAbsolute(options.config)\n\t\t\t? options.config\n\t\t\t: path.resolve(process.cwd(), options.config);\n\t\tcwd = path.dirname(absoluteConfigPath);\n\t\tconfigPath = path.basename(absoluteConfigPath);\n\t\tpatterns = [DEFAULT_FILE_PATTERN];\n\t}\n\n\tconst autoDiscover = hasAutoFlag;\n\n\treturn {\n\t\tcwd,\n\t\tconfigPath,\n\t\tpatterns: autoDiscover ? [] : patterns,\n\t\tautoDiscover,\n\t\tfix: options.fix || false,\n\t\tverbose: options.verbose || false,\n\t};\n}\n\nfunction truncateFilename(filename: string): string {\n\treturn filename.length > MAX_FILENAME_DISPLAY_LENGTH\n\t\t? `...${filename.slice(-MAX_FILENAME_DISPLAY_LENGTH)}`\n\t\t: filename;\n}\n\nasync function displayResults(\n\tfiles: LintFileResult[],\n\tfixMode: boolean,\n): Promise<void> {\n\tlet totalErrors = 0;\n\tlet totalWarnings = 0;\n\tlet totalFixed = 0;\n\tlet filesWithIssues = 0;\n\tlet isFirstFile = true;\n\n\tfor (const file of files) {\n\t\tif (file.diagnostics.length > 0 || (fixMode && file.fixed)) {\n\t\t\tif (isFirstFile) {\n\t\t\t\tconsole.log();\n\t\t\t\tisFirstFile = false;\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t\tconsole.log(chalk.underline.bold(file.path));\n\n\t\t\tif (fixMode && file.fixed) {\n\t\t\t\tconst issueText = `${file.fixedCount || 0} issue${file.fixedCount !== 1 ? \"s\" : \"\"}`;\n\t\t\t\tconsole.log(chalk.green(` ✔ Fixed ${issueText}`));\n\t\t\t\ttotalFixed += file.fixedCount || 0;\n\t\t\t}\n\n\t\t\tconst { errors, warnings } = countDiagnosticsBySeverity(file.diagnostics);\n\t\t\ttotalErrors += errors;\n\t\t\ttotalWarnings += warnings;\n\n\t\t\tif (file.diagnostics.length > 0) {\n\t\t\t\tfilesWithIssues++;\n\t\t\t}\n\n\t\t\tfor (const diagnostic of file.diagnostics) {\n\t\t\t\tconst line = diagnostic.range.start.line + 1;\n\t\t\t\tconst char = diagnostic.range.start.character + 1;\n\t\t\t\tconst severity = diagnostic.severity === 1 ? \"error\" : \"warning\";\n\t\t\t\tconst severityColor =\n\t\t\t\t\tdiagnostic.severity === 1\n\t\t\t\t\t\t? chalk.red(severity)\n\t\t\t\t\t\t: chalk.yellow(severity);\n\t\t\t\tconst code = diagnostic.code ? chalk.dim(` (${diagnostic.code})`) : \"\";\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ${chalk.dim(`${line}:${char}`)} ${severityColor} ${diagnostic.message}${code}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tconsole.log();\n\n\tif (totalErrors === 0 && totalWarnings === 0) {\n\t\tif (totalFixed > 0) {\n\t\t\tconst issueText = `${totalFixed} issue${totalFixed !== 1 ? \"s\" : \"\"}`;\n\t\t\tconsole.log(chalk.green.bold(`✔ Fixed ${issueText}`));\n\t\t} else {\n\t\t\tconsole.log(chalk.green.bold(\"✔ No issues found\"));\n\t\t}\n\t} else {\n\t\tconst parts = [];\n\t\tif (totalErrors > 0) {\n\t\t\tparts.push(`${totalErrors} error${totalErrors !== 1 ? \"s\" : \"\"}`);\n\t\t}\n\t\tif (totalWarnings > 0) {\n\t\t\tparts.push(`${totalWarnings} warning${totalWarnings !== 1 ? \"s\" : \"\"}`);\n\t\t}\n\n\t\tconst fileText = `${filesWithIssues} file${filesWithIssues !== 1 ? \"s\" : \"\"}`;\n\t\tconst summary = `Found ${parts.join(\" and \")} in ${fileText}`;\n\n\t\tif (totalFixed > 0) {\n\t\t\tconst issueText = `${totalFixed} issue${totalFixed !== 1 ? \"s\" : \"\"}`;\n\t\t\tconsole.log(chalk.green.bold(`✔ Fixed ${issueText}`));\n\t\t\tconsole.log(summary);\n\t\t} else {\n\t\t\tconsole.log(summary);\n\t\t}\n\t}\n}\n\nconst program = new Command();\n\nconst getVersion = (): string => {\n\tconst packageJsonPath = path.join(__dirname, \"../package.json\");\n\ttry {\n\t\tconst pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n\t\treturn pkg.version || DEFAULT_VERSION;\n\t} catch {\n\t\treturn DEFAULT_VERSION;\n\t}\n};\n\nprogram.configureHelp({\n\tformatHelp: (cmd, helper) => {\n\t\tconst termWidth = helper.padWidth(cmd, helper);\n\t\tlet output = \"\";\n\n\t\toutput += `${chalk.bold.cyan(\"Usage:\")} ${helper.commandUsage(cmd)}\\n\\n`;\n\n\t\tif (cmd.description()) {\n\t\t\toutput += `${cmd.description()}\\n\\n`;\n\t\t}\n\n\t\tconst args = helper.visibleArguments(cmd);\n\t\tif (args.length > 0) {\n\t\t\toutput += `${chalk.bold.cyan(\"Arguments:\")}\\n`;\n\t\t\targs.forEach((arg) => {\n\t\t\t\tconst argName = arg.required ? `<${arg.name()}>` : `[${arg.name()}]`;\n\t\t\t\toutput += ` ${chalk.green(argName.padEnd(termWidth))} ${arg.description}\\n`;\n\t\t\t});\n\t\t\toutput += \"\\n\";\n\t\t}\n\n\t\tconst options = helper.visibleOptions(cmd);\n\t\tif (options.length > 0) {\n\t\t\toutput += `${chalk.bold.cyan(\"Options:\")}\\n`;\n\t\t\toptions.forEach((option) => {\n\t\t\t\tconst flags = helper.optionTerm(option);\n\t\t\t\tconst description = helper.optionDescription(option);\n\t\t\t\toutput += ` ${chalk.yellow(flags.padEnd(termWidth))} ${description}\\n`;\n\t\t\t});\n\t\t\toutput += \"\\n\";\n\t\t}\n\n\t\treturn output;\n\t},\n});\n\nprogram\n\t.name(\"tailwind-lint\")\n\t.description(\"A CLI tool for linting Tailwind CSS class usage\")\n\t.version(getVersion())\n\t.argument(\n\t\t\"[files...]\",\n\t\t'File patterns to lint (e.g., \"src/**/*.{js,jsx,ts,tsx}\")',\n\t)\n\t.option(\n\t\t\"-c, --config <path>\",\n\t\t\"Path to Tailwind config file (default: auto-discover)\",\n\t)\n\t.option(\n\t\t\"-a, --auto\",\n\t\t\"Auto-discover files from Tailwind config content patterns\",\n\t)\n\t.option(\"--fix\", \"Automatically fix problems that can be fixed\")\n\t.option(\"-v, --verbose\", \"Enable verbose logging for debugging\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\n${chalk.bold.cyan(\"Examples:\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"src/**/*.{js,jsx,ts,tsx}\"')}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.yellow(\"--auto\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.yellow(\"--config\")} ${chalk.green(\"./tailwind.config.js\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"src/**/*.tsx\"')} ${chalk.yellow(\"--fix\")}\n ${chalk.dim(\"$\")} tailwind-lint ${chalk.green('\"**/*.vue\"')}\n\n${chalk.bold.cyan(\"Notes:\")}\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--auto\")} to auto-discover files from your Tailwind config (v3 only)\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--config\")} alone to lint common file types from that directory\n ${chalk.dim(\"•\")} Default pattern: ${chalk.dim(\"./**/*.{js,jsx,ts,tsx,html}\")}\n ${chalk.dim(\"•\")} Use ${chalk.yellow(\"--fix\")} to automatically resolve fixable issues\n`,\n\t)\n\t.action(async (files: string[], options) => {\n\t\tconst hasConfigFlag = !!options.config;\n\t\tconst hasAutoFlag = !!options.auto;\n\t\tconst hasFiles = files.length > 0;\n\n\t\tif (!hasFiles && !hasAutoFlag && !hasConfigFlag) {\n\t\t\tconsole.error(\n\t\t\t\t\"Error: No files specified. Use glob patterns, --auto flag, or --config flag.\\n\",\n\t\t\t);\n\t\t\tprogram.help();\n\t\t}\n\n\t\tconst resolved = resolveOptions(files, options);\n\n\t\ttry {\n\t\t\tif (resolved.verbose) {\n\t\t\t\tconsole.log(chalk.cyan(\"→ Running in verbose mode\"));\n\t\t\t\tconsole.log(chalk.dim(` Working directory: ${resolved.cwd}`));\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(` Config path: ${resolved.configPath || \"auto-discover\"}`),\n\t\t\t\t);\n\t\t\t\tconsole.log(chalk.dim(` Fix mode: ${resolved.fix}`));\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(\n\t\t\t\t\t\t` Patterns: ${resolved.patterns.length > 0 ? resolved.patterns.join(\", \") : \"auto-discover\"}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconsole.log();\n\n\t\t\tconst results = await lint({\n\t\t\t\t...resolved,\n\t\t\t\tonProgress: (current, total, file) => {\n\t\t\t\t\tif (process.stdout.isTTY && !resolved.verbose) {\n\t\t\t\t\t\tconst displayFile = truncateFilename(file);\n\t\t\t\t\t\tprocess.stdout.write(\n\t\t\t\t\t\t\t`\\rLinting files... (${current}/${total}) ${chalk.dim(displayFile)}${\" \".repeat(10)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (resolved.verbose) {\n\t\t\t\t\t\tconsole.log(chalk.dim(` [${current}/${total}] Linting ${file}`));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (process.stdout.isTTY && !resolved.verbose) {\n\t\t\t\tprocess.stdout.write(\"\\n\");\n\t\t\t}\n\n\t\t\tif (results.totalFilesProcessed === 0) {\n\t\t\t\tconsole.log(chalk.yellow(\"No files found to lint.\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\tif (results.files.length === 0) {\n\t\t\t\tconsole.log(chalk.green.bold(\"✔ No issues found\"));\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\tawait displayResults(results.files, resolved.fix);\n\n\t\t\tconst hasErrors = results.files.some((file) =>\n\t\t\t\tfile.diagnostics.some((d) => d.severity === 1),\n\t\t\t);\n\t\t\tprocess.exit(hasErrors ? 1 : 0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tconsole.error(chalk.red(\"✖ Error:\"), errorMessage);\n\n\t\t\tif (resolved.verbose && error instanceof Error) {\n\t\t\t\tconsole.error(chalk.dim(\"\\nStack trace:\"));\n\t\t\t\tconsole.error(chalk.dim(error.stack || error.toString()));\n\t\t\t}\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const require_constants = require('./constants-BFubEpZ9.cjs');
1
+ const require_constants = require('./constants-DgveH41I.cjs');
2
2
 
3
3
  exports.V3_CONFIG_PATHS = require_constants.V3_CONFIG_PATHS;
4
4
  exports.V4_CSS_FOLDERS = require_constants.V4_CSS_FOLDERS;
@@ -32,13 +32,43 @@ const V4_CSS_FOLDERS = [
32
32
  "./app/",
33
33
  "./styles/"
34
34
  ];
35
+ const LANGUAGE_MAP = {
36
+ ".astro": "astro",
37
+ ".css": "css",
38
+ ".erb": "erb",
39
+ ".hbs": "handlebars",
40
+ ".htm": "html",
41
+ ".html": "html",
42
+ ".js": "javascript",
43
+ ".jsx": "javascriptreact",
44
+ ".less": "less",
45
+ ".md": "markdown",
46
+ ".mdx": "mdx",
47
+ ".php": "php",
48
+ ".sass": "sass",
49
+ ".scss": "scss",
50
+ ".svelte": "svelte",
51
+ ".ts": "typescript",
52
+ ".tsx": "typescriptreact",
53
+ ".twig": "twig",
54
+ ".vue": "vue"
55
+ };
35
56
  const DEFAULT_VERSION = "0.0.1";
36
- const MAX_FIX_ITERATIONS = 10;
37
57
  const DEFAULT_TAB_SIZE = 2;
38
58
  const DEFAULT_SEPARATOR = ":";
39
59
  const DEFAULT_ROOT_FONT_SIZE = 16;
60
+ const CONCURRENT_FILES = 10;
61
+ function getLanguageId(filePath) {
62
+ return LANGUAGE_MAP[filePath.substring(filePath.lastIndexOf(".")).toLowerCase()] || "html";
63
+ }
40
64
 
41
65
  //#endregion
66
+ Object.defineProperty(exports, 'CONCURRENT_FILES', {
67
+ enumerable: true,
68
+ get: function () {
69
+ return CONCURRENT_FILES;
70
+ }
71
+ });
42
72
  Object.defineProperty(exports, 'DEFAULT_FILE_PATTERN', {
43
73
  enumerable: true,
44
74
  get: function () {
@@ -75,10 +105,10 @@ Object.defineProperty(exports, 'DEFAULT_VERSION', {
75
105
  return DEFAULT_VERSION;
76
106
  }
77
107
  });
78
- Object.defineProperty(exports, 'MAX_FIX_ITERATIONS', {
108
+ Object.defineProperty(exports, 'LANGUAGE_MAP', {
79
109
  enumerable: true,
80
110
  get: function () {
81
- return MAX_FIX_ITERATIONS;
111
+ return LANGUAGE_MAP;
82
112
  }
83
113
  });
84
114
  Object.defineProperty(exports, 'V3_CONFIG_PATHS', {
@@ -99,4 +129,10 @@ Object.defineProperty(exports, 'V4_CSS_NAMES', {
99
129
  return V4_CSS_NAMES;
100
130
  }
101
131
  });
102
- //# sourceMappingURL=constants-BFubEpZ9.cjs.map
132
+ Object.defineProperty(exports, 'getLanguageId', {
133
+ enumerable: true,
134
+ get: function () {
135
+ return getLanguageId;
136
+ }
137
+ });
138
+ //# sourceMappingURL=constants-DgveH41I.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants-BFubEpZ9.cjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const DEFAULT_IGNORE_PATTERNS = [\n\t\"**/node_modules/**\",\n\t\"**/dist/**\",\n\t\"**/build/**\",\n\t\"**/.git/**\",\n\t\"**/.next/**\",\n\t\"**/.nuxt/**\",\n\t\"**/coverage/**\",\n\t\"**/.vscode/**\",\n\t\"**/.idea/**\",\n\t\"**/.cache/**\",\n\t\"**/.DS_Store/**\",\n];\n\nexport const DEFAULT_FILE_PATTERN = \"./**/*.{js,jsx,ts,tsx,html}\";\n\nexport const V3_CONFIG_PATHS = [\n\t\"tailwind.config.js\",\n\t\"tailwind.config.cjs\",\n\t\"tailwind.config.mjs\",\n\t\"tailwind.config.ts\",\n];\n\nexport const V4_CSS_NAMES = [\n\t\"app.css\",\n\t\"index.css\",\n\t\"tailwind.css\",\n\t\"globals.css\",\n];\n\nexport const V4_CSS_FOLDERS = [\"./\", \"./src/\", \"./app/\", \"./styles/\"];\n\nexport const LANGUAGE_MAP: Record<string, string> = {\n\t\".astro\": \"astro\",\n\t\".css\": \"css\",\n\t\".erb\": \"erb\",\n\t\".hbs\": \"handlebars\",\n\t\".htm\": \"html\",\n\t\".html\": \"html\",\n\t\".js\": \"javascript\",\n\t\".jsx\": \"javascriptreact\",\n\t\".less\": \"less\",\n\t\".md\": \"markdown\",\n\t\".mdx\": \"mdx\",\n\t\".php\": \"php\",\n\t\".sass\": \"sass\",\n\t\".scss\": \"scss\",\n\t\".svelte\": \"svelte\",\n\t\".ts\": \"typescript\",\n\t\".tsx\": \"typescriptreact\",\n\t\".twig\": \"twig\",\n\t\".vue\": \"vue\",\n};\n\nexport const DEFAULT_VERSION = \"0.0.1\";\n\nexport const MAX_FIX_ITERATIONS = 10;\n\nexport const DEFAULT_TAB_SIZE = 2;\n\nexport const DEFAULT_SEPARATOR = \":\";\n\nexport const DEFAULT_ROOT_FONT_SIZE = 16;\n"],"mappings":";;AAAA,MAAa,0BAA0B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAED,MAAa,uBAAuB;AAEpC,MAAa,kBAAkB;CAC9B;CACA;CACA;CACA;CACA;AAED,MAAa,eAAe;CAC3B;CACA;CACA;CACA;CACA;AAED,MAAa,iBAAiB;CAAC;CAAM;CAAU;CAAU;CAAY;AAwBrE,MAAa,kBAAkB;AAE/B,MAAa,qBAAqB;AAElC,MAAa,mBAAmB;AAEhC,MAAa,oBAAoB;AAEjC,MAAa,yBAAyB"}
1
+ {"version":3,"file":"constants-DgveH41I.cjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const DEFAULT_IGNORE_PATTERNS = [\n\t\"**/node_modules/**\",\n\t\"**/dist/**\",\n\t\"**/build/**\",\n\t\"**/.git/**\",\n\t\"**/.next/**\",\n\t\"**/.nuxt/**\",\n\t\"**/coverage/**\",\n\t\"**/.vscode/**\",\n\t\"**/.idea/**\",\n\t\"**/.cache/**\",\n\t\"**/.DS_Store/**\",\n];\n\nexport const DEFAULT_FILE_PATTERN = \"./**/*.{js,jsx,ts,tsx,html}\";\n\nexport const V3_CONFIG_PATHS = [\n\t\"tailwind.config.js\",\n\t\"tailwind.config.cjs\",\n\t\"tailwind.config.mjs\",\n\t\"tailwind.config.ts\",\n];\n\nexport const V4_CSS_NAMES = [\n\t\"app.css\",\n\t\"index.css\",\n\t\"tailwind.css\",\n\t\"globals.css\",\n];\n\nexport const V4_CSS_FOLDERS = [\"./\", \"./src/\", \"./app/\", \"./styles/\"];\n\nexport const LANGUAGE_MAP: Record<string, string> = {\n\t\".astro\": \"astro\",\n\t\".css\": \"css\",\n\t\".erb\": \"erb\",\n\t\".hbs\": \"handlebars\",\n\t\".htm\": \"html\",\n\t\".html\": \"html\",\n\t\".js\": \"javascript\",\n\t\".jsx\": \"javascriptreact\",\n\t\".less\": \"less\",\n\t\".md\": \"markdown\",\n\t\".mdx\": \"mdx\",\n\t\".php\": \"php\",\n\t\".sass\": \"sass\",\n\t\".scss\": \"scss\",\n\t\".svelte\": \"svelte\",\n\t\".ts\": \"typescript\",\n\t\".tsx\": \"typescriptreact\",\n\t\".twig\": \"twig\",\n\t\".vue\": \"vue\",\n};\n\nexport const DEFAULT_VERSION = \"0.0.1\";\n\nexport const DEFAULT_TAB_SIZE = 2;\n\nexport const DEFAULT_SEPARATOR = \":\";\n\nexport const DEFAULT_ROOT_FONT_SIZE = 16;\n\nexport const CONCURRENT_FILES = 10;\n\nexport function getLanguageId(filePath: string): string {\n\tconst ext = filePath.substring(filePath.lastIndexOf(\".\")).toLowerCase();\n\treturn LANGUAGE_MAP[ext] || \"html\";\n}\n"],"mappings":";;AAAA,MAAa,0BAA0B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAED,MAAa,uBAAuB;AAEpC,MAAa,kBAAkB;CAC9B;CACA;CACA;CACA;CACA;AAED,MAAa,eAAe;CAC3B;CACA;CACA;CACA;CACA;AAED,MAAa,iBAAiB;CAAC;CAAM;CAAU;CAAU;CAAY;AAErE,MAAa,eAAuC;CACnD,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,SAAS;CACT,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR;AAED,MAAa,kBAAkB;AAE/B,MAAa,mBAAmB;AAEhC,MAAa,oBAAoB;AAEjC,MAAa,yBAAyB;AAEtC,MAAa,mBAAmB;AAEhC,SAAgB,cAAc,UAA0B;AAEvD,QAAO,aADK,SAAS,UAAU,SAAS,YAAY,IAAI,CAAC,CAAC,aAAa,KAC3C"}
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  }) : target, mod));
26
26
 
27
27
  //#endregion
28
- const require_constants = require('./constants-BFubEpZ9.cjs');
28
+ const require_constants = require('./constants-DgveH41I.cjs');
29
29
  let node_path = require("node:path");
30
30
  node_path = __toESM(node_path);
31
31
  let _tailwindcss_language_service = require("@tailwindcss/language-service");
@@ -37,29 +37,6 @@ node_fs = __toESM(node_fs);
37
37
  let node_module = require("node:module");
38
38
 
39
39
  //#region src/code-actions.ts
40
- function getLanguageId$1(filePath) {
41
- return {
42
- ".astro": "astro",
43
- ".css": "css",
44
- ".erb": "erb",
45
- ".hbs": "handlebars",
46
- ".htm": "html",
47
- ".html": "html",
48
- ".js": "javascript",
49
- ".jsx": "javascriptreact",
50
- ".less": "less",
51
- ".md": "markdown",
52
- ".mdx": "mdx",
53
- ".php": "php",
54
- ".sass": "sass",
55
- ".scss": "scss",
56
- ".svelte": "svelte",
57
- ".ts": "typescript",
58
- ".tsx": "typescriptreact",
59
- ".twig": "twig",
60
- ".vue": "vue"
61
- }[node_path.extname(filePath).toLowerCase()] || "html";
62
- }
63
40
  async function getQuickfixes(state, document, uri, diagnostics) {
64
41
  const lspDiagnostics = diagnostics.map((diag) => ({
65
42
  range: diag.range,
@@ -104,31 +81,40 @@ async function applyCodeActions(state, filePath, content, diagnostics) {
104
81
  changed: false,
105
82
  fixedCount: 0
106
83
  };
107
- const languageId = getLanguageId$1(filePath);
108
- const uri = `file://${filePath}`;
109
- let currentDocument = vscode_languageserver_textdocument.TextDocument.create(uri, languageId, 1, content);
110
- let currentContent = content;
111
- let totalFixed = 0;
112
- let iteration = 0;
113
- for (; iteration < require_constants.MAX_FIX_ITERATIONS; iteration++) {
114
- const currentDiagnostics = await (0, _tailwindcss_language_service.doValidate)(state, currentDocument);
115
- if (currentDiagnostics.length === 0) break;
116
- const quickfixes = await getQuickfixes(state, currentDocument, uri, currentDiagnostics);
117
- if (quickfixes.length === 0) break;
118
- const fixResult = applyFirstQuickfix(quickfixes[0], uri, currentDocument, currentContent);
119
- if (!fixResult) break;
120
- currentContent = fixResult.content;
121
- currentDocument = vscode_languageserver_textdocument.TextDocument.create(uri, languageId, currentDocument.version + 1, currentContent);
122
- totalFixed++;
123
- }
124
- if (iteration === require_constants.MAX_FIX_ITERATIONS) {
125
- if ((await (0, _tailwindcss_language_service.doValidate)(state, currentDocument)).length > 0) console.warn(`Warning: Reached maximum fix iterations (${require_constants.MAX_FIX_ITERATIONS}) for ${filePath}. Some issues may remain.`);
84
+ try {
85
+ const languageId = require_constants.getLanguageId(filePath);
86
+ const uri = `file://${filePath}`;
87
+ let currentDocument = vscode_languageserver_textdocument.TextDocument.create(uri, languageId, 1, content);
88
+ let currentContent = content;
89
+ let totalFixed = 0;
90
+ while (true) {
91
+ const currentDiagnostics = await (0, _tailwindcss_language_service.doValidate)(state, currentDocument);
92
+ if (currentDiagnostics.length === 0) break;
93
+ const quickfixes = await getQuickfixes(state, currentDocument, uri, currentDiagnostics);
94
+ if (quickfixes.length === 0) break;
95
+ const fixResult = applyFirstQuickfix(quickfixes[0], uri, currentDocument, currentContent);
96
+ if (!fixResult) break;
97
+ currentContent = fixResult.content;
98
+ currentDocument = vscode_languageserver_textdocument.TextDocument.create(uri, languageId, currentDocument.version + 1, currentContent);
99
+ totalFixed++;
100
+ }
101
+ return {
102
+ content: currentContent,
103
+ changed: currentContent !== content,
104
+ fixedCount: totalFixed
105
+ };
106
+ } catch (error) {
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ if (message.includes("Cannot read") || message.includes("undefined")) {
109
+ console.warn(`Warning: Language service crashed while applying fixes to ${filePath}. Skipping auto-fix for this file.`);
110
+ return {
111
+ content,
112
+ changed: false,
113
+ fixedCount: 0
114
+ };
115
+ }
116
+ throw error;
126
117
  }
127
- return {
128
- content: currentContent,
129
- changed: currentContent !== content,
130
- fixedCount: totalFixed
131
- };
132
118
  }
133
119
 
134
120
  //#endregion
@@ -391,6 +377,8 @@ async function loadTailwindConfig$1(configPath) {
391
377
  return config;
392
378
  } catch (error) {
393
379
  const errorMessage = error instanceof Error ? error.message : String(error);
380
+ if (errorMessage.includes("Cannot find module")) throw new Error(`Failed to load config from ${configPath}.\nThe config file may have missing dependencies. Check that all imports are installed.`);
381
+ if (errorMessage.includes("SyntaxError") || errorMessage.includes("Unexpected token")) throw new Error(`Failed to parse config from ${configPath}.\nThe config file has syntax errors. Check your JavaScript/TypeScript syntax.`);
394
382
  throw new Error(`Failed to load config from ${configPath}: ${errorMessage}`);
395
383
  }
396
384
  }
@@ -418,12 +406,12 @@ function resolveTailwindPath(cwd, configDir) {
418
406
  try {
419
407
  return require$1.resolve("tailwindcss", { paths });
420
408
  } catch {
421
- throw new Error(`Could not resolve tailwindcss module from ${paths.join(" or ")}`);
409
+ throw new Error(`Could not find tailwindcss module in ${paths.join(" or ")}.\nInstall it with: npm install -D tailwindcss`);
422
410
  }
423
411
  }
424
412
  async function createState(cwd, configPath, verbose = false) {
425
413
  const resolvedConfigPath = await findTailwindConfigPath$1(cwd, configPath);
426
- if (!resolvedConfigPath) throw new Error("Could not find tailwind config file (JS/TS or CSS)");
414
+ if (!resolvedConfigPath) throw new Error("Could not find Tailwind config file. Expected one of:\n • Tailwind v4 (CSS): app.css, index.css, tailwind.css in project root or src/\n • Tailwind v3 (JS): tailwind.config.js, tailwind.config.ts\nRun 'npx tailwindcss init' to create a config file.");
427
415
  const isCssConfig = isCssConfigFile$1(resolvedConfigPath);
428
416
  const tailwindcss = require$1(resolveTailwindPath(cwd, node_path.dirname(resolvedConfigPath)));
429
417
  const version = getTailwindVersion(cwd);
@@ -500,44 +488,25 @@ function serializeDiagnostics(diagnostics) {
500
488
  source: diagnostic.source
501
489
  }));
502
490
  }
503
- function getLanguageId(filePath) {
504
- return {
505
- ".astro": "astro",
506
- ".css": "css",
507
- ".erb": "erb",
508
- ".hbs": "handlebars",
509
- ".htm": "html",
510
- ".html": "html",
511
- ".js": "javascript",
512
- ".jsx": "javascriptreact",
513
- ".less": "less",
514
- ".md": "markdown",
515
- ".mdx": "mdx",
516
- ".php": "php",
517
- ".sass": "sass",
518
- ".scss": "scss",
519
- ".svelte": "svelte",
520
- ".ts": "typescript",
521
- ".tsx": "typescriptreact",
522
- ".twig": "twig",
523
- ".vue": "vue"
524
- }[node_path.extname(filePath).toLowerCase()] || "html";
525
- }
526
491
  async function validateDocument(state, filePath, content) {
527
492
  try {
528
493
  if (!state) throw new Error("State is not initialized");
529
494
  if (state.v4 && !state.designSystem) throw new Error("Design system not initialized for Tailwind v4. This might indicate a configuration issue.");
530
495
  if (!state.v4 && !state.modules?.tailwindcss) throw new Error("Tailwind modules not initialized for Tailwind v3. This might indicate a configuration issue.");
531
- const languageId = getLanguageId(filePath);
496
+ const languageId = require_constants.getLanguageId(filePath);
532
497
  const uri = `file://${filePath}`;
533
498
  return serializeDiagnostics(await (0, _tailwindcss_language_service.doValidate)(state, vscode_languageserver_textdocument.TextDocument.create(uri, languageId, 1, content)));
534
499
  } catch (error) {
535
500
  const message = error instanceof Error ? error.message : String(error);
501
+ if (message.includes("Cannot read") || message.includes("undefined")) {
502
+ console.warn(`Warning: Language service crashed while validating ${filePath}. Skipping this file.`);
503
+ return [];
504
+ }
536
505
  throw new Error(`Failed to validate document ${filePath}: ${message}`);
537
506
  }
538
507
  }
539
508
  async function findTailwindConfigPath(cwd, configPath) {
540
- const { V3_CONFIG_PATHS, V4_CSS_FOLDERS, V4_CSS_NAMES } = await Promise.resolve().then(() => require("./constants-Bstz7FuV.cjs"));
509
+ const { V3_CONFIG_PATHS, V4_CSS_FOLDERS, V4_CSS_NAMES } = await Promise.resolve().then(() => require("./constants-BqCgJ23N.cjs"));
541
510
  if (configPath) {
542
511
  const resolved = node_path.isAbsolute(configPath) ? configPath : node_path.resolve(cwd, configPath);
543
512
  return fileExists(resolved) ? resolved : null;
@@ -597,15 +566,15 @@ async function expandPatterns(cwd, patterns) {
597
566
  }
598
567
  async function discoverFilesFromConfig(cwd, configPath) {
599
568
  const configFilePath = await findTailwindConfigPath(cwd, configPath);
600
- if (!configFilePath) throw new Error("Could not find Tailwind config");
569
+ if (!configFilePath) throw new Error("Could not find Tailwind config for auto-discovery.\nUse --config to specify the path, or provide file patterns directly.");
601
570
  if (!isCssConfigFile(configFilePath)) {
602
571
  const config = await loadTailwindConfig(configFilePath);
603
- if (!config || !config.content) throw new Error("Could not find Tailwind config or config has no content property");
572
+ if (!config || !config.content) throw new Error("Tailwind config is missing the 'content' property.\nAdd a content array to specify which files to scan:\n content: ['./src/**/*.{js,jsx,ts,tsx}']");
604
573
  const patterns = extractContentPatterns(config);
605
- if (patterns.length === 0) throw new Error("No content patterns found in Tailwind config");
574
+ if (patterns.length === 0) throw new Error("No content patterns found in Tailwind config.\nEnsure your config has a content array with file patterns.");
606
575
  return expandPatterns(cwd, patterns);
607
576
  }
608
- throw new Error("Auto-discovery is not supported for CSS-based configs (v4). Please specify file patterns.");
577
+ throw new Error("Auto-discovery is not supported for Tailwind v4 CSS-based configs.\nPlease specify file patterns explicitly:\n tailwind-lint \"src/**/*.{js,jsx,ts,tsx}\"");
609
578
  }
610
579
  function extractContentPatterns(config) {
611
580
  if (!config.content) return [];
@@ -615,10 +584,14 @@ function extractContentPatterns(config) {
615
584
  }
616
585
  async function processFiles(state, cwd, files, fix, onProgress) {
617
586
  const results = [];
618
- for (let i = 0; i < files.length; i++) {
619
- if (onProgress) onProgress(i + 1, files.length, files[i]);
620
- const result = await processFile(state, cwd, files[i], fix);
621
- if (result) results.push(result);
587
+ for (let i = 0; i < files.length; i += require_constants.CONCURRENT_FILES) {
588
+ const batchPromises = files.slice(i, i + require_constants.CONCURRENT_FILES).map(async (file, batchIndex) => {
589
+ const fileIndex = i + batchIndex;
590
+ if (onProgress) onProgress(fileIndex + 1, files.length, file);
591
+ return await processFile(state, cwd, file, fix);
592
+ });
593
+ const batchResults = await Promise.all(batchPromises);
594
+ for (const result of batchResults) if (result) results.push(result);
622
595
  }
623
596
  return results;
624
597
  }
@@ -683,4 +656,4 @@ Object.defineProperty(exports, 'lint', {
683
656
  return lint;
684
657
  }
685
658
  });
686
- //# sourceMappingURL=linter-QRh7wAZ7.cjs.map
659
+ //# sourceMappingURL=linter-psTnhyzO.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linter-psTnhyzO.cjs","names":["getLanguageId","TextDocument","fs","DEFAULT_TAB_SIZE","DEFAULT_ROOT_FONT_SIZE","path","require","path","require","fileExists","fs","readFileSync","path","require","fileExists","fs","readFileSync","isCssConfigFile","loadTailwindConfig","path","findTailwindConfigPath","V3_CONFIG_PATHS","V4_CSS_FOLDERS","V4_CSS_NAMES","DEFAULT_SEPARATOR","getLanguageId","TextDocument","path","DEFAULT_IGNORE_PATTERNS","CONCURRENT_FILES"],"sources":["../src/code-actions.ts","../src/adapters/editor-state-adapter.ts","../src/types.ts","../src/adapters/v3-adapter.ts","../src/adapters/v4-adapter.ts","../src/state.ts","../src/linter.ts"],"sourcesContent":["import type { State } from \"@tailwindcss/language-service\";\nimport { doCodeActions, doValidate } from \"@tailwindcss/language-service\";\nimport type { CodeActionParams, Diagnostic } from \"vscode-languageserver\";\nimport { TextDocument } from \"vscode-languageserver-textdocument\";\nimport { getLanguageId } from \"./constants\";\nimport type { ApplyCodeActionsResult, SerializedDiagnostic } from \"./types\";\n\nexport type { ApplyCodeActionsResult };\n\ninterface QuickfixAction {\n\tkind?: string;\n\tedit?: {\n\t\tchanges?: Record<string, unknown[]>;\n\t};\n}\n\nasync function getQuickfixes(\n\tstate: State,\n\tdocument: TextDocument,\n\turi: string,\n\tdiagnostics: Diagnostic[],\n): Promise<QuickfixAction[]> {\n\tconst lspDiagnostics: Diagnostic[] = diagnostics.map((diag) => ({\n\t\trange: diag.range,\n\t\tseverity: diag.severity,\n\t\tmessage: diag.message,\n\t\tcode: diag.code,\n\t\tsource: diag.source || \"tailwindcss\",\n\t}));\n\n\tconst params: CodeActionParams = {\n\t\ttextDocument: {\n\t\t\turi,\n\t\t},\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: 0,\n\t\t\t\tcharacter: 0,\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tline: document.lineCount,\n\t\t\t\tcharacter: 0,\n\t\t\t},\n\t\t},\n\t\tcontext: {\n\t\t\tdiagnostics: lspDiagnostics,\n\t\t},\n\t};\n\n\tconst codeActions = await doCodeActions(state, params, document);\n\n\treturn codeActions.filter(\n\t\t(action) =>\n\t\t\taction.kind === \"quickfix\" || action.kind?.startsWith(\"quickfix.\"),\n\t) as QuickfixAction[];\n}\n\nfunction applyFirstQuickfix(\n\taction: QuickfixAction,\n\turi: string,\n\tdocument: TextDocument,\n\tcontent: string,\n): {\n\tcontent: string;\n} | null {\n\tif (!action.edit?.changes?.[uri]) return null;\n\n\tconst edits = action.edit.changes[uri] as {\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: number;\n\t\t\t\tcharacter: number;\n\t\t\t};\n\t\t\tend: {\n\t\t\t\tline: number;\n\t\t\t\tcharacter: number;\n\t\t\t};\n\t\t};\n\t\tnewText: string;\n\t}[];\n\n\tconst sortedEdits = [...edits].sort((a, b) => {\n\t\tconst lineDiff = b.range.start.line - a.range.start.line;\n\t\tif (lineDiff !== 0) return lineDiff;\n\t\treturn b.range.start.character - a.range.start.character;\n\t});\n\n\tlet newContent = content;\n\tfor (const edit of sortedEdits) {\n\t\tconst startOffset = document.offsetAt(edit.range.start);\n\t\tconst endOffset = document.offsetAt(edit.range.end);\n\t\tnewContent =\n\t\t\tnewContent.substring(0, startOffset) +\n\t\t\tedit.newText +\n\t\t\tnewContent.substring(endOffset);\n\t}\n\n\treturn { content: newContent };\n}\n\nexport async function applyCodeActions(\n\tstate: State,\n\tfilePath: string,\n\tcontent: string,\n\tdiagnostics: SerializedDiagnostic[],\n): Promise<ApplyCodeActionsResult> {\n\tif (diagnostics.length === 0) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\tchanged: false,\n\t\t\tfixedCount: 0,\n\t\t};\n\t}\n\n\ttry {\n\t\tconst languageId = getLanguageId(filePath);\n\t\tconst uri = `file://${filePath}`;\n\t\tlet currentDocument = TextDocument.create(uri, languageId, 1, content);\n\t\tlet currentContent = content;\n\t\tlet totalFixed = 0;\n\n\t\t// Keep fixing until no more fixable issues remain\n\t\twhile (true) {\n\t\t\tconst currentDiagnostics = await doValidate(state, currentDocument);\n\t\t\tif (currentDiagnostics.length === 0) break;\n\n\t\t\tconst quickfixes = await getQuickfixes(\n\t\t\t\tstate,\n\t\t\t\tcurrentDocument,\n\t\t\t\turi,\n\t\t\t\tcurrentDiagnostics,\n\t\t\t);\n\t\t\tif (quickfixes.length === 0) break;\n\n\t\t\tconst fixResult = applyFirstQuickfix(\n\t\t\t\tquickfixes[0],\n\t\t\t\turi,\n\t\t\t\tcurrentDocument,\n\t\t\t\tcurrentContent,\n\t\t\t);\n\t\t\tif (!fixResult) break;\n\n\t\t\tcurrentContent = fixResult.content;\n\t\t\tcurrentDocument = TextDocument.create(\n\t\t\t\turi,\n\t\t\t\tlanguageId,\n\t\t\t\tcurrentDocument.version + 1,\n\t\t\t\tcurrentContent,\n\t\t\t);\n\t\t\ttotalFixed++;\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: currentContent,\n\t\t\tchanged: currentContent !== content,\n\t\t\tfixedCount: totalFixed,\n\t\t};\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\n\t\t// Handle language service crashes gracefully\n\t\tif (message.includes(\"Cannot read\") || message.includes(\"undefined\")) {\n\t\t\tconsole.warn(\n\t\t\t\t`Warning: Language service crashed while applying fixes to ${filePath}. Skipping auto-fix for this file.`,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tcontent,\n\t\t\t\tchanged: false,\n\t\t\t\tfixedCount: 0,\n\t\t\t};\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { EditorState, Settings } from \"@tailwindcss/language-service\";\nimport { DEFAULT_ROOT_FONT_SIZE, DEFAULT_TAB_SIZE } from \"../constants\";\n\nfunction isDirectory(filePath: string): boolean {\n\ttry {\n\t\treturn fs.statSync(filePath).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function createEditorState(cwd: string): EditorState {\n\tconst settings: Settings = {\n\t\teditor: {\n\t\t\ttabSize: DEFAULT_TAB_SIZE,\n\t\t},\n\t\ttailwindCSS: {\n\t\t\tinspectPort: null,\n\t\t\temmetCompletions: false,\n\t\t\tincludeLanguages: {},\n\t\t\tclassAttributes: [\n\t\t\t\t\"class\",\n\t\t\t\t\"className\",\n\t\t\t\t\"ngClass\",\n\t\t\t\t\"[class]\",\n\t\t\t\t\":class\",\n\t\t\t\t\"v-bind:class\",\n\t\t\t\t\"x-bind:class\",\n\t\t\t\t\"class:list\",\n\t\t\t\t\"classList\",\n\t\t\t],\n\t\t\tclassFunctions: [],\n\t\t\tcodeActions: true,\n\t\t\thovers: true,\n\t\t\tcodeLens: false,\n\t\t\tsuggestions: true,\n\t\t\tvalidate: true,\n\t\t\tcolorDecorators: true,\n\t\t\trootFontSize: DEFAULT_ROOT_FONT_SIZE,\n\t\t\tshowPixelEquivalents: true,\n\t\t\tfiles: {\n\t\t\t\texclude: [\n\t\t\t\t\t\"**/.git/**\",\n\t\t\t\t\t\"**/node_modules/**\",\n\t\t\t\t\t\"**/.hg/**\",\n\t\t\t\t\t\"**/.svn/**\",\n\t\t\t\t],\n\t\t\t},\n\t\t\texperimental: {\n\t\t\t\tconfigFile: null,\n\t\t\t\tclassRegex: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\tcssConflict: \"warning\",\n\t\t\t\tinvalidApply: \"error\",\n\t\t\t\tinvalidScreen: \"error\",\n\t\t\t\tinvalidVariant: \"error\",\n\t\t\t\tinvalidConfigPath: \"error\",\n\t\t\t\tinvalidTailwindDirective: \"error\",\n\t\t\t\tinvalidSourceDirective: \"error\",\n\t\t\t\trecommendedVariantOrder: \"warning\",\n\t\t\t\tusedBlocklistedClass: \"warning\",\n\t\t\t\tsuggestCanonicalClasses: \"warning\",\n\t\t\t},\n\t\t},\n\t};\n\n\treturn {\n\t\tconnection: null as unknown as EditorState[\"connection\"],\n\t\tfolder: cwd,\n\t\tuserLanguages: {},\n\t\tcapabilities: {\n\t\t\tconfiguration: true,\n\t\t\tdiagnosticRelatedInformation: true,\n\t\t\titemDefaults: [],\n\t\t},\n\t\tgetConfiguration: async () => settings,\n\t\tgetDocumentSymbols: async () => [],\n\t\treadDirectory: async (document, directory) => {\n\t\t\tconst docPath =\n\t\t\t\ttypeof document === \"string\"\n\t\t\t\t\t? document\n\t\t\t\t\t: document.uri.replace(\"file://\", \"\");\n\t\t\tconst dir = path.resolve(path.dirname(docPath), directory);\n\t\t\ttry {\n\t\t\t\tconst files = fs.readdirSync(dir);\n\t\t\t\treturn files.map((file) => [\n\t\t\t\t\tfile,\n\t\t\t\t\t{ isDirectory: isDirectory(path.join(dir, file)) },\n\t\t\t\t]);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\t};\n}\n","export interface TailwindConfig {\n\tcontent?: string[] | { files?: string[] };\n\tseparator?: string;\n\t[key: string]: unknown;\n}\n\nexport interface ResolvedTailwindConfig extends TailwindConfig {\n\tseparator: string;\n}\n\nexport interface DesignSystem {\n\tcandidatesToAst?: (candidates: string[]) => unknown[];\n\tcandidatesToCss?: (candidates: string[]) => string[];\n\t[key: string]: unknown;\n}\n\nexport interface ContextUtils {\n\t[key: string]: unknown;\n}\n\nexport interface GenerateRulesModule {\n\tgenerateRules?: (set: unknown, context: unknown) => unknown[];\n\t[key: string]: unknown;\n}\n\nexport interface SerializedDiagnostic {\n\trange: {\n\t\tstart: { line: number; character: number };\n\t\tend: { line: number; character: number };\n\t};\n\tseverity: number;\n\tmessage: string;\n\tcode?: string;\n\tsource?: string;\n}\n\nexport interface ApplyCodeActionsResult {\n\tcontent: string;\n\tchanged: boolean;\n\tfixedCount: number;\n}\n\nexport interface LintFileResult {\n\tpath: string;\n\tdiagnostics: SerializedDiagnostic[];\n\tfixed?: boolean;\n\tfixedCount?: number;\n}\n\nexport interface LintOptions {\n\tcwd: string;\n\tpatterns: string[];\n\tconfigPath?: string;\n\tautoDiscover: boolean;\n\tfix?: boolean;\n\tverbose?: boolean;\n\tonProgress?: (current: number, total: number, file: string) => void;\n}\n\nexport interface LintResult {\n\tfiles: LintFileResult[];\n\ttotalFilesProcessed: number;\n}\n\n/**\n * Error thrown when adapter fails to load required modules\n */\nexport class AdapterLoadError extends Error {\n\tconstructor(\n\t\tpublic readonly version: string,\n\t\tcause: Error,\n\t) {\n\t\tsuper(`Failed to load ${version} adapter: ${cause.message}`);\n\t\tthis.name = \"AdapterLoadError\";\n\t}\n}\n","import { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport type { ContextUtils, GenerateRulesModule } from \"../types\";\nimport { AdapterLoadError } from \"../types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nexport async function loadV3ClassMetadata(\n\tstate: State,\n\tcwd: string,\n\tverbose = false,\n): Promise<void> {\n\ttry {\n\t\tconst tailwindPath = require.resolve(\"tailwindcss\", { paths: [cwd] });\n\t\tconst tailwindcss = require(tailwindPath) as unknown;\n\n\t\ttry {\n\t\t\tconst tailwindDir = path.dirname(\n\t\t\t\trequire.resolve(\"tailwindcss/package.json\", { paths: [cwd] }),\n\t\t\t);\n\n\t\t\tconst contextUtils = require(\n\t\t\t\tpath.join(tailwindDir, \"lib\", \"lib\", \"setupContextUtils\"),\n\t\t\t) as ContextUtils;\n\t\t\tconst generateRulesModule = require(\n\t\t\t\tpath.join(tailwindDir, \"lib\", \"lib\", \"generateRules\"),\n\t\t\t) as GenerateRulesModule;\n\n\t\t\tstate.modules = {\n\t\t\t\ttailwindcss: {\n\t\t\t\t\tversion: state.version || \"unknown\",\n\t\t\t\t\tmodule: tailwindcss,\n\t\t\t\t},\n\t\t\t\tjit: {\n\t\t\t\t\tgenerateRules: {\n\t\t\t\t\t\tmodule:\n\t\t\t\t\t\t\tgenerateRulesModule.generateRules ||\n\t\t\t\t\t\t\t((_set: unknown, _context: unknown) => []),\n\t\t\t\t\t},\n\t\t\t\t\tcreateContext: {\n\t\t\t\t\t\tmodule: contextUtils.createContext,\n\t\t\t\t\t},\n\t\t\t\t\texpandApplyAtRules: {\n\t\t\t\t\t\tmodule: generateRulesModule.expandApplyAtRules,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tif (verbose) {\n\t\t\t\tconsole.log(\" ✓ Loaded v3 JIT modules\");\n\t\t\t}\n\t\t} catch (jitError) {\n\t\t\tif (verbose) {\n\t\t\t\tconst message =\n\t\t\t\t\tjitError instanceof Error ? jitError.message : String(jitError);\n\t\t\t\tconsole.log(` ⚠ Warning: Could not load v3 JIT modules: ${message}`);\n\t\t\t}\n\n\t\t\tstate.modules = {\n\t\t\t\ttailwindcss: {\n\t\t\t\t\tversion: state.version || \"unknown\",\n\t\t\t\t\tmodule: tailwindcss,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\textractConfigMetadata(state);\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tthrow new AdapterLoadError(\"v3\", error);\n\t\t}\n\t\tthrow new Error(`Failed to load v3 class metadata: ${String(error)}`);\n\t}\n}\n\nfunction extractConfigMetadata(state: State): void {\n\tconst { config } = state;\n\tif (!config || typeof config !== \"object\") return;\n\n\tconst theme = (config as Record<string, unknown>).theme as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tstate.screens = Object.keys(\n\t\t(theme?.screens as Record<string, unknown>) ?? {},\n\t);\n\tstate.blocklist = (config.blocklist as string[] | undefined) ?? [];\n\n\tif (config.variants && typeof config.variants === \"object\") {\n\t\tstate.variants = Object.keys(config.variants).map((name) => ({\n\t\t\tname,\n\t\t\tvalues: [],\n\t\t\tisArbitrary: false,\n\t\t\thasDash: true,\n\t\t\tselectors: () => [],\n\t\t}));\n\t}\n\n\tif (config.corePlugins) {\n\t\tstate.corePlugins = Array.isArray(config.corePlugins)\n\t\t\t? (config.corePlugins as string[])\n\t\t\t: Object.keys(config.corePlugins as Record<string, unknown>);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport type { DesignSystem } from \"../types\";\nimport { AdapterLoadError } from \"../types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn fs.existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn fs.readFileSync(filePath, \"utf-8\");\n}\n\nexport async function loadV4DesignSystem(\n\tstate: State,\n\tcwd: string,\n\tconfigPath: string,\n\tverbose = false,\n): Promise<void> {\n\ttry {\n\t\tconst tailwindPath = require.resolve(\"tailwindcss\", { paths: [cwd] });\n\t\tconst tailwindcss = require(tailwindPath) as unknown;\n\n\t\tif (\n\t\t\ttailwindcss !== null &&\n\t\t\ttailwindcss !== undefined &&\n\t\t\t(typeof tailwindcss === \"object\" || typeof tailwindcss === \"function\") &&\n\t\t\t\"__unstable__loadDesignSystem\" in tailwindcss &&\n\t\t\ttypeof tailwindcss.__unstable__loadDesignSystem === \"function\"\n\t\t) {\n\t\t\tlet cssContent: string;\n\t\t\tconst basePath = path.dirname(configPath);\n\n\t\t\tif (fileExists(configPath)) {\n\t\t\t\tcssContent = readFileSync(configPath, true);\n\t\t\t} else {\n\t\t\t\tcssContent = '@import \"tailwindcss\";';\n\t\t\t}\n\n\t\t\ttype LoadDesignSystemFn = (\n\t\t\t\tcss: string,\n\t\t\t\toptions: {\n\t\t\t\t\tbase: string;\n\t\t\t\t\tloadStylesheet: (\n\t\t\t\t\t\tid: string,\n\t\t\t\t\t\tbase: string,\n\t\t\t\t\t\tcontent?: string,\n\t\t\t\t\t) => Promise<{ base: string; content: string }>;\n\t\t\t\t},\n\t\t\t) => Promise<DesignSystem>;\n\n\t\t\tconst loadDesignSystem =\n\t\t\t\ttailwindcss.__unstable__loadDesignSystem as LoadDesignSystemFn;\n\n\t\t\tconst designSystem = await loadDesignSystem(cssContent, {\n\t\t\t\tbase: basePath,\n\t\t\t\tasync loadStylesheet(\n\t\t\t\t\t_id: string,\n\t\t\t\t\tbase: string,\n\t\t\t\t\tcontent?: string,\n\t\t\t\t): Promise<{ base: string; content: string }> {\n\t\t\t\t\tif (content) {\n\t\t\t\t\t\treturn { base, content };\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!_id.startsWith(\".\") && !_id.startsWith(\"/\")) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst pkgJsonPath = require.resolve(`${_id}/package.json`, {\n\t\t\t\t\t\t\t\tpaths: [base, cwd],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst pkgDir = path.dirname(pkgJsonPath);\n\t\t\t\t\t\t\tconst cssPath = path.join(pkgDir, \"index.css\");\n\t\t\t\t\t\t\tif (fileExists(cssPath)) {\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tbase: pkgDir,\n\t\t\t\t\t\t\t\t\tcontent: readFileSync(cssPath, true),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst filePath = path.resolve(base, _id);\n\t\t\t\t\tif (fileExists(filePath)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tbase: path.dirname(filePath),\n\t\t\t\t\t\t\tcontent: readFileSync(filePath, true),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { base, content: \"\" };\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tObject.assign(designSystem, {\n\t\t\t\tdependencies: () => new Set<string>(),\n\n\t\t\t\tcompile(classes: string[]): unknown[][] {\n\t\t\t\t\tconst results = designSystem.candidatesToAst\n\t\t\t\t\t\t? designSystem.candidatesToAst(classes)\n\t\t\t\t\t\t: designSystem.candidatesToCss?.(classes) || [];\n\n\t\t\t\t\treturn results.map((result: unknown) => {\n\t\t\t\t\t\tif (Array.isArray(result)) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (result === null) {\n\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// @ts-expect-error - DesignSystem types are loaded dynamically at runtime\n\t\t\tstate.designSystem = designSystem;\n\n\t\t\tif (!state.classNames) {\n\t\t\t\tstate.classNames = {\n\t\t\t\t\tcontext: {},\n\t\t\t\t} as unknown as typeof state.classNames;\n\t\t\t}\n\n\t\t\tif (verbose) {\n\t\t\t\tconsole.log(\" ✓ Loaded v4 design system\");\n\t\t\t}\n\t\t} else {\n\t\t\tconst error = new Error(\n\t\t\t\t\"Tailwind v4 __unstable__loadDesignSystem is not available. Please ensure you have Tailwind CSS v4 installed.\",\n\t\t\t);\n\t\t\tthrow new AdapterLoadError(\"v4\", error);\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof AdapterLoadError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new AdapterLoadError(\"v4\", error);\n\t\t}\n\t\tthrow new Error(`Failed to load v4 design system: ${String(error)}`);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport { createEditorState } from \"./adapters/editor-state-adapter\";\nimport { loadV3ClassMetadata } from \"./adapters/v3-adapter\";\nimport { loadV4DesignSystem } from \"./adapters/v4-adapter\";\nimport {\n\tDEFAULT_SEPARATOR,\n\tV3_CONFIG_PATHS,\n\tV4_CSS_FOLDERS,\n\tV4_CSS_NAMES,\n} from \"./constants\";\nimport type { ResolvedTailwindConfig, TailwindConfig } from \"./types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn fs.existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn fs.readFileSync(filePath, \"utf-8\");\n}\n\nfunction getTailwindVersion(cwd: string): string | undefined {\n\ttry {\n\t\tconst tailwindPackageJson = require.resolve(\"tailwindcss/package.json\", {\n\t\t\tpaths: [cwd],\n\t\t});\n\t\tconst pkg = JSON.parse(fs.readFileSync(tailwindPackageJson, \"utf-8\")) as {\n\t\t\tversion?: string;\n\t\t};\n\t\treturn pkg.version;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isV4Config(version: string | undefined): boolean {\n\treturn version?.startsWith(\"4.\") ?? false;\n}\n\nfunction isCssConfigFile(filePath: string): boolean {\n\treturn filePath.endsWith(\".css\");\n}\n\nasync function loadTailwindConfig(configPath: string): Promise<TailwindConfig> {\n\tif (isCssConfigFile(configPath)) {\n\t\treturn {};\n\t}\n\n\tif (!path.isAbsolute(configPath)) {\n\t\tthrow new Error(\n\t\t\t`Config path must be absolute for security reasons: ${configPath}`,\n\t\t);\n\t}\n\n\ttry {\n\t\tdelete require.cache[configPath];\n\n\t\tconst configModule = require(configPath) as\n\t\t\t| TailwindConfig\n\t\t\t| { default: TailwindConfig };\n\t\tconst config = (\n\t\t\t\"default\" in configModule ? configModule.default : configModule\n\t\t) as TailwindConfig;\n\n\t\tif (typeof config !== \"object\" || config === null) {\n\t\t\tthrow new Error(\"Config must be an object\");\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\n\t\tif (errorMessage.includes(\"Cannot find module\")) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to load config from ${configPath}.\\n` +\n\t\t\t\t\t\"The config file may have missing dependencies. Check that all imports are installed.\",\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\terrorMessage.includes(\"SyntaxError\") ||\n\t\t\terrorMessage.includes(\"Unexpected token\")\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to parse config from ${configPath}.\\n` +\n\t\t\t\t\t\"The config file has syntax errors. Check your JavaScript/TypeScript syntax.\",\n\t\t\t);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`Failed to load config from ${configPath}: ${errorMessage}`,\n\t\t);\n\t}\n}\n\nasync function findTailwindConfigPath(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string | null> {\n\tif (configPath) {\n\t\tconst resolved = path.isAbsolute(configPath)\n\t\t\t? configPath\n\t\t\t: path.resolve(cwd, configPath);\n\t\treturn fileExists(resolved) ? resolved : null;\n\t}\n\n\tfor (const p of V3_CONFIG_PATHS) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\treturn fullPath;\n\t\t}\n\t}\n\n\tconst v4Paths = V4_CSS_FOLDERS.flatMap((folder) =>\n\t\tV4_CSS_NAMES.map((name) => path.join(folder, name)),\n\t);\n\n\tfor (const p of v4Paths) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(fullPath);\n\t\t\t\tif (\n\t\t\t\t\tcontent.includes('@import \"tailwindcss\"') ||\n\t\t\t\t\tcontent.includes(\"@import 'tailwindcss'\")\n\t\t\t\t) {\n\t\t\t\t\treturn fullPath;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction resolveTailwindPath(cwd: string, configDir?: string): string {\n\tconst paths = configDir ? [configDir, cwd] : [cwd];\n\ttry {\n\t\treturn require.resolve(\"tailwindcss\", { paths });\n\t} catch {\n\t\tthrow new Error(\n\t\t\t`Could not find tailwindcss module in ${paths.join(\" or \")}.\\n` +\n\t\t\t\t\"Install it with: npm install -D tailwindcss\",\n\t\t);\n\t}\n}\n\nexport async function createState(\n\tcwd: string,\n\tconfigPath?: string,\n\tverbose = false,\n): Promise<State> {\n\tconst resolvedConfigPath = await findTailwindConfigPath(cwd, configPath);\n\n\tif (!resolvedConfigPath) {\n\t\tthrow new Error(\n\t\t\t\"Could not find Tailwind config file. Expected one of:\\n\" +\n\t\t\t\t\" • Tailwind v4 (CSS): app.css, index.css, tailwind.css in project root or src/\\n\" +\n\t\t\t\t\" • Tailwind v3 (JS): tailwind.config.js, tailwind.config.ts\\n\" +\n\t\t\t\t\"Run 'npx tailwindcss init' to create a config file.\",\n\t\t);\n\t}\n\n\tconst isCssConfig = isCssConfigFile(resolvedConfigPath);\n\tconst configDir = path.dirname(resolvedConfigPath);\n\tconst tailwindPath = resolveTailwindPath(cwd, configDir);\n\n\tconst tailwindcss = require(tailwindPath) as {\n\t\tresolveConfig?: (config: unknown) => unknown;\n\t};\n\n\tconst version = getTailwindVersion(cwd);\n\tconst isV4 = isV4Config(version);\n\n\tif (verbose) {\n\t\tconsole.log(` Tailwind version: ${version || \"unknown\"}`);\n\t\tconsole.log(` Config type: ${isCssConfig ? \"CSS (v4)\" : \"JavaScript\"}`);\n\t\tconsole.log(` Config path: ${resolvedConfigPath}`);\n\t}\n\n\tlet config: TailwindConfig = {};\n\tlet resolvedConfig: ResolvedTailwindConfig = { separator: \":\" };\n\n\tif (!isCssConfig) {\n\t\tconfig = await loadTailwindConfig(resolvedConfigPath);\n\t\tresolvedConfig = {\n\t\t\t...config,\n\t\t\tseparator: config.separator ?? DEFAULT_SEPARATOR,\n\t\t};\n\t\tif (tailwindcss.resolveConfig) {\n\t\t\tresolvedConfig = tailwindcss.resolveConfig(\n\t\t\t\tconfig,\n\t\t\t) as ResolvedTailwindConfig;\n\t\t}\n\t}\n\n\tconst state: State = {\n\t\tenabled: true,\n\t\tconfigPath: resolvedConfigPath,\n\t\tconfig: resolvedConfig,\n\t\tversion,\n\t\tv4: isV4 || undefined,\n\t\tseparator: resolvedConfig.separator || DEFAULT_SEPARATOR,\n\t\tscreens: [],\n\t\tvariants: [],\n\t\tclassNames: undefined,\n\t\tclassList: undefined,\n\t\tmodules: undefined,\n\t\tblocklist: [],\n\t\teditor: createEditorState(cwd),\n\t\tfeatures: [\"diagnostics\"] as unknown as State[\"features\"],\n\t};\n\n\tif (isV4 || isCssConfig) {\n\t\tawait loadV4DesignSystem(state, cwd, resolvedConfigPath, verbose);\n\t} else {\n\t\tawait loadV3ClassMetadata(state, cwd, verbose);\n\t}\n\n\treturn state;\n}\n","import * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport { doValidate } from \"@tailwindcss/language-service\";\nimport glob from \"fast-glob\";\nimport { TextDocument } from \"vscode-languageserver-textdocument\";\nimport { applyCodeActions } from \"./code-actions\";\nimport {\n\tCONCURRENT_FILES,\n\tDEFAULT_IGNORE_PATTERNS,\n\tgetLanguageId,\n} from \"./constants\";\nimport { createState } from \"./state\";\nimport type {\n\tLintFileResult,\n\tLintOptions,\n\tLintResult,\n\tSerializedDiagnostic,\n\tTailwindConfig,\n} from \"./types\";\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn require(\"node:fs\").existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn require(\"node:fs\").readFileSync(filePath, \"utf-8\");\n}\n\nfunction writeFileSync(filePath: string, content: string): void {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\tif (typeof content !== \"string\") {\n\t\tthrow new TypeError(\"Content must be a string\");\n\t}\n\trequire(\"node:fs\").writeFileSync(filePath, content, \"utf-8\");\n}\n\nfunction serializeDiagnostics(\n\tdiagnostics: import(\"vscode-languageserver\").Diagnostic[],\n): SerializedDiagnostic[] {\n\treturn diagnostics.map((diagnostic) => ({\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: diagnostic.range.start.line,\n\t\t\t\tcharacter: diagnostic.range.start.character,\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tline: diagnostic.range.end.line,\n\t\t\t\tcharacter: diagnostic.range.end.character,\n\t\t\t},\n\t\t},\n\t\tseverity: diagnostic.severity || 2,\n\t\tmessage: diagnostic.message,\n\t\tcode: diagnostic.code?.toString(),\n\t\tsource: diagnostic.source,\n\t}));\n}\n\nasync function validateDocument(\n\tstate: State,\n\tfilePath: string,\n\tcontent: string,\n): Promise<SerializedDiagnostic[]> {\n\ttry {\n\t\tif (!state) {\n\t\t\tthrow new Error(\"State is not initialized\");\n\t\t}\n\n\t\tif (state.v4 && !state.designSystem) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Design system not initialized for Tailwind v4. This might indicate a configuration issue.\",\n\t\t\t);\n\t\t}\n\n\t\tif (!state.v4 && !state.modules?.tailwindcss) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Tailwind modules not initialized for Tailwind v3. This might indicate a configuration issue.\",\n\t\t\t);\n\t\t}\n\n\t\tconst languageId = getLanguageId(filePath);\n\t\tconst uri = `file://${filePath}`;\n\t\tconst document = TextDocument.create(uri, languageId, 1, content);\n\n\t\tconst diagnostics = await doValidate(state, document);\n\n\t\treturn serializeDiagnostics(diagnostics);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\n\t\t// Handle crashes from the language service gracefully\n\t\tif (message.includes(\"Cannot read\") || message.includes(\"undefined\")) {\n\t\t\tconsole.warn(\n\t\t\t\t`Warning: Language service crashed while validating ${filePath}. Skipping this file.`,\n\t\t\t);\n\t\t\treturn [];\n\t\t}\n\n\t\tthrow new Error(`Failed to validate document ${filePath}: ${message}`);\n\t}\n}\n\nasync function findTailwindConfigPath(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string | null> {\n\tconst { V3_CONFIG_PATHS, V4_CSS_FOLDERS, V4_CSS_NAMES } = await import(\n\t\t\"./constants\"\n\t);\n\n\tif (configPath) {\n\t\tconst resolved = path.isAbsolute(configPath)\n\t\t\t? configPath\n\t\t\t: path.resolve(cwd, configPath);\n\t\treturn fileExists(resolved) ? resolved : null;\n\t}\n\n\tfor (const p of V3_CONFIG_PATHS) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\treturn fullPath;\n\t\t}\n\t}\n\n\tconst v4Paths = V4_CSS_FOLDERS.flatMap((folder) =>\n\t\tV4_CSS_NAMES.map((name) => path.join(folder, name)),\n\t);\n\n\tfor (const p of v4Paths) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(fullPath);\n\t\t\t\tif (\n\t\t\t\t\tcontent.includes('@import \"tailwindcss\"') ||\n\t\t\t\t\tcontent.includes(\"@import 'tailwindcss'\")\n\t\t\t\t) {\n\t\t\t\t\treturn fullPath;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction isCssConfigFile(filePath: string): boolean {\n\treturn filePath.endsWith(\".css\");\n}\n\nasync function loadTailwindConfig(configPath: string): Promise<TailwindConfig> {\n\tif (isCssConfigFile(configPath)) {\n\t\treturn {};\n\t}\n\n\tif (!path.isAbsolute(configPath)) {\n\t\tthrow new Error(\n\t\t\t`Config path must be absolute for security reasons: ${configPath}`,\n\t\t);\n\t}\n\n\ttry {\n\t\tconst { createRequire } = await import(\"node:module\");\n\t\tconst require = createRequire(import.meta.url || __filename);\n\t\tdelete require.cache[configPath];\n\n\t\tconst configModule = require(configPath) as\n\t\t\t| TailwindConfig\n\t\t\t| { default: TailwindConfig };\n\t\tconst config = (\n\t\t\t\"default\" in configModule ? configModule.default : configModule\n\t\t) as TailwindConfig;\n\n\t\tif (typeof config !== \"object\" || config === null) {\n\t\t\tthrow new Error(\"Config must be an object\");\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(\n\t\t\t`Failed to load config from ${configPath}: ${errorMessage}`,\n\t\t);\n\t}\n}\n\nasync function discoverFiles(\n\tcwd: string,\n\tpatterns: string[],\n\tconfigPath: string | undefined,\n\tautoDiscover: boolean,\n): Promise<string[]> {\n\tif (autoDiscover) {\n\t\treturn discoverFilesFromConfig(cwd, configPath);\n\t}\n\treturn expandPatterns(cwd, patterns);\n}\n\nasync function expandPatterns(\n\tcwd: string,\n\tpatterns: string[],\n): Promise<string[]> {\n\tconst explicitFiles: string[] = [];\n\tconst globPatterns: string[] = [];\n\n\tfor (const pattern of patterns) {\n\t\tif (\n\t\t\tpattern.includes(\"*\") ||\n\t\t\tpattern.includes(\"?\") ||\n\t\t\tpattern.includes(\"[\")\n\t\t) {\n\t\t\tglobPatterns.push(pattern);\n\t\t} else {\n\t\t\tconst fullPath = path.resolve(cwd, pattern);\n\t\t\tif (fileExists(fullPath)) {\n\t\t\t\texplicitFiles.push(pattern);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (globPatterns.length === 0) {\n\t\treturn explicitFiles;\n\t}\n\n\tconst globResults = await glob(globPatterns, {\n\t\tcwd,\n\t\tabsolute: false,\n\t\tignore: DEFAULT_IGNORE_PATTERNS,\n\t});\n\n\tif (explicitFiles.length === 0) {\n\t\treturn globResults;\n\t}\n\n\tconst fileSet = new Set(explicitFiles);\n\tfor (const file of globResults) {\n\t\tfileSet.add(file);\n\t}\n\treturn Array.from(fileSet);\n}\n\nasync function discoverFilesFromConfig(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string[]> {\n\tconst configFilePath = await findTailwindConfigPath(cwd, configPath);\n\n\tif (!configFilePath) {\n\t\tthrow new Error(\n\t\t\t\"Could not find Tailwind config for auto-discovery.\\n\" +\n\t\t\t\t\"Use --config to specify the path, or provide file patterns directly.\",\n\t\t);\n\t}\n\n\tif (!isCssConfigFile(configFilePath)) {\n\t\tconst config = await loadTailwindConfig(configFilePath);\n\n\t\tif (!config || !config.content) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Tailwind config is missing the 'content' property.\\n\" +\n\t\t\t\t\t\"Add a content array to specify which files to scan:\\n\" +\n\t\t\t\t\t\" content: ['./src/**/*.{js,jsx,ts,tsx}']\",\n\t\t\t);\n\t\t}\n\n\t\tconst patterns = extractContentPatterns(config);\n\n\t\tif (patterns.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"No content patterns found in Tailwind config.\\n\" +\n\t\t\t\t\t\"Ensure your config has a content array with file patterns.\",\n\t\t\t);\n\t\t}\n\n\t\treturn expandPatterns(cwd, patterns);\n\t}\n\n\tthrow new Error(\n\t\t\"Auto-discovery is not supported for Tailwind v4 CSS-based configs.\\n\" +\n\t\t\t\"Please specify file patterns explicitly:\\n\" +\n\t\t\t' tailwind-lint \"src/**/*.{js,jsx,ts,tsx}\"',\n\t);\n}\n\nfunction extractContentPatterns(config: TailwindConfig): string[] {\n\tif (!config.content) return [];\n\n\tif (Array.isArray(config.content)) {\n\t\treturn config.content.filter((p): p is string => typeof p === \"string\");\n\t}\n\n\tif (config.content.files) {\n\t\treturn config.content.files.filter(\n\t\t\t(p): p is string => typeof p === \"string\",\n\t\t);\n\t}\n\n\treturn [];\n}\n\nasync function processFiles(\n\tstate: State,\n\tcwd: string,\n\tfiles: string[],\n\tfix: boolean,\n\tonProgress?: (current: number, total: number, file: string) => void,\n): Promise<LintFileResult[]> {\n\tconst results: LintFileResult[] = [];\n\n\tfor (let i = 0; i < files.length; i += CONCURRENT_FILES) {\n\t\tconst batch = files.slice(i, i + CONCURRENT_FILES);\n\n\t\tconst batchPromises = batch.map(async (file, batchIndex) => {\n\t\t\tconst fileIndex = i + batchIndex;\n\t\t\tif (onProgress) {\n\t\t\t\tonProgress(fileIndex + 1, files.length, file);\n\t\t\t}\n\n\t\t\tconst result = await processFile(state, cwd, file, fix);\n\t\t\treturn result;\n\t\t});\n\n\t\tconst batchResults = await Promise.all(batchPromises);\n\n\t\tfor (const result of batchResults) {\n\t\t\tif (result) {\n\t\t\t\tresults.push(result);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n}\n\nasync function processFile(\n\tstate: State,\n\tcwd: string,\n\tfilePath: string,\n\tfix: boolean,\n): Promise<LintFileResult | null> {\n\tconst absolutePath = path.isAbsolute(filePath)\n\t\t? filePath\n\t\t: path.resolve(cwd, filePath);\n\n\tif (!fileExists(absolutePath)) {\n\t\treturn null;\n\t}\n\n\tlet content = readFileSync(absolutePath);\n\tlet diagnostics = await validateDocument(state, absolutePath, content);\n\n\tlet fixedCount = 0;\n\tlet wasFixed = false;\n\n\tif (fix && diagnostics.length > 0) {\n\t\tconst fixResult = await applyCodeActions(\n\t\t\tstate,\n\t\t\tabsolutePath,\n\t\t\tcontent,\n\t\t\tdiagnostics,\n\t\t);\n\n\t\tif (fixResult.changed) {\n\t\t\twriteFileSync(absolutePath, fixResult.content);\n\t\t\tcontent = fixResult.content;\n\t\t\twasFixed = true;\n\t\t\tfixedCount = fixResult.fixedCount;\n\t\t\tdiagnostics = await validateDocument(state, absolutePath, content);\n\t\t}\n\t}\n\n\treturn {\n\t\tpath: path.relative(cwd, absolutePath),\n\t\tdiagnostics,\n\t\tfixed: wasFixed,\n\t\tfixedCount,\n\t};\n}\nasync function initializeState(\n\tcwd: string,\n\tconfigPath?: string,\n\tverbose = false,\n) {\n\ttry {\n\t\tif (verbose) {\n\t\t\tconsole.log(\"→ Initializing Tailwind CSS language service...\");\n\t\t}\n\t\tconst state = await createState(cwd, configPath, verbose);\n\t\tif (verbose) {\n\t\t\tconsole.log(\" ✓ State initialized successfully\\n\");\n\t\t}\n\t\treturn state;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to initialize Tailwind state: ${message}`);\n\t}\n}\n\nexport type { LintFileResult, LintOptions, LintResult };\n\nexport async function lint({\n\tcwd,\n\tpatterns,\n\tconfigPath,\n\tautoDiscover,\n\tfix = false,\n\tverbose = false,\n\tonProgress,\n}: LintOptions): Promise<LintResult> {\n\tconst files = await discoverFiles(cwd, patterns, configPath, autoDiscover);\n\n\tif (verbose) {\n\t\tconsole.log(\n\t\t\t`→ Discovered ${files.length} file${files.length !== 1 ? \"s\" : \"\"} to lint`,\n\t\t);\n\t}\n\n\tif (files.length === 0) {\n\t\treturn { files: [], totalFilesProcessed: 0 };\n\t}\n\n\tconst state = await initializeState(cwd, configPath, verbose);\n\tconst results = await processFiles(state, cwd, files, fix, onProgress);\n\n\treturn {\n\t\tfiles: results.filter(\n\t\t\t(result) => result.diagnostics.length > 0 || result.fixed,\n\t\t),\n\t\ttotalFilesProcessed: files.length,\n\t};\n}\n"],"mappings":"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"}
package/dist/linter.cjs CHANGED
@@ -1,3 +1,3 @@
1
- const require_linter = require('./linter-QRh7wAZ7.cjs');
1
+ const require_linter = require('./linter-psTnhyzO.cjs');
2
2
 
3
3
  exports.lint = require_linter.lint;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-lint",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "A command-line tool that uses the Tailwind CSS IntelliSense plugin to show linting suggestions for your Tailwind CSS classes",
5
5
  "keywords": [
6
6
  "tailwindcss",
@@ -1 +0,0 @@
1
- {"version":3,"file":"linter-QRh7wAZ7.cjs","names":["getLanguageId","path","TextDocument","MAX_FIX_ITERATIONS","fs","DEFAULT_TAB_SIZE","DEFAULT_ROOT_FONT_SIZE","path","require","path","require","fileExists","fs","readFileSync","path","require","fileExists","fs","readFileSync","isCssConfigFile","loadTailwindConfig","path","findTailwindConfigPath","V3_CONFIG_PATHS","V4_CSS_FOLDERS","V4_CSS_NAMES","DEFAULT_SEPARATOR","path","TextDocument","DEFAULT_IGNORE_PATTERNS"],"sources":["../src/code-actions.ts","../src/adapters/editor-state-adapter.ts","../src/types.ts","../src/adapters/v3-adapter.ts","../src/adapters/v4-adapter.ts","../src/state.ts","../src/linter.ts"],"sourcesContent":["import * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport { doCodeActions, doValidate } from \"@tailwindcss/language-service\";\nimport type { CodeActionParams, Diagnostic } from \"vscode-languageserver\";\nimport { TextDocument } from \"vscode-languageserver-textdocument\";\nimport { MAX_FIX_ITERATIONS } from \"./constants\";\nimport type { ApplyCodeActionsResult, SerializedDiagnostic } from \"./types\";\n\nexport type { ApplyCodeActionsResult };\n\nfunction getLanguageId(filePath: string): string {\n\tconst LANGUAGE_MAP: Record<string, string> = {\n\t\t\".astro\": \"astro\",\n\t\t\".css\": \"css\",\n\t\t\".erb\": \"erb\",\n\t\t\".hbs\": \"handlebars\",\n\t\t\".htm\": \"html\",\n\t\t\".html\": \"html\",\n\t\t\".js\": \"javascript\",\n\t\t\".jsx\": \"javascriptreact\",\n\t\t\".less\": \"less\",\n\t\t\".md\": \"markdown\",\n\t\t\".mdx\": \"mdx\",\n\t\t\".php\": \"php\",\n\t\t\".sass\": \"sass\",\n\t\t\".scss\": \"scss\",\n\t\t\".svelte\": \"svelte\",\n\t\t\".ts\": \"typescript\",\n\t\t\".tsx\": \"typescriptreact\",\n\t\t\".twig\": \"twig\",\n\t\t\".vue\": \"vue\",\n\t};\n\tconst ext = path.extname(filePath).toLowerCase();\n\treturn LANGUAGE_MAP[ext] || \"html\";\n}\n\ninterface QuickfixAction {\n\tkind?: string;\n\tedit?: {\n\t\tchanges?: Record<string, unknown[]>;\n\t};\n}\n\nasync function getQuickfixes(\n\tstate: State,\n\tdocument: TextDocument,\n\turi: string,\n\tdiagnostics: Diagnostic[],\n): Promise<QuickfixAction[]> {\n\tconst lspDiagnostics: Diagnostic[] = diagnostics.map((diag) => ({\n\t\trange: diag.range,\n\t\tseverity: diag.severity,\n\t\tmessage: diag.message,\n\t\tcode: diag.code,\n\t\tsource: diag.source || \"tailwindcss\",\n\t}));\n\n\tconst params: CodeActionParams = {\n\t\ttextDocument: {\n\t\t\turi,\n\t\t},\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: 0,\n\t\t\t\tcharacter: 0,\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tline: document.lineCount,\n\t\t\t\tcharacter: 0,\n\t\t\t},\n\t\t},\n\t\tcontext: {\n\t\t\tdiagnostics: lspDiagnostics,\n\t\t},\n\t};\n\n\tconst codeActions = await doCodeActions(state, params, document);\n\n\treturn codeActions.filter(\n\t\t(action) =>\n\t\t\taction.kind === \"quickfix\" || action.kind?.startsWith(\"quickfix.\"),\n\t) as QuickfixAction[];\n}\n\nfunction applyFirstQuickfix(\n\taction: QuickfixAction,\n\turi: string,\n\tdocument: TextDocument,\n\tcontent: string,\n): {\n\tcontent: string;\n} | null {\n\tif (!action.edit?.changes?.[uri]) return null;\n\n\tconst edits = action.edit.changes[uri] as {\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: number;\n\t\t\t\tcharacter: number;\n\t\t\t};\n\t\t\tend: {\n\t\t\t\tline: number;\n\t\t\t\tcharacter: number;\n\t\t\t};\n\t\t};\n\t\tnewText: string;\n\t}[];\n\n\tconst sortedEdits = [...edits].sort((a, b) => {\n\t\tconst lineDiff = b.range.start.line - a.range.start.line;\n\t\tif (lineDiff !== 0) return lineDiff;\n\t\treturn b.range.start.character - a.range.start.character;\n\t});\n\n\tlet newContent = content;\n\tfor (const edit of sortedEdits) {\n\t\tconst startOffset = document.offsetAt(edit.range.start);\n\t\tconst endOffset = document.offsetAt(edit.range.end);\n\t\tnewContent =\n\t\t\tnewContent.substring(0, startOffset) +\n\t\t\tedit.newText +\n\t\t\tnewContent.substring(endOffset);\n\t}\n\n\treturn { content: newContent };\n}\n\nexport async function applyCodeActions(\n\tstate: State,\n\tfilePath: string,\n\tcontent: string,\n\tdiagnostics: SerializedDiagnostic[],\n): Promise<ApplyCodeActionsResult> {\n\tif (diagnostics.length === 0) {\n\t\treturn {\n\t\t\tcontent,\n\t\t\tchanged: false,\n\t\t\tfixedCount: 0,\n\t\t};\n\t}\n\n\tconst languageId = getLanguageId(filePath);\n\tconst uri = `file://${filePath}`;\n\tlet currentDocument = TextDocument.create(uri, languageId, 1, content);\n\tlet currentContent = content;\n\tlet totalFixed = 0;\n\n\tlet iteration = 0;\n\tfor (; iteration < MAX_FIX_ITERATIONS; iteration++) {\n\t\tconst currentDiagnostics = await doValidate(state, currentDocument);\n\t\tif (currentDiagnostics.length === 0) break;\n\n\t\tconst quickfixes = await getQuickfixes(\n\t\t\tstate,\n\t\t\tcurrentDocument,\n\t\t\turi,\n\t\t\tcurrentDiagnostics,\n\t\t);\n\t\tif (quickfixes.length === 0) break;\n\n\t\tconst fixResult = applyFirstQuickfix(\n\t\t\tquickfixes[0],\n\t\t\turi,\n\t\t\tcurrentDocument,\n\t\t\tcurrentContent,\n\t\t);\n\t\tif (!fixResult) break;\n\n\t\tcurrentContent = fixResult.content;\n\t\tcurrentDocument = TextDocument.create(\n\t\t\turi,\n\t\t\tlanguageId,\n\t\t\tcurrentDocument.version + 1,\n\t\t\tcurrentContent,\n\t\t);\n\t\ttotalFixed++;\n\t}\n\n\tif (iteration === MAX_FIX_ITERATIONS) {\n\t\tconst remainingDiagnostics = await doValidate(state, currentDocument);\n\t\tif (remainingDiagnostics.length > 0) {\n\t\t\tconsole.warn(\n\t\t\t\t`Warning: Reached maximum fix iterations (${MAX_FIX_ITERATIONS}) for ${filePath}. Some issues may remain.`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn {\n\t\tcontent: currentContent,\n\t\tchanged: currentContent !== content,\n\t\tfixedCount: totalFixed,\n\t};\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { EditorState, Settings } from \"@tailwindcss/language-service\";\nimport { DEFAULT_ROOT_FONT_SIZE, DEFAULT_TAB_SIZE } from \"../constants\";\n\nfunction isDirectory(filePath: string): boolean {\n\ttry {\n\t\treturn fs.statSync(filePath).isDirectory();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function createEditorState(cwd: string): EditorState {\n\tconst settings: Settings = {\n\t\teditor: {\n\t\t\ttabSize: DEFAULT_TAB_SIZE,\n\t\t},\n\t\ttailwindCSS: {\n\t\t\tinspectPort: null,\n\t\t\temmetCompletions: false,\n\t\t\tincludeLanguages: {},\n\t\t\tclassAttributes: [\n\t\t\t\t\"class\",\n\t\t\t\t\"className\",\n\t\t\t\t\"ngClass\",\n\t\t\t\t\"[class]\",\n\t\t\t\t\":class\",\n\t\t\t\t\"v-bind:class\",\n\t\t\t\t\"x-bind:class\",\n\t\t\t\t\"class:list\",\n\t\t\t\t\"classList\",\n\t\t\t],\n\t\t\tclassFunctions: [],\n\t\t\tcodeActions: true,\n\t\t\thovers: true,\n\t\t\tcodeLens: false,\n\t\t\tsuggestions: true,\n\t\t\tvalidate: true,\n\t\t\tcolorDecorators: true,\n\t\t\trootFontSize: DEFAULT_ROOT_FONT_SIZE,\n\t\t\tshowPixelEquivalents: true,\n\t\t\tfiles: {\n\t\t\t\texclude: [\n\t\t\t\t\t\"**/.git/**\",\n\t\t\t\t\t\"**/node_modules/**\",\n\t\t\t\t\t\"**/.hg/**\",\n\t\t\t\t\t\"**/.svn/**\",\n\t\t\t\t],\n\t\t\t},\n\t\t\texperimental: {\n\t\t\t\tconfigFile: null,\n\t\t\t\tclassRegex: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\tcssConflict: \"warning\",\n\t\t\t\tinvalidApply: \"error\",\n\t\t\t\tinvalidScreen: \"error\",\n\t\t\t\tinvalidVariant: \"error\",\n\t\t\t\tinvalidConfigPath: \"error\",\n\t\t\t\tinvalidTailwindDirective: \"error\",\n\t\t\t\tinvalidSourceDirective: \"error\",\n\t\t\t\trecommendedVariantOrder: \"warning\",\n\t\t\t\tusedBlocklistedClass: \"warning\",\n\t\t\t\tsuggestCanonicalClasses: \"warning\",\n\t\t\t},\n\t\t},\n\t};\n\n\treturn {\n\t\tconnection: null as unknown as EditorState[\"connection\"],\n\t\tfolder: cwd,\n\t\tuserLanguages: {},\n\t\tcapabilities: {\n\t\t\tconfiguration: true,\n\t\t\tdiagnosticRelatedInformation: true,\n\t\t\titemDefaults: [],\n\t\t},\n\t\tgetConfiguration: async () => settings,\n\t\tgetDocumentSymbols: async () => [],\n\t\treadDirectory: async (document, directory) => {\n\t\t\tconst docPath =\n\t\t\t\ttypeof document === \"string\"\n\t\t\t\t\t? document\n\t\t\t\t\t: document.uri.replace(\"file://\", \"\");\n\t\t\tconst dir = path.resolve(path.dirname(docPath), directory);\n\t\t\ttry {\n\t\t\t\tconst files = fs.readdirSync(dir);\n\t\t\t\treturn files.map((file) => [\n\t\t\t\t\tfile,\n\t\t\t\t\t{ isDirectory: isDirectory(path.join(dir, file)) },\n\t\t\t\t]);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\t};\n}\n","export interface TailwindConfig {\n\tcontent?: string[] | { files?: string[] };\n\tseparator?: string;\n\t[key: string]: unknown;\n}\n\nexport interface ResolvedTailwindConfig extends TailwindConfig {\n\tseparator: string;\n}\n\nexport interface DesignSystem {\n\tcandidatesToAst?: (candidates: string[]) => unknown[];\n\tcandidatesToCss?: (candidates: string[]) => string[];\n\t[key: string]: unknown;\n}\n\nexport interface ContextUtils {\n\t[key: string]: unknown;\n}\n\nexport interface GenerateRulesModule {\n\tgenerateRules?: (set: unknown, context: unknown) => unknown[];\n\t[key: string]: unknown;\n}\n\nexport interface SerializedDiagnostic {\n\trange: {\n\t\tstart: { line: number; character: number };\n\t\tend: { line: number; character: number };\n\t};\n\tseverity: number;\n\tmessage: string;\n\tcode?: string;\n\tsource?: string;\n}\n\nexport interface ApplyCodeActionsResult {\n\tcontent: string;\n\tchanged: boolean;\n\tfixedCount: number;\n}\n\nexport interface LintFileResult {\n\tpath: string;\n\tdiagnostics: SerializedDiagnostic[];\n\tfixed?: boolean;\n\tfixedCount?: number;\n}\n\nexport interface LintOptions {\n\tcwd: string;\n\tpatterns: string[];\n\tconfigPath?: string;\n\tautoDiscover: boolean;\n\tfix?: boolean;\n\tverbose?: boolean;\n\tonProgress?: (current: number, total: number, file: string) => void;\n}\n\nexport interface LintResult {\n\tfiles: LintFileResult[];\n\ttotalFilesProcessed: number;\n}\n\n/**\n * Error thrown when adapter fails to load required modules\n */\nexport class AdapterLoadError extends Error {\n\tconstructor(\n\t\tpublic readonly version: string,\n\t\tcause: Error,\n\t) {\n\t\tsuper(`Failed to load ${version} adapter: ${cause.message}`);\n\t\tthis.name = \"AdapterLoadError\";\n\t}\n}\n","import { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport type { ContextUtils, GenerateRulesModule } from \"../types\";\nimport { AdapterLoadError } from \"../types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nexport async function loadV3ClassMetadata(\n\tstate: State,\n\tcwd: string,\n\tverbose = false,\n): Promise<void> {\n\ttry {\n\t\tconst tailwindPath = require.resolve(\"tailwindcss\", { paths: [cwd] });\n\t\tconst tailwindcss = require(tailwindPath) as unknown;\n\n\t\ttry {\n\t\t\tconst tailwindDir = path.dirname(\n\t\t\t\trequire.resolve(\"tailwindcss/package.json\", { paths: [cwd] }),\n\t\t\t);\n\n\t\t\tconst contextUtils = require(\n\t\t\t\tpath.join(tailwindDir, \"lib\", \"lib\", \"setupContextUtils\"),\n\t\t\t) as ContextUtils;\n\t\t\tconst generateRulesModule = require(\n\t\t\t\tpath.join(tailwindDir, \"lib\", \"lib\", \"generateRules\"),\n\t\t\t) as GenerateRulesModule;\n\n\t\t\tstate.modules = {\n\t\t\t\ttailwindcss: {\n\t\t\t\t\tversion: state.version || \"unknown\",\n\t\t\t\t\tmodule: tailwindcss,\n\t\t\t\t},\n\t\t\t\tjit: {\n\t\t\t\t\tgenerateRules: {\n\t\t\t\t\t\tmodule:\n\t\t\t\t\t\t\tgenerateRulesModule.generateRules ||\n\t\t\t\t\t\t\t((_set: unknown, _context: unknown) => []),\n\t\t\t\t\t},\n\t\t\t\t\tcreateContext: {\n\t\t\t\t\t\tmodule: contextUtils.createContext,\n\t\t\t\t\t},\n\t\t\t\t\texpandApplyAtRules: {\n\t\t\t\t\t\tmodule: generateRulesModule.expandApplyAtRules,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tif (verbose) {\n\t\t\t\tconsole.log(\" ✓ Loaded v3 JIT modules\");\n\t\t\t}\n\t\t} catch (jitError) {\n\t\t\tif (verbose) {\n\t\t\t\tconst message =\n\t\t\t\t\tjitError instanceof Error ? jitError.message : String(jitError);\n\t\t\t\tconsole.log(` ⚠ Warning: Could not load v3 JIT modules: ${message}`);\n\t\t\t}\n\n\t\t\tstate.modules = {\n\t\t\t\ttailwindcss: {\n\t\t\t\t\tversion: state.version || \"unknown\",\n\t\t\t\t\tmodule: tailwindcss,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\textractConfigMetadata(state);\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tthrow new AdapterLoadError(\"v3\", error);\n\t\t}\n\t\tthrow new Error(`Failed to load v3 class metadata: ${String(error)}`);\n\t}\n}\n\nfunction extractConfigMetadata(state: State): void {\n\tconst { config } = state;\n\tif (!config || typeof config !== \"object\") return;\n\n\tconst theme = (config as Record<string, unknown>).theme as\n\t\t| Record<string, unknown>\n\t\t| undefined;\n\tstate.screens = Object.keys(\n\t\t(theme?.screens as Record<string, unknown>) ?? {},\n\t);\n\tstate.blocklist = (config.blocklist as string[] | undefined) ?? [];\n\n\tif (config.variants && typeof config.variants === \"object\") {\n\t\tstate.variants = Object.keys(config.variants).map((name) => ({\n\t\t\tname,\n\t\t\tvalues: [],\n\t\t\tisArbitrary: false,\n\t\t\thasDash: true,\n\t\t\tselectors: () => [],\n\t\t}));\n\t}\n\n\tif (config.corePlugins) {\n\t\tstate.corePlugins = Array.isArray(config.corePlugins)\n\t\t\t? (config.corePlugins as string[])\n\t\t\t: Object.keys(config.corePlugins as Record<string, unknown>);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport type { DesignSystem } from \"../types\";\nimport { AdapterLoadError } from \"../types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn fs.existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn fs.readFileSync(filePath, \"utf-8\");\n}\n\nexport async function loadV4DesignSystem(\n\tstate: State,\n\tcwd: string,\n\tconfigPath: string,\n\tverbose = false,\n): Promise<void> {\n\ttry {\n\t\tconst tailwindPath = require.resolve(\"tailwindcss\", { paths: [cwd] });\n\t\tconst tailwindcss = require(tailwindPath) as unknown;\n\n\t\tif (\n\t\t\ttailwindcss !== null &&\n\t\t\ttailwindcss !== undefined &&\n\t\t\t(typeof tailwindcss === \"object\" || typeof tailwindcss === \"function\") &&\n\t\t\t\"__unstable__loadDesignSystem\" in tailwindcss &&\n\t\t\ttypeof tailwindcss.__unstable__loadDesignSystem === \"function\"\n\t\t) {\n\t\t\tlet cssContent: string;\n\t\t\tconst basePath = path.dirname(configPath);\n\n\t\t\tif (fileExists(configPath)) {\n\t\t\t\tcssContent = readFileSync(configPath, true);\n\t\t\t} else {\n\t\t\t\tcssContent = '@import \"tailwindcss\";';\n\t\t\t}\n\n\t\t\ttype LoadDesignSystemFn = (\n\t\t\t\tcss: string,\n\t\t\t\toptions: {\n\t\t\t\t\tbase: string;\n\t\t\t\t\tloadStylesheet: (\n\t\t\t\t\t\tid: string,\n\t\t\t\t\t\tbase: string,\n\t\t\t\t\t\tcontent?: string,\n\t\t\t\t\t) => Promise<{ base: string; content: string }>;\n\t\t\t\t},\n\t\t\t) => Promise<DesignSystem>;\n\n\t\t\tconst loadDesignSystem =\n\t\t\t\ttailwindcss.__unstable__loadDesignSystem as LoadDesignSystemFn;\n\n\t\t\tconst designSystem = await loadDesignSystem(cssContent, {\n\t\t\t\tbase: basePath,\n\t\t\t\tasync loadStylesheet(\n\t\t\t\t\t_id: string,\n\t\t\t\t\tbase: string,\n\t\t\t\t\tcontent?: string,\n\t\t\t\t): Promise<{ base: string; content: string }> {\n\t\t\t\t\tif (content) {\n\t\t\t\t\t\treturn { base, content };\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!_id.startsWith(\".\") && !_id.startsWith(\"/\")) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst pkgJsonPath = require.resolve(`${_id}/package.json`, {\n\t\t\t\t\t\t\t\tpaths: [base, cwd],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst pkgDir = path.dirname(pkgJsonPath);\n\t\t\t\t\t\t\tconst cssPath = path.join(pkgDir, \"index.css\");\n\t\t\t\t\t\t\tif (fileExists(cssPath)) {\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tbase: pkgDir,\n\t\t\t\t\t\t\t\t\tcontent: readFileSync(cssPath, true),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst filePath = path.resolve(base, _id);\n\t\t\t\t\tif (fileExists(filePath)) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tbase: path.dirname(filePath),\n\t\t\t\t\t\t\tcontent: readFileSync(filePath, true),\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn { base, content: \"\" };\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tObject.assign(designSystem, {\n\t\t\t\tdependencies: () => new Set<string>(),\n\n\t\t\t\tcompile(classes: string[]): unknown[][] {\n\t\t\t\t\tconst results = designSystem.candidatesToAst\n\t\t\t\t\t\t? designSystem.candidatesToAst(classes)\n\t\t\t\t\t\t: designSystem.candidatesToCss?.(classes) || [];\n\n\t\t\t\t\treturn results.map((result: unknown) => {\n\t\t\t\t\t\tif (Array.isArray(result)) {\n\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (result === null) {\n\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// @ts-expect-error - DesignSystem types are loaded dynamically at runtime\n\t\t\tstate.designSystem = designSystem;\n\n\t\t\tif (!state.classNames) {\n\t\t\t\tstate.classNames = {\n\t\t\t\t\tcontext: {},\n\t\t\t\t} as unknown as typeof state.classNames;\n\t\t\t}\n\n\t\t\tif (verbose) {\n\t\t\t\tconsole.log(\" ✓ Loaded v4 design system\");\n\t\t\t}\n\t\t} else {\n\t\t\tconst error = new Error(\n\t\t\t\t\"Tailwind v4 __unstable__loadDesignSystem is not available. Please ensure you have Tailwind CSS v4 installed.\",\n\t\t\t);\n\t\t\tthrow new AdapterLoadError(\"v4\", error);\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof AdapterLoadError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (error instanceof Error) {\n\t\t\tthrow new AdapterLoadError(\"v4\", error);\n\t\t}\n\t\tthrow new Error(`Failed to load v4 design system: ${String(error)}`);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport { createEditorState } from \"./adapters/editor-state-adapter\";\nimport { loadV3ClassMetadata } from \"./adapters/v3-adapter\";\nimport { loadV4DesignSystem } from \"./adapters/v4-adapter\";\nimport {\n\tDEFAULT_SEPARATOR,\n\tV3_CONFIG_PATHS,\n\tV4_CSS_FOLDERS,\n\tV4_CSS_NAMES,\n} from \"./constants\";\nimport type { ResolvedTailwindConfig, TailwindConfig } from \"./types\";\n\nconst require = createRequire(import.meta.url || __filename);\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn fs.existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn fs.readFileSync(filePath, \"utf-8\");\n}\n\nfunction getTailwindVersion(cwd: string): string | undefined {\n\ttry {\n\t\tconst tailwindPackageJson = require.resolve(\"tailwindcss/package.json\", {\n\t\t\tpaths: [cwd],\n\t\t});\n\t\tconst pkg = JSON.parse(fs.readFileSync(tailwindPackageJson, \"utf-8\")) as {\n\t\t\tversion?: string;\n\t\t};\n\t\treturn pkg.version;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction isV4Config(version: string | undefined): boolean {\n\treturn version?.startsWith(\"4.\") ?? false;\n}\n\nfunction isCssConfigFile(filePath: string): boolean {\n\treturn filePath.endsWith(\".css\");\n}\n\nasync function loadTailwindConfig(configPath: string): Promise<TailwindConfig> {\n\tif (isCssConfigFile(configPath)) {\n\t\treturn {};\n\t}\n\n\tif (!path.isAbsolute(configPath)) {\n\t\tthrow new Error(\n\t\t\t`Config path must be absolute for security reasons: ${configPath}`,\n\t\t);\n\t}\n\n\ttry {\n\t\tdelete require.cache[configPath];\n\n\t\tconst configModule = require(configPath) as\n\t\t\t| TailwindConfig\n\t\t\t| { default: TailwindConfig };\n\t\tconst config = (\n\t\t\t\"default\" in configModule ? configModule.default : configModule\n\t\t) as TailwindConfig;\n\n\t\tif (typeof config !== \"object\" || config === null) {\n\t\t\tthrow new Error(\"Config must be an object\");\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(\n\t\t\t`Failed to load config from ${configPath}: ${errorMessage}`,\n\t\t);\n\t}\n}\n\nasync function findTailwindConfigPath(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string | null> {\n\tif (configPath) {\n\t\tconst resolved = path.isAbsolute(configPath)\n\t\t\t? configPath\n\t\t\t: path.resolve(cwd, configPath);\n\t\treturn fileExists(resolved) ? resolved : null;\n\t}\n\n\tfor (const p of V3_CONFIG_PATHS) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\treturn fullPath;\n\t\t}\n\t}\n\n\tconst v4Paths = V4_CSS_FOLDERS.flatMap((folder) =>\n\t\tV4_CSS_NAMES.map((name) => path.join(folder, name)),\n\t);\n\n\tfor (const p of v4Paths) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(fullPath);\n\t\t\t\tif (\n\t\t\t\t\tcontent.includes('@import \"tailwindcss\"') ||\n\t\t\t\t\tcontent.includes(\"@import 'tailwindcss'\")\n\t\t\t\t) {\n\t\t\t\t\treturn fullPath;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction resolveTailwindPath(cwd: string, configDir?: string): string {\n\tconst paths = configDir ? [configDir, cwd] : [cwd];\n\ttry {\n\t\treturn require.resolve(\"tailwindcss\", { paths });\n\t} catch {\n\t\tthrow new Error(\n\t\t\t`Could not resolve tailwindcss module from ${paths.join(\" or \")}`,\n\t\t);\n\t}\n}\n\nexport async function createState(\n\tcwd: string,\n\tconfigPath?: string,\n\tverbose = false,\n): Promise<State> {\n\tconst resolvedConfigPath = await findTailwindConfigPath(cwd, configPath);\n\n\tif (!resolvedConfigPath) {\n\t\tthrow new Error(\"Could not find tailwind config file (JS/TS or CSS)\");\n\t}\n\n\tconst isCssConfig = isCssConfigFile(resolvedConfigPath);\n\tconst configDir = path.dirname(resolvedConfigPath);\n\tconst tailwindPath = resolveTailwindPath(cwd, configDir);\n\n\tconst tailwindcss = require(tailwindPath) as {\n\t\tresolveConfig?: (config: unknown) => unknown;\n\t};\n\n\tconst version = getTailwindVersion(cwd);\n\tconst isV4 = isV4Config(version);\n\n\tif (verbose) {\n\t\tconsole.log(` Tailwind version: ${version || \"unknown\"}`);\n\t\tconsole.log(` Config type: ${isCssConfig ? \"CSS (v4)\" : \"JavaScript\"}`);\n\t\tconsole.log(` Config path: ${resolvedConfigPath}`);\n\t}\n\n\tlet config: TailwindConfig = {};\n\tlet resolvedConfig: ResolvedTailwindConfig = { separator: \":\" };\n\n\tif (!isCssConfig) {\n\t\tconfig = await loadTailwindConfig(resolvedConfigPath);\n\t\tresolvedConfig = {\n\t\t\t...config,\n\t\t\tseparator: config.separator ?? DEFAULT_SEPARATOR,\n\t\t};\n\t\tif (tailwindcss.resolveConfig) {\n\t\t\tresolvedConfig = tailwindcss.resolveConfig(\n\t\t\t\tconfig,\n\t\t\t) as ResolvedTailwindConfig;\n\t\t}\n\t}\n\n\tconst state: State = {\n\t\tenabled: true,\n\t\tconfigPath: resolvedConfigPath,\n\t\tconfig: resolvedConfig,\n\t\tversion,\n\t\tv4: isV4 || undefined,\n\t\tseparator: resolvedConfig.separator || DEFAULT_SEPARATOR,\n\t\tscreens: [],\n\t\tvariants: [],\n\t\tclassNames: undefined,\n\t\tclassList: undefined,\n\t\tmodules: undefined,\n\t\tblocklist: [],\n\t\teditor: createEditorState(cwd),\n\t\tfeatures: [\"diagnostics\"] as unknown as State[\"features\"],\n\t};\n\n\tif (isV4 || isCssConfig) {\n\t\tawait loadV4DesignSystem(state, cwd, resolvedConfigPath, verbose);\n\t} else {\n\t\tawait loadV3ClassMetadata(state, cwd, verbose);\n\t}\n\n\treturn state;\n}\n","import * as path from \"node:path\";\nimport type { State } from \"@tailwindcss/language-service\";\nimport { doValidate } from \"@tailwindcss/language-service\";\nimport glob from \"fast-glob\";\nimport { TextDocument } from \"vscode-languageserver-textdocument\";\nimport { applyCodeActions } from \"./code-actions\";\nimport { DEFAULT_IGNORE_PATTERNS } from \"./constants\";\nimport { createState } from \"./state\";\nimport type {\n\tLintFileResult,\n\tLintOptions,\n\tLintResult,\n\tSerializedDiagnostic,\n\tTailwindConfig,\n} from \"./types\";\n\nfunction fileExists(filePath: string): boolean {\n\ttry {\n\t\treturn require(\"node:fs\").existsSync(filePath);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction readFileSync(filePath: string): string {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\treturn require(\"node:fs\").readFileSync(filePath, \"utf-8\");\n}\n\nfunction writeFileSync(filePath: string, content: string): void {\n\tif (!filePath || typeof filePath !== \"string\") {\n\t\tthrow new TypeError(\"File path must be a non-empty string\");\n\t}\n\tif (typeof content !== \"string\") {\n\t\tthrow new TypeError(\"Content must be a string\");\n\t}\n\trequire(\"node:fs\").writeFileSync(filePath, content, \"utf-8\");\n}\n\nfunction serializeDiagnostics(\n\tdiagnostics: import(\"vscode-languageserver\").Diagnostic[],\n): SerializedDiagnostic[] {\n\treturn diagnostics.map((diagnostic) => ({\n\t\trange: {\n\t\t\tstart: {\n\t\t\t\tline: diagnostic.range.start.line,\n\t\t\t\tcharacter: diagnostic.range.start.character,\n\t\t\t},\n\t\t\tend: {\n\t\t\t\tline: diagnostic.range.end.line,\n\t\t\t\tcharacter: diagnostic.range.end.character,\n\t\t\t},\n\t\t},\n\t\tseverity: diagnostic.severity || 2,\n\t\tmessage: diagnostic.message,\n\t\tcode: diagnostic.code?.toString(),\n\t\tsource: diagnostic.source,\n\t}));\n}\n\nfunction getLanguageId(filePath: string): string {\n\tconst LANGUAGE_MAP: Record<string, string> = {\n\t\t\".astro\": \"astro\",\n\t\t\".css\": \"css\",\n\t\t\".erb\": \"erb\",\n\t\t\".hbs\": \"handlebars\",\n\t\t\".htm\": \"html\",\n\t\t\".html\": \"html\",\n\t\t\".js\": \"javascript\",\n\t\t\".jsx\": \"javascriptreact\",\n\t\t\".less\": \"less\",\n\t\t\".md\": \"markdown\",\n\t\t\".mdx\": \"mdx\",\n\t\t\".php\": \"php\",\n\t\t\".sass\": \"sass\",\n\t\t\".scss\": \"scss\",\n\t\t\".svelte\": \"svelte\",\n\t\t\".ts\": \"typescript\",\n\t\t\".tsx\": \"typescriptreact\",\n\t\t\".twig\": \"twig\",\n\t\t\".vue\": \"vue\",\n\t};\n\tconst ext = path.extname(filePath).toLowerCase();\n\treturn LANGUAGE_MAP[ext] || \"html\";\n}\n\nasync function validateDocument(\n\tstate: State,\n\tfilePath: string,\n\tcontent: string,\n): Promise<SerializedDiagnostic[]> {\n\ttry {\n\t\tif (!state) {\n\t\t\tthrow new Error(\"State is not initialized\");\n\t\t}\n\n\t\tif (state.v4 && !state.designSystem) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Design system not initialized for Tailwind v4. This might indicate a configuration issue.\",\n\t\t\t);\n\t\t}\n\n\t\tif (!state.v4 && !state.modules?.tailwindcss) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Tailwind modules not initialized for Tailwind v3. This might indicate a configuration issue.\",\n\t\t\t);\n\t\t}\n\n\t\tconst languageId = getLanguageId(filePath);\n\t\tconst uri = `file://${filePath}`;\n\t\tconst document = TextDocument.create(uri, languageId, 1, content);\n\n\t\tconst diagnostics = await doValidate(state, document);\n\n\t\treturn serializeDiagnostics(diagnostics);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to validate document ${filePath}: ${message}`);\n\t}\n}\n\nasync function findTailwindConfigPath(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string | null> {\n\tconst { V3_CONFIG_PATHS, V4_CSS_FOLDERS, V4_CSS_NAMES } = await import(\n\t\t\"./constants\"\n\t);\n\n\tif (configPath) {\n\t\tconst resolved = path.isAbsolute(configPath)\n\t\t\t? configPath\n\t\t\t: path.resolve(cwd, configPath);\n\t\treturn fileExists(resolved) ? resolved : null;\n\t}\n\n\tfor (const p of V3_CONFIG_PATHS) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\treturn fullPath;\n\t\t}\n\t}\n\n\tconst v4Paths = V4_CSS_FOLDERS.flatMap((folder) =>\n\t\tV4_CSS_NAMES.map((name) => path.join(folder, name)),\n\t);\n\n\tfor (const p of v4Paths) {\n\t\tconst fullPath = path.join(cwd, p);\n\t\tif (fileExists(fullPath)) {\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(fullPath);\n\t\t\t\tif (\n\t\t\t\t\tcontent.includes('@import \"tailwindcss\"') ||\n\t\t\t\t\tcontent.includes(\"@import 'tailwindcss'\")\n\t\t\t\t) {\n\t\t\t\t\treturn fullPath;\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction isCssConfigFile(filePath: string): boolean {\n\treturn filePath.endsWith(\".css\");\n}\n\nasync function loadTailwindConfig(configPath: string): Promise<TailwindConfig> {\n\tif (isCssConfigFile(configPath)) {\n\t\treturn {};\n\t}\n\n\tif (!path.isAbsolute(configPath)) {\n\t\tthrow new Error(\n\t\t\t`Config path must be absolute for security reasons: ${configPath}`,\n\t\t);\n\t}\n\n\ttry {\n\t\tconst { createRequire } = await import(\"node:module\");\n\t\tconst require = createRequire(import.meta.url || __filename);\n\t\tdelete require.cache[configPath];\n\n\t\tconst configModule = require(configPath) as\n\t\t\t| TailwindConfig\n\t\t\t| { default: TailwindConfig };\n\t\tconst config = (\n\t\t\t\"default\" in configModule ? configModule.default : configModule\n\t\t) as TailwindConfig;\n\n\t\tif (typeof config !== \"object\" || config === null) {\n\t\t\tthrow new Error(\"Config must be an object\");\n\t\t}\n\n\t\treturn config;\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(\n\t\t\t`Failed to load config from ${configPath}: ${errorMessage}`,\n\t\t);\n\t}\n}\n\nasync function discoverFiles(\n\tcwd: string,\n\tpatterns: string[],\n\tconfigPath: string | undefined,\n\tautoDiscover: boolean,\n): Promise<string[]> {\n\tif (autoDiscover) {\n\t\treturn discoverFilesFromConfig(cwd, configPath);\n\t}\n\treturn expandPatterns(cwd, patterns);\n}\n\nasync function expandPatterns(\n\tcwd: string,\n\tpatterns: string[],\n): Promise<string[]> {\n\tconst explicitFiles: string[] = [];\n\tconst globPatterns: string[] = [];\n\n\tfor (const pattern of patterns) {\n\t\tif (\n\t\t\tpattern.includes(\"*\") ||\n\t\t\tpattern.includes(\"?\") ||\n\t\t\tpattern.includes(\"[\")\n\t\t) {\n\t\t\tglobPatterns.push(pattern);\n\t\t} else {\n\t\t\tconst fullPath = path.resolve(cwd, pattern);\n\t\t\tif (fileExists(fullPath)) {\n\t\t\t\texplicitFiles.push(pattern);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (globPatterns.length === 0) {\n\t\treturn explicitFiles;\n\t}\n\n\tconst globResults = await glob(globPatterns, {\n\t\tcwd,\n\t\tabsolute: false,\n\t\tignore: DEFAULT_IGNORE_PATTERNS,\n\t});\n\n\tif (explicitFiles.length === 0) {\n\t\treturn globResults;\n\t}\n\n\tconst fileSet = new Set(explicitFiles);\n\tfor (const file of globResults) {\n\t\tfileSet.add(file);\n\t}\n\treturn Array.from(fileSet);\n}\n\nasync function discoverFilesFromConfig(\n\tcwd: string,\n\tconfigPath?: string,\n): Promise<string[]> {\n\tconst configFilePath = await findTailwindConfigPath(cwd, configPath);\n\n\tif (!configFilePath) {\n\t\tthrow new Error(\"Could not find Tailwind config\");\n\t}\n\n\tif (!isCssConfigFile(configFilePath)) {\n\t\tconst config = await loadTailwindConfig(configFilePath);\n\n\t\tif (!config || !config.content) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Could not find Tailwind config or config has no content property\",\n\t\t\t);\n\t\t}\n\n\t\tconst patterns = extractContentPatterns(config);\n\n\t\tif (patterns.length === 0) {\n\t\t\tthrow new Error(\"No content patterns found in Tailwind config\");\n\t\t}\n\n\t\treturn expandPatterns(cwd, patterns);\n\t}\n\n\tthrow new Error(\n\t\t\"Auto-discovery is not supported for CSS-based configs (v4). Please specify file patterns.\",\n\t);\n}\n\nfunction extractContentPatterns(config: TailwindConfig): string[] {\n\tif (!config.content) return [];\n\n\tif (Array.isArray(config.content)) {\n\t\treturn config.content.filter((p): p is string => typeof p === \"string\");\n\t}\n\n\tif (config.content.files) {\n\t\treturn config.content.files.filter(\n\t\t\t(p): p is string => typeof p === \"string\",\n\t\t);\n\t}\n\n\treturn [];\n}\n\nasync function processFiles(\n\tstate: State,\n\tcwd: string,\n\tfiles: string[],\n\tfix: boolean,\n\tonProgress?: (current: number, total: number, file: string) => void,\n): Promise<LintFileResult[]> {\n\tconst results: LintFileResult[] = [];\n\n\tfor (let i = 0; i < files.length; i++) {\n\t\tif (onProgress) {\n\t\t\tonProgress(i + 1, files.length, files[i]);\n\t\t}\n\n\t\tconst result = await processFile(state, cwd, files[i], fix);\n\t\tif (result) {\n\t\t\tresults.push(result);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nasync function processFile(\n\tstate: State,\n\tcwd: string,\n\tfilePath: string,\n\tfix: boolean,\n): Promise<LintFileResult | null> {\n\tconst absolutePath = path.isAbsolute(filePath)\n\t\t? filePath\n\t\t: path.resolve(cwd, filePath);\n\n\tif (!fileExists(absolutePath)) {\n\t\treturn null;\n\t}\n\n\tlet content = readFileSync(absolutePath);\n\tlet diagnostics = await validateDocument(state, absolutePath, content);\n\n\tlet fixedCount = 0;\n\tlet wasFixed = false;\n\n\tif (fix && diagnostics.length > 0) {\n\t\tconst fixResult = await applyCodeActions(\n\t\t\tstate,\n\t\t\tabsolutePath,\n\t\t\tcontent,\n\t\t\tdiagnostics,\n\t\t);\n\n\t\tif (fixResult.changed) {\n\t\t\twriteFileSync(absolutePath, fixResult.content);\n\t\t\tcontent = fixResult.content;\n\t\t\twasFixed = true;\n\t\t\tfixedCount = fixResult.fixedCount;\n\n\t\t\t// Re-validate to get remaining diagnostics\n\t\t\tdiagnostics = await validateDocument(state, absolutePath, content);\n\t\t}\n\t}\n\n\treturn {\n\t\tpath: path.relative(cwd, absolutePath),\n\t\tdiagnostics,\n\t\tfixed: wasFixed,\n\t\tfixedCount,\n\t};\n}\nasync function initializeState(\n\tcwd: string,\n\tconfigPath?: string,\n\tverbose = false,\n) {\n\ttry {\n\t\tif (verbose) {\n\t\t\tconsole.log(\"→ Initializing Tailwind CSS language service...\");\n\t\t}\n\t\tconst state = await createState(cwd, configPath, verbose);\n\t\tif (verbose) {\n\t\t\tconsole.log(\" ✓ State initialized successfully\\n\");\n\t\t}\n\t\treturn state;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to initialize Tailwind state: ${message}`);\n\t}\n}\n\nexport type { LintFileResult, LintOptions, LintResult };\n\nexport async function lint({\n\tcwd,\n\tpatterns,\n\tconfigPath,\n\tautoDiscover,\n\tfix = false,\n\tverbose = false,\n\tonProgress,\n}: LintOptions): Promise<LintResult> {\n\tconst files = await discoverFiles(cwd, patterns, configPath, autoDiscover);\n\n\tif (verbose) {\n\t\tconsole.log(\n\t\t\t`→ Discovered ${files.length} file${files.length !== 1 ? \"s\" : \"\"} to lint`,\n\t\t);\n\t}\n\n\tif (files.length === 0) {\n\t\treturn { files: [], totalFilesProcessed: 0 };\n\t}\n\n\tconst state = await initializeState(cwd, configPath, verbose);\n\tconst results = await processFiles(state, cwd, files, fix, onProgress);\n\n\treturn {\n\t\tfiles: results.filter(\n\t\t\t(result) => result.diagnostics.length > 0 || result.fixed,\n\t\t),\n\t\ttotalFilesProcessed: files.length,\n\t};\n}\n"],"mappings":"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"}