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 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. **Before
142
- creating any UI element, check the component manifest below - if it exists, use or extend
143
- it (\`synthesisui component <slug> <name>\` materializes it as your code).** To review a
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)
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {