synthesisui 0.16.472 → 0.16.473

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.
@@ -4648,6 +4648,16 @@ quiet = false) {
4648
4648
  say(body(n));
4649
4649
  }
4650
4650
  }
4651
+ /**
4652
+ * A FRASE DO NASCIMENTO - e ela depende de o código dele nomear alguma coisa. Bateria, 28/09 (b2): num projeto sem
4653
+ * token nenhum o sistema inteiro é a semente, e "v1 is your tokens" levava ao contrário. Ver
4654
+ * `nao-espelha-o-que-nao-existe.spec.ts`.
4655
+ */
4656
+ export function birthLine(name, declared) {
4657
+ return declared === 0
4658
+ ? `${name} - your code names no token yet, so this system is our starting point, with your colours and sizes measured next to it (listed in the report).`
4659
+ : `${name} - v1 is your tokens, nothing improved yet; where your code names nothing, it keeps the starting point's value (listed in the report).`;
4660
+ }
4651
4661
  export async function runImport(opts) {
4652
4662
  const root = opts.root ?? process.cwd();
4653
4663
  /**
@@ -5141,7 +5151,7 @@ export async function runImport(opts) {
5141
5151
  * NÃO "ESPELHA EXATAMENTE" - rodadas 11 e 13, 28/09: a v1 trazia um `display` de 4rem e uma mono JetBrains que
5142
5152
  * o projeto nunca declarou, e a frase dizia o contrário. As fundações vêm da semente onde ele não nomeia nada.
5143
5153
  */
5144
- `${paint.strong(payload?.name ?? "Your system")} - v1 is your tokens, nothing improved yet; where your code names nothing, it keeps the starting point's value (listed in the report).`));
5154
+ birthLine(paint.strong(payload?.name ?? "Your system"), Object.keys(census.declared ?? {}).length)));
5145
5155
  /**
5146
5156
  * ONDE ELE NASCEU, dito pela plataforma e não pelo que foi pedido.
5147
5157
  *
@@ -50,9 +50,25 @@ export async function login(opts) {
50
50
  */
51
51
  if (!opts.force) {
52
52
  const existing = await readCredentials();
53
- if (existing && sameRegistry(existing.registry, base)) {
53
+ /**
54
+ * E DIZ QUEM - bateria, 28/09 (b11). O passo Install da galeria acabou de dizer que a CONTA importa ("the
55
+ * account that owns <slug>"), e esta linha dizia só o host. A mesma pergunta que o `status` já faz (#1630).
56
+ * Um token que a plataforma responde e não aceita mais não é "já entrou": segue para o login de verdade.
57
+ * Sem resposta nenhuma, vale o que a máquina tem - offline não é motivo para abrir um browser.
58
+ */
59
+ const who = existing && sameRegistry(existing.registry, base)
60
+ ? await fetch(`${base}/api/auth/get-session`, {
61
+ headers: { Authorization: `Bearer ${existing.token}` },
62
+ })
63
+ .then(async (r) => r.ok ? (await r.json()) : null)
64
+ .then((j) => ({ reached: true, email: j?.user?.email ?? null }))
65
+ .catch(() => ({ reached: false, email: null }))
66
+ : null;
67
+ if (who && (who.email || !who.reached)) {
54
68
  console.log("");
55
- console.log(`✓ Already signed in to ${base} on this machine.`);
69
+ console.log(who.email
70
+ ? `✓ Already signed in as ${who.email} on ${base}.`
71
+ : `✓ Already signed in to ${base} on this machine (the account could not be confirmed - the registry did not answer).`);
56
72
  console.log(" Run `synthesisui login --force` to sign in as someone else,");
57
73
  console.log(" or `synthesisui logout` to sign out of this machine.");
58
74
  return;
@@ -490,6 +490,44 @@ export function scanSource(file, source, table) {
490
490
  }
491
491
  return scanCore(file, source, table);
492
492
  }
493
+ /**
494
+ * OS SELETORES QUE DECLARAM VOCABULÁRIO - `@theme`, `:root` e a redefinição por tema (bateria, 28/09: b5 escreve
495
+ * `[data-theme="dark"] { --c-bg: #0f172a; ... }`). Dentro deles uma `--x: valor` é a definição, não um uso.
496
+ */
497
+ const TOKEN_SELECTOR_PART = /^(@theme\b.*|:root(\[[^\]]*\])?|html(\[[^\]]*\]|\.[\w-]+)?|\[data-(theme|mode|scheme|color-scheme)(=[^\]]*)?\]|\.(dark|light))$/;
498
+ /**
499
+ * O SELETOR INTEIRO precisa ser a raiz do tema - `html.dark .shell { --shell-fill: … }` é uma variável de UM
500
+ * componente redefinida por tema, e essa continua sendo acusada (o corpus `css-global-custom-property`).
501
+ */
502
+ function isTokenSelector(selector) {
503
+ const parts = selector.split(",").map((p) => p.trim());
504
+ return parts.length > 0 && parts.every((p) => TOKEN_SELECTOR_PART.test(p));
505
+ }
506
+ /**
507
+ * ONDE ESTÃO OS VALORES QUE ESTA LINHA ATRIBUI A UMA VARIÁVEL, dentro de um bloco de vocabulário - bateria, 28/09.
508
+ *
509
+ * A guarda de `scanCore` lia `--x:` só no COMEÇO da linha, e `:root { --q-stone: #44403c; ... }` numa linha só
510
+ * voltava como quatro "replace now" (b8). Trocar `#44403c` por `var(--q-stone)` na própria declaração faz o token
511
+ * apontar para si mesmo: o navegador descarta o valor e toda cor do app some. O seletor que governa cada
512
+ * declaração é o do último `{` antes dela na linha; sem `{` antes, vale o bloco multilinha em que a linha está.
513
+ */
514
+ function declarationSpans(line, inBlock) {
515
+ const out = [];
516
+ for (const m of line.matchAll(DECLARES_ALL)) {
517
+ const start = m.index ?? 0;
518
+ const open = line.lastIndexOf("{", start + 1);
519
+ const governed = open < 0
520
+ ? inBlock
521
+ : line.lastIndexOf("}", start) < open &&
522
+ isTokenSelector(line.slice(line.lastIndexOf("}", open) + 1, open).trim());
523
+ if (!governed)
524
+ continue;
525
+ const colon = m[0].indexOf(":");
526
+ const valueAt = start + m[0].indexOf(m[2], colon);
527
+ out.push([valueAt, valueAt + m[2].length]);
528
+ }
529
+ return out;
530
+ }
493
531
  /** `--color-ocean-500: #059aed;` - uma declaração de custom property no CSS dele. */
494
532
  /** Cada declaração `--x: valor;` da linha, quantas houver - ver o laço em `scanCore`. */
495
533
  const DECLARES_ALL = /(?:^|[\s{;])(--[a-z0-9-]+)\s*:\s*([^;{}]+);/gi;
@@ -558,7 +596,7 @@ function scanCore(file, source, table) {
558
596
  const indent = line ? raw.indexOf(line) : 0;
559
597
  const at = i + 1;
560
598
  const depthBefore = braceDepth;
561
- const opensTokenBlock = /^(@theme\b|:root\b)/.test(line) && line.includes("{");
599
+ const opensTokenBlock = line.includes("{") && isTokenSelector(line.slice(0, line.indexOf("{")).trim());
562
600
  if (opensTokenBlock && tokenBlockDepth === 0)
563
601
  tokenBlockDepth = depthBefore + 1;
564
602
  const inTokenBlock = tokenBlockDepth > 0 && (opensTokenBlock || depthBefore >= tokenBlockDepth);
@@ -639,6 +677,8 @@ function scanCore(file, source, table) {
639
677
  // written by hand - flagging it would be telling someone to tokenize a
640
678
  // variable. And the same literal twice in one declaration (a two-stop
641
679
  // shadow) is one decision, so it is reported once.
680
+ const declared = declarationSpans(line, inTokenBlock && !opensTokenBlock);
681
+ const inDeclaration = (at) => declared.some(([a, b]) => at >= a && at < b);
642
682
  const spans = fallbackSpans(line, table);
643
683
  const inFallback = (at) => spans.some(([a, b]) => at >= a && at <= b);
644
684
  /** Ver `markupTextSpans`: HTML montado como texto sai do alcance da folha do app. */
@@ -653,6 +693,9 @@ function scanCore(file, source, table) {
653
693
  const push = (kind, literal, col = -1) => {
654
694
  if (literal.includes("$") || literal.includes("{"))
655
695
  return;
696
+ /** A definição do token não é drift - ver `declarationSpans`. */
697
+ if (col >= 0 && inDeclaration(col))
698
+ return;
656
699
  if (col >= 0 && inFallback(col)) {
657
700
  setAside("a token's own fallback");
658
701
  return;
package/dist/fonts.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { subsetsToEmit, weightsToEmit, } from "./next-font-weights.js";
2
- // Fallbacks genéricos do CSS - não são webfonts.
2
+ // Fallbacks genéricos do CSS e as famílias de sistema - nenhuma delas é webfont para baixar.
3
3
  const GENERIC_FAMILIES = new Set([
4
4
  "sans-serif",
5
5
  "serif",
@@ -12,6 +12,24 @@ const GENERIC_FAMILIES = new Set([
12
12
  "fantasy",
13
13
  "inherit",
14
14
  "initial",
15
+ /**
16
+ * AS FAMÍLIAS QUE JÁ ESTÃO EM TODA MÁQUINA - bateria, 28/09. Georgia, Arial e Verdana não se baixam de lugar
17
+ * nenhum, e pedi-las ao Google Fonts gerava um `<link>` para o que ele não tem, logo abaixo da frase que dizia isso.
18
+ */
19
+ "arial",
20
+ "helvetica",
21
+ "helvetica neue",
22
+ "georgia",
23
+ "verdana",
24
+ "tahoma",
25
+ "trebuchet ms",
26
+ "times new roman",
27
+ "times",
28
+ "courier new",
29
+ "courier",
30
+ "segoe ui",
31
+ "-apple-system",
32
+ "blinkmacsystemfont",
15
33
  ]);
16
34
  /**
17
35
  * A PRIMEIRA FAMÍLIA DE UMA PILHA - `"Geist Mono", ui-monospace, monospace` é `Geist Mono`.
@@ -300,7 +300,11 @@
300
300
  * o sync destacado deixa para o fim do turno dizer (re-rodada depois do #1631). Uma pasta escrita antes deixaria esse
301
301
  * arquivo local entrar num commit.
302
302
  */
303
- export const MATERIALISER_SINCE = "0.16.472";
303
+ /**
304
+ * 0.16.472 -> 0.16.473 em 28/09, e o passo 1 dá **SIM** (a bateria): as famílias de sistema (Georgia, Arial, Verdana)
305
+ * deixam de virar `<link>` do Google Fonts, e a webfont ao lado delas ganha o `fonts.ts` que antes não saía.
306
+ */
307
+ export const MATERIALISER_SINCE = "0.16.473";
304
308
  /**
305
309
  * A ÚLTIMA VERSÃO EM QUE O QUE O HOOK RODA MUDOU.
306
310
  *
@@ -476,7 +480,12 @@ export const COUNTED_DIFFERENTLY = "this run counts a value as named only when Y
476
480
  * 0.16.471 -> 0.16.472 em 28/09, e o passo 1 dá **SIM**: o fim do turno entrega ao agente o que o sync destacado do turno
477
481
  * anterior mandou para o rascunho (re-rodada, f12). Um hook anterior deixa esses componentes entrarem calados.
478
482
  */
479
- export const CHECKER_SINCE = "0.16.472";
483
+ /**
484
+ * 0.16.472 -> 0.16.473 em 28/09, e o passo 1 dá **SIM** (a bateria, b8): o hook deixa de acusar o valor que um
485
+ * `:root { --q-stone: #44403c; … }` de uma linha atribui ao token. Um hook anterior manda trocar a definição pelo
486
+ * próprio nome, e quem obedece apaga a cor.
487
+ */
488
+ export const CHECKER_SINCE = "0.16.473";
480
489
  /**
481
490
  * A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
482
491
  *
@@ -941,7 +950,12 @@ export const CHECKER_SINCE = "0.16.472";
941
950
  * não põe no sistema a peça do framework (`StrictMode`, `next/link`) nem a raiz do Vite (`src/App.tsx`); e o que
942
951
  * mora na pasta compartilhada de componentes nunca vira "feature". Um censo lido antes guardou tudo isso errado.
943
952
  */
944
- export const READER_SINCE = "0.16.471";
953
+ /**
954
+ * 0.16.471 -> 0.16.473 em 28/09, e o passo 1 dá **SIM** (a bateria, b3, b5, b8): a varredura deixa de contar como valor à
955
+ * mão o que um `:root { --a: x; }` ou um `[data-theme="dark"] { … }` de UMA linha atribui a uma variável - a definição do
956
+ * token. Quatro apps do corpus moveram. Um censo lido antes guardou essas declarações como drift.
957
+ */
958
+ export const READER_SINCE = "0.16.473";
945
959
  /**
946
960
  * O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
947
961
  *
@@ -1,3 +1,4 @@
1
+ import { SKIP_LABEL } from "./doctor/component-gate.js";
1
2
  /**
2
3
  * O QUE ESTA LEITURA NÃO CONSEGUIU SEGURAR, escrito pela esteira e não pedido a ninguém.
3
4
  *
@@ -69,7 +70,9 @@ export function notExpressed(census) {
69
70
  " a reading to correct - and the reason below is the one to argue with.");
70
71
  out.push("");
71
72
  for (const s of skipped)
72
- out.push(` ${s.name}${s.file ? ` (${s.file})` : ""}\n ${s.because}`);
73
+ out.push(
74
+ /** `because` é opcional; sem ele, o rótulo do `why` - nunca `undefined` (bateria, 28/09). */
75
+ ` ${s.name}${s.file ? ` (${s.file})` : ""}\n ${s.because ?? SKIP_LABEL[s.why] ?? s.why}`);
73
76
  }
74
77
  out.push("");
75
78
  return `${out.join("\n")}\n`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.472",
3
+ "version": "0.16.473",
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": {