synthesisui 0.16.69 → 0.16.71

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.
@@ -6,11 +6,11 @@ import { isNearDuplicate, isNeutral, lightness, } from "../doctor/color-distance
6
6
  import { emptyTally, internalSpecifiers, scanComponentsInto, tallyToInventory, } from "../doctor/components-scan.js";
7
7
  import { crosswalk, observedRules } from "../doctor/crosswalk.js";
8
8
  import { reconcile, scanDefinitions, } from "../doctor/definitions-scan.js";
9
- import { describeConvention, detectConventions, IDIOM_LABEL, } from "../doctor/idiom.js";
9
+ import { describeConvention, describeRemainder, detectConventions, } from "../doctor/idiom.js";
10
10
  import { diagnose, scanSource } from "../doctor/scan.js";
11
11
  import { parseSchemeBlocks } from "../doctor/scheme-blocks.js";
12
12
  import { buildTable } from "../doctor/tokens.js";
13
- import { rootClasses, transcribe, } from "../doctor/transcribe.js";
13
+ import { rootClasses, rootTag, transcribe, } from "../doctor/transcribe.js";
14
14
  import { body, paint, section } from "../output.js";
15
15
  import { walk, walkAll } from "./doctor.js";
16
16
  /**
@@ -312,8 +312,10 @@ export async function takeCensus(root) {
312
312
  const size = Object.keys(t.base).length +
313
313
  Object.keys(t.dark).length +
314
314
  Object.keys(t.states).length;
315
- if (size > 0)
316
- looks[found[0].name] = t;
315
+ const tag = rootTag(src);
316
+ if (size > 0 || tag) {
317
+ looks[found[0].name] = tag ? { ...t, rootTag: tag } : t;
318
+ }
317
319
  }
318
320
  }
319
321
  }
@@ -490,13 +492,12 @@ function sayConventions(c) {
490
492
  console.log(section("How you reference a value"));
491
493
  for (const conv of list) {
492
494
  console.log(body(describeConvention(conv)));
493
- const off = conv.offIdiom.filter((o) => o.count > 0).slice(0, 3);
494
- if (off.length > 0) {
495
- console.log(body(paint.faint(` and ${off.map((o) => `${o.count} ${IDIOM_LABEL[o.idiom]}`).join(", ")}`)));
496
- }
495
+ const remainder = describeRemainder(conv);
496
+ if (remainder)
497
+ console.log(body(paint.faint(` ${remainder}`)));
497
498
  }
498
499
  console.log("");
499
- console.log(body(paint.faint("Nothing here is a rule we brought. It is what your own files do most, so the rest can be named against it.")));
500
+ console.log(body(paint.faint("Nothing here is a rule we brought - it is what your own files already do, and the system now knows it. None of the rest has to move today: this is a complement, not a correction.")));
500
501
  }
501
502
  /**
502
503
  * NOT DRIFT - BROKEN. A `var()` no declaration answers renders nothing at all,
@@ -122,10 +122,38 @@ export function detectConventions(sources, minReferences = 20) {
122
122
  export function describeConvention(c) {
123
123
  const pct = Math.round(c.share * 100);
124
124
  if (c.idiom === "raw-hex") {
125
- return `${c.language} has no convention - ${pct}% of its ${c.total} references are values typed in place`;
125
+ return `${c.language} has no single convention yet - ${pct}% of its ${c.total} references are values typed in place`;
126
126
  }
127
127
  return `${c.language} reaches for ${IDIOM_LABEL[c.idiom]} - ${pct}% of the ${c.total} references in it`;
128
128
  }
129
+ /**
130
+ * WHAT IS NOT YET IN THE CONVENTION - and the wording is the whole point.
131
+ *
132
+ * "and 1154 raw hex" reads as 1154 errors in the author's face. The measurement
133
+ * is the same and the accusation is gratuitous: this system exists to make their
134
+ * work SCALABLE, not to mark it wrong, and a design system is somebody's
135
+ * judgement before it is anybody's audit (dono, 01/08 - "entrar como um
136
+ * complemento").
137
+ *
138
+ * So the number is stated as coverage, not as a count of mistakes, and it says
139
+ * out loud that none of it has to change today.
140
+ */
141
+ export function describeRemainder(c) {
142
+ const off = c.offIdiom.filter((o) => o.count > 0);
143
+ if (off.length === 0)
144
+ return null;
145
+ const total = off.reduce((n, o) => n + o.count, 0);
146
+ const named = off
147
+ .slice(0, 3)
148
+ .map((o) => `${o.count} ${IDIOM_LABEL[o.idiom]}`)
149
+ .join(", ");
150
+ // The reassurance belongs at the END of the section, once. Repeated on every
151
+ // line it becomes noise, and noise is how a report stops being read.
152
+ if (!hasConvention(c)) {
153
+ return `the other ${total} are ${named} - no single answer dominates here yet`;
154
+ }
155
+ return `${total} are not in it yet: ${named}`;
156
+ }
129
157
  /** True when this language's dominant answer is "no answer". */
130
158
  export function hasConvention(c) {
131
159
  return c.idiom !== "raw-hex";
@@ -288,7 +288,12 @@ export function transcribe(classes, declared) {
288
288
  if (target[decl.property] != null)
289
289
  continue;
290
290
  target[decl.property] = decl.value;
291
- out.fromToken += 1;
291
+ // Both travel now, so both are counted honestly. The platform decides which
292
+ // becomes a declaration; this only reports what the reading was made of.
293
+ if (decl.token)
294
+ out.fromToken += 1;
295
+ else
296
+ out.fromLiteral += 1;
292
297
  }
293
298
  return out;
294
299
  }
@@ -304,6 +309,25 @@ export function transcribe(classes, declared) {
304
309
  * nothing, and nothing is a contract with an empty base - which is exactly what
305
310
  * the import already produces, so failing here costs no ground.
306
311
  */
312
+ /**
313
+ * The TAG of the element a component returns - `button`, `input`, `div`.
314
+ *
315
+ * Cheap, and it is half of what decides a preview's anatomy: a component whose
316
+ * root is a `<button>` is an action however it is named, and one whose root is a
317
+ * bare `<span>` is an indicator. The platform pairs this with the name; see
318
+ * `preview-kind.ts`.
319
+ *
320
+ * A composed root (`<Radio.Root>`) returns the component name, not an HTML tag -
321
+ * which is still a signal, just a weaker one, so it travels as written and the
322
+ * platform decides what to do with it.
323
+ */
324
+ export function rootTag(source) {
325
+ const ret = source.search(/return\s*\(/);
326
+ if (ret === -1)
327
+ return null;
328
+ const m = /<([A-Za-z][A-Za-z0-9.]*)/.exec(source.slice(ret));
329
+ return m ? m[1] : null;
330
+ }
307
331
  export function rootClasses(source) {
308
332
  const ret = source.search(/return\s*\(/);
309
333
  if (ret === -1)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.69",
3
+ "version": "0.16.71",
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": {