@nurix/etna 0.19.10 → 0.19.12

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 (491) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/code/harness.json +1 -1
  3. package/data/harnesses/code/rules/frontend.md +5 -5
  4. package/data/harnesses/code/skills/design/SKILL.md +70 -50
  5. package/data/harnesses/code/skills/design/components/charts.md +76 -0
  6. package/data/harnesses/code/skills/design/components/collections.md +132 -0
  7. package/data/harnesses/code/skills/design/components/feedback.md +47 -0
  8. package/data/harnesses/code/skills/design/components/hooks.md +35 -0
  9. package/data/harnesses/code/skills/design/components/index.md +143 -0
  10. package/data/harnesses/code/skills/design/components/inputs.md +327 -0
  11. package/data/harnesses/code/skills/design/components/layout.md +52 -0
  12. package/data/harnesses/code/skills/design/components/media.md +66 -0
  13. package/data/harnesses/code/skills/design/components/motion.md +82 -0
  14. package/data/harnesses/code/skills/design/components/navigation.md +29 -0
  15. package/data/harnesses/code/skills/design/components/overlays.md +72 -0
  16. package/data/harnesses/code/skills/design/components/setup.md +40 -0
  17. package/data/harnesses/code/skills/design/components/typography.md +46 -0
  18. package/data/harnesses/code/skills/design/components/utils.md +37 -0
  19. package/data/harnesses/code/skills/design/data/blueprints/browse.md +38 -0
  20. package/data/harnesses/code/skills/design/data/blueprints/creation-flow.md +38 -0
  21. package/data/harnesses/code/skills/design/data/blueprints/dashboard.md +38 -0
  22. package/data/harnesses/code/skills/design/data/blueprints/grid.md +38 -0
  23. package/data/harnesses/code/skills/design/data/blueprints/queue.md +38 -0
  24. package/data/harnesses/code/skills/design/data/blueprints/record-detail.md +38 -0
  25. package/data/harnesses/code/skills/design/data/blueprints/settings.md +38 -0
  26. package/data/harnesses/code/skills/design/data/chart-styling/Readme.md +33 -0
  27. package/data/harnesses/code/skills/design/data/chart-styling/carbon-accessible-alert-semantic.md +19 -0
  28. package/data/harnesses/code/skills/design/data/chart-styling/carbon-monochrome-sequential-trend.md +19 -0
  29. package/data/harnesses/code/skills/design/data/chart-styling/datadog-classic-six-aligned.md +19 -0
  30. package/data/harnesses/code/skills/design/data/chart-styling/datawrapper-tiered-gray-hierarchy.md +19 -0
  31. package/data/harnesses/code/skills/design/data/chart-styling/econ-red-rule-horizontal.md +19 -0
  32. package/data/harnesses/code/skills/design/data/chart-styling/financial-diverging-threshold-overlay.md +19 -0
  33. package/data/harnesses/code/skills/design/data/chart-styling/ft-vocabulary-ranked-muted.md +19 -0
  34. package/data/harnesses/code/skills/design/data/chart-styling/grafana-dark-threshold-bands.md +19 -0
  35. package/data/harnesses/code/skills/design/data/chart-styling/material-rounded-explicit-label.md +19 -0
  36. package/data/harnesses/code/skills/design/data/chart-styling/nyt-ghost-grid-direct-label.md +19 -0
  37. package/data/harnesses/code/skills/design/data/chart-styling/plot-currentcolor-inherit.md +19 -0
  38. package/data/harnesses/code/skills/design/data/chart-styling/saas-gradient-glow-area.md +19 -0
  39. package/data/harnesses/code/skills/design/data/chart-styling/shadcn-composable-css-vars.md +19 -0
  40. package/data/harnesses/code/skills/design/data/charts/census.csv +58 -0
  41. package/data/harnesses/code/skills/design/data/checklists/browse.md +21 -0
  42. package/data/harnesses/code/skills/design/data/checklists/creation-flow.md +20 -0
  43. package/data/harnesses/code/skills/design/data/checklists/dashboard.md +21 -0
  44. package/data/harnesses/code/skills/design/data/checklists/grid.md +21 -0
  45. package/data/harnesses/code/skills/design/data/checklists/queue.md +21 -0
  46. package/data/harnesses/code/skills/design/data/checklists/record-detail.md +21 -0
  47. package/data/harnesses/code/skills/design/data/checklists/settings.md +21 -0
  48. package/data/harnesses/code/skills/design/data/chrome/board-column.md +68 -0
  49. package/data/harnesses/code/skills/design/data/chrome/data-table.md +63 -0
  50. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +60 -0
  51. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +78 -0
  52. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +62 -0
  53. package/data/harnesses/code/skills/design/data/chrome/topbar.md +65 -0
  54. package/data/harnesses/code/skills/design/data/color/accent-presets.md +90 -0
  55. package/data/harnesses/code/skills/design/data/color/aesop-earth-mute.md +91 -0
  56. package/data/harnesses/code/skills/design/data/color/arc-peach-play.md +90 -0
  57. package/data/harnesses/code/skills/design/data/color/attio-hunter-teal.md +90 -0
  58. package/data/harnesses/code/skills/design/data/color/carbon-cyan-signal.md +90 -0
  59. package/data/harnesses/code/skills/design/data/color/clay-parchment.md +90 -0
  60. package/data/harnesses/code/skills/design/data/color/duolingo-feather.md +90 -0
  61. package/data/harnesses/code/skills/design/data/color/geist-mono-signal.md +90 -0
  62. package/data/harnesses/code/skills/design/data/color/linear-graphite-violet.md +90 -0
  63. package/data/harnesses/code/skills/design/data/color/mercury-onyx-cobalt.md +90 -0
  64. package/data/harnesses/code/skills/design/data/color/notion-paper-ink.md +90 -0
  65. package/data/harnesses/code/skills/design/data/color/radix-slate-iris.md +90 -0
  66. package/data/harnesses/code/skills/design/data/color/raycast-void-spectrum.md +90 -0
  67. package/data/harnesses/code/skills/design/data/color/spectrum-celery-fuchsia.md +90 -0
  68. package/data/harnesses/code/skills/design/data/color/stripe-blurple-ruby.md +90 -0
  69. package/data/harnesses/code/skills/design/data/color/superhuman-cod-picton.md +89 -0
  70. package/data/harnesses/code/skills/design/data/corpora/operations-review/companies.csv +15 -0
  71. package/data/harnesses/code/skills/design/data/corpora/operations-review/corpus.md +87 -0
  72. package/data/harnesses/code/skills/design/data/corpora/operations-review/people.csv +25 -0
  73. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/companies.csv +15 -0
  74. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/corpus.md +83 -0
  75. package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/people.csv +25 -0
  76. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/companies.csv +15 -0
  77. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/corpus.md +89 -0
  78. package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/people.csv +25 -0
  79. package/data/harnesses/code/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  80. package/data/harnesses/code/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  81. package/data/harnesses/code/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  82. package/data/harnesses/code/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  83. package/data/harnesses/code/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  84. package/data/harnesses/code/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  85. package/data/harnesses/code/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  86. package/data/harnesses/code/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  87. package/data/harnesses/code/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  88. package/data/harnesses/code/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  89. package/data/harnesses/code/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  90. package/data/harnesses/code/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  91. package/data/harnesses/code/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  92. package/data/harnesses/code/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  93. package/data/harnesses/code/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  94. package/data/harnesses/code/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  95. package/data/harnesses/code/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  96. package/data/harnesses/code/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  97. package/data/harnesses/code/skills/design/data/gradients/amber-attention-fill.md +16 -0
  98. package/data/harnesses/code/skills/design/data/gradients/cloud-shadow-wash.md +16 -0
  99. package/data/harnesses/code/skills/design/data/gradients/confident-lavender-wash.md +16 -0
  100. package/data/harnesses/code/skills/design/data/gradients/ember-ship-flare.md +18 -0
  101. package/data/harnesses/code/skills/design/data/gradients/full-metal-wash.md +16 -0
  102. package/data/harnesses/code/skills/design/data/gradients/indigo-ruby-cta-band.md +18 -0
  103. package/data/harnesses/code/skills/design/data/gradients/linear-graphite-wash.md +18 -0
  104. package/data/harnesses/code/skills/design/data/gradients/marble-quartz-wash.md +16 -0
  105. package/data/harnesses/code/skills/design/data/gradients/midnight-aurora-panel.md +16 -0
  106. package/data/harnesses/code/skills/design/data/gradients/neutral-volume-fill.md +16 -0
  107. package/data/harnesses/code/skills/design/data/gradients/revenue-uptrend-fill.md +16 -0
  108. package/data/harnesses/code/skills/design/data/gradients/risk-decline-fill.md +16 -0
  109. package/data/harnesses/code/skills/design/data/gradients/signal-blue-develop.md +18 -0
  110. package/data/harnesses/code/skills/design/data/gradients/slate-mist-wash.md +16 -0
  111. package/data/harnesses/code/skills/design/data/gradients/stripe-atmosphere-mesh.md +18 -0
  112. package/data/harnesses/code/skills/design/data/gradients/teal-signal-accent.md +16 -0
  113. package/data/harnesses/code/skills/design/data/gradients/violet-magenta-promo.md +16 -0
  114. package/data/harnesses/code/skills/design/data/iconography.md +199 -0
  115. package/data/harnesses/code/skills/design/data/motion/accordion-expand.md +18 -0
  116. package/data/harnesses/code/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  117. package/data/harnesses/code/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  118. package/data/harnesses/code/skills/design/data/motion/empty-state-arrive.md +18 -0
  119. package/data/harnesses/code/skills/design/data/motion/hover-lift.md +18 -0
  120. package/data/harnesses/code/skills/design/data/motion/modal-center-arrive.md +18 -0
  121. package/data/harnesses/code/skills/design/data/motion/number-ticker-roll.md +18 -0
  122. package/data/harnesses/code/skills/design/data/motion/onboarding-bounce.md +18 -0
  123. package/data/harnesses/code/skills/design/data/motion/panel-slide.md +18 -0
  124. package/data/harnesses/code/skills/design/data/motion/press-feedback.md +18 -0
  125. package/data/harnesses/code/skills/design/data/motion/progress-linear-loop.md +18 -0
  126. package/data/harnesses/code/skills/design/data/motion/route-crossfade.md +18 -0
  127. package/data/harnesses/code/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  128. package/data/harnesses/code/skills/design/data/motion/skeleton-shimmer.md +18 -0
  129. package/data/harnesses/code/skills/design/data/motion/stagger-arrive.md +18 -0
  130. package/data/harnesses/code/skills/design/data/motion/toast-enter-stack.md +18 -0
  131. package/data/harnesses/code/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  132. package/data/harnesses/code/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  133. package/data/harnesses/code/skills/design/data/tells.csv +34 -0
  134. package/data/harnesses/code/skills/design/data/typography/anton-work-sans.md +17 -0
  135. package/data/harnesses/code/skills/design/data/typography/archivo-black-archivo.md +17 -0
  136. package/data/harnesses/code/skills/design/data/typography/bitter-karla.md +17 -0
  137. package/data/harnesses/code/skills/design/data/typography/dm-serif-dm-sans.md +17 -0
  138. package/data/harnesses/code/skills/design/data/typography/fraunces-inter.md +17 -0
  139. package/data/harnesses/code/skills/design/data/typography/geist-geist-mono.md +17 -0
  140. package/data/harnesses/code/skills/design/data/typography/hubot-sans-mona-sans.md +17 -0
  141. package/data/harnesses/code/skills/design/data/typography/ibm-plex-sans-operator-single-family.md +17 -0
  142. package/data/harnesses/code/skills/design/data/typography/instrument-serif-instrument-sans.md +17 -0
  143. package/data/harnesses/code/skills/design/data/typography/inter-operator-single-family.md +17 -0
  144. package/data/harnesses/code/skills/design/data/typography/libre-baskerville-libre-franklin.md +17 -0
  145. package/data/harnesses/code/skills/design/data/typography/newsreader-inter.md +17 -0
  146. package/data/harnesses/code/skills/design/data/typography/playfair-display-source-sans.md +17 -0
  147. package/data/harnesses/code/skills/design/data/typography/public-sans-operator-single-family.md +17 -0
  148. package/data/harnesses/code/skills/design/data/typography/sohne-inter-fintech.md +17 -0
  149. package/data/harnesses/code/skills/design/data/typography/source-serif-source-sans.md +17 -0
  150. package/data/harnesses/code/skills/design/data/typography/space-grotesk-work-sans-space-mono.md +17 -0
  151. package/data/harnesses/code/skills/design/data/typography/spectral-manrope.md +17 -0
  152. package/data/harnesses/code/skills/design/data/voices/bright-collaborator.md +29 -0
  153. package/data/harnesses/code/skills/design/data/voices/direct-operator.md +29 -0
  154. package/data/harnesses/code/skills/design/data/voices/earnest-helper.md +29 -0
  155. package/data/harnesses/code/skills/design/data/voices/editorial-composed.md +29 -0
  156. package/data/harnesses/code/skills/design/data/voices/quiet-concierge.md +29 -0
  157. package/data/harnesses/code/skills/design/data/voices/warm-guide.md +29 -0
  158. package/data/harnesses/code/skills/design/design-md/SCHEMA.md +179 -0
  159. package/data/harnesses/code/skills/design/design-md/index.csv +67 -0
  160. package/data/harnesses/code/skills/design/design-md/library/airbnb.md +207 -0
  161. package/data/harnesses/code/skills/design/design-md/library/airtable.md +205 -0
  162. package/data/harnesses/code/skills/design/design-md/library/anthropic-claude.md +203 -0
  163. package/data/harnesses/code/skills/design/design-md/library/apple.md +206 -0
  164. package/data/harnesses/code/skills/design/design-md/library/binance.md +210 -0
  165. package/data/harnesses/code/skills/design/design-md/library/bmw.md +210 -0
  166. package/data/harnesses/code/skills/design/design-md/library/cal.md +209 -0
  167. package/data/harnesses/code/skills/design/design-md/library/clay.md +204 -0
  168. package/data/harnesses/code/skills/design/design-md/library/clickhouse.md +205 -0
  169. package/data/harnesses/code/skills/design/design-md/library/cohere.md +205 -0
  170. package/data/harnesses/code/skills/design/design-md/library/coinbase.md +198 -0
  171. package/data/harnesses/code/skills/design/design-md/library/composio.md +198 -0
  172. package/data/harnesses/code/skills/design/design-md/library/cursor.md +197 -0
  173. package/data/harnesses/code/skills/design/design-md/library/elevenlabs.md +199 -0
  174. package/data/harnesses/code/skills/design/design-md/library/expo.md +200 -0
  175. package/data/harnesses/code/skills/design/design-md/library/figma.md +199 -0
  176. package/data/harnesses/code/skills/design/design-md/library/framer.md +202 -0
  177. package/data/harnesses/code/skills/design/design-md/library/hashicorp.md +205 -0
  178. package/data/harnesses/code/skills/design/design-md/library/ibm.md +205 -0
  179. package/data/harnesses/code/skills/design/design-md/library/intercom.md +204 -0
  180. package/data/harnesses/code/skills/design/design-md/library/kraken.md +200 -0
  181. package/data/harnesses/code/skills/design/design-md/library/linear-app.md +198 -0
  182. package/data/harnesses/code/skills/design/design-md/library/lovable.md +199 -0
  183. package/data/harnesses/code/skills/design/design-md/library/meta.md +204 -0
  184. package/data/harnesses/code/skills/design/design-md/library/minimax.md +204 -0
  185. package/data/harnesses/code/skills/design/design-md/library/mintlify.md +210 -0
  186. package/data/harnesses/code/skills/design/design-md/library/miro.md +209 -0
  187. package/data/harnesses/code/skills/design/design-md/library/mistral-ai.md +201 -0
  188. package/data/harnesses/code/skills/design/design-md/library/mongodb.md +201 -0
  189. package/data/harnesses/code/skills/design/design-md/library/notion.md +204 -0
  190. package/data/harnesses/code/skills/design/design-md/library/nvidia.md +215 -0
  191. package/data/harnesses/code/skills/design/design-md/library/ollama.md +213 -0
  192. package/data/harnesses/code/skills/design/design-md/library/opencode-ai.md +216 -0
  193. package/data/harnesses/code/skills/design/design-md/library/posthog.md +218 -0
  194. package/data/harnesses/code/skills/design/design-md/library/raycast.md +214 -0
  195. package/data/harnesses/code/skills/design/design-md/library/replicate.md +202 -0
  196. package/data/harnesses/code/skills/design/design-md/library/resend.md +203 -0
  197. package/data/harnesses/code/skills/design/design-md/library/revolut.md +203 -0
  198. package/data/harnesses/code/skills/design/design-md/library/runwayml.md +203 -0
  199. package/data/harnesses/code/skills/design/design-md/library/sanity.md +200 -0
  200. package/data/harnesses/code/skills/design/design-md/library/sentry.md +201 -0
  201. package/data/harnesses/code/skills/design/design-md/library/shopify.md +202 -0
  202. package/data/harnesses/code/skills/design/design-md/library/slack.md +202 -0
  203. package/data/harnesses/code/skills/design/design-md/library/spacex.md +206 -0
  204. package/data/harnesses/code/skills/design/design-md/library/spotify.md +206 -0
  205. package/data/harnesses/code/skills/design/design-md/library/stripe.md +196 -0
  206. package/data/harnesses/code/skills/design/design-md/library/supabase.md +196 -0
  207. package/data/harnesses/code/skills/design/design-md/library/superhuman.md +194 -0
  208. package/data/harnesses/code/skills/design/design-md/library/tesla.md +198 -0
  209. package/data/harnesses/code/skills/design/design-md/library/theverge.md +199 -0
  210. package/data/harnesses/code/skills/design/design-md/library/together-ai.md +193 -0
  211. package/data/harnesses/code/skills/design/design-md/library/uber.md +195 -0
  212. package/data/harnesses/code/skills/design/design-md/library/vercel.md +195 -0
  213. package/data/harnesses/code/skills/design/design-md/library/voltagent.md +197 -0
  214. package/data/harnesses/code/skills/design/design-md/library/warp.md +196 -0
  215. package/data/harnesses/code/skills/design/design-md/library/webflow.md +197 -0
  216. package/data/harnesses/code/skills/design/design-md/library/wired.md +197 -0
  217. package/data/harnesses/code/skills/design/design-md/library/wise.md +198 -0
  218. package/data/harnesses/code/skills/design/design-md/library/x-ai.md +199 -0
  219. package/data/harnesses/code/skills/design/design-md/library/zapier.md +198 -0
  220. package/data/harnesses/code/skills/design/design-md/nurix.md +214 -0
  221. package/data/harnesses/code/skills/design/design-md/variants/editorial-luxury.md +184 -0
  222. package/data/harnesses/code/skills/design/design-md/variants/expressive-saas.md +216 -0
  223. package/data/harnesses/code/skills/design/design-md/variants/quiet-premium.md +211 -0
  224. package/data/harnesses/code/skills/design/design-md/variants/terse-dense-operator.md +212 -0
  225. package/data/harnesses/code/skills/design/design-md/variants/warm-approachable.md +216 -0
  226. package/data/harnesses/code/skills/design/references/compose.md +23 -0
  227. package/data/harnesses/code/skills/design/references/content.md +28 -0
  228. package/data/harnesses/code/skills/design/references/emission.md +21 -0
  229. package/data/harnesses/code/skills/design/references/existing-apps.md +27 -0
  230. package/data/harnesses/code/skills/design/references/intake.md +36 -0
  231. package/data/harnesses/code/skills/design/references/object-pass.md +24 -0
  232. package/data/harnesses/code/skills/design/references/ship-gate.md +29 -0
  233. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +195 -0
  234. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +49 -0
  235. package/data/harnesses/code/skills/design/references/ux-patterns/attributes-lifecycle.md +43 -0
  236. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +44 -0
  237. package/data/harnesses/code/skills/design/references/ux-patterns/creation-paths.md +46 -0
  238. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +42 -0
  239. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +42 -0
  240. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +46 -0
  241. package/data/harnesses/code/skills/design/references/ux-patterns/page-archetype.md +48 -0
  242. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +37 -0
  243. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +42 -0
  244. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +46 -0
  245. package/data/harnesses/code/skills/design/references/ux-patterns/state-matrix.md +41 -0
  246. package/data/harnesses/code/skills/design/references/ux-patterns/table-mechanics.md +48 -0
  247. package/data/harnesses/code/skills/design/references/ux-patterns/verbs.md +45 -0
  248. package/data/harnesses/code/skills/design/references/ux-patterns/viewer-context.md +40 -0
  249. package/data/harnesses/code/skills/design/scripts/README-validator.md +27 -0
  250. package/data/harnesses/code/skills/design/scripts/select-chart.mjs +596 -0
  251. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +1198 -0
  252. package/data/harnesses/discussion/CLAUDE.md +1 -1
  253. package/data/harnesses/discussion/agents/discussion-baseline.md +27 -2
  254. package/data/harnesses/discussion/harness.json +2 -2
  255. package/data/harnesses/discussion/rules/artifacts.md +2 -0
  256. package/data/harnesses/discussion/rules/method.md +5 -1
  257. package/package.json +1 -1
  258. package/data/harnesses/code/skills/design/data/catalog/rules.csv +0 -137
  259. package/data/harnesses/code/skills/design/data/combinations/Readme.md +0 -33
  260. package/data/harnesses/code/skills/design/data/combinations/accent-presets.md +0 -113
  261. package/data/harnesses/code/skills/design/data/combinations/charts.csv +0 -33
  262. package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +0 -448
  263. package/data/harnesses/code/skills/design/data/combinations/icons.csv +0 -157
  264. package/data/harnesses/code/skills/design/data/combinations/landing.csv +0 -38
  265. package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +0 -2001
  266. package/data/harnesses/code/skills/design/data/combinations/manifest.json +0 -330
  267. package/data/harnesses/code/skills/design/data/combinations/motion.csv +0 -10
  268. package/data/harnesses/code/skills/design/data/combinations/palettes.csv +0 -92
  269. package/data/harnesses/code/skills/design/data/combinations/product-router.csv +0 -80
  270. package/data/harnesses/code/skills/design/data/combinations/styles.csv +0 -67
  271. package/data/harnesses/code/skills/design/data/combinations/typography.csv +0 -64
  272. package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +0 -106
  273. package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +0 -154
  274. package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +0 -151
  275. package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +0 -139
  276. package/data/harnesses/code/skills/design/data/design-md/library/apple.md +0 -139
  277. package/data/harnesses/code/skills/design/data/design-md/library/binance.md +0 -140
  278. package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +0 -140
  279. package/data/harnesses/code/skills/design/data/design-md/library/cal.md +0 -140
  280. package/data/harnesses/code/skills/design/data/design-md/library/clay.md +0 -139
  281. package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +0 -139
  282. package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +0 -147
  283. package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +0 -156
  284. package/data/harnesses/code/skills/design/data/design-md/library/composio.md +0 -138
  285. package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +0 -138
  286. package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +0 -137
  287. package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -148
  288. package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -141
  289. package/data/harnesses/code/skills/design/data/design-md/library/framer.md +0 -156
  290. package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +0 -140
  291. package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +0 -153
  292. package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +0 -158
  293. package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +0 -156
  294. package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -122
  295. package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +0 -140
  296. package/data/harnesses/code/skills/design/data/design-md/library/meta.md +0 -139
  297. package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +0 -139
  298. package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +0 -139
  299. package/data/harnesses/code/skills/design/data/design-md/library/miro.md +0 -153
  300. package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +0 -140
  301. package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +0 -155
  302. package/data/harnesses/code/skills/design/data/design-md/library/notion.md +0 -140
  303. package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +0 -141
  304. package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +0 -145
  305. package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +0 -142
  306. package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +0 -152
  307. package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +0 -137
  308. package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +0 -140
  309. package/data/harnesses/code/skills/design/data/design-md/library/resend.md +0 -170
  310. package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +0 -145
  311. package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -137
  312. package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +0 -168
  313. package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +0 -163
  314. package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +0 -147
  315. package/data/harnesses/code/skills/design/data/design-md/library/slack.md +0 -158
  316. package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +0 -171
  317. package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +0 -166
  318. package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +0 -160
  319. package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +0 -173
  320. package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +0 -145
  321. package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +0 -153
  322. package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +0 -167
  323. package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +0 -140
  324. package/data/harnesses/code/skills/design/data/design-md/library/uber.md +0 -140
  325. package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +0 -140
  326. package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +0 -130
  327. package/data/harnesses/code/skills/design/data/design-md/library/warp.md +0 -140
  328. package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +0 -140
  329. package/data/harnesses/code/skills/design/data/design-md/library/wired.md +0 -139
  330. package/data/harnesses/code/skills/design/data/design-md/library/wise.md +0 -137
  331. package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +0 -138
  332. package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +0 -158
  333. package/data/harnesses/code/skills/design/data/design-md/nurix.md +0 -138
  334. package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +0 -695
  335. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +0 -20
  336. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +0 -1272
  337. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +0 -20
  338. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +0 -1268
  339. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +0 -20
  340. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +0 -1273
  341. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +0 -20
  342. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +0 -1262
  343. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +0 -20
  344. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +0 -1257
  345. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +0 -20
  346. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +0 -1270
  347. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +0 -20
  348. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +0 -1270
  349. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +0 -20
  350. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +0 -1261
  351. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +0 -20
  352. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +0 -1268
  353. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +0 -20
  354. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +0 -1281
  355. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +0 -20
  356. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +0 -1262
  357. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +0 -20
  358. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +0 -1271
  359. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +0 -20
  360. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +0 -1276
  361. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +0 -20
  362. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +0 -1293
  363. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +0 -20
  364. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +0 -1270
  365. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +0 -20
  366. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +0 -1276
  367. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +0 -20
  368. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +0 -1267
  369. package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +0 -251
  370. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +0 -20
  371. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +0 -1273
  372. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +0 -20
  373. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +0 -1286
  374. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +0 -20
  375. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +0 -1290
  376. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +0 -20
  377. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +0 -1270
  378. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +0 -23
  379. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +0 -599
  380. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +0 -1272
  381. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +0 -20
  382. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +0 -1267
  383. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +0 -20
  384. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +0 -1289
  385. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +0 -20
  386. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +0 -1258
  387. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +0 -20
  388. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +0 -1284
  389. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +0 -20
  390. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +0 -1291
  391. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +0 -20
  392. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +0 -1263
  393. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +0 -20
  394. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +0 -1270
  395. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +0 -20
  396. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +0 -1261
  397. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +0 -20
  398. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +0 -1209
  399. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +0 -20
  400. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +0 -1265
  401. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +0 -20
  402. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +0 -1253
  403. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +0 -20
  404. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +0 -1268
  405. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +0 -20
  406. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +0 -1261
  407. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +0 -20
  408. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +0 -1263
  409. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +0 -20
  410. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +0 -1266
  411. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +0 -23
  412. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +0 -623
  413. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +0 -1276
  414. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +0 -20
  415. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +0 -1264
  416. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +0 -20
  417. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +0 -1268
  418. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +0 -20
  419. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +0 -1270
  420. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +0 -20
  421. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +0 -1288
  422. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +0 -20
  423. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +0 -1272
  424. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +0 -20
  425. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +0 -1265
  426. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +0 -20
  427. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +0 -1287
  428. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +0 -20
  429. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +0 -1286
  430. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +0 -20
  431. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +0 -1285
  432. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +0 -20
  433. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +0 -1287
  434. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +0 -20
  435. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +0 -1278
  436. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +0 -20
  437. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +0 -1269
  438. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +0 -20
  439. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +0 -1285
  440. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +0 -20
  441. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +0 -1303
  442. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +0 -20
  443. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +0 -1274
  444. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +0 -20
  445. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +0 -1296
  446. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +0 -23
  447. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +0 -612
  448. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +0 -1282
  449. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +0 -20
  450. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +0 -1287
  451. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +0 -20
  452. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +0 -1268
  453. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +0 -20
  454. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +0 -1276
  455. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +0 -20
  456. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +0 -1273
  457. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +0 -20
  458. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +0 -1296
  459. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +0 -20
  460. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +0 -1286
  461. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +0 -249
  462. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +0 -249
  463. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +0 -225
  464. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +0 -249
  465. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +0 -224
  466. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +0 -249
  467. package/data/harnesses/code/skills/design/data/operator-pack/fixtures.md +0 -88
  468. package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +0 -132
  469. package/data/harnesses/code/skills/design/data/operator-pack/trust-rubric.md +0 -76
  470. package/data/harnesses/code/skills/design/references/create.md +0 -173
  471. package/data/harnesses/code/skills/design/references/diagnosis.md +0 -108
  472. package/data/harnesses/code/skills/design/references/hard-rules.md +0 -177
  473. package/data/harnesses/code/skills/design/references/improve.md +0 -116
  474. package/data/harnesses/code/skills/design/references/interaction.md +0 -77
  475. package/data/harnesses/code/skills/design/references/introspect.md +0 -100
  476. package/data/harnesses/code/skills/design/references/lifecycle.md +0 -73
  477. package/data/harnesses/code/skills/design/references/personality.md +0 -575
  478. package/data/harnesses/code/skills/design/references/structure.md +0 -159
  479. package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +0 -1312
  480. package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +0 -1498
  481. package/data/harnesses/code/skills/design/scripts/generate-fixtures.mjs +0 -551
  482. package/data/harnesses/code/skills/design/scripts/lib/checks.mjs +0 -1092
  483. package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +0 -26
  484. package/data/harnesses/code/skills/design/scripts/lib/vocabulary.mjs +0 -65
  485. package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +0 -538
  486. package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +0 -312
  487. package/data/harnesses/code/skills/design/scripts/render-rung.mjs +0 -890
  488. package/data/harnesses/code/skills/design/scripts/scaffold.mjs +0 -769
  489. package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +0 -675
  490. package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +0 -164
  491. package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +0 -439
@@ -1,551 +0,0 @@
1
- // skills/design/scripts/generate-fixtures.mjs — emits seeded, domain-shaped fixture modules and entity types from docs/design/structure.md
2
- import { mkdirSync, writeFileSync, readFileSync, existsSync } from "node:fs";
3
- import { dirname, join } from "node:path";
4
-
5
- const ARCHETYPES = ["list-detail", "dashboard", "entity-detail", "create-edit", "log-stream", "command-center"];
6
- const LIST_BEARING_ARCHETYPES = new Set(["list-detail", "log-stream", "command-center"]);
7
-
8
- // Print the refusal (problem + exact fix) to stderr and exit non-zero.
9
- function refuse(problem, fix) {
10
- process.stderr.write(`generate-fixtures.mjs: ${problem}\n`);
11
- process.stderr.write(`fix: ${fix}\n`);
12
- process.exit(1);
13
- }
14
-
15
- // Parse argv into positionals (_) and --flags (supporting --k v and --k=v).
16
- function parseArgs(argv) {
17
- const args = { _: [] };
18
- for (let i = 0; i < argv.length; i++) {
19
- const a = argv[i];
20
- if (a.startsWith("--")) {
21
- const eq = a.indexOf("=");
22
- if (eq !== -1) {
23
- args[a.slice(2, eq)] = a.slice(eq + 1);
24
- } else {
25
- const next = argv[i + 1];
26
- if (next !== undefined && !next.startsWith("--")) {
27
- args[a.slice(2)] = next;
28
- i++;
29
- } else {
30
- args[a.slice(2)] = true;
31
- }
32
- }
33
- } else {
34
- args._.push(a);
35
- }
36
- }
37
- return args;
38
- }
39
-
40
- // Strip a trailing/full-line YAML comment (structure-block values never contain '#').
41
- function stripComment(line) {
42
- const h = line.indexOf("#");
43
- if (h === -1) return line;
44
- if (h === 0 || /\s/.test(line[h - 1])) return line.slice(0, h).replace(/\s+$/, "");
45
- return line;
46
- }
47
-
48
- // Extract the body of the fenced ```yaml structure block by its info-string.
49
- function extractStructureBlock(text) {
50
- const m = text.match(/```yaml structure[^\n]*\n([\s\S]*?)\n```/);
51
- return m ? m[1] : null;
52
- }
53
-
54
- // Collapse the block into indent-tagged, comment-free, non-blank lines.
55
- function toLines(body) {
56
- const out = [];
57
- for (const raw of body.split(/\r?\n/)) {
58
- const noComment = stripComment(raw);
59
- if (noComment.trim() === "") continue;
60
- out.push({ indent: noComment.length - noComment.trimStart().length, text: noComment.trim() });
61
- }
62
- return out;
63
- }
64
-
65
- // Parse a scalar, inline flow sequence [a, b], or inline flow mapping {k: v}.
66
- function parseScalarOrFlow(s) {
67
- const t = s.trim();
68
- if (t.startsWith("[") && t.endsWith("]")) {
69
- const inner = t.slice(1, -1).trim();
70
- if (inner === "") return [];
71
- return inner.split(",").map((x) => parseScalarOrFlow(x));
72
- }
73
- if (t.startsWith("{") && t.endsWith("}")) {
74
- const inner = t.slice(1, -1).trim();
75
- const obj = {};
76
- if (inner === "") return obj;
77
- for (const pair of inner.split(",")) {
78
- const idx = pair.indexOf(":");
79
- if (idx === -1) continue;
80
- obj[pair.slice(0, idx).trim()] = parseScalarOrFlow(pair.slice(idx + 1));
81
- }
82
- return obj;
83
- }
84
- return t;
85
- }
86
-
87
- // Dispatch a contiguous line range [start,end) to a sequence or mapping parse.
88
- function parseBlock(lines, start, end) {
89
- if (start >= end) return null;
90
- const base = lines[start].indent;
91
- if (lines[start].text.startsWith("- ")) return parseSequence(lines, start, end, base);
92
- return parseMapping(lines, start, end, base);
93
- }
94
-
95
- // Parse a YAML sequence: each "- " item, with inline-first-pair mapping items merged with their children.
96
- function parseSequence(lines, start, end, base) {
97
- const items = [];
98
- let i = start;
99
- while (i < end && lines[i].indent === base && lines[i].text.startsWith("- ")) {
100
- const content = lines[i].text.slice(2).trim();
101
- let j = i + 1;
102
- while (j < end && lines[j].indent > base) j++;
103
- if (content.startsWith("{") || content.startsWith("[")) {
104
- items.push(parseScalarOrFlow(content));
105
- } else if (content.indexOf(":") !== -1) {
106
- const map = {};
107
- const c = content.indexOf(":");
108
- const key = content.slice(0, c).trim();
109
- const rest = content.slice(c + 1).trim();
110
- map[key] = rest !== "" ? parseScalarOrFlow(rest) : null;
111
- if (i + 1 < j) {
112
- const child = parseBlock(lines, i + 1, j);
113
- if (child && typeof child === "object" && !Array.isArray(child)) Object.assign(map, child);
114
- }
115
- items.push(map);
116
- } else {
117
- items.push(parseScalarOrFlow(content));
118
- }
119
- i = j;
120
- }
121
- return items;
122
- }
123
-
124
- // Parse a YAML mapping: key/value pairs at one indent, recursing into nested blocks.
125
- function parseMapping(lines, start, end, base) {
126
- const map = {};
127
- let i = start;
128
- while (i < end && lines[i].indent === base && !lines[i].text.startsWith("- ")) {
129
- const line = lines[i].text;
130
- const c = line.indexOf(":");
131
- if (c === -1) {
132
- i++;
133
- continue;
134
- }
135
- const key = line.slice(0, c).trim();
136
- const rest = line.slice(c + 1).trim();
137
- if (rest !== "") {
138
- map[key] = parseScalarOrFlow(rest);
139
- i++;
140
- } else {
141
- let j = i + 1;
142
- while (j < end && lines[j].indent > base) j++;
143
- map[key] = i + 1 < j ? parseBlock(lines, i + 1, j) : null;
144
- i = j;
145
- }
146
- }
147
- return map;
148
- }
149
-
150
- // Split a name into alphanumeric words on any separator.
151
- function words(s) {
152
- return String(s).trim().split(/[^A-Za-z0-9]+/).filter(Boolean);
153
- }
154
-
155
- // PascalCase a name (Support Ticket -> SupportTicket).
156
- function toPascal(s) {
157
- return words(s).map((w) => w[0].toUpperCase() + w.slice(1).toLowerCase()).join("");
158
- }
159
-
160
- // kebab-case a name (Ticket Queue -> ticket-queue).
161
- function toKebab(s) {
162
- return words(s).map((w) => w.toLowerCase()).join("-");
163
- }
164
-
165
- // camelCase a name, preserving already-camel single tokens (created_at -> createdAt, slaMinutes -> slaMinutes).
166
- function toCamel(s) {
167
- const str = String(s).trim();
168
- if (/^[A-Za-z0-9]+$/.test(str)) return str[0].toLowerCase() + str.slice(1);
169
- const w = words(str);
170
- if (!w.length) return "";
171
- return w[0].toLowerCase() + w.slice(1).map((x) => x[0].toUpperCase() + x.slice(1).toLowerCase()).join("");
172
- }
173
-
174
- // Naive English pluralization sufficient for entity nouns.
175
- function pluralize(word) {
176
- const w = String(word);
177
- if (/[^aeiou]y$/i.test(w)) return w.slice(0, -1) + "ies";
178
- if (/(s|x|z|ch|sh)$/i.test(w)) return w + "es";
179
- return w + "s";
180
- }
181
-
182
- // Capitalize the first character.
183
- function cap(s) {
184
- return s ? s[0].toUpperCase() + s.slice(1) : s;
185
- }
186
-
187
- // SNAKE_UPPER a camelCase identifier (supportTickets -> SUPPORT_TICKETS).
188
- function snakeUpper(s) {
189
- return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").toUpperCase();
190
- }
191
-
192
- // Canonical per-entity identifiers shared with scaffold.mjs (module paths and export names must agree).
193
- function entityNames(name) {
194
- const arrayVar = pluralize(toCamel(name));
195
- return {
196
- iface: toPascal(name),
197
- statusType: toPascal(name) + "Status",
198
- typeFile: toKebab(name),
199
- fixtureFile: pluralize(toKebab(name)),
200
- arrayVar,
201
- emptyVar: "empty" + cap(arrayVar),
202
- degradedVar: "degraded" + cap(arrayVar),
203
- seedConst: snakeUpper(arrayVar) + "_SEED",
204
- };
205
- }
206
-
207
- // Deterministic FNV-1a hash so a base seed derives a stable, distinct effective seed per entity.
208
- function hashString(s) {
209
- let h = 2166136261 >>> 0;
210
- for (let k = 0; k < s.length; k++) {
211
- h ^= s.charCodeAt(k);
212
- h = Math.imul(h, 16777619);
213
- }
214
- return h >>> 0;
215
- }
216
-
217
- // Read, parse, and validate docs/design/structure.md into a normalized model, refusing on malformed input.
218
- function loadStructure(path) {
219
- if (!existsSync(path)) refuse(`structure map not found at ${path}`, "pass the path to docs/design/structure.md as the first argument");
220
- const body = extractStructureBlock(readFileSync(path, "utf8"));
221
- if (body === null) {
222
- refuse(
223
- `no fenced \`\`\`yaml structure block in ${path}`,
224
- "docs/design/structure.md must carry a fenced ```yaml structure block (see references/structure.md); run the structure phase to produce it",
225
- );
226
- }
227
- const lines = toLines(body);
228
- const parsed = parseBlock(lines, 0, lines.length) || {};
229
- const entities = Array.isArray(parsed.entities) ? parsed.entities : [];
230
- if (entities.length === 0) {
231
- refuse(
232
- "the structure map declares no entities",
233
- "the object pass must populate entities[] before fixtures generate (structure.md); an empty pass fails the structure gate",
234
- );
235
- }
236
- const surfaces = (Array.isArray(parsed.surfaces) ? parsed.surfaces : []).map((s, idx) => {
237
- if (s && typeof s.archetype === "string" && !ARCHETYPES.includes(s.archetype.trim())) {
238
- refuse(
239
- `surface #${idx + 1} ("${s.name || "?"}") has archetype "${s.archetype}", not one of the closed six`,
240
- `set archetype to one of: ${ARCHETYPES.join(", ")} (surface-catalog.md; membership is closed)`,
241
- );
242
- }
243
- return { name: s && s.name, archetype: s && s.archetype && String(s.archetype).trim(), entity: s && s.entity && String(s.entity).trim() };
244
- });
245
- return {
246
- unitOfWork: typeof parsed["unit-of-work"] === "string" ? parsed["unit-of-work"].trim() : "",
247
- entities: entities.map((e) => ({
248
- name: String(e.name).trim(),
249
- attributes: Array.isArray(e.attributes) ? e.attributes.map((a) => String(a).trim()) : [],
250
- lifecycle: Array.isArray(e.lifecycle) ? e.lifecycle.map((l) => String(l).trim()) : [],
251
- relationships: Array.isArray(e.relationships) ? e.relationships : [],
252
- })),
253
- surfaces,
254
- };
255
- }
256
-
257
- // Classify one attribute into a TS type + a runtime generation category.
258
- function classify(prop, entity, hasLifecycle) {
259
- const p = prop.toLowerCase();
260
- const t = (tsType, nullable, category) => ({ prop, tsType, nullable, category });
261
- if (/(at|date)$/.test(p) || p.includes("date")) return t("string", false, "isoDate");
262
- if (hasLifecycle && (p === "status" || p === "state")) return t(entityNames(entity.name).statusType, false, "status");
263
- if (/^(is|has)[a-z0-9]/.test(prop) || p === "is" || p === "has") return t("boolean", false, "bool");
264
- if (/(count|amount|total|price|qty|quantity|replies|remaining|minutes|seconds|score|size|age|balance|rate|num|weight)$/.test(p) || /^(count|num)/.test(p)) {
265
- return t("number", false, "int");
266
- }
267
- if (p === "email" || /email$/.test(p)) return t("string", false, "email");
268
- if (/(assignee|owner|manager|contact)$/.test(p)) return t("string | null", true, "person");
269
- if (/(name|requester|customer|author|user|person|agent)$/.test(p)) return t("string", false, "person");
270
- if (/(company|org|account|vendor|team|tenant)$/.test(p)) return t("string | null", true, "company");
271
- if (/(priority|severity|level|channel|role|type|kind|category|availability|status|state)$/.test(p)) return t("string", false, "token");
272
- if (/(subject|title|summary|label|description|body|message|note|text|reason|comment)$/.test(p)) return t("string", false, "sentence");
273
- return t("string", false, "phrase");
274
- }
275
-
276
- // Build the ordered field plan for an entity: id, its attributes, and FK columns from many-to-one relationships.
277
- function fieldPlans(entity, entities) {
278
- const plans = [];
279
- const seen = new Set();
280
- const add = (plan) => {
281
- if (seen.has(plan.prop)) return;
282
- seen.add(plan.prop);
283
- plans.push(plan);
284
- };
285
- const hasLifecycle = entity.lifecycle.length > 0;
286
- add({ prop: "id", tsType: "string", nullable: false, category: "uuid" });
287
- for (const attr of entity.attributes) {
288
- const prop = toCamel(attr);
289
- if (prop === "id" || prop === "") continue;
290
- add(classify(prop, entity, hasLifecycle));
291
- }
292
- for (const rel of entity.relationships) {
293
- if (String(rel && rel.cardinality).trim() !== "many-to-one") continue;
294
- if (!rel.to || rel.to === entity.name) continue;
295
- const related = entities.find((e) => e.name === rel.to);
296
- if (!related) continue;
297
- const ren = entityNames(rel.to);
298
- add({ prop: toCamel(rel.to) + "Id", tsType: "string | null", nullable: true, category: "fk", related: ren });
299
- }
300
- return plans;
301
- }
302
-
303
- // The name of the token pool a short-enum field draws from.
304
- function tokenPool(prop) {
305
- const p = prop.toLowerCase();
306
- if (/priority/.test(p)) return "PRIORITIES";
307
- if (/channel/.test(p)) return "CHANNELS";
308
- if (/role/.test(p)) return "ROLES";
309
- if (/sever/.test(p)) return "SEVERITIES";
310
- if (/avail/.test(p)) return "AVAILABILITIES";
311
- return "GENERIC_TOKENS";
312
- }
313
-
314
- const POOL_DECLS = {
315
- FIRST_NAMES:
316
- 'const FIRST_NAMES = ["Amara", "Diego", "Priya", "Elias", "Naomi", "Tomas", "Leila", "Marcus", "Yuki", "Ravi", "Sofia", "Idris", "Hana", "Owen", "Chidi", "Wen"];',
317
- LAST_NAMES:
318
- 'const LAST_NAMES = ["Okafor", "Reyes", "Sharma", "Novak", "Bennett", "Costa", "Haddad", "Lindqvist", "Tanaka", "Mehta", "Rossi", "Abara", "Kim", "Fletcher", "Nwosu", "Zhao"];',
319
- COMPANIES:
320
- 'const COMPANIES = ["Northwind Trading", "Blue Harbor Labs", "Meridian Freight", "Cedar and Vale", "Halcyon Systems", "Ironwood Retail", "Sunstone Analytics", "Tidewater Health", "Brightfold Media", "Kestrel Logistics"];',
321
- EMAIL_DOMAINS: 'const EMAIL_DOMAINS = ["example.com", "mail.test", "corp.example", "inbox.test"];',
322
- SENTENCES:
323
- 'const SENTENCES = ["Payment retries failing after billing migration", "Export job stuck in queued state", "Login blocked for SSO users", "Webhook deliveries returning 500", "Dashboard widgets render stale totals", "Bulk import drops rows past 10k", "API rate limit hit during nightly sync", "Attachment preview times out on large files"];',
324
- PHRASES: 'const PHRASES = ["north region", "priority lane", "overflow shard", "batch window", "cold path", "edge tier"];',
325
- PRIORITIES: 'const PRIORITIES = ["low", "medium", "high", "urgent"];',
326
- CHANNELS: 'const CHANNELS = ["email", "chat", "phone", "web", "api"];',
327
- ROLES: 'const ROLES = ["agent", "admin", "viewer", "lead"];',
328
- SEVERITIES: 'const SEVERITIES = ["info", "warning", "error", "critical"];',
329
- AVAILABILITIES: 'const AVAILABILITIES = ["online", "away", "busy", "offline"];',
330
- GENERIC_TOKENS: 'const GENERIC_TOKENS = ["alpha", "beta", "gamma", "delta"];',
331
- };
332
-
333
- const LONG_TEXT_DECL =
334
- 'const LONG_TEXT =\n "Checkout returns 500 on multi-currency carts after the 3.4 billing migration when tax is estimated for split shipments across regions";';
335
-
336
- // The runtime helper source snippets emitted into each fixture module.
337
- const HELPERS = {
338
- mulberry32: `// mulberry32: a tiny deterministic PRNG so the same seed yields byte-identical rows.
339
- function mulberry32(seedValue: number): () => number {
340
- let a = seedValue >>> 0;
341
- return function next(): number {
342
- a = (a + 0x6d2b79f5) | 0;
343
- let t = Math.imul(a ^ (a >>> 15), 1 | a);
344
- t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
345
- return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
346
- };
347
- }`,
348
- randInt: `// A deterministic integer in [min, max] drawn from the seeded stream.
349
- function randInt(min: number, max: number): number {
350
- return min + Math.floor(rand() * (max - min + 1));
351
- }`,
352
- pick: `// A deterministic pick from a fixed pool.
353
- function pick<T>(items: readonly T[]): T {
354
- return items[Math.floor(rand() * items.length)];
355
- }`,
356
- uuid: `// A deterministic UUID-shaped id from the seeded stream.
357
- function uuid(): string {
358
- const hex = "0123456789abcdef";
359
- let s = "";
360
- for (let k = 0; k < 32; k++) s += hex[Math.floor(rand() * 16)];
361
- return s.slice(0, 8) + "-" + s.slice(8, 12) + "-4" + s.slice(13, 16) + "-" + "89ab"[Math.floor(rand() * 4)] + s.slice(17, 20) + "-" + s.slice(20, 32);
362
- }`,
363
- isoOffset: `// A deterministic ISO timestamp offset from a fixed reference instant (never Date.now()).
364
- function isoOffset(daysBack: number): string {
365
- return new Date(BASE_EPOCH - daysBack * 86400000).toISOString();
366
- }`,
367
- };
368
-
369
- // Produce the runtime value expression for a field, recording the pools/helpers/imports it needs.
370
- function fieldExpr(plan, use) {
371
- const p = plan.prop.toLowerCase();
372
- switch (plan.category) {
373
- case "uuid":
374
- use.helpers.add("uuid");
375
- return "uuid()";
376
- case "isoDate": {
377
- use.helpers.add("isoOffset");
378
- use.helpers.add("randInt");
379
- if (/updated|modified|last/.test(p)) return "isoOffset(randInt(0, 30))";
380
- if (/(due|expire|deadline|sla)/.test(p)) return "i % 7 === 0 ? isoOffset(-randInt(1, 21)) : isoOffset(randInt(0, 14))";
381
- return "isoOffset(randInt(1, 400))";
382
- }
383
- case "status":
384
- use.statuses = true;
385
- return "STATUSES[i % STATUSES.length]";
386
- case "bool":
387
- return "rand() > 0.5";
388
- case "int":
389
- use.helpers.add("randInt");
390
- return "i % 13 === 0 ? 0 : i % 7 === 0 ? -randInt(1, 50) : i % 101 === 0 ? 999999 : randInt(1, 480)";
391
- case "email":
392
- use.helpers.add("pick");
393
- use.pools.add("FIRST_NAMES");
394
- use.pools.add("LAST_NAMES");
395
- use.pools.add("EMAIL_DOMAINS");
396
- return 'pick(FIRST_NAMES).toLowerCase() + "." + pick(LAST_NAMES).toLowerCase() + "@" + pick(EMAIL_DOMAINS)';
397
- case "person": {
398
- use.helpers.add("pick");
399
- use.pools.add("FIRST_NAMES");
400
- use.pools.add("LAST_NAMES");
401
- const base = 'pick(FIRST_NAMES) + " " + pick(LAST_NAMES)';
402
- return plan.nullable ? `i % 9 === 0 ? null : ${base}` : base;
403
- }
404
- case "company":
405
- use.helpers.add("pick");
406
- use.pools.add("COMPANIES");
407
- return plan.nullable ? "i % 11 === 0 ? null : pick(COMPANIES)" : "pick(COMPANIES)";
408
- case "token": {
409
- use.helpers.add("pick");
410
- const pool = tokenPool(plan.prop);
411
- use.pools.add(pool);
412
- return `pick(${pool})`;
413
- }
414
- case "sentence":
415
- use.helpers.add("pick");
416
- use.pools.add("SENTENCES");
417
- use.longText = true;
418
- return "i % 5 === 0 ? LONG_TEXT : pick(SENTENCES)";
419
- case "phrase":
420
- use.helpers.add("pick");
421
- use.pools.add("PHRASES");
422
- return "pick(PHRASES)";
423
- case "fk":
424
- use.fkImports.set(plan.related.arrayVar, plan.related.fixtureFile);
425
- return `${plan.related.arrayVar}[i % ${plan.related.arrayVar}.length].id`;
426
- default:
427
- use.helpers.add("pick");
428
- use.pools.add("PHRASES");
429
- return "pick(PHRASES)";
430
- }
431
- }
432
-
433
- // Render one entity's type module: the lifecycle enum (when present) and the row interface.
434
- function typeModule(entity, entities) {
435
- const en = entityNames(entity.name);
436
- const plans = fieldPlans(entity, entities);
437
- let out = `// src/types/${en.typeFile}.ts — ${en.iface} entity type (generated from docs/design/structure.md; do not hand-edit).\n\n`;
438
- const usesStatus = plans.some((f) => f.category === "status");
439
- if (usesStatus) {
440
- out += `export type ${en.statusType} = ${entity.lifecycle.map((s) => `"${s}"`).join(" | ")};\n\n`;
441
- }
442
- out += `export interface ${en.iface} {\n`;
443
- for (const f of plans) out += ` ${f.prop}: ${f.tsType};\n`;
444
- out += `}\n`;
445
- return { rel: `src/types/${en.typeFile}.ts`, content: out };
446
- }
447
-
448
- // Render one entity's fixture module: seeded PRNG, pools, a row builder, and empty/degraded variants.
449
- function fixtureModule(entity, entities, baseSeed, listBearing) {
450
- const en = entityNames(entity.name);
451
- const plans = fieldPlans(entity, entities);
452
- const effectiveSeed = (baseSeed + hashString(entity.name)) >>> 0;
453
- const volume = listBearing ? 500 : 120;
454
- const use = { helpers: new Set(), pools: new Set(), fkImports: new Map(), statuses: false, longText: false };
455
-
456
- const fieldLines = plans.map((f) => ` ${f.prop}: ${fieldExpr(f, use)},`);
457
-
458
- const usesStatus = plans.some((f) => f.category === "status");
459
- const typeImports = [en.iface];
460
- if (usesStatus) typeImports.push(en.statusType);
461
-
462
- const fkImportLines = [...use.fkImports.entries()]
463
- .map(([arrayVar, file]) => `import { ${arrayVar} } from "./${file}";`)
464
- .join("\n");
465
-
466
- const helperOrder = ["mulberry32", "randInt", "pick", "uuid", "isoOffset"];
467
- const helperBlocks = [];
468
- helperBlocks.push(HELPERS.mulberry32);
469
- helperBlocks.push(`const rand = mulberry32(${en.seedConst});`);
470
- if (use.helpers.has("randInt")) helperBlocks.push(HELPERS.randInt);
471
- if (use.helpers.has("pick")) helperBlocks.push(HELPERS.pick);
472
- if (use.helpers.has("uuid")) helperBlocks.push(HELPERS.uuid);
473
- if (use.helpers.has("isoOffset")) {
474
- helperBlocks.push("const BASE_EPOCH = Date.UTC(2026, 0, 1);");
475
- helperBlocks.push(HELPERS.isoOffset);
476
- }
477
- void helperOrder;
478
-
479
- const poolBlocks = [];
480
- for (const name of Object.keys(POOL_DECLS)) if (use.pools.has(name)) poolBlocks.push(POOL_DECLS[name]);
481
- if (use.longText) poolBlocks.push(LONG_TEXT_DECL);
482
- if (use.statuses) poolBlocks.push(`const STATUSES: ${en.statusType}[] = [${entity.lifecycle.map((s) => `"${s}"`).join(", ")}];`);
483
-
484
- const degradedOverrides = plans
485
- .filter((f) => f.nullable)
486
- .map((f) => ` ${f.prop}: null,`);
487
- const firstInt = plans.find((f) => f.category === "int");
488
- if (firstInt) degradedOverrides.push(` ${firstInt.prop}: 0,`);
489
-
490
- const parts = [];
491
- parts.push(`// src/fixtures/${en.fixtureFile}.ts — seeded ${en.iface} fixtures (generated; do not hand-edit rows).`);
492
- const importGroup = [`import type { ${typeImports.join(", ")} } from "../types/${en.typeFile}";`];
493
- if (fkImportLines) importGroup.push(fkImportLines);
494
- parts.push(importGroup.join("\n"));
495
- parts.push(`export const ${en.seedConst} = ${effectiveSeed};`);
496
- parts.push(helperBlocks.join("\n\n"));
497
- if (poolBlocks.length) parts.push(poolBlocks.join("\n"));
498
- parts.push(
499
- `// One ${en.iface} row shaped like production data; unhappy values are seeded in by index.\n` +
500
- `function build${en.iface}(i: number): ${en.iface} {\n return {\n${fieldLines.join("\n")}\n };\n}`,
501
- );
502
- parts.push(
503
- `// ${volume} rows exercise ${listBearing ? "queue and table density" : "reference-join volume"}; lifecycle states are distributed across the set.\n` +
504
- `export const ${en.arrayVar}: ${en.iface}[] = Array.from({ length: ${volume} }, (_row, i) => build${en.iface}(i));`,
505
- );
506
- parts.push(`// The same surface, empty: a first-run or filtered-to-nothing result.\nexport const ${en.emptyVar}: ${en.iface}[] = [];`);
507
- parts.push(
508
- `// The same surface, degraded: enrichment failed and joins did not resolve.\n` +
509
- `export const ${en.degradedVar}: ${en.iface}[] = ${en.arrayVar}.slice(0, 12).map((row) => ({\n ...row,\n${degradedOverrides.join("\n")}\n}));`,
510
- );
511
- return { rel: `src/fixtures/${en.fixtureFile}.ts`, content: parts.join("\n\n") + "\n" };
512
- }
513
-
514
- // Write a file under the project root, creating parent directories.
515
- function emit(root, rel, content, written) {
516
- const abs = join(root, rel);
517
- mkdirSync(dirname(abs), { recursive: true });
518
- writeFileSync(abs, content, "utf8");
519
- written.push(rel);
520
- }
521
-
522
- // Entry point: load the map, emit type + fixture modules per entity, and report what was written.
523
- function main() {
524
- const args = parseArgs(process.argv.slice(2));
525
- const structurePath = args._[0];
526
- const out = typeof args.out === "string" ? args.out : null;
527
- const seedRaw = args.seed;
528
- if (!structurePath || !out || seedRaw === undefined || seedRaw === true) {
529
- refuse("missing arguments", "usage: generate-fixtures.mjs <docs/design/structure.md> --seed <n> --out <project-root-dir>");
530
- }
531
- const baseSeed = Number.parseInt(String(seedRaw), 10);
532
- if (Number.isNaN(baseSeed)) {
533
- refuse(`--seed "${seedRaw}" is not an integer`, "pass an integer base seed, e.g. --seed 4173");
534
- }
535
- const model = loadStructure(structurePath);
536
- const listBearingEntities = new Set();
537
- if (model.unitOfWork) listBearingEntities.add(model.unitOfWork);
538
- for (const s of model.surfaces) if (LIST_BEARING_ARCHETYPES.has(s.archetype)) listBearingEntities.add(s.entity);
539
-
540
- const written = [];
541
- for (const entity of model.entities) {
542
- const typeMod = typeModule(entity, model.entities);
543
- emit(out, typeMod.rel, typeMod.content, written);
544
- const fixtureMod = fixtureModule(entity, model.entities, baseSeed, listBearingEntities.has(entity.name));
545
- emit(out, fixtureMod.rel, fixtureMod.content, written);
546
- }
547
- process.stdout.write(`generate-fixtures.mjs: wrote ${written.length} files under ${out} (base seed ${baseSeed})\n`);
548
- for (const rel of written) process.stdout.write(` ${rel}\n`);
549
- }
550
-
551
- main();