pasika 0.10.131 → 0.10.133

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.
@@ -120,6 +120,7 @@ declare const nextjsPackageJsonRules: {
120
120
  };
121
121
 
122
122
  declare const tailwindRules: {
123
+ "at-rule-spacing": _eslint_css.CSSRuleDefinition;
123
124
  "theme-reset": _eslint_css.CSSRuleDefinition;
124
125
  "theme-mode": _eslint_css.CSSRuleDefinition;
125
126
  "color-role-usage": _eslint_css.CSSRuleDefinition;
@@ -161,6 +162,7 @@ declare const pasikaPlugin: {
161
162
  "exact-version": _eslint_json.JSONRuleDefinition;
162
163
  "lint-setup": _eslint_json.JSONRuleDefinition;
163
164
  "vitest-coverage": _eslint_json.JSONRuleDefinition;
165
+ "at-rule-spacing": _eslint_css.CSSRuleDefinition;
164
166
  "theme-reset": _eslint_css.CSSRuleDefinition;
165
167
  "theme-mode": _eslint_css.CSSRuleDefinition;
166
168
  "color-role-usage": _eslint_css.CSSRuleDefinition;
@@ -9720,6 +9720,46 @@ var applyUsageRule = {
9720
9720
  }
9721
9721
  };
9722
9722
 
9723
+ // eslint/rules/tailwind/at-rule-spacing.ts
9724
+ var EMPTY_LINE = /\n[ \t]*\n/u;
9725
+ var LINE_BREAK = /\r\n|\n|\r/u;
9726
+ var atRuleSpacingRule = {
9727
+ meta: {
9728
+ schema: [],
9729
+ type: "layout",
9730
+ fixable: "whitespace",
9731
+ docs: {
9732
+ description: "Require a blank line between adjacent top-level CSS at-rules, excluding grouped imports."
9733
+ }
9734
+ },
9735
+ create(context) {
9736
+ return {
9737
+ "StyleSheet:exit"(node) {
9738
+ const source = context.sourceCode.text;
9739
+ const newline = source.includes("\r\n") ? "\r\n" : "\n";
9740
+ for (let index = 1; index < node.children.length; index += 1) {
9741
+ const previous = node.children[index - 1];
9742
+ const current = node.children[index];
9743
+ if (previous?.type !== "Atrule" || current?.type !== "Atrule") continue;
9744
+ if (previous.name === "import" && current.name === "import") continue;
9745
+ if (!previous.loc || !current.loc) continue;
9746
+ const start = previous.loc.end.offset;
9747
+ const end = current.loc.start.offset;
9748
+ const between = source.slice(start, end);
9749
+ if (EMPTY_LINE.test(between.replace(/\r\n|\r/gu, "\n"))) continue;
9750
+ context.report({
9751
+ node: current,
9752
+ message: "Adjacent top-level @ rules must have a blank line between them.",
9753
+ fix(fixer) {
9754
+ return fixer.insertTextBeforeRange([end, end], LINE_BREAK.test(between) ? newline : newline + newline);
9755
+ }
9756
+ });
9757
+ }
9758
+ }
9759
+ };
9760
+ }
9761
+ };
9762
+
9723
9763
  // eslint/rules/tailwind/base-layer-pair.ts
9724
9764
  import { existsSync as existsSync8 } from "fs";
9725
9765
  import path66 from "path";
@@ -11542,6 +11582,27 @@ function singleCssFunction(value) {
11542
11582
  const args = value.slice(match[0].length, -1).trim();
11543
11583
  return args ? { name, args } : void 0;
11544
11584
  }
11585
+ function gradientOnlyBackground(value) {
11586
+ if (!value || /[;{}'"\\]/u.test(value)) return false;
11587
+ const layers = [];
11588
+ let depth = 0;
11589
+ let start = 0;
11590
+ for (let index = 0; index < value.length; index++) {
11591
+ if (value[index] === "(") depth++;
11592
+ if (value[index] === ")") depth--;
11593
+ if (depth < 0) return false;
11594
+ if (value[index] === "," && depth === 0) {
11595
+ layers.push(value.slice(start, index).trim());
11596
+ start = index + 1;
11597
+ }
11598
+ }
11599
+ if (depth !== 0) return false;
11600
+ layers.push(value.slice(start).trim());
11601
+ return layers.every((layer) => {
11602
+ const fn = singleCssFunction(layer);
11603
+ return fn !== void 0 && /^(?:repeating-)?(?:linear|radial|conic)-gradient$/u.test(fn.name);
11604
+ });
11605
+ }
11545
11606
  function boxShadowNamespace(value) {
11546
11607
  const layers = [];
11547
11608
  let depth = 0;
@@ -11604,7 +11665,9 @@ function themeCandidate(name, utilityText) {
11604
11665
  if (!cssValue) return void 0;
11605
11666
  const namedOperation = arbitraryApply?.groups?.prefix ? arbitraryApplyOperation(arbitraryApply.groups.prefix, cssValue) : void 0;
11606
11667
  if (arbitraryApply && !namedOperation) return void 0;
11607
- const property = arbitrary?.groups?.property ?? direct?.groups?.property ?? namedOperation?.property;
11668
+ const declaredProperty = arbitrary?.groups?.property ?? direct?.groups?.property ?? namedOperation?.property;
11669
+ const gradientShorthand = declaredProperty === "background" && gradientOnlyBackground(cssValue);
11670
+ const property = gradientShorthand ? "background-image" : declaredProperty;
11608
11671
  const functionValue = property === "filter" || property === "backdrop-filter" ? singleCssFunction(cssValue) : void 0;
11609
11672
  const shadowNamespace = property === "box-shadow" ? boxShadowNamespace(cssValue) : void 0;
11610
11673
  if (property === "box-shadow" && !shadowNamespace) return void 0;
@@ -11640,7 +11703,8 @@ function themeCandidate(name, utilityText) {
11640
11703
  value,
11641
11704
  prefix: matched.prefix,
11642
11705
  namespace: matched.namespace,
11643
- probe: Boolean(arbitraryApply) || matched.property === "transition-property"
11706
+ probe: Boolean(arbitraryApply) || matched.property === "transition-property",
11707
+ gradientShorthand
11644
11708
  };
11645
11709
  }
11646
11710
  var builtInTextSizes = /* @__PURE__ */ new Set([
@@ -11679,6 +11743,9 @@ function isTypographySize(name) {
11679
11743
  return /^--text-(?!.*--)(?:[a-z0-9]+-)*[a-z0-9]+$/u.test(name);
11680
11744
  }
11681
11745
  function suggestedThemeToken(candidate) {
11746
+ if (candidate.namespace === "background-image") {
11747
+ return candidate.token.endsWith("-canvas") ? candidate.token : `${candidate.token}-canvas`;
11748
+ }
11682
11749
  if (candidate.namespace !== "color") return candidate.token;
11683
11750
  let role = "edge";
11684
11751
  if (["bg", "fill"].includes(candidate.prefix)) {
@@ -11696,7 +11763,8 @@ function themeMigrationGuidance(candidate, utilityName) {
11696
11763
  const runtimeDependent = /\bvar\s*\(/iu.test(candidate.value);
11697
11764
  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. `;
11698
11765
  const classGuidance = generatedClass === utilityName ? "Preserve the generated class name" : `Update class usages to "${generatedClass}"`;
11699
- return `${action}${classGuidance} and compare compiled CSS before removing the utility.`;
11766
+ const resetWarning = candidate.gradientShorthand ? " Replacing the background shorthand with background-image stops resetting other background properties; verify cascade and rendering." : "";
11767
+ return `${action}${classGuidance} and compare compiled CSS before removing the utility.${resetWarning}`;
11700
11768
  }
11701
11769
  var utilityMappingRule = {
11702
11770
  meta: {
@@ -11889,7 +11957,7 @@ var utilityMappingRule = {
11889
11957
  if (candidate && equivalent && nameCounts.get(name) === 1) {
11890
11958
  context.report({
11891
11959
  node: utility,
11892
- message: `Custom utility "${name}" duplicates theme-generated "${equivalent}" (${candidate.property}: ${candidate.value}); reuse "${equivalent}" instead.`
11960
+ message: `Custom utility "${name}" duplicates theme-generated "${equivalent}" (${candidate.property}: ${candidate.value}); reuse "${equivalent}" instead.${candidate.gradientShorthand ? " Check background shorthand reset behavior before switching to background-image." : ""}`
11893
11961
  });
11894
11962
  continue;
11895
11963
  }
@@ -11905,7 +11973,7 @@ var utilityMappingRule = {
11905
11973
  if (!candidate.token) {
11906
11974
  context.report({
11907
11975
  node: utility,
11908
- 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.${candidate.property === "box-shadow" ? " Compare compiled CSS and ring/inset-shadow composition before migration." : ""}`
11976
+ message: `Custom utility "${name}" only maps ${candidate.property} (${candidate.value}); define ${candidate.gradientShorthand ? "a semantic" : "an"} @theme token in the "--${candidate.namespace}-*${candidate.gradientShorthand ? "-canvas" : ""}" namespace and use its generated "${candidate.prefix}-*" class instead.${candidate.property === "box-shadow" ? " Compare compiled CSS and ring/inset-shadow composition before migration." : ""}${candidate.gradientShorthand ? " Check background shorthand reset behavior before switching to background-image." : ""}`
11909
11977
  });
11910
11978
  continue;
11911
11979
  }
@@ -11972,7 +12040,6 @@ var utilityMappingRule = {
11972
12040
 
11973
12041
  // eslint/rules/tailwind/utility-name-parity.ts
11974
12042
  import { spawnSync as spawnSync2 } from "child_process";
11975
- import { createHash } from "crypto";
11976
12043
  import { existsSync as existsSync13 } from "fs";
11977
12044
  import path80 from "path";
11978
12045
  import { generate as generate7, parse as parse7, toPlainObject as toPlainObject2 } from "@eslint/css-tree";
@@ -12014,14 +12081,6 @@ function readableValue(value) {
12014
12081
  const slug = parts.join("-");
12015
12082
  return slug.length <= 70 ? slug : void 0;
12016
12083
  }
12017
- function compoundValue(value) {
12018
- const readable = readableValue(value);
12019
- if (readable) return readable;
12020
- const candidate = /^(?<fn>[a-z][a-z0-9-]*)\(/iu.exec(value.trim())?.groups?.fn?.toLowerCase();
12021
- const hint = candidate?.endsWith("-") ? void 0 : candidate;
12022
- const digest = createHash("sha256").update(value.trim()).digest("hex").slice(0, 12);
12023
- return [hint, "hash", digest].filter(Boolean).join("-");
12024
- }
12025
12084
  var TAILWIND_WORKER = String.raw`
12026
12085
  import { readFileSync } from "node:fs";
12027
12086
  import { compile } from "tailwindcss";
@@ -12095,7 +12154,8 @@ function compiledOperation(compiled, index) {
12095
12154
  return { property: declaration.property, value: generate7(declaration.value).trim() };
12096
12155
  }
12097
12156
  function expectedName(operation) {
12098
- const value = compoundValue(operation.value);
12157
+ const value = readableValue(operation.value);
12158
+ if (!value) return void 0;
12099
12159
  const property = operation.property.replace(/^-+/u, "").replace(/^background-/u, "bg-");
12100
12160
  return `${property}-${value}`;
12101
12161
  }
@@ -12111,7 +12171,7 @@ var utilityNameParityRule = {
12111
12171
  schema: [],
12112
12172
  type: "problem",
12113
12173
  docs: {
12114
- description: "Require single-operation custom utilities to have deterministic property/value-derived names."
12174
+ description: "Use property/value-derived names for readable values and semantic names for complex values."
12115
12175
  }
12116
12176
  },
12117
12177
  create(context) {
@@ -12141,6 +12201,15 @@ var utilityNameParityRule = {
12141
12201
  continue;
12142
12202
  }
12143
12203
  const expected = expectedName(operation);
12204
+ if (!expected) {
12205
+ if (/-hash-[a-f0-9]{12}$/u.test(candidate.name)) {
12206
+ context.report({
12207
+ node: candidate.utility,
12208
+ message: `Custom utility "${candidate.name}" uses an opaque hash for a complex ${operation.property} value; use a semantic name, or prefer a theme-generated utility where supported.`
12209
+ });
12210
+ }
12211
+ continue;
12212
+ }
12144
12213
  if (candidate.name === expected) continue;
12145
12214
  context.report({
12146
12215
  node: candidate.utility,
@@ -12154,6 +12223,7 @@ var utilityNameParityRule = {
12154
12223
 
12155
12224
  // eslint/rules/tailwind/index.ts
12156
12225
  var tailwindRules = {
12226
+ "at-rule-spacing": atRuleSpacingRule,
12157
12227
  "theme-reset": themeResetRule,
12158
12228
  "theme-mode": themeModeRule,
12159
12229
  "color-role-usage": colorRoleUsageRule,
@@ -13563,6 +13633,7 @@ var tailwindImportGraph = {
13563
13633
  language: "css/css",
13564
13634
  languageOptions: { tolerant: true },
13565
13635
  rules: {
13636
+ "pasika/at-rule-spacing": "error",
13566
13637
  "pasika/css-entry-point": "error",
13567
13638
  "pasika/feature-css-placement": "error",
13568
13639
  "pasika/unique-css-definition": "error",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.131",
3
+ "version": "0.10.133",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",