@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.
- package/README.md +6 -4
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/agents/maintenance.md +1 -1
- package/data/harnesses/code/harness.json +1 -1
- package/data/harnesses/code/rules/frontend.md +5 -5
- package/data/harnesses/code/skills/design/SKILL.md +70 -50
- package/data/harnesses/code/skills/design/components/charts.md +76 -0
- package/data/harnesses/code/skills/design/components/collections.md +132 -0
- package/data/harnesses/code/skills/design/components/feedback.md +47 -0
- package/data/harnesses/code/skills/design/components/hooks.md +35 -0
- package/data/harnesses/code/skills/design/components/index.md +143 -0
- package/data/harnesses/code/skills/design/components/inputs.md +327 -0
- package/data/harnesses/code/skills/design/components/layout.md +52 -0
- package/data/harnesses/code/skills/design/components/media.md +66 -0
- package/data/harnesses/code/skills/design/components/motion.md +82 -0
- package/data/harnesses/code/skills/design/components/navigation.md +29 -0
- package/data/harnesses/code/skills/design/components/overlays.md +72 -0
- package/data/harnesses/code/skills/design/components/setup.md +40 -0
- package/data/harnesses/code/skills/design/components/typography.md +46 -0
- package/data/harnesses/code/skills/design/components/utils.md +37 -0
- package/data/harnesses/code/skills/design/data/blueprints/browse.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/creation-flow.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/dashboard.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/grid.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/queue.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/record-detail.md +38 -0
- package/data/harnesses/code/skills/design/data/blueprints/settings.md +38 -0
- package/data/harnesses/code/skills/design/data/chart-styling/Readme.md +33 -0
- package/data/harnesses/code/skills/design/data/chart-styling/carbon-accessible-alert-semantic.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/carbon-monochrome-sequential-trend.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/datadog-classic-six-aligned.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/datawrapper-tiered-gray-hierarchy.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/econ-red-rule-horizontal.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/financial-diverging-threshold-overlay.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/ft-vocabulary-ranked-muted.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/grafana-dark-threshold-bands.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/material-rounded-explicit-label.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/nyt-ghost-grid-direct-label.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/plot-currentcolor-inherit.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/saas-gradient-glow-area.md +19 -0
- package/data/harnesses/code/skills/design/data/chart-styling/shadcn-composable-css-vars.md +19 -0
- package/data/harnesses/code/skills/design/data/charts/census.csv +58 -0
- package/data/harnesses/code/skills/design/data/checklists/browse.md +21 -0
- package/data/harnesses/code/skills/design/data/checklists/creation-flow.md +20 -0
- package/data/harnesses/code/skills/design/data/checklists/dashboard.md +21 -0
- package/data/harnesses/code/skills/design/data/checklists/grid.md +21 -0
- package/data/harnesses/code/skills/design/data/checklists/queue.md +21 -0
- package/data/harnesses/code/skills/design/data/checklists/record-detail.md +21 -0
- package/data/harnesses/code/skills/design/data/checklists/settings.md +21 -0
- package/data/harnesses/code/skills/design/data/chrome/board-column.md +68 -0
- package/data/harnesses/code/skills/design/data/chrome/data-table.md +63 -0
- package/data/harnesses/code/skills/design/data/chrome/side-panel.md +60 -0
- package/data/harnesses/code/skills/design/data/chrome/sidebar.md +78 -0
- package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +62 -0
- package/data/harnesses/code/skills/design/data/chrome/topbar.md +65 -0
- package/data/harnesses/code/skills/design/data/color/accent-presets.md +90 -0
- package/data/harnesses/code/skills/design/data/color/aesop-earth-mute.md +91 -0
- package/data/harnesses/code/skills/design/data/color/arc-peach-play.md +90 -0
- package/data/harnesses/code/skills/design/data/color/attio-hunter-teal.md +90 -0
- package/data/harnesses/code/skills/design/data/color/carbon-cyan-signal.md +90 -0
- package/data/harnesses/code/skills/design/data/color/clay-parchment.md +90 -0
- package/data/harnesses/code/skills/design/data/color/duolingo-feather.md +90 -0
- package/data/harnesses/code/skills/design/data/color/geist-mono-signal.md +90 -0
- package/data/harnesses/code/skills/design/data/color/linear-graphite-violet.md +90 -0
- package/data/harnesses/code/skills/design/data/color/mercury-onyx-cobalt.md +90 -0
- package/data/harnesses/code/skills/design/data/color/notion-paper-ink.md +90 -0
- package/data/harnesses/code/skills/design/data/color/radix-slate-iris.md +90 -0
- package/data/harnesses/code/skills/design/data/color/raycast-void-spectrum.md +90 -0
- package/data/harnesses/code/skills/design/data/color/spectrum-celery-fuchsia.md +90 -0
- package/data/harnesses/code/skills/design/data/color/stripe-blurple-ruby.md +90 -0
- package/data/harnesses/code/skills/design/data/color/superhuman-cod-picton.md +89 -0
- package/data/harnesses/code/skills/design/data/corpora/operations-review/companies.csv +15 -0
- package/data/harnesses/code/skills/design/data/corpora/operations-review/corpus.md +87 -0
- package/data/harnesses/code/skills/design/data/corpora/operations-review/people.csv +25 -0
- package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/companies.csv +15 -0
- package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/corpus.md +83 -0
- package/data/harnesses/code/skills/design/data/corpora/procurement-approvals/people.csv +25 -0
- package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/companies.csv +15 -0
- package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/corpus.md +89 -0
- package/data/harnesses/code/skills/design/data/corpora/revenue-analytics/people.csv +25 -0
- package/data/harnesses/code/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
- package/data/harnesses/code/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
- package/data/harnesses/code/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
- package/data/harnesses/code/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
- package/data/harnesses/code/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
- package/data/harnesses/code/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
- package/data/harnesses/code/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
- package/data/harnesses/code/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
- package/data/harnesses/code/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
- package/data/harnesses/code/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
- package/data/harnesses/code/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
- package/data/harnesses/code/skills/design/data/gradients/amber-attention-fill.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/cloud-shadow-wash.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/confident-lavender-wash.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/ember-ship-flare.md +18 -0
- package/data/harnesses/code/skills/design/data/gradients/full-metal-wash.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/indigo-ruby-cta-band.md +18 -0
- package/data/harnesses/code/skills/design/data/gradients/linear-graphite-wash.md +18 -0
- package/data/harnesses/code/skills/design/data/gradients/marble-quartz-wash.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/midnight-aurora-panel.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/neutral-volume-fill.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/revenue-uptrend-fill.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/risk-decline-fill.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/signal-blue-develop.md +18 -0
- package/data/harnesses/code/skills/design/data/gradients/slate-mist-wash.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/stripe-atmosphere-mesh.md +18 -0
- package/data/harnesses/code/skills/design/data/gradients/teal-signal-accent.md +16 -0
- package/data/harnesses/code/skills/design/data/gradients/violet-magenta-promo.md +16 -0
- package/data/harnesses/code/skills/design/data/iconography.md +199 -0
- package/data/harnesses/code/skills/design/data/motion/accordion-expand.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/destructive-hold-confirm.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/empty-state-arrive.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/hover-lift.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/modal-center-arrive.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/number-ticker-roll.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/onboarding-bounce.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/panel-slide.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/press-feedback.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/progress-linear-loop.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/route-crossfade.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/rubber-band-overscroll.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/skeleton-shimmer.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/stagger-arrive.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/toast-enter-stack.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/tooltip-chain-instant.md +18 -0
- package/data/harnesses/code/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
- package/data/harnesses/code/skills/design/data/tells.csv +34 -0
- package/data/harnesses/code/skills/design/data/typography/anton-work-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/archivo-black-archivo.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/bitter-karla.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/dm-serif-dm-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/fraunces-inter.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/geist-geist-mono.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/hubot-sans-mona-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/ibm-plex-sans-operator-single-family.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/instrument-serif-instrument-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/inter-operator-single-family.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/libre-baskerville-libre-franklin.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/newsreader-inter.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/playfair-display-source-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/public-sans-operator-single-family.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/sohne-inter-fintech.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/source-serif-source-sans.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/space-grotesk-work-sans-space-mono.md +17 -0
- package/data/harnesses/code/skills/design/data/typography/spectral-manrope.md +17 -0
- package/data/harnesses/code/skills/design/data/voices/bright-collaborator.md +29 -0
- package/data/harnesses/code/skills/design/data/voices/direct-operator.md +29 -0
- package/data/harnesses/code/skills/design/data/voices/earnest-helper.md +29 -0
- package/data/harnesses/code/skills/design/data/voices/editorial-composed.md +29 -0
- package/data/harnesses/code/skills/design/data/voices/quiet-concierge.md +29 -0
- package/data/harnesses/code/skills/design/data/voices/warm-guide.md +29 -0
- package/data/harnesses/code/skills/design/design-md/SCHEMA.md +179 -0
- package/data/harnesses/code/skills/design/design-md/index.csv +67 -0
- package/data/harnesses/code/skills/design/design-md/library/airbnb.md +207 -0
- package/data/harnesses/code/skills/design/design-md/library/airtable.md +205 -0
- package/data/harnesses/code/skills/design/design-md/library/anthropic-claude.md +203 -0
- package/data/harnesses/code/skills/design/design-md/library/apple.md +206 -0
- package/data/harnesses/code/skills/design/design-md/library/binance.md +210 -0
- package/data/harnesses/code/skills/design/design-md/library/bmw.md +210 -0
- package/data/harnesses/code/skills/design/design-md/library/cal.md +209 -0
- package/data/harnesses/code/skills/design/design-md/library/clay.md +204 -0
- package/data/harnesses/code/skills/design/design-md/library/clickhouse.md +205 -0
- package/data/harnesses/code/skills/design/design-md/library/cohere.md +205 -0
- package/data/harnesses/code/skills/design/design-md/library/coinbase.md +198 -0
- package/data/harnesses/code/skills/design/design-md/library/composio.md +198 -0
- package/data/harnesses/code/skills/design/design-md/library/cursor.md +197 -0
- package/data/harnesses/code/skills/design/design-md/library/elevenlabs.md +199 -0
- package/data/harnesses/code/skills/design/design-md/library/expo.md +200 -0
- package/data/harnesses/code/skills/design/design-md/library/figma.md +199 -0
- package/data/harnesses/code/skills/design/design-md/library/framer.md +202 -0
- package/data/harnesses/code/skills/design/design-md/library/hashicorp.md +205 -0
- package/data/harnesses/code/skills/design/design-md/library/ibm.md +205 -0
- package/data/harnesses/code/skills/design/design-md/library/intercom.md +204 -0
- package/data/harnesses/code/skills/design/design-md/library/kraken.md +200 -0
- package/data/harnesses/code/skills/design/design-md/library/linear-app.md +198 -0
- package/data/harnesses/code/skills/design/design-md/library/lovable.md +199 -0
- package/data/harnesses/code/skills/design/design-md/library/meta.md +204 -0
- package/data/harnesses/code/skills/design/design-md/library/minimax.md +204 -0
- package/data/harnesses/code/skills/design/design-md/library/mintlify.md +210 -0
- package/data/harnesses/code/skills/design/design-md/library/miro.md +209 -0
- package/data/harnesses/code/skills/design/design-md/library/mistral-ai.md +201 -0
- package/data/harnesses/code/skills/design/design-md/library/mongodb.md +201 -0
- package/data/harnesses/code/skills/design/design-md/library/notion.md +204 -0
- package/data/harnesses/code/skills/design/design-md/library/nvidia.md +215 -0
- package/data/harnesses/code/skills/design/design-md/library/ollama.md +213 -0
- package/data/harnesses/code/skills/design/design-md/library/opencode-ai.md +216 -0
- package/data/harnesses/code/skills/design/design-md/library/posthog.md +218 -0
- package/data/harnesses/code/skills/design/design-md/library/raycast.md +214 -0
- package/data/harnesses/code/skills/design/design-md/library/replicate.md +202 -0
- package/data/harnesses/code/skills/design/design-md/library/resend.md +203 -0
- package/data/harnesses/code/skills/design/design-md/library/revolut.md +203 -0
- package/data/harnesses/code/skills/design/design-md/library/runwayml.md +203 -0
- package/data/harnesses/code/skills/design/design-md/library/sanity.md +200 -0
- package/data/harnesses/code/skills/design/design-md/library/sentry.md +201 -0
- package/data/harnesses/code/skills/design/design-md/library/shopify.md +202 -0
- package/data/harnesses/code/skills/design/design-md/library/slack.md +202 -0
- package/data/harnesses/code/skills/design/design-md/library/spacex.md +206 -0
- package/data/harnesses/code/skills/design/design-md/library/spotify.md +206 -0
- package/data/harnesses/code/skills/design/design-md/library/stripe.md +196 -0
- package/data/harnesses/code/skills/design/design-md/library/supabase.md +196 -0
- package/data/harnesses/code/skills/design/design-md/library/superhuman.md +194 -0
- package/data/harnesses/code/skills/design/design-md/library/tesla.md +198 -0
- package/data/harnesses/code/skills/design/design-md/library/theverge.md +199 -0
- package/data/harnesses/code/skills/design/design-md/library/together-ai.md +193 -0
- package/data/harnesses/code/skills/design/design-md/library/uber.md +195 -0
- package/data/harnesses/code/skills/design/design-md/library/vercel.md +195 -0
- package/data/harnesses/code/skills/design/design-md/library/voltagent.md +197 -0
- package/data/harnesses/code/skills/design/design-md/library/warp.md +196 -0
- package/data/harnesses/code/skills/design/design-md/library/webflow.md +197 -0
- package/data/harnesses/code/skills/design/design-md/library/wired.md +197 -0
- package/data/harnesses/code/skills/design/design-md/library/wise.md +198 -0
- package/data/harnesses/code/skills/design/design-md/library/x-ai.md +199 -0
- package/data/harnesses/code/skills/design/design-md/library/zapier.md +198 -0
- package/data/harnesses/code/skills/design/design-md/nurix.md +214 -0
- package/data/harnesses/code/skills/design/design-md/variants/editorial-luxury.md +184 -0
- package/data/harnesses/code/skills/design/design-md/variants/expressive-saas.md +216 -0
- package/data/harnesses/code/skills/design/design-md/variants/quiet-premium.md +211 -0
- package/data/harnesses/code/skills/design/design-md/variants/terse-dense-operator.md +212 -0
- package/data/harnesses/code/skills/design/design-md/variants/warm-approachable.md +216 -0
- package/data/harnesses/code/skills/design/references/compose.md +23 -0
- package/data/harnesses/code/skills/design/references/content.md +28 -0
- package/data/harnesses/code/skills/design/references/emission.md +21 -0
- package/data/harnesses/code/skills/design/references/existing-apps.md +27 -0
- package/data/harnesses/code/skills/design/references/intake.md +36 -0
- package/data/harnesses/code/skills/design/references/object-pass.md +24 -0
- package/data/harnesses/code/skills/design/references/ship-gate.md +29 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +195 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +49 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/attributes-lifecycle.md +43 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +44 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/creation-paths.md +46 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +42 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +42 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +46 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/page-archetype.md +48 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +37 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +42 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +46 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/state-matrix.md +41 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/table-mechanics.md +48 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/verbs.md +45 -0
- package/data/harnesses/code/skills/design/references/ux-patterns/viewer-context.md +40 -0
- package/data/harnesses/code/skills/design/scripts/README-validator.md +27 -0
- package/data/harnesses/code/skills/design/scripts/select-chart.mjs +596 -0
- package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +1198 -0
- package/data/harnesses/discussion/agents/discussion-baseline.md +1 -1
- package/data/harnesses/discussion/harness.json +1 -1
- package/data/harnesses/etna/agents/maintenance.md +1 -1
- package/data/harnesses/etna/harness.json +1 -1
- package/data/harnesses/hr/CLAUDE.md +1 -1
- package/data/harnesses/hr/harness.json +1 -1
- package/package.json +1 -1
- package/data/harnesses/code/skills/design/data/catalog/rules.csv +0 -137
- package/data/harnesses/code/skills/design/data/combinations/Readme.md +0 -33
- package/data/harnesses/code/skills/design/data/combinations/accent-presets.md +0 -113
- package/data/harnesses/code/skills/design/data/combinations/charts.csv +0 -33
- package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +0 -448
- package/data/harnesses/code/skills/design/data/combinations/icons.csv +0 -157
- package/data/harnesses/code/skills/design/data/combinations/landing.csv +0 -38
- package/data/harnesses/code/skills/design/data/combinations/lucide-names.json +0 -2001
- package/data/harnesses/code/skills/design/data/combinations/manifest.json +0 -330
- package/data/harnesses/code/skills/design/data/combinations/motion.csv +0 -10
- package/data/harnesses/code/skills/design/data/combinations/palettes.csv +0 -92
- package/data/harnesses/code/skills/design/data/combinations/product-router.csv +0 -80
- package/data/harnesses/code/skills/design/data/combinations/styles.csv +0 -67
- package/data/harnesses/code/skills/design/data/combinations/typography.csv +0 -64
- package/data/harnesses/code/skills/design/data/design-md/SCHEMA.md +0 -106
- package/data/harnesses/code/skills/design/data/design-md/library/airbnb.md +0 -154
- package/data/harnesses/code/skills/design/data/design-md/library/airtable.md +0 -151
- package/data/harnesses/code/skills/design/data/design-md/library/anthropic-claude.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/apple.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/binance.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/bmw.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/cal.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/clay.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/clickhouse.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/cohere.md +0 -147
- package/data/harnesses/code/skills/design/data/design-md/library/coinbase.md +0 -156
- package/data/harnesses/code/skills/design/data/design-md/library/composio.md +0 -138
- package/data/harnesses/code/skills/design/data/design-md/library/cursor.md +0 -138
- package/data/harnesses/code/skills/design/data/design-md/library/elevenlabs.md +0 -137
- package/data/harnesses/code/skills/design/data/design-md/library/expo.md +0 -148
- package/data/harnesses/code/skills/design/data/design-md/library/figma.md +0 -141
- package/data/harnesses/code/skills/design/data/design-md/library/framer.md +0 -156
- package/data/harnesses/code/skills/design/data/design-md/library/hashicorp.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/ibm.md +0 -153
- package/data/harnesses/code/skills/design/data/design-md/library/intercom.md +0 -158
- package/data/harnesses/code/skills/design/data/design-md/library/kraken.md +0 -156
- package/data/harnesses/code/skills/design/data/design-md/library/linear-app.md +0 -122
- package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/meta.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/mintlify.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/miro.md +0 -153
- package/data/harnesses/code/skills/design/data/design-md/library/mistral-ai.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/mongodb.md +0 -155
- package/data/harnesses/code/skills/design/data/design-md/library/notion.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/nvidia.md +0 -141
- package/data/harnesses/code/skills/design/data/design-md/library/ollama.md +0 -145
- package/data/harnesses/code/skills/design/data/design-md/library/opencode-ai.md +0 -142
- package/data/harnesses/code/skills/design/data/design-md/library/posthog.md +0 -152
- package/data/harnesses/code/skills/design/data/design-md/library/raycast.md +0 -137
- package/data/harnesses/code/skills/design/data/design-md/library/replicate.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/resend.md +0 -170
- package/data/harnesses/code/skills/design/data/design-md/library/revolut.md +0 -145
- package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +0 -137
- package/data/harnesses/code/skills/design/data/design-md/library/sanity.md +0 -168
- package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +0 -163
- package/data/harnesses/code/skills/design/data/design-md/library/shopify.md +0 -147
- package/data/harnesses/code/skills/design/data/design-md/library/slack.md +0 -158
- package/data/harnesses/code/skills/design/data/design-md/library/spacex.md +0 -171
- package/data/harnesses/code/skills/design/data/design-md/library/spotify.md +0 -166
- package/data/harnesses/code/skills/design/data/design-md/library/stripe.md +0 -160
- package/data/harnesses/code/skills/design/data/design-md/library/supabase.md +0 -173
- package/data/harnesses/code/skills/design/data/design-md/library/superhuman.md +0 -145
- package/data/harnesses/code/skills/design/data/design-md/library/tesla.md +0 -153
- package/data/harnesses/code/skills/design/data/design-md/library/theverge.md +0 -167
- package/data/harnesses/code/skills/design/data/design-md/library/together-ai.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/uber.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/vercel.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/voltagent.md +0 -130
- package/data/harnesses/code/skills/design/data/design-md/library/warp.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +0 -140
- package/data/harnesses/code/skills/design/data/design-md/library/wired.md +0 -139
- package/data/harnesses/code/skills/design/data/design-md/library/wise.md +0 -137
- package/data/harnesses/code/skills/design/data/design-md/library/x-ai.md +0 -138
- package/data/harnesses/code/skills/design/data/design-md/library/zapier.md +0 -158
- package/data/harnesses/code/skills/design/data/design-md/nurix.md +0 -138
- package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +0 -695
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +0 -1272
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +0 -1268
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +0 -1273
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +0 -1262
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +0 -1257
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +0 -1261
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +0 -1268
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +0 -1281
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +0 -1262
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +0 -1271
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +0 -1276
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +0 -1293
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +0 -1276
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +0 -1267
- package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +0 -251
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +0 -1273
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +0 -1286
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +0 -1290
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +0 -23
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +0 -599
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +0 -1272
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +0 -1267
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +0 -1289
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +0 -1258
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +0 -1284
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +0 -1291
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +0 -1263
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +0 -1261
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +0 -1209
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +0 -1265
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +0 -1253
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +0 -1268
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +0 -1261
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +0 -1263
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +0 -1266
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +0 -23
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +0 -623
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +0 -1276
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +0 -1264
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +0 -1268
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +0 -1270
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +0 -1288
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +0 -1272
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +0 -1265
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +0 -1287
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +0 -1286
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +0 -1285
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +0 -1287
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +0 -1278
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +0 -1269
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +0 -1285
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +0 -1303
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +0 -1274
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +0 -1296
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +0 -23
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +0 -612
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +0 -1282
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +0 -1287
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +0 -1268
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +0 -1276
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +0 -1273
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +0 -1296
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.resolver.json +0 -20
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +0 -1286
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +0 -249
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +0 -249
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +0 -225
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +0 -249
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +0 -224
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +0 -249
- package/data/harnesses/code/skills/design/data/operator-pack/fixtures.md +0 -88
- package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +0 -132
- package/data/harnesses/code/skills/design/data/operator-pack/trust-rubric.md +0 -76
- package/data/harnesses/code/skills/design/references/create.md +0 -173
- package/data/harnesses/code/skills/design/references/diagnosis.md +0 -108
- package/data/harnesses/code/skills/design/references/hard-rules.md +0 -177
- package/data/harnesses/code/skills/design/references/improve.md +0 -116
- package/data/harnesses/code/skills/design/references/interaction.md +0 -77
- package/data/harnesses/code/skills/design/references/introspect.md +0 -100
- package/data/harnesses/code/skills/design/references/lifecycle.md +0 -73
- package/data/harnesses/code/skills/design/references/personality.md +0 -575
- package/data/harnesses/code/skills/design/references/structure.md +0 -159
- package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +0 -1312
- package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +0 -1498
- package/data/harnesses/code/skills/design/scripts/generate-fixtures.mjs +0 -551
- package/data/harnesses/code/skills/design/scripts/lib/checks.mjs +0 -1092
- package/data/harnesses/code/skills/design/scripts/lib/golden.mjs +0 -26
- package/data/harnesses/code/skills/design/scripts/lib/vocabulary.mjs +0 -65
- package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +0 -538
- package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +0 -312
- package/data/harnesses/code/skills/design/scripts/render-rung.mjs +0 -890
- package/data/harnesses/code/skills/design/scripts/scaffold.mjs +0 -769
- package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +0 -675
- package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +0 -164
- 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();
|