synthesisui 0.16.0 → 0.16.2
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 +13 -3
- package/dist/commands/adopt.js +37 -1
- package/package.json +1 -1
package/dist/claude-md.js
CHANGED
|
@@ -138,9 +138,19 @@ instead, because a new token is a decision for a person to make. There is no com
|
|
|
138
138
|
manifest for an adopted system - the tokens ARE the contract.${SELF_CHECK}`
|
|
139
139
|
: `**When creating or editing components, read the system's GUIDE.md and follow it:** use only semantic tokens
|
|
140
140
|
(\`var(--ds-color-semantic-*)\`, \`--ds-spacing-*\`, etc.), scope the UI with \`data-ds="<slug>"\`,
|
|
141
|
-
and reuse the \`.ds-*\` classes. Do not use raw values outside the system's scale.
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
and reuse the \`.ds-*\` classes. Do not use raw values outside the system's scale.
|
|
142
|
+
|
|
143
|
+
**Before creating any UI element, look it up in the manifest below.** If something there
|
|
144
|
+
already covers the purpose, do not write it from scratch - run
|
|
145
|
+
|
|
146
|
+
npx synthesisui@latest component <slug> <name>
|
|
147
|
+
|
|
148
|
+
YOURSELF. It materializes that component as real typed code in this project, and you use and
|
|
149
|
+
extend that. The person who asked you for a feature should never have to know these command
|
|
150
|
+
names or type them; finding the right component is your job, not theirs.
|
|
151
|
+
|
|
152
|
+
Only write something new when nothing in the manifest covers the purpose - and when you do,
|
|
153
|
+
say which entry you considered and why it did not fit. To review a
|
|
144
154
|
component, create an isolated sample page (e.g. \`app/synthesisui-samples/<component>/\`) - do not
|
|
145
155
|
apply it to real production pages unless asked.${SELF_CHECK}`;
|
|
146
156
|
const body = `## Design Systems (via SynthesisUI)
|
package/dist/commands/adopt.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
1
|
+
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join, relative, resolve } from "node:path";
|
|
3
3
|
import { syncClaudeMd } from "../claude-md.js";
|
|
4
4
|
import { parseRootTokens } from "../doctor/tokens.js";
|
|
@@ -75,6 +75,34 @@ function guessSlug(tokens, pkgName) {
|
|
|
75
75
|
.replace(/^-|-$/g, "")
|
|
76
76
|
.toLowerCase() || "my-system");
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* A system WE installed, if there is one.
|
|
80
|
+
*
|
|
81
|
+
* Run inside a repo already carrying Moments - 158 tokens, 93% coverage - adopt
|
|
82
|
+
* announced "found no custom properties … if you do not have a system yet,
|
|
83
|
+
* start from one" (27/07). Telling somebody with a design system that they have
|
|
84
|
+
* none is the exact dead end this command was written to avoid: our own tokens
|
|
85
|
+
* live under `_synthesisui/`, which the walk skips, so it looked and found
|
|
86
|
+
* nothing and drew the wrong conclusion from it.
|
|
87
|
+
*/
|
|
88
|
+
async function installedSystems(root) {
|
|
89
|
+
const dir = join(root, "_synthesisui", "ds");
|
|
90
|
+
const slugs = [];
|
|
91
|
+
for (const e of await readdir(dir, { withFileTypes: true }).catch(() => [])) {
|
|
92
|
+
if (!e.isDirectory())
|
|
93
|
+
continue;
|
|
94
|
+
const raw = await readFile(join(dir, e.name, ".lock"), "utf8").catch(() => "");
|
|
95
|
+
try {
|
|
96
|
+
const lock = JSON.parse(raw);
|
|
97
|
+
if (!lock.adopted)
|
|
98
|
+
slugs.push(lock.name ?? e.name);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// no readable lock - not something we put there
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return slugs;
|
|
105
|
+
}
|
|
78
106
|
async function findTokens(root, only) {
|
|
79
107
|
let files = 0;
|
|
80
108
|
const from = [];
|
|
@@ -146,6 +174,14 @@ export async function adopt(opts) {
|
|
|
146
174
|
const found = await findTokens(root, opts.tokens);
|
|
147
175
|
console.log(section("Adopt"));
|
|
148
176
|
if (found.tokens.size === 0) {
|
|
177
|
+
const already = await installedSystems(root);
|
|
178
|
+
if (already.length > 0) {
|
|
179
|
+
console.log(body(`${already.join(", ")} ${already.length === 1 ? "is" : "are"} already installed here, and adopt is for a system we did not install.`));
|
|
180
|
+
console.log("");
|
|
181
|
+
console.log(body("Nothing to do. To see how the code is holding up:"));
|
|
182
|
+
console.log(snippet(["npx synthesisui@latest doctor"]));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
149
185
|
// Never "failed to adopt". Always: what was looked for, where, and the
|
|
150
186
|
// next thing to type. Being stuck with no move is the worst outcome.
|
|
151
187
|
console.log(body(`Looked in ${SCOPE_HINT} across ${found.files} stylesheet${found.files === 1 ? "" : "s"} and found no custom properties.`));
|
package/package.json
CHANGED