synthesisui 0.16.337 → 0.16.338

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.
@@ -52,12 +52,98 @@ const SHAPES = [
52
52
  describe: (a) => `Every component sits directly under \`${a.root}\`, one folder deep. It is the shape that stays legible longest while a system is small, and the one to revisit when the folder passes about forty names.`,
53
53
  },
54
54
  ];
55
+ /**
56
+ * A MESMA ORGANIZAÇÃO VISTA DE MAIS PERTO NÃO É UMA SEGUNDA ESCOLHA (`INV-COB-09`).
57
+ *
58
+ * O QUE O CLIENTE GANHA: a pergunta "qual organização tem PRIORIDADE" só lhe oferece
59
+ * organizações que disputam de verdade. Sem isto ele escolhe entre uma escada atômica e uma
60
+ * pasta que mora DENTRO dela - a mesma organização, medida de duas distâncias -, e qualquer
61
+ * resposta que ele der é a mesma resposta. Uma pergunta cujas opções não se excluem não é uma
62
+ * pergunta: é um formulário que ele preenche sem que nada mude no que os agentes dele escrevem.
63
+ *
64
+ * A PROPRIEDADE: uma organização é reconhecida no lugar mais RASO que a explica. Uma forma é a
65
+ * mesma organização vista de mais perto quando é do MESMO tipo de uma que já a cobre, ou quando é
66
+ * a leitura genérica (`flat`) de um lugar que outra forma já nomeia com mais informação. Formas de
67
+ * tipos DIFERENTES descrevem fatos diferentes, e nenhuma apaga a outra - o peso (`MINOR_SHARE`) já
68
+ * decide qual delas pede decisão e qual é dita como canto.
69
+ *
70
+ * O DESEMPATE NO MESMO ROOT continua sendo só o de `flat`, e ele não muda aqui: duas formas
71
+ * específicas na mesma pasta (`layered` e `colocated` em `src`, por exemplo) são duas leituras
72
+ * legítimas do mesmo lugar, e escolher entre elas é justamente a decisão que a pergunta existe
73
+ * para pedir. `flat` é a forma mais permissiva das cinco - basta uma pasta `components` -, então
74
+ * onde uma específica também casa, ela é a mesma coisa dita com menos informação.
75
+ *
76
+ * MEDIÇÃO de 31/08 - população e régua de enumeração de escopo escritas UMA vez em
77
+ * `contracts/camada-4-cobertura.md` (`INV-COB-09`), e não recopiadas aqui: 65 formas reconhecidas
78
+ * em 43 escopos passam a 56; as 9 subordinadas dizem o mesmo fato de um ancestral, e estão em 6
79
+ * escopos. Foto daquelas populações naquele dia, nunca invariante.
80
+ */
81
+ export function dropShapesAlreadyExplained(found) {
82
+ return found.filter((a) => !found.some((b) => b !== a && explains(b, a)));
83
+ }
84
+ /**
85
+ * `other` é a MESMA organização que `shape`, vista de mais longe?
86
+ *
87
+ * A pergunta não é "está por perto": é se as duas dizem o mesmo fato. Uma forma é a mesma
88
+ * organização vista de mais perto quando é do MESMO tipo de uma que já a cobre, ou quando é a
89
+ * leitura genérica (`flat`) de um lugar que outra forma já nomeia com mais informação.
90
+ *
91
+ * FORMAS DE TIPOS DIFERENTES DESCREVEM FATOS DIFERENTES, e nenhuma apaga a outra - nem quando uma
92
+ * mora dentro da outra. O layout React mais comum que existe é a prova: `src/{components}` com
93
+ * `src/components/{atoms, molecules, organisms}` embaixo. Com o ancestral vencendo sempre, a
94
+ * escada atômica SOME, e o que sobra é a leitura mais pobre das duas - o cliente recebe no
95
+ * `CLAUDE.md` dele a regra "Every component sits directly under `src`, one folder deep", que é
96
+ * FALSA no repositório dele, e o caminho `src/{components}`, que manda o agente parar um degrau
97
+ * antes de onde o componente nasce. Uma opção errada é pior que duas opções: ele nem sabe que
98
+ * havia o que decidir.
99
+ *
100
+ * Quem decide qual das duas pede decisão e qual é dita como canto é o PESO (`MINOR_SHARE`), e não
101
+ * este predicado - uma escada de 6 arquivos dentro de um `colocated` de 780 continua sendo dita,
102
+ * e continua não virando pergunta.
103
+ */
104
+ function explains(other, shape) {
105
+ if (isUnderPath(other.root, shape.root))
106
+ return other.kind === shape.kind || shape.kind === "flat";
107
+ return (pathKey(other.root) === pathKey(shape.root) &&
108
+ shape.kind === "flat" &&
109
+ other.kind !== "flat");
110
+ }
111
+ /**
112
+ * O CAMINHO COMPARÁVEL - a raiz do escopo é escrita `.` pela caminhada, e comparada com `""` ela é
113
+ * a mesma pasta. Comparar as strings cruas faria a raiz deixar de explicar o que está embaixo
114
+ * dela, que é o caso mais comum de todos.
115
+ *
116
+ * AS DUAS OUTRAS NORMALIZAÇÕES SÃO DEFENSIVAS, e ficam nomeadas como tal: barra final e `./` na
117
+ * frente não são alcançáveis pela caminhada real - `import.ts` escreve `path || "."` e monta o
118
+ * resto com `parts.slice(…).join("/")` -, então nenhum teste pode reprová-las por comportamento.
119
+ * Elas custam duas chamadas de `replace` e protegem quem montar a árvore à mão.
120
+ */
121
+ function pathKey(path) {
122
+ const tidy = path.replace(/\/+$/, "").replace(/^\.\//, "");
123
+ return tidy === "." ? "" : tidy;
124
+ }
125
+ /**
126
+ * `path` está DENTRO de `ancestor` - por SEGMENTO, nunca por prefixo de texto.
127
+ *
128
+ * `"src/ui-kit".startsWith("src/ui")` é verdadeiro e está errado: são duas pastas irmãs, e por
129
+ * essa comparação uma organização real desapareceria da pergunta sem que nada a explicasse.
130
+ */
131
+ function isUnderPath(ancestor, path) {
132
+ const a = pathKey(ancestor);
133
+ const p = pathKey(path);
134
+ /**
135
+ * A MESMA PASTA JÁ CAI FORA POR CONSTRUÇÃO, e por isso não há guarda para ela: com `a === p`,
136
+ * `p.startsWith(`${a}/`)` é falso (uma pasta não é filha de si mesma) e a raiz cai no `p !== ""`.
137
+ * Uma guarda a mais aqui seria linha que nenhum caso alcança - e código que nenhum caso alcança
138
+ * é código que nenhum teste pode reprovar.
139
+ */
140
+ return a === "" ? p !== "" : p.startsWith(`${a}/`);
141
+ }
55
142
  /**
56
143
  * Which shapes this tree actually has, ranked by how much code each holds.
57
144
  *
58
- * `flat` is checked last and only reported when nothing more specific matched under the
59
- * same root: a `components/` folder inside an atomic library is not a second
60
- * architecture, it is the same one seen from further away.
145
+ * O que sobra é o que governa código que nenhuma outra forma já governa - a subordinação inteira
146
+ * mora em `dropShapesAlreadyExplained` (`INV-COB-09`), numa redação só.
61
147
  */
62
148
  export function detectArchitectures(entries) {
63
149
  const found = [];
@@ -76,10 +162,6 @@ export function detectArchitectures(entries) {
76
162
  }
77
163
  if (!complete)
78
164
  continue;
79
- if (shape.kind === "flat" &&
80
- found.some((f) => f.root === entry.path && f.kind !== "flat")) {
81
- continue;
82
- }
83
165
  found.push({
84
166
  kind: shape.kind,
85
167
  root: entry.path,
@@ -88,10 +170,7 @@ export function detectArchitectures(entries) {
88
170
  });
89
171
  }
90
172
  }
91
- return found
92
- .filter((a) => a.kind !== "flat" ||
93
- !found.some((b) => b.root === a.root && b.kind !== "flat"))
94
- .sort((a, b) => b.files - a.files || a.root.localeCompare(b.root));
173
+ return dropShapesAlreadyExplained(found).sort((a, b) => b.files - a.files || a.root.localeCompare(b.root));
95
174
  }
96
175
  /** The sentence that becomes the rule. Written for an agent about to add a file. */
97
176
  export function describeArchitecture(a) {
@@ -389,7 +389,33 @@ export const CHECKER_SINCE = "0.16.308";
389
389
  * nenhum dos 43 escopos medidos, então ninguém recebe uma organização DIFERENTE - só o número
390
390
  * honesto.
391
391
  */
392
- export const READER_SINCE = "0.16.337";
392
+ /**
393
+ * 0.16.337 -> 0.16.338 em 31/08 (`INV-COB-09`): uma organização passou a ser reconhecida no lugar
394
+ * mais RASO que a explica. Uma forma do MESMO tipo de outra que já a cobre, ou a leitura genérica
395
+ * de um lugar que outra já nomeia com mais informação, deixa de ser gravada como uma segunda
396
+ * organização. Tipos DIFERENTES continuam os dois gravados: eles dizem fatos diferentes sobre o
397
+ * mesmo código, e apagar o de dentro entregaria a leitura mais pobre como se fosse a única.
398
+ *
399
+ * A marca sobe porque um censo já gravado carrega as entradas duplicadas e não há como saber quais
400
+ * eram subordinadas sem reler a árvore do disco: a subordinação se decide comparando os CAMINHOS
401
+ * medidos, e um censo antigo guarda o que foi reconhecido, não a caminhada que o reconheceu. Só a
402
+ * remedição lê o disco.
403
+ *
404
+ * O QUE O `sync` ENTREGA, e o que ele NÃO entrega. Ele remede com `takeCensus`, então o campo
405
+ * `architectures` do censo é reescrito sem as entradas subordinadas e o censo reenviado já chega
406
+ * limpo. Ele NÃO reimprime a seção de organização no terminal - essa seção é do relatório de
407
+ * `import` -, e NÃO reescreve a regra no `CLAUDE.md` dele: aquela linha nasce da conversa de
408
+ * import, que lê `architectures[].rule` do censo, e `rulesFromCensus` não olha para este campo.
409
+ * Quem já tem a regra escrita a partir de uma organização subordinada continua com ela até um
410
+ * import novo, e dizer o contrário seria prometer que um comando conserta o que ele não conserta.
411
+ *
412
+ * MEDIÇÃO de 31/08 - população e régua de enumeração de escopo em
413
+ * `contracts/camada-4-cobertura.md` (`INV-COB-09`): 65 formas reconhecidas em 43 escopos passam a
414
+ * 56; as 9 subordinadas dizem o mesmo fato de um ancestral, e estão em 6 escopos. O hash do corpus
415
+ * NÃO se moveu, e isso é a informação: nenhum dos 28 apps dourados tem forma repetindo o que uma
416
+ * ancestral já diz, então a estabilidade ali prova ausência de regressão e não ausência de efeito.
417
+ */
418
+ export const READER_SINCE = "0.16.338";
393
419
  /**
394
420
  * O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
395
421
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.337",
3
+ "version": "0.16.338",
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": {