synthesisui 0.16.182 → 0.16.184

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.
@@ -922,11 +922,17 @@ export async function doctor(opts) {
922
922
  for (const r of repeats) {
923
923
  const where = `${r.count}\u00d7 in ${r.files} file${r.files === 1 ? "" : "s"}`;
924
924
  const near = r.token ? null : nearestToken(table, r.literal);
925
- const named = r.token
926
- ? ` → ${r.token}`
927
- : near
928
- ? ` → nearest is ${near.name} (${near.value})`
929
- : "";
925
+ /**
926
+ * COINCIDÊNCIA NÃO É RESPOSTA - ver `crossFamily` em `scan.ts`. Para aquele `kind` o
927
+ * sistema não tem nome; o valor mora noutra família, e dizer só a seta afirma o contrário.
928
+ */
929
+ const named = r.crossFamily
930
+ ? ` → no ${r.kind} named for it · the value lives as ${r.token}`
931
+ : r.token
932
+ ? ` → ${r.token}`
933
+ : near
934
+ ? ` → nearest is ${near.name} (${near.value})`
935
+ : "";
930
936
  say(` ${r.literal.padEnd(w)} ${where}${named}`);
931
937
  }
932
938
  }
@@ -942,11 +948,13 @@ export async function doctor(opts) {
942
948
  // A dead end with a neighbour is not a dead end. Only for lengths -
943
949
  // "nearly the same blue" is the guess this tool must never make.
944
950
  const near = x.token ? null : nearestToken(table, x.literal);
945
- const named = x.token
946
- ? `→ ${x.token}`
947
- : near
948
- ? `→ nearest is ${near.name} (${near.value})`
949
- : "→ no token holds this value yet";
951
+ const named = x.crossFamily
952
+ ? `→ no ${x.kind} named for it · the value lives as ${x.token}`
953
+ : x.token
954
+ ? `→ ${x.token}`
955
+ : near
956
+ ? `→ nearest is ${near.name} (${near.value})`
957
+ : "→ no token holds this value yet";
950
958
  say(` ${String(x.line).padStart(4)} ${x.literal} ${named}`);
951
959
  }
952
960
  if (f.findings.length > shown.length) {
@@ -1264,8 +1272,19 @@ export async function doctor(opts) {
1264
1272
  * mentir por omissão. Muda a ordem e muda quantos de cada aparecem no teto de cinco.
1265
1273
  */
1266
1274
  const migrating = intent.intent === "migrate";
1267
- const named = d.repeats.filter((x) => x.token);
1268
- const unnamed = d.repeats.filter((x) => !x.token);
1275
+ /**
1276
+ * UMA COINCIDÊNCIA NÃO ENTRA NA LISTA DE BARATOS - ver `crossFamily` em `scan.ts`.
1277
+ *
1278
+ * A lista dos "cheap" existe para quem tem dez minutos: trocar o literal pelo token e pronto. Um
1279
+ * match de outra família não é isso - `--fix` o recusa, e o trabalho ali é decidir se aquele
1280
+ * `kind` merece um nome. Medido no repo do dono em 08/08: `2rem` era oferecido como raio porque
1281
+ * existe como degrau de tipo, dez vezes.
1282
+ *
1283
+ * Ele não some: vai para o grupo de quem NÃO tem nome, que é literalmente o que ele é para
1284
+ * aquele kind - e a linha diz onde o valor mora hoje.
1285
+ */
1286
+ const named = d.repeats.filter((x) => x.token && !x.crossFamily);
1287
+ const unnamed = d.repeats.filter((x) => !x.token || x.crossFamily);
1269
1288
  for (const r of named.slice(0, migrating ? 2 : 3)) {
1270
1289
  plan.push({
1271
1290
  rank: migrating ? 4 : 3,
@@ -1280,7 +1299,9 @@ export async function doctor(opts) {
1280
1299
  rank: migrating ? 3 : 4,
1281
1300
  what: near
1282
1301
  ? `${r.literal} - name it, or snap to ${near.name}`
1283
- : `${r.literal} - the system has no name for it`,
1302
+ : r.crossFamily
1303
+ ? `${r.literal} - no ${r.kind} named for it, and the value lives as ${r.token} in another family`
1304
+ : `${r.literal} - the system has no name for it`,
1284
1305
  size: `${r.files} file${r.files === 1 ? "" : "s"}`,
1285
1306
  cheap: false,
1286
1307
  });
@@ -82,7 +82,9 @@ export function compareToBaseline(d, base, now) {
82
82
  /** O que a mensagem de uma anotação diz, e é a mesma frase nos dois formatos. */
83
83
  function messageFor(f) {
84
84
  return f.token
85
- ? `${f.literal} is written by hand, and this project's system already names it: var(${f.token}). Use the token.`
85
+ ? f.crossFamily
86
+ ? `${f.literal} is written by hand, and this project's system has no ${f.kind} named for it. The value does exist elsewhere in the system - as \`${f.token}\`, in another family - so this is a decision to make, not a swap: name a ${f.kind}, or leave it.`
87
+ : `${f.literal} is written by hand, and this project's system already names it: var(${f.token}). Use the token.`
86
88
  : `${f.literal} is a ${f.kind} value written by hand, and the system has no name for it yet. Name it, or file a token request: npx synthesisui request token`;
87
89
  }
88
90
  /**
@@ -489,6 +489,7 @@ export function diagnose(files) {
489
489
  token: f.token,
490
490
  count: 1,
491
491
  files: new Set([f.file]),
492
+ ...(f.crossFamily ? { crossFamily: true } : {}),
492
493
  });
493
494
  }
494
495
  }
@@ -499,6 +500,7 @@ export function diagnose(files) {
499
500
  token: v.token,
500
501
  count: v.count,
501
502
  files: v.files.size,
503
+ ...(v.crossFamily ? { crossFamily: true } : {}),
502
504
  }))
503
505
  .filter((r) => r.count > 1)
504
506
  .sort((a, b) => b.count - a.count);
@@ -83,6 +83,7 @@ export function buildLedger(cli, seen) {
83
83
  files: 0,
84
84
  because: BECAUSE[reason],
85
85
  examples: [],
86
+ unreadable: [],
86
87
  seenFiles: new Set(),
87
88
  };
88
89
  group.uses += 1;
@@ -94,6 +95,30 @@ export function buildLedger(cli, seen) {
94
95
  line: f.line,
95
96
  text: f.text.replace(/\s+/g, " ").trim().slice(0, 160),
96
97
  });
98
+ /**
99
+ * SÓ `shape-not-read`, E SÓ TEXTO DISTINTO - as duas restrições vieram de medir, não de supor.
100
+ *
101
+ * DAS QUATRO RAZÕES, uma só é alcançável por um leitor novo. `value-not-read` diz que a forma FOI
102
+ * lida e o valor está fora das escalas deles - texto não ensina nada a leitor nenhum. `computed`
103
+ * é montado em runtime e não existe na fonte. `component-not-admitted` é o portão, não a leitura.
104
+ * Sobra `shape-not-read`: "nenhum leitor desta versão entende esta forma", que é exatamente a
105
+ * frase que um leitor novo responde.
106
+ *
107
+ * E TEXTO DISTINTO, porque a primeira versão disto reprovou no spec do repo vivo: guardar todo
108
+ * fragmento deu 723 215 bytes no dashboard dele, contra um teto de 65 536. Oito mil cópias da
109
+ * mesma string não ensinam mais que uma - o que um leitor precisa é da variedade de FORMAS.
110
+ *
111
+ * O teto de 512 é declarado e não mudo: `uses` continua contando tudo, então a diferença entre o
112
+ * contado e o que viajou é visível em vez de silenciosa.
113
+ */
114
+ if (reason === "shape-not-read" &&
115
+ group.unreadable.length < 512 &&
116
+ !group.unreadable.some((u) => u.text === f.text))
117
+ group.unreadable.push({
118
+ file: f.file,
119
+ line: f.line,
120
+ text: f.text.replace(/\s+/g, " ").trim().slice(0, 400),
121
+ });
97
122
  groups.set(key, group);
98
123
  }
99
124
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.182",
3
+ "version": "0.16.184",
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": {