synthesisui 0.16.398 → 0.16.400

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.
@@ -585,6 +585,28 @@ export async function add(slug, opts) {
585
585
  const sheet = await globalSheetOf(projectRoot, `${appDir}/globals.css`);
586
586
  const importPrefix = prefixFrom(sheet);
587
587
  console.log(section("One-time setup (once per app)"));
588
+ /**
589
+ * QUANDO O SETUP É NECESSÁRIO, E QUANDO ELE É UMA ESCOLHA - a última porta onde a pergunta faltava.
590
+ *
591
+ * O `doctor` e o `component` passaram a perguntar antes de cobrar (ver `sheet-needed.ts`, 07/09,
592
+ * a partir da objeção do dono: *"esse import gera dependência ao design system, e a gente quer
593
+ * isolar os dois pontos - o nosso deve ser apenas uma REFERÊNCIA"*). Aqui a pergunta não tem como
594
+ * ser respondida da mesma forma: o sistema acabou de ser instalado e não há código gerado para
595
+ * medir.
596
+ *
597
+ * O QUE MUDA É A HONESTIDADE DO ENUNCIADO. "One-time setup" lido logo após a instalação soa como
598
+ * obrigação, e para metade dos casos ele não é: quem vai trazer componentes como CÓDIGO SEU não
599
+ * precisa de folha nenhuma - o `component` traduz para o vocabulário do próprio repositório e diz,
600
+ * arquivo a arquivo, se sobrou algo. Quem vai ESCREVER as classes do sistema (`bg-brand`,
601
+ * `rounded-lg` no valor dele) precisa, porque só o `@theme` do adaptador as gera.
602
+ *
603
+ * Então a instrução continua inteira - suprimi-la entregaria um projeto sem as classes - e ganha a
604
+ * linha que diz QUAL dos dois casos exige cada coisa. A escolha volta a ser dele, informada.
605
+ */
606
+ console.log(line("(needed if you will WRITE this system's utility classes - only its @theme generates them."));
607
+ console.log(line(" Bringing components in as YOUR code needs none of it: `component` translates them into"));
608
+ console.log(line(" your own vocabulary and tells you, per file, if anything is left.)"));
609
+ console.log("");
588
610
  /**
589
611
  * "ONCE PER APP" É LITERAL NUM MONOREPO, e calar os outros apps entrega metade da fiação. Os
590
612
  * caminhos abaixo são de um só; sem esta linha o cliente conclui que o repositório inteiro está
@@ -12,7 +12,7 @@ import { installedThemeCss, whatOnlyTheSheetResolves, } from "../sheet-needed.js
12
12
  import { flavourResolver } from "../styles-flavour.js";
13
13
  import { inTheirTongue, projectTongue, sumSpoken, } from "../their-tongue.js";
14
14
  import { readCensus, unreadComment, unreadForComponent, } from "../unread-for-component.js";
15
- import { recordWritten } from "../written.js";
15
+ import { editedSinceWritten, readWritten, recordWritten } from "../written.js";
16
16
  /**
17
17
  * Writes the shared `cn.ts` next to the components, built from THIS project's
18
18
  * installed theme.
@@ -233,6 +233,36 @@ export async function component(slug, name, opts) {
233
233
  * a mesma pergunta - qual nome este comando vai ocupar - e duas respostas para ela é o defeito.
234
234
  */
235
235
  const local = localName(res.name, opts.as);
236
+ /**
237
+ * A EDIÇÃO DELE NO QUE NÓS ESCREVEMOS - a mesma promessa do `upgrade`, no comando que a violava.
238
+ *
239
+ * O QUE ACONTECIA, caminhado em 07/09 com o binário publicado: gerei `btn2`, escrevi uma linha
240
+ * à mão no topo do arquivo, rodei `component codelevel button --as btn2` de novo - e a linha
241
+ * sumiu. Sem aviso, sem `--force`, sem uma frase.
242
+ *
243
+ * O GUARD QUE EXISTE ACIMA RESPONDE OUTRA PERGUNTA: *"você já tem este componente no seu
244
+ * repositório?"*, sobre o arquivo de ORIGEM (`recipe.api.file`), de onde o sistema foi
245
+ * importado. Ele nada sabe sobre o que NÓS escrevemos depois.
246
+ *
247
+ * E a informação existia o tempo todo: `recordWritten` grava o fingerprint de cada arquivo a
248
+ * cada escrita, e o `upgrade` a lê para dizer `kept YOUR file(s)`. Este comando gravava e nunca
249
+ * lia - a promessa valia num caminho e não no outro, e o outro é o mais percorrido: alguém traz
250
+ * o componente, ajusta, e roda de novo para pegar uma correção.
251
+ *
252
+ * A saída oferecida é a mesma que o `upgrade` oferece, e é a que ele já tem na mão: `--force`.
253
+ */
254
+ const slugDir = join(root, "_synthesisui", "ds", slug);
255
+ const editedHere = await editedSinceWritten((await readWritten(slugDir))[local], join(root, config.componentsDir, local));
256
+ if (editedHere && editedHere.length > 0 && !opts.force) {
257
+ console.log(section("You edited this one"));
258
+ console.log(body(`${editedHere.join(", ")} in ${config.componentsDir}/${local} changed after we wrote ${editedHere.length === 1 ? "it" : "them"} - kept YOUR file(s).`));
259
+ console.log("");
260
+ console.log(body("To take the new version anyway:"));
261
+ console.log(snippet([
262
+ `npx synthesisui component ${slug} ${res.name}${opts.as ? ` --as ${opts.as}` : ""} --force`,
263
+ ]));
264
+ return;
265
+ }
236
266
  const localPascal = local
237
267
  .split(/[^a-zA-Z0-9]+/)
238
268
  .filter(Boolean)
@@ -360,6 +360,26 @@ export function describeSignals(s) {
360
360
  else if (t.prefersColorScheme > 0) {
361
361
  out.push(`no dark utilities, but ${t.prefersColorScheme} \`prefers-color-scheme\` rule${t.prefersColorScheme === 1 ? "" : "s"} - the second scheme lives in CSS rather than in class names.`);
362
362
  }
363
+ else if (t.library) {
364
+ /**
365
+ * NENHUM SINAL DE SEGUNDO ESQUEMA, MAS UM ALTERNADOR INSTALADO - e as duas frases se negavam.
366
+ *
367
+ * MEDIDO EM 07/09 no `~/projects/web-subscribe`, caminhando o ATO 3: o relatório imprimia, em
368
+ * linhas CONSECUTIVAS, *"one scheme, and adding a second is a decision rather than a
369
+ * discovery"* e *"switched by next-themes"*. Quem lê recebe as duas ao mesmo tempo: não existe
370
+ * segundo esquema, e existe uma biblioteca que alterna entre esquemas.
371
+ *
372
+ * AS DUAS METADES ESTÃO CERTAS separadamente, e é isso que torna a contradição fácil de
373
+ * escrever: uma conta utilitários `dark:` e regras `prefers-color-scheme` no CSS; a outra lê o
374
+ * `package.json` e o provider. O que faltava era uma olhar para a outra.
375
+ *
376
+ * E O FATO COMBINADO É MAIS ÚTIL QUE QUALQUER UMA DAS DUAS: o alternador está instalado e não
377
+ * há nada para ele alternar. Isso é uma pendência do projeto dele - e é acionável, ao contrário
378
+ * de "adicionar um segundo esquema é uma decisão", que ele já tomou quando instalou a
379
+ * biblioteca.
380
+ */
381
+ out.push(`no dark utilities and no \`prefers-color-scheme\` - so the second scheme has nothing to paint yet, even though ${t.library} is installed to switch between them.`);
382
+ }
363
383
  else {
364
384
  out.push("no dark utilities and no `prefers-color-scheme` - one scheme, and adding a second is a decision rather than a discovery.");
365
385
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.398",
3
+ "version": "0.16.400",
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": {