pasika 0.10.121 → 0.10.122

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.
@@ -136,7 +136,6 @@ declare const tailwindRules: {
136
136
  "unique-css-definition": _eslint_css.CSSRuleDefinition;
137
137
  "unique-css-token-value": _eslint_css.CSSRuleDefinition;
138
138
  "no-utility-alias": _eslint_css.CSSRuleDefinition;
139
- "global-selector-styling": _eslint_css.CSSRuleDefinition;
140
139
  };
141
140
 
142
141
  declare const vulykRules: {
@@ -177,7 +176,6 @@ declare const pasikaPlugin: {
177
176
  "unique-css-definition": _eslint_css.CSSRuleDefinition;
178
177
  "unique-css-token-value": _eslint_css.CSSRuleDefinition;
179
178
  "no-utility-alias": _eslint_css.CSSRuleDefinition;
180
- "global-selector-styling": _eslint_css.CSSRuleDefinition;
181
179
  "doc-kind-suffix": _eslint_markdown.MarkdownRuleDefinition;
182
180
  "title-matches-file-name": _eslint_markdown.MarkdownRuleDefinition;
183
181
  overview: _eslint_markdown.MarkdownRuleDefinition;
@@ -9671,17 +9671,19 @@ function selectorNames(node) {
9671
9671
  }
9672
9672
 
9673
9673
  // eslint/rules/tailwind/apply-usage.ts
9674
- function reportRawDeclarations(context, rule) {
9674
+ function reportRawDeclarations(context, rule, insideBase) {
9675
9675
  for (const child of blockChildren2(rule)) {
9676
9676
  if (child.type === "Declaration") {
9677
- if (child.property.startsWith("--")) continue;
9677
+ if (!insideBase && child.property.startsWith("--")) continue;
9678
9678
  context.report({
9679
9679
  node: child,
9680
- message: `Style declaration "${child.property}" inside a global selector must use @apply.`
9680
+ message: insideBase ? `Global selectors inside @layer base may only contain @apply directives; found "${child.property}".` : `Style declaration "${child.property}" inside a global selector must use @apply.`
9681
9681
  });
9682
9682
  continue;
9683
9683
  }
9684
- if (child.type === "Rule") reportRawDeclarations(context, child);
9684
+ if (child.type === "Rule" || child.type === "Atrule" && child.name !== "apply") {
9685
+ reportRawDeclarations(context, child, insideBase);
9686
+ }
9685
9687
  }
9686
9688
  }
9687
9689
  var applyUsageRule = {
@@ -9689,19 +9691,25 @@ var applyUsageRule = {
9689
9691
  schema: [],
9690
9692
  type: "problem",
9691
9693
  docs: {
9692
- description: "Require @apply for project style declarations inside global selectors."
9694
+ description: "Require only @apply directives in global selectors inside @layer base."
9693
9695
  }
9694
9696
  },
9695
9697
  create(context) {
9696
9698
  return {
9697
9699
  "StyleSheet:exit"(node) {
9698
- for (const child of node.children) {
9699
- if (child.type === "Rule") reportRawDeclarations(context, child);
9700
- if (child.type !== "Atrule" || child.name !== "layer") continue;
9701
- for (const layered of blockChildren2(child)) {
9702
- if (layered.type === "Rule") reportRawDeclarations(context, layered);
9700
+ function visit(current, insideBase = false) {
9701
+ if (current.type === "Atrule" && ["theme", "utility", "keyframes"].includes(current.name)) return;
9702
+ if (current.type === "Rule") {
9703
+ reportRawDeclarations(context, current, insideBase);
9704
+ return;
9705
+ }
9706
+ const inBaseLayer = insideBase || current.type === "Atrule" && current.name === "layer" && preludeIdentifiers(current).includes("base");
9707
+ const children = current.type === "StyleSheet" ? current.children : blockChildren2(current);
9708
+ for (const child of children) {
9709
+ if (child.type === "Rule" || child.type === "Atrule") visit(child, inBaseLayer);
9703
9710
  }
9704
9711
  }
9712
+ visit(node);
9705
9713
  }
9706
9714
  };
9707
9715
  }
@@ -9767,10 +9775,6 @@ function importedSpecifiers(text) {
9767
9775
  (match) => match.groups?.spec ?? ""
9768
9776
  );
9769
9777
  }
9770
- function moduleImports(text, fileName) {
9771
- const escaped = fileName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9772
- return new RegExp(`(?:import|require)\\s*\\(?\\s*["'][^"']*${escaped}["']`, "i").test(text);
9773
- }
9774
9778
  function resolveSpecifier2(fromFile, spec, sourceRoot) {
9775
9779
  if (spec.startsWith("/")) return path65.resolve(spec);
9776
9780
  if (spec.startsWith("./") || spec.startsWith("../")) return path65.resolve(path65.dirname(fromFile), spec);
@@ -9781,22 +9785,6 @@ function buildStylesheetGraph(options) {
9781
9785
  const { cssFiles, sourceRoot, textOf } = options;
9782
9786
  const cssSet = new Set(cssFiles.map((file) => path65.normalize(file)));
9783
9787
  const globals = cssFiles.filter((file) => registersTailwind(textOf(file)));
9784
- const reachable = /* @__PURE__ */ new Set();
9785
- const queue = [...globals];
9786
- for (const global of globals) reachable.add(path65.normalize(global));
9787
- while (queue.length > 0) {
9788
- const from = queue.shift();
9789
- if (!from) continue;
9790
- for (const spec of importedSpecifiers(textOf(from))) {
9791
- const target = resolveSpecifier2(from, spec, sourceRoot);
9792
- if (!target) continue;
9793
- const normalized = path65.normalize(target);
9794
- if (cssSet.has(normalized) && !reachable.has(normalized)) {
9795
- reachable.add(normalized);
9796
- queue.push(normalized);
9797
- }
9798
- }
9799
- }
9800
9788
  const directChildren = /* @__PURE__ */ new Set();
9801
9789
  for (const global of globals) {
9802
9790
  for (const spec of importedSpecifiers(textOf(global))) {
@@ -9806,7 +9794,7 @@ function buildStylesheetGraph(options) {
9806
9794
  if (cssSet.has(normalized)) directChildren.add(normalized);
9807
9795
  }
9808
9796
  }
9809
- return { globals, reachable, directChildren };
9797
+ return { globals, directChildren };
9810
9798
  }
9811
9799
 
9812
9800
  // eslint/rules/tailwind/base-layer-pair.ts
@@ -9945,7 +9933,7 @@ var cssEntryPointRule = {
9945
9933
  schema: [],
9946
9934
  type: "problem",
9947
9935
  docs: {
9948
- description: "Require the app/styles CSS root, one global entry point, and direct project-CSS imports."
9936
+ description: "Require the app/styles CSS root, one global entry point, and direct imports for every project stylesheet."
9949
9937
  }
9950
9938
  },
9951
9939
  create(context) {
@@ -9961,7 +9949,7 @@ var cssEntryPointRule = {
9961
9949
  }
9962
9950
  const textOf = cachedTextReader();
9963
9951
  const graph = buildStylesheetGraph({ cssFiles, sourceRoot, textOf });
9964
- const { globals, reachable, directChildren } = graph;
9952
+ const { globals, directChildren } = graph;
9965
9953
  return {
9966
9954
  "StyleSheet:exit"(node) {
9967
9955
  if (globals.length === 0) return;
@@ -9982,13 +9970,33 @@ var cssEntryPointRule = {
9982
9970
  });
9983
9971
  return;
9984
9972
  }
9985
- const basename = path67.basename(current);
9986
- const importCount = moduleFiles.filter((modulePath) => moduleImports(textOf(modulePath), basename)).length;
9973
+ const importers = moduleFiles.filter((modulePath) => {
9974
+ const source = textOf(modulePath);
9975
+ for (const match of source.matchAll(
9976
+ /\b(?:import\s*(?:[^"'`;]*?\bfrom\s*)?|require\s*\(\s*)["'](?<specifier>[^"']+\.css)["']/gu
9977
+ )) {
9978
+ const specifier = match.groups?.specifier;
9979
+ if (!specifier) continue;
9980
+ const resolved = resolveSpecifier2(modulePath, specifier, sourceRoot);
9981
+ if (resolved && path67.normalize(resolved) === current) return true;
9982
+ }
9983
+ return false;
9984
+ });
9985
+ const importCount = importers.length;
9987
9986
  if (importCount !== 1) {
9988
9987
  context.report({
9989
9988
  node,
9990
9989
  message: `The global stylesheet entry point must be imported by exactly one module (the root layout), but it is imported by ${String(importCount)} module(s).`
9991
9990
  });
9991
+ } else {
9992
+ const importer = importers[0];
9993
+ const isRootLayout = importer !== void 0 && path67.dirname(importer) === path67.join(sourceRoot, "app") && /^layout\.(?:[cm]?[jt]sx?)$/u.test(path67.basename(importer));
9994
+ if (!isRootLayout) {
9995
+ context.report({
9996
+ node,
9997
+ message: "The global stylesheet entry point must be imported by src/app/layout, not another module."
9998
+ });
9999
+ }
9992
10000
  }
9993
10001
  return;
9994
10002
  }
@@ -10000,22 +10008,10 @@ var cssEntryPointRule = {
10000
10008
  });
10001
10009
  return;
10002
10010
  }
10003
- const hasProjectCss = node.children.some((child) => {
10004
- if (child.type === "Atrule" && child.name === "import") return false;
10005
- if (child.type === "Comment") return false;
10006
- return true;
10007
- });
10008
- if (hasProjectCss && !directChildren.has(current)) {
10009
- context.report({
10010
- node,
10011
- message: "Project CSS may only live in a stylesheet the global entry point imports directly; route it through a direct import or into the entry point."
10012
- });
10013
- return;
10014
- }
10015
- if (!reachable.has(current)) {
10011
+ if (!directChildren.has(current)) {
10016
10012
  context.report({
10017
10013
  node,
10018
- message: "This stylesheet must be imported by the global stylesheet entry point via @import, so CSS arrives through one door."
10014
+ message: "Every project stylesheet must be imported directly by src/app/styles/globals.css."
10019
10015
  });
10020
10016
  }
10021
10017
  }
@@ -10516,7 +10512,6 @@ var featureCssPlacementRule = {
10516
10512
  const basename = path70.basename(current);
10517
10513
  const featureName = basename.slice(0, -".css".length);
10518
10514
  const isFeatureFile = path70.dirname(current) === styles && FEATURE_CSS.test(basename) && existsSync9(path70.join(sourceRoot, "features", featureName));
10519
- if (basename !== GLOBALS && !isFeatureFile) return {};
10520
10515
  const read = cachedTextReader();
10521
10516
  const css2 = findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({ path: file, content: read(file) }));
10522
10517
  const modules = findFiles(sourceRoot, MODULE_EXTENSIONS4).map((file) => ({ path: file, content: read(file) }));
@@ -10529,7 +10524,9 @@ var featureCssPlacementRule = {
10529
10524
  const owner = owners.get(symbolId(definition));
10530
10525
  if (!owner) continue;
10531
10526
  const expected = owner === GLOBALS ? GLOBALS : `${owner}.css`;
10532
- if (basename === GLOBALS && expected !== GLOBALS && !existsSync9(path70.join(styles, expected))) continue;
10527
+ if (owner !== GLOBALS && (basename === GLOBALS || !isFeatureFile) && !existsSync9(path70.join(styles, expected))) {
10528
+ continue;
10529
+ }
10533
10530
  if (basename === expected) continue;
10534
10531
  const kind = LABELS[definition.kind] ?? definition.kind;
10535
10532
  context.report({
@@ -10546,38 +10543,6 @@ var featureCssPlacementRule = {
10546
10543
  }
10547
10544
  };
10548
10545
 
10549
- // eslint/rules/tailwind/global-selector-styling.ts
10550
- function hasStyling(node) {
10551
- for (const child of blockChildren2(node)) {
10552
- if (child.type === "Declaration" && !child.property.startsWith("--")) return true;
10553
- if (child.type === "Atrule" && child.name === "apply") return true;
10554
- if (child.type === "Rule" && hasStyling(child)) return true;
10555
- }
10556
- return false;
10557
- }
10558
- var globalSelectorStylingRule = {
10559
- meta: {
10560
- schema: [],
10561
- type: "problem",
10562
- docs: {
10563
- description: "Forbid element/component styling in global selectors outside @layer base."
10564
- }
10565
- },
10566
- create(context) {
10567
- return {
10568
- "StyleSheet:exit"(node) {
10569
- for (const child of node.children) {
10570
- if (child.type !== "Rule" || !hasStyling(child)) continue;
10571
- context.report({
10572
- node: child,
10573
- message: "Global selectors outside @layer base may only override CSS variables; keep element/component styling as Tailwind classes in the consumer."
10574
- });
10575
- }
10576
- }
10577
- };
10578
- }
10579
- };
10580
-
10581
10546
  // eslint/rules/tailwind/global-stylesheet.ts
10582
10547
  import { existsSync as existsSync10 } from "fs";
10583
10548
  import path71 from "path";
@@ -10662,7 +10627,18 @@ import path72 from "path";
10662
10627
  import { generate as generate3, parse as parse6, walk as walk3 } from "@eslint/css-tree";
10663
10628
  var INLINE_MESSAGE = "Define design tokens with direct values in @theme, not @theme inline.";
10664
10629
  var INDIRECT_MESSAGE = "Define design tokens that reference CSS variables via var() in @theme inline.";
10630
+ var MIXED_THEME_MESSAGE = "Use either @theme or @theme inline across the project, not both.";
10665
10631
  var REDUNDANT_INLINE_MESSAGE = (name) => `Tailwind token "${name}" has no runtime overrides; define its value directly in @theme instead of using :root and @theme inline.`;
10632
+ var EXTERNAL_FONT_FALLBACK_MESSAGE = (name, variable) => `Tailwind font token "${name}" references external font "${variable}" without a fallback inside var(); use var(${variable}, Arial) or another font-family fallback.`;
10633
+ function hasVarFallback(source, variable) {
10634
+ for (const match of source.matchAll(/\bvar\s*\(\s*(?<name>--[\w-]+)\s*,/gu)) {
10635
+ if (match.groups?.name !== variable) continue;
10636
+ const start = match.index + match[0].length;
10637
+ const close = source.indexOf(")", start);
10638
+ if (close !== -1 && /[^,\s]/u.test(source.slice(start, close))) return true;
10639
+ }
10640
+ return false;
10641
+ }
10666
10642
  var rootVariablesRule = {
10667
10643
  meta: {
10668
10644
  schema: [],
@@ -10689,11 +10665,17 @@ var rootVariablesRule = {
10689
10665
  graph.definitions.filter((symbol) => symbol.kind === "theme-token").map((symbol) => symbol.name)
10690
10666
  );
10691
10667
  const mirroredTokens = /* @__PURE__ */ new Set();
10668
+ let hasPlainThemeBlocks = false;
10669
+ let hasInlineThemeBlocks = false;
10692
10670
  for (const file of [...stylesheets.filter((candidate) => path72.normalize(candidate) !== current), current]) {
10693
10671
  const source = (path72.normalize(file) === current ? context.sourceCode.text : textOf(file)).replace(
10694
10672
  /\/\*[\s\S]*?\*\//gu,
10695
10673
  " "
10696
10674
  );
10675
+ for (const header of source.matchAll(/@theme(?<options>(?:\s+[\w-]+)*)\s*\{/gu)) {
10676
+ if (/\binline\b/u.test(header.groups?.options ?? "")) hasInlineThemeBlocks = true;
10677
+ else hasPlainThemeBlocks = true;
10678
+ }
10697
10679
  for (const theme of source.matchAll(/@theme(?<options>(?:\s+[\w-]+)*)\s*\{(?<body>[^{}]*)\}/gu)) {
10698
10680
  const inline = /\binline\b/u.test(theme.groups?.options ?? "");
10699
10681
  for (const declaration of (theme.groups?.body ?? "").matchAll(
@@ -10732,7 +10714,11 @@ var rootVariablesRule = {
10732
10714
  );
10733
10715
  return {
10734
10716
  "StyleSheet:exit"(node) {
10735
- for (const theme of atrulesNamed(node, "theme")) {
10717
+ const localThemes = atrulesNamed(node, "theme");
10718
+ if (hasPlainThemeBlocks && hasInlineThemeBlocks && localThemes[0]) {
10719
+ context.report({ node: localThemes[0], message: MIXED_THEME_MESSAGE });
10720
+ }
10721
+ for (const theme of localThemes) {
10736
10722
  const inline = preludeIdentifiers(theme).includes("inline");
10737
10723
  const source = context.sourceCode.getText(theme).replace(/\/\*[\s\S]*?\*\//gu, (comment) => comment.replace(/[^\r\n]/gu, " "));
10738
10724
  for (const match of source.matchAll(
@@ -10746,8 +10732,10 @@ var rootVariablesRule = {
10746
10732
  for (const reference of unquoted.matchAll(/\bvar\(\s*(?<variable>--[\w-]+)/gu)) {
10747
10733
  const runtime = reference.groups?.variable;
10748
10734
  if (runtime && runtime !== name) {
10749
- const externalFont = name.startsWith("--font-") && runtime.startsWith("--font-") && /,\s*[^\s,)]+/u.test(unquoted);
10750
- if (!names.has(runtime) && !externalFont) {
10735
+ const externalFont = name.startsWith("--font-") && runtime.startsWith("--font-");
10736
+ if (externalFont && !hasVarFallback(value, runtime)) {
10737
+ context.report({ node: theme, message: EXTERNAL_FONT_FALLBACK_MESSAGE(name, runtime) });
10738
+ } else if (!externalFont) {
10751
10739
  context.report({
10752
10740
  node: theme,
10753
10741
  message: `Tailwind token "${name}" must reference its same-named CSS variable, not "${runtime}".`
@@ -10828,7 +10816,14 @@ var rootVariablesRule = {
10828
10816
  };
10829
10817
 
10830
10818
  // eslint/rules/tailwind/stylesheet-ordering.ts
10819
+ import path73 from "path";
10831
10820
  var SECTION_ORDER = ["imports", "custom-variant", "root", "theme", "utility", "base styles", "keyframes"];
10821
+ function scopesCustomProperties(node) {
10822
+ if (node.type === "Declaration") return node.property.startsWith("--");
10823
+ if (node.type === "Atrule" && !["media", "supports", "container"].includes(node.name)) return false;
10824
+ if (node.type !== "Atrule" && node.type !== "Rule") return false;
10825
+ return blockChildren2(node).some(scopesCustomProperties);
10826
+ }
10832
10827
  var stylesheetOrderingRule = {
10833
10828
  meta: {
10834
10829
  schema: [],
@@ -10838,6 +10833,9 @@ var stylesheetOrderingRule = {
10838
10833
  }
10839
10834
  },
10840
10835
  create(context) {
10836
+ const sourceRoot = sourceRootOf(context);
10837
+ const entryPoint = path73.normalize(path73.join(sourceRoot, "app", "styles", "globals.css"));
10838
+ if (path73.normalize(path73.resolve(context.filename)) !== entryPoint) return {};
10841
10839
  return {
10842
10840
  "StyleSheet:exit"(node) {
10843
10841
  const sections = [];
@@ -10857,7 +10855,9 @@ var stylesheetOrderingRule = {
10857
10855
  if (preludeIdentifiers(child).includes("base")) {
10858
10856
  sections.push({ name: "base styles", at: index });
10859
10857
  }
10860
- } else if (child.type === "Rule" && selectorNames(child).includes("root")) {
10858
+ } else if (child.type === "Rule" && (selectorNames(child).includes("root") || scopesCustomProperties(child))) {
10859
+ sections.push({ name: "root", at: index });
10860
+ } else if (child.type === "Atrule" && scopesCustomProperties(child)) {
10861
10861
  sections.push({ name: "root", at: index });
10862
10862
  }
10863
10863
  index += 1;
@@ -10902,7 +10902,7 @@ var stylesheetOrderingRule = {
10902
10902
 
10903
10903
  // eslint/rules/tailwind/theme-reset.ts
10904
10904
  import { existsSync as existsSync11 } from "fs";
10905
- import path73 from "path";
10905
+ import path74 from "path";
10906
10906
  import { generate as generate4, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
10907
10907
  function isThemeReset(node) {
10908
10908
  if (!node) return false;
@@ -10930,8 +10930,8 @@ var themeResetRule = {
10930
10930
  },
10931
10931
  create(context) {
10932
10932
  const sourceRoot = sourceRootOf(context);
10933
- const current = path73.normalize(path73.resolve(context.filename));
10934
- const entryPoint = path73.normalize(path73.join(sourceRoot, "app", "styles", "globals.css"));
10933
+ const current = path74.normalize(path74.resolve(context.filename));
10934
+ const entryPoint = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
10935
10935
  if (current !== entryPoint) return {};
10936
10936
  return {
10937
10937
  "StyleSheet:exit"(node) {
@@ -10944,8 +10944,8 @@ var themeResetRule = {
10944
10944
  if (!from) continue;
10945
10945
  for (const specifier of importedSpecifiers(from.source)) {
10946
10946
  const target = resolveSpecifier2(from.file, specifier, sourceRoot);
10947
- if (!target || path73.extname(target) !== ".css") continue;
10948
- const filename = path73.normalize(target);
10947
+ if (!target || path74.extname(target) !== ".css") continue;
10948
+ const filename = path74.normalize(target);
10949
10949
  if (seen.has(filename) || !existsSync11(filename)) continue;
10950
10950
  seen.add(filename);
10951
10951
  const source = textOf(filename);
@@ -10964,7 +10964,7 @@ var themeResetRule = {
10964
10964
  };
10965
10965
 
10966
10966
  // eslint/rules/tailwind/unique-css-definition.ts
10967
- import path74 from "path";
10967
+ import path75 from "path";
10968
10968
  function ownershipKey(symbol) {
10969
10969
  if (symbol.kind === "selector") return void 0;
10970
10970
  if (symbol.kind === "root-variable" && symbol.scope !== "default") return void 0;
@@ -10996,7 +10996,7 @@ var uniqueCssDefinitionRule = {
10996
10996
  },
10997
10997
  create(context) {
10998
10998
  const sourceRoot = sourceRootOf(context);
10999
- const current = path74.normalize(path74.resolve(context.filename));
10999
+ const current = path75.normalize(path75.resolve(context.filename));
11000
11000
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11001
11001
  if (cssFiles.length === 0) return {};
11002
11002
  const textOf = cachedTextReader();
@@ -11004,7 +11004,7 @@ var uniqueCssDefinitionRule = {
11004
11004
  sourceRoot,
11005
11005
  css: cssFiles.map((file) => ({
11006
11006
  path: file,
11007
- content: path74.normalize(file) === current ? context.sourceCode.text : textOf(file)
11007
+ content: path75.normalize(file) === current ? context.sourceCode.text : textOf(file)
11008
11008
  })),
11009
11009
  modules: [],
11010
11010
  includeReferences: false
@@ -11026,7 +11026,7 @@ var uniqueCssDefinitionRule = {
11026
11026
  if (!canonical) continue;
11027
11027
  for (const symbol of definitions.slice(1)) {
11028
11028
  if (symbol.file !== current) continue;
11029
- const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path74.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
11029
+ const message = symbol.file === canonical.file ? `${symbolLabel(symbol)} "${symbol.name}" is defined more than once in this CSS file; define it only once.` : `${symbolLabel(symbol)} "${symbol.name}" is also defined in ${path75.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
11030
11030
  context.report({
11031
11031
  node,
11032
11032
  loc: {
@@ -11043,7 +11043,7 @@ var uniqueCssDefinitionRule = {
11043
11043
  };
11044
11044
 
11045
11045
  // eslint/rules/tailwind/unique-css-token-value.ts
11046
- import path75 from "path";
11046
+ import path76 from "path";
11047
11047
  function valueIdentity(value) {
11048
11048
  const text = value.trim();
11049
11049
  const hex = /^#(?<digits>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(text)?.groups?.digits;
@@ -11071,14 +11071,14 @@ var uniqueCssTokenValueRule = {
11071
11071
  },
11072
11072
  create(context) {
11073
11073
  const sourceRoot = sourceRootOf(context);
11074
- const current = path75.normalize(path75.resolve(context.filename));
11074
+ const current = path76.normalize(path76.resolve(context.filename));
11075
11075
  const textOf = cachedTextReader();
11076
11076
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11077
11077
  const graph = buildCssDependencyGraph({
11078
11078
  sourceRoot,
11079
11079
  css: cssFiles.map((file) => ({
11080
11080
  path: file,
11081
- content: path75.normalize(file) === current ? context.sourceCode.text : textOf(file)
11081
+ content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11082
11082
  })),
11083
11083
  modules: [],
11084
11084
  includeReferences: false
@@ -11110,7 +11110,7 @@ var uniqueCssTokenValueRule = {
11110
11110
  start: { line: definition.line, column: 1 },
11111
11111
  end: { line: definition.line, column: 2 }
11112
11112
  },
11113
- message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path75.relative(
11113
+ message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path76.relative(
11114
11114
  sourceRoot,
11115
11115
  original.file
11116
11116
  )}:${String(original.line)}; reuse one design token.`
@@ -11123,7 +11123,7 @@ var uniqueCssTokenValueRule = {
11123
11123
 
11124
11124
  // eslint/rules/tailwind/unused-utility.ts
11125
11125
  import { statSync as statSync5 } from "fs";
11126
- import path76 from "path";
11126
+ import path77 from "path";
11127
11127
  var unusedUtilityRule = {
11128
11128
  meta: {
11129
11129
  schema: [],
@@ -11139,7 +11139,7 @@ var unusedUtilityRule = {
11139
11139
  } catch {
11140
11140
  return {};
11141
11141
  }
11142
- const current = path76.normalize(path76.resolve(context.filename));
11142
+ const current = path77.normalize(path77.resolve(context.filename));
11143
11143
  const textOf = cachedTextReader();
11144
11144
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11145
11145
  const moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
@@ -11147,7 +11147,7 @@ var unusedUtilityRule = {
11147
11147
  sourceRoot,
11148
11148
  css: cssFiles.map((file) => ({
11149
11149
  path: file,
11150
- content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11150
+ content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11151
11151
  })),
11152
11152
  modules: moduleFiles.map((file) => ({ path: file, content: textOf(file) }))
11153
11153
  });
@@ -11168,7 +11168,7 @@ var unusedUtilityRule = {
11168
11168
  };
11169
11169
 
11170
11170
  // eslint/rules/tailwind/utility-mapping.ts
11171
- import path77 from "path";
11171
+ import path78 from "path";
11172
11172
  function applyOperationCount(utility) {
11173
11173
  let count = 0;
11174
11174
  for (const apply of atrulesNamed(utility, "apply")) {
@@ -11294,6 +11294,26 @@ function canonicalToken(name) {
11294
11294
  function isTypographySize(name) {
11295
11295
  return /^--text-(?!.*--)(?:[a-z0-9]+-)*[a-z0-9]+$/u.test(name);
11296
11296
  }
11297
+ function suggestedThemeToken(candidate) {
11298
+ if (candidate.namespace !== "color") return candidate.token;
11299
+ let role = "edge";
11300
+ if (["bg", "fill"].includes(candidate.prefix)) {
11301
+ role = "canvas";
11302
+ } else if (["text", "caret", "decoration"].includes(candidate.prefix)) {
11303
+ role = "ink";
11304
+ }
11305
+ const semantic = /^--color-(?<domain>[a-z][a-z0-9-]*)-(?:canvas|ink|edge)$/u.exec(candidate.token);
11306
+ const domain = semantic?.groups?.domain;
11307
+ return domain ? `--color-${domain}-${role}` : `${candidate.token}-${role}`;
11308
+ }
11309
+ function themeMigrationGuidance(candidate, utilityName) {
11310
+ const token = suggestedThemeToken(candidate);
11311
+ const generatedClass = `${candidate.prefix}-${token.slice(`--${candidate.namespace}-`.length)}`;
11312
+ const runtimeDependent = /\bvar\s*\(/iu.test(candidate.value);
11313
+ const action = runtimeDependent ? `only use a self-named @theme inline token "${token}" with an unconditional :root default and a detected runtime override; otherwise resolve the fixed value directly in @theme. ` : `define a direct @theme token "${token}" with value "${candidate.value}" rather than adding a :root bridge. `;
11314
+ const classGuidance = generatedClass === utilityName ? "Preserve the generated class name" : `Update class usages to "${generatedClass}"`;
11315
+ return `${action}${classGuidance} and compare compiled CSS before removing the utility.`;
11316
+ }
11297
11317
  var utilityMappingRule = {
11298
11318
  meta: {
11299
11319
  schema: [],
@@ -11304,13 +11324,13 @@ var utilityMappingRule = {
11304
11324
  },
11305
11325
  create(context) {
11306
11326
  const sourceRoot = sourceRootOf(context);
11307
- const current = path77.normalize(path77.resolve(context.filename));
11327
+ const current = path78.normalize(path78.resolve(context.filename));
11308
11328
  const textOf = cachedTextReader();
11309
11329
  const graph = buildCssDependencyGraph({
11310
11330
  sourceRoot,
11311
11331
  css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
11312
11332
  path: file,
11313
- content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11333
+ content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
11314
11334
  })),
11315
11335
  modules: [],
11316
11336
  includeReferences: false
@@ -11503,7 +11523,7 @@ var utilityMappingRule = {
11503
11523
  if (candidate.property === "font-size" && themeTokens.has(`--color-${name.slice(5)}`)) continue;
11504
11524
  context.report({
11505
11525
  node: utility,
11506
- message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); prefer @theme inline token "${candidate.token}" backed by a :root variable. Preserve the class name and compare compiled CSS before removing the utility.`
11526
+ message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); ${themeMigrationGuidance(candidate, name)}`
11507
11527
  });
11508
11528
  }
11509
11529
  function checkClass(cssNode) {
@@ -11563,7 +11583,7 @@ var utilityMappingRule = {
11563
11583
  import { spawnSync } from "child_process";
11564
11584
  import { createHash } from "crypto";
11565
11585
  import { existsSync as existsSync12 } from "fs";
11566
- import path78 from "path";
11586
+ import path79 from "path";
11567
11587
  import { generate as generate5, parse as parse8, toPlainObject as toPlainObject3 } from "@eslint/css-tree";
11568
11588
  function numericPart(value) {
11569
11589
  const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
@@ -11713,8 +11733,8 @@ var utilityNameParityRule = {
11713
11733
  return apply ? [{ utility, name, apply }] : [];
11714
11734
  });
11715
11735
  if (candidates.length === 0) return;
11716
- const physicalDir = path78.dirname(context.physicalFilename);
11717
- const cwd = path78.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11736
+ const physicalDir = path79.dirname(context.physicalFilename);
11737
+ const cwd = path79.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11718
11738
  const compiled = compileApplies(
11719
11739
  candidates.map((candidate) => candidate.apply),
11720
11740
  cwd
@@ -11758,12 +11778,11 @@ var tailwindRules = {
11758
11778
  "unused-utility": unusedUtilityRule,
11759
11779
  "unique-css-definition": uniqueCssDefinitionRule,
11760
11780
  "unique-css-token-value": uniqueCssTokenValueRule,
11761
- "no-utility-alias": noUtilityAliasRule,
11762
- "global-selector-styling": globalSelectorStylingRule
11781
+ "no-utility-alias": noUtilityAliasRule
11763
11782
  };
11764
11783
 
11765
11784
  // eslint/rules/type-extraction.ts
11766
- import path79 from "path";
11785
+ import path80 from "path";
11767
11786
  var typeExtractionRule = {
11768
11787
  meta: {
11769
11788
  schema: [],
@@ -11774,7 +11793,7 @@ var typeExtractionRule = {
11774
11793
  },
11775
11794
  create(context) {
11776
11795
  const sourceRoot = sourceRootOf(context);
11777
- const file = path79.resolve(context.filename);
11796
+ const file = path80.resolve(context.filename);
11778
11797
  const segments = segmentsOf(file, sourceRoot);
11779
11798
  if (segments.length === 0) return {};
11780
11799
  const index = getProjectIndex(sourceRoot);
@@ -11915,7 +11934,7 @@ var uiStateRule = {
11915
11934
  // eslint/rules/unknown-utility.ts
11916
11935
  import { existsSync as existsSync13, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
11917
11936
  import { createRequire } from "module";
11918
- import path80 from "path";
11937
+ import path81 from "path";
11919
11938
  var PREFIX_NAMESPACES = {
11920
11939
  bg: ["color", "background-image"],
11921
11940
  text: ["color", "text"],
@@ -12196,7 +12215,7 @@ function stylesheetFiles(dir) {
12196
12215
  }
12197
12216
  return entries.flatMap((entry) => {
12198
12217
  if (entry.startsWith(".") || entry === "node_modules") return [];
12199
- const entryPath = path80.join(dir, entry);
12218
+ const entryPath = path81.join(dir, entry);
12200
12219
  let stats;
12201
12220
  try {
12202
12221
  stats = statSync6(entryPath);
@@ -12204,7 +12223,7 @@ function stylesheetFiles(dir) {
12204
12223
  return [];
12205
12224
  }
12206
12225
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
12207
- return path80.extname(entry) === ".css" ? [entryPath] : [];
12226
+ return path81.extname(entry) === ".css" ? [entryPath] : [];
12208
12227
  });
12209
12228
  }
12210
12229
  function packageNameOf(specifier) {
@@ -12215,10 +12234,10 @@ function packageNameOf(specifier) {
12215
12234
  function resolvePackageStylesheet(fromFile, specifier) {
12216
12235
  const packageName = packageNameOf(specifier);
12217
12236
  if (!packageName || packageName === "tailwindcss") return void 0;
12218
- let directory = path80.dirname(fromFile);
12219
- while (directory !== path80.dirname(directory)) {
12220
- const packageRoot = path80.join(directory, "node_modules", packageName);
12221
- const manifestPath = path80.join(packageRoot, "package.json");
12237
+ let directory = path81.dirname(fromFile);
12238
+ while (directory !== path81.dirname(directory)) {
12239
+ const packageRoot = path81.join(directory, "node_modules", packageName);
12240
+ const manifestPath = path81.join(packageRoot, "package.json");
12222
12241
  if (existsSync13(manifestPath)) {
12223
12242
  try {
12224
12243
  const manifest = readFileSync15(manifestPath, "utf8");
@@ -12226,13 +12245,13 @@ function resolvePackageStylesheet(fromFile, specifier) {
12226
12245
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
12227
12246
  const target = stylesheet ?? main;
12228
12247
  if (!target) return void 0;
12229
- const resolved = path80.resolve(packageRoot, target);
12248
+ const resolved = path81.resolve(packageRoot, target);
12230
12249
  return existsSync13(resolved) ? resolved : void 0;
12231
12250
  } catch {
12232
12251
  return void 0;
12233
12252
  }
12234
12253
  }
12235
- directory = path80.dirname(directory);
12254
+ directory = path81.dirname(directory);
12236
12255
  }
12237
12256
  return void 0;
12238
12257
  }
@@ -12492,7 +12511,7 @@ var unknownUtilityRule = {
12492
12511
  };
12493
12512
 
12494
12513
  // eslint/rules/util-file-name.ts
12495
- import path81 from "path";
12514
+ import path82 from "path";
12496
12515
  function toKebabCase2(value) {
12497
12516
  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();
12498
12517
  }
@@ -12505,7 +12524,7 @@ var utilFileNameRule = {
12505
12524
  }
12506
12525
  },
12507
12526
  create(context) {
12508
- const filename = path81.resolve(context.filename);
12527
+ const filename = path82.resolve(context.filename);
12509
12528
  const segments = filename.replace(/\\/g, "/").split("/");
12510
12529
  if (!segments.includes("utils")) return {};
12511
12530
  let module;
@@ -12519,13 +12538,13 @@ var utilFileNameRule = {
12519
12538
  const functionName = functions[0]?.name;
12520
12539
  if (!functionName) return {};
12521
12540
  const expected = toKebabCase2(functionName);
12522
- const actual = path81.basename(filename, path81.extname(filename));
12541
+ const actual = path82.basename(filename, path82.extname(filename));
12523
12542
  if (!expected || actual === expected) return {};
12524
12543
  return {
12525
12544
  Program(node) {
12526
12545
  context.report({
12527
12546
  node,
12528
- message: `A utility file exporting ${functionName} must be named ${expected}.${path81.extname(filename).slice(1)}.`
12547
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path82.extname(filename).slice(1)}.`
12529
12548
  });
12530
12549
  }
12531
12550
  };
@@ -12533,7 +12552,7 @@ var utilFileNameRule = {
12533
12552
  };
12534
12553
 
12535
12554
  // eslint/rules/value-extraction.ts
12536
- import path82 from "path";
12555
+ import path83 from "path";
12537
12556
  var valueExtractionRule = {
12538
12557
  meta: {
12539
12558
  schema: [],
@@ -12544,7 +12563,7 @@ var valueExtractionRule = {
12544
12563
  },
12545
12564
  create(context) {
12546
12565
  const sourceRoot = sourceRootOf(context);
12547
- const file = path82.resolve(context.filename);
12566
+ const file = path83.resolve(context.filename);
12548
12567
  const segments = segmentsOf(file, sourceRoot);
12549
12568
  if (segments.length === 0 || segments[0] !== "app") return {};
12550
12569
  const index = getProjectIndex(sourceRoot);
@@ -12566,7 +12585,7 @@ var valueExtractionRule = {
12566
12585
 
12567
12586
  // eslint/rules/vulyk/tracked-docs.ts
12568
12587
  import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
12569
- import path83 from "path";
12588
+ import path84 from "path";
12570
12589
  var PASIKA_REPO = "Bredansky/pasika";
12571
12590
  var BASE_REQUIRED_TRACKED_DOCS = [
12572
12591
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -12599,8 +12618,8 @@ var trackedDocsRule = {
12599
12618
  if (!context.filename.endsWith("package.json")) return;
12600
12619
  const root = node.body;
12601
12620
  if (root.type !== "Object") return;
12602
- const projectRoot = path83.dirname(path83.resolve(context.filename));
12603
- const configPath = path83.join(projectRoot, "vulyk.config.ts");
12621
+ const projectRoot = path84.dirname(path84.resolve(context.filename));
12622
+ const configPath = path84.join(projectRoot, "vulyk.config.ts");
12604
12623
  if (!existsSync14(configPath)) {
12605
12624
  context.report({
12606
12625
  node,
@@ -12625,7 +12644,7 @@ var trackedDocsRule = {
12625
12644
  });
12626
12645
  }
12627
12646
  }
12628
- const agentsPath = path83.join(projectRoot, "AGENTS.md");
12647
+ const agentsPath = path84.join(projectRoot, "AGENTS.md");
12629
12648
  if (!existsSync14(agentsPath)) {
12630
12649
  context.report({
12631
12650
  node,
@@ -12725,7 +12744,7 @@ var withResponseHelperRule = {
12725
12744
 
12726
12745
  // eslint/rules/zirka-baseline.ts
12727
12746
  import fs7 from "fs";
12728
- import path84 from "path";
12747
+ import path85 from "path";
12729
12748
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
12730
12749
  var PRETTIER_CONFIGS = [
12731
12750
  "prettier.config.mjs",
@@ -12744,10 +12763,10 @@ var zirkaBaselineRule = {
12744
12763
  }
12745
12764
  },
12746
12765
  create(context) {
12747
- const filename = path84.resolve(context.filename);
12748
- const basename = path84.basename(filename);
12766
+ const filename = path85.resolve(context.filename);
12767
+ const basename = path85.basename(filename);
12749
12768
  if (!ESLINT_CONFIG.test(basename)) return {};
12750
- const projectRoot = path84.dirname(filename);
12769
+ const projectRoot = path85.dirname(filename);
12751
12770
  const report3 = (message) => {
12752
12771
  context.report({
12753
12772
  node: context.sourceCode.ast,
@@ -12762,7 +12781,7 @@ var zirkaBaselineRule = {
12762
12781
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
12763
12782
  );
12764
12783
  }
12765
- const tsconfigPath = path84.join(projectRoot, "tsconfig.json");
12784
+ const tsconfigPath = path85.join(projectRoot, "tsconfig.json");
12766
12785
  if (!fs7.existsSync(tsconfigPath)) {
12767
12786
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
12768
12787
  } else {
@@ -12780,13 +12799,13 @@ var zirkaBaselineRule = {
12780
12799
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
12781
12800
  }
12782
12801
  }
12783
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path84.join(projectRoot, name)));
12802
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path85.join(projectRoot, name)));
12784
12803
  if (!prettierConfigFile) {
12785
12804
  report3(
12786
12805
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
12787
12806
  );
12788
12807
  } else {
12789
- const content = fs7.readFileSync(path84.join(projectRoot, prettierConfigFile), "utf8");
12808
+ const content = fs7.readFileSync(path85.join(projectRoot, prettierConfigFile), "utf8");
12790
12809
  if (!content.includes("zirka")) {
12791
12810
  report3(
12792
12811
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.121",
3
+ "version": "0.10.122",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",