synthesisui 0.16.421 → 0.16.422
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 +37 -97
- 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/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/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
package/dist/claude-md.js
CHANGED
|
@@ -158,34 +158,21 @@ best reasoning you produce.`;
|
|
|
158
158
|
* agent is pointed at the harmless half and told to ask for the other.
|
|
159
159
|
*/
|
|
160
160
|
/**
|
|
161
|
-
*
|
|
161
|
+
* A PONTE DO SHADCN SAIU DAQUI EM 11/09 - `INV-GERAL-13`.
|
|
162
162
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
163
|
+
* O QUE ESTE PARÁGRAFO FAZIA: mandava o agente dele colar `@import "_synthesisui/ds/<slug>/shadcn.css"`
|
|
164
|
+
* na folha dele, para que os componentes shadcn do projeto vestissem o sistema em vez dos defaults
|
|
165
|
+
* do shadcn. O valor é real - era a resposta para *"por que não só usar shadcn?"* -, e a forma
|
|
166
|
+
* estava errada: um bloco escrito no `CLAUDE.md` dele, que ele lê a cada sessão, pedindo um import
|
|
167
|
+
* da nossa folha.
|
|
167
168
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* sidebar on shadcn's defaults next to components wearing the system, which
|
|
171
|
-
* reads as a broken product rather than a missing import.
|
|
169
|
+
* ERA O PIOR LUGAR PARA A INSTRUÇÃO EXISTIR. Um comentário no terminal rola; este bloco é lido por
|
|
170
|
+
* todo agente em toda sessão, e um agente obediente cola a linha sem que uma pessoa decida nada.
|
|
172
171
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
172
|
+
* A ponte continua sendo compilada e continua caindo em `_synthesisui/ds/<slug>/`, como insumo
|
|
173
|
+
* nosso. Vestir os componentes shadcn dele é uma frente própria, e ela se resolve como o resto do
|
|
174
|
+
* produto: escrevendo no vocabulário DELE, não pedindo que ele carregue o nosso.
|
|
175
175
|
*/
|
|
176
|
-
const SHADCN = (slug) => `
|
|
177
|
-
|
|
178
|
-
**This project has shadcn, and this system already speaks its language.** A
|
|
179
|
-
generated bridge maps shadcn's whole variable contract - colour, charts, radius,
|
|
180
|
-
the sidebar family - onto this system's tokens, in both schemes:
|
|
181
|
-
|
|
182
|
-
@import "_synthesisui/ds/${slug}/shadcn.css";
|
|
183
|
-
|
|
184
|
-
after the tokens.css import, in the same stylesheet. With that line in place,
|
|
185
|
-
shadcn components wear this system and need no edits from you. Without it they
|
|
186
|
-
stay on shadcn's defaults, which looks like the design system failing rather than
|
|
187
|
-
one import missing - so check for it before you add a shadcn component, and add
|
|
188
|
-
it if it is not there.`;
|
|
189
176
|
/**
|
|
190
177
|
* A REGRA QUE TIRA O "O DEV FAZ ALGO", e ela vale para todo agente que lê este bloco.
|
|
191
178
|
*
|
|
@@ -462,9 +449,9 @@ is no component index for an adopted system: the tokens ARE the contract.
|
|
|
462
449
|
\`system_doctrine\` for the rules and the voice, \`find_token\` for a value you are about to write.${memoryLine}${selfCheck}`
|
|
463
450
|
: `**These are true without asking anyone:**
|
|
464
451
|
|
|
465
|
-
-
|
|
466
|
-
|
|
467
|
-
|
|
452
|
+
- The system's vocabulary only - and it is written in the names THIS project declares. \`find_token\`
|
|
453
|
+
answers with the exact name for a value you are about to write. No raw values outside the scale,
|
|
454
|
+
and never a name from a stylesheet this project does not have.
|
|
468
455
|
- To override a style a component already sets, use this system's semantic role class - never \`!\`.
|
|
469
456
|
If the override is ignored, regenerate that component: older ones predate the resolver.
|
|
470
457
|
- Motion is selection, not improvisation. The base is quiet: nothing moves until a person asks, and
|
|
@@ -489,9 +476,10 @@ project's OWN custom properties, exactly as the guide lists them. Do not write r
|
|
|
489
476
|
spacings or radii that a token already covers, and do not invent a new token silently - say so
|
|
490
477
|
instead, because a new token is a decision for a person to make. There is no component
|
|
491
478
|
manifest for an adopted system - the tokens ARE the contract.${selfCheck}`
|
|
492
|
-
: `**When creating or editing components, read the system's GUIDE.md and follow it:** use
|
|
493
|
-
|
|
494
|
-
|
|
479
|
+
: `**When creating or editing components, read the system's GUIDE.md and follow it:** use the
|
|
480
|
+
vocabulary it lists - every name in it is a name THIS project already declares, written exactly as
|
|
481
|
+
you would write it. Do not use raw values outside the system's scale, and never a name from a
|
|
482
|
+
stylesheet this project does not have.
|
|
495
483
|
|
|
496
484
|
**Before creating any UI element, look it up in the manifest below.** If something there
|
|
497
485
|
already covers the purpose, do not write it from scratch - run
|
|
@@ -539,16 +527,9 @@ element. Write every user-facing string in that language - labels, empty states,
|
|
|
539
527
|
\`alt\`. A screen reader pronounces \`aria-label\` using \`lang\`, so a mixed-language interface is
|
|
540
528
|
worse than an untranslated one. If the attribute is wrong, change it rather than writing against
|
|
541
529
|
it.`;
|
|
542
|
-
// Named for the first installed system: the bridge is per-system, and a
|
|
543
|
-
// project with two of them has already chosen which one dresses the app.
|
|
544
|
-
const bridgeable = installed.find((d) => !d.adopted);
|
|
545
|
-
const shadcn = bridgeable &&
|
|
546
|
-
(await readFile(join(projectRoot, "components.json"), "utf8").then(() => true, () => false))
|
|
547
|
-
? SHADCN(bridgeable.slug)
|
|
548
|
-
: "";
|
|
549
530
|
const body = `## Design Systems (via SynthesisUI)
|
|
550
531
|
|
|
551
|
-
This project uses design system(s) tracked by the \`synthesisui\` CLI. ${rule}${language}
|
|
532
|
+
This project uses design system(s) tracked by the \`synthesisui\` CLI. ${rule}${language}
|
|
552
533
|
|
|
553
534
|
${sections.join("\n")}
|
|
554
535
|
|
package/dist/commands/add.js
CHANGED
|
@@ -5,7 +5,7 @@ import { syncClaudeMd } from "../claude-md.js";
|
|
|
5
5
|
import { readProjectConfig, readToken, resolveRegistry } from "../config.js";
|
|
6
6
|
import { parseRules } from "../doctrine.js";
|
|
7
7
|
import { customFontFamilies, googleFontsHref, nextFontSnippet, } from "../fonts.js";
|
|
8
|
-
import { detectAppDirs
|
|
8
|
+
import { detectAppDirs } from "../global-sheet.js";
|
|
9
9
|
import { lockReference } from "../group-role.js";
|
|
10
10
|
import { buildGuide } from "../guide.js";
|
|
11
11
|
import { censusScope } from "../measured-scope.js";
|
|
@@ -17,6 +17,7 @@ import { repoStateOf } from "../repo-state.js";
|
|
|
17
17
|
import { describeFiltered, ruleApplies, rulesForProject, } from "../rule-filter.js";
|
|
18
18
|
import { detectStack } from "../stack.js";
|
|
19
19
|
import { onlyWhatMatched } from "../their-theme.js";
|
|
20
|
+
import { tongueOf } from "../their-tongue.js";
|
|
20
21
|
import { pointTokensAtTheirNames } from "../their-vars.js";
|
|
21
22
|
import { tracksAnyOf } from "../tracked.js";
|
|
22
23
|
/**
|
|
@@ -245,7 +246,16 @@ export async function add(slug, opts) {
|
|
|
245
246
|
* certa, não uma falha - lá não existe `next/font` para ter peso nenhum.
|
|
246
247
|
*/
|
|
247
248
|
const fontFacts = await nextFontFacts(projectRoot);
|
|
248
|
-
|
|
249
|
+
/**
|
|
250
|
+
* O GUIA FALA A LÍNGUA DELE - `INV-GERAL-13`, e a folha REESCRITA é a fonte.
|
|
251
|
+
*
|
|
252
|
+
* `theirVars.css` é o `tokens.css` já apontado para o vocabulário dele nesta máquina, que é
|
|
253
|
+
* exatamente o que caiu na pasta um passo acima. Ler dali, e não do payload cru, é o que garante
|
|
254
|
+
* que o guia e o componente materializado digam o MESMO nome para o mesmo valor - duas leituras
|
|
255
|
+
* da mesma folha, uma delas livre para discordar, é a forma de dois textos nossos ensinarem dois
|
|
256
|
+
* vocabulários.
|
|
257
|
+
*/
|
|
258
|
+
await writeFile(join(versionDir, "GUIDE.md"), buildGuide(payload, tools.available, fontFacts, tongueOf(theirVars.pairs, theirVars.css)), "utf8");
|
|
249
259
|
// 4. stable root re-exports for each CSS artifact → always the active version,
|
|
250
260
|
// so the consumer's @import path never changes across updates
|
|
251
261
|
const cssArtifacts = Object.keys(payload.artifacts).filter((f) => f.endsWith(".css") && !(f === "shadcn.css" && !wantsShadcn));
|
|
@@ -585,106 +595,40 @@ export async function add(slug, opts) {
|
|
|
585
595
|
: ` CLAUDE.md updated - your file is intact, with our block inside it (${claudeMd.count} system(s) indexed)`);
|
|
586
596
|
if (opts.setupHints === false)
|
|
587
597
|
return;
|
|
588
|
-
const hasTheme = cssArtifacts.includes("theme.css");
|
|
589
598
|
// ── DX: concrete paths + copy-pasteable snippets, with breathing room ──
|
|
590
|
-
// Where the app actually lives (app/ vs src/app/) drives
|
|
591
|
-
//
|
|
599
|
+
// Where the app actually lives (app/ vs src/app/) still drives where `fonts.ts`
|
|
600
|
+
// lands and which layout the snippet names. The @import depth went with the
|
|
601
|
+
// setup block - see the comment below.
|
|
592
602
|
const projectConfig = await readProjectConfig(projectRoot);
|
|
593
603
|
const appDirs = await detectAppDirs(projectRoot, projectConfig.pagesDir);
|
|
594
604
|
/** Nenhuma pasta encontrada: os caminhos viram exemplo, e o texto abaixo diz isso. */
|
|
595
605
|
const appDir = appDirs[0] ?? projectConfig.pagesDir;
|
|
596
606
|
const appDirFound = appDirs.length > 0;
|
|
597
607
|
/**
|
|
598
|
-
*
|
|
608
|
+
* O SETUP SAIU DAQUI EM 11/09 - `INV-GERAL-13`, e eram os dois `@import` mais o `data-ds`.
|
|
599
609
|
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
* O QUE MUDA É A HONESTIDADE DO ENUNCIADO. "One-time setup" lido logo após a instalação soa como
|
|
618
|
-
* obrigação, e para metade dos casos ele não é: quem vai trazer componentes como CÓDIGO SEU não
|
|
619
|
-
* precisa de folha nenhuma - o `component` traduz para o vocabulário do próprio repositório e diz,
|
|
620
|
-
* arquivo a arquivo, se sobrou algo. Quem vai ESCREVER as classes do sistema (`bg-brand`,
|
|
621
|
-
* `rounded-lg` no valor dele) precisa, porque só o `@theme` do adaptador as gera.
|
|
622
|
-
*
|
|
623
|
-
* Então a instrução continua inteira - suprimi-la entregaria um projeto sem as classes - e ganha a
|
|
624
|
-
* linha que diz QUAL dos dois casos exige cada coisa. A escolha volta a ser dele, informada.
|
|
625
|
-
*/
|
|
626
|
-
console.log(line("(needed if you will WRITE this system's utility classes - only its @theme generates them."));
|
|
627
|
-
console.log(line(" Bringing components in as YOUR code needs none of it: `component` translates them into"));
|
|
628
|
-
console.log(line(" your own vocabulary and tells you, per file, if anything is left.)"));
|
|
629
|
-
console.log("");
|
|
630
|
-
/**
|
|
631
|
-
* "ONCE PER APP" É LITERAL NUM MONOREPO, e calar os outros apps entrega metade da fiação. Os
|
|
632
|
-
* caminhos abaixo são de um só; sem esta linha o cliente conclui que o repositório inteiro está
|
|
633
|
-
* ligado quando só o primeiro está.
|
|
610
|
+
* O QUE O DONO VIU, e é o que abriu esta etapa: o `upgrade` imprimiu
|
|
611
|
+
*
|
|
612
|
+
* @import "../../../../_synthesisui/ds/codelevel/tokens.css";
|
|
613
|
+
* @import "../../../../_synthesisui/ds/codelevel/theme.css";
|
|
614
|
+
*
|
|
615
|
+
* e a resposta dele foi *"não! isso nunca deve acontecer, a gente havia combinado isso"*.
|
|
616
|
+
*
|
|
617
|
+
* A INSTRUÇÃO EXISTIA POR UMA RAZÃO REAL, e a razão acabou. Sem a folha carregada, o
|
|
618
|
+
* `var(--ds-*)` que a plataforma escrevia não resolvia e o componente chegava sem cor. Nada que
|
|
619
|
+
* a plataforma escreve carrega mais uma variável nossa (`their-tongue.ts`) nem um utilitário que
|
|
620
|
+
* dependa do nosso `@theme` (`theirThemeVars`), então não há nada para o app dele carregar.
|
|
621
|
+
*
|
|
622
|
+
* O QUE A PASTA PASSA A SER, e é o que ele descreveu em 07/09: *"só pra gente ter uma base para
|
|
623
|
+
* interpretar o design da pessoa e replicar no nosso lado"*. `tokens.css` e `theme.css` continuam
|
|
624
|
+
* caindo em `_synthesisui/ds/<slug>/` como INSUMO - o hook, o doctor e o MCP os leem para
|
|
625
|
+
* interpretar o design dele. O que muda é que aquilo deixou de ser folha que o app dele importa.
|
|
634
626
|
*/
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
console.log(line(
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
console.log(line(` (the path is relative to that file - hence the leading ${importPrefix}):`));
|
|
641
|
-
console.log("");
|
|
642
|
-
// THE BRIDGE ONLY EXISTS FOR PEOPLE WHO ALREADY HAVE SHADCN, so it only
|
|
643
|
-
// appears for them. Every system compiles a `shadcn.css` mapping shadcn's
|
|
644
|
-
// whole variable contract onto its own tokens, and until 28/07 nothing said
|
|
645
|
-
// so - not this output, not the managed block, not the GUIDE beyond a filename
|
|
646
|
-
// in a list. The person it mattered most to asked "I don't get the use case, I
|
|
647
|
-
// can just build a design system with shadcn", with the answer sitting
|
|
648
|
-
// unimported in his own repo. Naming it to everybody would be noise; naming it
|
|
649
|
-
// to whoever has `components.json` is the whole feature arriving.
|
|
650
|
-
/** A MESMA pergunta que decide a ESCRITA - ver `wantsShadcn`. Duas leituras seriam duas regras. */
|
|
651
|
-
const hasShadcn = await wearsShadcn(projectRoot);
|
|
652
|
-
console.log(snippet([
|
|
653
|
-
...(hasTheme ? [`@import "tailwindcss";`] : []),
|
|
654
|
-
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/tokens.css";`,
|
|
655
|
-
...(hasTheme
|
|
656
|
-
? [
|
|
657
|
-
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/theme.css"; /* Tailwind utilities on your tokens */`,
|
|
658
|
-
]
|
|
659
|
-
: []),
|
|
660
|
-
...(hasShadcn
|
|
661
|
-
? [
|
|
662
|
-
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/shadcn.css"; /* your shadcn components, wearing this system */`,
|
|
663
|
-
]
|
|
664
|
-
: []),
|
|
665
|
-
]));
|
|
666
|
-
if (hasShadcn) {
|
|
667
|
-
console.log("");
|
|
668
|
-
console.log(line(` You have shadcn here. That third line maps its whole variable contract`));
|
|
669
|
-
console.log(line(` onto this system - colour, charts, radius and the sidebar - so its`));
|
|
670
|
-
console.log(line(` components stop using shadcn's defaults. Both schemes included.`));
|
|
671
|
-
}
|
|
672
|
-
console.log("");
|
|
673
|
-
console.log(line(`2. Scope your app: add data-ds="${payload.slug}" to a ROOT element, e.g. ${appDir}/layout.tsx:`));
|
|
674
|
-
console.log("");
|
|
675
|
-
console.log(snippet([
|
|
676
|
-
`<body data-ds="${payload.slug}" className="bg-canvas">{children}</body>`,
|
|
677
|
-
]));
|
|
678
|
-
// THE SCOPE DELIBERATELY DOES NOT PAINT A BACKGROUND, and every project hits
|
|
679
|
-
// it. `[data-ds]` sets ink and body family only, because scopes NEST: a dark
|
|
680
|
-
// contrast section over a photograph carries its own nested `data-ds` so its
|
|
681
|
-
// tokens remap, and a background on every scope would paint over the picture.
|
|
682
|
-
// So the page background is the root element's job, and saying so here is the
|
|
683
|
-
// fix - an agent found this by reading rendered CSS on 28/07 and had to
|
|
684
|
-
// deduce it.
|
|
685
|
-
console.log(line(` \`bg-canvas\` is not optional: the scope sets text colour and type, not the page`));
|
|
686
|
-
console.log(line(` background. Scopes nest (a dark section carries its own), so painting every one`));
|
|
687
|
-
console.log(line(` would cover whatever is behind it.`));
|
|
627
|
+
console.log(section("What landed, and what it is for"));
|
|
628
|
+
console.log(line(`_synthesisui/ds/${payload.slug}/ is ours to READ - the check, the doctor and the MCP`));
|
|
629
|
+
console.log(line(`server use it to interpret your design. Nothing in your app imports it, and nothing`));
|
|
630
|
+
console.log(line(`we write into your repository needs it at runtime: a component arrives speaking the`));
|
|
631
|
+
console.log(line(`names YOUR code declares, or carrying the value itself.`));
|
|
688
632
|
// 3. Load the type - the DS ships token NAMES, not the fonts themselves.
|
|
689
633
|
// Next apps get fonts.ts MATERIALIZED (deterministic does, not teaches):
|
|
690
634
|
// next/font = self-hosted + preloaded + adjusted fallback, no FOUT
|
|
@@ -700,9 +644,7 @@ export async function add(slug, opts) {
|
|
|
700
644
|
const fontPlan = projectConfig.target === "next"
|
|
701
645
|
? nextFontSnippet({
|
|
702
646
|
families,
|
|
703
|
-
slug: payload.slug,
|
|
704
647
|
appDir,
|
|
705
|
-
seam: payload.fontSeam,
|
|
706
648
|
facts: fontFacts,
|
|
707
649
|
declaredWeights: payload.document.foundations.typography.weights,
|
|
708
650
|
})
|
|
@@ -778,9 +720,7 @@ export async function add(slug, opts) {
|
|
|
778
720
|
continue;
|
|
779
721
|
const plan = nextFontSnippet({
|
|
780
722
|
families,
|
|
781
|
-
slug: payload.slug,
|
|
782
723
|
appDir: dir,
|
|
783
|
-
seam: payload.fontSeam,
|
|
784
724
|
facts: fontFacts,
|
|
785
725
|
declaredWeights: payload.document.foundations.typography.weights,
|
|
786
726
|
});
|