synthesisui 0.16.342 → 0.16.343

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.
@@ -8,7 +8,7 @@ import { emptyTally, internalSpecifiers, scanComponentsInto, tallyToInventory, }
8
8
  import { checkContracts } from "../doctor/contract-check.js";
9
9
  import { describeMissing, missingDependencies, summarizeMissing, } from "../doctor/dependencies.js";
10
10
  import { findFrozenBindings } from "../doctor/frozen.js";
11
- import { appendEvent, COVERAGE_RULE, readEvents, suggestionsFrom, unrepresentedFrom, summarize, } from "../doctor/ledger.js";
11
+ import { appendEvent, COVERAGE_RULE, readEvents, suggestionsFrom, summarize, unrepresentedFrom, } from "../doctor/ledger.js";
12
12
  import { bindingsFromDocument, countComponents, findOverrides, } from "../doctor/overrides.js";
13
13
  import { checkableName, readRequests, verifyAndCloseRequests, } from "../doctor/requests.js";
14
14
  import { DEFAULT_ROOT_PX, rootSizeOf, saidOfRoot, } from "../doctor/root-size.js";
@@ -156,6 +156,28 @@ export async function* walkAll(roots) {
156
156
  * doctor como se fosse um componente pedido. Uma tela que rotula errado é pior que uma que não
157
157
  * rotula: quem lê decide em cima do rótulo.
158
158
  */
159
+ /**
160
+ * O EMPATE DITO EM VOZ ALTA - a metade que faltava do nome dele.
161
+ *
162
+ * O QUE ELE PERDIA: quando mais de um token DELE segura o mesmo valor, a esteira desempata por
163
+ * critérios lidos do repositório dele e o relatório imprimia só o vencedor, `→ {color.tier-gold}`,
164
+ * como se fosse fato. No sistema do dono aquele `#f59e0b` é `--color-tier-gold` E
165
+ * `--color-feedback-warning` - gamificação e estado, dois conceitos dele com o mesmo hex -, e a
166
+ * escolha entre eles nunca foi dele. Medido em 31/08 nos 26 sistemas do banco: 7 (27%) têm ao
167
+ * menos um valor com mais de um nome.
168
+ *
169
+ * A ESCOLHA CONTINUA SENDO FEITA, porque o `--fix` precisa de UM nome para escrever. O que muda é
170
+ * que ela para de passar por fato: ele vê que houve empate e pode discordar com informação, que é
171
+ * a diferença entre uma lacuna declarada e um silêncio.
172
+ *
173
+ * UM SÓ É NOMEADO, o resto vira contagem: dois nomes cabem na linha, cinco viram uma parede que
174
+ * ninguém lê - e o número já diz que a decisão existe.
175
+ */
176
+ const alsoNamed = (f) => !f.theirAlso?.length
177
+ ? ""
178
+ : f.theirAlso.length === 1
179
+ ? ` · you also call it ${f.theirAlso[0]}`
180
+ : ` · you also call it ${f.theirAlso[0]} and ${f.theirAlso.length - 1} other${f.theirAlso.length - 1 === 1 ? "" : "s"}`;
159
181
  function requestLabel(r) {
160
182
  if (r.kind === "token")
161
183
  return `token ${r.value} as ${r.name}`;
@@ -1314,7 +1336,7 @@ export async function doctor(opts) {
1314
1336
  const named = r.crossFamily && !r.theirToken
1315
1337
  ? ` → no ${r.kind} named for it · the value lives as ${r.token}`
1316
1338
  : nameToWrite(r)
1317
- ? ` → ${nameToWrite(r)}`
1339
+ ? ` → ${nameToWrite(r)}${alsoNamed(r)}`
1318
1340
  : near
1319
1341
  ? ` → nearest is ${near.theirs ?? near.name} (${near.value})`
1320
1342
  : "";
@@ -1338,7 +1360,7 @@ export async function doctor(opts) {
1338
1360
  const named = x.crossFamily && !x.theirToken
1339
1361
  ? `→ no ${x.kind} named for it · the value lives as ${x.token}`
1340
1362
  : nameToWrite(x)
1341
- ? `→ ${nameToWrite(x)}`
1363
+ ? `→ ${nameToWrite(x)}${alsoNamed(x)}`
1342
1364
  : near
1343
1365
  ? `→ nearest is ${near.theirs ?? near.name} (${near.value})`
1344
1366
  : "→ no token holds this value yet";
@@ -404,9 +404,9 @@ async function findToken(root, value) {
404
404
  */
405
405
  const theirNameFor = (v) => {
406
406
  const norm = normalizeValue(v, table.rootPx);
407
- for (const [key, name] of table.aliases)
407
+ for (const [key, theirs] of table.aliases)
408
408
  if (key.endsWith(`:${norm}`))
409
- return name;
409
+ return theirs.name;
410
410
  return null;
411
411
  };
412
412
  const exact = tokenFor(table, value);
@@ -420,7 +420,8 @@ function scanCore(file, source, table) {
420
420
  ...(/(?<!r)em$/i.test(literal.trim())
421
421
  ? { fontRelative: true }
422
422
  : {}),
423
- ...(theirs ? { theirToken: theirs } : {}),
423
+ ...(theirs ? { theirToken: theirs.name } : {}),
424
+ ...(theirs?.also.length ? { theirAlso: theirs.also } : {}),
424
425
  /**
425
426
  * A COINCIDÊNCIA VIAJA COM O ACHADO - ver `tokenMatch`.
426
427
  *
@@ -609,6 +610,7 @@ export function diagnose(files) {
609
610
  kind: f.kind,
610
611
  token: f.token,
611
612
  ...(f.theirToken ? { theirToken: f.theirToken } : {}),
613
+ ...(f.theirAlso?.length ? { theirAlso: f.theirAlso } : {}),
612
614
  ...(f.fontRelative ? { fontRelative: true } : {}),
613
615
  count: 1,
614
616
  files: new Set([f.file]),
@@ -622,6 +624,7 @@ export function diagnose(files) {
622
624
  kind: v.kind,
623
625
  token: v.token,
624
626
  ...(v.theirToken ? { theirToken: v.theirToken } : {}),
627
+ ...(v.theirAlso?.length ? { theirAlso: v.theirAlso } : {}),
625
628
  ...(v.fontRelative ? { fontRelative: true } : {}),
626
629
  count: v.count,
627
630
  files: v.files.size,
@@ -98,6 +98,18 @@ function pick(candidates, ours, convention) {
98
98
  * `24px` pode ser raio, espaçamento ou tamanho de fonte, e sem um token nosso não há o que validasse.
99
99
  * Esses continuam saindo como "no name for it", que é verdade e é o caminho do `absorb`.
100
100
  */
101
+ /**
102
+ * O VENCEDOR E OS PRETERIDOS, juntos - porque um empate silencioso é o defeito.
103
+ *
104
+ * `pick` escolhe entre nomes DELE por critérios lidos do repositório dele, e isso continua certo:
105
+ * o achado precisa de UM nome para escrever. O que estava errado era descartar os outros. No
106
+ * sistema do dono, `#f59e0b` é `--color-tier-gold` E `--color-feedback-warning` - dois conceitos
107
+ * dele, gamificação e estado -, e o relatório dizia `→ {color.tier-gold}` como se fosse fato.
108
+ */
109
+ function escolha(candidates, ours, convention) {
110
+ const name = pick(candidates, ours, convention);
111
+ return { name, also: candidates.filter((c) => c !== name) };
112
+ }
101
113
  export function theirNames(ours, theirs) {
102
114
  const out = new Map();
103
115
  if (theirs.byName.size === 0)
@@ -139,7 +151,7 @@ export function theirNames(ours, theirs) {
139
151
  : candidates.filter((n) => familySays(kind, n));
140
152
  if (usable.length === 0)
141
153
  continue;
142
- out.set(key, pick(usable, name, convention));
154
+ out.set(key, escolha(usable, name, convention));
143
155
  }
144
156
  }
145
157
  for (const [value, candidates] of theirs.byValue) {
@@ -149,7 +161,7 @@ export function theirNames(ours, theirs) {
149
161
  const key = `${kind}:${value}`;
150
162
  if (out.has(key))
151
163
  continue;
152
- out.set(key, pick(candidates, null, convention));
164
+ out.set(key, escolha(candidates, null, convention));
153
165
  }
154
166
  }
155
167
  return out;
@@ -418,7 +418,7 @@ kind) {
418
418
  const theirs = kind
419
419
  ? table.aliases.get(`${kind}:${normalizeValue(best.value, table.rootPx)}`)
420
420
  : undefined;
421
- return theirs ? { ...best, theirs } : best;
421
+ return theirs ? { ...best, theirs: theirs.name } : best;
422
422
  }
423
423
  /**
424
424
  * The family a token belongs to, from the drift it was found in.
@@ -115,7 +115,7 @@ export function pointAtTheirNames(css, theirs, resolvable) {
115
115
  const kind = Object.entries(FAMILY_KIND).find(([prefix]) => name.startsWith(prefix))?.[1];
116
116
  if (!kind)
117
117
  return line;
118
- const theirName = alias.get(`${kind}:${normalizeValue(value.trim(), ours.rootPx)}`);
118
+ const theirName = alias.get(`${kind}:${normalizeValue(value.trim(), ours.rootPx)}`)?.name;
119
119
  if (!theirName || theirName === name)
120
120
  return line;
121
121
  if (!resolvable.has(theirName)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.342",
3
+ "version": "0.16.343",
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": {