synthesisui 0.16.217 → 0.16.219
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 +78 -8
- package/dist/doctor/frozen.js +15 -5
- package/dist/doctor/ledger.js +30 -4
- package/dist/doctor/scan.js +81 -3
- package/dist/doctor/transcribe.js +18 -7
- package/dist/install-marks.js +11 -1
- package/package.json +1 -1
package/dist/commands/doctor.js
CHANGED
|
@@ -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, readEvents, suggestionsFrom, summarize, } from "../doctor/ledger.js";
|
|
11
|
+
import { appendEvent, COVERAGE_RULE, readEvents, suggestionsFrom, summarize, } 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 { diagnose, scanSource, siblingTokens, } from "../doctor/scan.js";
|
|
@@ -352,7 +352,15 @@ function verdict(d, hasSystem, overruled, conflicts) {
|
|
|
352
352
|
}
|
|
353
353
|
const lines = [
|
|
354
354
|
...head,
|
|
355
|
-
|
|
355
|
+
/**
|
|
356
|
+
* "JÁ TÊM NOME" LEU COMO "JÁ ESTÃO NOMEADOS" - e o dono fez essa leitura em voz alta em 13/08:
|
|
357
|
+
* *"aqui diz que eu já tenho 243 nomeados no projeto, certo?"*. Não: os 243 estão DENTRO dos
|
|
358
|
+
* escritos à mão. O nome existe no sistema dele e o código continua escrevendo o literal.
|
|
359
|
+
*
|
|
360
|
+
* A frase estava tecnicamente correta e induziu a leitura errada em quem construiu a ferramenta.
|
|
361
|
+
* O verbo agora é do SISTEMA, não do valor: um nome ESPERA por eles.
|
|
362
|
+
*/
|
|
363
|
+
body(`${d.named} of ${d.findings.length} have a name waiting in your system - still written as literals.`),
|
|
356
364
|
body("Those are the cheap ones: swap the literal for the token."),
|
|
357
365
|
];
|
|
358
366
|
if (d.findings.length > d.named) {
|
|
@@ -702,6 +710,7 @@ export async function doctor(opts) {
|
|
|
702
710
|
kind: "doctor",
|
|
703
711
|
at: new Date().toISOString(),
|
|
704
712
|
coverage: d.coverage,
|
|
713
|
+
rule: COVERAGE_RULE,
|
|
705
714
|
named: d.named,
|
|
706
715
|
...(d.findings.some((f) => f.crossFamily)
|
|
707
716
|
? { crossFamily: d.findings.filter((f) => f.crossFamily).length }
|
|
@@ -718,7 +727,7 @@ export async function doctor(opts) {
|
|
|
718
727
|
console.log(body("and the page would change. Wire the two lines first."));
|
|
719
728
|
}
|
|
720
729
|
else {
|
|
721
|
-
console.log(body(`${d.named} of the ${d.findings.length} hand-written values found
|
|
730
|
+
console.log(body(`${d.named} of the ${d.findings.length} hand-written values found have a name waiting in`));
|
|
722
731
|
console.log(body("your system, and that number becomes actionable the moment both are true."));
|
|
723
732
|
}
|
|
724
733
|
return;
|
|
@@ -757,7 +766,46 @@ export async function doctor(opts) {
|
|
|
757
766
|
if (hasSystem && measurable) {
|
|
758
767
|
console.log("");
|
|
759
768
|
console.log(body(`Token coverage ${meter(d.coverage)} ${paint.strong(`${String(d.coverage).padStart(3)}%`)}`));
|
|
760
|
-
console.log(body(paint.dim(` ${d.tokenUses} from the system, ${d.findings.length} by hand${d.phantomUses > 0 ? `, ${d.phantomUses} naming nothing` : ""}`)));
|
|
769
|
+
console.log(body(paint.dim(` ${d.tokenUses} from the system${d.ownUses > 0 ? `, ${d.ownUses} from your own tokens` : ""}, ${d.findings.length} by hand${d.phantomUses > 0 ? `, ${d.phantomUses} naming nothing` : ""}`)));
|
|
770
|
+
/**
|
|
771
|
+
* A CAMADA DE TOKEN DELE, CONTADA - e a decisão é do dono, em 13/08.
|
|
772
|
+
*
|
|
773
|
+
* `--ds-*` é normalização NOSSA, para poder governar. Um projeto que declara
|
|
774
|
+
* `--color-ocean-500: #059aed` no CSS global tem um design system de verdade, escrito antes de a
|
|
775
|
+
* gente existir. A régua tratava aquilo como se não existisse - não era cobertura e não era
|
|
776
|
+
* deriva -, e a tela dizia "1 do sistema" sobre um repositório com 93 variáveis próprias usadas
|
|
777
|
+
* 122 vezes: *"não está fazendo sentido ter apenas 1 token no sistema"*.
|
|
778
|
+
*
|
|
779
|
+
* E a linha seguinte é a que torna a adoção barata: 89 daquelas 93 seguram um valor que um
|
|
780
|
+
* `--ds-*` também segura. Apontar uma para a outra é uma linha por variável, num arquivo só - e
|
|
781
|
+
* os 122 usos seguem o sistema sem tocar em um componente sequer.
|
|
782
|
+
*/
|
|
783
|
+
if (d.ownTokens > 0) {
|
|
784
|
+
console.log(body(paint.dim(` ${d.ownTokens} token${d.ownTokens === 1 ? "" : "s"} of your own, used ${d.ownUses}x${d.ownMirrored > 0 ? ` - ${d.ownMirrored} hold a value this system also names` : ""}`)));
|
|
785
|
+
if (d.ownMirrored > 0)
|
|
786
|
+
console.log(body(paint.dim(` point those at the \`--ds-*\` that holds it: ${d.ownMirrored} lines, one file`)));
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* O QUE UM COMANDO ALCANÇA, ao lado do que é verdade hoje - e são DUAS contas de propósito.
|
|
790
|
+
*
|
|
791
|
+
* O dono propôs em 13/08 usar os "já têm nome" como a porcentagem do medidor. A metade certa da
|
|
792
|
+
* proposta é que um `0%` sozinho não é acionável: ele descreve e não diz o que fazer. A metade
|
|
793
|
+
* que não pode acontecer é o medidor passar a mostrar a segunda conta - a barra andaria de 0 para
|
|
794
|
+
* 5 sem uma linha do app dele mudar, prometendo uma adoção que não aconteceu.
|
|
795
|
+
*
|
|
796
|
+
* Então o medidor segue medindo o que o código APONTA hoje, e o alcance vira uma linha ao lado,
|
|
797
|
+
* com o comando. O número já era impresso duas seções abaixo, solto: o que faltava era dizer que
|
|
798
|
+
* ele está a um comando de distância.
|
|
799
|
+
*
|
|
800
|
+
* Medido no repo do dono: 1 uso do sistema, 4 433 à mão, 243 com nome - o medidor diz 0% e a
|
|
801
|
+
* linha diz 5%.
|
|
802
|
+
*/
|
|
803
|
+
const nameable = d.findings.filter((f) => f.token).length;
|
|
804
|
+
if (nameable > 0) {
|
|
805
|
+
const reach = Math.round(((d.tokenUses + nameable) / (d.tokenUses + d.findings.length)) * 100);
|
|
806
|
+
console.log(body(paint.dim(` ${reach}% is one command away - ${nameable} of those have a name waiting`)));
|
|
807
|
+
console.log(body(paint.dim(" npx synthesisui doctor --fix")));
|
|
808
|
+
}
|
|
761
809
|
/**
|
|
762
810
|
* ZERO NUM REPO QUE ORIGINOU O SISTEMA É O ESTADO CERTO, e sem esta linha ele lê como falha
|
|
763
811
|
* NOSSA.
|
|
@@ -773,7 +821,18 @@ export async function doctor(opts) {
|
|
|
773
821
|
*
|
|
774
822
|
* A lei 14 em uma linha: um zero pelado lê como falha nossa, um zero com motivo lê como fato.
|
|
775
823
|
*/
|
|
776
|
-
|
|
824
|
+
/**
|
|
825
|
+
* A CONDIÇÃO É O QUE A TELA MOSTRA - e um único uso calava o parágrafo inteiro.
|
|
826
|
+
*
|
|
827
|
+
* Ela perguntava `tokenUses === 0`, e o medidor mostra a PORCENTAGEM: com 1 uso em 4 434
|
|
828
|
+
* valores, a barra diz `0%` e a explicação não sai. Foi exatamente o que o dono viu em 13/08 -
|
|
829
|
+
* *"Token coverage 0% · 1 from the system, 4433 by hand"*, sem uma linha dizendo por quê, que é
|
|
830
|
+
* o zero pelado que o comentário logo acima existe para impedir.
|
|
831
|
+
*
|
|
832
|
+
* O `1` não muda nada do que a frase afirma: os valores escritos à mão continuam sendo a FONTE
|
|
833
|
+
* de onde os tokens saíram, e não um desvio deles.
|
|
834
|
+
*/
|
|
835
|
+
if (d.coverage === 0 && measured.system) {
|
|
777
836
|
console.log(body(paint.dim(` zero is the expected start here - this system was measured FROM`)));
|
|
778
837
|
console.log(body(paint.dim(` \`${measured.system}\`, so these values are its source, not a drift`)));
|
|
779
838
|
console.log(body(paint.dim(` from it. They count once the code points at the names they became.`)));
|
|
@@ -785,7 +844,7 @@ export async function doctor(opts) {
|
|
|
785
844
|
const named = d.findings.filter((f) => f.token).length;
|
|
786
845
|
if (named > 0) {
|
|
787
846
|
console.log("");
|
|
788
|
-
console.log(body(`${paint.strong(String(named))} of the ${d.findings.length} hand-written values
|
|
847
|
+
console.log(body(`${paint.strong(String(named))} of the ${d.findings.length} hand-written values have a name waiting in YOUR system - they are still literals.`));
|
|
789
848
|
console.log(body(paint.dim("Your agent has no way to know: the tokens exist, the contract does not.")));
|
|
790
849
|
}
|
|
791
850
|
}
|
|
@@ -817,6 +876,8 @@ export async function doctor(opts) {
|
|
|
817
876
|
kind: "doctor",
|
|
818
877
|
at: new Date().toISOString(),
|
|
819
878
|
coverage: d.coverage,
|
|
879
|
+
/** Qual régua mediu - ver `COVERAGE_RULE`. Sem isto a tendência compara duas réguas. */
|
|
880
|
+
rule: COVERAGE_RULE,
|
|
820
881
|
named: d.named,
|
|
821
882
|
...(crossFamily > 0 ? { crossFamily } : {}),
|
|
822
883
|
/** E os pares em si, para a plataforma reavaliar sem esperar outra medição - ver `matched`. */
|
|
@@ -842,6 +903,15 @@ export async function doctor(opts) {
|
|
|
842
903
|
if (record.coverage && record.coverage.from !== record.coverage.to) {
|
|
843
904
|
console.log(body(` coverage ${record.coverage.from}% → ${record.coverage.to}% since the first run.`));
|
|
844
905
|
}
|
|
906
|
+
/**
|
|
907
|
+
* A RÉGUA MUDOU, DITO - em vez de um salto que ninguém fez.
|
|
908
|
+
*
|
|
909
|
+
* Quando a cobertura passou a contar a camada de token dele, o mesmo repositório saltou de 0%
|
|
910
|
+
* para 37% sem uma linha de código mudada. Somar as duas fotos anunciaria um progresso
|
|
911
|
+
* inventado; calar a mudança deixaria alguém procurar o que fez o número pular.
|
|
912
|
+
*/
|
|
913
|
+
if (record.ruleChanged)
|
|
914
|
+
console.log(body(" the coverage ruler changed in 0.16.219 - your own tokens now count, so the trend restarts here."));
|
|
845
915
|
}
|
|
846
916
|
}
|
|
847
917
|
/**
|
|
@@ -1077,8 +1147,8 @@ export async function doctor(opts) {
|
|
|
1077
1147
|
if (frozen.length > 0) {
|
|
1078
1148
|
say(section("These will not follow your other scheme"));
|
|
1079
1149
|
say(body(frozen.length === 1
|
|
1080
|
-
? "One recipe names a primitive where a role holds the same value."
|
|
1081
|
-
: `${frozen.length} recipes name a primitive where a role holds the same value.`));
|
|
1150
|
+
? "One recipe names a primitive where a SURFACE role of yours holds the same value."
|
|
1151
|
+
: `${frozen.length} recipes name a primitive where a SURFACE role of yours holds the same value.`));
|
|
1082
1152
|
say("");
|
|
1083
1153
|
for (const f of frozen) {
|
|
1084
1154
|
say(body(`ds-${f.component} · ${f.where}`));
|
package/dist/doctor/frozen.js
CHANGED
|
@@ -64,9 +64,23 @@ export function findFrozenBindings(document) {
|
|
|
64
64
|
// Several roles can hold one primitive (Vesper's navy-700 is raised, overlay
|
|
65
65
|
// AND border). Surfaces are preferred, because this only ever reports a
|
|
66
66
|
// background - naming "border" for a background reads like a bug in the tool.
|
|
67
|
+
/**
|
|
68
|
+
* SÓ PAPEL DE SUPERFÍCIE, e agora é uma LISTA FECHADA em vez de uma preferência.
|
|
69
|
+
*
|
|
70
|
+
* Ela nasceu como ranking com fallback - "prefira superfície, e na falta use qualquer um" -, e o
|
|
71
|
+
* fallback é que produziu conselho perigoso no sistema real (13/08): o fundo do `card` apontando
|
|
72
|
+
* para `foreground`, o papel do TEXTO, e o do `text-editor` para `loader`, que vira azul no
|
|
73
|
+
* escuro. O comentário acima já dizia que nomear `border` para um fundo *"lê como um bug na
|
|
74
|
+
* ferramenta"*; nomear `foreground` é a mesma frase, um degrau pior.
|
|
75
|
+
*
|
|
76
|
+
* Um valor que só um papel de texto segura não ganha sugestão nenhuma - e o fato de o fundo não
|
|
77
|
+
* acompanhar o esquema continua sendo dito.
|
|
78
|
+
*/
|
|
67
79
|
const RANK = ["surface", "raised", "canvas", "overlay", "border"];
|
|
68
80
|
const roleOf = new Map();
|
|
69
81
|
for (const [role, ref] of Object.entries(semantic)) {
|
|
82
|
+
if (!RANK.includes(role))
|
|
83
|
+
continue;
|
|
70
84
|
const other = alt[role];
|
|
71
85
|
if (typeof ref !== "string" || typeof other !== "string")
|
|
72
86
|
continue;
|
|
@@ -77,11 +91,7 @@ export function findFrozenBindings(document) {
|
|
|
77
91
|
continue;
|
|
78
92
|
const key = `${m[1]}.${m[2]}`.toLowerCase();
|
|
79
93
|
const held = roleOf.get(key);
|
|
80
|
-
|
|
81
|
-
(RANK.indexOf(role) !== -1 &&
|
|
82
|
-
(RANK.indexOf(held.role) === -1 ||
|
|
83
|
-
RANK.indexOf(role) < RANK.indexOf(held.role)));
|
|
84
|
-
if (better)
|
|
94
|
+
if (!held || RANK.indexOf(role) < RANK.indexOf(held.role))
|
|
85
95
|
roleOf.set(key, { role, becomes: other });
|
|
86
96
|
}
|
|
87
97
|
if (roleOf.size === 0)
|
package/dist/doctor/ledger.js
CHANGED
|
@@ -140,6 +140,18 @@ export async function readEvents(root) {
|
|
|
140
140
|
}
|
|
141
141
|
return out;
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* An INCIDENT is a file going dirty until it is next seen clean. Consecutive
|
|
145
|
+
* dirty checks of the same file are the same incident - an agent that edits a
|
|
146
|
+
* file four times before the fix did not have four problems.
|
|
147
|
+
*/
|
|
148
|
+
/**
|
|
149
|
+
* A VERSÃO DA RÉGUA DA COBERTURA - sobe quando o mesmo repositório passa a dar outro número.
|
|
150
|
+
*
|
|
151
|
+
* A 2 é a camada de token DELE entrando na conta (13/08): `var(--color-ocean-500)`, que ele declara
|
|
152
|
+
* no CSS global, deixou de ser invisível e passou a contar como valor governado.
|
|
153
|
+
*/
|
|
154
|
+
export const COVERAGE_RULE = 2;
|
|
143
155
|
export function summarize(events) {
|
|
144
156
|
const hooks = events.filter((e) => e.kind === "hook" && e.file);
|
|
145
157
|
const byFile = new Map();
|
|
@@ -170,11 +182,25 @@ export function summarize(events) {
|
|
|
170
182
|
}
|
|
171
183
|
}
|
|
172
184
|
const snaps = events.filter((e) => e.kind === "doctor" && typeof e.coverage === "number");
|
|
173
|
-
|
|
185
|
+
/**
|
|
186
|
+
* SÓ O QUE FOI MEDIDO PELA MESMA RÉGUA - ver `LedgerEntry.rule`.
|
|
187
|
+
*
|
|
188
|
+
* A régua da última foto é a que vale; as anteriores viram "a régua mudou". Sem isto, o dia em
|
|
189
|
+
* que a cobertura passou a contar a camada dele viraria um salto de 0% para 37% que ninguém fez.
|
|
190
|
+
*/
|
|
191
|
+
const rule = snaps.length > 0 ? (snaps[snaps.length - 1].rule ?? 0) : 0;
|
|
192
|
+
const same = snaps.filter((e) => (e.rule ?? 0) === rule);
|
|
193
|
+
const coverage = same.length >= 2
|
|
174
194
|
? {
|
|
175
|
-
from:
|
|
176
|
-
to:
|
|
195
|
+
from: same[0].coverage,
|
|
196
|
+
to: same[same.length - 1].coverage,
|
|
177
197
|
}
|
|
178
198
|
: null;
|
|
179
|
-
return {
|
|
199
|
+
return {
|
|
200
|
+
checks: hooks.length,
|
|
201
|
+
resolved,
|
|
202
|
+
open,
|
|
203
|
+
coverage,
|
|
204
|
+
...(same.length !== snaps.length ? { ruleChanged: true } : {}),
|
|
205
|
+
};
|
|
180
206
|
}
|
package/dist/doctor/scan.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Text in, findings out. No filesystem, no AST, no network - a diagnosis that
|
|
10
10
|
* takes eight seconds and needs a build step is a diagnosis nobody runs.
|
|
11
11
|
*/
|
|
12
|
-
import { tokenMatch } from "./tokens.js";
|
|
12
|
+
import { normalizeValue, tokenMatch } from "./tokens.js";
|
|
13
13
|
/**
|
|
14
14
|
* `next/og` renders JSX to a PNG on the server. There is no document, so there
|
|
15
15
|
* is no `var(--ds-*)` to read: every colour in such a file MUST be a literal.
|
|
@@ -269,9 +269,13 @@ export function scanSource(file, source, table) {
|
|
|
269
269
|
}
|
|
270
270
|
return scanCore(file, source, table);
|
|
271
271
|
}
|
|
272
|
+
/** `--color-ocean-500: #059aed;` - uma declaração de custom property no CSS dele. */
|
|
273
|
+
const DECLARES = /^\s*(--[a-z0-9-]+)\s*:\s*([^;]+);/i;
|
|
272
274
|
function scanCore(file, source, table) {
|
|
273
275
|
const findings = [];
|
|
274
276
|
const phantoms = [];
|
|
277
|
+
const ownDeclared = [];
|
|
278
|
+
const ownCandidates = new Map();
|
|
275
279
|
let tokenUses = 0;
|
|
276
280
|
// Reason by reason. Rolling two into "A or B" was the one place the report
|
|
277
281
|
// still lumped things it had told apart everywhere else.
|
|
@@ -295,6 +299,34 @@ function scanCore(file, source, table) {
|
|
|
295
299
|
const line = raw.trim();
|
|
296
300
|
const at = i + 1;
|
|
297
301
|
tokenUses += countTokenUses(line, table);
|
|
302
|
+
/**
|
|
303
|
+
* O QUE ESTE ARQUIVO DECLARA E O QUE ELE USA DE FORA DO SISTEMA - ver `FileReport.ownDeclared`.
|
|
304
|
+
*
|
|
305
|
+
* Os dois são coletados aqui e cruzados no fim: uma variável pode ser usada num arquivo e
|
|
306
|
+
* declarada em outro, então a resposta não existe enquanto a varredura não terminar.
|
|
307
|
+
*/
|
|
308
|
+
const declaredHere = DECLARES.exec(line);
|
|
309
|
+
if (declaredHere && !declaredHere[1].toLowerCase().startsWith("--ds-")) {
|
|
310
|
+
const value = declaredHere[2].trim();
|
|
311
|
+
ownDeclared.push({
|
|
312
|
+
name: declaredHere[1].toLowerCase(),
|
|
313
|
+
value,
|
|
314
|
+
/**
|
|
315
|
+
* O SISTEMA TAMBÉM SEGURA ESTE VALOR? A comparação é aqui porque é aqui que a tabela existe -
|
|
316
|
+
* e é por VALOR, não por nome: `--color-ocean-500` e `--ds-color-ocean-500` só são a mesma
|
|
317
|
+
* decisão porque os dois seguram `#059aed`.
|
|
318
|
+
*/
|
|
319
|
+
...(table.byValue.has(normalizeValue(value))
|
|
320
|
+
? { mirrored: true }
|
|
321
|
+
: null),
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
for (const m of line.matchAll(ANY_VAR_USE)) {
|
|
325
|
+
const name = m[1].toLowerCase();
|
|
326
|
+
if (isKnownToken(name, table))
|
|
327
|
+
continue;
|
|
328
|
+
ownCandidates.set(name, (ownCandidates.get(name) ?? 0) + 1);
|
|
329
|
+
}
|
|
298
330
|
for (const name of findPhantoms(line, table))
|
|
299
331
|
phantoms.push({ name, line: at });
|
|
300
332
|
// Depth at the START of this line, carried before the early return so a
|
|
@@ -451,6 +483,15 @@ function scanCore(file, source, table) {
|
|
|
451
483
|
findings,
|
|
452
484
|
tokenUses,
|
|
453
485
|
...(phantoms.length > 0 ? { phantoms } : null),
|
|
486
|
+
...(ownDeclared.length > 0 ? { ownDeclared } : null),
|
|
487
|
+
...(ownCandidates.size > 0
|
|
488
|
+
? {
|
|
489
|
+
ownCandidates: [...ownCandidates].map(([name, count]) => ({
|
|
490
|
+
name,
|
|
491
|
+
count,
|
|
492
|
+
})),
|
|
493
|
+
}
|
|
494
|
+
: null),
|
|
454
495
|
...(aside.size > 0
|
|
455
496
|
? {
|
|
456
497
|
setAside: [...aside].map(([reason, count]) => ({ reason, count })),
|
|
@@ -474,7 +515,41 @@ export function diagnose(files) {
|
|
|
474
515
|
// sit outside the fraction. Reporting 100% directly above "2 names your
|
|
475
516
|
// system never declares" is the report contradicting itself in six lines.
|
|
476
517
|
const phantomUses = files.reduce((n, f) => n + (f.phantoms?.length ?? 0), 0);
|
|
477
|
-
|
|
518
|
+
/**
|
|
519
|
+
* A CAMADA DELE, CRUZADA NO FIM - ver `FileReport.ownDeclared`.
|
|
520
|
+
*
|
|
521
|
+
* Uma variável é declarada num arquivo e usada em vinte, então a resposta só existe depois da
|
|
522
|
+
* varredura inteira. `ownUses` conta só o que aponta para um nome que ESTE repositório declara: um
|
|
523
|
+
* `var(--algo)` que ninguém declara continua fora da conta, porque ele não pinta nada.
|
|
524
|
+
*/
|
|
525
|
+
const ownDeclared = new Map();
|
|
526
|
+
for (const f of files)
|
|
527
|
+
for (const d of f.ownDeclared ?? [])
|
|
528
|
+
if (!ownDeclared.has(d.name))
|
|
529
|
+
ownDeclared.set(d.name, d.value);
|
|
530
|
+
const ownUses = files.reduce((n, f) => n +
|
|
531
|
+
(f.ownCandidates ?? []).reduce((m, c) => m + (ownDeclared.has(c.name) ? c.count : 0), 0), 0);
|
|
532
|
+
/**
|
|
533
|
+
* E QUANTAS DELAS O SISTEMA TAMBÉM NOMEIA - pelo VALOR, que é o que torna a adoção barata.
|
|
534
|
+
*
|
|
535
|
+
* A comparação é sobre o valor declarado e não sobre o nome: `--color-ocean-500` e
|
|
536
|
+
* `--ds-color-ocean-500` só são a mesma decisão porque os dois seguram `#059aed`.
|
|
537
|
+
*/
|
|
538
|
+
const mirrored = new Set();
|
|
539
|
+
for (const f of files)
|
|
540
|
+
for (const d of f.ownDeclared ?? [])
|
|
541
|
+
if (d.mirrored)
|
|
542
|
+
mirrored.add(d.name);
|
|
543
|
+
const ownMirrored = mirrored.size;
|
|
544
|
+
/**
|
|
545
|
+
* A COBERTURA PASSA A CONTAR A CAMADA DELE - e a decisão é do dono, em 13/08.
|
|
546
|
+
*
|
|
547
|
+
* O `--ds-*` é normalização NOSSA, para governar. Um projeto que declara o próprio vocabulário
|
|
548
|
+
* tem um design system de verdade, e medir isso como não-cobertura é dizer que o trabalho dele é
|
|
549
|
+
* deriva. A pergunta que separa governança de bagunça é literal-versus-NOME; de quem é o nome vira
|
|
550
|
+
* a linha de baixo, que diz quantos daqueles nomes o sistema também tem.
|
|
551
|
+
*/
|
|
552
|
+
const total = tokenUses + ownUses + flat.length + phantomUses;
|
|
478
553
|
const byLiteral = new Map();
|
|
479
554
|
for (const f of flat) {
|
|
480
555
|
const key = `${f.kind}:${f.literal.toLowerCase()}`;
|
|
@@ -513,7 +588,10 @@ export function diagnose(files) {
|
|
|
513
588
|
named: flat.filter((f) => f.token).length,
|
|
514
589
|
tokenUses,
|
|
515
590
|
phantomUses,
|
|
516
|
-
coverage: total === 0 ? 100 : Math.round((tokenUses / total) * 100),
|
|
591
|
+
coverage: total === 0 ? 100 : Math.round(((tokenUses + ownUses) / total) * 100),
|
|
592
|
+
ownTokens: ownDeclared.size,
|
|
593
|
+
ownUses,
|
|
594
|
+
ownMirrored,
|
|
517
595
|
scanned: files.length,
|
|
518
596
|
repeats,
|
|
519
597
|
};
|
|
@@ -16,13 +16,24 @@
|
|
|
16
16
|
* chance of a value nobody wrote: every declaration it emits either points at a
|
|
17
17
|
* token they declared or carries a literal they typed.
|
|
18
18
|
*
|
|
19
|
-
* WHY NOT `refit
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* NEAREST allowed token and never emits a raw
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
19
|
+
* WHY NOT `refit`, AND WHERE IT DOES BELONG.
|
|
20
|
+
*
|
|
21
|
+
* That endpoint already turns arbitrary component code into a token-only
|
|
22
|
+
* recipe. It maps every value to the NEAREST allowed token and never emits a raw
|
|
23
|
+
* one - which is NORMALISATION, and v1 is a mirror. That is the whole reason it
|
|
24
|
+
* is not here, and it is a reason about meaning rather than about cost: a v1
|
|
25
|
+
* that arrived already interpreted would leave the v2 with nothing to propose.
|
|
26
|
+
*
|
|
27
|
+
* Its place is exactly there, in the v2 (dono, 01/08). v1 carries their
|
|
28
|
+
* `RadioCard` with the `#ffffff` they actually typed; v2 offers the same
|
|
29
|
+
* component expressed entirely in their tokens, and they approve it. Same
|
|
30
|
+
* division as the colour collapse: mirror first, proposal second, and the person
|
|
31
|
+
* decides.
|
|
32
|
+
*
|
|
33
|
+
* An earlier version of this comment also argued that refit costs credits and
|
|
34
|
+
* carries a daily quota. That argument is retired: quotas are becoming an
|
|
35
|
+
* internal control rather than a product surface, under a 30-day-free-then-paid
|
|
36
|
+
* plan. Cost was never the real reason and should not be recorded as one.
|
|
26
37
|
*
|
|
27
38
|
* THE MODIFIER SAYS WHERE THE VALUE GOES, which is what makes this tractable:
|
|
28
39
|
*
|
package/dist/install-marks.js
CHANGED
|
@@ -74,7 +74,17 @@ export const MATERIALISER_SINCE = "0.16.217";
|
|
|
74
74
|
*
|
|
75
75
|
* Os arquivos que decidem: `doctor/` inteiro e `commands/hook.ts`.
|
|
76
76
|
*/
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
|
+
* 0.16.202 -> 0.16.218 em 13/08, e o passo 1 foi SIM: a lente `frozen` parou de aconselhar um fundo
|
|
79
|
+
* a apontar para um papel que não é superfície.
|
|
80
|
+
*
|
|
81
|
+
* 0.16.218 -> 0.16.219 no mesmo dia, SIM de novo: a cobertura passou a contar a CAMADA DE TOKEN
|
|
82
|
+
* DELE. Um hook pinado antes disso mede o mesmo repositório e devolve outro número - e o número é o
|
|
83
|
+
* que a pessoa lê para decidir se adotou ou não. Um hook pinado numa versão anterior segue dizendo ao
|
|
84
|
+
* agente dele que o fundo do `card` deveria apontar para `foreground` - o papel do TEXTO -, e é
|
|
85
|
+
* exatamente uma verificação que o pinado faz diferente.
|
|
86
|
+
*/
|
|
87
|
+
export const CHECKER_SINCE = "0.16.219";
|
|
78
88
|
/**
|
|
79
89
|
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
80
90
|
*
|
package/package.json
CHANGED