@utopia-studio-design/design-system-cli 0.6.1 → 0.7.0

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.
Files changed (123) hide show
  1. package/README.md +28 -10
  2. package/bin/utopia-ds-mcp.mjs +6 -2
  3. package/bin/utopia-ds.mjs +94 -21
  4. package/data/docs/arabic-friendly.md +19 -2
  5. package/data/docs/billing-setup.md +80 -0
  6. package/data/docs/cer-003-032-033-round-8-repair.md +41 -0
  7. package/data/docs/cer-007-checkout.md +51 -0
  8. package/data/docs/cer-008-011-qa-repair.md +64 -0
  9. package/data/docs/cer-016-023-round-6-repair.md +92 -0
  10. package/data/docs/cer-024-031-round-7-repair.md +51 -0
  11. package/data/docs/cer-033-035-036-round-12-repair.md +37 -0
  12. package/data/docs/cer-035-037-round-10-repair.md +34 -0
  13. package/data/docs/charts.md +34 -3
  14. package/data/docs/chat-service-methodology.md +181 -0
  15. package/data/docs/code-block.md +20 -0
  16. package/data/docs/creative-production.md +149 -0
  17. package/data/docs/designer-agent-backend-contract.md +552 -0
  18. package/data/docs/email-resend.md +29 -0
  19. package/data/docs/foundations.md +46 -8
  20. package/data/docs/guide.md +9 -9
  21. package/data/docs/handover-billing-aiden.md +132 -0
  22. package/data/docs/logo-maker-methodology.md +109 -0
  23. package/data/docs/presentation-asset-repository.md +53 -0
  24. package/data/docs/product-architecture.md +42 -0
  25. package/data/docs/quick-start-ai.md +4 -4
  26. package/data/docs/shadcn-conversion.md +1 -1
  27. package/data/docs/sidebar-placement.md +56 -0
  28. package/data/docs/theme-authoring.md +6 -3
  29. package/data/manifests/catalog.json +42 -46
  30. package/data/manifests/components.json +317 -66
  31. package/data/manifests/logo-skills.json +174 -0
  32. package/data/manifests/motion-profiles.json +2 -2
  33. package/data/manifests/patterns.json +201 -7
  34. package/data/manifests/presentation-assets.schema.json +44 -0
  35. package/data/manifests/templates.json +87 -1
  36. package/data/manifests/theme-dextrum.json +7 -7
  37. package/data/manifests/theme-prism-mono.json +19 -0
  38. package/data/manifests/theme-utopia-cloudblur.json +135 -0
  39. package/data/manifests/theme-utopia-default.json +31 -31
  40. package/data/manifests/theme-vyapti.json +17 -1
  41. package/data/manifests/theme-y2k-pop.json +18 -0
  42. package/data/manifests/themes.json +285 -57
  43. package/data/templates/analytics-dashboard/main.tsx +14 -1
  44. package/data/templates/calendar-application/main.tsx +14 -1
  45. package/data/templates/chat-workspace/README.md +12 -0
  46. package/data/templates/chat-workspace/index.html +11 -0
  47. package/data/templates/chat-workspace/main.tsx +97 -0
  48. package/data/templates/chat-workspace/styles.css +19 -0
  49. package/data/templates/chat-workspace/template.manifest.json +13 -0
  50. package/data/templates/composition-registry-lab/main.tsx +12 -1
  51. package/data/templates/dashboard-composer/main.tsx +14 -1
  52. package/data/templates/database-workspace/main.tsx +14 -1
  53. package/data/templates/interaction-lab/main.tsx +12 -1
  54. package/data/templates/quantum-verification-story/README.md +12 -0
  55. package/data/templates/quantum-verification-story/components.json +21 -0
  56. package/data/templates/quantum-verification-story/eslint.config.mjs +13 -0
  57. package/data/templates/quantum-verification-story/next-env.d.ts +7 -0
  58. package/data/templates/quantum-verification-story/next.config.mjs +11 -0
  59. package/data/templates/quantum-verification-story/package-lock.json +7535 -0
  60. package/data/templates/quantum-verification-story/package.json +46 -0
  61. package/data/templates/quantum-verification-story/postcss.config.js +6 -0
  62. package/data/templates/quantum-verification-story/src/app/assessment/page.tsx +138 -0
  63. package/data/templates/quantum-verification-story/src/app/ceramic-theme.css +48 -0
  64. package/data/templates/quantum-verification-story/src/app/deployment/page.tsx +178 -0
  65. package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Bold.ttf +0 -0
  66. package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Medium.ttf +0 -0
  67. package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Regular.ttf +0 -0
  68. package/data/templates/quantum-verification-story/src/app/fonts/ReadexPro-Variable.ttf +0 -0
  69. package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-350.ttf +0 -0
  70. package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-500.ttf +0 -0
  71. package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-700.ttf +0 -0
  72. package/data/templates/quantum-verification-story/src/app/globals.css +175 -0
  73. package/data/templates/quantum-verification-story/src/app/layout.tsx +45 -0
  74. package/data/templates/quantum-verification-story/src/app/not-found.tsx +39 -0
  75. package/data/templates/quantum-verification-story/src/app/page.tsx +24 -0
  76. package/data/templates/quantum-verification-story/src/app/products/page.tsx +132 -0
  77. package/data/templates/quantum-verification-story/src/app/utopia-default.css +312 -0
  78. package/data/templates/quantum-verification-story/src/components/RotatingText.css +36 -0
  79. package/data/templates/quantum-verification-story/src/components/RotatingText.tsx +189 -0
  80. package/data/templates/quantum-verification-story/src/components/brand-mark.tsx +14 -0
  81. package/data/templates/quantum-verification-story/src/components/console-preview-section.tsx +57 -0
  82. package/data/templates/quantum-verification-story/src/components/console-preview.tsx +72 -0
  83. package/data/templates/quantum-verification-story/src/components/fade-up.tsx +54 -0
  84. package/data/templates/quantum-verification-story/src/components/floating-network.tsx +125 -0
  85. package/data/templates/quantum-verification-story/src/components/footer.tsx +83 -0
  86. package/data/templates/quantum-verification-story/src/components/harvest-timeline.tsx +70 -0
  87. package/data/templates/quantum-verification-story/src/components/lattice-diagram.tsx +73 -0
  88. package/data/templates/quantum-verification-story/src/components/lattice-field.tsx +129 -0
  89. package/data/templates/quantum-verification-story/src/components/nav.tsx +104 -0
  90. package/data/templates/quantum-verification-story/src/components/presentation-layout.tsx +91 -0
  91. package/data/templates/quantum-verification-story/src/components/readiness-estimator.tsx +135 -0
  92. package/data/templates/quantum-verification-story/src/components/scramble-text.tsx +60 -0
  93. package/data/templates/quantum-verification-story/src/components/section-backdrop.tsx +38 -0
  94. package/data/templates/quantum-verification-story/src/components/sections/clients.tsx +140 -0
  95. package/data/templates/quantum-verification-story/src/components/sections/contact.tsx +125 -0
  96. package/data/templates/quantum-verification-story/src/components/sections/hero.tsx +92 -0
  97. package/data/templates/quantum-verification-story/src/components/sections/moat.tsx +73 -0
  98. package/data/templates/quantum-verification-story/src/components/sections/offer.tsx +113 -0
  99. package/data/templates/quantum-verification-story/src/components/sections/pilot.tsx +63 -0
  100. package/data/templates/quantum-verification-story/src/components/sections/problem.tsx +53 -0
  101. package/data/templates/quantum-verification-story/src/components/text-particle.tsx +204 -0
  102. package/data/templates/quantum-verification-story/src/components/ticker.tsx +27 -0
  103. package/data/templates/quantum-verification-story/src/components/ui/badge.tsx +29 -0
  104. package/data/templates/quantum-verification-story/src/components/ui/button.tsx +55 -0
  105. package/data/templates/quantum-verification-story/src/components/ui/card.tsx +46 -0
  106. package/data/templates/quantum-verification-story/src/components/ui/cursor-driven-particle-typography.tsx +288 -0
  107. package/data/templates/quantum-verification-story/src/components/ui/input.tsx +20 -0
  108. package/data/templates/quantum-verification-story/src/components/ui/label.tsx +21 -0
  109. package/data/templates/quantum-verification-story/src/components/ui/separator.tsx +25 -0
  110. package/data/templates/quantum-verification-story/src/components/ui/textarea.tsx +19 -0
  111. package/data/templates/quantum-verification-story/src/lib/utils.ts +6 -0
  112. package/data/templates/quantum-verification-story/tailwind.config.js +95 -0
  113. package/data/templates/quantum-verification-story/template.manifest.json +23 -0
  114. package/data/templates/quantum-verification-story/tsconfig.json +42 -0
  115. package/data/templates/saas-solution-homepage/main.tsx +91 -14
  116. package/data/templates/saas-solution-homepage/privacy/index.html +1 -0
  117. package/data/templates/saas-solution-homepage/styles.css +47 -2
  118. package/data/templates/saas-solution-homepage/team/index.html +1 -0
  119. package/data/templates/saas-solution-homepage/template.manifest.json +41 -0
  120. package/data/templates/saas-solution-homepage/terms/index.html +1 -0
  121. package/lib/api.mjs +52 -3
  122. package/lib/template-runtime.mjs +1 -0
  123. package/package.json +2 -2
@@ -19,8 +19,11 @@
19
19
  { "id": "customers", "path": "customers/index.html", "purpose": "Customer proof library" },
20
20
  { "id": "customer-story", "path": "customers/aster-labs/index.html", "purpose": "Long-form customer case study" },
21
21
  { "id": "pricing", "path": "pricing/index.html", "purpose": "Plans, comparison, and FAQ" },
22
+ { "id": "team", "path": "team/index.html", "purpose": "Company story, operating principles, team profiles, and recruiting CTA" },
22
23
  { "id": "changelog", "path": "changelog/index.html", "purpose": "Product update timeline" },
23
24
  { "id": "contact-sales", "path": "contact-sales/index.html", "purpose": "Sales qualification form and success state" }
25
+ ,{ "id": "terms", "path": "terms/index.html", "purpose": "Terms of Use legal template" }
26
+ ,{ "id": "privacy", "path": "privacy/index.html", "purpose": "Privacy Policy legal template" }
24
27
  ],
25
28
  "features": { "lightDark": true, "rtl": true, "responsive": true, "seededDemoData": true, "scrollAwareNavigation": true, "reducedMotion": true },
26
29
  "useWhen": ["A SaaS product needs a complete product-led marketing narrative", "A real interface preview can carry the product proof", "Automation, integrations, and reliability are material buying criteria"],
@@ -32,5 +35,43 @@
32
35
  "default": "utopia-default",
33
36
  "generationFlag": "--theme <id>",
34
37
  "ownership": "The active theme owns dark/light semantic mappings; the template owns no brand primitives."
38
+ },
39
+ "executionContract": {
40
+ "defaultMode": "adapt",
41
+ "alwaysLocked": ["semanticRoles", "accessibility", "componentAllowlist"],
42
+ "modes": {
43
+ "exact": {
44
+ "locked": ["sectionOrder", "componentTree", "layoutGrid", "spacingScale", "typeScale", "responsiveRules"],
45
+ "editable": ["content", "media", "approvedData"]
46
+ },
47
+ "adapt": {
48
+ "locked": ["sectionOrder", "componentTree", "layoutGrid", "responsiveRules"],
49
+ "editable": ["content", "media", "semanticTheme", "approvedVariants", "approvedData"]
50
+ },
51
+ "explore": {
52
+ "locked": [],
53
+ "editable": ["content", "media", "semanticTheme", "approvedVariants", "sectionOrder", "optionalSections"]
54
+ }
55
+ },
56
+ "componentAllowlist": ["TopNav", "TopNavItem", "Button", "Badge", "Card", "CardContent", "CardDescription", "CardHeader", "CardTitle", "Select", "SelectContent", "SelectItem", "SelectTrigger", "SelectValue", "Textarea", "TextInput", "MotionProvider"],
57
+ "tokenPolicy": {
58
+ "mapping": "semantic-role-only",
59
+ "allowedNamespaces": ["background", "foreground", "surface", "border", "primary", "secondary", "muted", "ring", "radius-*", "space-*", "font-*", "motion-*"],
60
+ "forbidRawBrandPrimitives": true
61
+ },
62
+ "contentPolicy": {
63
+ "sectionOrder": ["Hero", "Product interface preview", "Core workflow", "Agents and automation", "Integrations", "Security and reliability", "Team proof", "Adoption CTA", "Footer"],
64
+ "headlineMaxLines": 3,
65
+ "ctaCount": { "min": 1, "max": 2 },
66
+ "mediaRoles": ["product-proof", "workflow-explanation", "customer-proof"]
67
+ },
68
+ "validation": {
69
+ "allowUnknownComponents": false,
70
+ "allowAdHocColors": false,
71
+ "allowAdHocSpacing": false,
72
+ "requireResponsiveRules": true,
73
+ "requireReducedMotion": true,
74
+ "requireRTL": true
75
+ }
35
76
  }
36
77
  }
@@ -0,0 +1 @@
1
+ <!doctype html><html lang="en" dir="ltr" data-theme="utopia-default" data-color-mode="dark"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="color-scheme" content="dark light" /><style>html{color-scheme:dark}html[data-color-mode="light"]{color-scheme:light}html,body,#root{min-block-size:100%;margin:0;background:Canvas;color:CanvasText}</style><script>try{const mode=localStorage.getItem("ceramic-saas-mode");const locale=localStorage.getItem("ceramic-saas-locale");if(mode==="light")document.documentElement.dataset.colorMode="light";if(locale==="ar"){document.documentElement.lang="ar";document.documentElement.dir="rtl"}}catch{}</script><meta name="description" content="Terms of Use template." /><title>Terms of Use — SaaS Solution Template</title></head><body><a class="skip-link" href="#main-content">Skip to content</a><div id="root"></div><script type="module" src="../main.tsx"></script></body></html>
package/lib/api.mjs CHANGED
@@ -130,6 +130,44 @@ export function getMotionProfile(name) {
130
130
  return profile ? { ...profile, adapters: registry.adapters, contract: registry.contract } : null
131
131
  }
132
132
 
133
+ export function getLogoSkillRegistry() {
134
+ return readJson(join(paths().manifests, 'logo-skills.json'))
135
+ }
136
+
137
+ export function listLogoSkills() {
138
+ return getLogoSkillRegistry().skills
139
+ }
140
+
141
+ export function getLogoSkill(name) {
142
+ const key = normalize(name)
143
+ return listLogoSkills().find((item) => normalize(item.id) === key || normalize(item.name) === key) ?? null
144
+ }
145
+
146
+ export function prepareLogoMakerRun({ skillId, brandName, brief, referenceIds = [] }, root = process.cwd()) {
147
+ const skill = getLogoSkill(skillId)
148
+ if (!skill) return { ok: false, code: 'UNKNOWN_LOGO_SKILL', message: `Unknown logo skill "${skillId}".`, allowedSkillIds: listLogoSkills().map((item) => item.id) }
149
+ const room = getRoomContext(root)
150
+ const resolvedBrandName = String(brandName || room?.brandName || '').trim()
151
+ const resolvedBrief = String(brief || '').trim()
152
+ if (!resolvedBrandName) return { ok: false, code: 'BRAND_NAME_REQUIRED', message: 'Provide brandName or connect a Ceramic Brand Room.' }
153
+ if (resolvedBrief.length < 12) return { ok: false, code: 'BRIEF_TOO_SHORT', message: 'Provide at least 12 characters of design intent.' }
154
+ const references = Array.isArray(referenceIds) ? referenceIds.filter((value) => typeof value === 'string').slice(0, 3) : []
155
+ const registry = getLogoSkillRegistry()
156
+ const prompt = [`Create a professional ${skill.name} logo design concept for the following brand: ${resolvedBrandName}. ${resolvedBrief}`, '', 'Design requirements:', ...skill.requirements.map((requirement) => `- ${requirement}`)].join('\n')
157
+ return {
158
+ ok: true,
159
+ toolId: 'logo-maker',
160
+ logoSkillId: skill.id,
161
+ room,
162
+ input: { brandName: resolvedBrandName, brief: resolvedBrief, referenceIds: references },
163
+ prompt,
164
+ qualityFramework: registry.qualityFramework,
165
+ review: { required: true, policy: registry.qualityFramework.approvalPolicy, referencePolicy: registry.workflow.referencePolicy },
166
+ workflow: registry.workflow.sequence,
167
+ nextAction: 'Generate a draft from this prompt, present it as a proposal, and request human review before checkpointing an approved artifact.',
168
+ }
169
+ }
170
+
133
171
  export function listDocs() {
134
172
  return readdirSync(paths().docs)
135
173
  .filter((name) => name.endsWith('.md'))
@@ -143,6 +181,14 @@ export function getDoc(topic) {
143
181
  return { topic: match, content: readFileSync(join(paths().docs, `${match}.md`), 'utf8') }
144
182
  }
145
183
 
184
+ export function getRoomContext(root = process.cwd()) {
185
+ const roomPath = join(resolve(root), '.ceramic', 'room.json')
186
+ if (!existsSync(roomPath)) return null
187
+ const room = readJson(roomPath)
188
+ if (room?.apiVersion !== 1 || typeof room?.id !== 'string' || typeof room?.brandName !== 'string') return null
189
+ return room
190
+ }
191
+
146
192
  export function search(query) {
147
193
  const terms = String(query).toLowerCase().split(/\s+/).filter(Boolean)
148
194
  const score = (text) => terms.reduce((total, term) => total + (text.toLowerCase().includes(term) ? 1 : 0), 0)
@@ -153,6 +199,7 @@ export function search(query) {
153
199
  ...listTemplates().map((item) => ({ kind: 'template', id: item.id, title: item.title, summary: `${item.category} ${item.purpose}`, item })),
154
200
  ...listThemes().map((item) => ({ kind: 'theme', id: item.id, title: item.name, summary: item.role, item })),
155
201
  ...listMotionProfiles().map((item) => ({ kind: 'motion-profile', id: item.id, title: item.label, summary: `${item.description} ${item.rules.join(' ')}`, item })),
202
+ ...listLogoSkills().map((item) => ({ kind: 'logo-skill', id: item.id, title: item.name, summary: `${item.tagline} ${item.description} ${item.guidance}`, item })),
156
203
  ...listDocs().map((topic) => ({ kind: 'docs', id: topic, title: topic, summary: getDoc(topic)?.content.slice(0, 500) ?? '', item: { topic } })),
157
204
  ]
158
205
  return results
@@ -174,14 +221,16 @@ export function capabilityManifest() {
174
221
  ],
175
222
  commands: [
176
223
  { name: 'init', args: ['[directory]'], flags: ['--yes', '--theme <id>'], responseType: 'init-result' },
224
+ { name: 'room', args: ['connect'], flags: ['--id <id>', '--slug <slug>', '--name <room>', '--brand <brand>', '--source <mode>', '--client <client>', '--directory <path>'], responseType: 'room-connect-result' },
177
225
  { name: 'search', args: ['<query>'], flags: [], responseType: 'search-results' },
178
226
  { name: 'component', args: ['<name>|--list'], flags: [], responseType: 'component|component-list' },
179
227
  { name: 'registry', args: ['<block-id>|--list'], flags: ['--renderable'], responseType: 'block-definition|block-definition-list' },
180
228
  { name: 'layout', args: ['validate <file>', 'serialize <file>'], flags: [], responseType: 'layout-validation-result|layout-serialization-result' },
181
229
  { name: 'block', args: ['<id>|--list'], flags: ['--copy <directory>', '--force'], responseType: 'block|block-list|block-copy-result' },
182
- { name: 'template', args: ['<id>|--list', 'validate [directory]', 'submit [directory]'], flags: ['--skeleton', '--copy <directory>', '--theme <id>', '--force'], responseType: 'template|template-list|template-copy-result|template-validation-result|template-submit-result' },
230
+ { name: 'template', args: ['<id>|--list', 'validate [directory]', 'submit [directory]'], flags: ['--skeleton', '--copy <directory>', '--theme <id>', '--mode <exact|adapt|explore>', '--force'], responseType: 'template|template-list|template-copy-result|template-validation-result|template-submit-result' },
183
231
  { name: 'theme', args: ['<id>|--list', 'create <id> [directory]'], flags: ['--force'], responseType: 'theme|theme-list|theme-create-result' },
184
232
  { name: 'motion', args: ['<id>|--list'], flags: [], responseType: 'motion-profile|motion-profile-list' },
233
+ { name: 'logo-skill', args: ['<id>|--list'], flags: [], responseType: 'logo-skill|logo-skill-list' },
185
234
  { name: 'docs', args: ['<topic>|--list'], flags: [], responseType: 'docs|docs-list' },
186
235
  { name: 'manifest', args: [], flags: [], responseType: 'manifest' },
187
236
  { name: 'doctor', args: [], flags: [], responseType: 'doctor-result' },
@@ -189,14 +238,14 @@ export function capabilityManifest() {
189
238
  ],
190
239
  mcp: {
191
240
  ...mcpLaunch,
192
- tools: ['search', 'list_components', 'get_component', 'list_block_definitions', 'get_block_definition', 'validate_layout', 'validate_agent_layout_mutation', 'list_blocks', 'get_block', 'list_templates', 'get_template', 'list_themes', 'get_theme', 'list_motion_profiles', 'get_motion_profile', 'list_docs', 'get_docs', 'doctor'],
241
+ tools: ['get_room_context', 'search', 'list_components', 'get_component', 'list_block_definitions', 'get_block_definition', 'validate_layout', 'validate_agent_layout_mutation', 'list_blocks', 'get_block', 'list_templates', 'get_template', 'list_themes', 'get_theme', 'list_motion_profiles', 'get_motion_profile', 'list_logo_skills', 'get_logo_skill', 'prepare_logo_maker_run', 'list_docs', 'get_docs', 'doctor'],
193
242
  },
194
243
  }
195
244
  }
196
245
 
197
246
  export function repositoryDoctor() {
198
247
  const required = [
199
- 'catalog.json', 'components.json', 'blocks.json', 'composition-registry.json', 'templates.json', 'themes.json', 'motion-profiles.json',
248
+ 'catalog.json', 'components.json', 'blocks.json', 'composition-registry.json', 'templates.json', 'themes.json', 'motion-profiles.json', 'logo-skills.json',
200
249
  ].map((name) => join(paths().manifests, name))
201
250
  const docs = ['quick-start-ai', 'arabic-friendly', 'theme-authoring', 'composition-registry'].map((name) => join(paths().docs, `${name}.md`))
202
251
  const missing = [...required, ...docs].filter((path) => !existsSync(path))
@@ -0,0 +1 @@
1
+ export * from '../../design-system/src/lib/template-runtime.mjs'
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@utopia-studio-design/design-system-cli",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "AI-readable CLI and MCP server for Ceramic Design System",
5
5
  "ceramic": {
6
- "designSystem": "^0.8.0"
6
+ "designSystem": "^0.9.1"
7
7
  },
8
8
  "type": "module",
9
9
  "license": "MIT",