pasika 0.10.130 → 0.10.131

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.
@@ -121,6 +121,7 @@ declare const nextjsPackageJsonRules: {
121
121
 
122
122
  declare const tailwindRules: {
123
123
  "theme-reset": _eslint_css.CSSRuleDefinition;
124
+ "theme-mode": _eslint_css.CSSRuleDefinition;
124
125
  "color-role-usage": _eslint_css.CSSRuleDefinition;
125
126
  "root-variables": _eslint_css.CSSRuleDefinition;
126
127
  "apply-usage": _eslint_css.CSSRuleDefinition;
@@ -161,6 +162,7 @@ declare const pasikaPlugin: {
161
162
  "lint-setup": _eslint_json.JSONRuleDefinition;
162
163
  "vitest-coverage": _eslint_json.JSONRuleDefinition;
163
164
  "theme-reset": _eslint_css.CSSRuleDefinition;
165
+ "theme-mode": _eslint_css.CSSRuleDefinition;
164
166
  "color-role-usage": _eslint_css.CSSRuleDefinition;
165
167
  "root-variables": _eslint_css.CSSRuleDefinition;
166
168
  "apply-usage": _eslint_css.CSSRuleDefinition;
@@ -2866,6 +2866,16 @@ var rulePairedExamplesRule = {
2866
2866
  node,
2867
2867
  message: `${String(incorrect.length)} Incorrect and ${String(correct.length)} Correct examples`
2868
2868
  });
2869
+ } else {
2870
+ const misplaced = exampleHeadings.find(
2871
+ (heading, index) => !heading.text.startsWith(index % 2 === 0 ? "Incorrect" : "Correct")
2872
+ );
2873
+ if (misplaced) {
2874
+ context.report({
2875
+ node,
2876
+ message: `Rule examples must alternate Incorrect then Correct; found "${misplaced.text}" at line ${String(misplaced.line)}.`
2877
+ });
2878
+ }
2869
2879
  }
2870
2880
  }
2871
2881
  };
@@ -10829,19 +10839,16 @@ var rootVariablesRule = {
10829
10839
  return;
10830
10840
  }
10831
10841
  const isConditional = conditional || currentNode.type === "Atrule" && currentNode.name !== "layer";
10832
- if (currentNode.type === "Rule") {
10833
- const selector = context.sourceCode.getText(currentNode.prelude).trim();
10834
- const isDefaultRoot = selector === ":root" && !isConditional;
10835
- if (!isDefaultRoot) {
10836
- for (const declaration of blockChildren2(currentNode)) {
10837
- if (declaration.type !== "Declaration") continue;
10838
- if (mirroredTokens.has(declaration.property)) continue;
10839
- if (!names.has(declaration.property) && !declaration.property.startsWith("--color-")) continue;
10840
- context.report({
10841
- node: declaration,
10842
- message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
10843
- });
10844
- }
10842
+ const isDefaultRoot = currentNode.type === "Rule" && context.sourceCode.getText(currentNode.prelude).trim() === ":root" && !isConditional;
10843
+ if (currentNode.type === "Rule" && !isDefaultRoot || currentNode.type === "Atrule" && currentNode.name === "variant") {
10844
+ for (const declaration of blockChildren2(currentNode)) {
10845
+ if (declaration.type !== "Declaration") continue;
10846
+ if (mirroredTokens.has(declaration.property)) continue;
10847
+ if (!names.has(declaration.property) && !declaration.property.startsWith("--color-")) continue;
10848
+ context.report({
10849
+ node: declaration,
10850
+ message: `Tailwind token "${declaration.property}" must not be redeclared outside @theme; map it through @theme inline to its same-named runtime variable instead.`
10851
+ });
10845
10852
  }
10846
10853
  }
10847
10854
  const children = currentNode.type === "StyleSheet" ? currentNode.children : blockChildren2(currentNode);
@@ -10869,7 +10876,27 @@ var rootVariablesRule = {
10869
10876
 
10870
10877
  // eslint/rules/tailwind/stylesheet-ordering.ts
10871
10878
  import path73 from "path";
10879
+ import { generate as generate4 } from "@eslint/css-tree";
10872
10880
  var SECTION_ORDER = ["imports", "custom-variant", "root", "theme", "utility", "base styles", "keyframes"];
10881
+ var LATE_RESET_ERROR = "The global --*: initial theme reset must precede feature stylesheet imports, or it will erase their theme tokens.";
10882
+ function themeBody(node, source) {
10883
+ if (node.type !== "Atrule" || node.name !== "theme" || !node.loc) return void 0;
10884
+ const raw = source.slice(node.loc.start.offset, node.loc.end.offset);
10885
+ const start = raw.indexOf("{");
10886
+ const end = raw.lastIndexOf("}");
10887
+ if (start < 0 || end <= start) return void 0;
10888
+ return raw.slice(start + 1, end).replace(/\/\*[\s\S]*?\*\//gu, "").trim();
10889
+ }
10890
+ function containsThemeReset(body) {
10891
+ return body !== void 0 && /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(body);
10892
+ }
10893
+ function isStandaloneThemeReset(body) {
10894
+ return body !== void 0 && /^--\*\s*:\s*initial\s*;?$/u.test(body);
10895
+ }
10896
+ function isTailwindImport(node) {
10897
+ if (node.type !== "Atrule" || node.name !== "import" || !node.prelude) return false;
10898
+ return /^["']tailwindcss["'](?:\s|$)/u.test(generate4(node.prelude).trim());
10899
+ }
10873
10900
  function scopesCustomProperties(node) {
10874
10901
  if (node.type === "Declaration") return node.property.startsWith("--");
10875
10902
  if (node.type === "Atrule" && !["media", "supports", "container"].includes(node.name)) return false;
@@ -10892,9 +10919,24 @@ var stylesheetOrderingRule = {
10892
10919
  "StyleSheet:exit"(node) {
10893
10920
  const sections = [];
10894
10921
  let index = 0;
10922
+ let sawTailwindImport = false;
10923
+ let sawFeatureImport = false;
10924
+ let sawNonImport = false;
10925
+ let sawEarlyReset = false;
10895
10926
  for (const child of node.children) {
10927
+ const body = themeBody(child, context.sourceCode.text);
10928
+ let isEarlyReset = false;
10929
+ if (containsThemeReset(body) && sawFeatureImport) {
10930
+ context.report({ node: child, message: LATE_RESET_ERROR });
10931
+ return;
10932
+ }
10896
10933
  if (child.type === "Atrule" && child.name === "import") {
10897
10934
  sections.push({ name: "imports", at: index });
10935
+ if (isTailwindImport(child)) sawTailwindImport = true;
10936
+ else sawFeatureImport = true;
10937
+ } else if (isStandaloneThemeReset(body) && sawTailwindImport && !sawFeatureImport && !sawNonImport && !sawEarlyReset) {
10938
+ sawEarlyReset = true;
10939
+ isEarlyReset = true;
10898
10940
  } else if (child.type === "Atrule" && child.name === "custom-variant") {
10899
10941
  sections.push({ name: "custom-variant", at: index });
10900
10942
  } else if (child.type === "Atrule" && child.name === "theme") {
@@ -10912,6 +10954,9 @@ var stylesheetOrderingRule = {
10912
10954
  } else if (child.type === "Atrule" && scopesCustomProperties(child)) {
10913
10955
  sections.push({ name: "root", at: index });
10914
10956
  }
10957
+ if (child.type !== "Comment" && !(child.type === "Atrule" && child.name === "import") && !isEarlyReset) {
10958
+ sawNonImport = true;
10959
+ }
10915
10960
  index += 1;
10916
10961
  }
10917
10962
  const firstAt = /* @__PURE__ */ new Map();
@@ -10952,14 +10997,135 @@ var stylesheetOrderingRule = {
10952
10997
  }
10953
10998
  };
10954
10999
 
10955
- // eslint/rules/tailwind/theme-reset.ts
10956
- import { existsSync as existsSync12 } from "fs";
11000
+ // eslint/rules/tailwind/theme-mode.ts
10957
11001
  import path74 from "path";
10958
- import { generate as generate4, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
11002
+ import { generate as generate5 } from "@eslint/css-tree";
11003
+ var MODE_NAME = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
11004
+ var MODE_REFERENCE = /(?:^|[^a-z0-9-])(?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*):(?=[a-z[(])/gu;
11005
+ var MODE_ATTRIBUTE = /data-theme\s*=\s*["'](?<name>[a-z][a-z0-9]*(?:-[a-z0-9]+)*)["']/gu;
11006
+ var CUSTOM_REGISTRATION = /@custom-variant\s+(?<name>[a-z][a-z0-9-]*)\b(?<selector>[^;]*);/gu;
11007
+ var MODE_SELECTOR = /\[\s*data-theme\s*=\s*["']?(?<mode>[a-z][a-z0-9-]*)["']?\s*\]/u;
11008
+ var SELECTOR_OVERRIDE = "Use a data-theme @custom-variant for mode-specific styles; direct [data-theme] selectors are not allowed.";
11009
+ var CLASS_OVERRIDE = "Use the data-theme @custom-variant instead of a .dark CSS selector.";
11010
+ var SYSTEM_OVERRIDE = "Use data-theme with @custom-variant for mode styling; resolve system preferences in application code, not a prefers-color-scheme CSS media query.";
11011
+ var MODE_LOCATION = "Declare appearance-mode @custom-variant definitions in globals.css only.";
11012
+ var MISSING_CSS_VARIANT = (name) => `CSS @variant "${name}" requires a matching @custom-variant declaration in globals.css.`;
11013
+ function variantName(prelude) {
11014
+ return /^(?<name>[a-z][a-z0-9-]*)\b/u.exec(prelude.trim())?.groups?.name;
11015
+ }
11016
+ function isModeVariant(name, prelude) {
11017
+ return name === "dark" || name.startsWith("theme-") || /\[\s*data-theme\b/u.test(prelude);
11018
+ }
11019
+ function canonicalModePrelude(name, source) {
11020
+ if (!MODE_NAME.test(name)) return false;
11021
+ const normalized = source.replace(/\/\*[\s\S]*?\*\//gu, "").replace(/["']/gu, "").replace(/\s+/gu, "");
11022
+ return normalized === `${name}(&:where([data-theme=${name}],[data-theme=${name}]*))`;
11023
+ }
11024
+ function registeredModes(source) {
11025
+ const result = /* @__PURE__ */ new Set();
11026
+ for (const match of source.replace(/\/\*[\s\S]*?\*\//gu, "").matchAll(CUSTOM_REGISTRATION)) {
11027
+ const name = match.groups?.name;
11028
+ if (name && isModeVariant(name, `${name}${match.groups?.selector ?? ""}`)) result.add(name);
11029
+ }
11030
+ return result;
11031
+ }
11032
+ var themeModeRule = {
11033
+ meta: {
11034
+ schema: [],
11035
+ type: "problem",
11036
+ docs: { description: "Require a single data-theme/@custom-variant strategy for appearance modes." }
11037
+ },
11038
+ create(context) {
11039
+ const sourceRoot = sourceRootOf(context);
11040
+ const current = path74.normalize(path74.resolve(context.filename));
11041
+ const globalFile = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
11042
+ if (path74.dirname(current) !== path74.dirname(globalFile)) return {};
11043
+ const read = cachedTextReader();
11044
+ return {
11045
+ "StyleSheet:exit"(node) {
11046
+ const registered = /* @__PURE__ */ new Set();
11047
+ for (const variant of atrulesNamed(node, "custom-variant")) {
11048
+ if (variant.type !== "Atrule") continue;
11049
+ const prelude = variant.prelude ? generate5(variant.prelude) : "";
11050
+ const name = variantName(prelude);
11051
+ if (!name) continue;
11052
+ if (!isModeVariant(name, prelude)) continue;
11053
+ if (current !== globalFile) {
11054
+ context.report({ node: variant, message: MODE_LOCATION });
11055
+ continue;
11056
+ }
11057
+ if (!canonicalModePrelude(name, prelude)) {
11058
+ const selected = MODE_SELECTOR.exec(prelude)?.groups?.mode;
11059
+ context.report({
11060
+ node: variant,
11061
+ message: selected && selected !== name ? `Theme variant "${name}" must be named "${selected}" to match its data-theme selector.` : `Theme variant "${name}" must match both [data-theme="${name}"] and its descendants with &:where(...).`
11062
+ });
11063
+ }
11064
+ if (registered.has(name)) {
11065
+ context.report({ node: variant, message: `Theme variant "${name}" is already defined in globals.css.` });
11066
+ }
11067
+ registered.add(name);
11068
+ }
11069
+ const modeHints = /* @__PURE__ */ new Set();
11070
+ for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
11071
+ for (const match of read(file).matchAll(MODE_ATTRIBUTE)) {
11072
+ if (match.groups?.name) modeHints.add(match.groups.name);
11073
+ }
11074
+ }
11075
+ const globalRegistrations = current === globalFile ? registered : registeredModes(read(globalFile));
11076
+ for (const variant of atrulesNamed(node, "variant")) {
11077
+ if (variant.type !== "Atrule" || !variant.prelude) continue;
11078
+ const name = variantName(generate5(variant.prelude));
11079
+ if (name && (name === "dark" || name.startsWith("theme-") || globalRegistrations.has(name) || modeHints.has(name)) && !globalRegistrations.has(name)) {
11080
+ context.report({ node: variant, message: MISSING_CSS_VARIANT(name) });
11081
+ }
11082
+ }
11083
+ for (const rule of rules(node)) {
11084
+ if (rule.type !== "Rule") continue;
11085
+ const selector = generate5(rule.prelude);
11086
+ if (/\[\s*data-theme(?:\s*[~|^$*]?=|\s*\])/u.test(selector)) {
11087
+ context.report({ node: rule, message: SELECTOR_OVERRIDE });
11088
+ } else if (/\.dark(?![\w-])/u.test(selector)) {
11089
+ context.report({ node: rule, message: CLASS_OVERRIDE });
11090
+ }
11091
+ }
11092
+ walkNodes(node, (child) => {
11093
+ if (child.type !== "Atrule" || child.name !== "media" || !child.prelude) return;
11094
+ if (/\bprefers-color-scheme\b/u.test(generate5(child.prelude))) {
11095
+ context.report({ node: child, message: SYSTEM_OVERRIDE });
11096
+ }
11097
+ });
11098
+ if (current !== globalFile) return;
11099
+ const referenced = /* @__PURE__ */ new Set();
11100
+ for (const file of findFiles(sourceRoot, MODULE_EXTENSIONS4)) {
11101
+ for (const match of read(file).matchAll(MODE_REFERENCE)) {
11102
+ const name = match.groups?.name;
11103
+ if (!name) continue;
11104
+ if (name === "dark" || name.startsWith("theme-") || registered.has(name) || modeHints.has(name)) {
11105
+ referenced.add(name);
11106
+ }
11107
+ }
11108
+ }
11109
+ for (const name of referenced) {
11110
+ if (!registered.has(name)) {
11111
+ context.report({
11112
+ node,
11113
+ message: `Theme utility prefix "${name}:" requires a matching @custom-variant in globals.css; Tailwind's default media-based dark mode is not allowed.`
11114
+ });
11115
+ }
11116
+ }
11117
+ }
11118
+ };
11119
+ }
11120
+ };
11121
+
11122
+ // eslint/rules/tailwind/theme-reset.ts
11123
+ import path75 from "path";
11124
+ import { generate as generate6 } from "@eslint/css-tree";
10959
11125
  function isThemeReset(node) {
10960
11126
  if (!node) return false;
10961
- if (node.type === "Declaration") return node.property === "--*" && generate4(node.value).trim() === "initial";
10962
- if (node.type === "Raw") return /--\*\s*:\s*initial\s*;/u.test(node.value);
11127
+ if (node.type === "Declaration") return node.property === "--*" && generate6(node.value).trim() === "initial";
11128
+ if (node.type === "Raw") return /(?:^|[;{])\s*--\*\s*:\s*initial\s*(?:;|$)/u.test(node.value);
10963
11129
  return false;
10964
11130
  }
10965
11131
  function hasThemeReset(node) {
@@ -10977,46 +11143,39 @@ var themeResetRule = {
10977
11143
  schema: [],
10978
11144
  type: "problem",
10979
11145
  docs: {
10980
- description: "Require the CSS tree to reset Tailwind's default theme with --*: initial."
11146
+ description: "Require the default-theme reset in globals.css, never in feature stylesheets."
10981
11147
  }
10982
11148
  },
10983
11149
  create(context) {
10984
11150
  const sourceRoot = sourceRootOf(context);
10985
- const current = path74.normalize(path74.resolve(context.filename));
10986
- const entryPoint = path74.normalize(path74.join(sourceRoot, "app", "styles", "globals.css"));
10987
- if (current !== entryPoint) return {};
11151
+ const current = path75.normalize(path75.resolve(context.filename));
11152
+ const entryPoint = path75.normalize(path75.join(sourceRoot, "app", "styles", "globals.css"));
11153
+ if (path75.dirname(current) !== path75.dirname(entryPoint)) return {};
10988
11154
  return {
10989
11155
  "StyleSheet:exit"(node) {
10990
- if (hasThemeReset(node)) return;
10991
- const textOf = cachedTextReader();
10992
- const seen = /* @__PURE__ */ new Set([current]);
10993
- const queue = [{ file: current, source: context.sourceCode.text }];
10994
- while (queue.length > 0) {
10995
- const from = queue.shift();
10996
- if (!from) continue;
10997
- for (const specifier of importedSpecifiers(from.source)) {
10998
- const target = resolveSpecifier2(from.file, specifier, sourceRoot);
10999
- if (!target || path74.extname(target) !== ".css") continue;
11000
- const filename = path74.normalize(target);
11001
- if (seen.has(filename) || !existsSync12(filename)) continue;
11002
- seen.add(filename);
11003
- const source = textOf(filename);
11004
- const parsed = toPlainObject2(parse7(source, { parseAtrulePrelude: false }));
11005
- if (parsed.type === "StyleSheet" && hasThemeReset(parsed)) return;
11006
- queue.push({ file: filename, source });
11156
+ const hasReset = hasThemeReset(node);
11157
+ if (current !== entryPoint) {
11158
+ if (hasReset) {
11159
+ context.report({
11160
+ node,
11161
+ message: "Only globals.css may reset Tailwind's default theme with --*: initial; remove it from feature stylesheets."
11162
+ });
11007
11163
  }
11164
+ return;
11165
+ }
11166
+ if (!hasReset) {
11167
+ context.report({
11168
+ node,
11169
+ message: "globals.css must reset Tailwind's default theme with --*: initial inside @theme or @theme inline."
11170
+ });
11008
11171
  }
11009
- context.report({
11010
- node,
11011
- message: "The global stylesheet must reset Tailwind's default theme with --*: initial inside an @theme block."
11012
- });
11013
11172
  }
11014
11173
  };
11015
11174
  }
11016
11175
  };
11017
11176
 
11018
11177
  // eslint/rules/tailwind/unique-css-definition.ts
11019
- import path75 from "path";
11178
+ import path76 from "path";
11020
11179
  function ownershipKey(symbol) {
11021
11180
  if (symbol.kind === "selector") return void 0;
11022
11181
  if (symbol.kind === "root-variable" && symbol.scope !== "default") return void 0;
@@ -11048,7 +11207,7 @@ var uniqueCssDefinitionRule = {
11048
11207
  },
11049
11208
  create(context) {
11050
11209
  const sourceRoot = sourceRootOf(context);
11051
- const current = path75.normalize(path75.resolve(context.filename));
11210
+ const current = path76.normalize(path76.resolve(context.filename));
11052
11211
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11053
11212
  if (cssFiles.length === 0) return {};
11054
11213
  const textOf = cachedTextReader();
@@ -11056,7 +11215,7 @@ var uniqueCssDefinitionRule = {
11056
11215
  sourceRoot,
11057
11216
  css: cssFiles.map((file) => ({
11058
11217
  path: file,
11059
- content: path75.normalize(file) === current ? context.sourceCode.text : textOf(file)
11218
+ content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11060
11219
  })),
11061
11220
  modules: [],
11062
11221
  includeReferences: false
@@ -11078,7 +11237,7 @@ var uniqueCssDefinitionRule = {
11078
11237
  if (!canonical) continue;
11079
11238
  for (const symbol of definitions.slice(1)) {
11080
11239
  if (symbol.file !== current) continue;
11081
- 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.`;
11240
+ 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 ${path76.relative(sourceRoot, canonical.file)}; define it in only one CSS file.`;
11082
11241
  context.report({
11083
11242
  node,
11084
11243
  loc: {
@@ -11095,7 +11254,7 @@ var uniqueCssDefinitionRule = {
11095
11254
  };
11096
11255
 
11097
11256
  // eslint/rules/tailwind/unique-css-token-value.ts
11098
- import path76 from "path";
11257
+ import path77 from "path";
11099
11258
  function valueIdentity(value) {
11100
11259
  const text = value.trim();
11101
11260
  const hex = /^#(?<digits>[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/iu.exec(text)?.groups?.digits;
@@ -11123,14 +11282,14 @@ var uniqueCssTokenValueRule = {
11123
11282
  },
11124
11283
  create(context) {
11125
11284
  const sourceRoot = sourceRootOf(context);
11126
- const current = path76.normalize(path76.resolve(context.filename));
11285
+ const current = path77.normalize(path77.resolve(context.filename));
11127
11286
  const textOf = cachedTextReader();
11128
11287
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11129
11288
  const graph = buildCssDependencyGraph({
11130
11289
  sourceRoot,
11131
11290
  css: cssFiles.map((file) => ({
11132
11291
  path: file,
11133
- content: path76.normalize(file) === current ? context.sourceCode.text : textOf(file)
11292
+ content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11134
11293
  })),
11135
11294
  modules: [],
11136
11295
  includeReferences: false
@@ -11162,7 +11321,7 @@ var uniqueCssTokenValueRule = {
11162
11321
  start: { line: definition.line, column: 1 },
11163
11322
  end: { line: definition.line, column: 2 }
11164
11323
  },
11165
- message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path76.relative(
11324
+ message: `Token "${definition.name}" duplicates the value of "${original.name}" in ${path77.relative(
11166
11325
  sourceRoot,
11167
11326
  original.file
11168
11327
  )}:${String(original.line)}; reuse one design token.`
@@ -11175,7 +11334,7 @@ var uniqueCssTokenValueRule = {
11175
11334
 
11176
11335
  // eslint/rules/tailwind/unused-utility.ts
11177
11336
  import { statSync as statSync5 } from "fs";
11178
- import path77 from "path";
11337
+ import path78 from "path";
11179
11338
  var unusedUtilityRule = {
11180
11339
  meta: {
11181
11340
  schema: [],
@@ -11191,7 +11350,7 @@ var unusedUtilityRule = {
11191
11350
  } catch {
11192
11351
  return {};
11193
11352
  }
11194
- const current = path77.normalize(path77.resolve(context.filename));
11353
+ const current = path78.normalize(path78.resolve(context.filename));
11195
11354
  const textOf = cachedTextReader();
11196
11355
  const cssFiles = findFiles(sourceRoot, CSS_EXTENSIONS);
11197
11356
  const moduleFiles = findFiles(sourceRoot, MODULE_EXTENSIONS4);
@@ -11199,7 +11358,7 @@ var unusedUtilityRule = {
11199
11358
  sourceRoot,
11200
11359
  css: cssFiles.map((file) => ({
11201
11360
  path: file,
11202
- content: path77.normalize(file) === current ? context.sourceCode.text : textOf(file)
11361
+ content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
11203
11362
  })),
11204
11363
  modules: moduleFiles.map((file) => ({ path: file, content: textOf(file) }))
11205
11364
  });
@@ -11221,8 +11380,8 @@ var unusedUtilityRule = {
11221
11380
 
11222
11381
  // eslint/rules/tailwind/utility-mapping.ts
11223
11382
  import { spawnSync } from "child_process";
11224
- import { existsSync as existsSync13 } from "fs";
11225
- import path78 from "path";
11383
+ import { existsSync as existsSync12 } from "fs";
11384
+ import path79 from "path";
11226
11385
  function applyOperationCount(utility, textOf) {
11227
11386
  let count = 0;
11228
11387
  for (const apply of atrulesNamed(utility, "apply")) {
@@ -11549,13 +11708,13 @@ var utilityMappingRule = {
11549
11708
  },
11550
11709
  create(context) {
11551
11710
  const sourceRoot = sourceRootOf(context);
11552
- const current = path78.normalize(path78.resolve(context.filename));
11711
+ const current = path79.normalize(path79.resolve(context.filename));
11553
11712
  const textOf = cachedTextReader();
11554
11713
  const graph = buildCssDependencyGraph({
11555
11714
  sourceRoot,
11556
11715
  css: findFiles(sourceRoot, CSS_EXTENSIONS).map((file) => ({
11557
11716
  path: file,
11558
- content: path78.normalize(file) === current ? context.sourceCode.text : textOf(file)
11717
+ content: path79.normalize(file) === current ? context.sourceCode.text : textOf(file)
11559
11718
  })),
11560
11719
  modules: [],
11561
11720
  includeReferences: false
@@ -11703,8 +11862,8 @@ var utilityMappingRule = {
11703
11862
  const generatorCandidates = utilities.map(
11704
11863
  (utility) => themeCandidate(preludeIdentifiers(utility)[0] ?? "unknown", context.sourceCode.getText(utility))
11705
11864
  ).filter((candidate) => Boolean(candidate && requiresGeneratorProbe(candidate)));
11706
- const physicalDir = path78.dirname(context.physicalFilename);
11707
- const tailwindCwd = path78.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
11865
+ const physicalDir = path79.dirname(context.physicalFilename);
11866
+ const tailwindCwd = path79.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11708
11867
  const themeGenerators = themeSupportedGenerators(generatorCandidates, tailwindCwd);
11709
11868
  for (const utility of utilities) {
11710
11869
  const name = preludeIdentifiers(utility)[0] ?? "unknown";
@@ -11814,9 +11973,9 @@ var utilityMappingRule = {
11814
11973
  // eslint/rules/tailwind/utility-name-parity.ts
11815
11974
  import { spawnSync as spawnSync2 } from "child_process";
11816
11975
  import { createHash } from "crypto";
11817
- import { existsSync as existsSync14 } from "fs";
11818
- import path79 from "path";
11819
- import { generate as generate5, parse as parse8, toPlainObject as toPlainObject3 } from "@eslint/css-tree";
11976
+ import { existsSync as existsSync13 } from "fs";
11977
+ import path80 from "path";
11978
+ import { generate as generate7, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
11820
11979
  function numericPart(value) {
11821
11980
  const match = /^(?<negative>-?)(?<number>(?:\d+(?:\.\d+)?|\.\d+))(?<unit>%|px|rem|em|vw|vh|dvw|dvh|ch|fr|s|ms|deg|turn)?$/u.exec(
11822
11981
  value
@@ -11916,7 +12075,7 @@ function compileApplies(applies, cwd) {
11916
12075
  }
11917
12076
  function compiledOperation(compiled, index) {
11918
12077
  if (!compiled.css) return void 0;
11919
- const sheet = toPlainObject3(parse8(compiled.css, { parseValue: false }));
12078
+ const sheet = toPlainObject2(parse7(compiled.css, { parseValue: false }));
11920
12079
  const probe = rules(sheet).find((candidate) => selectorNames(candidate).includes(`pasika-probe-${String(index)}`));
11921
12080
  if (!probe) return void 0;
11922
12081
  const declarations = blockChildren2(probe).filter(
@@ -11930,10 +12089,10 @@ function compiledOperation(compiled, index) {
11930
12089
  (child) => child.type === "Declaration" && child.property === "--tw-shadow"
11931
12090
  );
11932
12091
  if (shadow?.type === "Declaration") {
11933
- return { property: "box-shadow", value: generate5(shadow.value).trim() };
12092
+ return { property: "box-shadow", value: generate7(shadow.value).trim() };
11934
12093
  }
11935
12094
  }
11936
- return { property: declaration.property, value: generate5(declaration.value).trim() };
12095
+ return { property: declaration.property, value: generate7(declaration.value).trim() };
11937
12096
  }
11938
12097
  function expectedName(operation) {
11939
12098
  const value = compoundValue(operation.value);
@@ -11965,8 +12124,8 @@ var utilityNameParityRule = {
11965
12124
  return apply ? [{ utility, name, apply }] : [];
11966
12125
  });
11967
12126
  if (candidates.length === 0) return;
11968
- const physicalDir = path79.dirname(context.physicalFilename);
11969
- const cwd = path79.isAbsolute(physicalDir) && existsSync14(physicalDir) ? physicalDir : context.cwd;
12127
+ const physicalDir = path80.dirname(context.physicalFilename);
12128
+ const cwd = path80.isAbsolute(physicalDir) && existsSync13(physicalDir) ? physicalDir : context.cwd;
11970
12129
  const compiled = compileApplies(
11971
12130
  candidates.map((candidate) => candidate.apply),
11972
12131
  cwd
@@ -11996,6 +12155,7 @@ var utilityNameParityRule = {
11996
12155
  // eslint/rules/tailwind/index.ts
11997
12156
  var tailwindRules = {
11998
12157
  "theme-reset": themeResetRule,
12158
+ "theme-mode": themeModeRule,
11999
12159
  "color-role-usage": colorRoleUsageRule,
12000
12160
  "root-variables": rootVariablesRule,
12001
12161
  "apply-usage": applyUsageRule,
@@ -12014,7 +12174,7 @@ var tailwindRules = {
12014
12174
  };
12015
12175
 
12016
12176
  // eslint/rules/type-extraction.ts
12017
- import path80 from "path";
12177
+ import path81 from "path";
12018
12178
  var typeExtractionRule = {
12019
12179
  meta: {
12020
12180
  schema: [],
@@ -12025,7 +12185,7 @@ var typeExtractionRule = {
12025
12185
  },
12026
12186
  create(context) {
12027
12187
  const sourceRoot = sourceRootOf(context);
12028
- const file = path80.resolve(context.filename);
12188
+ const file = path81.resolve(context.filename);
12029
12189
  const segments = segmentsOf(file, sourceRoot);
12030
12190
  if (segments.length === 0) return {};
12031
12191
  const index = getProjectIndex(sourceRoot);
@@ -12164,9 +12324,9 @@ var uiStateRule = {
12164
12324
  };
12165
12325
 
12166
12326
  // eslint/rules/unknown-utility.ts
12167
- import { existsSync as existsSync15, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
12327
+ import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync6 } from "fs";
12168
12328
  import { createRequire } from "module";
12169
- import path81 from "path";
12329
+ import path82 from "path";
12170
12330
  var PREFIX_NAMESPACES = {
12171
12331
  bg: ["color", "background-image"],
12172
12332
  text: ["color", "text"],
@@ -12452,7 +12612,7 @@ function stylesheetFiles(dir) {
12452
12612
  }
12453
12613
  return entries.flatMap((entry) => {
12454
12614
  if (entry.startsWith(".") || entry === "node_modules") return [];
12455
- const entryPath = path81.join(dir, entry);
12615
+ const entryPath = path82.join(dir, entry);
12456
12616
  let stats;
12457
12617
  try {
12458
12618
  stats = statSync6(entryPath);
@@ -12460,7 +12620,7 @@ function stylesheetFiles(dir) {
12460
12620
  return [];
12461
12621
  }
12462
12622
  if (stats.isDirectory()) return stylesheetFiles(entryPath);
12463
- return path81.extname(entry) === ".css" ? [entryPath] : [];
12623
+ return path82.extname(entry) === ".css" ? [entryPath] : [];
12464
12624
  });
12465
12625
  }
12466
12626
  function packageNameOf(specifier) {
@@ -12471,24 +12631,24 @@ function packageNameOf(specifier) {
12471
12631
  function resolvePackageStylesheet(fromFile, specifier) {
12472
12632
  const packageName = packageNameOf(specifier);
12473
12633
  if (!packageName || packageName === "tailwindcss") return void 0;
12474
- let directory = path81.dirname(fromFile);
12475
- while (directory !== path81.dirname(directory)) {
12476
- const packageRoot = path81.join(directory, "node_modules", packageName);
12477
- const manifestPath = path81.join(packageRoot, "package.json");
12478
- if (existsSync15(manifestPath)) {
12634
+ let directory = path82.dirname(fromFile);
12635
+ while (directory !== path82.dirname(directory)) {
12636
+ const packageRoot = path82.join(directory, "node_modules", packageName);
12637
+ const manifestPath = path82.join(packageRoot, "package.json");
12638
+ if (existsSync14(manifestPath)) {
12479
12639
  try {
12480
12640
  const manifest = readFileSync15(manifestPath, "utf8");
12481
12641
  const stylesheet = /"style"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
12482
12642
  const main = /"main"\s*:\s*"(?<file>[^"]+\.css)"/.exec(manifest)?.groups?.file;
12483
12643
  const target = stylesheet ?? main;
12484
12644
  if (!target) return void 0;
12485
- const resolved = path81.resolve(packageRoot, target);
12486
- return existsSync15(resolved) ? resolved : void 0;
12645
+ const resolved = path82.resolve(packageRoot, target);
12646
+ return existsSync14(resolved) ? resolved : void 0;
12487
12647
  } catch {
12488
12648
  return void 0;
12489
12649
  }
12490
12650
  }
12491
- directory = path81.dirname(directory);
12651
+ directory = path82.dirname(directory);
12492
12652
  }
12493
12653
  return void 0;
12494
12654
  }
@@ -12760,7 +12920,7 @@ var unknownUtilityRule = {
12760
12920
  };
12761
12921
 
12762
12922
  // eslint/rules/util-file-name.ts
12763
- import path82 from "path";
12923
+ import path83 from "path";
12764
12924
  function toKebabCase2(value) {
12765
12925
  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();
12766
12926
  }
@@ -12773,7 +12933,7 @@ var utilFileNameRule = {
12773
12933
  }
12774
12934
  },
12775
12935
  create(context) {
12776
- const filename = path82.resolve(context.filename);
12936
+ const filename = path83.resolve(context.filename);
12777
12937
  const segments = filename.replace(/\\/g, "/").split("/");
12778
12938
  if (!segments.includes("utils")) return {};
12779
12939
  let module;
@@ -12787,13 +12947,13 @@ var utilFileNameRule = {
12787
12947
  const functionName = functions[0]?.name;
12788
12948
  if (!functionName) return {};
12789
12949
  const expected = toKebabCase2(functionName);
12790
- const actual = path82.basename(filename, path82.extname(filename));
12950
+ const actual = path83.basename(filename, path83.extname(filename));
12791
12951
  if (!expected || actual === expected) return {};
12792
12952
  return {
12793
12953
  Program(node) {
12794
12954
  context.report({
12795
12955
  node,
12796
- message: `A utility file exporting ${functionName} must be named ${expected}.${path82.extname(filename).slice(1)}.`
12956
+ message: `A utility file exporting ${functionName} must be named ${expected}.${path83.extname(filename).slice(1)}.`
12797
12957
  });
12798
12958
  }
12799
12959
  };
@@ -12801,7 +12961,7 @@ var utilFileNameRule = {
12801
12961
  };
12802
12962
 
12803
12963
  // eslint/rules/value-extraction.ts
12804
- import path83 from "path";
12964
+ import path84 from "path";
12805
12965
  var valueExtractionRule = {
12806
12966
  meta: {
12807
12967
  schema: [],
@@ -12812,7 +12972,7 @@ var valueExtractionRule = {
12812
12972
  },
12813
12973
  create(context) {
12814
12974
  const sourceRoot = sourceRootOf(context);
12815
- const file = path83.resolve(context.filename);
12975
+ const file = path84.resolve(context.filename);
12816
12976
  const segments = segmentsOf(file, sourceRoot);
12817
12977
  if (segments.length === 0 || segments[0] !== "app") return {};
12818
12978
  const index = getProjectIndex(sourceRoot);
@@ -12833,8 +12993,8 @@ var valueExtractionRule = {
12833
12993
  };
12834
12994
 
12835
12995
  // eslint/rules/vulyk/tracked-docs.ts
12836
- import { existsSync as existsSync16, readFileSync as readFileSync16 } from "fs";
12837
- import path84 from "path";
12996
+ import { existsSync as existsSync15, readFileSync as readFileSync16 } from "fs";
12997
+ import path85 from "path";
12838
12998
  var PASIKA_REPO = "Bredansky/pasika";
12839
12999
  var BASE_REQUIRED_TRACKED_DOCS = [
12840
13000
  { name: "documentation-guide", path: "docs/documentation-guide" },
@@ -12867,9 +13027,9 @@ var trackedDocsRule = {
12867
13027
  if (!context.filename.endsWith("package.json")) return;
12868
13028
  const root = node.body;
12869
13029
  if (root.type !== "Object") return;
12870
- const projectRoot = path84.dirname(path84.resolve(context.filename));
12871
- const configPath = path84.join(projectRoot, "vulyk.config.ts");
12872
- if (!existsSync16(configPath)) {
13030
+ const projectRoot = path85.dirname(path85.resolve(context.filename));
13031
+ const configPath = path85.join(projectRoot, "vulyk.config.ts");
13032
+ if (!existsSync15(configPath)) {
12873
13033
  context.report({
12874
13034
  node,
12875
13035
  message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's required tracked docs."
@@ -12893,8 +13053,8 @@ var trackedDocsRule = {
12893
13053
  });
12894
13054
  }
12895
13055
  }
12896
- const agentsPath = path84.join(projectRoot, "AGENTS.md");
12897
- if (!existsSync16(agentsPath)) {
13056
+ const agentsPath = path85.join(projectRoot, "AGENTS.md");
13057
+ if (!existsSync15(agentsPath)) {
12898
13058
  context.report({
12899
13059
  node,
12900
13060
  message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
@@ -12993,7 +13153,7 @@ var withResponseHelperRule = {
12993
13153
 
12994
13154
  // eslint/rules/zirka-baseline.ts
12995
13155
  import fs7 from "fs";
12996
- import path85 from "path";
13156
+ import path86 from "path";
12997
13157
  var ESLINT_CONFIG = /^eslint\.config\.(?:ts|mts|cts|js|mjs|cjs)$/;
12998
13158
  var PRETTIER_CONFIGS = [
12999
13159
  "prettier.config.mjs",
@@ -13012,10 +13172,10 @@ var zirkaBaselineRule = {
13012
13172
  }
13013
13173
  },
13014
13174
  create(context) {
13015
- const filename = path85.resolve(context.filename);
13016
- const basename = path85.basename(filename);
13175
+ const filename = path86.resolve(context.filename);
13176
+ const basename = path86.basename(filename);
13017
13177
  if (!ESLINT_CONFIG.test(basename)) return {};
13018
- const projectRoot = path85.dirname(filename);
13178
+ const projectRoot = path86.dirname(filename);
13019
13179
  const report3 = (message) => {
13020
13180
  context.report({
13021
13181
  node: context.sourceCode.ast,
@@ -13030,7 +13190,7 @@ var zirkaBaselineRule = {
13030
13190
  'ESLint config must take its configuration from zirka (import { styleguide } from "zirka") instead of restating rules locally.'
13031
13191
  );
13032
13192
  }
13033
- const tsconfigPath = path85.join(projectRoot, "tsconfig.json");
13193
+ const tsconfigPath = path86.join(projectRoot, "tsconfig.json");
13034
13194
  if (!fs7.existsSync(tsconfigPath)) {
13035
13195
  report3('No tsconfig.json found. Create one extending the zirka TypeScript base config ("zirka/typescript").');
13036
13196
  } else {
@@ -13048,13 +13208,13 @@ var zirkaBaselineRule = {
13048
13208
  report3('tsconfig.json must extend the zirka TypeScript base config ("zirka/typescript").');
13049
13209
  }
13050
13210
  }
13051
- const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path85.join(projectRoot, name)));
13211
+ const prettierConfigFile = PRETTIER_CONFIGS.find((name) => fs7.existsSync(path86.join(projectRoot, name)));
13052
13212
  if (!prettierConfigFile) {
13053
13213
  report3(
13054
13214
  "No prettier config found. Create one that takes its configuration from zirka (styleguide({ prettier: true }).prettierConfig)."
13055
13215
  );
13056
13216
  } else {
13057
- const content = fs7.readFileSync(path85.join(projectRoot, prettierConfigFile), "utf8");
13217
+ const content = fs7.readFileSync(path86.join(projectRoot, prettierConfigFile), "utf8");
13058
13218
  if (!content.includes("zirka")) {
13059
13219
  report3(
13060
13220
  "The prettier config must take its configuration from zirka (styleguide({ prettier: true }).prettierConfig) instead of restating it locally."
@@ -13390,7 +13550,7 @@ var tailwindStructureRules = {
13390
13550
  languageOptions: { tolerant: true },
13391
13551
  rules: Object.fromEntries(
13392
13552
  tailwindRuleIds.filter(
13393
- (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"
13553
+ (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" && id !== "pasika/theme-mode"
13394
13554
  ).map((id) => [id, "error"])
13395
13555
  )
13396
13556
  };
@@ -13411,7 +13571,8 @@ var tailwindImportGraph = {
13411
13571
  "pasika/utility-name-parity": "error",
13412
13572
  "pasika/no-utility-alias": "error",
13413
13573
  "pasika/root-variables": "error",
13414
- "pasika/color-role-usage": "error"
13574
+ "pasika/color-role-usage": "error",
13575
+ "pasika/theme-mode": "error"
13415
13576
  }
13416
13577
  };
13417
13578
  var pasikaAppPackageJsonConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.130",
3
+ "version": "0.10.131",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",