synthesisui 0.16.15 → 0.16.16
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 +37 -1
- package/dist/commands/add.js +29 -9
- package/dist/commands/doctor.js +56 -1
- package/package.json +1 -1
package/dist/claude-md.js
CHANGED
|
@@ -134,6 +134,35 @@ drift because it looks solved.`;
|
|
|
134
134
|
* `--force` needs a person because it deletes. The dry run does not, so the
|
|
135
135
|
* agent is pointed at the harmless half and told to ask for the other.
|
|
136
136
|
*/
|
|
137
|
+
/**
|
|
138
|
+
* THE ONE THING MOST LIKELY TO ALREADY BE IN THE PROJECT.
|
|
139
|
+
*
|
|
140
|
+
* Every system compiles a `shadcn.css` mapping shadcn's whole variable contract
|
|
141
|
+
* onto its own tokens. It has been generated into every project since it was
|
|
142
|
+
* built and nothing ever mentioned it, so the feature that answers "why not just
|
|
143
|
+
* use shadcn" was sitting unimported in the repo of the person who asked.
|
|
144
|
+
*
|
|
145
|
+
* Told to the AGENT and not only to the person, because the agent is who reaches
|
|
146
|
+
* for a shadcn block. Left to guess, it installs `dashboard-01` and gets a
|
|
147
|
+
* sidebar on shadcn's defaults next to components wearing the system, which
|
|
148
|
+
* reads as a broken product rather than a missing import.
|
|
149
|
+
*
|
|
150
|
+
* Conditional on `components.json`: a project without shadcn must not carry a
|
|
151
|
+
* paragraph about it.
|
|
152
|
+
*/
|
|
153
|
+
const SHADCN = (slug) => `
|
|
154
|
+
|
|
155
|
+
**This project has shadcn, and this system already speaks its language.** A
|
|
156
|
+
generated bridge maps shadcn's whole variable contract - colour, charts, radius,
|
|
157
|
+
the sidebar family - onto this system's tokens, in both schemes:
|
|
158
|
+
|
|
159
|
+
@import "_synthesisui/ds/${slug}/shadcn.css";
|
|
160
|
+
|
|
161
|
+
after the tokens.css import, in the same stylesheet. With that line in place,
|
|
162
|
+
shadcn components wear this system and need no edits from you. Without it they
|
|
163
|
+
stay on shadcn's defaults, which looks like the design system failing rather than
|
|
164
|
+
one import missing - so check for it before you add a shadcn component, and add
|
|
165
|
+
it if it is not there.`;
|
|
137
166
|
const VERIFY = `
|
|
138
167
|
|
|
139
168
|
**Verify with a build, not a running server.** If you do start a dev server, stop
|
|
@@ -277,9 +306,16 @@ element. Write every user-facing string in that language - labels, empty states,
|
|
|
277
306
|
\`alt\`. A screen reader pronounces \`aria-label\` using \`lang\`, so a mixed-language interface is
|
|
278
307
|
worse than an untranslated one. If the attribute is wrong, change it rather than writing against
|
|
279
308
|
it.`;
|
|
309
|
+
// Named for the first installed system: the bridge is per-system, and a
|
|
310
|
+
// project with two of them has already chosen which one dresses the app.
|
|
311
|
+
const bridgeable = installed.find((d) => !d.adopted);
|
|
312
|
+
const shadcn = bridgeable &&
|
|
313
|
+
(await readFile(join(projectRoot, "components.json"), "utf8").then(() => true, () => false))
|
|
314
|
+
? SHADCN(bridgeable.slug)
|
|
315
|
+
: "";
|
|
280
316
|
const body = `## Design Systems (via SynthesisUI)
|
|
281
317
|
|
|
282
|
-
This project uses design system(s) tracked by the \`synthesisui\` CLI. ${rule}${language}
|
|
318
|
+
This project uses design system(s) tracked by the \`synthesisui\` CLI. ${rule}${language}${shadcn}
|
|
283
319
|
|
|
284
320
|
${sections.join("\n")}
|
|
285
321
|
|
package/dist/commands/add.js
CHANGED
|
@@ -138,15 +138,35 @@ export async function add(slug, opts) {
|
|
|
138
138
|
console.log(line(`1. Import the system in your GLOBAL stylesheet, e.g. ${appDir}/globals.css`));
|
|
139
139
|
console.log(line(` (the path is relative to that file - hence the leading ${importPrefix}):`));
|
|
140
140
|
console.log("");
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
141
|
+
// THE BRIDGE ONLY EXISTS FOR PEOPLE WHO ALREADY HAVE SHADCN, so it only
|
|
142
|
+
// appears for them. Every system compiles a `shadcn.css` mapping shadcn's
|
|
143
|
+
// whole variable contract onto its own tokens, and until 28/07 nothing said
|
|
144
|
+
// so - not this output, not the managed block, not the GUIDE beyond a filename
|
|
145
|
+
// in a list. The person it mattered most to asked "I don't get the use case, I
|
|
146
|
+
// can just build a design system with shadcn", with the answer sitting
|
|
147
|
+
// unimported in his own repo. Naming it to everybody would be noise; naming it
|
|
148
|
+
// to whoever has `components.json` is the whole feature arriving.
|
|
149
|
+
const hasShadcn = await access(join(projectRoot, "components.json")).then(() => true, () => false);
|
|
150
|
+
console.log(snippet([
|
|
151
|
+
...(hasTheme ? [`@import "tailwindcss";`] : []),
|
|
152
|
+
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/tokens.css";`,
|
|
153
|
+
...(hasTheme
|
|
154
|
+
? [
|
|
155
|
+
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/theme.css"; /* Tailwind utilities on your tokens */`,
|
|
156
|
+
]
|
|
157
|
+
: []),
|
|
158
|
+
...(hasShadcn
|
|
159
|
+
? [
|
|
160
|
+
`@import "${importPrefix}_synthesisui/ds/${payload.slug}/shadcn.css"; /* your shadcn components, wearing this system */`,
|
|
161
|
+
]
|
|
162
|
+
: []),
|
|
163
|
+
]));
|
|
164
|
+
if (hasShadcn) {
|
|
165
|
+
console.log("");
|
|
166
|
+
console.log(line(` You have shadcn here. That third line maps its whole variable contract`));
|
|
167
|
+
console.log(line(` onto this system - colour, charts, radius and the sidebar - so its`));
|
|
168
|
+
console.log(line(` components stop using shadcn's defaults. Both schemes included.`));
|
|
169
|
+
}
|
|
150
170
|
console.log("");
|
|
151
171
|
console.log(line(`2. Scope your app: add data-ds="${payload.slug}" to a ROOT element, e.g. ${appDir}/layout.tsx:`));
|
|
152
172
|
console.log("");
|
package/dist/commands/doctor.js
CHANGED
|
@@ -287,15 +287,37 @@ async function readWiring(root, slug) {
|
|
|
287
287
|
fontsWritten: false,
|
|
288
288
|
/** …and the stylesheet actually maps it onto the system's type tokens. */
|
|
289
289
|
fontsMapped: false,
|
|
290
|
+
/**
|
|
291
|
+
* THE FEATURE NOBODY KNEW WE SHIPPED.
|
|
292
|
+
*
|
|
293
|
+
* Every system compiles a `shadcn.css` mapping shadcn's whole variable
|
|
294
|
+
* contract onto its own tokens, so shadcn components wear the system instead
|
|
295
|
+
* of shadcn's defaults. It has been generated into every project since it
|
|
296
|
+
* was built, and until 28/07 nothing mentioned it: not `add`, not the
|
|
297
|
+
* managed block, not the GUIDE except as a filename in a list. The only
|
|
298
|
+
* documentation was a comment inside the file, which is the same as none.
|
|
299
|
+
*
|
|
300
|
+
* The person it mattered most to is the one who asked "I don't get the use
|
|
301
|
+
* case, I can just build a design system with shadcn" - and the answer was
|
|
302
|
+
* sitting unimported in his own repo.
|
|
303
|
+
*
|
|
304
|
+
* Reported only when the project HAS shadcn. Telling everybody about a
|
|
305
|
+
* bridge they will never use is how a report earns the skim.
|
|
306
|
+
*/
|
|
307
|
+
hasShadcn: false,
|
|
308
|
+
bridged: false,
|
|
290
309
|
};
|
|
291
310
|
if (!slug)
|
|
292
311
|
return w;
|
|
312
|
+
w.hasShadcn = await readFile(join(root, "components.json"), "utf8").then(() => true, () => false);
|
|
293
313
|
for await (const file of walk(root)) {
|
|
294
314
|
const src = await readFile(file, "utf8").catch(() => "");
|
|
295
315
|
if (!src)
|
|
296
316
|
continue;
|
|
297
317
|
if (src.includes(`_synthesisui/ds/${slug}/tokens.css`))
|
|
298
318
|
w.imported = true;
|
|
319
|
+
if (src.includes(`_synthesisui/ds/${slug}/shadcn.css`))
|
|
320
|
+
w.bridged = true;
|
|
299
321
|
if (src.includes(`data-ds="${slug}"`))
|
|
300
322
|
w.scoped = true;
|
|
301
323
|
// The requirement that stayed invisible. `init` writes a fonts file and
|
|
@@ -306,7 +328,9 @@ async function readWiring(root, slug) {
|
|
|
306
328
|
w.fontsWritten = true;
|
|
307
329
|
if (/--ds-typography-families-\w+\s*:\s*var\(\s*--font-ds-/.test(src))
|
|
308
330
|
w.fontsMapped = true;
|
|
309
|
-
|
|
331
|
+
// The bridge joins the early exit, otherwise the walk can stop before the
|
|
332
|
+
// stylesheet that imports it and report a wired project as unbridged.
|
|
333
|
+
if (w.imported && w.scoped && w.fontsMapped && (!w.hasShadcn || w.bridged))
|
|
310
334
|
break;
|
|
311
335
|
}
|
|
312
336
|
return w;
|
|
@@ -461,6 +485,37 @@ export async function doctor(opts) {
|
|
|
461
485
|
}
|
|
462
486
|
console.log(body("The exact snippets are in the output of `init`."));
|
|
463
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* SHADCN IS THE MOST LIKELY THING ALREADY IN THE PROJECT, AND THE BRIDGE WAS
|
|
490
|
+
* INVISIBLE.
|
|
491
|
+
*
|
|
492
|
+
* Two states, and both are worth a line. Unimported is a real finding: the
|
|
493
|
+
* components a person spends all day looking at are on shadcn's defaults while
|
|
494
|
+
* everything around them wears the system, which reads as "this product does
|
|
495
|
+
* not work here" rather than "one import missing".
|
|
496
|
+
*
|
|
497
|
+
* Imported is worth saying too, and that is the unusual part. It is the only
|
|
498
|
+
* place we can answer "how do I know my shadcn is going through the system?"
|
|
499
|
+
* with something checked rather than claimed. A governance tool that cannot
|
|
500
|
+
* show its work is asking for trust it has not earned.
|
|
501
|
+
*/
|
|
502
|
+
if (hasSystem && wiring.hasShadcn) {
|
|
503
|
+
console.log("");
|
|
504
|
+
if (wiring.bridged) {
|
|
505
|
+
console.log(body(`✓ shadcn is reading ${table.name ?? table.slug}, not its own`));
|
|
506
|
+
console.log(body(" defaults. Colour, charts, radius and the sidebar all resolve"));
|
|
507
|
+
console.log(body(" to this system's tokens, in both schemes."));
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
console.log(body("This project has shadcn, and it is not wearing the"));
|
|
511
|
+
console.log(body("system yet - its components are still on shadcn's defaults."));
|
|
512
|
+
console.log("");
|
|
513
|
+
console.log(body(` @import "_synthesisui/ds/${table.slug}/shadcn.css";`));
|
|
514
|
+
console.log("");
|
|
515
|
+
console.log(body(" after the tokens.css import, in the same stylesheet. One line,"));
|
|
516
|
+
console.log(body(" and every shadcn component switches over."));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
464
519
|
if (hasSystem && measurable) {
|
|
465
520
|
console.log("");
|
|
466
521
|
console.log(body(`Token coverage ${meter(d.coverage)} ${String(d.coverage).padStart(3)}%`));
|
package/package.json
CHANGED