synthesisui 0.16.52 → 0.16.54

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.
@@ -291,10 +291,37 @@ export async function takeCensus(root) {
291
291
  }
292
292
  const d = diagnose(reports);
293
293
  const inventory = tallyToInventory(tally);
294
+ /**
295
+ * THE TWO READINGS BECOME ONE LIST before anything is judged.
296
+ *
297
+ * The crosswalk saw only what a project COMPOSES, so a library's report said
298
+ * "only yours (4)" three lines above "37 components exported here" - the two
299
+ * sections talking past each other (dono, 31/07). Worse, the contracts that
300
+ * travel are picked from that list, so a library would have sent four.
301
+ *
302
+ * A component that is defined and never composed here is still a component:
303
+ * in a library that is the entire point. Its axes come from the TYPE, which
304
+ * is the better source anyway - usage shows what somebody picked, the
305
+ * declaration shows what the author designed.
306
+ */
307
+ const composed = new Set(inventory.map((c) => c.name));
308
+ const fromTypes = defined
309
+ .filter((d) => !composed.has(d.name))
310
+ .map((d) => ({
311
+ name: d.name,
312
+ count: 0,
313
+ files: 0,
314
+ props: {
315
+ ...Object.fromEntries(Object.entries(d.axes)),
316
+ ...Object.fromEntries(d.flags.map((f) => [f, ["true"]])),
317
+ },
318
+ propFiles: {},
319
+ }));
320
+ const merged = [...inventory, ...fromTypes];
294
321
  // The verdict travels WITH the payload: the platform reads one reading rather
295
322
  // than computing a second opinion from the same numbers, which is how two
296
323
  // implementations of the same judgement start disagreeing.
297
- const verdicts = new Map(crosswalk(inventory).map((r) => [
324
+ const verdicts = new Map(crosswalk(merged).map((r) => [
298
325
  r.component.name,
299
326
  { bucket: r.bucket, canonical: r.canonical, because: r.because },
300
327
  ]));
@@ -302,7 +329,7 @@ export async function takeCensus(root) {
302
329
  for (const r of observedRules(inventory)) {
303
330
  laws.set(r.component, [...(laws.get(r.component) ?? []), r.text]);
304
331
  }
305
- const components = inventory.map((c) => ({
332
+ const components = merged.map((c) => ({
306
333
  ...c,
307
334
  ...(verdicts.get(c.name) ?? {}),
308
335
  ...(laws.has(c.name) ? { laws: laws.get(c.name) } : {}),
@@ -361,9 +388,13 @@ function summarize(c) {
361
388
  // The inventory, phase one: what this project composes. Printed, never
362
389
  // mapped - deciding that their `Pill` is our `ds-badge` is a judgement a
363
390
  // person approves, and it does not happen in a census.
364
- if (c.components && c.components.length > 0) {
365
- const withProps = c.components.filter((x) => Object.keys(x.props).length > 0).length;
366
- console.log(body(`${c.components.length} components composed here, ${withProps} of them with props written literally`));
391
+ // COMPOSED means composed. The payload also carries components that are only
392
+ // DECLARED (a library exports what it never uses), and counting those here
393
+ // made the line say 108 where 80 things are actually composed (dono, 31/07).
394
+ const composedOnly = (c.components ?? []).filter((x) => x.count > 0);
395
+ if (composedOnly.length > 0) {
396
+ const withProps = composedOnly.filter((x) => Object.keys(x.props).length > 0).length;
397
+ console.log(body(`${composedOnly.length} components composed here, ${withProps} of them with props written literally`));
367
398
  }
368
399
  if (c.totals.named > 0) {
369
400
  console.log(body(`${paint.strong(String(c.totals.named))} of those values ALREADY have a name in your system - ${c.totals.coverage}% of your design values come from it today`));
@@ -395,7 +426,7 @@ function printComponents(c) {
395
426
  if (list.length === 0)
396
427
  return;
397
428
  console.log("");
398
- const mine = list.filter((x) => !x.from);
429
+ const mine = list.filter((x) => !x.from && x.count > 0);
399
430
  const theirs = list.filter((x) => x.from);
400
431
  console.log(section("What this project composes"));
401
432
  if (theirs.length > 0) {
@@ -412,7 +443,7 @@ function printComponents(c) {
412
443
  if (mine.length > 12) {
413
444
  console.log(body(paint.faint(`(${mine.length - 12} more of yours)`)));
414
445
  }
415
- printCrosswalk(mine);
446
+ printCrosswalk(list.filter((x) => !x.from));
416
447
  printObserved(mine);
417
448
  printDefined(c, mine);
418
449
  }
@@ -441,7 +472,10 @@ function printDefined(census, used) {
441
472
  if (withAxes.length > 8) {
442
473
  console.log(body(paint.faint(` (${withAxes.length - 8} more)`)));
443
474
  }
444
- const crossed = reconcile(defined, used);
475
+ // Orphans are found by asking what has no USAGE, so this has to see the
476
+ // composed list alone: handing it the union made every declared component
477
+ // look used by itself, and 29 orphans became 1.
478
+ const crossed = reconcile(defined, used.filter((u) => u.count > 0));
445
479
  const dead = crossed.filter((r) => r.deadOptions.length > 0);
446
480
  const stray = crossed.filter((r) => r.undeclared.length > 0);
447
481
  const orphans = crossed.filter((r) => r.orphan);
@@ -509,7 +543,7 @@ function printCrosswalk(mine) {
509
543
  return;
510
544
  console.log(body(paint.strong(title)));
511
545
  for (const r of list.slice(0, limit)) {
512
- console.log(body(` ${r.component.name.padEnd(18)} ${paint.faint(`${r.component.files} files`)} ${paint.dim(r.because)}`));
546
+ console.log(body(` ${r.component.name.padEnd(18)} ${paint.faint(r.component.files === 0 ? "declared" : `${r.component.files} files`)} ${paint.dim(r.because)}`));
513
547
  }
514
548
  if (list.length > limit) {
515
549
  console.log(body(paint.faint(` (${list.length - limit} more)`)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.52",
3
+ "version": "0.16.54",
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": {