tailwind-lint 0.10.2 → 0.11.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/README.md CHANGED
@@ -65,7 +65,7 @@ tailwind-lint --verbose
65
65
  ### Options
66
66
 
67
67
  - `-c, --config <path>` - Path to Tailwind config file (default: auto-discover)
68
- - `-a, --auto` - Auto-discover files from config content patterns (legacy, enabled by default)
68
+ - `-a, --auto` - Auto-discover files from the resolved Tailwind config or CSS `@source` directives
69
69
  - `--fix` - Automatically fix problems that can be fixed
70
70
  - `--format <text|json>` - Output format (`text` default, `json` for machine-readable output)
71
71
  - `-v, --verbose` - Enable verbose logging for debugging
@@ -81,6 +81,9 @@ tailwind-lint "src/**/*.{js,jsx,ts,tsx}"
81
81
  # Specify a custom config location
82
82
  tailwind-lint --config ./config/tailwind.config.js
83
83
 
84
+ # Scan files based on an explicit config
85
+ tailwind-lint --config ./src/app.css
86
+
84
87
  # Lint and fix specific file types
85
88
  tailwind-lint "**/*.vue" --fix
86
89
 
@@ -109,6 +112,8 @@ The JSON payload includes:
109
112
  - `config` - resolved runtime values (`cwd`, `configPath`, `autoDiscover`, `fix`, `patterns`)
110
113
  - `files[]` - per-file diagnostics with 1-based `line`/`column` ranges
111
114
 
115
+ On JSON errors, the CLI keeps the same top-level shape and adds `error` so agent integrations do not need a separate parser for failure cases.
116
+
112
117
  Typical agent flow:
113
118
 
114
119
  1. Run `tailwind-lint --auto --format json`.
@@ -147,6 +152,52 @@ export default defineConfig({
147
152
 
148
153
  If a real CSS config is also present, the CLI uses that file so custom `@theme` tokens and `@source` directives are available to diagnostics.
149
154
 
155
+ ### Workspace Settings
156
+
157
+ The CLI also reads Tailwind workspace settings from common editor config files so extraction behavior can match your editor more closely.
158
+
159
+ Supported locations:
160
+
161
+ - `.zed/settings.json`
162
+ - `.vscode/settings.json`
163
+
164
+ Supported settings:
165
+
166
+ - `classFunctions`
167
+ - `experimental.classRegex`
168
+ - `classAttributes`
169
+ - `includeLanguages`
170
+ - `files.exclude`
171
+ - `lint`
172
+
173
+ Zed format:
174
+
175
+ ```json
176
+ {
177
+ "lsp": {
178
+ "tailwindcss-language-server": {
179
+ "settings": {
180
+ "classFunctions": ["cva", "cx"],
181
+ "experimental": {
182
+ "classRegex": ["tw=\"([^\"]*)\""]
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ ```
189
+
190
+ VS Code format:
191
+
192
+ ```json
193
+ {
194
+ "tailwindCSS.classFunctions": ["cva", "cx"],
195
+ "tailwindCSS.experimental": {
196
+ "classRegex": ["tw=\"([^\"]*)\""]
197
+ }
198
+ }
199
+ ```
200
+
150
201
  ### Tailwind CSS v3 (Legacy)
151
202
 
152
203
  Create a JavaScript config file (`tailwind.config.js`):
package/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_linter = require("./linter-ChZk2xMs.cjs");
2
+ const require_linter = require("./linter-BBFc8gnJ.cjs");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_linter.__toESM(node_path, 1);
5
5
  let ansis = require("ansis");
@@ -74,6 +74,27 @@ function createJsonOutput({ files, totalFilesProcessed, cwd, configPath, autoDis
74
74
  files: mappedFiles
75
75
  };
76
76
  }
77
+ function createJsonErrorOutput({ error, cwd, configPath, autoDiscover, fix, patterns }) {
78
+ return {
79
+ ok: false,
80
+ error,
81
+ summary: {
82
+ errors: 0,
83
+ warnings: 0,
84
+ fixed: 0,
85
+ filesWithIssues: 0,
86
+ totalFilesProcessed: 0
87
+ },
88
+ config: {
89
+ cwd,
90
+ configPath: configPath || null,
91
+ autoDiscover,
92
+ fix,
93
+ patterns
94
+ },
95
+ files: []
96
+ };
97
+ }
77
98
  //#endregion
78
99
  //#region src/cli.ts
79
100
  const MAX_FILENAME_DISPLAY_LENGTH = 50;
@@ -84,13 +105,13 @@ function resolveOptions(files, options) {
84
105
  let cwd = process.cwd();
85
106
  let configPath = options.config;
86
107
  let patterns = files;
108
+ let autoDiscover = hasAutoFlag;
109
+ if (hasConfigFlag && options.config) configPath = node_path.isAbsolute(options.config) ? options.config : node_path.resolve(process.cwd(), options.config);
87
110
  if (hasConfigFlag && options.config && !hasFiles) {
88
- const absoluteConfigPath = node_path.isAbsolute(options.config) ? options.config : node_path.resolve(process.cwd(), options.config);
89
- cwd = node_path.dirname(absoluteConfigPath);
90
- configPath = node_path.basename(absoluteConfigPath);
91
- patterns = [require_linter.DEFAULT_FILE_PATTERN];
111
+ cwd = node_path.dirname(configPath);
112
+ patterns = [];
113
+ autoDiscover = true;
92
114
  }
93
- const autoDiscover = hasAutoFlag;
94
115
  return {
95
116
  cwd,
96
117
  configPath,
@@ -101,7 +122,7 @@ function resolveOptions(files, options) {
101
122
  };
102
123
  }
103
124
  function truncateFilename(filename) {
104
- return filename.length > MAX_FILENAME_DISPLAY_LENGTH ? `...${filename.slice(-MAX_FILENAME_DISPLAY_LENGTH)}` : filename;
125
+ return filename.length > MAX_FILENAME_DISPLAY_LENGTH ? `...${filename.slice(-50)}` : filename;
105
126
  }
106
127
  async function displayResults(files, fixMode) {
107
128
  let totalErrors = 0;
@@ -186,19 +207,22 @@ program.configureHelp({ formatHelp: (cmd, helper) => {
186
207
  }
187
208
  return output;
188
209
  } });
189
- program.name("tailwind-lint").description("A CLI tool for linting Tailwind CSS class usage").version(getVersion()).argument("[files...]", "File patterns to lint (e.g., \"src/**/*.{js,jsx,ts,tsx}\")").option("-c, --config <path>", "Path to Tailwind config file (default: auto-discover)").option("-a, --auto", "Auto-discover files from Tailwind config content patterns").option("--fix", "Automatically fix problems that can be fixed").option("-v, --verbose", "Enable verbose logging for debugging").option("--format <format>", "Output format: text or json", "text").addHelpText("after", `
210
+ program.name("tailwind-lint").description("A CLI tool for linting Tailwind CSS class usage").version(getVersion()).argument("[files...]", "File patterns to lint (e.g., \"src/**/*.{js,jsx,ts,tsx}\")").option("-c, --config <path>", "Path to Tailwind config file (default: auto-discover)").option("-a, --auto", "Auto-discover files from Tailwind config or CSS @source patterns").option("--fix", "Automatically fix problems that can be fixed").option("-v, --verbose", "Enable verbose logging for debugging").option("--format <format>", "Output format: text or json", "text").addHelpText("after", `
190
211
  ${ansis.default.bold.cyan("Examples:")}
191
212
  ${ansis.default.dim("$")} tailwind-lint
192
213
  ${ansis.default.dim("$")} tailwind-lint ${ansis.default.green("\"src/**/*.{js,jsx,ts,tsx}\"")}
193
214
  ${ansis.default.dim("$")} tailwind-lint ${ansis.default.yellow("--config")} ${ansis.default.green("./tailwind.config.js")}
215
+ ${ansis.default.dim("$")} tailwind-lint ${ansis.default.yellow("--config")} ${ansis.default.green("./src/app.css")}
194
216
  ${ansis.default.dim("$")} tailwind-lint ${ansis.default.green("\"src/**/*.tsx\"")} ${ansis.default.yellow("--fix")}
195
217
  ${ansis.default.dim("$")} tailwind-lint ${ansis.default.green("\"**/*.vue\"")}
196
218
 
197
219
  ${ansis.default.bold.cyan("Notes:")}
198
220
  ${ansis.default.dim("•")} Running without arguments auto-discovers config and files
221
+ ${ansis.default.dim("•")} Using ${ansis.default.yellow("--config")} without files scans based on that config
199
222
  ${ansis.default.dim("•")} For v3: uses content patterns from tailwind.config.js
200
- ${ansis.default.dim("•")} For v4: uses @source patterns from CSS config, or default pattern
201
- ${ansis.default.dim("•")} Default pattern: ${ansis.default.dim("./**/*.{js,jsx,ts,tsx,html}")}
223
+ ${ansis.default.dim("•")} For v4: uses @source patterns from CSS config, Vite detection, or default pattern
224
+ ${ansis.default.dim("•")} Default pattern: ${ansis.default.dim(require_linter.DEFAULT_FILE_PATTERN)}
225
+ ${ansis.default.dim("•")} Reads Tailwind workspace settings from ${ansis.default.dim(".zed/settings.json")} and ${ansis.default.dim(".vscode/settings.json")}
202
226
  ${ansis.default.dim("•")} Use ${ansis.default.yellow("--fix")} to automatically resolve fixable issues
203
227
  `).action(async (files, options) => {
204
228
  const hasConfigFlag = !!options.config;
@@ -257,10 +281,10 @@ ${ansis.default.bold.cyan("Notes:")}
257
281
  process.exit(hasErrors ? 1 : 0);
258
282
  } catch (error) {
259
283
  const errorMessage = error instanceof Error ? error.message : String(error);
260
- if (isJsonOutput) console.log(JSON.stringify({
261
- ok: false,
262
- error: errorMessage
263
- }));
284
+ if (isJsonOutput) console.log(JSON.stringify(createJsonErrorOutput({
285
+ error: errorMessage,
286
+ ...resolved
287
+ })));
264
288
  else console.error(ansis.default.red("✖ Error:"), errorMessage);
265
289
  if (resolved.verbose && error instanceof Error && !isJsonOutput) {
266
290
  console.error(ansis.default.dim("\nStack trace:"));
@@ -206,6 +206,182 @@ async function applyCodeActions(state, filePath, content, diagnostics) {
206
206
  }
207
207
  }
208
208
  //#endregion
209
+ //#region src/utils/fs.ts
210
+ function fileExists(filePath) {
211
+ try {
212
+ return node_fs.existsSync(filePath);
213
+ } catch {
214
+ return false;
215
+ }
216
+ }
217
+ function readFileSync(filePath) {
218
+ if (!filePath || typeof filePath !== "string") throw new TypeError("File path must be a non-empty string");
219
+ return node_fs.readFileSync(filePath, "utf-8");
220
+ }
221
+ function writeFileSync(filePath, content) {
222
+ if (!filePath || typeof filePath !== "string") throw new TypeError("File path must be a non-empty string");
223
+ if (typeof content !== "string") throw new TypeError("Content must be a string");
224
+ node_fs.writeFileSync(filePath, content, "utf-8");
225
+ }
226
+ function readGitignorePatterns(cwd) {
227
+ const gitignorePath = node_path.join(cwd, ".gitignore");
228
+ if (!fileExists(gitignorePath)) return [];
229
+ try {
230
+ return node_fs.readFileSync(gitignorePath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#") && !line.startsWith("!")).map((pattern) => {
231
+ const cleaned = pattern.replace(/\/+$/, "");
232
+ if (cleaned.includes("/") || cleaned.includes("*")) return cleaned.endsWith("/**") ? cleaned : `${cleaned}/**`;
233
+ return `**/${cleaned}/**`;
234
+ });
235
+ } catch {
236
+ return [];
237
+ }
238
+ }
239
+ //#endregion
240
+ //#region src/utils/settings.ts
241
+ function loadWorkspaceTailwindSettings(cwd) {
242
+ return mergeTailwindSettings(readVsCodeTailwindSettings(cwd), readZedTailwindSettings(cwd));
243
+ }
244
+ function readVsCodeTailwindSettings(cwd) {
245
+ const parsed = readJsoncFile(node_path.join(cwd, ".vscode", "settings.json"));
246
+ if (!parsed || typeof parsed !== "object") return {};
247
+ const raw = parsed;
248
+ const experimental = readNestedObject(raw, "tailwindCSS.experimental");
249
+ const files = readNestedObject(raw, "tailwindCSS.files");
250
+ const lint = readNestedObject(raw, "tailwindCSS.lint");
251
+ return {
252
+ includeLanguages: asRecord(raw["tailwindCSS.includeLanguages"]),
253
+ classAttributes: asStringArray(raw["tailwindCSS.classAttributes"]),
254
+ classFunctions: asStringArray(raw["tailwindCSS.classFunctions"]),
255
+ experimental: {
256
+ classRegex: asClassRegex(experimental?.classRegex),
257
+ configFile: asConfigFile(experimental?.configFile)
258
+ },
259
+ files: { exclude: asStringArray(files?.exclude) },
260
+ lint: asLintSettings(lint)
261
+ };
262
+ }
263
+ function readZedTailwindSettings(cwd) {
264
+ const parsed = readJsoncFile(node_path.join(cwd, ".zed", "settings.json"));
265
+ if (!parsed || typeof parsed !== "object") return {};
266
+ const serverSettings = asRecord(asRecord(asRecord(parsed.lsp)?.["tailwindcss-language-server"])?.settings);
267
+ const normalized = asRecord(serverSettings?.tailwindCSS) ?? serverSettings;
268
+ if (!normalized) return {};
269
+ return {
270
+ includeLanguages: asRecord(normalized.includeLanguages),
271
+ classAttributes: asStringArray(normalized.classAttributes),
272
+ classFunctions: asStringArray(normalized.classFunctions),
273
+ experimental: {
274
+ classRegex: asClassRegex(asRecord(normalized.experimental)?.classRegex),
275
+ configFile: asConfigFile(asRecord(normalized.experimental)?.configFile)
276
+ },
277
+ files: { exclude: asStringArray(asRecord(normalized.files)?.exclude) },
278
+ lint: asLintSettings(asRecord(normalized.lint))
279
+ };
280
+ }
281
+ function readJsoncFile(filePath) {
282
+ if (!fileExists(filePath)) return null;
283
+ try {
284
+ return JSON.parse(stripJsonComments(readFileSync(filePath)));
285
+ } catch {
286
+ return null;
287
+ }
288
+ }
289
+ function stripJsonComments(content) {
290
+ return content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, "").replace(/,\s*([}\]])/g, "$1");
291
+ }
292
+ function readNestedObject(input, key) {
293
+ return asRecord(input[key]);
294
+ }
295
+ function asRecord(value) {
296
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
297
+ }
298
+ function asStringArray(value) {
299
+ return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
300
+ }
301
+ function asClassRegex(value) {
302
+ if (!Array.isArray(value)) return;
303
+ if (value.every((item) => typeof item === "string")) return value;
304
+ if (value.every((item) => Array.isArray(item) && item.length === 2 && item.every((part) => typeof part === "string"))) return value;
305
+ }
306
+ function asConfigFile(value) {
307
+ if (typeof value === "string" || value === null) return value;
308
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
309
+ const record = value;
310
+ const entries = Object.entries(record).filter(([, entry]) => typeof entry === "string" || Array.isArray(entry) && entry.every((item) => typeof item === "string"));
311
+ return entries.length === Object.keys(record).length ? Object.fromEntries(entries) : void 0;
312
+ }
313
+ function asLintSettings(value) {
314
+ if (!value) return;
315
+ const entries = Object.entries(value).filter(([, entry]) => [
316
+ "ignore",
317
+ "warning",
318
+ "error"
319
+ ].includes(String(entry)));
320
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
321
+ }
322
+ function mergeTailwindSettings(...patches) {
323
+ return patches.reduce((acc, patch) => {
324
+ if (patch.includeLanguages) acc.includeLanguages = {
325
+ ...acc.includeLanguages,
326
+ ...patch.includeLanguages
327
+ };
328
+ if (patch.classAttributes) acc.classAttributes = uniqueStrings(acc.classAttributes, patch.classAttributes);
329
+ if (patch.classFunctions) acc.classFunctions = uniqueStrings(acc.classFunctions, patch.classFunctions);
330
+ if (patch.experimental) acc.experimental = {
331
+ ...acc.experimental,
332
+ ...patch.experimental,
333
+ classRegex: mergeClassRegex(acc.experimental?.classRegex, patch.experimental.classRegex)
334
+ };
335
+ if (patch.files?.exclude) acc.files = { exclude: uniqueStrings(acc.files?.exclude, patch.files.exclude) };
336
+ if (patch.lint) acc.lint = {
337
+ ...acc.lint,
338
+ ...patch.lint
339
+ };
340
+ return acc;
341
+ }, {});
342
+ }
343
+ function uniqueStrings(...arrays) {
344
+ return [...new Set(arrays.flatMap((array) => array ?? []))];
345
+ }
346
+ function mergeClassRegex(current, next) {
347
+ if (!next) return current;
348
+ if (!current) return next;
349
+ const serialized = /* @__PURE__ */ new Set();
350
+ const merged = [];
351
+ for (const item of [...current, ...next]) {
352
+ const key = JSON.stringify(item);
353
+ if (serialized.has(key)) continue;
354
+ serialized.add(key);
355
+ merged.push(item);
356
+ }
357
+ return merged;
358
+ }
359
+ function mergeEditorSettings(defaultSettings, overrides) {
360
+ return {
361
+ ...defaultSettings,
362
+ tailwindCSS: {
363
+ ...defaultSettings.tailwindCSS,
364
+ ...overrides,
365
+ includeLanguages: {
366
+ ...defaultSettings.tailwindCSS.includeLanguages,
367
+ ...overrides.includeLanguages
368
+ },
369
+ classAttributes: uniqueStrings(defaultSettings.tailwindCSS.classAttributes, overrides.classAttributes),
370
+ classFunctions: uniqueStrings(defaultSettings.tailwindCSS.classFunctions, overrides.classFunctions),
371
+ files: { exclude: uniqueStrings(defaultSettings.tailwindCSS.files.exclude, overrides.files?.exclude) },
372
+ experimental: {
373
+ ...defaultSettings.tailwindCSS.experimental,
374
+ ...overrides.experimental,
375
+ classRegex: mergeClassRegex(defaultSettings.tailwindCSS.experimental.classRegex, overrides.experimental?.classRegex) ?? defaultSettings.tailwindCSS.experimental.classRegex
376
+ },
377
+ lint: {
378
+ ...defaultSettings.tailwindCSS.lint,
379
+ ...overrides.lint
380
+ }
381
+ }
382
+ };
383
+ }
384
+ //#endregion
209
385
  //#region src/adapters/editor-state-adapter.ts
210
386
  function isDirectory(filePath) {
211
387
  try {
@@ -215,7 +391,7 @@ function isDirectory(filePath) {
215
391
  }
216
392
  }
217
393
  function createEditorState(cwd) {
218
- const settings = {
394
+ const settings = mergeEditorSettings({
219
395
  editor: { tabSize: 2 },
220
396
  tailwindCSS: {
221
397
  validate: true,
@@ -264,7 +440,7 @@ function createEditorState(cwd) {
264
440
  suggestCanonicalClasses: "warning"
265
441
  }
266
442
  }
267
- };
443
+ }, loadWorkspaceTailwindSettings(cwd));
268
444
  return {
269
445
  connection: null,
270
446
  folder: cwd,
@@ -293,6 +469,7 @@ function createEditorState(cwd) {
293
469
  * Error thrown when adapter fails to load required modules
294
470
  */
295
471
  var AdapterLoadError = class extends Error {
472
+ version;
296
473
  constructor(version, cause) {
297
474
  super(`Failed to load ${version} adapter: ${cause.message}`);
298
475
  this.version = version;
@@ -366,37 +543,6 @@ function extractConfigMetadata(state) {
366
543
  if (config.corePlugins) state.corePlugins = Array.isArray(config.corePlugins) ? config.corePlugins : Object.keys(config.corePlugins);
367
544
  }
368
545
  //#endregion
369
- //#region src/utils/fs.ts
370
- function fileExists(filePath) {
371
- try {
372
- return node_fs.existsSync(filePath);
373
- } catch {
374
- return false;
375
- }
376
- }
377
- function readFileSync(filePath) {
378
- if (!filePath || typeof filePath !== "string") throw new TypeError("File path must be a non-empty string");
379
- return node_fs.readFileSync(filePath, "utf-8");
380
- }
381
- function writeFileSync(filePath, content) {
382
- if (!filePath || typeof filePath !== "string") throw new TypeError("File path must be a non-empty string");
383
- if (typeof content !== "string") throw new TypeError("Content must be a string");
384
- node_fs.writeFileSync(filePath, content, "utf-8");
385
- }
386
- function readGitignorePatterns(cwd) {
387
- const gitignorePath = node_path.join(cwd, ".gitignore");
388
- if (!fileExists(gitignorePath)) return [];
389
- try {
390
- return node_fs.readFileSync(gitignorePath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#") && !line.startsWith("!")).map((pattern) => {
391
- const cleaned = pattern.replace(/\/+$/, "");
392
- if (cleaned.includes("/") || cleaned.includes("*")) return cleaned.endsWith("/**") ? cleaned : `${cleaned}/**`;
393
- return `**/${cleaned}/**`;
394
- });
395
- } catch {
396
- return [];
397
- }
398
- }
399
- //#endregion
400
546
  //#region src/adapters/v4-adapter.ts
401
547
  const require$3 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href || __filename);
402
548
  async function loadV4DesignSystem(state, cwd, configPath, verbose = false) {
package/dist/linter.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_linter = require("./linter-ChZk2xMs.cjs");
2
+ const require_linter = require("./linter-BBFc8gnJ.cjs");
3
3
  exports.extractImportSourceDirectives = require_linter.extractImportSourceDirectives;
4
4
  exports.extractSourcePatterns = require_linter.extractSourcePatterns;
5
5
  exports.lint = require_linter.lint;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-lint",
3
- "version": "0.10.2",
3
+ "version": "0.11.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
  "cli",
@@ -59,23 +59,23 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@tailwindcss/language-service": "^0.14.29",
62
- "ansis": "^4.2.0",
62
+ "ansis": "^4.3.0",
63
63
  "commander": "^14.0.3",
64
- "postcss": "^8.5.10",
64
+ "postcss": "^8.5.15",
65
65
  "tinyglobby": "^0.2.16",
66
66
  "vscode-languageserver-textdocument": "^1.0.12"
67
67
  },
68
68
  "devDependencies": {
69
- "@types/node": "^25.6.0",
70
- "oxfmt": "^0.46.0",
71
- "oxlint": "^1.61.0",
72
- "tsdown": "^0.21.10",
69
+ "@types/node": "^25.9.1",
70
+ "oxfmt": "^0.51.0",
71
+ "oxlint": "^1.66.0",
72
+ "tsdown": "^0.22.0",
73
73
  "typescript": "^6.0.3",
74
- "vitest": "^4.1.5"
74
+ "vitest": "^4.1.7"
75
75
  },
76
76
  "engines": {
77
77
  "node": ">=22.0.0",
78
78
  "pnpm": ">=10.0.0"
79
79
  },
80
- "packageManager": "pnpm@10.33.2"
80
+ "packageManager": "pnpm@11.2.2"
81
81
  }