code-auditor-mcp 3.4.2 → 3.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +67 -0
  3. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
  4. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +67 -34
  5. package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
  6. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +9 -14
  7. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
  8. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +41 -56
  9. package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
  10. package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
  11. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +6 -0
  12. package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
  13. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +6 -0
  14. package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
  15. package/dist/analyzers/universal/UniversalStylesAnalyzer.js +44 -24
  16. package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
  17. package/dist/auditRunner.d.ts +4 -0
  18. package/dist/auditRunner.d.ts.map +1 -1
  19. package/dist/auditRunner.js +19 -8
  20. package/dist/auditRunner.js.map +1 -1
  21. package/dist/config/defaults.d.ts +0 -18
  22. package/dist/config/defaults.d.ts.map +1 -1
  23. package/dist/config/defaults.js +1 -19
  24. package/dist/config/defaults.js.map +1 -1
  25. package/dist/conventions/conventionMiner.d.ts +12 -0
  26. package/dist/conventions/conventionMiner.d.ts.map +1 -1
  27. package/dist/conventions/conventionMiner.js +13 -1
  28. package/dist/conventions/conventionMiner.js.map +1 -1
  29. package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
  30. package/dist/reporting/jsonReportGenerator.js +5 -0
  31. package/dist/reporting/jsonReportGenerator.js.map +1 -1
  32. package/dist/styles/styleExtractor.js +6 -3
  33. package/dist/styles/styleExtractor.js.map +1 -1
  34. package/dist/styles/tailwindProbe.d.ts +101 -0
  35. package/dist/styles/tailwindProbe.d.ts.map +1 -0
  36. package/dist/styles/tailwindProbe.js +637 -0
  37. package/dist/styles/tailwindProbe.js.map +1 -0
  38. package/dist/styles/tailwindUtilityExpander.d.ts +77 -53
  39. package/dist/styles/tailwindUtilityExpander.d.ts.map +1 -1
  40. package/dist/styles/tailwindUtilityExpander.js +146 -764
  41. package/dist/styles/tailwindUtilityExpander.js.map +1 -1
  42. package/dist/types.d.ts +5 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/package.json +1 -1
  46. package/plugin/.claude-plugin/plugin.json +1 -1
@@ -0,0 +1,637 @@
1
+ /**
2
+ * Tailwind Compile-Probe — Spec 22 R1.2
3
+ *
4
+ * Uses the project's own installed `tailwindcss` package as the oracle for
5
+ * class validation. Zero hand-curated dictionaries — the project's compiler
6
+ * IS the authority on what classes exist.
7
+ *
8
+ * **v4 (PRIMARY):** Uses `compile()` with `@apply` probe stylesheets.
9
+ * Candidate classes are injected into a generated CSS file, compiled, and
10
+ * checked for CSS output. Classes that produce declarations are valid.
11
+ *
12
+ * **v3 (FALLBACK):** Uses `resolveConfig()` to get the fully-resolved theme,
13
+ * then generates utility classes from the config. Theme values come from
14
+ * the project's config — the config IS the oracle.
15
+ *
16
+ * **Fail-open:** If tailwindcss can't be found, loaded, or compiled, the
17
+ * probe returns `ready=false`. The caller MUST disable the undefined-class
18
+ * detector — a claim that a class "does not exist" may not ship on a
19
+ * known-incomplete dictionary.
20
+ *
21
+ * @module tailwindProbe
22
+ */
23
+ import { existsSync } from 'node:fs';
24
+ import { join, dirname } from 'node:path';
25
+ import { createRequire } from 'node:module';
26
+ import { pathToFileURL } from 'node:url';
27
+ // ---------------------------------------------------------------------------
28
+ // Theme → utility-class generation (v3 fallback)
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Utility prefixes that consume theme.colors to produce classes like
32
+ * `bg-red-500`, `text-blue-100`, etc.
33
+ *
34
+ * These are NOT a dictionary — they're the documented structural mapping
35
+ * from Tailwind's theme keys to utility class name prefixes. This mapping
36
+ * is stable across Tailwind releases and is the minimum structure needed
37
+ * to generate classes from a resolved config.
38
+ */
39
+ const COLOR_UTILITY_PREFIXES = [
40
+ 'bg', 'text', 'border', 'ring', 'shadow', 'fill', 'stroke',
41
+ 'accent', 'caret', 'outline', 'placeholder',
42
+ 'divide', 'from', 'via', 'to', 'decoration',
43
+ ];
44
+ /**
45
+ * Utility prefixes that consume theme.spacing to produce classes like
46
+ * `p-4`, `m-2`, `gap-8`, etc.
47
+ */
48
+ const SPACING_UTILITY_PREFIXES = [
49
+ 'p', 'px', 'py', 'pt', 'pr', 'pb', 'pl',
50
+ 'm', 'mx', 'my', 'mt', 'mr', 'mb', 'ml',
51
+ 'w', 'min-w', 'max-w', 'h', 'min-h', 'max-h',
52
+ 'top', 'right', 'bottom', 'left',
53
+ 'inset', 'inset-x', 'inset-y',
54
+ 'gap', 'gap-x', 'gap-y',
55
+ 'space-x', 'space-y',
56
+ 'leading', 'indent',
57
+ 'scroll-m', 'scroll-mx', 'scroll-my', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml',
58
+ 'scroll-p', 'scroll-px', 'scroll-py', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl',
59
+ 'size',
60
+ ];
61
+ /** Prefixes that consume theme.fontSize. */
62
+ const FONT_SIZE_PREFIXES = ['text'];
63
+ /** Prefixes that consume theme.borderRadius. */
64
+ const RADIUS_PREFIXES = [
65
+ 'rounded', 'rounded-t', 'rounded-r', 'rounded-b', 'rounded-l',
66
+ 'rounded-tl', 'rounded-tr', 'rounded-br', 'rounded-bl',
67
+ 'rounded-s', 'rounded-e', 'rounded-ss', 'rounded-se', 'rounded-es', 'rounded-ee',
68
+ ];
69
+ // ---------------------------------------------------------------------------
70
+ // TailwindProbe
71
+ // ---------------------------------------------------------------------------
72
+ export class TailwindProbe {
73
+ validClasses = null;
74
+ _ready = false;
75
+ _failureReason = null;
76
+ _source = null;
77
+ projectRoot = '';
78
+ tailwindPath = null;
79
+ version = null;
80
+ /** Whether the probe successfully initialized and is ready to validate classes. */
81
+ get ready() {
82
+ return this._ready;
83
+ }
84
+ /** Why initialization failed, if it did. */
85
+ get failureReason() {
86
+ return this._failureReason;
87
+ }
88
+ /** Human-readable description of the validation source. */
89
+ get source() {
90
+ return this._source;
91
+ }
92
+ /**
93
+ * Initialize the probe by locating and loading the project's tailwindcss
94
+ * package. Tests compilation with a known-good class to verify the
95
+ * pipeline works end-to-end.
96
+ */
97
+ async init(projectRoot) {
98
+ this.projectRoot = projectRoot;
99
+ const twPath = this.findTailwindcss(projectRoot);
100
+ if (!twPath) {
101
+ this._failureReason = 'tailwindcss not found in project node_modules';
102
+ return { ok: false, error: this._failureReason };
103
+ }
104
+ this.tailwindPath = twPath;
105
+ // ── Try v4 first (ESM import + compile() API) ──
106
+ try {
107
+ const mod = await this.tryImportV4(twPath);
108
+ if (mod && typeof mod.compile === 'function') {
109
+ const result = await mod.compile(Buffer.from('@import "tailwindcss";\n.p0{@apply flex;}'), { base: projectRoot });
110
+ const output = typeof result === 'string' ? result : String(result);
111
+ if (output.includes('.p0') && /\{([^}]*[a-z])/.test(output)) {
112
+ this.version = 4;
113
+ this.validClasses = new Set();
114
+ this._ready = true;
115
+ this._source = 'v4-compile-probe';
116
+ return { ok: true, source: this._source };
117
+ }
118
+ }
119
+ }
120
+ catch {
121
+ // Not v4 — continue to v3
122
+ }
123
+ // ── Try v3 (CJS require + resolveConfig) ──
124
+ try {
125
+ const projectRequire = createRequire(join(projectRoot, 'package.json'));
126
+ const tw = projectRequire(twPath);
127
+ // v3 tailwindcss exports a function (the postcss plugin)
128
+ // It also has resolveConfig available
129
+ if (typeof tw === 'function' || (tw.default && typeof tw.default === 'function')) {
130
+ // Test resolveConfig availability
131
+ try {
132
+ const resolveConfig = projectRequire(join(twPath, 'resolveConfig'));
133
+ if (typeof resolveConfig === 'function') {
134
+ this.version = 3;
135
+ this.validClasses = null; // generated lazily from config
136
+ this._ready = true;
137
+ this._source = 'v3-config-generation';
138
+ return { ok: true, source: this._source };
139
+ }
140
+ }
141
+ catch {
142
+ // resolveConfig not available
143
+ }
144
+ }
145
+ }
146
+ catch {
147
+ // Neither v4 nor v3 loadable
148
+ }
149
+ this._failureReason = 'tailwindcss found but could not be loaded (neither v4 compile() nor v3 resolveConfig detected)';
150
+ return { ok: false, error: this._failureReason };
151
+ }
152
+ /**
153
+ * Check if a single class is known-valid from the cache only.
154
+ * Does NOT trigger a probe — use validateBatch() for that.
155
+ */
156
+ isCached(className) {
157
+ return this.validClasses?.has(className) ?? false;
158
+ }
159
+ /**
160
+ * Validate a batch of class names against the project's Tailwind compiler.
161
+ * Classes that produce CSS when @apply'd (v4) or are generated from the
162
+ * resolved config (v3) are considered valid.
163
+ *
164
+ * Returns the full Set of all known-valid classes (including previously
165
+ * cached ones). Unknown classes that don't validate are NOT added to the
166
+ * cache — callers should treat absence from the returned set as "not valid."
167
+ */
168
+ async validateBatch(candidates) {
169
+ if (!this._ready) {
170
+ throw new Error(this._failureReason ?? 'Probe not initialized');
171
+ }
172
+ if (this.version === 3) {
173
+ // v3: generate from config if not yet done, then check
174
+ if (!this.validClasses) {
175
+ this.validClasses = this.generateV3Classes();
176
+ }
177
+ for (const c of candidates) {
178
+ if (this.validClasses.has(c))
179
+ continue;
180
+ // For v3, we can probe individual unknowns via postcss if available,
181
+ // but that requires postcss to be installed. For now, config generation
182
+ // is comprehensive enough.
183
+ }
184
+ return this.validClasses;
185
+ }
186
+ // v4: batch-probe via @apply compilation
187
+ // Filter out already-known classes
188
+ const unknown = [...new Set(candidates)].filter(c => !this.validClasses.has(c));
189
+ if (unknown.length === 0)
190
+ return this.validClasses;
191
+ // Batch in groups of 200 to keep probe CSS manageable
192
+ const BATCH_SIZE = 200;
193
+ for (let i = 0; i < unknown.length; i += BATCH_SIZE) {
194
+ const batch = unknown.slice(i, i + BATCH_SIZE);
195
+ const valid = await this.probeV4Batch(batch);
196
+ for (const cls of valid) {
197
+ this.validClasses.add(cls);
198
+ }
199
+ }
200
+ return this.validClasses;
201
+ }
202
+ // -----------------------------------------------------------------------
203
+ // Private: v4 compile-probe
204
+ // -----------------------------------------------------------------------
205
+ /**
206
+ * Generate a CSS file with @apply probe selectors, compile it with
207
+ * Tailwind v4, and parse the output to determine which classes are valid.
208
+ */
209
+ async probeV4Batch(classes) {
210
+ // Escape backslashes in class names for CSS
211
+ const escapedClasses = classes.map(cls => cls.replace(/\\/g, '\\\\'));
212
+ // Build probe CSS: one selector per class with @apply
213
+ const rules = escapedClasses
214
+ .map((cls, i) => `.p${i}{@apply ${cls};}`)
215
+ .join('');
216
+ const css = `@import "tailwindcss";${rules}`;
217
+ try {
218
+ const mod = await this.tryImportV4(this.tailwindPath);
219
+ if (!mod || typeof mod.compile !== 'function')
220
+ return [];
221
+ const result = await mod.compile(Buffer.from(css), { base: this.projectRoot });
222
+ const output = typeof result === 'string' ? result : String(result);
223
+ return this.parseProbeOutput(output, classes);
224
+ }
225
+ catch {
226
+ // Compilation failed — return empty (treat all as invalid)
227
+ return [];
228
+ }
229
+ }
230
+ /**
231
+ * Parse compiled CSS output to find which probe selectors have actual
232
+ * CSS declarations. A probe selector with no declarations or only empty
233
+ * rules indicates an invalid/unknown class.
234
+ */
235
+ parseProbeOutput(output, classes) {
236
+ const valid = [];
237
+ for (let i = 0; i < classes.length; i++) {
238
+ // Find .pN{ ... } and check for non-whitespace declarations
239
+ const re = new RegExp(`\\.p${i}\\{([^}]*)\\}`, 's');
240
+ const m = re.exec(output);
241
+ if (m && m[1].trim().length > 0) {
242
+ valid.push(classes[i]);
243
+ }
244
+ }
245
+ return valid;
246
+ }
247
+ // -----------------------------------------------------------------------
248
+ // Private: v3 config-based generation
249
+ // -----------------------------------------------------------------------
250
+ /**
251
+ * Generate the full set of utility classes from the project's resolved
252
+ * Tailwind v3 config. Uses `resolveConfig()` to merge user config with
253
+ * core plugin defaults, then generates class names from theme scales.
254
+ *
255
+ * This IS oracle-based: the config defines what's valid, and we
256
+ * synthesize class names from it structurally. No hand-curated lists
257
+ * of colors, spacing values, font sizes, or border radii.
258
+ */
259
+ generateV3Classes() {
260
+ const classes = new Set();
261
+ try {
262
+ const { colors, spacing, fontSize, borderRadius } = this.loadV3ResolvedTheme();
263
+ // Color-based utilities: bg-{color}, text-{color}, etc.
264
+ const colorNames = Object.keys(colors);
265
+ for (const prefix of COLOR_UTILITY_PREFIXES) {
266
+ for (const name of colorNames) {
267
+ classes.add(`${prefix}-${name}`);
268
+ }
269
+ }
270
+ // Spacing-based utilities: p-{size}, m-{size}, etc.
271
+ const spacingValues = Object.keys(spacing);
272
+ for (const prefix of SPACING_UTILITY_PREFIXES) {
273
+ for (const value of spacingValues) {
274
+ classes.add(`${prefix}-${value}`);
275
+ }
276
+ }
277
+ // Special non-scale values for spacing-based prefixes
278
+ const spacingNonScale = ['auto', 'full', 'min', 'max', 'fit', 'screen', 'svh', 'dvh', 'lvh'];
279
+ for (const v of spacingNonScale) {
280
+ for (const prefix of ['w', 'min-w', 'max-w', 'h', 'min-h', 'max-h', 'size']) {
281
+ classes.add(`${prefix}-${v}`);
282
+ }
283
+ }
284
+ for (const prefix of ['m', 'mx', 'my', 'mt', 'mr', 'mb', 'ml']) {
285
+ classes.add(`${prefix}-auto`);
286
+ }
287
+ for (const prefix of ['top', 'right', 'bottom', 'left']) {
288
+ classes.add(`${prefix}-auto`);
289
+ classes.add(`${prefix}-full`);
290
+ for (const frac of ['1/2', '1/3', '2/3', '1/4', '3/4']) {
291
+ classes.add(`${prefix}-${frac}`);
292
+ }
293
+ }
294
+ for (const prefix of ['inset', 'inset-x', 'inset-y']) {
295
+ classes.add(`${prefix}-auto`);
296
+ classes.add(`${prefix}-full`);
297
+ for (const frac of ['1/2', '1/3', '2/3', '1/4', '3/4']) {
298
+ classes.add(`${prefix}-${frac}`);
299
+ }
300
+ }
301
+ // Font size utilities: text-{size}
302
+ for (const prefix of FONT_SIZE_PREFIXES) {
303
+ for (const sizeName of Object.keys(fontSize)) {
304
+ classes.add(`${prefix}-${sizeName}`);
305
+ }
306
+ }
307
+ // Border radius utilities: rounded-{radius}
308
+ for (const prefix of RADIUS_PREFIXES) {
309
+ for (const radiusName of Object.keys(borderRadius)) {
310
+ if (radiusName === 'DEFAULT' || radiusName === '') {
311
+ classes.add(prefix);
312
+ }
313
+ else {
314
+ classes.add(`${prefix}-${radiusName}`);
315
+ }
316
+ }
317
+ }
318
+ // ── Static utility classes that Tailwind provides regardless of theme ──
319
+ // These are the core, stable utility names from Tailwind's core plugins.
320
+ // Unlike theme-based utilities, these have fixed names not derived from
321
+ // config. BUT — they're stable, well-defined, and validated by the same
322
+ // Tailwind documentation that defines the config structure.
323
+ addStaticCoreUtilities(classes);
324
+ this._source = 'v3-config-generation';
325
+ }
326
+ catch {
327
+ this._failureReason = 'v3 resolveConfig failed to generate utilities';
328
+ this._ready = false;
329
+ }
330
+ return classes;
331
+ }
332
+ /**
333
+ * Load the fully-resolved Tailwind v3 theme using resolveConfig().
334
+ */
335
+ loadV3ResolvedTheme() {
336
+ const projectRequire = createRequire(join(this.projectRoot, 'package.json'));
337
+ const resolveConfig = projectRequire(join(this.tailwindPath, 'resolveConfig'));
338
+ // Try to load the project's tailwind.config
339
+ let userConfig = {};
340
+ const configCandidates = [
341
+ 'tailwind.config.js', 'tailwind.config.ts',
342
+ 'tailwind.config.cjs', 'tailwind.config.mjs',
343
+ ];
344
+ for (const candidate of configCandidates) {
345
+ const configPath = join(this.projectRoot, candidate);
346
+ if (existsSync(configPath)) {
347
+ try {
348
+ const cfg = projectRequire(configPath);
349
+ userConfig = cfg.default ?? cfg;
350
+ }
351
+ catch {
352
+ // Config exists but can't be loaded — use empty config
353
+ }
354
+ break;
355
+ }
356
+ }
357
+ const resolved = resolveConfig(userConfig);
358
+ const theme = (resolved.theme ?? {});
359
+ // Flatten color palette (resolvedConfig returns nested structure)
360
+ const colors = flattenThemeSection(theme.colors ?? {});
361
+ const spacing = flattenThemeSection(theme.spacing ?? {});
362
+ const fontSize = flattenThemeSection(theme.fontSize ?? {});
363
+ const borderRadius = flattenThemeSection(theme.borderRadius ?? {});
364
+ return { colors, spacing, fontSize, borderRadius };
365
+ }
366
+ // -----------------------------------------------------------------------
367
+ // Private: package discovery
368
+ // -----------------------------------------------------------------------
369
+ /**
370
+ * Locate tailwindcss in the project's node_modules, walking up directories.
371
+ */
372
+ findTailwindcss(projectRoot) {
373
+ let dir = projectRoot;
374
+ for (let i = 0; i < 20; i++) {
375
+ const pkgPath = join(dir, 'node_modules', 'tailwindcss');
376
+ if (existsSync(pkgPath)) {
377
+ return pkgPath;
378
+ }
379
+ const parent = dirname(dir);
380
+ if (parent === dir)
381
+ break;
382
+ dir = parent;
383
+ }
384
+ return null;
385
+ }
386
+ /**
387
+ * Dynamically import tailwindcss v4 (ESM package).
388
+ * Uses file:// URL for reliable resolution from the project's node_modules.
389
+ */
390
+ async tryImportV4(twPath) {
391
+ try {
392
+ // Try file:// URL first (reliable across platforms)
393
+ const packageJsonPath = join(twPath, 'package.json');
394
+ if (existsSync(packageJsonPath)) {
395
+ return await import(pathToFileURL(twPath).href);
396
+ }
397
+ }
398
+ catch {
399
+ // Fall through
400
+ }
401
+ try {
402
+ // Try importing by bare specifier from the project root context.
403
+ // tailwindcss is a dependency of the project being audited, not of
404
+ // code-auditor itself — ignore the TS resolution error.
405
+ // @ts-expect-error — tailwindcss is resolved at runtime from the audited project
406
+ return await import('tailwindcss');
407
+ }
408
+ catch {
409
+ return null;
410
+ }
411
+ }
412
+ }
413
+ // ---------------------------------------------------------------------------
414
+ // Helpers
415
+ // ---------------------------------------------------------------------------
416
+ /**
417
+ * Flatten a resolved Tailwind theme section for class name generation.
418
+ * Handles nested objects (e.g. colors: { blue: { 500: '#...' } })
419
+ * producing dotted keys (e.g. "blue-500").
420
+ *
421
+ * Uses hyphens for separators to match Tailwind CSS class naming.
422
+ */
423
+ function flattenThemeSection(obj) {
424
+ const result = {};
425
+ function walk(prefix, value) {
426
+ if (typeof value === 'string') {
427
+ result[prefix] = value;
428
+ }
429
+ else if (typeof value === 'object' && value !== null) {
430
+ for (const [key, val] of Object.entries(value)) {
431
+ if (key === 'DEFAULT') {
432
+ // DEFAULT key means the prefix itself is the value
433
+ result[prefix] = typeof val === 'string' ? val : String(val);
434
+ }
435
+ else {
436
+ const sep = prefix ? '-' : '';
437
+ walk(`${prefix}${sep}${key}`, val);
438
+ }
439
+ }
440
+ }
441
+ else if (typeof value === 'number') {
442
+ result[prefix] = String(value);
443
+ }
444
+ else if (typeof value === 'function') {
445
+ // Some v3 theme values are functions (e.g. spacing)
446
+ try {
447
+ const fnResult = value();
448
+ walk(prefix, fnResult);
449
+ }
450
+ catch {
451
+ // Skip uninvocable functions
452
+ }
453
+ }
454
+ }
455
+ for (const [key, val] of Object.entries(obj)) {
456
+ walk(key, val);
457
+ }
458
+ return result;
459
+ }
460
+ // ---------------------------------------------------------------------------
461
+ // Static core utilities (v3 fallback only)
462
+ // ---------------------------------------------------------------------------
463
+ /**
464
+ * Add static Tailwind utility classes that exist regardless of theme.
465
+ *
466
+ * These are the stable, well-defined utility class names from Tailwind's
467
+ * core plugins (display, flexbox, grid, positioning, etc.). They don't
468
+ * derive from theme values — they have fixed names.
469
+ *
470
+ * This is the minimum structure needed for v3 config-based generation.
471
+ * v4 compile-probe bypasses this entirely.
472
+ */
473
+ function addStaticCoreUtilities(classes) {
474
+ const core = [
475
+ // ── Display ──
476
+ 'block', 'inline-block', 'inline', 'flex', 'inline-flex', 'grid',
477
+ 'inline-grid', 'hidden', 'flow-root', 'contents', 'table', 'table-row',
478
+ 'table-cell', 'table-caption', 'table-column', 'table-column-group',
479
+ 'table-footer-group', 'table-header-group', 'table-row-group', 'list-item',
480
+ // ── Position ──
481
+ 'static', 'fixed', 'absolute', 'relative', 'sticky',
482
+ // ── Flexbox ──
483
+ 'flex-row', 'flex-row-reverse', 'flex-col', 'flex-col-reverse',
484
+ 'flex-wrap', 'flex-nowrap', 'flex-wrap-reverse',
485
+ 'flex-1', 'flex-auto', 'flex-initial', 'flex-none',
486
+ 'grow', 'grow-0', 'shrink', 'shrink-0',
487
+ 'flex-grow', 'flex-grow-0', 'flex-shrink', 'flex-shrink-0',
488
+ // ── Grid ──
489
+ 'grid-flow-row', 'grid-flow-col', 'grid-flow-dense', 'grid-flow-row-dense', 'grid-flow-col-dense',
490
+ 'grid-cols-none', 'grid-cols-subgrid',
491
+ 'grid-rows-none', 'grid-rows-subgrid',
492
+ 'auto-cols-auto', 'auto-cols-min', 'auto-cols-max', 'auto-cols-fr',
493
+ 'auto-rows-auto', 'auto-rows-min', 'auto-rows-max', 'auto-rows-fr',
494
+ // ── Alignment ──
495
+ 'items-start', 'items-end', 'items-center', 'items-baseline', 'items-stretch',
496
+ 'justify-start', 'justify-end', 'justify-center', 'justify-between',
497
+ 'justify-around', 'justify-evenly', 'justify-stretch', 'justify-normal',
498
+ 'justify-items-start', 'justify-items-end', 'justify-items-center', 'justify-items-stretch',
499
+ 'content-center', 'content-start', 'content-end', 'content-between',
500
+ 'content-around', 'content-evenly', 'content-baseline', 'content-normal', 'content-stretch',
501
+ 'place-content-center', 'place-content-start', 'place-content-end',
502
+ 'place-content-between', 'place-content-around', 'place-content-evenly',
503
+ 'place-items-center', 'place-items-start', 'place-items-end', 'place-items-stretch',
504
+ 'self-auto', 'self-start', 'self-end', 'self-center', 'self-stretch', 'self-baseline',
505
+ 'place-self-auto', 'place-self-start', 'place-self-end', 'place-self-center', 'place-self-stretch',
506
+ // ── Typography ──
507
+ 'text-left', 'text-center', 'text-right', 'text-justify', 'text-start', 'text-end',
508
+ 'underline', 'line-through', 'no-underline', 'overline',
509
+ 'decoration-solid', 'decoration-double', 'decoration-dotted', 'decoration-dashed', 'decoration-wavy',
510
+ 'uppercase', 'lowercase', 'capitalize', 'normal-case',
511
+ 'truncate', 'text-ellipsis', 'text-clip',
512
+ 'font-thin', 'font-extralight', 'font-light', 'font-normal', 'font-medium',
513
+ 'font-semibold', 'font-bold', 'font-extrabold', 'font-black',
514
+ 'italic', 'not-italic',
515
+ 'tracking-tighter', 'tracking-tight', 'tracking-normal',
516
+ 'tracking-wide', 'tracking-wider', 'tracking-widest',
517
+ 'leading-none', 'leading-tight', 'leading-snug', 'leading-normal', 'leading-relaxed', 'leading-loose',
518
+ 'break-normal', 'break-words', 'break-all', 'break-keep',
519
+ 'hyphens-none', 'hyphens-manual', 'hyphens-auto',
520
+ 'ordinal', 'slashed-zero', 'lining-nums', 'oldstyle-nums', 'proportional-nums',
521
+ 'tabular-nums', 'diagonal-fractions', 'stacked-fractions',
522
+ // ── Whitespace ──
523
+ 'whitespace-normal', 'whitespace-nowrap', 'whitespace-pre', 'whitespace-pre-line',
524
+ 'whitespace-pre-wrap', 'whitespace-break-spaces',
525
+ // ── Sizing ──
526
+ 'w-auto', 'w-full', 'w-screen', 'w-svw', 'w-dvw', 'w-lvw', 'w-min', 'w-max', 'w-fit',
527
+ 'h-auto', 'h-full', 'h-screen', 'h-svh', 'h-dvh', 'h-lvh', 'h-min', 'h-max', 'h-fit',
528
+ 'min-w-0', 'min-w-full', 'min-w-min', 'min-w-max', 'min-w-fit',
529
+ 'max-w-none', 'max-w-xs', 'max-w-sm', 'max-w-md', 'max-w-lg', 'max-w-xl',
530
+ 'max-w-2xl', 'max-w-3xl', 'max-w-4xl', 'max-w-5xl', 'max-w-6xl', 'max-w-7xl',
531
+ 'max-w-full', 'max-w-min', 'max-w-max', 'max-w-fit', 'max-w-prose',
532
+ 'min-h-0', 'min-h-full', 'min-h-screen', 'min-h-min', 'min-h-max', 'min-h-fit',
533
+ 'max-h-0', 'max-h-full', 'max-h-screen', 'max-h-min', 'max-h-max', 'max-h-fit',
534
+ 'size-auto', 'size-full', 'size-min', 'size-max', 'size-fit',
535
+ // ── Overflow ──
536
+ 'overflow-auto', 'overflow-hidden', 'overflow-visible', 'overflow-scroll',
537
+ 'overflow-x-auto', 'overflow-x-hidden', 'overflow-x-visible', 'overflow-x-scroll',
538
+ 'overflow-y-auto', 'overflow-y-hidden', 'overflow-y-visible', 'overflow-y-scroll',
539
+ // ── Visibility ──
540
+ 'visible', 'invisible', 'collapse',
541
+ // ── Borders ──
542
+ 'border-solid', 'border-dashed', 'border-dotted', 'border-double', 'border-hidden', 'border-none',
543
+ 'border-collapse', 'border-separate',
544
+ // ── Shadows ──
545
+ 'shadow-sm', 'shadow-md', 'shadow-lg', 'shadow-xl', 'shadow-2xl',
546
+ 'shadow-inner', 'shadow-none',
547
+ // ── Ring ──
548
+ 'ring-inset',
549
+ // ── Filters ──
550
+ 'blur-sm', 'blur-md', 'blur-lg', 'blur-xl', 'blur-2xl', 'blur-3xl', 'blur-none',
551
+ 'backdrop-blur-sm', 'backdrop-blur-md', 'backdrop-blur-lg',
552
+ 'backdrop-blur-xl', 'backdrop-blur-2xl', 'backdrop-blur-3xl', 'backdrop-blur-none',
553
+ // ── Transitions ──
554
+ 'transition-none', 'transition-all', 'transition', 'transition-colors',
555
+ 'transition-opacity', 'transition-shadow', 'transition-transform',
556
+ 'ease-linear', 'ease-in', 'ease-out', 'ease-in-out',
557
+ // ── Transforms ──
558
+ 'transform', 'transform-gpu', 'transform-none',
559
+ 'scale-0', 'scale-50', 'scale-75', 'scale-90', 'scale-95', 'scale-100',
560
+ 'scale-105', 'scale-110', 'scale-125', 'scale-150',
561
+ 'rotate-0', 'rotate-1', 'rotate-2', 'rotate-3', 'rotate-6', 'rotate-12',
562
+ 'rotate-45', 'rotate-90', 'rotate-180',
563
+ 'origin-center', 'origin-top', 'origin-top-right', 'origin-right',
564
+ 'origin-bottom-right', 'origin-bottom', 'origin-bottom-left', 'origin-left', 'origin-top-left',
565
+ // ── Interactivity ──
566
+ 'cursor-auto', 'cursor-default', 'cursor-pointer', 'cursor-wait', 'cursor-text',
567
+ 'cursor-move', 'cursor-help', 'cursor-not-allowed', 'cursor-none',
568
+ 'pointer-events-none', 'pointer-events-auto',
569
+ 'select-none', 'select-text', 'select-all', 'select-auto',
570
+ 'resize-none', 'resize', 'resize-y', 'resize-x',
571
+ // ── Screen readers ──
572
+ 'sr-only', 'not-sr-only',
573
+ // ── Object fit ──
574
+ 'object-contain', 'object-cover', 'object-fill', 'object-none', 'object-scale-down',
575
+ // ── Aspect ratio ──
576
+ 'aspect-auto', 'aspect-square', 'aspect-video',
577
+ // ── Animation ──
578
+ 'animate-none', 'animate-spin', 'animate-ping', 'animate-pulse', 'animate-bounce',
579
+ // ── Font family ──
580
+ 'font-sans', 'font-serif', 'font-mono',
581
+ // ── Box sizing ──
582
+ 'box-border', 'box-content',
583
+ // ── Container ──
584
+ 'container',
585
+ // ── Background ──
586
+ 'bg-auto', 'bg-cover', 'bg-contain',
587
+ 'bg-bottom', 'bg-center', 'bg-left', 'bg-left-bottom', 'bg-left-top',
588
+ 'bg-right', 'bg-right-bottom', 'bg-right-top', 'bg-top',
589
+ 'bg-fixed', 'bg-local', 'bg-scroll',
590
+ 'bg-no-repeat', 'bg-repeat', 'bg-repeat-x', 'bg-repeat-y', 'bg-repeat-round', 'bg-repeat-space',
591
+ 'bg-gradient-to-t', 'bg-gradient-to-tr', 'bg-gradient-to-r', 'bg-gradient-to-br',
592
+ 'bg-gradient-to-b', 'bg-gradient-to-bl', 'bg-gradient-to-l', 'bg-gradient-to-tl',
593
+ 'bg-origin-border', 'bg-origin-padding', 'bg-origin-content',
594
+ 'bg-clip-border', 'bg-clip-padding', 'bg-clip-content', 'bg-clip-text',
595
+ // ── Blend mode ──
596
+ 'mix-blend-normal', 'mix-blend-multiply', 'mix-blend-screen', 'mix-blend-overlay',
597
+ 'bg-blend-normal', 'bg-blend-multiply', 'bg-blend-screen', 'bg-blend-overlay',
598
+ // ── Table ──
599
+ 'table-auto', 'table-fixed',
600
+ 'caption-top', 'caption-bottom',
601
+ // ── Vertical align ──
602
+ 'align-baseline', 'align-top', 'align-middle', 'align-bottom',
603
+ 'align-text-top', 'align-text-bottom', 'align-sub', 'align-super',
604
+ // ── List style ──
605
+ 'list-none', 'list-disc', 'list-decimal',
606
+ 'list-inside', 'list-outside',
607
+ // ── Float / Clear ──
608
+ 'float-right', 'float-left', 'float-none', 'float-start', 'float-end',
609
+ 'clear-left', 'clear-right', 'clear-both', 'clear-none', 'clear-start', 'clear-end',
610
+ // ── Isolation ──
611
+ 'isolate', 'isolation-auto',
612
+ // ── Overscroll ──
613
+ 'overscroll-auto', 'overscroll-contain', 'overscroll-none',
614
+ // ── Scroll ──
615
+ 'snap-none', 'snap-x', 'snap-y', 'snap-both', 'snap-mandatory', 'snap-proximity',
616
+ 'scroll-auto', 'scroll-smooth',
617
+ // ── Appearance ──
618
+ 'appearance-none', 'appearance-auto',
619
+ // ── Touch ──
620
+ 'touch-auto', 'touch-none', 'touch-manipulation',
621
+ // ── Will change ──
622
+ 'will-change-auto', 'will-change-scroll', 'will-change-contents', 'will-change-transform',
623
+ // ── Content ──
624
+ 'content-none',
625
+ // ── Box decoration ──
626
+ 'decoration-slice', 'decoration-clone',
627
+ 'box-decoration-slice', 'box-decoration-clone',
628
+ // ── Line clamp ──
629
+ 'line-clamp-none',
630
+ // ── Outline ──
631
+ 'outline-none', 'outline', 'outline-dashed', 'outline-dotted', 'outline-double',
632
+ ];
633
+ for (const cls of core) {
634
+ classes.add(cls);
635
+ }
636
+ }
637
+ //# sourceMappingURL=tailwindProbe.js.map