synthesisui 0.1.18 → 0.1.19

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,95 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { readProjectConfig } from "../config.js";
4
+ async function readRootLock(path) {
5
+ try {
6
+ return JSON.parse(await readFile(path, "utf8"));
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ }
12
+ async function exists(path) {
13
+ try {
14
+ await access(path);
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ /**
22
+ * `synthesisui use <slug> "<intent>"` - the platform↔app bridge (INS-10).
23
+ *
24
+ * Reads only LOCAL state (the installed `.lock`, the project `config.json`, and
25
+ * which guidance files exist) and prints a ready-to-paste prompt for your coding
26
+ * agent (Claude Code, Cursor, …) describing the task **on-system**: which files
27
+ * to read first, the scope attribute, the styling contract, and where files go.
28
+ * Works for both *bringing in* new UI ("a pricing section with 3 tiers") and
29
+ * *modifying* existing UI ("make the card shadow softer in components/Card.tsx").
30
+ *
31
+ * No network: the DS must already be installed (`synthesisui add <slug>`).
32
+ */
33
+ export async function use(slug, intent, opts) {
34
+ const root = opts.dir ?? process.cwd();
35
+ const slugDir = join(root, "_synthesisui", "ds", slug);
36
+ const lock = await readRootLock(join(slugDir, ".lock"));
37
+ if (!lock) {
38
+ console.error(`error: "${slug}" is not installed in this project.\n` +
39
+ ` run \`synthesisui add ${slug}\` first (brings tokens.css + GUIDE.md), then retry.`);
40
+ process.exitCode = 1;
41
+ return;
42
+ }
43
+ const config = await readProjectConfig(root);
44
+ const { version, name } = lock;
45
+ const base = `_synthesisui/ds/${slug}`;
46
+ // Highest-authority guidance first; only list files that actually exist.
47
+ const hasRules = await exists(join(slugDir, "rules.md"));
48
+ const hasPhilosophy = await exists(join(slugDir, "philosophy.md"));
49
+ const readFirst = [
50
+ hasRules
51
+ ? `- ${base}/rules.md — project rules for this system; obey them above everything else`
52
+ : "",
53
+ hasPhilosophy
54
+ ? `- ${base}/philosophy.md — the mission, voice and principles; let it shape every screen`
55
+ : "",
56
+ `- ${base}/v${version}/GUIDE.md — how to apply the system, the recipes and the token vocabulary`,
57
+ ].filter(Boolean);
58
+ // The styling contract differs by target: Next projects in this product use
59
+ // Tailwind v4 backed by the DS; the "general" target is framework-agnostic CSS.
60
+ const stylingRule = config.target === "general"
61
+ ? `- Style with the design system only: reuse the \`.ds-*\` recipe classes and the ` +
62
+ `\`var(--ds-*)\` custom properties. Never use raw hex/px outside the system's scale.`
63
+ : `- Style with the design system only: reuse the \`.ds-*\` recipe classes and the ` +
64
+ `DS-backed Tailwind utilities (\`bg-primary\`, \`text-foreground\`, \`p-md\`, \`rounded-lg\`, ` +
65
+ `\`font-display\`…). Never use raw hex/px outside the system's scale.`;
66
+ const task = intent.trim() || "build the UI I describe next";
67
+ const prompt = [
68
+ `Use the "${name}" design system (slug: ${slug}, v${version}) to: ${task}`,
69
+ "",
70
+ "Read these files in the project first (highest authority first):",
71
+ ...readFirst,
72
+ "",
73
+ "Follow this contract:",
74
+ `- Scope the markup with \`data-ds="${slug}"\` (or rely on it at the app root).`,
75
+ stylingRule,
76
+ `- Target framework: ${config.target}. Put new components in \`${config.componentsDir}/\` ` +
77
+ `and pages in \`${config.pagesDir}/\`.`,
78
+ config.target === "next"
79
+ ? '- Make sure `tokens.css` + `theme.css` are imported in the global CSS (see the GUIDE\'s "How to apply").'
80
+ : '- Make sure `tokens.css` is imported in the global CSS (see the GUIDE\'s "How to apply").',
81
+ "- Wire the behavior yourself (open/close, focus, routing) - the system ships the looks, not the JS.",
82
+ "",
83
+ "Deliver senior-level, production-quality code: clean structure, accessible (ARIA + keyboard), and responsive.",
84
+ ].join("\n");
85
+ // Framing lines go to stderr so `synthesisui use … | pbcopy` copies only the
86
+ // prompt itself (stdout), while the human still sees the guidance.
87
+ console.error(`✓ ${name} v${version} · target ${config.target}\n`);
88
+ console.error("Copy the prompt below and paste it to your coding agent:\n");
89
+ console.error("──────────────────────────────────────────────────────────");
90
+ console.log(prompt);
91
+ console.error("──────────────────────────────────────────────────────────");
92
+ console.error("\nTip: `synthesisui use " +
93
+ slug +
94
+ ' "…" | pbcopy` (macOS) copies just the prompt.');
95
+ }
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { init } from "./commands/init.js";
6
6
  import { list } from "./commands/list.js";
7
7
  import { login } from "./commands/login.js";
8
8
  import { page } from "./commands/page.js";
9
+ import { use } from "./commands/use.js";
9
10
  import { RegistryError } from "./registry.js";
10
11
  const HELP = `synthesisui - bring SynthesisUI design systems into your project
11
12
 
@@ -15,6 +16,7 @@ Usage:
15
16
  synthesisui list [options] list the published design systems
16
17
  synthesisui add <slug> [options] materialize a DS into _synthesisui/ds/<slug>/
17
18
  synthesisui page <slug> <template> materialize a whole page from a DS template
19
+ synthesisui use <slug> "<intent>" print a ready-to-paste agent prompt to build/modify on-system
18
20
  synthesisui advise "<value prop>" engagement-pattern proposals for this project (login required)
19
21
  synthesisui generate "<desc>" generate a token-only component recipe for your DS (login required)
20
22
 
@@ -39,6 +41,8 @@ Examples:
39
41
  synthesisui add halogen --version 3
40
42
  synthesisui page halogen dashboard-sidebar
41
43
  synthesisui page halogen landing --out app/page.tsx
44
+ synthesisui use halogen "a pricing section with three tiers and a highlighted plan"
45
+ synthesisui use halogen "make the card shadow softer in components/StatCard.tsx"
42
46
  synthesisui advise "habit-building app for tracking personal finances"
43
47
  synthesisui generate "an upgrade banner with a title, message and a primary CTA"
44
48
  `;
@@ -143,6 +147,17 @@ async function main() {
143
147
  await page(slug, template, { registry, dir, out, target, version });
144
148
  break;
145
149
  }
150
+ case "use": {
151
+ const slug = args[0];
152
+ if (!slug) {
153
+ console.error('error: provide the slug and your intent - `synthesisui use <slug> "<intent>"`');
154
+ process.exitCode = 1;
155
+ return;
156
+ }
157
+ const intent = args.slice(1).join(" ").trim();
158
+ await use(slug, intent, { dir });
159
+ break;
160
+ }
146
161
  case "advise": {
147
162
  const valueProp = args.join(" ").trim();
148
163
  if (!valueProp) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Traz design systems do SynthesisUI para qualquer projeto (materializa em _local/ds/).",
5
5
  "type": "module",
6
6
  "bin": {