@warpgogol/werkstatt-shared 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +352 -0
- package/src/checks/index.ts +24 -0
- package/src/checks/lib/astro-site-url.ts +30 -0
- package/src/checks/lib/i18n.ts +30 -0
- package/src/checks/result-helpers.ts +102 -0
- package/src/checks/suppressions-config.ts +195 -0
- package/src/index.ts +14 -0
- package/src/integration/README.md +38 -0
- package/src/integration/adapters.ts +143 -0
- package/src/integration/crm-buffer.ts +491 -0
- package/src/integration/dispatch.ts +106 -0
- package/src/integration/funnel.ts +379 -0
- package/src/integration/index.ts +56 -0
- package/src/integration/lifecycle.ts +155 -0
- package/src/integration/orchestration.ts +439 -0
- package/src/integration/port-barrel.ts +124 -0
- package/src/integration/port.ts +143 -0
- package/src/integration/qstash.ts +134 -0
- package/src/integration/sharding.ts +133 -0
- package/src/integration/tests/deliver-event.test.ts +52 -0
- package/src/integration/tests/dispatch.test.ts +88 -0
- package/src/integration/tests/funnel-bridge.test.ts +46 -0
- package/src/integration/tests/hub-runtime.test.ts +128 -0
- package/src/integration/tests/lifecycle.test.ts +69 -0
- package/src/integration/tests/qstash.test.ts +83 -0
- package/src/integration/tests/sharding.test.ts +64 -0
- package/src/integration/vitest.config.ts +8 -0
- package/src/integration-adapter-supabase-crm/adapter.ts +437 -0
- package/src/integration-adapter-supabase-crm/client.ts +605 -0
- package/src/integration-adapter-supabase-crm/index.ts +28 -0
- package/src/integration-adapter-supabase-crm/pipedrive-sync-target.ts +482 -0
- package/src/integration-adapter-supabase-crm/supabase-rest.ts +89 -0
- package/src/integration-adapter-supabase-crm/tenant-registry.ts +334 -0
- package/src/integration-adapter-supabase-crm/tests/change-balance.pbt.test.ts +83 -0
- package/src/integration-adapter-supabase-crm/tests/funnel-persistence.test.ts +409 -0
- package/src/integration-adapter-supabase-crm/tests/lifecycle-sync.test.ts +288 -0
- package/src/integration-adapter-supabase-crm/tests/stage-map.test.ts +80 -0
- package/src/integration-adapter-supabase-crm/vitest.config.ts +8 -0
- package/src/integration-adapter-supabase-crm/worker.ts +223 -0
- package/src/observability/conventions.ts +93 -0
- package/src/observability/env-resolver.ts +57 -0
- package/src/observability/index.ts +57 -0
- package/src/observability/metric-registry.ts +184 -0
- package/src/observability/otlp-converter.ts +125 -0
- package/src/observability/otlp-json.ts +135 -0
- package/src/observability/otlp-transport.ts +68 -0
- package/src/observability/pusher.ts +142 -0
- package/src/observability/redact.ts +27 -0
- package/src/observability/tests/conventions.test.ts +100 -0
- package/src/observability/tests/metric-registry.test.ts +117 -0
- package/src/observability/tests/otlp-converter.pbt.test.ts +77 -0
- package/src/observability/tests/otlp-converter.test.ts +157 -0
- package/src/observability/tests/otlp-json.test.ts +120 -0
- package/src/observability/tests/pusher.test.ts +75 -0
- package/src/observability/tests/redact.pbt.test.ts +71 -0
- package/src/observability/tests/redact.test.ts +37 -0
- package/src/observability/typed-refs.ts +137 -0
- package/src/observability/vitest.config.ts +8 -0
- package/src/ontology/analytics/matomo-binding.yaml +172 -0
- package/src/ontology/analytics/matomo-fleet.registry.yaml +26 -0
- package/src/ontology/analytics/messkanon.yaml +151 -0
- package/src/ontology/archetype-registry.ts +61 -0
- package/src/ontology/archetypes/components/brand-label.yaml +19 -0
- package/src/ontology/archetypes/components/copyright.yaml +19 -0
- package/src/ontology/archetypes/components/currency-aware-price-display.yaml +19 -0
- package/src/ontology/archetypes/components/currency-selector.yaml +19 -0
- package/src/ontology/archetypes/components/footer-promo.yaml +19 -0
- package/src/ontology/archetypes/components/lang-switcher.yaml +19 -0
- package/src/ontology/archetypes/components/layout.yaml +19 -0
- package/src/ontology/archetypes/components/live-photo.yaml +20 -0
- package/src/ontology/archetypes/components/material-credit.yaml +20 -0
- package/src/ontology/archetypes/components/media.yaml +21 -0
- package/src/ontology/archetypes/components/nachweis-card.yaml +34 -0
- package/src/ontology/archetypes/components/nachweis-detail.yaml +43 -0
- package/src/ontology/archetypes/components/nachweis-list.yaml +37 -0
- package/src/ontology/archetypes/components/nachweis-verify.yaml +31 -0
- package/src/ontology/archetypes/components/not-found.yaml +22 -0
- package/src/ontology/archetypes/components/offer-capacity.yaml +21 -0
- package/src/ontology/archetypes/components/passport-header.yaml +19 -0
- package/src/ontology/archetypes/components/passport-provenance.yaml +20 -0
- package/src/ontology/archetypes/components/passport-score-grid.yaml +20 -0
- package/src/ontology/archetypes/components/passport-star-map.yaml +20 -0
- package/src/ontology/archetypes/components/person-profile.yaml +20 -0
- package/src/ontology/archetypes/components/pulsar.yaml +20 -0
- package/src/ontology/archetypes/components/responsive-image.yaml +19 -0
- package/src/ontology/archetypes/components/scroll-to-top.yaml +22 -0
- package/src/ontology/archetypes/components/social-meta.yaml +20 -0
- package/src/ontology/archetypes/components/structured-data.yaml +19 -0
- package/src/ontology/archetypes/index.json +1003 -0
- package/src/ontology/archetypes/index.yaml +821 -0
- package/src/ontology/archetypes/sections/approach.yaml +23 -0
- package/src/ontology/archetypes/sections/article-list.yaml +30 -0
- package/src/ontology/archetypes/sections/audience-cards.yaml +30 -0
- package/src/ontology/archetypes/sections/breadcrumbs.yaml +21 -0
- package/src/ontology/archetypes/sections/chat-widget.yaml +37 -0
- package/src/ontology/archetypes/sections/comparison-cards.yaml +31 -0
- package/src/ontology/archetypes/sections/controlled-responsibility-block.yaml +34 -0
- package/src/ontology/archetypes/sections/credits.yaml +29 -0
- package/src/ontology/archetypes/sections/donation-card.yaml +53 -0
- package/src/ontology/archetypes/sections/donation-use.yaml +23 -0
- package/src/ontology/archetypes/sections/dynamic-status-block.yaml +35 -0
- package/src/ontology/archetypes/sections/faq-list.yaml +26 -0
- package/src/ontology/archetypes/sections/final-cta.yaml +53 -0
- package/src/ontology/archetypes/sections/hero-decision-card.yaml +65 -0
- package/src/ontology/archetypes/sections/hero.yaml +50 -0
- package/src/ontology/archetypes/sections/impact.yaml +23 -0
- package/src/ontology/archetypes/sections/markdown.yaml +43 -0
- package/src/ontology/archetypes/sections/mountain-journey.yaml +43 -0
- package/src/ontology/archetypes/sections/navigation.yaml +20 -0
- package/src/ontology/archetypes/sections/notausgang-block.yaml +41 -0
- package/src/ontology/archetypes/sections/open-source-registry.yaml +26 -0
- package/src/ontology/archetypes/sections/ownership-block.yaml +57 -0
- package/src/ontology/archetypes/sections/people.yaml +48 -0
- package/src/ontology/archetypes/sections/price-card.yaml +50 -0
- package/src/ontology/archetypes/sections/problem.yaml +23 -0
- package/src/ontology/archetypes/sections/send-message.yaml +63 -0
- package/src/ontology/archetypes/sections/service-metadata-block.yaml +40 -0
- package/src/ontology/archetypes/sections/social-proof.yaml +27 -0
- package/src/ontology/archetypes/sections/transparency.yaml +32 -0
- package/src/ontology/archetypes/sections/trust-strip.yaml +42 -0
- package/src/ontology/archetypes/sections/video-section.yaml +27 -0
- package/src/ontology/archetypes/sections/women.yaml +29 -0
- package/src/ontology/biome-token-projection.ts +229 -0
- package/src/ontology/biomes/check-concrete-blueprint.yaml +118 -0
- package/src/ontology/biomes/handwerk-material-warm.yaml +135 -0
- package/src/ontology/biomes/nonprofit-trust.yaml +123 -0
- package/src/ontology/blueprints/offer.yaml +39 -0
- package/src/ontology/blueprints/prompts/local-market-signal.md +13 -0
- package/src/ontology/blueprints/prompts/website-local-narrative.md +24 -0
- package/src/ontology/blueprints/ratgeber.yaml +62 -0
- package/src/ontology/blueprints/website-local.yaml +309 -0
- package/src/ontology/blueprints/website-service.yaml +84 -0
- package/src/ontology/capabilities/lead.submit.yaml +44 -0
- package/src/ontology/cosmic/index.ts +48 -0
- package/src/ontology/cosmic/moon-catalog.ts +173 -0
- package/src/ontology/cosmic/planet-catalog.ts +82 -0
- package/src/ontology/cosmic/star-catalog.ts +337 -0
- package/src/ontology/enums.ts +159 -0
- package/src/ontology/external-surfaces/index.ts +158 -0
- package/src/ontology/external-surfaces/jsonld-types.yaml +135 -0
- package/src/ontology/external-surfaces/sitemap-shape.yaml +6 -0
- package/src/ontology/external-surfaces/url-schema.yaml +95 -0
- package/src/ontology/growth/events/contact-email-click.yaml +21 -0
- package/src/ontology/growth/events/contact-form-submit.yaml +25 -0
- package/src/ontology/growth/events/contact-phone-click.yaml +21 -0
- package/src/ontology/growth/events/contact-route-click.yaml +21 -0
- package/src/ontology/growth/events/contact-submit.yaml +28 -0
- package/src/ontology/growth/events/contact-whatsapp-click.yaml +21 -0
- package/src/ontology/growth/events/cta-click.yaml +30 -0
- package/src/ontology/growth/events/donation-confirmed.yaml +32 -0
- package/src/ontology/growth/events/donation-form-start.yaml +21 -0
- package/src/ontology/growth/events/donation-form-submit.yaml +29 -0
- package/src/ontology/growth/events/donation-intent.yaml +29 -0
- package/src/ontology/growth/events/form-error.yaml +27 -0
- package/src/ontology/growth/events/form-start.yaml +21 -0
- package/src/ontology/growth/events/form-submit.yaml +21 -0
- package/src/ontology/growth/events/outbound-click.yaml +25 -0
- package/src/ontology/growth/events/page-view.yaml +24 -0
- package/src/ontology/growth/events/passport-view.yaml +28 -0
- package/src/ontology/growth/events/star-map-navigate.yaml +30 -0
- package/src/ontology/index.ts +165 -0
- package/src/ontology/manifest.ts +344 -0
- package/src/ontology/operations/index.ts +1 -0
- package/src/ontology/schemas/biome.ts +303 -0
- package/src/ontology/schemas/capability.ts +104 -0
- package/src/ontology/schemas/constellation.ts +114 -0
- package/src/ontology/schemas/dns-records.ts +53 -0
- package/src/ontology/schemas/index.ts +95 -0
- package/src/ontology/schemas/manifest-resolver.ts +123 -0
- package/src/ontology/schemas/page-entry.ts +213 -0
- package/src/ontology/schemas/section-archetype.ts +109 -0
- package/src/ontology/schemas/site-family.ts +98 -0
- package/src/ontology/schemas/system/growth.ts +80 -0
- package/src/ontology/schemas/system/integrations.ts +143 -0
- package/src/ontology/schemas/system/manifest.ts +492 -0
- package/src/ontology/schemas/system/page-output.ts +99 -0
- package/src/ontology/schemas/system/release.ts +58 -0
- package/src/ontology/schemas/system/text.ts +58 -0
- package/src/ontology/schemas/system.ts +53 -0
- package/src/ontology/shared-section-props/body-fragments.ts +182 -0
- package/src/ontology/shared-section-props/catalog.ts +195 -0
- package/src/ontology/shared-section-props/common.ts +178 -0
- package/src/ontology/shared-section-props/index.ts +34 -0
- package/src/ontology/shared-section-props/visual-header.ts +163 -0
- package/src/ontology/site-families/charity-donation-trust/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/charity-donation-trust/family.yaml +44 -0
- package/src/ontology/site-families/charity-donation-trust/linguistic-rules.yaml +6 -0
- package/src/ontology/site-families/check-quality-operator/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/check-quality-operator/family.yaml +40 -0
- package/src/ontology/site-families/check-quality-operator/linguistic-rules.yaml +6 -0
- package/src/ontology/site-families/handwerk-trust-engineering/cultural-rules.yaml +6 -0
- package/src/ontology/site-families/handwerk-trust-engineering/family.yaml +53 -0
- package/src/ontology/site-families/handwerk-trust-engineering/linguistic-rules.yaml +6 -0
- package/src/ontology/tests/catalogs.pbt.test.ts +89 -0
- package/src/ontology/tests/enums.test.ts +203 -0
- package/src/ontology/tests/sternsystem-owner.test.ts +63 -0
- package/src/ontology/vitest.config.ts +8 -0
- package/src/passport/dht-sign.test.ts +99 -0
- package/src/passport/dht-sign.ts +73 -0
- package/src/passport/identity-sign.test.ts +134 -0
- package/src/passport/identity-sign.ts +85 -0
- package/src/passport/index.ts +53 -0
- package/src/passport/key-rotate.ts +133 -0
- package/src/passport/schema.ts +198 -0
- package/src/passport/sign.ts +225 -0
- package/src/passport/tests/schema.pbt.test.ts +93 -0
- package/src/passport/tests/schema.test.ts +222 -0
- package/src/passport/vitest.config.ts +8 -0
- package/src/share/agent/api-catalog.ts +77 -0
- package/src/share/agent/capability.ts +68 -0
- package/src/share/agent/dns-aid.test.ts +74 -0
- package/src/share/agent/dns-aid.ts +53 -0
- package/src/share/agent/fleet-catalog.ts +149 -0
- package/src/share/agent/index.ts +29 -0
- package/src/share/agent/knowledge.ts +96 -0
- package/src/share/agent/manifest.ts +126 -0
- package/src/share/agent/mcp-card.ts +63 -0
- package/src/share/agent/omit-empty.ts +77 -0
- package/src/share/agent/openapi.ts +157 -0
- package/src/share/agent/proof.ts +61 -0
- package/src/share/attribution-display.ts +86 -0
- package/src/share/check-hints.ts +38 -0
- package/src/share/content/entity-id.ts +65 -0
- package/src/share/content/index.ts +16 -0
- package/src/share/content/merge.ts +86 -0
- package/src/share/content/resolve-field-path.ts +39 -0
- package/src/share/content/substitute-deep.ts +47 -0
- package/src/share/content-discipline/index.ts +14 -0
- package/src/share/content-discipline/parsers.ts +66 -0
- package/src/share/content-discipline/types.ts +118 -0
- package/src/share/content-reference.ts +333 -0
- package/src/share/counter-utils.ts +75 -0
- package/src/share/css-value-normalize.ts +48 -0
- package/src/share/dev-props-validator.ts +131 -0
- package/src/share/entitlement.ts +172 -0
- package/src/share/env.d.ts +73 -0
- package/src/share/feature-policy.ts +367 -0
- package/src/share/formula-eval.ts +364 -0
- package/src/share/fs/index.ts +96 -0
- package/src/share/i18n/localization.ts +57 -0
- package/src/share/image-provider.ts +314 -0
- package/src/share/index.ts +86 -0
- package/src/share/knowledge/claim.ts +129 -0
- package/src/share/knowledge/derivation.ts +55 -0
- package/src/share/knowledge/freshness.ts +127 -0
- package/src/share/knowledge/index.ts +23 -0
- package/src/share/knowledge/ledger.ts +222 -0
- package/src/share/knowledge/plan.ts +122 -0
- package/src/share/knowledge/source.ts +170 -0
- package/src/share/legal/translation-policy.ts +133 -0
- package/src/share/material-credits.ts +181 -0
- package/src/share/middleware/language-redirect.ts +49 -0
- package/src/share/offer-capacity.ts +149 -0
- package/src/share/onboarding-yaml/index.ts +162 -0
- package/src/share/page.ts +351 -0
- package/src/share/redirects.test.ts +62 -0
- package/src/share/redirects.ts +54 -0
- package/src/share/rfc0042-utils.ts +95 -0
- package/src/share/runtime-context.ts +70 -0
- package/src/share/schemas/claim-records.ts +69 -0
- package/src/share/schemas/claims.ts +150 -0
- package/src/share/schemas/effects.ts +212 -0
- package/src/share/schemas/features.ts +147 -0
- package/src/share/schemas/horizontal-align.ts +22 -0
- package/src/share/schemas/icon-color.ts +27 -0
- package/src/share/schemas/index.ts +43 -0
- package/src/share/schemas/live-photo.ts +53 -0
- package/src/share/schemas/material-credit.ts +292 -0
- package/src/share/schemas/media.ts +220 -0
- package/src/share/schemas/navigation.ts +74 -0
- package/src/share/schemas/page-base.ts +33 -0
- package/src/share/schemas/participant.ts +247 -0
- package/src/share/schemas/person.ts +24 -0
- package/src/share/schemas/print.ts +93 -0
- package/src/share/schemas/section-background.ts +106 -0
- package/src/share/schemas/section-body.ts +138 -0
- package/src/share/schemas/section-cards.ts +37 -0
- package/src/share/schemas/section-cta.ts +74 -0
- package/src/share/schemas/section-header.ts +77 -0
- package/src/share/schemas/section-image.ts +77 -0
- package/src/share/schemas/section-motion.ts +52 -0
- package/src/share/schemas/section-shell.ts +63 -0
- package/src/share/schemas/section-stats.ts +37 -0
- package/src/share/schemas/site-background.ts +78 -0
- package/src/share/schemas/standard-list-item.ts +38 -0
- package/src/share/scripts/external-links.ts +45 -0
- package/src/share/scripts/gsap-counter.ts +168 -0
- package/src/share/scripts/gsap-mountain-journey.ts +236 -0
- package/src/share/scripts/gsap-parallax.ts +50 -0
- package/src/share/scripts/gsap-reveal.ts +65 -0
- package/src/share/scripts/gsap-stagger.ts +54 -0
- package/src/share/scripts/index.ts +25 -0
- package/src/share/scripts/inline-number-animation.ts +120 -0
- package/src/share/scripts/lenis.ts +109 -0
- package/src/share/scripts/live-photos.ts +250 -0
- package/src/share/scripts/lordicon.ts +94 -0
- package/src/share/scripts/orchestrator.ts +138 -0
- package/src/share/scripts/scheduler.ts +53 -0
- package/src/share/scripts/video-player.ts +116 -0
- package/src/share/semantic/ai.ts +140 -0
- package/src/share/semantic/block-extraction.ts +52 -0
- package/src/share/semantic/block-extractors/index.ts +502 -0
- package/src/share/semantic/breadcrumbs.ts +120 -0
- package/src/share/semantic/build-page.ts +309 -0
- package/src/share/semantic/business-projection.ts +278 -0
- package/src/share/semantic/derived-prices-loader.ts +36 -0
- package/src/share/semantic/extract.ts +118 -0
- package/src/share/semantic/feed.ts +124 -0
- package/src/share/semantic/ids.ts +76 -0
- package/src/share/semantic/image-sitemap.ts +153 -0
- package/src/share/semantic/index.ts +36 -0
- package/src/share/semantic/jsonld/article.ts +47 -0
- package/src/share/semantic/jsonld/breadcrumb.ts +47 -0
- package/src/share/semantic/jsonld/collection-list.ts +30 -0
- package/src/share/semantic/jsonld/context.ts +46 -0
- package/src/share/semantic/jsonld/faq.ts +49 -0
- package/src/share/semantic/jsonld/initiative.ts +53 -0
- package/src/share/semantic/jsonld/organization.ts +101 -0
- package/src/share/semantic/jsonld/person.ts +71 -0
- package/src/share/semantic/jsonld/service.ts +80 -0
- package/src/share/semantic/jsonld/shared.ts +31 -0
- package/src/share/semantic/jsonld/types.ts +18 -0
- package/src/share/semantic/jsonld/webpage.ts +98 -0
- package/src/share/semantic/jsonld/website.ts +27 -0
- package/src/share/semantic/jsonld.ts +75 -0
- package/src/share/semantic/llms-policy.ts +74 -0
- package/src/share/semantic/llms.ts +394 -0
- package/src/share/semantic/markdown-hygiene.ts +68 -0
- package/src/share/semantic/markdown-twin-provenance.ts +242 -0
- package/src/share/semantic/models.ts +402 -0
- package/src/share/semantic/organization-profile.ts +160 -0
- package/src/share/semantic/output-projection.ts +131 -0
- package/src/share/semantic/page-builders/markdown-page.ts +84 -0
- package/src/share/semantic/page-markdown.ts +234 -0
- package/src/share/semantic/page-utils.ts +125 -0
- package/src/share/semantic/price-marker-resolver.ts +92 -0
- package/src/share/semantic/robots.ts +127 -0
- package/src/share/semantic/update-stamp.ts +136 -0
- package/src/share/shared-context.ts +177 -0
- package/src/share/string-utils.ts +19 -0
- package/src/share/tests/api-catalog.test.ts +97 -0
- package/src/share/tests/breadcrumbs.test.ts +126 -0
- package/src/share/tests/build-page-price-markers.test.ts +160 -0
- package/src/share/tests/capability.test.ts +107 -0
- package/src/share/tests/claim.test.ts +90 -0
- package/src/share/tests/content-ref-index.test.ts +328 -0
- package/src/share/tests/create-dev-props-validator.test.ts +38 -0
- package/src/share/tests/derivation.test.ts +39 -0
- package/src/share/tests/dev-props-validator.test.ts +88 -0
- package/src/share/tests/fleet-catalog.test.ts +134 -0
- package/src/share/tests/formula-eval.test.ts +619 -0
- package/src/share/tests/freshness.test.ts +60 -0
- package/src/share/tests/hero-section-numbering-parity.test.ts +51 -0
- package/src/share/tests/image-sitemap.test.ts +101 -0
- package/src/share/tests/jsonld-service.test.ts +282 -0
- package/src/share/tests/knowledge.test.ts +86 -0
- package/src/share/tests/ledger.test.ts +125 -0
- package/src/share/tests/llms-0789.test.ts +63 -0
- package/src/share/tests/manifest.test.ts +100 -0
- package/src/share/tests/markdown-twin-provenance.test.ts +108 -0
- package/src/share/tests/mcp-card.test.ts +57 -0
- package/src/share/tests/onboarding-yaml.test.ts +111 -0
- package/src/share/tests/ontology-role-by-cosmic-name.test.ts +28 -0
- package/src/share/tests/openapi.test.ts +116 -0
- package/src/share/tests/organization-jsonld.test.ts +74 -0
- package/src/share/tests/output-projection.test.ts +61 -0
- package/src/share/tests/plan.test.ts +97 -0
- package/src/share/tests/price-marker-resolver.test.ts +141 -0
- package/src/share/tests/proof.test.ts +72 -0
- package/src/share/tests/resolve-field-path.test.ts +52 -0
- package/src/share/tests/source.test.ts +81 -0
- package/src/share/tests/substitute-deep.test.ts +65 -0
- package/src/share/tests/text-normalize.pbt.test.ts +143 -0
- package/src/share/tests/text-normalize.test.ts +285 -0
- package/src/share/tests/twin-path.test.ts +43 -0
- package/src/share/text-normalize.ts +548 -0
- package/src/share/text-position.ts +19 -0
- package/src/share/types/hls-js-light.d.ts +16 -0
- package/src/share/visibility.ts +167 -0
- package/src/share/vitest.config.ts +8 -0
- package/src/share/wrap-inline-numbers.ts +139 -0
- package/src/surface/blueprint-schema.ts +314 -0
- package/src/surface/blueprint-types.ts +256 -0
- package/src/surface/blueprint.ts +300 -0
- package/src/surface/breaker.ts +57 -0
- package/src/surface/decision-composer.ts +156 -0
- package/src/surface/eligibility.ts +372 -0
- package/src/surface/evidence-records.ts +97 -0
- package/src/surface/fleet.ts +60 -0
- package/src/surface/geo.ts +170 -0
- package/src/surface/governance.ts +146 -0
- package/src/surface/index.ts +216 -0
- package/src/surface/io/index.ts +18 -0
- package/src/surface/io/surface-module-context-io.ts +60 -0
- package/src/surface/io/visibility-outcomes-io.ts +46 -0
- package/src/surface/module-context.ts +120 -0
- package/src/surface/substance.ts +161 -0
- package/src/surface/tests/eligibility.pbt.test.ts +137 -0
- package/src/surface/tests/eligibility.test.ts +302 -0
- package/src/surface/types.ts +289 -0
- package/src/surface/visibility.ts +57 -0
- package/src/surface/vitest.config.ts +8 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
Zod schema for manifest.yaml — the colocated per-component/section/page metadata
|
|
5
|
+
file that forms the fifth leg of the Mirror Quintet (DNA-17, RFC-0023).
|
|
6
|
+
Exports a discriminated union on `layer` so TypeScript narrows the `role` and
|
|
7
|
+
`cosmicName` fields to the correct closed enum automatically.
|
|
8
|
+
</purpose>
|
|
9
|
+
<non-goals>
|
|
10
|
+
<item>Do not parse YAML here — the caller (manifest.contract.validate command
|
|
11
|
+
and uni.registry.build) is responsible for reading the file and passing
|
|
12
|
+
the parsed object to manifestSchema.parse().</item>
|
|
13
|
+
<item>Do not hard-code file paths. The schema is path-agnostic.</item>
|
|
14
|
+
<item>Do not add business-shaped fields (company, services, etc.) — those
|
|
15
|
+
belong in @warpgogol/werkstatt-site/pbp schemas (RFC-0024, RFC-0471).</item>
|
|
16
|
+
</non-goals>
|
|
17
|
+
</MODULE_CONTRACT>
|
|
18
|
+
<CHANGE_SUMMARY>
|
|
19
|
+
<item>Initial creation as part of Wave 1 (RFC-0023 rollout).</item>
|
|
20
|
+
<item>Wave 1 (RFC-0025): Added required cosmicName per layer — StarName for pages,
|
|
21
|
+
PlanetName for sections, MoonName for components (DNA-23).</item>
|
|
22
|
+
</CHANGE_SUMMARY>
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { z } from "zod";
|
|
26
|
+
import { layerSchema, componentRoleSchema, industrySchema } from "./enums.ts";
|
|
27
|
+
import { starNameSchema } from "./cosmic/star-catalog.ts";
|
|
28
|
+
import { planetNameSchema } from "./cosmic/planet-catalog.ts";
|
|
29
|
+
import { moonNameSchema } from "./cosmic/moon-catalog.ts";
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Intent (open vocabulary)
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Well-known intent strings for manifest.yaml `intent[]` fields.
|
|
37
|
+
*
|
|
38
|
+
* Intent is an OPEN vocabulary (typed as string). This list is advisory:
|
|
39
|
+
* it documents the canonical phrases in active use and enables autocomplete,
|
|
40
|
+
* but it is NOT enforced as a closed enum (DNA-19). New intents may be added
|
|
41
|
+
* locally without an RFC.
|
|
42
|
+
*
|
|
43
|
+
* Intents describe *user goals* this component serves, not its technical role.
|
|
44
|
+
*/
|
|
45
|
+
export const KNOWN_INTENTS = [
|
|
46
|
+
// Conversion / acquisition
|
|
47
|
+
"convert-visitor",
|
|
48
|
+
"capture-lead",
|
|
49
|
+
"drive-contact",
|
|
50
|
+
"drive-booking",
|
|
51
|
+
"drive-donation",
|
|
52
|
+
// Trust / credibility
|
|
53
|
+
"build-trust",
|
|
54
|
+
"show-social-proof",
|
|
55
|
+
"demonstrate-expertise",
|
|
56
|
+
"signal-transparency",
|
|
57
|
+
// Identity / differentiation
|
|
58
|
+
"establish-identity",
|
|
59
|
+
"clarify-positioning",
|
|
60
|
+
"explain-approach",
|
|
61
|
+
"articulate-problem",
|
|
62
|
+
"highlight-impact",
|
|
63
|
+
// Navigation / discovery
|
|
64
|
+
"guide-navigation",
|
|
65
|
+
"orient-visitor",
|
|
66
|
+
"surface-content",
|
|
67
|
+
// Team / human connection
|
|
68
|
+
"introduce-team",
|
|
69
|
+
"humanise-brand",
|
|
70
|
+
// Legal / compliance
|
|
71
|
+
"fulfill-legal-requirement",
|
|
72
|
+
"display-compliance",
|
|
73
|
+
] as const;
|
|
74
|
+
|
|
75
|
+
export type KnownIntent = (typeof KNOWN_INTENTS)[number];
|
|
76
|
+
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Semver helper
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
const semverPattern = /^\d+\.\d+\.\d+(?:-[a-z0-9.-]+)?(?:\+[a-z0-9.-]+)?$/i;
|
|
82
|
+
const semverSchema = z
|
|
83
|
+
.string()
|
|
84
|
+
.regex(semverPattern, "version must be a valid semver string (e.g. 1.0.0)");
|
|
85
|
+
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Kebab-case helper
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
const kebabPattern = /^[a-z][a-z0-9-]*$/;
|
|
91
|
+
const kebabSchema = z
|
|
92
|
+
.string()
|
|
93
|
+
.regex(kebabPattern, "Must be kebab-case (lowercase letters, digits, hyphens)");
|
|
94
|
+
|
|
95
|
+
const archetypeIdSchema = z
|
|
96
|
+
.string()
|
|
97
|
+
.regex(
|
|
98
|
+
/^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*$/,
|
|
99
|
+
"archetype must be kebab-case segments separated by dots",
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Shared base schema
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Fields common to all three manifest layers (page | section | component).
|
|
108
|
+
* `layer` and `role` are declared per-layer to enable discriminated union narrowing.
|
|
109
|
+
*/
|
|
110
|
+
const manifestBaseSchema = z.object({
|
|
111
|
+
/**
|
|
112
|
+
* Unique stable identifier for this UI atom in the Uni registry.
|
|
113
|
+
* Format: <semantic-id>[-<variant>]-<layer-suffix>
|
|
114
|
+
* Examples: "hero-section", "footer-component", "home-page"
|
|
115
|
+
*/
|
|
116
|
+
id: kebabSchema,
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Display/marketing name for the Uni UI Ontology.
|
|
120
|
+
* At MVP this equals `semanticId` (RFC-0023 nonGoal). A future naming RFC
|
|
121
|
+
* may assign distinct values (e.g. "Beacon" for a hero section variant).
|
|
122
|
+
*/
|
|
123
|
+
uniName: z.string().min(1),
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The kebab-case semantic identifier matching the component's filename stem.
|
|
127
|
+
* Examples: "hero", "final-cta", "footer", "person-profile"
|
|
128
|
+
*/
|
|
129
|
+
semanticId: kebabSchema,
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* RFC-0072 stable archetype identifier used to bind manifests to the central
|
|
133
|
+
* archetype catalog in packages/werkstatt-site/src/domain/ontology/archetypes/sections/.
|
|
134
|
+
* Supports grouped ids such as "shell.header".
|
|
135
|
+
*/
|
|
136
|
+
archetype: archetypeIdSchema,
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* SemVer version string. Patch = backwards-compatible content change.
|
|
140
|
+
* Minor = new optional props. Major = breaking prop/schema change.
|
|
141
|
+
*/
|
|
142
|
+
version: semverSchema,
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Open-vocabulary list of user-goal phrases this component serves.
|
|
146
|
+
* Use values from KNOWN_INTENTS when possible; new values are allowed
|
|
147
|
+
* without an RFC (DNA-19).
|
|
148
|
+
*/
|
|
149
|
+
intent: z.array(z.string()).min(1, "At least one intent is required"),
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Industry verticals for which this component is a natural fit.
|
|
153
|
+
* Empty array = universally applicable.
|
|
154
|
+
* Uses the closed Industry enum (DNA-19).
|
|
155
|
+
*/
|
|
156
|
+
industryFit: z.array(industrySchema),
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Key of the Zod content schema this component consumes.
|
|
160
|
+
* Must match an export of @warpgogol/werkstatt-shared/share or the app-local content/schemas/.
|
|
161
|
+
* Set to null for structural components that consume no content schema
|
|
162
|
+
* (e.g. breadcrumbs, lang-switcher).
|
|
163
|
+
*/
|
|
164
|
+
contentSchemaKey: z.string().nullable(),
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* When true, this component can be placed outside the standard
|
|
168
|
+
* page → section → component hierarchy (DNA-8).
|
|
169
|
+
* Example: a standalone <CookieBanner> injected at the layout level.
|
|
170
|
+
* Default: false.
|
|
171
|
+
*/
|
|
172
|
+
standalone: z.boolean().optional().default(false),
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Per-layer manifest schemas (discriminated union)
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Manifest for a page (layer = "page").
|
|
181
|
+
* Pages may carry a descriptive role string but it is not validated
|
|
182
|
+
* against a closed enum — pages are too varied to enumerate centrally.
|
|
183
|
+
* cosmicName must be a value from the StarCatalog (DNA-23, RFC-0025).
|
|
184
|
+
*/
|
|
185
|
+
export const pageManifestSchema = manifestBaseSchema.extend({
|
|
186
|
+
layer: z.literal(layerSchema.enum.page),
|
|
187
|
+
/**
|
|
188
|
+
* Optional page-type descriptor. Free-form at MVP.
|
|
189
|
+
* Examples: "landing", "legal", "detail"
|
|
190
|
+
*/
|
|
191
|
+
role: z.string().optional(),
|
|
192
|
+
/**
|
|
193
|
+
* The IAU star name assigned to this page in the cosmic overlay (DNA-23).
|
|
194
|
+
* Must be a value from StarCatalog. Validated at deploy time by
|
|
195
|
+
* cosmic.catalog.validate (unique per workspace).
|
|
196
|
+
*/
|
|
197
|
+
cosmicName: starNameSchema,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Manifest for a section (layer = "section").
|
|
202
|
+
* Role is an open kebab-case string; cross-file validation against the
|
|
203
|
+
* archetype-derived sectionRoles[] set is performed by
|
|
204
|
+
* archetype.registry.validate (RFC-0084). The closed SemanticRoleValues
|
|
205
|
+
* enum was retired because the archetype catalog is the actual source of
|
|
206
|
+
* truth for permitted section semantic roles.
|
|
207
|
+
* cosmicName must be a value from the PlanetCatalog (DNA-23, RFC-0025).
|
|
208
|
+
*/
|
|
209
|
+
export const sectionManifestSchema = manifestBaseSchema.extend({
|
|
210
|
+
layer: z.literal(layerSchema.enum.section),
|
|
211
|
+
role: z.string().min(1),
|
|
212
|
+
/**
|
|
213
|
+
* The IAU moon/dwarf-planet name assigned to this section in the cosmic overlay (DNA-23).
|
|
214
|
+
* Must be a value from PlanetCatalog. Validated at deploy time by
|
|
215
|
+
* cosmic.catalog.validate (unique per workspace).
|
|
216
|
+
*/
|
|
217
|
+
cosmicName: planetNameSchema,
|
|
218
|
+
/**
|
|
219
|
+
* JSON Schema (draft-07 compatible) describing the props this section accepts.
|
|
220
|
+
* Used by buildPage / page.block.validate to validate block props at build time (RFC-0026).
|
|
221
|
+
* additionalProperties: false is enforced by page.block.validate — extra keys fail the build.
|
|
222
|
+
* Omitting this field disables strict prop validation for this section (MVP: not all
|
|
223
|
+
* sections have propsSchema yet; they will be added progressively in Wave 1 of RFC-0026).
|
|
224
|
+
*/
|
|
225
|
+
propsSchema: z.record(z.string(), z.unknown()).optional(),
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* RFC-0101 + RFC-0102 + RFC-0103: list of shared fragment ids whose JSON
|
|
229
|
+
* Schema properties are merged into `propsSchema` before validation runs.
|
|
230
|
+
* Eliminates the 60–100 lines of duplicated visual/header/body schema that
|
|
231
|
+
* every section manifest used to carry. Fragments are merged in declared
|
|
232
|
+
* order; the manifest's local `propsSchema` (when present) wins over any
|
|
233
|
+
* composed property. See packages/werkstatt-site/src/domain/ontology/src/shared-section-props/index.ts
|
|
234
|
+
* for the catalog. Unknown ids fail manifest.contract.validate.
|
|
235
|
+
*/
|
|
236
|
+
propsSchemaCompose: z
|
|
237
|
+
.array(
|
|
238
|
+
z
|
|
239
|
+
.string()
|
|
240
|
+
.regex(/^[a-z][a-z0-9-]*(@\d+)?$/, "must match `<id>` or `<id>@<version>` (RFC-0119)"),
|
|
241
|
+
)
|
|
242
|
+
.optional(),
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* RFC-0149: server API routes this section requires. When a site uses this
|
|
246
|
+
* section, `api.routes.generate` emits a thin GENERATED Astro APIRoute at
|
|
247
|
+
* `src/pages/api/<route>.ts` per entry (`export const prerender = false` +
|
|
248
|
+
* a re-export of the section handler), and projects the entry's `secrets`
|
|
249
|
+
* into the app's astro:env schema. Handler logic lives once in the section
|
|
250
|
+
* package; sites carry only the re-export. Omit the field for sections with
|
|
251
|
+
* no endpoint.
|
|
252
|
+
*/
|
|
253
|
+
api: z
|
|
254
|
+
.array(
|
|
255
|
+
z.object({
|
|
256
|
+
/** Route stem under src/pages/api/. Becomes /api/<route>. Kebab-case. */
|
|
257
|
+
route: kebabSchema,
|
|
258
|
+
/**
|
|
259
|
+
* Bare-import specifier of the module exporting the Astro APIRoute
|
|
260
|
+
* handlers, named for the HTTP method (`POST`, `GET`, …). The generated
|
|
261
|
+
* route re-exports the handlers named for `methods`.
|
|
262
|
+
*/
|
|
263
|
+
handler: z.string().min(1),
|
|
264
|
+
/**
|
|
265
|
+
* HTTP methods this endpoint serves. Each maps to an Astro APIRoute
|
|
266
|
+
* export named for the uppercased method (e.g. `POST`) that the
|
|
267
|
+
* generated route re-exports by name. Defaults to ["POST"] when omitted.
|
|
268
|
+
*/
|
|
269
|
+
methods: z
|
|
270
|
+
.array(z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]))
|
|
271
|
+
.nonempty()
|
|
272
|
+
.optional(),
|
|
273
|
+
/**
|
|
274
|
+
* Runtime secret env keys this endpoint reads via `astro:env/server`.
|
|
275
|
+
* `api.routes.generate` projects the union of all used sections' secrets
|
|
276
|
+
* into the app's generated astro:env schema (declared optional so a
|
|
277
|
+
* missing secret degrades to the handler's error path). Kebab/SCREAMING
|
|
278
|
+
* naming is the section's choice; keys must be valid env identifiers.
|
|
279
|
+
*/
|
|
280
|
+
secrets: z
|
|
281
|
+
.array(z.string().regex(/^[A-Z][A-Z0-9_]*$/, "must be a SCREAMING_SNAKE_CASE env key"))
|
|
282
|
+
.optional(),
|
|
283
|
+
}),
|
|
284
|
+
)
|
|
285
|
+
.optional(),
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Manifest for a component (layer = "component").
|
|
290
|
+
* Role is narrowed to the closed ComponentRole enum (DNA-19).
|
|
291
|
+
* cosmicName must be a value from the MoonCatalog (DNA-23, RFC-0025).
|
|
292
|
+
*/
|
|
293
|
+
export const componentManifestSchema = manifestBaseSchema.extend({
|
|
294
|
+
layer: z.literal(layerSchema.enum.component),
|
|
295
|
+
role: componentRoleSchema,
|
|
296
|
+
/**
|
|
297
|
+
* The IAU small-moon name assigned to this component in the cosmic overlay (DNA-23).
|
|
298
|
+
* Must be a value from MoonCatalog. Validated at deploy time by
|
|
299
|
+
* cosmic.catalog.validate (unique per workspace).
|
|
300
|
+
*
|
|
301
|
+
* Passport-reserved names (Methone, Bianca, Klarissa, Adrastea, Despina) are
|
|
302
|
+
* EXCLUSIVELY assigned to the five passport components in
|
|
303
|
+
* packages/werkstatt-site/src/domain/ui/components/{passport-header,passport-provenance,
|
|
304
|
+
* passport-score-grid,passport-star-map,pulsar} (RFC-0028, DNA-31).
|
|
305
|
+
* Do not use these five names for any other component manifest.
|
|
306
|
+
*/
|
|
307
|
+
cosmicName: moonNameSchema,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Discriminated union of all three layer-specific manifest schemas.
|
|
312
|
+
* This is the authoritative runtime validator for any parsed manifest.yaml.
|
|
313
|
+
*
|
|
314
|
+
* Usage:
|
|
315
|
+
* import { manifestSchema } from "@warpgogol/werkstatt-shared/ontology/manifest";
|
|
316
|
+
* const manifest = manifestSchema.parse(parsedYaml);
|
|
317
|
+
* // manifest.layer narrows to "page" | "section" | "component"
|
|
318
|
+
* // manifest.role narrows accordingly
|
|
319
|
+
*/
|
|
320
|
+
// @ai-invariant: manifestSchema is the authoritative runtime validator for every
|
|
321
|
+
// manifest.yaml in packages/ui. It is a discriminated union on `layer` — adding
|
|
322
|
+
// a new layer requires extending the union. cosmicName must be drawn from the
|
|
323
|
+
// layer-appropriate closed catalog (StarCatalog/PlanetCatalog/MoonCatalog, DNA-23).
|
|
324
|
+
// Role values are closed enums per layer — do not invent ad-hoc roles.
|
|
325
|
+
|
|
326
|
+
export const manifestSchema = z.discriminatedUnion("layer", [
|
|
327
|
+
pageManifestSchema,
|
|
328
|
+
sectionManifestSchema,
|
|
329
|
+
componentManifestSchema,
|
|
330
|
+
]);
|
|
331
|
+
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
// Exported TypeScript types
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
|
|
336
|
+
export type PageManifest = z.infer<typeof pageManifestSchema>;
|
|
337
|
+
export type SectionManifest = z.infer<typeof sectionManifestSchema>;
|
|
338
|
+
export type ComponentManifest = z.infer<typeof componentManifestSchema>;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Union of all three manifest variants.
|
|
342
|
+
* Use this when writing code that handles manifests of any layer.
|
|
343
|
+
*/
|
|
344
|
+
export type Manifest = z.infer<typeof manifestSchema>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@warpgogol/werkstatt/schemas";
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/*
|
|
2
|
+
<MODULE_CONTRACT>
|
|
3
|
+
<purpose>
|
|
4
|
+
Zod schema for Biome definition files (packages/werkstatt-site/src/domain/ontology/biomes/*.yaml).
|
|
5
|
+
A Biome is a full visual-DNA contract: family linkage, provenance, closed design
|
|
6
|
+
axes, palette, typography, spacing, motion, geometry, and authoring constraints.
|
|
7
|
+
Applied via html[data-biome="<id>"] in the cascade layer stack.
|
|
8
|
+
</purpose>
|
|
9
|
+
<non-goals>
|
|
10
|
+
<item>Do not parse YAML here; the caller is responsible for parsing.</item>
|
|
11
|
+
<item>Do not define CSS; the codegen command (biome-css.ts) produces CSS from
|
|
12
|
+
parsed Biome objects.</item>
|
|
13
|
+
<item>Do not reference business or app logic.</item>
|
|
14
|
+
</non-goals>
|
|
15
|
+
</MODULE_CONTRACT>
|
|
16
|
+
<CHANGE_SUMMARY>
|
|
17
|
+
<item>Wave 1 (RFC-0025): Initial creation.</item>
|
|
18
|
+
<item>RFC-0071: Replace narrow token overrides with the extended biome visual-DNA contract.</item>
|
|
19
|
+
<item>RFC-0371: Add optional <code>fonts</code> field for biome-driven Fontsource CSS imports.</item>
|
|
20
|
+
</CHANGE_SUMMARY>
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
25
|
+
const semver = z
|
|
26
|
+
.string()
|
|
27
|
+
.regex(/^\d+\.\d+\.\d+(?:-[a-z0-9.-]+)?$/i, "version must be valid semver");
|
|
28
|
+
const kebabId = z
|
|
29
|
+
.string()
|
|
30
|
+
.regex(/^[a-z][a-z0-9-]*$/, "id must be kebab-case (lowercase letters, digits, hyphens)");
|
|
31
|
+
const cssValue = z.string().min(1);
|
|
32
|
+
const sourceArtifact = z
|
|
33
|
+
.string()
|
|
34
|
+
.regex(/^\d{2}-[a-z0-9][a-z0-9.-]*(?:\.[a-z0-9]+)?(?:\.[a-z0-9]+)?$/i);
|
|
35
|
+
|
|
36
|
+
export const biomeProvenanceSchema = z
|
|
37
|
+
.object({
|
|
38
|
+
client: kebabId,
|
|
39
|
+
selectedConcept: z.string().regex(/^concept-\d+$/),
|
|
40
|
+
selectedDirection: z.number().int().positive(),
|
|
41
|
+
sourceFiles: z.array(sourceArtifact).min(1),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
|
|
45
|
+
export const biomeAxesSchema = z
|
|
46
|
+
.object({
|
|
47
|
+
warmth: z.enum(["cool", "neutral", "warm"]),
|
|
48
|
+
contrast: z.enum(["low", "medium", "high"]),
|
|
49
|
+
density: z.enum(["dense", "comfortable", "airy"]),
|
|
50
|
+
typographySharpness: z.enum(["soft", "balanced", "sharp"]),
|
|
51
|
+
diagramPresence: z.enum(["absent", "minimal", "supportive", "central"]),
|
|
52
|
+
photoStance: z.enum(["none", "founder-only", "documentary", "editorial"]),
|
|
53
|
+
motionStance: z.enum(["static", "restrained", "expressive"]),
|
|
54
|
+
textContrast: z.enum(["aa", "aaa"]),
|
|
55
|
+
cornerRadius: cssValue,
|
|
56
|
+
borderWeight: cssValue,
|
|
57
|
+
})
|
|
58
|
+
.strict();
|
|
59
|
+
|
|
60
|
+
export const biomePaletteSchema = z
|
|
61
|
+
.object({
|
|
62
|
+
brand: cssValue,
|
|
63
|
+
brandHover: cssValue,
|
|
64
|
+
brandContrast: cssValue,
|
|
65
|
+
accent: cssValue,
|
|
66
|
+
surface: cssValue,
|
|
67
|
+
surfaceMuted: cssValue,
|
|
68
|
+
ink: cssValue,
|
|
69
|
+
inkSoft: cssValue,
|
|
70
|
+
inkMuted: cssValue,
|
|
71
|
+
divider: cssValue,
|
|
72
|
+
success: cssValue,
|
|
73
|
+
warning: cssValue,
|
|
74
|
+
danger: cssValue,
|
|
75
|
+
info: cssValue,
|
|
76
|
+
})
|
|
77
|
+
.strict();
|
|
78
|
+
|
|
79
|
+
export const biomeComponentsSchema = z
|
|
80
|
+
.object({
|
|
81
|
+
heroOverlay: cssValue.optional(),
|
|
82
|
+
heroText: cssValue.optional(),
|
|
83
|
+
surfaceGlass: cssValue.optional(),
|
|
84
|
+
sectionAltBase: cssValue.optional(),
|
|
85
|
+
sectionAltText: cssValue.optional(),
|
|
86
|
+
sectionAltTextSoft: cssValue.optional(),
|
|
87
|
+
sectionAltLink: cssValue.optional(),
|
|
88
|
+
sectionAltLinkVisited: cssValue.optional(),
|
|
89
|
+
sectionAltLinkHover: cssValue.optional(),
|
|
90
|
+
sectionAltAccent: cssValue.optional(),
|
|
91
|
+
statsBg: cssValue.optional(),
|
|
92
|
+
footerBg: cssValue.optional(),
|
|
93
|
+
footerText: cssValue.optional(),
|
|
94
|
+
footerTextMuted: cssValue.optional(),
|
|
95
|
+
cardBg: cssValue.optional(),
|
|
96
|
+
cardBorder: cssValue.optional(),
|
|
97
|
+
cta: cssValue.optional(),
|
|
98
|
+
ctaHover: cssValue.optional(),
|
|
99
|
+
ctaText: cssValue.optional(),
|
|
100
|
+
surfaceAlt: cssValue.optional(),
|
|
101
|
+
textSoftOnDark: cssValue.optional(),
|
|
102
|
+
textInverse84: cssValue.optional(),
|
|
103
|
+
})
|
|
104
|
+
.strict()
|
|
105
|
+
.optional();
|
|
106
|
+
|
|
107
|
+
export const biomeTypographySchema = z
|
|
108
|
+
.object({
|
|
109
|
+
headingFamily: cssValue,
|
|
110
|
+
bodyFamily: cssValue,
|
|
111
|
+
monoFamily: cssValue,
|
|
112
|
+
scaleRatio: z.number().positive(),
|
|
113
|
+
baseSize: cssValue,
|
|
114
|
+
lineHeightBody: z.number().positive(),
|
|
115
|
+
lineHeightHeading: z.number().positive(),
|
|
116
|
+
measureBody: cssValue,
|
|
117
|
+
measureHeading: cssValue,
|
|
118
|
+
numericFeatures: cssValue,
|
|
119
|
+
})
|
|
120
|
+
.strict();
|
|
121
|
+
|
|
122
|
+
export const biomeSpacingSchema = z
|
|
123
|
+
.object({
|
|
124
|
+
base: cssValue,
|
|
125
|
+
sectionPaddingY: cssValue,
|
|
126
|
+
containerMaxWidth: cssValue,
|
|
127
|
+
containerNarrow: cssValue.optional(),
|
|
128
|
+
gutter: cssValue,
|
|
129
|
+
})
|
|
130
|
+
.strict();
|
|
131
|
+
|
|
132
|
+
export const biomeMotionSchema = z
|
|
133
|
+
.object({
|
|
134
|
+
durationFast: cssValue,
|
|
135
|
+
durationMedium: cssValue,
|
|
136
|
+
durationSlow: cssValue,
|
|
137
|
+
easing: cssValue,
|
|
138
|
+
reduceMotionRespect: z.boolean(),
|
|
139
|
+
})
|
|
140
|
+
.strict();
|
|
141
|
+
|
|
142
|
+
export const biomeGeometrySchema = z
|
|
143
|
+
.object({
|
|
144
|
+
diagramLineWeight: cssValue.optional(),
|
|
145
|
+
diagramAccentColor: cssValue.optional(),
|
|
146
|
+
decorativeAllowed: z.boolean(),
|
|
147
|
+
})
|
|
148
|
+
.strict();
|
|
149
|
+
|
|
150
|
+
// RFC-0098: shadows are visual-DNA — a "soft warm material" biome reads
|
|
151
|
+
// different elevation cues than a "trustworthy nonprofit" biome. Keys map
|
|
152
|
+
// 1:1 to the historical --ds-shadow-* studio defaults; biome wins when set.
|
|
153
|
+
export const biomeShadowsSchema = z
|
|
154
|
+
.object({
|
|
155
|
+
sm: cssValue.optional(),
|
|
156
|
+
md: cssValue.optional(),
|
|
157
|
+
lg: cssValue.optional(),
|
|
158
|
+
xl: cssValue.optional(),
|
|
159
|
+
glass: cssValue.optional(),
|
|
160
|
+
glow: cssValue.optional(),
|
|
161
|
+
header: cssValue.optional(),
|
|
162
|
+
appeal: cssValue.optional(),
|
|
163
|
+
})
|
|
164
|
+
.strict()
|
|
165
|
+
.optional();
|
|
166
|
+
|
|
167
|
+
// RFC-0098: gradients carry brand DNA (the previous studio defaults baked
|
|
168
|
+
// nicaragua-projekt brand RGB into --ds-gradient-primary / accent which is
|
|
169
|
+
// app-specific). Biome-scoped gradients keep the brand color where the brand
|
|
170
|
+
// is declared.
|
|
171
|
+
export const biomeGradientsSchema = z
|
|
172
|
+
.object({
|
|
173
|
+
accent: cssValue.optional(),
|
|
174
|
+
primary: cssValue.optional(),
|
|
175
|
+
vignetteDark: cssValue.optional(),
|
|
176
|
+
})
|
|
177
|
+
.strict()
|
|
178
|
+
.optional();
|
|
179
|
+
|
|
180
|
+
export const biomeConstraintsSchema = z
|
|
181
|
+
.object({
|
|
182
|
+
forbidStockPhotoTags: z.array(z.string().min(1)).default([]),
|
|
183
|
+
forbidPhrases: z.array(z.string().min(1)).default([]),
|
|
184
|
+
enforceTabularNumeralsIn: z.array(z.string().min(1)).default([]),
|
|
185
|
+
})
|
|
186
|
+
.strict();
|
|
187
|
+
|
|
188
|
+
// RFC-0114: site-background layer schema mirrored from
|
|
189
|
+
// @warpgogol/werkstatt-shared/share/schemas/site-background. Defined locally to avoid a
|
|
190
|
+
// cross-package import dependency (ontology must not depend on share).
|
|
191
|
+
const biomeSiteBackgroundLayerSchema = z.discriminatedUnion("kind", [
|
|
192
|
+
z
|
|
193
|
+
.object({
|
|
194
|
+
kind: z.literal("color"),
|
|
195
|
+
color: cssValue.optional(),
|
|
196
|
+
})
|
|
197
|
+
.strict(),
|
|
198
|
+
z
|
|
199
|
+
.object({
|
|
200
|
+
kind: z.literal("image"),
|
|
201
|
+
imageName: z.string().min(1),
|
|
202
|
+
fit: z.enum(["cover", "tile", "stretch-width", "stretch-height"]).optional(),
|
|
203
|
+
quality: z.enum(["low", "mid", "high", "max"]).optional(),
|
|
204
|
+
loading: z.enum(["eager", "lazy"]).optional(),
|
|
205
|
+
tint: z
|
|
206
|
+
.object({
|
|
207
|
+
color: cssValue.optional(),
|
|
208
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
209
|
+
})
|
|
210
|
+
.strict()
|
|
211
|
+
.optional(),
|
|
212
|
+
parallax: z
|
|
213
|
+
.object({
|
|
214
|
+
speed: z.number().min(0).max(2).optional(),
|
|
215
|
+
respectReducedMotion: z.boolean().optional(),
|
|
216
|
+
})
|
|
217
|
+
.strict()
|
|
218
|
+
.optional(),
|
|
219
|
+
})
|
|
220
|
+
.strict(),
|
|
221
|
+
z
|
|
222
|
+
.object({
|
|
223
|
+
kind: z.literal("gradient"),
|
|
224
|
+
direction: z.enum(["vertical", "horizontal", "radial"]),
|
|
225
|
+
stops: z
|
|
226
|
+
.array(
|
|
227
|
+
z
|
|
228
|
+
.object({
|
|
229
|
+
at: z.number().min(0).max(1),
|
|
230
|
+
color: cssValue,
|
|
231
|
+
opacity: z.number().min(0).max(1).optional(),
|
|
232
|
+
})
|
|
233
|
+
.strict(),
|
|
234
|
+
)
|
|
235
|
+
.min(2),
|
|
236
|
+
})
|
|
237
|
+
.strict(),
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
export const biomeSiteBackgroundSchema = z
|
|
241
|
+
.object({
|
|
242
|
+
layers: z.array(biomeSiteBackgroundLayerSchema).min(1),
|
|
243
|
+
})
|
|
244
|
+
.strict();
|
|
245
|
+
|
|
246
|
+
// RFC-0371: biome-driven Fontsource CSS imports. Each entry declares a
|
|
247
|
+
// @fontsource/* package and the weights (and optional italic weights) the
|
|
248
|
+
// biome needs. fonts.imports.generate reads this to emit @import statements.
|
|
249
|
+
export const biomeFontEntrySchema = z
|
|
250
|
+
.object({
|
|
251
|
+
family: z.string().min(1),
|
|
252
|
+
package: z.string().regex(/^@fontsource\//, "package must start with @fontsource/"),
|
|
253
|
+
weights: z.array(z.number().int().positive()).min(1),
|
|
254
|
+
italicWeights: z.array(z.number().int().positive()).optional(),
|
|
255
|
+
})
|
|
256
|
+
.strict();
|
|
257
|
+
|
|
258
|
+
export const biomeFontsSchema = z.array(biomeFontEntrySchema).optional();
|
|
259
|
+
|
|
260
|
+
export const biomeSchema = z
|
|
261
|
+
.object({
|
|
262
|
+
id: kebabId,
|
|
263
|
+
version: semver,
|
|
264
|
+
displayName: z.string().min(1),
|
|
265
|
+
family: kebabId,
|
|
266
|
+
provenance: biomeProvenanceSchema.optional(),
|
|
267
|
+
axes: biomeAxesSchema,
|
|
268
|
+
palette: biomePaletteSchema,
|
|
269
|
+
components: biomeComponentsSchema,
|
|
270
|
+
typography: biomeTypographySchema,
|
|
271
|
+
spacing: biomeSpacingSchema,
|
|
272
|
+
motion: biomeMotionSchema,
|
|
273
|
+
geometry: biomeGeometrySchema,
|
|
274
|
+
// RFC-0098: optional visual-DNA blocks promoted from studio tokens.
|
|
275
|
+
shadows: biomeShadowsSchema,
|
|
276
|
+
gradients: biomeGradientsSchema,
|
|
277
|
+
// RFC-0114: optional site-background defaults. When absent, the deriver
|
|
278
|
+
// (biome.site-background.derive) produces a sensible default from axes;
|
|
279
|
+
// when present, it is used verbatim and onboarding.scaffold seeds the
|
|
280
|
+
// new app's system.md shell.background from this block.
|
|
281
|
+
siteBackground: biomeSiteBackgroundSchema.optional(),
|
|
282
|
+
// RFC-0371: optional Fontsource CSS import declarations. When absent,
|
|
283
|
+
// the biome relies on system font fallbacks only.
|
|
284
|
+
fonts: biomeFontsSchema,
|
|
285
|
+
constraints: biomeConstraintsSchema,
|
|
286
|
+
})
|
|
287
|
+
.strict();
|
|
288
|
+
|
|
289
|
+
export type BiomeProvenance = z.infer<typeof biomeProvenanceSchema>;
|
|
290
|
+
export type BiomeAxes = z.infer<typeof biomeAxesSchema>;
|
|
291
|
+
export type BiomePalette = z.infer<typeof biomePaletteSchema>;
|
|
292
|
+
export type BiomeComponents = z.infer<typeof biomeComponentsSchema>;
|
|
293
|
+
export type BiomeTypography = z.infer<typeof biomeTypographySchema>;
|
|
294
|
+
export type BiomeSpacing = z.infer<typeof biomeSpacingSchema>;
|
|
295
|
+
export type BiomeMotion = z.infer<typeof biomeMotionSchema>;
|
|
296
|
+
export type BiomeGeometry = z.infer<typeof biomeGeometrySchema>;
|
|
297
|
+
export type BiomeShadows = z.infer<typeof biomeShadowsSchema>;
|
|
298
|
+
export type BiomeGradients = z.infer<typeof biomeGradientsSchema>;
|
|
299
|
+
export type BiomeConstraints = z.infer<typeof biomeConstraintsSchema>;
|
|
300
|
+
export type BiomeSiteBackground = z.infer<typeof biomeSiteBackgroundSchema>;
|
|
301
|
+
export type BiomeFontEntry = z.infer<typeof biomeFontEntrySchema>;
|
|
302
|
+
export type BiomeFontsConfig = z.infer<typeof biomeFontsSchema>;
|
|
303
|
+
export type Biome = z.infer<typeof biomeSchema>;
|