synthesisui 0.16.372 → 0.16.374
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.
- package/dist/commands/doctor.js +107 -36
- package/dist/doctor/gap-triage.js +32 -2
- package/package.json +1 -1
package/dist/commands/doctor.js
CHANGED
|
@@ -589,6 +589,55 @@ async function readWiring(root, slug) {
|
|
|
589
589
|
}
|
|
590
590
|
/** Onde o retrato mora por default: dentro do que a esteira já escreve, e commitável. */
|
|
591
591
|
const DEFAULT_BASELINE = "_synthesisui/drift-baseline.json";
|
|
592
|
+
/**
|
|
593
|
+
* A PORTA ÚNICA DO `--fix` - e ela existe porque o conserto passou a ter DOIS chamadores.
|
|
594
|
+
*
|
|
595
|
+
* O caminho normal chama com o diagnóstico inteiro. O caminho de um projeto sem fiação chama com o
|
|
596
|
+
* subconjunto que o código DELE já resolve - ver `ownName` e o bloco que decide isso. Duas cópias
|
|
597
|
+
* desta sequência divergiriam no dia em que uma delas ganhasse um passo: o `writeFix` sem o
|
|
598
|
+
* `appendEvent`, ou o recibo sem a linha que manda ler o diff.
|
|
599
|
+
*/
|
|
600
|
+
async function runFix(root, d, writing) {
|
|
601
|
+
const read = await readerFor(root, d.findings.filter((f) => nameToWrite(f)).map((f) => f.file));
|
|
602
|
+
const { result, next } = planFix(d, read);
|
|
603
|
+
if (writing)
|
|
604
|
+
await writeFix(root, next);
|
|
605
|
+
console.log(section(writing ? "Fixed what had an answer" : "What --fix would do"));
|
|
606
|
+
for (const line of describeFix(result, !writing))
|
|
607
|
+
console.log(body(line));
|
|
608
|
+
if (!writing && result.applied.length > 0) {
|
|
609
|
+
console.log("");
|
|
610
|
+
console.log(body("Nothing was written. When the list above is what you want:"));
|
|
611
|
+
console.log(paint.blue(snippet(["npx synthesisui@latest doctor --fix --write"])));
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* O CONSERTO DEIXA RASTRO - ver `CheckEvent.kind: "fix"`.
|
|
615
|
+
*
|
|
616
|
+
* Sem esta linha, "ele trocou 129 valores por token" existia só no terminal daquele minuto: o
|
|
617
|
+
* ledger deduz conserto por arquivo que limpou, e um `--fix` que toca 79 arquivos de uma vez não
|
|
618
|
+
* aparece como um ato.
|
|
619
|
+
*/
|
|
620
|
+
if (writing && result.applied.length > 0) {
|
|
621
|
+
await appendEvent(root, {
|
|
622
|
+
kind: "fix",
|
|
623
|
+
at: new Date().toISOString(),
|
|
624
|
+
named: result.applied.length,
|
|
625
|
+
});
|
|
626
|
+
console.log("");
|
|
627
|
+
console.log(body(paint.dim("Read the diff before committing - it is your code, and this replaced literals with the tokens your own system declares.")));
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* O NOME QUE ESTA TROCA ESCREVERIA É DELE? - a pergunta que a recusa do `--fix` nunca fez.
|
|
632
|
+
*
|
|
633
|
+
* `nameToWrite` devolve `theirToken ?? token`: quando o repositório dele nomeia aquele valor, é o
|
|
634
|
+
* nome DELE que vai para o código. Um nome dele resolve no navegador dele HOJE, com ou sem a nossa
|
|
635
|
+
* folha instalada - a folha só é necessária para os `--ds-*`, que são nossos.
|
|
636
|
+
*/
|
|
637
|
+
const ownName = (f) => {
|
|
638
|
+
const name = nameToWrite(f);
|
|
639
|
+
return Boolean(name && !name.startsWith("--ds-"));
|
|
640
|
+
};
|
|
592
641
|
export async function doctor(opts) {
|
|
593
642
|
const root = resolve(opts.dir ?? process.cwd());
|
|
594
643
|
/**
|
|
@@ -877,6 +926,21 @@ export async function doctor(opts) {
|
|
|
877
926
|
* `"yours"` e `"adopted"` são o vocabulário dela, e não há duas linhas para ligar.
|
|
878
927
|
*/
|
|
879
928
|
const blocked = table.source === "installed" && (!wiring.imported || !wiring.scoped);
|
|
929
|
+
/**
|
|
930
|
+
* QUANTAS DAS DUAS FALTAM - e sem este número três frases mandavam consertar DUAS coisas quando
|
|
931
|
+
* faltava UMA.
|
|
932
|
+
*
|
|
933
|
+
* `blocked` é um OU, e as frases que ele governa foram escritas assumindo o E: *"Until both are
|
|
934
|
+
* true"*, *"--fix is refused while those two are false"* e *"Wire the two lines first"*. Visto na
|
|
935
|
+
* máquina do dono em 04/09, num repositório onde `data-ds` já estava lá com um ✓ impresso três
|
|
936
|
+
* linhas acima: a tela contradizia a própria lista, e a terceira frase é INSTRUÇÃO - a pessoa está
|
|
937
|
+
* bloqueada, procurando o que escrever, e ela manda escrever duas linhas.
|
|
938
|
+
*
|
|
939
|
+
* O caso de faltar UMA é o mais comum: uma instalação que parou no meio erra um dos dois passos,
|
|
940
|
+
* não os dois. Derivado da mesma leitura que decide `blocked`, para as duas nunca discordarem.
|
|
941
|
+
*/
|
|
942
|
+
const missingWiring = (wiring.imported ? 0 : 1) + (wiring.scoped ? 0 : 1);
|
|
943
|
+
const bothMissing = missingWiring === 2;
|
|
880
944
|
const unwired = table.source === "installed" &&
|
|
881
945
|
(!wiring.imported || !wiring.scoped || fontsPending);
|
|
882
946
|
if (unwired) {
|
|
@@ -907,7 +971,9 @@ export async function doctor(opts) {
|
|
|
907
971
|
* enquanto imprimia o número abaixo; agora não há número abaixo, e prometer um seria a mesma
|
|
908
972
|
* incoerência ao contrário.
|
|
909
973
|
*/
|
|
910
|
-
console.log(body(
|
|
974
|
+
console.log(body(bothMissing
|
|
975
|
+
? `Until both are true, none of the ${table.byName.size} tokens reach the browser.`
|
|
976
|
+
: `Until that one is true, none of the ${table.byName.size} tokens reach the browser.`));
|
|
911
977
|
}
|
|
912
978
|
else {
|
|
913
979
|
console.log(body("Colour and spacing are working. Type is not: the system's faces"));
|
|
@@ -965,10 +1031,45 @@ export async function doctor(opts) {
|
|
|
965
1031
|
}).catch(() => { });
|
|
966
1032
|
console.log("");
|
|
967
1033
|
if (opts.fix) {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1034
|
+
/**
|
|
1035
|
+
* A RECUSA PASSA A SER POR VALOR, E NÃO PELO COMANDO INTEIRO.
|
|
1036
|
+
*
|
|
1037
|
+
* NASCEU DE UMA PERGUNTA DO DONO (04/09): *"se o design system dele já está funcionando e são
|
|
1038
|
+
* as mesmas referências, faz sentido esse ligamento? combinamos que não seria invasivo"*.
|
|
1039
|
+
*
|
|
1040
|
+
* A MEDIÇÃO DEU RAZÃO A ELE, pelo mesmo caminho que a tela usa (`loadSystem` + `scanSource` +
|
|
1041
|
+
* `diagnose` sobre packages/ui + apps/landing + apps/web do codelevel): dos 216 valores com
|
|
1042
|
+
* nome esperando, **156 (72%) escreveriam o nome DELE** - `--color-brand-violet`,
|
|
1043
|
+
* `--color-tier-gold`, `--duration-base` - e esses resolvem no navegador dele HOJE, sem folha
|
|
1044
|
+
* nenhuma instalada. Só 60 apontam para `--ds-*`, que são nossos e precisam da fiação.
|
|
1045
|
+
*
|
|
1046
|
+
* A recusa olhava `blocked` e nada mais. Ela nunca perguntava de quem era o nome que ia
|
|
1047
|
+
* escrever, embora `nameToWrite` já responda isso (`theirToken ?? token`). O produto recusava
|
|
1048
|
+
* 156 consertos que funcionariam para proteger 60 que quebrariam - e cobrava, em troca, uma
|
|
1049
|
+
* folha inteira dentro do app de alguém que só queria governar o próprio vocabulário.
|
|
1050
|
+
*
|
|
1051
|
+
* ISSO ATINGE O CASO DE USO CENTRAL: quem importa um design system que já existe tem, por
|
|
1052
|
+
* construção, a maioria dos nomes sendo dele.
|
|
1053
|
+
*
|
|
1054
|
+
* O QUE FICA DE FORA CONTINUA SENDO DITO, com o número e o motivo - Lei 8. O que muda é que a
|
|
1055
|
+
* lacuna deixou de fechar a porta inteira.
|
|
1056
|
+
*/
|
|
1057
|
+
const theirs = d.findings.filter(ownName).length;
|
|
1058
|
+
const ours = d.findings.filter((f) => nameToWrite(f) && !ownName(f)).length;
|
|
1059
|
+
if (theirs > 0) {
|
|
1060
|
+
console.log(body(`${theirs} of your hand-written values ${theirs === 1 ? "carries" : "carry"} a name your own code declares, and ${theirs === 1 ? "it resolves" : "those resolve"} today - --fix will swap ${theirs === 1 ? "it" : "them"}.`));
|
|
1061
|
+
if (ours > 0)
|
|
1062
|
+
console.log(body(`${ours} more point at ${table.name ?? table.slug} tokens, which only resolve once the wiring above is done. Left alone.`));
|
|
1063
|
+
console.log("");
|
|
1064
|
+
await runFix(root, { ...d, findings: d.findings.filter(ownName) }, opts.write === true);
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
/** Nenhum nome dele em jogo: aqui a recusa continua sendo a resposta certa, e inteira. */
|
|
1068
|
+
const one = ours === 1;
|
|
1069
|
+
console.log(body(`--fix is refused while ${bothMissing ? "those two are" : "that one is"} false. ${ours} of your hand-written values`));
|
|
1070
|
+
console.log(body(`${one ? "does" : "do"} have a name in the system, and swapping ${one ? "it" : "them"} now would point ${one ? "it" : "them"} at`));
|
|
1071
|
+
console.log(body(`variables the browser cannot resolve - the ${one ? "declaration" : "declarations"} would be dropped`));
|
|
1072
|
+
console.log(body(`and the page would change. Wire ${bothMissing ? "the two lines" : "that line"} first.`));
|
|
972
1073
|
}
|
|
973
1074
|
else {
|
|
974
1075
|
console.log(body(`${d.named} of the ${d.findings.length} hand-written values found have a name waiting in`));
|
|
@@ -1859,37 +1960,7 @@ export async function doctor(opts) {
|
|
|
1859
1960
|
* 1500 achados e depois dizer "troquei 900" é fazer a pessoa procurar a linha que importa.
|
|
1860
1961
|
*/
|
|
1861
1962
|
if (opts.fix) {
|
|
1862
|
-
|
|
1863
|
-
const { result, next } = planFix(d, read);
|
|
1864
|
-
const writing = opts.write === true;
|
|
1865
|
-
if (writing)
|
|
1866
|
-
await writeFix(root, next);
|
|
1867
|
-
console.log(section(writing ? "Fixed what had an answer" : "What --fix would do"));
|
|
1868
|
-
for (const line of describeFix(result, !writing))
|
|
1869
|
-
console.log(body(line));
|
|
1870
|
-
if (!writing && result.applied.length > 0) {
|
|
1871
|
-
console.log("");
|
|
1872
|
-
console.log(body("Nothing was written. When the list above is what you want:"));
|
|
1873
|
-
console.log(paint.blue(snippet(["npx synthesisui@latest doctor --fix --write"])));
|
|
1874
|
-
}
|
|
1875
|
-
/**
|
|
1876
|
-
* O CONSERTO DEIXA RASTRO - ver `CheckEvent.kind: "fix"`.
|
|
1877
|
-
*
|
|
1878
|
-
* Sem esta linha, "ele trocou 129 valores por token" existia só no terminal daquele minuto: o
|
|
1879
|
-
* ledger deduz conserto por arquivo que limpou, e um `--fix` que toca 79 arquivos de uma vez não
|
|
1880
|
-
* aparece como um ato.
|
|
1881
|
-
*/
|
|
1882
|
-
if (writing && result.applied.length > 0) {
|
|
1883
|
-
await appendEvent(root, {
|
|
1884
|
-
kind: "fix",
|
|
1885
|
-
at: new Date().toISOString(),
|
|
1886
|
-
named: result.applied.length,
|
|
1887
|
-
});
|
|
1888
|
-
}
|
|
1889
|
-
if (writing && result.applied.length > 0) {
|
|
1890
|
-
console.log("");
|
|
1891
|
-
console.log(body(paint.dim("Read the diff before committing - it is your code, and this replaced literals with the tokens your own system declares.")));
|
|
1892
|
-
}
|
|
1963
|
+
await runFix(root, d, opts.write === true);
|
|
1893
1964
|
return;
|
|
1894
1965
|
}
|
|
1895
1966
|
if (opts.writeBaseline) {
|
|
@@ -235,13 +235,43 @@ values) {
|
|
|
235
235
|
* VALOR daquilo está no sistema, e não só que não há o que consertar.
|
|
236
236
|
*/
|
|
237
237
|
const theirs = group.reduce((n, g) => n + (g.withTheirTokens ?? 0), 0);
|
|
238
|
-
lines.push("",
|
|
238
|
+
lines.push("",
|
|
239
|
+
/**
|
|
240
|
+
* O DENOMINADOR VAI NA FRASE - e a falta dele era o mesmo defeito consertado pela METADE.
|
|
241
|
+
*
|
|
242
|
+
* A linha de cima estabelece decisões (1063, das quais 1007 interpretadas: 56 fora), e este
|
|
243
|
+
* percentual é sobre FRAGMENTOS (32). Dizer só "of what was not interpreted" faz as duas
|
|
244
|
+
* grandezas usarem a mesma palavra na mesma tela: quem soma 81 + 9 + 9 conclui que a triagem
|
|
245
|
+
* cobriu tudo, e ela cobriu 32 de 56.
|
|
246
|
+
*
|
|
247
|
+
* Em 03/09 o dono viu exatamente isto e o conserto reescreveu a linha do MEIO ("They live in N
|
|
248
|
+
* places in your code"). Estes três cabeçalhos ficaram com a expressão antiga - mesma tela,
|
|
249
|
+
* mesmo defeito, na parte que não foi olhada. Visto de novo em 04/09.
|
|
250
|
+
*/
|
|
251
|
+
`${label[verdict]} - ${total} fragment${total === 1 ? "" : "s"}, ${unread > 0 ? Math.round((total / unread) * 100) : 0}% of those ${unread} place${unread === 1 ? "" : "s"}${theirs > 0
|
|
239
252
|
? ` — and ${theirs} of them already wear a token you declare, so their value is in the system`
|
|
240
253
|
: ""}`);
|
|
241
254
|
for (const gap of group) {
|
|
242
255
|
lines.push(` ${gap.uses} ${gap.shape} in ${gap.files} file${gap.files === 1 ? "" : "s"} (${gap.share}%) - ${gap.work}`);
|
|
243
|
-
|
|
256
|
+
/**
|
|
257
|
+
* TODOS OS QUE O CENSO GUARDOU, E O QUE FICOU DE FORA DITO EM VOZ ALTA.
|
|
258
|
+
*
|
|
259
|
+
* Isto cortava em dois (`slice(0, 2)`) sobre os até TRÊS que `style-ledger` grava - um por
|
|
260
|
+
* arquivo -, e não dizia nada. Na tela do dono em 04/09: *"3 class in 3 files"* seguido de dois
|
|
261
|
+
* arquivos, e o terceiro sumiu sem uma palavra. Ele conserta dois e acha que acabou.
|
|
262
|
+
*
|
|
263
|
+
* O GÊMEO JÁ TINHA O AVISO e este não: a tela de admin ganhou *"Not the whole set: N more"* no
|
|
264
|
+
* #1304. Duas superfícies respondem a mesma pergunta, e só uma admitia o corte - que é a Lei 8
|
|
265
|
+
* ao contrário, lacuna calada.
|
|
266
|
+
*
|
|
267
|
+
* O QUE FALTA SÃO ARQUIVOS, e é isso que a linha conta: o censo guarda um exemplo por arquivo,
|
|
268
|
+
* então `files` menos os mostrados é literalmente quantos arquivos você não está vendo.
|
|
269
|
+
*/
|
|
270
|
+
for (const example of gap.examples)
|
|
244
271
|
lines.push(` ${example.file}:${example.line} ${example.text.slice(0, 76)}`);
|
|
272
|
+
const hidden = gap.files - gap.examples.length;
|
|
273
|
+
if (hidden > 0)
|
|
274
|
+
lines.push(` not the whole set: ${hidden} more file${hidden === 1 ? "" : "s"} with this shape, not listed here`);
|
|
245
275
|
}
|
|
246
276
|
}
|
|
247
277
|
return lines;
|
package/package.json
CHANGED