synthesisui 0.16.285 → 0.16.289

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.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * O QUE ESTA LEITURA NÃO CONSEGUIU SEGURAR, escrito pela esteira e não pedido a ninguém.
3
+ *
4
+ * O QUE O CLIENTE GANHA: ele sabe, no minuto do import, o que não chegou - com o número do
5
+ * repositório dele e o arquivo e a linha de cada caso. É a lei 8 do método: o cliente perdoa o que
6
+ * a gente diz que não faz, e não perdoa descobrir sozinho.
7
+ *
8
+ * POR QUE ISTO EXISTE. O arquivo era escrito pelo AGENTE, instruído por três frases dentro das
9
+ * descrições das tools do MCP. Em 23/08 o mesmo repositório foi importado duas vezes: a primeira
10
+ * rodada escreveu 37 linhas de lacunas declaradas, a segunda escreveu nenhuma. As lacunas
11
+ * continuaram todas lá - 198 declarações de CSS sem leitor, 5 `var()` que não pintam nada -, e só o
12
+ * aviso desapareceu. Um pedido em texto a um modelo é uma sugestão, e nada percebia quando ela não
13
+ * era seguida.
14
+ *
15
+ * O PISO É DETERMINÍSTICO, e todo dado que ele usa já estava medido no censo. O agente continua
16
+ * livre para ACRESCENTAR o que só ele viu; o que ele não pode mais é ser a única testemunha.
17
+ *
18
+ * `null` quando não há lacuna nenhuma: um arquivo vazio dizendo "nada a declarar" é ruído, e a
19
+ * ausência do arquivo já é a resposta.
20
+ */
21
+ export function notExpressed(census) {
22
+ const ledger = census.ledger;
23
+ const unread = ledger?.unread ?? [];
24
+ const broken = census.brokenRefs ?? [];
25
+ const skipped = census.skipped ?? [];
26
+ if (unread.length === 0 && broken.length === 0 && skipped.length === 0)
27
+ return null;
28
+ const out = [];
29
+ const scope = census.scope ? ` of \`${census.scope}\`` : "";
30
+ out.push(`# What this reading could not hold`);
31
+ out.push("");
32
+ out.push(`Measured by synthesisui \`${ledger?.cli ?? "unknown"}\`${scope}. Every number here is from` +
33
+ ` your files. This file is written by the pipeline on every import - what it lists is what` +
34
+ ` did NOT reach a recipe.`);
35
+ if (unread.length > 0) {
36
+ out.push("");
37
+ out.push("## Style your files hold and no recipe received");
38
+ for (const group of unread) {
39
+ out.push("");
40
+ out.push(`### ${group.uses} ${group.shape} declaration${group.uses === 1 ? "" : "s"}` +
41
+ ` across ${group.files} file${group.files === 1 ? "" : "s"} - ${group.reason}`);
42
+ out.push("");
43
+ out.push(group.because);
44
+ out.push("");
45
+ for (const ex of group.examples ?? [])
46
+ out.push(` ${ex.file}:${ex.line} ${ex.text}`);
47
+ }
48
+ }
49
+ if (broken.length > 0) {
50
+ out.push("");
51
+ out.push("## Variables referenced and never declared");
52
+ out.push("");
53
+ out.push("These do not paint a different colour - they paint nothing. They are yours to fix, in your" +
54
+ " own words. Up to three places are listed for each; the count says how many there are in" +
55
+ " total.");
56
+ out.push("");
57
+ for (const ref of broken) {
58
+ out.push(` ${ref.name} ${ref.count} reference${ref.count === 1 ? "" : "s"}` +
59
+ ` in ${ref.files} file${ref.files === 1 ? "" : "s"}`);
60
+ for (const place of ref.at ?? [])
61
+ out.push(` ${place.file}:${place.line}`);
62
+ }
63
+ }
64
+ if (skipped.length > 0) {
65
+ out.push("");
66
+ out.push("## Exports the gate left out, and why");
67
+ out.push("");
68
+ out.push("Nothing here was dropped in silence. If one of these IS a component of your system, that is" +
69
+ " a reading to correct - and the reason below is the one to argue with.");
70
+ out.push("");
71
+ for (const s of skipped)
72
+ out.push(` ${s.name}${s.file ? ` (${s.file})` : ""}\n ${s.because}`);
73
+ }
74
+ out.push("");
75
+ return `${out.join("\n")}\n`;
76
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * O NOME QUE UM TOKEN DELE TEM DENTRO DO DOCUMENTO - uma regra, num lugar só.
3
+ *
4
+ * O QUE O CLIENTE GANHA: mudar um valor no Studio repinta o componente que o usa. Um ref liga os
5
+ * dois; um `var()` literal não liga nada - ele renderiza certo hoje e fica órfão da edição.
6
+ *
7
+ * ESTA FUNÇÃO EXISTIA DUAS VEZES, em `transcribe.ts` e em `css-modules.ts`, e as duas divergiam: a
8
+ * segunda não conhecia `--font-*`, então a família de fonte dele virava referência quando lida de uma
9
+ * classe e `var()` quando lida de uma folha - a mesma decisão dele com dois destinos, dependendo de
10
+ * onde a esteira olhou. Gêmeo não declarado sempre acaba assim.
11
+ *
12
+ * E O GRADIENTE ERA DECIDIDO PELO NOME. A regra reconhecia `--gradient-*`; o cliente escreveu
13
+ * `--grad-cool`. O escritor da plataforma reconhece pelo VALOR - `linear-gradient(…)` - e guarda em
14
+ * `foundations.gradients.grad-cool`, então o token TINHA casa no documento e a classe que o usa
15
+ * apontava para o vazio. É a lei 13 aplicada a token: a origem decide, e aqui a origem é o valor.
16
+ *
17
+ * Medido: `--grad-*` são 5 no `codelevel-ui`, `--gradient-*` são 3 no `frontend-hub`, e as duas
18
+ * grafias passam a chegar onde o documento as guarda.
19
+ */
20
+ export function tokenRefFor(name,
21
+ /**
22
+ * O que cada token DELE vale. O mapa é o que permite reconhecer um gradiente pela forma em vez do
23
+ * nome; vazio, a decisão volta a ser só pelo nome, que é o comportamento de quem não tem o valor
24
+ * em mãos.
25
+ */
26
+ declared) {
27
+ const bare = name.replace(/^--/, "");
28
+ if (bare.startsWith("color-"))
29
+ return refFor(bare.slice("color-".length));
30
+ if (bare.startsWith("radius-"))
31
+ return `{radius.${bare.slice(7)}}`;
32
+ if (bare.startsWith("spacing-"))
33
+ return `{spacing.${bare.slice(8)}}`;
34
+ if (bare.startsWith("shadow-"))
35
+ return `{shadow.${bare.slice(7)}}`;
36
+ // `--gradient-ui` e `--background-image-gradient-ui` são um token em duas grafias - o namespace de
37
+ // utility do Tailwind v4 embrulha o primeiro. Os dois chegam a `{gradients.ui}`.
38
+ if (bare.startsWith("background-image-gradient-")) {
39
+ return `{gradients.${bare.slice("background-image-gradient-".length)}}`;
40
+ }
41
+ if (bare.startsWith("gradient-"))
42
+ return `{gradients.${bare.slice(9)}}`;
43
+ if (bare.startsWith("text-")) {
44
+ /**
45
+ * O TOKEN COMPANHEIRO. O Tailwind v4 escreve "a altura de linha DE text-body-s" como
46
+ * `--text-body-s--line-height` - um duplo hífen dentro de um nome. Lido como nome de passo ele
47
+ * produzia `{typography.scale.body-s--line-height.fontSize}`, cujo duplo hífen nenhuma gramática
48
+ * de ref aceita, e a receita inteira era RECUSADA na validação (test13, 01/08). O sufixo nomeia a
49
+ * propriedade; o meio nomeia o passo.
50
+ */
51
+ const companion = /^text-(.+?)--(line-height|letter-spacing|font-weight)$/.exec(bare);
52
+ if (companion) {
53
+ const prop = {
54
+ "line-height": "lineHeight",
55
+ "letter-spacing": "letterSpacing",
56
+ "font-weight": "weight",
57
+ }[companion[2]];
58
+ return `{typography.scale.${companion[1]}.${prop}}`;
59
+ }
60
+ // Qualquer outro duplo hífen é um nome que esta gramática não segura - o `var()` literal ainda
61
+ // resolve contra a folha dele, e um ref inválido não ajuda ninguém.
62
+ if (bare.slice(5).includes("--"))
63
+ return `var(${name})`;
64
+ return `{typography.scale.${bare.slice(5)}.fontSize}`;
65
+ }
66
+ if (bare.startsWith("font-"))
67
+ return `{typography.families.${bare.slice(5)}}`;
68
+ /**
69
+ * O GRADIENTE PELA FORMA DO VALOR, e é a última pergunta e não a primeira.
70
+ *
71
+ * Os namespaces acima são vocabulário conhecido e ganham deste teste - `--color-brand` que valha um
72
+ * `linear-gradient` continua sendo cor pelo nome que ele deu. Aqui embaixo estão os nomes que a
73
+ * gente NÃO modela, e é onde `--grad-cool` cai. A chave é o nome dele inteiro, que é exatamente o
74
+ * que `gradientsFromCensus` guarda no documento.
75
+ */
76
+ const value = declared.get(name);
77
+ if (value && /\b(?:linear|radial|conic)-gradient\(/.test(value)) {
78
+ return `{gradients.${bare}}`;
79
+ }
80
+ // Um namespace que não modelamos. O `var()` literal continua sendo CSS correto contra a folha
81
+ // dele, e inventar um ref apontaria para nada.
82
+ return `var(${name})`;
83
+ }
84
+ /**
85
+ * `ocean-500` → `{color.ocean.500}`. O passo é o número final; o que vem antes é a família, hífens
86
+ * intactos, porque `royal-blue-500` é uma família chamada `royal-blue`.
87
+ */
88
+ function refFor(name) {
89
+ const m = /^(.*)-(\d{2,4})$/.exec(name);
90
+ if (!m)
91
+ return `{color.${name}}`;
92
+ return `{color.${m[1]}.${m[2]}}`;
93
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.285",
3
+ "version": "0.16.289",
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": {