synthesisui 0.1.23 → 0.1.24

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.
@@ -0,0 +1,27 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { resolveRegistry } from "../config.js";
4
+ import { fetchComponent } from "../registry.js";
5
+ /**
6
+ * Brings ONE component from a design system into the project (granular "bring
7
+ * specific", INS-18 fatia 3) - its recipe + compiled CSS, written under
8
+ * `_synthesisui/ds/<slug>/components/`. Handy for a component you refit/created
9
+ * on the platform. The component's styles reference the DS tokens, so the system
10
+ * itself must be installed (`synthesisui add <slug>`) for `tokens.css` to resolve.
11
+ */
12
+ export async function component(slug, name, opts) {
13
+ const base = resolveRegistry(opts.registry);
14
+ const root = opts.dir ?? process.cwd();
15
+ console.log(`→ fetching "${name}" from "${slug}" …`);
16
+ const res = await fetchComponent(base, slug, name, opts.version);
17
+ const dir = join(root, "_synthesisui", "ds", slug, "components");
18
+ await mkdir(dir, { recursive: true });
19
+ await writeFile(join(dir, `${res.name}.json`), `${JSON.stringify(res.recipe, null, 2)}\n`, "utf8");
20
+ await writeFile(join(dir, `${res.name}.css`), `${res.css}\n`, "utf8");
21
+ console.log(`✓ ${res.name} → _synthesisui/ds/${slug}/components/${res.name}.{json,css} (${slug} v${res.version})`);
22
+ console.log("");
23
+ console.log("Use it:");
24
+ console.log(` • ensure the DS is installed: synthesisui add ${slug} (provides tokens.css)`);
25
+ console.log(` • @import "_synthesisui/ds/${slug}/components/${res.name}.css" in your CSS`);
26
+ console.log(` • <div data-ds="${slug}"><div class="ds-${res.name}">…</div></div>`);
27
+ }
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { add } from "./commands/add.js";
3
3
  import { advise } from "./commands/advise.js";
4
+ import { component } from "./commands/component.js";
4
5
  import { generate } from "./commands/generate.js";
5
6
  import { init } from "./commands/init.js";
6
7
  import { list } from "./commands/list.js";
@@ -16,6 +17,7 @@ Usage:
16
17
  synthesisui list [options] list the published design systems
17
18
  synthesisui add <slug> [options] materialize a DS into _synthesisui/ds/<slug>/
18
19
  synthesisui template <slug> <name> materialize a whole page from a DS template
20
+ synthesisui component <slug> <name> bring one component (recipe + css) into the project
19
21
  synthesisui use <slug> "<intent>" print a ready-to-paste agent prompt to build/modify on-system
20
22
  synthesisui advise "<value prop>" engagement-pattern proposals for this project (login required)
21
23
  synthesisui generate "<desc>" generate a token-only component recipe for your DS (login required)
@@ -41,6 +43,7 @@ Examples:
41
43
  synthesisui add halogen --version 3
42
44
  synthesisui template halogen dashboard-sidebar
43
45
  synthesisui template halogen landing --out app/page.tsx
46
+ synthesisui component halogen pricing-tier
44
47
  synthesisui use halogen "a pricing section with three tiers and a highlighted plan"
45
48
  synthesisui use halogen "make the card shadow softer in components/StatCard.tsx"
46
49
  synthesisui advise "habit-building app for tracking personal finances"
@@ -153,6 +156,26 @@ async function main() {
153
156
  await template(slug, name, { registry, dir, out, target, version });
154
157
  break;
155
158
  }
159
+ case "component": {
160
+ const slug = args[0];
161
+ const name = args[1];
162
+ if (!slug || !name) {
163
+ console.error("error: provide slug and component name - `synthesisui component <slug> <name>`");
164
+ process.exitCode = 1;
165
+ return;
166
+ }
167
+ let version;
168
+ if (typeof flags.version === "string") {
169
+ version = Number.parseInt(flags.version.replace(/^v/i, ""), 10);
170
+ if (!Number.isInteger(version) || version < 1) {
171
+ console.error(`error: invalid --version "${flags.version}" - use an integer ≥ 1`);
172
+ process.exitCode = 1;
173
+ return;
174
+ }
175
+ }
176
+ await component(slug, name, { registry, dir, version });
177
+ break;
178
+ }
156
179
  case "use": {
157
180
  const slug = args[0];
158
181
  if (!slug) {
package/dist/registry.js CHANGED
@@ -63,6 +63,27 @@ export async function fetchTemplate(base, slug, template, target, version) {
63
63
  }
64
64
  return (await res.json());
65
65
  }
66
+ /**
67
+ * Fetches ONE component from a DS (`?component=<name>`): its recipe + compiled
68
+ * CSS. Granular "bring specific" - the system must exist; works for public DS
69
+ * without login (private/owned needs the token).
70
+ */
71
+ export async function fetchComponent(base, slug, name, version) {
72
+ const url = new URL(`${base}/api/registry/ds/${encodeURIComponent(slug)}`);
73
+ url.searchParams.set("component", name);
74
+ if (version != null)
75
+ url.searchParams.set("version", String(version));
76
+ const res = await request(url.toString());
77
+ if (res.status === 404) {
78
+ const body = (await res.json().catch(() => ({})));
79
+ throw new RegistryError(body.message ??
80
+ `No component "${name}" in "${slug}". Run \`synthesisui add ${slug}\` and check its components.`);
81
+ }
82
+ if (!res.ok) {
83
+ throw new RegistryError(`Registry responded ${res.status} while fetching "${name}".`);
84
+ }
85
+ return (await res.json());
86
+ }
66
87
  /**
67
88
  * Calls the hosted advisor (`POST /api/ai/advisor`). Gated + metered server-side:
68
89
  * 401 = not logged in, 429 = daily quota reached. Sends the Bearer token if present.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Traz design systems do SynthesisUI para qualquer projeto (materializa em _local/ds/).",
5
5
  "type": "module",
6
6
  "bin": {