pasika 0.10.118 → 0.10.119

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.
@@ -128,6 +128,7 @@ declare const tailwindRules: {
128
128
  "stylesheet-ordering": _eslint_css.CSSRuleDefinition;
129
129
  "custom-utility-apply": _eslint_css.CSSRuleDefinition;
130
130
  "utility-mapping": _eslint_css.CSSRuleDefinition;
131
+ "utility-name-parity": _eslint_css.CSSRuleDefinition;
131
132
  "css-entry-point": _eslint_css.CSSRuleDefinition;
132
133
  "feature-css-placement": _eslint_css.CSSRuleDefinition;
133
134
  "global-stylesheet": _eslint_css.CSSRuleDefinition;
@@ -168,6 +169,7 @@ declare const pasikaPlugin: {
168
169
  "stylesheet-ordering": _eslint_css.CSSRuleDefinition;
169
170
  "custom-utility-apply": _eslint_css.CSSRuleDefinition;
170
171
  "utility-mapping": _eslint_css.CSSRuleDefinition;
172
+ "utility-name-parity": _eslint_css.CSSRuleDefinition;
171
173
  "css-entry-point": _eslint_css.CSSRuleDefinition;
172
174
  "feature-css-placement": _eslint_css.CSSRuleDefinition;
173
175
  "global-stylesheet": _eslint_css.CSSRuleDefinition;
@@ -11200,30 +11200,29 @@ function themeCandidate(name, utilityText) {
11200
11200
  const property = arbitrary?.groups?.property ?? direct?.groups?.property;
11201
11201
  const matched = themeOperations.find((operation) => {
11202
11202
  if (property) return property === operation.property;
11203
- if (!name.startsWith(`${operation.prefix}-`) || name.length <= operation.prefix.length + 1) return false;
11204
11203
  if (typed?.groups?.kind !== operation.prefix) return false;
11205
11204
  const hint = typed.groups.hint;
11206
11205
  if (operation.prefix === "text") return hint === (operation.property === "font-size" ? "length:" : "color:");
11207
11206
  if (operation.prefix === "font") {
11208
11207
  return hint === (operation.property === "font-family" ? "family-name:" : "number:");
11209
11208
  }
11209
+ if (operation.prefix === "bg") {
11210
+ return hint === (operation.property === "background-image" ? "image:" : "color:");
11211
+ }
11212
+ if (["border", "outline", "decoration", "stroke"].includes(operation.prefix)) return hint === "color:";
11210
11213
  return hint === void 0;
11211
11214
  });
11212
11215
  if (!matched) return void 0;
11213
11216
  const value = arbitrary?.groups?.value?.trim() ?? direct?.groups?.value?.trim() ?? (typed?.groups?.variable ? `var(${typed.groups.variable})` : void 0);
11214
11217
  if (!value) return void 0;
11215
- const simple = /^-?(?:\d+(?:\.\d+)?|\.\d+)(?:px|rem|em|%|vh|vw|ch|deg)?$/u.test(value);
11216
- const variable = /^var\(--[a-z][a-z0-9-]*\)$/u.test(value);
11217
- const color = /^#[\da-f]{3,8}$/iu.test(value);
11218
- const keyword = /^[a-z][a-z-]*$/u.test(value);
11219
- const ratio = /^\d+\/\d+$/u.test(value);
11220
- if (!simple && !variable && !color && !keyword && !ratio) return void 0;
11221
- if (matched.property === "font-size" && value.startsWith("-")) return void 0;
11218
+ if (arbitrary && (/\\|["']|\burl\(/iu.test(value) || /var\(--[^)]*_/iu.test(value))) return void 0;
11219
+ const cssValue = arbitrary ? value.replaceAll("_", " ") : value;
11220
+ if (matched.property === "font-size" && cssValue.startsWith("-")) return void 0;
11222
11221
  const stem = name.startsWith(`${matched.prefix}-`) ? name.slice(matched.prefix.length + 1) : void 0;
11223
11222
  return {
11224
11223
  token: stem ? `--${matched.namespace}-${stem}` : "",
11225
11224
  property: matched.property,
11226
- value,
11225
+ value: cssValue,
11227
11226
  prefix: matched.prefix,
11228
11227
  namespace: matched.namespace
11229
11228
  };
@@ -11426,7 +11425,23 @@ var utilityMappingRule = {
11426
11425
  }
11427
11426
  for (const utility of utilities) {
11428
11427
  const name = preludeIdentifiers(utility)[0] ?? "unknown";
11429
- const candidate = themeCandidate(name, context.sourceCode.getText(utility));
11428
+ const source = context.sourceCode.getText(utility);
11429
+ const zIndex = /^@utility\s+[\w-]+\s*\{\s*@apply\s+\[z-index:(?<value>-?\d+|auto)\];?\s*\}$/u.exec(source)?.groups?.value;
11430
+ const numericZIndex = zIndex && zIndex !== "auto" ? Number(zIndex) : void 0;
11431
+ let nativeClass;
11432
+ if (zIndex === "auto") {
11433
+ nativeClass = "z-auto";
11434
+ } else if (numericZIndex !== void 0 && Number.isSafeInteger(numericZIndex)) {
11435
+ nativeClass = numericZIndex < 0 ? `-z-${String(-numericZIndex)}` : `z-${String(numericZIndex)}`;
11436
+ }
11437
+ if (nativeClass && zIndex) {
11438
+ context.report({
11439
+ node: utility,
11440
+ message: `Custom utility "${name}" duplicates built-in "${nativeClass}" (z-index: ${zIndex}); use "${nativeClass}" directly.`
11441
+ });
11442
+ continue;
11443
+ }
11444
+ const candidate = themeCandidate(name, source);
11430
11445
  const equivalent = candidate ? matchingThemeToken(candidate) : void 0;
11431
11446
  if (candidate && equivalent && nameCounts.get(name) === 1) {
11432
11447
  context.report({
@@ -11443,7 +11458,14 @@ var utilityMappingRule = {
11443
11458
  });
11444
11459
  continue;
11445
11460
  }
11446
- if (nameCounts.get(name) !== 1 || !candidate?.token) continue;
11461
+ if (nameCounts.get(name) !== 1 || !candidate) continue;
11462
+ if (!candidate.token) {
11463
+ context.report({
11464
+ node: utility,
11465
+ message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); define an @theme token in the "--${candidate.namespace}-*" namespace and use its generated "${candidate.prefix}-*" class instead.`
11466
+ });
11467
+ continue;
11468
+ }
11447
11469
  const tokenAlreadyDefined = themeTokens.has(candidate.token) || projectTokens.some((token) => token.name === candidate.token);
11448
11470
  if (tokenAlreadyDefined) continue;
11449
11471
  if (candidate.property === "font-size" && themeTokens.has(`--color-${name.slice(5)}`)) continue;
@@ -11505,6 +11527,180 @@ var utilityMappingRule = {
11505
11527
  }
11506
11528
  };
11507
11529
 
11530
+ // eslint/rules/tailwind/utility-name-parity.ts
11531
+ import { spawnSync } from "child_process";
11532
+ import { createHash } from "crypto";
11533
+ import { existsSync as existsSync12 } from "fs";
11534
+ import path78 from "path";
11535
+ import { generate as generate4, parse as parse7, toPlainObject as toPlainObject3 } from "@eslint/css-tree";
11536
+ function numericPart(value) {
11537
+ const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
11538
+ value
11539
+ );
11540
+ if (!match?.groups?.number) return void 0;
11541
+ const number = String(Number(match.groups.number)).replace(".", "p");
11542
+ const sign = match.groups.negative === "-" ? "neg-" : "";
11543
+ return sign + number + (match.groups.unit === "%" ? "pct" : match.groups.unit ?? "");
11544
+ }
11545
+ function readableValue(value) {
11546
+ const words = value.trim().replace(/,/gu, "_comma_").split(/[_\s]+/u).filter(Boolean);
11547
+ if (words.length === 0 || words.length > 8) return void 0;
11548
+ const parts = [];
11549
+ for (const word of words) {
11550
+ const numeric = numericPart(word);
11551
+ if (numeric) {
11552
+ parts.push(numeric);
11553
+ continue;
11554
+ }
11555
+ const hex = /^#(?<color>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(word)?.groups?.color;
11556
+ if (hex) {
11557
+ parts.push("hex", hex.toLowerCase());
11558
+ continue;
11559
+ }
11560
+ const variable = /^var\(--(?<name>[a-z][a-z0-9-]*)\)$/u.exec(word)?.groups?.name;
11561
+ if (variable) {
11562
+ parts.push("var", variable);
11563
+ continue;
11564
+ }
11565
+ if (/^[a-z][a-z0-9-]*$/iu.test(word)) {
11566
+ parts.push(word.toLowerCase());
11567
+ continue;
11568
+ }
11569
+ return void 0;
11570
+ }
11571
+ const slug = parts.join("-");
11572
+ return slug.length <= 70 ? slug : void 0;
11573
+ }
11574
+ function compoundValue(value) {
11575
+ const readable = readableValue(value);
11576
+ if (readable) return readable;
11577
+ const candidate = /^(?<fn>[a-z][a-z0-9-]*)\(/iu.exec(value.trim())?.groups?.fn?.toLowerCase();
11578
+ const hint = candidate?.endsWith("-") ? void 0 : candidate;
11579
+ const digest = createHash("sha256").update(value.trim()).digest("hex").slice(0, 12);
11580
+ return [hint, "hash", digest].filter(Boolean).join("-");
11581
+ }
11582
+ var TAILWIND_WORKER = String.raw`
11583
+ import { readFileSync } from "node:fs";
11584
+ import { compile } from "tailwindcss";
11585
+ const applies = JSON.parse(readFileSync(0, "utf8"));
11586
+ const results = [];
11587
+ for (const [index, apply] of applies.entries()) {
11588
+ const name = "pasika-probe-" + index;
11589
+ try {
11590
+ const compiler = await compile("@tailwind utilities; @utility " + name + " { " + apply + " }");
11591
+ results.push({ css: compiler.build([name]) });
11592
+ } catch (error) {
11593
+ results.push({ error: String(error instanceof Error ? error.message : error) });
11594
+ }
11595
+ }
11596
+ process.stdout.write(JSON.stringify(results));
11597
+ `;
11598
+ var compilerCache = /* @__PURE__ */ new Map();
11599
+ function isCompiledResult(value) {
11600
+ if (typeof value !== "object" || value === null) return false;
11601
+ return "css" in value && typeof value.css === "string" || "error" in value && typeof value.error === "string";
11602
+ }
11603
+ function compileApplies(applies, cwd) {
11604
+ const key = `${cwd}\0${JSON.stringify(applies)}`;
11605
+ const cached = compilerCache.get(key);
11606
+ if (cached) return cached;
11607
+ const child = spawnSync(process.execPath, ["--input-type=module", "--eval", TAILWIND_WORKER], {
11608
+ cwd,
11609
+ input: JSON.stringify(applies),
11610
+ encoding: "utf8",
11611
+ timeout: 3e4,
11612
+ maxBuffer: 8 * 1024 * 1024,
11613
+ windowsHide: true
11614
+ });
11615
+ let results;
11616
+ if (child.error || child.status !== 0) {
11617
+ const reason = child.error?.message ?? (child.stderr.trim() || "Tailwind compilation failed");
11618
+ results = applies.map(() => ({ error: reason }));
11619
+ } else {
11620
+ try {
11621
+ const parsed = JSON.parse(child.stdout);
11622
+ if (!Array.isArray(parsed)) throw new Error("Unexpected Tailwind output");
11623
+ const values = parsed;
11624
+ results = values.filter(isCompiledResult);
11625
+ if (results.length !== applies.length) throw new Error("Unexpected Tailwind output");
11626
+ } catch {
11627
+ results = applies.map(() => ({ error: "Invalid Tailwind compiler response" }));
11628
+ }
11629
+ }
11630
+ compilerCache.set(key, results);
11631
+ return results;
11632
+ }
11633
+ function compiledOperation(compiled, index) {
11634
+ if (!compiled.css) return void 0;
11635
+ const sheet = toPlainObject3(parse7(compiled.css, { parseValue: false }));
11636
+ const probe = rules(sheet).find((candidate) => selectorNames(candidate).includes(`pasika-probe-${String(index)}`));
11637
+ if (!probe) return void 0;
11638
+ const declarations = blockChildren2(probe).filter(
11639
+ (child) => child.type === "Declaration" && !child.property.startsWith("--tw-")
11640
+ );
11641
+ if (declarations.length !== 1) return void 0;
11642
+ const declaration = declarations[0];
11643
+ if (declaration?.type !== "Declaration") return void 0;
11644
+ return { property: declaration.property, value: generate4(declaration.value).trim() };
11645
+ }
11646
+ function expectedName(operation) {
11647
+ const value = compoundValue(operation.value);
11648
+ const property = operation.property.replace(/^-+/u, "").replace(/^background-/u, "bg-");
11649
+ return `${property}-${value}`;
11650
+ }
11651
+ function singleApply(utility, textOf) {
11652
+ const children = blockChildren2(utility);
11653
+ if (children.length !== 1) return void 0;
11654
+ const child = children[0];
11655
+ if (child?.type !== "Atrule" || child.name !== "apply") return void 0;
11656
+ return textOf(child);
11657
+ }
11658
+ var utilityNameParityRule = {
11659
+ meta: {
11660
+ schema: [],
11661
+ type: "problem",
11662
+ docs: {
11663
+ description: "Require single-operation custom utilities to have deterministic property/value-derived names."
11664
+ }
11665
+ },
11666
+ create(context) {
11667
+ return {
11668
+ "StyleSheet:exit"(node) {
11669
+ const candidates = atrulesNamed(node, "utility").flatMap((utility) => {
11670
+ const name = preludeIdentifiers(utility)[0];
11671
+ if (!name || name.endsWith("-*")) return [];
11672
+ const apply = singleApply(utility, (child) => context.sourceCode.getText(child));
11673
+ return apply ? [{ utility, name, apply }] : [];
11674
+ });
11675
+ if (candidates.length === 0) return;
11676
+ const physicalDir = path78.dirname(context.physicalFilename);
11677
+ const cwd = path78.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11678
+ const compiled = compileApplies(
11679
+ candidates.map((candidate) => candidate.apply),
11680
+ cwd
11681
+ );
11682
+ for (const [index, candidate] of candidates.entries()) {
11683
+ const result = compiled[index];
11684
+ const operation = result ? compiledOperation(result, index) : void 0;
11685
+ if (!operation) {
11686
+ context.report({
11687
+ node: candidate.utility,
11688
+ message: `Custom utility "${candidate.name}" applies "${candidate.apply}", but Tailwind cannot resolve exactly one CSS property${result?.error ? `: ${result.error}` : ""}; use an explicit [property:value] @apply mapping instead.`
11689
+ });
11690
+ continue;
11691
+ }
11692
+ const expected = expectedName(operation);
11693
+ if (candidate.name === expected) continue;
11694
+ context.report({
11695
+ node: candidate.utility,
11696
+ message: `Custom utility "${candidate.name}" maps ${operation.property}: ${operation.value}; rename it "${expected}" to preserve property/value parity.`
11697
+ });
11698
+ }
11699
+ }
11700
+ };
11701
+ }
11702
+ };
11703
+
11508
11704
  // eslint/rules/tailwind/index.ts
11509
11705
  var tailwindRules = {
11510
11706
  "theme-reset": themeResetRule,
@@ -11515,6 +11711,7 @@ var tailwindRules = {
11515
11711
  "stylesheet-ordering": stylesheetOrderingRule,
11516
11712
  "custom-utility-apply": customUtilityApplyRule,
11517
11713
  "utility-mapping": utilityMappingRule,
11714
+ "utility-name-parity": utilityNameParityRule,
11518
11715
  "css-entry-point": cssEntryPointRule,
11519
11716
  "feature-css-placement": featureCssPlacementRule,
11520
11717
  "global-stylesheet": globalStylesheetRule,
@@ -11526,7 +11723,7 @@ var tailwindRules = {
11526
11723
  };
11527
11724
 
11528
11725
  // eslint/rules/type-extraction.ts
11529
- import path78 from "path";
11726
+ import path79 from "path";
11530
11727
  var typeExtractionRule = {
11531
11728
  meta: {
11532
11729
  schema: [],
@@ -11537,7 +11734,7 @@ var typeExtractionRule = {
11537
11734
  },
11538
11735
  create(context) {
11539
11736
  const sourceRoot = sourceRootOf(context);
11540
- const file = path78.resolve(context.filename);
11737
+ const file = path79.resolve(context.filename);
11541
11738
  const segments = segmentsOf(file, sourceRoot);
11542
11739
  if (segments.length === 0) return {};
11543
11740
  const index = getProjectIndex(sourceRoot);
@@ -11676,9 +11873,9 @@ var uiStateRule = {
11676
11873
  };
11677
11874
 
11678
11875
  // eslint/rules/unknown-utility.ts
11679
- import { existsSync as existsSync12, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
11876
+ import { existsSync as existsSync13, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
11680
11877
  import { createRequire } from "module";
11681
- import path79 from "path";
11878
+ import path80 from "path";
11682
11879
  var PREFIX_NAMESPACES = {
11683
11880
  bg: ["color", "background-image"],
11684
11881
  text: ["color", "text"],
@@ -11959,7 +12156,7 @@ function stylesheetFiles(dir) {
11959
12156
  }
11960
12157
  return entries.flatMap((entry) => {
11961
12158
  if (entry.startsWith(".") || entry === "node_modules") return [];
11962
- const entryPath = path79.join(dir, entry);
12159
+ const entryPath = path80.join(dir, entry);
11963
12160
  let stats;
11964
12161
  try {
11965
12162
  stats = statSync6(entryPath);
@@ -11967,7 +12164,7 @@ function stylesheetFiles(dir) {
11967
12164
  return [];
11968
12165
  }
11969
12166
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
11970
- return path79.extname(entry) === ".css" ? [entryPath] : [];
12167
+ return path80.extname(entry) === ".css" ? [entryPath] : [];
11971
12168
  });
11972
12169
  }
11973
12170
  function packageNameOf(specifier) {
@@ -11978,24 +12175,24 @@ function packageNameOf(specifier) {
11978
12175
  function resolvePackageStylesheet(fromFile, specifier) {
11979
12176
  const packageName = packageNameOf(specifier);
11980
12177
  if (!packageName || packageName === "tailwindcss") return void 0;
11981
- let directory = path79.dirname(fromFile);
11982
- while (directory !== path79.dirname(directory)) {
11983
- const packageRoot = path79.join(directory, "node_modules", packageName);
11984
- const manifestPath = path79.join(packageRoot, "package.json");
11985
- if (existsSync12(manifestPath)) {
12178
+ let directory = path80.dirname(fromFile);
12179
+ while (directory !== path80.dirname(directory)) {
12180
+ const packageRoot = path80.join(directory, "node_modules", packageName);
12181
+ const manifestPath = path80.join(packageRoot, "package.json");
12182
+ if (existsSync13(manifestPath)) {
11986
12183
  try {
11987
12184
  const manifest = readFileSync15(manifestPath, "utf8");
11988
12185
  const stylesheet = /"style"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
11989
12186
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
11990
12187
  const target = stylesheet ?? main;
11991
12188
  if (!target) return void 0;
11992
- const resolved = path79.resolve(packageRoot, target);
11993
- return existsSync12(resolved) ? resolved : void 0;
12189
+ const resolved = path80.resolve(packageRoot, target);
12190
+ return existsSync13(resolved) ? resolved : void 0;
11994
12191
  } catch {
11995
12192
  return void 0;
11996
12193
  }
11997
12194
  }
11998
- directory = path79.dirname(directory);
12195
+ directory = path80.dirname(directory);
11999
12196
  }
12000
12197
  return void 0;
12001
12198
  }
@@ -12255,7 +12452,7 @@ var unknownUtilityRule = {
12255
12452
  };
12256
12453
 
12257
12454
  // eslint/rules/util-file-name.ts
12258
- import path80 from "path";
12455
+ import path81 from "path";
12259
12456
  function toKebabCase2(value) {
12260
12457
  return value.replace(/(?<lower>[a-z0-9])(?<upper>[A-Z])/g, "$<lower>-$<upper>").replace(/(?<first>[A-Z])(?<rest>[A-Z][a-z])/g, "$<first>-$<rest>").toLowerCase();
12261
12458
  }
@@ -12268,7 +12465,7 @@ var utilFileNameRule = {
12268
12465
  }
12269
12466
  },
12270
12467
  create(context) {
12271
- const filename = path80.resolve(context.filename);
12468
+ const filename = path81.resolve(context.filename);
12272
12469
  const segments = filename.replace(/\\/g, "/").split("/");
12273
12470
  if (!segments.includes("utils")) return {};
12274
12471
  let module;
@@ -12282,13 +12479,13 @@ var utilFileNameRule = {
12282
12479
  const functionName = functions[0]?.name;
12283
12480
  if (!functionName) return {};
12284
12481
  const expected = toKebabCase2(functionName);
12285
- const actual = path80.basename(filename, path80.extname(filename));
12482
+ const actual = path81.basename(filename, path81.extname(filename));
12286
12483
  if (!expected || actual === expected) return {};
12287
12484
  return {
12288
12485
  Program(node) {
12289
12486
  context.report({
12290
12487
  node,
12291
- message: `A utility file exporting ${functionName} must be named ${expected}.${path80.extname(filename).slice(1)}.`
12488
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path81.extname(filename).slice(1)}.`
12292
12489
  });
12293
12490
  }
12294
12491
  };
@@ -12296,7 +12493,7 @@ var utilFileNameRule = {
12296
12493
  };
12297
12494
 
12298
12495
  // eslint/rules/value-extraction.ts
12299
- import path81 from "path";
12496
+ import path82 from "path";
12300
12497
  var valueExtractionRule = {
12301
12498
  meta: {
12302
12499
  schema: [],
@@ -12307,7 +12504,7 @@ var valueExtractionRule = {
12307
12504
  },
12308
12505
  create(context) {
12309
12506
  const sourceRoot = sourceRootOf(context);
12310
- const file = path81.resolve(context.filename);
12507
+ const file = path82.resolve(context.filename);
12311
12508
  const segments = segmentsOf(file, sourceRoot);
12312
12509
  if (segments.length === 0 || segments[0] !== "app") return {};
12313
12510
  const index = getProjectIndex(sourceRoot);
@@ -12328,8 +12525,8 @@ var valueExtractionRule = {
12328
12525
  };
12329
12526
 
12330
12527
  // eslint/rules/vulyk/tracked-docs.ts
12331
- import { existsSync as existsSync13, readFileSync as readFileSync16 } from "fs";
12332
- import path82 from "path";
12528
+ import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
12529
+ import path83 from "path";
12333
12530
  var PASIKA_REPO = "Bredansky/pasika";
12334
12531
  var BASE_REQUIRED_TRACKED_DOCS = [
12335
12532
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -12362,9 +12559,9 @@ var trackedDocsRule = {
12362
12559
  if (!context.filename.endsWith("package.json")) return;
12363
12560
  const root = node.body;
12364
12561
  if (root.type !== "Object") return;
12365
- const projectRoot = path82.dirname(path82.resolve(context.filename));
12366
- const configPath = path82.join(projectRoot, "vulyk.config.ts");
12367
- if (!existsSync13(configPath)) {
12562
+ const projectRoot = path83.dirname(path83.resolve(context.filename));
12563
+ const configPath = path83.join(projectRoot, "vulyk.config.ts");
12564
+ if (!existsSync14(configPath)) {
12368
12565
  context.report({
12369
12566
  node,
12370
12567
  message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's required tracked docs."
@@ -12388,8 +12585,8 @@ var trackedDocsRule = {
12388
12585
  });
12389
12586
  }
12390
12587
  }
12391
- const agentsPath = path82.join(projectRoot, "AGENTS.md");
12392
- if (!existsSync13(agentsPath)) {
12588
+ const agentsPath = path83.join(projectRoot, "AGENTS.md");
12589
+ if (!existsSync14(agentsPath)) {
12393
12590
  context.report({
12394
12591
  node,
12395
12592
  message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
@@ -12488,7 +12685,7 @@ var withResponseHelperRule = {
12488
12685
 
12489
12686
  // eslint/rules/zirka-baseline.ts
12490
12687
  import fs7 from "fs";
12491
- import path83 from "path";
12688
+ import path84 from "path";
12492
12689
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
12493
12690
  var PRETTIER_CONFIGS = [
12494
12691
  "prettier.config.mjs",
@@ -12507,10 +12704,10 @@ var zirkaBaselineRule = {
12507
12704
  }
12508
12705
  },
12509
12706
  create(context) {
12510
- const filename = path83.resolve(context.filename);
12511
- const basename = path83.basename(filename);
12707
+ const filename = path84.resolve(context.filename);
12708
+ const basename = path84.basename(filename);
12512
12709
  if (!ESLINT_CONFIG.test(basename)) return {};
12513
- const projectRoot = path83.dirname(filename);
12710
+ const projectRoot = path84.dirname(filename);
12514
12711
  const report3 = (message) => {
12515
12712
  context.report({
12516
12713
  node: context.sourceCode.ast,
@@ -12525,7 +12722,7 @@ var zirkaBaselineRule = {
12525
12722
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
12526
12723
  );
12527
12724
  }
12528
- const tsconfigPath = path83.join(projectRoot, "tsconfig.json");
12725
+ const tsconfigPath = path84.join(projectRoot, "tsconfig.json");
12529
12726
  if (!fs7.existsSync(tsconfigPath)) {
12530
12727
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
12531
12728
  } else {
@@ -12543,13 +12740,13 @@ var zirkaBaselineRule = {
12543
12740
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
12544
12741
  }
12545
12742
  }
12546
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path83.join(projectRoot, name)));
12743
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path84.join(projectRoot, name)));
12547
12744
  if (!prettierConfigFile) {
12548
12745
  report3(
12549
12746
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
12550
12747
  );
12551
12748
  } else {
12552
- const content = fs7.readFileSync(path83.join(projectRoot, prettierConfigFile), "utf8");
12749
+ const content = fs7.readFileSync(path84.join(projectRoot, prettierConfigFile), "utf8");
12553
12750
  if (!content.includes("zirka")) {
12554
12751
  report3(
12555
12752
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -12885,7 +13082,7 @@ var tailwindStructureRules = {
12885
13082
  languageOptions: { tolerant: true },
12886
13083
  rules: Object.fromEntries(
12887
13084
  tailwindRuleIds.filter(
12888
- (id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
13085
+ (id) => id !== "pasika/css-entry-point" && id !== "pasika/feature-css-placement" && id !== "pasika/unique-css-definition" && id !== "pasika/utility-mapping" && id !== "pasika/utility-name-parity" && id !== "pasika/no-utility-alias" && id !== "pasika/root-variables" && id !== "pasika/color-role-usage"
12889
13086
  ).map((id) => [id, "error"])
12890
13087
  )
12891
13088
  };
@@ -12903,6 +13100,7 @@ var tailwindImportGraph = {
12903
13100
  "pasika/unique-css-definition": "error",
12904
13101
  "pasika/unique-css-token-value": "error",
12905
13102
  "pasika/utility-mapping": "error",
13103
+ "pasika/utility-name-parity": "error",
12906
13104
  "pasika/no-utility-alias": "error",
12907
13105
  "pasika/root-variables": "error",
12908
13106
  "pasika/color-role-usage": "error"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.118",
3
+ "version": "0.10.119",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",
@@ -90,6 +90,7 @@
90
90
  "next": "16.3.5",
91
91
  "prettier": "3.8.1",
92
92
  "tailwind-merge": "3.7.0",
93
+ "tailwindcss": "4.3.3",
93
94
  "tsup": "8.5.1",
94
95
  "tsx": "4.23.12",
95
96
  "typescript": "6.0.3",
@@ -105,6 +106,7 @@
105
106
  "clsx": ">=2.0.0",
106
107
  "next": ">=15.0.0",
107
108
  "tailwind-merge": ">=3.0.0",
109
+ "tailwindcss": "^4.0.0",
108
110
  "zod": ">=4.0.0"
109
111
  },
110
112
  "peerDependenciesMeta": {
@@ -117,6 +119,9 @@
117
119
  "tailwind-merge": {
118
120
  "optional": true
119
121
  },
122
+ "tailwindcss": {
123
+ "optional": true
124
+ },
120
125
  "zod": {
121
126
  "optional": true
122
127
  }