@nurix/etna 0.19.11 → 0.19.13

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 (494) hide show
  1. package/README.md +6 -4
  2. package/data/harness-index.json +1 -1
  3. package/data/harnesses/code/agents/maintenance.md +1 -1
  4. package/data/harnesses/code/harness.json +1 -1
  5. package/data/harnesses/code/rules/frontend.md +5 -5
  6. package/data/harnesses/code/skills/design/SKILL.md +70 -50
  7. package/data/harnesses/code/skills/design/components/charts.md +76 -0
  8. package/data/harnesses/code/skills/design/components/collections.md +132 -0
  9. package/data/harnesses/code/skills/design/components/feedback.md +47 -0
  10. package/data/harnesses/code/skills/design/components/hooks.md +35 -0
  11. package/data/harnesses/code/skills/design/components/index.md +143 -0
  12. package/data/harnesses/code/skills/design/components/inputs.md +327 -0
  13. package/data/harnesses/code/skills/design/components/layout.md +52 -0
  14. package/data/harnesses/code/skills/design/components/media.md +66 -0
  15. package/data/harnesses/code/skills/design/components/motion.md +82 -0
  16. package/data/harnesses/code/skills/design/components/navigation.md +29 -0
  17. package/data/harnesses/code/skills/design/components/overlays.md +72 -0
  18. package/data/harnesses/code/skills/design/components/setup.md +40 -0
  19. package/data/harnesses/code/skills/design/components/typography.md +46 -0
  20. package/data/harnesses/code/skills/design/components/utils.md +37 -0
  21. package/data/harnesses/code/skills/design/data/blueprints/browse.md +38 -0
  22. package/data/harnesses/code/skills/design/data/blueprints/creation-flow.md +38 -0
  23. package/data/harnesses/code/skills/design/data/blueprints/dashboard.md +38 -0
  24. package/data/harnesses/code/skills/design/data/blueprints/grid.md +38 -0
  25. package/data/harnesses/code/skills/design/data/blueprints/queue.md +38 -0
  26. package/data/harnesses/code/skills/design/data/blueprints/record-detail.md +38 -0
  27. package/data/harnesses/code/skills/design/data/blueprints/settings.md +38 -0
  28. package/data/harnesses/code/skills/design/data/chart-styling/Readme.md +33 -0
  29. package/data/harnesses/code/skills/design/data/chart-styling/carbon-accessible-alert-semantic.md +19 -0
  30. package/data/harnesses/code/skills/design/data/chart-styling/carbon-monochrome-sequential-trend.md +19 -0
  31. package/data/harnesses/code/skills/design/data/chart-styling/datadog-classic-six-aligned.md +19 -0
  32. package/data/harnesses/code/skills/design/data/chart-styling/datawrapper-tiered-gray-hierarchy.md +19 -0
  33. package/data/harnesses/code/skills/design/data/chart-styling/econ-red-rule-horizontal.md +19 -0
  34. package/data/harnesses/code/skills/design/data/chart-styling/financial-diverging-threshold-overlay.md +19 -0
  35. package/data/harnesses/code/skills/design/data/chart-styling/ft-vocabulary-ranked-muted.md +19 -0
  36. package/data/harnesses/code/skills/design/data/chart-styling/grafana-dark-threshold-bands.md +19 -0
  37. package/data/harnesses/code/skills/design/data/chart-styling/material-rounded-explicit-label.md +19 -0
  38. package/data/harnesses/code/skills/design/data/chart-styling/nyt-ghost-grid-direct-label.md +19 -0
  39. package/data/harnesses/code/skills/design/data/chart-styling/plot-currentcolor-inherit.md +19 -0
  40. package/data/harnesses/code/skills/design/data/chart-styling/saas-gradient-glow-area.md +19 -0
  41. package/data/harnesses/code/skills/design/data/chart-styling/shadcn-composable-css-vars.md +19 -0
  42. package/data/harnesses/code/skills/design/data/charts/census.csv +58 -0
  43. package/data/harnesses/code/skills/design/data/checklists/browse.md +21 -0
  44. package/data/harnesses/code/skills/design/data/checklists/creation-flow.md +20 -0
  45. package/data/harnesses/code/skills/design/data/checklists/dashboard.md +21 -0
  46. package/data/harnesses/code/skills/design/data/checklists/grid.md +21 -0
  47. package/data/harnesses/code/skills/design/data/checklists/queue.md +21 -0
  48. package/data/harnesses/code/skills/design/data/checklists/record-detail.md +21 -0
  49. package/data/harnesses/code/skills/design/data/checklists/settings.md +21 -0
  50. package/data/harnesses/code/skills/design/data/chrome/board-column.md +68 -0
  51. package/data/harnesses/code/skills/design/data/chrome/data-table.md +63 -0
  52. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +60 -0
  53. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +78 -0
  54. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +62 -0
  55. package/data/harnesses/code/skills/design/data/chrome/topbar.md +65 -0
  56. package/data/harnesses/code/skills/design/data/color/accent-presets.md +90 -0
  57. package/data/harnesses/code/skills/design/data/color/aesop-earth-mute.md +91 -0
  58. package/data/harnesses/code/skills/design/data/color/arc-peach-play.md +90 -0
  59. package/data/harnesses/code/skills/design/data/color/attio-hunter-teal.md +90 -0
  60. package/data/harnesses/code/skills/design/data/color/carbon-cyan-signal.md +90 -0
  61. package/data/harnesses/code/skills/design/data/color/clay-parchment.md +90 -0
  62. package/data/harnesses/code/skills/design/data/color/duolingo-feather.md +90 -0
  63. package/data/harnesses/code/skills/design/data/color/geist-mono-signal.md +90 -0
  64. package/data/harnesses/code/skills/design/data/color/linear-graphite-violet.md +90 -0
  65. package/data/harnesses/code/skills/design/data/color/mercury-onyx-cobalt.md +90 -0
  66. package/data/harnesses/code/skills/design/data/color/notion-paper-ink.md +90 -0
  67. package/data/harnesses/code/skills/design/data/color/radix-slate-iris.md +90 -0
  68. package/data/harnesses/code/skills/design/data/color/raycast-void-spectrum.md +90 -0
  69. package/data/harnesses/code/skills/design/data/color/spectrum-celery-fuchsia.md +90 -0
  70. package/data/harnesses/code/skills/design/data/color/stripe-blurple-ruby.md +90 -0
  71. package/data/harnesses/code/skills/design/data/color/superhuman-cod-picton.md +89 -0
  72. package/data/harnesses/code/skills/design/data/corpora/operations-review/companies.csv +15 -0
  73. package/data/harnesses/code/skills/design/data/corpora/operations-review/corpus.md +87 -0
  74. package/data/harnesses/code/skills/design/data/corpora/operations-review/people.csv +25 -0
  75. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/companies.csv +15 -0
  76. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/corpus.md +83 -0
  77. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/people.csv +25 -0
  78. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/companies.csv +15 -0
  79. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/corpus.md +89 -0
  80. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/people.csv +25 -0
  81. package/data/harnesses/code/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  82. package/data/harnesses/code/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  83. package/data/harnesses/code/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  84. package/data/harnesses/code/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  85. package/data/harnesses/code/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  86. package/data/harnesses/code/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  87. package/data/harnesses/code/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  88. package/data/harnesses/code/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  89. package/data/harnesses/code/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  90. package/data/harnesses/code/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  91. package/data/harnesses/code/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  92. package/data/harnesses/code/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  93. package/data/harnesses/code/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  94. package/data/harnesses/code/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  95. package/data/harnesses/code/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  96. package/data/harnesses/code/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  97. package/data/harnesses/code/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  98. package/data/harnesses/code/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  99. package/data/harnesses/code/skills/design/data/gradients/amber-attention-fill.md +16 -0
  100. package/data/harnesses/code/skills/design/data/gradients/cloud-shadow-wash.md +16 -0
  101. package/data/harnesses/code/skills/design/data/gradients/confident-lavender-wash.md +16 -0
  102. package/data/harnesses/code/skills/design/data/gradients/ember-ship-flare.md +18 -0
  103. package/data/harnesses/code/skills/design/data/gradients/full-metal-wash.md +16 -0
  104. package/data/harnesses/code/skills/design/data/gradients/indigo-ruby-cta-band.md +18 -0
  105. package/data/harnesses/code/skills/design/data/gradients/linear-graphite-wash.md +18 -0
  106. package/data/harnesses/code/skills/design/data/gradients/marble-quartz-wash.md +16 -0
  107. package/data/harnesses/code/skills/design/data/gradients/midnight-aurora-panel.md +16 -0
  108. package/data/harnesses/code/skills/design/data/gradients/neutral-volume-fill.md +16 -0
  109. package/data/harnesses/code/skills/design/data/gradients/revenue-uptrend-fill.md +16 -0
  110. package/data/harnesses/code/skills/design/data/gradients/risk-decline-fill.md +16 -0
  111. package/data/harnesses/code/skills/design/data/gradients/signal-blue-develop.md +18 -0
  112. package/data/harnesses/code/skills/design/data/gradients/slate-mist-wash.md +16 -0
  113. package/data/harnesses/code/skills/design/data/gradients/stripe-atmosphere-mesh.md +18 -0
  114. package/data/harnesses/code/skills/design/data/gradients/teal-signal-accent.md +16 -0
  115. package/data/harnesses/code/skills/design/data/gradients/violet-magenta-promo.md +16 -0
  116. package/data/harnesses/code/skills/design/data/iconography.md +199 -0
  117. package/data/harnesses/code/skills/design/data/motion/accordion-expand.md +18 -0
  118. package/data/harnesses/code/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  119. package/data/harnesses/code/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  120. package/data/harnesses/code/skills/design/data/motion/empty-state-arrive.md +18 -0
  121. package/data/harnesses/code/skills/design/data/motion/hover-lift.md +18 -0
  122. package/data/harnesses/code/skills/design/data/motion/modal-center-arrive.md +18 -0
  123. package/data/harnesses/code/skills/design/data/motion/number-ticker-roll.md +18 -0
  124. package/data/harnesses/code/skills/design/data/motion/onboarding-bounce.md +18 -0
  125. package/data/harnesses/code/skills/design/data/motion/panel-slide.md +18 -0
  126. package/data/harnesses/code/skills/design/data/motion/press-feedback.md +18 -0
  127. package/data/harnesses/code/skills/design/data/motion/progress-linear-loop.md +18 -0
  128. package/data/harnesses/code/skills/design/data/motion/route-crossfade.md +18 -0
  129. package/data/harnesses/code/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  130. package/data/harnesses/code/skills/design/data/motion/skeleton-shimmer.md +18 -0
  131. package/data/harnesses/code/skills/design/data/motion/stagger-arrive.md +18 -0
  132. package/data/harnesses/code/skills/design/data/motion/toast-enter-stack.md +18 -0
  133. package/data/harnesses/code/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  134. package/data/harnesses/code/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  135. package/data/harnesses/code/skills/design/data/tells.csv +34 -0
  136. package/data/harnesses/code/skills/design/data/typography/anton-work-sans.md +17 -0
  137. package/data/harnesses/code/skills/design/data/typography/archivo-black-archivo.md +17 -0
  138. package/data/harnesses/code/skills/design/data/typography/bitter-karla.md +17 -0
  139. package/data/harnesses/code/skills/design/data/typography/dm-serif-dm-sans.md +17 -0
  140. package/data/harnesses/code/skills/design/data/typography/fraunces-inter.md +17 -0
  141. package/data/harnesses/code/skills/design/data/typography/geist-geist-mono.md +17 -0
  142. package/data/harnesses/code/skills/design/data/typography/hubot-sans-mona-sans.md +17 -0
  143. package/data/harnesses/code/skills/design/data/typography/ibm-plex-sans-operator-single-family.md +17 -0
  144. package/data/harnesses/code/skills/design/data/typography/instrument-serif-instrument-sans.md +17 -0
  145. package/data/harnesses/code/skills/design/data/typography/inter-operator-single-family.md +17 -0
  146. package/data/harnesses/code/skills/design/data/typography/libre-baskerville-libre-franklin.md +17 -0
  147. package/data/harnesses/code/skills/design/data/typography/newsreader-inter.md +17 -0
  148. package/data/harnesses/code/skills/design/data/typography/playfair-display-source-sans.md +17 -0
  149. package/data/harnesses/code/skills/design/data/typography/public-sans-operator-single-family.md +17 -0
  150. package/data/harnesses/code/skills/design/data/typography/sohne-inter-fintech.md +17 -0
  151. package/data/harnesses/code/skills/design/data/typography/source-serif-source-sans.md +17 -0
  152. package/data/harnesses/code/skills/design/data/typography/space-grotesk-work-sans-space-mono.md +17 -0
  153. package/data/harnesses/code/skills/design/data/typography/spectral-manrope.md +17 -0
  154. package/data/harnesses/code/skills/design/data/voices/bright-collaborator.md +29 -0
  155. package/data/harnesses/code/skills/design/data/voices/direct-operator.md +29 -0
  156. package/data/harnesses/code/skills/design/data/voices/earnest-helper.md +29 -0
  157. package/data/harnesses/code/skills/design/data/voices/editorial-composed.md +29 -0
  158. package/data/harnesses/code/skills/design/data/voices/quiet-concierge.md +29 -0
  159. package/data/harnesses/code/skills/design/data/voices/warm-guide.md +29 -0
  160. package/data/harnesses/code/skills/design/design-md/SCHEMA.md +179 -0
  161. package/data/harnesses/code/skills/design/design-md/index.csv +67 -0
  162. package/data/harnesses/code/skills/design/design-md/library/airbnb.md +207 -0
  163. package/data/harnesses/code/skills/design/design-md/library/airtable.md +205 -0
  164. package/data/harnesses/code/skills/design/design-md/library/anthropic-claude.md +203 -0
  165. package/data/harnesses/code/skills/design/design-md/library/apple.md +206 -0
  166. package/data/harnesses/code/skills/design/design-md/library/binance.md +210 -0
  167. package/data/harnesses/code/skills/design/design-md/library/bmw.md +210 -0
  168. package/data/harnesses/code/skills/design/design-md/library/cal.md +209 -0
  169. package/data/harnesses/code/skills/design/design-md/library/clay.md +204 -0
  170. package/data/harnesses/code/skills/design/design-md/library/clickhouse.md +205 -0
  171. package/data/harnesses/code/skills/design/design-md/library/cohere.md +205 -0
  172. package/data/harnesses/code/skills/design/design-md/library/coinbase.md +198 -0
  173. package/data/harnesses/code/skills/design/design-md/library/composio.md +198 -0
  174. package/data/harnesses/code/skills/design/design-md/library/cursor.md +197 -0
  175. package/data/harnesses/code/skills/design/design-md/library/elevenlabs.md +199 -0
  176. package/data/harnesses/code/skills/design/design-md/library/expo.md +200 -0
  177. package/data/harnesses/code/skills/design/design-md/library/figma.md +199 -0
  178. package/data/harnesses/code/skills/design/design-md/library/framer.md +202 -0
  179. package/data/harnesses/code/skills/design/design-md/library/hashicorp.md +205 -0
  180. package/data/harnesses/code/skills/design/design-md/library/ibm.md +205 -0
  181. package/data/harnesses/code/skills/design/design-md/library/intercom.md +204 -0
  182. package/data/harnesses/code/skills/design/design-md/library/kraken.md +200 -0
  183. package/data/harnesses/code/skills/design/design-md/library/linear-app.md +198 -0
  184. package/data/harnesses/code/skills/design/design-md/library/lovable.md +199 -0
  185. package/data/harnesses/code/skills/design/design-md/library/meta.md +204 -0
  186. package/data/harnesses/code/skills/design/design-md/library/minimax.md +204 -0
  187. package/data/harnesses/code/skills/design/design-md/library/mintlify.md +210 -0
  188. package/data/harnesses/code/skills/design/design-md/library/miro.md +209 -0
  189. package/data/harnesses/code/skills/design/design-md/library/mistral-ai.md +201 -0
  190. package/data/harnesses/code/skills/design/design-md/library/mongodb.md +201 -0
  191. package/data/harnesses/code/skills/design/design-md/library/notion.md +204 -0
  192. package/data/harnesses/code/skills/design/design-md/library/nvidia.md +215 -0
  193. package/data/harnesses/code/skills/design/design-md/library/ollama.md +213 -0
  194. package/data/harnesses/code/skills/design/design-md/library/opencode-ai.md +216 -0
  195. package/data/harnesses/code/skills/design/design-md/library/posthog.md +218 -0
  196. package/data/harnesses/code/skills/design/design-md/library/raycast.md +214 -0
  197. package/data/harnesses/code/skills/design/design-md/library/replicate.md +202 -0
  198. package/data/harnesses/code/skills/design/design-md/library/resend.md +203 -0
  199. package/data/harnesses/code/skills/design/design-md/library/revolut.md +203 -0
  200. package/data/harnesses/code/skills/design/design-md/library/runwayml.md +203 -0
  201. package/data/harnesses/code/skills/design/design-md/library/sanity.md +200 -0
  202. package/data/harnesses/code/skills/design/design-md/library/sentry.md +201 -0
  203. package/data/harnesses/code/skills/design/design-md/library/shopify.md +202 -0
  204. package/data/harnesses/code/skills/design/design-md/library/slack.md +202 -0
  205. package/data/harnesses/code/skills/design/design-md/library/spacex.md +206 -0
  206. package/data/harnesses/code/skills/design/design-md/library/spotify.md +206 -0
  207. package/data/harnesses/code/skills/design/design-md/library/stripe.md +196 -0
  208. package/data/harnesses/code/skills/design/design-md/library/supabase.md +196 -0
  209. package/data/harnesses/code/skills/design/design-md/library/superhuman.md +194 -0
  210. package/data/harnesses/code/skills/design/design-md/library/tesla.md +198 -0
  211. package/data/harnesses/code/skills/design/design-md/library/theverge.md +199 -0
  212. package/data/harnesses/code/skills/design/design-md/library/together-ai.md +193 -0
  213. package/data/harnesses/code/skills/design/design-md/library/uber.md +195 -0
  214. package/data/harnesses/code/skills/design/design-md/library/vercel.md +195 -0
  215. package/data/harnesses/code/skills/design/design-md/library/voltagent.md +197 -0
  216. package/data/harnesses/code/skills/design/design-md/library/warp.md +196 -0
  217. package/data/harnesses/code/skills/design/design-md/library/webflow.md +197 -0
  218. package/data/harnesses/code/skills/design/design-md/library/wired.md +197 -0
  219. package/data/harnesses/code/skills/design/design-md/library/wise.md +198 -0
  220. package/data/harnesses/code/skills/design/design-md/library/x-ai.md +199 -0
  221. package/data/harnesses/code/skills/design/design-md/library/zapier.md +198 -0
  222. package/data/harnesses/code/skills/design/design-md/nurix.md +214 -0
  223. package/data/harnesses/code/skills/design/design-md/variants/editorial-luxury.md +184 -0
  224. package/data/harnesses/code/skills/design/design-md/variants/expressive-saas.md +216 -0
  225. package/data/harnesses/code/skills/design/design-md/variants/quiet-premium.md +211 -0
  226. package/data/harnesses/code/skills/design/design-md/variants/terse-dense-operator.md +212 -0
  227. package/data/harnesses/code/skills/design/design-md/variants/warm-approachable.md +216 -0
  228. package/data/harnesses/code/skills/design/references/compose.md +23 -0
  229. package/data/harnesses/code/skills/design/references/content.md +28 -0
  230. package/data/harnesses/code/skills/design/references/emission.md +21 -0
  231. package/data/harnesses/code/skills/design/references/existing-apps.md +27 -0
  232. package/data/harnesses/code/skills/design/references/intake.md +36 -0
  233. package/data/harnesses/code/skills/design/references/object-pass.md +24 -0
  234. package/data/harnesses/code/skills/design/references/ship-gate.md +29 -0
  235. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +195 -0
  236. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +49 -0
  237. package/data/harnesses/code/skills/design/references/ux-patterns/attributes-lifecycle.md +43 -0
  238. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +44 -0
  239. package/data/harnesses/code/skills/design/references/ux-patterns/creation-paths.md +46 -0
  240. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +42 -0
  241. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +42 -0
  242. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +46 -0
  243. package/data/harnesses/code/skills/design/references/ux-patterns/page-archetype.md +48 -0
  244. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +37 -0
  245. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +42 -0
  246. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +46 -0
  247. package/data/harnesses/code/skills/design/references/ux-patterns/state-matrix.md +41 -0
  248. package/data/harnesses/code/skills/design/references/ux-patterns/table-mechanics.md +48 -0
  249. package/data/harnesses/code/skills/design/references/ux-patterns/verbs.md +45 -0
  250. package/data/harnesses/code/skills/design/references/ux-patterns/viewer-context.md +40 -0
  251. package/data/harnesses/code/skills/design/scripts/README-validator.md +27 -0
  252. package/data/harnesses/code/skills/design/scripts/select-chart.mjs +596 -0
  253. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +1198 -0
  254. package/data/harnesses/discussion/agents/discussion-baseline.md +1 -1
  255. package/data/harnesses/discussion/harness.json +1 -1
  256. package/data/harnesses/etna/agents/maintenance.md +1 -1
  257. package/data/harnesses/etna/harness.json +1 -1
  258. package/data/harnesses/hr/CLAUDE.md +1 -1
  259. package/data/harnesses/hr/harness.json +1 -1
  260. package/package.json +1 -1
  261. package/data/harnesses/code/skills/design/data/catalog/rules.csv +0 -137
  262. package/data/harnesses/code/skills/design/data/combinations/Readme.md +0 -33
  263. package/data/harnesses/code/skills/design/data/combinations/accent-presets.md +0 -113
  264. package/data/harnesses/code/skills/design/data/combinations/charts.csv +0 -33
  265. package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +0 -448
  266. package/data/harnesses/code/skills/design/data/combinations/icons.csv +0 -157
  267. package/data/harnesses/code/skills/design/data/combinations/landing.csv +0 -38
  268. package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +0 -2001
  269. package/data/harnesses/code/skills/design/data/combinations/manifest.json +0 -330
  270. package/data/harnesses/code/skills/design/data/combinations/motion.csv +0 -10
  271. package/data/harnesses/code/skills/design/data/combinations/palettes.csv +0 -92
  272. package/data/harnesses/code/skills/design/data/combinations/product-router.csv +0 -80
  273. package/data/harnesses/code/skills/design/data/combinations/styles.csv +0 -67
  274. package/data/harnesses/code/skills/design/data/combinations/typography.csv +0 -64
  275. package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +0 -106
  276. package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +0 -154
  277. package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +0 -151
  278. package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +0 -139
  279. package/data/harnesses/code/skills/design/data/design-md/library/apple.md +0 -139
  280. package/data/harnesses/code/skills/design/data/design-md/library/binance.md +0 -140
  281. package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +0 -140
  282. package/data/harnesses/code/skills/design/data/design-md/library/cal.md +0 -140
  283. package/data/harnesses/code/skills/design/data/design-md/library/clay.md +0 -139
  284. package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +0 -139
  285. package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +0 -147
  286. package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +0 -156
  287. package/data/harnesses/code/skills/design/data/design-md/library/composio.md +0 -138
  288. package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +0 -138
  289. package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +0 -137
  290. package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -148
  291. package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -141
  292. package/data/harnesses/code/skills/design/data/design-md/library/framer.md +0 -156
  293. package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +0 -140
  294. package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +0 -153
  295. package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +0 -158
  296. package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +0 -156
  297. package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -122
  298. package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +0 -140
  299. package/data/harnesses/code/skills/design/data/design-md/library/meta.md +0 -139
  300. package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +0 -139
  301. package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +0 -139
  302. package/data/harnesses/code/skills/design/data/design-md/library/miro.md +0 -153
  303. package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +0 -140
  304. package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +0 -155
  305. package/data/harnesses/code/skills/design/data/design-md/library/notion.md +0 -140
  306. package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +0 -141
  307. package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +0 -145
  308. package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +0 -142
  309. package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +0 -152
  310. package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +0 -137
  311. package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +0 -140
  312. package/data/harnesses/code/skills/design/data/design-md/library/resend.md +0 -170
  313. package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +0 -145
  314. package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -137
  315. package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +0 -168
  316. package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +0 -163
  317. package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +0 -147
  318. package/data/harnesses/code/skills/design/data/design-md/library/slack.md +0 -158
  319. package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +0 -171
  320. package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +0 -166
  321. package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +0 -160
  322. package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +0 -173
  323. package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +0 -145
  324. package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +0 -153
  325. package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +0 -167
  326. package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +0 -140
  327. package/data/harnesses/code/skills/design/data/design-md/library/uber.md +0 -140
  328. package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +0 -140
  329. package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +0 -130
  330. package/data/harnesses/code/skills/design/data/design-md/library/warp.md +0 -140
  331. package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +0 -140
  332. package/data/harnesses/code/skills/design/data/design-md/library/wired.md +0 -139
  333. package/data/harnesses/code/skills/design/data/design-md/library/wise.md +0 -137
  334. package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +0 -138
  335. package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +0 -158
  336. package/data/harnesses/code/skills/design/data/design-md/nurix.md +0 -138
  337. package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +0 -695
  338. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +0 -20
  339. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +0 -1272
  340. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +0 -20
  341. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +0 -1268
  342. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +0 -20
  343. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +0 -1273
  344. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +0 -20
  345. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +0 -1262
  346. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +0 -20
  347. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +0 -1257
  348. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +0 -20
  349. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +0 -1270
  350. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +0 -20
  351. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +0 -1270
  352. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +0 -20
  353. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +0 -1261
  354. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +0 -20
  355. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +0 -1268
  356. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +0 -20
  357. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +0 -1281
  358. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +0 -20
  359. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +0 -1262
  360. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +0 -20
  361. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +0 -1271
  362. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +0 -20
  363. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +0 -1276
  364. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +0 -20
  365. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +0 -1293
  366. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +0 -20
  367. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +0 -1270
  368. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +0 -20
  369. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +0 -1276
  370. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +0 -20
  371. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +0 -1267
  372. package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +0 -251
  373. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +0 -20
  374. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +0 -1273
  375. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +0 -20
  376. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +0 -1286
  377. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +0 -20
  378. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +0 -1290
  379. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +0 -20
  380. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +0 -1270
  381. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +0 -23
  382. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +0 -599
  383. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +0 -1272
  384. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +0 -20
  385. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +0 -1267
  386. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +0 -20
  387. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +0 -1289
  388. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +0 -20
  389. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +0 -1258
  390. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +0 -20
  391. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +0 -1284
  392. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +0 -20
  393. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +0 -1291
  394. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +0 -20
  395. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +0 -1263
  396. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +0 -20
  397. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +0 -1270
  398. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +0 -20
  399. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +0 -1261
  400. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +0 -20
  401. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +0 -1209
  402. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +0 -20
  403. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +0 -1265
  404. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +0 -20
  405. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +0 -1253
  406. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +0 -20
  407. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +0 -1268
  408. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +0 -20
  409. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +0 -1261
  410. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +0 -20
  411. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +0 -1263
  412. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +0 -20
  413. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +0 -1266
  414. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +0 -23
  415. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +0 -623
  416. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +0 -1276
  417. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +0 -20
  418. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +0 -1264
  419. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +0 -20
  420. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +0 -1268
  421. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +0 -20
  422. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +0 -1270
  423. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +0 -20
  424. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +0 -1288
  425. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +0 -20
  426. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +0 -1272
  427. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +0 -20
  428. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +0 -1265
  429. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +0 -20
  430. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +0 -1287
  431. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +0 -20
  432. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +0 -1286
  433. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +0 -20
  434. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +0 -1285
  435. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +0 -20
  436. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +0 -1287
  437. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +0 -20
  438. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +0 -1278
  439. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +0 -20
  440. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +0 -1269
  441. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +0 -20
  442. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +0 -1285
  443. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +0 -20
  444. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +0 -1303
  445. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +0 -20
  446. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +0 -1274
  447. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +0 -20
  448. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +0 -1296
  449. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +0 -23
  450. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +0 -612
  451. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +0 -1282
  452. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +0 -20
  453. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +0 -1287
  454. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +0 -20
  455. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +0 -1268
  456. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +0 -20
  457. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +0 -1276
  458. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +0 -20
  459. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +0 -1273
  460. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +0 -20
  461. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +0 -1296
  462. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +0 -20
  463. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +0 -1286
  464. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +0 -249
  465. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +0 -249
  466. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +0 -225
  467. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +0 -249
  468. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +0 -224
  469. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +0 -249
  470. package/data/harnesses/code/skills/design/data/operator-pack/fixtures.md +0 -88
  471. package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +0 -132
  472. package/data/harnesses/code/skills/design/data/operator-pack/trust-rubric.md +0 -76
  473. package/data/harnesses/code/skills/design/references/create.md +0 -173
  474. package/data/harnesses/code/skills/design/references/diagnosis.md +0 -108
  475. package/data/harnesses/code/skills/design/references/hard-rules.md +0 -177
  476. package/data/harnesses/code/skills/design/references/improve.md +0 -116
  477. package/data/harnesses/code/skills/design/references/interaction.md +0 -77
  478. package/data/harnesses/code/skills/design/references/introspect.md +0 -100
  479. package/data/harnesses/code/skills/design/references/lifecycle.md +0 -73
  480. package/data/harnesses/code/skills/design/references/personality.md +0 -575
  481. package/data/harnesses/code/skills/design/references/structure.md +0 -159
  482. package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +0 -1312
  483. package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +0 -1498
  484. package/data/harnesses/code/skills/design/scripts/generate-fixtures.mjs +0 -551
  485. package/data/harnesses/code/skills/design/scripts/lib/checks.mjs +0 -1092
  486. package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +0 -26
  487. package/data/harnesses/code/skills/design/scripts/lib/vocabulary.mjs +0 -65
  488. package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +0 -538
  489. package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +0 -312
  490. package/data/harnesses/code/skills/design/scripts/render-rung.mjs +0 -890
  491. package/data/harnesses/code/skills/design/scripts/scaffold.mjs +0 -769
  492. package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +0 -675
  493. package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +0 -164
  494. package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +0 -439
@@ -1,769 +0,0 @@
1
- // skills/design/scripts/scaffold.mjs — generates the non-creative app substrate (routes, nav, per-surface state shells, the theme + chart-colors lib helpers) from docs/design/structure.md
2
- import { mkdirSync, writeFileSync, readFileSync, existsSync } from "node:fs";
3
- import { dirname, join } from "node:path";
4
- import { BUDGETS, BUDGET_STAMPS, stampFor, THEME_ATTR, THEME_VALUES, resolveThemeDefault, MOTION_LIFT_CLASS, MOTION_STAGGER_CLASS, STAGGER_CHILD_CAP } from "./lib/vocabulary.mjs";
5
-
6
- const ARCHETYPES = ["list-detail", "dashboard", "entity-detail", "create-edit", "log-stream", "command-center"];
7
- const LANDING = new Set(["list-detail", "dashboard", "log-stream", "command-center"]);
8
- // Archetypes whose composition substrate is a row table (rows consume motion-lift) vs a card grid
9
- // (the grid consumes motion-stagger — brand-forward surfaces only: baseline skips arrival cascades, mot-08).
10
- const TABLE_ARCHETYPES = new Set(["list-detail", "log-stream", "command-center"]);
11
- const CARD_GRID_ARCHETYPES = new Set(["dashboard"]);
12
- // Archetypes whose surfaces typically carry charts — their composition region names the token wiring.
13
- const CHART_ARCHETYPES = new Set(["dashboard", "command-center"]);
14
-
15
- // Print the refusal (problem + exact fix) to stderr and exit non-zero.
16
- function refuse(problem, fix) {
17
- process.stderr.write(`scaffold.mjs: ${problem}\n`);
18
- process.stderr.write(`fix: ${fix}\n`);
19
- process.exit(1);
20
- }
21
-
22
- // Parse argv into positionals (_) and --flags (supporting --k v and --k=v).
23
- function parseArgs(argv) {
24
- const args = { _: [] };
25
- for (let i = 0; i < argv.length; i++) {
26
- const a = argv[i];
27
- if (a.startsWith("--")) {
28
- const eq = a.indexOf("=");
29
- if (eq !== -1) {
30
- args[a.slice(2, eq)] = a.slice(eq + 1);
31
- } else {
32
- const next = argv[i + 1];
33
- if (next !== undefined && !next.startsWith("--")) {
34
- args[a.slice(2)] = next;
35
- i++;
36
- } else {
37
- args[a.slice(2)] = true;
38
- }
39
- }
40
- } else {
41
- args._.push(a);
42
- }
43
- }
44
- return args;
45
- }
46
-
47
- // Strip a trailing/full-line YAML comment (structure-block values never contain '#').
48
- function stripComment(line) {
49
- const h = line.indexOf("#");
50
- if (h === -1) return line;
51
- if (h === 0 || /\s/.test(line[h - 1])) return line.slice(0, h).replace(/\s+$/, "");
52
- return line;
53
- }
54
-
55
- // Extract the body of the fenced ```yaml structure block by its info-string.
56
- function extractStructureBlock(text) {
57
- const m = text.match(/```yaml structure[^\n]*\n([\s\S]*?)\n```/);
58
- return m ? m[1] : null;
59
- }
60
-
61
- // Collapse the block into indent-tagged, comment-free, non-blank lines.
62
- function toLines(body) {
63
- const out = [];
64
- for (const raw of body.split(/\r?\n/)) {
65
- const noComment = stripComment(raw);
66
- if (noComment.trim() === "") continue;
67
- out.push({ indent: noComment.length - noComment.trimStart().length, text: noComment.trim() });
68
- }
69
- return out;
70
- }
71
-
72
- // Parse a scalar, inline flow sequence [a, b], or inline flow mapping {k: v}.
73
- function parseScalarOrFlow(s) {
74
- const t = s.trim();
75
- if (t.startsWith("[") && t.endsWith("]")) {
76
- const inner = t.slice(1, -1).trim();
77
- if (inner === "") return [];
78
- return inner.split(",").map((x) => parseScalarOrFlow(x));
79
- }
80
- if (t.startsWith("{") && t.endsWith("}")) {
81
- const inner = t.slice(1, -1).trim();
82
- const obj = {};
83
- if (inner === "") return obj;
84
- for (const pair of inner.split(",")) {
85
- const idx = pair.indexOf(":");
86
- if (idx === -1) continue;
87
- obj[pair.slice(0, idx).trim()] = parseScalarOrFlow(pair.slice(idx + 1));
88
- }
89
- return obj;
90
- }
91
- return t;
92
- }
93
-
94
- // Dispatch a contiguous line range [start,end) to a sequence or mapping parse.
95
- function parseBlock(lines, start, end) {
96
- if (start >= end) return null;
97
- const base = lines[start].indent;
98
- if (lines[start].text.startsWith("- ")) return parseSequence(lines, start, end, base);
99
- return parseMapping(lines, start, end, base);
100
- }
101
-
102
- // Parse a YAML sequence: each "- " item, with inline-first-pair mapping items merged with their children.
103
- function parseSequence(lines, start, end, base) {
104
- const items = [];
105
- let i = start;
106
- while (i < end && lines[i].indent === base && lines[i].text.startsWith("- ")) {
107
- const content = lines[i].text.slice(2).trim();
108
- let j = i + 1;
109
- while (j < end && lines[j].indent > base) j++;
110
- if (content.startsWith("{") || content.startsWith("[")) {
111
- items.push(parseScalarOrFlow(content));
112
- } else if (content.indexOf(":") !== -1) {
113
- const map = {};
114
- const c = content.indexOf(":");
115
- const key = content.slice(0, c).trim();
116
- const rest = content.slice(c + 1).trim();
117
- map[key] = rest !== "" ? parseScalarOrFlow(rest) : null;
118
- if (i + 1 < j) {
119
- const child = parseBlock(lines, i + 1, j);
120
- if (child && typeof child === "object" && !Array.isArray(child)) Object.assign(map, child);
121
- }
122
- items.push(map);
123
- } else {
124
- items.push(parseScalarOrFlow(content));
125
- }
126
- i = j;
127
- }
128
- return items;
129
- }
130
-
131
- // Parse a YAML mapping: key/value pairs at one indent, recursing into nested blocks.
132
- function parseMapping(lines, start, end, base) {
133
- const map = {};
134
- let i = start;
135
- while (i < end && lines[i].indent === base && !lines[i].text.startsWith("- ")) {
136
- const line = lines[i].text;
137
- const c = line.indexOf(":");
138
- if (c === -1) {
139
- i++;
140
- continue;
141
- }
142
- const key = line.slice(0, c).trim();
143
- const rest = line.slice(c + 1).trim();
144
- if (rest !== "") {
145
- map[key] = parseScalarOrFlow(rest);
146
- i++;
147
- } else {
148
- let j = i + 1;
149
- while (j < end && lines[j].indent > base) j++;
150
- map[key] = i + 1 < j ? parseBlock(lines, i + 1, j) : null;
151
- i = j;
152
- }
153
- }
154
- return map;
155
- }
156
-
157
- // Split a name into alphanumeric words on any separator.
158
- function words(s) {
159
- return String(s).trim().split(/[^A-Za-z0-9]+/).filter(Boolean);
160
- }
161
-
162
- // PascalCase a name (Support Ticket -> SupportTicket).
163
- function toPascal(s) {
164
- return words(s).map((w) => w[0].toUpperCase() + w.slice(1).toLowerCase()).join("");
165
- }
166
-
167
- // kebab-case a name (Ticket Queue -> ticket-queue).
168
- function toKebab(s) {
169
- return words(s).map((w) => w.toLowerCase()).join("-");
170
- }
171
-
172
- // camelCase a name, preserving already-camel single tokens (created_at -> createdAt, slaMinutes -> slaMinutes).
173
- function toCamel(s) {
174
- const str = String(s).trim();
175
- if (/^[A-Za-z0-9]+$/.test(str)) return str[0].toLowerCase() + str.slice(1);
176
- const w = words(str);
177
- if (!w.length) return "";
178
- return w[0].toLowerCase() + w.slice(1).map((x) => x[0].toUpperCase() + x.slice(1).toLowerCase()).join("");
179
- }
180
-
181
- // Naive English pluralization sufficient for entity nouns.
182
- function pluralize(word) {
183
- const w = String(word);
184
- if (/[^aeiou]y$/i.test(w)) return w.slice(0, -1) + "ies";
185
- if (/(s|x|z|ch|sh)$/i.test(w)) return w + "es";
186
- return w + "s";
187
- }
188
-
189
- // Capitalize the first character.
190
- function cap(s) {
191
- return s ? s[0].toUpperCase() + s.slice(1) : s;
192
- }
193
-
194
- // Canonical per-entity identifiers shared with generate-fixtures.mjs (module paths and export names must agree).
195
- function entityNames(name) {
196
- const arrayVar = pluralize(toCamel(name));
197
- return {
198
- iface: toPascal(name),
199
- typeFile: toKebab(name),
200
- fixtureFile: pluralize(toKebab(name)),
201
- arrayVar,
202
- emptyVar: "empty" + cap(arrayVar),
203
- degradedVar: "degraded" + cap(arrayVar),
204
- };
205
- }
206
-
207
- // Normalize a surface's declared delight budget to a legal enum value, defaulting to the safe floor
208
- // `baseline` when the map omits it or carries an unknown value (references/structure.md, the delight budget).
209
- function normalizeBudget(v) {
210
- const b = String(v ?? "").trim().toLowerCase();
211
- return BUDGETS.includes(b) ? b : "baseline";
212
- }
213
-
214
- // Normalize a surface's declared states to the canonical loading/empty/error/degraded set.
215
- function normalizeStates(arr) {
216
- const alias = { partial: "degraded", degraded: "degraded", loading: "loading", empty: "empty", error: "error" };
217
- const order = ["loading", "empty", "error", "degraded"];
218
- const set = new Set();
219
- for (const s of arr || []) {
220
- const n = alias[String(s).trim().toLowerCase()];
221
- if (n) set.add(n);
222
- }
223
- const picked = order.filter((s) => set.has(s));
224
- return picked.length ? picked : order.slice();
225
- }
226
-
227
- // Read, parse, and validate docs/design/structure.md into a normalized model, refusing on malformed input.
228
- function loadStructure(path, { requireSurfaces }) {
229
- if (!existsSync(path)) refuse(`structure map not found at ${path}`, "pass the path to docs/design/structure.md as the first argument");
230
- const body = extractStructureBlock(readFileSync(path, "utf8"));
231
- if (body === null) {
232
- refuse(
233
- `no fenced \`\`\`yaml structure block in ${path}`,
234
- "docs/design/structure.md must carry a fenced ```yaml structure block (see references/structure.md); run the structure phase to produce it",
235
- );
236
- }
237
- const parsed = parseBlock(toLines(body), 0, toLines(body).length) || {};
238
- const rawSurfaces = Array.isArray(parsed.surfaces) ? parsed.surfaces : [];
239
- const surfaces = rawSurfaces.map((s, idx) => {
240
- for (const key of ["name", "archetype", "route", "entity"]) {
241
- if (!s || typeof s[key] !== "string" || s[key].trim() === "") {
242
- refuse(
243
- `surface #${idx + 1} is missing required field "${key}"`,
244
- `every surfaces[] entry needs name, archetype, route, entity (structure.md schema)`,
245
- );
246
- }
247
- }
248
- const archetype = String(s.archetype).trim();
249
- if (!ARCHETYPES.includes(archetype)) {
250
- refuse(
251
- `surface "${s.name}" has archetype "${archetype}", not one of the closed six`,
252
- `set archetype to one of: ${ARCHETYPES.join(", ")} (surface-catalog.md; membership is closed)`,
253
- );
254
- }
255
- let mod = 0;
256
- if (s["density-modifier"] !== undefined && s["density-modifier"] !== null && String(s["density-modifier"]).trim() !== "") {
257
- mod = Number.parseInt(String(s["density-modifier"]).trim(), 10);
258
- if (Number.isNaN(mod)) {
259
- refuse(
260
- `surface "${s.name}" has a non-integer density-modifier "${s["density-modifier"]}"`,
261
- "density-modifier is a signed integer (+1 denser / 0 / -1 looser) per surface-catalog.md",
262
- );
263
- }
264
- }
265
- return {
266
- name: String(s.name).trim(),
267
- archetype,
268
- route: String(s.route).trim(),
269
- entity: String(s.entity).trim(),
270
- densityModifier: mod,
271
- budget: normalizeBudget(s.budget),
272
- states: normalizeStates(s.states),
273
- };
274
- });
275
- if (requireSurfaces && surfaces.length === 0) {
276
- refuse(
277
- "the structure map declares no surfaces",
278
- "the object pass must assign at least one surface an archetype before scaffold opens (structure.md); an empty pass fails the structure gate",
279
- );
280
- }
281
- return {
282
- unitOfWork: typeof parsed["unit-of-work"] === "string" ? parsed["unit-of-work"].trim() : "",
283
- coreLoop: typeof parsed["core-loop"] === "string" ? parsed["core-loop"].trim() : "",
284
- entities: Array.isArray(parsed.entities) ? parsed.entities : [],
285
- temporal: parsed.temporal || {},
286
- surfaces,
287
- };
288
- }
289
-
290
- // Write a file under the project root, creating parent directories.
291
- function emit(root, rel, content, written) {
292
- const abs = join(root, rel);
293
- mkdirSync(dirname(abs), { recursive: true });
294
- writeFileSync(abs, content, "utf8");
295
- written.push(rel);
296
- }
297
-
298
- // Read the emitted default theme from the artifact payload (payload.theme-default, else derived from
299
- // look.theme via both → light), returning light when the artifact is absent, unreadable, or silent.
300
- function readThemeDefault(out) {
301
- const artifactPath = join(out, "design.tokens.json");
302
- if (!existsSync(artifactPath)) return "light";
303
- let tokens;
304
- try {
305
- tokens = JSON.parse(readFileSync(artifactPath, "utf8"));
306
- } catch {
307
- return "light";
308
- }
309
- const payload = tokens && tokens.$extensions && tokens.$extensions["com.nurix.design"];
310
- if (!payload || typeof payload !== "object") return "light";
311
- if (THEME_VALUES.includes(payload["theme-default"])) return payload["theme-default"];
312
- if (payload.look && typeof payload.look === "object") return resolveThemeDefault(payload.look.theme);
313
- return "light";
314
- }
315
-
316
- // Render index.html. data-theme is written from the artifact's resolved theme-default; the other
317
- // <html data-*> personality attributes are placeholders derive-personality.mjs --emit resolves.
318
- function indexHtml(themeDefault) {
319
- return `<!doctype html>
320
- <!-- Generated by scaffold.mjs. Personality state lives in these <html data-*> attributes (code is the cache).
321
- data-theme is written from the project artifact's theme-default; the remaining values are placeholders
322
- derive-personality.mjs --emit resolves from the design-tokens artifact (design.tokens.json). -->
323
- <html
324
- lang="en"
325
- data-style="app"
326
- data-density="standard"
327
- data-verbosity="default"
328
- data-feedback="subtle"
329
- data-theme="${themeDefault}"
330
- >
331
- <head>
332
- <meta charset="UTF-8" />
333
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
334
- <title>Operator UI</title>
335
- </head>
336
- <body>
337
- <div id="root"></div>
338
- <script type="module" src="/src/main.tsx"></script>
339
- </body>
340
- </html>
341
- `;
342
- }
343
-
344
- // Render src/main.tsx: apply the persisted theme, mount the router app, load the emitted stylesheet.
345
- function mainTsx() {
346
- return `// src/main.tsx — Vite entry: applies the persisted theme, mounts the router app, and loads the emitted global stylesheet (generated by scaffold.mjs; do not hand-edit).
347
- import { StrictMode } from "react";
348
- import { createRoot } from "react-dom/client";
349
- import App from "./App";
350
- import { initTheme } from "./lib/theme";
351
- import "./styles/globals.css";
352
-
353
- // A stored theme preference overrides the boot attribute before first paint.
354
- initTheme();
355
-
356
- const rootElement = document.getElementById("root");
357
- if (!rootElement) {
358
- throw new Error("Root element #root not found in index.html");
359
- }
360
-
361
- createRoot(rootElement).render(
362
- <StrictMode>
363
- <App />
364
- </StrictMode>,
365
- );
366
- `;
367
- }
368
-
369
- // Render src/lib/theme.ts: the data-theme toggle + persistence helper — one attribute convention,
370
- // four writers (personality.css armor, scaffold's <html>, @custom-variant dark, this helper).
371
- function themeTs() {
372
- const themeUnion = THEME_VALUES.map((v) => `"${v}"`).join(" | ");
373
- return `// src/lib/theme.ts — ${THEME_ATTR} toggle + persistence (generated by scaffold.mjs; do not hand-edit).
374
- // Code is the cache: <html ${THEME_ATTR}> is the single runtime theme state — the same attribute
375
- // personality.css armors (:root[${THEME_ATTR}="dark"]) and globals.css's @custom-variant dark follows.
376
- // index.html carries the artifact's theme-default as the boot value; a stored preference overrides it.
377
-
378
- export type Theme = ${themeUnion};
379
-
380
- const THEME_ATTRIBUTE = "${THEME_ATTR}";
381
- const THEME_STORAGE_KEY = "theme";
382
- const THEMES: Theme[] = [${THEME_VALUES.map((v) => `"${v}"`).join(", ")}];
383
-
384
- // The active theme, read from the attribute (the cache), defaulting to light.
385
- export function getTheme(): Theme {
386
- const value = document.documentElement.getAttribute(THEME_ATTRIBUTE);
387
- return THEMES.includes(value as Theme) ? (value as Theme) : "light";
388
- }
389
-
390
- // Set the theme: write the attribute (the cascade flips) and persist the preference.
391
- export function setTheme(theme: Theme): void {
392
- document.documentElement.setAttribute(THEME_ATTRIBUTE, theme);
393
- try {
394
- localStorage.setItem(THEME_STORAGE_KEY, theme);
395
- } catch {
396
- // storage unavailable (private mode) — the attribute still flips for this session
397
- }
398
- }
399
-
400
- // Flip between light and dark, returning the new theme.
401
- export function toggleTheme(): Theme {
402
- const next: Theme = getTheme() === "dark" ? "light" : "dark";
403
- setTheme(next);
404
- return next;
405
- }
406
-
407
- // Apply a stored preference over the boot attribute; called once by main.tsx before mount.
408
- export function initTheme(): void {
409
- let stored: string | null = null;
410
- try {
411
- stored = localStorage.getItem(THEME_STORAGE_KEY);
412
- } catch {
413
- return;
414
- }
415
- if (stored !== null && THEMES.includes(stored as Theme)) {
416
- document.documentElement.setAttribute(THEME_ATTRIBUTE, stored as Theme);
417
- }
418
- }
419
- `;
420
- }
421
-
422
- // Render src/lib/chart-colors.ts: token-backed chart palettes so the identity survives to the pixel.
423
- function chartColorsTs() {
424
- return `// src/lib/chart-colors.ts — chart color wiring over the emitted tokens (generated by scaffold.mjs; do not hand-edit).
425
- // @nurix/components charts accept color props (probed at 0.14.0): LineGraph/PieGraph take a series
426
- // list, BarGraph takes a status map (success | degraded | error | info | empty). Always pass these
427
- // exports — never literals — so every chart inherits the theme through the emitted tokens; chart
428
- // chrome (gridlines, axis labels) stays library-internal, a known substrate limit.
429
-
430
- // Series palette for LineGraph / PieGraph \`colors\` — the artifact's five chart tokens, in order.
431
- export const SERIES_COLORS = [
432
- "var(--chart-1)",
433
- "var(--chart-2)",
434
- "var(--chart-3)",
435
- "var(--chart-4)",
436
- "var(--chart-5)",
437
- ];
438
-
439
- // Status map for BarGraph \`colors\`. info/empty ride accent / muted-foreground: the 36-role
440
- // artifact carries no dedicated info or empty token, and those two are their closest semantic homes.
441
- export const STATUS_COLORS = {
442
- success: "var(--success)",
443
- degraded: "var(--warning)",
444
- error: "var(--destructive)",
445
- info: "var(--accent)",
446
- empty: "var(--muted-foreground)",
447
- };
448
- `;
449
- }
450
-
451
- // Render src/App.tsx: one route per surface, wrapped in the persistent operator shell.
452
- function appTsx(surfaces) {
453
- const imports = surfaces
454
- .map((s) => `import { ${toPascal(s.name)} } from "./routes/${toKebab(s.name)}/${toPascal(s.name)}";`)
455
- .join("\n");
456
- const routes = surfaces
457
- .map((s) => ` <Route path="${s.route}" element={<${toPascal(s.name)} />} />`)
458
- .join("\n");
459
- return `// src/App.tsx — application routes and layout wiring (generated from docs/design/structure.md; do not hand-edit).
460
- import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom";
461
- import { AppNav } from "./components/nav/AppNav";
462
- ${imports}
463
-
464
- // Persistent operator shell: the navigation rail beside the routed surface.
465
- function AppLayout() {
466
- return (
467
- <div className="flex min-h-[100dvh] bg-background text-foreground">
468
- <AppNav />
469
- <main className="flex min-h-0 flex-1 flex-col overflow-auto">
470
- <Outlet />
471
- </main>
472
- </div>
473
- );
474
- }
475
-
476
- // Router: one route per surface in the entity/surface map.
477
- export default function App() {
478
- return (
479
- <BrowserRouter>
480
- <Routes>
481
- <Route element={<AppLayout />}>
482
- ${routes}
483
- </Route>
484
- </Routes>
485
- </BrowserRouter>
486
- );
487
- }
488
- `;
489
- }
490
-
491
- // Render src/components/nav/AppNav.tsx: top-level entries derived from the object model, secondary surfaces reached by drilling in.
492
- function navTsx(surfaces) {
493
- const navItems = surfaces.filter(
494
- (s) => LANDING.has(s.archetype) && !s.route.includes(":") && !/\/new$/.test(s.route),
495
- );
496
- const items = navItems
497
- .map((s) => ` { label: "${s.name}", route: "${s.route}" },`)
498
- .join("\n");
499
- return `// src/components/nav/AppNav.tsx — top-level navigation derived from the object model (generated; do not hand-edit).
500
- import { NavLink } from "react-router-dom";
501
-
502
- interface NavItem {
503
- label: string;
504
- route: string;
505
- }
506
-
507
- // Top-level entries are the primary entities' home surfaces; detail and create surfaces are reached by drilling in.
508
- const NAV_ITEMS: NavItem[] = [
509
- ${items}
510
- ];
511
-
512
- // Left navigation rail: one entry per top-level operator surface.
513
- export function AppNav() {
514
- return (
515
- <nav
516
- aria-label="Primary"
517
- className="flex w-56 shrink-0 flex-col gap-1 border-r border-sidebar-border bg-sidebar p-3 text-sidebar-foreground"
518
- >
519
- {NAV_ITEMS.map((item) => (
520
- <NavLink
521
- key={item.route}
522
- to={item.route}
523
- end
524
- className={({ isActive }) =>
525
- [
526
- "rounded-md px-3 py-2 text-sm font-medium transition-colors",
527
- isActive
528
- ? "bg-sidebar-accent text-sidebar-accent-foreground"
529
- : "text-sidebar-foreground hover:bg-sidebar-accent/60",
530
- ].join(" ")
531
- }
532
- >
533
- {item.label}
534
- </NavLink>
535
- ))}
536
- </nav>
537
- );
538
- }
539
- `;
540
- }
541
-
542
- // Composition region for one surface, per archetype: table archetypes get a substrate row table
543
- // (rows consume motion-lift — hover feedback, budget-free); card-grid archetypes get a substrate
544
- // grid (motion-stagger on brand-forward surfaces only — baseline skips arrival cascades, mot-08);
545
- // chart archetypes carry the token wiring instruction; the rest keep the compose-here placeholder.
546
- function compositionFn(surface, en) {
547
- const comp = toPascal(surface.name);
548
- const chartNote = CHART_ARCHETYPES.has(surface.archetype)
549
- ? `
550
- {/* Charts: import { SERIES_COLORS, STATUS_COLORS } from "../../lib/chart-colors" and pass
551
- colors={SERIES_COLORS} to LineGraph/PieGraph, colors={STATUS_COLORS} to BarGraph —
552
- token-backed palettes only; chart chrome is library-internal (a substrate limit). */}`
553
- : "";
554
-
555
- if (TABLE_ARCHETYPES.has(surface.archetype)) {
556
- return `// Composition region: the surfaces phase composes the ${surface.archetype} archetype here, following its exemplar and the emitted tokens.
557
- function ${comp}Composition({ rows, degraded = false }: { rows: ${en.iface}[]; degraded?: boolean }) {
558
- const columns = rows.length > 0 ? Object.keys(rows[0] as unknown as Record<string, unknown>).slice(0, 5) : [];
559
- return (
560
- <div className="flex flex-1 flex-col rounded-lg border border-border bg-card text-card-foreground">
561
- <div className="flex items-center justify-between border-b border-border px-4 py-3">
562
- <p className="text-sm font-medium text-foreground">${surface.name}</p>
563
- <p className="text-xs text-muted-foreground tabular-nums">
564
- {rows.length} records{degraded ? " (partial)" : ""}
565
- </p>
566
- </div>
567
- <div className="overflow-x-auto">
568
- <table className="w-full table-fixed text-sm">
569
- <thead>
570
- <tr className="border-b border-border text-left">
571
- {columns.map((column) => (
572
- <th key={column} scope="col" className="truncate px-4 py-2 text-xs font-medium text-muted-foreground">
573
- {column}
574
- </th>
575
- ))}
576
- </tr>
577
- </thead>
578
- <tbody>
579
- {rows.map((row, index) => (
580
- <tr key={index} className="${MOTION_LIFT_CLASS} border-b border-border">
581
- {columns.map((column) => (
582
- <td key={column} className="truncate px-4 py-2">
583
- {String((row as unknown as Record<string, unknown>)[column] ?? "")}
584
- </td>
585
- ))}
586
- </tr>
587
- ))}
588
- </tbody>
589
- </table>
590
- </div>${chartNote}
591
- <p className="border-t border-border px-4 py-3 text-xs text-muted-foreground">
592
- Substrate table: compose the ${surface.archetype} surface for ${surface.entity} here.
593
- </p>
594
- </div>
595
- );
596
- }`;
597
- }
598
-
599
- if (CARD_GRID_ARCHETYPES.has(surface.archetype)) {
600
- const staggerClass = surface.budget === "brand-forward" ? ` ${MOTION_STAGGER_CLASS}` : "";
601
- return `// Composition region: the surfaces phase composes the ${surface.archetype} archetype here, following its exemplar and the emitted tokens.
602
- function ${comp}Composition({ rows, degraded = false }: { rows: ${en.iface}[]; degraded?: boolean }) {
603
- return (
604
- <div className="flex flex-1 flex-col gap-3">
605
- <div className="flex items-center justify-between">
606
- <p className="text-sm font-medium text-foreground">${surface.name}</p>
607
- <p className="text-xs text-muted-foreground tabular-nums">
608
- {rows.length} records{degraded ? " (partial)" : ""}
609
- </p>
610
- </div>
611
- <div className="grid auto-rows-min grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3${staggerClass}">
612
- {rows.slice(0, ${STAGGER_CHILD_CAP}).map((row, index) => (
613
- <article key={index} className="flex flex-col gap-2 rounded-lg border border-border bg-card p-4 text-card-foreground shadow-sm">
614
- {Object.entries(row as unknown as Record<string, unknown>).slice(0, 4).map(([field, value]) => (
615
- <div key={field} className="flex items-baseline justify-between gap-3">
616
- <span className="truncate text-xs text-muted-foreground">{field}</span>
617
- <span className="truncate text-sm font-medium">{String(value ?? "")}</span>
618
- </div>
619
- ))}
620
- </article>
621
- ))}
622
- </div>${chartNote}
623
- <p className="text-xs text-muted-foreground">
624
- Substrate card grid: compose the ${surface.archetype} surface for ${surface.entity} here.
625
- </p>
626
- </div>
627
- );
628
- }`;
629
- }
630
-
631
- return `// Composition region: the surfaces phase composes the ${surface.archetype} archetype here, following its exemplar and the emitted tokens.
632
- function ${comp}Composition({ rows, degraded = false }: { rows: ${en.iface}[]; degraded?: boolean }) {
633
- return (
634
- <div className="flex flex-1 flex-col rounded-lg border border-border bg-card text-card-foreground">
635
- <div className="flex items-center justify-between border-b border-border px-4 py-3">
636
- <p className="text-sm font-medium text-foreground">${surface.name}</p>
637
- <p className="text-xs text-muted-foreground tabular-nums">
638
- {rows.length} records{degraded ? " (partial)" : ""}
639
- </p>
640
- </div>${chartNote}
641
- <p className="px-4 py-6 text-sm text-muted-foreground">
642
- Compose the ${surface.archetype} surface for ${surface.entity} here.
643
- </p>
644
- </div>
645
- );
646
- }`;
647
- }
648
-
649
- // Render one surface shell: typed props, fixture wiring, pre-created lifecycle state shells, and the density-step root.
650
- function surfaceShell(surface) {
651
- const comp = toPascal(surface.name);
652
- const slug = toKebab(surface.name);
653
- const en = entityNames(surface.entity);
654
- const states = surface.states;
655
- const hasEmpty = states.includes("empty");
656
- const hasDegraded = states.includes("degraded");
657
- const union = [...states, "ready"].map((s) => `"${s}"`).join(" | ");
658
- const densityAttr =
659
- surface.densityModifier > 0 ? ' data-density-step="tighter"' : surface.densityModifier < 0 ? ' data-density-step="looser"' : "";
660
-
661
- const named = [en.arrayVar];
662
- if (hasEmpty) named.push(en.emptyVar);
663
- if (hasDegraded) named.push(en.degradedVar);
664
-
665
- const branches = [];
666
- if (states.includes("loading")) {
667
- branches.push(` {state === "loading" && (
668
- <div className="flex flex-1 items-center justify-center py-12" aria-busy="true">
669
- <p className="text-sm text-muted-foreground">Loading ${surface.name}</p>
670
- </div>
671
- )}`);
672
- }
673
- if (hasEmpty) {
674
- branches.push(` {state === "empty" && (
675
- <div className="flex flex-1 flex-col items-center justify-center gap-1 py-12 text-center">
676
- <p className="text-sm font-medium text-foreground">Nothing here yet</p>
677
- <p className="max-w-sm text-sm text-muted-foreground">
678
- ${surface.name} has no records yet. New records appear here as the operator creates them.
679
- </p>
680
- </div>
681
- )}`);
682
- }
683
- if (states.includes("error")) {
684
- branches.push(` {state === "error" && (
685
- <div role="alert" className="flex flex-1 flex-col items-center justify-center gap-1 py-12 text-center">
686
- <p className="text-sm font-medium text-destructive">Could not load ${surface.name}</p>
687
- <p className="max-w-sm text-sm text-muted-foreground">The request failed. Retry to reload this surface.</p>
688
- </div>
689
- )}`);
690
- }
691
- if (hasDegraded) {
692
- branches.push(` {state === "degraded" && (
693
- <div className="flex flex-1 flex-col gap-2">
694
- <p className="text-sm text-warning">Showing partial data. Some records are stale or failed to enrich.</p>
695
- <${comp}Composition rows={rows} degraded />
696
- </div>
697
- )}`);
698
- }
699
- branches.push(` {state === "ready" && <${comp}Composition rows={rows} />}`);
700
-
701
- const pickBody = [];
702
- if (hasDegraded) pickBody.push(` if (state === "degraded") return ${en.degradedVar};`);
703
- if (hasEmpty) pickBody.push(` if (state === "empty") return ${en.emptyVar};`);
704
- pickBody.push(` return ${en.arrayVar};`);
705
-
706
- const stamp = stampFor(surface.budget) || BUDGET_STAMPS.baseline;
707
- const content = `${stamp}
708
- // src/routes/${slug}/${comp}.tsx — ${surface.name} surface shell (${surface.archetype}; generated by scaffold.mjs; do not hand-edit).
709
- import type { ${en.iface} } from "../../types/${en.typeFile}";
710
- import { ${named.join(", ")} } from "../../fixtures/${en.fixtureFile}";
711
-
712
- type SurfaceState = ${union};
713
-
714
- interface ${comp}Props {
715
- state?: SurfaceState;
716
- }
717
-
718
- // ${surface.name}: the ${surface.archetype} surface; scaffold pre-creates every lifecycle shell for the surfaces phase to fill.
719
- export function ${comp}({ state = "ready" }: ${comp}Props) {
720
- const rows: ${en.iface}[] = pickRows(state);
721
- return (
722
- <section${densityAttr} aria-label="${surface.name}" className="flex h-full min-h-0 flex-col gap-4 p-6">
723
- <header className="flex items-center justify-between border-b border-border pb-3">
724
- <div className="flex flex-col gap-1">
725
- <h1 className="text-base font-semibold tracking-tight text-foreground">${surface.name}</h1>
726
- <p className="text-xs text-muted-foreground">${surface.archetype} - ${surface.entity}</p>
727
- </div>
728
- <span className="text-xs text-muted-foreground tabular-nums">{rows.length} records</span>
729
- </header>
730
- ${branches.join("\n")}
731
- </section>
732
- );
733
- }
734
-
735
- ${compositionFn(surface, en)}
736
-
737
- // Select the fixture set backing the requested lifecycle state.
738
- function pickRows(state: SurfaceState): ${en.iface}[] {
739
- ${pickBody.join("\n")}
740
- }
741
- `;
742
- return { rel: `src/routes/${slug}/${comp}.tsx`, content };
743
- }
744
-
745
- // Entry point: load the map, emit the substrate, and report what was written.
746
- function main() {
747
- const args = parseArgs(process.argv.slice(2));
748
- const structurePath = args._[0];
749
- const out = typeof args.out === "string" ? args.out : null;
750
- if (!structurePath || !out) {
751
- refuse("missing arguments", "usage: scaffold.mjs <docs/design/structure.md> --out <project-root-dir>");
752
- }
753
- const model = loadStructure(structurePath, { requireSurfaces: true });
754
- const written = [];
755
- emit(out, "index.html", indexHtml(readThemeDefault(out)), written);
756
- emit(out, "src/main.tsx", mainTsx(), written);
757
- emit(out, "src/lib/theme.ts", themeTs(), written);
758
- emit(out, "src/lib/chart-colors.ts", chartColorsTs(), written);
759
- emit(out, "src/App.tsx", appTsx(model.surfaces), written);
760
- emit(out, "src/components/nav/AppNav.tsx", navTsx(model.surfaces), written);
761
- for (const surface of model.surfaces) {
762
- const shell = surfaceShell(surface);
763
- emit(out, shell.rel, shell.content, written);
764
- }
765
- process.stdout.write(`scaffold.mjs: wrote ${written.length} files under ${out}\n`);
766
- for (const rel of written) process.stdout.write(` ${rel}\n`);
767
- }
768
-
769
- main();