synthesisui 0.9.1 → 0.10.0

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.
@@ -147,11 +147,25 @@ function meter(pct, width = 24) {
147
147
  const filled = Math.round((pct / 100) * width);
148
148
  return `${"█".repeat(filled)}${"░".repeat(width - filled)}`;
149
149
  }
150
- function verdict(d, hasSystem, overruled) {
150
+ function verdict(d, hasSystem, overruled, conflicts) {
151
+ // A system at war with itself outranks every other number here. The closing
152
+ // line is the one people quote, and it used to end on "6 of 14 have a name"
153
+ // while the page above it said the recipe contradicts its own law.
154
+ const head = conflicts > 0
155
+ ? [
156
+ body(conflicts === 1
157
+ ? "First, above everything: your system contradicts itself in one place."
158
+ : `First, above everything: your system contradicts itself in ${conflicts} places.`),
159
+ body("A law says one thing and the recipe under it does another, and"),
160
+ body("no code can be correct against a rule that disagrees with itself."),
161
+ "",
162
+ ]
163
+ : [];
151
164
  // Nothing found and nothing installed: a utility package, a config folder,
152
165
  // the wrong directory. Selling a design system here would be noise.
153
166
  if (!hasSystem && d.findings.length === 0) {
154
167
  return [
168
+ ...head,
155
169
  body("No design values are written by hand here, and no system is"),
156
170
  body("installed. Nothing to fix, and nothing to compare against."),
157
171
  ];
@@ -159,6 +173,7 @@ function verdict(d, hasSystem, overruled) {
159
173
  if (!hasSystem) {
160
174
  const distinct = new Set(d.findings.map((f) => f.literal.toLowerCase()));
161
175
  return [
176
+ ...head,
162
177
  body(`${distinct.size} distinct design values are written by hand here.`),
163
178
  body("No design system is installed, so none of them has a name yet."),
164
179
  "",
@@ -169,6 +184,7 @@ function verdict(d, hasSystem, overruled) {
169
184
  }
170
185
  if (d.findings.length === 0 && overruled === 0) {
171
186
  return [
187
+ ...head,
172
188
  body("No drift. Every design value in this project comes from the"),
173
189
  body("system. That is a rarer sentence than it sounds."),
174
190
  ];
@@ -177,6 +193,7 @@ function verdict(d, hasSystem, overruled) {
177
193
  // "no drift" is a report nobody believes twice.
178
194
  if (d.findings.length === 0) {
179
195
  return [
196
+ ...head,
180
197
  body("No loose values - everything is a token."),
181
198
  body(overruled === 1
182
199
  ? "But one place takes a component the system defines and"
@@ -188,6 +205,7 @@ function verdict(d, hasSystem, overruled) {
188
205
  ];
189
206
  }
190
207
  const lines = [
208
+ ...head,
191
209
  body(`${d.named} of ${d.findings.length} already have a name in your system.`),
192
210
  body("Those are the cheap ones: swap the literal for the token."),
193
211
  ];
@@ -362,9 +380,33 @@ export async function doctor(opts) {
362
380
  };
363
381
  const drifting = overrides.filter((o) => lawKept(o) === null);
364
382
  const correcting = overrides.length - drifting.length;
383
+ /**
384
+ * Two very different acts wearing one label. Choosing a DIFFERENT token
385
+ * from the system is a decision inside the vocabulary - the recipe says
386
+ * surface, the author wanted raised, and both are the system's words.
387
+ * Writing `#fff` leaves the system entirely. Reporting them identically
388
+ * buried the ones that matter (investidorez, 25/07).
389
+ */
390
+ const onSystem = (o) => {
391
+ if (o.wrote.includes("var(--ds-"))
392
+ return true;
393
+ // a utility whose step exists in the scale - `gap-2xs` when the project
394
+ // has --ds-spacing-2xs - is the scale being used, just at another step
395
+ const step = /-([a-z0-9]+)$/.exec(o.wrote);
396
+ if (!step || o.wrote.includes("["))
397
+ return false;
398
+ for (const name of table.byName.keys()) {
399
+ if (name.endsWith(`-${step[1]}`))
400
+ return true;
401
+ }
402
+ return false;
403
+ };
404
+ const offSystem = drifting.filter((o) => !onSystem(o)).length;
365
405
  console.log(section("Overruled"));
366
406
  console.log(body(`${drifting.length} place${drifting.length === 1 ? "" : "s"} where the code takes a component`));
367
407
  console.log(body("the system defines, and then overrules it locally."));
408
+ console.log("");
409
+ console.log(body(`${offSystem} of them leave the system entirely; the rest pick a different token.`));
368
410
  if (correcting > 0) {
369
411
  console.log("");
370
412
  console.log(body(correcting === 1
@@ -392,6 +434,9 @@ export async function doctor(opts) {
392
434
  console.log(` the recipe binds ${o.recipe}`);
393
435
  else if (o.where)
394
436
  console.log(` the recipe binds it ${o.where}`);
437
+ if (!onSystem(o) && lawKept(o) === null) {
438
+ console.log(" ↑ a raw value, not a token");
439
+ }
395
440
  const kept = lawKept(o);
396
441
  if (kept) {
397
442
  console.log(` ✓ but the law says: "${kept}"`);
@@ -434,7 +479,7 @@ export async function doctor(opts) {
434
479
  }
435
480
  }
436
481
  console.log(section("What this means"));
437
- for (const line of verdict(d, hasSystem, overrides.length))
482
+ for (const line of verdict(d, hasSystem, overrides.length, conflictsInUse.length))
438
483
  console.log(line);
439
484
  console.log("");
440
485
  if (opts.strict && (d.findings.length > 0 || overrides.length > 0))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
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": {