synthesisui 0.4.5 → 0.4.6
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 +68 -8
- package/package.json +1 -1
package/dist/claude-md.js
CHANGED
|
@@ -26,23 +26,83 @@ async function readInstalled(projectRoot) {
|
|
|
26
26
|
}
|
|
27
27
|
return locks;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
/** First sentence of a description, capped - the manifest must stay lean. */
|
|
30
|
+
function summarize(desc) {
|
|
31
|
+
if (typeof desc !== "string" || !desc.trim())
|
|
32
|
+
return "";
|
|
33
|
+
const first = desc.trim().split(/(?<=\.)\s/)[0] ?? desc.trim();
|
|
34
|
+
return first.length > 90 ? `${first.slice(0, 87)}…` : first;
|
|
35
|
+
}
|
|
36
|
+
/** One manifest line per recipe: name, what it is, and its variant axes. */
|
|
37
|
+
function catalogLines(recipes) {
|
|
38
|
+
return Object.entries(recipes)
|
|
39
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
40
|
+
.map(([name, recipe]) => {
|
|
41
|
+
const r = recipe;
|
|
42
|
+
const axes = Object.entries(r.variants ?? {})
|
|
43
|
+
.map(([axis, options]) => {
|
|
44
|
+
const keys = Object.keys(options);
|
|
45
|
+
return keys.length <= 4 ? `${axis}: ${keys.join("|")}` : axis;
|
|
46
|
+
})
|
|
47
|
+
.join("; ");
|
|
48
|
+
const desc = summarize(r.description);
|
|
49
|
+
return {
|
|
50
|
+
name,
|
|
51
|
+
line: ` - \`ds-${name}\`${desc ? ` - ${desc}` : ""}${axes ? ` [${axes}]` : ""}`,
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The COMPONENT MANIFEST for one installed system, read from its versioned
|
|
57
|
+
* design-system.json. This is what lets the app's agent know what it already
|
|
58
|
+
* HAS - "use these before creating new ones" - instead of re-inventing
|
|
59
|
+
* buttons. Returns null when the document isn't readable (older installs).
|
|
60
|
+
*/
|
|
61
|
+
async function readManifest(projectRoot, ds) {
|
|
62
|
+
try {
|
|
63
|
+
const raw = await readFile(join(projectRoot, "_synthesisui", "ds", ds.slug, `v${ds.version}`, "design-system.json"), "utf8");
|
|
64
|
+
const doc = JSON.parse(raw);
|
|
65
|
+
const components = catalogLines(doc.components ?? {});
|
|
66
|
+
const blocks = catalogLines(doc.blocks ?? {});
|
|
67
|
+
if (components.length === 0 && blocks.length === 0)
|
|
68
|
+
return null;
|
|
69
|
+
const lines = [];
|
|
70
|
+
if (components.length > 0) {
|
|
71
|
+
lines.push(` Components (${components.length}) - USE these before creating new ones:`);
|
|
72
|
+
lines.push(...components.map((c) => c.line));
|
|
73
|
+
}
|
|
74
|
+
if (blocks.length > 0) {
|
|
75
|
+
lines.push(` Engagement blocks (${blocks.length}):`);
|
|
76
|
+
lines.push(...blocks.map((c) => c.line));
|
|
77
|
+
}
|
|
78
|
+
return lines.join("\n");
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function renderRegion(projectRoot, installed) {
|
|
30
85
|
if (installed.length === 0) {
|
|
31
86
|
return `${START}\n${END}`;
|
|
32
87
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
.
|
|
88
|
+
const sections = [];
|
|
89
|
+
for (const ds of installed) {
|
|
90
|
+
const head = `- **${ds.name}** (\`${ds.slug}\`, v${ds.version}) - guide: \`_synthesisui/ds/${ds.slug}/v${ds.version}/GUIDE.md\``;
|
|
91
|
+
const manifest = await readManifest(projectRoot, ds);
|
|
92
|
+
sections.push(manifest ? `${head}\n${manifest}` : head);
|
|
93
|
+
}
|
|
36
94
|
const body = `## Design Systems (via SynthesisUI)
|
|
37
95
|
|
|
38
96
|
This project uses design system(s) brought in by the \`synthesisui\` CLI. **When creating or editing
|
|
39
97
|
components, read the system's GUIDE.md and follow it:** use only semantic tokens
|
|
40
98
|
(\`var(--ds-color-semantic-*)\`, \`--ds-spacing-*\`, etc.), scope the UI with \`data-ds="<slug>"\`,
|
|
41
|
-
and reuse the \`.ds-*\` classes. Do not use raw values outside the system's scale. **
|
|
99
|
+
and reuse the \`.ds-*\` classes. Do not use raw values outside the system's scale. **Before
|
|
100
|
+
creating any UI element, check the component manifest below - if it exists, use or extend
|
|
101
|
+
it (\`synthesisui component <slug> <name>\` materializes it as your code).** To review a
|
|
42
102
|
component, create an isolated sample page (e.g. \`app/synthesisui-samples/<component>/\`) - do not
|
|
43
|
-
apply it to real production pages unless asked
|
|
103
|
+
apply it to real production pages unless asked.
|
|
44
104
|
|
|
45
|
-
${
|
|
105
|
+
${sections.join("\n")}
|
|
46
106
|
|
|
47
107
|
_Block managed by the CLI - do not edit by hand; run \`synthesisui add <slug>\` to update._`;
|
|
48
108
|
return `${START}\n${body}\n${END}`;
|
|
@@ -54,7 +114,7 @@ _Block managed by the CLI - do not edit by hand; run \`synthesisui add <slug>\`
|
|
|
54
114
|
*/
|
|
55
115
|
export async function syncClaudeMd(projectRoot) {
|
|
56
116
|
const installed = await readInstalled(projectRoot);
|
|
57
|
-
const region = renderRegion(installed);
|
|
117
|
+
const region = await renderRegion(projectRoot, installed);
|
|
58
118
|
const path = join(projectRoot, "CLAUDE.md");
|
|
59
119
|
let existing = null;
|
|
60
120
|
try {
|