synthesisui 0.11.1 → 0.11.3

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.
@@ -266,7 +266,9 @@ export async function doctor(opts) {
266
266
  for (const r of reports) {
267
267
  if (!r.setAside)
268
268
  continue;
269
- aside.set(r.setAside.reason, (aside.get(r.setAside.reason) ?? 0) + r.setAside.count);
269
+ for (const a of r.setAside) {
270
+ aside.set(a.reason, (aside.get(a.reason) ?? 0) + a.count);
271
+ }
270
272
  }
271
273
  for (const [reason, count] of aside) {
272
274
  console.log(body(`set aside: ${count} value(s) in ${reason}`));
@@ -375,6 +377,7 @@ export async function doctor(opts) {
375
377
  console.log(body("complains - the surface just stays put when the scheme"));
376
378
  console.log(body("moves around it."));
377
379
  }
380
+ const frozenAt = new Set(frozen.map((f) => `${f.component}:${f.where.split(" · ").pop()}`));
378
381
  if (overrides.length > 0) {
379
382
  // An override on a property the component's own law FORBIDS, written as a
380
383
  // reset, is not drift - it is the author keeping a promise the recipe
@@ -465,6 +468,13 @@ export async function doctor(opts) {
465
468
  ? " ↑ removes it rather than replacing it"
466
469
  : " ↑ a raw value, not a token");
467
470
  }
471
+ // The recipe froze this binding at a primitive and the author reached
472
+ // for a ROLE. Theirs follows the scheme; the recipe's does not. Listing
473
+ // that as an infraction is the same unfairness as the law case above.
474
+ if (frozenAt.has(`${o.component}:${o.prop}`) &&
475
+ /var\(\s*--ds-color-semantic-/.test(o.wrote)) {
476
+ console.log(" ✓ the recipe is frozen here; yours names a role");
477
+ }
468
478
  const kept = lawKept(o);
469
479
  if (kept) {
470
480
  console.log(` ✓ but the law says: "${kept}"`);
@@ -60,16 +60,21 @@ const IDIOM = new Set(["0", "0px", "1px", "9999px", "100%", "50%"]);
60
60
  export function scanSource(file, source, table) {
61
61
  const findings = [];
62
62
  let tokenUses = 0;
63
- let aside = 0;
63
+ // Reason by reason. Rolling two into "A or B" was the one place the report
64
+ // still lumped things it had told apart everywhere else.
65
+ const aside = new Map();
66
+ const setAside = (reason) => aside.set(reason, (aside.get(reason) ?? 0) + 1);
64
67
  if (RENDERS_IMAGE.test(source)) {
65
68
  return {
66
69
  file,
67
70
  findings: [],
68
71
  tokenUses: 0,
69
- setAside: {
70
- reason: "renders to an image, where CSS variables do not exist",
71
- count: (source.match(COLOR) ?? []).length,
72
- },
72
+ setAside: [
73
+ {
74
+ reason: "renders to an image, where CSS variables do not exist",
75
+ count: (source.match(COLOR) ?? []).length,
76
+ },
77
+ ],
73
78
  };
74
79
  }
75
80
  let svgDepth = 0;
@@ -101,7 +106,7 @@ export function scanSource(file, source, table) {
101
106
  if (literal.includes("$") || literal.includes("{"))
102
107
  return;
103
108
  if (col >= 0 && inFallback(col)) {
104
- aside++;
109
+ setAside("a token's own fallback");
105
110
  return;
106
111
  }
107
112
  const key = `${kind}:${literal}`;
@@ -123,7 +128,7 @@ export function scanSource(file, source, table) {
123
128
  (before.match(/<\/svg>/g) ?? []).length;
124
129
  // inside an <svg>, a colour on fill= or stroke= is paint, not surface
125
130
  if (depthHere > 0 && SVG_PAINT.test(before)) {
126
- aside++;
131
+ setAside("SVG artwork");
127
132
  continue;
128
133
  }
129
134
  push("color", m[0], m.index ?? -1);
@@ -150,12 +155,9 @@ export function scanSource(file, source, table) {
150
155
  file,
151
156
  findings,
152
157
  tokenUses,
153
- ...(aside > 0
158
+ ...(aside.size > 0
154
159
  ? {
155
- setAside: {
156
- reason: "SVG artwork or a token's own fallback",
157
- count: aside,
158
- },
160
+ setAside: [...aside].map(([reason, count]) => ({ reason, count })),
159
161
  }
160
162
  : null),
161
163
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.11.1",
3
+ "version": "0.11.3",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {