pasika 0.10.110 → 0.10.111

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.
@@ -10375,24 +10375,72 @@ function applyOperationCount(utility) {
10375
10375
  }
10376
10376
  return count;
10377
10377
  }
10378
+ function themeCandidate(name, utilityText) {
10379
+ const match = /^@utility\s+[\w-]+\s*\{\s*@apply\s+\[(?<property>font-size|letter-spacing):(?<value>[^\]\r\n;{}]+)\];?\s*\}$/u.exec(
10380
+ utilityText.trim()
10381
+ );
10382
+ if (!match) return void 0;
10383
+ const property = match.groups?.property;
10384
+ const value = match.groups?.value?.trim();
10385
+ if (!property || !value) return void 0;
10386
+ const prefix = property === "font-size" ? "text-" : "tracking-";
10387
+ if (!name.startsWith(prefix) || name.length === prefix.length) return void 0;
10388
+ const length = /^-?(?:\d+(?:\.\d+)?|\.\d+)(?:px|rem|em|%)$/u.test(value);
10389
+ const variable = /^var\(--[a-z][a-z0-9-]*\)$/u.test(value);
10390
+ if (!length && !variable) return void 0;
10391
+ if (property === "font-size" && value.startsWith("-")) return void 0;
10392
+ return { token: `--${name}`, property, value };
10393
+ }
10378
10394
  var utilityMappingRule = {
10379
10395
  meta: {
10380
- schema: [],
10396
+ schema: [
10397
+ {
10398
+ type: "object",
10399
+ properties: { preferThemeTokens: { type: "boolean" } },
10400
+ additionalProperties: false
10401
+ }
10402
+ ],
10381
10403
  type: "problem",
10382
10404
  docs: {
10383
- description: "Require custom utilities to map exactly one Tailwind styling operation."
10405
+ description: "Require one styling operation per custom utility; optionally suggest theme-generated utilities."
10384
10406
  }
10385
10407
  },
10386
10408
  create(context) {
10409
+ const option = context.options[0];
10410
+ const preferThemeTokens = typeof option === "object" && option !== null && "preferThemeTokens" in option && option.preferThemeTokens === true;
10387
10411
  return {
10388
10412
  "StyleSheet:exit"(node) {
10389
- for (const utility of atrulesNamed(node, "utility")) {
10413
+ const utilities = atrulesNamed(node, "utility");
10414
+ const themeTokens = /* @__PURE__ */ new Set();
10415
+ const nameCounts = /* @__PURE__ */ new Map();
10416
+ if (preferThemeTokens) {
10417
+ for (const theme of atrulesNamed(node, "theme")) {
10418
+ for (const child of blockChildren2(theme)) {
10419
+ if (child.type === "Declaration") themeTokens.add(child.property);
10420
+ }
10421
+ }
10422
+ for (const utility of utilities) {
10423
+ const name = preludeIdentifiers(utility)[0] ?? "";
10424
+ nameCounts.set(name, (nameCounts.get(name) ?? 0) + 1);
10425
+ }
10426
+ }
10427
+ for (const utility of utilities) {
10390
10428
  const name = preludeIdentifiers(utility)[0] ?? "unknown";
10391
10429
  const operationCount = applyOperationCount(utility);
10392
- if (operationCount === 1) continue;
10430
+ if (operationCount !== 1) {
10431
+ context.report({
10432
+ node: utility,
10433
+ message: `Custom utility "${name}" maps ${String(operationCount)} Tailwind operations; custom utilities must map exactly one operation. Reusable presentation belongs in a component.`
10434
+ });
10435
+ continue;
10436
+ }
10437
+ if (!preferThemeTokens || nameCounts.get(name) !== 1) continue;
10438
+ const candidate = themeCandidate(name, context.sourceCode.getText(utility));
10439
+ if (!candidate || themeTokens.has(candidate.token)) continue;
10440
+ if (candidate.property === "font-size" && themeTokens.has(`--color-${name.slice(5)}`)) continue;
10393
10441
  context.report({
10394
10442
  node: utility,
10395
- message: `Custom utility "${name}" maps ${String(operationCount)} Tailwind operations; custom utilities must map exactly one operation. Reusable presentation belongs in a component.`
10443
+ 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.`
10396
10444
  });
10397
10445
  }
10398
10446
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.110",
3
+ "version": "0.10.111",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",