synthesisui 0.16.421 → 0.16.423
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/claude-md.js +19 -38
- package/dist/commands/add.js +57 -94
- package/dist/commands/component.js +96 -201
- package/dist/commands/connect.js +41 -0
- package/dist/commands/doctor.js +74 -428
- package/dist/commands/generate.js +25 -4
- package/dist/commands/import.js +2 -2
- package/dist/commands/init.js +13 -10
- package/dist/commands/refit.js +13 -2
- package/dist/commands/summary.js +9 -5
- package/dist/commands/sync.js +84 -0
- package/dist/commands/template.js +81 -53
- package/dist/commands/upgrade.js +5 -3
- package/dist/commands/use.js +7 -8
- package/dist/component-codegen.js +50 -23
- package/dist/copy/connect.pt-BR.js +3 -0
- package/dist/doctor/apply-fix.js +2 -2
- package/dist/doctor/scan.js +33 -2
- package/dist/doctor/their-names.js +8 -2
- package/dist/fonts.js +29 -5
- package/dist/global-sheet.js +14 -125
- package/dist/guide.js +131 -83
- package/dist/install-marks.js +4 -4
- package/dist/local-edits.js +257 -0
- package/dist/project-facts.js +138 -32
- package/dist/recipe-css.js +249 -0
- package/dist/skills.js +5 -16
- package/dist/their-tongue.js +180 -43
- package/dist/wired-slugs.js +31 -17
- package/package.json +1 -1
- package/dist/setup-prompt.js +0 -95
- package/dist/sheet-needed.js +0 -317
- package/dist/skill-configure.js +0 -13
- package/dist/wiring-read.js +0 -212
|
@@ -7,14 +7,12 @@ import { readProjectConfig, resolveRegistry } from "../config.js";
|
|
|
7
7
|
import { detectAppDirs } from "../global-sheet.js";
|
|
8
8
|
import { hasInteractiveTemplate, interactiveTemplate, } from "../interactive-templates.js";
|
|
9
9
|
import { body, section, snippet } from "../output.js";
|
|
10
|
-
import { findCollision,
|
|
10
|
+
import { findCollision, reactMajorOf, readInstalledConvention, readInstalledScheme, theirThemeVars, } from "../project-facts.js";
|
|
11
11
|
import { fetchComponent, fetchDesignSystem, RegistryError, } from "../registry.js";
|
|
12
|
-
import { installedThemeCss, whatOnlyTheSheetResolves, } from "../sheet-needed.js";
|
|
13
12
|
import { flavourResolver } from "../styles-flavour.js";
|
|
14
13
|
import { inTheirTongue, projectTongue, sumSpoken, tongueFromArtifacts, } from "../their-tongue.js";
|
|
15
14
|
import { resolvableVars } from "../their-vars.js";
|
|
16
15
|
import { readCensus, unreadComment, unreadForComponent, } from "../unread-for-component.js";
|
|
17
|
-
import { readWiring } from "../wiring-read.js";
|
|
18
16
|
import { editedSinceWritten, readWritten, recordWritten } from "../written.js";
|
|
19
17
|
/**
|
|
20
18
|
* Writes the shared `cn.ts` next to the components, built from THIS project's
|
|
@@ -72,18 +70,6 @@ export function localName(blueprint, asked) {
|
|
|
72
70
|
* The component's styles reference the DS tokens, so the system itself must be
|
|
73
71
|
* installed (`synthesisui add <slug>`) for `tokens.css`/`theme.css` to resolve.
|
|
74
72
|
*/
|
|
75
|
-
/**
|
|
76
|
-
* O QUE NESTE ARQUIVO PRECISA DA FOLHA, dito uma vez.
|
|
77
|
-
*
|
|
78
|
-
* A frase aparece nos três desfechos do bloco de setup (está aí · está no repo · falta), e três
|
|
79
|
-
* redações da mesma medição são três respostas no dia em que uma for editada.
|
|
80
|
-
*/
|
|
81
|
-
function whatNeedsIt(need) {
|
|
82
|
-
const some = (list) => `${list.slice(0, 3).join(", ")}${list.length > 3 ? `, +${list.length - 3}` : ""}`;
|
|
83
|
-
return need.variables.length > 0
|
|
84
|
-
? some(need.variables)
|
|
85
|
-
: `the ${some(need.classes)} ${need.classes.length === 1 ? "utility" : "utilities"}`;
|
|
86
|
-
}
|
|
87
73
|
export async function component(slug, name, opts) {
|
|
88
74
|
const base = resolveRegistry(opts.registry);
|
|
89
75
|
const root = opts.dir ?? process.cwd();
|
|
@@ -130,19 +116,12 @@ export async function component(slug, name, opts) {
|
|
|
130
116
|
* faz, feita aqui e jogada fora depois de traduzir.
|
|
131
117
|
*
|
|
132
118
|
* UMA IDA A MAIS A' REDE, e so' neste caminho: quem ja' instalou o sistema le' do `.lock` como
|
|
133
|
-
* sempre. O `catch` mantem o comportamento antigo - sem
|
|
134
|
-
*
|
|
119
|
+
* sempre. O `catch` mantem o comportamento antigo - sem traducao, e o relato abaixo DIZ que nada
|
|
120
|
+
* foi traduzido, em vez de deixar a pessoa descobrir pela cor que nao apareceu.
|
|
135
121
|
*/
|
|
136
122
|
const fromRegistry = installedTongue
|
|
137
123
|
? null
|
|
138
124
|
: await fetchDesignSystem(base, slug, opts.version).catch(() => null);
|
|
139
|
-
/** A leitura do sistema NAO chegou - rede fora, ou sistema privado sem sessao. Ver o relato. */
|
|
140
|
-
const installedSheetMissing = !installedTongue && fromRegistry === null;
|
|
141
|
-
/**
|
|
142
|
-
* A NOSSA FOLHA ESTA' NA PASTA DELE? - o `.lock` responde, e e' o mesmo arquivo que o `add`
|
|
143
|
-
* escreve. Desde o A1 esta pergunta deixou de ser retorica: `component` roda sem ele.
|
|
144
|
-
*/
|
|
145
|
-
const installedHere = await readFile(join(root, "_synthesisui", "ds", slug, ".lock"), "utf8").then(() => true, () => false);
|
|
146
125
|
const tongue = installedTongue ??
|
|
147
126
|
(fromRegistry
|
|
148
127
|
? await tongueFromArtifacts(root, fromRegistry.artifacts)
|
|
@@ -157,13 +136,6 @@ export async function component(slug, name, opts) {
|
|
|
157
136
|
* sai no fim - depois da linha que nomeia o que foi escrito.
|
|
158
137
|
*/
|
|
159
138
|
let spoken = null;
|
|
160
|
-
/**
|
|
161
|
-
* OS BYTES QUE FORAM A DISCO - é sobre ELES que a pergunta "precisa da folha?" se responde.
|
|
162
|
-
*
|
|
163
|
-
* Pela mesma razão que `spoken` é preenchido em cada caminho de escrita: perguntar sobre o
|
|
164
|
-
* recipe, ou sobre o css antes da tradução, seria responder sobre um arquivo que ninguém abriu.
|
|
165
|
-
*/
|
|
166
|
-
let writtenSource = "";
|
|
167
139
|
/**
|
|
168
140
|
* O VEREDITO DA RAIZ - ver `GeneratedRoot` em `component-codegen.ts`.
|
|
169
141
|
*
|
|
@@ -181,7 +153,6 @@ export async function component(slug, name, opts) {
|
|
|
181
153
|
const sheet = tongue ? inTheirTongue(res.css, tongue) : null;
|
|
182
154
|
if (sheet)
|
|
183
155
|
spoken = sheet;
|
|
184
|
-
writtenSource = sheet ? sheet.css : res.css;
|
|
185
156
|
await writeFile(join(dir, `${res.name}.css`), `${sheet ? sheet.css : res.css}\n`, "utf8");
|
|
186
157
|
console.log(`✓ ${res.name} → _synthesisui/ds/${slug}/components/${res.name}.{json,css} (${slug} v${res.version})`);
|
|
187
158
|
}
|
|
@@ -380,7 +351,6 @@ export async function component(slug, name, opts) {
|
|
|
380
351
|
];
|
|
381
352
|
for (const f of written)
|
|
382
353
|
await writeFile(join(compDir, f.filename), f.content, "utf8");
|
|
383
|
-
writtenSource = written.map((f) => f.content).join("\n");
|
|
384
354
|
/** O fingerprint do que escrevemos - é o que protege a edição dele no upgrade (T7). */
|
|
385
355
|
await recordWritten(join(root, "_synthesisui", "ds", slug), local, written);
|
|
386
356
|
filenames = written.map((f) => f.filename);
|
|
@@ -405,7 +375,17 @@ export async function component(slug, name, opts) {
|
|
|
405
375
|
* O ARQUIVO e o EXPORT levam o nome dele; a CLASSE continua sendo a do blueprint. Um
|
|
406
376
|
* `<CardPreview>` vestindo `.ds-card` está estilizado certo e não faz sombra em nada dele.
|
|
407
377
|
*/
|
|
408
|
-
local, await readInstalledScheme(root, slug), tongue,
|
|
378
|
+
local, await readInstalledScheme(root, slug), tongue,
|
|
379
|
+
/**
|
|
380
|
+
* AS PASTAS DE APP, para a resposta ser a INTERSEÇÃO delas - ver `theirThemeVars`.
|
|
381
|
+
*
|
|
382
|
+
* Um componente materializado vai para uma pasta que num monorepo os dois apps importam, e
|
|
383
|
+
* ele não sabe em qual será usado. Varrer da raiz faria o `@theme` do app A responder por
|
|
384
|
+
* um componente escrito no app B: emitimos `bg-brand`, aquele app não gera a classe, e a
|
|
385
|
+
* propriedade renderiza NADA - pior que o valor arbitrário, porque nada falta na tela. É a
|
|
386
|
+
* mesma lição de `INV-VOLTA-12`, que saiu com a instrução de import e não com a topologia.
|
|
387
|
+
*/
|
|
388
|
+
await theirThemeVars(root, await detectAppDirs(root, config.pagesDir)));
|
|
409
389
|
spoken = said;
|
|
410
390
|
root_ = generatedRoot;
|
|
411
391
|
/**
|
|
@@ -430,7 +410,6 @@ export async function component(slug, name, opts) {
|
|
|
430
410
|
}));
|
|
431
411
|
for (const f of written)
|
|
432
412
|
await writeFile(join(compDir, f.filename), f.content, "utf8");
|
|
433
|
-
writtenSource = written.map((f) => f.content).join("\n");
|
|
434
413
|
await recordWritten(join(root, "_synthesisui", "ds", slug), local, written);
|
|
435
414
|
if (flavour === "tailwind")
|
|
436
415
|
await writeCn(root, compDir, slug);
|
|
@@ -449,11 +428,37 @@ export async function component(slug, name, opts) {
|
|
|
449
428
|
* pergunta é uma: o que foi escrito ainda precisa da nossa folha? Enquanto isto era calculado
|
|
450
429
|
* antes da materialização, a resposta descrevia outro arquivo.
|
|
451
430
|
*/
|
|
431
|
+
/**
|
|
432
|
+
* `left` É A FALHA, E ELE SAI PRIMEIRO - fora de qualquer condição sobre o que deu certo.
|
|
433
|
+
*
|
|
434
|
+
* O DEFEITO QUE ISTO CONSERTA, achado pela revisão de QA do fecho: este aviso estava ANINHADO em
|
|
435
|
+
* `named > 0 || inlined > 0`. O caso em que ele mais importa é justamente o que zera os dois - uma
|
|
436
|
+
* folha instalada de versão anterior, que não declara a variável que o componente novo usa. Ali
|
|
437
|
+
* `named=0`, `inlined=0`, `left=["--ds-…"]`, o byte com a nossa grafia ia para o repositório dele,
|
|
438
|
+
* e o terminal não dizia uma palavra: o ramo `else if (!tongue)` também não pega, porque o
|
|
439
|
+
* vocabulário EXISTE.
|
|
440
|
+
*
|
|
441
|
+
* É o skew de versão que `component-codegen.ts` já documenta como tendo acontecido, e a lei 8 na
|
|
442
|
+
* forma mais cara dela - a lacuna calada no único momento em que a lacuna é real.
|
|
443
|
+
*/
|
|
444
|
+
if (spoken && spoken.left.length > 0)
|
|
445
|
+
console.log(` ${spoken.left.length} value${spoken.left.length === 1 ? "" : "s"} the system declares no value for (${spoken.left.slice(0, 3).join(", ")}${spoken.left.length > 3 ? ", …" : ""}) - ${spoken.left.length === 1 ? "that declaration is" : "those declarations are"} dropped by the browser. Run \`npx synthesisui upgrade ${slug}\` to re-read the system; if it persists, please report it.`);
|
|
452
446
|
if (spoken && (spoken.named > 0 || spoken.inlined > 0)) {
|
|
453
447
|
console.log(` ${spoken.named} reference${spoken.named === 1 ? "" : "s"} now speak${spoken.named === 1 ? "s" : ""} the name YOUR code gives the value${spoken.inlined > 0 ? `, and ${spoken.inlined} carr${spoken.inlined === 1 ? "ies" : "y"} the value because your code names no token for it` : ""}.`);
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
448
|
+
if (spoken.left.length === 0)
|
|
449
|
+
console.log(` Nothing in what was just written points at us - every value is a name YOUR code declares, or the value itself.`);
|
|
450
|
+
/**
|
|
451
|
+
* O QUE CONGELOU ENTRE OS ESQUEMAS - ver `Tongue.frozen`, e é lei 8 na forma mais barata dela.
|
|
452
|
+
*
|
|
453
|
+
* Um valor que muda com o tema e que o código dele não nomeia sai como o literal do esquema
|
|
454
|
+
* base: renderiza certo hoje, e não vira quando ele alterna. É o tipo de coisa que ele nota na
|
|
455
|
+
* tela e não tem como explicar - e nomear aquele valor no próprio vocabulário é o conserto, que
|
|
456
|
+
* é decisão dele.
|
|
457
|
+
*
|
|
458
|
+
* MEDIDO em 11/09 na folha do `codelevel`: 3 de 119.
|
|
459
|
+
*/
|
|
460
|
+
if (spoken.froze > 0)
|
|
461
|
+
console.log(` ${spoken.froze} of ${spoken.froze === 1 ? "those changes" : "those change"} with the colour scheme, and ${spoken.froze === 1 ? "it is" : "they are"} written here as the value of the resting one - so ${spoken.froze === 1 ? "it does" : "they do"} not flip when the scheme does. Name ${spoken.froze === 1 ? "it" : "them"} in your own code and the next run writes your name instead.`);
|
|
457
462
|
/**
|
|
458
463
|
* E DIZER DE ONDE VEIO O VOCABULARIO, quando o sistema NAO esta' instalado aqui.
|
|
459
464
|
*
|
|
@@ -464,179 +469,56 @@ export async function component(slug, name, opts) {
|
|
|
464
469
|
*/
|
|
465
470
|
if (fromRegistry)
|
|
466
471
|
console.log(` Nothing of ours was installed to do that - the system was read at v${fromRegistry.version}, and the names came from your own code.`);
|
|
467
|
-
}
|
|
468
|
-
else if (!tongue) {
|
|
469
472
|
/**
|
|
470
|
-
*
|
|
473
|
+
* E POR QUE NENHUM NOME DELE ENTROU, quando nenhum entrou - lei 8, e a causa tem conserto.
|
|
471
474
|
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
+
* `their-vars.ts` recusa todo par que o BUILD dele não emite, por desenho: um nome afirmado sem
|
|
476
|
+
* prova pinta a cor errada no dia em que ele o renomear. Num clone fresco isso é o caso normal,
|
|
477
|
+
* e o efeito é um arquivo inteiro de valores literais - que funciona, e que perde a ligação com
|
|
478
|
+
* as decisões dele.
|
|
475
479
|
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
480
|
+
* A frase que este ramo substituiu dizia *"nada foi traduzido"*, e ela era verdade quando a
|
|
481
|
+
* tradução dependia do mapa. Desde 11/09 a folha responde sozinha: sempre há tradução, e o que
|
|
482
|
+
* varia é se ela achou NOMES dele ou só valores.
|
|
479
483
|
*/
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
* desenho: um nome afirmado sem prova pinta a cor errada no dia
|
|
487
|
-
* em que ele o renomear. Num clone fresco isso e' o caso normal
|
|
488
|
-
* o codigo dele nao nomeia nada a unica que o silencio de fato descrevia
|
|
489
|
-
*/
|
|
490
|
-
const noBuild = !installedSheetMissing && (await resolvableVars(root)) === null;
|
|
491
|
-
console.log(installedSheetMissing
|
|
492
|
-
? ` Nothing was translated: "${slug}" could not be read from the registry just now, so the variables stayed as ours. Check your connection, or run: npx synthesisui login`
|
|
493
|
-
: noBuild
|
|
494
|
-
? ` Nothing was translated: this project has no build output to read, and a name we cannot see your build emit is a name we will not write. Run your build once and ask for it again - the file then speaks your own names.`
|
|
495
|
-
: ` Nothing was translated: your code names none of the values this system declares yet, so the variables stayed as ours and tokens.css is what resolves them.`);
|
|
484
|
+
if (spoken.named === 0 && spoken.inlined > 0) {
|
|
485
|
+
const noBuild = (await resolvableVars(root)) === null;
|
|
486
|
+
console.log(noBuild
|
|
487
|
+
? ` None of them is a name yet: this project has no build output to read, and a name we cannot see your build emit is a name we will not write. Run your build once and ask again - the file then speaks your own names.`
|
|
488
|
+
: ` None of them is a name yet: your code names none of the values this system declares. The values above work as they are; naming one is yours to decide.`);
|
|
489
|
+
}
|
|
496
490
|
}
|
|
497
|
-
|
|
498
|
-
const tailwind = flavour === "tailwind";
|
|
499
|
-
const imports = tailwind
|
|
500
|
-
? [
|
|
501
|
-
`@import "tailwindcss";`,
|
|
502
|
-
`@import "../_synthesisui/ds/${slug}/tokens.css";`,
|
|
503
|
-
`@import "../_synthesisui/ds/${slug}/theme.css";`,
|
|
504
|
-
]
|
|
505
|
-
: [`@import "../_synthesisui/ds/${slug}/tokens.css";`];
|
|
506
|
-
/**
|
|
507
|
-
* O SETUP SÓ É COBRADO QUANDO ESTE ARQUIVO PRECISA DELE - ver `sheet-needed.ts`.
|
|
508
|
-
*
|
|
509
|
-
* O DEFEITO, apontado pelo dono olhando a própria tela (07/09): o comando terminava dizendo
|
|
510
|
-
* *"No variable in what was just written points at our stylesheet"* e, três linhas abaixo,
|
|
511
|
-
* imprimia **One-time setup** mandando colar dois `@import`. As duas frases não podem ser
|
|
512
|
-
* verdadeiras ao mesmo tempo, e a segunda pedia uma dependência de runtime para um arquivo que
|
|
513
|
-
* não a usa.
|
|
514
|
-
*
|
|
515
|
-
* A VERSÃO ANTERIOR DESTE BLOCO já tinha visto metade do problema e parou na metade: manteve o
|
|
516
|
-
* setup e acrescentou *"o que estes imports ainda trazem são os utilitários do sistema e o
|
|
517
|
-
* movimento"*. A razão é real - `INV-VOLTA-13` deixa no `@theme` os nomes que só o sistema tem -
|
|
518
|
-
* mas ela era AFIRMADA, nunca medida. No `codelevel` aquele `@theme` declara 50 variáveis, todas
|
|
519
|
-
* `--animate-*` e `--max-width-*`, e o componente gerado não veste nenhuma delas: as duas
|
|
520
|
-
* animações que ele usa são declaradas pelo `globals.css` DELE.
|
|
521
|
-
*
|
|
522
|
-
* Então a pergunta passa a ser feita: sobrou variável nossa, ou classe que só o nosso `@theme`
|
|
523
|
-
* gera? Se nenhuma das duas, o arquivo está isolado e o bloco diz isso - com o que o import ainda
|
|
524
|
-
* daria, para a escolha continuar sendo dele.
|
|
525
|
-
*/
|
|
526
|
-
const need = whatOnlyTheSheetResolves({
|
|
527
|
-
source: writtenSource,
|
|
491
|
+
else if (!tongue) {
|
|
528
492
|
/**
|
|
529
|
-
*
|
|
493
|
+
* NEM A FOLHA VEIO - e desde 11/09 é a ÚNICA causa que resta para não haver tradução.
|
|
530
494
|
*
|
|
531
|
-
* A
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
|
|
535
|
-
themeCss: fromRegistry?.artifacts?.["theme.css"] ??
|
|
536
|
-
(await installedThemeCss(root, slug)),
|
|
537
|
-
/** O vocabulário DELE sai da conta - ver `theirNames`. O mapa do `.lock` é a via mais barata. */
|
|
538
|
-
theirNames: tongue?.names ? [...tongue.names.values()] : [],
|
|
539
|
-
/**
|
|
540
|
-
* A TERCEIRA FONTE NÃO É MEDIDA AQUI, e o vazio é a resposta EXPLÍCITA disso.
|
|
495
|
+
* A pasta não existe e a leitura do registry não chegou: rede fora, sessão ausente, sistema
|
|
496
|
+
* privado. O arquivo sai com a nossa grafia porque não há de onde tirar nem nome nem valor, e
|
|
497
|
+
* isso SE DIZ - a pessoa abre o arquivo, vê variáveis que o `globals.css` dela não declara, e a
|
|
498
|
+
* única forma de descobrir por que a cor não apareceu seria ler o nosso código.
|
|
541
499
|
*
|
|
542
|
-
* As
|
|
543
|
-
*
|
|
544
|
-
* diz *"This file needs nothing else… It is yours."* sobre um componente cujo estilo inteiro vem
|
|
545
|
-
* de `.ds-button`. Ligar a medição aqui é mudar o que este comando promete, com o bloco de setup
|
|
546
|
-
* dele para redesenhar: é etapa própria. O que o argumento obrigatório garante é que a omissão
|
|
547
|
-
* está ESCRITA, e não escondida num parâmetro que ninguém passou.
|
|
500
|
+
* As outras duas causas que este ramo distinguia - o build ausente e o código que não nomeia
|
|
501
|
+
* nada - deixaram de impedir a tradução, e viraram a linha logo acima.
|
|
548
502
|
*/
|
|
549
|
-
|
|
550
|
-
});
|
|
551
|
-
if (!need.needed) {
|
|
552
|
-
console.log(section("This file needs nothing else"));
|
|
553
|
-
console.log(body("Every variable and class in it is declared by your own code - no import, no scope"));
|
|
554
|
-
console.log(body("attribute, nothing at runtime. It is yours."));
|
|
555
|
-
console.log("");
|
|
556
|
-
console.log(body(`The system stays what it is here: the reference your agent reads to build ON it.`));
|
|
557
|
-
console.log(body(`If you later want the utilities only its own @theme generates, that is when`));
|
|
558
|
-
console.log(body(`importing earns its place - and \`doctor\` says so.`));
|
|
503
|
+
console.log(` Nothing was translated: "${slug}" could not be read from the registry just now, so the variables stayed as ours. Check your connection, or run: npx synthesisui login`);
|
|
559
504
|
}
|
|
560
505
|
/**
|
|
561
|
-
* E
|
|
562
|
-
* junto a única linha que diz COMO importar o componente. Dizer "está isolado" e sonegar o
|
|
563
|
-
* `import { ButtonSample }` troca um defeito por outro.
|
|
564
|
-
*/
|
|
565
|
-
/**
|
|
566
|
-
* A FIAÇÃO JÁ ESTÁ AQUI? - ver `wiring-read.ts`, a MESMA leitura que o `doctor` usa.
|
|
506
|
+
* E NÃO HÁ SETUP A PEDIR - `INV-GERAL-13`, e este bloco tinha 120 linhas até 11/09.
|
|
567
507
|
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
508
|
+
* O QUE ELE FAZIA: media se o arquivo recém-escrito ainda apontava para a nossa folha e, quando
|
|
509
|
+
* sim, imprimia **One-time setup** com dois `@import` e um `data-ds` para colar. O dono leu isso
|
|
510
|
+
* na própria tela e a frase dele fecha o assunto: *"isso nunca deve acontecer, a gente havia
|
|
511
|
+
* combinado (...) garanta que nunca mais você irá falar desse import e nem solicitar e nem
|
|
512
|
+
* precisar nos projetos"*.
|
|
571
513
|
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* O ADAPTADOR CONTA quando o que precisa da folha são UTILITÁRIOS - eles só existem pelo
|
|
578
|
-
* `@theme` do `theme.css`. Dizer "está tudo aí" com o `tokens.css` sozinho declararia resolvido
|
|
579
|
-
* exatamente o que continua faltando.
|
|
580
|
-
*/
|
|
581
|
-
const sheetsThere = wiring?.imported === true && (!tailwind || wiring?.themed === true);
|
|
582
|
-
/**
|
|
583
|
-
* E A RESPOSTA É DO PROJETO, NÃO DO APP - então num repositório com mais de um app ela não
|
|
584
|
-
* decide, e o comando diz isso em vez de afirmar (`INV-VOLTA-12`: monorepo é a forma comum).
|
|
514
|
+
* O QUE MATOU A PERGUNTA foi a causa, não o texto. Nenhuma variável nossa chega ao arquivo
|
|
515
|
+
* (`speak`), e nenhum utilitário nomeado depende do nosso `@theme` (`theirThemeVars`). Não sobra
|
|
516
|
+
* nada para uma folha nossa resolver - então não há o que perguntar, e a leitura da fiação
|
|
517
|
+
* (`readWiring`, `sheet-needed.ts`) saiu junto com a cobrança.
|
|
585
518
|
*
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* acabou de escrever vai para uma pasta só de componentes, que não desambigua qual app o usa.
|
|
519
|
+
* O relatório da tradução, logo acima, é o que substitui: ele diz o que aconteceu com os bytes
|
|
520
|
+
* que foram a disco, e o que sobrou quando algo sobrou.
|
|
589
521
|
*/
|
|
590
|
-
const appDirs = await detectAppDirs(root, config.pagesDir ?? "app");
|
|
591
|
-
const oneApp = appDirs.length <= 1;
|
|
592
|
-
const alreadyWired = sheetsThere && wiring?.scoped === true;
|
|
593
|
-
if (need.needed && alreadyWired && !oneApp) {
|
|
594
|
-
console.log(section(`This file needs the sheet - and this repo has it`));
|
|
595
|
-
console.log(body(`What needs it: ${whatNeedsIt(need)}.`));
|
|
596
|
-
console.log(body(`Measured across this repository, not per app: ${slug}'s sheet is imported and`));
|
|
597
|
-
console.log(body(`data-ds="${slug}" is set somewhere in it. There ${appDirs.length === 2 ? "are two apps" : `are ${appDirs.length} apps`} here (${appDirs.slice(0, 2).join(", ")}${appDirs.length > 2 ? ", …" : ""}),`));
|
|
598
|
-
console.log(body(`so if this file lands in one that does not carry them, run \`doctor\` inside it.`));
|
|
599
|
-
}
|
|
600
|
-
if (need.needed && alreadyWired && oneApp) {
|
|
601
|
-
console.log(section(`This file needs the sheet - and it is already there`));
|
|
602
|
-
console.log(body(`What needs it: ${whatNeedsIt(need)}.`));
|
|
603
|
-
console.log(body(`This project already imports ${slug}'s ${tailwind ? "tokens.css and theme.css" : "tokens.css"} and carries data-ds="${slug}",`));
|
|
604
|
-
console.log(body(wiring?.fontsMapped
|
|
605
|
-
? `and its type is mapped onto the system's family tokens. Nothing to set up.`
|
|
606
|
-
: `so nothing to set up here. \`doctor\` says whether the type is mapped too.`));
|
|
607
|
-
}
|
|
608
|
-
if (need.needed && !alreadyWired) {
|
|
609
|
-
console.log(section(`One-time setup (once per app, for "${slug}")`));
|
|
610
|
-
/**
|
|
611
|
-
* O PASSO ZERO VEM PRIMEIRO QUANDO A FOLHA NAO EXISTE - e desde o A1 este e' o caso comum.
|
|
612
|
-
*
|
|
613
|
-
* O QUE ACONTECIA: o passo 1 mandava colar `@import ".../tokens.css"` e o aviso de que o
|
|
614
|
-
* sistema nao esta' instalado saia na ULTIMA linha, entre parenteses. Quem nunca rodou `add`
|
|
615
|
-
* - agora um caminho normal, porque o `component` deixou de exigi-lo - lia a instrucao de
|
|
616
|
-
* cima para baixo e importava um caminho que nao existe. O erro do build nao fala de
|
|
617
|
-
* install: fala de um arquivo ausente.
|
|
618
|
-
*
|
|
619
|
-
* O motivo antes da instrucao, e nao depois dela.
|
|
620
|
-
*/
|
|
621
|
-
if (!installedHere)
|
|
622
|
-
console.log(body(`First: "${slug}" is not installed in this project yet, so the file the import below points at does not exist. Run \`npx synthesisui add ${slug}\` before pasting it.`));
|
|
623
|
-
console.log(body(need.variables.length > 0
|
|
624
|
-
? `(what still needs the sheet here: ${need.variables.slice(0, 3).join(", ")}${need.variables.length > 3 ? `, +${need.variables.length - 3}` : ""} - your code names no value for ${need.variables.length === 1 ? "it" : "them"})`
|
|
625
|
-
: `(what still needs the sheet here: the ${need.classes.slice(0, 3).join(", ")}${need.classes.length > 3 ? `, +${need.classes.length - 3}` : ""} ${need.classes.length === 1 ? "utility" : "utilities"}, which only this system's @theme generates)`));
|
|
626
|
-
console.log("");
|
|
627
|
-
console.log(body(`1. Import the design system in your GLOBAL stylesheet, e.g. app/globals.css`));
|
|
628
|
-
console.log(body(` (the path is relative to that file - hence the leading ../):`));
|
|
629
|
-
console.log("");
|
|
630
|
-
console.log(snippet(imports));
|
|
631
|
-
console.log("");
|
|
632
|
-
console.log(body(`2. Scope your app: add data-ds="${slug}" to a ROOT element, e.g. app/layout.tsx:`));
|
|
633
|
-
console.log("");
|
|
634
|
-
console.log(snippet([`<body data-ds="${slug}">{children}</body>`]));
|
|
635
|
-
if (installedHere) {
|
|
636
|
-
console.log("");
|
|
637
|
-
console.log(body(`(If you haven't installed the system yet, run: synthesisui add ${slug})`));
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
522
|
/**
|
|
641
523
|
* O ELEMENTO QUE SAIU NÃO ATIVA O QUE A RECEITA PEDE - e isso se diz, em vez de sumir (lei 8).
|
|
642
524
|
*
|
|
@@ -709,11 +591,24 @@ export async function component(slug, name, opts) {
|
|
|
709
591
|
]));
|
|
710
592
|
}
|
|
711
593
|
else {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
594
|
+
/**
|
|
595
|
+
* O CAMINHO DOS ARTEFATOS NÃO MANDA IMPORTAR DA NOSSA PASTA - `INV-GERAL-13`, 11/09.
|
|
596
|
+
*
|
|
597
|
+
* A instrução era `@import "../_synthesisui/ds/<slug>/components/<name>.css"`, e ela criava
|
|
598
|
+
* exatamente a dependência que esta etapa fechou: a folha dele passava a apontar para dentro da
|
|
599
|
+
* nossa pasta, e o build dele quebrava no dia em que aquela pasta mudasse de nome ou saísse do
|
|
600
|
+
* versionamento (é o defeito medido em 24/08, com `Can't resolve` e exit code 1).
|
|
601
|
+
*
|
|
602
|
+
* O ARQUIVO JÁ É DELE, e é isso que torna a resposta simples: ele passou pela porta de tradução
|
|
603
|
+
* um pouco acima, então cada valor nele é um nome que o código dele declara ou o valor em si.
|
|
604
|
+
* Copiá-lo para onde as folhas dele vivem não perde nada, e o que fica em `_synthesisui/` segue
|
|
605
|
+
* sendo a nossa referência.
|
|
606
|
+
*/
|
|
607
|
+
console.log(body("The stylesheet above already speaks your vocabulary -"));
|
|
608
|
+
console.log(body("copy it next to the markup that uses it, wherever your"));
|
|
609
|
+
console.log(body("stylesheets live. Nothing of ours has to be loaded:"));
|
|
610
|
+
console.log("");
|
|
611
|
+
console.log(snippet([`<div class="ds-${res.name}">…</div>`]));
|
|
717
612
|
}
|
|
718
613
|
console.log("");
|
|
719
614
|
}
|
package/dist/commands/connect.js
CHANGED
|
@@ -39,6 +39,26 @@ import { installedSlugs } from "./sync.js";
|
|
|
39
39
|
* um cliente que rodou `connect` há um mês não sabe que o nome mudou.
|
|
40
40
|
*/
|
|
41
41
|
const LEGACY_SKILLS = ["import-design-system"];
|
|
42
|
+
/**
|
|
43
|
+
* SKILLS QUE SAÍRAM DO PRODUTO - e a régua aqui é o OPOSTO da de cima.
|
|
44
|
+
*
|
|
45
|
+
* `LEGACY_SKILLS` é renomeação: o mesmo playbook mudou de nome, e apagar a pasta antiga é o conserto
|
|
46
|
+
* porque a nova ocupa o lugar dela. Aqui o playbook deixou de existir, e não há substituto - então a
|
|
47
|
+
* regra é a que ele fixou em 10/09 sobre os agentes: **desmarcar nunca apaga, mas NOMEIA o que
|
|
48
|
+
* ficou**. Uma pasta que some sozinha de `.claude/skills/` do repositório dele é a plataforma
|
|
49
|
+
* editando o repositório de alguém sem pedir.
|
|
50
|
+
*
|
|
51
|
+
* `sui-configure-ds` existia para uma coisa só: *"set up an installed design system in the app so
|
|
52
|
+
* its tokens actually reach the browser - the stylesheet import"*. Nada no app dele carrega nada
|
|
53
|
+
* nosso (`INV-GERAL-13`), então ela não tem mais objeto - e um agente que a invocar hoje vai
|
|
54
|
+
* executar um playbook que pede exatamente o que o produto promete nunca pedir.
|
|
55
|
+
*/
|
|
56
|
+
const RETIRED_SKILLS = [
|
|
57
|
+
{
|
|
58
|
+
dir: "sui-configure-ds",
|
|
59
|
+
why: "retired - nothing of ours loads in your app any more",
|
|
60
|
+
},
|
|
61
|
+
];
|
|
42
62
|
/**
|
|
43
63
|
* OS ARQUIVOS DO INSTALL, PÔSTOS EM DIA COM ESTE CLI.
|
|
44
64
|
*
|
|
@@ -566,6 +586,27 @@ export async function connect(opts) {
|
|
|
566
586
|
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
567
587
|
row(true, `✕ /${legacy.padEnd(21)} ${say("removed - renamed to /sui-import-ds")}`);
|
|
568
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* A SKILL APOSENTADA É NOMEADA, e o arquivo fica - ver `RETIRED_SKILLS`.
|
|
591
|
+
*
|
|
592
|
+
* Com o caminho literal, porque uma linha que diz *"uma skill saiu"* devolve a ele o trabalho de
|
|
593
|
+
* procurar qual (pedido dele, 09/09). Só aparece para quem TEM o arquivo: avisar sobre uma pasta
|
|
594
|
+
* que nunca existiu é ruído.
|
|
595
|
+
*/
|
|
596
|
+
for (const retired of RETIRED_SKILLS) {
|
|
597
|
+
const path = join(".claude", "skills", retired.dir, "SKILL.md");
|
|
598
|
+
if (!(await exists(join(root, path))))
|
|
599
|
+
continue;
|
|
600
|
+
/**
|
|
601
|
+
* O CAMINHO VAI NO `under` DA MESMA LINHA, e não numa linha própria.
|
|
602
|
+
*
|
|
603
|
+
* `row(false, …)` não IMPRIME: ele entra na contagem de *"N outras peças já atuais"*, que é o
|
|
604
|
+
* mecanismo que mantém a tela curta. Uma segunda chamada para o caminho fazia a linha da skill
|
|
605
|
+
* sair sem ele - exatamente o *"uma linha que espera ele e não diz ONDE"* que o formato de
|
|
606
|
+
* resposta proíbe. Medido rodando o comando: a prova de A6 pegou.
|
|
607
|
+
*/
|
|
608
|
+
row(true, `✕ /${retired.dir.padEnd(21)} ${say(retired.why)}`, `${say("it stays in your repo - yours to delete")}: ${path}`);
|
|
609
|
+
}
|
|
569
610
|
/** Se ALGUMA skill mudou nesta rodada - é o que autoriza a frase da sessão nova a citá-las. */
|
|
570
611
|
let skillsMoved = false;
|
|
571
612
|
for (const skill of skills) {
|